isaacscript-common 20.9.1 → 20.11.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/index.d.ts +36 -6
- package/dist/isaacscript-common.lua +216 -156
- package/dist/src/classes/features/callbackLogic/SlotDestroyedDetection.d.ts.map +1 -1
- package/dist/src/classes/features/callbackLogic/SlotDestroyedDetection.lua +3 -0
- package/dist/src/classes/features/other/RoomHistory.d.ts +8 -0
- package/dist/src/classes/features/other/RoomHistory.d.ts.map +1 -1
- package/dist/src/classes/features/other/RoomHistory.lua +4 -0
- package/dist/src/classes/features/other/RunInNFrames.d.ts +29 -6
- package/dist/src/classes/features/other/RunInNFrames.d.ts.map +1 -1
- package/dist/src/classes/features/other/RunInNFrames.lua +98 -45
- package/dist/src/features.d.ts.map +1 -1
- package/dist/src/features.lua +1 -1
- package/package.json +1 -1
- package/src/classes/features/callbackLogic/SlotDestroyedDetection.ts +3 -0
- package/src/classes/features/other/RoomHistory.ts +11 -0
- package/src/classes/features/other/RunInNFrames.ts +146 -53
- package/src/features.ts +2 -1
|
@@ -1,43 +1,56 @@
|
|
|
1
1
|
import { ModCallback, PlayerType } from "isaac-typescript-definitions";
|
|
2
2
|
import { game } from "../../../core/cachedClasses";
|
|
3
3
|
import { Exported } from "../../../decorators";
|
|
4
|
+
import { ISCFeature } from "../../../enums/ISCFeature";
|
|
4
5
|
import { arrayRemoveInPlace } from "../../../functions/array";
|
|
5
6
|
import { restart } from "../../../functions/run";
|
|
6
7
|
import { Feature } from "../../private/Feature";
|
|
8
|
+
import { RoomHistory } from "./RoomHistory";
|
|
7
9
|
|
|
8
10
|
/** Used for `runInNFrames` functions. */
|
|
9
|
-
|
|
11
|
+
interface QueuedFunction {
|
|
12
|
+
func: () => void;
|
|
13
|
+
frameCountToFire: int;
|
|
14
|
+
numRoomsEntered: int;
|
|
15
|
+
cancelIfRoomChanges: boolean;
|
|
16
|
+
}
|
|
10
17
|
|
|
11
18
|
/**
|
|
12
19
|
* Used for `setInterval` functions.
|
|
13
20
|
*
|
|
14
21
|
* The return value is whether or not to continue the function from firing.
|
|
15
22
|
*/
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
23
|
+
interface IntervalFunction {
|
|
24
|
+
func: () => boolean;
|
|
25
|
+
frameCountToFire: int;
|
|
26
|
+
numRoomsEntered: int;
|
|
27
|
+
cancelIfRoomChanges: boolean;
|
|
28
|
+
numIntervalFrames: int;
|
|
29
|
+
}
|
|
21
30
|
|
|
22
31
|
export class RunInNFrames extends Feature {
|
|
23
32
|
/** @internal */
|
|
24
33
|
public override v = {
|
|
25
34
|
run: {
|
|
26
|
-
|
|
27
|
-
|
|
35
|
+
queuedGameFunctions: [] as QueuedFunction[],
|
|
36
|
+
queuedRenderFunctions: [] as QueuedFunction[],
|
|
28
37
|
|
|
29
|
-
|
|
30
|
-
|
|
38
|
+
intervalGameFunctions: [] as IntervalFunction[],
|
|
39
|
+
intervalRenderFunctions: [] as IntervalFunction[],
|
|
31
40
|
},
|
|
32
41
|
};
|
|
33
42
|
|
|
34
43
|
// eslint-disable-next-line class-methods-use-this
|
|
35
44
|
public override vConditionalFunc = (): boolean => false;
|
|
36
45
|
|
|
46
|
+
private roomHistory: RoomHistory;
|
|
47
|
+
|
|
37
48
|
/** @internal */
|
|
38
|
-
constructor() {
|
|
49
|
+
constructor(roomHistory: RoomHistory) {
|
|
39
50
|
super();
|
|
40
51
|
|
|
52
|
+
this.featuresUsed = [ISCFeature.ROOM_HISTORY];
|
|
53
|
+
|
|
41
54
|
this.callbacksUsed = [
|
|
42
55
|
// 1
|
|
43
56
|
[ModCallback.POST_UPDATE, this.postUpdate],
|
|
@@ -45,33 +58,41 @@ export class RunInNFrames extends Feature {
|
|
|
45
58
|
// 2
|
|
46
59
|
[ModCallback.POST_RENDER, this.postRender],
|
|
47
60
|
];
|
|
61
|
+
|
|
62
|
+
this.roomHistory = roomHistory;
|
|
48
63
|
}
|
|
49
64
|
|
|
50
65
|
// ModCallback.POST_UPDATE (1)
|
|
51
66
|
private postUpdate = (): void => {
|
|
52
67
|
const gameFrameCount = game.GetFrameCount();
|
|
68
|
+
const numRoomsEntered = this.roomHistory.getNumRoomsEntered();
|
|
53
69
|
|
|
54
70
|
checkExecuteQueuedFunctions(
|
|
71
|
+
this.v.run.queuedGameFunctions,
|
|
55
72
|
gameFrameCount,
|
|
56
|
-
|
|
73
|
+
numRoomsEntered,
|
|
57
74
|
);
|
|
58
75
|
checkExecuteIntervalFunctions(
|
|
76
|
+
this.v.run.intervalGameFunctions,
|
|
59
77
|
gameFrameCount,
|
|
60
|
-
|
|
78
|
+
numRoomsEntered,
|
|
61
79
|
);
|
|
62
80
|
};
|
|
63
81
|
|
|
64
82
|
// ModCallback.POST_RENDER (2)
|
|
65
83
|
private postRender = (): void => {
|
|
66
84
|
const renderFrameCount = Isaac.GetFrameCount();
|
|
85
|
+
const numRoomsEntered = this.roomHistory.getNumRoomsEntered();
|
|
67
86
|
|
|
68
87
|
checkExecuteQueuedFunctions(
|
|
88
|
+
this.v.run.queuedRenderFunctions,
|
|
69
89
|
renderFrameCount,
|
|
70
|
-
|
|
90
|
+
numRoomsEntered,
|
|
71
91
|
);
|
|
72
92
|
checkExecuteIntervalFunctions(
|
|
93
|
+
this.v.run.intervalRenderFunctions,
|
|
73
94
|
renderFrameCount,
|
|
74
|
-
|
|
95
|
+
numRoomsEntered,
|
|
75
96
|
);
|
|
76
97
|
};
|
|
77
98
|
|
|
@@ -102,13 +123,29 @@ export class RunInNFrames extends Feature {
|
|
|
102
123
|
* deferred functions manually using serializable data.
|
|
103
124
|
*
|
|
104
125
|
* In order to use this function, you must upgrade your mod with `ISCFeature.RUN_IN_N_FRAMES`.
|
|
126
|
+
*
|
|
127
|
+
* @param func The function to run.
|
|
128
|
+
* @param gameFrames The amount of game frames to wait before running the function.
|
|
129
|
+
* @param cancelIfRoomChanges Optional. Whether or not to cancel running the function if a new
|
|
130
|
+
* room is loaded in the interim. Default is false.
|
|
105
131
|
*/
|
|
106
132
|
@Exported
|
|
107
|
-
public runInNGameFrames(
|
|
133
|
+
public runInNGameFrames(
|
|
134
|
+
func: () => void,
|
|
135
|
+
gameFrames: int,
|
|
136
|
+
cancelIfRoomChanges = false,
|
|
137
|
+
): void {
|
|
108
138
|
const gameFrameCount = game.GetFrameCount();
|
|
109
|
-
const
|
|
110
|
-
|
|
111
|
-
|
|
139
|
+
const numRoomsEntered = this.roomHistory.getNumRoomsEntered();
|
|
140
|
+
|
|
141
|
+
const frameCountToFire = gameFrameCount + gameFrames;
|
|
142
|
+
const queuedFunction: QueuedFunction = {
|
|
143
|
+
func,
|
|
144
|
+
frameCountToFire,
|
|
145
|
+
numRoomsEntered,
|
|
146
|
+
cancelIfRoomChanges,
|
|
147
|
+
};
|
|
148
|
+
this.v.run.queuedGameFunctions.push(queuedFunction);
|
|
112
149
|
}
|
|
113
150
|
|
|
114
151
|
/**
|
|
@@ -122,13 +159,29 @@ export class RunInNFrames extends Feature {
|
|
|
122
159
|
* deferred functions manually using serializable data.
|
|
123
160
|
*
|
|
124
161
|
* In order to use this function, you must upgrade your mod with `ISCFeature.RUN_IN_N_FRAMES`.
|
|
162
|
+
*
|
|
163
|
+
* @param func The function to run.
|
|
164
|
+
* @param renderFrames The amount of render frames to wait before running the function.
|
|
165
|
+
* @param cancelIfRoomChanges Optional. Whether or not to cancel running the function if a new
|
|
166
|
+
* room is loaded in the interim. Default is false.
|
|
125
167
|
*/
|
|
126
168
|
@Exported
|
|
127
|
-
public runInNRenderFrames(
|
|
169
|
+
public runInNRenderFrames(
|
|
170
|
+
func: () => void,
|
|
171
|
+
renderFrames: int,
|
|
172
|
+
cancelIfRoomChanges = false,
|
|
173
|
+
): void {
|
|
128
174
|
const renderFrameCount = Isaac.GetFrameCount();
|
|
129
|
-
const
|
|
130
|
-
|
|
131
|
-
|
|
175
|
+
const numRoomsEntered = this.roomHistory.getNumRoomsEntered();
|
|
176
|
+
|
|
177
|
+
const frameCountToFire = renderFrameCount + renderFrames;
|
|
178
|
+
const queuedFunction: QueuedFunction = {
|
|
179
|
+
func,
|
|
180
|
+
frameCountToFire,
|
|
181
|
+
numRoomsEntered,
|
|
182
|
+
cancelIfRoomChanges,
|
|
183
|
+
};
|
|
184
|
+
this.v.run.queuedRenderFunctions.push(queuedFunction);
|
|
132
185
|
}
|
|
133
186
|
|
|
134
187
|
/**
|
|
@@ -160,10 +213,14 @@ export class RunInNFrames extends Feature {
|
|
|
160
213
|
* deferred functions manually using serializable data.
|
|
161
214
|
*
|
|
162
215
|
* In order to use this function, you must upgrade your mod with `ISCFeature.RUN_IN_N_FRAMES`.
|
|
216
|
+
*
|
|
217
|
+
* @param func The function to run.
|
|
218
|
+
* @param cancelIfRoomChanges Optional. Whether or not to cancel running the function if a new
|
|
219
|
+
* room is loaded in the interim. Default is false.
|
|
163
220
|
*/
|
|
164
221
|
@Exported
|
|
165
|
-
public runNextGameFrame(func: () => void): void {
|
|
166
|
-
this.runInNGameFrames(func, 1);
|
|
222
|
+
public runNextGameFrame(func: () => void, cancelIfRoomChanges = false): void {
|
|
223
|
+
this.runInNGameFrames(func, 1, cancelIfRoomChanges);
|
|
167
224
|
}
|
|
168
225
|
|
|
169
226
|
/**
|
|
@@ -175,10 +232,17 @@ export class RunInNFrames extends Feature {
|
|
|
175
232
|
* Note that this function will not handle saving and quitting.
|
|
176
233
|
*
|
|
177
234
|
* In order to use this function, you must upgrade your mod with `ISCFeature.RUN_IN_N_FRAMES`.
|
|
235
|
+
*
|
|
236
|
+
* @param func The function to run.
|
|
237
|
+
* @param cancelIfRoomChanges Optional. Whether or not to cancel running the function if a new
|
|
238
|
+
* room is loaded in the interim. Default is false.
|
|
178
239
|
*/
|
|
179
240
|
@Exported
|
|
180
|
-
public runNextRenderFrame(
|
|
181
|
-
|
|
241
|
+
public runNextRenderFrame(
|
|
242
|
+
func: () => void,
|
|
243
|
+
cancelIfRoomChanges = false,
|
|
244
|
+
): void {
|
|
245
|
+
this.runInNRenderFrames(func, 1, cancelIfRoomChanges);
|
|
182
246
|
}
|
|
183
247
|
|
|
184
248
|
/**
|
|
@@ -198,17 +262,27 @@ export class RunInNFrames extends Feature {
|
|
|
198
262
|
* @param gameFrames The amount of game frames to wait between each run.
|
|
199
263
|
* @param runImmediately Whether or not to execute the function right now before waiting for the
|
|
200
264
|
* interval.
|
|
265
|
+
* @param cancelIfRoomChanges Optional. Whether or not to cancel running the function if a new
|
|
266
|
+
* room is loaded in the interim. Default is false.
|
|
201
267
|
*/
|
|
202
268
|
@Exported
|
|
203
269
|
public setIntervalGameFrames(
|
|
204
270
|
func: () => boolean,
|
|
205
271
|
gameFrames: int,
|
|
206
272
|
runImmediately: boolean,
|
|
273
|
+
cancelIfRoomChanges = false,
|
|
207
274
|
): void {
|
|
208
275
|
const gameFrameCount = game.GetFrameCount();
|
|
209
|
-
const
|
|
210
|
-
|
|
211
|
-
|
|
276
|
+
const numRoomsEntered = this.roomHistory.getNumRoomsEntered();
|
|
277
|
+
|
|
278
|
+
const intervalFunction: IntervalFunction = {
|
|
279
|
+
func,
|
|
280
|
+
frameCountToFire: gameFrameCount + gameFrames,
|
|
281
|
+
numRoomsEntered,
|
|
282
|
+
cancelIfRoomChanges,
|
|
283
|
+
numIntervalFrames: gameFrames,
|
|
284
|
+
};
|
|
285
|
+
this.v.run.intervalGameFunctions.push(intervalFunction);
|
|
212
286
|
|
|
213
287
|
if (runImmediately) {
|
|
214
288
|
func();
|
|
@@ -232,21 +306,27 @@ export class RunInNFrames extends Feature {
|
|
|
232
306
|
* @param renderFrames The amount of game frames to wait between each run.
|
|
233
307
|
* @param runImmediately Whether or not to execute the function right now before waiting for the
|
|
234
308
|
* interval.
|
|
309
|
+
* @param cancelIfRoomChanges Optional. Whether or not to cancel running the function if a new
|
|
310
|
+
* room is loaded in the interim. Default is false.
|
|
235
311
|
*/
|
|
236
312
|
@Exported
|
|
237
313
|
public setIntervalRenderFrames(
|
|
238
314
|
func: () => boolean,
|
|
239
315
|
renderFrames: int,
|
|
240
316
|
runImmediately: boolean,
|
|
317
|
+
cancelIfRoomChanges = false,
|
|
241
318
|
): void {
|
|
242
319
|
const renderFrameCount = Isaac.GetFrameCount();
|
|
243
|
-
const
|
|
244
|
-
|
|
245
|
-
|
|
320
|
+
const numRoomsEntered = this.roomHistory.getNumRoomsEntered();
|
|
321
|
+
|
|
322
|
+
const intervalFunction: IntervalFunction = {
|
|
246
323
|
func,
|
|
247
|
-
renderFrames,
|
|
248
|
-
|
|
249
|
-
|
|
324
|
+
frameCountToFire: renderFrameCount + renderFrames,
|
|
325
|
+
numRoomsEntered,
|
|
326
|
+
cancelIfRoomChanges,
|
|
327
|
+
numIntervalFrames: renderFrames,
|
|
328
|
+
};
|
|
329
|
+
this.v.run.intervalGameFunctions.push(intervalFunction);
|
|
250
330
|
|
|
251
331
|
if (runImmediately) {
|
|
252
332
|
func();
|
|
@@ -255,42 +335,55 @@ export class RunInNFrames extends Feature {
|
|
|
255
335
|
}
|
|
256
336
|
|
|
257
337
|
function checkExecuteQueuedFunctions(
|
|
338
|
+
functionTuples: QueuedFunction[],
|
|
258
339
|
frameCount: int,
|
|
259
|
-
|
|
340
|
+
newNumRoomsEntered: int,
|
|
260
341
|
) {
|
|
261
342
|
const firingFunctions = functionTuples.filter(
|
|
262
|
-
(
|
|
343
|
+
({ frameCountToFire }) => frameCount >= frameCountToFire,
|
|
263
344
|
);
|
|
264
345
|
|
|
265
|
-
for (const
|
|
266
|
-
const
|
|
267
|
-
|
|
268
|
-
|
|
346
|
+
for (const firingFunction of firingFunctions) {
|
|
347
|
+
const { func, cancelIfRoomChanges, numRoomsEntered } = firingFunction;
|
|
348
|
+
|
|
349
|
+
if (!cancelIfRoomChanges || numRoomsEntered === newNumRoomsEntered) {
|
|
350
|
+
func();
|
|
351
|
+
}
|
|
352
|
+
|
|
353
|
+
arrayRemoveInPlace(functionTuples, firingFunction);
|
|
269
354
|
}
|
|
270
355
|
}
|
|
271
356
|
|
|
272
357
|
function checkExecuteIntervalFunctions(
|
|
358
|
+
functionTuples: IntervalFunction[],
|
|
273
359
|
frameCount: int,
|
|
274
|
-
|
|
360
|
+
newNumRoomsEntered: int,
|
|
275
361
|
) {
|
|
276
362
|
const firingFunctions = functionTuples.filter(
|
|
277
|
-
(
|
|
363
|
+
({ frameCountToFire }) => frameCount >= frameCountToFire,
|
|
278
364
|
);
|
|
279
365
|
|
|
280
|
-
for (const
|
|
281
|
-
const
|
|
282
|
-
|
|
283
|
-
|
|
366
|
+
for (const firingFunction of firingFunctions) {
|
|
367
|
+
const { func, cancelIfRoomChanges, numRoomsEntered, numIntervalFrames } =
|
|
368
|
+
firingFunction;
|
|
369
|
+
|
|
370
|
+
let returnValue = false;
|
|
371
|
+
if (!cancelIfRoomChanges || numRoomsEntered === newNumRoomsEntered) {
|
|
372
|
+
returnValue = func();
|
|
373
|
+
}
|
|
374
|
+
|
|
375
|
+
arrayRemoveInPlace(functionTuples, firingFunction);
|
|
284
376
|
|
|
285
377
|
// Queue the next interval (as long as the function did not return false).
|
|
286
378
|
if (returnValue) {
|
|
287
|
-
const
|
|
288
|
-
const newTuple: IntervalFunctionTuple = [
|
|
289
|
-
nextFireFrame,
|
|
379
|
+
const newIntervalFunction: IntervalFunction = {
|
|
290
380
|
func,
|
|
381
|
+
frameCountToFire: frameCount + numIntervalFrames,
|
|
382
|
+
numRoomsEntered,
|
|
383
|
+
cancelIfRoomChanges,
|
|
291
384
|
numIntervalFrames,
|
|
292
|
-
|
|
293
|
-
functionTuples.push(
|
|
385
|
+
};
|
|
386
|
+
functionTuples.push(newIntervalFunction);
|
|
294
387
|
}
|
|
295
388
|
}
|
|
296
389
|
}
|
package/src/features.ts
CHANGED
|
@@ -143,11 +143,12 @@ export function getFeatures(
|
|
|
143
143
|
const preventCollectibleRotation = new PreventCollectibleRotation();
|
|
144
144
|
const roomClearFrame = new RoomClearFrame();
|
|
145
145
|
const roomHistory = new RoomHistory();
|
|
146
|
-
const runInNFrames = new RunInNFrames();
|
|
147
146
|
const runNextRoom = new RunNextRoom();
|
|
148
147
|
const saveDataManager = new SaveDataManager(mod);
|
|
149
148
|
const stageHistory = new StageHistory();
|
|
150
149
|
|
|
150
|
+
const runInNFrames = new RunInNFrames(roomHistory);
|
|
151
|
+
|
|
151
152
|
const customGridEntities = new CustomGridEntities(runInNFrames);
|
|
152
153
|
const moddedElementSets = new ModdedElementSets(moddedElementDetection);
|
|
153
154
|
const itemPoolDetection = new ItemPoolDetection(moddedElementSets);
|