isaacscript-common 6.11.1 → 6.13.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.
- package/dist/callbacks/postFlip.lua +2 -2
- package/dist/callbacks/postGridEntityCustomRender.d.ts +2 -0
- package/dist/callbacks/postGridEntityCustomRender.d.ts.map +1 -0
- package/dist/callbacks/postGridEntityCustomRender.lua +36 -0
- package/dist/callbacks/postGridEntityCustomUpdate.d.ts +2 -0
- package/dist/callbacks/postGridEntityCustomUpdate.d.ts.map +1 -0
- package/dist/callbacks/postGridEntityCustomUpdate.lua +36 -0
- package/dist/callbacks/postNewRoomEarly.lua +2 -2
- package/dist/callbacks/postPickupInitFirst.lua +1 -20
- package/dist/callbacks/reorderedCallbacks.d.ts +5 -5
- package/dist/callbacks/reorderedCallbacks.d.ts.map +1 -1
- package/dist/callbacks/reorderedCallbacks.lua +5 -5
- package/dist/callbacks/subscriptions/postFirstFlip.d.ts +1 -1
- package/dist/callbacks/subscriptions/postFirstFlip.d.ts.map +1 -1
- package/dist/callbacks/subscriptions/postFirstFlip.lua +2 -2
- package/dist/callbacks/subscriptions/postFlip.d.ts +1 -1
- package/dist/callbacks/subscriptions/postFlip.d.ts.map +1 -1
- package/dist/callbacks/subscriptions/postFlip.lua +2 -2
- package/dist/callbacks/subscriptions/postGridEntityCustomRender.d.ts +6 -0
- package/dist/callbacks/subscriptions/postGridEntityCustomRender.d.ts.map +1 -0
- package/dist/callbacks/subscriptions/postGridEntityCustomRender.lua +29 -0
- package/dist/callbacks/subscriptions/postGridEntityCustomUpdate.d.ts +6 -0
- package/dist/callbacks/subscriptions/postGridEntityCustomUpdate.d.ts.map +1 -0
- package/dist/callbacks/subscriptions/postGridEntityCustomUpdate.lua +29 -0
- package/dist/constants.d.ts +1 -5
- package/dist/constants.d.ts.map +1 -1
- package/dist/constants.lua +0 -7
- package/dist/constantsFirstLast.d.ts +5 -1
- package/dist/constantsFirstLast.d.ts.map +1 -1
- package/dist/constantsFirstLast.lua +6 -0
- package/dist/enums/ModCallbackCustom.d.ts +91 -68
- package/dist/enums/ModCallbackCustom.d.ts.map +1 -1
- package/dist/enums/ModCallbackCustom.lua +62 -58
- package/dist/enums/private/StageTravelState.d.ts +6 -1
- package/dist/enums/private/StageTravelState.d.ts.map +1 -1
- package/dist/enums/private/StageTravelState.lua +10 -0
- package/dist/enums/private/TrapdoorAnimation.d.ts +6 -0
- package/dist/enums/private/TrapdoorAnimation.d.ts.map +1 -0
- package/dist/enums/private/TrapdoorAnimation.lua +6 -0
- package/dist/features/collectibleItemPoolType.d.ts +2 -2
- package/dist/features/collectibleItemPoolType.lua +2 -2
- package/dist/features/customGridEntity.d.ts +17 -5
- package/dist/features/customGridEntity.d.ts.map +1 -1
- package/dist/features/customGridEntity.lua +78 -15
- package/dist/features/customStage/exports.d.ts.map +1 -1
- package/dist/features/customStage/exports.lua +0 -13
- package/dist/features/customStage/init.d.ts.map +1 -1
- package/dist/features/customStage/init.lua +16 -1
- package/dist/features/customStage/streakText.d.ts.map +1 -1
- package/dist/features/customStage/streakText.lua +0 -1
- package/dist/features/customTrapdoor/blackSprite.d.ts +2 -0
- package/dist/features/customTrapdoor/blackSprite.d.ts.map +1 -0
- package/dist/features/customTrapdoor/blackSprite.lua +19 -0
- package/dist/features/customTrapdoor/customTrapdoorConstants.d.ts +8 -3
- package/dist/features/customTrapdoor/customTrapdoorConstants.d.ts.map +1 -1
- package/dist/features/customTrapdoor/customTrapdoorConstants.lua +9 -1
- package/dist/features/customTrapdoor/exports.d.ts +11 -19
- package/dist/features/customTrapdoor/exports.d.ts.map +1 -1
- package/dist/features/customTrapdoor/exports.lua +48 -82
- package/dist/features/customTrapdoor/init.d.ts +3 -0
- package/dist/features/customTrapdoor/init.d.ts.map +1 -0
- package/dist/features/customTrapdoor/init.lua +174 -0
- package/dist/features/customTrapdoor/openClose.d.ts +5 -0
- package/dist/features/customTrapdoor/openClose.d.ts.map +1 -0
- package/dist/features/customTrapdoor/openClose.lua +60 -0
- package/dist/features/customTrapdoor/touched.d.ts +4 -0
- package/dist/features/customTrapdoor/touched.d.ts.map +1 -0
- package/dist/features/customTrapdoor/touched.lua +159 -0
- package/dist/features/customTrapdoor/v.d.ts +16 -2
- package/dist/features/customTrapdoor/v.d.ts.map +1 -1
- package/dist/features/customTrapdoor/v.lua +8 -6
- package/dist/features/deployJSONRoom.d.ts +2 -2
- package/dist/features/deployJSONRoom.lua +2 -2
- package/dist/features/extraConsoleCommands/init.d.ts.map +1 -1
- package/dist/features/extraConsoleCommands/init.lua +14 -15
- package/dist/features/extraConsoleCommands/listCommands.d.ts +15 -19
- package/dist/features/extraConsoleCommands/listCommands.d.ts.map +1 -1
- package/dist/features/extraConsoleCommands/listCommands.lua +34 -42
- package/dist/features/pause.d.ts +1 -1
- package/dist/features/pause.d.ts.map +1 -1
- package/dist/features/pause.lua +87 -8
- package/dist/features/persistentEntities.d.ts.map +1 -1
- package/dist/features/persistentEntities.lua +7 -7
- package/dist/features/pickupIndex.d.ts +19 -0
- package/dist/features/pickupIndex.d.ts.map +1 -0
- package/dist/features/pickupIndex.lua +197 -0
- package/dist/features/roomHistory.d.ts +24 -0
- package/dist/features/roomHistory.d.ts.map +1 -0
- package/dist/features/roomHistory.lua +89 -0
- package/dist/features/taintedLazarusPlayers.d.ts.map +1 -1
- package/dist/features/taintedLazarusPlayers.lua +13 -21
- package/dist/functions/collectibles.d.ts +26 -13
- package/dist/functions/collectibles.d.ts.map +1 -1
- package/dist/functions/collectibles.lua +26 -13
- package/dist/functions/entities.d.ts +3 -3
- package/dist/functions/entities.d.ts.map +1 -1
- package/dist/functions/entities.lua +8 -3
- package/dist/functions/gridEntities.d.ts +2 -2
- package/dist/functions/gridEntities.lua +2 -2
- package/dist/functions/isaacAPIClass.d.ts +64 -0
- package/dist/functions/isaacAPIClass.d.ts.map +1 -1
- package/dist/functions/isaacAPIClass.lua +84 -1
- package/dist/functions/log.lua +3 -3
- package/dist/functions/map.d.ts +2 -0
- package/dist/functions/map.d.ts.map +1 -1
- package/dist/functions/map.lua +7 -0
- package/dist/functions/pickupVariants.d.ts +2 -2
- package/dist/functions/pickupVariants.d.ts.map +1 -1
- package/dist/functions/pickupVariants.lua +2 -2
- package/dist/functions/playerCenter.lua +2 -2
- package/dist/functions/playerIndex.d.ts +5 -3
- package/dist/functions/playerIndex.d.ts.map +1 -1
- package/dist/functions/playerIndex.lua +15 -24
- package/dist/functions/roomData.d.ts +3 -2
- package/dist/functions/roomData.d.ts.map +1 -1
- package/dist/functions/roomData.lua +3 -2
- package/dist/functions/rooms.d.ts +6 -6
- package/dist/functions/rooms.lua +6 -6
- package/dist/functions/set.d.ts +2 -0
- package/dist/functions/set.d.ts.map +1 -1
- package/dist/functions/set.lua +6 -0
- package/dist/functions/stage.d.ts +1 -0
- package/dist/functions/stage.d.ts.map +1 -1
- package/dist/functions/stage.lua +4 -0
- package/dist/functions/table.d.ts +1 -1
- package/dist/functions/table.d.ts.map +1 -1
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.lua +23 -0
- package/dist/initCustomCallbacks.d.ts.map +1 -1
- package/dist/initCustomCallbacks.lua +6 -0
- package/dist/initFeatures.d.ts.map +1 -1
- package/dist/initFeatures.lua +9 -0
- package/dist/interfaces/AddCallbackParameterCustom.d.ts +4 -0
- package/dist/interfaces/AddCallbackParameterCustom.d.ts.map +1 -1
- package/dist/interfaces/CustomGridEntityData.d.ts +5 -1
- package/dist/interfaces/CustomGridEntityData.d.ts.map +1 -1
- package/dist/interfaces/RoomDescription.d.ts +14 -0
- package/dist/interfaces/RoomDescription.d.ts.map +1 -0
- package/dist/interfaces/RoomDescription.lua +2 -0
- package/dist/interfaces/private/CustomTrapdoorDescription.d.ts +3 -0
- package/dist/interfaces/private/CustomTrapdoorDescription.d.ts.map +1 -1
- package/dist/objects/callbackRegisterFunctions.d.ts.map +1 -1
- package/dist/objects/callbackRegisterFunctions.lua +6 -0
- package/dist/types/CollectibleIndex.d.ts +1 -1
- package/dist/types/PickupIndex.d.ts +17 -0
- package/dist/types/PickupIndex.d.ts.map +1 -0
- package/dist/types/PickupIndex.lua +2 -0
- package/dist/types/PlayerIndex.d.ts +1 -1
- package/dist/upgradeMod.d.ts.map +1 -1
- package/package.json +2 -2
- package/src/callbacks/postFlip.ts +3 -2
- package/src/callbacks/postGridEntityCustomRender.ts +44 -0
- package/src/callbacks/postGridEntityCustomUpdate.ts +44 -0
- package/src/callbacks/postNewRoomEarly.ts +2 -2
- package/src/callbacks/postPickupInitFirst.ts +3 -32
- package/src/callbacks/postPlayerReorderedCallbacks.ts +3 -3
- package/src/callbacks/reorderedCallbacks.ts +9 -8
- package/src/callbacks/subscriptions/postFirstFlip.ts +6 -3
- package/src/callbacks/subscriptions/postFlip.ts +6 -3
- package/src/callbacks/subscriptions/postGridEntityCustomRender.ts +41 -0
- package/src/callbacks/subscriptions/postGridEntityCustomUpdate.ts +41 -0
- package/src/constants.ts +1 -9
- package/src/constantsFirstLast.ts +16 -0
- package/src/enums/ModCallbackCustom.ts +35 -10
- package/src/enums/private/StageTravelState.ts +5 -1
- package/src/enums/private/TrapdoorAnimation.ts +5 -0
- package/src/features/collectibleItemPoolType.ts +3 -3
- package/src/features/customGridEntity.ts +93 -10
- package/src/features/customStage/exports.ts +3 -22
- package/src/features/customStage/init.ts +20 -0
- package/src/features/customStage/streakText.ts +0 -1
- package/src/features/customTrapdoor/blackSprite.ts +22 -0
- package/src/features/customTrapdoor/customTrapdoorConstants.ts +13 -3
- package/src/features/customTrapdoor/exports.ts +52 -121
- package/src/features/customTrapdoor/init.ts +217 -0
- package/src/features/customTrapdoor/openClose.ts +103 -0
- package/src/features/customTrapdoor/touched.ts +195 -0
- package/src/features/customTrapdoor/v.ts +16 -10
- package/src/features/deployJSONRoom.ts +5 -5
- package/src/features/extraConsoleCommands/init.ts +22 -16
- package/src/features/extraConsoleCommands/listCommands.ts +38 -43
- package/src/features/pause.ts +97 -7
- package/src/features/persistentEntities.ts +9 -8
- package/src/features/pickupIndex.ts +257 -0
- package/src/features/playerInventory.ts +2 -2
- package/src/features/roomHistory.ts +113 -0
- package/src/features/saveDataManager/main.ts +3 -3
- package/src/features/taintedLazarusPlayers.ts +37 -36
- package/src/functions/collectibles.ts +26 -13
- package/src/functions/deepCopy.ts +2 -2
- package/src/functions/entities.ts +7 -4
- package/src/functions/gridEntities.ts +2 -2
- package/src/functions/isaacAPIClass.ts +106 -1
- package/src/functions/map.ts +10 -0
- package/src/functions/pickupVariants.ts +2 -2
- package/src/functions/playerCenter.ts +2 -2
- package/src/functions/playerIndex.ts +20 -21
- package/src/functions/rng.ts +1 -1
- package/src/functions/roomData.ts +3 -2
- package/src/functions/rooms.ts +6 -6
- package/src/functions/set.ts +7 -1
- package/src/functions/stage.ts +10 -1
- package/src/functions/table.ts +2 -2
- package/src/index.ts +3 -0
- package/src/initCustomCallbacks.ts +4 -0
- package/src/initFeatures.ts +6 -0
- package/src/interfaces/AddCallbackParameterCustom.ts +4 -0
- package/src/interfaces/CustomGridEntityData.ts +6 -1
- package/src/interfaces/RoomDescription.ts +19 -0
- package/src/interfaces/private/CustomTrapdoorDescription.ts +4 -0
- package/src/objects/callbackRegisterFunctions.ts +6 -0
- package/src/types/CollectibleIndex.ts +1 -1
- package/src/types/PickupIndex.ts +15 -0
- package/src/types/PlayerIndex.ts +1 -1
- package/src/upgradeMod.ts +2 -1
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
// The item pool type of a collectible is not stored on the collectible. Thus, we scan for incoming
|
|
2
|
-
// item pool types in the
|
|
2
|
+
// item pool types in the `PRE_GET_COLLECTIBLE` callback, and then assume that the next spawned
|
|
3
3
|
// collectible has this item pool type.
|
|
4
4
|
|
|
5
5
|
import {
|
|
@@ -45,8 +45,8 @@ function postPickupInitCollectible(pickup: EntityPickup) {
|
|
|
45
45
|
|
|
46
46
|
/**
|
|
47
47
|
* Helper function to get the item pool type that a given collectible came from. Since there is no
|
|
48
|
-
* native method in the API to get this, we listen in the
|
|
49
|
-
* types, and then assume that the next spawned collectible will match.
|
|
48
|
+
* native method in the API to get this, we listen in the `PRE_GET_COLLECTIBLE` callback for item
|
|
49
|
+
* pool types, and then assume that the next spawned collectible will match.
|
|
50
50
|
*/
|
|
51
51
|
export function getCollectibleItemPoolType(
|
|
52
52
|
collectible: EntityPickup,
|
|
@@ -19,6 +19,7 @@ import {
|
|
|
19
19
|
import { getRoomListIndex } from "../functions/roomData";
|
|
20
20
|
import { isVector } from "../functions/vector";
|
|
21
21
|
import { CustomGridEntityData } from "../interfaces/CustomGridEntityData";
|
|
22
|
+
import { runNextGameFrame } from "./runInNFrames";
|
|
22
23
|
import { saveDataManager } from "./saveDataManager/exports";
|
|
23
24
|
|
|
24
25
|
const FEATURE_NAME = "customGridEntity";
|
|
@@ -30,6 +31,10 @@ const v = {
|
|
|
30
31
|
() => new Map(),
|
|
31
32
|
),
|
|
32
33
|
},
|
|
34
|
+
|
|
35
|
+
room: {
|
|
36
|
+
manuallyUsingShovel: false,
|
|
37
|
+
},
|
|
33
38
|
};
|
|
34
39
|
|
|
35
40
|
/** @internal */
|
|
@@ -53,12 +58,54 @@ export function customGridEntityInit(mod: ModUpgraded): void {
|
|
|
53
58
|
function preUseItemWeNeedToGoDeeper(
|
|
54
59
|
_collectibleType: CollectibleType,
|
|
55
60
|
_rng: RNG,
|
|
56
|
-
|
|
61
|
+
player: EntityPlayer,
|
|
57
62
|
_useFlags: BitFlags<UseFlag>,
|
|
58
63
|
_activeSlot: ActiveSlot,
|
|
59
64
|
_customVarData: int,
|
|
60
65
|
): boolean | undefined {
|
|
61
|
-
|
|
66
|
+
// If a player uses We Need to Go Deeper on top of a custom grid entity, then they will always get
|
|
67
|
+
// a crawlspace, due to how custom grids are implemented with decorations. Thus, remove the custom
|
|
68
|
+
// grid entity to prevent this from happening if needed.
|
|
69
|
+
const room = game.GetRoom();
|
|
70
|
+
const roomListIndex = getRoomListIndex();
|
|
71
|
+
const roomCustomGridEntities = v.level.customGridEntities.get(roomListIndex);
|
|
72
|
+
if (roomCustomGridEntities === undefined) {
|
|
73
|
+
return undefined;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
const gridIndex = room.GetGridIndex(player.Position);
|
|
77
|
+
const customGridEntity = roomCustomGridEntities.get(gridIndex);
|
|
78
|
+
if (customGridEntity === undefined) {
|
|
79
|
+
return undefined;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
// If the custom grid entity has collision, then the player should not be able to be standing on
|
|
83
|
+
// top of it.
|
|
84
|
+
if (customGridEntity.gridCollisionClass !== GridCollisionClass.NONE) {
|
|
85
|
+
return undefined;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
removeGridEntity(customGridEntity.gridIndex, false);
|
|
89
|
+
|
|
90
|
+
const playerPtr = EntityPtr(player);
|
|
91
|
+
runNextGameFrame(() => {
|
|
92
|
+
const futureEntity = playerPtr.Ref;
|
|
93
|
+
if (futureEntity === undefined) {
|
|
94
|
+
return;
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
const futurePlayer = futureEntity.ToPlayer();
|
|
98
|
+
if (futurePlayer === undefined) {
|
|
99
|
+
return;
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
v.room.manuallyUsingShovel = true;
|
|
103
|
+
futurePlayer.UseActiveItem(CollectibleType.WE_NEED_TO_GO_DEEPER);
|
|
104
|
+
v.room.manuallyUsingShovel = false;
|
|
105
|
+
});
|
|
106
|
+
|
|
107
|
+
// Cancel the original effect.
|
|
108
|
+
return true;
|
|
62
109
|
}
|
|
63
110
|
|
|
64
111
|
// ModCallbackCustom.POST_NEW_ROOM_REORDERED
|
|
@@ -81,12 +128,18 @@ function postNewRoomReordered() {
|
|
|
81
128
|
|
|
82
129
|
const sprite = decoration.GetSprite();
|
|
83
130
|
sprite.Load(data.anm2Path, true);
|
|
84
|
-
|
|
131
|
+
const animationToPlay =
|
|
132
|
+
data.defaultAnimation === undefined
|
|
133
|
+
? sprite.GetDefaultAnimation()
|
|
134
|
+
: data.defaultAnimation;
|
|
135
|
+
sprite.Play(animationToPlay, true);
|
|
85
136
|
}
|
|
86
137
|
}
|
|
87
138
|
|
|
88
139
|
/**
|
|
89
|
-
* Helper function to spawn a custom grid entity.
|
|
140
|
+
* Helper function to spawn a custom grid entity. Custom grid entities are persistent in that they
|
|
141
|
+
* will reappear if the player leaves and re-enters the room. (It will be manually respawned in the
|
|
142
|
+
* `POST_NEW_ROOM` callback.)
|
|
90
143
|
*
|
|
91
144
|
* This is an IsaacScript feature because the vanilla game does not support any custom grid
|
|
92
145
|
* entities. Under the hood, IsaacScript accomplishes this by using decorations with an arbitrary
|
|
@@ -103,17 +156,18 @@ function postNewRoomReordered() {
|
|
|
103
156
|
* @param gridIndexOrPosition The grid index or position in the room that you want to spawn the grid
|
|
104
157
|
* entity at. If a position is specified, the closest grid index will be
|
|
105
158
|
* used.
|
|
106
|
-
* @param anm2Path The path to the ANM2 file to use for the sprite.
|
|
107
|
-
* @param defaultAnimation The name of the animation to play after the sprite is initialized and
|
|
108
|
-
* after the player re-enters a room with this grid entity in it.
|
|
109
159
|
* @param gridCollisionClass The collision class that you want the custom grid entity to have.
|
|
160
|
+
* @param anm2Path The path to the ANM2 file to use for the sprite.
|
|
161
|
+
* @param defaultAnimation Optional. The name of the animation to play after the sprite is
|
|
162
|
+
* initialized and after the player re-enters a room with this grid entity
|
|
163
|
+
* in it. If not specified, the default animation in the anm2 will be used.
|
|
110
164
|
*/
|
|
111
165
|
export function spawnCustomGridEntity(
|
|
112
166
|
gridEntityTypeCustom: GridEntityType,
|
|
113
167
|
gridIndexOrPosition: int | Vector,
|
|
114
|
-
anm2Path: string,
|
|
115
|
-
defaultAnimation: string,
|
|
116
168
|
gridCollisionClass: GridCollisionClass,
|
|
169
|
+
anm2Path: string,
|
|
170
|
+
defaultAnimation?: string,
|
|
117
171
|
): GridEntity {
|
|
118
172
|
errorIfFeaturesNotInitialized(FEATURE_NAME);
|
|
119
173
|
|
|
@@ -142,7 +196,11 @@ export function spawnCustomGridEntity(
|
|
|
142
196
|
|
|
143
197
|
const sprite = decoration.GetSprite();
|
|
144
198
|
sprite.Load(anm2Path, true);
|
|
145
|
-
|
|
199
|
+
const animationToPlay =
|
|
200
|
+
defaultAnimation === undefined
|
|
201
|
+
? sprite.GetDefaultAnimation()
|
|
202
|
+
: defaultAnimation;
|
|
203
|
+
sprite.Play(animationToPlay, true);
|
|
146
204
|
|
|
147
205
|
const customGridEntityData: CustomGridEntityData = {
|
|
148
206
|
gridEntityTypeCustom,
|
|
@@ -216,3 +274,28 @@ export function removeCustomGrid(
|
|
|
216
274
|
|
|
217
275
|
return decoration;
|
|
218
276
|
}
|
|
277
|
+
|
|
278
|
+
/**
|
|
279
|
+
* Helper function to get the custom grid entities in the current room. Returns an array of tuples
|
|
280
|
+
* containing the raw decoration grid entity and the associated entity data.
|
|
281
|
+
*/
|
|
282
|
+
export function getCustomGridEntities(): Array<
|
|
283
|
+
[gridEntity: GridEntity, data: CustomGridEntityData]
|
|
284
|
+
> {
|
|
285
|
+
const roomListIndex = getRoomListIndex();
|
|
286
|
+
const roomCustomGridEntities = v.level.customGridEntities.get(roomListIndex);
|
|
287
|
+
if (roomCustomGridEntities === undefined) {
|
|
288
|
+
return [];
|
|
289
|
+
}
|
|
290
|
+
|
|
291
|
+
const room = game.GetRoom();
|
|
292
|
+
const customGridEntities: Array<[GridEntity, CustomGridEntityData]> = [];
|
|
293
|
+
for (const [gridIndex, data] of roomCustomGridEntities.entries()) {
|
|
294
|
+
const gridEntity = room.GetGridEntity(gridIndex);
|
|
295
|
+
if (gridEntity !== undefined) {
|
|
296
|
+
customGridEntities.push([gridEntity, data]);
|
|
297
|
+
}
|
|
298
|
+
}
|
|
299
|
+
|
|
300
|
+
return customGridEntities;
|
|
301
|
+
}
|
|
@@ -1,10 +1,8 @@
|
|
|
1
1
|
import {
|
|
2
|
-
Direction,
|
|
3
2
|
EntityType,
|
|
4
3
|
GridRoom,
|
|
5
4
|
LevelStage,
|
|
6
5
|
RoomShape,
|
|
7
|
-
RoomTransitionAnim,
|
|
8
6
|
RoomType,
|
|
9
7
|
StageType,
|
|
10
8
|
} from "isaac-typescript-definitions";
|
|
@@ -12,12 +10,10 @@ import { game } from "../../cachedClasses";
|
|
|
12
10
|
import { reorderedCallbacksSetStage } from "../../callbacks/reorderedCallbacks";
|
|
13
11
|
import { getEntityIDFromConstituents } from "../../functions/entities";
|
|
14
12
|
import { log, logError } from "../../functions/log";
|
|
15
|
-
import { movePlayersToCenter } from "../../functions/playerCenter";
|
|
16
13
|
import { newRNG } from "../../functions/rng";
|
|
17
14
|
import { getRoomData } from "../../functions/roomData";
|
|
18
15
|
import { getRooms } from "../../functions/rooms";
|
|
19
16
|
import { getGotoCommand, setStage } from "../../functions/stage";
|
|
20
|
-
import { runNextRoom } from "../runNextRoom";
|
|
21
17
|
import { getRandomCustomStageRoom } from "./customStageUtils";
|
|
22
18
|
import { topStreakTextStart } from "./streakText";
|
|
23
19
|
import v, {
|
|
@@ -136,24 +132,9 @@ export function setCustomStage(name: string, verbose = false): void {
|
|
|
136
132
|
|
|
137
133
|
// We must reload the current room in order for the `Level.SetStage` method to take effect.
|
|
138
134
|
// Furthermore, we need to cancel the queued warp to the `GridRoom.DEBUG` room. We can accomplish
|
|
139
|
-
// both of these things by initiating a room transition to
|
|
140
|
-
//
|
|
141
|
-
|
|
142
|
-
startingRoomGridIndex,
|
|
143
|
-
Direction.NO_DIRECTION,
|
|
144
|
-
RoomTransitionAnim.FADE,
|
|
145
|
-
);
|
|
146
|
-
|
|
147
|
-
// We do more setup once the room is reloaded from the transition.
|
|
148
|
-
runNextRoom(postRoomTransition);
|
|
149
|
-
}
|
|
150
|
-
|
|
151
|
-
function postRoomTransition() {
|
|
152
|
-
// After the room transition, the players will be placed next to a door, but they should be in the
|
|
153
|
-
// center of the room to emulate what happens on a vanilla stage.
|
|
154
|
-
movePlayersToCenter();
|
|
155
|
-
|
|
156
|
-
topStreakTextStart();
|
|
135
|
+
// both of these things by initiating a room transition to an arbitrary room. However, we rely on
|
|
136
|
+
// the parent function to do this, since for normal purposes, we need to initiate a room
|
|
137
|
+
// transition for pixelation purposes.
|
|
157
138
|
}
|
|
158
139
|
|
|
159
140
|
export function setCustomStageDebug(): void {
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import {
|
|
2
2
|
DoorSlotFlag,
|
|
3
3
|
GridEntityType,
|
|
4
|
+
LevelCurse,
|
|
4
5
|
ModCallback,
|
|
5
6
|
RoomShape,
|
|
6
7
|
RoomType,
|
|
@@ -8,6 +9,7 @@ import {
|
|
|
8
9
|
import { ModUpgraded } from "../../classes/ModUpgraded";
|
|
9
10
|
import { ModCallbackCustom } from "../../enums/ModCallbackCustom";
|
|
10
11
|
import { isArray } from "../../functions/array";
|
|
12
|
+
import { hasFlag, removeFlag } from "../../functions/flag";
|
|
11
13
|
import { CustomStage, RoomTypeMap } from "../../interfaces/CustomStage";
|
|
12
14
|
import {
|
|
13
15
|
CustomStageLua,
|
|
@@ -49,6 +51,7 @@ export function customStageInit(mod: ModUpgraded): void {
|
|
|
49
51
|
versusScreenInit();
|
|
50
52
|
|
|
51
53
|
mod.AddCallback(ModCallback.POST_RENDER, postRender); // 2
|
|
54
|
+
mod.AddCallback(ModCallback.POST_CURSE_EVAL, postCurseEval); // 12
|
|
52
55
|
mod.AddCallback(ModCallback.POST_GAME_STARTED, postGameStarted); // 15
|
|
53
56
|
mod.AddCallback(ModCallback.GET_SHADER_PARAMS, getShaderParams); // 21
|
|
54
57
|
mod.AddCallbackCustom(
|
|
@@ -137,6 +140,23 @@ function postRender() {
|
|
|
137
140
|
versusScreenPostRender();
|
|
138
141
|
}
|
|
139
142
|
|
|
143
|
+
// ModCallback.POST_CURSE_EVAL (12)
|
|
144
|
+
function postCurseEval(
|
|
145
|
+
curses: BitFlags<LevelCurse>,
|
|
146
|
+
): BitFlags<LevelCurse> | undefined {
|
|
147
|
+
const customStage = v.run.currentCustomStage;
|
|
148
|
+
if (customStage === null) {
|
|
149
|
+
return undefined;
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
// Prevent XL floors on custom stages, since the streak text will not work properly.
|
|
153
|
+
if (hasFlag(curses, LevelCurse.MAZE)) {
|
|
154
|
+
return removeFlag(curses, LevelCurse.MAZE);
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
return undefined;
|
|
158
|
+
}
|
|
159
|
+
|
|
140
160
|
// ModCallback.POST_GAME_STARTED (15)
|
|
141
161
|
function postGameStarted() {
|
|
142
162
|
// We don't early return here because we need to unconditionally reset the sprites.
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { VectorZero } from "../../constants";
|
|
2
|
+
import { StageTravelState } from "../../enums/private/StageTravelState";
|
|
3
|
+
import v from "./v";
|
|
4
|
+
|
|
5
|
+
// In order to represent a black sprite, we just use the first frame of the boss versus screen
|
|
6
|
+
// animation. However, we must lazy load the sprite in order to prevent issues with mods that
|
|
7
|
+
// replace the vanilla files. (For some reason, loading the sprites will cause the overwrite to no
|
|
8
|
+
// longer apply on the second and subsequent runs.)
|
|
9
|
+
const blackSprite = Sprite();
|
|
10
|
+
|
|
11
|
+
export function drawBlackSprite(): void {
|
|
12
|
+
if (v.run.state !== StageTravelState.PAUSING_ON_BLACK) {
|
|
13
|
+
return;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
if (!blackSprite.IsLoaded()) {
|
|
17
|
+
blackSprite.Load("gfx/ui/boss/versusscreen.anm2", true);
|
|
18
|
+
blackSprite.SetFrame("Scene", 0);
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
blackSprite.RenderLayer(0, VectorZero);
|
|
22
|
+
}
|
|
@@ -2,12 +2,22 @@ import { GridEntityType } from "isaac-typescript-definitions";
|
|
|
2
2
|
|
|
3
3
|
export const CUSTOM_TRAPDOOR_FEATURE_NAME = "customTrapdoor";
|
|
4
4
|
|
|
5
|
+
export const GridEntityTypeCustom = {
|
|
6
|
+
TRAPDOOR_CUSTOM: 1000 as GridEntityType,
|
|
7
|
+
} as const;
|
|
8
|
+
|
|
5
9
|
/** This also applies to crawl spaces. The value was determined through trial and error. */
|
|
6
10
|
export const TRAPDOOR_OPEN_DISTANCE = 60;
|
|
7
11
|
|
|
8
12
|
export const TRAPDOOR_OPEN_DISTANCE_AFTER_BOSS = TRAPDOOR_OPEN_DISTANCE * 2.5;
|
|
9
13
|
export const TRAPDOOR_BOSS_REACTION_FRAMES = 30;
|
|
10
14
|
|
|
11
|
-
export const
|
|
12
|
-
|
|
13
|
-
|
|
15
|
+
export const TRAPDOOR_TOUCH_DISTANCE = 16.5;
|
|
16
|
+
|
|
17
|
+
export const ANIMATIONS_THAT_PREVENT_STAGE_TRAVEL: ReadonlySet<string> =
|
|
18
|
+
new Set(["Happy", "Sad", "Jump"]);
|
|
19
|
+
|
|
20
|
+
export const PIXELATION_TO_BLACK_FRAMES = 52;
|
|
21
|
+
|
|
22
|
+
export const OTHER_PLAYER_TRAPDOOR_JUMP_DELAY_GAME_FRAMES = 6;
|
|
23
|
+
export const OTHER_PLAYER_TRAPDOOR_JUMP_DURATION_GAME_FRAMES = 5;
|
|
@@ -1,23 +1,22 @@
|
|
|
1
1
|
import {
|
|
2
2
|
GridCollisionClass,
|
|
3
3
|
LevelStage,
|
|
4
|
-
RoomType,
|
|
5
4
|
StageType,
|
|
6
5
|
} from "isaac-typescript-definitions";
|
|
7
6
|
import { game } from "../../cachedClasses";
|
|
7
|
+
import { TrapdoorAnimation } from "../../enums/private/TrapdoorAnimation";
|
|
8
8
|
import { errorIfFeaturesNotInitialized } from "../../featuresInitialized";
|
|
9
9
|
import { getNextStage, getNextStageType } from "../../functions/nextStage";
|
|
10
|
-
import {
|
|
10
|
+
import { getRoomListIndex } from "../../functions/roomData";
|
|
11
|
+
import { isVector } from "../../functions/vector";
|
|
12
|
+
import { CustomTrapdoorDescription } from "../../interfaces/private/CustomTrapdoorDescription";
|
|
11
13
|
import { spawnCustomGridEntity } from "../customGridEntity";
|
|
12
|
-
import { getRoomClearGameFrame } from "../roomClearFrame";
|
|
13
14
|
import {
|
|
14
15
|
CUSTOM_TRAPDOOR_FEATURE_NAME,
|
|
15
16
|
GridEntityTypeCustom,
|
|
16
|
-
TRAPDOOR_BOSS_REACTION_FRAMES,
|
|
17
|
-
TRAPDOOR_OPEN_DISTANCE,
|
|
18
|
-
TRAPDOOR_OPEN_DISTANCE_AFTER_BOSS,
|
|
19
17
|
} from "./customTrapdoorConstants";
|
|
20
|
-
import {
|
|
18
|
+
import { shouldTrapdoorSpawnOpen } from "./openClose";
|
|
19
|
+
import v from "./v";
|
|
21
20
|
|
|
22
21
|
/**
|
|
23
22
|
* Helper function to spawn a trapdoor grid entity that will have one or more of the following
|
|
@@ -26,7 +25,7 @@ import { getCustomTrapdoorDescription } from "./v";
|
|
|
26
25
|
* - custom destination (or custom logic for after the player enters)
|
|
27
26
|
* - custom graphics
|
|
28
27
|
* - custom logic for opening/closing
|
|
29
|
-
* - TODO: animation
|
|
28
|
+
* - TODO: player jumping animation?
|
|
30
29
|
*
|
|
31
30
|
* You can use this function to take the player to your custom stage.
|
|
32
31
|
*
|
|
@@ -34,135 +33,67 @@ import { getCustomTrapdoorDescription } from "./v";
|
|
|
34
33
|
* respawned every time the player re-enters the room.
|
|
35
34
|
*
|
|
36
35
|
* @param gridIndexOrPosition The location in the room to spawn the trapdoor.
|
|
37
|
-
* @param
|
|
38
|
-
*
|
|
39
|
-
*
|
|
40
|
-
*
|
|
41
|
-
*
|
|
42
|
-
* function that returns one of these things. By default, the destination will
|
|
43
|
-
* be set to the next floor like that of a vanilla trapdoor.
|
|
36
|
+
* @param destination Optional. Used to specify where the player will go after jumping into the
|
|
37
|
+
* trapdoor. Can either be a tuple containing the stage and stage type, or a
|
|
38
|
+
* string containing the name of a custom stage. If not specified at all, then
|
|
39
|
+
* the "normal" destination corresponding to the current stage and room will be
|
|
40
|
+
* used (e.g. the next floor).
|
|
44
41
|
* @param anm2Path Optional. The path to the anm2 file to use. By default, the vanilla trapdoor anm2
|
|
45
|
-
* of "gfx/grid/door_11_trapdoor.anm2" will be used.
|
|
46
|
-
*
|
|
47
|
-
*
|
|
48
|
-
*
|
|
49
|
-
* @param _shouldCloseFunc Optional. If the trapdoor is currently open, this function will run on
|
|
50
|
-
* every frame to determine if it should close. By default, a function that
|
|
51
|
-
* emulates a vanilla trapdoor will be used.
|
|
52
|
-
* @param _spawnOpen Optional. Whether or not to spawn the trapdoor in an open state. Can either be
|
|
53
|
-
* a boolean or a function returning a boolean. By default, a function that
|
|
54
|
-
* emulates a vanilla trapdoor will be used.
|
|
42
|
+
* of "gfx/grid/door_11_trapdoor.anm2" will be used. The specified anm2 file must
|
|
43
|
+
* have animations called "Opened", "Closed", and "Open Animation".
|
|
44
|
+
* @param spawnOpen Optional. Whether or not to spawn the trapdoor in an open state. By default,
|
|
45
|
+
* behavior will be used that emulates a vanilla trapdoor.
|
|
55
46
|
*/
|
|
56
47
|
export function spawnCustomTrapdoor(
|
|
57
48
|
gridIndexOrPosition: int | Vector,
|
|
58
|
-
|
|
59
|
-
| [stage: LevelStage, stageType: StageType]
|
|
60
|
-
| string
|
|
61
|
-
| ((
|
|
62
|
-
gridEntity: GridEntity,
|
|
63
|
-
) =>
|
|
64
|
-
| [stage: LevelStage, stageType: StageType]
|
|
65
|
-
| string
|
|
66
|
-
| undefined) = defaultDestinationFunc,
|
|
49
|
+
destination?: [stage: LevelStage, stageType: StageType] | string,
|
|
67
50
|
anm2Path = "gfx/grid/door_11_trapdoor.anm2",
|
|
68
|
-
|
|
69
|
-
_shouldCloseFunc: (
|
|
70
|
-
gridEntity: GridEntity,
|
|
71
|
-
) => boolean = defaultShouldCloseFunc,
|
|
72
|
-
_spawnOpen:
|
|
73
|
-
| boolean
|
|
74
|
-
| ((gridEntity: GridEntity) => boolean) = defaultShouldSpawnOpenFunc,
|
|
51
|
+
spawnOpen?: boolean,
|
|
75
52
|
): GridEntity {
|
|
76
53
|
errorIfFeaturesNotInitialized(CUSTOM_TRAPDOOR_FEATURE_NAME);
|
|
77
54
|
|
|
78
|
-
|
|
79
|
-
|
|
55
|
+
const room = game.GetRoom();
|
|
56
|
+
const roomFrameCount = room.GetFrameCount();
|
|
57
|
+
const roomListIndex = getRoomListIndex();
|
|
58
|
+
const gridIndex = isVector(gridIndexOrPosition)
|
|
59
|
+
? room.GetGridIndex(gridIndexOrPosition)
|
|
60
|
+
: gridIndexOrPosition;
|
|
61
|
+
|
|
62
|
+
const gridEntity = spawnCustomGridEntity(
|
|
80
63
|
GridEntityTypeCustom.TRAPDOOR_CUSTOM,
|
|
81
64
|
gridIndexOrPosition,
|
|
82
|
-
anm2Path,
|
|
83
|
-
"Closed",
|
|
84
65
|
GridCollisionClass.NONE,
|
|
66
|
+
anm2Path,
|
|
67
|
+
TrapdoorAnimation.OPENED,
|
|
85
68
|
);
|
|
86
|
-
}
|
|
87
|
-
|
|
88
|
-
function defaultDestinationFunc(): [stage: LevelStage, stageType: StageType] {
|
|
89
|
-
const nextStage = getNextStage();
|
|
90
|
-
const nextStageType = getNextStageType();
|
|
91
|
-
|
|
92
|
-
return [nextStage, nextStageType];
|
|
93
|
-
}
|
|
94
|
-
|
|
95
|
-
function defaultShouldOpenFunc(gridEntity: GridEntity): boolean {
|
|
96
|
-
const trapdoorDescription = getCustomTrapdoorDescription(gridEntity);
|
|
97
|
-
if (trapdoorDescription === undefined) {
|
|
98
|
-
return false;
|
|
99
|
-
}
|
|
100
|
-
|
|
101
|
-
const room = game.GetRoom();
|
|
102
|
-
const roomClear = room.IsClear();
|
|
103
|
-
|
|
104
|
-
return (
|
|
105
|
-
!anyPlayerCloserThan(gridEntity.Position, TRAPDOOR_OPEN_DISTANCE) &&
|
|
106
|
-
!isPlayerCloseAfterBoss(gridEntity.Position) &&
|
|
107
|
-
!shouldBeClosedFromStartingInRoomWithEnemies(
|
|
108
|
-
trapdoorDescription.firstSpawn,
|
|
109
|
-
roomClear,
|
|
110
|
-
)
|
|
111
|
-
);
|
|
112
|
-
}
|
|
113
69
|
|
|
114
|
-
|
|
115
|
-
const
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
70
|
+
const firstSpawn = roomFrameCount !== 0;
|
|
71
|
+
const open =
|
|
72
|
+
spawnOpen === undefined
|
|
73
|
+
? shouldTrapdoorSpawnOpen(gridEntity, firstSpawn)
|
|
74
|
+
: spawnOpen;
|
|
75
|
+
const destinationToUse =
|
|
76
|
+
destination === undefined ? getDefaultDestination() : destination;
|
|
77
|
+
|
|
78
|
+
const roomTrapdoorMap = v.level.trapdoors.getAndSetDefault(roomListIndex);
|
|
79
|
+
const customTrapdoorDescription: CustomTrapdoorDescription = {
|
|
80
|
+
open,
|
|
81
|
+
destination: destinationToUse,
|
|
82
|
+
firstSpawn,
|
|
83
|
+
};
|
|
84
|
+
roomTrapdoorMap.set(gridIndex, customTrapdoorDescription);
|
|
85
|
+
|
|
86
|
+
if (!open) {
|
|
87
|
+
const sprite = gridEntity.GetSprite();
|
|
88
|
+
sprite.Play(TrapdoorAnimation.CLOSED, true);
|
|
128
89
|
}
|
|
129
90
|
|
|
130
|
-
return
|
|
91
|
+
return gridEntity;
|
|
131
92
|
}
|
|
132
93
|
|
|
133
|
-
function
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
) {
|
|
137
|
-
return firstSpawn && !roomClear;
|
|
138
|
-
}
|
|
139
|
-
|
|
140
|
-
/** By default, trapdoors will never close if they are already open. */
|
|
141
|
-
function defaultShouldCloseFunc(): boolean {
|
|
142
|
-
return false;
|
|
143
|
-
}
|
|
144
|
-
|
|
145
|
-
function defaultShouldSpawnOpenFunc(gridEntity: GridEntity): boolean {
|
|
146
|
-
const room = game.GetRoom();
|
|
147
|
-
const roomFrameCount = room.GetFrameCount();
|
|
148
|
-
const roomClear = room.IsClear();
|
|
149
|
-
|
|
150
|
-
// Trapdoors created after a room has already initialized should spawn closed by default:
|
|
151
|
-
// - Trapdoors created after bosses should spawn closed so that players do not accidentally jump
|
|
152
|
-
// into them.
|
|
153
|
-
// - Trapdoors created by We Need to Go Deeper should spawn closed because the player will be
|
|
154
|
-
// standing on top of them.
|
|
155
|
-
if (roomFrameCount > 0) {
|
|
156
|
-
return false;
|
|
157
|
-
}
|
|
158
|
-
|
|
159
|
-
// If we just entered a new room with enemies in it, spawn the trapdoor closed so that the player
|
|
160
|
-
// has to defeat the enemies first before using the trapdoor.
|
|
161
|
-
if (!roomClear) {
|
|
162
|
-
return false;
|
|
163
|
-
}
|
|
94
|
+
function getDefaultDestination(): [stage: LevelStage, stageType: StageType] {
|
|
95
|
+
const nextStage = getNextStage();
|
|
96
|
+
const nextStageType = getNextStageType();
|
|
164
97
|
|
|
165
|
-
|
|
166
|
-
// standing close to it, and open otherwise.
|
|
167
|
-
return defaultShouldOpenFunc(gridEntity);
|
|
98
|
+
return [nextStage, nextStageType];
|
|
168
99
|
}
|