isaacscript-common 1.0.461 → 1.0.465
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 +4 -4
- package/dist/functions/collectibles.lua +14 -12
- 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/player.d.ts +7 -7
- 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/trinketGive.d.ts +1 -1
- 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
|
|
@@ -42,10 +42,10 @@ export declare function removeAllCollectibles(): void;
|
|
|
42
42
|
* Python program located at: https://github.com/Rchardon/RebirthItemTracker
|
|
43
43
|
*/
|
|
44
44
|
export declare function removeCollectibleFromItemTracker(collectibleType: CollectibleType | int): void;
|
|
45
|
-
export declare function setCollectibleBlind(
|
|
46
|
-
export declare function setCollectibleSprite(
|
|
45
|
+
export declare function setCollectibleBlind(collectible: EntityPickup): void;
|
|
46
|
+
export declare function setCollectibleSprite(collectible: EntityPickup, pngPath: string): void;
|
|
47
47
|
/**
|
|
48
|
-
* Helper function to change the
|
|
49
|
-
* sufficient because
|
|
48
|
+
* Helper function to change the collectible on a pedestal. Simply updating the SubType property is
|
|
49
|
+
* not sufficient because the sprite will not change.
|
|
50
50
|
*/
|
|
51
51
|
export declare function setCollectibleSubType(collectible: EntityPickup, newCollectibleType: CollectibleType | int): void;
|
|
@@ -6,13 +6,13 @@ local ____collectibleNameMap = require("collectibleNameMap")
|
|
|
6
6
|
local COLLECTIBLE_NAME_MAP = ____collectibleNameMap.COLLECTIBLE_NAME_MAP
|
|
7
7
|
local ____entity = require("functions.entity")
|
|
8
8
|
local removeAllMatchingEntities = ____entity.removeAllMatchingEntities
|
|
9
|
-
function ____exports.setCollectibleSprite(self,
|
|
10
|
-
if
|
|
9
|
+
function ____exports.setCollectibleSprite(self, collectible, pngPath)
|
|
10
|
+
if collectible.Variant ~= PickupVariant.PICKUP_COLLECTIBLE then
|
|
11
11
|
error(
|
|
12
|
-
"You cannot set a collectible sprite for pickups of variant: " .. tostring(
|
|
12
|
+
"You cannot set a collectible sprite for pickups of variant: " .. tostring(collectible.Variant)
|
|
13
13
|
)
|
|
14
14
|
end
|
|
15
|
-
local sprite =
|
|
15
|
+
local sprite = collectible:GetSprite()
|
|
16
16
|
sprite:ReplaceSpritesheet(COLLECTIBLE_SPRITE_LAYER, pngPath)
|
|
17
17
|
sprite:LoadGraphics()
|
|
18
18
|
end
|
|
@@ -121,18 +121,20 @@ function ____exports.removeCollectibleFromItemTracker(self, collectibleType)
|
|
|
121
121
|
((("Removing collectible " .. tostring(collectibleType)) .. " (") .. collectibleName) .. ") on player 0 (Player)"
|
|
122
122
|
)
|
|
123
123
|
end
|
|
124
|
-
function ____exports.setCollectibleBlind(self,
|
|
125
|
-
|
|
124
|
+
function ____exports.setCollectibleBlind(self, collectible)
|
|
125
|
+
if collectible.Variant ~= PickupVariant.PICKUP_COLLECTIBLE then
|
|
126
|
+
error(
|
|
127
|
+
"You cannot set a collectible to be blind for pickups of variant: " .. tostring(collectible.Variant)
|
|
128
|
+
)
|
|
129
|
+
end
|
|
130
|
+
____exports.setCollectibleSprite(nil, collectible, BLIND_ITEM_PNG_PATH)
|
|
126
131
|
end
|
|
127
132
|
function ____exports.setCollectibleSubType(self, collectible, newCollectibleType)
|
|
128
|
-
collectible.
|
|
129
|
-
local itemConfig = Isaac.GetItemConfig()
|
|
130
|
-
local itemConfigItem = itemConfig:GetCollectible(newCollectibleType)
|
|
131
|
-
if itemConfigItem == nil then
|
|
133
|
+
if collectible.Variant ~= PickupVariant.PICKUP_COLLECTIBLE then
|
|
132
134
|
error(
|
|
133
|
-
"
|
|
135
|
+
"You cannot set a collectible sub type for pickups of variant: " .. tostring(collectible.Variant)
|
|
134
136
|
)
|
|
135
137
|
end
|
|
136
|
-
|
|
138
|
+
collectible:Morph(EntityType.ENTITY_PICKUP, PickupVariant.PICKUP_COLLECTIBLE, newCollectibleType, true, true, true)
|
|
137
139
|
end
|
|
138
140
|
return ____exports
|
|
@@ -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;
|