isaacscript-common 6.22.4 → 7.1.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/callbacks/postPlayerChangeHealth.lua +8 -1
- package/dist/callbacks/postPlayerChangeStat.d.ts +3 -0
- package/dist/callbacks/postPlayerChangeStat.d.ts.map +1 -0
- package/dist/callbacks/postPlayerChangeStat.lua +59 -0
- package/dist/callbacks/subscriptions/postPlayerChangeHealth.d.ts +2 -2
- package/dist/callbacks/subscriptions/postPlayerChangeHealth.d.ts.map +1 -1
- package/dist/callbacks/subscriptions/postPlayerChangeHealth.lua +9 -2
- package/dist/callbacks/subscriptions/postPlayerChangeStat.d.ts +12 -0
- package/dist/callbacks/subscriptions/postPlayerChangeStat.d.ts.map +1 -0
- package/dist/callbacks/subscriptions/postPlayerChangeStat.lua +35 -0
- package/dist/classes/DefaultMap.d.ts +3 -3
- package/dist/classes/DefaultMap.d.ts.map +1 -1
- package/dist/classes/DefaultMap.lua +37 -0
- package/dist/core/constants.d.ts +1 -1
- package/dist/core/constants.d.ts.map +1 -1
- package/dist/core/constants.lua +1 -1
- package/dist/enums/ModCallbackCustom.d.ts +70 -39
- package/dist/enums/ModCallbackCustom.d.ts.map +1 -1
- package/dist/enums/ModCallbackCustom.lua +37 -35
- package/dist/enums/StatType.d.ts +30 -0
- package/dist/enums/StatType.d.ts.map +1 -0
- package/dist/enums/StatType.lua +30 -0
- package/dist/enums/index.d.ts +1 -0
- package/dist/enums/index.d.ts.map +1 -1
- package/dist/enums/index.lua +8 -0
- package/dist/enums/private/CopyableIsaacAPIClassType.d.ts +5 -1
- package/dist/enums/private/CopyableIsaacAPIClassType.d.ts.map +1 -1
- package/dist/enums/private/CopyableIsaacAPIClassType.lua +3 -1
- package/dist/enums/private/SerializationBrand.d.ts +1 -0
- package/dist/enums/private/SerializationBrand.d.ts.map +1 -1
- package/dist/enums/private/SerializationBrand.lua +1 -0
- package/dist/features/customStage/versusScreen.lua +2 -2
- package/dist/features/disableInputs.d.ts +1 -1
- package/dist/features/disableInputs.d.ts.map +1 -1
- package/dist/features/runInNFrames.lua +1 -6
- package/dist/features/runNextRoom.lua +1 -6
- package/dist/features/saveDataManager/exports.d.ts +13 -8
- package/dist/features/saveDataManager/exports.d.ts.map +1 -1
- package/dist/features/saveDataManager/exports.lua +12 -7
- package/dist/features/saveDataManager/maps.d.ts +2 -2
- package/dist/features/saveDataManager/maps.d.ts.map +1 -1
- package/dist/features/saveDataManager/merge.d.ts +1 -0
- package/dist/features/saveDataManager/merge.d.ts.map +1 -1
- package/dist/features/saveDataManager/merge.lua +1 -0
- package/dist/features/taintedLazarusPlayers.lua +1 -6
- package/dist/functions/bitSet128.d.ts +25 -0
- package/dist/functions/bitSet128.d.ts.map +1 -0
- package/dist/functions/bitSet128.lua +71 -0
- package/dist/functions/collectibles.d.ts +2 -2
- package/dist/functions/collectibles.lua +2 -2
- package/dist/functions/color.d.ts +1 -1
- package/dist/functions/color.d.ts.map +1 -1
- package/dist/functions/color.lua +2 -2
- package/dist/functions/deepCopy.d.ts +1 -0
- package/dist/functions/deepCopy.d.ts.map +1 -1
- package/dist/functions/deepCopy.lua +2 -1
- package/dist/functions/familiars.d.ts +4 -4
- package/dist/functions/familiars.lua +4 -4
- package/dist/functions/flag.d.ts +1 -1
- package/dist/functions/flag.lua +1 -1
- package/dist/functions/index.d.ts +2 -0
- package/dist/functions/index.d.ts.map +1 -1
- package/dist/functions/index.lua +16 -0
- package/dist/functions/isaacAPIClass.d.ts +1 -1
- package/dist/functions/isaacAPIClass.d.ts.map +1 -1
- package/dist/functions/jsonRoom.lua +4 -4
- package/dist/functions/kColor.d.ts +1 -1
- package/dist/functions/kColor.d.ts.map +1 -1
- package/dist/functions/kColor.lua +2 -2
- package/dist/functions/log.lua +1 -1
- package/dist/functions/npcs.d.ts +2 -2
- package/dist/functions/npcs.lua +2 -2
- package/dist/functions/playerIndex.d.ts +1 -1
- package/dist/functions/playerIndex.lua +1 -1
- package/dist/functions/playerStats.d.ts +6 -0
- package/dist/functions/playerStats.d.ts.map +1 -0
- package/dist/functions/playerStats.lua +22 -0
- package/dist/functions/players.d.ts +1 -1
- package/dist/functions/players.lua +1 -1
- package/dist/functions/rng.d.ts +1 -1
- package/dist/functions/rng.d.ts.map +1 -1
- package/dist/functions/rng.lua +2 -2
- package/dist/functions/roomTransition.d.ts +1 -1
- package/dist/functions/roomTransition.lua +1 -1
- package/dist/functions/rooms.d.ts +1 -1
- package/dist/functions/rooms.lua +1 -1
- package/dist/functions/sprites.d.ts +3 -3
- package/dist/functions/sprites.lua +3 -3
- package/dist/functions/tears.d.ts +5 -4
- package/dist/functions/tears.d.ts.map +1 -1
- package/dist/functions/tears.lua +5 -4
- package/dist/functions/utils.d.ts +4 -1
- package/dist/functions/utils.d.ts.map +1 -1
- package/dist/functions/utils.lua +4 -1
- package/dist/functions/vector.d.ts +1 -1
- package/dist/functions/vector.d.ts.map +1 -1
- package/dist/functions/vector.lua +2 -2
- package/dist/initCustomCallbacks.d.ts.map +1 -1
- package/dist/initCustomCallbacks.lua +3 -0
- package/dist/interfaces/SaveData.d.ts +44 -8
- package/dist/interfaces/SaveData.d.ts.map +1 -1
- package/dist/interfaces/SaveData.lua +66 -0
- package/dist/interfaces/StatTypeType.d.ts +18 -0
- package/dist/interfaces/StatTypeType.d.ts.map +1 -0
- package/dist/interfaces/StatTypeType.lua +4 -0
- package/dist/interfaces/index.d.ts +1 -0
- package/dist/interfaces/index.d.ts.map +1 -1
- package/dist/interfaces/private/AddCallbackParameterCustom.d.ts +2 -0
- package/dist/interfaces/private/AddCallbackParameterCustom.d.ts.map +1 -1
- package/dist/objects/callbackRegisterFunctions.d.ts.map +1 -1
- package/dist/objects/callbackRegisterFunctions.lua +3 -0
- package/dist/objects/isaacAPIClassTypeToBrand.d.ts.map +1 -1
- package/dist/objects/isaacAPIClassTypeToBrand.lua +7 -1
- package/dist/objects/isaacAPIClassTypeToFunctions.d.ts.map +1 -1
- package/dist/objects/isaacAPIClassTypeToFunctions.lua +12 -1
- package/dist/types/index.d.ts +0 -1
- package/dist/types/index.d.ts.map +1 -1
- package/package.json +2 -2
- package/src/callbacks/postPlayerChangeHealth.ts +7 -1
- package/src/callbacks/postPlayerChangeStat.ts +68 -0
- package/src/callbacks/subscriptions/postPlayerChangeHealth.ts +5 -1
- package/src/callbacks/subscriptions/postPlayerChangeStat.ts +55 -0
- package/src/classes/DefaultMap.ts +36 -7
- package/src/core/constants.ts +1 -1
- package/src/enums/ModCallbackCustom.ts +36 -4
- package/src/enums/StatType.ts +47 -0
- package/src/enums/index.ts +1 -0
- package/src/enums/indexTypeDoc.ts +1 -0
- package/src/enums/private/CopyableIsaacAPIClassType.ts +5 -1
- package/src/enums/private/SerializationBrand.ts +1 -0
- package/src/features/customStage/versusScreen.ts +2 -2
- package/src/features/disableInputs.ts +3 -9
- package/src/features/runInNFrames.ts +1 -1
- package/src/features/runNextRoom.ts +1 -1
- package/src/features/saveDataManager/exports.ts +28 -10
- package/src/features/saveDataManager/merge.ts +1 -0
- package/src/features/saveDataManager/save.ts +2 -1
- package/src/features/taintedLazarusPlayers.ts +2 -2
- package/src/functions/bitSet128.ts +96 -0
- package/src/functions/collectibles.ts +2 -2
- package/src/functions/color.ts +3 -2
- package/src/functions/deepCopy.ts +2 -1
- package/src/functions/entities.ts +2 -2
- package/src/functions/familiars.ts +4 -4
- package/src/functions/flag.ts +1 -1
- package/src/functions/index.ts +2 -0
- package/src/functions/indexTypeDoc.ts +2 -0
- package/src/functions/isaacAPIClass.ts +0 -1
- package/src/functions/jsonRoom.ts +4 -4
- package/src/functions/kColor.ts +2 -2
- package/src/functions/log.ts +1 -1
- package/src/functions/npcs.ts +2 -2
- package/src/functions/playerIndex.ts +1 -1
- package/src/functions/playerStats.ts +26 -0
- package/src/functions/players.ts +1 -1
- package/src/functions/rng.ts +2 -2
- package/src/functions/roomTransition.ts +1 -1
- package/src/functions/rooms.ts +1 -1
- package/src/functions/sprites.ts +3 -3
- package/src/functions/tears.ts +5 -4
- package/src/functions/utils.ts +5 -1
- package/src/functions/vector.ts +2 -2
- package/src/initCustomCallbacks.ts +2 -0
- package/src/interfaces/SaveData.ts +256 -8
- package/src/interfaces/StatTypeType.ts +18 -0
- package/src/interfaces/index.ts +1 -0
- package/src/interfaces/indexTypeDoc.ts +1 -0
- package/src/interfaces/private/AddCallbackParameterCustom.ts +2 -0
- package/src/objects/callbackRegisterFunctions.ts +2 -0
- package/src/objects/isaacAPIClassTypeToBrand.ts +1 -0
- package/src/objects/isaacAPIClassTypeToFunctions.ts +12 -0
- package/src/types/index.ts +0 -1
- package/src/types/indexTypeDoc.ts +0 -1
- package/dist/classes/indexTypeDoc.d.ts +0 -3
- package/dist/classes/indexTypeDoc.d.ts.map +0 -1
- package/dist/classes/indexTypeDoc.lua +0 -4
- package/dist/core/indexTypeDoc.d.ts +0 -5
- package/dist/core/indexTypeDoc.d.ts.map +0 -1
- package/dist/core/indexTypeDoc.lua +0 -6
- package/dist/enums/indexTypeDoc.d.ts +0 -9
- package/dist/enums/indexTypeDoc.d.ts.map +0 -1
- package/dist/enums/indexTypeDoc.lua +0 -10
- package/dist/features/indexTypeDoc.d.ts +0 -30
- package/dist/features/indexTypeDoc.d.ts.map +0 -1
- package/dist/features/indexTypeDoc.lua +0 -31
- package/dist/functions/indexTypeDoc.d.ts +0 -99
- package/dist/functions/indexTypeDoc.d.ts.map +0 -1
- package/dist/functions/indexTypeDoc.lua +0 -100
- package/dist/indexTypeDoc.d.ts +0 -10
- package/dist/indexTypeDoc.d.ts.map +0 -1
- package/dist/indexTypeDoc.lua +0 -11
- package/dist/interfaces/indexTypeDoc.d.ts +0 -11
- package/dist/interfaces/indexTypeDoc.d.ts.map +0 -1
- package/dist/interfaces/indexTypeDoc.lua +0 -2
- package/dist/maps/indexTypeDoc.d.ts +0 -5
- package/dist/maps/indexTypeDoc.d.ts.map +0 -1
- package/dist/maps/indexTypeDoc.lua +0 -6
- package/dist/objects/indexTypeDoc.d.ts +0 -2
- package/dist/objects/indexTypeDoc.d.ts.map +0 -1
- package/dist/objects/indexTypeDoc.lua +0 -3
- package/dist/types/IsaacAPIClass.d.ts +0 -5
- package/dist/types/IsaacAPIClass.d.ts.map +0 -1
- package/dist/types/IsaacAPIClass.lua +0 -2
- package/dist/types/indexTypeDoc.d.ts +0 -12
- package/dist/types/indexTypeDoc.d.ts.map +0 -1
- package/dist/types/indexTypeDoc.lua +0 -3
- package/src/types/IsaacAPIClass.ts +0 -3
|
@@ -5,9 +5,7 @@ import { isFunction, isPrimitive } from "../functions/types";
|
|
|
5
5
|
* A function that creates the default value for your `DefaultMap`. For example, if it was a
|
|
6
6
|
* `DefaultMap` containing maps, the factory function would be: `() => new Map()`
|
|
7
7
|
*/
|
|
8
|
-
export type FactoryFunction<V, Args extends unknown[]> = (
|
|
9
|
-
...extraArgs: Args
|
|
10
|
-
) => V;
|
|
8
|
+
export type FactoryFunction<V, Args extends unknown[]> = (...args: Args) => V;
|
|
11
9
|
|
|
12
10
|
/**
|
|
13
11
|
* `DefaultMap` is a data structure that makes working with default values easier.
|
|
@@ -127,13 +125,13 @@ export class DefaultMap<Key, Value, Args extends unknown[] = []> extends Map<
|
|
|
127
125
|
* If the key exists, this will return the same thing as the normal `Map.get` method. Otherwise,
|
|
128
126
|
* it will set a default value for the provided key, and then return the default value.
|
|
129
127
|
*/
|
|
130
|
-
getAndSetDefault(key: Key, ...
|
|
128
|
+
getAndSetDefault(key: Key, ...args: Args): Value {
|
|
131
129
|
const value = super.get(key);
|
|
132
130
|
if (value !== undefined) {
|
|
133
131
|
return value;
|
|
134
132
|
}
|
|
135
133
|
|
|
136
|
-
const defaultValue = this.getDefaultValue(...
|
|
134
|
+
const defaultValue = this.getDefaultValue(...args);
|
|
137
135
|
this.set(key, defaultValue);
|
|
138
136
|
return defaultValue;
|
|
139
137
|
}
|
|
@@ -142,13 +140,13 @@ export class DefaultMap<Key, Value, Args extends unknown[] = []> extends Map<
|
|
|
142
140
|
* Returns the default value to be used for a new key. (If a factory function was provided during
|
|
143
141
|
* instantiation, this will execute the factory function.)
|
|
144
142
|
*/
|
|
145
|
-
getDefaultValue(...
|
|
143
|
+
getDefaultValue(...args: Args): Value {
|
|
146
144
|
if (this.defaultValue !== undefined) {
|
|
147
145
|
return this.defaultValue;
|
|
148
146
|
}
|
|
149
147
|
|
|
150
148
|
if (this.defaultValueFactory !== undefined) {
|
|
151
|
-
return this.defaultValueFactory(...
|
|
149
|
+
return this.defaultValueFactory(...args);
|
|
152
150
|
}
|
|
153
151
|
|
|
154
152
|
error("A DefaultMap was incorrectly instantiated.");
|
|
@@ -170,3 +168,34 @@ export class DefaultMap<Key, Value, Args extends unknown[] = []> extends Map<
|
|
|
170
168
|
error("A DefaultMap was incorrectly instantiated.");
|
|
171
169
|
}
|
|
172
170
|
}
|
|
171
|
+
|
|
172
|
+
/* eslint-disable @typescript-eslint/no-unused-vars */
|
|
173
|
+
function test() {
|
|
174
|
+
// Boolean
|
|
175
|
+
const myDefaultMapBoolean = new DefaultMap<string, boolean>(false);
|
|
176
|
+
const myDefaultMapBooleanFactory = new DefaultMap<string, boolean>(
|
|
177
|
+
() => false,
|
|
178
|
+
);
|
|
179
|
+
const myDefaultMapBooleanWithoutParams = new DefaultMap(false);
|
|
180
|
+
|
|
181
|
+
// Number
|
|
182
|
+
const myDefaultMapNumber = new DefaultMap<string, number>(123);
|
|
183
|
+
const myDefaultMapNumberFactory = new DefaultMap<string, number>(() => 123);
|
|
184
|
+
const myDefaultMapNumberWithoutParams = new DefaultMap(123);
|
|
185
|
+
|
|
186
|
+
// String
|
|
187
|
+
const myDefaultMapString = new DefaultMap<string, string>("foo");
|
|
188
|
+
const myDefaultMapStringFactory = new DefaultMap<string, string>(() => "foo");
|
|
189
|
+
const myDefaultMapStringWithoutParams = new DefaultMap("foo");
|
|
190
|
+
|
|
191
|
+
// Array
|
|
192
|
+
const myDefaultMapArray = new DefaultMap<string, string[]>(() => []);
|
|
193
|
+
const myDefaultMapArrayWithoutParams = new DefaultMap(() => []);
|
|
194
|
+
|
|
195
|
+
// Map
|
|
196
|
+
const myDefaultMapMap = new DefaultMap<string, Map<string, string>>(
|
|
197
|
+
() => new Map(),
|
|
198
|
+
);
|
|
199
|
+
const myDefaultMapMapWithoutParams = new DefaultMap(() => new Map());
|
|
200
|
+
}
|
|
201
|
+
/* eslint-enable @typescript-eslint/no-unused-vars */
|
package/src/core/constants.ts
CHANGED
|
@@ -36,7 +36,7 @@ export const BLIND_ITEM_PNG_PATH = "gfx/items/collectibles/questionmark.png";
|
|
|
36
36
|
/** Bombs explode when their frame count is equal to this value. */
|
|
37
37
|
export const BOMB_EXPLODE_FRAME = 45;
|
|
38
38
|
|
|
39
|
-
/** This is the initial value of the `EntityPickup.Wait`
|
|
39
|
+
/** This is the initial value of the `EntityPickup.Wait` field after a collectible is spawned. */
|
|
40
40
|
export const COLLECTIBLE_INITIAL_WAIT = 20;
|
|
41
41
|
|
|
42
42
|
export const DEFAULT_ITEM_POOL_TYPE = ItemPoolType.TREASURE;
|
|
@@ -798,8 +798,8 @@ export enum ModCallbackCustom {
|
|
|
798
798
|
POST_PIT_UPDATE,
|
|
799
799
|
|
|
800
800
|
/**
|
|
801
|
-
* Fires from the `POST_PEFFECT_UPDATE` callback when a player
|
|
802
|
-
*
|
|
801
|
+
* Fires from the `POST_PEFFECT_UPDATE` callback when a player's health (i.e. hearts) is different
|
|
802
|
+
* than what it was on the previous frame. For more information, see the `PlayerHealth` enum.
|
|
803
803
|
*
|
|
804
804
|
* - When registering the callback, takes an optional second argument that will make the callback
|
|
805
805
|
* only fire if the player matches the `PlayerVariant` provided.
|
|
@@ -811,15 +811,47 @@ export enum ModCallbackCustom {
|
|
|
811
811
|
* player: EntityPlayer,
|
|
812
812
|
* healthType: HealthType,
|
|
813
813
|
* difference: int,
|
|
814
|
+
* oldValue: int,
|
|
815
|
+
* newValue: int,
|
|
814
816
|
* ): void {}
|
|
815
817
|
* ```
|
|
816
818
|
*/
|
|
817
819
|
POST_PLAYER_CHANGE_HEALTH,
|
|
818
820
|
|
|
821
|
+
/**
|
|
822
|
+
* Fires from the `POST_PEFFECT_UPDATE` callback when one of the player's stats change from what
|
|
823
|
+
* they were on the previous frame.
|
|
824
|
+
*
|
|
825
|
+
* The type of `oldValue` and `newValue` will depend on what kind of stat it is. For example,
|
|
826
|
+
* `StatType.FLYING` will be a boolean. (You can use the "Types" helper functions to narrow the
|
|
827
|
+
* type.)
|
|
828
|
+
*
|
|
829
|
+
* For `StatType.TEAR_FLAG`, `StatType.TEAR_COLOR`, `StatType.FLYING`, and `StatType.SIZE`, the
|
|
830
|
+
* `difference` argument will always be a value of 0, since the type of these stats are not
|
|
831
|
+
* numbers. (For these cases, you should examine the `oldValue` and `newValue` arguments
|
|
832
|
+
* accordingly.)
|
|
833
|
+
*
|
|
834
|
+
* - When registering the callback, takes an optional second argument that will make the callback
|
|
835
|
+
* only fire if the player matches the `PlayerVariant` provided.
|
|
836
|
+
* - When registering the callback, takes an optional third argument that will make the callback
|
|
837
|
+
* only fire if the player matches the `PlayerType` provided.
|
|
838
|
+
*
|
|
839
|
+
* ```ts
|
|
840
|
+
* function postPlayerChangeStat(
|
|
841
|
+
* player: EntityPlayer,
|
|
842
|
+
* statType: StatType,
|
|
843
|
+
* difference: int,
|
|
844
|
+
* oldValue: number | boolean | BitFlags<TearFlag> | Color | Vector,
|
|
845
|
+
* newValue: number | boolean | BitFlags<TearFlag> | Color | Vector,
|
|
846
|
+
* ): void {}
|
|
847
|
+
* ```
|
|
848
|
+
*/
|
|
849
|
+
POST_PLAYER_CHANGE_STAT,
|
|
850
|
+
|
|
819
851
|
/**
|
|
820
852
|
* Fires from the `POST_PEFFECT_UPDATE` callback when a player entity changes its player type
|
|
821
|
-
* (i.e. character). For example, it will fire after using
|
|
822
|
-
* Shadow collectible, etc.
|
|
853
|
+
* (i.e. character) from what it was on the previous frame. For example, it will fire after using
|
|
854
|
+
* Clicker, after dying with the Judas' Shadow collectible, etc.
|
|
823
855
|
*
|
|
824
856
|
* Notably, it does not fire after the player uses the Flip item or the Esau Jr. item, because
|
|
825
857
|
* those items cause separate player entities to be created. Use the `POST_FLIP` and
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
/** This represents the kinds of stats that a player can have. */
|
|
2
|
+
export enum StatType {
|
|
3
|
+
/** Corresponds to `CacheFlag.DAMAGE` (1 << 0) and `EntityPlayer.Damage`. */
|
|
4
|
+
DAMAGE,
|
|
5
|
+
|
|
6
|
+
/** Corresponds to `CacheFlag.FIRE_DELAY` (1 << 1) and `EntityPlayer.MaxFireDelay`. */
|
|
7
|
+
FIRE_DELAY,
|
|
8
|
+
|
|
9
|
+
/** Corresponds to `CacheFlag.SHOT_SPEED` (1 << 2) and `EntityPlayer.ShotSpeed`. */
|
|
10
|
+
SHOT_SPEED,
|
|
11
|
+
|
|
12
|
+
/** Corresponds to `CacheFlag.RANGE` (1 << 3) and `EntityPlayer.TearHeight`. */
|
|
13
|
+
TEAR_HEIGHT,
|
|
14
|
+
|
|
15
|
+
/** Corresponds to `CacheFlag.RANGE` (1 << 3) and `EntityPlayer.TearRange`. */
|
|
16
|
+
TEAR_RANGE,
|
|
17
|
+
|
|
18
|
+
/** Corresponds to `CacheFlag.RANGE` (1 << 3) and `EntityPlayer.TearFallingAcceleration`. */
|
|
19
|
+
TEAR_FALLING_ACCELERATION,
|
|
20
|
+
|
|
21
|
+
/** Corresponds to `CacheFlag.RANGE` (1 << 3) and `EntityPlayer.TearFallingSpeed`. */
|
|
22
|
+
TEAR_FALLING_SPEED,
|
|
23
|
+
|
|
24
|
+
/** Corresponds to `CacheFlag.SPEED` (1 << 4) and `EntityPlayer.MoveSpeed`. */
|
|
25
|
+
MOVE_SPEED,
|
|
26
|
+
|
|
27
|
+
/** Corresponds to `CacheFlag.TEAR_FLAG` (1 << 5) and `EntityPlayer.TearFlags`. */
|
|
28
|
+
TEAR_FLAG,
|
|
29
|
+
|
|
30
|
+
/** Corresponds to `CacheFlag.TEAR_COLOR` (1 << 6) and `EntityPlayer.TearColor`. */
|
|
31
|
+
TEAR_COLOR,
|
|
32
|
+
|
|
33
|
+
/** Corresponds to `CacheFlag.FLYING` (1 << 7) and `EntityPlayer.CanFly`. */
|
|
34
|
+
FLYING,
|
|
35
|
+
|
|
36
|
+
// `CacheFlag.WEAPON` (1 << 8) does not have a corresponding `EntityPlayer` field.
|
|
37
|
+
// `CacheFlag.FAMILIARS` (1 << 9) does not have a corresponding `EntityPlayer` field.
|
|
38
|
+
|
|
39
|
+
/** Corresponds to `CacheFlag.LUCK` (1 << 10) and `EntityPlayer.Luck`. */
|
|
40
|
+
LUCK,
|
|
41
|
+
|
|
42
|
+
/** Corresponds to `CacheFlag.SIZE` (1 << 11) and `EntityPlayer.SizeMulti`. */
|
|
43
|
+
SIZE,
|
|
44
|
+
|
|
45
|
+
// `CacheFlag.COLOR` (1 << 12) does not have a corresponding `EntityPlayer` field.
|
|
46
|
+
// `CacheFlag.PICKUP_VISION` (1 << 13) does not have a corresponding `EntityPlayer` field.
|
|
47
|
+
}
|
package/src/enums/index.ts
CHANGED
|
@@ -1,5 +1,9 @@
|
|
|
1
|
-
/**
|
|
1
|
+
/**
|
|
2
|
+
* - This must match the JSDoc comments for `deepCopy` and `merge`.
|
|
3
|
+
* - This must match the `SerializableIsaacAPIClass` type union.
|
|
4
|
+
*/
|
|
2
5
|
export enum CopyableIsaacAPIClassType {
|
|
6
|
+
BIT_SET_128 = "BitSet128",
|
|
3
7
|
COLOR = "Color",
|
|
4
8
|
K_COLOR = "KColor",
|
|
5
9
|
RNG = "RNG",
|
|
@@ -76,13 +76,13 @@ const versusScreenSprite = Sprite();
|
|
|
76
76
|
|
|
77
77
|
/**
|
|
78
78
|
* Unfortunately, we must split the background layer into an entirely different sprite so that we
|
|
79
|
-
* can color it with the `Color`
|
|
79
|
+
* can color it with the `Color` field.
|
|
80
80
|
*/
|
|
81
81
|
const versusScreenBackgroundSprite = Sprite();
|
|
82
82
|
|
|
83
83
|
/**
|
|
84
84
|
* Unfortunately, we must split the dirt layer into an entirely different sprite so that we can
|
|
85
|
-
* color it with the `Color`
|
|
85
|
+
* color it with the `Color` field.
|
|
86
86
|
*/
|
|
87
87
|
const versusScreenDirtSpotSprite = Sprite();
|
|
88
88
|
|
|
@@ -12,16 +12,10 @@ const FEATURE_NAME = "disableInputs";
|
|
|
12
12
|
const v = {
|
|
13
13
|
run: {
|
|
14
14
|
/** Indexed by the requesting feature key. */
|
|
15
|
-
disableInputsWithWhitelistMap: new Map<
|
|
16
|
-
string,
|
|
17
|
-
Set<ButtonAction> | ReadonlySet<ButtonAction>
|
|
18
|
-
>(),
|
|
15
|
+
disableInputsWithWhitelistMap: new Map<string, ReadonlySet<ButtonAction>>(),
|
|
19
16
|
|
|
20
17
|
/** Indexed by the requesting feature key. */
|
|
21
|
-
enableInputsWithBlacklistMap: new Map<
|
|
22
|
-
string,
|
|
23
|
-
Set<ButtonAction> | ReadonlySet<ButtonAction>
|
|
24
|
-
>(),
|
|
18
|
+
enableInputsWithBlacklistMap: new Map<string, ReadonlySet<ButtonAction>>(),
|
|
25
19
|
},
|
|
26
20
|
};
|
|
27
21
|
|
|
@@ -154,7 +148,7 @@ export function enableAllInputsExceptFor(
|
|
|
154
148
|
*/
|
|
155
149
|
export function disableAllInputsExceptFor(
|
|
156
150
|
key: string,
|
|
157
|
-
whitelist: Set<ButtonAction>,
|
|
151
|
+
whitelist: Set<ButtonAction> | ReadonlySet<ButtonAction>,
|
|
158
152
|
): void {
|
|
159
153
|
errorIfFeaturesNotInitialized(FEATURE_NAME);
|
|
160
154
|
|
|
@@ -31,7 +31,7 @@ const v = {
|
|
|
31
31
|
};
|
|
32
32
|
|
|
33
33
|
export function runInNFramesInit(mod: Mod): void {
|
|
34
|
-
saveDataManager(FEATURE_NAME, v,
|
|
34
|
+
saveDataManager(FEATURE_NAME, v, false); // Functions are not serializable.
|
|
35
35
|
|
|
36
36
|
mod.AddCallback(ModCallback.POST_UPDATE, postUpdate); // 1
|
|
37
37
|
mod.AddCallback(ModCallback.POST_RENDER, postRender); // 2
|
|
@@ -13,7 +13,7 @@ const v = {
|
|
|
13
13
|
};
|
|
14
14
|
|
|
15
15
|
export function runNextRoomInit(mod: ModUpgraded): void {
|
|
16
|
-
saveDataManager(FEATURE_NAME, v,
|
|
16
|
+
saveDataManager(FEATURE_NAME, v, false); // Functions are not serializable.
|
|
17
17
|
|
|
18
18
|
mod.AddCallbackCustom(
|
|
19
19
|
ModCallbackCustom.POST_NEW_ROOM_REORDERED,
|
|
@@ -96,18 +96,30 @@ import { SAVE_DATA_MANAGER_FEATURE_NAME } from "./saveDataManagerConstants";
|
|
|
96
96
|
* manager. The save data manager will throw an error if the key is already registered.
|
|
97
97
|
* @param v An object that corresponds to the `SaveData` interface. The object is conventionally
|
|
98
98
|
* called "v" for brevity. ("v" is short for "local variables").
|
|
99
|
-
* @param conditionalFunc
|
|
100
|
-
*
|
|
101
|
-
*
|
|
102
|
-
*
|
|
103
|
-
*
|
|
104
|
-
* save
|
|
105
|
-
*
|
|
99
|
+
* @param conditionalFunc Optional. A function to run to check if this save data should be written
|
|
100
|
+
* to disk. Default is `() => true`, meaning that this save data will always
|
|
101
|
+
* be written to disk. Use a conditional function for the situations when the
|
|
102
|
+
* local variables are for a feature that the end-user can disable. (If the
|
|
103
|
+
* feature is disabled, then there would be no point in writing any of the
|
|
104
|
+
* variables to the "save#.dat" file.) You can also specify `false` to this
|
|
105
|
+
* argument in order to completely disable saving data. (Specifying `false`
|
|
106
|
+
* will allow you to use non-serializable objects in your save data, such as
|
|
107
|
+
* `EntityPtr`.
|
|
106
108
|
*/
|
|
109
|
+
export function saveDataManager<Persistent, Run, Level>(
|
|
110
|
+
key: string, // This is the overload for the standard case with serializable data.
|
|
111
|
+
v: SaveData<Persistent, Run, Level>,
|
|
112
|
+
conditionalFunc?: () => boolean,
|
|
113
|
+
): void;
|
|
107
114
|
export function saveDataManager(
|
|
108
|
-
key: string,
|
|
115
|
+
key: string, // This is the overload for the case when saving data is disabled.
|
|
109
116
|
v: SaveData,
|
|
110
|
-
conditionalFunc
|
|
117
|
+
conditionalFunc: false,
|
|
118
|
+
): void;
|
|
119
|
+
export function saveDataManager<Persistent, Run, Level>(
|
|
120
|
+
key: string,
|
|
121
|
+
v: SaveData<Persistent, Run, Level>,
|
|
122
|
+
conditionalFunc?: (() => boolean) | false,
|
|
111
123
|
): void {
|
|
112
124
|
errorIfFeaturesNotInitialized(SAVE_DATA_MANAGER_FEATURE_NAME);
|
|
113
125
|
|
|
@@ -126,6 +138,12 @@ export function saveDataManager(
|
|
|
126
138
|
// Add the new save data to the map.
|
|
127
139
|
saveDataMap.set(key, v);
|
|
128
140
|
|
|
141
|
+
// Convert the boolean to a function, if necessary. (Having the argument be a boolean is necessary
|
|
142
|
+
// in order for the overloads to work properly.)
|
|
143
|
+
if (conditionalFunc === false) {
|
|
144
|
+
conditionalFunc = () => false;
|
|
145
|
+
}
|
|
146
|
+
|
|
129
147
|
// If the only key in the save data is "room", then we don't have to worry about saving this data
|
|
130
148
|
// to disk (because the room would be reloaded upon resuming a continued run).
|
|
131
149
|
const saveDataKeys = Object.keys(v);
|
|
@@ -135,7 +153,7 @@ export function saveDataManager(
|
|
|
135
153
|
|
|
136
154
|
// Make a copy of the initial save data so that we can use it to restore the default values later
|
|
137
155
|
// on.
|
|
138
|
-
const saveDataCopy = deepCopy(v, SerializationType.NONE, key) as
|
|
156
|
+
const saveDataCopy = deepCopy(v, SerializationType.NONE, key) as typeof v;
|
|
139
157
|
saveDataDefaultsMap.set(key, saveDataCopy);
|
|
140
158
|
|
|
141
159
|
// Store the conditional function for later, if present.
|
|
@@ -44,7 +44,8 @@ function getAllSaveDataToWriteToDisk(
|
|
|
44
44
|
}
|
|
45
45
|
}
|
|
46
46
|
|
|
47
|
-
// Strip out the room part of the save data
|
|
47
|
+
// Strip out the room part of the save data (and any other arbitrary fields that they might
|
|
48
|
+
// have added).
|
|
48
49
|
const saveDataWithoutRoom: SaveData = {
|
|
49
50
|
persistent: saveData.persistent,
|
|
50
51
|
run: saveData.run,
|
|
@@ -31,10 +31,10 @@ const v = {
|
|
|
31
31
|
};
|
|
32
32
|
|
|
33
33
|
export function taintedLazarusPlayersInit(mod: ModUpgraded): void {
|
|
34
|
-
// `EntityPtr` is not serializable, so we cannot save data. However, this is inconsequential,
|
|
34
|
+
// `EntityPtr` is not serializable, so we cannot save the data. However, this is inconsequential,
|
|
35
35
|
// since the `POST_PLAYER_INIT` callback will fire when a run is continued, which will repopulate
|
|
36
36
|
// the `subPlayerMap`.
|
|
37
|
-
saveDataManager(FEATURE_NAME, v,
|
|
37
|
+
saveDataManager(FEATURE_NAME, v, false);
|
|
38
38
|
|
|
39
39
|
mod.AddCallback(ModCallback.POST_PLAYER_INIT, postPlayerInit);
|
|
40
40
|
}
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
import { SerializationBrand } from "../enums/private/SerializationBrand";
|
|
2
|
+
import { isIsaacAPIClassOfType } from "./isaacAPIClass";
|
|
3
|
+
import { copyValuesToTable, getNumbersFromTable, tableHasKeys } from "./table";
|
|
4
|
+
import { isTable } from "./types";
|
|
5
|
+
|
|
6
|
+
export type SerializedBitSet128 = LuaMap<string, unknown> & {
|
|
7
|
+
readonly __serializedBitSet128Brand: symbol;
|
|
8
|
+
};
|
|
9
|
+
|
|
10
|
+
const OBJECT_NAME = "BitSet128";
|
|
11
|
+
const KEYS = ["l", "h"];
|
|
12
|
+
|
|
13
|
+
/** Helper function to copy a `BitSet128` Isaac API class. */
|
|
14
|
+
export function copyBitSet128(bitSet128: BitSet128): BitSet128 {
|
|
15
|
+
if (!isBitSet128(bitSet128)) {
|
|
16
|
+
error(
|
|
17
|
+
`Failed to copy a ${OBJECT_NAME} object since the provided object was not a userdata ${OBJECT_NAME} class.`,
|
|
18
|
+
);
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
const lowBits = bitSet128.l;
|
|
22
|
+
const highBits = bitSet128.h;
|
|
23
|
+
|
|
24
|
+
return BitSet128(lowBits, highBits);
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* Helper function to convert a `SerializedBitSet128` object to a normal `BitSet128` object. (This
|
|
29
|
+
* is used by the save data manager when reading data from the "save#.dat" file.)
|
|
30
|
+
*/
|
|
31
|
+
export function deserializeBitSet128(
|
|
32
|
+
bitSet128: SerializedBitSet128,
|
|
33
|
+
): BitSet128 {
|
|
34
|
+
if (!isTable(bitSet128)) {
|
|
35
|
+
error(
|
|
36
|
+
`Failed to deserialize a ${OBJECT_NAME} object since the provided object was not a Lua table.`,
|
|
37
|
+
);
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
const [l, h] = getNumbersFromTable(
|
|
41
|
+
bitSet128 as LuaMap<string, unknown>,
|
|
42
|
+
OBJECT_NAME,
|
|
43
|
+
...KEYS,
|
|
44
|
+
);
|
|
45
|
+
|
|
46
|
+
if (l === undefined) {
|
|
47
|
+
error(
|
|
48
|
+
`Failed to deserialize a ${OBJECT_NAME} object since the provided object did not have a value for: l`,
|
|
49
|
+
);
|
|
50
|
+
}
|
|
51
|
+
if (h === undefined) {
|
|
52
|
+
error(
|
|
53
|
+
`Failed to deserialize a ${OBJECT_NAME} object since the provided object did not have a value for: h`,
|
|
54
|
+
);
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
return BitSet128(l, h);
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
/** Helper function to check if something is an instantiated `BitSet128` object. */
|
|
61
|
+
export function isBitSet128(object: unknown): object is BitSet128 {
|
|
62
|
+
return isIsaacAPIClassOfType(object, OBJECT_NAME);
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
/**
|
|
66
|
+
* Used to determine is the given table is a serialized `BitSet128` object created by the save data
|
|
67
|
+
* manager and/or the `deepCopy` function.
|
|
68
|
+
*/
|
|
69
|
+
export function isSerializedBitSet128(
|
|
70
|
+
object: unknown,
|
|
71
|
+
): object is SerializedBitSet128 {
|
|
72
|
+
if (!isTable(object)) {
|
|
73
|
+
return false;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
return (
|
|
77
|
+
tableHasKeys(object, ...KEYS) && object.has(SerializationBrand.BIT_SET_128)
|
|
78
|
+
);
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
/**
|
|
82
|
+
* Helper function to convert a `BitSet128` object to a `SerializedBitSet128` object. (This is used
|
|
83
|
+
* by the save data manager when writing data from the "save#.dat" file.)
|
|
84
|
+
*/
|
|
85
|
+
export function serializeBitSet128(bitSet128: BitSet128): SerializedBitSet128 {
|
|
86
|
+
if (!isBitSet128(bitSet128)) {
|
|
87
|
+
error(
|
|
88
|
+
`Failed to serialize a ${OBJECT_NAME} object since the provided object was not a userdata ${OBJECT_NAME} class.`,
|
|
89
|
+
);
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
const bitSet128Table = new LuaMap<string, unknown>();
|
|
93
|
+
copyValuesToTable(bitSet128, KEYS, bitSet128Table);
|
|
94
|
+
bitSet128Table.set(SerializationBrand.BIT_SET_128, "");
|
|
95
|
+
return bitSet128Table as SerializedBitSet128;
|
|
96
|
+
}
|
|
@@ -614,8 +614,8 @@ export function setCollectibleSprite(
|
|
|
614
614
|
}
|
|
615
615
|
|
|
616
616
|
/**
|
|
617
|
-
* Helper function to change the collectible on a pedestal. Simply updating the `SubType`
|
|
618
|
-
*
|
|
617
|
+
* Helper function to change the collectible on a pedestal. Simply updating the `SubType` field is
|
|
618
|
+
* not sufficient because the sprite will not change.
|
|
619
619
|
*/
|
|
620
620
|
export function setCollectibleSubType(
|
|
621
621
|
collectible: EntityPickup,
|
package/src/functions/color.ts
CHANGED
|
@@ -9,8 +9,8 @@ export type SerializedColor = LuaMap<string, unknown> & {
|
|
|
9
9
|
readonly __serializedColorBrand: symbol;
|
|
10
10
|
};
|
|
11
11
|
|
|
12
|
-
const KEYS = ["R", "G", "B", "A", "RO", "GO", "BO"];
|
|
13
12
|
const OBJECT_NAME = "Color";
|
|
13
|
+
const KEYS = ["R", "G", "B", "A", "RO", "GO", "BO"];
|
|
14
14
|
|
|
15
15
|
export function colorEquals(color1: Color, color2: Color): boolean {
|
|
16
16
|
return isaacAPIClassEquals(color1, color2, KEYS);
|
|
@@ -91,7 +91,7 @@ export function getRandomColor(
|
|
|
91
91
|
return Color(r, g, b, alpha);
|
|
92
92
|
}
|
|
93
93
|
|
|
94
|
-
/** Helper function to check if something is an instantiated Color object. */
|
|
94
|
+
/** Helper function to check if something is an instantiated `Color` object. */
|
|
95
95
|
export function isColor(object: unknown): object is Color {
|
|
96
96
|
return isIsaacAPIClassOfType(object, OBJECT_NAME);
|
|
97
97
|
}
|
|
@@ -107,6 +107,7 @@ export function isSerializedColor(object: unknown): object is SerializedColor {
|
|
|
107
107
|
|
|
108
108
|
return tableHasKeys(object, ...KEYS) && object.has(SerializationBrand.COLOR);
|
|
109
109
|
}
|
|
110
|
+
|
|
110
111
|
/**
|
|
111
112
|
* Helper function to convert a `Color` object to a `SerializedColor` object. (This is used by the
|
|
112
113
|
* save data manager when writing data from the "save#.dat" file.)
|
|
@@ -42,6 +42,7 @@ const COPYABLE_ISAAC_API_CLASS_TYPES_SET = new Set<string>(
|
|
|
42
42
|
* - TSTL `Set`
|
|
43
43
|
* - TSTL classes
|
|
44
44
|
* - `DefaultMap`
|
|
45
|
+
* - Isaac `BitSet128` objects
|
|
45
46
|
* - Isaac `Color` objects
|
|
46
47
|
* - Isaac `KColor` objects
|
|
47
48
|
* - Isaac `RNG` objects
|
|
@@ -233,7 +234,7 @@ function deepCopyDefaultMap(
|
|
|
233
234
|
// throw a run-time error to immediately alert the end-user that their data structure is
|
|
234
235
|
// invalid.
|
|
235
236
|
error(
|
|
236
|
-
|
|
237
|
+
"Failed to deep copy a DefaultMap because it was instantiated with a factory function and was also inside of an array, map, or set. For more information, see: https://isaacscript.github.io/main/gotchas#failed-to-deep-copy-a-defaultmap",
|
|
237
238
|
);
|
|
238
239
|
} else {
|
|
239
240
|
// In most cases, the DefaultMap will be attached to a normal table element. In this case, if
|
|
@@ -187,9 +187,9 @@ function setPrimitiveEntityFields(
|
|
|
187
187
|
const indexKey = key as keyof typeof entity;
|
|
188
188
|
const value = entity[indexKey];
|
|
189
189
|
if (isPrimitive(value)) {
|
|
190
|
-
entityFields.set(indexKey, value);
|
|
190
|
+
entityFields.set(indexKey as string, value);
|
|
191
191
|
} else if (isVector(value)) {
|
|
192
|
-
entityFields.set(indexKey, vectorToString(value));
|
|
192
|
+
entityFields.set(indexKey as string, vectorToString(value));
|
|
193
193
|
}
|
|
194
194
|
}
|
|
195
195
|
}
|
|
@@ -11,8 +11,8 @@ import { getFamiliars } from "./entitiesSpecific";
|
|
|
11
11
|
* specify an incorrect RNG object. (The vanilla method is bugged in that it does not increment the
|
|
12
12
|
* RNG object; see the documentation of the method for more details.)
|
|
13
13
|
*
|
|
14
|
-
* This function is meant to be called in the
|
|
15
|
-
* to `CacheFlag.FAMILIARS`).
|
|
14
|
+
* This function is meant to be called in the `EVALUATE_CACHE` callback (when the cache flag is
|
|
15
|
+
* equal to `CacheFlag.FAMILIARS`).
|
|
16
16
|
*
|
|
17
17
|
* Note that this function is only meant to be used in special circumstances where the familiar
|
|
18
18
|
* count is completely custom and does not correspond to the amount of collectibles. For the general
|
|
@@ -56,8 +56,8 @@ export function checkFamiliar(
|
|
|
56
56
|
* Use this helper function instead of invoking the `EntityPlayer.CheckFamiliar` method directly so
|
|
57
57
|
* that the target count is handled automatically.
|
|
58
58
|
*
|
|
59
|
-
* This function is meant to be called in the
|
|
60
|
-
* to `CacheFlag.FAMILIARS`).
|
|
59
|
+
* This function is meant to be called in the `EVALUATE_CACHE` callback (when the cache flag is
|
|
60
|
+
* equal to `CacheFlag.FAMILIARS`).
|
|
61
61
|
*
|
|
62
62
|
* Use this function when the amount of familiars should be equal to the amount of associated
|
|
63
63
|
* collectibles that the player has (plus any extras from having used Box of Friends or Monster
|
package/src/functions/flag.ts
CHANGED
|
@@ -42,7 +42,7 @@ export function addFlag<T extends BitFlag | BitFlag128>(
|
|
|
42
42
|
* Helper function for casting a flag enum value to a `BitFlags` object.
|
|
43
43
|
*
|
|
44
44
|
* This is useful because the compiler will prevent you from assigning a specific flag to a
|
|
45
|
-
* `BitFlags`
|
|
45
|
+
* `BitFlags` field. (It does this to ensure type safety, since `BitFlags` can represent a zero
|
|
46
46
|
* value or a composition of N flags.)
|
|
47
47
|
*
|
|
48
48
|
* For example:
|
package/src/functions/index.ts
CHANGED
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
export * from "./ambush";
|
|
4
4
|
export * from "./array";
|
|
5
5
|
export * from "./benchmark";
|
|
6
|
+
export * from "./bitSet128";
|
|
6
7
|
export * from "./bitwise";
|
|
7
8
|
export * from "./bombs";
|
|
8
9
|
export * from "./bosses";
|
|
@@ -63,6 +64,7 @@ export * from "./playerDataStructures";
|
|
|
63
64
|
export * from "./playerHealth";
|
|
64
65
|
export * from "./playerIndex";
|
|
65
66
|
export * from "./players";
|
|
67
|
+
export * from "./playerStats";
|
|
66
68
|
export * from "./pocketItems";
|
|
67
69
|
export * from "./positionVelocity";
|
|
68
70
|
export * from "./pressurePlate";
|
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
export * as Ambush from "./ambush";
|
|
4
4
|
export * as Array from "./array";
|
|
5
5
|
export * as Benchmark from "./benchmark";
|
|
6
|
+
export * as BitSet128 from "./bitSet128";
|
|
6
7
|
export * as Bitwise from "./bitwise";
|
|
7
8
|
export * as Bombs from "./bombs";
|
|
8
9
|
export * as Bosses from "./bosses";
|
|
@@ -63,6 +64,7 @@ export * as PlayerDataStructures from "./playerDataStructures";
|
|
|
63
64
|
export * as PlayerHealth from "./playerHealth";
|
|
64
65
|
export * as PlayerIndex from "./playerIndex";
|
|
65
66
|
export * as Players from "./players";
|
|
67
|
+
export * as PlayerStats from "./playerStats";
|
|
66
68
|
export * as PocketItems from "./pocketItems";
|
|
67
69
|
export * as PositionVelocity from "./positionVelocity";
|
|
68
70
|
export * as PressurePlate from "./pressurePlate";
|