isaacscript-common 6.11.1 → 6.11.2
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/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/enums/ModCallbackCustom.d.ts +2 -2
- 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/customGridEntity.d.ts +8 -5
- package/dist/features/customGridEntity.d.ts.map +1 -1
- package/dist/features/customGridEntity.lua +58 -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 +173 -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 +141 -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/extraConsoleCommands/init.d.ts.map +1 -1
- package/dist/features/extraConsoleCommands/init.lua +3 -1
- package/dist/features/taintedLazarusPlayers.d.ts.map +1 -1
- package/dist/features/taintedLazarusPlayers.lua +13 -21
- package/dist/functions/log.lua +3 -3
- package/dist/functions/playerIndex.d.ts +5 -0
- package/dist/functions/playerIndex.d.ts.map +1 -1
- package/dist/functions/playerIndex.lua +16 -6
- package/dist/functions/table.d.ts +1 -1
- package/dist/functions/table.d.ts.map +1 -1
- package/dist/initFeatures.d.ts.map +1 -1
- package/dist/initFeatures.lua +3 -0
- package/dist/interfaces/CustomGridEntityData.d.ts +5 -1
- package/dist/interfaces/CustomGridEntityData.d.ts.map +1 -1
- package/dist/interfaces/private/CustomTrapdoorDescription.d.ts +3 -0
- package/dist/interfaces/private/CustomTrapdoorDescription.d.ts.map +1 -1
- package/package.json +2 -2
- package/src/callbacks/postFlip.ts +3 -2
- package/src/callbacks/subscriptions/postFirstFlip.ts +6 -3
- package/src/callbacks/subscriptions/postFlip.ts +6 -3
- package/src/enums/ModCallbackCustom.ts +2 -2
- package/src/enums/private/StageTravelState.ts +5 -1
- package/src/enums/private/TrapdoorAnimation.ts +5 -0
- package/src/features/customGridEntity.ts +68 -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 +16 -0
- package/src/features/customTrapdoor/customTrapdoorConstants.ts +13 -3
- package/src/features/customTrapdoor/exports.ts +52 -121
- package/src/features/customTrapdoor/init.ts +215 -0
- package/src/features/customTrapdoor/openClose.ts +103 -0
- package/src/features/customTrapdoor/touched.ts +175 -0
- package/src/features/customTrapdoor/v.ts +16 -10
- package/src/features/deployJSONRoom.ts +1 -1
- package/src/features/extraConsoleCommands/init.ts +5 -2
- package/src/features/saveDataManager/main.ts +1 -1
- package/src/features/taintedLazarusPlayers.ts +32 -31
- package/src/functions/deepCopy.ts +2 -2
- package/src/functions/entities.ts +1 -1
- package/src/functions/playerIndex.ts +12 -0
- package/src/functions/rng.ts +1 -1
- package/src/functions/table.ts +2 -2
- package/src/initFeatures.ts +2 -0
- package/src/interfaces/CustomGridEntityData.ts +6 -1
- package/src/interfaces/private/CustomTrapdoorDescription.ts +4 -0
|
@@ -0,0 +1,175 @@
|
|
|
1
|
+
import {
|
|
2
|
+
EntityCollisionClass,
|
|
3
|
+
EntityPartition,
|
|
4
|
+
PlayerType,
|
|
5
|
+
} from "isaac-typescript-definitions";
|
|
6
|
+
import { VectorZero } from "../../constants";
|
|
7
|
+
import { StageTravelState } from "../../enums/private/StageTravelState";
|
|
8
|
+
import {
|
|
9
|
+
getOtherPlayers,
|
|
10
|
+
getPlayers,
|
|
11
|
+
isChildPlayer,
|
|
12
|
+
} from "../../functions/playerIndex";
|
|
13
|
+
import { isCharacter } from "../../functions/players";
|
|
14
|
+
import { CustomTrapdoorDescription } from "../../interfaces/private/CustomTrapdoorDescription";
|
|
15
|
+
import { disableAllInputs } from "../disableInputs";
|
|
16
|
+
import { isPlayerUsingPony } from "../ponyDetection";
|
|
17
|
+
import { runInNGameFrames, runNextGameFrame } from "../runInNFrames";
|
|
18
|
+
import {
|
|
19
|
+
ANIMATIONS_THAT_PREVENT_STAGE_TRAVEL,
|
|
20
|
+
CUSTOM_TRAPDOOR_FEATURE_NAME,
|
|
21
|
+
OTHER_PLAYER_TRAPDOOR_JUMP_DELAY_GAME_FRAMES,
|
|
22
|
+
OTHER_PLAYER_TRAPDOOR_JUMP_DURATION_GAME_FRAMES,
|
|
23
|
+
TRAPDOOR_TOUCH_DISTANCE,
|
|
24
|
+
} from "./customTrapdoorConstants";
|
|
25
|
+
import v from "./v";
|
|
26
|
+
|
|
27
|
+
export function checkCustomTrapdoorPlayerTouched(
|
|
28
|
+
gridEntity: GridEntity,
|
|
29
|
+
trapdoorDescription: CustomTrapdoorDescription,
|
|
30
|
+
): void {
|
|
31
|
+
if (v.run.state !== StageTravelState.NONE) {
|
|
32
|
+
return;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
if (!trapdoorDescription.open) {
|
|
36
|
+
return;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
const playersTouching = Isaac.FindInRadius(
|
|
40
|
+
gridEntity.Position,
|
|
41
|
+
TRAPDOOR_TOUCH_DISTANCE,
|
|
42
|
+
EntityPartition.PLAYER,
|
|
43
|
+
);
|
|
44
|
+
for (const playerEntity of playersTouching) {
|
|
45
|
+
const player = playerEntity.ToPlayer();
|
|
46
|
+
if (player === undefined) {
|
|
47
|
+
continue;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
if (
|
|
51
|
+
// We don't want a Pony dash to transition to a new floor or a crawl space.
|
|
52
|
+
!isPlayerUsingPony(player) &&
|
|
53
|
+
!isChildPlayer(player) &&
|
|
54
|
+
canPlayerInteractWithTrapdoor(player)
|
|
55
|
+
) {
|
|
56
|
+
playerTouchedCustomTrapdoor(gridEntity, trapdoorDescription, player);
|
|
57
|
+
return; // Prevent two players from touching the same entity.
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
function canPlayerInteractWithTrapdoor(player: EntityPlayer) {
|
|
63
|
+
// Players cannot interact with stage travel entities when items are queued or while playing
|
|
64
|
+
// certain animations.
|
|
65
|
+
const sprite = player.GetSprite();
|
|
66
|
+
const animation = sprite.GetAnimation();
|
|
67
|
+
return (
|
|
68
|
+
!player.IsHoldingItem() &&
|
|
69
|
+
!ANIMATIONS_THAT_PREVENT_STAGE_TRAVEL.has(animation)
|
|
70
|
+
);
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
function playerTouchedCustomTrapdoor(
|
|
74
|
+
gridEntity: GridEntity,
|
|
75
|
+
trapdoorDescription: CustomTrapdoorDescription,
|
|
76
|
+
player: EntityPlayer,
|
|
77
|
+
) {
|
|
78
|
+
v.run.state = StageTravelState.PLAYERS_JUMPING_DOWN;
|
|
79
|
+
v.run.destination = trapdoorDescription.destination;
|
|
80
|
+
|
|
81
|
+
disableAllInputs(CUSTOM_TRAPDOOR_FEATURE_NAME);
|
|
82
|
+
setPlayerAttributes(player, gridEntity.Position);
|
|
83
|
+
dropTaintedForgotten(player);
|
|
84
|
+
|
|
85
|
+
player.PlayExtraAnimation("Trapdoor");
|
|
86
|
+
|
|
87
|
+
const otherPlayers = getOtherPlayers(player);
|
|
88
|
+
otherPlayers.forEach((otherPlayer, i) => {
|
|
89
|
+
const gameFramesToWaitBeforeJumping =
|
|
90
|
+
OTHER_PLAYER_TRAPDOOR_JUMP_DELAY_GAME_FRAMES * (i + 1);
|
|
91
|
+
const otherPlayerPtr = EntityPtr(otherPlayer);
|
|
92
|
+
runInNGameFrames(() => {
|
|
93
|
+
startDelayedJump(otherPlayerPtr, gridEntity.Position);
|
|
94
|
+
}, gameFramesToWaitBeforeJumping);
|
|
95
|
+
});
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
function startDelayedJump(entityPtr: EntityPtr, trapdoorPosition: Vector) {
|
|
99
|
+
const entity = entityPtr.Ref;
|
|
100
|
+
if (entity === undefined) {
|
|
101
|
+
return;
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
const player = entity.ToPlayer();
|
|
105
|
+
if (player === undefined) {
|
|
106
|
+
return;
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
player.PlayExtraAnimation("Trapdoor");
|
|
110
|
+
|
|
111
|
+
adjustPlayerVelocityToTrapdoor(entityPtr, player.Position, trapdoorPosition);
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
function adjustPlayerVelocityToTrapdoor(
|
|
115
|
+
entityPtr: EntityPtr,
|
|
116
|
+
startPos: Vector,
|
|
117
|
+
endPos: Vector,
|
|
118
|
+
) {
|
|
119
|
+
const entity = entityPtr.Ref;
|
|
120
|
+
if (entity === undefined) {
|
|
121
|
+
return;
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
const player = entity.ToPlayer();
|
|
125
|
+
if (player === undefined) {
|
|
126
|
+
return;
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
const sprite = player.GetSprite();
|
|
130
|
+
if (sprite.IsFinished("Trapdoor")) {
|
|
131
|
+
return;
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
const frame = sprite.GetFrame();
|
|
135
|
+
if (frame > OTHER_PLAYER_TRAPDOOR_JUMP_DURATION_GAME_FRAMES) {
|
|
136
|
+
// We have already arrived at the trapdoor.
|
|
137
|
+
return;
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
const totalDifference = endPos.sub(startPos);
|
|
141
|
+
const differencePerFrame = totalDifference.div(
|
|
142
|
+
OTHER_PLAYER_TRAPDOOR_JUMP_DURATION_GAME_FRAMES,
|
|
143
|
+
);
|
|
144
|
+
const differenceForThisFrame = differencePerFrame.mul(frame + 1);
|
|
145
|
+
const targetPosition = startPos.add(differenceForThisFrame);
|
|
146
|
+
const calculatedVelocity = player.Position.sub(targetPosition);
|
|
147
|
+
|
|
148
|
+
player.Velocity = calculatedVelocity;
|
|
149
|
+
|
|
150
|
+
runNextGameFrame(() => {
|
|
151
|
+
adjustPlayerVelocityToTrapdoor(entityPtr, startPos, endPos);
|
|
152
|
+
});
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
function setPlayerAttributes(trapdoorPlayer: EntityPlayer, position: Vector) {
|
|
156
|
+
// Snap the player to the exact position of the trapdoor so that they cleanly jump down the hole.
|
|
157
|
+
trapdoorPlayer.Position = position;
|
|
158
|
+
|
|
159
|
+
for (const player of getPlayers()) {
|
|
160
|
+
// Freeze all players.
|
|
161
|
+
player.Velocity = VectorZero;
|
|
162
|
+
|
|
163
|
+
// We don't want enemy attacks to move the players.
|
|
164
|
+
player.EntityCollisionClass = EntityCollisionClass.NONE;
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
function dropTaintedForgotten(player: EntityPlayer) {
|
|
169
|
+
if (isCharacter(player, PlayerType.THE_FORGOTTEN_B)) {
|
|
170
|
+
const taintedSoul = player.GetOtherTwin();
|
|
171
|
+
if (taintedSoul !== undefined) {
|
|
172
|
+
taintedSoul.ThrowHeldEntity(VectorZero);
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
}
|
|
@@ -1,20 +1,26 @@
|
|
|
1
|
+
import { LevelStage, StageType } from "isaac-typescript-definitions";
|
|
2
|
+
import { DefaultMap } from "../../classes/DefaultMap";
|
|
1
3
|
import { StageTravelState } from "../../enums/private/StageTravelState";
|
|
2
4
|
import { CustomTrapdoorDescription } from "../../interfaces/private/CustomTrapdoorDescription";
|
|
3
5
|
|
|
4
6
|
const v = {
|
|
5
7
|
run: {
|
|
6
8
|
state: StageTravelState.NONE,
|
|
9
|
+
|
|
10
|
+
/** The render frame that this state was reached. */
|
|
11
|
+
stateRenderFrame: null as int | null,
|
|
12
|
+
|
|
13
|
+
destination: null as
|
|
14
|
+
| [stage: LevelStage, stageType: StageType]
|
|
15
|
+
| string
|
|
16
|
+
| null,
|
|
7
17
|
},
|
|
8
18
|
|
|
9
|
-
|
|
10
|
-
/** Indexed by grid index. */
|
|
11
|
-
trapdoors: new Map<int, CustomTrapdoorDescription
|
|
19
|
+
level: {
|
|
20
|
+
/** Indexed by room list index and grid index. */
|
|
21
|
+
trapdoors: new DefaultMap<int, Map<int, CustomTrapdoorDescription>>(
|
|
22
|
+
() => new Map(),
|
|
23
|
+
),
|
|
12
24
|
},
|
|
13
25
|
};
|
|
14
|
-
|
|
15
|
-
export function getCustomTrapdoorDescription(
|
|
16
|
-
gridEntity: GridEntity,
|
|
17
|
-
): CustomTrapdoorDescription | undefined {
|
|
18
|
-
const gridIndex = gridEntity.GetGridIndex();
|
|
19
|
-
return v.room.trapdoors.get(gridIndex);
|
|
20
|
-
}
|
|
26
|
+
export default v;
|
|
@@ -8,6 +8,7 @@ import {
|
|
|
8
8
|
} from "isaac-typescript-definitions";
|
|
9
9
|
import { ModUpgraded } from "../../classes/ModUpgraded";
|
|
10
10
|
import { MAX_SPEED_STAT } from "../../constants";
|
|
11
|
+
import { bitFlags } from "../../functions/flag";
|
|
11
12
|
import { getMapPartialMatch } from "../../functions/map";
|
|
12
13
|
import { printConsole } from "../../functions/utils";
|
|
13
14
|
import { debugDisplayInit } from "../debugDisplay/debugDisplay";
|
|
@@ -349,8 +350,10 @@ function entityTakeDmgPlayer() {
|
|
|
349
350
|
}
|
|
350
351
|
|
|
351
352
|
// ModCallback.POST_CURSE_EVAL (12)
|
|
352
|
-
function postCurseEval(
|
|
353
|
-
|
|
353
|
+
function postCurseEval(
|
|
354
|
+
curses: BitFlags<LevelCurse>,
|
|
355
|
+
): BitFlags<LevelCurse> | undefined {
|
|
356
|
+
return v.persistent.disableCurses ? bitFlags(LevelCurse.NONE) : curses;
|
|
354
357
|
}
|
|
355
358
|
|
|
356
359
|
// ModCallback.EXECUTE_CMD (22)
|
|
@@ -2,29 +2,39 @@
|
|
|
2
2
|
// Lazarus.
|
|
3
3
|
|
|
4
4
|
import { ModCallback, PlayerType } from "isaac-typescript-definitions";
|
|
5
|
+
import { ModUpgraded } from "../classes/ModUpgraded";
|
|
5
6
|
import { errorIfFeaturesNotInitialized } from "../featuresInitialized";
|
|
7
|
+
import { logError } from "../functions/log";
|
|
6
8
|
import { saveDataManager } from "./saveDataManager/exports";
|
|
7
9
|
|
|
8
10
|
const FEATURE_NAME = "taintedLazarusPlayers";
|
|
9
11
|
|
|
10
12
|
const v = {
|
|
11
13
|
run: {
|
|
12
|
-
queuedTaintedLazarus: [] as
|
|
13
|
-
queuedDeadTaintedLazarus: [] as
|
|
14
|
+
queuedTaintedLazarus: [] as EntityPlayer[],
|
|
15
|
+
queuedDeadTaintedLazarus: [] as EntityPlayer[],
|
|
14
16
|
|
|
15
17
|
/**
|
|
16
|
-
* The
|
|
18
|
+
* The `POST_PLAYER_INIT` callback fires for Dead Tainted Lazarus at the beginning of the run.
|
|
17
19
|
* However, the player index for the Dead Tainted Lazarus player object at that time does not
|
|
18
20
|
* actually correspond to the player index for the real player once Flip has been used. Thus, we
|
|
19
21
|
* revert to using PtrHash as an index for our map, which is consistent between the Dead Tainted
|
|
20
|
-
* Lazarus object in the
|
|
22
|
+
* Lazarus object in the `POST_PLAYER_INIT` callback and the "real" Dead Tainted Lazarus.
|
|
23
|
+
*
|
|
24
|
+
* We use `EntityPlayer` as the value for the map instead of `EntityPtr` because using the
|
|
25
|
+
* pointer does not work for some reason. (When we unwrap it after one or more flips have been
|
|
26
|
+
* used, the pointers no longer point to the original objects, even if we manually update the
|
|
27
|
+
* pointers in the `POST_FLIP` callback.)
|
|
21
28
|
*/
|
|
22
|
-
subPlayerMap: new Map<PtrHash,
|
|
29
|
+
subPlayerMap: new Map<PtrHash, EntityPlayer>(),
|
|
23
30
|
},
|
|
24
31
|
};
|
|
25
32
|
|
|
26
33
|
/** @internal */
|
|
27
|
-
export function taintedLazarusPlayersInit(mod:
|
|
34
|
+
export function taintedLazarusPlayersInit(mod: ModUpgraded): void {
|
|
35
|
+
// `EntityPtr` is not serializable, so we cannot save data. However, this is inconsequential,
|
|
36
|
+
// since the `POST_PLAYER_INIT` callback will fire when a run is continued, which will repopulate
|
|
37
|
+
// the `subPlayerMap`.
|
|
28
38
|
saveDataManager(FEATURE_NAME, v, () => false);
|
|
29
39
|
|
|
30
40
|
mod.AddCallback(ModCallback.POST_PLAYER_INIT, postPlayerInit);
|
|
@@ -32,13 +42,12 @@ export function taintedLazarusPlayersInit(mod: Mod): void {
|
|
|
32
42
|
|
|
33
43
|
// ModCallback.POST_PLAYER_INIT (9)
|
|
34
44
|
function postPlayerInit(player: EntityPlayer) {
|
|
35
|
-
const entityPtr = EntityPtr(player);
|
|
36
45
|
const character = player.GetPlayerType();
|
|
37
46
|
|
|
38
47
|
if (character === PlayerType.LAZARUS_B) {
|
|
39
|
-
v.run.queuedTaintedLazarus.push(
|
|
48
|
+
v.run.queuedTaintedLazarus.push(player);
|
|
40
49
|
} else if (character === PlayerType.LAZARUS_2_B) {
|
|
41
|
-
v.run.queuedDeadTaintedLazarus.push(
|
|
50
|
+
v.run.queuedDeadTaintedLazarus.push(player);
|
|
42
51
|
} else {
|
|
43
52
|
return;
|
|
44
53
|
}
|
|
@@ -47,6 +56,8 @@ function postPlayerInit(player: EntityPlayer) {
|
|
|
47
56
|
}
|
|
48
57
|
|
|
49
58
|
/**
|
|
59
|
+
* Indexes are the `PtrHash`, values are the `EntityPtr` of the *other* Lazarus.
|
|
60
|
+
*
|
|
50
61
|
* When starting a run, the PostPlayerInit callback will fire first for Dead Tainted Lazarus, then
|
|
51
62
|
* for Tainted Lazarus. When continuing a run, the PostPlayerInit callback will fire first for the
|
|
52
63
|
* character that is currently active. Thus, since the order of the characters is not certain, we
|
|
@@ -61,15 +72,8 @@ function checkDequeue() {
|
|
|
61
72
|
return;
|
|
62
73
|
}
|
|
63
74
|
|
|
64
|
-
const
|
|
65
|
-
const
|
|
66
|
-
|
|
67
|
-
if (taintedLazarusPtr === undefined || deadTaintedLazarusPtr === undefined) {
|
|
68
|
-
return;
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
const taintedLazarus = taintedLazarusPtr.Ref;
|
|
72
|
-
const deadTaintedLazarus = deadTaintedLazarusPtr.Ref;
|
|
75
|
+
const taintedLazarus = v.run.queuedTaintedLazarus.shift();
|
|
76
|
+
const deadTaintedLazarus = v.run.queuedDeadTaintedLazarus.shift();
|
|
73
77
|
|
|
74
78
|
if (taintedLazarus === undefined || deadTaintedLazarus === undefined) {
|
|
75
79
|
return;
|
|
@@ -78,8 +82,15 @@ function checkDequeue() {
|
|
|
78
82
|
const taintedLazarusPtrHash = GetPtrHash(taintedLazarus);
|
|
79
83
|
const deadTaintedLazarusPtrHash = GetPtrHash(deadTaintedLazarus);
|
|
80
84
|
|
|
81
|
-
|
|
82
|
-
|
|
85
|
+
if (taintedLazarusPtrHash === deadTaintedLazarusPtrHash) {
|
|
86
|
+
logError(
|
|
87
|
+
"Failed to cache the Tainted Lazarus player objects, since the hash for Tainted Lazarus and Dead Tainted Lazarus were the same.",
|
|
88
|
+
);
|
|
89
|
+
return;
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
v.run.subPlayerMap.set(taintedLazarusPtrHash, deadTaintedLazarus);
|
|
93
|
+
v.run.subPlayerMap.set(deadTaintedLazarusPtrHash, taintedLazarus);
|
|
83
94
|
}
|
|
84
95
|
|
|
85
96
|
/**
|
|
@@ -99,15 +110,5 @@ export function getTaintedLazarusSubPlayer(
|
|
|
99
110
|
errorIfFeaturesNotInitialized(FEATURE_NAME);
|
|
100
111
|
|
|
101
112
|
const ptrHash = GetPtrHash(player);
|
|
102
|
-
|
|
103
|
-
if (entityPtr === undefined) {
|
|
104
|
-
return undefined;
|
|
105
|
-
}
|
|
106
|
-
|
|
107
|
-
const entity = entityPtr.Ref;
|
|
108
|
-
if (entity === undefined) {
|
|
109
|
-
return undefined;
|
|
110
|
-
}
|
|
111
|
-
|
|
112
|
-
return entity.ToPlayer();
|
|
113
|
+
return v.run.subPlayerMap.get(ptrHash);
|
|
113
114
|
}
|
|
@@ -550,8 +550,8 @@ function getCopiedEntries(
|
|
|
550
550
|
entries: Array<[key: AnyNotNil, value: unknown]>;
|
|
551
551
|
convertedNumberKeysToStrings: boolean;
|
|
552
552
|
} {
|
|
553
|
-
// First, shallow copy the entries. We cannot use "pairs" to iterate over a Map or Set
|
|
554
|
-
// use "[...pairs(object)]", as it results in a run-time error.
|
|
553
|
+
// First, shallow copy the entries. We cannot use "pairs" to iterate over a `Map` or `Set`. We
|
|
554
|
+
// cannot use "[...pairs(object)]", as it results in a run-time error.
|
|
555
555
|
const entries: Array<[key: AnyNotNil, value: unknown]> = [];
|
|
556
556
|
if (isTSTLMap(object) || isTSTLSet(object) || isDefaultMap(object)) {
|
|
557
557
|
for (const [key, value] of object.entries()) {
|
|
@@ -181,7 +181,7 @@ function setPrimitiveEntityFields(
|
|
|
181
181
|
error('Failed to get the "__propget" table for an entity.');
|
|
182
182
|
}
|
|
183
183
|
|
|
184
|
-
for (const [key] of
|
|
184
|
+
for (const [key] of propGetTable) {
|
|
185
185
|
// The values of this table are functions. Thus, we use the key to index the original entity.
|
|
186
186
|
const indexKey = key as keyof typeof entity;
|
|
187
187
|
const value = entity[indexKey];
|
|
@@ -28,6 +28,18 @@ export function getAllPlayers(): EntityPlayer[] {
|
|
|
28
28
|
return players;
|
|
29
29
|
}
|
|
30
30
|
|
|
31
|
+
/**
|
|
32
|
+
* Helper function to get all of the other players in the room besides the one provided. (This
|
|
33
|
+
* includes "child" players.)
|
|
34
|
+
*/
|
|
35
|
+
export function getOtherPlayers(player: EntityPlayer): EntityPlayer[] {
|
|
36
|
+
const playerPtrHash = GetPtrHash(player);
|
|
37
|
+
const players = getAllPlayers();
|
|
38
|
+
return players.filter(
|
|
39
|
+
(otherPlayer) => GetPtrHash(otherPlayer) !== playerPtrHash,
|
|
40
|
+
);
|
|
41
|
+
}
|
|
42
|
+
|
|
31
43
|
/**
|
|
32
44
|
* Helper function to get the corresponding `EntityPlayer` object that corresponds to a
|
|
33
45
|
* `PlayerIndex`.
|
package/src/functions/rng.ts
CHANGED
|
@@ -142,7 +142,7 @@ export function setAllRNGToSeed(object: unknown, seed: Seed): void {
|
|
|
142
142
|
}
|
|
143
143
|
|
|
144
144
|
let setAtLeastOneSeed = false;
|
|
145
|
-
for (const [_key, value] of
|
|
145
|
+
for (const [_key, value] of object) {
|
|
146
146
|
if (isRNG(value)) {
|
|
147
147
|
setSeed(value, seed);
|
|
148
148
|
setAtLeastOneSeed = true;
|
package/src/functions/table.ts
CHANGED
|
@@ -4,8 +4,8 @@ import { isBoolean, isNumber, isString } from "./types";
|
|
|
4
4
|
* In a `Map`, you can use the `clear` method to delete every element. However, in a `LuaMap`, the
|
|
5
5
|
* `clear` method does not exist. Use this helper function as a drop-in replacement for this.
|
|
6
6
|
*/
|
|
7
|
-
export function clearTable(luaMap: LuaMap): void {
|
|
8
|
-
for (const [key] of
|
|
7
|
+
export function clearTable(luaMap: LuaMap<AnyNotNil, unknown>): void {
|
|
8
|
+
for (const [key] of luaMap) {
|
|
9
9
|
luaMap.delete(key);
|
|
10
10
|
}
|
|
11
11
|
}
|
package/src/initFeatures.ts
CHANGED
|
@@ -4,6 +4,7 @@ import { characterStatsInit } from "./features/characterStats";
|
|
|
4
4
|
import { collectibleItemPoolTypeInit } from "./features/collectibleItemPoolType";
|
|
5
5
|
import { customGridEntityInit } from "./features/customGridEntity";
|
|
6
6
|
import { customStageInit } from "./features/customStage/init";
|
|
7
|
+
import { customTrapdoorInit } from "./features/customTrapdoor/init";
|
|
7
8
|
import { deployJSONRoomInit } from "./features/deployJSONRoom";
|
|
8
9
|
import { disableAllSoundInit } from "./features/disableAllSound";
|
|
9
10
|
import { disableInputsInit } from "./features/disableInputs";
|
|
@@ -38,6 +39,7 @@ function initFeaturesMajor(mod: ModUpgraded) {
|
|
|
38
39
|
}
|
|
39
40
|
|
|
40
41
|
function initFeaturesMinor(mod: ModUpgraded) {
|
|
42
|
+
customTrapdoorInit(mod);
|
|
41
43
|
disableAllSoundInit(mod);
|
|
42
44
|
disableInputsInit(mod);
|
|
43
45
|
fadeInRemoverInit(mod);
|
|
@@ -4,10 +4,15 @@ import {
|
|
|
4
4
|
} from "isaac-typescript-definitions";
|
|
5
5
|
|
|
6
6
|
export interface CustomGridEntityData {
|
|
7
|
+
/**
|
|
8
|
+
* This is not a real `GridEntityType`; rather it is an arbitrary integer selected by end-user
|
|
9
|
+
* mods.
|
|
10
|
+
*/
|
|
7
11
|
gridEntityTypeCustom: GridEntityType;
|
|
12
|
+
|
|
8
13
|
roomListIndex: int;
|
|
9
14
|
gridIndex: int;
|
|
10
15
|
anm2Path: string;
|
|
11
|
-
defaultAnimation
|
|
16
|
+
defaultAnimation?: string;
|
|
12
17
|
gridCollisionClass: GridCollisionClass;
|
|
13
18
|
}
|