isaacscript-common 6.4.0 → 6.6.0

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.
Files changed (34) hide show
  1. package/enums/DecorationVariant.d.ts +9 -0
  2. package/enums/DecorationVariant.lua +7 -0
  3. package/enums/RockAltType.d.ts +7 -0
  4. package/enums/RockAltType.lua +13 -0
  5. package/features/customGridEntity.d.ts +2 -2
  6. package/features/customGridEntity.lua +7 -5
  7. package/features/customStage/backdrop.lua +7 -16
  8. package/features/customStage/gridEntities.d.ts +18 -0
  9. package/features/customStage/gridEntities.lua +215 -0
  10. package/features/customStage/init.lua +43 -1
  11. package/features/customStage/shadows.d.ts +3 -0
  12. package/features/customStage/shadows.lua +59 -0
  13. package/features/customStage/streakText.d.ts +1 -0
  14. package/features/customStage/streakText.lua +7 -0
  15. package/features/customStage/v.d.ts +3 -0
  16. package/features/customStage/v.lua +1 -1
  17. package/features/customStage/versusScreen.lua +18 -10
  18. package/features/extraConsoleCommands/init.lua +2 -0
  19. package/features/extraConsoleCommands/listCommands.d.ts +9 -2
  20. package/features/extraConsoleCommands/listCommands.lua +20 -4
  21. package/functions/doors.d.ts +10 -5
  22. package/functions/doors.lua +20 -17
  23. package/functions/gridEntity.d.ts +34 -0
  24. package/functions/gridEntity.lua +76 -0
  25. package/functions/pickups.d.ts +9 -9
  26. package/functions/run.d.ts +7 -0
  27. package/functions/run.lua +16 -4
  28. package/interfaces/CustomStageLua.d.ts +271 -88
  29. package/objects/backdropTypeToRockAltType.d.ts +6 -0
  30. package/objects/backdropTypeToRockAltType.lua +69 -0
  31. package/package.json +2 -2
  32. package/shaderCrashFix.d.ts +7 -0
  33. package/shaderCrashFix.lua +18 -0
  34. package/upgradeMod.lua +4 -1
@@ -0,0 +1,9 @@
1
+ export declare enum DecorationVariant {
2
+ VANILLA_DECORATION = 0,
3
+ /**
4
+ * The vanilla game does not support any custom grid entities. Under the hood, IsaacScript allows
5
+ * for custom grid entities by using decorations with this variant to represent custom grid
6
+ * entities.
7
+ */
8
+ CUSTOM_GRID_ENTITY = 1
9
+ }
@@ -0,0 +1,7 @@
1
+ local ____exports = {}
2
+ ____exports.DecorationVariant = {}
3
+ ____exports.DecorationVariant.VANILLA_DECORATION = 0
4
+ ____exports.DecorationVariant[____exports.DecorationVariant.VANILLA_DECORATION] = "VANILLA_DECORATION"
5
+ ____exports.DecorationVariant.CUSTOM_GRID_ENTITY = 1
6
+ ____exports.DecorationVariant[____exports.DecorationVariant.CUSTOM_GRID_ENTITY] = "CUSTOM_GRID_ENTITY"
7
+ return ____exports
@@ -0,0 +1,7 @@
1
+ export declare enum RockAltType {
2
+ URN = 0,
3
+ MUSHROOM = 1,
4
+ SKULL = 2,
5
+ POLYP = 3,
6
+ BUCKET = 4
7
+ }
@@ -0,0 +1,13 @@
1
+ local ____exports = {}
2
+ ____exports.RockAltType = {}
3
+ ____exports.RockAltType.URN = 0
4
+ ____exports.RockAltType[____exports.RockAltType.URN] = "URN"
5
+ ____exports.RockAltType.MUSHROOM = 1
6
+ ____exports.RockAltType[____exports.RockAltType.MUSHROOM] = "MUSHROOM"
7
+ ____exports.RockAltType.SKULL = 2
8
+ ____exports.RockAltType[____exports.RockAltType.SKULL] = "SKULL"
9
+ ____exports.RockAltType.POLYP = 3
10
+ ____exports.RockAltType[____exports.RockAltType.POLYP] = "POLYP"
11
+ ____exports.RockAltType.BUCKET = 4
12
+ ____exports.RockAltType[____exports.RockAltType.BUCKET] = "BUCKET"
13
+ return ____exports
@@ -3,8 +3,8 @@ import { GridCollisionClass, GridEntityType } from "isaac-typescript-definitions
3
3
  * Helper function to spawn a custom grid entity.
4
4
  *
5
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.
6
+ * entities. Under the hood, IsaacScript accomplishes this by using decorations with an arbitrary
7
+ * non-zero variant to represent custom grid entities.
8
8
  *
9
9
  * Once a custom grid entity is spawned, you can take advantage of the custom grid callbacks such as
10
10
  * `POST_GRID_ENTITY_CUSTOM_UPDATE`.
@@ -10,13 +10,15 @@ local ____cachedClasses = require("cachedClasses")
10
10
  local game = ____cachedClasses.game
11
11
  local ____DefaultMap = require("classes.DefaultMap")
12
12
  local DefaultMap = ____DefaultMap.DefaultMap
