isaacscript-common 6.10.1 → 6.11.1
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/postPlayerFatalDamage.lua +1 -1
- package/dist/callbacks/postPlayerInitFirst.d.ts +2 -0
- package/dist/callbacks/postPlayerInitFirst.d.ts.map +1 -0
- package/dist/callbacks/postPlayerInitFirst.lua +42 -0
- package/dist/callbacks/postPlayerInitLate.lua +5 -5
- package/dist/callbacks/postPlayerReorderedCallbacks.d.ts +2 -0
- package/dist/callbacks/postPlayerReorderedCallbacks.d.ts.map +1 -0
- package/dist/callbacks/{postPlayerReordered.lua → postPlayerReorderedCallbacks.lua} +11 -37
- package/dist/callbacks/subscriptions/{postPlayerInitReordered.d.ts → postPlayerInitFirst.d.ts} +2 -2
- package/dist/callbacks/subscriptions/postPlayerInitFirst.d.ts.map +1 -0
- package/dist/callbacks/subscriptions/{postPlayerInitReordered.lua → postPlayerInitFirst.lua} +3 -3
- package/dist/enums/ModCallbackCustom.d.ts +17 -15
- package/dist/enums/ModCallbackCustom.d.ts.map +1 -1
- package/dist/enums/ModCallbackCustom.lua +3 -3
- package/dist/enums/private/StageTravelState.d.ts +4 -0
- package/dist/enums/private/StageTravelState.d.ts.map +1 -0
- package/dist/enums/private/StageTravelState.lua +5 -0
- package/dist/features/customGridEntity.d.ts +2 -2
- package/dist/features/customGridEntity.d.ts.map +1 -1
- package/dist/features/customGridEntity.lua +14 -8
- package/dist/features/customStage/init.d.ts.map +1 -1
- package/dist/features/customStage/init.lua +8 -1
- package/dist/features/customStage/streakText.d.ts +6 -0
- package/dist/features/customStage/streakText.d.ts.map +1 -1
- package/dist/features/customStage/streakText.lua +16 -11
- package/dist/features/customStage/versusScreen.d.ts +6 -0
- package/dist/features/customStage/versusScreen.d.ts.map +1 -1
- package/dist/features/customStage/versusScreen.lua +10 -5
- package/dist/features/customTrapdoor/customTrapdoorConstants.d.ts +10 -0
- package/dist/features/customTrapdoor/customTrapdoorConstants.d.ts.map +1 -0
- package/dist/features/customTrapdoor/customTrapdoorConstants.lua +8 -0
- package/dist/features/customTrapdoor/exports.d.ts +37 -0
- package/dist/features/customTrapdoor/exports.d.ts.map +1 -0
- package/dist/features/customTrapdoor/exports.lua +127 -0
- package/dist/features/customTrapdoor/v.d.ts +4 -0
- package/dist/features/customTrapdoor/v.d.ts.map +1 -0
- package/dist/features/customTrapdoor/v.lua +15 -0
- package/dist/features/deployJSONRoom.d.ts.map +1 -1
- package/dist/features/deployJSONRoom.lua +1 -1
- package/dist/features/extraConsoleCommands/listCommands.lua +2 -2
- package/dist/functions/{character.d.ts → characters.d.ts} +3 -1
- package/dist/functions/characters.d.ts.map +1 -0
- package/dist/functions/{character.lua → characters.lua} +12 -0
- package/dist/functions/deepCopy.lua +20 -3
- package/dist/functions/deepCopyTests.d.ts.map +1 -1
- package/dist/functions/deepCopyTests.lua +55 -1
- package/dist/functions/jsonHelpers.d.ts +6 -0
- package/dist/functions/jsonHelpers.d.ts.map +1 -1
- package/dist/functions/jsonHelpers.lua +9 -3
- package/dist/functions/mergeTests.lua +0 -4
- package/dist/functions/playerIndex.d.ts +6 -2
- package/dist/functions/playerIndex.d.ts.map +1 -1
- package/dist/functions/playerIndex.lua +4 -2
- package/dist/functions/players.lua +4 -4
- package/dist/functions/revive.lua +2 -2
- package/dist/index.d.ts +3 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.lua +10 -2
- package/dist/initCustomCallbacks.d.ts.map +1 -1
- package/dist/initCustomCallbacks.lua +5 -2
- package/dist/initFeatures.d.ts +1 -2
- package/dist/initFeatures.d.ts.map +1 -1
- package/dist/initFeatures.lua +7 -2
- package/dist/interfaces/AddCallbackParameterCustom.d.ts +2 -2
- package/dist/interfaces/AddCallbackParameterCustom.d.ts.map +1 -1
- package/dist/interfaces/CustomGridEntityData.d.ts +1 -1
- package/dist/interfaces/CustomGridEntityData.d.ts.map +1 -1
- package/dist/interfaces/private/CustomTrapdoorDescription.d.ts +4 -0
- package/dist/interfaces/private/CustomTrapdoorDescription.d.ts.map +1 -0
- package/dist/interfaces/private/CustomTrapdoorDescription.lua +2 -0
- package/dist/lib/jsonLua.lua +390 -0
- package/dist/objects/callbackRegisterFunctions.d.ts.map +1 -1
- package/dist/objects/callbackRegisterFunctions.lua +3 -3
- package/dist/objects/characterDamageMultipliers.d.ts +6 -0
- package/dist/objects/characterDamageMultipliers.d.ts.map +1 -0
- package/dist/objects/characterDamageMultipliers.lua +49 -0
- package/dist/upgradeMod.d.ts.map +1 -1
- package/dist/upgradeMod.lua +2 -4
- package/package.json +2 -2
- package/src/callbacks/customRevive.ts +3 -3
- package/src/callbacks/itemPickup.ts +3 -3
- package/src/callbacks/postAmbush.ts +3 -3
- package/src/callbacks/postEsauJr.ts +3 -3
- package/src/callbacks/postFlip.ts +3 -3
- package/src/callbacks/postGridEntity.ts +5 -5
- package/src/callbacks/postPlayerCollectible.ts +2 -2
- package/src/callbacks/postPlayerFatalDamage.ts +5 -0
- package/src/callbacks/postPlayerInitFirst.ts +57 -0
- package/src/callbacks/postPlayerInitLate.ts +9 -5
- package/src/callbacks/{postPlayerReordered.ts → postPlayerReorderedCallbacks.ts} +9 -29
- package/src/callbacks/postSlotInitUpdate.ts +5 -2
- package/src/callbacks/postSlotRender.ts +2 -2
- package/src/callbacks/reorderedCallbacks.ts +1 -1
- package/src/callbacks/subscriptions/{postPlayerInitReordered.ts → postPlayerInitFirst.ts} +6 -6
- package/src/enums/ModCallbackCustom.ts +17 -15
- package/src/enums/private/StageTravelState.ts +4 -0
- package/src/features/customGridEntity.ts +29 -6
- package/src/features/customStage/init.ts +10 -1
- package/src/features/customStage/streakText.ts +13 -4
- package/src/features/customStage/versusScreen.ts +20 -12
- package/src/features/customTrapdoor/customTrapdoorConstants.ts +13 -0
- package/src/features/customTrapdoor/exports.ts +168 -0
- package/src/features/customTrapdoor/v.ts +20 -0
- package/src/features/deployJSONRoom.ts +5 -0
- package/src/features/extraConsoleCommands/listCommands.ts +1 -1
- package/src/functions/{character.ts → characters.ts} +13 -0
- package/src/functions/deepCopy.ts +18 -1
- package/src/functions/deepCopyTests.ts +112 -0
- package/src/functions/jsonHelpers.ts +9 -3
- package/src/functions/mergeTests.ts +0 -8
- package/src/functions/playerIndex.ts +6 -2
- package/src/functions/players.ts +1 -1
- package/src/functions/revive.ts +1 -1
- package/src/index.ts +6 -2
- package/src/initCustomCallbacks.ts +3 -1
- package/src/initFeatures.ts +7 -2
- package/src/interfaces/AddCallbackParameterCustom.ts +2 -2
- package/src/interfaces/CustomGridEntityData.ts +1 -1
- package/src/interfaces/private/CustomTrapdoorDescription.ts +3 -0
- package/src/lib/jsonLua.d.ts +10 -0
- package/src/lib/jsonLua.lua +390 -0
- package/src/objects/callbackRegisterFunctions.ts +2 -3
- package/src/objects/characterDamageMultipliers.ts +49 -0
- package/src/upgradeMod.ts +2 -3
- package/dist/callbacks/postPlayerReordered.d.ts +0 -2
- package/dist/callbacks/postPlayerReordered.d.ts.map +0 -1
- package/dist/callbacks/subscriptions/postPlayerInitReordered.d.ts.map +0 -1
- package/dist/functions/character.d.ts.map +0 -1
|
@@ -66,30 +66,38 @@ const PLAYER_PORTRAIT_PNG_PATH_PREFIX = "gfx/ui/stage";
|
|
|
66
66
|
const VANILLA_VERSUS_PLAYBACK_SPEED = 0.5;
|
|
67
67
|
|
|
68
68
|
const versusScreenSprite = Sprite();
|
|
69
|
-
versusScreenSprite.Load("gfx/ui/boss/versusscreen.anm2", false);
|
|
70
|
-
|
|
71
|
-
// In vanilla, the "overlay.png" file has a white background. We must convert it to a PNG that uses
|
|
72
|
-
// a transparent background in order for the background behind it to be visible. We use the same
|
|
73
|
-
// "overlay.png" file as StageAPI uses for this purpose.
|
|
74
|
-
versusScreenSprite.ReplaceSpritesheet(
|
|
75
|
-
OVERLAY_ANM2_LAYER,
|
|
76
|
-
`${ISAACSCRIPT_CUSTOM_STAGE_GFX_PATH}/overlay.png`,
|
|
77
|
-
);
|
|
78
|
-
versusScreenSprite.LoadGraphics();
|
|
79
69
|
|
|
80
70
|
/**
|
|
81
71
|
* Unfortunately, we must split the background layer into an entirely different sprite so that we
|
|
82
72
|
* can color it with the `Color` property.
|
|
83
73
|
*/
|
|
84
74
|
const versusScreenBackgroundSprite = Sprite();
|
|
85
|
-
versusScreenBackgroundSprite.Load("gfx/ui/boss/versusscreen.anm2", true);
|
|
86
75
|
|
|
87
76
|
/**
|
|
88
77
|
* Unfortunately, we must split the dirt layer into an entirely different sprite so that we can
|
|
89
78
|
* color it with the `Color` property.
|
|
90
79
|
*/
|
|
91
80
|
const versusScreenDirtSpotSprite = Sprite();
|
|
92
|
-
|
|
81
|
+
|
|
82
|
+
/**
|
|
83
|
+
* We must load the sprites in an init function to prevent issues with mods that replace the vanilla
|
|
84
|
+
* files. (For some reason, loading the sprites will cause the overwrite to no longer apply on the
|
|
85
|
+
* second and subsequent runs.)
|
|
86
|
+
*/
|
|
87
|
+
export function versusScreenInit(): void {
|
|
88
|
+
// In vanilla, the "overlay.png" file has a white background. We must convert it to a PNG that
|
|
89
|
+
// uses a transparent background in order for the background behind it to be visible. We use the
|
|
90
|
+
// same "overlay.png" file as StageAPI uses for this purpose.
|
|
91
|
+
versusScreenSprite.Load("gfx/ui/boss/versusscreen.anm2", false);
|
|
92
|
+
versusScreenSprite.ReplaceSpritesheet(
|
|
93
|
+
OVERLAY_ANM2_LAYER,
|
|
94
|
+
`${ISAACSCRIPT_CUSTOM_STAGE_GFX_PATH}/overlay.png`,
|
|
95
|
+
);
|
|
96
|
+
versusScreenSprite.LoadGraphics();
|
|
97
|
+
|
|
98
|
+
versusScreenBackgroundSprite.Load("gfx/ui/boss/versusscreen.anm2", true);
|
|
99
|
+
versusScreenDirtSpotSprite.Load("gfx/ui/boss/versusscreen.anm2", true);
|
|
100
|
+
}
|
|
93
101
|
|
|
94
102
|
export function playVersusScreenAnimation(customStage: CustomStage): void {
|
|
95
103
|
const room = game.GetRoom();
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { GridEntityType } from "isaac-typescript-definitions";
|
|
2
|
+
|
|
3
|
+
export const CUSTOM_TRAPDOOR_FEATURE_NAME = "customTrapdoor";
|
|
4
|
+
|
|
5
|
+
/** This also applies to crawl spaces. The value was determined through trial and error. */
|
|
6
|
+
export const TRAPDOOR_OPEN_DISTANCE = 60;
|
|
7
|
+
|
|
8
|
+
export const TRAPDOOR_OPEN_DISTANCE_AFTER_BOSS = TRAPDOOR_OPEN_DISTANCE * 2.5;
|
|
9
|
+
export const TRAPDOOR_BOSS_REACTION_FRAMES = 30;
|
|
10
|
+
|
|
11
|
+
export const GridEntityTypeCustom = {
|
|
12
|
+
TRAPDOOR_CUSTOM: 1000 as GridEntityType,
|
|
13
|
+
} as const;
|
|
@@ -0,0 +1,168 @@
|
|
|
1
|
+
import {
|
|
2
|
+
GridCollisionClass,
|
|
3
|
+
LevelStage,
|
|
4
|
+
RoomType,
|
|
5
|
+
StageType,
|
|
6
|
+
} from "isaac-typescript-definitions";
|
|
7
|
+
import { game } from "../../cachedClasses";
|
|
8
|
+
import { errorIfFeaturesNotInitialized } from "../../featuresInitialized";
|
|
9
|
+
import { getNextStage, getNextStageType } from "../../functions/nextStage";
|
|
10
|
+
import { anyPlayerCloserThan } from "../../functions/positionVelocity";
|
|
11
|
+
import { spawnCustomGridEntity } from "../customGridEntity";
|
|
12
|
+
import { getRoomClearGameFrame } from "../roomClearFrame";
|
|
13
|
+
import {
|
|
14
|
+
CUSTOM_TRAPDOOR_FEATURE_NAME,
|
|
15
|
+
GridEntityTypeCustom,
|
|
16
|
+
TRAPDOOR_BOSS_REACTION_FRAMES,
|
|
17
|
+
TRAPDOOR_OPEN_DISTANCE,
|
|
18
|
+
TRAPDOOR_OPEN_DISTANCE_AFTER_BOSS,
|
|
19
|
+
} from "./customTrapdoorConstants";
|
|
20
|
+
import { getCustomTrapdoorDescription } from "./v";
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* Helper function to spawn a trapdoor grid entity that will have one or more of the following
|
|
24
|
+
* attributes:
|
|
25
|
+
*
|
|
26
|
+
* - custom destination (or custom logic for after the player enters)
|
|
27
|
+
* - custom graphics
|
|
28
|
+
* - custom logic for opening/closing
|
|
29
|
+
* - TODO: animation
|
|
30
|
+
*
|
|
31
|
+
* You can use this function to take the player to your custom stage.
|
|
32
|
+
*
|
|
33
|
+
* Under the hood, the custom trapdoor is represented by a decoration grid entity and is manually
|
|
34
|
+
* respawned every time the player re-enters the room.
|
|
35
|
+
*
|
|
36
|
+
* @param gridIndexOrPosition The location in the room to spawn the trapdoor.
|
|
37
|
+
* @param _destination Used to specify where the player will go after jumping into the trapdoor. Can
|
|
38
|
+
* either be a tuple containing the stage and stage type, a string containing
|
|
39
|
+
* the name of a custom stage, or undefined. If undefined, nothing will happen
|
|
40
|
+
* after the player jumps in the trapdoor. (Use undefined to perform some custom
|
|
41
|
+
* behavior and/or handle the traveling part yourself.) You can also specify a
|
|
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.
|
|
44
|
+
* @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
|
+
* @param _shouldOpenFunc Optional. If the trapdoor is currently closed, this function will run on
|
|
47
|
+
* every frame to determine if it should open. By default, a function that
|
|
48
|
+
* emulates a vanilla trapdoor will be used.
|
|
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.
|
|
55
|
+
*/
|
|
56
|
+
export function spawnCustomTrapdoor(
|
|
57
|
+
gridIndexOrPosition: int | Vector,
|
|
58
|
+
_destination:
|
|
59
|
+
| [stage: LevelStage, stageType: StageType]
|
|
60
|
+
| string
|
|
61
|
+
| ((
|
|
62
|
+
gridEntity: GridEntity,
|
|
63
|
+
) =>
|
|
64
|
+
| [stage: LevelStage, stageType: StageType]
|
|
65
|
+
| string
|
|
66
|
+
| undefined) = defaultDestinationFunc,
|
|
67
|
+
anm2Path = "gfx/grid/door_11_trapdoor.anm2",
|
|
68
|
+
_shouldOpenFunc: (gridEntity: GridEntity) => boolean = defaultShouldOpenFunc,
|
|
69
|
+
_shouldCloseFunc: (
|
|
70
|
+
gridEntity: GridEntity,
|
|
71
|
+
) => boolean = defaultShouldCloseFunc,
|
|
72
|
+
_spawnOpen:
|
|
73
|
+
| boolean
|
|
74
|
+
| ((gridEntity: GridEntity) => boolean) = defaultShouldSpawnOpenFunc,
|
|
75
|
+
): GridEntity {
|
|
76
|
+
errorIfFeaturesNotInitialized(CUSTOM_TRAPDOOR_FEATURE_NAME);
|
|
77
|
+
|
|
78
|
+
// TODO
|
|
79
|
+
return spawnCustomGridEntity(
|
|
80
|
+
GridEntityTypeCustom.TRAPDOOR_CUSTOM,
|
|
81
|
+
gridIndexOrPosition,
|
|
82
|
+
anm2Path,
|
|
83
|
+
"Closed",
|
|
84
|
+
GridCollisionClass.NONE,
|
|
85
|
+
);
|
|
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
|
+
|
|
114
|
+
function isPlayerCloseAfterBoss(position: Vector) {
|
|
115
|
+
const gameFrameCount = game.GetFrameCount();
|
|
116
|
+
const room = game.GetRoom();
|
|
117
|
+
const roomType = room.GetType();
|
|
118
|
+
const roomClearGameFrame = getRoomClearGameFrame();
|
|
119
|
+
|
|
120
|
+
// In order to prevent a player from accidentally entering a freshly-spawned trapdoor after
|
|
121
|
+
// killing the boss of the floor, we use a wider open distance for a short amount of frames.
|
|
122
|
+
if (
|
|
123
|
+
roomType !== RoomType.BOSS ||
|
|
124
|
+
roomClearGameFrame === undefined ||
|
|
125
|
+
gameFrameCount >= roomClearGameFrame + TRAPDOOR_BOSS_REACTION_FRAMES
|
|
126
|
+
) {
|
|
127
|
+
return false;
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
return anyPlayerCloserThan(position, TRAPDOOR_OPEN_DISTANCE_AFTER_BOSS);
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
function shouldBeClosedFromStartingInRoomWithEnemies(
|
|
134
|
+
firstSpawn: boolean,
|
|
135
|
+
roomClear: boolean,
|
|
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
|
+
}
|
|
164
|
+
|
|
165
|
+
// If we just entered a new room that is already cleared, spawn the trapdoor closed if we are
|
|
166
|
+
// standing close to it, and open otherwise.
|
|
167
|
+
return defaultShouldOpenFunc(gridEntity);
|
|
168
|
+
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { StageTravelState } from "../../enums/private/StageTravelState";
|
|
2
|
+
import { CustomTrapdoorDescription } from "../../interfaces/private/CustomTrapdoorDescription";
|
|
3
|
+
|
|
4
|
+
const v = {
|
|
5
|
+
run: {
|
|
6
|
+
state: StageTravelState.NONE,
|
|
7
|
+
},
|
|
8
|
+
|
|
9
|
+
room: {
|
|
10
|
+
/** Indexed by grid index. */
|
|
11
|
+
trapdoors: new Map<int, CustomTrapdoorDescription>(),
|
|
12
|
+
},
|
|
13
|
+
};
|
|
14
|
+
|
|
15
|
+
export function getCustomTrapdoorDescription(
|
|
16
|
+
gridEntity: GridEntity,
|
|
17
|
+
): CustomTrapdoorDescription | undefined {
|
|
18
|
+
const gridIndex = gridEntity.GetGridIndex();
|
|
19
|
+
return v.room.trapdoors.get(gridIndex);
|
|
20
|
+
}
|
|
@@ -4,6 +4,7 @@
|
|
|
4
4
|
// it from scratch based on the JSON data.
|
|
5
5
|
|
|
6
6
|
import {
|
|
7
|
+
ActiveSlot,
|
|
7
8
|
CollectibleType,
|
|
8
9
|
EffectVariant,
|
|
9
10
|
EntityCollisionClass,
|
|
@@ -16,6 +17,7 @@ import {
|
|
|
16
17
|
PickupVariant,
|
|
17
18
|
PitfallVariant,
|
|
18
19
|
RoomType,
|
|
20
|
+
UseFlag,
|
|
19
21
|
} from "isaac-typescript-definitions";
|
|
20
22
|
import { game } from "../cachedClasses";
|
|
21
23
|
import { DefaultMap } from "../classes/DefaultMap";
|
|
@@ -113,6 +115,9 @@ function preUseItemWeNeedToGoDeeper(
|
|
|
113
115
|
_collectibleType: CollectibleType,
|
|
114
116
|
_rng: RNG,
|
|
115
117
|
player: EntityPlayer,
|
|
118
|
+
_useFlags: BitFlags<UseFlag>,
|
|
119
|
+
_activeSlot: ActiveSlot,
|
|
120
|
+
_customVarData: int,
|
|
116
121
|
): boolean | undefined {
|
|
117
122
|
if (v.room.manuallyUsingShovel) {
|
|
118
123
|
return undefined;
|
|
@@ -50,7 +50,7 @@ import {
|
|
|
50
50
|
} from "../../constantsFirstLast";
|
|
51
51
|
import { HealthType } from "../../enums/HealthType";
|
|
52
52
|
import { getCardName } from "../../functions/cards";
|
|
53
|
-
import { getCharacterName } from "../../functions/
|
|
53
|
+
import { getCharacterName } from "../../functions/characters";
|
|
54
54
|
import { addCharge } from "../../functions/charge";
|
|
55
55
|
import { isValidCollectibleType } from "../../functions/collectibles";
|
|
56
56
|
import { runDeepCopyTests } from "../../functions/deepCopyTests";
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { PlayerType } from "isaac-typescript-definitions";
|
|
2
2
|
import { LAST_VANILLA_CHARACTER } from "../constantsFirstLast";
|
|
3
|
+
import { CHARACTER_DAMAGE_MULTIPLIERS } from "../objects/characterDamageMultipliers";
|
|
3
4
|
import { CHARACTER_NAMES } from "../objects/characterNames";
|
|
4
5
|
import { CHARACTERS_THAT_START_WITH_AN_ACTIVE_ITEM_SET } from "../sets/charactersThatStartWithAnActiveItemSet";
|
|
5
6
|
import { CHARACTERS_WITH_BLACK_HEART_FROM_ETERNAL_HEART_SET } from "../sets/charactersWithBlackHeartFromEternalHeartSet";
|
|
@@ -56,6 +57,18 @@ export function characterStartsWithActiveItem(character: PlayerType): boolean {
|
|
|
56
57
|
return CHARACTERS_THAT_START_WITH_AN_ACTIVE_ITEM_SET.has(character);
|
|
57
58
|
}
|
|
58
59
|
|
|
60
|
+
/** Helper function to get the numerical damage multiplier for a character. */
|
|
61
|
+
export function getCharacterDamageMultiplier(
|
|
62
|
+
character: PlayerType,
|
|
63
|
+
hasWhoreOfBabylon = false,
|
|
64
|
+
): float {
|
|
65
|
+
if (character === PlayerType.EVE && hasWhoreOfBabylon) {
|
|
66
|
+
return 1.0;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
return CHARACTER_DAMAGE_MULTIPLIERS[character];
|
|
70
|
+
}
|
|
71
|
+
|
|
59
72
|
/**
|
|
60
73
|
* - Most characters have a 56 frame death animation (i.e. the "Death" animation).
|
|
61
74
|
* - The Lost and Tainted Lost have a 38 frame death animation (i.e. the "LostDeath" animation).
|
|
@@ -568,6 +568,14 @@ function getCopiedEntries(
|
|
|
568
568
|
entries.sort(twoDimensionalSort);
|
|
569
569
|
}
|
|
570
570
|
|
|
571
|
+
// During serialization, we brand some Lua tables with a special identifier to signify that it has
|
|
572
|
+
// keys that should be deserialized to numbers.
|
|
573
|
+
const convertStringKeysToNumbers =
|
|
574
|
+
serializationType === SerializationType.DESERIALIZE &&
|
|
575
|
+
entries.some(
|
|
576
|
+
([key]) => key === (SerializationBrand.OBJECT_WITH_NUMBER_KEYS as string),
|
|
577
|
+
);
|
|
578
|
+
|
|
571
579
|
const hasNumberKeys = entries.some(([key]) => isNumber(key));
|
|
572
580
|
const convertNumberKeysToStrings =
|
|
573
581
|
serializationType === SerializationType.SERIALIZE && hasNumberKeys;
|
|
@@ -589,7 +597,16 @@ function getCopiedEntries(
|
|
|
589
597
|
insideMap,
|
|
590
598
|
);
|
|
591
599
|
|
|
592
|
-
|
|
600
|
+
let keyToUse = key;
|
|
601
|
+
if (convertStringKeysToNumbers) {
|
|
602
|
+
const numberKey = tonumber(key);
|
|
603
|
+
if (numberKey !== undefined) {
|
|
604
|
+
keyToUse = numberKey;
|
|
605
|
+
}
|
|
606
|
+
}
|
|
607
|
+
if (convertNumberKeysToStrings) {
|
|
608
|
+
keyToUse = tostring(key);
|
|
609
|
+
}
|
|
593
610
|
copiedEntries.push([keyToUse, newValue]);
|
|
594
611
|
}
|
|
595
612
|
|
|
@@ -32,6 +32,12 @@ export function runDeepCopyTests(): void {
|
|
|
32
32
|
copiedDefaultMapHasChildDefaultMap();
|
|
33
33
|
copiedDefaultMapHasBrand();
|
|
34
34
|
|
|
35
|
+
copiedSerializedMapHasStringKey();
|
|
36
|
+
copiedSerializedMapHasNumberKey();
|
|
37
|
+
|
|
38
|
+
copiedSerializedDefaultMapHasStringKey();
|
|
39
|
+
copiedSerializedDefaultMapHasNumberKey();
|
|
40
|
+
|
|
35
41
|
log("All deep copy tests passed!");
|
|
36
42
|
}
|
|
37
43
|
|
|
@@ -457,3 +463,109 @@ function copiedDefaultMapHasBrand() {
|
|
|
457
463
|
);
|
|
458
464
|
}
|
|
459
465
|
}
|
|
466
|
+
|
|
467
|
+
function copiedSerializedMapHasStringKey() {
|
|
468
|
+
const mapKey = "123";
|
|
469
|
+
const mapValue = 456;
|
|
470
|
+
const oldMap = new Map<string, number>();
|
|
471
|
+
oldMap.set(mapKey, mapValue);
|
|
472
|
+
|
|
473
|
+
const serializedOldMap = deepCopy(
|
|
474
|
+
oldMap,
|
|
475
|
+
SerializationType.SERIALIZE,
|
|
476
|
+
"copiedSerializedMapHasStringKey-serialize",
|
|
477
|
+
);
|
|
478
|
+
|
|
479
|
+
const newTable = deepCopy(
|
|
480
|
+
serializedOldMap,
|
|
481
|
+
SerializationType.DESERIALIZE,
|
|
482
|
+
"copiedSerializedMapHasStringKey-deserialize",
|
|
483
|
+
);
|
|
484
|
+
|
|
485
|
+
const newMap = newTable as Map<string, number>;
|
|
486
|
+
if (!newMap.has(mapKey)) {
|
|
487
|
+
const keyType = type(mapKey);
|
|
488
|
+
error(
|
|
489
|
+
`The copied Map did not have a key of: ${mapKey} with type ${keyType}`,
|
|
490
|
+
);
|
|
491
|
+
}
|
|
492
|
+
}
|
|
493
|
+
|
|
494
|
+
function copiedSerializedMapHasNumberKey() {
|
|
495
|
+
const mapKey = 123;
|
|
496
|
+
const mapValue = 456;
|
|
497
|
+
const oldMap = new Map<number, number>();
|
|
498
|
+
oldMap.set(mapKey, mapValue);
|
|
499
|
+
|
|
500
|
+
const serializedOldMap = deepCopy(
|
|
501
|
+
oldMap,
|
|
502
|
+
SerializationType.SERIALIZE,
|
|
503
|
+
"copiedSerializedMapHasNumberKey-serialize",
|
|
504
|
+
);
|
|
505
|
+
|
|
506
|
+
const newTable = deepCopy(
|
|
507
|
+
serializedOldMap,
|
|
508
|
+
SerializationType.DESERIALIZE,
|
|
509
|
+
"copiedSerializedMapHasNumberKey-deserialize",
|
|
510
|
+
);
|
|
511
|
+
|
|
512
|
+
const newMap = newTable as Map<number, number>;
|
|
513
|
+
if (!newMap.has(mapKey)) {
|
|
514
|
+
const keyType = type(mapKey);
|
|
515
|
+
error(
|
|
516
|
+
`The copied Map did not have a key of: ${mapKey} with type ${keyType}`,
|
|
517
|
+
);
|
|
518
|
+
}
|
|
519
|
+
}
|
|
520
|
+
|
|
521
|
+
function copiedSerializedDefaultMapHasStringKey() {
|
|
522
|
+
const mapKey = "123";
|
|
523
|
+
const oldDefaultMap = new DefaultMap<string, number>(456);
|
|
524
|
+
oldDefaultMap.getAndSetDefault(mapKey);
|
|
525
|
+
|
|
526
|
+
const serializedOldDefaultMap = deepCopy(
|
|
527
|
+
oldDefaultMap,
|
|
528
|
+
SerializationType.SERIALIZE,
|
|
529
|
+
"copiedSerializedDefaultMapHasStringKey-serialize",
|
|
530
|
+
);
|
|
531
|
+
|
|
532
|
+
const newTable = deepCopy(
|
|
533
|
+
serializedOldDefaultMap,
|
|
534
|
+
SerializationType.DESERIALIZE,
|
|
535
|
+
"copiedSerializedDefaultMapHasStringKey-deserialize",
|
|
536
|
+
);
|
|
537
|
+
|
|
538
|
+
const newDefaultMap = newTable as DefaultMap<string, number>;
|
|
539
|
+
if (!newDefaultMap.has(mapKey)) {
|
|
540
|
+
const keyType = type(mapKey);
|
|
541
|
+
error(
|
|
542
|
+
`The copied DefaultMap did not have a key of "${mapKey}" with type: ${keyType}`,
|
|
543
|
+
);
|
|
544
|
+
}
|
|
545
|
+
}
|
|
546
|
+
|
|
547
|
+
function copiedSerializedDefaultMapHasNumberKey() {
|
|
548
|
+
const mapKey = 123;
|
|
549
|
+
const oldDefaultMap = new DefaultMap<number, number>(456);
|
|
550
|
+
oldDefaultMap.getAndSetDefault(mapKey);
|
|
551
|
+
|
|
552
|
+
const serializedOldDefaultMap = deepCopy(
|
|
553
|
+
oldDefaultMap,
|
|
554
|
+
SerializationType.SERIALIZE,
|
|
555
|
+
"copiedSerializedDefaultMapHasNumberKey-serialize",
|
|
556
|
+
);
|
|
557
|
+
|
|
558
|
+
const newTable = deepCopy(
|
|
559
|
+
serializedOldDefaultMap,
|
|
560
|
+
SerializationType.DESERIALIZE,
|
|
561
|
+
"copiedSerializedDefaultMapHasNumberKey-deserialize",
|
|
562
|
+
);
|
|
563
|
+
|
|
564
|
+
const newDefaultMap = newTable as DefaultMap<number, number>;
|
|
565
|
+
if (!newDefaultMap.has(mapKey)) {
|
|
566
|
+
const keyType = type(mapKey);
|
|
567
|
+
error(
|
|
568
|
+
`The copied DefaultMap did not have a key of: ${mapKey} with type ${keyType}`,
|
|
569
|
+
);
|
|
570
|
+
}
|
|
571
|
+
}
|
|
@@ -1,12 +1,12 @@
|
|
|
1
|
-
import * as
|
|
1
|
+
import * as jsonLua from "../lib/jsonLua";
|
|
2
2
|
import { logError } from "./log";
|
|
3
3
|
|
|
4
4
|
function tryDecode(this: void, jsonString: string) {
|
|
5
|
-
return
|
|
5
|
+
return jsonLua.decode(jsonString) as LuaMap;
|
|
6
6
|
}
|
|
7
7
|
|
|
8
8
|
function tryEncode(this: void, luaTable: unknown) {
|
|
9
|
-
return
|
|
9
|
+
return jsonLua.encode(luaTable);
|
|
10
10
|
}
|
|
11
11
|
|
|
12
12
|
/**
|
|
@@ -16,6 +16,9 @@ function tryEncode(this: void, luaTable: unknown) {
|
|
|
16
16
|
* fails, it will return a blank Lua table instead of throwing an error. (This allows execution to
|
|
17
17
|
* continue in cases where users have no current save data or have manually removed their existing
|
|
18
18
|
* save data.)
|
|
19
|
+
*
|
|
20
|
+
* Under the hood, this uses a custom JSON parser that was measured to be 11.8 times faster than the
|
|
21
|
+
* vanilla JSON parser.
|
|
19
22
|
*/
|
|
20
23
|
export function jsonDecode(jsonString: string): LuaMap<AnyNotNil, unknown> {
|
|
21
24
|
const [ok, luaTableOrErrMsg] = pcall(tryDecode, jsonString);
|
|
@@ -34,6 +37,9 @@ export function jsonDecode(jsonString: string): LuaMap<AnyNotNil, unknown> {
|
|
|
34
37
|
* In most cases, this function will be used for writing data to a "save#.dat" file. If encoding
|
|
35
38
|
* fails, it will throw an error to prevent writing a blank string or corrupted data to a user's
|
|
36
39
|
* "save#.dat" file.
|
|
40
|
+
*
|
|
41
|
+
* Under the hood, this uses a custom JSON parser that was measured to be 11.8 times faster than the
|
|
42
|
+
* vanilla JSON parser.
|
|
37
43
|
*/
|
|
38
44
|
export function jsonEncode(luaTable: unknown): string {
|
|
39
45
|
const [ok, jsonStringOrErrMsg] = pcall(tryEncode, luaTable);
|
|
@@ -266,8 +266,6 @@ function oldTableHasFilledDefaultMap() {
|
|
|
266
266
|
}
|
|
267
267
|
|
|
268
268
|
function oldTableHasVector() {
|
|
269
|
-
log("Starting test: oldTableHasVector");
|
|
270
|
-
|
|
271
269
|
interface Foo {
|
|
272
270
|
bar: Vector;
|
|
273
271
|
}
|
|
@@ -307,8 +305,6 @@ function oldTableHasVector() {
|
|
|
307
305
|
}
|
|
308
306
|
|
|
309
307
|
function oldTableHasVectorSerialized() {
|
|
310
|
-
log("Starting test: oldTableHasVectorSerialized");
|
|
311
|
-
|
|
312
308
|
interface Foo {
|
|
313
309
|
bar: Vector;
|
|
314
310
|
}
|
|
@@ -355,8 +351,6 @@ function oldTableHasVectorSerialized() {
|
|
|
355
351
|
}
|
|
356
352
|
|
|
357
353
|
function oldTableHasRNG() {
|
|
358
|
-
log("Starting test: oldTableHasRNG");
|
|
359
|
-
|
|
360
354
|
interface Foo {
|
|
361
355
|
bar: RNG;
|
|
362
356
|
}
|
|
@@ -392,8 +386,6 @@ function oldTableHasRNG() {
|
|
|
392
386
|
}
|
|
393
387
|
|
|
394
388
|
function oldTableHasRNGSerialized() {
|
|
395
|
-
log("Starting test: oldTableHasRNGSerialized");
|
|
396
|
-
|
|
397
389
|
interface Foo {
|
|
398
390
|
bar: RNG;
|
|
399
391
|
}
|
|
@@ -28,6 +28,10 @@ export function getAllPlayers(): EntityPlayer[] {
|
|
|
28
28
|
return players;
|
|
29
29
|
}
|
|
30
30
|
|
|
31
|
+
/**
|
|
32
|
+
* Helper function to get the corresponding `EntityPlayer` object that corresponds to a
|
|
33
|
+
* `PlayerIndex`.
|
|
34
|
+
*/
|
|
31
35
|
export function getPlayerFromIndex(
|
|
32
36
|
playerIndex: PlayerIndex,
|
|
33
37
|
): EntityPlayer | undefined {
|
|
@@ -194,8 +198,8 @@ export function getSubPlayerParent(
|
|
|
194
198
|
}
|
|
195
199
|
|
|
196
200
|
/**
|
|
197
|
-
*
|
|
198
|
-
* example, the Strawman Keeper.)
|
|
201
|
+
* Helper function to detect if a particular player is a "child" player, meaning that they have a
|
|
202
|
+
* non-undefined `EntityPlayer.Parent` property. (For example, the Strawman Keeper.)
|
|
199
203
|
*/
|
|
200
204
|
export function isChildPlayer(player: EntityPlayer): boolean {
|
|
201
205
|
return player.Parent !== undefined;
|
package/src/functions/players.ts
CHANGED
|
@@ -17,7 +17,7 @@ import {
|
|
|
17
17
|
getCharacterMaxHeartContainers,
|
|
18
18
|
getCharacterName,
|
|
19
19
|
isVanillaCharacter,
|
|
20
|
-
} from "./
|
|
20
|
+
} from "./characters";
|
|
21
21
|
import { getCollectibleMaxCharges } from "./collectibles";
|
|
22
22
|
import { getCollectibleArray } from "./collectibleSet";
|
|
23
23
|
import { getEnumValues } from "./enums";
|
package/src/functions/revive.ts
CHANGED
|
@@ -10,7 +10,7 @@ import {
|
|
|
10
10
|
MAX_TAINTED_SAMSON_BERSERK_CHARGE,
|
|
11
11
|
TAINTED_SAMSON_BERSERK_CHARGE_FROM_TAKING_DAMAGE,
|
|
12
12
|
} from "../constants";
|
|
13
|
-
import { getCharacterDeathAnimationName } from "./
|
|
13
|
+
import { getCharacterDeathAnimationName } from "./characters";
|
|
14
14
|
import {
|
|
15
15
|
getPlayerMaxHeartContainers,
|
|
16
16
|
getPlayerNumHitsRemaining,
|
package/src/index.ts
CHANGED
|
@@ -22,8 +22,12 @@ export {
|
|
|
22
22
|
} from "./features/characterHealthConversion";
|
|
23
23
|
export { registerCharacterStats } from "./features/characterStats";
|
|
24
24
|
export { getCollectibleItemPoolType } from "./features/collectibleItemPoolType";
|
|
25
|
-
export {
|
|
25
|
+
export {
|
|
26
|
+
removeCustomGrid,
|
|
27
|
+
spawnCustomGridEntity as spawnCustomGrid,
|
|
28
|
+
} from "./features/customGridEntity";
|
|
26
29
|
export * from "./features/customStage/exports";
|
|
30
|
+
export * from "./features/customTrapdoor/exports";
|
|
27
31
|
export * from "./features/debugDisplay/exports";
|
|
28
32
|
export {
|
|
29
33
|
deployJSONRoom,
|
|
@@ -82,7 +86,7 @@ export * from "./functions/bosses";
|
|
|
82
86
|
export * from "./functions/cacheFlag";
|
|
83
87
|
export * from "./functions/cards";
|
|
84
88
|
export * from "./functions/challenges";
|
|
85
|
-
export * from "./functions/
|
|
89
|
+
export * from "./functions/characters";
|
|
86
90
|
export * from "./functions/charge";
|
|
87
91
|
export * from "./functions/chargeBar";
|
|
88
92
|
export * from "./functions/collectibleCacheFlag";
|
|
@@ -37,8 +37,9 @@ import { postPlayerChangeHealthInit } from "./callbacks/postPlayerChangeHealth";
|
|
|
37
37
|
import { postPlayerChangeTypeInit } from "./callbacks/postPlayerChangeType";
|
|
38
38
|
import { postPlayerCollectibleCallbacksInit } from "./callbacks/postPlayerCollectible";
|
|
39
39
|
import { postPlayerFatalDamageInit } from "./callbacks/postPlayerFatalDamage";
|
|
40
|
+
import { postPlayerInitFirstInit } from "./callbacks/postPlayerInitFirst";
|
|
40
41
|
import { postPlayerInitLateInit } from "./callbacks/postPlayerInitLate";
|
|
41
|
-
import { postPlayerReorderedCallbacksInit } from "./callbacks/
|
|
42
|
+
import { postPlayerReorderedCallbacksInit } from "./callbacks/postPlayerReorderedCallbacks";
|
|
42
43
|
import { postPoopRenderInit } from "./callbacks/postPoopRender";
|
|
43
44
|
import { postPoopUpdateInit } from "./callbacks/postPoopUpdate";
|
|
44
45
|
import { postPressurePlateRenderInit } from "./callbacks/postPressurePlateRender";
|
|
@@ -105,6 +106,7 @@ export function initCustomCallbacks(mod: ModUpgraded): void {
|
|
|
105
106
|
postPlayerChangeTypeInit(mod);
|
|
106
107
|
postPlayerCollectibleCallbacksInit(mod);
|
|
107
108
|
postPlayerFatalDamageInit(mod);
|
|
109
|
+
postPlayerInitFirstInit(mod);
|
|
108
110
|
postPlayerInitLateInit(mod);
|
|
109
111
|
postPlayerReorderedCallbacksInit(mod);
|
|
110
112
|
postPoopRenderInit(mod);
|
package/src/initFeatures.ts
CHANGED
|
@@ -23,7 +23,12 @@ import { sirenHelpersInit } from "./features/sirenHelpers";
|
|
|
23
23
|
import { stageHistoryInit } from "./features/stageHistory";
|
|
24
24
|
import { taintedLazarusPlayersInit } from "./features/taintedLazarusPlayers";
|
|
25
25
|
|
|
26
|
-
export function
|
|
26
|
+
export function initFeatures(mod: ModUpgraded): void {
|
|
27
|
+
initFeaturesMajor(mod);
|
|
28
|
+
initFeaturesMinor(mod);
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
function initFeaturesMajor(mod: ModUpgraded) {
|
|
27
32
|
customStageInit(mod);
|
|
28
33
|
deployJSONRoomInit(mod);
|
|
29
34
|
runInNFramesInit(mod);
|
|
@@ -32,7 +37,7 @@ export function initFeaturesMajor(mod: ModUpgraded): void {
|
|
|
32
37
|
customGridEntityInit(mod);
|
|
33
38
|
}
|
|
34
39
|
|
|
35
|
-
|
|
40
|
+
function initFeaturesMinor(mod: ModUpgraded) {
|
|
36
41
|
disableAllSoundInit(mod);
|
|
37
42
|
disableInputsInit(mod);
|
|
38
43
|
fadeInRemoverInit(mod);
|
|
@@ -50,8 +50,8 @@ import { PostPlayerChangeTypeRegisterParameters } from "../callbacks/subscriptio
|
|
|
50
50
|
import { PostPlayerCollectibleAddedRegisterParameters } from "../callbacks/subscriptions/postPlayerCollectibleAdded";
|
|
51
51
|
import { PostPlayerCollectibleRemovedRegisterParameters } from "../callbacks/subscriptions/postPlayerCollectibleRemoved";
|
|
52
52
|
import { PostPlayerFatalDamageRegisterParameters } from "../callbacks/subscriptions/postPlayerFatalDamage";
|
|
53
|
+
import { PostPlayerInitFirstRegisterParameters } from "../callbacks/subscriptions/postPlayerInitFirst";
|
|
53
54
|
import { PostPlayerInitLateRegisterParameters } from "../callbacks/subscriptions/postPlayerInitLate";
|
|
54
|
-
import { PostPlayerInitReorderedRegisterParameters } from "../callbacks/subscriptions/postPlayerInitReordered";
|
|
55
55
|
import { PostPlayerRenderReorderedRegisterParameters } from "../callbacks/subscriptions/postPlayerRenderReordered";
|
|
56
56
|
import { PostPlayerUpdateReorderedRegisterParameters } from "../callbacks/subscriptions/postPlayerUpdateReordered";
|
|
57
57
|
import { PostPoopRenderRegisterParameters } from "../callbacks/subscriptions/postPoopRender";
|
|
@@ -136,8 +136,8 @@ export interface AddCallbackParameterCustom {
|
|
|
136
136
|
[ModCallbackCustom.POST_PLAYER_COLLECTIBLE_ADDED]: PostPlayerCollectibleAddedRegisterParameters;
|
|
137
137
|
[ModCallbackCustom.POST_PLAYER_COLLECTIBLE_REMOVED]: PostPlayerCollectibleRemovedRegisterParameters;
|
|
138
138
|
[ModCallbackCustom.POST_PLAYER_FATAL_DAMAGE]: PostPlayerFatalDamageRegisterParameters;
|
|
139
|
+
[ModCallbackCustom.POST_PLAYER_INIT_FIRST]: PostPlayerInitFirstRegisterParameters;
|
|
139
140
|
[ModCallbackCustom.POST_PLAYER_INIT_LATE]: PostPlayerInitLateRegisterParameters;
|
|
140
|
-
[ModCallbackCustom.POST_PLAYER_INIT_REORDERED]: PostPlayerInitReorderedRegisterParameters;
|
|
141
141
|
[ModCallbackCustom.POST_PLAYER_RENDER_REORDERED]: PostPlayerRenderReorderedRegisterParameters;
|
|
142
142
|
[ModCallbackCustom.POST_PLAYER_UPDATE_REORDERED]: PostPlayerUpdateReorderedRegisterParameters;
|
|
143
143
|
[ModCallbackCustom.POST_POOP_RENDER]: PostPoopRenderRegisterParameters;
|