isaacscript-common 12.5.1 → 12.6.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/index.d.ts CHANGED
@@ -1665,6 +1665,12 @@ export declare class DefaultMap<Key, Value, Args extends unknown[] = []> extends
1665
1665
  getConstructorArg(): Value | FactoryFunction<Value, Args>;
1666
1666
  }
1667
1667
 
1668
+ /**
1669
+ * Helper function to get the value from a `DefaultMap` that corresponds to an entity, assuming that
1670
+ * the map uses `PtrHash` as an index.
1671
+ */
1672
+ export declare function defaultMapGetHash<V, A extends unknown[]>(map: DefaultMap<PtrHash, V, A>, entity: Entity, ...extraArgs: A): V;
1673
+
1668
1674
  /**
1669
1675
  * Helper function to make using default maps with an index of `PlayerIndex` easier. Use this
1670
1676
  * instead of the `DefaultMap.getAndSetDefault` method if you have a default map of this type.
@@ -1685,6 +1691,15 @@ export declare class DefaultMap<Key, Value, Args extends unknown[] = []> extends
1685
1691
  */
1686
1692
  export declare function defaultMapGetPlayer<V, A extends unknown[]>(map: DefaultMap<PlayerIndex, V, A>, player: EntityPlayer, ...extraArgs: A): V;
1687
1693
 
1694
+ /**
1695
+ * Helper function to set a value for a `DefaultMap` that corresponds to an entity, assuming that
1696
+ * the map uses `PtrHash` as an index.
1697
+ *
1698
+ * Since `Map` and `DefaultMap` set values in the same way, this function is simply an alias for the
1699
+ * `mapSetHash` helper function.
1700
+ */
1701
+ export declare function defaultMapSetHash<V>(map: Map<PtrHash, V>, entity: Entity, value: V): void;
1702
+
1688
1703
  /**
1689
1704
  * Helper function to make using maps with an index of `PlayerIndex` easier. Use this instead of the
1690
1705
  * `Map.set` method if you have a map of this type.
@@ -1764,7 +1779,7 @@ export declare function deployJSONRoom(jsonRoom: JSONRoom | Readonly<JSONRoom>,
1764
1779
  * @param verbose Optional. If specified, will write entries to the "log.txt" file that describe
1765
1780
  * what the function is doing. Default is false.
1766
1781
  */
1767
- export declare function deployRandomJSONRoom(jsonRooms: JSONRoom[] | readonly JSONRoom[], seedOrRNG?: Seed | RNG, verbose?: boolean): void;
1782
+ export declare function deployRandomJSONRoom(jsonRooms: JSONRoom[], seedOrRNG?: Seed | RNG, verbose?: boolean): void;
1768
1783
 
1769
1784
  /**
1770
1785
  * Helper function to convert a `SerializedBitSet128` object to a normal `BitSet128` object. (This
@@ -4512,6 +4527,21 @@ export declare function getRandomFromWeightedArray<T>(weightedArray: WeightedArr
4512
4527
  */
4513
4528
  export declare function getRandomInt(min: int, max: int, seedOrRNG?: Seed | RNG, exceptions?: int[] | readonly int[]): int;
4514
4529
 
4530
+ /**
4531
+ * Helper function to get a random JSON entity from an array of JSON entities.
4532
+ *
4533
+ * Note that this function does not simply choose a random element in the provided array; it will
4534
+ * properly account for each room weight using the algorithm from:
4535
+ * https://stackoverflow.com/questions/1761626/weighted-random-numbers
4536
+ *
4537
+ * @param jsonEntities The array of entities to randomly choose between.
4538
+ * @param seedOrRNG Optional. The `Seed` or `RNG` object to use. If an `RNG` object is provided, the
4539
+ * `RNG.Next` method will be called. Default is `getRandomSeed()`.
4540
+ * @param verbose Optional. If specified, will write entries to the "log.txt" file that describe
4541
+ * what the function is doing. Default is false.
4542
+ */
4543
+ export declare function getRandomJSONEntity(jsonEntities: JSONEntity[], seedOrRNG?: Seed | RNG, verbose?: boolean): JSONEntity;
4544
+
4515
4545
  /**
4516
4546
  * Helper function to get a random JSON room from an array of JSON rooms.
4517
4547
  *
@@ -4519,13 +4549,13 @@ export declare function getRandomInt(min: int, max: int, seedOrRNG?: Seed | RNG,
4519
4549
  * properly account for each room weight using the algorithm from:
4520
4550
  * https://stackoverflow.com/questions/1761626/weighted-random-numbers
4521
4551
  *
4522
- * @param jsonRooms The array of rooms to random choose between.
4552
+ * @param jsonRooms The array of rooms to randomly choose between.
4523
4553
  * @param seedOrRNG Optional. The `Seed` or `RNG` object to use. If an `RNG` object is provided, the
4524
4554
  * `RNG.Next` method will be called. Default is `getRandomSeed()`.
4525
4555
  * @param verbose Optional. If specified, will write entries to the "log.txt" file that describe
4526
4556
  * what the function is doing. Default is false.
4527
4557
  */
4528
- export declare function getRandomJSONRoom(jsonRooms: JSONRoom[] | readonly JSONRoom[], seedOrRNG?: Seed | RNG, verbose?: boolean): JSONRoom;
4558
+ export declare function getRandomJSONRoom(jsonRooms: JSONRoom[], seedOrRNG?: Seed | RNG, verbose?: boolean): JSONRoom;
4529
4559
 
4530
4560
  /**
4531
4561
  * Helper function to get a random color.
@@ -6996,6 +7026,12 @@ export declare function mapGetPlayer<V>(map: Map<PlayerIndex, V>, player: Entity
6996
7026
  */
6997
7027
  export declare function mapHasPlayer<V>(map: Map<PlayerIndex, V>, player: EntityPlayer): boolean;
6998
7028
 
