isaacscript-common 87.3.0 → 87.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (49) hide show
  1. package/dist/cachedEnumValues.d.ts +15 -3
  2. package/dist/cachedEnumValues.d.ts.map +1 -1
  3. package/dist/classes/features/callbackLogic/ItemPickupDetection.d.ts.map +1 -1
  4. package/dist/classes/features/callbackLogic/ItemPickupDetection.js +6 -2
  5. package/dist/classes/features/callbackLogic/ItemPickupDetection.lua +6 -1
  6. package/dist/core/constants.d.ts +5 -1
  7. package/dist/core/constants.d.ts.map +1 -1
  8. package/dist/enums/ModCallbackCustom.d.ts +5 -4
  9. package/dist/enums/ModCallbackCustom.d.ts.map +1 -1
  10. package/dist/enums/ModCallbackCustom.js +5 -4
  11. package/dist/functions/entities.d.ts +3 -3
  12. package/dist/functions/entities.d.ts.map +1 -1
  13. package/dist/functions/entities.js +5 -4
  14. package/dist/functions/entities.lua +4 -11
  15. package/dist/functions/gridEntities.d.ts.map +1 -1
  16. package/dist/functions/gridEntities.js +6 -0
  17. package/dist/functions/gridEntities.lua +9 -5
  18. package/dist/functions/players.d.ts +2 -0
  19. package/dist/functions/players.d.ts.map +1 -1
  20. package/dist/functions/players.js +2 -0
  21. package/dist/functions/players.lua +2 -0
  22. package/dist/functions/string.d.ts +1 -1
  23. package/dist/functions/string.js +1 -1
  24. package/dist/functions/string.lua +1 -1
  25. package/dist/functions/utils.d.ts +11 -0
  26. package/dist/functions/utils.d.ts.map +1 -1
  27. package/dist/functions/utils.js +20 -1
  28. package/dist/functions/utils.lua +16 -0
  29. package/dist/index.lua +432 -0
  30. package/dist/index.rollup.d.ts +33 -12
  31. package/dist/indexLua.lua +432 -0
  32. package/dist/interfaces/private/AddCallbackParametersCustom.d.ts +5 -3
  33. package/dist/interfaces/private/AddCallbackParametersCustom.d.ts.map +1 -1
  34. package/dist/isaacscript-common.lua +1099 -1895
  35. package/dist/lualib_bundle.lua +97 -4
  36. package/dist/maps/defaultPlayerStatMap.d.ts +5 -1
  37. package/dist/maps/defaultPlayerStatMap.d.ts.map +1 -1
  38. package/dist/objects/doorSlotToDoorSlotFlag.d.ts +45 -9
  39. package/dist/objects/doorSlotToDoorSlotFlag.d.ts.map +1 -1
  40. package/dist/tsdoc-metadata.json +1 -1
  41. package/package.json +2 -2
  42. package/src/classes/features/callbackLogic/ItemPickupDetection.ts +6 -2
  43. package/src/enums/ModCallbackCustom.ts +5 -4
  44. package/src/functions/entities.ts +5 -11
  45. package/src/functions/gridEntities.ts +12 -0
  46. package/src/functions/players.ts +2 -0
  47. package/src/functions/string.ts +1 -1
  48. package/src/functions/utils.ts +29 -0
  49. package/src/interfaces/private/AddCallbackParametersCustom.ts +8 -3
@@ -773,10 +773,11 @@ end
773
773
 
774
774
  local __TS__AsyncAwaiter, __TS__Await
775
775
  do
776
- local cocreate = coroutine.create
777
- local coresume = coroutine.resume
778
- local costatus = coroutine.status
779
- local coyield = coroutine.yield
776
+ local ____coroutine = _G.coroutine or ({})
777
+ local cocreate = ____coroutine.create
778
+ local coresume = ____coroutine.resume
779
+ local costatus = ____coroutine.status
780
+ local coyield = ____coroutine.yield
780
781
  function __TS__AsyncAwaiter(generator)
