isaacscript-common 6.18.0 → 6.19.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/features/playerInventory.d.ts.map +1 -1
- package/dist/features/playerInventory.lua +2 -4
- package/dist/functions/eden.d.ts.map +1 -1
- package/dist/functions/eden.lua +2 -4
- package/dist/functions/itemPool.d.ts +18 -0
- package/dist/functions/itemPool.d.ts.map +1 -0
- package/dist/functions/itemPool.lua +133 -0
- package/dist/functions/rockAlt.d.ts +4 -4
- package/dist/functions/rockAlt.d.ts.map +1 -1
- package/dist/functions/rockAlt.lua +69 -20
- package/dist/functions/saveFile.d.ts +1 -6
- package/dist/functions/saveFile.d.ts.map +1 -1
- package/dist/functions/saveFile.lua +4 -113
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.lua +8 -0
- package/package.json +1 -1
- package/src/features/playerInventory.ts +2 -3
- package/src/functions/eden.ts +2 -4
- package/src/functions/itemPool.ts +178 -0
- package/src/functions/rockAlt.ts +111 -29
- package/src/functions/saveFile.ts +5 -147
- package/src/index.ts +1 -0
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"playerInventory.d.ts","sourceRoot":"","sources":["../../src/features/playerInventory.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAe,MAAM,8BAA8B,CAAC;
|
|
1
|
+
{"version":3,"file":"playerInventory.d.ts","sourceRoot":"","sources":["../../src/features/playerInventory.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAe,MAAM,8BAA8B,CAAC;AAyG5E;;;;;;;;;;;GAWG;AACH,wBAAgB,kBAAkB,CAChC,MAAM,EAAE,YAAY,EACpB,yBAAyB,UAAO,GAC/B,eAAe,EAAE,CAanB"}
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
local ____lualib = require("lualib_bundle")
|
|
2
2
|
local __TS__New = ____lualib.__TS__New
|
|
3
|
-
local __TS__Iterator = ____lualib.__TS__Iterator
|
|
4
3
|
local __TS__ArrayFilter = ____lualib.__TS__ArrayFilter
|
|
5
4
|
local ____exports = {}
|
|
6
5
|
local newPlayerInventory, resetInventory, useItemD4, postGameStarted, postCollectibleAdded, postCollectibleRemoved, v
|
|
@@ -19,7 +18,7 @@ local copyArray = ____array.copyArray
|
|
|
19
18
|
local ____collectibles = require("functions.collectibles")
|
|
20
19
|
local isActiveCollectible = ____collectibles.isActiveCollectible
|
|
21
20
|
local ____collectibleSet = require("functions.collectibleSet")
|
|
22
|
-
local
|
|
21
|
+
local getCollectibleArray = ____collectibleSet.getCollectibleArray
|
|
23
22
|
local ____playerDataStructures = require("functions.playerDataStructures")
|
|
24
23
|
local defaultMapGetPlayer = ____playerDataStructures.defaultMapGetPlayer
|
|
25
24
|
local mapSetPlayer = ____playerDataStructures.mapSetPlayer
|
|
@@ -32,8 +31,7 @@ local ____exports = require("features.saveDataManager.exports")
|
|
|
32
31
|
local saveDataManager = ____exports.saveDataManager
|
|
33
32
|
function newPlayerInventory(self, player)
|
|
34
33
|
local inventory = {}
|
|
35
|
-
|
|
36
|
-
for ____, collectibleType in __TS__Iterator(collectibleSet:values()) do
|
|
34
|
+
for ____, collectibleType in ipairs(getCollectibleArray(nil)) do
|
|
37
35
|
local numCollectibles = player:GetCollectibleNum(collectibleType, true)
|
|
38
36
|
____repeat(
|
|
39
37
|
nil,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"eden.d.ts","sourceRoot":"","sources":["../../src/functions/eden.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAiB,MAAM,8BAA8B,CAAC;
|
|
1
|
+
{"version":3,"file":"eden.d.ts","sourceRoot":"","sources":["../../src/functions/eden.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAiB,MAAM,8BAA8B,CAAC;AAqB9E,wBAAgB,eAAe,IAAI,GAAG,CAAC,eAAe,CAAC,CAOtD;AAED,wBAAgB,oBAAoB,CAClC,SAAS,GAAE,IAAI,GAAG,GAAqB,EACvC,UAAU,GAAE,eAAe,EAAE,GAAG,SAAS,eAAe,EAAO,GAC9D,eAAe,CAWjB"}
|
package/dist/functions/eden.lua
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
local ____lualib = require("lualib_bundle")
|
|
2
2
|
local Set = ____lualib.Set
|
|
3
3
|
local __TS__New = ____lualib.__TS__New
|
|
4
|
-
local __TS__Iterator = ____lualib.__TS__Iterator
|
|
5
4
|
local ____exports = {}
|
|
6
5
|
local ____isaac_2Dtypescript_2Ddefinitions = require("isaac-typescript-definitions")
|
|
7
6
|
local ItemConfigTag = ____isaac_2Dtypescript_2Ddefinitions.ItemConfigTag
|
|
@@ -9,7 +8,7 @@ local ____collectibles = require("functions.collectibles")
|
|
|
9
8
|
local isHiddenCollectible = ____collectibles.isHiddenCollectible
|
|
10
9
|
local isPassiveCollectible = ____collectibles.isPassiveCollectible
|
|
11
10
|
local ____collectibleSet = require("functions.collectibleSet")
|
|
12
|
-
local
|
|
11
|
+
local getCollectibleArray = ____collectibleSet.getCollectibleArray
|
|
13
12
|
local ____collectibleTag = require("functions.collectibleTag")
|
|
14
13
|
local collectibleHasTag = ____collectibleTag.collectibleHasTag
|
|
15
14
|
local ____rng = require("functions.rng")
|
|
@@ -19,8 +18,7 @@ local copySet = ____set.copySet
|
|
|
19
18
|
local getRandomSetElement = ____set.getRandomSetElement
|
|
20
19
|
local EDEN_PASSIVE_COLLECTIBLES_SET = __TS__New(Set)
|
|
21
20
|
local function initCollectibleSet(self)
|
|
22
|
-
|
|
23
|
-
for ____, collectibleType in __TS__Iterator(collectibleSet:values()) do
|
|
21
|
+
for ____, collectibleType in ipairs(getCollectibleArray(nil)) do
|
|
24
22
|
if isPassiveCollectible(nil, collectibleType) and not isHiddenCollectible(nil, collectibleType) and not collectibleHasTag(nil, collectibleType, ItemConfigTag.NO_EDEN) then
|
|
25
23
|
EDEN_PASSIVE_COLLECTIBLES_SET:add(collectibleType)
|
|
26
24
|
end
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { CollectibleType, ItemPoolType } from "isaac-typescript-definitions";
|
|
2
|
+
/**
|
|
3
|
+
* Helper function to get the remaining collectibles in a given item pool. This function is
|
|
4
|
+
* expensive, so only use it in situations where the lag is acceptable.
|
|
5
|
+
*/
|
|
6
|
+
export declare function getCollectiblesInItemPool(itemPoolType: ItemPoolType): CollectibleType[];
|
|
7
|
+
/**
|
|
8
|
+
* Helper function to see if the given collectible is still present in the given item pool.
|
|
9
|
+
*
|
|
10
|
+
* If the collectible is non-offensive, any Tainted Losts will be temporarily changed to Isaac and
|
|
11
|
+
* then changed back. (This is because Tainted Lost is not able to retrieve non-offensive
|
|
12
|
+
* collectibles from item pools).
|
|
13
|
+
*
|
|
14
|
+
* Under the hood, this function works by using the `ItemPool.AddRoomBlacklist` method to blacklist
|
|
15
|
+
* every collectible except for the one provided.
|
|
16
|
+
*/
|
|
17
|
+
export declare function isCollectibleInItemPool(collectibleType: CollectibleType, itemPoolType: ItemPoolType): boolean;
|
|
18
|
+
//# sourceMappingURL=itemPool.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"itemPool.d.ts","sourceRoot":"","sources":["../../src/functions/itemPool.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,eAAe,EAEf,YAAY,EAGb,MAAM,8BAA8B,CAAC;AAsBtC;;;GAGG;AACH,wBAAgB,yBAAyB,CACvC,YAAY,EAAE,YAAY,GACzB,eAAe,EAAE,CAKnB;AAED;;;;;;;;;GASG;AACH,wBAAgB,uBAAuB,CACrC,eAAe,EAAE,eAAe,EAChC,YAAY,EAAE,YAAY,GACzB,OAAO,CA6DT"}
|
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
local ____lualib = require("lualib_bundle")
|
|
2
|
+
local __TS__ArrayFilter = ____lualib.__TS__ArrayFilter
|
|
3
|
+
local Map = ____lualib.Map
|
|
4
|
+
local __TS__New = ____lualib.__TS__New
|
|
5
|
+
local ____exports = {}
|
|
6
|
+
local removeItemsAndTrinketsThatAffectItemPools, restoreItemsAndTrinketsThatAffectItemPools, COLLECTIBLES_THAT_AFFECT_ITEM_POOLS, TRINKETS_THAT_AFFECT_ITEM_POOLS, COLLECTIBLE_TYPE_THAT_IS_NOT_IN_ANY_POOLS
|
|
7
|
+
local ____isaac_2Dtypescript_2Ddefinitions = require("isaac-typescript-definitions")
|
|
8
|
+
local CollectibleType = ____isaac_2Dtypescript_2Ddefinitions.CollectibleType
|
|
9
|
+
local ItemConfigTag = ____isaac_2Dtypescript_2Ddefinitions.ItemConfigTag
|
|
10
|
+
local PlayerType = ____isaac_2Dtypescript_2Ddefinitions.PlayerType
|
|
11
|
+
local TrinketType = ____isaac_2Dtypescript_2Ddefinitions.TrinketType
|
|
12
|
+
local ____cachedClasses = require("cachedClasses")
|
|
13
|
+
local game = ____cachedClasses.game
|
|
14
|
+
local ____collectibleSet = require("functions.collectibleSet")
|
|
15
|
+
local getCollectibleArray = ____collectibleSet.getCollectibleArray
|
|
16
|
+
local ____collectibleTag = require("functions.collectibleTag")
|
|
17
|
+
local collectibleHasTag = ____collectibleTag.collectibleHasTag
|
|
18
|
+
local ____playerDataStructures = require("functions.playerDataStructures")
|
|
19
|
+
local mapGetPlayer = ____playerDataStructures.mapGetPlayer
|
|
20
|
+
local mapSetPlayer = ____playerDataStructures.mapSetPlayer
|
|
21
|
+
local ____playerIndex = require("functions.playerIndex")
|
|
22
|
+
local getPlayers = ____playerIndex.getPlayers
|
|
23
|
+
local ____players = require("functions.players")
|
|
24
|
+
local getPlayersOfType = ____players.getPlayersOfType
|
|
25
|
+
local ____utils = require("functions.utils")
|
|
26
|
+
local ____repeat = ____utils["repeat"]
|
|
27
|
+
--- Helper function to see if the given collectible is still present in the given item pool.
|
|
28
|
+
--
|
|
29
|
+
-- If the collectible is non-offensive, any Tainted Losts will be temporarily changed to Isaac and
|
|
30
|
+
-- then changed back. (This is because Tainted Lost is not able to retrieve non-offensive
|
|
31
|
+
-- collectibles from item pools).
|
|
32
|
+
--
|
|
33
|
+
-- Under the hood, this function works by using the `ItemPool.AddRoomBlacklist` method to blacklist
|
|
34
|
+
-- every collectible except for the one provided.
|
|
35
|
+
function ____exports.isCollectibleInItemPool(self, collectibleType, itemPoolType)
|
|
36
|
+
if collectibleType == COLLECTIBLE_TYPE_THAT_IS_NOT_IN_ANY_POOLS then
|
|
37
|
+
return false
|
|
38
|
+
end
|
|
39
|
+
local taintedLosts = getPlayersOfType(nil, PlayerType.THE_LOST_B)
|
|
40
|
+
local isOffensive = collectibleHasTag(nil, collectibleType, ItemConfigTag.OFFENSIVE)
|
|
41
|
+
local changedPlayerTypes = false
|
|
42
|
+
if not isOffensive then
|
|
43
|
+
changedPlayerTypes = true
|
|
44
|
+
for ____, player in ipairs(taintedLosts) do
|
|
45
|
+
player:ChangePlayerType(PlayerType.ISAAC)
|
|
46
|
+
end
|
|
47
|
+
end
|
|
48
|
+
local removedItemsMap, removedTrinketsMap = table.unpack(removeItemsAndTrinketsThatAffectItemPools(nil))
|
|
49
|
+
local itemPool = game:GetItemPool()
|
|
50
|
+
itemPool:ResetRoomBlacklist()
|
|
51
|
+
for ____, collectibleTypeInSet in ipairs(getCollectibleArray(nil)) do
|
|
52
|
+
if collectibleTypeInSet ~= collectibleType then
|
|
53
|
+
itemPool:AddRoomBlacklist(collectibleTypeInSet)
|
|
54
|
+
end
|
|
55
|
+
end
|
|
56
|
+
local seed = 1
|
|
57
|
+
local retrievedCollectibleType = itemPool:GetCollectible(itemPoolType, false, seed, COLLECTIBLE_TYPE_THAT_IS_NOT_IN_ANY_POOLS)
|
|
58
|
+
local collectibleUnlocked = retrievedCollectibleType == collectibleType
|
|
59
|
+
itemPool:ResetRoomBlacklist()
|
|
60
|
+
restoreItemsAndTrinketsThatAffectItemPools(nil, removedItemsMap, removedTrinketsMap)
|
|
61
|
+
if changedPlayerTypes then
|
|
62
|
+
for ____, player in ipairs(taintedLosts) do
|
|
63
|
+
player:ChangePlayerType(PlayerType.THE_LOST_B)
|
|
64
|
+
end
|
|
65
|
+
end
|
|
66
|
+
return collectibleUnlocked
|
|
67
|
+
end
|
|
68
|
+
function removeItemsAndTrinketsThatAffectItemPools(self)
|
|
69
|
+
local removedItemsMap = __TS__New(Map)
|
|
70
|
+
local removedTrinketsMap = __TS__New(Map)
|
|
71
|
+
for ____, player in ipairs(getPlayers(nil)) do
|
|
72
|
+
local removedItems = {}
|
|
73
|
+
for ____, itemToRemove in ipairs(COLLECTIBLES_THAT_AFFECT_ITEM_POOLS) do
|
|
74
|
+
if player:HasCollectible(itemToRemove) then
|
|
75
|
+
local numCollectibles = player:GetCollectibleNum(itemToRemove)
|
|
76
|
+
____repeat(
|
|
77
|
+
nil,
|
|
78
|
+
numCollectibles,
|
|
79
|
+
function()
|
|
80
|
+
player:RemoveCollectible(itemToRemove)
|
|
81
|
+
removedItems[#removedItems + 1] = itemToRemove
|
|
82
|
+
end
|
|
83
|
+
)
|
|
84
|
+
end
|
|
85
|
+
end
|
|
86
|
+
mapSetPlayer(nil, removedItemsMap, player, removedItems)
|
|
87
|
+
local removedTrinkets = {}
|
|
88
|
+
for ____, trinketToRemove in ipairs(TRINKETS_THAT_AFFECT_ITEM_POOLS) do
|
|
89
|
+
if player:HasTrinket(trinketToRemove) then
|
|
90
|
+
local numTrinkets = player:GetTrinketMultiplier(trinketToRemove)
|
|
91
|
+
____repeat(
|
|
92
|
+
nil,
|
|
93
|
+
numTrinkets,
|
|
94
|
+
function()
|
|
95
|
+
player:TryRemoveTrinket(trinketToRemove)
|
|
96
|
+
removedTrinkets[#removedTrinkets + 1] = trinketToRemove
|
|
97
|
+
end
|
|
98
|
+
)
|
|
99
|
+
end
|
|
100
|
+
end
|
|
101
|
+
mapSetPlayer(nil, removedTrinketsMap, player, removedTrinkets)
|
|
102
|
+
end
|
|
103
|
+
return {removedItemsMap, removedTrinketsMap}
|
|
104
|
+
end
|
|
105
|
+
function restoreItemsAndTrinketsThatAffectItemPools(self, removedItemsMap, removedTrinketsMap)
|
|
106
|
+
for ____, player in ipairs(getPlayers(nil)) do
|
|
107
|
+
local removedItems = mapGetPlayer(nil, removedItemsMap, player)
|
|
108
|
+
if removedItems ~= nil then
|
|
109
|
+
for ____, collectibleType in ipairs(removedItems) do
|
|
110
|
+
player:AddCollectible(collectibleType, 0, false)
|
|
111
|
+
end
|
|
112
|
+
end
|
|
113
|
+
local removedTrinkets = mapGetPlayer(nil, removedTrinketsMap, player)
|
|
114
|
+
if removedTrinkets ~= nil then
|
|
115
|
+
for ____, trinketType in ipairs(removedTrinkets) do
|
|
116
|
+
player:AddTrinket(trinketType, false)
|
|
117
|
+
end
|
|
118
|
+
end
|
|
119
|
+
end
|
|
120
|
+
end
|
|
121
|
+
COLLECTIBLES_THAT_AFFECT_ITEM_POOLS = {CollectibleType.CHAOS, CollectibleType.SACRED_ORB, CollectibleType.TMTRAINER}
|
|
122
|
+
TRINKETS_THAT_AFFECT_ITEM_POOLS = {TrinketType.NO}
|
|
123
|
+
COLLECTIBLE_TYPE_THAT_IS_NOT_IN_ANY_POOLS = CollectibleType.KEY_PIECE_1
|
|
124
|
+
--- Helper function to get the remaining collectibles in a given item pool. This function is
|
|
125
|
+
-- expensive, so only use it in situations where the lag is acceptable.
|
|
126
|
+
function ____exports.getCollectiblesInItemPool(self, itemPoolType)
|
|
127
|
+
local collectibleArray = getCollectibleArray(nil)
|
|
128
|
+
return __TS__ArrayFilter(
|
|
129
|
+
collectibleArray,
|
|
130
|
+
function(____, collectibleType) return ____exports.isCollectibleInItemPool(nil, collectibleType, itemPoolType) end
|
|
131
|
+
)
|
|
132
|
+
end
|
|
133
|
+
return ____exports
|
|
@@ -24,10 +24,10 @@ export declare function getRockAltType(): RockAltType;
|
|
|
24
24
|
* Most of the time, this function will do nothing, similar to how most of the time, when an
|
|
25
25
|
* individual urn is destroyed, nothing will spawn.
|
|
26
26
|
*
|
|
27
|
-
* Note that in vanilla,
|
|
28
|
-
*
|
|
29
|
-
*
|
|
30
|
-
*
|
|
27
|
+
* Note that in vanilla, trinkets will not spawn if they have already been removed from the trinket
|
|
28
|
+
* pool. This function cannot replicate that behavior because there is no way to check to see if a
|
|
29
|
+
* trinket is still in the pool. Thus, it will always have a chance to spawn the respective trinket
|
|
30
|
+
* (e.g. Swallowed Penny from urns).
|
|
31
31
|
*
|
|
32
32
|
* The logic in this function is based on the rewards listed on the wiki:
|
|
33
33
|
* https://bindingofisaacrebirth.fandom.com/wiki/Rocks
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"rockAlt.d.ts","sourceRoot":"","sources":["../../src/functions/rockAlt.ts"],"names":[],"mappings":";;;
|
|
1
|
+
{"version":3,"file":"rockAlt.d.ts","sourceRoot":"","sources":["../../src/functions/rockAlt.ts"],"names":[],"mappings":";;;AAcA,OAAO,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAC;AA+BnD;;;;;;;;;;;;;GAaG;AACH,wBAAgB,cAAc,IAAI,WAAW,CAK5C;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AACH,wBAAgB,kBAAkB,CAChC,QAAQ,EAAE,MAAM,EAChB,WAAW,EAAE,WAAW,EACxB,OAAO,SAAI,EACX,SAAS,GAAE,IAAI,GAAG,GAAqB,GACtC,OAAO,CAwBT"}
|
|
@@ -7,6 +7,7 @@ local CollectibleType = ____isaac_2Dtypescript_2Ddefinitions.CollectibleType
|
|
|
7
7
|
local EffectVariant = ____isaac_2Dtypescript_2Ddefinitions.EffectVariant
|
|
8
8
|
local EntityType = ____isaac_2Dtypescript_2Ddefinitions.EntityType
|
|
9
9
|
local HeartSubType = ____isaac_2Dtypescript_2Ddefinitions.HeartSubType
|
|
10
|
+
local ItemPoolType = ____isaac_2Dtypescript_2Ddefinitions.ItemPoolType
|
|
10
11
|
local PillColor = ____isaac_2Dtypescript_2Ddefinitions.PillColor
|
|
11
12
|
local RoomType = ____isaac_2Dtypescript_2Ddefinitions.RoomType
|
|
12
13
|
local TrinketType = ____isaac_2Dtypescript_2Ddefinitions.TrinketType
|
|
@@ -21,6 +22,8 @@ local BACKDROP_TYPE_TO_ROCK_ALT_TYPE = ____backdropTypeToRockAltType.BACKDROP_TY
|
|
|
21
22
|
local ____entitiesSpecific = require("functions.entitiesSpecific")
|
|
22
23
|
local spawnEffectWithSeed = ____entitiesSpecific.spawnEffectWithSeed
|
|
23
24
|
local spawnNPCWithSeed = ____entitiesSpecific.spawnNPCWithSeed
|
|
25
|
+
local ____itemPool = require("functions.itemPool")
|
|
26
|
+
local isCollectibleInItemPool = ____itemPool.isCollectibleInItemPool
|
|
24
27
|
local ____pickupsSpecific = require("functions.pickupsSpecific")
|
|
25
28
|
local spawnCardWithSeed = ____pickupsSpecific.spawnCardWithSeed
|
|
26
29
|
local spawnCoinWithSeed = ____pickupsSpecific.spawnCoinWithSeed
|
|
@@ -77,8 +80,12 @@ function spawnRockAltRewardUrn(self, position, rng)
|
|
|
77
80
|
end
|
|
78
81
|
totalChance = totalChance + ROCK_ALT_CHANCES.COLLECTIBLE
|
|
79
82
|
if chance < totalChance then
|
|
80
|
-
|
|
81
|
-
|
|
83
|
+
local stillInPools = isCollectibleInItemPool(nil, CollectibleType.QUARTER, ItemPoolType.DEVIL)
|
|
84
|
+
if stillInPools then
|
|
85
|
+
spawnCollectible(nil, CollectibleType.QUARTER, position, rng)
|
|
86
|
+
return true
|
|
87
|
+
end
|
|
88
|
+
return false
|
|
82
89
|
end
|
|
83
90
|
local numSpidersChance = getRandom(nil, rng)
|
|
84
91
|
local numSpiders = numSpidersChance < 0.5 and 1 or 2
|
|
@@ -125,14 +132,30 @@ function spawnRockAltRewardMushroom(self, position, rng)
|
|
|
125
132
|
if roomType == RoomType.SECRET then
|
|
126
133
|
local wavyCapChance = getRandom(nil, rng)
|
|
127
134
|
if wavyCapChance < 0.0272 then
|
|
128
|
-
|
|
129
|
-
|
|
135
|
+
local stillInPools = isCollectibleInItemPool(nil, CollectibleType.WAVY_CAP, ItemPoolType.SECRET)
|
|
136
|
+
if stillInPools then
|
|
137
|
+
spawnCollectible(nil, CollectibleType.WAVY_CAP, position, rng)
|
|
138
|
+
return true
|
|
139
|
+
end
|
|
130
140
|
end
|
|
131
141
|
end
|
|
132
|
-
local
|
|
133
|
-
local
|
|
134
|
-
|
|
135
|
-
|
|
142
|
+
local magicMushroomStillInPools = isCollectibleInItemPool(nil, CollectibleType.MAGIC_MUSHROOM, ItemPoolType.TREASURE)
|
|
143
|
+
local miniMushStillInPools = isCollectibleInItemPool(nil, CollectibleType.MINI_MUSH, ItemPoolType.TREASURE)
|
|
144
|
+
if magicMushroomStillInPools and miniMushStillInPools then
|
|
145
|
+
local collectibleChance = getRandom(nil, rng)
|
|
146
|
+
local collectibleType = collectibleChance < 0.5 and CollectibleType.MAGIC_MUSHROOM or CollectibleType.MINI_MUSH
|
|
147
|
+
spawnCollectible(nil, collectibleType, position, rng)
|
|
148
|
+
return true
|
|
149
|
+
end
|
|
150
|
+
if magicMushroomStillInPools then
|
|
151
|
+
spawnCollectible(nil, CollectibleType.MINI_MUSH, position, rng)
|
|
152
|
+
return true
|
|
153
|
+
end
|
|
154
|
+
if miniMushStillInPools then
|
|
155
|
+
spawnCollectible(nil, CollectibleType.MAGIC_MUSHROOM, position, rng)
|
|
156
|
+
return true
|
|
157
|
+
end
|
|
158
|
+
return false
|
|
136
159
|
end
|
|
137
160
|
spawnEffectWithSeed(
|
|
138
161
|
nil,
|
|
@@ -162,10 +185,23 @@ function spawnRockAltRewardSkull(self, position, rng)
|
|
|
162
185
|
end
|
|
163
186
|
totalChance = totalChance + ROCK_ALT_CHANCES.COLLECTIBLE
|
|
164
187
|
if chance < totalChance then
|
|
165
|
-
local
|
|
166
|
-
local
|
|
167
|
-
|
|
168
|
-
|
|
188
|
+
local ghostBabyStillInPools = isCollectibleInItemPool(nil, CollectibleType.GHOST_BABY, ItemPoolType.TREASURE)
|
|
189
|
+
local dryBabyStillInPools = isCollectibleInItemPool(nil, CollectibleType.DRY_BABY, ItemPoolType.TREASURE)
|
|
190
|
+
if ghostBabyStillInPools and dryBabyStillInPools then
|
|
191
|
+
local collectibleChance = getRandom(nil, rng)
|
|
192
|
+
local collectibleType = collectibleChance < 0.5 and CollectibleType.GHOST_BABY or CollectibleType.DRY_BABY
|
|
193
|
+
spawnCollectible(nil, collectibleType, position, rng)
|
|
194
|
+
return true
|
|
195
|
+
end
|
|
196
|
+
if ghostBabyStillInPools then
|
|
197
|
+
spawnCollectible(nil, CollectibleType.DRY_BABY, position, rng)
|
|
198
|
+
return true
|
|
199
|
+
end
|
|
200
|
+
if dryBabyStillInPools then
|
|
201
|
+
spawnCollectible(nil, CollectibleType.GHOST_BABY, position, rng)
|
|
202
|
+
return true
|
|
203
|
+
end
|
|
204
|
+
return false
|
|
169
205
|
end
|
|
170
206
|
spawnNPCWithSeed(
|
|
171
207
|
nil,
|
|
@@ -196,10 +232,23 @@ function spawnRockAltRewardPolyp(self, position, rng)
|
|
|
196
232
|
end
|
|
197
233
|
totalChance = totalChance + ROCK_ALT_CHANCES.COLLECTIBLE
|
|
198
234
|
if chance < totalChance then
|
|
199
|
-
local
|
|
200
|
-
local
|
|
201
|
-
|
|
202
|
-
|
|
235
|
+
local placentaStillInPools = isCollectibleInItemPool(nil, CollectibleType.PLACENTA, ItemPoolType.BOSS)
|
|
236
|
+
local bloodClotStillInPools = isCollectibleInItemPool(nil, CollectibleType.BLOOD_CLOT, ItemPoolType.BOSS)
|
|
237
|
+
if bloodClotStillInPools and placentaStillInPools then
|
|
238
|
+
local collectibleChance = getRandom(nil, rng)
|
|
239
|
+
local collectibleType = collectibleChance < 0.5 and CollectibleType.PLACENTA or CollectibleType.BLOOD_CLOT
|
|
240
|
+
spawnCollectible(nil, collectibleType, position, rng)
|
|
241
|
+
return true
|
|
242
|
+
end
|
|
243
|
+
if bloodClotStillInPools then
|
|
244
|
+
spawnCollectible(nil, CollectibleType.MINI_MUSH, position, rng)
|
|
245
|
+
return true
|
|
246
|
+
end
|
|
247
|
+
if placentaStillInPools then
|
|
248
|
+
spawnCollectible(nil, CollectibleType.MAGIC_MUSHROOM, position, rng)
|
|
249
|
+
return true
|
|
250
|
+
end
|
|
251
|
+
return false
|
|
203
252
|
end
|
|
204
253
|
spawnEffectWithSeed(
|
|
205
254
|
nil,
|
|
@@ -252,10 +301,10 @@ end
|
|
|
252
301
|
-- Most of the time, this function will do nothing, similar to how most of the time, when an
|
|
253
302
|
-- individual urn is destroyed, nothing will spawn.
|
|
254
303
|
--
|
|
255
|
-
-- Note that in vanilla,
|
|
256
|
-
--
|
|
257
|
-
--
|
|
258
|
-
--
|
|
304
|
+
-- Note that in vanilla, trinkets will not spawn if they have already been removed from the trinket
|
|
305
|
+
-- pool. This function cannot replicate that behavior because there is no way to check to see if a
|
|
306
|
+
-- trinket is still in the pool. Thus, it will always have a chance to spawn the respective trinket
|
|
307
|
+
-- (e.g. Swallowed Penny from urns).
|
|
259
308
|
--
|
|
260
309
|
-- The logic in this function is based on the rewards listed on the wiki:
|
|
261
310
|
-- https://bindingofisaacrebirth.fandom.com/wiki/Rocks
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { CollectibleType, ItemPoolType } from "isaac-typescript-definitions";
|
|
2
2
|
/**
|
|
3
3
|
* Helper function to see if the given collectible is unlocked on the current save file. This
|
|
4
|
-
* requires providing the corresponding item pool that the collectible is located in.
|
|
4
|
+
* requires providing the corresponding item pool that the collectible is normally located in.
|
|
5
5
|
*
|
|
6
6
|
* - If any player currently has the collectible, then it is assumed to be unlocked. (This is
|
|
7
7
|
* because in almost all cases, when a collectible is added to a player's inventory, it is
|
|
@@ -12,11 +12,6 @@ import { CollectibleType, ItemPoolType } from "isaac-typescript-definitions";
|
|
|
12
12
|
* - If the collectible is non-offensive, any Tainted Losts will be temporarily changed to Isaac and
|
|
13
13
|
* then changed back. (This is because Tainted Lost is not able to retrieve non-offensive
|
|
14
14
|
* collectibles from item pools).
|
|
15
|
-
*
|
|
16
|
-
* Under the hood, this function works by using the `ItemPool.AddRoomBlacklist` method to blacklist
|
|
17
|
-
* every collectible except for the one provided. Unfortunately, this is not a general-purpose
|
|
18
|
-
* "isCollectibleInItemPool" algorithm, because when a pool is depleted, it will automatically pull
|
|
19
|
-
* items from the Treasure Room pool, and there is no way to distinguish when this happens.
|
|
20
15
|
*/
|
|
21
16
|
export declare function isCollectibleUnlocked(collectibleType: CollectibleType, itemPoolType: ItemPoolType): boolean;
|
|
22
17
|
//# sourceMappingURL=saveFile.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"saveFile.d.ts","sourceRoot":"","sources":["../../src/functions/saveFile.ts"],"names":[],"mappings":"AAAA,OAAO,
|
|
1
|
+
{"version":3,"file":"saveFile.d.ts","sourceRoot":"","sources":["../../src/functions/saveFile.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,YAAY,EAAE,MAAM,8BAA8B,CAAC;AAI7E;;;;;;;;;;;;;GAaG;AACH,wBAAgB,qBAAqB,CACnC,eAAe,EAAE,eAAe,EAChC,YAAY,EAAE,YAAY,GACzB,OAAO,CAMT"}
|
|
@@ -1,87 +1,10 @@
|
|
|
1
|
-
local ____lualib = require("lualib_bundle")
|
|
2
|
-
local Map = ____lualib.Map
|
|
3
|
-
local __TS__Iterator = ____lualib.__TS__Iterator
|
|
4
|
-
local __TS__New = ____lualib.__TS__New
|
|
5
1
|
local ____exports = {}
|
|
6
|
-
local
|
|
7
|
-
local
|
|
8
|
-
local CollectibleType = ____isaac_2Dtypescript_2Ddefinitions.CollectibleType
|
|
9
|
-
local ItemConfigTag = ____isaac_2Dtypescript_2Ddefinitions.ItemConfigTag
|
|
10
|
-
local PlayerType = ____isaac_2Dtypescript_2Ddefinitions.PlayerType
|
|
11
|
-
local TrinketType = ____isaac_2Dtypescript_2Ddefinitions.TrinketType
|
|
12
|
-
local ____cachedClasses = require("cachedClasses")
|
|
13
|
-
local game = ____cachedClasses.game
|
|
14
|
-
local ____collectibleSet = require("functions.collectibleSet")
|
|
15
|
-
local getCollectibleSet = ____collectibleSet.getCollectibleSet
|
|
16
|
-
local ____collectibleTag = require("functions.collectibleTag")
|
|
17
|
-
local collectibleHasTag = ____collectibleTag.collectibleHasTag
|
|
18
|
-
local ____playerDataStructures = require("functions.playerDataStructures")
|
|
19
|
-
local mapGetPlayer = ____playerDataStructures.mapGetPlayer
|
|
20
|
-
local mapSetPlayer = ____playerDataStructures.mapSetPlayer
|
|
21
|
-
local ____playerIndex = require("functions.playerIndex")
|
|
22
|
-
local getPlayers = ____playerIndex.getPlayers
|
|
2
|
+
local ____itemPool = require("functions.itemPool")
|
|
3
|
+
local isCollectibleInItemPool = ____itemPool.isCollectibleInItemPool
|
|
23
4
|
local ____players = require("functions.players")
|
|
24
5
|
local anyPlayerHasCollectible = ____players.anyPlayerHasCollectible
|
|
25
|
-
local getPlayersOfType = ____players.getPlayersOfType
|
|
26
|
-
local ____utils = require("functions.utils")
|
|
27
|
-
local ____repeat = ____utils["repeat"]
|
|
28
|
-
function removeItemsAndTrinketsThatAffectItemPools(self)
|
|
29
|
-
local removedItemsMap = __TS__New(Map)
|
|
30
|
-
local removedTrinketsMap = __TS__New(Map)
|
|
31
|
-
for ____, player in ipairs(getPlayers(nil)) do
|
|
32
|
-
local removedItems = {}
|
|
33
|
-
for ____, itemToRemove in ipairs(COLLECTIBLES_THAT_AFFECT_ITEM_POOLS) do
|
|
34
|
-
if player:HasCollectible(itemToRemove) then
|
|
35
|
-
local numCollectibles = player:GetCollectibleNum(itemToRemove)
|
|
36
|
-
____repeat(
|
|
37
|
-
nil,
|
|
38
|
-
numCollectibles,
|
|
39
|
-
function()
|
|
40
|
-
player:RemoveCollectible(itemToRemove)
|
|
41
|
-
removedItems[#removedItems + 1] = itemToRemove
|
|
42
|
-
end
|
|
43
|
-
)
|
|
44
|
-
end
|
|
45
|
-
end
|
|
46
|
-
mapSetPlayer(nil, removedItemsMap, player, removedItems)
|
|
47
|
-
local removedTrinkets = {}
|
|
48
|
-
for ____, trinketToRemove in ipairs(TRINKETS_THAT_AFFECT_ITEM_POOLS) do
|
|
49
|
-
if player:HasTrinket(trinketToRemove) then
|
|
50
|
-
local numTrinkets = player:GetTrinketMultiplier(trinketToRemove)
|
|
51
|
-
____repeat(
|
|
52
|
-
nil,
|
|
53
|
-
numTrinkets,
|
|
54
|
-
function()
|
|
55
|
-
player:TryRemoveTrinket(trinketToRemove)
|
|
56
|
-
removedTrinkets[#removedTrinkets + 1] = trinketToRemove
|
|
57
|
-
end
|
|
58
|
-
)
|
|
59
|
-
end
|
|
60
|
-
end
|
|
61
|
-
mapSetPlayer(nil, removedTrinketsMap, player, removedTrinkets)
|
|
62
|
-
end
|
|
63
|
-
return {removedItemsMap, removedTrinketsMap}
|
|
64
|
-
end
|
|
65
|
-
function restoreItemsAndTrinketsThatAffectItemPools(self, removedItemsMap, removedTrinketsMap)
|
|
66
|
-
for ____, player in ipairs(getPlayers(nil)) do
|
|
67
|
-
local removedItems = mapGetPlayer(nil, removedItemsMap, player)
|
|
68
|
-
if removedItems ~= nil then
|
|
69
|
-
for ____, collectibleType in ipairs(removedItems) do
|
|
70
|
-
player:AddCollectible(collectibleType, 0, false)
|
|
71
|
-
end
|
|
72
|
-
end
|
|
73
|
-
local removedTrinkets = mapGetPlayer(nil, removedTrinketsMap, player)
|
|
74
|
-
if removedTrinkets ~= nil then
|
|
75
|
-
for ____, trinketType in ipairs(removedTrinkets) do
|
|
76
|
-
player:AddTrinket(trinketType, false)
|
|
77
|
-
end
|
|
78
|
-
end
|
|
79
|
-
end
|
|
80
|
-
end
|
|
81
|
-
COLLECTIBLES_THAT_AFFECT_ITEM_POOLS = {CollectibleType.CHAOS, CollectibleType.SACRED_ORB, CollectibleType.TMTRAINER}
|
|
82
|
-
TRINKETS_THAT_AFFECT_ITEM_POOLS = {TrinketType.NO}
|
|
83
6
|
--- Helper function to see if the given collectible is unlocked on the current save file. This
|
|
84
|
-
-- requires providing the corresponding item pool that the collectible is located in.
|
|
7
|
+
-- requires providing the corresponding item pool that the collectible is normally located in.
|
|
85
8
|
--
|
|
86
9
|
-- - If any player currently has the collectible, then it is assumed to be unlocked. (This is
|
|
87
10
|
-- because in almost all cases, when a collectible is added to a player's inventory, it is
|
|
@@ -92,42 +15,10 @@ TRINKETS_THAT_AFFECT_ITEM_POOLS = {TrinketType.NO}
|
|
|
92
15
|
-- - If the collectible is non-offensive, any Tainted Losts will be temporarily changed to Isaac and
|
|
93
16
|
-- then changed back. (This is because Tainted Lost is not able to retrieve non-offensive
|
|
94
17
|
-- collectibles from item pools).
|
|
95
|
-
--
|
|
96
|
-
-- Under the hood, this function works by using the `ItemPool.AddRoomBlacklist` method to blacklist
|
|
97
|
-
-- every collectible except for the one provided. Unfortunately, this is not a general-purpose
|
|
98
|
-
-- "isCollectibleInItemPool" algorithm, because when a pool is depleted, it will automatically pull
|
|
99
|
-
-- items from the Treasure Room pool, and there is no way to distinguish when this happens.
|
|
100
18
|
function ____exports.isCollectibleUnlocked(self, collectibleType, itemPoolType)
|
|
101
19
|
if anyPlayerHasCollectible(nil, collectibleType) then
|
|
102
20
|
return true
|
|
103
21
|
end
|
|
104
|
-
|
|
105
|
-
local isOffensive = collectibleHasTag(nil, collectibleType, ItemConfigTag.OFFENSIVE)
|
|
106
|
-
local changedPlayerTypes = false
|
|
107
|
-
if not isOffensive then
|
|
108
|
-
changedPlayerTypes = true
|
|
109
|
-
for ____, player in ipairs(taintedLosts) do
|
|
110
|
-
player:ChangePlayerType(PlayerType.ISAAC)
|
|
111
|
-
end
|
|
112
|
-
end
|
|
113
|
-
local removedItemsMap, removedTrinketsMap = table.unpack(removeItemsAndTrinketsThatAffectItemPools(nil))
|
|
114
|
-
local itemPool = game:GetItemPool()
|
|
115
|
-
local collectibleSet = getCollectibleSet(nil)
|
|
116
|
-
for ____, collectibleTypeInSet in __TS__Iterator(collectibleSet:values()) do
|
|
117
|
-
if collectibleTypeInSet ~= collectibleType then
|
|
118
|
-
itemPool:AddRoomBlacklist(collectibleTypeInSet)
|
|
119
|
-
end
|
|
120
|
-
end
|
|
121
|
-
local seed = 1
|
|
122
|
-
local retrievedCollectibleType = itemPool:GetCollectible(itemPoolType, false, seed)
|
|
123
|
-
local collectibleUnlocked = retrievedCollectibleType == collectibleType
|
|
124
|
-
itemPool:ResetRoomBlacklist()
|
|
125
|
-
restoreItemsAndTrinketsThatAffectItemPools(nil, removedItemsMap, removedTrinketsMap)
|
|
126
|
-
if changedPlayerTypes then
|
|
127
|
-
for ____, player in ipairs(taintedLosts) do
|
|
128
|
-
player:ChangePlayerType(PlayerType.THE_LOST_B)
|
|
129
|
-
end
|
|
130
|
-
end
|
|
131
|
-
return collectibleUnlocked
|
|
22
|
+
return isCollectibleInItemPool(nil, collectibleType, itemPoolType)
|
|
132
23
|
end
|
|
133
24
|
return ____exports
|
package/dist/index.d.ts
CHANGED
|
@@ -74,6 +74,7 @@ export * from "./functions/gridEntities";
|
|
|
74
74
|
export * from "./functions/gridEntitiesSpecific";
|
|
75
75
|
export * from "./functions/input";
|
|
76
76
|
export * from "./functions/isaacAPIClass";
|
|
77
|
+
export * from "./functions/itemPool";
|
|
77
78
|
export * from "./functions/jsonHelpers";
|
|
78
79
|
export * from "./functions/jsonRoom";
|
|
79
80
|
export * from "./functions/kColor";
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,iBAAiB,CAAC;AAChC,OAAO,EACL,cAAc,EACd,eAAe,GAChB,MAAM,iCAAiC,CAAC;AACzC,OAAO,EACL,qBAAqB,EACrB,oBAAoB,EACpB,0BAA0B,GAC3B,MAAM,gCAAgC,CAAC;AACxC,cAAc,sBAAsB,CAAC;AACrC,cAAc,uBAAuB,CAAC;AACtC,cAAc,aAAa,CAAC;AAC5B,cAAc,sBAAsB,CAAC;AACrC,cAAc,oBAAoB,CAAC;AACnC,cAAc,2BAA2B,CAAC;AAC1C,cAAc,wBAAwB,CAAC;AACvC,cAAc,2BAA2B,CAAC;AAC1C,OAAO,EACL,sBAAsB,EACtB,iCAAiC,GAClC,MAAM,sCAAsC,CAAC;AAC9C,OAAO,EAAE,sBAAsB,EAAE,MAAM,2BAA2B,CAAC;AACnE,OAAO,EAAE,0BAA0B,EAAE,MAAM,oCAAoC,CAAC;AAChF,OAAO,EACL,sBAAsB,IAAI,gBAAgB,EAC1C,qBAAqB,IAAI,eAAe,GACzC,MAAM,6BAA6B,CAAC;AACrC,cAAc,gCAAgC,CAAC;AAC/C,cAAc,mCAAmC,CAAC;AAClD,cAAc,iCAAiC,CAAC;AAChD,OAAO,EACL,cAAc,EACd,oBAAoB,EACpB,SAAS,GACV,MAAM,2BAA2B,CAAC;AACnC,OAAO,EAAE,eAAe,EAAE,cAAc,EAAE,MAAM,4BAA4B,CAAC;AAC7E,OAAO,EACL,gBAAgB,EAChB,yBAAyB,EACzB,qBAAqB,EACrB,qBAAqB,EACrB,eAAe,EACf,wBAAwB,GACzB,MAAM,0BAA0B,CAAC;AAClC,cAAc,yCAAyC,CAAC;AACxD,OAAO,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,0BAA0B,CAAC;AACvE,OAAO,EAAE,gBAAgB,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAC;AACzE,OAAO,EAAE,eAAe,EAAE,MAAM,4BAA4B,CAAC;AAC7D,OAAO,EAAE,KAAK,EAAE,OAAO,EAAE,MAAM,kBAAkB,CAAC;AAClD,OAAO,EACL,sBAAsB,EACtB,qBAAqB,GACtB,MAAM,+BAA+B,CAAC;AACvC,cAAc,wBAAwB,CAAC;AACvC,OAAO,EAAE,kBAAkB,EAAE,MAAM,4BAA4B,CAAC;AAChE,OAAO,EACL,kBAAkB,EAClB,iBAAiB,GAClB,MAAM,0BAA0B,CAAC;AAClC,OAAO,EAAE,0BAA0B,EAAE,MAAM,uCAAuC,CAAC;AACnF,OAAO,EAAE,cAAc,EAAE,gBAAgB,EAAE,MAAM,2BAA2B,CAAC;AAC7E,OAAO,EACL,qBAAqB,EACrB,qBAAqB,GACtB,MAAM,2BAA2B,CAAC;AACnC,cAAc,wBAAwB,CAAC;AACvC,OAAO,EACL,gBAAgB,EAChB,kBAAkB,EAClB,gBAAgB,EAChB,kBAAkB,EAClB,qBAAqB,EACrB,uBAAuB,GACxB,MAAM,yBAAyB,CAAC;AACjC,cAAc,oCAAoC,CAAC;AACnD,OAAO,EACL,sBAAsB,EACtB,uBAAuB,GACxB,MAAM,yBAAyB,CAAC;AACjC,OAAO,EAAE,eAAe,EAAE,eAAe,EAAE,MAAM,yBAAyB,CAAC;AAC3E,OAAO,EAAE,0BAA0B,EAAE,MAAM,kCAAkC,CAAC;AAC9E,cAAc,oBAAoB,CAAC;AACnC,cAAc,mBAAmB,CAAC;AAClC,cAAc,uBAAuB,CAAC;AACtC,cAAc,qBAAqB,CAAC;AACpC,cAAc,mBAAmB,CAAC;AAClC,cAAc,oBAAoB,CAAC;AACnC,cAAc,uBAAuB,CAAC;AACtC,cAAc,mBAAmB,CAAC;AAClC,cAAc,wBAAwB,CAAC;AACvC,cAAc,wBAAwB,CAAC;AACvC,cAAc,oBAAoB,CAAC;AACnC,cAAc,uBAAuB,CAAC;AACtC,cAAc,kCAAkC,CAAC;AACjD,cAAc,0BAA0B,CAAC;AACzC,cAAc,4BAA4B,CAAC;AAC3C,cAAc,4BAA4B,CAAC;AAC3C,cAAc,mBAAmB,CAAC;AAClC,cAAc,mBAAmB,CAAC;AAClC,cAAc,sBAAsB,CAAC;AACrC,cAAc,2BAA2B,CAAC;AAC1C,cAAc,uBAAuB,CAAC;AACtC,cAAc,mBAAmB,CAAC;AAClC,cAAc,oBAAoB,CAAC;AACnC,cAAc,kBAAkB,CAAC;AACjC,cAAc,qBAAqB,CAAC;AACpC,cAAc,sBAAsB,CAAC;AACrC,cAAc,8BAA8B,CAAC;AAC7C,cAAc,yBAAyB,CAAC;AACxC,cAAc,mBAAmB,CAAC;AAClC,cAAc,uBAAuB,CAAC;AACtC,cAAc,kBAAkB,CAAC;AACjC,cAAc,oBAAoB,CAAC;AACnC,cAAc,qBAAqB,CAAC;AACpC,cAAc,0BAA0B,CAAC;AACzC,cAAc,kCAAkC,CAAC;AACjD,cAAc,mBAAmB,CAAC;AAClC,cAAc,2BAA2B,CAAC;AAC1C,cAAc,yBAAyB,CAAC;AACxC,cAAc,sBAAsB,CAAC;AACrC,cAAc,oBAAoB,CAAC;AACnC,cAAc,sBAAsB,CAAC;AACrC,cAAc,mBAAmB,CAAC;AAClC,cAAc,iBAAiB,CAAC;AAChC,cAAc,iBAAiB,CAAC;AAChC,cAAc,kBAAkB,CAAC;AACjC,cAAc,wBAAwB,CAAC;AACvC,cAAc,qBAAqB,CAAC;AACpC,cAAc,uBAAuB,CAAC;AACtC,cAAc,kBAAkB,CAAC;AACjC,cAAc,qBAAqB,CAAC;AACpC,cAAc,6BAA6B,CAAC;AAC5C,cAAc,4BAA4B,CAAC;AAC3C,cAAc,mBAAmB,CAAC;AAClC,cAAc,0BAA0B,CAAC;AACzC,cAAc,kCAAkC,CAAC;AACjD,cAAc,0BAA0B,CAAC;AACzC,cAAc,yBAAyB,CAAC;AACxC,cAAc,qBAAqB,CAAC;AACpC,cAAc,yBAAyB,CAAC;AACxC,cAAc,8BAA8B,CAAC;AAC7C,cAAc,2BAA2B,CAAC;AAC1C,cAAc,yBAAyB,CAAC;AACxC,cAAc,oBAAoB,CAAC;AACnC,cAAc,oBAAoB,CAAC;AACnC,cAAc,iBAAiB,CAAC;AAChC,cAAc,qBAAqB,CAAC;AACpC,cAAc,sBAAsB,CAAC;AACrC,cAAc,sBAAsB,CAAC;AACrC,cAAc,mBAAmB,CAAC;AAClC,cAAc,uBAAuB,CAAC;AACtC,cAAc,iBAAiB,CAAC;AAChC,cAAc,sBAAsB,CAAC;AACrC,cAAc,mBAAmB,CAAC;AAClC,cAAc,2BAA2B,CAAC;AAC1C,cAAc,iBAAiB,CAAC;AAChC,cAAc,mBAAmB,CAAC;AAClC,cAAc,8BAA8B,CAAC;AAC7C,cAAc,qBAAqB,CAAC;AACpC,cAAc,mBAAmB,CAAC;AAClC,cAAc,oBAAoB,CAAC;AACnC,cAAc,mBAAmB,CAAC;AAClC,cAAc,mBAAmB,CAAC;AAClC,cAAc,6BAA6B,CAAC;AAC5C,cAAc,8BAA8B,CAAC;AAC7C,cAAc,yBAAyB,CAAC;AACxC,cAAc,sBAAsB,CAAC;AACrC,cAAc,uBAAuB,CAAC;AACtC,cAAc,mBAAmB,CAAC;AAClC,cAAc,gBAAgB,CAAC;AAC/B,cAAc,mBAAmB,CAAC;AAClC,cAAc,oBAAoB,CAAC;AACnC,cAAc,yCAAyC,CAAC;AACxD,cAAc,+BAA+B,CAAC;AAC9C,cAAc,4BAA4B,CAAC;AAC3C,cAAc,2BAA2B,CAAC;AAC1C,cAAc,oCAAoC,CAAC;AACnD,cAAc,uBAAuB,CAAC;AACtC,cAAc,+BAA+B,CAAC;AAC9C,cAAc,gBAAgB,CAAC;AAC/B,cAAc,qBAAqB,CAAC;AACpC,cAAc,sBAAsB,CAAC;AACrC,cAAc,oBAAoB,CAAC;AACnC,cAAc,kBAAkB,CAAC;AACjC,cAAc,mBAAmB,CAAC;AAClC,cAAc,0BAA0B,CAAC;AACzC,cAAc,uBAAuB,CAAC;AACtC,cAAc,qBAAqB,CAAC;AACpC,cAAc,cAAc,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
package/dist/index.lua
CHANGED
|
@@ -590,6 +590,14 @@ do
|
|
|
590
590
|
end
|
|
591
591
|
end
|
|
592
592
|
end
|
|
593
|
+
do
|
|
594
|
+
local ____export = require("functions.itemPool")
|
|
595
|
+
for ____exportKey, ____exportValue in pairs(____export) do
|
|
596
|
+
if ____exportKey ~= "default" then
|
|
597
|
+
____exports[____exportKey] = ____exportValue
|
|
598
|
+
end
|
|
599
|
+
end
|
|
600
|
+
end
|
|
593
601
|
do
|
|
594
602
|
local ____export = require("functions.jsonHelpers")
|
|
595
603
|
for ____exportKey, ____exportValue in pairs(____export) do
|
package/package.json
CHANGED
|
@@ -5,7 +5,7 @@ import { ModCallbackCustom } from "../enums/ModCallbackCustom";
|
|
|
5
5
|
import { errorIfFeaturesNotInitialized } from "../featuresInitialized";
|
|
6
6
|
import { arrayRemoveInPlace, copyArray } from "../functions/array";
|
|
7
7
|
import { isActiveCollectible } from "../functions/collectibles";
|
|
8
|
-
import {
|
|
8
|
+
import { getCollectibleArray } from "../functions/collectibleSet";
|
|
9
9
|
import {
|
|
10
10
|
defaultMapGetPlayer,
|
|
11
11
|
mapSetPlayer,
|
|
@@ -30,8 +30,7 @@ const v = {
|
|
|
30
30
|
function newPlayerInventory(player: EntityPlayer) {
|
|
31
31
|
const inventory: CollectibleType[] = [];
|
|
32
32
|
|
|
33
|
-
const
|
|
34
|
-
for (const collectibleType of collectibleSet.values()) {
|
|
33
|
+
for (const collectibleType of getCollectibleArray()) {
|
|
35
34
|
const numCollectibles = player.GetCollectibleNum(collectibleType, true);
|
|
36
35
|
repeat(numCollectibles, () => {
|
|
37
36
|
inventory.push(collectibleType);
|
package/src/functions/eden.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { CollectibleType, ItemConfigTag } from "isaac-typescript-definitions";
|
|
2
2
|
import { isHiddenCollectible, isPassiveCollectible } from "./collectibles";
|
|
3
|
-
import {
|
|
3
|
+
import { getCollectibleArray } from "./collectibleSet";
|
|
4
4
|
import { collectibleHasTag } from "./collectibleTag";
|
|
5
5
|
import { getRandomSeed } from "./rng";
|
|
6
6
|
import { copySet, getRandomSetElement } from "./set";
|
|
@@ -8,9 +8,7 @@ import { copySet, getRandomSetElement } from "./set";
|
|
|
8
8
|
const EDEN_PASSIVE_COLLECTIBLES_SET = new Set<CollectibleType>();
|
|
9
9
|
|
|
10
10
|
function initCollectibleSet() {
|
|
11
|
-
const
|
|
12
|
-
|
|
13
|
-
for (const collectibleType of collectibleSet.values()) {
|
|
11
|
+
for (const collectibleType of getCollectibleArray()) {
|
|
14
12
|
if (
|
|
15
13
|
isPassiveCollectible(collectibleType) &&
|
|
16
14
|
!isHiddenCollectible(collectibleType) &&
|
|
@@ -0,0 +1,178 @@
|
|
|
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 { getCollectibleArray } 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
|
+
const COLLECTIBLE_TYPE_THAT_IS_NOT_IN_ANY_POOLS = CollectibleType.KEY_PIECE_1;
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* Helper function to get the remaining collectibles in a given item pool. This function is
|
|
31
|
+
* expensive, so only use it in situations where the lag is acceptable.
|
|
32
|
+
*/
|
|
33
|
+
export function getCollectiblesInItemPool(
|
|
34
|
+
itemPoolType: ItemPoolType,
|
|
35
|
+
): CollectibleType[] {
|
|
36
|
+
const collectibleArray = getCollectibleArray();
|
|
37
|
+
return collectibleArray.filter((collectibleType) =>
|
|
38
|
+
isCollectibleInItemPool(collectibleType, itemPoolType),
|
|
39
|
+
);
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* Helper function to see if the given collectible is still present in the given item pool.
|
|
44
|
+
*
|
|
45
|
+
* If the collectible is non-offensive, any Tainted Losts will be temporarily changed to Isaac and
|
|
46
|
+
* then changed back. (This is because Tainted Lost is not able to retrieve non-offensive
|
|
47
|
+
* collectibles from item pools).
|
|
48
|
+
*
|
|
49
|
+
* Under the hood, this function works by using the `ItemPool.AddRoomBlacklist` method to blacklist
|
|
50
|
+
* every collectible except for the one provided.
|
|
51
|
+
*/
|
|
52
|
+
export function isCollectibleInItemPool(
|
|
53
|
+
collectibleType: CollectibleType,
|
|
54
|
+
itemPoolType: ItemPoolType,
|
|
55
|
+
): boolean {
|
|
56
|
+
// We use a specific collectible which is known to not be in any pools as a default value. Thus,
|
|
57
|
+
// we must explicitly handle this case.
|
|
58
|
+
if (collectibleType === COLLECTIBLE_TYPE_THAT_IS_NOT_IN_ANY_POOLS) {
|
|
59
|
+
return false;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
// On Tainted Lost, it is impossible to retrieve non-offensive collectibles from pools, so we
|
|
63
|
+
// temporarily change the character to Isaac.
|
|
64
|
+
const taintedLosts = getPlayersOfType(PlayerType.THE_LOST_B);
|
|
65
|
+
const isOffensive = collectibleHasTag(
|
|
66
|
+
collectibleType,
|
|
67
|
+
ItemConfigTag.OFFENSIVE,
|
|
68
|
+
);
|
|
69
|
+
let changedPlayerTypes = false;
|
|
70
|
+
if (!isOffensive) {
|
|
71
|
+
changedPlayerTypes = true;
|
|
72
|
+
for (const player of taintedLosts) {
|
|
73
|
+
player.ChangePlayerType(PlayerType.ISAAC);
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
const [removedItemsMap, removedTrinketsMap] =
|
|
78
|
+
removeItemsAndTrinketsThatAffectItemPools();
|
|
79
|
+
|
|
80
|
+
// Blacklist every collectible in the game except for the provided collectible.
|
|
81
|
+
const itemPool = game.GetItemPool();
|
|
82
|
+
itemPool.ResetRoomBlacklist();
|
|
83
|
+
for (const collectibleTypeInSet of getCollectibleArray()) {
|
|
84
|
+
if (collectibleTypeInSet !== collectibleType) {
|
|
85
|
+
itemPool.AddRoomBlacklist(collectibleTypeInSet);
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
// Get a collectible from the pool and see if it is the intended collectible. (We can use any
|
|
90
|
+
// arbitrary value as the seed since it should not influence the result.)
|
|
91
|
+
const seed = 1 as Seed;
|
|
92
|
+
const retrievedCollectibleType = itemPool.GetCollectible(
|
|
93
|
+
itemPoolType,
|
|
94
|
+
false,
|
|
95
|
+
seed,
|
|
96
|
+
COLLECTIBLE_TYPE_THAT_IS_NOT_IN_ANY_POOLS,
|
|
97
|
+
);
|
|
98
|
+
const collectibleUnlocked = retrievedCollectibleType === collectibleType;
|
|
99
|
+
|
|
100
|
+
// Reset the blacklist
|
|
101
|
+
itemPool.ResetRoomBlacklist();
|
|
102
|
+
|
|
103
|
+
restoreItemsAndTrinketsThatAffectItemPools(
|
|
104
|
+
removedItemsMap,
|
|
105
|
+
removedTrinketsMap,
|
|
106
|
+
);
|
|
107
|
+
|
|
108
|
+
// Change any players back to Tainted Lost, if necessary.
|
|
109
|
+
if (changedPlayerTypes) {
|
|
110
|
+
for (const player of taintedLosts) {
|
|
111
|
+
player.ChangePlayerType(PlayerType.THE_LOST_B);
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
return collectibleUnlocked;
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
/**
|
|
119
|
+
* Before checking the item pools, remove any collectibles or trinkets that would affect the
|
|
120
|
+
* retrieved collectible types.
|
|
121
|
+
*/
|
|
122
|
+
function removeItemsAndTrinketsThatAffectItemPools(): [
|
|
123
|
+
removedItemsMap: Map<PlayerIndex, CollectibleType[]>,
|
|
124
|
+
removedTrinketsMap: Map<PlayerIndex, TrinketType[]>,
|
|
125
|
+
] {
|
|
126
|
+
const removedItemsMap = new Map<PlayerIndex, CollectibleType[]>();
|
|
127
|
+
const removedTrinketsMap = new Map<PlayerIndex, TrinketType[]>();
|
|
128
|
+
for (const player of getPlayers()) {
|
|
129
|
+
const removedItems: CollectibleType[] = [];
|
|
130
|
+
for (const itemToRemove of COLLECTIBLES_THAT_AFFECT_ITEM_POOLS) {
|
|
131
|
+
if (player.HasCollectible(itemToRemove)) {
|
|
132
|
+
const numCollectibles = player.GetCollectibleNum(itemToRemove);
|
|
133
|
+
repeat(numCollectibles, () => {
|
|
134
|
+
player.RemoveCollectible(itemToRemove);
|
|
135
|
+
removedItems.push(itemToRemove);
|
|
136
|
+
});
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
mapSetPlayer(removedItemsMap, player, removedItems);
|
|
141
|
+
|
|
142
|
+
const removedTrinkets: TrinketType[] = [];
|
|
143
|
+
for (const trinketToRemove of TRINKETS_THAT_AFFECT_ITEM_POOLS) {
|
|
144
|
+
if (player.HasTrinket(trinketToRemove)) {
|
|
145
|
+
const numTrinkets = player.GetTrinketMultiplier(trinketToRemove);
|
|
146
|
+
repeat(numTrinkets, () => {
|
|
147
|
+
player.TryRemoveTrinket(trinketToRemove);
|
|
148
|
+
removedTrinkets.push(trinketToRemove);
|
|
149
|
+
});
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
mapSetPlayer(removedTrinketsMap, player, removedTrinkets);
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
return [removedItemsMap, removedTrinketsMap];
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
function restoreItemsAndTrinketsThatAffectItemPools(
|
|
160
|
+
removedItemsMap: Map<PlayerIndex, CollectibleType[]>,
|
|
161
|
+
removedTrinketsMap: Map<PlayerIndex, TrinketType[]>,
|
|
162
|
+
) {
|
|
163
|
+
for (const player of getPlayers()) {
|
|
164
|
+
const removedItems = mapGetPlayer(removedItemsMap, player);
|
|
165
|
+
if (removedItems !== undefined) {
|
|
166
|
+
for (const collectibleType of removedItems) {
|
|
167
|
+
player.AddCollectible(collectibleType, 0, false); // Prevent Chaos from spawning pickups
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
const removedTrinkets = mapGetPlayer(removedTrinketsMap, player);
|
|
172
|
+
if (removedTrinkets !== undefined) {
|
|
173
|
+
for (const trinketType of removedTrinkets) {
|
|
174
|
+
player.AddTrinket(trinketType, false);
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
}
|
package/src/functions/rockAlt.ts
CHANGED
|
@@ -5,6 +5,7 @@ import {
|
|
|
5
5
|
EffectVariant,
|
|
6
6
|
EntityType,
|
|
7
7
|
HeartSubType,
|
|
8
|
+
ItemPoolType,
|
|
8
9
|
PillColor,
|
|
9
10
|
RoomType,
|
|
10
11
|
TrinketType,
|
|
@@ -14,6 +15,7 @@ import { DISTANCE_OF_GRID_TILE } from "../constants";
|
|
|
14
15
|
import { RockAltType } from "../enums/RockAltType";
|
|
15
16
|
import { BACKDROP_TYPE_TO_ROCK_ALT_TYPE } from "../objects/backdropTypeToRockAltType";
|
|
16
17
|
import { spawnEffectWithSeed, spawnNPCWithSeed } from "./entitiesSpecific";
|
|
18
|
+
import { isCollectibleInItemPool } from "./itemPool";
|
|
17
19
|
import {
|
|
18
20
|
spawnCardWithSeed,
|
|
19
21
|
spawnCoinWithSeed,
|
|
@@ -69,10 +71,10 @@ export function getRockAltType(): RockAltType {
|
|
|
69
71
|
* Most of the time, this function will do nothing, similar to how most of the time, when an
|
|
70
72
|
* individual urn is destroyed, nothing will spawn.
|
|
71
73
|
*
|
|
72
|
-
* Note that in vanilla,
|
|
73
|
-
*
|
|
74
|
-
*
|
|
75
|
-
*
|
|
74
|
+
* Note that in vanilla, trinkets will not spawn if they have already been removed from the trinket
|
|
75
|
+
* pool. This function cannot replicate that behavior because there is no way to check to see if a
|
|
76
|
+
* trinket is still in the pool. Thus, it will always have a chance to spawn the respective trinket
|
|
77
|
+
* (e.g. Swallowed Penny from urns).
|
|
76
78
|
*
|
|
77
79
|
* The logic in this function is based on the rewards listed on the wiki:
|
|
78
80
|
* https://bindingofisaacrebirth.fandom.com/wiki/Rocks
|
|
@@ -150,8 +152,16 @@ function spawnRockAltRewardUrn(position: Vector, rng: RNG): boolean {
|
|
|
150
152
|
|
|
151
153
|
totalChance += ROCK_ALT_CHANCES.COLLECTIBLE;
|
|
152
154
|
if (chance < totalChance) {
|
|
153
|
-
|
|
154
|
-
|
|
155
|
+
const stillInPools = isCollectibleInItemPool(
|
|
156
|
+
CollectibleType.QUARTER,
|
|
157
|
+
ItemPoolType.DEVIL,
|
|
158
|
+
);
|
|
159
|
+
if (stillInPools) {
|
|
160
|
+
spawnCollectible(CollectibleType.QUARTER, position, rng);
|
|
161
|
+
return true;
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
return false;
|
|
155
165
|
}
|
|
156
166
|
|
|
157
167
|
// Since the detrimental effect is the final option, we don't need to check the chance.
|
|
@@ -196,18 +206,46 @@ function spawnRockAltRewardMushroom(position: Vector, rng: RNG): boolean {
|
|
|
196
206
|
if (roomType === RoomType.SECRET) {
|
|
197
207
|
const wavyCapChance = getRandom(rng);
|
|
198
208
|
if (wavyCapChance < 0.0272) {
|
|
199
|
-
|
|
200
|
-
|
|
209
|
+
const stillInPools = isCollectibleInItemPool(
|
|
210
|
+
CollectibleType.WAVY_CAP,
|
|
211
|
+
ItemPoolType.SECRET,
|
|
212
|
+
);
|
|
213
|
+
if (stillInPools) {
|
|
214
|
+
spawnCollectible(CollectibleType.WAVY_CAP, position, rng);
|
|
215
|
+
return true;
|
|
216
|
+
}
|
|
201
217
|
}
|
|
202
218
|
}
|
|
203
219
|
|
|
204
|
-
const
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
220
|
+
const magicMushroomStillInPools = isCollectibleInItemPool(
|
|
221
|
+
CollectibleType.MAGIC_MUSHROOM,
|
|
222
|
+
ItemPoolType.TREASURE,
|
|
223
|
+
);
|
|
224
|
+
const miniMushStillInPools = isCollectibleInItemPool(
|
|
225
|
+
CollectibleType.MINI_MUSH,
|
|
226
|
+
ItemPoolType.TREASURE,
|
|
227
|
+
);
|
|
228
|
+
if (magicMushroomStillInPools && miniMushStillInPools) {
|
|
229
|
+
const collectibleChance = getRandom(rng);
|
|
230
|
+
const collectibleType =
|
|
231
|
+
collectibleChance < 0.5
|
|
232
|
+
? CollectibleType.MAGIC_MUSHROOM // 12
|
|
233
|
+
: CollectibleType.MINI_MUSH; // 71
|
|
234
|
+
spawnCollectible(collectibleType, position, rng);
|
|
235
|
+
return true;
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
if (magicMushroomStillInPools) {
|
|
239
|
+
spawnCollectible(CollectibleType.MINI_MUSH, position, rng);
|
|
240
|
+
return true;
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
if (miniMushStillInPools) {
|
|
244
|
+
spawnCollectible(CollectibleType.MAGIC_MUSHROOM, position, rng);
|
|
245
|
+
return true;
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
return false;
|
|
211
249
|
}
|
|
212
250
|
|
|
213
251
|
// Since the detrimental effect is the final option, we don't need to check the chance.
|
|
@@ -238,13 +276,35 @@ function spawnRockAltRewardSkull(position: Vector, rng: RNG): boolean {
|
|
|
238
276
|
|
|
239
277
|
totalChance += ROCK_ALT_CHANCES.COLLECTIBLE;
|
|
240
278
|
if (chance < totalChance) {
|
|
241
|
-
const
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
279
|
+
const ghostBabyStillInPools = isCollectibleInItemPool(
|
|
280
|
+
CollectibleType.GHOST_BABY,
|
|
281
|
+
ItemPoolType.TREASURE,
|
|
282
|
+
);
|
|
283
|
+
const dryBabyStillInPools = isCollectibleInItemPool(
|
|
284
|
+
CollectibleType.DRY_BABY,
|
|
285
|
+
ItemPoolType.TREASURE,
|
|
286
|
+
);
|
|
287
|
+
if (ghostBabyStillInPools && dryBabyStillInPools) {
|
|
288
|
+
const collectibleChance = getRandom(rng);
|
|
289
|
+
const collectibleType =
|
|
290
|
+
collectibleChance < 0.5
|
|
291
|
+
? CollectibleType.GHOST_BABY // 163
|
|
292
|
+
: CollectibleType.DRY_BABY; // 265
|
|
293
|
+
spawnCollectible(collectibleType, position, rng);
|
|
294
|
+
return true;
|
|
295
|
+
}
|
|
296
|
+
|
|
297
|
+
if (ghostBabyStillInPools) {
|
|
298
|
+
spawnCollectible(CollectibleType.DRY_BABY, position, rng);
|
|
299
|
+
return true;
|
|
300
|
+
}
|
|
301
|
+
|
|
302
|
+
if (dryBabyStillInPools) {
|
|
303
|
+
spawnCollectible(CollectibleType.GHOST_BABY, position, rng);
|
|
304
|
+
return true;
|
|
305
|
+
}
|
|
306
|
+
|
|
307
|
+
return false;
|
|
248
308
|
}
|
|
249
309
|
|
|
250
310
|
// Since the detrimental effect is the final option, we don't need to check the chance.
|
|
@@ -275,13 +335,35 @@ function spawnRockAltRewardPolyp(position: Vector, rng: RNG): boolean {
|
|
|
275
335
|
|
|
276
336
|
totalChance += ROCK_ALT_CHANCES.COLLECTIBLE;
|
|
277
337
|
if (chance < totalChance) {
|
|
278
|
-
const
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
338
|
+
const placentaStillInPools = isCollectibleInItemPool(
|
|
339
|
+
CollectibleType.PLACENTA,
|
|
340
|
+
ItemPoolType.BOSS,
|
|
341
|
+
);
|
|
342
|
+
const bloodClotStillInPools = isCollectibleInItemPool(
|
|
343
|
+
CollectibleType.BLOOD_CLOT,
|
|
344
|
+
ItemPoolType.BOSS,
|
|
345
|
+
);
|
|
346
|
+
if (bloodClotStillInPools && placentaStillInPools) {
|
|
347
|
+
const collectibleChance = getRandom(rng);
|
|
348
|
+
const collectibleType =
|
|
349
|
+
collectibleChance < 0.5
|
|
350
|
+
? CollectibleType.PLACENTA // 218
|
|
351
|
+
: CollectibleType.BLOOD_CLOT; // 254
|
|
352
|
+
spawnCollectible(collectibleType, position, rng);
|
|
353
|
+
return true;
|
|
354
|
+
}
|
|
355
|
+
|
|
356
|
+
if (bloodClotStillInPools) {
|
|
357
|
+
spawnCollectible(CollectibleType.MINI_MUSH, position, rng);
|
|
358
|
+
return true;
|
|
359
|
+
}
|
|
360
|
+
|
|
361
|
+
if (placentaStillInPools) {
|
|
362
|
+
spawnCollectible(CollectibleType.MAGIC_MUSHROOM, position, rng);
|
|
363
|
+
return true;
|
|
364
|
+
}
|
|
365
|
+
|
|
366
|
+
return false;
|
|
285
367
|
}
|
|
286
368
|
|
|
287
369
|
// Since the detrimental effect is the final option, we don't need to check the chance.
|
|
@@ -1,32 +1,10 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
3
|
-
|
|
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 { anyPlayerHasCollectible, 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
|
-
];
|
|
1
|
+
import { CollectibleType, ItemPoolType } from "isaac-typescript-definitions";
|
|
2
|
+
import { isCollectibleInItemPool } from "./itemPool";
|
|
3
|
+
import { anyPlayerHasCollectible } from "./players";
|
|
26
4
|
|
|
27
5
|
/**
|
|
28
6
|
* Helper function to see if the given collectible is unlocked on the current save file. This
|
|
29
|
-
* requires providing the corresponding item pool that the collectible is located in.
|
|
7
|
+
* requires providing the corresponding item pool that the collectible is normally located in.
|
|
30
8
|
*
|
|
31
9
|
* - If any player currently has the collectible, then it is assumed to be unlocked. (This is
|
|
32
10
|
* because in almost all cases, when a collectible is added to a player's inventory, it is
|
|
@@ -37,11 +15,6 @@ const TRINKETS_THAT_AFFECT_ITEM_POOLS: readonly TrinketType[] = [
|
|
|
37
15
|
* - If the collectible is non-offensive, any Tainted Losts will be temporarily changed to Isaac and
|
|
38
16
|
* then changed back. (This is because Tainted Lost is not able to retrieve non-offensive
|
|
39
17
|
* collectibles from item pools).
|
|
40
|
-
*
|
|
41
|
-
* Under the hood, this function works by using the `ItemPool.AddRoomBlacklist` method to blacklist
|
|
42
|
-
* every collectible except for the one provided. Unfortunately, this is not a general-purpose
|
|
43
|
-
* "isCollectibleInItemPool" algorithm, because when a pool is depleted, it will automatically pull
|
|
44
|
-
* items from the Treasure Room pool, and there is no way to distinguish when this happens.
|
|
45
18
|
*/
|
|
46
19
|
export function isCollectibleUnlocked(
|
|
47
20
|
collectibleType: CollectibleType,
|
|
@@ -51,120 +24,5 @@ export function isCollectibleUnlocked(
|
|
|
51
24
|
return true;
|
|
52
25
|
}
|
|
53
26
|
|
|
54
|
-
|
|
55
|
-
// temporarily change the character to Isaac.
|
|
56
|
-
const taintedLosts = getPlayersOfType(PlayerType.THE_LOST_B);
|
|
57
|
-
const isOffensive = collectibleHasTag(
|
|
58
|
-
collectibleType,
|
|
59
|
-
ItemConfigTag.OFFENSIVE,
|
|
60
|
-
);
|
|
61
|
-
let changedPlayerTypes = false;
|
|
62
|
-
if (!isOffensive) {
|
|
63
|
-
changedPlayerTypes = true;
|
|
64
|
-
for (const player of taintedLosts) {
|
|
65
|
-
player.ChangePlayerType(PlayerType.ISAAC);
|
|
66
|
-
}
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
const [removedItemsMap, removedTrinketsMap] =
|
|
70
|
-
removeItemsAndTrinketsThatAffectItemPools();
|
|
71
|
-
|
|
72
|
-
// Blacklist every collectible in the game except for the provided collectible.
|
|
73
|
-
const itemPool = game.GetItemPool();
|
|
74
|
-
const collectibleSet = getCollectibleSet();
|
|
75
|
-
for (const collectibleTypeInSet of collectibleSet.values()) {
|
|
76
|
-
if (collectibleTypeInSet !== collectibleType) {
|
|
77
|
-
itemPool.AddRoomBlacklist(collectibleTypeInSet);
|
|
78
|
-
}
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
// Get a collectible from the pool and see if it is the intended collectible. (We can use any
|
|
82
|
-
// arbitrary value as the seed since it should not influence the result.)
|
|
83
|
-
const seed = 1 as Seed;
|
|
84
|
-
const retrievedCollectibleType = itemPool.GetCollectible(
|
|
85
|
-
itemPoolType,
|
|
86
|
-
false,
|
|
87
|
-
seed,
|
|
88
|
-
);
|
|
89
|
-
|
|
90
|
-
const collectibleUnlocked = retrievedCollectibleType === collectibleType;
|
|
91
|
-
|
|
92
|
-
// Reset the blacklist
|
|
93
|
-
itemPool.ResetRoomBlacklist();
|
|
94
|
-
|
|
95
|
-
restoreItemsAndTrinketsThatAffectItemPools(
|
|
96
|
-
removedItemsMap,
|
|
97
|
-
removedTrinketsMap,
|
|
98
|
-
);
|
|
99
|
-
|
|
100
|
-
// Change any players back to Tainted Lost, if necessary.
|
|
101
|
-
if (changedPlayerTypes) {
|
|
102
|
-
for (const player of taintedLosts) {
|
|
103
|
-
player.ChangePlayerType(PlayerType.THE_LOST_B);
|
|
104
|
-
}
|
|
105
|
-
}
|
|
106
|
-
|
|
107
|
-
return collectibleUnlocked;
|
|
108
|
-
}
|
|
109
|
-
|
|
110
|
-
/**
|
|
111
|
-
* Before checking the item pools, remove any collectibles or trinkets that would affect the
|
|
112
|
-
* retrieved collectible types.
|
|
113
|
-
*/
|
|
114
|
-
function removeItemsAndTrinketsThatAffectItemPools(): [
|
|
115
|
-
removedItemsMap: Map<PlayerIndex, CollectibleType[]>,
|
|
116
|
-
removedTrinketsMap: Map<PlayerIndex, TrinketType[]>,
|
|
117
|
-
] {
|
|
118
|
-
const removedItemsMap = new Map<PlayerIndex, CollectibleType[]>();
|
|
119
|
-
const removedTrinketsMap = new Map<PlayerIndex, TrinketType[]>();
|
|
120
|
-
for (const player of getPlayers()) {
|
|
121
|
-
const removedItems: CollectibleType[] = [];
|
|
122
|
-
for (const itemToRemove of COLLECTIBLES_THAT_AFFECT_ITEM_POOLS) {
|
|
123
|
-
if (player.HasCollectible(itemToRemove)) {
|
|
124
|
-
const numCollectibles = player.GetCollectibleNum(itemToRemove);
|
|
125
|
-
repeat(numCollectibles, () => {
|
|
126
|
-
player.RemoveCollectible(itemToRemove);
|
|
127
|
-
removedItems.push(itemToRemove);
|
|
128
|
-
});
|
|
129
|
-
}
|
|
130
|
-
}
|
|
131
|
-
|
|
132
|
-
mapSetPlayer(removedItemsMap, player, removedItems);
|
|
133
|
-
|
|
134
|
-
const removedTrinkets: TrinketType[] = [];
|
|
135
|
-
for (const trinketToRemove of TRINKETS_THAT_AFFECT_ITEM_POOLS) {
|
|
136
|
-
if (player.HasTrinket(trinketToRemove)) {
|
|
137
|
-
const numTrinkets = player.GetTrinketMultiplier(trinketToRemove);
|
|
138
|
-
repeat(numTrinkets, () => {
|
|
139
|
-
player.TryRemoveTrinket(trinketToRemove);
|
|
140
|
-
removedTrinkets.push(trinketToRemove);
|
|
141
|
-
});
|
|
142
|
-
}
|
|
143
|
-
}
|
|
144
|
-
|
|
145
|
-
mapSetPlayer(removedTrinketsMap, player, removedTrinkets);
|
|
146
|
-
}
|
|
147
|
-
|
|
148
|
-
return [removedItemsMap, removedTrinketsMap];
|
|
149
|
-
}
|
|
150
|
-
|
|
151
|
-
function restoreItemsAndTrinketsThatAffectItemPools(
|
|
152
|
-
removedItemsMap: Map<PlayerIndex, CollectibleType[]>,
|
|
153
|
-
removedTrinketsMap: Map<PlayerIndex, TrinketType[]>,
|
|
154
|
-
) {
|
|
155
|
-
for (const player of getPlayers()) {
|
|
156
|
-
const removedItems = mapGetPlayer(removedItemsMap, player);
|
|
157
|
-
if (removedItems !== undefined) {
|
|
158
|
-
for (const collectibleType of removedItems) {
|
|
159
|
-
player.AddCollectible(collectibleType, 0, false); // Prevent Chaos from spawning pickups
|
|
160
|
-
}
|
|
161
|
-
}
|
|
162
|
-
|
|
163
|
-
const removedTrinkets = mapGetPlayer(removedTrinketsMap, player);
|
|
164
|
-
if (removedTrinkets !== undefined) {
|
|
165
|
-
for (const trinketType of removedTrinkets) {
|
|
166
|
-
player.AddTrinket(trinketType, false);
|
|
167
|
-
}
|
|
168
|
-
}
|
|
169
|
-
}
|
|
27
|
+
return isCollectibleInItemPool(collectibleType, itemPoolType);
|
|
170
28
|
}
|
package/src/index.ts
CHANGED
|
@@ -117,6 +117,7 @@ export * from "./functions/gridEntities";
|
|
|
117
117
|
export * from "./functions/gridEntitiesSpecific";
|
|
118
118
|
export * from "./functions/input";
|
|
119
119
|
export * from "./functions/isaacAPIClass";
|
|
120
|
+
export * from "./functions/itemPool";
|
|
120
121
|
export * from "./functions/jsonHelpers";
|
|
121
122
|
export * from "./functions/jsonRoom";
|
|
122
123
|
export * from "./functions/kColor";
|