7029
+ /**
7030
+ * Helper function to set a value for a `DefaultMap` that corresponds to an entity, assuming that
7031
+ * the map uses `PtrHash` as an index.
7032
+ */
7033
+ export declare function mapSetHash<V>(map: Map<PtrHash, V>, entity: Entity, value: V): void;
7034
+
6999
7035
  /**
7000
7036
  * Helper function to make using maps with an index of `PlayerIndex` easier. Use this instead of the
7001
7037
  * `Map.set` method if you have a map of this type.
@@ -1,6 +1,6 @@
1
1
  --[[
2
2
 
3
- isaacscript-common 12.5.1
3
+ isaacscript-common 12.6.0
4
4
 
5
5
  This is the "isaacscript-common" library, which was created with the IsaacScript tool.
6
6
 
@@ -9323,7 +9323,7 @@ ____exports.ClottyVariant.GRILLED_CLOTTY = 3
9323
9323
  ____exports.ClottyVariant[____exports.ClottyVariant.GRILLED_CLOTTY] = "GRILLED_CLOTTY"
9324
9324
  --- For `EntityType.MULLIGAN` (16).
9325
9325
  ____exports.MulliganVariant = {}
9326
- ____exports.MulliganVariant.MULLIGAN = 16
9326
+ ____exports.MulliganVariant.MULLIGAN = 0
9327
9327
  ____exports.MulliganVariant[____exports.MulliganVariant.MULLIGAN] = "MULLIGAN"
9328
9328
  ____exports.MulliganVariant.MULLIGOON = 1
9329
9329
  ____exports.MulliganVariant[____exports.MulliganVariant.MULLIGOON] = "MULLIGOON"
@@ -12533,6 +12533,8 @@ local ____exports = {}
12533
12533
  --
12534
12534
  -- The `gridspawn` console command accepts `GridEntityXMLType` instead of `GridEntityType`.
12535
12535
  ____exports.GridEntityXMLType = {}
12536
+ ____exports.GridEntityXMLType.DECORATION = 0
12537
+ ____exports.GridEntityXMLType[____exports.GridEntityXMLType.DECORATION] = "DECORATION"
12536
12538
  ____exports.GridEntityXMLType.ROCK = 1000
12537
12539
  ____exports.GridEntityXMLType[____exports.GridEntityXMLType.ROCK] = "ROCK"
12538
12540
  ____exports.GridEntityXMLType.ROCK_BOMB = 1001
@@ -19233,6 +19235,7 @@ local RockVariant = ____isaac_2Dtypescript_2Ddefinitions.RockVariant
19233
19235
  local StatueVariant = ____isaac_2Dtypescript_2Ddefinitions.StatueVariant
19234
19236
  local TrapdoorVariant = ____isaac_2Dtypescript_2Ddefinitions.TrapdoorVariant
19235
19237
  ____exports.GRID_ENTITY_XML_MAP = __TS__New(Map, {
19238
+ {GridEntityXMLType.DECORATION, {GridEntityType.DECORATION, 0}},
19236
19239
  {GridEntityXMLType.ROCK, {GridEntityType.ROCK, RockVariant.NORMAL}},
19237
19240
  {GridEntityXMLType.ROCK_BOMB, {GridEntityType.ROCK_BOMB, 0}},
19238
19241
  {GridEntityXMLType.ROCK_ALT, {GridEntityType.ROCK_ALT, 0}},
@@ -40808,7 +40811,7 @@ local ____lualib = require("lualib_bundle")
40808
40811
  local __TS__ArrayFilter = ____lualib.__TS__ArrayFilter
40809
40812
  local __TS__ArrayMap = ____lualib.__TS__ArrayMap
40810
40813
  local ____exports = {}
40811
- local getTotalWeightOfJSONRooms, getJSONRoomWithChosenWeight
40814
+ local getTotalWeightOfJSONObject, getJSONObjectWithChosenWeight
40812
40815
  local ____isaac_2Dtypescript_2Ddefinitions = require("lua_modules.isaac-typescript-definitions.dist.src.index")
40813
40816
  local DoorSlotFlagZero = ____isaac_2Dtypescript_2Ddefinitions.DoorSlotFlagZero
40814
40817
  local ____array = require("src.functions.array")
@@ -40824,33 +40827,34 @@ local ____random = require("src.functions.random")
40824
40827
  local getRandomFloat = ____random.getRandomFloat
40825
40828
  local ____rng = require("src.functions.rng")
40826
40829
  local getRandomSeed = ____rng.getRandomSeed
40827
- function getTotalWeightOfJSONRooms(self, jsonRooms)
40830
+ function getTotalWeightOfJSONObject(self, jsonOjectArray)
40828
40831
  local weights = __TS__ArrayMap(
40829
- jsonRooms,
40830
- function(____, jsonRoom)
40831
- local roomWeightString = jsonRoom["$"].weight
40832
- local roomWeight = tonumber(roomWeightString)
40833
- if roomWeight == nil then
40834
- error(("Failed to parse the weight of a JSON room: " .. roomWeightString) .. ".")
40832
+ jsonOjectArray,
40833
+ function(____, jsonObject)
40834
+ local weightString = jsonObject["$"].weight
40835
+ local weight = tonumber(weightString)
40836
+ if weight == nil then
40837
+ error(("Failed to parse the weight of a JSON object: " .. tostring(weightString)) .. ".")
40835
40838
  end
40836
- return roomWeight
40839
+ return weight
40837
40840
  end
40838
40841
  )
40839
40842
  return sumArray(nil, weights)
40840
40843
  end
40841
- function getJSONRoomWithChosenWeight(self, jsonRooms, chosenWeight)
40842
- for ____, jsonRoom in ipairs(jsonRooms) do
40843
- local roomWeightString = jsonRoom["$"].weight
40844
- local roomWeight = tonumber(roomWeightString)
40845
- if roomWeight == nil then
40846
- error("Failed to parse the weight of a JSON room: " .. roomWeightString)
40844
+ function getJSONObjectWithChosenWeight(self, jsonOjectArray, chosenWeight)
40845
+ local weightAccumulator = 0
40846
+ for ____, jsonObject in ipairs(jsonOjectArray) do
40847
+ local weightString = jsonObject["$"].weight
40848
+ local weight = tonumber(weightString)
40849
+ if weight == nil then
40850
+ error("Failed to parse the weight of a JSON object: " .. tostring(weightString))
40847
40851
  end
40848
- if chosenWeight < roomWeight then
40849
- return jsonRoom
40852
+ weightAccumulator = weightAccumulator + weight
40853
+ if weightAccumulator >= chosenWeight then
40854
+ return jsonObject
40850
40855
  end
40851
- chosenWeight = chosenWeight - roomWeight
40852
40856
  end
40853
- error("Failed to get a JSON room with chosen weight: " .. tostring(chosenWeight))
40857
+ return nil
40854
40858
  end
40855
40859
  function ____exports.getJSONRoomDoorSlotFlags(self, jsonRoom)
40856
40860
  local roomShapeString = jsonRoom["$"].shape
@@ -40917,6 +40921,33 @@ function ____exports.getJSONRoomsOfSubType(self, jsonRooms, subType)
40917
40921
  end
40918
40922
  )
40919
40923
  end
40924
+ function ____exports.getRandomJSONEntity(self, jsonEntities, seedOrRNG, verbose)
40925
+ if seedOrRNG == nil then
40926
+ seedOrRNG = getRandomSeed(nil)
40927
+ end
40928
+ if verbose == nil then
40929
+ verbose = false
40930
+ end
40931
+ local totalWeight = getTotalWeightOfJSONObject(nil, jsonEntities)
40932
+ if verbose then
40933
+ log(
40934
+ nil,
40935
+ "Total weight of the JSON entities provided: " .. tostring(totalWeight)
40936
+ )
40937
+ end
40938
+ local chosenWeight = getRandomFloat(nil, 0, totalWeight, seedOrRNG)
40939
+ if verbose then
40940
+ log(
40941
+ nil,
40942
+ "Randomly chose weight for JSON entity: " .. tostring(chosenWeight)
40943
+ )
40944
+ end
40945
+ local randomJSONEntity = getJSONObjectWithChosenWeight(nil, jsonEntities, chosenWeight)
40946
+ if randomJSONEntity == nil then
40947
+ error("Failed to get a JSON entity with chosen weight: " .. tostring(chosenWeight))
40948
+ end
40949
+ return randomJSONEntity
40950
+ end
40920
40951
  function ____exports.getRandomJSONRoom(self, jsonRooms, seedOrRNG, verbose)
40921
40952
  if seedOrRNG == nil then
40922
40953
  seedOrRNG = getRandomSeed(nil)
@@ -40924,7 +40955,7 @@ function ____exports.getRandomJSONRoom(self, jsonRooms, seedOrRNG, verbose)
40924
40955
  if verbose == nil then
40925
40956
  verbose = false
40926
40957
  end
40927
- local totalWeight = getTotalWeightOfJSONRooms(nil, jsonRooms)
40958
+ local totalWeight = getTotalWeightOfJSONObject(nil, jsonRooms)
40928
40959
  if verbose then
40929
40960
  log(
40930
40961
  nil,
@@ -40938,7 +40969,11 @@ function ____exports.getRandomJSONRoom(self, jsonRooms, seedOrRNG, verbose)
40938
40969
  "Randomly chose weight for JSON room: " .. tostring(chosenWeight)
40939
40970
  )
40940
40971
  end
40941
- return getJSONRoomWithChosenWeight(nil, jsonRooms, chosenWeight)
40972
+ local randomJSONRoom = getJSONObjectWithChosenWeight(nil, jsonRooms, chosenWeight)
40973
+ if randomJSONRoom == nil then
40974
+ error("Failed to get a JSON room with chosen weight: " .. tostring(chosenWeight))
40975
+ end
40976
+ return randomJSONRoom
40942
40977
  end
40943
40978
  return ____exports
40944
40979
  end,
@@ -41252,7 +41287,7 @@ local __TS__New = ____lualib.__TS__New
41252
41287
  local Map = ____lualib.Map
41253
41288
  local __TS__Iterator = ____lualib.__TS__Iterator
41254
41289
  local ____exports = {}
41255
- local preUseItemWeNeedToGoDeeper, postNewRoomReordered, setDecorationsInvisible, respawnPersistentEntities, removeSpecificNPCs, fillRoomWithDecorations, spawnAllEntities, spawnGridEntityForJSONRoom, spawnNormalEntityForJSONRoom, storePersistentEntity, fixPitGraphics, getPitMap, getPitFrame, FEATURE_NAME, NPC_TYPES_TO_NOT_REMOVE, PERSISTENT_ENTITY_TYPES, v
41290
+ local preUseItemWeNeedToGoDeeper, postNewRoomReordered, setDecorationsInvisible, respawnPersistentEntities, removeSpecificNPCs, fillRoomWithDecorations, spawnAllEntities, spawnGridEntityForJSONRoom, spawnNormalEntityForJSONRoom, storePersistentEntity, fixPitGraphics, getPitMap, getPitFrame, FEATURE_NAME, NPC_TYPES_TO_NOT_REMOVE, PERSISTENT_ENTITY_TYPES, GRID_ENTITY_XML_TYPE_SET, v
41256
41291
  local ____isaac_2Dtypescript_2Ddefinitions = require("lua_modules.isaac-typescript-definitions.dist.src.index")
41257
41292
  local CollectibleType = ____isaac_2Dtypescript_2Ddefinitions.CollectibleType
41258
41293
  local EffectVariant = ____isaac_2Dtypescript_2Ddefinitions.EffectVariant
@@ -41261,6 +41296,7 @@ local EntityFlag = ____isaac_2Dtypescript_2Ddefinitions.EntityFlag
41261
41296
  local EntityGridCollisionClass = ____isaac_2Dtypescript_2Ddefinitions.EntityGridCollisionClass
41262
41297
  local EntityType = ____isaac_2Dtypescript_2Ddefinitions.EntityType
41263
41298
  local GridEntityType = ____isaac_2Dtypescript_2Ddefinitions.GridEntityType
41299
+ local GridEntityXMLType = ____isaac_2Dtypescript_2Ddefinitions.GridEntityXMLType
41264
41300
  local ModCallback = ____isaac_2Dtypescript_2Ddefinitions.ModCallback
41265
41301
  local PickupVariant = ____isaac_2Dtypescript_2Ddefinitions.PickupVariant
41266
41302
  local PitfallVariant = ____isaac_2Dtypescript_2Ddefinitions.PitfallVariant
@@ -41284,6 +41320,8 @@ local ____entitiesSpecific = require("src.functions.entitiesSpecific")
41284
41320
  local getNPCs = ____entitiesSpecific.getNPCs
41285
41321
  local removeAllBombs = ____entitiesSpecific.removeAllBombs
41286
41322
  local removeAllPickups = ____entitiesSpecific.removeAllPickups
41323
+ local ____enums = require("src.functions.enums")
41324
+ local getEnumValues = ____enums.getEnumValues
41287
41325
  local ____gridEntities = require("src.functions.gridEntities")
41288
41326
  local convertXMLGridEntityType = ____gridEntities.convertXMLGridEntityType
41289
41327
  local getAllGridIndexes = ____gridEntities.getAllGridIndexes
@@ -41293,6 +41331,7 @@ local removeGridEntity = ____gridEntities.removeGridEntity
41293
41331
  local setGridEntityInvisible = ____gridEntities.setGridEntityInvisible
41294
41332
  local spawnGridEntityWithVariant = ____gridEntities.spawnGridEntityWithVariant
41295
41333
  local ____jsonRoom = require("src.functions.jsonRoom")
41334
+ local getRandomJSONEntity = ____jsonRoom.getRandomJSONEntity
41296
41335
  local getRandomJSONRoom = ____jsonRoom.getRandomJSONRoom
41297
41336
  local ____log = require("src.functions.log")
41298
41337
  local log = ____log.log
@@ -41459,29 +41498,24 @@ function spawnAllEntities(self, jsonRoom, rng, verbose)
41459
41498
  if y == nil then
41460
41499
  error("Failed to convert the following y coordinate to a number (for a spawn): " .. yString)
41461
41500
  end
41462
- if #jsonSpawn.entity > 1 then
41463
- error("Stacked entities are not implemented for JSON rooms.")
41464
- end
41465
- local firstXMLEntity = jsonSpawn.entity[1]
41466
- if firstXMLEntity == nil then
41467
- error("Failed to get the first JSON entity from an \"entity\" array.")
41468
- end
41469
- local entityTypeString = firstXMLEntity["$"].type
41501
+ local jsonEntity = getRandomJSONEntity(nil, jsonSpawn.entity)
41502
+ local entityTypeString = jsonEntity["$"].type
41470
41503
  local entityTypeNumber = tonumber(entityTypeString)
41471
41504
  if entityTypeNumber == nil then
41472
41505
  error("Failed to convert the entity type to a number: " .. entityTypeString)
41473
41506
  end
41474
- local variantString = firstXMLEntity["$"].variant
41507
+ local variantString = jsonEntity["$"].variant
41475
41508
  local variant = tonumber(variantString)
41476
41509
  if variant == nil then
41477
41510
  error("Failed to convert the entity variant to a number: " .. tostring(variant))
41478
41511
  end
41479
- local subTypeString = firstXMLEntity["$"].subtype
41512
+ local subTypeString = jsonEntity["$"].subtype
41480
41513
  local subType = tonumber(subTypeString)
41481
41514
  if subType == nil then
41482
41515
  error("Failed to convert the entity sub-type to a number: " .. tostring(subType))
41483
41516
  end
41484
- if entityTypeNumber >= 1000 then
41517
+ local isGridEntity = GRID_ENTITY_XML_TYPE_SET:has(entityTypeNumber)
41518
+ if isGridEntity then
41485
41519
  local gridEntityXMLType = entityTypeNumber
41486
41520
  if verbose then
41487
41521
  log(
@@ -41705,6 +41739,8 @@ end
41705
41739
  FEATURE_NAME = "deployJSONRoom"
41706
41740
  NPC_TYPES_TO_NOT_REMOVE = __TS__New(Set, {EntityType.DARK_ESAU})
41707
41741
  PERSISTENT_ENTITY_TYPES = __TS__New(Set, {EntityType.WALL_HUGGER})
41742
+ local gridEntityXMLTypes = getEnumValues(nil, GridEntityXMLType)
41743
+ GRID_ENTITY_XML_TYPE_SET = __TS__New(Set, gridEntityXMLTypes)
41708
41744
  v = {
41709
41745
  level = {
41710
41746
  deployedRoomListIndexes = __TS__New(Set),
@@ -42793,6 +42829,10 @@ local ____array = require("src.functions.array")
42793
42829
  local sumArray = ____array.sumArray
42794
42830
  local ____string = require("src.functions.string")
42795
42831
  local getPartialMatch = ____string.getPartialMatch
42832
+ function ____exports.mapSetHash(self, map, entity, value)
42833
+ local hash = GetPtrHash(entity)
42834
+ map:set(hash, value)
42835
+ end
42796
42836
  function ____exports.copyMap(self, oldMap)
42797
42837
  local newMap = __TS__New(Map)
42798
42838
  for ____, ____value in __TS__Iterator(oldMap:entries()) do
@@ -42802,6 +42842,13 @@ function ____exports.copyMap(self, oldMap)
42802
42842
  end
42803
42843
  return newMap
42804
42844
  end
42845
+ function ____exports.defaultMapGetHash(self, map, entity, ...)
42846
+ local ptrHash = GetPtrHash(entity)
42847
+ return map:getAndSetDefault(ptrHash, ...)
42848
+ end
42849
+ function ____exports.defaultMapSetHash(self, map, entity, value)
42850
+ ____exports.mapSetHash(nil, map, entity, value)
42851
+ end
42805
42852
  function ____exports.getMapPartialMatch(self, searchText, map)
42806
42853
  local keys = {__TS__Spread(map:keys())}
42807
42854
  local matchingKey = getPartialMatch(nil, searchText, keys)
@@ -62,7 +62,7 @@ export declare function deployJSONRoom(jsonRoom: JSONRoom | Readonly<JSONRoom>,
62
62
  * @param verbose Optional. If specified, will write entries to the "log.txt" file that describe
63
63
  * what the function is doing. Default is false.
64
64
  */
