isaacscript-common 5.1.2 → 5.1.3

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,41 @@
1
+ import { GridCollisionClass, GridEntityType } from "isaac-typescript-definitions";
2
+ /**
3
+ * Helper function to spawn a custom grid entity.
4
+ *
5
+ * This is an IsaacScript feature because the vanilla game does not support any custom grid
6
+ * entities. Under the hood, IsaacScript accomplishes this by using decorations to represent custom
7
+ * grid entities.
8
+ *
9
+ * Once a custom grid entity is spawned, you can take advantage of the custom grid callbacks such as
10
+ * `POST_GRID_ENTITY_CUSTOM_UPDATE`.
11
+ *
12
+ * @param gridEntityTypeCustom An integer that identifies what kind of grid entity you are creating.
13
+ * It should correspond to a local enum value in your mod. The integer
14
+ * can be any unique value and will not correspond to the actual grid
15
+ * entity type used. (This integer is used in the various custom grid
16
+ * entity callbacks.)
17
+ * @param gridIndexOrPosition The grid index or position in the room that you want to spawn the grid
18
+ * entity at. If a position is specified, the closest grid index will be
19
+ * used.
20
+ * @param anm2 The path to the ANM2 file to use for the sprite.
21
+ * @param defaultAnimation The name of the animation to play after the sprite is initialized and
22
+ * after the player re-enters a room with this grid entity in it.
23
+ * @param gridCollisionClass The collision class that you want the custom grid entity to have.
24
+ */
25
+ export declare function spawnCustomGrid(gridEntityTypeCustom: GridEntityType, gridIndexOrPosition: int | Vector, anm2: string, defaultAnimation: string, gridCollisionClass: GridCollisionClass): GridEntity;
26
+ /**
27
+ * Helper function to remove a custom grid entity created by the `spawnCustomGrid` function.
28
+ *
29
+ * @param gridIndexOrPositionOrGridEntity You can specify the custom grid entity to remove by
30
+ * providing the grid index, the room position, or the grid entity
31
+ * itself.
32
+ * @param updateRoom Optional. Whether or not to update the room after the grid entity is removed.
33
+ * Default is true. This is generally a good idea because if the room is not
34
+ * updated, you will be unable to spawn another grid entity on the same tile until
35
+ * a frame has passed. However, doing this is expensive, since it involves a call
36
+ * to `Isaac.GetRoomEntities`, so set it to false if you need to invoke this
37
+ * function multiple times.
38
+ * @returns The grid entity that was removed. Returns undefined if no grid entity was found at the
39
+ * given location or if the given grid entity was not a custom grid entity.
40
+ */
41
+ export declare function removeCustomGrid(gridIndexOrPositionOrGridEntity: int | Vector | GridEntity, updateRoom?: boolean): GridEntity | undefined;
@@ -0,0 +1,154 @@
1
+ local ____lualib = require("lualib_bundle")
2
+ local Map = ____lualib.Map
3
+ local __TS__New = ____lualib.__TS__New
4
+ local __TS__Iterator = ____lualib.__TS__Iterator
5
+ local ____exports = {}
6
+ local postNewRoomReordered, v
7
+ local ____isaac_2Dtypescript_2Ddefinitions = require("isaac-typescript-definitions")
8
+ local GridEntityType = ____isaac_2Dtypescript_2Ddefinitions.GridEntityType
9
+ local ____cachedClasses = require("cachedClasses")
10
+ local game = ____cachedClasses.game
11
+ local ____DefaultMap = require("classes.DefaultMap")
12
+ local DefaultMap = ____DefaultMap.DefaultMap
13
+ local ____ModCallbackCustom = require("enums.ModCallbackCustom")
14
+ local ModCallbackCustom = ____ModCallbackCustom.ModCallbackCustom
15
+ local ____featuresInitialized = require("featuresInitialized")
16
+ local errorIfFeaturesNotInitialized = ____featuresInitialized.errorIfFeaturesNotInitialized
17
+ local ____gridEntity = require("functions.gridEntity")
18
+ local removeGrid = ____gridEntity.removeGrid
19
+ local spawnGrid = ____gridEntity.spawnGrid
20
+ local ____roomData = require("functions.roomData")
21
+ local getRoomListIndex = ____roomData.getRoomListIndex
22
+ local ____vector = require("functions.vector")
23
+ local isVector = ____vector.isVector
24
+ local ____exports = require("features.saveDataManager.exports")
25
+ local saveDataManager = ____exports.saveDataManager
26
+ function postNewRoomReordered(self)
27
+ local roomListIndex = getRoomListIndex(nil)
28
+ local roomCustomGridEntities = v.level.customGridEntities:get(roomListIndex)
29
+ if roomCustomGridEntities == nil then
30
+ return
31
+ end
32
+ local room = game:GetRoom()
33
+ for ____, ____value in __TS__Iterator(roomCustomGridEntities:entries()) do
34
+ local gridIndex = ____value[1]
35
+ local data = ____value[2]
36
+ do
37
+ local decoration = room:GetGridEntity(gridIndex)
38
+ if decoration == nil then
39
+ roomCustomGridEntities:delete(gridIndex)
40
+ goto __continue6
41
+ end
42
+ local sprite = decoration:GetSprite()
43
+ sprite:Load(data.anm2, true)
44
+ sprite:Play(data.defaultAnimation, true)
45
+ end
46
+ ::__continue6::
47
+ end
48
+ end
49
+ local FEATURE_NAME = "customGridEntity"
50
+ v = {level = {customGridEntities = __TS__New(
51
+ DefaultMap,
52
+ function() return __TS__New(Map) end
53
+ )}}
54
+ ---
55
+ -- @internal
56
+ function ____exports.customGridEntityInit(self, mod)
57
+ saveDataManager(nil, FEATURE_NAME, v)
58
+ mod:AddCallbackCustom(ModCallbackCustom.POST_NEW_ROOM_REORDERED, postNewRoomReordered)
59
+ end
60
+ --- Helper function to spawn a custom grid entity.
61
+ --
62
+ -- This is an IsaacScript feature because the vanilla game does not support any custom grid
63
+ -- entities. Under the hood, IsaacScript accomplishes this by using decorations to represent custom
64
+ -- grid entities.
65
+ --
66
+ -- Once a custom grid entity is spawned, you can take advantage of the custom grid callbacks such as
67
+ -- `POST_GRID_ENTITY_CUSTOM_UPDATE`.
68
+ --
69
+ -- @param gridEntityTypeCustom An integer that identifies what kind of grid entity you are creating.
70
+ -- It should correspond to a local enum value in your mod. The integer
71
+ -- can be any unique value and will not correspond to the actual grid
72
+ -- entity type used. (This integer is used in the various custom grid
73
+ -- entity callbacks.)
74
+ -- @param gridIndexOrPosition The grid index or position in the room that you want to spawn the grid
75
+ -- entity at. If a position is specified, the closest grid index will be
76
+ -- used.
77
+ -- @param anm2 The path to the ANM2 file to use for the sprite.
78
+ -- @param defaultAnimation The name of the animation to play after the sprite is initialized and
79
+ -- after the player re-enters a room with this grid entity in it.
80
+ -- @param gridCollisionClass The collision class that you want the custom grid entity to have.
81
+ function ____exports.spawnCustomGrid(self, gridEntityTypeCustom, gridIndexOrPosition, anm2, defaultAnimation, gridCollisionClass)
82
+ errorIfFeaturesNotInitialized(nil, FEATURE_NAME)
83
+ local room = game:GetRoom()
84
+ local roomListIndex = getRoomListIndex(nil)
85
+ local gridIndex = isVector(nil, gridIndexOrPosition) and room:GetGridIndex(gridIndexOrPosition) or gridIndexOrPosition
86
+ local existingGridEntity = room:GetGridEntity(gridIndex)
87
+ local isExistingDecoration = existingGridEntity ~= nil and existingGridEntity:GetType() == GridEntityType.DECORATION
88
+ local decoration = isExistingDecoration and existingGridEntity or spawnGrid(nil, GridEntityType.DECORATION, gridIndexOrPosition)
89
+ if decoration == nil then
90
+ error("Failed to spawn a decoration for a custom grid entity.")
91
+ end
92
+ local sprite = decoration:GetSprite()
93
+ sprite:Load(anm2, true)
94
+ sprite:Play(defaultAnimation, true)
95
+ local customGridEntityData = {
96
+ gridEntityTypeCustom = gridEntityTypeCustom,
97
+ roomListIndex = roomListIndex,
98
+ gridIndex = gridIndex,
99
+ anm2 = anm2,
100
+ defaultAnimation = defaultAnimation,
101
+ gridCollisionClass = gridCollisionClass
102
+ }
103
+ local roomCustomGridEntities = v.level.customGridEntities:getAndSetDefault(roomListIndex)
104
+ roomCustomGridEntities:set(gridIndex, customGridEntityData)
105
+ return decoration
106
+ end
107
+ --- Helper function to remove a custom grid entity created by the `spawnCustomGrid` function.
108
+ --
109
+ -- @param gridIndexOrPositionOrGridEntity You can specify the custom grid entity to remove by
110
+ -- providing the grid index, the room position, or the grid entity
111
+ -- itself.
112
+ -- @param updateRoom Optional. Whether or not to update the room after the grid entity is removed.
113
+ -- Default is true. This is generally a good idea because if the room is not
114
+ -- updated, you will be unable to spawn another grid entity on the same tile until
115
+ -- a frame has passed. However, doing this is expensive, since it involves a call
116
+ -- to `Isaac.GetRoomEntities`, so set it to false if you need to invoke this
117
+ -- function multiple times.
118
+ -- @returns The grid entity that was removed. Returns undefined if no grid entity was found at the
119
+ -- given location or if the given grid entity was not a custom grid entity.
120
+ function ____exports.removeCustomGrid(self, gridIndexOrPositionOrGridEntity, updateRoom)
121
+ if updateRoom == nil then
122
+ updateRoom = true
123
+ end
124
+ local room = game:GetRoom()
125
+ local roomListIndex = getRoomListIndex(nil)
126
+ local decoration
127
+ if type(gridIndexOrPositionOrGridEntity) == "number" then
128
+ local gridIndex = gridIndexOrPositionOrGridEntity
129
+ local gridEntity = room:GetGridEntity(gridIndex)
130
+ if gridEntity == nil then
131
+ return nil
132
+ end
133
+ decoration = gridEntity
134
+ elseif isVector(nil, gridIndexOrPositionOrGridEntity) then
135
+ local position = gridIndexOrPositionOrGridEntity
136
+ local gridEntity = room:GetGridEntityFromPos(position)
137
+ if gridEntity == nil then
138
+ return nil
139
+ end
140
+ decoration = gridEntity
141
+ else
142
+ decoration = gridIndexOrPositionOrGridEntity
143
+ end
144
+ local gridIndex = decoration:GetGridIndex()
145
+ local roomCustomGridEntities = v.level.customGridEntities:getAndSetDefault(roomListIndex)
146
+ local exists = roomCustomGridEntities:has(gridIndex)
147
+ if not exists then
148
+ return nil
149
+ end
150
+ roomCustomGridEntities:delete(gridIndex)
151
+ removeGrid(nil, decoration, updateRoom)
152
+ return decoration
153
+ end
154
+ return ____exports
@@ -0,0 +1,18 @@
1
+ import { RoomType } from "isaac-typescript-definitions";
2
+ /**
3
+ * In order to keep the size of the STB file small, we only allow certain room types to be used in
4
+ * IsaacScript custom stages.
5
+ */
6
+ export declare const CUSTOM_STAGE_ILLEGAL_ROOM_TYPES: Set<RoomType>;
7
+ /** StageAPI uses 70000 as a base. */
8
+ export declare const CUSTOM_STAGE_BASE_ROOM_VARIANT = 80000;
9
+ /**
10
+ * - The `RoomShape` enum goes from 1 to 12.
11
+ * - 12 in binary is 1100.
12
+ * - Thus, we need 4 bits to represent `RoomShape`.
13
+ */
14
+ export declare const CUSTOM_STAGE_NUM_ROOM_SHAPE_BITS = 4;
15
+ /**
16
+ * One for each possible door slot. We add one to account for `DoorSlot.LEFT_0` being equal to zero.
17
+ */
18
+ export declare const CUSTOM_STAGE_NUM_DOOR_SLOT_BITS: number;
@@ -0,0 +1,29 @@
1
+ local ____lualib = require("lualib_bundle")
2
+ local Set = ____lualib.Set
3
+ local __TS__New = ____lualib.__TS__New
4
+ local ____exports = {}
5
+ local ____isaac_2Dtypescript_2Ddefinitions = require("isaac-typescript-definitions")
6
+ local DoorSlot = ____isaac_2Dtypescript_2Ddefinitions.DoorSlot
7
+ local RoomType = ____isaac_2Dtypescript_2Ddefinitions.RoomType
8
+ local ____enums = require("functions.enums")
9
+ local getLastEnumValue = ____enums.getLastEnumValue
10
+ --- In order to keep the size of the STB file small, we only allow certain room types to be used in
11
+ -- IsaacScript custom stages.
12
+ ____exports.CUSTOM_STAGE_ILLEGAL_ROOM_TYPES = __TS__New(Set, {
13
+ RoomType.BOSS_RUSH,
14
+ RoomType.BLACK_MARKET,
15
+ RoomType.GREED_EXIT,
16
+ RoomType.TELEPORTER,
17
+ RoomType.TELEPORTER_EXIT,
18
+ RoomType.SECRET_EXIT,
19
+ RoomType.BLUE
20
+ })
21
+ --- StageAPI uses 70000 as a base.
22
+ ____exports.CUSTOM_STAGE_BASE_ROOM_VARIANT = 80000
23
+ --- - The `RoomShape` enum goes from 1 to 12.
24
+ -- - 12 in binary is 1100.
25
+ -- - Thus, we need 4 bits to represent `RoomShape`.
26
+ ____exports.CUSTOM_STAGE_NUM_ROOM_SHAPE_BITS = 4
27
+ --- One for each possible door slot. We add one to account for `DoorSlot.LEFT_0` being equal to zero.
28
+ ____exports.CUSTOM_STAGE_NUM_DOOR_SLOT_BITS = getLastEnumValue(nil, DoorSlot) + 1
29
+ return ____exports
@@ -0,0 +1,13 @@
1
+ import { LevelStage } from "isaac-typescript-definitions";
2
+ import { JSONRoom } from "../../interfaces/JSONRoom";
3
+ /**
4
+ * Helper function to register a new custom stage with the IsaacScript standard library stage
5
+ * system.
6
+ */
7
+ export declare function registerCustomStage(name: string, baseStage: LevelStage, jsonRooms: JSONRoom[] | readonly JSONRoom[]): void;
8
+ /**
9
+ * Helper function to warp to a custom stage/level.
10
+ *
11
+ * Custom stages/levels must first be registered with the `registerCustomStage` function.
12
+ */
13
+ export declare function setCustomStage(_name: string): void;
@@ -0,0 +1,23 @@
1
+ local ____lualib = require("lualib_bundle")
2
+ local Map = ____lualib.Map
3
+ local ____exports = {}
4
+ local ____v = require("features.customStage.v")
5
+ local customStages = ____v.customStages
6
+ --- Helper function to register a new custom stage with the IsaacScript standard library stage
7
+ -- system.
8
+ function ____exports.registerCustomStage(self, name, baseStage, jsonRooms)
9
+ if customStages:has(name) then
10
+ error(("Failed to register a custom stage of \"" .. name) .. "\" since there is already a custom stage registered by that name.")
11
+ end
12
+ if #jsonRooms == 0 then
13
+ error(("Failed to register a custom stage of \"" .. name) .. "\" since the provided JSON room array was empty.")
14
+ end
15
+ local customStageData = {name = name, baseStage = baseStage}
16
+ customStages:set(name, customStageData)
17
+ end
18
+ --- Helper function to warp to a custom stage/level.
19
+ --
20
+ -- Custom stages/levels must first be registered with the `registerCustomStage` function.
21
+ function ____exports.setCustomStage(self, _name)
22
+ end
23
+ return ____exports
@@ -0,0 +1,27 @@
1
+ /**
2
+ * Since room data is immutable, we need to create an array of empty rooms like the following:
3
+ *
4
+ * ```xml
5
+ * <room variant="80150" name="1x1" type="2" subtype="0" shape="1" width="13" height="7"
6
+ * difficulty="1" weight="0.0">
7
+ * <door exists="True" x="-1" y="3"/>
8
+ * <door exists="True" x="6" y="-1"/>
9
+ * <door exists="True" x="6" y="7"/>
10
+ * <door exists="True" x="13" y="3"/>
11
+ * </room>
12
+ * ```
13
+ *
14
+ * - We can repeat room variants between different room types.
15
+ * - The `RoomShape` enum goes from 1 to 12.
16
+ * - 12 in binary is 1100.
17
+ * - Thus, we need 4 bits to represent `RoomShape`.
18
+ * - There are 8 possible door slots.
19
+ * - Thus, we need 8 bits to represent `BitFlags<DoorSlot>`.
20
+ *
21
+ * Thus, the room variant has the following sequence:
22
+ * - 4 bits of `RoomShape` + 8 bits of `BitFlags<DoorSlot>`
23
+ *
24
+ * Even though Basement Renovator does not allow setting variants to values above 16 bits, values
25
+ * with 17 bits work fine in-game.
26
+ */
27
+ export declare function generateCustomStageBaseRooms(): void;
@@ -0,0 +1,126 @@
1
+ local ____lualib = require("lualib_bundle")
2
+ local Set = ____lualib.Set
3
+ local __TS__New = ____lualib.__TS__New
4
+ local __TS__SparseArrayNew = ____lualib.__TS__SparseArrayNew
5
+ local __TS__SparseArrayPush = ____lualib.__TS__SparseArrayPush
6
+ local __TS__SparseArraySpread = ____lualib.__TS__SparseArraySpread
7
+ local __TS__StringTrim = ____lualib.__TS__StringTrim
8
+ local __TS__StringSplit = ____lualib.__TS__StringSplit
9
+ local ____exports = {}
10
+ local ____isaac_2Dtypescript_2Ddefinitions = require("isaac-typescript-definitions")
11
+ local DoorSlot = ____isaac_2Dtypescript_2Ddefinitions.DoorSlot
12
+ local RoomShape = ____isaac_2Dtypescript_2Ddefinitions.RoomShape
13
+ local RoomType = ____isaac_2Dtypescript_2Ddefinitions.RoomType
14
+ local ____bitwise = require("functions.bitwise")
15
+ local convertBinaryToDecimal = ____bitwise.convertBinaryToDecimal
16
+ local convertDecimalToBinary = ____bitwise.convertDecimalToBinary
17
+ local setToBitFlags = ____bitwise.setToBitFlags
18
+ local ____doors = require("functions.doors")
19
+ local doorSlotToDoorSlotFlag = ____doors.doorSlotToDoorSlotFlag
20
+ local getDoorSlotsForRoomShape = ____doors.getDoorSlotsForRoomShape
21
+ local getRoomShapeDoorSlotCoordinates = ____doors.getRoomShapeDoorSlotCoordinates
22
+ local ____enums = require("functions.enums")
23
+ local getEnumValues = ____enums.getEnumValues
24
+ local ____flag = require("functions.flag")
25
+ local hasFlag = ____flag.hasFlag
26
+ local ____roomShape = require("functions.roomShape")
27
+ local getRoomShapeLayoutSize = ____roomShape.getRoomShapeLayoutSize
28
+ local ____set = require("functions.set")
29
+ local getSetCombinations = ____set.getSetCombinations
30
+ local getSortedSetValues = ____set.getSortedSetValues
31
+ local ____constants = require("features.customStage.constants")
32
+ local CUSTOM_STAGE_BASE_ROOM_VARIANT = ____constants.CUSTOM_STAGE_BASE_ROOM_VARIANT
33
+ local CUSTOM_STAGE_ILLEGAL_ROOM_TYPES = ____constants.CUSTOM_STAGE_ILLEGAL_ROOM_TYPES
34
+ local CUSTOM_STAGE_NUM_DOOR_SLOT_BITS = ____constants.CUSTOM_STAGE_NUM_DOOR_SLOT_BITS
35
+ local CUSTOM_STAGE_NUM_ROOM_SHAPE_BITS = ____constants.CUSTOM_STAGE_NUM_ROOM_SHAPE_BITS
36
+ --- Since room data is immutable, we need to create an array of empty rooms like the following:
37
+ --
38
+ -- ```xml
39
+ -- <room variant="80150" name="1x1" type="2" subtype="0" shape="1" width="13" height="7"
40
+ -- difficulty="1" weight="0.0">
41
+ -- <door exists="True" x="-1" y="3"/>
42
+ -- <door exists="True" x="6" y="-1"/>
43
+ -- <door exists="True" x="6" y="7"/>
44
+ -- <door exists="True" x="13" y="3"/>
45
+ -- </room>
46
+ -- ```
47
+ --
48
+ -- - We can repeat room variants between different room types.
49
+ -- - The `RoomShape` enum goes from 1 to 12.
50
+ -- - 12 in binary is 1100.
51
+ -- - Thus, we need 4 bits to represent `RoomShape`.
52
+ -- - There are 8 possible door slots.
53
+ -- - Thus, we need 8 bits to represent `BitFlags<DoorSlot>`.
54
+ --
55
+ -- Thus, the room variant has the following sequence:
56
+ -- - 4 bits of `RoomShape` + 8 bits of `BitFlags<DoorSlot>`
57
+ --
58
+ -- Even though Basement Renovator does not allow setting variants to values above 16 bits, values
59
+ -- with 17 bits work fine in-game.
60
+ function ____exports.generateCustomStageBaseRooms(self)
61
+ local rooms = {}
62
+ for ____, roomType in ipairs(getEnumValues(nil, RoomType)) do
63
+ do
64
+ if CUSTOM_STAGE_ILLEGAL_ROOM_TYPES:has(roomType) then
65
+ goto __continue3
66
+ end
67
+ for ____, roomShape in ipairs(getEnumValues(nil, RoomShape)) do
68
+ do
69
+ if roomType ~= RoomType.DEFAULT and roomShape ~= RoomShape.SHAPE_1x1 then
70
+ goto __continue5
71
+ end
72
+ local roomShapeBits = convertDecimalToBinary(nil, roomShape, CUSTOM_STAGE_NUM_ROOM_SHAPE_BITS)
73
+ local doorSlotsSet = getDoorSlotsForRoomShape(nil, roomShape)
74
+ local doorSlots = getSortedSetValues(nil, doorSlotsSet)
75
+ local doorSlotFlagsSet = __TS__New(Set)
76
+ for ____, doorSlot in ipairs(doorSlots) do
77
+ local doorSlotFlag = doorSlotToDoorSlotFlag(nil, doorSlot)
78
+ doorSlotFlagsSet:add(doorSlotFlag)
79
+ end
80
+ local doorSlotFlagCombinations = getSetCombinations(nil, doorSlotFlagsSet, false)
81
+ for ____, doorSlotFlagCombination in ipairs(doorSlotFlagCombinations) do
82
+ local doorSlotFlags = setToBitFlags(nil, doorSlotFlagCombination)
83
+ local doorSlotBits = convertDecimalToBinary(nil, doorSlotFlags, CUSTOM_STAGE_NUM_DOOR_SLOT_BITS)
84
+ local ____array_0 = __TS__SparseArrayNew(table.unpack(roomShapeBits))
85
+ __TS__SparseArrayPush(
86
+ ____array_0,
87
+ table.unpack(doorSlotBits)
88
+ )
89
+ local combinedBits = {__TS__SparseArraySpread(____array_0)}
90
+ local roomVariant = CUSTOM_STAGE_BASE_ROOM_VARIANT + convertBinaryToDecimal(nil, combinedBits)
91
+ local name = (((("Type: " .. tostring(roomType)) .. ", Shape: ") .. tostring(roomShape)) .. ", DoorSlotFlags: ") .. tostring(doorSlotFlags)
92
+ local width, height = table.unpack(getRoomShapeLayoutSize(nil, roomShape))
93
+ local roomHeader = (((((((((((" <room name=\"" .. name) .. "\" type=\"") .. tostring(roomType)) .. "\" variant=\"") .. tostring(roomVariant)) .. "\" subtype=\"0\" shape=\"") .. tostring(roomShape)) .. "\" width=\"") .. tostring(width)) .. "\" height=\"") .. tostring(height)) .. "\" difficulty=\"1\" weight=\"0.0\">\n"
94
+ local doors = {}
95
+ for ____, doorSlot in ipairs(doorSlots) do
96
+ local thisDoorSlotFlag = doorSlotToDoorSlotFlag(nil, doorSlot)
97
+ local exists = hasFlag(nil, doorSlotFlags, thisDoorSlotFlag)
98
+ local existsText = exists and "True" or "False"
99
+ local coordinates = getRoomShapeDoorSlotCoordinates(nil, roomShape, doorSlot)
100
+ if coordinates == nil then
101
+ error(((((((("Failed to get the coordinates for room shape " .. tostring(RoomShape[roomShape])) .. " (") .. tostring(roomShape)) .. ") and door slot ") .. tostring(DoorSlot[doorSlot])) .. " (") .. tostring(doorSlot)) .. ").")
102
+ end
103
+ local x, y = table.unpack(coordinates)
104
+ local door = (((((" <door exists=\"" .. existsText) .. "\" x=\"") .. tostring(x)) .. "\" y=\"") .. tostring(y)) .. "\" />\n"
105
+ doors[#doors + 1] = door
106
+ end
107
+ local doorsXML = table.concat(doors, "")
108
+ local roomFooter = " </room>\n"
109
+ local room = (roomHeader .. doorsXML) .. roomFooter
110
+ rooms[#rooms + 1] = room
111
+ end
112
+ end
113
+ ::__continue5::
114
+ end
115
+ end
116
+ ::__continue3::
117
+ end
118
+ local xml = table.concat({
119
+ __TS__StringTrim(("\n<?xml version=\"1.0\" ?>\n<rooms>\n" .. table.concat(rooms, "")) .. "\n</rooms>"),
120
+ "\n"
121
+ })
122
+ for ____, line in ipairs(__TS__StringSplit(xml, "\n")) do
123
+ Isaac.DebugString(line)
124
+ end
125
+ end
126
+ return ____exports
@@ -0,0 +1,2 @@
1
+ import { CustomStageData } from "../../interfaces/CustomStageData";
2
+ export declare const customStages: Map<string, CustomStageData>;
@@ -0,0 +1,6 @@
1
+ local ____lualib = require("lualib_bundle")
2
+ local Map = ____lualib.Map
3
+ local __TS__New = ____lualib.__TS__New
4
+ local ____exports = {}
5
+ ____exports.customStages = __TS__New(Map)
6
+ return ____exports
@@ -1,21 +1,3 @@
1
- /// <reference types="isaac-typescript-definitions" />
2
- /// <reference types="isaac-typescript-definitions" />
3
- /// <reference types="isaac-typescript-definitions" />
4
- /// <reference types="isaac-typescript-definitions" />
5
- /// <reference types="isaac-typescript-definitions" />
6
- /// <reference types="isaac-typescript-definitions" />
7
- /// <reference types="isaac-typescript-definitions" />
8
- /// <reference types="isaac-typescript-definitions" />
9
- /// <reference types="isaac-typescript-definitions" />
10
- /// <reference types="isaac-typescript-definitions" />
11
- /// <reference types="isaac-typescript-definitions" />
12
- /// <reference types="isaac-typescript-definitions" />
13
- /// <reference types="isaac-typescript-definitions" />
14
- /// <reference types="isaac-typescript-definitions" />
15
- /// <reference types="isaac-typescript-definitions" />
16
- /// <reference types="isaac-typescript-definitions" />
17
- /// <reference types="isaac-typescript-definitions" />
18
- /// <reference types="isaac-typescript-definitions" />
19
1
  declare const v: {
20
2
  run: {
21
3
  player: boolean;
@@ -24,7 +24,7 @@ import { JSONRoom } from "../interfaces/JSONRoom";
24
24
  * @param verbose Optional. If specified, will write entries to the "log.txt" file that describe
25
25
  * what the function is doing. Default is false.
26
26
  */
27
- export declare function deployJSONRoom(jsonRoom: JSONRoom, seedOrRNG?: Seed | RNG, verbose?: boolean): void;
27
+ export declare function deployJSONRoom(jsonRoom: JSONRoom | Readonly<JSONRoom>, seedOrRNG?: Seed | RNG, verbose?: boolean): void;
28
28
  /**
29
29
  * Helper function to deconstruct a vanilla room and set up a custom room in its place.
30
30
  * Specifically, this will clear the current room of all entities and grid entities, and then spawn
@@ -52,7 +52,7 @@ export declare function deployJSONRoom(jsonRoom: JSONRoom, seedOrRNG?: Seed | RN
52
52
  * @param verbose Optional. If specified, will write entries to the "log.txt" file that describe
53
53
  * what the function is doing. Default is false.
54
54
  */
55
- export declare function deployRandomJSONRoom(jsonRooms: JSONRoom[], seedOrRNG?: Seed | RNG, verbose?: boolean): void;
55
+ export declare function deployRandomJSONRoom(jsonRooms: JSONRoom[] | readonly JSONRoom[], seedOrRNG?: Seed | RNG, verbose?: boolean): void;
56
56
  /**
57
57
  * Helper function to remove all naturally spawning entities and grid entities from a room. Notably,
58
58
  * this will not remove players (1), tears (2), familiars (3), lasers (7), knives (8), projectiles
@@ -38,7 +38,7 @@ function postPEffectUpdateReordered(self, player)
38
38
  setDeletePlayer(nil, v.run.playersIsPonyActive, player)
39
39
  end
40
40
  end
41
- local FEATURE_NAME = "ponyDetector"
41
+ local FEATURE_NAME = "ponyDetection"
42
42
  FLAGS_WHEN_PONY_IS_ACTIVE = {EntityFlag.NO_KNOCKBACK, EntityFlag.NO_PHYSICS_KNOCKBACK, EntityFlag.NO_DAMAGE_BLINK}
43
43
  v = {run = {playersIsPonyActive = __TS__New(Set)}}
44
44
  ---
@@ -1,7 +1,7 @@
1
1
  local ____lualib = require("lualib_bundle")
2
- local __TS__ArrayForEach = ____lualib.__TS__ArrayForEach
2
+ local __TS__ArrayFilter = ____lualib.__TS__ArrayFilter
3
3
  local ____exports = {}
4
- local postUpdate, postRender, checkExecuteQueuedFunctions, checkExecuteIntervalFunctions, getFunctionsThatShouldFireOnThisFrame, v
4
+ local postUpdate, postRender, checkExecuteQueuedFunctions, checkExecuteIntervalFunctions, v
5
5
  local ____isaac_2Dtypescript_2Ddefinitions = require("isaac-typescript-definitions")
6
6
  local ModCallback = ____isaac_2Dtypescript_2Ddefinitions.ModCallback
7
7
  local ____cachedClasses = require("cachedClasses")
@@ -9,7 +9,7 @@ local game = ____cachedClasses.game
9
9
  local ____featuresInitialized = require("featuresInitialized")
10
10
  local errorIfFeaturesNotInitialized = ____featuresInitialized.errorIfFeaturesNotInitialized
11
11
  local ____array = require("functions.array")
12
- local arrayRemoveIndexInPlace = ____array.arrayRemoveIndexInPlace
12
+ local arrayRemoveInPlace = ____array.arrayRemoveInPlace
13
13
  local ____exports = require("features.saveDataManager.exports")
14
14
  local saveDataManager = ____exports.saveDataManager
15
15
  function postUpdate(self)
@@ -23,43 +23,40 @@ function postRender(self)
23
23
  checkExecuteIntervalFunctions(nil, renderFrameCount, v.run.intervalRenderFunctionTuples)
24
24
  end
25
25
  function checkExecuteQueuedFunctions(self, frameCount, functionTuples)
26
- local firingFunctions = getFunctionsThatShouldFireOnThisFrame(nil, frameCount, functionTuples)
27
- for ____, ____value in ipairs(firingFunctions) do
28
- local i = ____value[1]
29
- local func = ____value[2]
26
+ local firingFunctions = __TS__ArrayFilter(
27
+ functionTuples,
28
+ function(____, ____bindingPattern0)
29
+ local frameCountToFire
30
+ frameCountToFire = ____bindingPattern0[1]
31
+ return frameCount >= frameCountToFire
32
+ end
33
+ )
34
+ for ____, tuple in ipairs(firingFunctions) do
35
+ local _frameCountToFire, func = table.unpack(tuple)
30
36
  func(nil)
31
- arrayRemoveIndexInPlace(nil, functionTuples, i)
37
+ arrayRemoveInPlace(nil, functionTuples, tuple)
32
38
  end
33
39
  end
34
40
  function checkExecuteIntervalFunctions(self, frameCount, functionTuples)
35
- local firingFunctions = getFunctionsThatShouldFireOnThisFrame(nil, frameCount, functionTuples)
36
- for ____, ____value in ipairs(firingFunctions) do
37
- local i = ____value[1]
38
- local func = ____value[2]
39
- local numIntervalFrames = ____value[3]
41
+ local firingFunctions = __TS__ArrayFilter(
42
+ functionTuples,
43
+ function(____, ____bindingPattern0)
44
+ local frameCountToFire
45
+ frameCountToFire = ____bindingPattern0[1]
46
+ return frameCount >= frameCountToFire
47
+ end
48
+ )
49
+ for ____, tuple in ipairs(firingFunctions) do
50
+ local _frameCountToFire, func, numIntervalFrames = table.unpack(tuple)
40
51
  local returnValue = func(nil)
41
- arrayRemoveIndexInPlace(nil, functionTuples, i)
42
- if numIntervalFrames ~= nil and returnValue ~= false then
52
+ arrayRemoveInPlace(nil, functionTuples, tuple)
53
+ if returnValue then
43
54
  local nextFireFrame = frameCount + numIntervalFrames
44
- local tuple = {nextFireFrame, func, numIntervalFrames}
45
- functionTuples[#functionTuples + 1] = tuple
55
+ local newTuple = {nextFireFrame, func, numIntervalFrames}
56
+ functionTuples[#functionTuples + 1] = newTuple
46
57
  end
47
58
  end
48
59
  end
49
- function getFunctionsThatShouldFireOnThisFrame(self, frameCount, functionTuples)
50
- local firingFunctionTuples = {}
51
- __TS__ArrayForEach(
52
- functionTuples,
53
- function(____, functionTuple, i)
54
- local frameCountToFire, func, numIntervalFrames = table.unpack(functionTuple)
55
- if frameCount >= frameCountToFire then
56
- local firingFunctionTuple = {i, func, numIntervalFrames}
57
- firingFunctionTuples[#firingFunctionTuples + 1] = firingFunctionTuple
58
- end
59
- end
60
- )
61
- return firingFunctionTuples
62
- end
63
60
  local FEATURE_NAME = "runInNFrames"
64
61
  v = {run = {queuedGameFunctionTuples = {}, queuedRenderFunctionTuples = {}, intervalGameFunctionTuples = {}, intervalRenderFunctionTuples = {}}}
65
62
  ---
@@ -2,15 +2,14 @@ local ____lualib = require("lualib_bundle")
2
2
  local __TS__ArrayFilter = ____lualib.__TS__ArrayFilter
3
3
  local ____exports = {}
4
4
  local ____isaac_2Dtypescript_2Ddefinitions = require("isaac-typescript-definitions")
5
- local PickupVariant = ____isaac_2Dtypescript_2Ddefinitions.PickupVariant
5
+ local SackSubType = ____isaac_2Dtypescript_2Ddefinitions.SackSubType
6
6
  local ____runInNFrames = require("features.runInNFrames")
7
7
  local runNextGameFrame = ____runInNFrames.runNextGameFrame
8
8
  local ____entity = require("functions.entity")
9
9
  local removeEntities = ____entity.removeEntities
10
- local ____entitySpecific = require("functions.entitySpecific")
11
- local spawnPickupWithSeed = ____entitySpecific.spawnPickupWithSeed
12
10
  local ____pickups = require("functions.pickups")
13
11
  local getCoins = ____pickups.getCoins
12
+ local spawnSackWithSeed = ____pickups.spawnSackWithSeed
14
13
  --- Hard-coding this makes it easier to clean up the pickups afterwards.
15
14
  local SACK_SEED_THAT_SPAWNS_TWO_COINS = 6
16
15
  --- Helper function to start a Challenge Room or the Boss Rush.
@@ -19,13 +18,7 @@ local SACK_SEED_THAT_SPAWNS_TWO_COINS = 6
19
18
  -- and then removing the sack and the pickups that the sack dropped.
20
19
  function ____exports.startAmbush(self)
21
20
  local player = Isaac.GetPlayer()
22
- local sack = spawnPickupWithSeed(
23
- nil,
24
- PickupVariant.SACK,
25
- 0,
26
- player.Position,
27
- SACK_SEED_THAT_SPAWNS_TWO_COINS
28
- )
21
+ local sack = spawnSackWithSeed(nil, SackSubType.NULL, player.Position, SACK_SEED_THAT_SPAWNS_TWO_COINS)
29
22
  local sprite = sack:GetSprite()
30
23
  sprite:Stop()
31
24
  local sackPtr = EntityPtr(sack)
@@ -12,13 +12,48 @@ export declare function arrayEquals<T>(array1: T[] | readonly T[], array2: T[] |
12
12
  * array.
13
13
  *
14
14
  * This function is variadic, meaning that you can specify N arguments to remove N elements.
15
+ *
16
+ * If there is more than one matching element in the array, this function will only remove the first
17
+ * matching element. If you want to remove all of the elements, use the `arrayRemoveAll` function
18
+ * instead.
15
19
  */
16
20
  export declare function arrayRemove<T>(originalArray: T[] | readonly T[], ...elementsToRemove: T[]): T[];
21
+ /**
22
+ * Shallow copies and removes the specified element(s) from the array. Returns the copied array. If
23
+ * the specified element(s) are not found in the array, it will simply return a shallow copy of the
24
+ * array.
25
+ *
26
+ * This function is variadic, meaning that you can specify N arguments to remove N elements.
27
+ *
28
+ * If there is more than one matching element in the array, this function will remove every matching
29
+ * element. If you want to only remove the first matching element, use the `arrayRemove` function
30
+ * instead.
31
+ */
32
+ export declare function arrayRemoveAll<T>(originalArray: T[] | readonly T[], ...elementsToRemove: T[]): T[];
33
+ /**
34
+ * Removes all of the specified element(s) from the array. If the specified element(s) are not found
35
+ * in the array, this function will do nothing.
36
+ *
37
+ * This function is variadic, meaning that you can specify N arguments to remove N elements.
38
+ *
39
+ * If there is more than one matching element in the array, this function will remove every matching
40
+ * element. If you want to only remove the first matching element, use the `arrayRemoveInPlace`
41
+ * function instead.
42
+ *
43
+ * @returns True if one or more elements were removed, false otherwise.
44
+ */
45
+ export declare function arrayRemoveAllInPlace<T>(array: T[], ...elementsToRemove: T[]): boolean;
17
46
  /**
18
47
  * Removes the specified element(s) from the array. If the specified element(s) are not found in the
19
- * array, this function will do nothing. Returns true if one or more elements were removed.
48
+ * array, this function will do nothing.
20
49
  *
21
50
  * This function is variadic, meaning that you can specify N arguments to remove N elements.
51
+ *
52
+ * If there is more than one matching element in the array, this function will only remove the first
53
+ * matching element. If you want to remove all of the elements, use the `arrayRemoveAllInPlace`
54
+ * function instead.
55
+ *
56
+ * @returns True if one or more elements were removed, false otherwise.
22
57
  */
23
58
  export declare function arrayRemoveInPlace<T>(array: T[], ...elementsToRemove: T[]): boolean;
24
59
  /**
@@ -35,6 +70,8 @@ export declare function arrayRemoveIndex<T>(originalArray: T[] | readonly T[], .
35
70
  * removed.
36
71
  *
37
72
  * This function is variadic, meaning that you can specify N arguments to remove N elements.
73
+ *
74
+ * @returns Whether or not any array elements were removed.
38
75
  */
39
76
  export declare function arrayRemoveIndexInPlace<T>(array: T[], ...indexesToRemove: int[]): boolean;
40
77
  export declare function arrayToString<T>(array: T[] | readonly T[]): string;
@@ -1,9 +1,9 @@
1
1
  local ____lualib = require("lualib_bundle")
2
2
  local __TS__ArrayEvery = ____lualib.__TS__ArrayEvery
3
- local Set = ____lualib.Set
4
- local __TS__New = ____lualib.__TS__New
5
3
  local __TS__ArrayIndexOf = ____lualib.__TS__ArrayIndexOf
6
4
  local __TS__ArraySplice = ____lualib.__TS__ArraySplice
5
+ local Set = ____lualib.Set
6
+ local __TS__New = ____lualib.__TS__New
7
7
  local __TS__ArrayForEach = ____lualib.__TS__ArrayForEach
8
8
  local __TS__ArrayFilter = ____lualib.__TS__ArrayFilter
9
9
  local __TS__ArraySort = ____lualib.__TS__ArraySort
@@ -27,6 +27,77 @@ local isTable = ____types.isTable
27
27
  local ____utils = require("functions.utils")
28
28
  local erange = ____utils.erange
29
29
  local ____repeat = ____utils["repeat"]
30
+ --- Removes all of the specified element(s) from the array. If the specified element(s) are not found
31
+ -- in the array, this function will do nothing.
32
+ --
33
+ -- This function is variadic, meaning that you can specify N arguments to remove N elements.
34
+ --
35
+ -- If there is more than one matching element in the array, this function will remove every matching
36
+ -- element. If you want to only remove the first matching element, use the `arrayRemoveInPlace`
37
+ -- function instead.
38
+ --
39
+ -- @returns True if one or more elements were removed, false otherwise.
40
+ function ____exports.arrayRemoveAllInPlace(self, array, ...)
41
+ local elementsToRemove = {...}
42
+ local removedOneOrMoreElements = false
43
+ for ____, element in ipairs(elementsToRemove) do
44
+ local index
45
+ repeat
46
+ do
47
+ index = __TS__ArrayIndexOf(array, element)
48
+ if index > -1 then
49
+ removedOneOrMoreElements = true
50
+ __TS__ArraySplice(array, index, 1)
51
+ end
52
+ end
53
+ until not (index > -1)
54
+ end
55
+ return removedOneOrMoreElements
56
+ end
57
+ --- Removes the specified element(s) from the array. If the specified element(s) are not found in the
58
+ -- array, this function will do nothing.
59
+ --
60
+ -- This function is variadic, meaning that you can specify N arguments to remove N elements.
61
+ --
62
+ -- If there is more than one matching element in the array, this function will only remove the first
63
+ -- matching element. If you want to remove all of the elements, use the `arrayRemoveAllInPlace`
64
+ -- function instead.
65
+ --
66
+ -- @returns True if one or more elements were removed, false otherwise.
67
+ function ____exports.arrayRemoveInPlace(self, array, ...)
68
+ local elementsToRemove = {...}
69
+ local removedOneOrMoreElements = false
70
+ for ____, element in ipairs(elementsToRemove) do
71
+ local index = __TS__ArrayIndexOf(array, element)
72
+ if index > -1 then
73
+ removedOneOrMoreElements = true
74
+ __TS__ArraySplice(array, index, 1)
75
+ end
76
+ end
77
+ return removedOneOrMoreElements
78
+ end
79
+ --- Helper function to perform a shallow copy.
80
+ --
81
+ -- @param oldArray The array to copy.
82
+ -- @param numElements Optional. If specified, will only copy the first N elements. By default, the
83
+ -- entire array will be copied.
84
+ function ____exports.copyArray(self, oldArray, numElements)
85
+ if numElements == nil then
86
+ numElements = #oldArray
87
+ end
88
+ local newArray = {}
89
+ do
90
+ local i = 0
91
+ while i < numElements do
92
+ local oldElement = oldArray[i + 1]
93
+ if oldElement ~= nil then
94
+ newArray[#newArray + 1] = oldElement
95
+ end
96
+ i = i + 1
97
+ end
98
+ end
99
+ return newArray
100
+ end
30
101
  --- Helper function to get a random index from the provided array.
31
102
  --
32
103
  -- @param array The array to get the index from.
@@ -97,32 +168,28 @@ end
97
168
  -- array.
98
169
  --
99
170
  -- This function is variadic, meaning that you can specify N arguments to remove N elements.
171
+ --
172
+ -- If there is more than one matching element in the array, this function will only remove the first
173
+ -- matching element. If you want to remove all of the elements, use the `arrayRemoveAll` function
174
+ -- instead.
100
175
  function ____exports.arrayRemove(self, originalArray, ...)
101
- local elementsToRemove = {...}
102
- local elementsToRemoveSet = __TS__New(Set, elementsToRemove)
103
- local array = {}
104
- for ____, element in ipairs(originalArray) do
105
- if not elementsToRemoveSet:has(element) then
106
- array[#array + 1] = element
107
- end
108
- end
176
+ local array = ____exports.copyArray(nil, originalArray)
177
+ ____exports.arrayRemoveInPlace(nil, array, ...)
109
178
  return array
110
179
  end
111
- --- Removes the specified element(s) from the array. If the specified element(s) are not found in the
112
- -- array, this function will do nothing. Returns true if one or more elements were removed.
180
+ --- Shallow copies and removes the specified element(s) from the array. Returns the copied array. If
181
+ -- the specified element(s) are not found in the array, it will simply return a shallow copy of the
182
+ -- array.
113
183
  --
114
184
  -- This function is variadic, meaning that you can specify N arguments to remove N elements.
115
- function ____exports.arrayRemoveInPlace(self, array, ...)
116
- local elementsToRemove = {...}
117
- local removedOneOrMoreElements = false
118
- for ____, element in ipairs(elementsToRemove) do
119
- local index = __TS__ArrayIndexOf(array, element)
120
- if index > -1 then
121
- removedOneOrMoreElements = true
122
- __TS__ArraySplice(array, index, 1)
123
- end
124
- end
125
- return removedOneOrMoreElements
185
+ --
186
+ -- If there is more than one matching element in the array, this function will remove every matching
187
+ -- element. If you want to only remove the first matching element, use the `arrayRemove` function
188
+ -- instead.
189
+ function ____exports.arrayRemoveAll(self, originalArray, ...)
190
+ local array = ____exports.copyArray(nil, originalArray)
191
+ ____exports.arrayRemoveAllInPlace(nil, array, ...)
192
+ return array
126
193
  end
127
194
  --- Shallow copies and removes the elements at the specified indexes from the array. Returns the
128
195
  -- copied array. If the specified indexes are not found in the array, it will simply return a
@@ -148,6 +215,8 @@ end
148
215
  -- removed.
149
216
  --
150
217
  -- This function is variadic, meaning that you can specify N arguments to remove N elements.
218
+ --
219
+ -- @returns Whether or not any array elements were removed.
151
220
  function ____exports.arrayRemoveIndexInPlace(self, array, ...)
152
221
  local indexesToRemove = {...}
153
222
  local legalIndexes = __TS__ArrayFilter(
@@ -193,28 +262,6 @@ function ____exports.combineArrays(self, ...)
193
262
  end
194
263
  return elements
195
264
  end
196
- --- Helper function to perform a shallow copy.
197
- --
198
- -- @param oldArray The array to copy.
199
- -- @param numElements Optional. If specified, will only copy the first N elements. By default, the
200
- -- entire array will be copied.
201
- function ____exports.copyArray(self, oldArray, numElements)
202
- if numElements == nil then
203
- numElements = #oldArray
204
- end
205
- local newArray = {}
206
- do
207
- local i = 0
208
- while i < numElements do
209
- local oldElement = oldArray[i + 1]
210
- if oldElement ~= nil then
211
- newArray[#newArray + 1] = oldElement
212
- end
213
- i = i + 1
214
- end
215
- end
216
- return newArray
217
- end
218
265
  --- Helper function to remove all of the elements in an array in-place.
219
266
  function ____exports.emptyArray(self, array)
220
267
  __TS__ArraySplice(array, 0, #array)
@@ -1,5 +1,5 @@
1
- /// <reference types="isaac-typescript-definitions" />
2
1
  /// <reference types="typescript-to-lua/language-extensions" />
2
+ /// <reference types="isaac-typescript-definitions" />
3
3
  import { SerializationType } from "../enums/SerializationType";
4
4
  declare type SerializedColor = LuaTable<string, unknown> & {
5
5
  readonly __serializedColorBrand: symbol;
@@ -44,6 +44,13 @@ export declare function getCollidingEntitiesWithGridEntity(gridEntity: GridEntit
44
44
  * ```
45
45
  */
46
46
  export declare function getGridEntities(...gridEntityTypes: GridEntityType[]): GridEntity[];
47
+ /**
48
+ * Helper function to get every grid entity in the current room except for certain specific types.
49
+ *
50
+ * This function is variadic, meaning that you can specify as many grid entity types as you want to
51
+ * exclude.
52
+ */
53
+ export declare function getGridEntitiesExcept(...gridEntityTypes: GridEntityType[]): GridEntity[];
47
54
  /**
48
55
  * Helper function to get a map of every grid entity in the current room. The indexes of the map are
49
56
  * equal to the grid index. The values of the map are equal to the grid entities.
@@ -121,9 +128,10 @@ export declare function removeAllGridExcept(...gridEntityTypes: GridEntityType[]
121
128
  */
122
129
  export declare function removeAllMatchingGridEntities(...gridEntityType: GridEntityType[]): GridEntity[];
123
130
  /**
124
- * Helper function to remove a grid entity simply by providing the grid entity object.
131
+ * Helper function to remove a grid entity simply by providing the grid entity object. By default,
132
+ * this will also update the room.
125
133
  *
126
- * @param gridEntity The grid entity to remove.
134
+ * @param gridEntityOrGridIndex The grid entity or grid index to remove.
127
135
  * @param updateRoom Optional. Whether or not to update the room after the grid entity is removed.
128
136
  * Default is true. This is generally a good idea because if the room is not
129
137
  * updated, you will be unable to spawn another grid entity on the same tile until
@@ -131,7 +139,7 @@ export declare function removeAllMatchingGridEntities(...gridEntityType: GridEnt
131
139
  * to `Isaac.GetRoomEntities`, so set it to false if you need to invoke this
132
140
  * function multiple times.
133
141
  */
134
- export declare function removeGrid(gridEntity: GridEntity, updateRoom?: boolean): void;
142
+ export declare function removeGrid(gridEntityOrGridIndex: GridEntity, updateRoom?: boolean): void;
135
143
  /**
136
144
  * Helper function to make a grid entity invisible. This is accomplished by setting its sprite to an
137
145
  * empty/missing PNG file.
@@ -59,21 +59,22 @@ function ____exports.getTopLeftWallGridIndex(self)
59
59
  local topLeftWallGridIndex = ROOM_SHAPE_TO_TOP_LEFT_WALL_GRID_INDEX_MAP:get(roomShape)
60
60
  return topLeftWallGridIndex == nil and DEFAULT_TOP_LEFT_WALL_GRID_INDEX or topLeftWallGridIndex
61
61
  end
62
- --- Helper function to remove a grid entity simply by providing the grid entity object.
62
+ --- Helper function to remove a grid entity simply by providing the grid entity object. By default,
63
+ -- this will also update the room.
63
64
  --
64
- -- @param gridEntity The grid entity to remove.
65
+ -- @param gridEntityOrGridIndex The grid entity or grid index to remove.
65
66
  -- @param updateRoom Optional. Whether or not to update the room after the grid entity is removed.
66
67
  -- Default is true. This is generally a good idea because if the room is not
67
68
  -- updated, you will be unable to spawn another grid entity on the same tile until
68
69
  -- a frame has passed. However, doing this is expensive, since it involves a call
69
70
  -- to `Isaac.GetRoomEntities`, so set it to false if you need to invoke this
70
71
  -- function multiple times.
71
- function ____exports.removeGrid(self, gridEntity, updateRoom)
72
+ function ____exports.removeGrid(self, gridEntityOrGridIndex, updateRoom)
72
73
  if updateRoom == nil then
73
74
  updateRoom = true
74
75
  end
75
76
  local room = game:GetRoom()
76
- local gridIndex = gridEntity:GetGridIndex()
77
+ local gridIndex = gridEntityOrGridIndex:GetGridIndex()
77
78
  room:RemoveGridEntity(gridIndex, 0, false)
78
79
  if updateRoom then
79
80
  roomUpdateSafe(nil)
@@ -201,6 +202,25 @@ function ____exports.getGridEntities(self, ...)
201
202
  end
202
203
  )
203
204
  end
205
+ --- Helper function to get every grid entity in the current room except for certain specific types.
206
+ --
207
+ -- This function is variadic, meaning that you can specify as many grid entity types as you want to
208
+ -- exclude.
209
+ function ____exports.getGridEntitiesExcept(self, ...)
210
+ local gridEntityTypes = {...}
211
+ local gridEntities = getAllGridEntities(nil)
212
+ if #gridEntityTypes == 0 then
213
+ return gridEntities
214
+ end
215
+ local gridEntityTypesSet = __TS__New(Set, gridEntityTypes)
216
+ return __TS__ArrayFilter(
217
+ gridEntities,
218
+ function(____, gridEntity)
219
+ local gridEntityType = gridEntity:GetType()
220
+ return not gridEntityTypesSet:has(gridEntityType)
221
+ end
222
+ )
223
+ end
204
224
  --- Helper function to get a map of every grid entity in the current room. The indexes of the map are
205
225
  -- equal to the grid index. The values of the map are equal to the grid entities.
206
226
  --
@@ -2,8 +2,8 @@
2
2
  /// <reference types="isaac-typescript-definitions" />
3
3
  /// <reference types="isaac-typescript-definitions" />
4
4
  import { JSONRoom } from "../interfaces/JSONRoom";
5
- export declare function getJSONRoomOfVariant(jsonRooms: JSONRoom[], variant: int): JSONRoom | undefined;
6
- export declare function getJSONRoomsOfSubType(jsonRooms: JSONRoom[], subType: int): JSONRoom[];
5
+ export declare function getJSONRoomOfVariant(jsonRooms: JSONRoom[] | readonly JSONRoom[], variant: int): JSONRoom | undefined;
6
+ export declare function getJSONRoomsOfSubType(jsonRooms: JSONRoom[] | readonly JSONRoom[], subType: int): JSONRoom[];
7
7
  /**
8
8
  * Helper function to get a random JSON room from an array of JSON rooms.
9
9
  *
@@ -11,4 +11,4 @@ export declare function getJSONRoomsOfSubType(jsonRooms: JSONRoom[], subType: in
11
11
  * properly account for each room weight using the algorithm from:
12
12
  * https://stackoverflow.com/questions/1761626/weighted-random-numbers
13
13
  */
14
- export declare function getRandomJSONRoom(jsonRooms: JSONRoom[], seedOrRNG?: Seed | RNG, verbose?: boolean): JSONRoom;
14
+ export declare function getRandomJSONRoom(jsonRooms: JSONRoom[] | readonly JSONRoom[], seedOrRNG?: Seed | RNG, verbose?: boolean): JSONRoom;
@@ -1,5 +1,5 @@
1
- /// <reference types="isaac-typescript-definitions" />
2
1
  /// <reference types="typescript-to-lua/language-extensions" />
2
+ /// <reference types="isaac-typescript-definitions" />
3
3
  import { SerializationType } from "../enums/SerializationType";
4
4
  declare type SerializedKColor = LuaTable<string, unknown> & {
5
5
  readonly __serializedKColorBrand: symbol;
@@ -1,6 +1,6 @@
1
+ /// <reference types="typescript-to-lua/language-extensions" />
1
2
  /// <reference types="isaac-typescript-definitions" />
2
3
  /// <reference types="isaac-typescript-definitions" />
3
- /// <reference types="typescript-to-lua/language-extensions" />
4
4
  import { SerializationType } from "../enums/SerializationType";
5
5
  declare type SerializedRNG = LuaTable<string, unknown> & {
6
6
  readonly __serializedRNGBrand: symbol;
package/index.d.ts CHANGED
@@ -12,6 +12,7 @@ export * from "./enums/SerializationType";
12
12
  export { ConversionHeartSubType, registerCharacterHealthConversion, } from "./features/characterHealthConversion";
13
13
  export { registerCharacterStats } from "./features/characterStats";
14
14
  export { getCollectibleItemPoolType } from "./features/collectibleItemPoolType";
15
+ export { removeCustomGrid, spawnCustomGrid } from "./features/customGridEntity";
15
16
  export * from "./features/debugDisplay/exports";
16
17
  export { deployJSONRoom, deployRandomJSONRoom, emptyRoom, } from "./features/deployJSONRoom";
17
18
  export { disableAllSound, enableAllSound } from "./features/disableAllSound";
package/index.lua CHANGED
@@ -100,6 +100,13 @@ do
100
100
  local getCollectibleItemPoolType = ____collectibleItemPoolType.getCollectibleItemPoolType
101
101
  ____exports.getCollectibleItemPoolType = getCollectibleItemPoolType
102
102
  end
103
+ do
104
+ local ____customGridEntity = require("features.customGridEntity")
105
+ local removeCustomGrid = ____customGridEntity.removeCustomGrid
106
+ local spawnCustomGrid = ____customGridEntity.spawnCustomGrid
107
+ ____exports.removeCustomGrid = removeCustomGrid
108
+ ____exports.spawnCustomGrid = spawnCustomGrid
109
+ end
103
110
  do
104
111
  local ____export = require("features.debugDisplay.exports")
105
112
  for ____exportKey, ____exportValue in pairs(____export) do
package/initFeatures.lua CHANGED
@@ -5,6 +5,8 @@ local ____characterStats = require("features.characterStats")
5
5
  local characterStatsInit = ____characterStats.characterStatsInit
6
6
  local ____collectibleItemPoolType = require("features.collectibleItemPoolType")
7
7
  local collectibleItemPoolTypeInit = ____collectibleItemPoolType.collectibleItemPoolTypeInit
8
+ local ____customGridEntity = require("features.customGridEntity")
9
+ local customGridEntityInit = ____customGridEntity.customGridEntityInit
8
10
  local ____deployJSONRoom = require("features.deployJSONRoom")
9
11
  local deployJSONRoomInit = ____deployJSONRoom.deployJSONRoomInit
10
12
  local ____disableAllSound = require("features.disableAllSound")
@@ -42,6 +44,7 @@ function ____exports.initFeaturesMajor(self, mod)
42
44
  runInNFramesInit(nil, mod)
43
45
  characterStatsInit(nil, mod)
44
46
  characterHealthConversionInit(nil, mod)
47
+ customGridEntityInit(nil, mod)
45
48
  end
46
49
  function ____exports.initFeaturesMinor(self, mod)
47
50
  disableAllSoundInit(nil, mod)
@@ -0,0 +1,9 @@
1
+ import { GridCollisionClass, GridEntityType } from "isaac-typescript-definitions";
2
+ export interface CustomGridEntityData {
3
+ gridEntityTypeCustom: GridEntityType;
4
+ roomListIndex: int;
5
+ gridIndex: int;
6
+ anm2: string;
7
+ defaultAnimation: string;
8
+ gridCollisionClass: GridCollisionClass;
9
+ }
@@ -0,0 +1,2 @@
1
+ local ____exports = {}
2
+ return ____exports
@@ -0,0 +1,5 @@
1
+ import { LevelStage } from "isaac-typescript-definitions";
2
+ export interface CustomStageData {
3
+ name: string;
4
+ baseStage: LevelStage;
5
+ }
@@ -0,0 +1,2 @@
1
+ local ____exports = {}
2
+ return ____exports
@@ -1,4 +1,3 @@
1
- /// <reference types="isaac-typescript-definitions" />
2
1
  /**
3
2
  * A collection of common colors that can be reused.
4
3
  *
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "isaacscript-common",
3
- "version": "5.1.2",
3
+ "version": "5.1.3",
4
4
  "description": "Helper functions and features for IsaacScript mods.",
5
5
  "keywords": [
6
6
  "isaac",