-
Notifications
You must be signed in to change notification settings - Fork 21
/
RoomHistory.ts
202 lines (185 loc) · 6.2 KB
/
RoomHistory.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
import { game } from "../../../core/cachedClasses";
import { Exported } from "../../../decorators";
import { ModCallbackCustom } from "../../../enums/ModCallbackCustom";
import { getDimension } from "../../../functions/dimensions";
import {
getRoomGridIndex,
getRoomListIndex,
getRoomName,
getRoomStageID,
getRoomSubType,
getRoomVariant,
getRoomVisitedCount,
} from "../../../functions/roomData";
import type { RoomDescription } from "../../../interfaces/RoomDescription";
import { Feature } from "../../private/Feature";
const v = {
run: {
roomHistory: [] as Array<Readonly<RoomDescription>>,
},
};
export class RoomHistory extends Feature {
/** @internal */
public override v = v;
/** @internal */
constructor() {
super();
this.customCallbacksUsed = [
[ModCallbackCustom.POST_NEW_ROOM_EARLY, this.postNewRoomEarly],
];
}
// ModCallbackCustom.POST_NEW_ROOM_EARLY
private readonly postNewRoomEarly = () => {
const level = game.GetLevel();
const stage = level.GetStage();
const stageType = level.GetStageType();
const room = game.GetRoom();
const roomType = room.GetType();
const seeds = game.GetSeeds();
const startSeedString = seeds.GetStartSeedString();
const stageID = getRoomStageID();
const dimension = getDimension();
const roomVariant = getRoomVariant();
const roomSubType = getRoomSubType();
const roomName = getRoomName();
const roomGridIndex = getRoomGridIndex();
const roomListIndex = getRoomListIndex();
const roomVisitedCount = getRoomVisitedCount();
const roomDescription: RoomDescription = {
startSeedString,
stage,
stageType,
stageID,
dimension,
roomType,
roomVariant,
roomSubType,
roomName,
roomGridIndex,
roomListIndex,
roomVisitedCount,
};
v.run.roomHistory.push(roomDescription);
};
/**
* Helper function to manually delete the last room description from the internal array. This is
* useful if a mod needs to send the player to a room temporarily and the room should not count as
* the player having traveled to that room.
*
* @public
*/
@Exported
public deleteLastRoomDescription(): void {
v.run.roomHistory.pop();
}
/**
* Helper function to get the total number of rooms that the player has entered thus far on the
* run. (Re-entering the same room will increment the number returned.)
*
* In order to use this function, you must upgrade your mod with `ISCFeature.ROOM_HISTORY`.
*
* @public
*/
@Exported
public getNumRoomsEntered(): int {
return v.run.roomHistory.length;
}
/**
* Helper function to get information about all of the rooms that a player has visited thus far on
* this run.
*
* In order to use this function, you must upgrade your mod with `ISCFeature.ROOM_HISTORY`.
*
* @public
*/
@Exported
public getRoomHistory(): ReadonlyArray<Readonly<RoomDescription>> {
return v.run.roomHistory;
}
/**
* Helper function to get information about the room that was previously visited.
*
* In the special case of only one room having been visited thus far (i.e. the starting room of
* the run), the starting room will be returned.
*
* In order to use this function, you must upgrade your mod with `ISCFeature.ROOM_HISTORY`.
*
* @public
*/
@Exported
public getPreviousRoomDescription(): Readonly<RoomDescription> {
const previousRoomDescription = v.run.roomHistory.at(-2);
if (previousRoomDescription !== undefined) {
return previousRoomDescription;
}
const startingRoomDescription = v.run.roomHistory[0];
if (startingRoomDescription !== undefined) {
return startingRoomDescription;
}
error(
"Failed to find a room description for any rooms thus far on this run.",
);
}
/**
* Helper function to get information about the most recent room that is stored in the room
* history array.
*
* This is useful in the `POST_ENTITY_REMOVE` callback; see the `isLeavingRoom` function.
*
* Note that this function can return undefined in the case where it is called on the first room
* of the run.
*
* In order to use this function, you must upgrade your mod with `ISCFeature.ROOM_HISTORY`.
*
* @public
*/
@Exported
public getLatestRoomDescription(): Readonly<RoomDescription> | undefined {
return v.run.roomHistory.at(-1);
}
/**
* Helper function to detect if the player is on the first room of the room.
*
* @public
*/
@Exported
public inFirstRoom(): boolean {
return v.run.roomHistory.length === 1;
}
/**
* Helper function to detect if the game is in the state where the room index has changed to a new
* room, but the entities from the previous room are currently in the process of despawning. (At
* this point, the `POST_NEW_ROOM` callback and the `POST_NEW_ROOM_EARLY` callback will not have
* fired yet, and there will not be an entry in the room history array for the current room.)
*
* This function is intended to be used in the `POST_ENTITY_REMOVE` callback to detect when an
* entity is despawning.
*
* In order to use this function, you must upgrade your mod with `ISCFeature.ROOM_HISTORY`.
*
* @public
*/
@Exported
public isLeavingRoom(): boolean {
const level = game.GetLevel();
const stage = level.GetStage();
const stageType = level.GetStageType();
const seeds = game.GetSeeds();
const startSeedString = seeds.GetStartSeedString();
const roomListIndex = getRoomListIndex();
const roomVisitedCount = getRoomVisitedCount();
const latestRoomDescription = this.getLatestRoomDescription();
// Sometimes, this function can be called in situations where entities from the previous run are
// being despawned. If this is the case, then the room history will currently be empty.
if (latestRoomDescription === undefined) {
return false;
}
return (
startSeedString !== latestRoomDescription.startSeedString ||
stage !== latestRoomDescription.stage ||
stageType !== latestRoomDescription.stageType ||
roomListIndex !== latestRoomDescription.roomListIndex ||
roomVisitedCount !== latestRoomDescription.roomVisitedCount
);
}
}