65
- export declare function deployRandomJSONRoom(jsonRooms: JSONRoom[] | readonly JSONRoom[], seedOrRNG?: Seed | RNG, verbose?: boolean): void;
65
+ export declare function deployRandomJSONRoom(jsonRooms: JSONRoom[], seedOrRNG?: Seed | RNG, verbose?: boolean): void;
66
66
  /**
67
67
  * Helper function to remove all naturally spawning entities and grid entities from a room. Notably,
68
68
  * this will not remove players (1), tears (2), familiars (3), lasers (7), knives (8), projectiles
@@ -1 +1 @@
1
- {"version":3,"file":"deployJSONRoom.d.ts","sourceRoot":"","sources":["../../../src/features/deployJSONRoom.ts"],"names":[],"mappings":";;AAuDA,OAAO,EAAE,QAAQ,EAAE,MAAM,6BAA6B,CAAC;AAuKvD;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AACH,wBAAgB,cAAc,CAC5B,QAAQ,EAAE,QAAQ,GAAG,QAAQ,CAAC,QAAQ,CAAC,EACvC,SAAS,GAAE,IAAI,GAAG,GAAqB,EACvC,OAAO,UAAQ,GACd,IAAI,CAuBN;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+BG;AACH,wBAAgB,oBAAoB,CAClC,SAAS,EAAE,QAAQ,EAAE,GAAG,SAAS,QAAQ,EAAE,EAC3C,SAAS,GAAE,IAAI,GAAG,GAAqB,EACvC,OAAO,UAAQ,GACd,IAAI,CAaN;AAED;;;;;;;;;GASG;AACH,wBAAgB,SAAS,CAAC,mBAAmB,EAAE,OAAO,GAAG,IAAI,CAwB5D"}
1
+ {"version":3,"file":"deployJSONRoom.d.ts","sourceRoot":"","sources":["../../../src/features/deployJSONRoom.ts"],"names":[],"mappings":";;AAwDA,OAAO,EAAE,QAAQ,EAAE,MAAM,6BAA6B,CAAC;AA4KvD;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AACH,wBAAgB,cAAc,CAC5B,QAAQ,EAAE,QAAQ,GAAG,QAAQ,CAAC,QAAQ,CAAC,EACvC,SAAS,GAAE,IAAI,GAAG,GAAqB,EACvC,OAAO,UAAQ,GACd,IAAI,CAuBN;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+BG;AACH,wBAAgB,oBAAoB,CAClC,SAAS,EAAE,QAAQ,EAAE,EACrB,SAAS,GAAE,IAAI,GAAG,GAAqB,EACvC,OAAO,UAAQ,GACd,IAAI,CAaN;AAED;;;;;;;;;GASG;AACH,wBAAgB,SAAS,CAAC,mBAAmB,EAAE,OAAO,GAAG,IAAI,CAwB5D"}
@@ -4,7 +4,7 @@ local __TS__New = ____lualib.__TS__New
4
4
  local Map = ____lualib.Map
5
5
  local __TS__Iterator = ____lualib.__TS__Iterator
6
6
  local ____exports = {}
7
- local preUseItemWeNeedToGoDeeper, postNewRoomReordered, setDecorationsInvisible, respawnPersistentEntities, removeSpecificNPCs, fillRoomWithDecorations, spawnAllEntities, spawnGridEntityForJSONRoom, spawnNormalEntityForJSONRoom, storePersistentEntity, fixPitGraphics, getPitMap, getPitFrame, FEATURE_NAME, NPC_TYPES_TO_NOT_REMOVE, PERSISTENT_ENTITY_TYPES, v
7
+ local preUseItemWeNeedToGoDeeper, postNewRoomReordered, setDecorationsInvisible, respawnPersistentEntities, removeSpecificNPCs, fillRoomWithDecorations, spawnAllEntities, spawnGridEntityForJSONRoom, spawnNormalEntityForJSONRoom, storePersistentEntity, fixPitGraphics, getPitMap, getPitFrame, FEATURE_NAME, NPC_TYPES_TO_NOT_REMOVE, PERSISTENT_ENTITY_TYPES, GRID_ENTITY_XML_TYPE_SET, v
8
8
  local ____isaac_2Dtypescript_2Ddefinitions = require("isaac-typescript-definitions")
9
9
  local CollectibleType = ____isaac_2Dtypescript_2Ddefinitions.CollectibleType
10
10
  local EffectVariant = ____isaac_2Dtypescript_2Ddefinitions.EffectVariant
@@ -13,6 +13,7 @@ local EntityFlag = ____isaac_2Dtypescript_2Ddefinitions.EntityFlag
13
13
  local EntityGridCollisionClass = ____isaac_2Dtypescript_2Ddefinitions.EntityGridCollisionClass
14
14
  local EntityType = ____isaac_2Dtypescript_2Ddefinitions.EntityType
15
15
  local GridEntityType = ____isaac_2Dtypescript_2Ddefinitions.GridEntityType
16
+ local GridEntityXMLType = ____isaac_2Dtypescript_2Ddefinitions.GridEntityXMLType
16
17
  local ModCallback = ____isaac_2Dtypescript_2Ddefinitions.ModCallback
17
18
  local PickupVariant = ____isaac_2Dtypescript_2Ddefinitions.PickupVariant
18
19
  local PitfallVariant = ____isaac_2Dtypescript_2Ddefinitions.PitfallVariant
@@ -36,6 +37,8 @@ local ____entitiesSpecific = require("src.functions.entitiesSpecific")
36
37
  local getNPCs = ____entitiesSpecific.getNPCs
37
38
  local removeAllBombs = ____entitiesSpecific.removeAllBombs
38
39
  local removeAllPickups = ____entitiesSpecific.removeAllPickups
40
+ local ____enums = require("src.functions.enums")
41
+ local getEnumValues = ____enums.getEnumValues
39
42
  local ____gridEntities = require("src.functions.gridEntities")
40
43
  local convertXMLGridEntityType = ____gridEntities.convertXMLGridEntityType
41
44
  local getAllGridIndexes = ____gridEntities.getAllGridIndexes
@@ -45,6 +48,7 @@ local removeGridEntity = ____gridEntities.removeGridEntity
45
48
  local setGridEntityInvisible = ____gridEntities.setGridEntityInvisible
46
49
  local spawnGridEntityWithVariant = ____gridEntities.spawnGridEntityWithVariant
47
50
  local ____jsonRoom = require("src.functions.jsonRoom")
51
+ local getRandomJSONEntity = ____jsonRoom.getRandomJSONEntity
48
52
  local getRandomJSONRoom = ____jsonRoom.getRandomJSONRoom
49
53
  local ____log = require("src.functions.log")
50
54
  local log = ____log.log
@@ -219,29 +223,24 @@ function spawnAllEntities(self, jsonRoom, rng, verbose)
219
223
  if y == nil then
220
224
  error("Failed to convert the following y coordinate to a number (for a spawn): " .. yString)
221
225
  end
222
- if #jsonSpawn.entity > 1 then
223
- error("Stacked entities are not implemented for JSON rooms.")
224
- end
225
- local firstXMLEntity = jsonSpawn.entity[1]
226
- if firstXMLEntity == nil then
227
- error("Failed to get the first JSON entity from an \"entity\" array.")
228
- end
229
- local entityTypeString = firstXMLEntity["$"].type
226
+ local jsonEntity = getRandomJSONEntity(nil, jsonSpawn.entity)
227
+ local entityTypeString = jsonEntity["$"].type
230
228
  local entityTypeNumber = tonumber(entityTypeString)
231
229
  if entityTypeNumber == nil then
232
230
  error("Failed to convert the entity type to a number: " .. entityTypeString)
233
231
  end
234
- local variantString = firstXMLEntity["$"].variant
232
+ local variantString = jsonEntity["$"].variant
235
233
  local variant = tonumber(variantString)
236
234
  if variant == nil then
237
235
  error("Failed to convert the entity variant to a number: " .. tostring(variant))
238
236
  end
239
- local subTypeString = firstXMLEntity["$"].subtype
237
+ local subTypeString = jsonEntity["$"].subtype
240
238
  local subType = tonumber(subTypeString)
241
239
  if subType == nil then
242
240
  error("Failed to convert the entity sub-type to a number: " .. tostring(subType))
243
241
  end
244
- if entityTypeNumber >= 1000 then
242
+ local isGridEntity = GRID_ENTITY_XML_TYPE_SET:has(entityTypeNumber)
243
+ if isGridEntity then
245
244
  local gridEntityXMLType = entityTypeNumber
246
245
  if verbose then
247
246
  log(
@@ -465,6 +464,8 @@ end
465
464
  FEATURE_NAME = "deployJSONRoom"
466
465
  NPC_TYPES_TO_NOT_REMOVE = __TS__New(Set, {EntityType.DARK_ESAU})
467
466
  PERSISTENT_ENTITY_TYPES = __TS__New(Set, {EntityType.WALL_HUGGER})
467
+ local gridEntityXMLTypes = getEnumValues(nil, GridEntityXMLType)
468
+ GRID_ENTITY_XML_TYPE_SET = __TS__New(Set, gridEntityXMLTypes)
468
469
  v = {
469
470
  level = {
470
471
  deployedRoomListIndexes = __TS__New(Set),
@@ -1,5 +1,5 @@
1
1
  import { DoorSlotFlag } from "isaac-typescript-definitions";
2
- import { JSONRoom } from "../interfaces/JSONRoomsFile";
2
+ import { JSONEntity, JSONRoom } from "../interfaces/JSONRoomsFile";
3
3
  /**
4
4
  * Helper function to calculate what the resulting `BitFlags<DoorSlotFlag>` value would be for a
5
5
  * given JSON room.
@@ -20,6 +20,20 @@ export declare function getJSONRoomOfVariant(jsonRooms: JSONRoom[] | readonly JS
20
20
  * @param subType The sub-type to match.
21
21
  */
