isaacscript-common 9.1.1 → 9.2.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.
@@ -4,12 +4,6 @@ import { LevelStage, StageType } from "isaac-typescript-definitions";
4
4
  * want to create a custom trapdoor that goes to a vanilla stage instead, use the
5
5
  * `spawnCustomTrapdoorToVanilla` helper function.
6
6
  *
7
- * Custom trapdoors can have one or more of the following attributes:
8
- *
9
- * - custom destination (or custom logic for after the player enters)
10
- * - custom graphics
11
- * - custom logic for opening/closing
12
- *
13
7
  * Under the hood, the custom trapdoor is represented by a decoration grid entity and is manually
14
8
  * respawned every time the player re-enters the room.
15
9
  *
@@ -1 +1 @@
1
- {"version":3,"file":"exports.d.ts","sourceRoot":"","sources":["../../../src/features/customTrapdoor/exports.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,8BAA8B,CAAC;AAOrE;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,wBAAgB,mBAAmB,CACjC,mBAAmB,EAAE,GAAG,GAAG,MAAM,EACjC,eAAe,EAAE,MAAM,EACvB,mBAAmB,EAAE,GAAG,EACxB,QAAQ,SAAmC,EAC3C,SAAS,CAAC,EAAE,OAAO,GAClB,UAAU,CAcZ;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,4BAA4B,CAC1C,mBAAmB,EAAE,GAAG,GAAG,MAAM,EACjC,KAAK,CAAC,EAAE,UAAU,EAClB,SAAS,CAAC,EAAE,SAAS,EACrB,QAAQ,SAAmC,EAC3C,SAAS,CAAC,EAAE,OAAO,GAClB,UAAU,CAkBZ"}
1
+ {"version":3,"file":"exports.d.ts","sourceRoot":"","sources":["../../../src/features/customTrapdoor/exports.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,8BAA8B,CAAC;AAOrE;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,mBAAmB,CACjC,mBAAmB,EAAE,GAAG,GAAG,MAAM,EACjC,eAAe,EAAE,MAAM,EACvB,mBAAmB,EAAE,GAAG,EACxB,QAAQ,SAAmC,EAC3C,SAAS,CAAC,EAAE,OAAO,GAClB,UAAU,CAcZ;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,4BAA4B,CAC1C,mBAAmB,EAAE,GAAG,GAAG,MAAM,EACjC,KAAK,CAAC,EAAE,UAAU,EAClB,SAAS,CAAC,EAAE,SAAS,EACrB,QAAQ,SAAmC,EAC3C,SAAS,CAAC,EAAE,OAAO,GAClB,UAAU,CAkBZ"}
@@ -12,12 +12,6 @@ local spawnCustomTrapdoorToDestination = ____spawn.spawnCustomTrapdoorToDestinat
12
12
  -- want to create a custom trapdoor that goes to a vanilla stage instead, use the
13
13
  -- `spawnCustomTrapdoorToVanilla` helper function.
14
14
  --
15
- -- Custom trapdoors can have one or more of the following attributes:
16
- --
17
- -- - custom destination (or custom logic for after the player enters)
18
- -- - custom graphics
19
- -- - custom logic for opening/closing
20
- --
21
15
  -- Under the hood, the custom trapdoor is represented by a decoration grid entity and is manually
22
16
  -- respawned every time the player re-enters the room.
23
17
  --
@@ -1 +1 @@
1
- {"version":3,"file":"main.d.ts","sourceRoot":"","sources":["../../../src/features/saveDataManager/main.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,WAAW,EAAE,MAAM,2BAA2B,CAAC;AAGxD,OAAO,EAAE,WAAW,EAAE,MAAM,yBAAyB,CAAC;AAKtD,OAAO,EAAE,QAAQ,EAAE,MAAM,2BAA2B,CAAC;AAsBrD,wBAAgB,mBAAmB,CAAC,WAAW,EAAE,WAAW,GAAG,IAAI,CAUlE;AAuED,wBAAgB,sBAAsB,CACpC,cAAc,EAAE,MAAM,EACtB,QAAQ,EAAE,QAAQ,EAClB,WAAW,EAAE,WAAW,GACvB,IAAI,CA4CN;AAiBD,wBAAgB,wBAAwB,IAAI,IAAI,CAM/C;AAED,wBAAgB,wBAAwB,IAAI,IAAI,CAM/C"}
1
+ {"version":3,"file":"main.d.ts","sourceRoot":"","sources":["../../../src/features/saveDataManager/main.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,WAAW,EAAE,MAAM,2BAA2B,CAAC;AAGxD,OAAO,EAAE,WAAW,EAAE,MAAM,yBAAyB,CAAC;AAMtD,OAAO,EAAE,QAAQ,EAAE,MAAM,2BAA2B,CAAC;AAsBrD,wBAAgB,mBAAmB,CAAC,WAAW,EAAE,WAAW,GAAG,IAAI,CAUlE;AAqFD,wBAAgB,sBAAsB,CACpC,cAAc,EAAE,MAAM,EACtB,QAAQ,EAAE,QAAQ,EAClB,WAAW,EAAE,WAAW,GACvB,IAAI,CA4CN;AAiBD,wBAAgB,wBAAwB,IAAI,IAAI,CAM/C;AAED,wBAAgB,wBAAwB,IAAI,IAAI,CAM/C"}
@@ -17,6 +17,8 @@ local ____deepCopy = require("functions.deepCopy")
17
17
  local deepCopy = ____deepCopy.deepCopy
18
18
  local ____log = require("functions.log")
19
19
  local logError = ____log.logError
20
+ local ____stage = require("functions.stage")
21
+ local onFirstFloor = ____stage.onFirstFloor
20
22
  local ____table = require("functions.table")
21
23
  local clearTable = ____table.clearTable
22
24
  local iterateTableInOrder = ____table.iterateTableInOrder
@@ -55,7 +57,13 @@ function preGameExit(self)
55
57
  loadedDataOnThisRun = false
56
58
  end
57
59
  function postNewLevel(self)
60
+ if mod == nil then
61
+ error(("The mod for the " .. SAVE_DATA_MANAGER_FEATURE_NAME) .. " was not initialized.")
62
+ end
58
63
  restoreDefaults(nil, SaveDataKey.LEVEL)
64
+ if not onFirstFloor(nil) then
65
+ saveToDisk(nil, mod, saveDataMap, saveDataConditionalFuncMap)
66
+ end
59
67
  end
60
68
  function postNewRoomEarly(self)
61
69
  restoreDefaults(nil, SaveDataKey.ROOM)
@@ -40,6 +40,13 @@ export declare function onDarkRoom(): boolean;
40
40
  * I AM ERROR room is never entered into the list of possibilities.
41
41
  */
42
42
  export declare function onFinalFloor(): boolean;
43
+ /**
44
+ * Returns whether or not the player is on the first floor of the particular run.
45
+ *
46
+ * This is tricky to determine because we have to handle the cases of Downpour/Dross 1 not being the
47
+ * first floor and The Ascent.
48
+ */
49
+ export declare function onFirstFloor(): boolean;
43
50
  export declare function onRepentanceStage(): boolean;
44
51
  export declare function onSheol(): boolean;
45
52
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"stage.d.ts","sourceRoot":"","sources":["../../src/functions/stage.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,UAAU,EACV,QAAQ,EACR,SAAS,EACV,MAAM,8BAA8B,CAAC;AAOtC;;;GAGG;AACH,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,UAAU,GAAG,SAAS,CA6B/D;AAED;;;GAGG;AACH,wBAAgB,4BAA4B,CAAC,KAAK,EAAE,UAAU,GAAG,SAAS,CAmBzE;AAED;;;;GAIG;AACH,wBAAgB,iBAAiB,IAAI,GAAG,CASvC;AAED;;;GAGG;AACH,wBAAgB,cAAc,CAAC,QAAQ,EAAE,QAAQ,EAAE,WAAW,EAAE,GAAG,GAAG,MAAM,CAG3E;AAED,6CAA6C;AAC7C,wBAAgB,QAAQ,IAAI,UAAU,CAIrC;AAED,iDAAiD;AACjD,wBAAgB,YAAY,IAAI,SAAS,CAIxC;AAED,8FAA8F;AAC9F,wBAAgB,SAAS,CAAC,KAAK,EAAE,UAAU,EAAE,SAAS,EAAE,SAAS,GAAG,IAAI,CAIvE;AAED,wBAAgB,iBAAiB,CAAC,SAAS,EAAE,SAAS,GAAG,OAAO,CAI/D;AAED,wBAAgB,QAAQ,IAAI,OAAO,CAElC;AAED,wBAAgB,WAAW,IAAI,OAAO,CASrC;AAED,wBAAgB,OAAO,IAAI,OAAO,CASjC;AAED,wBAAgB,UAAU,IAAI,OAAO,CAQpC;AAED;;;;;;;GAOG;AACH,wBAAgB,YAAY,IAAI,OAAO,CAUtC;AAED,wBAAgB,iBAAiB,IAAI,OAAO,CAK3C;AAED,wBAAgB,OAAO,IAAI,OAAO,CAQjC;AAED;;;;;;;;GAQG;AACH,wBAAgB,QAAQ,CACtB,KAAK,EAAE,UAAU,EACjB,SAAS,EAAE,SAAS,EACpB,MAAM,UAAQ,GACb,IAAI,CAUN;AAED;;;;;GAKG;AACH,wBAAgB,iBAAiB,CAAC,SAAS,EAAE,SAAS,GAAG,MAAM,CAE9D"}
1
+ {"version":3,"file":"stage.d.ts","sourceRoot":"","sources":["../../src/functions/stage.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,UAAU,EACV,QAAQ,EACR,SAAS,EACV,MAAM,8BAA8B,CAAC;AAOtC;;;GAGG;AACH,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,UAAU,GAAG,SAAS,CA6B/D;AAED;;;GAGG;AACH,wBAAgB,4BAA4B,CAAC,KAAK,EAAE,UAAU,GAAG,SAAS,CAmBzE;AAED;;;;GAIG;AACH,wBAAgB,iBAAiB,IAAI,GAAG,CASvC;AAED;;;GAGG;AACH,wBAAgB,cAAc,CAAC,QAAQ,EAAE,QAAQ,EAAE,WAAW,EAAE,GAAG,GAAG,MAAM,CAG3E;AAED,6CAA6C;AAC7C,wBAAgB,QAAQ,IAAI,UAAU,CAIrC;AAED,iDAAiD;AACjD,wBAAgB,YAAY,IAAI,SAAS,CAIxC;AAED,8FAA8F;AAC9F,wBAAgB,SAAS,CAAC,KAAK,EAAE,UAAU,EAAE,SAAS,EAAE,SAAS,GAAG,IAAI,CAIvE;AAED,wBAAgB,iBAAiB,CAAC,SAAS,EAAE,SAAS,GAAG,OAAO,CAI/D;AAED,wBAAgB,QAAQ,IAAI,OAAO,CAElC;AAED,wBAAgB,WAAW,IAAI,OAAO,CASrC;AAED,wBAAgB,OAAO,IAAI,OAAO,CASjC;AAED,wBAAgB,UAAU,IAAI,OAAO,CAQpC;AAED;;;;;;;GAOG;AACH,wBAAgB,YAAY,IAAI,OAAO,CAUtC;AAED;;;;;GAKG;AACH,wBAAgB,YAAY,IAAI,OAAO,CAKtC;AAED,wBAAgB,iBAAiB,IAAI,OAAO,CAK3C;AAED,wBAAgB,OAAO,IAAI,OAAO,CAQjC;AAED;;;;;;;;GAQG;AACH,wBAAgB,QAAQ,CACtB,KAAK,EAAE,UAAU,EACjB,SAAS,EAAE,SAAS,EACpB,MAAM,UAAQ,GACb,IAAI,CAUN;AAED;;;;;GAKG;AACH,wBAAgB,iBAAiB,CAAC,SAAS,EAAE,SAAS,GAAG,MAAM,CAE9D"}
@@ -125,6 +125,15 @@ function ____exports.onFinalFloor(self)
125
125
  local stage = level:GetStage()
126
126
  return stage == LevelStage.DARK_ROOM_CHEST or stage == LevelStage.THE_VOID or stage == LevelStage.HOME or stage == LevelStage.WOMB_2 and ____exports.onRepentanceStage(nil)
127
127
  end
128
+ --- Returns whether or not the player is on the first floor of the particular run.
129
+ --
130
+ -- This is tricky to determine because we have to handle the cases of Downpour/Dross 1 not being the
131
+ -- first floor and The Ascent.
132
+ function ____exports.onFirstFloor(self)
133
+ local effectiveStage = ____exports.getEffectiveStage(nil)
134
+ local isOnAscent = ____exports.onAscent(nil)
135
+ return effectiveStage == 1 and not isOnAscent
136
+ end
128
137
  function ____exports.onSheol(self)
129
138
  local level = game:GetLevel()
130
139
  local stage = level:GetStage()
package/dist/index.d.ts CHANGED
@@ -8255,6 +8255,14 @@ export declare const ONE_BY_ONE_ROOM_GRID_SIZE = 135;
8255
8255
  */
8256
8256
  export declare function onFinalFloor(): boolean;
8257
8257
 
8258
+ /**
8259
+ * Returns whether or not the player is on the first floor of the particular run.
8260
+ *
8261
+ * This is tricky to determine because we have to handle the cases of Downpour/Dross 1 not being the
8262
+ * first floor and The Ascent.
8263
+ */
8264
+ export declare function onFirstFloor(): boolean;
8265
+
8258
8266
  export declare function onRepentanceStage(): boolean;
8259
8267
 
8260
8268
  /**
@@ -10863,12 +10871,6 @@ export declare function spawnCustomGridEntity(gridEntityTypeCustom: GridEntityTy
10863
10871
  * want to create a custom trapdoor that goes to a vanilla stage instead, use the
10864
10872
  * `spawnCustomTrapdoorToVanilla` helper function.
10865
10873
  *
10866
- * Custom trapdoors can have one or more of the following attributes:
10867
- *
10868
- * - custom destination (or custom logic for after the player enters)
10869
- * - custom graphics
10870
- * - custom logic for opening/closing
10871
- *
10872
10874
  * Under the hood, the custom trapdoor is represented by a decoration grid entity and is manually
10873
10875
  * respawned every time the player re-enters the room.
10874
10876
  *
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "isaacscript-common",
3
- "version": "9.1.1",
3
+ "version": "9.2.0",
4
4
  "description": "Helper functions and features for IsaacScript mods.",
5
5
  "keywords": [
6
6
  "isaac",
@@ -10,12 +10,6 @@ import { spawnCustomTrapdoorToDestination } from "./spawn";
10
10
  * want to create a custom trapdoor that goes to a vanilla stage instead, use the
11
11
  * `spawnCustomTrapdoorToVanilla` helper function.
12
12
  *
13
- * Custom trapdoors can have one or more of the following attributes:
14
- *
15
- * - custom destination (or custom logic for after the player enters)
16
- * - custom graphics
17
- * - custom logic for opening/closing
18
- *
19
13
  * Under the hood, the custom trapdoor is represented by a decoration grid entity and is manually
20
14
  * respawned every time the player re-enters the room.
21
15
  *
@@ -6,6 +6,7 @@ import { SaveDataKey } from "../../enums/SaveDataKey";
6
6
  import { SerializationType } from "../../enums/SerializationType";
7
7
  import { deepCopy } from "../../functions/deepCopy";
8
8
  import { logError } from "../../functions/log";
9
+ import { onFirstFloor } from "../../functions/stage";
9
10
  import { clearTable, iterateTableInOrder } from "../../functions/table";
10
11
  import { SaveData } from "../../interfaces/SaveData";
11
12
  import { loadFromDisk } from "./load";
@@ -49,6 +50,8 @@ function postPlayerInit() {
49
50
  );
50
51
  }
51
52
 
53
+ // We want to only load data once per run to handle the case of a player using Genesis, a second
54
+ // player joining the run, and so on.
52
55
  if (loadedDataOnThisRun) {
53
56
  return;
54
57
  }
@@ -86,7 +89,19 @@ function preGameExit() {
86
89
 
87
90
  // ModCallback.POST_NEW_LEVEL (18)
88
91
  function postNewLevel() {
92
+ if (mod === null) {
93
+ error(
94
+ `The mod for the ${SAVE_DATA_MANAGER_FEATURE_NAME} was not initialized.`,
95
+ );
96
+ }
97
+
89
98
  restoreDefaults(SaveDataKey.LEVEL);
99
+
100
+ // We save data to disk at the beginning of every floor (for the 2nd floor and beyond) to emulate
101
+ // what the game does internally. (This mitigates data loss in the event of a crash).
102
+ if (!onFirstFloor()) {
103
+ saveToDisk(mod, saveDataMap, saveDataConditionalFuncMap);
104
+ }
90
105
  }
91
106
 
92
107
  // ModCallbackCustom.POST_NEW_ROOM_EARLY
@@ -178,6 +178,19 @@ export function onFinalFloor(): boolean {
178
178
  );
179
179
  }
180
180
 
181
+ /**
182
+ * Returns whether or not the player is on the first floor of the particular run.
183
+ *
184
+ * This is tricky to determine because we have to handle the cases of Downpour/Dross 1 not being the
185
+ * first floor and The Ascent.
186
+ */
187
+ export function onFirstFloor(): boolean {
188
+ const effectiveStage = getEffectiveStage();
189
+ const isOnAscent = onAscent();
190
+
191
+ return effectiveStage === 1 && !isOnAscent;
192
+ }
193
+
181
194
  export function onRepentanceStage(): boolean {
182
195
  const level = game.GetLevel();
183
196
  const stageType = level.GetStageType();