13
+ local ____DecorationVariant = require("enums.DecorationVariant")
14
+ local DecorationVariant = ____DecorationVariant.DecorationVariant
13
15
  local ____ModCallbackCustom = require("enums.ModCallbackCustom")
14
16
  local ModCallbackCustom = ____ModCallbackCustom.ModCallbackCustom
15
17
  local ____featuresInitialized = require("featuresInitialized")
16
18
  local errorIfFeaturesNotInitialized = ____featuresInitialized.errorIfFeaturesNotInitialized
17
19
  local ____gridEntity = require("functions.gridEntity")
18
20
  local removeGrid = ____gridEntity.removeGrid
19
- local spawnGrid = ____gridEntity.spawnGrid
21
+ local spawnGridWithVariant = ____gridEntity.spawnGridWithVariant
20
22
  local ____roomData = require("functions.roomData")
21
23
  local getRoomListIndex = ____roomData.getRoomListIndex
22
24
  local ____vector = require("functions.vector")
@@ -60,8 +62,8 @@ end
60
62
  --- Helper function to spawn a custom grid entity.
61
63
  --
62
64
  -- 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
+ -- entities. Under the hood, IsaacScript accomplishes this by using decorations with an arbitrary
66
+ -- non-zero variant to represent custom grid entities.
65
67
  --
66
68
  -- Once a custom grid entity is spawned, you can take advantage of the custom grid callbacks such as
67
69
  -- `POST_GRID_ENTITY_CUSTOM_UPDATE`.