22
22
  export declare function getJSONRoomsOfSubType(jsonRooms: JSONRoom[] | readonly JSONRoom[], subType: int): JSONRoom[];
23
+ /**
24
+ * Helper function to get a random JSON entity from an array of JSON entities.
25
+ *
26
+ * Note that this function does not simply choose a random element in the provided array; it will
27
+ * properly account for each room weight using the algorithm from:
28
+ * https://stackoverflow.com/questions/1761626/weighted-random-numbers
29
+ *
30
+ * @param jsonEntities The array of entities to randomly choose between.
31
+ * @param seedOrRNG Optional. The `Seed` or `RNG` object to use. If an `RNG` object is provided, the
32
+ * `RNG.Next` method will be called. Default is `getRandomSeed()`.
33
+ * @param verbose Optional. If specified, will write entries to the "log.txt" file that describe
34
+ * what the function is doing. Default is false.
35
+ */
36
+ export declare function getRandomJSONEntity(jsonEntities: JSONEntity[], seedOrRNG?: Seed | RNG, verbose?: boolean): JSONEntity;
23
37
  /**
24
38
  * Helper function to get a random JSON room from an array of JSON rooms.
25
39
  *
@@ -27,11 +41,11 @@ export declare function getJSONRoomsOfSubType(jsonRooms: JSONRoom[] | readonly J
27
41
  * properly account for each room weight using the algorithm from:
28
42
  * https://stackoverflow.com/questions/1761626/weighted-random-numbers
29
43
  *
30
- * @param jsonRooms The array of rooms to random choose between.
44
+ * @param jsonRooms The array of rooms to randomly choose between.
31
45
  * @param seedOrRNG Optional. The `Seed` or `RNG` object to use. If an `RNG` object is provided, the
32
46
  * `RNG.Next` method will be called. Default is `getRandomSeed()`.
33
47
  * @param verbose Optional. If specified, will write entries to the "log.txt" file that describe
34
48
  * what the function is doing. Default is false.
35
49
  */
