isaacscript-common 6.13.0 → 6.16.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/postGridEntityCustomCollision.d.ts +2 -0
- package/dist/callbacks/postGridEntityCustomCollision.d.ts.map +1 -0
- package/dist/callbacks/postGridEntityCustomCollision.lua +71 -0
- package/dist/callbacks/postGridEntityCustomRender.lua +0 -7
- package/dist/callbacks/postGridEntityCustomUpdate.lua +0 -7
- package/dist/callbacks/subscriptions/postGridEntityCustomBroken.d.ts +6 -0
- package/dist/callbacks/subscriptions/postGridEntityCustomBroken.d.ts.map +1 -0
- package/dist/callbacks/subscriptions/postGridEntityCustomBroken.lua +29 -0
- package/dist/callbacks/subscriptions/postGridEntityCustomCollision.d.ts +6 -0
- package/dist/callbacks/subscriptions/postGridEntityCustomCollision.d.ts.map +1 -0
- package/dist/callbacks/subscriptions/postGridEntityCustomCollision.lua +29 -0
- package/dist/enums/ModCallbackCustom.d.ts +96 -62
- package/dist/enums/ModCallbackCustom.d.ts.map +1 -1
- package/dist/enums/ModCallbackCustom.lua +64 -60
- package/dist/enums/private/SerializationBrand.d.ts +1 -1
- package/dist/enums/private/SerializationBrand.lua +1 -1
- package/dist/features/customGridEntity.d.ts +7 -3
- package/dist/features/customGridEntity.d.ts.map +1 -1
- package/dist/features/customGridEntity.lua +67 -7
- package/dist/features/extraConsoleCommands/exports.d.ts +4 -3
- package/dist/features/extraConsoleCommands/exports.d.ts.map +1 -1
- package/dist/features/extraConsoleCommands/exports.lua +4 -3
- package/dist/features/extraConsoleCommands/init.lua +1 -0
- package/dist/functions/collectibles.d.ts +6 -2
- package/dist/functions/collectibles.d.ts.map +1 -1
- package/dist/functions/collectibles.lua +4 -2
- package/dist/functions/color.d.ts +20 -14
- package/dist/functions/color.d.ts.map +1 -1
- package/dist/functions/color.lua +78 -73
- package/dist/functions/deepCopy.d.ts.map +1 -1
- package/dist/functions/deepCopy.lua +22 -1
- package/dist/functions/gridEntities.d.ts +2 -36
- package/dist/functions/gridEntities.d.ts.map +1 -1
- package/dist/functions/gridEntities.lua +2 -78
- package/dist/functions/isaacAPIClass.d.ts +1 -1
- package/dist/functions/isaacAPIClass.d.ts.map +1 -1
- package/dist/functions/itemPool.d.ts +10 -0
- package/dist/functions/itemPool.d.ts.map +1 -0
- package/dist/functions/itemPool.lua +116 -0
- package/dist/functions/kColor.d.ts +20 -14
- package/dist/functions/kColor.d.ts.map +1 -1
- package/dist/functions/kColor.lua +65 -60
- package/dist/functions/mergeTests.lua +2 -2
- package/dist/functions/npcs.d.ts +1 -29
- package/dist/functions/npcs.d.ts.map +1 -1
- package/dist/functions/npcs.lua +0 -45
- package/dist/functions/projectiles.d.ts +32 -0
- package/dist/functions/projectiles.d.ts.map +1 -0
- package/dist/functions/projectiles.lua +73 -0
- package/dist/functions/random.d.ts +1 -1
- package/dist/functions/random.lua +1 -1
- package/dist/functions/rng.d.ts +11 -15
- package/dist/functions/rng.d.ts.map +1 -1
- package/dist/functions/rng.lua +32 -52
- package/dist/functions/rockAlt.d.ts +48 -0
- package/dist/functions/rockAlt.d.ts.map +1 -0
- package/dist/functions/rockAlt.lua +365 -0
- package/dist/functions/saveFile.d.ts +8 -7
- package/dist/functions/saveFile.d.ts.map +1 -1
- package/dist/functions/saveFile.lua +10 -96
- package/dist/functions/serialization.d.ts +26 -7
- package/dist/functions/serialization.d.ts.map +1 -1
- package/dist/functions/serialization.lua +51 -19
- package/dist/functions/table.d.ts +2 -2
- package/dist/functions/table.lua +2 -2
- package/dist/functions/trinketGive.d.ts +13 -0
- package/dist/functions/trinketGive.d.ts.map +1 -1
- package/dist/functions/trinketGive.lua +16 -0
- package/dist/functions/tstlClass.d.ts +1 -1
- package/dist/functions/tstlClass.d.ts.map +1 -1
- package/dist/functions/vector.d.ts +21 -14
- package/dist/functions/vector.d.ts.map +1 -1
- package/dist/functions/vector.lua +58 -54
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.lua +16 -0
- package/dist/initCustomCallbacks.d.ts.map +1 -1
- package/dist/initCustomCallbacks.lua +3 -0
- package/dist/interfaces/AddCallbackParameterCustom.d.ts +4 -0
- package/dist/interfaces/AddCallbackParameterCustom.d.ts.map +1 -1
- package/dist/objects/callbackRegisterFunctions.d.ts.map +1 -1
- package/dist/objects/callbackRegisterFunctions.lua +6 -0
- package/dist/objects/isaacAPIClassTypeToFunctions.d.ts +12 -0
- package/dist/objects/isaacAPIClassTypeToFunctions.d.ts.map +1 -0
- package/dist/objects/isaacAPIClassTypeToFunctions.lua +25 -0
- package/dist/types/{private/IsaacAPIClass.d.ts → IsaacAPIClass.d.ts} +0 -0
- package/dist/types/IsaacAPIClass.d.ts.map +1 -0
- package/dist/types/{private/IsaacAPIClass.lua → IsaacAPIClass.lua} +0 -0
- package/dist/types/{private/SerializedIsaacAPIClass.d.ts → SerializedIsaacAPIClass.d.ts} +0 -0
- package/dist/types/SerializedIsaacAPIClass.d.ts.map +1 -0
- package/dist/types/{private/SerializedIsaacAPIClass.lua → SerializedIsaacAPIClass.lua} +0 -0
- package/dist/types/{private/TSTLClass.d.ts → TSTLClass.d.ts} +0 -0
- package/dist/types/TSTLClass.d.ts.map +1 -0
- package/dist/types/{private/TSTLClass.lua → TSTLClass.lua} +0 -0
- package/package.json +2 -2
- package/src/callbacks/postGridEntityCustomCollision.ts +74 -0
- package/src/callbacks/postGridEntityCustomRender.ts +1 -17
- package/src/callbacks/postGridEntityCustomUpdate.ts +1 -17
- package/src/callbacks/subscriptions/postGridEntityCustomBroken.ts +41 -0
- package/src/callbacks/subscriptions/postGridEntityCustomCollision.ts +43 -0
- package/src/enums/ModCallbackCustom.ts +38 -2
- package/src/enums/private/SerializationBrand.ts +1 -1
- package/src/features/customGridEntity.ts +78 -2
- package/src/features/extraConsoleCommands/exports.ts +4 -3
- package/src/features/extraConsoleCommands/init.ts +1 -0
- package/src/features/extraConsoleCommands/listCommands.ts +2 -2
- package/src/functions/collectibles.ts +6 -2
- package/src/functions/color.ts +89 -87
- package/src/functions/deepCopy.ts +15 -2
- package/src/functions/gridEntities.ts +2 -77
- package/src/functions/isaacAPIClass.ts +1 -1
- package/src/functions/itemPool.ts +153 -0
- package/src/functions/kColor.ts +87 -84
- package/src/functions/mergeTests.ts +2 -2
- package/src/functions/npcs.ts +1 -58
- package/src/functions/projectiles.ts +78 -0
- package/src/functions/random.ts +1 -1
- package/src/functions/rng.ts +45 -65
- package/src/functions/rockAlt.ts +396 -0
- package/src/functions/saveFile.ts +13 -119
- package/src/functions/serialization.ts +81 -25
- package/src/functions/table.ts +2 -2
- package/src/functions/trinketGive.ts +21 -0
- package/src/functions/tstlClass.ts +1 -1
- package/src/functions/vector.ts +78 -74
- package/src/index.ts +2 -0
- package/src/initCustomCallbacks.ts +2 -0
- package/src/interfaces/AddCallbackParameterCustom.ts +4 -0
- package/src/objects/callbackRegisterFunctions.ts +6 -0
- package/src/objects/isaacAPIClassTypeToFunctions.ts +63 -0
- package/src/types/{private/IsaacAPIClass.ts → IsaacAPIClass.ts} +0 -0
- package/src/types/{private/SerializedIsaacAPIClass.ts → SerializedIsaacAPIClass.ts} +0 -0
- package/src/types/{private/TSTLClass.ts → TSTLClass.ts} +0 -0
- package/dist/objects/isaacAPIClassTypeToCopyFunction.d.ts +0 -6
- package/dist/objects/isaacAPIClassTypeToCopyFunction.d.ts.map +0 -1
- package/dist/objects/isaacAPIClassTypeToCopyFunction.lua +0 -13
- package/dist/objects/serializedIsaacAPIClassTypeToIdentityFunction.d.ts +0 -5
- package/dist/objects/serializedIsaacAPIClassTypeToIdentityFunction.d.ts.map +0 -1
- package/dist/objects/serializedIsaacAPIClassTypeToIdentityFunction.lua +0 -13
- package/dist/types/private/IsaacAPIClass.d.ts.map +0 -1
- package/dist/types/private/SerializedIsaacAPIClass.d.ts.map +0 -1
- package/dist/types/private/TSTLClass.d.ts.map +0 -1
- package/src/objects/isaacAPIClassTypeToCopyFunction.ts +0 -18
- package/src/objects/serializedIsaacAPIClassTypeToIdentityFunction.ts +0 -14
package/src/functions/color.ts
CHANGED
|
@@ -1,19 +1,14 @@
|
|
|
1
1
|
import { SerializationBrand } from "../enums/private/SerializationBrand";
|
|
2
|
-
import { SerializationType } from "../enums/SerializationType";
|
|
3
2
|
import { isaacAPIClassEquals, isIsaacAPIClassOfType } from "./isaacAPIClass";
|
|
3
|
+
import { getRandom } from "./random";
|
|
4
|
+
import { getRandomSeed, isRNG, newRNG } from "./rng";
|
|
4
5
|
import { copyValuesToTable, getNumbersFromTable, tableHasKeys } from "./table";
|
|
5
6
|
import { isTable } from "./types";
|
|
6
7
|
|
|
7
|
-
type SerializedColor = LuaMap<string, unknown> & {
|
|
8
|
+
export type SerializedColor = LuaMap<string, unknown> & {
|
|
8
9
|
readonly __serializedColorBrand: symbol;
|
|
9
10
|
};
|
|
10
11
|
|
|
11
|
-
interface CopyColorReturn {
|
|
12
|
-
[SerializationType.NONE]: Color;
|
|
13
|
-
[SerializationType.SERIALIZE]: SerializedColor;
|
|
14
|
-
[SerializationType.DESERIALIZE]: Color;
|
|
15
|
-
}
|
|
16
|
-
|
|
17
12
|
const KEYS = ["R", "G", "B", "A", "RO", "GO", "BO"];
|
|
18
13
|
const OBJECT_NAME = "Color";
|
|
19
14
|
|
|
@@ -21,88 +16,79 @@ export function colorEquals(color1: Color, color2: Color): boolean {
|
|
|
21
16
|
return isaacAPIClassEquals(color1, color2, KEYS);
|
|
22
17
|
}
|
|
23
18
|
|
|
19
|
+
/** Helper function to copy a `Color` Isaac API class. */
|
|
20
|
+
export function copyColor(color: Color): Color {
|
|
21
|
+
if (!isColor(color)) {
|
|
22
|
+
error(
|
|
23
|
+
`Failed to copy a ${OBJECT_NAME} object since the provided object was not a userdata ${OBJECT_NAME} class.`,
|
|
24
|
+
);
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
return Color(
|
|
28
|
+
color.R,
|
|
29
|
+
color.G,
|
|
30
|
+
color.B,
|
|
31
|
+
color.A,
|
|
32
|
+
color.RO,
|
|
33
|
+
color.GO,
|
|
34
|
+
color.BO,
|
|
35
|
+
);
|
|
36
|
+
}
|
|
37
|
+
|
|
24
38
|
/**
|
|
25
|
-
* Helper function to
|
|
26
|
-
*
|
|
27
|
-
* @param color The Color object to copy. In the case of deserialization, this will actually be a
|
|
28
|
-
* Lua table instead of an instantiated Color class.
|
|
29
|
-
* @param serializationType Default is `SerializationType.NONE`.
|
|
39
|
+
* Helper function to convert a `SerializedColor` object to a normal `Color` object. (This is used
|
|
40
|
+
* by the save data manager when reading data from the "save#.dat" file.)
|
|
30
41
|
*/
|
|
31
|
-
export function
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
color: C,
|
|
37
|
-
): CopyColorReturn[SerializationType.NONE];
|
|
38
|
-
export function copyColor(
|
|
39
|
-
color: Color | SerializedColor,
|
|
40
|
-
serializationType = SerializationType.NONE,
|
|
41
|
-
): CopyColorReturn[keyof CopyColorReturn] {
|
|
42
|
-
switch (serializationType) {
|
|
43
|
-
case SerializationType.NONE: {
|
|
44
|
-
if (!isColor(color)) {
|
|
45
|
-
error(
|
|
46
|
-
`Failed to copy a ${OBJECT_NAME} object since the provided object was not a userdata ${OBJECT_NAME} class.`,
|
|
47
|
-
);
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
return Color(
|
|
51
|
-
color.R,
|
|
52
|
-
color.G,
|
|
53
|
-
color.B,
|
|
54
|
-
color.A,
|
|
55
|
-
color.RO,
|
|
56
|
-
color.GO,
|
|
57
|
-
color.BO,
|
|
58
|
-
);
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
case SerializationType.SERIALIZE: {
|
|
62
|
-
if (!isColor(color)) {
|
|
63
|
-
error(
|
|
64
|
-
`Failed to serialize a ${OBJECT_NAME} object since the provided object was not a userdata ${OBJECT_NAME} class.`,
|
|
65
|
-
);
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
const colorTable = new LuaMap<string, unknown>();
|
|
69
|
-
copyValuesToTable(color, KEYS, colorTable);
|
|
70
|
-
colorTable.set(SerializationBrand.COLOR, "");
|
|
71
|
-
return colorTable as SerializedColor;
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
case SerializationType.DESERIALIZE: {
|
|
75
|
-
if (!isTable(color)) {
|
|
76
|
-
error(
|
|
77
|
-
`Failed to deserialize a ${OBJECT_NAME} object since the provided object was not a Lua table.`,
|
|
78
|
-
);
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
const [r, g, b, a, ro, go, bo] = getNumbersFromTable(
|
|
82
|
-
color as LuaMap<string, unknown>,
|
|
83
|
-
OBJECT_NAME,
|
|
84
|
-
...KEYS,
|
|
85
|
-
);
|
|
86
|
-
|
|
87
|
-
if (r === undefined) {
|
|
88
|
-
error(
|
|
89
|
-
`Failed to deserialize a ${OBJECT_NAME} object since the provided object did not have a value for: r`,
|
|
90
|
-
);
|
|
91
|
-
}
|
|
92
|
-
if (g === undefined) {
|
|
93
|
-
error(
|
|
94
|
-
`Failed to deserialize a ${OBJECT_NAME} object since the provided object did not have a value for: g`,
|
|
95
|
-
);
|
|
96
|
-
}
|
|
97
|
-
if (b === undefined) {
|
|
98
|
-
error(
|
|
99
|
-
`Failed to deserialize a ${OBJECT_NAME} object since the provided object did not have a value for: b`,
|
|
100
|
-
);
|
|
101
|
-
}
|
|
102
|
-
|
|
103
|
-
return Color(r, g, b, a, ro, go, bo);
|
|
104
|
-
}
|
|
42
|
+
export function deserializeColor(color: SerializedColor): Color {
|
|
43
|
+
if (!isTable(color)) {
|
|
44
|
+
error(
|
|
45
|
+
`Failed to deserialize a ${OBJECT_NAME} object since the provided object was not a Lua table.`,
|
|
46
|
+
);
|
|
105
47
|
}
|
|
48
|
+
|
|
49
|
+
const [r, g, b, a, ro, go, bo] = getNumbersFromTable(
|
|
50
|
+
color as LuaMap<string, unknown>,
|
|
51
|
+
OBJECT_NAME,
|
|
52
|
+
...KEYS,
|
|
53
|
+
);
|
|
54
|
+
|
|
55
|
+
if (r === undefined) {
|
|
56
|
+
error(
|
|
57
|
+
`Failed to deserialize a ${OBJECT_NAME} object since the provided object did not have a value for: R`,
|
|
58
|
+
);
|
|
59
|
+
}
|
|
60
|
+
if (g === undefined) {
|
|
61
|
+
error(
|
|
62
|
+
`Failed to deserialize a ${OBJECT_NAME} object since the provided object did not have a value for: G`,
|
|
63
|
+
);
|
|
64
|
+
}
|
|
65
|
+
if (b === undefined) {
|
|
66
|
+
error(
|
|
67
|
+
`Failed to deserialize a ${OBJECT_NAME} object since the provided object did not have a value for: B`,
|
|
68
|
+
);
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
return Color(r, g, b, a, ro, go, bo);
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
/**
|
|
75
|
+
* Helper function to get a random color.
|
|
76
|
+
*
|
|
77
|
+
* @param seedOrRNG Optional. The `Seed` or `RNG` object to use. If an `RNG` object is provided, the
|
|
78
|
+
* `RNG.Next` method will be called. Default is `getRandomSeed()`.
|
|
79
|
+
* @param alpha Optional. The alpha value to use. Default is 1.
|
|
80
|
+
*/
|
|
81
|
+
export function getRandomColor(
|
|
82
|
+
seedOrRNG: Seed | RNG = getRandomSeed(),
|
|
83
|
+
alpha = 1,
|
|
84
|
+
): Color {
|
|
85
|
+
const rng = isRNG(seedOrRNG) ? seedOrRNG : newRNG(seedOrRNG);
|
|
86
|
+
|
|
87
|
+
const r = getRandom(rng);
|
|
88
|
+
const g = getRandom(rng);
|
|
89
|
+
const b = getRandom(rng);
|
|
90
|
+
|
|
91
|
+
return Color(r, g, b, alpha);
|
|
106
92
|
}
|
|
107
93
|
|
|
108
94
|
/** Helper function to check if something is an instantiated Color object. */
|
|
@@ -121,3 +107,19 @@ export function isSerializedColor(object: unknown): object is SerializedColor {
|
|
|
121
107
|
|
|
122
108
|
return tableHasKeys(object, ...KEYS) && object.has(SerializationBrand.COLOR);
|
|
123
109
|
}
|
|
110
|
+
/**
|
|
111
|
+
* Helper function to convert a `Color` object to a `SerializedColor` object. (This is used by the
|
|
112
|
+
* save data manager when writing data from the "save#.dat" file.)
|
|
113
|
+
*/
|
|
114
|
+
export function serializeColor(color: Color): SerializedColor {
|
|
115
|
+
if (!isColor(color)) {
|
|
116
|
+
error(
|
|
117
|
+
`Failed to serialize a ${OBJECT_NAME} object since the provided object was not a userdata ${OBJECT_NAME} class.`,
|
|
118
|
+
);
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
const colorTable = new LuaMap<string, unknown>();
|
|
122
|
+
copyValuesToTable(color, KEYS, colorTable);
|
|
123
|
+
colorTable.set(SerializationBrand.COLOR, "");
|
|
124
|
+
return colorTable as SerializedColor;
|
|
125
|
+
}
|
|
@@ -4,7 +4,7 @@ import { SerializationBrand } from "../enums/private/SerializationBrand";
|
|
|
4
4
|
import { SerializationType } from "../enums/SerializationType";
|
|
5
5
|
import { SAVE_DATA_MANAGER_DEBUG } from "../features/saveDataManager/saveDataManagerConstants";
|
|
6
6
|
import { isSerializationBrand } from "../features/saveDataManager/serializationBrands";
|
|
7
|
-
import { TSTLClass } from "../types/
|
|
7
|
+
import { TSTLClass } from "../types/TSTLClass";
|
|
8
8
|
import { isArray } from "./array";
|
|
9
9
|
import { getEnumValues } from "./enums";
|
|
10
10
|
import { getIsaacAPIClassName } from "./isaacAPIClass";
|
|
@@ -13,6 +13,7 @@ import {
|
|
|
13
13
|
copyIsaacAPIClass,
|
|
14
14
|
deserializeIsaacAPIClass,
|
|
15
15
|
isSerializedIsaacAPIClass,
|
|
16
|
+
serializeIsaacAPIClass,
|
|
16
17
|
} from "./serialization";
|
|
17
18
|
import {
|
|
18
19
|
getTSTLClassName,
|
|
@@ -664,5 +665,17 @@ function deepCopyUserdata(
|
|
|
664
665
|
);
|
|
665
666
|
}
|
|
666
667
|
|
|
667
|
-
|
|
668
|
+
switch (serializationType) {
|
|
669
|
+
case SerializationType.NONE: {
|
|
670
|
+
return copyIsaacAPIClass(value);
|
|
671
|
+
}
|
|
672
|
+
|
|
673
|
+
case SerializationType.SERIALIZE: {
|
|
674
|
+
return serializeIsaacAPIClass(value);
|
|
675
|
+
}
|
|
676
|
+
|
|
677
|
+
case SerializationType.DESERIALIZE: {
|
|
678
|
+
return deserializeIsaacAPIClass(value);
|
|
679
|
+
}
|
|
680
|
+
}
|
|
668
681
|
}
|
|
@@ -9,17 +9,14 @@ import {
|
|
|
9
9
|
} from "isaac-typescript-definitions";
|
|
10
10
|
import { game } from "../cachedClasses";
|
|
11
11
|
import { DISTANCE_OF_GRID_TILE } from "../constants";
|
|
12
|
-
import { RockAltType } from "../enums/RockAltType";
|
|
13
12
|
import { GRID_ENTITY_TYPE_TO_BROKEN_STATE_MAP } from "../maps/gridEntityTypeToBrokenStateMap";
|
|
14
13
|
import { GRID_ENTITY_XML_MAP } from "../maps/gridEntityXMLMap";
|
|
15
14
|
import {
|
|
16
15
|
DEFAULT_TOP_LEFT_WALL_GRID_INDEX,
|
|
17
16
|
ROOM_SHAPE_TO_TOP_LEFT_WALL_GRID_INDEX_MAP,
|
|
18
17
|
} from "../maps/roomShapeToTopLeftWallGridIndexMap";
|
|
19
|
-
import { BACKDROP_TYPE_TO_ROCK_ALT_TYPE } from "../objects/backdropTypeToRockAltType";
|
|
20
18
|
import { AnyGridEntity } from "../types/AnyGridEntity";
|
|
21
19
|
import { isCircleIntersectingRectangle } from "./math";
|
|
22
|
-
import { getRandomSeed } from "./rng";
|
|
23
20
|
import { roomUpdateSafe } from "./rooms";
|
|
24
21
|
import { clearSprite } from "./sprites";
|
|
25
22
|
import { isNumber } from "./types";
|
|
@@ -277,27 +274,6 @@ export function getMatchingGridEntities(
|
|
|
277
274
|
);
|
|
278
275
|
}
|
|
279
276
|
|
|
280
|
-
/**
|
|
281
|
-
* Helper function to get the alternate rock type (i.e. urn, mushroom, etc.) that the current room
|
|
282
|
-
* will have.
|
|
283
|
-
*
|
|
284
|
-
* The rock type is based on the backdrop of the room.
|
|
285
|
-
*
|
|
286
|
-
* For example, if you change the backdrop of the starting room of the run to `BackdropType.CAVES`,
|
|
287
|
-
* and then spawn `GridEntityType.ROCK_ALT`, it will be a mushroom instead of an urn. Additionally,
|
|
288
|
-
* if it is destroyed, it will generate mushroom-appropriate rewards.
|
|
289
|
-
*
|
|
290
|
-
* On the other hand, if an urn is spawned first before the backdrop is changed to
|
|
291
|
-
* `BackdropType.CAVES`, the graphic of the urn will not switch to a mushroom. However, when
|
|
292
|
-
* destroyed, the urn will still generate mushroom-appropriate rewards.
|
|
293
|
-
*/
|
|
294
|
-
export function getRockAltType(): RockAltType {
|
|
295
|
-
const room = game.GetRoom();
|
|
296
|
-
const backdropType = room.GetBackdropType();
|
|
297
|
-
|
|
298
|
-
return BACKDROP_TYPE_TO_ROCK_ALT_TYPE[backdropType];
|
|
299
|
-
}
|
|
300
|
-
|
|
301
277
|
export function getSurroundingGridEntities(
|
|
302
278
|
gridEntity: GridEntity,
|
|
303
279
|
): GridEntity[] {
|
|
@@ -488,7 +464,7 @@ export function removeAllMatchingGridEntities(
|
|
|
488
464
|
* generally a good idea because if the room is not updated, you will be unable to
|
|
489
465
|
* spawn another grid entity on the same tile until a frame has passed. However,
|
|
490
466
|
* doing this is expensive, since it involves a call to `Isaac.GetRoomEntities`,
|
|
491
|
-
* so set this to false if you need to
|
|
467
|
+
* so set this to false if you need to run this function multiple times.
|
|
492
468
|
* @param cap Optional. If specified, will only remove the given amount of entities.
|
|
493
469
|
* @returns An array of the entities that were removed.
|
|
494
470
|
*/
|
|
@@ -527,7 +503,7 @@ export function removeGridEntities<T extends AnyGridEntity>(
|
|
|
527
503
|
* generally a good idea because if the room is not updated, you will be unable to
|
|
528
504
|
* spawn another grid entity on the same tile until a frame has passed. However,
|
|
529
505
|
* doing this is expensive, since it involves a call to `Isaac.GetRoomEntities`,
|
|
530
|
-
* so set this to false if you need to
|
|
506
|
+
* so set this to false if you need to run this function multiple times.
|
|
531
507
|
*/
|
|
532
508
|
export function removeGridEntity(
|
|
533
509
|
gridEntityOrGridIndex: GridEntity | int,
|
|
@@ -654,57 +630,6 @@ export function spawnGridEntityWithVariant(
|
|
|
654
630
|
return gridEntity;
|
|
655
631
|
}
|
|
656
632
|
|
|
657
|
-
/**
|
|
658
|
-
* Helper function for emulating what happens when a vanilla `GridEntityType.ROCK_ALT` grid entity
|
|
659
|
-
* breaks.
|
|
660
|
-
*
|
|
661
|
-
* Note that most of the time, this function will do nothing, similar to how most of the time, when
|
|
662
|
-
* an individual urn is destroyed, nothing will spawn.
|
|
663
|
-
*
|
|
664
|
-
* The logic in this function is based on the rewards listed on the wiki:
|
|
665
|
-
* https://bindingofisaacrebirth.fandom.com/wiki/Rocks
|
|
666
|
-
*
|
|
667
|
-
* @param rockAltType The type of reward to spawn. For example, `RockAltType.URN` will have a chance
|
|
668
|
-
* at spawning coins and spiders.
|
|
669
|
-
* @param _seedOrRNG Optional. The `Seed` or `RNG` object to use. If an `RNG` object is provided,
|
|
670
|
-
* the `RNG.Next` method will be called. Default is `getRandomSeed()`. Normally,
|
|
671
|
-
* you should pass the `InitSeed` of the grid entity that was broken.
|
|
672
|
-
* @returns Whether or not this function spawned something.
|
|
673
|
-
*/
|
|
674
|
-
export function spawnRockAltReward(
|
|
675
|
-
rockAltType: RockAltType,
|
|
676
|
-
_seedOrRNG: Seed | RNG = getRandomSeed(),
|
|
677
|
-
): boolean {
|
|
678
|
-
/// const chance = getRandom(seedOrRNG);
|
|
679
|
-
|
|
680
|
-
switch (rockAltType) {
|
|
681
|
-
case RockAltType.URN: {
|
|
682
|
-
// TODO
|
|
683
|
-
return false;
|
|
684
|
-
}
|
|
685
|
-
|
|
686
|
-
case RockAltType.MUSHROOM: {
|
|
687
|
-
// TODO
|
|
688
|
-
return false;
|
|
689
|
-
}
|
|
690
|
-
|
|
691
|
-
case RockAltType.SKULL: {
|
|
692
|
-
// TODO
|
|
693
|
-
return false;
|
|
694
|
-
}
|
|
695
|
-
|
|
696
|
-
case RockAltType.POLYP: {
|
|
697
|
-
// TODO
|
|
698
|
-
return false;
|
|
699
|
-
}
|
|
700
|
-
|
|
701
|
-
case RockAltType.BUCKET: {
|
|
702
|
-
// TODO
|
|
703
|
-
return false;
|
|
704
|
-
}
|
|
705
|
-
}
|
|
706
|
-
}
|
|
707
|
-
|
|
708
633
|
/**
|
|
709
634
|
* Helper function to spawn a Void Portal. This is more complicated than simply spawning a trapdoor
|
|
710
635
|
* with the appropriate variant, as the game does not give it the correct sprite automatically.
|
|
@@ -0,0 +1,153 @@
|
|
|
1
|
+
import {
|
|
2
|
+
CollectibleType,
|
|
3
|
+
ItemConfigTag,
|
|
4
|
+
ItemPoolType,
|
|
5
|
+
PlayerType,
|
|
6
|
+
TrinketType,
|
|
7
|
+
} from "isaac-typescript-definitions";
|
|
8
|
+
import { game } from "../cachedClasses";
|
|
9
|
+
import { PlayerIndex } from "../types/PlayerIndex";
|
|
10
|
+
import { getCollectibleSet } from "./collectibleSet";
|
|
11
|
+
import { collectibleHasTag } from "./collectibleTag";
|
|
12
|
+
import { mapGetPlayer, mapSetPlayer } from "./playerDataStructures";
|
|
13
|
+
import { getPlayers } from "./playerIndex";
|
|
14
|
+
import { getPlayersOfType } from "./players";
|
|
15
|
+
import { repeat } from "./utils";
|
|
16
|
+
|
|
17
|
+
const COLLECTIBLES_THAT_AFFECT_ITEM_POOLS: readonly CollectibleType[] = [
|
|
18
|
+
CollectibleType.CHAOS, // 402
|
|
19
|
+
CollectibleType.SACRED_ORB, // 691
|
|
20
|
+
CollectibleType.TMTRAINER, // 721
|
|
21
|
+
];
|
|
22
|
+
|
|
23
|
+
const TRINKETS_THAT_AFFECT_ITEM_POOLS: readonly TrinketType[] = [
|
|
24
|
+
TrinketType.NO,
|
|
25
|
+
];
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* Helper function to see if the given collectible is still present in the given item pool.
|
|
29
|
+
*
|
|
30
|
+
* If the collectible is non-offensive, any Tainted Losts will be temporarily changed to Isaac and
|
|
31
|
+
* then changed back. (This is because Tainted Lost is not able to retrieve non-offensive
|
|
32
|
+
* collectibles from item pools).
|
|
33
|
+
*/
|
|
34
|
+
export function isCollectibleInItemPool(
|
|
35
|
+
collectibleType: CollectibleType,
|
|
36
|
+
itemPoolType: ItemPoolType,
|
|
37
|
+
): boolean {
|
|
38
|
+
// On Tainted Lost, it is impossible to retrieve non-offensive collectibles from pools, so we
|
|
39
|
+
// temporarily change the character to Isaac.
|
|
40
|
+
const taintedLosts = getPlayersOfType(PlayerType.THE_LOST_B);
|
|
41
|
+
const isOffensive = collectibleHasTag(
|
|
42
|
+
collectibleType,
|
|
43
|
+
ItemConfigTag.OFFENSIVE,
|
|
44
|
+
);
|
|
45
|
+
let changedPlayerTypes = false;
|
|
46
|
+
if (!isOffensive) {
|
|
47
|
+
changedPlayerTypes = true;
|
|
48
|
+
for (const player of taintedLosts) {
|
|
49
|
+
player.ChangePlayerType(PlayerType.ISAAC);
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
const [removedItemsMap, removedTrinketsMap] =
|
|
54
|
+
removeItemsAndTrinketsThatAffectItemPools();
|
|
55
|
+
|
|
56
|
+
// Blacklist every collectible in the game except for the provided collectible.
|
|
57
|
+
const itemPool = game.GetItemPool();
|
|
58
|
+
const collectibleSet = getCollectibleSet();
|
|
59
|
+
for (const collectibleTypeInSet of collectibleSet.values()) {
|
|
60
|
+
if (collectibleTypeInSet !== collectibleType) {
|
|
61
|
+
itemPool.AddRoomBlacklist(collectibleTypeInSet);
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
// Get a collectible from the pool and see if it is the intended collectible. (We can use any
|
|
66
|
+
// arbitrary value as the seed since it should not influence the result.)
|
|
67
|
+
const retrievedCollectibleType = itemPool.GetCollectible(
|
|
68
|
+
itemPoolType,
|
|
69
|
+
false,
|
|
70
|
+
1 as Seed,
|
|
71
|
+
);
|
|
72
|
+
|
|
73
|
+
const collectibleUnlocked = retrievedCollectibleType === collectibleType;
|
|
74
|
+
|
|
75
|
+
// Reset the blacklist
|
|
76
|
+
itemPool.ResetRoomBlacklist();
|
|
77
|
+
|
|
78
|
+
restoreItemsAndTrinketsThatAffectItemPools(
|
|
79
|
+
removedItemsMap,
|
|
80
|
+
removedTrinketsMap,
|
|
81
|
+
);
|
|
82
|
+
|
|
83
|
+
// Change any players back to Tainted Lost, if necessary.
|
|
84
|
+
if (changedPlayerTypes) {
|
|
85
|
+
for (const player of taintedLosts) {
|
|
86
|
+
player.ChangePlayerType(PlayerType.THE_LOST_B);
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
return collectibleUnlocked;
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
/**
|
|
94
|
+
* Before checking the item pools, remove any collectibles or trinkets that would affect the
|
|
95
|
+
* retrieved collectible types.
|
|
96
|
+
*/
|
|
97
|
+
function removeItemsAndTrinketsThatAffectItemPools(): [
|
|
98
|
+
removedItemsMap: Map<PlayerIndex, CollectibleType[]>,
|
|
99
|
+
removedTrinketsMap: Map<PlayerIndex, TrinketType[]>,
|
|
100
|
+
] {
|
|
101
|
+
const removedItemsMap = new Map<PlayerIndex, CollectibleType[]>();
|
|
102
|
+
const removedTrinketsMap = new Map<PlayerIndex, TrinketType[]>();
|
|
103
|
+
for (const player of getPlayers()) {
|
|
104
|
+
const removedItems: CollectibleType[] = [];
|
|
105
|
+
for (const itemToRemove of COLLECTIBLES_THAT_AFFECT_ITEM_POOLS) {
|
|
106
|
+
if (player.HasCollectible(itemToRemove)) {
|
|
107
|
+
const numCollectibles = player.GetCollectibleNum(itemToRemove);
|
|
108
|
+
repeat(numCollectibles, () => {
|
|
109
|
+
player.RemoveCollectible(itemToRemove);
|
|
110
|
+
removedItems.push(itemToRemove);
|
|
111
|
+
});
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
mapSetPlayer(removedItemsMap, player, removedItems);
|
|
116
|
+
|
|
117
|
+
const removedTrinkets: TrinketType[] = [];
|
|
118
|
+
for (const trinketToRemove of TRINKETS_THAT_AFFECT_ITEM_POOLS) {
|
|
119
|
+
if (player.HasTrinket(trinketToRemove)) {
|
|
120
|
+
const numTrinkets = player.GetTrinketMultiplier(trinketToRemove);
|
|
121
|
+
repeat(numTrinkets, () => {
|
|
122
|
+
player.TryRemoveTrinket(trinketToRemove);
|
|
123
|
+
removedTrinkets.push(trinketToRemove);
|
|
124
|
+
});
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
mapSetPlayer(removedTrinketsMap, player, removedTrinkets);
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
return [removedItemsMap, removedTrinketsMap];
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
function restoreItemsAndTrinketsThatAffectItemPools(
|
|
135
|
+
removedItemsMap: Map<PlayerIndex, CollectibleType[]>,
|
|
136
|
+
removedTrinketsMap: Map<PlayerIndex, TrinketType[]>,
|
|
137
|
+
) {
|
|
138
|
+
for (const player of getPlayers()) {
|
|
139
|
+
const removedItems = mapGetPlayer(removedItemsMap, player);
|
|
140
|
+
if (removedItems !== undefined) {
|
|
141
|
+
for (const collectibleType of removedItems) {
|
|
142
|
+
player.AddCollectible(collectibleType, 0, false); // Prevent Chaos from spawning pickups
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
const removedTrinkets = mapGetPlayer(removedTrinketsMap, player);
|
|
147
|
+
if (removedTrinkets !== undefined) {
|
|
148
|
+
for (const trinketType of removedTrinkets) {
|
|
149
|
+
player.AddTrinket(trinketType, false);
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
}
|