@@ -84,8 +86,8 @@ function ____exports.spawnCustomGrid(self, gridEntityTypeCustom, gridIndexOrPosi
84
86
  local roomListIndex = getRoomListIndex(nil)
85
87
  local gridIndex = isVector(nil, gridIndexOrPosition) and room:GetGridIndex(gridIndexOrPosition) or gridIndexOrPosition
86
88
  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
+ local isExistingDecoration = existingGridEntity ~= nil and existingGridEntity:GetType() == GridEntityType.DECORATION and existingGridEntity:GetVariant() == DecorationVariant.CUSTOM_GRID_ENTITY
90
+ local decoration = isExistingDecoration and existingGridEntity or spawnGridWithVariant(nil, GridEntityType.DECORATION, DecorationVariant.CUSTOM_GRID_ENTITY, gridIndexOrPosition)
89
91
  if decoration == nil then
90
92
  error("Failed to spawn a decoration for a custom grid entity.")
91
93
  end
@@ -2,7 +2,7 @@ local ____lualib = require("lualib_bundle")
2
2
  local Set = ____lualib.Set
3
3
  local __TS__New = ____lualib.__TS__New
4
4
  local ____exports = {}
5
- local getBackdropPNGPath, spawnWallEntity, spawnSecondWallEntity, spawnFloorEntity, getNumFloorLayers, BackdropKind, BackdropEntitySubType, ROOM_SHAPE_WALL_ANM2_LAYERS, ROOM_SHAPE_WALL_EXTRA_ANM2_LAYERS, WALL_OFFSET, BACKDROP_EFFECT_VARIANT
5
+ local getBackdropPNGPath, spawnWallEntity, spawnSecondWallEntity, spawnFloorEntity, getNumFloorLayers, BackdropKind, DEFAULT_BACKDROP, ROOM_SHAPE_WALL_ANM2_LAYERS, ROOM_SHAPE_WALL_EXTRA_ANM2_LAYERS, WALL_OFFSET, BACKDROP_EFFECT_VARIANT
6
6
  local ____isaac_2Dtypescript_2Ddefinitions = require("isaac-typescript-definitions")
7
7
  local EffectVariant = ____isaac_2Dtypescript_2Ddefinitions.EffectVariant
8
8
  local EntityFlag = ____isaac_2Dtypescript_2Ddefinitions.EntityFlag
@@ -29,18 +29,17 @@ local irange = ____utils.irange
29
29
  local ____customStageConstants = require("features.customStage.customStageConstants")
30
30
  local ISAACSCRIPT_CUSTOM_STAGE_GFX_PATH = ____customStageConstants.ISAACSCRIPT_CUSTOM_STAGE_GFX_PATH
31
31
  function getBackdropPNGPath(self, customStage, backdropKind, rng)
32
- local pathArray = customStage.backdrop[backdropKind]
33
- local path = getRandomArrayElement(nil, pathArray, rng)
34
- return (customStage.backdrop.prefix .. path) .. customStage.backdrop.suffix
32
+ local backdrop = customStage.backdropPNGPaths == nil and DEFAULT_BACKDROP or customStage.backdropPNGPaths
33
+ local pathArray = backdrop[backdropKind]
34
+ return getRandomArrayElement(nil, pathArray, rng)
35
35
  end
36
36
  function spawnWallEntity(self, customStage, rng, isExtraWall)
37
37
  local room = game:GetRoom()
38
38
  local roomShape = room:GetRoomShape()
39
- local subType = isExtraWall and BackdropEntitySubType.WALL_EXTRA or BackdropEntitySubType.WALL
40
39
  local wallEffect = spawnEffectWithSeed(
41
40
  nil,
42
41
  BACKDROP_EFFECT_VARIANT,
43
- subType,
42
+ 0,
44
43
  VectorZero,
45
44
  1
46
45
  )
@@ -85,7 +84,7 @@ function spawnFloorEntity(self, customStage, rng)
85
84
  local floorEffect = spawnEffectWithSeed(
86
85
  nil,
87
86
  BACKDROP_EFFECT_VARIANT,
88
- BackdropEntitySubType.FLOOR,
87
+ 0,
89
88
  VectorZero,
90
89
  1
91
90
  )
@@ -153,15 +152,7 @@ BackdropKind.N_FLOOR = "nFloors"
153
152
  BackdropKind.L_FLOOR = "lFloors"
154
153
  BackdropKind.WALL = "walls"
155
154
  BackdropKind.CORNER = "corners"
156
- BackdropEntitySubType = BackdropEntitySubType or ({})
157
- BackdropEntitySubType.VANILLA_LADDER = 0
158
- BackdropEntitySubType[BackdropEntitySubType.VANILLA_LADDER] = "VANILLA_LADDER"
159
- BackdropEntitySubType.WALL = 1
160
- BackdropEntitySubType[BackdropEntitySubType.WALL] = "WALL"
161
- BackdropEntitySubType.WALL_EXTRA = 2
162
- BackdropEntitySubType[BackdropEntitySubType.WALL_EXTRA] = "WALL_EXTRA"
163
- BackdropEntitySubType.FLOOR = 3
164
- BackdropEntitySubType[BackdropEntitySubType.FLOOR] = "FLOOR"
155
+ DEFAULT_BACKDROP = {nFloors = {ISAACSCRIPT_CUSTOM_STAGE_GFX_PATH .. "/backdrop/nfloor.png"}, lFloors = {ISAACSCRIPT_CUSTOM_STAGE_GFX_PATH .. "/backdrop/lfloor.png"}, walls = {ISAACSCRIPT_CUSTOM_STAGE_GFX_PATH .. "/backdrop/wall.png"}, corners = {ISAACSCRIPT_CUSTOM_STAGE_GFX_PATH .. "/backdrop/corner.png"}}
165
156
  ROOM_SHAPE_WALL_ANM2_LAYERS = {
166
157
  [RoomShape.SHAPE_1x1] = 44,
167
158
  [RoomShape.IH] = 36,
@@ -0,0 +1,18 @@
1
+ /// <reference types="isaac-typescript-definitions" />
2
+ import { CustomStage } from "../../interfaces/CustomStage";
3
+ /** For `GridEntityType.DECORATION` (1) */
4
+ export declare function setCustomDecorationGraphics(customStage: CustomStage, gridEntity: GridEntity): void;
5
+ /** For `GridEntityType.ROCK` (2) */
6
+ export declare function setCustomRockGraphics(customStage: CustomStage, gridEntity: GridEntity): void;
7
+ /** For `GridEntityType.PIT` (7) */
8
+ export declare function setCustomPitGraphics(customStage: CustomStage, gridEntity: GridEntity): void;
9
+ /** For GridEntityType.DOOR (16) */
10
+ export declare function setCustomDoorGraphics(customStage: CustomStage, gridEntity: GridEntity): void;
11
+ /**
12
+ * The rewards are based on the ones from the wiki:
13
+ * https://bindingofisaacrebirth.fandom.com/wiki/Rocks#Urns
14
+ *
15
+ * On the bugged stage of -1, only urns will spawn, so we do not have to handle the case of mushroom
16
+ * rewards, skull rewards, and so on.
17
+ */
18
+ export declare function removeUrnRewards(customStage: CustomStage, gridEntity: GridEntity): void;
@@ -0,0 +1,215 @@
1
+ local ____lualib = require("lualib_bundle")
2
+ local __TS__ArrayFilter = ____lualib.__TS__ArrayFilter
3
+ local ____exports = {}
4
+ local getNewDoorPNGPath, removeEntitiesSpawnedFromGridEntity
5
+ local ____isaac_2Dtypescript_2Ddefinitions = require("isaac-typescript-definitions")
6
+ local CollectibleType = ____isaac_2Dtypescript_2Ddefinitions.CollectibleType
7
+ local EntityType = ____isaac_2Dtypescript_2Ddefinitions.EntityType
8
+ local TrinketType = ____isaac_2Dtypescript_2Ddefinitions.TrinketType
9
+ local ____DecorationVariant = require("enums.DecorationVariant")
10
+ local DecorationVariant = ____DecorationVariant.DecorationVariant
11
+ local ____entity = require("functions.entity")
12
+ local removeEntities = ____entity.removeEntities
13
+ local ____entitySpecific = require("functions.entitySpecific")
14
+ local getNPCs = ____entitySpecific.getNPCs
15
+ local ____pickups = require("functions.pickups")
16
+ local getCoins = ____pickups.getCoins
17
+ local getCollectibles = ____pickups.getCollectibles
18
+ local getTrinkets = ____pickups.getTrinkets
19
+ local ____vector = require("functions.vector")
20
+ local vectorEquals = ____vector.vectorEquals
21
+ function getNewDoorPNGPath(self, customStage, fileName)
22
+ repeat
23
+ local ____switch16 = fileName
24
+ local ____cond16 = ____switch16 == "gfx/grid/door_01_normaldoor.anm2"
25
+ if ____cond16 then
26
+ do
27
+ local ____customStage_doorPNGPaths_normal_0 = customStage.doorPNGPaths
28
+ if ____customStage_doorPNGPaths_normal_0 ~= nil then
29
+ ____customStage_doorPNGPaths_normal_0 = ____customStage_doorPNGPaths_normal_0.normal
30
+ end
31
+ return ____customStage_doorPNGPaths_normal_0
32
+ end
33
+ end
34
+ ____cond16 = ____cond16 or ____switch16 == "gfx/grid/door_02_treasureroomdoor.anm2"
35
+ if ____cond16 then
36
+ do
37
+ local ____customStage_doorPNGPaths_treasureRoom_2 = customStage.doorPNGPaths
38
+ if ____customStage_doorPNGPaths_treasureRoom_2 ~= nil then
39
+ ____customStage_doorPNGPaths_treasureRoom_2 = ____customStage_doorPNGPaths_treasureRoom_2.treasureRoom
40
+ end
41
+ return ____customStage_doorPNGPaths_treasureRoom_2
42
+ end
43
+ end
44
+ ____cond16 = ____cond16 or ____switch16 == "gfx/grid/door_03_ambushroomdoor.anm2"
45
+ if ____cond16 then
46
+ do
47
+ local ____customStage_doorPNGPaths_normalChallengeRoom_4 = customStage.doorPNGPaths
48
+ if ____customStage_doorPNGPaths_normalChallengeRoom_4 ~= nil then
49
+ ____customStage_doorPNGPaths_normalChallengeRoom_4 = ____customStage_doorPNGPaths_normalChallengeRoom_4.normalChallengeRoom
50
+ end
51
+ return ____customStage_doorPNGPaths_normalChallengeRoom_4
52
+ end
53
+ end
54
+ ____cond16 = ____cond16 or ____switch16 == "gfx/grid/door_04_selfsacrificeroomdoor.anm2"
55
+ if ____cond16 then
56
+ do
57
+ local ____customStage_doorPNGPaths_curseRoom_6 = customStage.doorPNGPaths
58
+ if ____customStage_doorPNGPaths_curseRoom_6 ~= nil then
59
+ ____customStage_doorPNGPaths_curseRoom_6 = ____customStage_doorPNGPaths_curseRoom_6.curseRoom
60
+ end
61
+ return ____customStage_doorPNGPaths_curseRoom_6
62
+ end
63
+ end
64
+ ____cond16 = ____cond16 or ____switch16 == "gfx/grid/door_05_arcaderoomdoor.anm2"
65
+ if ____cond16 then
66
+ do
67
+ local ____customStage_doorPNGPaths_arcade_8 = customStage.doorPNGPaths
68
+ if ____customStage_doorPNGPaths_arcade_8 ~= nil then
69
+ ____customStage_doorPNGPaths_arcade_8 = ____customStage_doorPNGPaths_arcade_8.arcade
70
+ end
71
+ return ____customStage_doorPNGPaths_arcade_8
72
+ end
73
+ end
74
+ ____cond16 = ____cond16 or ____switch16 == "gfx/grid/door_07_devilroomdoor.anm2"
75
+ if ____cond16 then
76
+ do
77
+ local ____customStage_doorPNGPaths_devilRoom_10 = customStage.doorPNGPaths
78
+ if ____customStage_doorPNGPaths_devilRoom_10 ~= nil then
79
+ ____customStage_doorPNGPaths_devilRoom_10 = ____customStage_doorPNGPaths_devilRoom_10.devilRoom
80
+ end
81
+ return ____customStage_doorPNGPaths_devilRoom_10
82
+ end
83
+ end
84
+ ____cond16 = ____cond16 or ____switch16 == "gfx/grid/door_07_holyroomdoor.anm2"
85
+ if ____cond16 then
86
+ do
87
+ local ____customStage_doorPNGPaths_angelRoom_12 = customStage.doorPNGPaths
88
+ if ____customStage_doorPNGPaths_angelRoom_12 ~= nil then
89
+ ____customStage_doorPNGPaths_angelRoom_12 = ____customStage_doorPNGPaths_angelRoom_12.angelRoom
90
+ end
91
+ return ____customStage_doorPNGPaths_angelRoom_12
92
+ end
93
+ end
94
+ ____cond16 = ____cond16 or ____switch16 == "gfx/grid/door_08_holeinwall.anm2"
95
+ if ____cond16 then
96
+ do
97
+ local ____customStage_doorPNGPaths_secretRoom_14 = customStage.doorPNGPaths
98
+ if ____customStage_doorPNGPaths_secretRoom_14 ~= nil then
99
+ ____customStage_doorPNGPaths_secretRoom_14 = ____customStage_doorPNGPaths_secretRoom_14.secretRoom
100
+ end
101
+ return ____customStage_doorPNGPaths_secretRoom_14
102
+ end
103
+ end
104
+ ____cond16 = ____cond16 or ____switch16 == "gfx/grid/door_09_bossambushroomdoor.anm2"
105
+ if ____cond16 then
106
+ do
107
+ local ____customStage_doorPNGPaths_bossChallengeRoom_16 = customStage.doorPNGPaths
108
+ if ____customStage_doorPNGPaths_bossChallengeRoom_16 ~= nil then
109
+ ____customStage_doorPNGPaths_bossChallengeRoom_16 = ____customStage_doorPNGPaths_bossChallengeRoom_16.bossChallengeRoom
110
+ end
111
+ return ____customStage_doorPNGPaths_bossChallengeRoom_16
112
+ end
113
+ end
114
+ ____cond16 = ____cond16 or ____switch16 == "gfx/grid/door_10_bossroomdoor.anm2"
115
+ if ____cond16 then
116
+ do
117
+ local ____customStage_doorPNGPaths_bossRoom_18 = customStage.doorPNGPaths
118
+ if ____customStage_doorPNGPaths_bossRoom_18 ~= nil then
119
+ ____customStage_doorPNGPaths_bossRoom_18 = ____customStage_doorPNGPaths_bossRoom_18.bossRoom
120
+ end
121
+ return ____customStage_doorPNGPaths_bossRoom_18
122
+ end
123
+ end
124
+ ____cond16 = ____cond16 or ____switch16 == "gfx/grid/door_15_bossrushdoor.anm2"
125
+ if ____cond16 then
126
+ do
127
+ local ____customStage_doorPNGPaths_bossRush_20 = customStage.doorPNGPaths
128
+ if ____customStage_doorPNGPaths_bossRush_20 ~= nil then
129
+ ____customStage_doorPNGPaths_bossRush_20 = ____customStage_doorPNGPaths_bossRush_20.bossRush
130
+ end
131
+ return ____customStage_doorPNGPaths_bossRush_20
132
+ end
133
+ end
134
+ until true
135
+ return nil
136
+ end
137
+ function removeEntitiesSpawnedFromGridEntity(self, entities, gridEntity)
138
+ local entitiesFromGridEntity = __TS__ArrayFilter(
139
+ entities,
140
+ function(____, entity) return entity.FrameCount == 0 and vectorEquals(nil, entity.Position, gridEntity.Position) end
141
+ )
142
+ removeEntities(nil, entitiesFromGridEntity)
143
+ end
144
+ --- For `GridEntityType.DECORATION` (1)
145
+ function ____exports.setCustomDecorationGraphics(self, customStage, gridEntity)
146
+ if customStage.decorationsPNGPath == nil then
147
+ return
148
+ end
149
+ local variant = gridEntity:GetVariant()
150
+ if variant ~= DecorationVariant.VANILLA_DECORATION then
151
+ return
152
+ end
153
+ local sprite = gridEntity:GetSprite()
154
+ local fileName = sprite:GetFilename()
155
+ if string.lower(fileName) == "gfx/grid/props_01_basement.anm2" then
156
+ sprite:ReplaceSpritesheet(0, customStage.decorationsPNGPath)
157
+ sprite:LoadGraphics()
158
+ end
159
+ end
160
+ --- For `GridEntityType.ROCK` (2)
161
+ function ____exports.setCustomRockGraphics(self, customStage, gridEntity)
162
+ if customStage.rocksPNGPath == nil then
163
+ return
164
+ end
165
+ local sprite = gridEntity:GetSprite()
166
+ local fileName = sprite:GetFilename()
167
+ if fileName == "gfx/grid/grid_rock.anm2" then
168
+ sprite:ReplaceSpritesheet(0, customStage.rocksPNGPath)
169
+ sprite:LoadGraphics()
170
+ elseif fileName == "gfx/grid/grid_pit.anm2" then
171
+ sprite:ReplaceSpritesheet(1, customStage.rocksPNGPath)
172
+ sprite:LoadGraphics()
173
+ end
174
+ end
175
+ --- For `GridEntityType.PIT` (7)
176
+ function ____exports.setCustomPitGraphics(self, customStage, gridEntity)
177
+ if customStage.pitsPNGPath == nil then
178
+ return
179
+ end
180
+ local sprite = gridEntity:GetSprite()
181
+ local fileName = sprite:GetFilename()
182
+ if fileName == "gfx/grid/grid_pit.anm2" then
183
+ sprite:ReplaceSpritesheet(0, customStage.pitsPNGPath)
184
+ sprite:LoadGraphics()
185
+ end
186
+ end
187
+ --- For GridEntityType.DOOR (16)
188
+ function ____exports.setCustomDoorGraphics(self, customStage, gridEntity)
189
+ local sprite = gridEntity:GetSprite()
190
+ local fileName = sprite:GetFilename()
191
+ local doorPNGPath = getNewDoorPNGPath(nil, customStage, fileName)
192
+ if doorPNGPath ~= nil then
193
+ sprite:ReplaceSpritesheet(0, doorPNGPath)
194
+ sprite:LoadGraphics()
195
+ end
196
+ end
197
+ --- The rewards are based on the ones from the wiki:
198
+ -- https://bindingofisaacrebirth.fandom.com/wiki/Rocks#Urns
199
+ --
200
+ -- On the bugged stage of -1, only urns will spawn, so we do not have to handle the case of mushroom
201
+ -- rewards, skull rewards, and so on.
202
+ function ____exports.removeUrnRewards(self, customStage, gridEntity)
203
+ if customStage.rocksPNGPath == nil then
204
+ return
205
+ end
206
+ local spiders = getNPCs(nil, EntityType.SPIDER)
207
+ removeEntitiesSpawnedFromGridEntity(nil, spiders, gridEntity)
208
+ local coins = getCoins(nil)
209
+ removeEntitiesSpawnedFromGridEntity(nil, coins, gridEntity)
210
+ local quarters = getCollectibles(nil, CollectibleType.QUARTER)
211
+ removeEntitiesSpawnedFromGridEntity(nil, quarters, gridEntity)
212
+ local swallowedPennies = getTrinkets(nil, TrinketType.SWALLOWED_PENNY)
213
+ removeEntitiesSpawnedFromGridEntity(nil, swallowedPennies, gridEntity)
214
+ end
215
+ return ____exports
@@ -3,9 +3,12 @@ local Map = ____lualib.Map
3
3
  local __TS__ObjectAssign = ____lualib.__TS__ObjectAssign
4
4
  local __TS__New = ____lualib.__TS__New
5
5
  local ____exports = {}
6
- local initRoomTypeMaps, getRoomTypeMap, postRender, postNewRoomReordered
6
+ local initRoomTypeMaps, getRoomTypeMap, postRender, getShaderParams, postGridEntityBrokenRockAlt, postGridEntityBrokenInit, postNewRoomReordered
7
7
  local ____isaac_2Dtypescript_2Ddefinitions = require("isaac-typescript-definitions")
8
+ local GridEntityType = ____isaac_2Dtypescript_2Ddefinitions.GridEntityType
8
9
  local ModCallback = ____isaac_2Dtypescript_2Ddefinitions.ModCallback
10
+ local ____cachedClasses = require("cachedClasses")
11
+ local game = ____cachedClasses.game
9
12
  local ____ModCallbackCustom = require("enums.ModCallbackCustom")
10
13
  local ModCallbackCustom = ____ModCallbackCustom.ModCallbackCustom
11
14
  local ____array = require("functions.array")
@@ -14,8 +17,18 @@ local ____exports = require("features.saveDataManager.exports")
14
17
  local saveDataManager = ____exports.saveDataManager
15
18
  local ____backdrop = require("features.customStage.backdrop")
16
19
  local setBackdrop = ____backdrop.setBackdrop
20
+ local ____gridEntities = require("features.customStage.gridEntities")
21
+ local removeUrnRewards = ____gridEntities.removeUrnRewards
22
+ local setCustomDecorationGraphics = ____gridEntities.setCustomDecorationGraphics
23
+ local setCustomDoorGraphics = ____gridEntities.setCustomDoorGraphics
24
+ local setCustomPitGraphics = ____gridEntities.setCustomPitGraphics
25
+ local setCustomRockGraphics = ____gridEntities.setCustomRockGraphics
17
26
  local metadataJSON = require("features.customStage.metadata")
27
+ local ____shadows = require("features.customStage.shadows")
28
+ local setShadows = ____shadows.setShadows
29
+ local shadowsPostRender = ____shadows.shadowsPostRender
18
30
  local ____streakText = require("features.customStage.streakText")
31
+ local streakTextGetShaderParams = ____streakText.streakTextGetShaderParams
19
32
  local streakTextPostRender = ____streakText.streakTextPostRender
20
33
  local ____v = require("features.customStage.v")
21
34
  local v = ____v.default
@@ -64,21 +77,50 @@ function postRender(self)
64
77
  if customStage == nil then
65
78
  return
66
79
  end
80
+ local isPaused = game:IsPaused()
81
+ if isPaused then
82
+ return
83
+ end
67
84
  streakTextPostRender(nil, customStage)
85
+ shadowsPostRender(nil, customStage)
68
86
  versusScreenPostRender(nil)
69
87
  end
88
+ function getShaderParams(self, shaderName)
89
+ return streakTextGetShaderParams(nil, shaderName)
90
+ end
91
+ function postGridEntityBrokenRockAlt(self, gridEntity)
92
+ local customStage = v.run.currentCustomStage
93
+ if customStage == nil then
94
+ return
95
+ end
96
+ removeUrnRewards(nil, customStage, gridEntity)
97
+ end
98
+ function postGridEntityBrokenInit(self, gridEntity)
99
+ local customStage = v.run.currentCustomStage
100
+ if customStage == nil then
101
+ return
102
+ end
103
+ setCustomDecorationGraphics(nil, customStage, gridEntity)
104
+ setCustomRockGraphics(nil, customStage, gridEntity)
105
+ setCustomPitGraphics(nil, customStage, gridEntity)
106
+ setCustomDoorGraphics(nil, customStage, gridEntity)
107
+ end
70
108
  function postNewRoomReordered(self)
71
109
  local customStage = v.run.currentCustomStage
72
110
  if customStage == nil then
73
111
  return
74
112
  end
75
113
  setBackdrop(nil, customStage)
114
+ setShadows(nil, customStage)
76
115
  playVersusScreenAnimation(nil, customStage)
77
116
  end
78
117
  function ____exports.customStageInit(self, mod)
79
118
  saveDataManager(nil, "customStage", v)
80
119
  initRoomTypeMaps(nil)
81
120
  mod:AddCallback(ModCallback.POST_RENDER, postRender)
121
+ mod:AddCallback(ModCallback.GET_SHADER_PARAMS, getShaderParams)
122
+ mod:AddCallbackCustom(ModCallbackCustom.POST_GRID_ENTITY_BROKEN, postGridEntityBrokenRockAlt, GridEntityType.ROCK_ALT)
123
+ mod:AddCallbackCustom(ModCallbackCustom.POST_GRID_ENTITY_INIT, postGridEntityBrokenInit)
82
124
  mod:AddCallbackCustom(ModCallbackCustom.POST_NEW_ROOM_REORDERED, postNewRoomReordered)
83
125
  end
84
126
  return ____exports
@@ -0,0 +1,3 @@
1
+ import { CustomStage } from "../../interfaces/CustomStage";
2
+ export declare function setShadows(customStage: CustomStage): void;
3
+ export declare function shadowsPostRender(_customStage: CustomStage): void;
@@ -0,0 +1,59 @@
1
+ local ____exports = {}
2
+ local ____isaac_2Dtypescript_2Ddefinitions = require("isaac-typescript-definitions")
3
+ local RoomShape = ____isaac_2Dtypescript_2Ddefinitions.RoomShape
4
+ local ____cachedClasses = require("cachedClasses")
5
+ local game = ____cachedClasses.game
6
+ local ____constants = require("constants")
7
+ local VectorZero = ____constants.VectorZero
8
+ local ____array = require("functions.array")
9
+ local getRandomArrayElement = ____array.getRandomArrayElement
10
+ local ____customStageConstants = require("features.customStage.customStageConstants")
11
+ local ISAACSCRIPT_CUSTOM_STAGE_GFX_PATH = ____customStageConstants.ISAACSCRIPT_CUSTOM_STAGE_GFX_PATH
12
+ local ____v = require("features.customStage.v")
13
+ local v = ____v.default
14
+ --- The animation comes from StageAPI.
15
+ local ROOM_SHAPE_TO_SHADOW_ANIMATION = {
16
+ [RoomShape.SHAPE_1x1] = "1x1",
17
+ [RoomShape.IH] = "1x1",
18
+ [RoomShape.IV] = "1x1",
19
+ [RoomShape.SHAPE_1x2] = "1x2",
20
+ [RoomShape.IIV] = "1x2",
21
+ [RoomShape.SHAPE_2x1] = "2x1",
22
+ [RoomShape.IIH] = "2x1",
23
+ [RoomShape.SHAPE_2x2] = "2x2",
24
+ [RoomShape.LTL] = "2x2",
25
+ [RoomShape.LTR] = "2x2",
26
+ [RoomShape.LBL] = "2x2",
27
+ [RoomShape.LBR] = "2x2"
28
+ }
29
+ local shadowSprite = Sprite()
30
+ shadowSprite:Load(ISAACSCRIPT_CUSTOM_STAGE_GFX_PATH .. "/stage-shadow.anm2", true)
31
+ function ____exports.setShadows(self, customStage)
32
+ if customStage.shadowPNGPaths == nil then
33
+ return
34
+ end
35
+ local room = game:GetRoom()
36
+ local roomShape = room:GetRoomShape()
37
+ local animation = ROOM_SHAPE_TO_SHADOW_ANIMATION[roomShape]
38
+ local shadowPNGPaths = customStage.shadowPNGPaths[animation]
39
+ if shadowPNGPaths == nil then
40
+ return
41
+ end
42
+ local decorationSeed = room:GetDecorationSeed()
43
+ local shadowPNGPath = getRandomArrayElement(nil, shadowPNGPaths, decorationSeed)
44
+ shadowSprite:ReplaceSpritesheet(0, shadowPNGPath)
45
+ shadowSprite:LoadGraphics()
46
+ shadowSprite:SetFrame(animation, 0)
47
+ v.room.showingShadows = true
48
+ end
49
+ function ____exports.shadowsPostRender(self, _customStage)
50
+ if not v.room.showingShadows then
51
+ return
52
+ end
53
+ local room = game:GetRoom()
54
+ local renderPosition = Isaac.WorldToRenderPosition(VectorZero)
55
+ local renderScrollOffset = room:GetRenderScrollOffset()
56
+ local position = renderPosition + renderScrollOffset
57
+ shadowSprite:Render(position)
58
+ end
59
+ return ____exports
@@ -1,2 +1,3 @@
1
1
  import { CustomStage } from "../../interfaces/CustomStage";
2
2
  export declare function streakTextPostRender(customStage: CustomStage): void;
3
+ export declare function streakTextGetShaderParams(shaderName: string): Record<string, unknown> | undefined;
@@ -7,6 +7,7 @@ local ____ui = require("functions.ui")
7
7
  local getScreenBottomCenterPos = ____ui.getScreenBottomCenterPos
8
8
  local ____v = require("features.customStage.v")
9
9
  local v = ____v.default
10
+ local EMPTY_SHADER_NAME = "IsaacScriptEmptyShader"
10
11
  local STREAK_TEXT_BOTTOM_OFFSET = Vector(0, -60)
11
12
  function ____exports.streakTextPostRender(self, customStage)
12
13
  if not v.run.showingStreakText then
@@ -19,4 +20,10 @@ function ____exports.streakTextPostRender(self, customStage)
19
20
  local adjustedX = position.X - length / 2
20
21
  font:DrawString(customStage.name, adjustedX, position.Y, KColorDefault)
21
22
  end
23
+ function ____exports.streakTextGetShaderParams(self, shaderName)
24
+ if shaderName ~= EMPTY_SHADER_NAME then
25
+ return nil
26
+ end
27
+ return {}
28
+ end
22
29
  return ____exports
@@ -6,6 +6,9 @@ declare const v: {
6
6
  showingStreakText: boolean;
7
7
  showingBossVersusScreen: boolean;
8
8
  };
9
+ room: {
10
+ showingShadows: boolean;
11
+ };
9
12
  };
10
13
  export default v;
11
14
  /** Indexed by custom stage name. */
@@ -2,7 +2,7 @@ local ____lualib = require("lualib_bundle")
2
2
  local Map = ____lualib.Map
3
3
  local __TS__New = ____lualib.__TS__New
4
4
  local ____exports = {}
5
- local v = {run = {currentCustomStage = nil, showingStreakText = false, showingBossVersusScreen = false}}
5
+ local v = {run = {currentCustomStage = nil, showingStreakText = false, showingBossVersusScreen = false}, room = {showingShadows = false}}
6
6
  ____exports.default = v
7
7
  --- Indexed by custom stage name.
8
8
  ____exports.customStagesMap = __TS__New(Map)
@@ -139,20 +139,28 @@ function ____exports.playVersusScreenAnimation(self, customStage, force)
139
139
  versusScreenSprite:ReplaceSpritesheet(BOSS_PORTRAIT_ANM2_LAYER, bossPortraitPNGPath)
140
140
  versusScreenSprite:LoadGraphics()
141
141
  local backgroundColor = VERSUS_SCREEN_BACKGROUND_COLORS[DEFAULT_STAGE_ID]
142
- if customStage.versusScreenBackgroundColor ~= nil then
143
- local ____customStage_versusScreenBackgroundColor_0 = customStage.versusScreenBackgroundColor
144
- local r = ____customStage_versusScreenBackgroundColor_0.r
145
- local g = ____customStage_versusScreenBackgroundColor_0.g
146
- local b = ____customStage_versusScreenBackgroundColor_0.b
142
+ local ____customStage_versusScreen_backgroundColor_0 = customStage.versusScreen
143
+ if ____customStage_versusScreen_backgroundColor_0 ~= nil then
144
+ ____customStage_versusScreen_backgroundColor_0 = ____customStage_versusScreen_backgroundColor_0.backgroundColor
145
+ end
146
+ if ____customStage_versusScreen_backgroundColor_0 ~= nil then
147
+ local ____customStage_versusScreen_backgroundColor_2 = customStage.versusScreen.backgroundColor
148
+ local r = ____customStage_versusScreen_backgroundColor_2.r
149
+ local g = ____customStage_versusScreen_backgroundColor_2.g
150
+ local b = ____customStage_versusScreen_backgroundColor_2.b
147
151
  backgroundColor = Color(r, g, b)
148
152
  end
149
153
  versusScreenBackgroundSprite.Color = backgroundColor
150
154
  local dirtSpotColor = VERSUS_SCREEN_DIRT_SPOT_COLORS[DEFAULT_STAGE_ID]
151
- if customStage.versusScreenDirtSpotColor ~= nil then
152
- local ____customStage_versusScreenDirtSpotColor_1 = customStage.versusScreenDirtSpotColor
153
- local r = ____customStage_versusScreenDirtSpotColor_1.r
154
- local g = ____customStage_versusScreenDirtSpotColor_1.g
155
- local b = ____customStage_versusScreenDirtSpotColor_1.b
155
+ local ____customStage_versusScreen_dirtSpotColor_3 = customStage.versusScreen
156
+ if ____customStage_versusScreen_dirtSpotColor_3 ~= nil then
157
+ ____customStage_versusScreen_dirtSpotColor_3 = ____customStage_versusScreen_dirtSpotColor_3.dirtSpotColor
158
+ end
159
+ if ____customStage_versusScreen_dirtSpotColor_3 ~= nil then
160
+ local ____customStage_versusScreen_dirtSpotColor_5 = customStage.versusScreen.dirtSpotColor
161
+ local r = ____customStage_versusScreen_dirtSpotColor_5.r
162
+ local g = ____customStage_versusScreen_dirtSpotColor_5.g
163
+ local b = ____customStage_versusScreen_dirtSpotColor_5.b
156
164
  dirtSpotColor = Color(r, g, b)
157
165
  end
158
166
  versusScreenDirtSpotSprite.Color = dirtSpotColor
@@ -84,6 +84,7 @@ function initMap(self)
84
84
  extraConsoleCommandsFunctionMap:set("goldenKey", commands.goldenKey)
85
85
  extraConsoleCommandsFunctionMap:set("grid", commands.grid)
86
86
  extraConsoleCommandsFunctionMap:set("grid2", commands.grid2)
87
+ extraConsoleCommandsFunctionMap:set("gridCosts", commands.gridCosts)
87
88
  extraConsoleCommandsFunctionMap:set("gridEntities", commands.gridEntities)
88
89
  extraConsoleCommandsFunctionMap:set("h", commands.h)
89
90
  extraConsoleCommandsFunctionMap:set("hearts", commands.hearts)
@@ -168,6 +169,7 @@ function initMap(self)
168
169
  extraConsoleCommandsFunctionMap:set("trapdoor", commands.trapdoorCommand)
169
170
  extraConsoleCommandsFunctionMap:set("treasure", commands.treasure)
170
171
  extraConsoleCommandsFunctionMap:set("ultraSecret", commands.ultraSecret)
172
+ extraConsoleCommandsFunctionMap:set("unseed", commands.unseed)
171
173
  extraConsoleCommandsFunctionMap:set("up", commands.up)
172
174
  extraConsoleCommandsFunctionMap:set("warp", commands.warp)
173
175
  end