36
- export declare function getRandomJSONRoom(jsonRooms: JSONRoom[] | readonly JSONRoom[], seedOrRNG?: Seed | RNG, verbose?: boolean): JSONRoom;
50
+ export declare function getRandomJSONRoom(jsonRooms: JSONRoom[], seedOrRNG?: Seed | RNG, verbose?: boolean): JSONRoom;
37
51
  //# sourceMappingURL=jsonRoom.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"jsonRoom.d.ts","sourceRoot":"","sources":["../../../src/functions/jsonRoom.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,YAAY,EAGb,MAAM,8BAA8B,CAAC;AACtC,OAAO,EAAE,QAAQ,EAAE,MAAM,6BAA6B,CAAC;AAQvD;;;GAGG;AACH,wBAAgB,wBAAwB,CACtC,QAAQ,EAAE,QAAQ,GACjB,QAAQ,CAAC,YAAY,CAAC,CAgDxB;AAED;;;;;;GAMG;AACH,wBAAgB,oBAAoB,CAClC,SAAS,EAAE,QAAQ,EAAE,GAAG,SAAS,QAAQ,EAAE,EAC3C,OAAO,EAAE,GAAG,GACX,QAAQ,GAAG,SAAS,CAoBtB;AAED;;;;;GAKG;AACH,wBAAgB,qBAAqB,CACnC,SAAS,EAAE,QAAQ,EAAE,GAAG,SAAS,QAAQ,EAAE,EAC3C,OAAO,EAAE,GAAG,GACX,QAAQ,EAAE,CAMZ;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,iBAAiB,CAC/B,SAAS,EAAE,QAAQ,EAAE,GAAG,SAAS,QAAQ,EAAE,EAC3C,SAAS,GAAE,IAAI,GAAG,GAAqB,EACvC,OAAO,UAAQ,GACd,QAAQ,CAYV"}
1
+ {"version":3,"file":"jsonRoom.d.ts","sourceRoot":"","sources":["../../../src/functions/jsonRoom.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,YAAY,EAGb,MAAM,8BAA8B,CAAC;AACtC,OAAO,EAAE,UAAU,EAAE,QAAQ,EAAE,MAAM,6BAA6B,CAAC;AAanE;;;GAGG;AACH,wBAAgB,wBAAwB,CACtC,QAAQ,EAAE,QAAQ,GACjB,QAAQ,CAAC,YAAY,CAAC,CAgDxB;AAED;;;;;;GAMG;AACH,wBAAgB,oBAAoB,CAClC,SAAS,EAAE,QAAQ,EAAE,GAAG,SAAS,QAAQ,EAAE,EAC3C,OAAO,EAAE,GAAG,GACX,QAAQ,GAAG,SAAS,CAoBtB;AAED;;;;;GAKG;AACH,wBAAgB,qBAAqB,CACnC,SAAS,EAAE,QAAQ,EAAE,GAAG,SAAS,QAAQ,EAAE,EAC3C,OAAO,EAAE,GAAG,GACX,QAAQ,EAAE,CAMZ;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,mBAAmB,CACjC,YAAY,EAAE,UAAU,EAAE,EAC1B,SAAS,GAAE,IAAI,GAAG,GAAqB,EACvC,OAAO,UAAQ,GACd,UAAU,CAoBZ;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,iBAAiB,CAC/B,SAAS,EAAE,QAAQ,EAAE,EACrB,SAAS,GAAE,IAAI,GAAG,GAAqB,EACvC,OAAO,UAAQ,GACd,QAAQ,CAiBV"}
@@ -2,7 +2,7 @@ local ____lualib = require("lualib_bundle")
2
2
  local __TS__ArrayFilter = ____lualib.__TS__ArrayFilter
3
3
  local __TS__ArrayMap = ____lualib.__TS__ArrayMap
4
4
  local ____exports = {}
5
- local getTotalWeightOfJSONRooms, getJSONRoomWithChosenWeight
5
+ local getTotalWeightOfJSONObject, getJSONObjectWithChosenWeight
6
6
  local ____isaac_2Dtypescript_2Ddefinitions = require("isaac-typescript-definitions")
7
7
  local DoorSlotFlagZero = ____isaac_2Dtypescript_2Ddefinitions.DoorSlotFlagZero
8
8
  local ____array = require("src.functions.array")
@@ -18,33 +18,34 @@ local ____random = require("src.functions.random")
18
18
  local getRandomFloat = ____random.getRandomFloat
19
19
  local ____rng = require("src.functions.rng")
20
20
  local getRandomSeed = ____rng.getRandomSeed
21
- function getTotalWeightOfJSONRooms(self, jsonRooms)
21
+ function getTotalWeightOfJSONObject(self, jsonOjectArray)
22
22
  local weights = __TS__ArrayMap(
23
- jsonRooms,
24
- function(____, jsonRoom)
25
- local roomWeightString = jsonRoom["$"].weight
26
- local roomWeight = tonumber(roomWeightString)
27
- if roomWeight == nil then
28
- error(("Failed to parse the weight of a JSON room: " .. roomWeightString) .. ".")
23
+ jsonOjectArray,
24
+ function(____, jsonObject)
25
+ local weightString = jsonObject["$"].weight
26
+ local weight = tonumber(weightString)
27
+ if weight == nil then
28
+ error(("Failed to parse the weight of a JSON object: " .. tostring(weightString)) .. ".")
29
29
  end
30
- return roomWeight
30
+ return weight
31
31
  end
32
32
  )
33
33
  return sumArray(nil, weights)
34
34
  end
35
- function getJSONRoomWithChosenWeight(self, jsonRooms, chosenWeight)
36
- for ____, jsonRoom in ipairs(jsonRooms) do
37
- local roomWeightString = jsonRoom["$"].weight
38
- local roomWeight = tonumber(roomWeightString)
39
- if roomWeight == nil then
40
- error("Failed to parse the weight of a JSON room: " .. roomWeightString)
35
+ function getJSONObjectWithChosenWeight(self, jsonOjectArray, chosenWeight)
36
+ local weightAccumulator = 0
37
+ for ____, jsonObject in ipairs(jsonOjectArray) do
38
+ local weightString = jsonObject["$"].weight
39
+ local weight = tonumber(weightString)
40
+ if weight == nil then
41
+ error("Failed to parse the weight of a JSON object: " .. tostring(weightString))
41
42
  end
42
- if chosenWeight < roomWeight then
43
- return jsonRoom
43
+ weightAccumulator = weightAccumulator + weight
44
+ if weightAccumulator >= chosenWeight then
45
+ return jsonObject
44
46
  end
45
- chosenWeight = chosenWeight - roomWeight
46
47
  end
47
- error("Failed to get a JSON room with chosen weight: " .. tostring(chosenWeight))
48
+ return nil
48
49
  end
49
50
  --- Helper function to calculate what the resulting `BitFlags<DoorSlotFlag>` value would be for a
50
51
  -- given JSON room.
@@ -122,13 +123,51 @@ function ____exports.getJSONRoomsOfSubType(self, jsonRooms, subType)
122
123
  end
123
124
  )
124
125
  end
126
+ --- Helper function to get a random JSON entity from an array of JSON entities.
127
+ --
128
+ -- Note that this function does not simply choose a random element in the provided array; it will
129
+ -- properly account for each room weight using the algorithm from:
130
+ -- https://stackoverflow.com/questions/1761626/weighted-random-numbers
131
+ --
132
+ -- @param jsonEntities The array of entities to randomly choose between.
133
+ -- @param seedOrRNG Optional. The `Seed` or `RNG` object to use. If an `RNG` object is provided, the
134
+ -- `RNG.Next` method will be called. Default is `getRandomSeed()`.
135
+ -- @param verbose Optional. If specified, will write entries to the "log.txt" file that describe
136
+ -- what the function is doing. Default is false.
137
+ function ____exports.getRandomJSONEntity(self, jsonEntities, seedOrRNG, verbose)
138
+ if seedOrRNG == nil then
139
+ seedOrRNG = getRandomSeed(nil)
140
+ end
141
+ if verbose == nil then
142
+ verbose = false
143
+ end
144
+ local totalWeight = getTotalWeightOfJSONObject(nil, jsonEntities)
145
+ if verbose then
146
+ log(
147
+ nil,
148
+ "Total weight of the JSON entities provided: " .. tostring(totalWeight)
149
+ )
150
+ end
151
+ local chosenWeight = getRandomFloat(nil, 0, totalWeight, seedOrRNG)
152
+ if verbose then
153
+ log(
154
+ nil,
155
+ "Randomly chose weight for JSON entity: " .. tostring(chosenWeight)
156
+ )
157
+ end
158
+ local randomJSONEntity = getJSONObjectWithChosenWeight(nil, jsonEntities, chosenWeight)
159
+ if randomJSONEntity == nil then
160
+ error("Failed to get a JSON entity with chosen weight: " .. tostring(chosenWeight))
161
+ end
162
+ return randomJSONEntity
163
+ end
125
164
  --- Helper function to get a random JSON room from an array of JSON rooms.
