isaacscript-common 1.0.463 → 1.0.467
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/deployJSONRoom.d.ts +38 -0
- package/dist/features/deployJSONRoom.lua +385 -0
- package/dist/features/preventCollectibleRotate.d.ts +13 -0
- package/dist/features/preventCollectibleRotate.lua +49 -0
- package/dist/functions/collectibleSet.lua +2 -2
- package/dist/functions/collectibles.d.ts +5 -0
- package/dist/functions/collectibles.lua +8 -0
- package/dist/functions/doors.d.ts +1 -0
- package/dist/functions/doors.lua +25 -16
- package/dist/functions/gridEntity.d.ts +14 -0
- package/dist/functions/gridEntity.lua +26 -2
- package/dist/functions/jsonRoom.d.ts +5 -0
- package/dist/functions/jsonRoom.lua +65 -0
- package/dist/functions/rooms.d.ts +11 -0
- package/dist/functions/rooms.lua +36 -0
- package/dist/functions/spawnCollectible.d.ts +15 -0
- package/dist/functions/spawnCollectible.lua +41 -0
- package/dist/functions/trinketSet.lua +2 -2
- package/dist/index.d.ts +9 -0
- package/dist/index.lua +30 -0
- package/dist/initialized.d.ts +2 -0
- package/dist/initialized.lua +10 -0
- package/dist/types/JSONDoor.d.ts +10 -0
- package/dist/types/JSONDoor.lua +3 -0
- package/dist/types/JSONEntity.d.ts +12 -0
- package/dist/types/JSONEntity.lua +3 -0
- package/dist/types/JSONRoom.d.ts +30 -0
- package/dist/types/JSONRoom.lua +3 -0
- package/dist/types/JSONRooms.d.ts +11 -0
- package/dist/types/JSONRooms.lua +3 -0
- package/dist/types/JSONSpawn.d.ts +10 -0
- package/dist/types/JSONSpawn.lua +3 -0
- package/dist/types/PersistentEntityDescription.d.ts +7 -0
- package/dist/types/PersistentEntityDescription.lua +3 -0
- package/dist/upgradeMod.lua +11 -3
- package/package.json +3 -3
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
/// <reference types="isaac-typescript-definitions" />
|
|
2
|
+
import { JSONRoom } from "../types/JSONRoom";
|
|
3
|
+
import { ModUpgraded } from "../types/ModUpgraded";
|
|
4
|
+
/** @hidden */
|
|
5
|
+
export declare function deployJSONRoomInit(mod: ModUpgraded): void;
|
|
6
|
+
/**
|
|
7
|
+
* Helper function to deconstruct a vanilla room and set up a custom room in its place.
|
|
8
|
+
* Specifically, this will clear the current room of all entities and grid entities, and then spawn
|
|
9
|
+
* all of the entries and grid entities in the provided JSON room.
|
|
10
|
+
*
|
|
11
|
+
* This function is meant to be used in the PostNewRoom callback.
|
|
12
|
+
*
|
|
13
|
+
* @returns The iterated seed, which can be used in subsequent room deployments. (The seed is used
|
|
14
|
+
* to spawn every entity contained within the custom room.)
|
|
15
|
+
*/
|
|
16
|
+
export declare function deployJSONRoom(jsonRoom: JSONRoom, seed?: number): int;
|
|
17
|
+
/**
|
|
18
|
+
* Helper function to deconstruct a vanilla room and set up a custom room in its place.
|
|
19
|
+
* Specifically, this will clear the current room of all entities and grid entities, and then spawn
|
|
20
|
+
* all of the entries and grid entities in one of the provided JSON rooms.
|
|
21
|
+
*
|
|
22
|
+
* This function is meant to be used in the PostNewRoom callback.
|
|
23
|
+
*
|
|
24
|
+
* @returns The iterated seed, which can be used in subsequent room deployments. (The seed is used
|
|
25
|
+
* to spawn every entity contained within the custom room.)
|
|
26
|
+
*/
|
|
27
|
+
export declare function deployRandomJSONRoom(jsonRooms: JSONRoom[], seed?: number): int;
|
|
28
|
+
/**
|
|
29
|
+
* Helper function to remove all naturally spawning entities and grid entities from a room. Notably,
|
|
30
|
+
* this will not remove players (1), tears (2), familiars (3), lasers (7), knives (8),
|
|
31
|
+
* projectiles (9), blacklisted NPCs such as Dark Esau, charmed NPCs, friendly NPCs, and persistent
|
|
32
|
+
* NPCs.
|
|
33
|
+
*
|
|
34
|
+
* @param fillWithDecorations Optional. Set to true to fill every grid tile with an invisible
|
|
35
|
+
* decoration, which prevents vanilla entities in the room from respawning the next time that the
|
|
36
|
+
* player enters. False by default.
|
|
37
|
+
*/
|
|
38
|
+
export declare function emptyRoom(fillWithDecorations: boolean): void;
|
|
@@ -0,0 +1,385 @@
|
|
|
1
|
+
--[[ Generated with https://github.com/TypeScriptToLua/TypeScriptToLua ]]
|
|
2
|
+
require("lualib_bundle");
|
|
3
|
+
local ____exports = {}
|
|
4
|
+
local postNewRoom, setDecorationsInvisible, respawnPersistentEntities, removeSpecificNPCs, fillRoomWithDecorations, spawnAllEntities, spawnGridEntity, spawnNormalEntity, storePersistentEntity, fixPitGraphics, getPitMap, getPitFrame, FEATURE_NAME, NPCS_TO_NOT_REMOVE, PERSISTENT_ENTITY_TYPES, initialized, v
|
|
5
|
+
local ____errors = require("errors")
|
|
6
|
+
local getUpgradeErrorMsg = ____errors.getUpgradeErrorMsg
|
|
7
|
+
local ____entity = require("functions.entity")
|
|
8
|
+
local removeAllBombs = ____entity.removeAllBombs
|
|
9
|
+
local removeAllMatchingEntities = ____entity.removeAllMatchingEntities
|
|
10
|
+
local removeAllPickups = ____entity.removeAllPickups
|
|
11
|
+
local ____gridEntity = require("functions.gridEntity")
|
|
12
|
+
local convertXMLGridEntityType = ____gridEntity.convertXMLGridEntityType
|
|
13
|
+
local getGridEntities = ____gridEntity.getGridEntities
|
|
14
|
+
local setGridEntityInvisible = ____gridEntity.setGridEntityInvisible
|
|
15
|
+
local ____jsonRoom = require("functions.jsonRoom")
|
|
16
|
+
local getRandomJSONRoom = ____jsonRoom.getRandomJSONRoom
|
|
17
|
+
local ____npc = require("functions.npc")
|
|
18
|
+
local getNPCs = ____npc.getNPCs
|
|
19
|
+
local ____random = require("functions.random")
|
|
20
|
+
local nextSeed = ____random.nextSeed
|
|
21
|
+
local ____rooms = require("functions.rooms")
|
|
22
|
+
local getRoomIndex = ____rooms.getRoomIndex
|
|
23
|
+
local gridToPos = ____rooms.gridToPos
|
|
24
|
+
local setRoomCleared = ____rooms.setRoomCleared
|
|
25
|
+
local setRoomUncleared = ____rooms.setRoomUncleared
|
|
26
|
+
local ____spawnCollectible = require("functions.spawnCollectible")
|
|
27
|
+
local spawnCollectible = ____spawnCollectible.spawnCollectible
|
|
28
|
+
local ____exports = require("features.saveDataManager.exports")
|
|
29
|
+
local saveDataManager = ____exports.saveDataManager
|
|
30
|
+
function postNewRoom(self)
|
|
31
|
+
local roomIndex = getRoomIndex(nil)
|
|
32
|
+
if not v.level.deployedRoomIndexes:has(roomIndex) then
|
|
33
|
+
return
|
|
34
|
+
end
|
|
35
|
+
setDecorationsInvisible(nil)
|
|
36
|
+
respawnPersistentEntities(nil)
|
|
37
|
+
end
|
|
38
|
+
function setDecorationsInvisible(self)
|
|
39
|
+
local game = Game()
|
|
40
|
+
local room = game:GetRoom()
|
|
41
|
+
local roomIndex = getRoomIndex(nil)
|
|
42
|
+
local decorationGridIndexes = v.level.decorationGridIndexes:get(roomIndex)
|
|
43
|
+
if decorationGridIndexes == nil then
|
|
44
|
+
return
|
|
45
|
+
end
|
|
46
|
+
for ____, gridIndex in ipairs(decorationGridIndexes) do
|
|
47
|
+
local gridEntity = room:GetGridEntity(gridIndex)
|
|
48
|
+
if gridEntity ~= nil then
|
|
49
|
+
setGridEntityInvisible(nil, gridEntity)
|
|
50
|
+
end
|
|
51
|
+
end
|
|
52
|
+
end
|
|
53
|
+
function respawnPersistentEntities(self)
|
|
54
|
+
local game = Game()
|
|
55
|
+
local room = game:GetRoom()
|
|
56
|
+
local roomIndex = getRoomIndex(nil)
|
|
57
|
+
local persistentEntities = v.level.persistentEntities:get(roomIndex)
|
|
58
|
+
if persistentEntities == nil then
|
|
59
|
+
return
|
|
60
|
+
end
|
|
61
|
+
for ____, persistentEntity in ipairs(persistentEntities) do
|
|
62
|
+
local position = room:GetGridPosition(persistentEntity.gridIndex)
|
|
63
|
+
Isaac.Spawn(persistentEntity.type, persistentEntity.variant, persistentEntity.subType, position, Vector.Zero, nil)
|
|
64
|
+
end
|
|
65
|
+
end
|
|
66
|
+
function ____exports.emptyRoom(self, fillWithDecorations)
|
|
67
|
+
if not initialized then
|
|
68
|
+
local msg = getUpgradeErrorMsg(nil, FEATURE_NAME)
|
|
69
|
+
error(msg)
|
|
70
|
+
end
|
|
71
|
+
local roomIndex = getRoomIndex(nil)
|
|
72
|
+
v.level.deployedRoomIndexes:add(roomIndex)
|
|
73
|
+
removeAllBombs(nil)
|
|
74
|
+
removeAllPickups(nil)
|
|
75
|
+
removeAllMatchingEntities(nil, EntityType.ENTITY_SLOT)
|
|
76
|
+
removeSpecificNPCs(nil)
|
|
77
|
+
setRoomCleared(nil)
|
|
78
|
+
if fillWithDecorations then
|
|
79
|
+
fillRoomWithDecorations(nil)
|
|
80
|
+
end
|
|
81
|
+
end
|
|
82
|
+
function removeSpecificNPCs(self)
|
|
83
|
+
local game = Game()
|
|
84
|
+
local room = game:GetRoom()
|
|
85
|
+
for ____, npc in ipairs(
|
|
86
|
+
getNPCs(nil)
|
|
87
|
+
) do
|
|
88
|
+
do
|
|
89
|
+
if NPCS_TO_NOT_REMOVE:has(npc.Type) then
|
|
90
|
+
goto __continue20
|
|
91
|
+
end
|
|
92
|
+
if (npc:HasEntityFlags(EntityFlag.FLAG_CHARM) or npc:HasEntityFlags(EntityFlag.FLAG_FRIENDLY)) or npc:HasEntityFlags(EntityFlag.FLAG_PERSISTENT) then
|
|
93
|
+
goto __continue20
|
|
94
|
+
end
|
|
95
|
+
npc:ClearEntityFlags(EntityFlag.FLAG_APPEAR)
|
|
96
|
+
npc:Remove()
|
|
97
|
+
if npc.Type == EntityType.ENTITY_FIREPLACE then
|
|
98
|
+
local gridIndex = room:GetGridIndex(npc.Position)
|
|
99
|
+
room:SetGridPath(gridIndex, 0)
|
|
100
|
+
end
|
|
101
|
+
end
|
|
102
|
+
::__continue20::
|
|
103
|
+
end
|
|
104
|
+
end
|
|
105
|
+
function fillRoomWithDecorations(self)
|
|
106
|
+
local game = Game()
|
|
107
|
+
local room = game:GetRoom()
|
|
108
|
+
local gridSize = room:GetGridSize()
|
|
109
|
+
local roomIndex = getRoomIndex(nil)
|
|
110
|
+
local decorationGridIndexes = v.level.decorationGridIndexes:get(roomIndex)
|
|
111
|
+
if decorationGridIndexes == nil then
|
|
112
|
+
decorationGridIndexes = {}
|
|
113
|
+
v.level.decorationGridIndexes:set(roomIndex, decorationGridIndexes)
|
|
114
|
+
end
|
|
115
|
+
do
|
|
116
|
+
local gridIndex = 0
|
|
117
|
+
while gridIndex < gridSize do
|
|
118
|
+
do
|
|
119
|
+
local existingGridEntity = room:GetGridEntity(gridIndex)
|
|
120
|
+
if existingGridEntity ~= nil then
|
|
121
|
+
goto __continue26
|
|
122
|
+
end
|
|
123
|
+
local position = room:GetGridPosition(gridIndex)
|
|
124
|
+
local decoration = Isaac.GridSpawn(GridEntityType.GRID_DECORATION, 0, position, true)
|
|
125
|
+
setGridEntityInvisible(nil, decoration)
|
|
126
|
+
__TS__ArrayPush(decorationGridIndexes, gridIndex)
|
|
127
|
+
end
|
|
128
|
+
::__continue26::
|
|
129
|
+
gridIndex = gridIndex + 1
|
|
130
|
+
end
|
|
131
|
+
end
|
|
132
|
+
end
|
|
133
|
+
function spawnAllEntities(self, jsonRoom, seed)
|
|
134
|
+
local shouldUnclearRoom = false
|
|
135
|
+
for ____, spawn in ipairs(jsonRoom.spawn) do
|
|
136
|
+
local xString = spawn["$"].x
|
|
137
|
+
local x = tonumber(xString)
|
|
138
|
+
if x == nil then
|
|
139
|
+
error("Failed to convert the following x coordinate to a number (for a spawn): " .. xString)
|
|
140
|
+
end
|
|
141
|
+
local yString = spawn["$"].y
|
|
142
|
+
local y = tonumber(yString)
|
|
143
|
+
if y == nil then
|
|
144
|
+
error("Failed to convert the following y coordinate to a number (for a spawn): " .. yString)
|
|
145
|
+
end
|
|
146
|
+
local entityTypeString = spawn.entity["$"].type
|
|
147
|
+
local entityType = tonumber(entityTypeString)
|
|
148
|
+
if entityType == nil then
|
|
149
|
+
error("Failed to convert the entity type to a number: " .. entityTypeString)
|
|
150
|
+
end
|
|
151
|
+
local variantString = spawn.entity["$"].variant
|
|
152
|
+
local variant = tonumber(variantString)
|
|
153
|
+
if variant == nil then
|
|
154
|
+
error(
|
|
155
|
+
"Failed to convert the entity variant to a number: " .. tostring(variant)
|
|
156
|
+
)
|
|
157
|
+
end
|
|
158
|
+
local subTypeString = spawn.entity["$"].subtype
|
|
159
|
+
local subType = tonumber(subTypeString)
|
|
160
|
+
if subType == nil then
|
|
161
|
+
error(
|
|
162
|
+
"Failed to convert the entity sub-type to a number: " .. tostring(subType)
|
|
163
|
+
)
|
|
164
|
+
end
|
|
165
|
+
if entityType >= 1000 then
|
|
166
|
+
spawnGridEntity(nil, entityType, variant, x, y)
|
|
167
|
+
else
|
|
168
|
+
seed = nextSeed(nil, seed)
|
|
169
|
+
local entity = spawnNormalEntity(nil, entityType, variant, subType, x, y, seed)
|
|
170
|
+
local npc = entity:ToNPC()
|
|
171
|
+
if (npc ~= nil) and npc.CanShutDoors then
|
|
172
|
+
shouldUnclearRoom = true
|
|
173
|
+
end
|
|
174
|
+
end
|
|
175
|
+
end
|
|
176
|
+
if shouldUnclearRoom then
|
|
177
|
+
setRoomUncleared(nil)
|
|
178
|
+
end
|
|
179
|
+
return seed
|
|
180
|
+
end
|
|
181
|
+
function spawnGridEntity(self, xmlEntityType, xmlEntityVariant, x, y)
|
|
182
|
+
local gridEntityArray = convertXMLGridEntityType(nil, xmlEntityType, xmlEntityVariant)
|
|
183
|
+
if gridEntityArray == nil then
|
|
184
|
+
return nil
|
|
185
|
+
end
|
|
186
|
+
local entityType, variant = table.unpack(gridEntityArray)
|
|
187
|
+
local position = gridToPos(nil, x, y)
|
|
188
|
+
local gridEntity = Isaac.GridSpawn(entityType, variant, position, true)
|
|
189
|
+
if entityType == GridEntityType.GRID_PIT then
|
|
190
|
+
local pit = gridEntity:ToPit()
|
|
191
|
+
if pit ~= nil then
|
|
192
|
+
pit:UpdateCollision()
|
|
193
|
+
end
|
|
194
|
+
end
|
|
195
|
+
if entityType == GridEntityType.GRID_POOP then
|
|
196
|
+
local sprite = gridEntity:GetSprite()
|
|
197
|
+
sprite:Play("State1", true)
|
|
198
|
+
sprite:SetLastFrame()
|
|
199
|
+
end
|
|
200
|
+
return gridEntity
|
|
201
|
+
end
|
|
202
|
+
function spawnNormalEntity(self, entityType, variant, subType, x, y, seed)
|
|
203
|
+
local game = Game()
|
|
204
|
+
local room = game:GetRoom()
|
|
205
|
+
local roomType = room:GetType()
|
|
206
|
+
local position = gridToPos(nil, x, y)
|
|
207
|
+
local entity
|
|
208
|
+
if (entityType == EntityType.ENTITY_PICKUP) and (variant == PickupVariant.PICKUP_COLLECTIBLE) then
|
|
209
|
+
local options = roomType == RoomType.ROOM_ANGEL
|
|
210
|
+
entity = spawnCollectible(nil, subType, position, seed, options)
|
|
211
|
+
else
|
|
212
|
+
entity = game:Spawn(entityType, variant, position, Vector.Zero, nil, subType, seed)
|
|
213
|
+
end
|
|
214
|
+
if (entityType == EntityType.ENTITY_PITFALL) and (variant == 0) then
|
|
215
|
+
entity.EntityCollisionClass = EntityCollisionClass.ENTCOLL_ENEMIES
|
|
216
|
+
entity.GridCollisionClass = EntityGridCollisionClass.GRIDCOLL_WALLS
|
|
217
|
+
end
|
|
218
|
+
storePersistentEntity(nil, entity)
|
|
219
|
+
return entity
|
|
220
|
+
end
|
|
221
|
+
function storePersistentEntity(self, entity)
|
|
222
|
+
if not PERSISTENT_ENTITY_TYPES:has(entity.Type) then
|
|
223
|
+
return
|
|
224
|
+
end
|
|
225
|
+
local game = Game()
|
|
226
|
+
local room = game:GetRoom()
|
|
227
|
+
local gridIndex = room:GetGridIndex(entity.Position)
|
|
228
|
+
local roomIndex = getRoomIndex(nil)
|
|
229
|
+
local persistentEntity = {gridIndex = gridIndex, type = entity.Type, variant = entity.Variant, subType = entity.SubType}
|
|
230
|
+
local persistentEntities = v.level.persistentEntities:get(roomIndex)
|
|
231
|
+
if persistentEntities == nil then
|
|
232
|
+
persistentEntities = {}
|
|
233
|
+
v.level.persistentEntities:set(roomIndex, persistentEntities)
|
|
234
|
+
end
|
|
235
|
+
__TS__ArrayPush(persistentEntities, persistentEntity)
|
|
236
|
+
end
|
|
237
|
+
function fixPitGraphics(self)
|
|
238
|
+
local game = Game()
|
|
239
|
+
local room = game:GetRoom()
|
|
240
|
+
local gridWidth = room:GetGridWidth()
|
|
241
|
+
local pitMap = getPitMap(nil)
|
|
242
|
+
for ____, ____value in __TS__Iterator(
|
|
243
|
+
pitMap:entries()
|
|
244
|
+
) do
|
|
245
|
+
local gridIndex
|
|
246
|
+
gridIndex = ____value[1]
|
|
247
|
+
local gridEntity
|
|
248
|
+
gridEntity = ____value[2]
|
|
249
|
+
local gridIndexLeft = gridIndex - 1
|
|
250
|
+
local L = pitMap:has(gridIndexLeft)
|
|
251
|
+
local gridIndexRight = gridIndex + 1
|
|
252
|
+
local R = pitMap:has(gridIndexRight)
|
|
253
|
+
local gridIndexUp = gridIndex - gridWidth
|
|
254
|
+
local U = pitMap:has(gridIndexUp)
|
|
255
|
+
local gridIndexDown = gridIndex + gridWidth
|
|
256
|
+
local D = pitMap:has(gridIndexDown)
|
|
257
|
+
local gridIndexUpLeft = (gridIndex - gridWidth) - 1
|
|
258
|
+
local UL = pitMap:has(gridIndexUpLeft)
|
|
259
|
+
local gridIndexUpRight = (gridIndex - gridWidth) + 1
|
|
260
|
+
local UR = pitMap:has(gridIndexUpRight)
|
|
261
|
+
local gridIndexDownLeft = (gridIndex + gridWidth) - 1
|
|
262
|
+
local DL = pitMap:has(gridIndexDownLeft)
|
|
263
|
+
local gridIndexDownRight = (gridIndex + gridWidth) + 1
|
|
264
|
+
local DR = pitMap:has(gridIndexDownRight)
|
|
265
|
+
local pitFrame = getPitFrame(nil, L, R, U, D, UL, UR, DL, DR)
|
|
266
|
+
local sprite = gridEntity:GetSprite()
|
|
267
|
+
sprite:SetFrame(pitFrame)
|
|
268
|
+
end
|
|
269
|
+
end
|
|
270
|
+
function getPitMap(self)
|
|
271
|
+
local pitMap = __TS__New(Map)
|
|
272
|
+
for ____, gridEntity in ipairs(
|
|
273
|
+
getGridEntities(nil, GridEntityType.GRID_PIT)
|
|
274
|
+
) do
|
|
275
|
+
local gridIndex = gridEntity:GetGridIndex()
|
|
276
|
+
pitMap:set(gridIndex, gridEntity)
|
|
277
|
+
end
|
|
278
|
+
return pitMap
|
|
279
|
+
end
|
|
280
|
+
function getPitFrame(self, L, R, U, D, UL, UR, DL, DR)
|
|
281
|
+
local F = 0
|
|
282
|
+
if L then
|
|
283
|
+
F = F | 1
|
|
284
|
+
end
|
|
285
|
+
if U then
|
|
286
|
+
F = F | 2
|
|
287
|
+
end
|
|
288
|
+
if R then
|
|
289
|
+
F = F | 4
|
|
290
|
+
end
|
|
291
|
+
if D then
|
|
292
|
+
F = F | 8
|
|
293
|
+
end
|
|
294
|
+
if (((U and L) and (not UL)) and (not R)) and (not D) then
|
|
295
|
+
F = 17
|
|
296
|
+
end
|
|
297
|
+
if (((U and R) and (not UR)) and (not L)) and (not D) then
|
|
298
|
+
F = 18
|
|
299
|
+
end
|
|
300
|
+
if (((L and D) and (not DL)) and (not U)) and (not R) then
|
|
301
|
+
F = 19
|
|
302
|
+
end
|
|
303
|
+
if (((R and D) and (not DR)) and (not L)) and (not U) then
|
|
304
|
+
F = 20
|
|
305
|
+
end
|
|
306
|
+
if (((L and U) and R) and D) and (not UL) then
|
|
307
|
+
F = 21
|
|
308
|
+
end
|
|
309
|
+
if (((L and U) and R) and D) and (not UR) then
|
|
310
|
+
F = 22
|
|
311
|
+
end
|
|
312
|
+
if (((U and R) and D) and (not L)) and (not UR) then
|
|
313
|
+
F = 25
|
|
314
|
+
end
|
|
315
|
+
if (((L and U) and D) and (not R)) and (not UL) then
|
|
316
|
+
F = 26
|
|
317
|
+
end
|
|
318
|
+
if ((((L and U) and R) and D) and (not DL)) and (not DR) then
|
|
319
|
+
F = 24
|
|
320
|
+
end
|
|
321
|
+
if ((((L and U) and R) and D) and (not UR)) and (not UL) then
|
|
322
|
+
F = 23
|
|
323
|
+
end
|
|
324
|
+
if ((((L and U) and R) and UL) and (not UR)) and (not D) then
|
|
325
|
+
F = 27
|
|
326
|
+
end
|
|
327
|
+
if ((((L and U) and R) and UR) and (not UL)) and (not D) then
|
|
328
|
+
F = 28
|
|
329
|
+
end
|
|
330
|
+
if ((((L and U) and R) and (not D)) and (not UR)) and (not UL) then
|
|
331
|
+
F = 29
|
|
332
|
+
end
|
|
333
|
+
if ((((L and R) and D) and DL) and (not U)) and (not DR) then
|
|
334
|
+
F = 30
|
|
335
|
+
end
|
|
336
|
+
if ((((L and R) and D) and DR) and (not U)) and (not DL) then
|
|
337
|
+
F = 31
|
|
338
|
+
end
|
|
339
|
+
if ((((L and R) and D) and (not U)) and (not DL)) and (not DR) then
|
|
340
|
+
F = 32
|
|
341
|
+
end
|
|
342
|
+
return F
|
|
343
|
+
end
|
|
344
|
+
FEATURE_NAME = "JSON room deployer"
|
|
345
|
+
NPCS_TO_NOT_REMOVE = __TS__New(Set, {EntityType.ENTITY_DARK_ESAU})
|
|
346
|
+
PERSISTENT_ENTITY_TYPES = __TS__New(Set, {EntityType.ENTITY_WALL_HUGGER})
|
|
347
|
+
initialized = false
|
|
348
|
+
v = {
|
|
349
|
+
level = {
|
|
350
|
+
deployedRoomIndexes = __TS__New(Set),
|
|
351
|
+
persistentEntities = __TS__New(Map),
|
|
352
|
+
decorationGridIndexes = __TS__New(Map)
|
|
353
|
+
}
|
|
354
|
+
}
|
|
355
|
+
function ____exports.deployJSONRoomInit(self, mod)
|
|
356
|
+
initialized = true
|
|
357
|
+
saveDataManager(nil, "deployJSONRoom", v)
|
|
358
|
+
mod:AddCallback(ModCallbacks.MC_POST_NEW_ROOM, postNewRoom)
|
|
359
|
+
end
|
|
360
|
+
function ____exports.deployJSONRoom(self, jsonRoom, seed)
|
|
361
|
+
if seed == nil then
|
|
362
|
+
seed = Random()
|
|
363
|
+
end
|
|
364
|
+
if not initialized then
|
|
365
|
+
local msg = getUpgradeErrorMsg(nil, FEATURE_NAME)
|
|
366
|
+
error(msg)
|
|
367
|
+
end
|
|
368
|
+
____exports.emptyRoom(nil, false)
|
|
369
|
+
local newSeed = spawnAllEntities(nil, jsonRoom, seed)
|
|
370
|
+
fixPitGraphics(nil)
|
|
371
|
+
fillRoomWithDecorations(nil)
|
|
372
|
+
return newSeed
|
|
373
|
+
end
|
|
374
|
+
function ____exports.deployRandomJSONRoom(self, jsonRooms, seed)
|
|
375
|
+
if seed == nil then
|
|
376
|
+
seed = Random()
|
|
377
|
+
end
|
|
378
|
+
if not initialized then
|
|
379
|
+
local msg = getUpgradeErrorMsg(nil, FEATURE_NAME)
|
|
380
|
+
error(msg)
|
|
381
|
+
end
|
|
382
|
+
local randomJSONRoom = getRandomJSONRoom(nil, jsonRooms, seed)
|
|
383
|
+
return ____exports.deployJSONRoom(nil, randomJSONRoom, seed)
|
|
384
|
+
end
|
|
385
|
+
return ____exports
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/// <reference types="isaac-typescript-definitions" />
|
|
2
|
+
import { ModUpgraded } from "../types/ModUpgraded";
|
|
3
|
+
export declare function preventCollectibleRotateInit(mod: ModUpgraded): void;
|
|
4
|
+
/**
|
|
5
|
+
* Helper function to prevent a collectible from being affected by Tainted Isaac's rotation
|
|
6
|
+
* mechanic. (This mechanic also happens from Glitched Crown and Binge Eater.) This is useful
|
|
7
|
+
* because quest items that are manually spawned by mods will be automatically be affected by this
|
|
8
|
+
* mechanic.
|
|
9
|
+
*
|
|
10
|
+
* It is required to pass the intended collectible type to this function since it is possible for
|
|
11
|
+
* collectibles to rotate on the first frame that they are spawned.
|
|
12
|
+
*/
|
|
13
|
+
export declare function preventCollectibleRotate(collectible: EntityPickup, collectibleType: CollectibleType | int): void;
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
--[[ Generated with https://github.com/TypeScriptToLua/TypeScriptToLua ]]
|
|
2
|
+
require("lualib_bundle");
|
|
3
|
+
local ____exports = {}
|
|
4
|
+
local useCardSoulOfIsaac, postPickupUpdateCollectible, v
|
|
5
|
+
local ____errors = require("errors")
|
|
6
|
+
local getUpgradeErrorMsg = ____errors.getUpgradeErrorMsg
|
|
7
|
+
local ____collectibles = require("functions.collectibles")
|
|
8
|
+
local setCollectibleSubType = ____collectibles.setCollectibleSubType
|
|
9
|
+
local ____exports = require("features.saveDataManager.exports")
|
|
10
|
+
local saveDataManager = ____exports.saveDataManager
|
|
11
|
+
function useCardSoulOfIsaac(self)
|
|
12
|
+
v.room.trackedItems:clear()
|
|
13
|
+
end
|
|
14
|
+
function postPickupUpdateCollectible(self, pickup)
|
|
15
|
+
if pickup.SubType == CollectibleType.COLLECTIBLE_NULL then
|
|
16
|
+
return
|
|
17
|
+
end
|
|
18
|
+
local trackedCollectibleType = v.room.trackedItems:get(pickup.InitSeed)
|
|
19
|
+
if (trackedCollectibleType ~= nil) and (pickup.SubType ~= trackedCollectibleType) then
|
|
20
|
+
setCollectibleSubType(nil, pickup, trackedCollectibleType)
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
local FEATURE_NAME = "prevent collectible rotation"
|
|
24
|
+
local initialized = false
|
|
25
|
+
v = {
|
|
26
|
+
room = {
|
|
27
|
+
trackedItems = __TS__New(Map)
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
function ____exports.preventCollectibleRotateInit(self, mod)
|
|
31
|
+
initialized = true
|
|
32
|
+
saveDataManager(nil, "preventCollectibleRotate", v)
|
|
33
|
+
mod:AddCallback(ModCallbacks.MC_USE_CARD, useCardSoulOfIsaac, Card.CARD_SOUL_ISAAC)
|
|
34
|
+
mod:AddCallback(ModCallbacks.MC_POST_PICKUP_UPDATE, postPickupUpdateCollectible, PickupVariant.PICKUP_COLLECTIBLE)
|
|
35
|
+
end
|
|
36
|
+
function ____exports.preventCollectibleRotate(self, collectible, collectibleType)
|
|
37
|
+
if not initialized then
|
|
38
|
+
local msg = getUpgradeErrorMsg(nil, FEATURE_NAME)
|
|
39
|
+
error(msg)
|
|
40
|
+
end
|
|
41
|
+
if collectible.Variant ~= PickupVariant.PICKUP_COLLECTIBLE then
|
|
42
|
+
error(
|
|
43
|
+
"You cannot prevent the rotation for pickups of variant: " .. tostring(collectible.Variant)
|
|
44
|
+
)
|
|
45
|
+
end
|
|
46
|
+
v.room.trackedItems:set(collectible.InitSeed, collectibleType)
|
|
47
|
+
postPickupUpdateCollectible(nil, collectible)
|
|
48
|
+
end
|
|
49
|
+
return ____exports
|
|
@@ -6,7 +6,7 @@ local getMaxCollectibleID = ____collectibles.getMaxCollectibleID
|
|
|
6
6
|
local ____util = require("functions.util")
|
|
7
7
|
local copySet = ____util.copySet
|
|
8
8
|
local COLLECTIBLE_SET = __TS__New(Set)
|
|
9
|
-
local function
|
|
9
|
+
local function initCollectibleSet(self)
|
|
10
10
|
local itemConfig = Isaac.GetItemConfig()
|
|
11
11
|
do
|
|
12
12
|
local collectibleType = 1
|
|
@@ -21,7 +21,7 @@ local function initSet(self)
|
|
|
21
21
|
end
|
|
22
22
|
function ____exports.getCollectibleSet(self)
|
|
23
23
|
if COLLECTIBLE_SET.size == 0 then
|
|
24
|
-
|
|
24
|
+
initCollectibleSet(nil)
|
|
25
25
|
end
|
|
26
26
|
return copySet(nil, COLLECTIBLE_SET)
|
|
27
27
|
end
|
|
@@ -34,6 +34,11 @@ export declare function isGlitchedCollectible(entity: Entity): boolean;
|
|
|
34
34
|
export declare function isPassiveCollectible(collectibleType: CollectibleType | int): boolean;
|
|
35
35
|
export declare function isQuestCollectible(collectibleType: CollectibleType | int): boolean;
|
|
36
36
|
export declare function removeAllCollectibles(): void;
|
|
37
|
+
/**
|
|
38
|
+
* Helper function to remove all pickup delay on a collectible. By default, collectibles have a 20
|
|
39
|
+
* frame delay before they can be picked up by a player.
|
|
40
|
+
*/
|
|
41
|
+
export declare function removeCollectiblePickupDelay(collectible: EntityPickup): void;
|
|
37
42
|
/**
|
|
38
43
|
* Helper function to put a message in the log.txt file to let the Rebirth Item Tracker know that it
|
|
39
44
|
* should remove an item.
|
|
@@ -115,6 +115,14 @@ end
|
|
|
115
115
|
function ____exports.removeAllCollectibles(self)
|
|
116
116
|
removeAllMatchingEntities(nil, EntityType.ENTITY_PICKUP, PickupVariant.PICKUP_COLLECTIBLE)
|
|
117
117
|
end
|
|
118
|
+
function ____exports.removeCollectiblePickupDelay(self, collectible)
|
|
119
|
+
if collectible.Variant ~= PickupVariant.PICKUP_COLLECTIBLE then
|
|
120
|
+
error(
|
|
121
|
+
"You cannot remove pickup delay for pickups of variant: " .. tostring(collectible.Variant)
|
|
122
|
+
)
|
|
123
|
+
end
|
|
124
|
+
collectible.Wait = 0
|
|
125
|
+
end
|
|
118
126
|
function ____exports.removeCollectibleFromItemTracker(self, collectibleType)
|
|
119
127
|
local collectibleName = ____exports.getCollectibleName(nil, collectibleType)
|
|
120
128
|
Isaac.DebugString(
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
/// <reference types="isaac-typescript-definitions" />
|
|
2
|
+
export declare function closeAllDoors(): void;
|
|
2
3
|
export declare function getDoors(roomType?: RoomType): GridEntityDoor[];
|
|
3
4
|
export declare function getAngelRoomDoor(): GridEntityDoor | undefined;
|
|
4
5
|
export declare function getDevilRoomDoor(): GridEntityDoor | undefined;
|
package/dist/functions/doors.lua
CHANGED
|
@@ -3,20 +3,6 @@ require("lualib_bundle");
|
|
|
3
3
|
local ____exports = {}
|
|
4
4
|
local ____constants = require("constants")
|
|
5
5
|
local MAX_NUM_DOORS = ____constants.MAX_NUM_DOORS
|
|
6
|
-
function ____exports.isAngelRoomDoor(self, door)
|
|
7
|
-
return door.TargetRoomType == RoomType.ROOM_ANGEL
|
|
8
|
-
end
|
|
9
|
-
function ____exports.isDevilRoomDoor(self, door)
|
|
10
|
-
return door.TargetRoomType == RoomType.ROOM_DEVIL
|
|
11
|
-
end
|
|
12
|
-
function ____exports.isRepentanceDoor(self, door)
|
|
13
|
-
return door.TargetRoomIndex == GridRooms.ROOM_SECRET_EXIT_IDX
|
|
14
|
-
end
|
|
15
|
-
function ____exports.isSecretRoomDoor(self, door)
|
|
16
|
-
local sprite = door:GetSprite()
|
|
17
|
-
local filename = sprite:GetFilename()
|
|
18
|
-
return filename == "gfx/grid/Door_08_HoleInWall.anm2"
|
|
19
|
-
end
|
|
20
6
|
function ____exports.getDoors(self, roomType)
|
|
21
7
|
local game = Game()
|
|
22
8
|
local room = game:GetRoom()
|
|
@@ -27,7 +13,7 @@ function ____exports.getDoors(self, roomType)
|
|
|
27
13
|
do
|
|
28
14
|
local door = room:GetDoor(i)
|
|
29
15
|
if door == nil then
|
|
30
|
-
goto
|
|
16
|
+
goto __continue5
|
|
31
17
|
end
|
|
32
18
|
if roomType == nil then
|
|
33
19
|
__TS__ArrayPush(doors, door)
|
|
@@ -35,12 +21,35 @@ function ____exports.getDoors(self, roomType)
|
|
|
35
21
|
__TS__ArrayPush(doors, door)
|
|
36
22
|
end
|
|
37
23
|
end
|
|
38
|
-
::
|
|
24
|
+
::__continue5::
|
|
39
25
|
i = i + 1
|
|
40
26
|
end
|
|
41
27
|
end
|
|
42
28
|
return doors
|
|
43
29
|
end
|
|
30
|
+
function ____exports.isAngelRoomDoor(self, door)
|
|
31
|
+
return door.TargetRoomType == RoomType.ROOM_ANGEL
|
|
32
|
+
end
|
|
33
|
+
function ____exports.isDevilRoomDoor(self, door)
|
|
34
|
+
return door.TargetRoomType == RoomType.ROOM_DEVIL
|
|
35
|
+
end
|
|
36
|
+
function ____exports.isRepentanceDoor(self, door)
|
|
37
|
+
return door.TargetRoomIndex == GridRooms.ROOM_SECRET_EXIT_IDX
|
|
38
|
+
end
|
|
39
|
+
function ____exports.isSecretRoomDoor(self, door)
|
|
40
|
+
local sprite = door:GetSprite()
|
|
41
|
+
local filename = sprite:GetFilename()
|
|
42
|
+
return filename == "gfx/grid/Door_08_HoleInWall.anm2"
|
|
43
|
+
end
|
|
44
|
+
function ____exports.closeAllDoors(self)
|
|
45
|
+
for ____, door in ipairs(
|
|
46
|
+
____exports.getDoors(nil)
|
|
47
|
+
) do
|
|
48
|
+
door.State = DoorState.STATE_CLOSED
|
|
49
|
+
local sprite = door:GetSprite()
|
|
50
|
+
sprite:Play("Close", true)
|
|
51
|
+
end
|
|
52
|
+
end
|
|
44
53
|
function ____exports.getAngelRoomDoor(self)
|
|
45
54
|
for ____, door in ipairs(
|
|
46
55
|
____exports.getDoors(nil)
|
|
@@ -1,4 +1,10 @@
|
|
|
1
1
|
/// <reference types="isaac-typescript-definitions" />
|
|
2
|
+
/**
|
|
3
|
+
* Helper function to convert the grid entity type found in a room XML file to the corresponding
|
|
4
|
+
* grid entity type and variant normally used by the game. For example, a rock is represented as
|
|
5
|
+
* 1000.0 in a room XML file, but `GridEntityType.GRID_ROCK` is equal to 2.
|
|
6
|
+
*/
|
|
7
|
+
export declare function convertXMLGridEntityType(gridEntityXMLType: int, gridEntityXMLVariant: int): [int, int] | undefined;
|
|
2
8
|
/**
|
|
3
9
|
* Helper function to get every grid entity in the current room. Use it with no arguments to get
|
|
4
10
|
* every grid entity, or specify a variadic amount of arguments to match specific grid entity types.
|
|
@@ -35,6 +41,14 @@ export declare function isPostBossVoidPortal(gridEntity: GridEntity): boolean;
|
|
|
35
41
|
export declare function removeAllGridEntitiesExceptFor(...gridEntityTypes: GridEntityType[]): void;
|
|
36
42
|
export declare function removeAllMatchingGridEntities(gridEntityType: GridEntityType): void;
|
|
37
43
|
export declare function removeGridEntity(gridEntity: GridEntity): void;
|
|
44
|
+
/**
|
|
45
|
+
* Helper function to make a grid entity invisible. This is accomplished by setting its sprite to
|
|
46
|
+
* "gfx/none.png" (a non-existent PNG file).
|
|
47
|
+
*
|
|
48
|
+
* Using this function will cause spurious errors in the "log.txt file". If you want to remove them,
|
|
49
|
+
* create a transparent 1 pixel PNG file in your resources folder at "gfx/none.png".
|
|
50
|
+
*/
|
|
51
|
+
export declare function setGridEntityInvisible(gridEntity: GridEntity): void;
|
|
38
52
|
export declare function spawnGiantPoop(topLeftGridIndex: int): void;
|
|
39
53
|
export declare function spawnGridEntity(gridEntityType: GridEntityType, gridIndex: int): GridEntity;
|
|
40
54
|
export declare function spawnGridEntityWithVariant(gridEntityType: GridEntityType, variant: int, gridIndex: int): GridEntity;
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
--[[ Generated with https://github.com/TypeScriptToLua/TypeScriptToLua ]]
|
|
2
2
|
require("lualib_bundle");
|
|
3
3
|
local ____exports = {}
|
|
4
|
+
local ____constants = require("constants")
|
|
5
|
+
local GRID_ENTITY_XML_MAP = ____constants.GRID_ENTITY_XML_MAP
|
|
4
6
|
function ____exports.removeGridEntity(self, gridEntity)
|
|
5
7
|
local game = Game()
|
|
6
8
|
local room = game:GetRoom()
|
|
@@ -21,6 +23,23 @@ function ____exports.spawnGridEntityWithVariant(self, gridEntityType, variant, g
|
|
|
21
23
|
end
|
|
22
24
|
return gridEntity
|
|
23
25
|
end
|
|
26
|
+
function ____exports.convertXMLGridEntityType(self, gridEntityXMLType, gridEntityXMLVariant)
|
|
27
|
+
if gridEntityXMLType == EntityType.ENTITY_TRIGGER_OUTPUT then
|
|
28
|
+
return nil
|
|
29
|
+
end
|
|
30
|
+
local gridEntityArray = GRID_ENTITY_XML_MAP:get(gridEntityXMLType)
|
|
31
|
+
if gridEntityArray == nil then
|
|
32
|
+
error(
|
|
33
|
+
"Failed to find an entry in the grid entity map for XML entity type: " .. tostring(gridEntityXMLType)
|
|
34
|
+
)
|
|
35
|
+
end
|
|
36
|
+
local gridEntityType = gridEntityArray[1]
|
|
37
|
+
local gridEntityVariant = gridEntityArray[2]
|
|
38
|
+
if ((gridEntityType == GridEntityType.GRID_SPIKES_ONOFF) or (gridEntityType == GridEntityType.GRID_PRESSURE_PLATE)) or (gridEntityType == GridEntityType.GRID_TELEPORTER) then
|
|
39
|
+
gridEntityVariant = gridEntityXMLVariant
|
|
40
|
+
end
|
|
41
|
+
return {gridEntityType, gridEntityVariant}
|
|
42
|
+
end
|
|
24
43
|
function ____exports.getGridEntities(self, ...)
|
|
25
44
|
local gridEntityTypes = {...}
|
|
26
45
|
local game = Game()
|
|
@@ -34,7 +53,7 @@ function ____exports.getGridEntities(self, ...)
|
|
|
34
53
|
do
|
|
35
54
|
local gridEntity = room:GetGridEntity(gridIndex)
|
|
36
55
|
if gridEntity == nil then
|
|
37
|
-
goto
|
|
56
|
+
goto __continue7
|
|
38
57
|
end
|
|
39
58
|
if #gridEntityTypes == 0 then
|
|
40
59
|
__TS__ArrayPush(gridEntities, gridEntity)
|
|
@@ -45,7 +64,7 @@ function ____exports.getGridEntities(self, ...)
|
|
|
45
64
|
end
|
|
46
65
|
end
|
|
47
66
|
end
|
|
48
|
-
::
|
|
67
|
+
::__continue7::
|
|
49
68
|
gridIndex = gridIndex + 1
|
|
50
69
|
end
|
|
51
70
|
end
|
|
@@ -104,6 +123,11 @@ function ____exports.removeAllMatchingGridEntities(self, gridEntityType)
|
|
|
104
123
|
____exports.removeGridEntity(nil, gridEntity)
|
|
105
124
|
end
|
|
106
125
|
end
|
|
126
|
+
function ____exports.setGridEntityInvisible(self, gridEntity)
|
|
127
|
+
local sprite = gridEntity:GetSprite()
|
|
128
|
+
sprite:ReplaceSpritesheet(0, "gfx/none.png")
|
|
129
|
+
sprite:LoadGraphics()
|
|
130
|
+
end
|
|
107
131
|
function ____exports.spawnGiantPoop(self, topLeftGridIndex)
|
|
108
132
|
local game = Game()
|
|
109
133
|
local room = game:GetRoom()
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
/// <reference types="isaac-typescript-definitions" />
|
|
2
|
+
import { JSONRoom } from "../types/JSONRoom";
|
|
3
|
+
export declare function getJSONRoomOfVariant(jsonRooms: JSONRoom[], variant: int): JSONRoom | null;
|
|
4
|
+
export declare function getJSONRoomsOfSubType(jsonRooms: JSONRoom[], subType: int): JSONRoom[];
|
|
5
|
+
export declare function getRandomJSONRoom(jsonRooms: JSONRoom[], seed?: number): JSONRoom;
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
--[[ Generated with https://github.com/TypeScriptToLua/TypeScriptToLua ]]
|
|
2
|
+
require("lualib_bundle");
|
|
3
|
+
local ____exports = {}
|
|
4
|
+
local getTotalWeightOfJSONRooms, getJSONRoomWithChosenWeight
|
|
5
|
+
local ____random = require("functions.random")
|
|
6
|
+
local getRandomFloat = ____random.getRandomFloat
|
|
7
|
+
function getTotalWeightOfJSONRooms(self, jsonRooms)
|
|
8
|
+
local totalWeight = 0
|
|
9
|
+
for ____, jsonRoom in ipairs(jsonRooms) do
|
|
10
|
+
local roomWeightString = jsonRoom["$"].weight
|
|
11
|
+
local roomWeight = tonumber(roomWeightString)
|
|
12
|
+
if roomWeight == nil then
|
|
13
|
+
error(("Failed to parse the weight of a room: " .. roomWeightString) .. ".")
|
|
14
|
+
end
|
|
15
|
+
totalWeight = totalWeight + roomWeight
|
|
16
|
+
end
|
|
17
|
+
return totalWeight
|
|
18
|
+
end
|
|
19
|
+
function getJSONRoomWithChosenWeight(self, jsonRooms, chosenWeight)
|
|
20
|
+
for ____, jsonRoom in ipairs(jsonRooms) do
|
|
21
|
+
local roomWeightString = jsonRoom["$"].weight
|
|
22
|
+
local roomWeight = tonumber(roomWeightString)
|
|
23
|
+
if roomWeight == nil then
|
|
24
|
+
error("Failed to parse the weight of a room: " .. roomWeightString)
|
|
25
|
+
end
|
|
26
|
+
if chosenWeight < roomWeight then
|
|
27
|
+
return jsonRoom
|
|
28
|
+
end
|
|
29
|
+
chosenWeight = chosenWeight - roomWeight
|
|
30
|
+
end
|
|
31
|
+
error(
|
|
32
|
+
"Failed to get a room with chosen weight: " .. tostring(chosenWeight)
|
|
33
|
+
)
|
|
34
|
+
return jsonRooms[1]
|
|
35
|
+
end
|
|
36
|
+
function ____exports.getJSONRoomOfVariant(self, jsonRooms, variant)
|
|
37
|
+
for ____, jsonRoom in ipairs(jsonRooms) do
|
|
38
|
+
local roomVariantString = jsonRoom["$"].variant
|
|
39
|
+
local roomVariant = tonumber(roomVariantString)
|
|
40
|
+
if roomVariant == variant then
|
|
41
|
+
return jsonRoom
|
|
42
|
+
end
|
|
43
|
+
end
|
|
44
|
+
return nil
|
|
45
|
+
end
|
|
46
|
+
function ____exports.getJSONRoomsOfSubType(self, jsonRooms, subType)
|
|
47
|
+
local jsonRoomsOfSubType = {}
|
|
48
|
+
for ____, jsonRoom in ipairs(jsonRooms) do
|
|
49
|
+
local roomSubTypeString = jsonRoom["$"].subtype
|
|
50
|
+
local roomSubType = tonumber(roomSubTypeString)
|
|
51
|
+
if roomSubType == subType then
|
|
52
|
+
__TS__ArrayPush(jsonRoomsOfSubType, jsonRoom)
|
|
53
|
+
end
|
|
54
|
+
end
|
|
55
|
+
return jsonRoomsOfSubType
|
|
56
|
+
end
|
|
57
|
+
function ____exports.getRandomJSONRoom(self, jsonRooms, seed)
|
|
58
|
+
if seed == nil then
|
|
59
|
+
seed = Random()
|
|
60
|
+
end
|
|
61
|
+
local totalWeight = getTotalWeightOfJSONRooms(nil, jsonRooms)
|
|
62
|
+
local chosenWeight = getRandomFloat(nil, 0, totalWeight, seed)
|
|
63
|
+
return getJSONRoomWithChosenWeight(nil, jsonRooms, chosenWeight)
|
|
64
|
+
end
|
|
65
|
+
return ____exports
|
|
@@ -107,3 +107,14 @@ export declare function inDimension(dimension: Dimension): boolean;
|
|
|
107
107
|
export declare function inLRoom(): boolean;
|
|
108
108
|
export declare function inGenesisRoom(): boolean;
|
|
109
109
|
export declare function inStartingRoom(): boolean;
|
|
110
|
+
/**
|
|
111
|
+
* Helper function to convert an uncleared room to a cleared room in the PostNewRoom callback. This
|
|
112
|
+
* is useful because if enemies are removed in this callback, a room drop will be awarded and the
|
|
113
|
+
* doors will start closed and then open.
|
|
114
|
+
*/
|
|
115
|
+
export declare function setRoomCleared(): void;
|
|
116
|
+
/**
|
|
117
|
+
* Helper function to emulate what happens when you bomb an Angel Statue or push a Reward Plate that
|
|
118
|
+
* spawns an NPC.
|
|
119
|
+
*/
|
|
120
|
+
export declare function setRoomUncleared(): void;
|
package/dist/functions/rooms.lua
CHANGED
|
@@ -7,6 +7,10 @@ local GENESIS_ROOM_SUBTYPE = ____constants.GENESIS_ROOM_SUBTYPE
|
|
|
7
7
|
local GENESIS_ROOM_VARIANT = ____constants.GENESIS_ROOM_VARIANT
|
|
8
8
|
local MAX_ROOM_INDEX = ____constants.MAX_ROOM_INDEX
|
|
9
9
|
local ROOM_TYPE_TO_ITEM_POOL_TYPE_MAP = ____constants.ROOM_TYPE_TO_ITEM_POOL_TYPE_MAP
|
|
10
|
+
local ____doors = require("functions.doors")
|
|
11
|
+
local closeAllDoors = ____doors.closeAllDoors
|
|
12
|
+
local getDoors = ____doors.getDoors
|
|
13
|
+
local isHiddenSecretRoomDoor = ____doors.isHiddenSecretRoomDoor
|
|
10
14
|
function ____exports.getRoomIndex(self)
|
|
11
15
|
local game = Game()
|
|
12
16
|
local level = game:GetLevel()
|
|
@@ -184,4 +188,36 @@ function ____exports.inStartingRoom(self)
|
|
|
184
188
|
local roomIndex = ____exports.getRoomIndex(nil)
|
|
185
189
|
return roomIndex == startingRoomIndex
|
|
186
190
|
end
|
|
191
|
+
function ____exports.setRoomCleared(self)
|
|
192
|
+
local game = Game()
|
|
193
|
+
local room = game:GetRoom()
|
|
194
|
+
local roomClear = room:IsClear()
|
|
195
|
+
local sfx = SFXManager()
|
|
196
|
+
if roomClear then
|
|
197
|
+
return
|
|
198
|
+
end
|
|
199
|
+
room:SetClear(true)
|
|
200
|
+
for ____, door in ipairs(
|
|
201
|
+
getDoors(nil)
|
|
202
|
+
) do
|
|
203
|
+
do
|
|
204
|
+
if isHiddenSecretRoomDoor(nil, door) then
|
|
205
|
+
goto __continue37
|
|
206
|
+
end
|
|
207
|
+
door.State = DoorState.STATE_OPEN
|
|
208
|
+
local sprite = door:GetSprite()
|
|
209
|
+
sprite:Play("Opened", true)
|
|
210
|
+
door.ExtraVisible = false
|
|
211
|
+
end
|
|
212
|
+
::__continue37::
|
|
213
|
+
end
|
|
214
|
+
sfx:Stop(SoundEffect.SOUND_DOOR_HEAVY_OPEN)
|
|
215
|
+
game:ShakeScreen(0)
|
|
216
|
+
end
|
|
217
|
+
function ____exports.setRoomUncleared(self)
|
|
218
|
+
local game = Game()
|
|
219
|
+
local room = game:GetRoom()
|
|
220
|
+
room:SetClear(false)
|
|
221
|
+
closeAllDoors(nil)
|
|
222
|
+
end
|
|
187
223
|
return ____exports
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/// <reference types="isaac-typescript-definitions" />
|
|
2
|
+
/**
|
|
3
|
+
* Helper function to spawn a collectible. Use this instead of `Game.Spawn()` because it handles the
|
|
4
|
+
* cases of Tainted Keeper collectibles costing coins and preventing quest items from being rotated
|
|
5
|
+
* by Tainted Isaac's rotation mechanic.
|
|
6
|
+
*
|
|
7
|
+
* @param collectibleType The collectible type to spawn.
|
|
8
|
+
* @param position The position to spawn the collectible at.
|
|
9
|
+
* @param seed Optional. Random() by default.
|
|
10
|
+
* @param options Optional. Set to true to make the collectible a "There's Options" style
|
|
11
|
+
* collectible. False by default.
|
|
12
|
+
* @param forceFreeItem Optional. Set to true to disable the logic that gives the item a price for
|
|
13
|
+
* Tainted Keeper. False by default.
|
|
14
|
+
*/
|
|
15
|
+
export declare function spawnCollectible(collectibleType: CollectibleType | int, position: Vector, seed?: number, options?: boolean, forceFreeItem?: boolean): EntityPickup;
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
--[[ Generated with https://github.com/TypeScriptToLua/TypeScriptToLua ]]
|
|
2
|
+
local ____exports = {}
|
|
3
|
+
local ____preventCollectibleRotate = require("features.preventCollectibleRotate")
|
|
4
|
+
local preventCollectibleRotate = ____preventCollectibleRotate.preventCollectibleRotate
|
|
5
|
+
local ____initialized = require("initialized")
|
|
6
|
+
local areFeaturesInitialized = ____initialized.areFeaturesInitialized
|
|
7
|
+
local ____collectibles = require("functions.collectibles")
|
|
8
|
+
local isQuestCollectible = ____collectibles.isQuestCollectible
|
|
9
|
+
local ____player = require("functions.player")
|
|
10
|
+
local anyPlayerIs = ____player.anyPlayerIs
|
|
11
|
+
function ____exports.spawnCollectible(self, collectibleType, position, seed, options, forceFreeItem)
|
|
12
|
+
if seed == nil then
|
|
13
|
+
seed = Random()
|
|
14
|
+
end
|
|
15
|
+
if options == nil then
|
|
16
|
+
options = false
|
|
17
|
+
end
|
|
18
|
+
if forceFreeItem == nil then
|
|
19
|
+
forceFreeItem = false
|
|
20
|
+
end
|
|
21
|
+
if seed == 0 then
|
|
22
|
+
error("Failed to spawn a collectible since the provided seed was 0, which is not allowed. (It will cause the game to crash.)")
|
|
23
|
+
end
|
|
24
|
+
local game = Game()
|
|
25
|
+
local collectible = game:Spawn(EntityType.ENTITY_PICKUP, PickupVariant.PICKUP_COLLECTIBLE, position, Vector.Zero, nil, collectibleType, seed):ToPickup()
|
|
26
|
+
if collectible == nil then
|
|
27
|
+
error("Failed to spawn a collectible.")
|
|
28
|
+
end
|
|
29
|
+
if options then
|
|
30
|
+
collectible.OptionsPickupIndex = 1
|
|
31
|
+
end
|
|
32
|
+
if (anyPlayerIs(nil, PlayerType.PLAYER_KEEPER_B) and (not isQuestCollectible(nil, collectibleType))) and (not forceFreeItem) then
|
|
33
|
+
collectible.ShopItemId = -1
|
|
34
|
+
collectible.Price = 15
|
|
35
|
+
end
|
|
36
|
+
if isQuestCollectible(nil, collectibleType) and areFeaturesInitialized(nil) then
|
|
37
|
+
preventCollectibleRotate(nil, collectible, collectibleType)
|
|
38
|
+
end
|
|
39
|
+
return collectible
|
|
40
|
+
end
|
|
41
|
+
return ____exports
|
|
@@ -6,7 +6,7 @@ local getMaxTrinketID = ____trinkets.getMaxTrinketID
|
|
|
6
6
|
local ____util = require("functions.util")
|
|
7
7
|
local copySet = ____util.copySet
|
|
8
8
|
local TRINKET_SET = __TS__New(Set)
|
|
9
|
-
local function
|
|
9
|
+
local function initTrinketSet(self)
|
|
10
10
|
local itemConfig = Isaac.GetItemConfig()
|
|
11
11
|
do
|
|
12
12
|
local trinketType = 1
|
|
@@ -21,7 +21,7 @@ local function initSet(self)
|
|
|
21
21
|
end
|
|
22
22
|
function ____exports.getTrinketSet(self)
|
|
23
23
|
if TRINKET_SET.size == 0 then
|
|
24
|
-
|
|
24
|
+
initTrinketSet(nil)
|
|
25
25
|
end
|
|
26
26
|
return copySet(nil, TRINKET_SET)
|
|
27
27
|
end
|
package/dist/index.d.ts
CHANGED
|
@@ -2,9 +2,11 @@ export { forceNewLevelCallback, forceNewRoomCallback, } from "./callbacks/reorde
|
|
|
2
2
|
export * from "./cardNameMap";
|
|
3
3
|
export * from "./collectibleNameMap";
|
|
4
4
|
export * from "./constants";
|
|
5
|
+
export { deployJSONRoom, deployRandomJSONRoom, emptyRoom, } from "./features/deployJSONRoom";
|
|
5
6
|
export { disableAllInputs, disableAllInputsExceptFor, disableMovementInputs, disableShootingInputs, enableAllInputs, enableAllInputsExceptFor, } from "./features/disableInputs";
|
|
6
7
|
export { forgottenSwitch } from "./features/forgottenSwitch";
|
|
7
8
|
export { getCollectibleItemPoolType } from "./features/getCollectibleItemPoolType";
|
|
9
|
+
export { preventCollectibleRotate } from "./features/preventCollectibleRotate";
|
|
8
10
|
export { runInNFrames, runNextFrame } from "./features/runInNFrames";
|
|
9
11
|
export * from "./features/saveDataManager/exports";
|
|
10
12
|
export { hasSirenStolenFamiliar, setFamiliarNoSirenSteal, } from "./features/sirenHelpers";
|
|
@@ -23,6 +25,7 @@ export * from "./functions/flag";
|
|
|
23
25
|
export * from "./functions/gridEntity";
|
|
24
26
|
export * from "./functions/input";
|
|
25
27
|
export * from "./functions/json";
|
|
28
|
+
export * from "./functions/jsonRoom";
|
|
26
29
|
export * from "./functions/language";
|
|
27
30
|
export * from "./functions/log";
|
|
28
31
|
export * from "./functions/math";
|
|
@@ -35,6 +38,7 @@ export * from "./functions/position";
|
|
|
35
38
|
export * from "./functions/random";
|
|
36
39
|
export * from "./functions/revive";
|
|
37
40
|
export * from "./functions/rooms";
|
|
41
|
+
export * from "./functions/spawnCollectible";
|
|
38
42
|
export * from "./functions/sprite";
|
|
39
43
|
export * from "./functions/stage";
|
|
40
44
|
export * from "./functions/tears";
|
|
@@ -50,6 +54,11 @@ export * from "./transformationMap";
|
|
|
50
54
|
export * from "./trinketNameMap";
|
|
51
55
|
export * from "./types/CallbackParametersCustom";
|
|
52
56
|
export * from "./types/HealthType";
|
|
57
|
+
export * from "./types/JSONDoor";
|
|
58
|
+
export * from "./types/JSONEntity";
|
|
59
|
+
export * from "./types/JSONRoom";
|
|
60
|
+
export * from "./types/JSONRooms";
|
|
61
|
+
export * from "./types/JSONSpawn";
|
|
53
62
|
export * from "./types/ModCallbacksCustom";
|
|
54
63
|
export * from "./types/ModUpgraded";
|
|
55
64
|
export * from "./types/PickingUpItem";
|
package/dist/index.lua
CHANGED
|
@@ -31,6 +31,15 @@ do
|
|
|
31
31
|
end
|
|
32
32
|
end
|
|
33
33
|
end
|
|
34
|
+
do
|
|
35
|
+
local ____deployJSONRoom = require("features.deployJSONRoom")
|
|
36
|
+
local deployJSONRoom = ____deployJSONRoom.deployJSONRoom
|
|
37
|
+
local deployRandomJSONRoom = ____deployJSONRoom.deployRandomJSONRoom
|
|
38
|
+
local emptyRoom = ____deployJSONRoom.emptyRoom
|
|
39
|
+
____exports.deployJSONRoom = deployJSONRoom
|
|
40
|
+
____exports.deployRandomJSONRoom = deployRandomJSONRoom
|
|
41
|
+
____exports.emptyRoom = emptyRoom
|
|
42
|
+
end
|
|
34
43
|
do
|
|
35
44
|
local ____disableInputs = require("features.disableInputs")
|
|
36
45
|
local disableAllInputs = ____disableInputs.disableAllInputs
|
|
@@ -56,6 +65,11 @@ do
|
|
|
56
65
|
local getCollectibleItemPoolType = ____getCollectibleItemPoolType.getCollectibleItemPoolType
|
|
57
66
|
____exports.getCollectibleItemPoolType = getCollectibleItemPoolType
|
|
58
67
|
end
|
|
68
|
+
do
|
|
69
|
+
local ____preventCollectibleRotate = require("features.preventCollectibleRotate")
|
|
70
|
+
local preventCollectibleRotate = ____preventCollectibleRotate.preventCollectibleRotate
|
|
71
|
+
____exports.preventCollectibleRotate = preventCollectibleRotate
|
|
72
|
+
end
|
|
59
73
|
do
|
|
60
74
|
local ____runInNFrames = require("features.runInNFrames")
|
|
61
75
|
local runInNFrames = ____runInNFrames.runInNFrames
|
|
@@ -192,6 +206,14 @@ do
|
|
|
192
206
|
end
|
|
193
207
|
end
|
|
194
208
|
end
|
|
209
|
+
do
|
|
210
|
+
local ____export = require("functions.jsonRoom")
|
|
211
|
+
for ____exportKey, ____exportValue in pairs(____export) do
|
|
212
|
+
if ____exportKey ~= "default" then
|
|
213
|
+
____exports[____exportKey] = ____exportValue
|
|
214
|
+
end
|
|
215
|
+
end
|
|
216
|
+
end
|
|
195
217
|
do
|
|
196
218
|
local ____export = require("functions.language")
|
|
197
219
|
for ____exportKey, ____exportValue in pairs(____export) do
|
|
@@ -288,6 +310,14 @@ do
|
|
|
288
310
|
end
|
|
289
311
|
end
|
|
290
312
|
end
|
|
313
|
+
do
|
|
314
|
+
local ____export = require("functions.spawnCollectible")
|
|
315
|
+
for ____exportKey, ____exportValue in pairs(____export) do
|
|
316
|
+
if ____exportKey ~= "default" then
|
|
317
|
+
____exports[____exportKey] = ____exportValue
|
|
318
|
+
end
|
|
319
|
+
end
|
|
320
|
+
end
|
|
291
321
|
do
|
|
292
322
|
local ____export = require("functions.sprite")
|
|
293
323
|
for ____exportKey, ____exportValue in pairs(____export) do
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
--[[ Generated with https://github.com/TypeScriptToLua/TypeScriptToLua ]]
|
|
2
|
+
local ____exports = {}
|
|
3
|
+
local initialized = false
|
|
4
|
+
function ____exports.areFeaturesInitialized(self)
|
|
5
|
+
return initialized
|
|
6
|
+
end
|
|
7
|
+
function ____exports.setFeaturesInitialized(self)
|
|
8
|
+
initialized = true
|
|
9
|
+
end
|
|
10
|
+
return ____exports
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
export interface JSONEntity {
|
|
2
|
+
$: {
|
|
3
|
+
/** Needs to be converted to an int. */
|
|
4
|
+
type: string;
|
|
5
|
+
/** Needs to be converted to an int. */
|
|
6
|
+
variant: string;
|
|
7
|
+
/** Needs to be converted to an int. */
|
|
8
|
+
subtype: string;
|
|
9
|
+
/** Needs to be converted to a float. */
|
|
10
|
+
weight: string;
|
|
11
|
+
};
|
|
12
|
+
}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { JSONDoor } from "./JSONDoor";
|
|
2
|
+
import { JSONSpawn } from "./JSONSpawn";
|
|
3
|
+
/**
|
|
4
|
+
* Custom rooms are created with the Basement Renovator program, which outputs XML files and STB
|
|
5
|
+
* files. A `JSONRoom` is simply an XML room converted to JSON. You can convert your XML files using
|
|
6
|
+
* the following command: `npx convert-xml-to-json foo.xml foo.json`
|
|
7
|
+
*/
|
|
8
|
+
export interface JSONRoom {
|
|
9
|
+
$: {
|
|
10
|
+
/** Needs to be converted to an int. */
|
|
11
|
+
difficulty: string;
|
|
12
|
+
/** Needs to be converted to an int. */
|
|
13
|
+
height: string;
|
|
14
|
+
name: string;
|
|
15
|
+
/** Needs to be converted to an int. */
|
|
16
|
+
shape: string;
|
|
17
|
+
/** Needs to be converted to an int. */
|
|
18
|
+
subtype: string;
|
|
19
|
+
/** Needs to be converted to an int. */
|
|
20
|
+
type: string;
|
|
21
|
+
/** Needs to be converted to an int. */
|
|
22
|
+
variant: string;
|
|
23
|
+
/** Needs to be converted to a float. */
|
|
24
|
+
weight: string;
|
|
25
|
+
/** Needs to be converted to an int. */
|
|
26
|
+
width: string;
|
|
27
|
+
};
|
|
28
|
+
door: JSONDoor[];
|
|
29
|
+
spawn: JSONSpawn[];
|
|
30
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { JSONRoom } from "./JSONRoom";
|
|
2
|
+
/**
|
|
3
|
+
* Custom rooms are created with the Basement Renovator program, which outputs XML files and STB
|
|
4
|
+
* files. A `JSONRooms` object is simply an XML file converted to JSON. You can convert your XML
|
|
5
|
+
* files using the following command: `npx convert-xml-to-json foo.xml foo.json`
|
|
6
|
+
*/
|
|
7
|
+
export interface JSONRooms {
|
|
8
|
+
rooms: {
|
|
9
|
+
room: JSONRoom[];
|
|
10
|
+
};
|
|
11
|
+
}
|
package/dist/upgradeMod.lua
CHANGED
|
@@ -56,18 +56,25 @@ local ____postTransformation = require("callbacks.postTransformation")
|
|
|
56
56
|
local postTransformationCallbackInit = ____postTransformation.postTransformationCallbackInit
|
|
57
57
|
local ____reorderedCallbacks = require("callbacks.reorderedCallbacks")
|
|
58
58
|
local reorderedCallbacksInit = ____reorderedCallbacks.reorderedCallbacksInit
|
|
59
|
+
local ____deployJSONRoom = require("features.deployJSONRoom")
|
|
60
|
+
local deployJSONRoomInit = ____deployJSONRoom.deployJSONRoomInit
|
|
59
61
|
local ____disableInputs = require("features.disableInputs")
|
|
60
62
|
local disableInputsInit = ____disableInputs.disableInputsInit
|
|
61
63
|
local ____forgottenSwitch = require("features.forgottenSwitch")
|
|
62
64
|
local forgottenSwitchInit = ____forgottenSwitch.forgottenSwitchInit
|
|
63
65
|
local ____getCollectibleItemPoolType = require("features.getCollectibleItemPoolType")
|
|
64
66
|
local getCollectibleItemPoolTypeInit = ____getCollectibleItemPoolType.getCollectibleItemPoolTypeInit
|
|
67
|
+
local ____preventCollectibleRotate = require("features.preventCollectibleRotate")
|
|
68
|
+
local preventCollectibleRotateInit = ____preventCollectibleRotate.preventCollectibleRotateInit
|
|
65
69
|
local ____runInNFrames = require("features.runInNFrames")
|
|
66
70
|
local runInNFramesInit = ____runInNFrames.runInNFramesInit
|
|
67
71
|
local ____main = require("features.saveDataManager.main")
|
|
68
72
|
local saveDataManagerInit = ____main.saveDataManagerInit
|
|
69
73
|
local ____sirenHelpers = require("features.sirenHelpers")
|
|
70
74
|
local sirenHelpersInit = ____sirenHelpers.sirenHelpersInit
|
|
75
|
+
local ____initialized = require("initialized")
|
|
76
|
+
local areFeaturesInitialized = ____initialized.areFeaturesInitialized
|
|
77
|
+
local setFeaturesInitialized = ____initialized.setFeaturesInitialized
|
|
71
78
|
local ____ModUpgraded = require("types.ModUpgraded")
|
|
72
79
|
local ModUpgraded = ____ModUpgraded.ModUpgraded
|
|
73
80
|
function initCustomCallbacks(self, mod)
|
|
@@ -100,20 +107,21 @@ function initCustomCallbacks(self, mod)
|
|
|
100
107
|
postGridEntityCallbacksInit(nil, mod)
|
|
101
108
|
end
|
|
102
109
|
function initFeatures(self, mod)
|
|
110
|
+
deployJSONRoomInit(nil, mod)
|
|
103
111
|
disableInputsInit(nil, mod)
|
|
104
112
|
forgottenSwitchInit(nil, mod)
|
|
105
113
|
getCollectibleItemPoolTypeInit(nil, mod)
|
|
114
|
+
preventCollectibleRotateInit(nil, mod)
|
|
106
115
|
runInNFramesInit(nil, mod)
|
|
107
116
|
sirenHelpersInit(nil, mod)
|
|
108
117
|
end
|
|
109
|
-
local initialized = false
|
|
110
118
|
function ____exports.upgradeMod(self, mod, verbose)
|
|
111
119
|
if verbose == nil then
|
|
112
120
|
verbose = false
|
|
113
121
|
end
|
|
114
122
|
local modUpgraded = __TS__New(ModUpgraded, mod, verbose)
|
|
115
|
-
if not
|
|
116
|
-
|
|
123
|
+
if not areFeaturesInitialized(nil) then
|
|
124
|
+
setFeaturesInitialized(nil)
|
|
117
125
|
saveDataManagerInit(nil, modUpgraded)
|
|
118
126
|
initCustomCallbacks(nil, modUpgraded)
|
|
119
127
|
initFeatures(nil, modUpgraded)
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "isaacscript-common",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.467",
|
|
4
4
|
"description": "Helper functions for IsaacScript mods",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"isaac",
|
|
@@ -25,9 +25,9 @@
|
|
|
25
25
|
"dist/**/*.d.ts"
|
|
26
26
|
],
|
|
27
27
|
"devDependencies": {
|
|
28
|
-
"isaac-typescript-definitions": "^1.0.
|
|
28
|
+
"isaac-typescript-definitions": "^1.0.281",
|
|
29
29
|
"isaacscript-lint": "^1.0.67",
|
|
30
|
-
"typedoc": "^0.22.
|
|
30
|
+
"typedoc": "^0.22.10",
|
|
31
31
|
"typescript": "4.4.4",
|
|
32
32
|
"typescript-to-lua": "^1.1.1"
|
|
33
33
|
}
|