isaacscript-common 21.4.0 → 21.5.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 +186 -3766
- package/dist/isaacscript-common.lua +1055 -973
- package/dist/src/classes/ModFeature.d.ts +2 -2
- package/dist/src/classes/ModFeature.d.ts.map +1 -1
- package/dist/src/classes/{ModUpgradedBase.d.ts → ModUpgraded.d.ts} +20 -32
- package/dist/src/classes/ModUpgraded.d.ts.map +1 -0
- package/dist/src/classes/{ModUpgradedBase.lua → ModUpgraded.lua} +30 -29
- package/dist/src/classes/features/other/DebugDisplay.lua +2 -2
- package/dist/src/classes/features/other/ExtraConsoleCommands.lua +2 -2
- package/dist/src/classes/features/other/extraConsoleCommands/commands.d.ts.map +1 -1
- package/dist/src/classes/features/other/extraConsoleCommands/commands.lua +2 -1
- package/dist/src/classes/private/CustomCallback.d.ts +3 -1
- package/dist/src/classes/private/CustomCallback.d.ts.map +1 -1
- package/dist/src/classes/private/CustomCallback.lua +12 -4
- package/dist/src/core/upgradeMod.d.ts +0 -42
- package/dist/src/core/upgradeMod.d.ts.map +1 -1
- package/dist/src/core/upgradeMod.lua +46 -21
- package/dist/src/features.lua +2 -2
- package/dist/src/functions/console.d.ts +8 -0
- package/dist/src/functions/console.d.ts.map +1 -0
- package/dist/src/functions/console.lua +14 -0
- package/dist/src/functions/deepCopy.d.ts.map +1 -1
- package/dist/src/functions/deepCopy.lua +3 -2
- package/dist/src/functions/enums.d.ts +28 -0
- package/dist/src/functions/enums.d.ts.map +1 -1
- package/dist/src/functions/enums.lua +27 -0
- package/dist/src/functions/globals.lua +3 -3
- package/dist/src/functions/log.d.ts +5 -0
- package/dist/src/functions/log.d.ts.map +1 -1
- package/dist/src/functions/log.lua +6 -0
- package/dist/src/functions/mergeTests.lua +2 -2
- package/dist/src/functions/modFeatures.d.ts +1 -1
- package/dist/src/functions/modFeatures.d.ts.map +1 -1
- package/dist/src/functions/sort.d.ts +38 -0
- package/dist/src/functions/sort.d.ts.map +1 -0
- package/dist/src/functions/sort.lua +95 -0
- package/dist/src/functions/utils.d.ts +0 -54
- package/dist/src/functions/utils.d.ts.map +1 -1
- package/dist/src/functions/utils.lua +0 -91
- package/dist/src/index.d.ts +3 -2
- package/dist/src/index.d.ts.map +1 -1
- package/dist/src/index.lua +17 -1
- package/dist/src/interfaces/private/AddCallbackParametersCustom.lua +2 -2
- package/dist/src/interfaces/private/ModUpgradedInterface.d.ts +4 -2
- package/dist/src/interfaces/private/ModUpgradedInterface.d.ts.map +1 -1
- package/dist/src/types/{ModUpgraded.d.ts → private/ModUpgradedWithFeatures.d.ts} +13 -9
- package/dist/src/types/private/ModUpgradedWithFeatures.d.ts.map +1 -0
- package/dist/src/types/{ModUpgraded.lua → private/ModUpgradedWithFeatures.lua} +0 -0
- package/package.json +1 -1
- package/src/classes/ModFeature.ts +5 -5
- package/src/classes/{ModUpgradedBase.ts → ModUpgraded.ts} +33 -37
- package/src/classes/features/other/DebugDisplay.ts +1 -1
- package/src/classes/features/other/ExtraConsoleCommands.ts +1 -1
- package/src/classes/features/other/extraConsoleCommands/commands.ts +2 -1
- package/src/classes/private/CustomCallback.ts +17 -7
- package/src/core/upgradeMod.ts +55 -29
- package/src/features.ts +1 -1
- package/src/functions/console.ts +15 -0
- package/src/functions/deepCopy.ts +3 -2
- package/src/functions/enums.ts +33 -0
- package/src/functions/globals.ts +2 -2
- package/src/functions/log.ts +9 -0
- package/src/functions/mergeTests.ts +1 -1
- package/src/functions/modFeatures.ts +1 -1
- package/src/functions/sort.ts +128 -0
- package/src/functions/utils.ts +0 -124
- package/src/index.ts +3 -2
- package/src/interfaces/private/AddCallbackParametersCustom.ts +1 -1
- package/src/interfaces/private/ModUpgradedInterface.ts +4 -2
- package/src/types/{ModUpgraded.ts → private/ModUpgradedWithFeatures.ts} +13 -9
- package/dist/src/classes/ModUpgradedBase.d.ts.map +0 -1
- package/dist/src/types/ModUpgraded.d.ts.map +0 -1
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { Feature } from "
|
|
3
|
-
import { ISCFeature } from "
|
|
4
|
-
import { ISCFeatureToClass } from "
|
|
5
|
-
import { PublicInterface } from "
|
|
6
|
-
import { TupleToIntersection } from "
|
|
7
|
-
import { Writeable } from "
|
|
1
|
+
import { ModUpgraded } from "../../classes/ModUpgraded";
|
|
2
|
+
import { Feature } from "../../classes/private/Feature";
|
|
3
|
+
import { ISCFeature } from "../../enums/ISCFeature";
|
|
4
|
+
import { ISCFeatureToClass } from "../../features";
|
|
5
|
+
import { PublicInterface } from "../PublicInterface";
|
|
6
|
+
import { TupleToIntersection } from "../TupleToIntersection";
|
|
7
|
+
import { Writeable } from "../Writable";
|
|
8
8
|
/**
|
|
9
9
|
* `isaacscript-common` has many custom callbacks that you can use in your mods. Instead of
|
|
10
10
|
* hijacking the vanilla `Mod` object, we provide a `ModUpgraded` object for you to use, which
|
|
@@ -14,8 +14,12 @@ import { Writeable } from "./Writable";
|
|
|
14
14
|
*
|
|
15
15
|
* By specifying one or more optional features, end-users will get a version of `ModUpgraded` that
|
|
16
16
|
* has extra methods corresponding to the features that were specified.
|
|
17
|
+
*
|
|
18
|
+
* This type is in the private directory because if it was exported, it would cause all of the
|
|
19
|
+
* internal feature classes to populate the auto-complete of end-user mods (which should never be
|
|
20
|
+
* directly imported by end-users).
|
|
17
21
|
*/
|
|
18
|
-
export type
|
|
22
|
+
export type ModUpgradedWithFeatures<T extends readonly ISCFeature[] = []> = ModUpgraded & ISCFeaturesToKeys<T>;
|
|
19
23
|
/**
|
|
20
24
|
* We want to only extract the class public methods, so we omit the keys of the `Feature` base
|
|
21
25
|
* class.
|
|
@@ -29,4 +33,4 @@ type ISCFeatureTupleToClassTuple<T extends ISCFeature[]> = {
|
|
|
29
33
|
[Key in keyof T]: PublicInterface<ISCFeatureToClass[T[Key]]>;
|
|
30
34
|
};
|
|
31
35
|
export {};
|
|
32
|
-
//# sourceMappingURL=
|
|
36
|
+
//# sourceMappingURL=ModUpgradedWithFeatures.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ModUpgradedWithFeatures.d.ts","sourceRoot":"","sources":["../../../../src/types/private/ModUpgradedWithFeatures.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,2BAA2B,CAAC;AACxD,OAAO,EAAE,OAAO,EAAE,MAAM,+BAA+B,CAAC;AACxD,OAAO,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAC;AACpD,OAAO,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAC;AACnD,OAAO,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC;AACrD,OAAO,EAAE,mBAAmB,EAAE,MAAM,wBAAwB,CAAC;AAC7D,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAExC;;;;;;;;;;;;;GAaG;AACH,MAAM,MAAM,uBAAuB,CAAC,CAAC,SAAS,SAAS,UAAU,EAAE,GAAG,EAAE,IACtE,WAAW,GAAG,iBAAiB,CAAC,CAAC,CAAC,CAAC;AAErC;;;GAGG;AACH,KAAK,iBAAiB,CAAC,CAAC,SAAS,SAAS,UAAU,EAAE,IAAI,IAAI,CAC5D,mBAAmB,CAAC,2BAA2B,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,EAC9D,MAAM,OAAO,CACd,CAAC;AAEF;;;GAGG;AACH,KAAK,2BAA2B,CAAC,CAAC,SAAS,UAAU,EAAE,IAAI;KACxD,GAAG,IAAI,MAAM,CAAC,GAAG,eAAe,CAAC,iBAAiB,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;CAC7D,CAAC"}
|
|
File without changes
|
package/package.json
CHANGED
|
@@ -8,7 +8,7 @@ import {
|
|
|
8
8
|
import { isFunction, isNumber, isTable } from "../functions/types";
|
|
9
9
|
import { TSTLClassMetatable } from "../interfaces/TSTLClassMetatable";
|
|
10
10
|
import { AnyFunction } from "../types/AnyFunction";
|
|
11
|
-
import {
|
|
11
|
+
import { ModUpgraded } from "./ModUpgraded";
|
|
12
12
|
|
|
13
13
|
export const MOD_FEATURE_CALLBACKS_KEY = "__callbacks";
|
|
14
14
|
export const MOD_FEATURE_CUSTOM_CALLBACKS_KEY = "__customCallbacks";
|
|
@@ -62,7 +62,7 @@ type ModFeatureConstructor = TSTLClassMetatable["constructor"] & {
|
|
|
62
62
|
*/
|
|
63
63
|
|
|
64
64
|
export class ModFeature {
|
|
65
|
-
private mod:
|
|
65
|
+
private mod: ModUpgraded;
|
|
66
66
|
|
|
67
67
|
/**
|
|
68
68
|
* An optional method that allows for conditional callback execution. If specified, any class
|
|
@@ -105,7 +105,7 @@ export class ModFeature {
|
|
|
105
105
|
*/
|
|
106
106
|
public initialized = false;
|
|
107
107
|
|
|
108
|
-
constructor(mod:
|
|
108
|
+
constructor(mod: ModUpgraded, init = true) {
|
|
109
109
|
this.mod = mod;
|
|
110
110
|
|
|
111
111
|
if (init) {
|
|
@@ -234,7 +234,7 @@ function initDecoratedCallbacks(
|
|
|
234
234
|
function addCallback(
|
|
235
235
|
modFeature: ModFeature,
|
|
236
236
|
modFeatureConstructor: ModFeatureConstructor,
|
|
237
|
-
mod:
|
|
237
|
+
mod: ModUpgraded,
|
|
238
238
|
modCallback: ModCallback | ModCallbackCustom,
|
|
239
239
|
callback: Function, // eslint-disable-line @typescript-eslint/ban-types
|
|
240
240
|
parameters: unknown[],
|
|
@@ -297,7 +297,7 @@ function addCallback(
|
|
|
297
297
|
|
|
298
298
|
function removeCallback(
|
|
299
299
|
modFeatureConstructor: ModFeatureConstructor,
|
|
300
|
-
mod:
|
|
300
|
+
mod: ModUpgraded,
|
|
301
301
|
modCallback: ModCallback | ModCallbackCustom,
|
|
302
302
|
vanilla: boolean,
|
|
303
303
|
) {
|
|
@@ -24,10 +24,11 @@ import { Feature } from "./private/Feature";
|
|
|
24
24
|
*
|
|
25
25
|
* To upgrade your mod, use the `upgradeMod` helper function.
|
|
26
26
|
*
|
|
27
|
-
*
|
|
28
|
-
*
|
|
27
|
+
* By specifying one or more optional features when upgrading your mod, you will get a version of
|
|
28
|
+
* `ModUpgraded` that has extra methods corresponding to the features that were specified. (This
|
|
29
|
+
* corresponds to the internal-type `ModUpgradedWithFeatures` type, which extends `ModUpgraded`.)
|
|
29
30
|
*/
|
|
30
|
-
export class
|
|
31
|
+
export class ModUpgraded implements Mod {
|
|
31
32
|
// -----------------
|
|
32
33
|
// Vanilla variables
|
|
33
34
|
// -----------------
|
|
@@ -69,11 +70,6 @@ export class ModUpgradedBase implements Mod {
|
|
|
69
70
|
// Vanilla methods
|
|
70
71
|
// ---------------
|
|
71
72
|
|
|
72
|
-
/**
|
|
73
|
-
* Registers a function to be executed when an in-game event happens. For example, the
|
|
74
|
-
* `ModCallback.POST_UPDATE` event corresponds to being executed once at the end of every game
|
|
75
|
-
* logic frame.
|
|
76
|
-
*/
|
|
77
73
|
public AddCallback<T extends ModCallback | string>(
|
|
78
74
|
modCallback: T,
|
|
79
75
|
...args: T extends ModCallback ? AddCallbackParameters[T] : unknown[]
|
|
@@ -141,25 +137,14 @@ export class ModUpgradedBase implements Mod {
|
|
|
141
137
|
}
|
|
142
138
|
}
|
|
143
139
|
|
|
144
|
-
/** Returns whether or not a corresponding "save#.dat" file exists for the current mod. */
|
|
145
140
|
public HasData(): boolean {
|
|
146
141
|
return this.mod.HasData();
|
|
147
142
|
}
|
|
148
143
|
|
|
149
|
-
/**
|
|
150
|
-
* Returns a string containing all of the data inside of the corresponding "save#.dat" file for
|
|
151
|
-
* this mod.
|
|
152
|
-
*/
|
|
153
144
|
public LoadData(): string {
|
|
154
145
|
return this.mod.LoadData();
|
|
155
146
|
}
|
|
156
147
|
|
|
157
|
-
/**
|
|
158
|
-
* Unregisters a function that was previously registered with the `AddCallback` method.
|
|
159
|
-
*
|
|
160
|
-
* This method does not care about the tertiary argument. In other words, regardless of the
|
|
161
|
-
* conditions of how you registered the callback, it will be removed.
|
|
162
|
-
*/
|
|
163
148
|
public RemoveCallback<T extends ModCallback>(
|
|
164
149
|
modCallback: T,
|
|
165
150
|
callback: AddCallbackParameters[T][0],
|
|
@@ -167,14 +152,10 @@ export class ModUpgradedBase implements Mod {
|
|
|
167
152
|
this.mod.RemoveCallback(modCallback, callback);
|
|
168
153
|
}
|
|
169
154
|
|
|
170
|
-
/** Deletes the corresponding "save#.dat" file for this mod, if it exists. */
|
|
171
155
|
public RemoveData(): void {
|
|
172
156
|
this.mod.RemoveData();
|
|
173
157
|
}
|
|
174
158
|
|
|
175
|
-
/**
|
|
176
|
-
* Creates or updates the corresponding "save#.dat" file for this mod with the provided string.
|
|
177
|
-
*/
|
|
178
159
|
public SaveData(data: string): void {
|
|
179
160
|
this.mod.SaveData(data);
|
|
180
161
|
}
|
|
@@ -184,23 +165,46 @@ export class ModUpgradedBase implements Mod {
|
|
|
184
165
|
// ---------------------
|
|
185
166
|
|
|
186
167
|
/**
|
|
187
|
-
* Registers a function to be executed when an in-game event happens.
|
|
188
|
-
*
|
|
189
|
-
*
|
|
168
|
+
* Registers a function to be executed when an in-game event happens.
|
|
169
|
+
*
|
|
170
|
+
* This method is specifically for events that are provided by the IsaacScript standard library.
|
|
171
|
+
* For example, the `ModCallbackCustom.POST_BOMB_EXPLODE` event corresponds to when a bomb
|
|
172
|
+
* explodes.
|
|
190
173
|
*/
|
|
191
174
|
public AddCallbackCustom<T extends ModCallbackCustom>(
|
|
192
175
|
modCallbackCustom: T,
|
|
193
176
|
...args: AddCallbackParametersCustom[T]
|
|
177
|
+
): void {
|
|
178
|
+
this.AddPriorityCallbackCustom(
|
|
179
|
+
modCallbackCustom,
|
|
180
|
+
CallbackPriority.DEFAULT,
|
|
181
|
+
...args,
|
|
182
|
+
);
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
/**
|
|
186
|
+
* The same as the `ModUpgraded.AddCallbackCustom` method, but allows setting a custom priority.
|
|
187
|
+
* By default, callbacks are added with a priority of 0, so this allows you to add early or late
|
|
188
|
+
* callbacks as necessary. See the `CallbackPriority` enum.
|
|
189
|
+
*/
|
|
190
|
+
public AddPriorityCallbackCustom<T extends ModCallbackCustom>(
|
|
191
|
+
modCallbackCustom: T,
|
|
192
|
+
priority: CallbackPriority | int,
|
|
193
|
+
...args: AddCallbackParametersCustom[T]
|
|
194
194
|
): void {
|
|
195
195
|
const callbackClass = this.callbacks[modCallbackCustom];
|
|
196
196
|
// @ts-expect-error The compiler is not smart enough to figure out that the parameters match.
|
|
197
|
-
callbackClass.addSubscriber(...args);
|
|
197
|
+
callbackClass.addSubscriber(priority, ...args);
|
|
198
198
|
this.initFeature(callbackClass);
|
|
199
199
|
}
|
|
200
200
|
|
|
201
201
|
/**
|
|
202
202
|
* Unregisters a function that was previously registered with the `AddCallbackCustom` method.
|
|
203
203
|
*
|
|
204
|
+
* This method is specifically for events that are provided by the IsaacScript standard library.
|
|
205
|
+
* For example, the `ModCallbackCustom.POST_BOMB_EXPLODE` event corresponds to when a bomb
|
|
206
|
+
* explodes.
|
|
207
|
+
*
|
|
204
208
|
* This method does not care about the tertiary argument. In other words, regardless of the
|
|
205
209
|
* conditions of how you registered the callback, it will be removed.
|
|
206
210
|
*/
|
|
@@ -294,8 +298,9 @@ export class ModUpgradedBase implements Mod {
|
|
|
294
298
|
for (const callbackTuple of feature.callbacksUsed) {
|
|
295
299
|
const [modCallback, callbackFunc, optionalArgs] = callbackTuple;
|
|
296
300
|
// TypeScript is not smart enough to know that the arguments match the function.
|
|
297
|
-
(this.
|
|
301
|
+
(this.AddPriorityCallback as AnyFunction)(
|
|
298
302
|
modCallback,
|
|
303
|
+
CallbackPriority.IMPORTANT,
|
|
299
304
|
callbackFunc,
|
|
300
305
|
...(optionalArgs ?? []),
|
|
301
306
|
);
|
|
@@ -398,15 +403,6 @@ export class ModUpgradedBase implements Mod {
|
|
|
398
403
|
|
|
399
404
|
return getExportedMethodsFromFeature(featureClass);
|
|
400
405
|
}
|
|
401
|
-
|
|
402
|
-
/**
|
|
403
|
-
* This is mostly the same as the `AddCustomCallback` method, but we initialize the custom
|
|
404
|
-
* callback without actually registering a subscription.
|
|
405
|
-
*/
|
|
406
|
-
private initCustomCallbackEarly(modCallbackCustom: ModCallbackCustom) {
|
|
407
|
-
const callbackClass = this.callbacks[modCallbackCustom];
|
|
408
|
-
this.initFeature(callbackClass);
|
|
409
|
-
}
|
|
410
406
|
}
|
|
411
407
|
|
|
412
408
|
/**
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { Exported } from "../../../decorators";
|
|
2
|
-
import { printEnabled } from "../../../functions/
|
|
2
|
+
import { printEnabled } from "../../../functions/console";
|
|
3
3
|
import { ModUpgradedInterface } from "../../../interfaces/private/ModUpgradedInterface";
|
|
4
4
|
import { Feature } from "../../private/Feature";
|
|
5
5
|
import { DebugDisplayBomb } from "./debugDisplay/DebugDisplayBomb";
|
|
@@ -8,9 +8,9 @@ import {
|
|
|
8
8
|
} from "isaac-typescript-definitions";
|
|
9
9
|
import { Exported } from "../../../decorators";
|
|
10
10
|
import { ModCallbackCustom } from "../../../enums/ModCallbackCustom";
|
|
11
|
+
import { isVanillaConsoleCommand } from "../../../functions/console";
|
|
11
12
|
import { addFlag, bitFlags } from "../../../functions/flag";
|
|
12
13
|
import { getMapPartialMatch } from "../../../functions/map";
|
|
13
|
-
import { isVanillaConsoleCommand } from "../../../functions/utils";
|
|
14
14
|
import { Feature } from "../../private/Feature";
|
|
15
15
|
import * as commands from "./extraConsoleCommands/commands";
|
|
16
16
|
import { v } from "./extraConsoleCommands/v";
|
|
@@ -75,6 +75,7 @@ import { getCardName } from "../../../../functions/cards";
|
|
|
75
75
|
import { getCharacterName } from "../../../../functions/characters";
|
|
76
76
|
import { addCharge, getTotalCharge } from "../../../../functions/charge";
|
|
77
77
|
import { isValidCollectibleType } from "../../../../functions/collectibles";
|
|
78
|
+
import { printEnabled } from "../../../../functions/console";
|
|
78
79
|
import { runDeepCopyTests } from "../../../../functions/deepCopyTests";
|
|
79
80
|
import { getNPCs } from "../../../../functions/entitiesSpecific";
|
|
80
81
|
import { addFlag } from "../../../../functions/flag";
|
|
@@ -114,7 +115,7 @@ import {
|
|
|
114
115
|
asCollectibleType,
|
|
115
116
|
asTrinketType,
|
|
116
117
|
} from "../../../../functions/types";
|
|
117
|
-
import { iRange
|
|
118
|
+
import { iRange } from "../../../../functions/utils";
|
|
118
119
|
import { CARD_NAME_TO_TYPE_MAP } from "../../../../maps/cardNameToTypeMap";
|
|
119
120
|
import { CHARACTER_NAME_TO_TYPE_MAP } from "../../../../maps/characterNameToTypeMap";
|
|
120
121
|
import { COLLECTIBLE_NAME_TO_TYPE_MAP } from "../../../../maps/collectibleNameToTypeMap";
|
|
@@ -1,4 +1,6 @@
|
|
|
1
|
+
import { CallbackPriority } from "isaac-typescript-definitions/dist/src/enums/CallbackPriority";
|
|
1
2
|
import { ModCallbackCustom } from "../../enums/ModCallbackCustom";
|
|
3
|
+
import { sortObjectArrayByKey } from "../../functions/sort";
|
|
2
4
|
import { AddCallbackParametersCustom } from "../../interfaces/private/AddCallbackParametersCustom";
|
|
3
5
|
import { AllButFirst } from "../../types/AllButFirst";
|
|
4
6
|
import { AnyFunction } from "../../types/AnyFunction";
|
|
@@ -7,14 +9,16 @@ import { Feature } from "./Feature";
|
|
|
7
9
|
export type FireArgs<T extends ModCallbackCustom> = Parameters<
|
|
8
10
|
AddCallbackParametersCustom[T][0]
|
|
9
11
|
>;
|
|
12
|
+
|
|
10
13
|
export type OptionalArgs<T extends ModCallbackCustom> = AllButFirst<
|
|
11
14
|
AddCallbackParametersCustom[T]
|
|
12
15
|
>;
|
|
13
16
|
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
]
|
|
17
|
+
interface Subscription<T extends ModCallbackCustom> {
|
|
18
|
+
priority: CallbackPriority | int;
|
|
19
|
+
callbackFunc: AddCallbackParametersCustom[T][0];
|
|
20
|
+
optionalArgs: AllButFirst<AddCallbackParametersCustom[T]>;
|
|
21
|
+
}
|
|
18
22
|
|
|
19
23
|
/**
|
|
20
24
|
* The base class for a custom callback. Individual custom callbacks (and validation callbacks) will
|
|
@@ -26,11 +30,17 @@ export abstract class CustomCallback<
|
|
|
26
30
|
private subscriptions: Array<Subscription<T>> = [];
|
|
27
31
|
|
|
28
32
|
public addSubscriber(
|
|
33
|
+
priority: CallbackPriority | int,
|
|
29
34
|
callbackFunc: AddCallbackParametersCustom[T][0],
|
|
30
35
|
...optionalArgs: AllButFirst<AddCallbackParametersCustom[T]>
|
|
31
36
|
): void {
|
|
32
|
-
const subscription: Subscription<T> =
|
|
37
|
+
const subscription: Subscription<T> = {
|
|
38
|
+
priority,
|
|
39
|
+
callbackFunc,
|
|
40
|
+
optionalArgs,
|
|
41
|
+
};
|
|
33
42
|
this.subscriptions.push(subscription);
|
|
43
|
+
this.subscriptions.sort(sortObjectArrayByKey("priority"));
|
|
34
44
|
}
|
|
35
45
|
|
|
36
46
|
/**
|
|
@@ -40,7 +50,7 @@ export abstract class CustomCallback<
|
|
|
40
50
|
public removeSubscriber(callback: AddCallbackParametersCustom[T][0]): void {
|
|
41
51
|
const subscriptionIndexMatchingCallback = this.subscriptions.findIndex(
|
|
42
52
|
(subscription) => {
|
|
43
|
-
const subscriptionCallback = subscription
|
|
53
|
+
const subscriptionCallback = subscription.callbackFunc;
|
|
44
54
|
return callback === subscriptionCallback;
|
|
45
55
|
},
|
|
46
56
|
);
|
|
@@ -53,7 +63,7 @@ export abstract class CustomCallback<
|
|
|
53
63
|
...fireArgs: FireArgs<T>
|
|
54
64
|
): ReturnType<AddCallbackParametersCustom[T][0]> => {
|
|
55
65
|
for (const subscription of this.subscriptions) {
|
|
56
|
-
const
|
|
66
|
+
const { callbackFunc, optionalArgs } = subscription;
|
|
57
67
|
|
|
58
68
|
if (this.shouldFire(fireArgs, optionalArgs)) {
|
|
59
69
|
// TypeScript is not smart enough to know that the arguments match the function.
|
package/src/core/upgradeMod.ts
CHANGED
|
@@ -1,10 +1,9 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { ModUpgraded } from "../classes/ModUpgraded";
|
|
2
2
|
import { ISCFeature } from "../enums/ISCFeature";
|
|
3
|
-
import { ModCallbackCustom } from "../enums/ModCallbackCustom";
|
|
4
3
|
import { patchErrorFunction } from "../patchErrorFunctions";
|
|
5
4
|
import { applyShaderCrashFix } from "../shaderCrashFix";
|
|
6
5
|
import { AnyFunction } from "../types/AnyFunction";
|
|
7
|
-
import {
|
|
6
|
+
import { ModUpgradedWithFeatures } from "../types/private/ModUpgradedWithFeatures";
|
|
8
7
|
|
|
9
8
|
type ISCFeatureTuple<T extends readonly ISCFeature[]> =
|
|
10
9
|
ISCFeature extends T["length"]
|
|
@@ -31,28 +30,68 @@ type ISCFeatureTuple<T extends readonly ISCFeature[]> =
|
|
|
31
30
|
* @param modVanilla The mod object returned by the `RegisterMod` function.
|
|
32
31
|
* @param features Optional. An array containing the optional standard library features that you
|
|
33
32
|
* want to enable, if any. Default is an empty array.
|
|
34
|
-
* @param customCallbacksUsed Optional. An array containing the custom callbacks that you will be
|
|
35
|
-
* subscribing to after you upgrade your mod. Specifying this will
|
|
36
|
-
* immediately initialize the callbacks (as opposed to lazy-initializing
|
|
37
|
-
* them when you first subscribe to the callback). This is only necessary
|
|
38
|
-
* if you the order of callback firing is important for your mod. (For
|
|
39
|
-
* example, you may want the `POST_NEW_ROOM` part of the
|
|
40
|
-
* `POST_GRID_ENTITY_INIT` callback to fire before your own
|
|
41
|
-
* `POST_NEW_ROOM` callbacks.)
|
|
42
33
|
* @param debug Optional. Whether to log additional output when a callback is fired. Default is
|
|
43
34
|
* false.
|
|
44
35
|
* @param timeThreshold Optional. If provided, will only log callbacks that take longer than the
|
|
45
36
|
* specified number of seconds (if the "--luadebug" launch flag is turned on)
|
|
46
37
|
* or milliseconds (if the "--luadebug" launch flag is turned off).
|
|
47
38
|
* @returns The upgraded mod object.
|
|
39
|
+
* @notExported
|
|
40
|
+
* @rename upgradeMod
|
|
48
41
|
*/
|
|
42
|
+
// We duplicate the definition for `upgradeMod` because the original one has to be marked internal.
|
|
43
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
44
|
+
function upgradeModDocumentation(
|
|
45
|
+
modVanilla: Mod,
|
|
46
|
+
features: ISCFeature[] = [],
|
|
47
|
+
debug = false,
|
|
48
|
+
timeThreshold?: float,
|
|
49
|
+
): ModUpgraded {
|
|
50
|
+
print(modVanilla);
|
|
51
|
+
print(features);
|
|
52
|
+
print(debug);
|
|
53
|
+
print(timeThreshold);
|
|
54
|
+
|
|
55
|
+
const mod = RegisterMod("", 1);
|
|
56
|
+
return new ModUpgraded(mod, false);
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
/**
|
|
60
|
+
* Use this function to enable the custom callbacks and other optional features provided by
|
|
61
|
+
* `isaacscript-common`.
|
|
62
|
+
*
|
|
63
|
+
* For example:
|
|
64
|
+
*
|
|
65
|
+
* ```ts
|
|
66
|
+
* const modVanilla = RegisterMod("My Mod", 1);
|
|
67
|
+
* const mod = upgradeMod(modVanilla);
|
|
68
|
+
*
|
|
69
|
+
* // Subscribe to vanilla callbacks.
|
|
70
|
+
* mod.AddCallback(ModCallback.POST_UPDATE, postUpdate);
|
|
71
|
+
*
|
|
72
|
+
* // Subscribe to custom callbacks.
|
|
73
|
+
* mod.AddCallbackCustom(ModCallbackCustom.POST_ITEM_PICKUP, postItemPickup);
|
|
74
|
+
* ```
|
|
75
|
+
*
|
|
76
|
+
* @param modVanilla The mod object returned by the `RegisterMod` function.
|
|
77
|
+
* @param features Optional. An array containing the optional standard library features that you
|
|
78
|
+
* want to enable, if any. Default is an empty array.
|
|
79
|
+
* @param debug Optional. Whether to log additional output when a callback is fired. Default is
|
|
80
|
+
* false.
|
|
81
|
+
* @param timeThreshold Optional. If provided, will only log callbacks that take longer than the
|
|
82
|
+
* specified number of seconds (if the "--luadebug" launch flag is turned on)
|
|
83
|
+
* or milliseconds (if the "--luadebug" launch flag is turned off).
|
|
84
|
+
* @returns The upgraded mod object.
|
|
85
|
+
* @internal
|
|
86
|
+
*/
|
|
87
|
+
// This has to be marked internal or else it will cause all of the feature classes to be included in
|
|
88
|
+
// the output of `api-extractor`.
|
|
49
89
|
export function upgradeMod<T extends readonly ISCFeature[] = never[]>(
|
|
50
90
|
modVanilla: Mod,
|
|
51
91
|
features: ISCFeatureTuple<T> = [] as unknown as ISCFeatureTuple<T>,
|
|
52
|
-
customCallbacksUsed: ModCallbackCustom[] | readonly ModCallbackCustom[] = [],
|
|
53
92
|
debug = false,
|
|
54
93
|
timeThreshold?: float,
|
|
55
|
-
):
|
|
94
|
+
): ModUpgradedWithFeatures<T> {
|
|
56
95
|
// First, validate that all of the features exist (for Lua users who don't have type-safety).
|
|
57
96
|
for (const feature of features) {
|
|
58
97
|
const featureType = type(feature);
|
|
@@ -65,16 +104,15 @@ export function upgradeMod<T extends readonly ISCFeature[] = never[]>(
|
|
|
65
104
|
|
|
66
105
|
patchErrorFunction();
|
|
67
106
|
|
|
68
|
-
const mod = new
|
|
107
|
+
const mod = new ModUpgraded(modVanilla, debug, timeThreshold);
|
|
69
108
|
applyShaderCrashFix(mod);
|
|
70
109
|
initOptionalFeatures(mod, features as ISCFeature[]);
|
|
71
|
-
initCallbacksEarly(mod, customCallbacksUsed);
|
|
72
110
|
|
|
73
|
-
return mod as
|
|
111
|
+
return mod as ModUpgradedWithFeatures<T>;
|
|
74
112
|
}
|
|
75
113
|
|
|
76
114
|
/** Initialize every optional feature that the end-user specified. */
|
|
77
|
-
function initOptionalFeatures(mod:
|
|
115
|
+
function initOptionalFeatures(mod: ModUpgraded, features: ISCFeature[]) {
|
|
78
116
|
for (const feature of features) {
|
|
79
117
|
// We intentionally access the private method here, so we use the string index escape hatch:
|
|
80
118
|
// https://github.com/microsoft/TypeScript/issues/19335
|
|
@@ -89,15 +127,3 @@ function initOptionalFeatures(mod: ModUpgradedBase, features: ISCFeature[]) {
|
|
|
89
127
|
}
|
|
90
128
|
}
|
|
91
129
|
}
|
|
92
|
-
|
|
93
|
-
function initCallbacksEarly(
|
|
94
|
-
mod: ModUpgradedBase,
|
|
95
|
-
callbacks: ModCallbackCustom[] | readonly ModCallbackCustom[],
|
|
96
|
-
) {
|
|
97
|
-
for (const modCallbackCustom of callbacks) {
|
|
98
|
-
// We intentionally access the private method here, so we use the string index escape hatch:
|
|
99
|
-
// https://github.com/microsoft/TypeScript/issues/19335
|
|
100
|
-
// eslint-disable-next-line @typescript-eslint/dot-notation
|
|
101
|
-
mod["initCustomCallbackEarly"](modCallbackCustom);
|
|
102
|
-
}
|
|
103
|
-
}
|
package/src/features.ts
CHANGED
|
@@ -56,7 +56,7 @@ import { TaintedLazarusPlayers } from "./classes/features/other/TaintedLazarusPl
|
|
|
56
56
|
import { Feature } from "./classes/private/Feature";
|
|
57
57
|
import { ISCFeature } from "./enums/ISCFeature";
|
|
58
58
|
import { ModCallbackCustom } from "./enums/ModCallbackCustom";
|
|
59
|
-
import { validateInterfaceMatchesEnum } from "./functions/
|
|
59
|
+
import { validateInterfaceMatchesEnum } from "./functions/enums";
|
|
60
60
|
import { ModUpgradedInterface } from "./interfaces/private/ModUpgradedInterface";
|
|
61
61
|
|
|
62
62
|
export interface ISCFeatureToClass {
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { CONSOLE_COMMANDS_SET } from "../sets/consoleCommandsSet";
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Helper function to see if a particular command is a vanilla console command. This is useful
|
|
5
|
+
* because the `EXECUTE_CMD` callback will not fire for any vanilla commands.
|
|
6
|
+
*/
|
|
7
|
+
export function isVanillaConsoleCommand(commandName: string): boolean {
|
|
8
|
+
return CONSOLE_COMMANDS_SET.has(commandName);
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
/** Helper function to print whether something was enabled or disabled to the in-game console. */
|
|
12
|
+
export function printEnabled(enabled: boolean, description: string): void {
|
|
13
|
+
const enabledText = enabled ? "Enabled" : "Disabled";
|
|
14
|
+
print(`${enabledText} ${description}.`);
|
|
15
|
+
}
|
|
@@ -15,6 +15,7 @@ import {
|
|
|
15
15
|
isSerializedIsaacAPIClass,
|
|
16
16
|
serializeIsaacAPIClass,
|
|
17
17
|
} from "./serialization";
|
|
18
|
+
import { sortTwoDimensionalArray } from "./sort";
|
|
18
19
|
import {
|
|
19
20
|
getTSTLClassName,
|
|
20
21
|
isDefaultMap,
|
|
@@ -23,7 +24,7 @@ import {
|
|
|
23
24
|
newTSTLClass,
|
|
24
25
|
} from "./tstlClass";
|
|
25
26
|
import { asString, isNumber, isPrimitive } from "./types";
|
|
26
|
-
import { getTraversalDescription
|
|
27
|
+
import { getTraversalDescription } from "./utils";
|
|
27
28
|
|
|
28
29
|
/**
|
|
29
30
|
* `deepCopy` is a semi-generic deep cloner. It will recursively copy all of the values so that none
|
|
@@ -642,7 +643,7 @@ function getCopiedEntries(
|
|
|
642
643
|
}
|
|
643
644
|
|
|
644
645
|
if (SAVE_DATA_MANAGER_DEBUG) {
|
|
645
|
-
entries.sort(
|
|
646
|
+
entries.sort(sortTwoDimensionalArray);
|
|
646
647
|
}
|
|
647
648
|
|
|
648
649
|
// During serialization, we brand some Lua tables with a special identifier to signify that it has
|
package/src/functions/enums.ts
CHANGED
|
@@ -186,3 +186,36 @@ export function validateEnumContiguous<T>(
|
|
|
186
186
|
}
|
|
187
187
|
}
|
|
188
188
|
}
|
|
189
|
+
|
|
190
|
+
/**
|
|
191
|
+
* Helper function to validate that an interface contains all of the keys of an enum. You must
|
|
192
|
+
* specify both generic parameters in order for this to work properly (i.e. the interface and then
|
|
193
|
+
* the enum).
|
|
194
|
+
*
|
|
195
|
+
* For example:
|
|
196
|
+
*
|
|
197
|
+
* ```ts
|
|
198
|
+
* enum MyEnum {
|
|
199
|
+
* Value1,
|
|
200
|
+
* Value2,
|
|
201
|
+
* Value3,
|
|
202
|
+
* }
|
|
203
|
+
*
|
|
204
|
+
* interface MyEnumToType {
|
|
205
|
+
* [MyEnum.Value1]: boolean;
|
|
206
|
+
* [MyEnum.Value2]: number;
|
|
207
|
+
* [MyEnum.Value3]: string;
|
|
208
|
+
* }
|
|
209
|
+
*
|
|
210
|
+
* validateInterfaceMatchesEnum<MyEnumToType, MyEnum>();
|
|
211
|
+
* ```
|
|
212
|
+
*
|
|
213
|
+
* This function is only meant to be used with interfaces (i.e. types that will not exist at
|
|
214
|
+
* run-time). If you are generating an object that will contain all of the keys of an enum, use the
|
|
215
|
+
* `satisfies` operator with the `Record` type instead.
|
|
216
|
+
*/
|
|
217
|
+
export function validateInterfaceMatchesEnum<
|
|
218
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
219
|
+
T extends Record<Enum, unknown>,
|
|
220
|
+
Enum extends string | number,
|
|
221
|
+
>(): void {}
|
package/src/functions/globals.ts
CHANGED
|
@@ -5,7 +5,7 @@ import { log } from "./log";
|
|
|
5
5
|
import * as logEntitiesExports from "./logEntities";
|
|
6
6
|
import * as logMiscExports from "./logMisc";
|
|
7
7
|
import { addSetsToSet, copySet } from "./set";
|
|
8
|
-
import {
|
|
8
|
+
import { sortTwoDimensionalArray } from "./sort";
|
|
9
9
|
|
|
10
10
|
const DEFAULT_GLOBALS = new ReadonlySet<string>([
|
|
11
11
|
"ActionTriggers",
|
|
@@ -226,7 +226,7 @@ export function getNewGlobals(): ReadonlyArray<[AnyNotNil, unknown]> {
|
|
|
226
226
|
}
|
|
227
227
|
}
|
|
228
228
|
|
|
229
|
-
newGlobals.sort(
|
|
229
|
+
newGlobals.sort(sortTwoDimensionalArray);
|
|
230
230
|
|
|
231
231
|
return newGlobals;
|
|
232
232
|
}
|
package/src/functions/log.ts
CHANGED
|
@@ -65,3 +65,12 @@ export function log(
|
|
|
65
65
|
: `${parentFunctionDescription} - ${msg}`;
|
|
66
66
|
Isaac.DebugString(debugMsg);
|
|
67
67
|
}
|
|
68
|
+
|
|
69
|
+
/**
|
|
70
|
+
* Helper function to log a message to the "log.txt" file and to print it to the screen at the same
|
|
71
|
+
* time.
|
|
72
|
+
*/
|
|
73
|
+
export function logAndPrint(msg: string): void {
|
|
74
|
+
log(msg);
|
|
75
|
+
print(msg);
|
|
76
|
+
}
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import { DefaultMap } from "../classes/DefaultMap";
|
|
2
2
|
import { SerializationType } from "../enums/SerializationType";
|
|
3
3
|
import { deepCopy } from "./deepCopy";
|
|
4
|
+
import { logAndPrint } from "./log";
|
|
4
5
|
import { merge } from "./merge";
|
|
5
6
|
import { isRNG, newRNG } from "./rng";
|
|
6
7
|
import { isSerializedIsaacAPIClass } from "./serialization";
|
|
7
|
-
import { logAndPrint } from "./utils";
|
|
8
8
|
import { isVector, serializeVector } from "./vector";
|
|
9
9
|
|
|
10
10
|
/**
|