126
165
  --
127
166
  -- Note that this function does not simply choose a random element in the provided array; it will
128
167
  -- properly account for each room weight using the algorithm from:
129
168
  -- https://stackoverflow.com/questions/1761626/weighted-random-numbers
130
169
  --
131
- -- @param jsonRooms The array of rooms to random choose between.
170
+ -- @param jsonRooms The array of rooms to randomly choose between.
132
171
  -- @param seedOrRNG Optional. The `Seed` or `RNG` object to use. If an `RNG` object is provided, the
133
172
  -- `RNG.Next` method will be called. Default is `getRandomSeed()`.
134
173
  -- @param verbose Optional. If specified, will write entries to the "log.txt" file that describe
@@ -140,7 +179,7 @@ function ____exports.getRandomJSONRoom(self, jsonRooms, seedOrRNG, verbose)
140
179
  if verbose == nil then
141
180
  verbose = false
142
181
  end
143
- local totalWeight = getTotalWeightOfJSONRooms(nil, jsonRooms)
182
+ local totalWeight = getTotalWeightOfJSONObject(nil, jsonRooms)
144
183
  if verbose then
145
184
  log(
146
185
  nil,
@@ -154,6 +193,10 @@ function ____exports.getRandomJSONRoom(self, jsonRooms, seedOrRNG, verbose)
154
193
  "Randomly chose weight for JSON room: " .. tostring(chosenWeight)
155
194
  )
156
195
  end
157
- return getJSONRoomWithChosenWeight(nil, jsonRooms, chosenWeight)
196
+ local randomJSONRoom = getJSONObjectWithChosenWeight(nil, jsonRooms, chosenWeight)
197
+ if randomJSONRoom == nil then
198
+ error("Failed to get a JSON room with chosen weight: " .. tostring(chosenWeight))
199
+ end
200
+ return randomJSONRoom
158
201
  end
159
202
  return ____exports
@@ -1,5 +1,21 @@
1
+ /// <reference types="isaac-typescript-definitions" />
2
+ /// <reference types="isaac-typescript-definitions" />
3
+ import { DefaultMap } from "../classes/DefaultMap";
1
4
  /** Helper function to copy a map. (You can also use a Map constructor to accomplish this task.) */
2
5
  export declare function copyMap<K, V>(oldMap: Map<K, V>): Map<K, V>;
6
+ /**
7
+ * Helper function to get the value from a `DefaultMap` that corresponds to an entity, assuming that
8
+ * the map uses `PtrHash` as an index.
9
+ */
10
+ export declare function defaultMapGetHash<V, A extends unknown[]>(map: DefaultMap<PtrHash, V, A>, entity: Entity, ...extraArgs: A): V;
11
+ /**
12
+ * Helper function to set a value for a `DefaultMap` that corresponds to an entity, assuming that
13
+ * the map uses `PtrHash` as an index.
14
+ *
15
+ * Since `Map` and `DefaultMap` set values in the same way, this function is simply an alias for the
16
+ * `mapSetHash` helper function.
17
+ */
18
+ export declare function defaultMapSetHash<V>(map: Map<PtrHash, V>, entity: Entity, value: V): void;
3
19
  /**
4
20
  * Helper function to get the closest value from a map based on partial search text. For the
5
21
  * purposes of this function, both search text and map keys are converted to lowercase before
@@ -20,6 +36,11 @@ export declare function copyMap<K, V>(oldMap: Map<K, V>): Map<K, V>;
20
36
  * ```
21
37
  */
22
38
  export declare function getMapPartialMatch<T>(searchText: string, map: ReadonlyMap<string, T>): [string, T] | undefined;
39
+ /**
40
+ * Helper function to set a value for a `DefaultMap` that corresponds to an entity, assuming that
41
+ * the map uses `PtrHash` as an index.
42
+ */
43
+ export declare function mapSetHash<V>(map: Map<PtrHash, V>, entity: Entity, value: V): void;
23
44
  /** Helper function to sum every value in a map together. */
24
45
  export declare function sumMap(map: Map<unknown, number> | ReadonlyMap<unknown, number>): number;
25
46
  //# sourceMappingURL=map.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"map.d.ts","sourceRoot":"","sources":["../../../src/functions/map.ts"],"names":[],"mappings":"AAGA,mGAAmG;AACnG,wBAAgB,OAAO,CAAC,CAAC,EAAE,CAAC,EAAE,MAAM,EAAE,GAAG,CAAC,CAAC,EAAE,CAAC,CAAC,GAAG,GAAG,CAAC,CAAC,EAAE,CAAC,CAAC,CAO1D;AAED;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,kBAAkB,CAAC,CAAC,EAClC,UAAU,EAAE,MAAM,EAClB,GAAG,EAAE,WAAW,CAAC,MAAM,EAAE,CAAC,CAAC,GAC1B,CAAC,MAAM,EAAE,CAAC,CAAC,GAAG,SAAS,CAgBzB;AAED,4DAA4D;AAC5D,wBAAgB,MAAM,CACpB,GAAG,EAAE,GAAG,CAAC,OAAO,EAAE,MAAM,CAAC,GAAG,WAAW,CAAC,OAAO,EAAE,MAAM,CAAC,GACvD,MAAM,CAGR"}
1
+ {"version":3,"file":"map.d.ts","sourceRoot":"","sources":["../../../src/functions/map.ts"],"names":[],"mappings":";;AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,uBAAuB,CAAC;AAInD,mGAAmG;AACnG,wBAAgB,OAAO,CAAC,CAAC,EAAE,CAAC,EAAE,MAAM,EAAE,GAAG,CAAC,CAAC,EAAE,CAAC,CAAC,GAAG,GAAG,CAAC,CAAC,EAAE,CAAC,CAAC,CAO1D;AAED;;;GAGG;AACH,wBAAgB,iBAAiB,CAAC,CAAC,EAAE,CAAC,SAAS,OAAO,EAAE,EACtD,GAAG,EAAE,UAAU,CAAC,OAAO,EAAE,CAAC,EAAE,CAAC,CAAC,EAC9B,MAAM,EAAE,MAAM,EACd,GAAG,SAAS,EAAE,CAAC,GACd,CAAC,CAGH;AAED;;;;;;GAMG;AACH,wBAAgB,iBAAiB,CAAC,CAAC,EACjC,GAAG,EAAE,GAAG,CAAC,OAAO,EAAE,CAAC,CAAC,EACpB,MAAM,EAAE,MAAM,EACd,KAAK,EAAE,CAAC,GACP,IAAI,CAEN;AAED;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,kBAAkB,CAAC,CAAC,EAClC,UAAU,EAAE,MAAM,EAClB,GAAG,EAAE,WAAW,CAAC,MAAM,EAAE,CAAC,CAAC,GAC1B,CAAC,MAAM,EAAE,CAAC,CAAC,GAAG,SAAS,CAgBzB;AAED;;;GAGG;AACH,wBAAgB,UAAU,CAAC,CAAC,EAC1B,GAAG,EAAE,GAAG,CAAC,OAAO,EAAE,CAAC,CAAC,EACpB,MAAM,EAAE,MAAM,EACd,KAAK,EAAE,CAAC,GACP,IAAI,CAGN;AAED,4DAA4D;AAC5D,wBAAgB,MAAM,CACpB,GAAG,EAAE,GAAG,CAAC,OAAO,EAAE,MAAM,CAAC,GAAG,WAAW,CAAC,OAAO,EAAE,MAAM,CAAC,GACvD,MAAM,CAGR"}
@@ -8,6 +8,12 @@ local ____array = require("src.functions.array")
8
8
  local sumArray = ____array.sumArray
9
9
  local ____string = require("src.functions.string")
10
10
  local getPartialMatch = ____string.getPartialMatch
11
+ --- Helper function to set a value for a `DefaultMap` that corresponds to an entity, assuming that
12
+ -- the map uses `PtrHash` as an index.
13
+ function ____exports.mapSetHash(self, map, entity, value)
14
+ local hash = GetPtrHash(entity)
15
+ map:set(hash, value)
16
+ end
11
17
  --- Helper function to copy a map. (You can also use a Map constructor to accomplish this task.)
12
18
  function ____exports.copyMap(self, oldMap)
13
19
  local newMap = __TS__New(Map)