781
782
  return __TS__New(
782
783
  __TS__Promise,
@@ -1417,6 +1418,22 @@ do
1417
1418
  Map[Symbol.species] = Map
1418
1419
  end
1419
1420
 
1421
+ local function __TS__MapGroupBy(items, keySelector)
1422
+ local result = __TS__New(Map)
1423
+ local i = 0
1424
+ for ____, item in __TS__Iterator(items) do
1425
+ local key = keySelector(nil, item, i)
1426
+ if result:has(key) then
1427
+ local ____temp_0 = result:get(key)
1428
+ ____temp_0[#____temp_0 + 1] = item
1429
+ else
1430
+ result:set(key, {item})
1431
+ end
1432
+ i = i + 1
1433
+ end
1434
+ return result
1435
+ end
1436
+
1420
1437
  local __TS__Match = string.match
1421
1438
 
1422
1439
  local __TS__MathAtan2 = math.atan2 or math.atan
@@ -1671,6 +1688,22 @@ local function __TS__ObjectFromEntries(entries)
1671
1688
  return obj
1672
1689
  end
1673
1690
 
1691
+ local function __TS__ObjectGroupBy(items, keySelector)
1692
+ local result = {}
1693
+ local i = 0
1694
+ for ____, item in __TS__Iterator(items) do
1695
+ local key = keySelector(nil, item, i)
1696
+ if result[key] ~= nil then
1697
+ local ____result_key_0 = result[key]
1698
+ ____result_key_0[#____result_key_0 + 1] = item
1699
+ else
1700
+ result[key] = {item}
1701
+ end
1702
+ i = i + 1
1703
+ end
1704
+ return result
1705
+ end
1706
+
1674
1707
  local function __TS__ObjectKeys(obj)
1675
1708
  local result = {}
1676
1709
  local len = 0
@@ -1994,6 +2027,64 @@ do
1994
2027
  end
1995
2028
  }
1996
2029
  end
2030
+ function Set.prototype.union(self, other)
2031
+ local result = __TS__New(Set, self)
2032
+ for ____, item in __TS__Iterator(other) do
2033
+ result:add(item)
2034
+ end
2035
+ return result
2036
+ end
2037
+ function Set.prototype.intersection(self, other)
2038
+ local result = __TS__New(Set)
2039
+ for ____, item in __TS__Iterator(self) do
2040
+ if other:has(item) then
2041
+ result:add(item)
2042
+ end
2043
+ end
2044
+ return result
2045
+ end
2046
+ function Set.prototype.difference(self, other)
2047
+ local result = __TS__New(Set, self)
2048
+ for ____, item in __TS__Iterator(other) do
2049
+ result:delete(item)
2050
+ end
2051
+ return result
2052
+ end
2053
+ function Set.prototype.symmetricDifference(self, other)
2054
+ local result = __TS__New(Set, self)
2055
+ for ____, item in __TS__Iterator(other) do
2056
+ if self:has(item) then
2057
+ result:delete(item)
2058
+ else
2059
+ result:add(item)
2060
+ end
2061
+ end
2062
+ return result
2063
+ end
2064
+ function Set.prototype.isSubsetOf(self, other)
2065
+ for ____, item in __TS__Iterator(self) do
2066
+ if not other:has(item) then
2067
+ return false
2068
+ end
2069
+ end
2070
+ return true
2071
+ end
2072
+ function Set.prototype.isSupersetOf(self, other)
2073
+ for ____, item in __TS__Iterator(other) do
2074
+ if not self:has(item) then
2075
+ return false
2076
+ end
2077
+ end
2078
+ return true
2079
+ end
2080
+ function Set.prototype.isDisjointFrom(self, other)
2081
+ for ____, item in __TS__Iterator(self) do
2082
+ if other:has(item) then
2083
+ return false
2084
+ end
2085
+ end
2086
+ return true
2087
+ end
1997
2088
  Set[Symbol.species] = Set
1998
2089
  end
1999
2090
 
@@ -2563,6 +2654,7 @@ return {
2563
2654
  __TS__Iterator = __TS__Iterator,
2564
2655
  __TS__LuaIteratorSpread = __TS__LuaIteratorSpread,
2565
2656
  Map = Map,
2657
+ __TS__MapGroupBy = __TS__MapGroupBy,
2566
2658
  __TS__Match = __TS__Match,
2567
2659
  __TS__MathAtan2 = __TS__MathAtan2,
2568
2660
  __TS__MathModf = __TS__MathModf,
@@ -2582,6 +2674,7 @@ return {
2582
2674
  __TS__ObjectFromEntries = __TS__ObjectFromEntries,
2583
2675
  __TS__ObjectGetOwnPropertyDescriptor = __TS__ObjectGetOwnPropertyDescriptor,
2584
2676
  __TS__ObjectGetOwnPropertyDescriptors = __TS__ObjectGetOwnPropertyDescriptors,
2677
+ __TS__ObjectGroupBy = __TS__ObjectGroupBy,
2585
2678
  __TS__ObjectKeys = __TS__ObjectKeys,
2586
2679
  __TS__ObjectRest = __TS__ObjectRest,
2587
2680
  __TS__ObjectValues = __TS__ObjectValues,
@@ -1,3 +1,7 @@
1
1
  /** The default fire delay is represented in the tear stat, not the `MaxFireDelay` value. */
2
- export declare const DEFAULT_PLAYER_STAT_MAP: ReadonlyMap<import("isaac-typescript-definitions").CacheFlag, number>;
2
+ export declare const DEFAULT_PLAYER_STAT_MAP: ReadonlyMap<number & {
3
+ readonly __bitFlagBrand: symbol;
4
+ } & {
5
+ readonly __cacheFlagBrand: symbol;
6
+ }, number>;
3
7
  //# sourceMappingURL=defaultPlayerStatMap.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"defaultPlayerStatMap.d.ts","sourceRoot":"","sources":["../../src/maps/defaultPlayerStatMap.ts"],"names":[],"mappings":"AAMA,4FAA4F;AAC5F,eAAO,MAAM,uBAAuB,uEAUlC,CAAC"}
1
+ {"version":3,"file":"defaultPlayerStatMap.d.ts","sourceRoot":"","sources":["../../src/maps/defaultPlayerStatMap.ts"],"names":[],"mappings":"AAMA,4FAA4F;AAC5F,eAAO,MAAM,uBAAuB;;;;UAUlC,CAAC"}
@@ -1,13 +1,49 @@
1
1
  /// <reference types="isaac-typescript-definitions" />
2
2
  export declare const DOOR_SLOT_TO_DOOR_SLOT_FLAG: {
3
- readonly [-1]: BitFlags<import("isaac-typescript-definitions").DoorSlotFlag>;
4
- readonly 0: import("isaac-typescript-definitions").DoorSlotFlag;
5
- readonly 1: import("isaac-typescript-definitions").DoorSlotFlag;
6
- readonly 2: import("isaac-typescript-definitions").DoorSlotFlag;
7
- readonly 3: import("isaac-typescript-definitions").DoorSlotFlag;
8
- readonly 4: import("isaac-typescript-definitions").DoorSlotFlag;
9
- readonly 5: import("isaac-typescript-definitions").DoorSlotFlag;
10
- readonly 6: import("isaac-typescript-definitions").DoorSlotFlag;
11
- readonly 7: import("isaac-typescript-definitions").DoorSlotFlag;
3
+ readonly [-1]: BitFlags<number & {
4
+ readonly __bitFlagBrand: symbol;
5
+ } & {
6
+ readonly __doorSlotFlagBrand: symbol;
7
+ }>;
8
+ readonly 0: number & {
9
+ readonly __bitFlagBrand: symbol;
10
+ } & {
11
+ readonly __doorSlotFlagBrand: symbol;
12
+ };
13
+ readonly 1: number & {
14
+ readonly __bitFlagBrand: symbol;
15
+ } & {
16
+ readonly __doorSlotFlagBrand: symbol;
17
+ };
18
+ readonly 2: number & {
19
+ readonly __bitFlagBrand: symbol;
20
+ } & {
21
+ readonly __doorSlotFlagBrand: symbol;
22
+ };
23
+ readonly 3: number & {
24
+ readonly __bitFlagBrand: symbol;
25
+ } & {
26
+ readonly __doorSlotFlagBrand: symbol;
27
+ };
28
+ readonly 4: number & {
29
+ readonly __bitFlagBrand: symbol;
30
+ } & {
31
+ readonly __doorSlotFlagBrand: symbol;
32
+ };
33
+ readonly 5: number & {
34
+ readonly __bitFlagBrand: symbol;
35
+ } & {
36
+ readonly __doorSlotFlagBrand: symbol;
37
+ };
38
+ readonly 6: number & {
39
+ readonly __bitFlagBrand: symbol;
40
+ } & {
41
+ readonly __doorSlotFlagBrand: symbol;
42
+ };
43
+ readonly 7: number & {
44
+ readonly __bitFlagBrand: symbol;
45
+ } & {
46
+ readonly __doorSlotFlagBrand: symbol;
47
+ };
12
48
  };
13
49
  //# sourceMappingURL=doorSlotToDoorSlotFlag.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"doorSlotToDoorSlotFlag.d.ts","sourceRoot":"","sources":["../../src/objects/doorSlotToDoorSlotFlag.ts"],"names":[],"mappings":";AAMA,eAAO,MAAM,2BAA2B;;;;;;;;;;CAUW,CAAC"}
1
+ {"version":3,"file":"doorSlotToDoorSlotFlag.d.ts","sourceRoot":"","sources":["../../src/objects/doorSlotToDoorSlotFlag.ts"],"names":[],"mappings":";AAMA,eAAO,MAAM,2BAA2B;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAUW,CAAC"}
@@ -5,7 +5,7 @@
5
5
  "toolPackages": [
6
6
  {
7
7
  "packageName": "@microsoft/api-extractor",
8
- "packageVersion": "7.42.3"
8
+ "packageVersion": "7.47.0"
9
9
  }
10
10
  ]
11
11
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "isaacscript-common",
3
- "version": "87.3.0",
3
+ "version": "87.5.0",
4
4
  "description": "Helper functions and features for IsaacScript mods.",
5
5
  "keywords": [
6
6
  "isaac",
@@ -37,6 +37,6 @@
37
37
  "lint": "tsx --tsconfig ./scripts/tsconfig.json ./scripts/lint.mts"
38
38
  },
39
39
  "dependencies": {
40
- "isaac-typescript-definitions": "^41.1.0"
40
+ "isaac-typescript-definitions": "^42.2.0"
41
41
  }
42
42
  }
@@ -5,6 +5,7 @@ import type {
5
5
  import { ItemType } from "isaac-typescript-definitions";
6
6
  import { ModCallbackCustom } from "../../../enums/ModCallbackCustom";
7
7
  import { defaultMapGetPlayer } from "../../../functions/playerDataStructures";
8
+ import { dequeueItem } from "../../../functions/players";
8
9
  import { asNumber } from "../../../functions/types";
9
10
  import type { PickingUpItem } from "../../../types/PickingUpItem";
10
11
  import {
@@ -78,7 +79,7 @@ export class ItemPickupDetection extends Feature {
78
79
  private queueNotEmpty(player: EntityPlayer, pickingUpItem: PickingUpItem) {
79
80
  const queuedItem = player.QueuedItem.Item;
80
81
  if (queuedItem === undefined || queuedItem.Type === ItemType.NULL) {
81
- // This should never happen, since the `EntityPlayer.IsItemQueueEmpty` method returned true.
82
+ // This should never happen, since the `EntityPlayer.IsItemQueueEmpty` method returned false.
82
83
  return;
83
84
  }
84
85
 
@@ -90,7 +91,10 @@ export class ItemPickupDetection extends Feature {
90
91
  pickingUpItem.itemType = queuedItem.Type;
91
92
  pickingUpItem.subType = queuedItem.ID as CollectibleType | TrinketType;
92
93
 
93
- this.preItemPickup.fire(player, pickingUpItem);
94
+ const shouldBeGranted = this.preItemPickup.fire(player, pickingUpItem);
95
+ if (shouldBeGranted === false) {
96
+ dequeueItem(player);
97
+ }
94
98
  }
95
99
  }
96
100
  }
@@ -1648,8 +1648,8 @@ export enum ModCallbackCustom {
1648
1648
  POST_PLAYER_COLLECTIBLE_REMOVED,
1649
1649
 
1650
1650
  /**
1651
- * Fires from the `ENTITY_TAKE_DMG` callback when a player takes fatal damage. Return false to
1652
- * prevent the fatal damage.
1651
+ * Fires from the `ENTITY_TAKE_DMG` callback when a player takes fatal damage. You can optionally
1652
+ * return false to prevent the fatal damage.
1653
1653
  *
1654
1654
  * Note that this function does properly take into account Guppy's Collar, Broken Ankh, Spirit
1655
1655
  * Shackles, and Mysterious Paper. It also takes into account using The Bible on Satan.
@@ -2450,7 +2450,8 @@ export enum ModCallbackCustom {
2450
2450
 
2451
2451
  /**
2452
2452
  * Fires from the `POST_PEFFECT_UPDATE_REORDERED` callback when an item becomes queued (i.e. when
2453
- * the player begins to hold the item above their head).
2453
+ * the player begins to hold the item above their head). You can optionally return false if you
2454
+ * want the item to not be granted to the player.
2454
2455
  *
2455
2456
  * Note that this callback will only fire once per Forgotten/Soul pair.
2456
2457
  *
@@ -2464,7 +2465,7 @@ export enum ModCallbackCustom {
2464
2465
  * function preItemPickup(
2465
2466
  * player: EntityPlayer,
2466
2467
  * pickingUpItem: PickingUpItem,
2467
- * ): void {}
2468
+ * ): boolean | undefined {}
2468
2469
  * ```
2469
2470
  */
2470
2471
  PRE_ITEM_PICKUP,
@@ -640,8 +640,8 @@ export function setEntityRandomColor(entity: Entity): void {
640
640
  }
641
641
 
642
642
  /**
643
- * Helper function to spawn an entity. Use this instead of the `Isaac.Spawn` method if you do not
644
- * need to specify the velocity or spawner.
643
+ * Helper function to spawn an entity. Always use this instead of the `Isaac.Spawn` method, since
644
+ * using that method can crash the game.
645
645
  *
646
646
  * Also see the `spawnWithSeed` helper function.
647
647
  *
@@ -653,7 +653,7 @@ export function setEntityRandomColor(entity: Entity): void {
653
653
  * @param spawner Optional. The entity that will be the `SpawnerEntity`. Default is undefined.
654
654
  * @param seedOrRNG Optional. The seed or RNG object to use to generate the `InitSeed` of the
655
655
  * entity. Default is undefined, which will make the entity spawn with a random
656
- * seed using the `Isaac.Spawn` method.
656
+ * seed.
657
657
  */
658
658
  export function spawn(
659
659
  entityType: EntityType,
@@ -666,6 +666,7 @@ export function spawn(
666
666
  ): Entity {
667
667
  const room = game.GetRoom();
668
668
 
669
+ // We do an explicit check to prevent run-time errors in Lua environments.
669
670
  // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
670
671
  if (positionOrGridIndex === undefined) {
671
672
  const entityID = getEntityIDFromConstituents(entityType, variant, subType);
@@ -679,14 +680,7 @@ export function spawn(
679
680
  : room.GetGridPosition(positionOrGridIndex);
680
681
 
681
682
  if (seedOrRNG === undefined) {
682
- return Isaac.Spawn(
683
- entityType,
684
- variant,
685
- subType,
686
- position,
687
- velocity,
688
- spawner,
689
- );
683
+ seedOrRNG = newRNG();
690
684
  }
691
685
 
692
686
  const seed = isRNG(seedOrRNG) ? seedOrRNG.Next() : seedOrRNG;
@@ -1219,6 +1219,18 @@ export function spawnGridEntityWithVariant(
1219
1219
  ): GridEntity | undefined {
1220
1220
  const room = game.GetRoom();
1221
1221
 
1222
+ // We do an explicit check to prevent run-time errors in Lua environments.
1223
+ // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
1224
+ if (gridIndexOrPosition === undefined) {
1225
+ const gridEntityID = getGridEntityIDFromConstituents(
1226
+ gridEntityType,
1227
+ variant,
1228
+ );
1229
+ error(
1230
+ `Failed to spawn grid entity ${gridEntityID} since an undefined position was passed to the "spawnGridEntityWithVariant" function.`,
1231
+ );
1232
+ }
1233
+
1222
1234
  const existingGridEntity = isVector(gridIndexOrPosition)
1223
1235
  ? room.GetGridEntityFromPos(gridIndexOrPosition)
1224
1236
  : room.GetGridEntity(gridIndexOrPosition);
@@ -73,6 +73,8 @@ export function canPlayerCrushRocks(player: EntityPlayer): boolean {
73
73
  *
74
74
  * Under the hood, this clones the `QueuedItemData`, since directly setting the `Item` field to
75
75
  * `undefined` does not work for some reason.
76
+ *
77
+ * This method was discovered by im_tem.
76
78
  */
77
79
  export function dequeueItem(player: EntityPlayer): boolean {
78
80
  if (player.QueuedItem.Item === undefined) {
@@ -140,7 +140,7 @@ export function getPartialMatch(
140
140
  * Helper function to parse a Semantic Versioning string into its individual constituents. Returns
141
141
  * undefined if the submitted string was not a proper Semantic Version string.
142
142
  *
143
- * https://semver.org/
143
+ * @see https://semver.org/
144
144
  */
145
145
  export function parseSemanticVersion(versionString: string):
146
146
  | {
@@ -181,6 +181,35 @@ export function isRepentance(): boolean {
181
181
  return isFunction(getAnimation);
182
182
  }
183
183
 
184
+ /**
185
+ * Helper function to check if the player is using REPENTOGON, an exe-hack which expands the modding
186
+ * API.
187
+ *
188
+ * Although REPENTOGON has a `REPENTOGON` global to check if it's present, it is not safe to use as
189
+ * it can be overwritten by other mods.
190
+ *
191
+ * Specifically, this function checks for the `Sprite.Continue` method:
192
+ * https://repentogon.com/Sprite.html#continue
193
+ */
194
+ export function isRepentogon(): boolean {
195
+ const metatable = getmetatable(Sprite) as LuaMap<string, unknown> | undefined;
196
+ assertDefined(
197
+ metatable,
198
+ "Failed to get the metatable of the Sprite global table.",
199
+ );
200
+
201
+ const classTable = metatable.get("__class") as
202
+ | LuaMap<string, unknown>
203
+ | undefined;
204
+ assertDefined(
205
+ classTable,
206
+ 'Failed to get the "__class" key of the Sprite metatable.',
207
+ );
208
+
209
+ const getAnimation = classTable.get("Continue");
210
+ return isFunction(getAnimation);
211
+ }
212
+
184
213
  /**
185
214
  * Helper function to repeat code N times. This is faster to type and cleaner than using a for loop.
186
215
  *
@@ -975,12 +975,17 @@ export interface AddCallbackParametersCustom {
975
975
  ];
976
976
 
977
977
  [ModCallbackCustom.PRE_ITEM_PICKUP]:
978
- | [callback: (player: EntityPlayer, pickingUpItem: PickingUpItem) => void]
978
+ | [
979
+ callback: (
980
+ player: EntityPlayer,
981
+ pickingUpItem: PickingUpItem,
982
+ ) => boolean | undefined,
983
+ ]
979
984
  | [
980
985
  callback: (
981
986
  player: EntityPlayer,
982
987
  pickingUpItem: PickingUpItemCollectible,
983
- ) => void,
988
+ ) => boolean | undefined,
984
989
  itemType: ItemType.PASSIVE | ItemType.ACTIVE | ItemType.FAMILIAR,
985
990
  collectibleType?: CollectibleType,
986
991
  ]
@@ -988,7 +993,7 @@ export interface AddCallbackParametersCustom {
988
993
  callback: (
989
994
  player: EntityPlayer,
990
995
  pickingUpItem: PickingUpItemTrinket,
991
- ) => void,
996
+ ) => boolean | undefined,
992
997
  itemType: ItemType.TRINKET,
993
998
  trinketType?: TrinketType,
994
999
  ];