isaacscript-common 6.22.3 → 7.0.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/classes/DefaultMap.d.ts +3 -3
- package/dist/classes/DefaultMap.d.ts.map +1 -1
- package/dist/classes/DefaultMap.lua +37 -0
- package/dist/features/customStage/exports.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/taintedLazarusPlayers.lua +1 -6
- package/dist/functions/deepCopy.lua +1 -1
- package/dist/functions/isaacAPIClass.d.ts +1 -1
- package/dist/functions/isaacAPIClass.d.ts.map +1 -1
- package/dist/functions/level.lua +2 -2
- package/dist/functions/levelGrid.d.ts +3 -1
- package/dist/functions/levelGrid.d.ts.map +1 -1
- package/dist/functions/levelGrid.lua +15 -10
- package/dist/functions/minimap.lua +3 -3
- package/dist/functions/rooms.d.ts +1 -1
- package/dist/functions/rooms.d.ts.map +1 -1
- package/dist/functions/rooms.lua +4 -4
- package/dist/interfaces/SaveData.d.ts +43 -4
- package/dist/interfaces/SaveData.d.ts.map +1 -1
- package/dist/interfaces/SaveData.lua +66 -0
- package/dist/types/index.d.ts +0 -1
- package/dist/types/index.d.ts.map +1 -1
- package/package.json +2 -2
- package/src/classes/DefaultMap.ts +36 -7
- package/src/features/customStage/exports.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/save.ts +2 -1
- package/src/features/taintedLazarusPlayers.ts +2 -2
- package/src/functions/deepCopy.ts +1 -1
- package/src/functions/entities.ts +2 -2
- package/src/functions/isaacAPIClass.ts +0 -1
- package/src/functions/level.ts +2 -2
- package/src/functions/levelGrid.ts +16 -12
- package/src/functions/minimap.ts +3 -3
- package/src/functions/rooms.ts +4 -4
- package/src/interfaces/SaveData.ts +257 -5
- 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
|
@@ -1,2 +1,68 @@
|
|
|
1
|
+
local ____lualib = require("lualib_bundle")
|
|
2
|
+
local Map = ____lualib.Map
|
|
3
|
+
local __TS__New = ____lualib.__TS__New
|
|
4
|
+
local __TS__Class = ____lualib.__TS__Class
|
|
1
5
|
local ____exports = {}
|
|
6
|
+
local function test(self, _saveData)
|
|
7
|
+
end
|
|
8
|
+
do
|
|
9
|
+
local saveDataWithPrimitives = {run = {foo = 123, bar = "bar", baz = true, nested = {foo = 123, bar = "bar", baz = true}}}
|
|
10
|
+
test(nil, saveDataWithPrimitives)
|
|
11
|
+
end
|
|
12
|
+
do
|
|
13
|
+
local saveDataWithEntity = {run = {foo = {}}}
|
|
14
|
+
test(nil, saveDataWithEntity)
|
|
15
|
+
end
|
|
16
|
+
do
|
|
17
|
+
local saveDataWithMap = {run = {foo = __TS__New(Map)}}
|
|
18
|
+
test(nil, saveDataWithMap)
|
|
19
|
+
end
|
|
20
|
+
do
|
|
21
|
+
local saveDataWithMap = {run = {foo = __TS__New(Map)}}
|
|
22
|
+
test(nil, saveDataWithMap)
|
|
23
|
+
end
|
|
24
|
+
do
|
|
25
|
+
local saveDataWithMap = {run = {foo = __TS__New(Map)}}
|
|
26
|
+
test(nil, saveDataWithMap)
|
|
27
|
+
end
|
|
28
|
+
do
|
|
29
|
+
local Foo = __TS__Class()
|
|
30
|
+
Foo.name = "Foo"
|
|
31
|
+
function Foo.prototype.____constructor(self)
|
|
32
|
+
self.someField = 123
|
|
33
|
+
end
|
|
34
|
+
local saveDataWithClass = {run = {foo = __TS__New(Foo)}}
|
|
35
|
+
test(nil, saveDataWithClass)
|
|
36
|
+
end
|
|
37
|
+
do
|
|
38
|
+
local Foo = __TS__Class()
|
|
39
|
+
Foo.name = "Foo"
|
|
40
|
+
function Foo.prototype.____constructor(self)
|
|
41
|
+
self.someField = 123
|
|
42
|
+
end
|
|
43
|
+
function Foo.prototype.someMethod(self)
|
|
44
|
+
end
|
|
45
|
+
local saveDataWithClassWithMethod = {run = {foo = __TS__New(Foo)}}
|
|
46
|
+
test(nil, saveDataWithClassWithMethod)
|
|
47
|
+
end
|
|
48
|
+
do
|
|
49
|
+
local Foo = __TS__Class()
|
|
50
|
+
Foo.name = "Foo"
|
|
51
|
+
function Foo.prototype.____constructor(self)
|
|
52
|
+
self.someField = 123
|
|
53
|
+
end
|
|
54
|
+
local saveDataWithNestedClass = {run = {fooMap = __TS__New(Map)}}
|
|
55
|
+
test(nil, saveDataWithNestedClass)
|
|
56
|
+
end
|
|
57
|
+
do
|
|
58
|
+
local Foo = __TS__Class()
|
|
59
|
+
Foo.name = "Foo"
|
|
60
|
+
function Foo.prototype.____constructor(self)
|
|
61
|
+
self.someField = 123
|
|
62
|
+
end
|
|
63
|
+
function Foo.prototype.someMethod(self)
|
|
64
|
+
end
|
|
65
|
+
local saveDataWithNestedClass = {run = {fooMap = __TS__New(Map)}}
|
|
66
|
+
test(nil, saveDataWithNestedClass)
|
|
67
|
+
end
|
|
2
68
|
return ____exports
|
package/dist/types/index.d.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/types/index.ts"],"names":[],"mappings":"AAAA,cAAc,aAAa,CAAC;AAC5B,cAAc,iBAAiB,CAAC;AAChC,cAAc,oBAAoB,CAAC;AACnC,cAAc,aAAa,CAAC;AAC5B,cAAc,iBAAiB,CAAC;AAChC,cAAc,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/types/index.ts"],"names":[],"mappings":"AAAA,cAAc,aAAa,CAAC;AAC5B,cAAc,iBAAiB,CAAC;AAChC,cAAc,oBAAoB,CAAC;AACnC,cAAc,aAAa,CAAC;AAC5B,cAAc,iBAAiB,CAAC;AAChC,cAAc,eAAe,CAAC;AAC9B,cAAc,eAAe,CAAC;AAC9B,cAAc,2BAA2B,CAAC;AAC1C,cAAc,uBAAuB,CAAC;AACtC,cAAc,aAAa,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "isaacscript-common",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "7.0.0",
|
|
4
4
|
"description": "Helper functions and features for IsaacScript mods.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"isaac",
|
|
@@ -22,6 +22,6 @@
|
|
|
22
22
|
"main": "dist/index",
|
|
23
23
|
"types": "dist/index.d.ts",
|
|
24
24
|
"dependencies": {
|
|
25
|
-
"isaac-typescript-definitions": "^3.1
|
|
25
|
+
"isaac-typescript-definitions": "^3.2.1"
|
|
26
26
|
}
|
|
27
27
|
}
|
|
@@ -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 */
|
|
@@ -21,7 +21,7 @@ import { logError } from "../../functions/log";
|
|
|
21
21
|
import { newRNG } from "../../functions/rng";
|
|
22
22
|
import {
|
|
23
23
|
getRoomDataForTypeVariant,
|
|
24
|
-
|
|
24
|
+
getRoomsInsideGrid,
|
|
25
25
|
} from "../../functions/rooms";
|
|
26
26
|
import { setStage } from "../../functions/stage";
|
|
27
27
|
import { CustomStage } from "../../interfaces/private/CustomStage";
|
|
@@ -121,7 +121,7 @@ function setStageRoomsData(
|
|
|
121
121
|
const level = game.GetLevel();
|
|
122
122
|
const startingRoomGridIndex = level.GetStartingRoomIndex();
|
|
123
123
|
|
|
124
|
-
for (const room of
|
|
124
|
+
for (const room of getRoomsInsideGrid()) {
|
|
125
125
|
// The starting floor of each room should stay empty.
|
|
126
126
|
if (room.SafeGridIndex === startingRoomGridIndex) {
|
|
127
127
|
continue;
|
|
@@ -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
|
}
|
|
@@ -233,7 +233,7 @@ function deepCopyDefaultMap(
|
|
|
233
233
|
// throw a run-time error to immediately alert the end-user that their data structure is
|
|
234
234
|
// invalid.
|
|
235
235
|
error(
|
|
236
|
-
|
|
236
|
+
"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
237
|
);
|
|
238
238
|
} else {
|
|
239
239
|
// 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
|
}
|
package/src/functions/level.ts
CHANGED
|
@@ -2,14 +2,14 @@ import { DoorSlot } from "isaac-typescript-definitions";
|
|
|
2
2
|
import { game } from "../core/cachedClasses";
|
|
3
3
|
import { getEnumValues } from "./enums";
|
|
4
4
|
import { isDoorSlotValidAtGridIndexForRedRoom } from "./levelGrid";
|
|
5
|
-
import { getNumRooms,
|
|
5
|
+
import { getNumRooms, getRoomsInsideGrid } from "./rooms";
|
|
6
6
|
|
|
7
7
|
export function fillLevelWithRedRooms(): void {
|
|
8
8
|
const level = game.GetLevel();
|
|
9
9
|
|
|
10
10
|
let numRoomsInGrid: int;
|
|
11
11
|
do {
|
|
12
|
-
const roomsInGrid =
|
|
12
|
+
const roomsInGrid = getRoomsInsideGrid();
|
|
13
13
|
numRoomsInGrid = roomsInGrid.length;
|
|
14
14
|
|
|
15
15
|
for (const roomDescriptor of roomsInGrid) {
|
|
@@ -35,7 +35,7 @@ import {
|
|
|
35
35
|
getRoomGridIndex,
|
|
36
36
|
getRoomShape,
|
|
37
37
|
} from "./roomData";
|
|
38
|
-
import { getRooms,
|
|
38
|
+
import { getRooms, getRoomsInsideGrid } from "./rooms";
|
|
39
39
|
import { getGridIndexDelta } from "./roomShape";
|
|
40
40
|
|
|
41
41
|
const LEFT = -1;
|
|
@@ -63,7 +63,7 @@ export function getAdjacentRoomGridIndexes(roomGridIndex?: int): int[] {
|
|
|
63
63
|
const roomGridIndexToUse =
|
|
64
64
|
roomGridIndex === undefined ? getRoomGridIndex() : roomGridIndex;
|
|
65
65
|
|
|
66
|
-
if (!
|
|
66
|
+
if (!isRoomInsideGrid(roomGridIndexToUse)) {
|
|
67
67
|
return [];
|
|
68
68
|
}
|
|
69
69
|
|
|
@@ -72,7 +72,7 @@ export function getAdjacentRoomGridIndexes(roomGridIndex?: int): int[] {
|
|
|
72
72
|
);
|
|
73
73
|
|
|
74
74
|
return adjacentRoomGridIndexes.filter((adjacentRoomGridIndex) =>
|
|
75
|
-
|
|
75
|
+
isRoomInsideGrid(adjacentRoomGridIndex),
|
|
76
76
|
);
|
|
77
77
|
}
|
|
78
78
|
|
|
@@ -117,7 +117,7 @@ export function getNewRoomCandidatesBesideRoom(
|
|
|
117
117
|
): Array<[doorSlot: DoorSlot, roomGridIndex: int]> {
|
|
118
118
|
const roomDescriptor = getRoomDescriptor(roomGridIndex);
|
|
119
119
|
|
|
120
|
-
if (!
|
|
120
|
+
if (!isRoomInsideGrid(roomDescriptor.SafeGridIndex)) {
|
|
121
121
|
return [];
|
|
122
122
|
}
|
|
123
123
|
|
|
@@ -172,7 +172,7 @@ export function getNewRoomCandidatesBesideRoom(
|
|
|
172
172
|
export function getNewRoomCandidatesForLevel(): Array<
|
|
173
173
|
[adjacentRoomGridIndex: int, doorSlot: DoorSlot, newRoomGridIndex: int]
|
|
174
174
|
> {
|
|
175
|
-
const rooms =
|
|
175
|
+
const rooms = getRoomsInsideGrid();
|
|
176
176
|
const normalRooms = rooms.filter(
|
|
177
177
|
(room) =>
|
|
178
178
|
room.Data !== undefined &&
|
|
@@ -207,7 +207,7 @@ export function getNewRoomCandidatesForLevel(): Array<
|
|
|
207
207
|
export function getRoomGridIndexesForType(...roomTypes: RoomType[]): int[] {
|
|
208
208
|
const roomTypesSet = new Set<RoomType>([...roomTypes]);
|
|
209
209
|
|
|
210
|
-
const rooms =
|
|
210
|
+
const rooms = getRoomsInsideGrid();
|
|
211
211
|
const matchingRooms = rooms.filter(
|
|
212
212
|
(roomDescriptor) =>
|
|
213
213
|
roomDescriptor.Data !== undefined &&
|
|
@@ -230,7 +230,7 @@ export function getRoomGridIndexesForType(...roomTypes: RoomType[]): int[] {
|
|
|
230
230
|
export function getRoomNeighbors(roomGridIndex?: int): Map<DoorSlot, int> {
|
|
231
231
|
const roomDescriptor = getRoomDescriptor(roomGridIndex);
|
|
232
232
|
|
|
233
|
-
if (!
|
|
233
|
+
if (!isRoomInsideGrid(roomDescriptor.SafeGridIndex)) {
|
|
234
234
|
return new Map();
|
|
235
235
|
}
|
|
236
236
|
|
|
@@ -293,7 +293,7 @@ export function getRoomShapeNeighborGridIndexes(
|
|
|
293
293
|
const neighborGridIndexes = new Map<DoorSlot, int>();
|
|
294
294
|
for (const [doorSlot, delta] of roomShapeNeighborGridIndexDeltas.entries()) {
|
|
295
295
|
const roomGridIndex = safeRoomGridIndex + delta;
|
|
296
|
-
if (
|
|
296
|
+
if (isRoomInsideGrid(roomGridIndex)) {
|
|
297
297
|
neighborGridIndexes.set(doorSlot, roomGridIndex);
|
|
298
298
|
}
|
|
299
299
|
}
|
|
@@ -356,9 +356,7 @@ export function isDoorSlotValidAtGridIndexForRedRoom(
|
|
|
356
356
|
}
|
|
357
357
|
|
|
358
358
|
const redRoomGridIndex = roomGridIndex + delta;
|
|
359
|
-
return (
|
|
360
|
-
!roomExists(redRoomGridIndex) && isRoomGridIndexInBounds(redRoomGridIndex)
|
|
361
|
-
);
|
|
359
|
+
return !roomExists(redRoomGridIndex) && isRoomInsideGrid(redRoomGridIndex);
|
|
362
360
|
}
|
|
363
361
|
|
|
364
362
|
/**
|
|
@@ -376,8 +374,14 @@ export function isRedKeyRoom(roomGridIndex?: int): boolean {
|
|
|
376
374
|
* Helper function to determine if a given room grid index is inside of the normal 13x13 level grid.
|
|
377
375
|
*
|
|
378
376
|
* For example, Devil Rooms and the Mega Satan room are not considered to be inside the grid.
|
|
377
|
+
*
|
|
378
|
+
* @param roomGridIndex Optional. Default is the current room index.
|
|
379
379
|
*/
|
|
380
|
-
export function
|
|
380
|
+
export function isRoomInsideGrid(roomGridIndex?: int): boolean {
|
|
381
|
+
if (roomGridIndex === undefined) {
|
|
382
|
+
roomGridIndex = getRoomGridIndex();
|
|
383
|
+
}
|
|
384
|
+
|
|
381
385
|
return roomGridIndex >= 0 && roomGridIndex <= MAX_LEVEL_GRID_INDEX;
|
|
382
386
|
}
|
|
383
387
|
|
package/src/functions/minimap.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { DisplayFlag, DisplayFlagZero } from "isaac-typescript-definitions";
|
|
2
2
|
import { game } from "../core/cachedClasses";
|
|
3
3
|
import { getRoomDescriptor } from "./roomData";
|
|
4
|
-
import {
|
|
4
|
+
import { getRoomsInsideGrid } from "./rooms";
|
|
5
5
|
|
|
6
6
|
/**
|
|
7
7
|
* Helper function to set the value of `DisplayFlag` for every room on the floor to 0.
|
|
@@ -12,7 +12,7 @@ import { getRoomsInGrid } from "./rooms";
|
|
|
12
12
|
export function clearFloorDisplayFlags(): void {
|
|
13
13
|
const level = game.GetLevel();
|
|
14
14
|
|
|
15
|
-
for (const room of
|
|
15
|
+
for (const room of getRoomsInsideGrid()) {
|
|
16
16
|
room.DisplayFlags = DisplayFlagZero;
|
|
17
17
|
}
|
|
18
18
|
|
|
@@ -27,7 +27,7 @@ export function clearFloorDisplayFlags(): void {
|
|
|
27
27
|
export function getFloorDisplayFlags(): Map<int, BitFlags<DisplayFlag>> {
|
|
28
28
|
const displayFlagsMap = new Map<int, BitFlags<DisplayFlag>>();
|
|
29
29
|
|
|
30
|
-
const roomsInGrid =
|
|
30
|
+
const roomsInGrid = getRoomsInsideGrid();
|
|
31
31
|
for (const roomDescriptor of roomsInGrid) {
|
|
32
32
|
displayFlagsMap.set(
|
|
33
33
|
roomDescriptor.SafeGridIndex,
|
package/src/functions/rooms.ts
CHANGED
|
@@ -74,7 +74,7 @@ export function changeRoom(roomGridIndex: int): void {
|
|
|
74
74
|
* include off-grid rooms, like the Devil Room.
|
|
75
75
|
*/
|
|
76
76
|
export function getNumRooms(): int {
|
|
77
|
-
const rooms =
|
|
77
|
+
const rooms = getRoomsInsideGrid();
|
|
78
78
|
return rooms.length;
|
|
79
79
|
}
|
|
80
80
|
|
|
@@ -186,7 +186,7 @@ export function getRooms(
|
|
|
186
186
|
// The obvious way to get all of the rooms would be to iterate over the `RoomList` from the
|
|
187
187
|
// `Level.GetRooms` method. However, this results in read-only data, and we want to return a
|
|
188
188
|
// writable object. Instead, we let the heavy lifting be handled by other functions.
|
|
189
|
-
const roomsInGrid =
|
|
189
|
+
const roomsInGrid = getRoomsInsideGrid(includeExtraDimensionalRooms);
|
|
190
190
|
const roomsOutsideGrid = getRoomsOutsideGrid();
|
|
191
191
|
return [...roomsInGrid, ...roomsOutsideGrid];
|
|
192
192
|
}
|
|
@@ -201,7 +201,7 @@ export function getRooms(
|
|
|
201
201
|
* extra-dimensional rooms are automatically be generated. Default
|
|
202
202
|
* is false.
|
|
203
203
|
*/
|
|
204
|
-
export function
|
|
204
|
+
export function getRoomsInsideGrid(
|
|
205
205
|
includeExtraDimensionalRooms = false,
|
|
206
206
|
): RoomDescriptor[] {
|
|
207
207
|
const level = game.GetLevel();
|
|
@@ -463,7 +463,7 @@ export function inStartingRoom(): boolean {
|
|
|
463
463
|
export function isAllRoomsClear(onlyCheckRoomTypes?: RoomType[]): boolean {
|
|
464
464
|
const roomTypeWhitelist =
|
|
465
465
|
onlyCheckRoomTypes === undefined ? null : new Set(onlyCheckRoomTypes);
|
|
466
|
-
const rooms =
|
|
466
|
+
const rooms = getRoomsInsideGrid();
|
|
467
467
|
const matchingRooms =
|
|
468
468
|
roomTypeWhitelist === null
|
|
469
469
|
? rooms
|