@@ -18,6 +24,20 @@ function ____exports.copyMap(self, oldMap)
18
24
  end
19
25
  return newMap
20
26
  end
27
+ --- Helper function to get the value from a `DefaultMap` that corresponds to an entity, assuming that
28
+ -- the map uses `PtrHash` as an index.
29
+ function ____exports.defaultMapGetHash(self, map, entity, ...)
30
+ local ptrHash = GetPtrHash(entity)
31
+ return map:getAndSetDefault(ptrHash, ...)
32
+ end
33
+ --- Helper function to set a value for a `DefaultMap` that corresponds to an entity, assuming that
34
+ -- the map uses `PtrHash` as an index.
35
+ --
36
+ -- Since `Map` and `DefaultMap` set values in the same way, this function is simply an alias for the
37
+ -- `mapSetHash` helper function.
38
+ function ____exports.defaultMapSetHash(self, map, entity, value)
39
+ ____exports.mapSetHash(nil, map, entity, value)
40
+ end
21
41
  --- Helper function to get the closest value from a map based on partial search text. For the
22
42
  -- purposes of this function, both search text and map keys are converted to lowercase before
23
43
  -- attempting to find a match.
@@ -1 +1 @@
1
- {"version":3,"file":"gridEntityXMLMap.d.ts","sourceRoot":"","sources":["../../../src/maps/gridEntityXMLMap.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,cAAc,EACd,iBAAiB,EAOlB,MAAM,8BAA8B,CAAC;AAEtC;;;GAGG;AACH,eAAO,MAAM,mBAAmB,EAAE,WAAW,CAC3C,iBAAiB,EACjB;IAAC,cAAc;IAAE,GAAG;CAAC,CA6JrB,CAAC"}
1
+ {"version":3,"file":"gridEntityXMLMap.d.ts","sourceRoot":"","sources":["../../../src/maps/gridEntityXMLMap.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,cAAc,EACd,iBAAiB,EAOlB,MAAM,8BAA8B,CAAC;AAEtC;;;GAGG;AACH,eAAO,MAAM,mBAAmB,EAAE,WAAW,CAC3C,iBAAiB,EACjB;IAAC,cAAc;IAAE,GAAG;CAAC,CAgKrB,CAAC"}
@@ -15,6 +15,7 @@ local TrapdoorVariant = ____isaac_2Dtypescript_2Ddefinitions.TrapdoorVariant
15
15
  --- This maps the GridEntityXMLType (i.e. the type contained in the room XML/STB file) to the
16
16
  -- GridEntityType and the variant used by the game.
17
17
  ____exports.GRID_ENTITY_XML_MAP = __TS__New(Map, {
18
+ {GridEntityXMLType.DECORATION, {GridEntityType.DECORATION, 0}},
18
19
  {GridEntityXMLType.ROCK, {GridEntityType.ROCK, RockVariant.NORMAL}},
19
20
  {GridEntityXMLType.ROCK_BOMB, {GridEntityType.ROCK_BOMB, 0}},
20
21
  {GridEntityXMLType.ROCK_ALT, {GridEntityType.ROCK_ALT, 0}},
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "isaacscript-common",
3
- "version": "12.5.1",
3
+ "version": "12.6.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/src/index",
23
23
  "types": "dist/src/index.d.ts",
24
24
  "dependencies": {
25
- "isaac-typescript-definitions": "^7.2.5"
25
+ "isaac-typescript-definitions": "^7.2.6"
26
26
  }
27
27
  }
@@ -36,6 +36,7 @@ import {
36
36
  removeAllBombs,
37
37
  removeAllPickups,
38
38
  } from "../functions/entitiesSpecific";
39
+ import { getEnumValues } from "../functions/enums";
39
40
  import {
40
41
  convertXMLGridEntityType,
41
42
  getAllGridIndexes,
@@ -45,7 +46,7 @@ import {
45
46
  setGridEntityInvisible,
46
47
  spawnGridEntityWithVariant,
47
48
  } from "../functions/gridEntities";
48
- import { getRandomJSONRoom } from "../functions/jsonRoom";
49
+ import { getRandomJSONEntity, getRandomJSONRoom } from "../functions/jsonRoom";
49
50
  import { log } from "../functions/log";
50
51
  import { getRandomSeed, isRNG, newRNG } from "../functions/rng";
51
52
  import { getRoomListIndex } from "../functions/roomData";
@@ -74,6 +75,11 @@ const PERSISTENT_ENTITY_TYPES: ReadonlySet<EntityType> = new Set([
74
75
  EntityType.WALL_HUGGER,
75
76
  ]);
76
77
 
78
+ const gridEntityXMLTypes = getEnumValues(GridEntityXMLType);
79
+ const GRID_ENTITY_XML_TYPE_SET: ReadonlySet<number> = new Set(
80
+ gridEntityXMLTypes,
81
+ );
82
+
77
83
  const v = {
78
84
  level: {
79
85
  deployedRoomListIndexes: new Set<int>(),
@@ -310,7 +316,7 @@ export function deployJSONRoom(
310
316
  * what the function is doing. Default is false.
311
317
  */
312
318
  export function deployRandomJSONRoom(
313
- jsonRooms: JSONRoom[] | readonly JSONRoom[],
319
+ jsonRooms: JSONRoom[],
314
320
  seedOrRNG: Seed | RNG = getRandomSeed(),
315
321
  verbose = false,
316
322
  ): void {
@@ -463,16 +469,9 @@ function spawnAllEntities(
463
469
  );
464
470
  }
465
471
 
466
- if (jsonSpawn.entity.length > 1) {
467
- error("Stacked entities are not implemented for JSON rooms.");
468
- }
469
-
470
- const firstXMLEntity = jsonSpawn.entity[0];
471
- if (firstXMLEntity === undefined) {
472
- error('Failed to get the first JSON entity from an "entity" array.');
473
- }
472
+ const jsonEntity = getRandomJSONEntity(jsonSpawn.entity);
474
473
 
475
- const entityTypeString = firstXMLEntity.$.type;
474
+ const entityTypeString = jsonEntity.$.type;
476
475
  const entityTypeNumber = tonumber(entityTypeString);
477
476
  if (entityTypeNumber === undefined) {
478
477
  error(
@@ -480,20 +479,20 @@ function spawnAllEntities(
480
479
  );
481
480
  }
482
481
 
483
- const variantString = firstXMLEntity.$.variant;
482
+ const variantString = jsonEntity.$.variant;
484
483
  const variant = tonumber(variantString);
485
484
  if (variant === undefined) {
486
485
  error(`Failed to convert the entity variant to a number: ${variant}`);
487
486
  }
488
487
 
489
- const subTypeString = firstXMLEntity.$.subtype;
488
+ const subTypeString = jsonEntity.$.subtype;
490
489
  const subType = tonumber(subTypeString);
491
490
  if (subType === undefined) {
492
491
  error(`Failed to convert the entity sub-type to a number: ${subType}`);
493
492
  }
494
493
 
495
- // Note that XML entity type 1000 is a rock, not an effect.
496
- if (entityTypeNumber >= 1000) {
494
+ const isGridEntity = GRID_ENTITY_XML_TYPE_SET.has(entityTypeNumber);
495
+ if (isGridEntity) {
497
496
  const gridEntityXMLType = entityTypeNumber as GridEntityXMLType;
498
497
  if (verbose) {
499
498
  log(
@@ -3,7 +3,7 @@ import {
3
3
  DoorSlotFlagZero,
4
4
  RoomShape,
5
5
  } from "isaac-typescript-definitions";
6
- import { JSONRoom } from "../interfaces/JSONRoomsFile";
6
+ import { JSONEntity, JSONRoom } from "../interfaces/JSONRoomsFile";
7
7
  import { sumArray } from "./array";
8
8
  import { doorSlotToDoorSlotFlag, getRoomShapeDoorSlot } from "./doors";
9
9
  import { addFlag } from "./flag";
@@ -11,6 +11,11 @@ import { log } from "./log";
11
11
  import { getRandomFloat } from "./random";
12
12
  import { getRandomSeed } from "./rng";
13
13
 
14
+ /** This represents either a `JSONRoom` or a `JSONEntity`. */
15
+ interface JSONObject {
16
+ $: { weight: string | undefined };
17
+ }
18
+
14
19
  /**
15
20
  * Helper function to calculate what the resulting `BitFlags<DoorSlotFlag>` value would be for a
16
21
  * given JSON room.
@@ -116,6 +121,45 @@ export function getJSONRoomsOfSubType(
116
121
  });
117
122
  }
118
123
 
124
+ /**
125
+ * Helper function to get a random JSON entity from an array of JSON entities.
126
+ *
127
+ * Note that this function does not simply choose a random element in the provided array; it will
128
+ * properly account for each room weight using the algorithm from:
129
+ * https://stackoverflow.com/questions/1761626/weighted-random-numbers
130
+ *
131
+ * @param jsonEntities The array of entities to randomly choose between.
132
+ * @param seedOrRNG Optional. The `Seed` or `RNG` object to use. If an `RNG` object is provided, the
133
+ * `RNG.Next` method will be called. Default is `getRandomSeed()`.
134
+ * @param verbose Optional. If specified, will write entries to the "log.txt" file that describe
135
+ * what the function is doing. Default is false.
136
+ */
137
+ export function getRandomJSONEntity(
138
+ jsonEntities: JSONEntity[],
139
+ seedOrRNG: Seed | RNG = getRandomSeed(),
140
+ verbose = false,
141
+ ): JSONEntity {
142
+ const totalWeight = getTotalWeightOfJSONObject(jsonEntities);
143
+ if (verbose) {
144
+ log(`Total weight of the JSON entities provided: ${totalWeight}`);
145
+ }
146
+
147
+ const chosenWeight = getRandomFloat(0, totalWeight, seedOrRNG);
148
+ if (verbose) {
149
+ log(`Randomly chose weight for JSON entity: ${chosenWeight}`);
150
+ }
151
+
152
+ const randomJSONEntity = getJSONObjectWithChosenWeight(
153
+ jsonEntities,
154
+ chosenWeight,
155
+ );
156
+ if (randomJSONEntity === undefined) {
157
+ error(`Failed to get a JSON entity with chosen weight: ${chosenWeight}`);
158
+ }
159
+
160
+ return randomJSONEntity;
161
+ }
162
+
119
163
  /**
120
164
  * Helper function to get a random JSON room from an array of JSON rooms.
121
165
  *
@@ -123,18 +167,18 @@ export function getJSONRoomsOfSubType(
123
167
  * properly account for each room weight using the algorithm from:
124
168
  * https://stackoverflow.com/questions/1761626/weighted-random-numbers
125
169
  *
126
- * @param jsonRooms The array of rooms to random choose between.
170
+ * @param jsonRooms The array of rooms to randomly choose between.
127
171
  * @param seedOrRNG Optional. The `Seed` or `RNG` object to use. If an `RNG` object is provided, the
128
172
  * `RNG.Next` method will be called. Default is `getRandomSeed()`.
129
173
  * @param verbose Optional. If specified, will write entries to the "log.txt" file that describe
130
174
  * what the function is doing. Default is false.
131
175
  */
132
176
  export function getRandomJSONRoom(
133
- jsonRooms: JSONRoom[] | readonly JSONRoom[],
177
+ jsonRooms: JSONRoom[],
134
178
  seedOrRNG: Seed | RNG = getRandomSeed(),
135
179
  verbose = false,
136
180
  ): JSONRoom {
137
- const totalWeight = getTotalWeightOfJSONRooms(jsonRooms);
181
+ const totalWeight = getTotalWeightOfJSONObject(jsonRooms);
138
182
  if (verbose) {
139
183
  log(`Total weight of the JSON rooms provided: ${totalWeight}`);
140
184
  }
@@ -144,41 +188,46 @@ export function getRandomJSONRoom(
144
188
  log(`Randomly chose weight for JSON room: ${chosenWeight}`);
145
189
  }
146
190
 
147
- return getJSONRoomWithChosenWeight(jsonRooms, chosenWeight);
191
+ const randomJSONRoom = getJSONObjectWithChosenWeight(jsonRooms, chosenWeight);
192
+ if (randomJSONRoom === undefined) {
193
+ error(`Failed to get a JSON room with chosen weight: ${chosenWeight}`);
194
+ }
195
+
196
+ return randomJSONRoom;
148
197
  }
149
198
 
150
- function getTotalWeightOfJSONRooms(
151
- jsonRooms: JSONRoom[] | readonly JSONRoom[],
152
- ): float {
153
- const weights = jsonRooms.map((jsonRoom) => {
154
- const roomWeightString = jsonRoom.$.weight;
155
- const roomWeight = tonumber(roomWeightString);
156
- if (roomWeight === undefined) {
157
- error(`Failed to parse the weight of a JSON room: ${roomWeightString}.`);
199
+ function getTotalWeightOfJSONObject(jsonOjectArray: JSONObject[]): float {
200
+ const weights = jsonOjectArray.map((jsonObject) => {
201
+ const weightString = jsonObject.$.weight;
202
+ const weight = tonumber(weightString);
203
+ if (weight === undefined) {
204
+ error(`Failed to parse the weight of a JSON object: ${weightString}.`);
158
205
  }
159
- return roomWeight;
206
+
207
+ return weight;
160
208
  });
161
209
 
162
210
  return sumArray(weights);
163
211
  }
164
212
 
165
- function getJSONRoomWithChosenWeight(
166
- jsonRooms: JSONRoom[] | readonly JSONRoom[],
213
+ function getJSONObjectWithChosenWeight<T extends JSONObject>(
214
+ jsonOjectArray: T[],
167
215
  chosenWeight: float,
168
- ): JSONRoom {
169
- for (const jsonRoom of jsonRooms) {
170
- const roomWeightString = jsonRoom.$.weight;
171
- const roomWeight = tonumber(roomWeightString);
172
- if (roomWeight === undefined) {
173
- error(`Failed to parse the weight of a JSON room: ${roomWeightString}`);
216
+ ): T | undefined {
217
+ let weightAccumulator = 0;
218
+
219
+ for (const jsonObject of jsonOjectArray) {
220
+ const weightString = jsonObject.$.weight;
221
+ const weight = tonumber(weightString);
222
+ if (weight === undefined) {
223
+ error(`Failed to parse the weight of a JSON object: ${weightString}`);
174
224
  }
175
225
 
176
- if (chosenWeight < roomWeight) {
177
- return jsonRoom;
226
+ weightAccumulator += weight;
227
+ if (weightAccumulator >= chosenWeight) {
228
+ return jsonObject;
178
229
  }
179
-
180
- chosenWeight -= roomWeight;
181
230
  }
182
231
 
183
- error(`Failed to get a JSON room with chosen weight: ${chosenWeight}`);
232
+ return undefined;
184
233
  }
@@ -1,3 +1,4 @@
1
+ import { DefaultMap } from "../classes/DefaultMap";
1
2
  import { sumArray } from "./array";
2
3
  import { getPartialMatch } from "./string";
3
4
 
@@ -11,6 +12,34 @@ export function copyMap<K, V>(oldMap: Map<K, V>): Map<K, V> {
11
12
  return newMap;
12
13
  }
13
14
 
15
+ /**
16
+ * Helper function to get the value from a `DefaultMap` that corresponds to an entity, assuming that
17
+ * the map uses `PtrHash` as an index.
18
+ */
19
+ export function defaultMapGetHash<V, A extends unknown[]>(
20
+ map: DefaultMap<PtrHash, V, A>,
21
+ entity: Entity,
22
+ ...extraArgs: A
23
+ ): V {
24
+ const ptrHash = GetPtrHash(entity);
25
+ return map.getAndSetDefault(ptrHash, ...extraArgs);
26
+ }
27
+
28
+ /**
29
+ * Helper function to set a value for a `DefaultMap` that corresponds to an entity, assuming that
30
+ * the map uses `PtrHash` as an index.
31
+ *
32
+ * Since `Map` and `DefaultMap` set values in the same way, this function is simply an alias for the
33
+ * `mapSetHash` helper function.
34
+ */
35
+ export function defaultMapSetHash<V>(
36
+ map: Map<PtrHash, V>,
37
+ entity: Entity,
38
+ value: V,
39
+ ): void {
40
+ mapSetHash(map, entity, value);
41
+ }
42
+
14
43
  /**
15
44
  * Helper function to get the closest value from a map based on partial search text. For the
16
45
  * purposes of this function, both search text and map keys are converted to lowercase before
@@ -51,6 +80,19 @@ export function getMapPartialMatch<T>(
51
80
  return [matchingKey, value];
52
81
  }
53
82
 
83
+ /**
84
+ * Helper function to set a value for a `DefaultMap` that corresponds to an entity, assuming that
85
+ * the map uses `PtrHash` as an index.
86
+ */
87
+ export function mapSetHash<V>(
88
+ map: Map<PtrHash, V>,
89
+ entity: Entity,
90
+ value: V,
91
+ ): void {
92
+ const hash = GetPtrHash(entity);
93
+ map.set(hash, value);
94
+ }
95
+
54
96
  /** Helper function to sum every value in a map together. */
55
97
  export function sumMap(
56
98
  map: Map<unknown, number> | ReadonlyMap<unknown, number>,
@@ -18,6 +18,9 @@ export const GRID_ENTITY_XML_MAP: ReadonlyMap<
18
18
  GridEntityXMLType,
19
19
  [GridEntityType, int]
20
20
  > = new Map([
21
+ // 0
22
+ [GridEntityXMLType.DECORATION, [GridEntityType.DECORATION, 0]],
23
+
21
24
  // 1000
22
25
  [GridEntityXMLType.ROCK, [GridEntityType.ROCK, RockVariant.NORMAL]],
23
26