isaacscript-common 6.17.1 → 6.18.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/functions/rockAlt.d.ts +4 -4
- package/dist/functions/rockAlt.d.ts.map +1 -1
- package/dist/functions/rockAlt.lua +20 -69
- package/dist/functions/saveFile.d.ts +5 -0
- package/dist/functions/saveFile.d.ts.map +1 -1
- package/dist/functions/saveFile.lua +112 -3
- package/dist/index.d.ts +0 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.lua +0 -8
- package/package.json +1 -1
- package/src/functions/rockAlt.ts +29 -111
- package/src/functions/saveFile.ts +146 -4
- package/src/index.ts +0 -1
- package/dist/functions/itemPool.d.ts +0 -10
- package/dist/functions/itemPool.d.ts.map +0 -1
- package/dist/functions/itemPool.lua +0 -116
- package/src/functions/itemPool.ts +0 -153
|
@@ -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, trinkets will not spawn if they have already been removed
|
|
28
|
-
* pool. This function cannot replicate that behavior because there is no way to
|
|
29
|
-
* trinket is still in the pool. Thus, it will always have a chance
|
|
30
|
-
* (e.g. Swallowed Penny from urns).
|
|
27
|
+
* Note that in vanilla, collectibles and trinkets will not spawn if they have already been removed
|
|
28
|
+
* from the respective pool. This function cannot replicate that behavior because there is no way to
|
|
29
|
+
* check to see if a collectible or trinket is still in the pool. Thus, it will always have a chance
|
|
30
|
+
* to spawn the respective collectible/trinket (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":";;;AAaA,OAAO,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAC;AA8BnD;;;;;;;;;;;;;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,7 +7,6 @@ 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
|
|
11
10
|
local PillColor = ____isaac_2Dtypescript_2Ddefinitions.PillColor
|
|
12
11
|
local RoomType = ____isaac_2Dtypescript_2Ddefinitions.RoomType
|
|
13
12
|
local TrinketType = ____isaac_2Dtypescript_2Ddefinitions.TrinketType
|
|
@@ -22,8 +21,6 @@ local BACKDROP_TYPE_TO_ROCK_ALT_TYPE = ____backdropTypeToRockAltType.BACKDROP_TY
|
|
|
22
21
|
local ____entitiesSpecific = require("functions.entitiesSpecific")
|
|
23
22
|
local spawnEffectWithSeed = ____entitiesSpecific.spawnEffectWithSeed
|
|
24
23
|
local spawnNPCWithSeed = ____entitiesSpecific.spawnNPCWithSeed
|
|
25
|
-
local ____itemPool = require("functions.itemPool")
|
|
26
|
-
local isCollectibleInItemPool = ____itemPool.isCollectibleInItemPool
|
|
27
24
|
local ____pickupsSpecific = require("functions.pickupsSpecific")
|
|
28
25
|
local spawnCardWithSeed = ____pickupsSpecific.spawnCardWithSeed
|
|
29
26
|
local spawnCoinWithSeed = ____pickupsSpecific.spawnCoinWithSeed
|
|
@@ -80,12 +77,8 @@ function spawnRockAltRewardUrn(self, position, rng)
|
|
|
80
77
|
end
|
|
81
78
|
totalChance = totalChance + ROCK_ALT_CHANCES.COLLECTIBLE
|
|
82
79
|
if chance < totalChance then
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
spawnCollectible(nil, CollectibleType.QUARTER, position, rng)
|
|
86
|
-
return true
|
|
87
|
-
end
|
|
88
|
-
return false
|
|
80
|
+
spawnCollectible(nil, CollectibleType.QUARTER, position, rng)
|
|
81
|
+
return true
|
|
89
82
|
end
|
|
90
83
|
local numSpidersChance = getRandom(nil, rng)
|
|
91
84
|
local numSpiders = numSpidersChance < 0.5 and 1 or 2
|
|
@@ -132,30 +125,14 @@ function spawnRockAltRewardMushroom(self, position, rng)
|
|
|
132
125
|
if roomType == RoomType.SECRET then
|
|
133
126
|
local wavyCapChance = getRandom(nil, rng)
|
|
134
127
|
if wavyCapChance < 0.0272 then
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
spawnCollectible(nil, CollectibleType.WAVY_CAP, position, rng)
|
|
138
|
-
return true
|
|
139
|
-
end
|
|
128
|
+
spawnCollectible(nil, CollectibleType.WAVY_CAP, position, rng)
|
|
129
|
+
return true
|
|
140
130
|
end
|
|
141
131
|
end
|
|
142
|
-
local
|
|
143
|
-
local
|
|
144
|
-
|
|
145
|
-
|
|
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
|
|
132
|
+
local collectibleChance = getRandom(nil, rng)
|
|
133
|
+
local collectibleType = collectibleChance < 0.5 and CollectibleType.MAGIC_MUSHROOM or CollectibleType.MINI_MUSH
|
|
134
|
+
spawnCollectible(nil, collectibleType, position, rng)
|
|
135
|
+
return true
|
|
159
136
|
end
|
|
160
137
|
spawnEffectWithSeed(
|
|
161
138
|
nil,
|
|
@@ -185,23 +162,10 @@ function spawnRockAltRewardSkull(self, position, rng)
|
|
|
185
162
|
end
|
|
186
163
|
totalChance = totalChance + ROCK_ALT_CHANCES.COLLECTIBLE
|
|
187
164
|
if chance < totalChance then
|
|
188
|
-
local
|
|
189
|
-
local
|
|
190
|
-
|
|
191
|
-
|
|
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
|
|
165
|
+
local collectibleChance = getRandom(nil, rng)
|
|
166
|
+
local collectibleType = collectibleChance < 0.5 and CollectibleType.GHOST_BABY or CollectibleType.DRY_BABY
|
|
167
|
+
spawnCollectible(nil, collectibleType, position, rng)
|
|
168
|
+
return true
|
|
205
169
|
end
|
|
206
170
|
spawnNPCWithSeed(
|
|
207
171
|
nil,
|
|
@@ -232,23 +196,10 @@ function spawnRockAltRewardPolyp(self, position, rng)
|
|
|
232
196
|
end
|
|
233
197
|
totalChance = totalChance + ROCK_ALT_CHANCES.COLLECTIBLE
|
|
234
198
|
if chance < totalChance then
|
|
235
|
-
local
|
|
236
|
-
local
|
|
237
|
-
|
|
238
|
-
|
|
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
|
|
199
|
+
local collectibleChance = getRandom(nil, rng)
|
|
200
|
+
local collectibleType = collectibleChance < 0.5 and CollectibleType.PLACENTA or CollectibleType.BLOOD_CLOT
|
|
201
|
+
spawnCollectible(nil, collectibleType, position, rng)
|
|
202
|
+
return true
|
|
252
203
|
end
|
|
253
204
|
spawnEffectWithSeed(
|
|
254
205
|
nil,
|
|
@@ -301,10 +252,10 @@ end
|
|
|
301
252
|
-- Most of the time, this function will do nothing, similar to how most of the time, when an
|
|
302
253
|
-- individual urn is destroyed, nothing will spawn.
|
|
303
254
|
--
|
|
304
|
-
-- Note that in vanilla, trinkets will not spawn if they have already been removed
|
|
305
|
-
-- pool. This function cannot replicate that behavior because there is no way to
|
|
306
|
-
-- trinket is still in the pool. Thus, it will always have a chance
|
|
307
|
-
-- (e.g. Swallowed Penny from urns).
|
|
255
|
+
-- Note that in vanilla, collectibles and trinkets will not spawn if they have already been removed
|
|
256
|
+
-- from the respective pool. This function cannot replicate that behavior because there is no way to
|
|
257
|
+
-- check to see if a collectible or trinket is still in the pool. Thus, it will always have a chance
|
|
258
|
+
-- to spawn the respective collectible/trinket (e.g. Swallowed Penny from urns).
|
|
308
259
|
--
|
|
309
260
|
-- The logic in this function is based on the rewards listed on the wiki:
|
|
310
261
|
-- https://bindingofisaacrebirth.fandom.com/wiki/Rocks
|
|
@@ -12,6 +12,11 @@ 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.
|
|
15
20
|
*/
|
|
16
21
|
export declare function isCollectibleUnlocked(collectibleType: CollectibleType, itemPoolType: ItemPoolType): boolean;
|
|
17
22
|
//# 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,EACL,eAAe,EAEf,YAAY,EAGb,MAAM,8BAA8B,CAAC;AAoBtC;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,qBAAqB,CACnC,eAAe,EAAE,eAAe,EAChC,YAAY,EAAE,YAAY,GACzB,OAAO,CA2DT"}
|
|
@@ -1,8 +1,85 @@
|
|
|
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
|
|
1
5
|
local ____exports = {}
|
|
2
|
-
local
|
|
3
|
-
local
|
|
6
|
+
local removeItemsAndTrinketsThatAffectItemPools, restoreItemsAndTrinketsThatAffectItemPools, COLLECTIBLES_THAT_AFFECT_ITEM_POOLS, TRINKETS_THAT_AFFECT_ITEM_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 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
|
|
4
23
|
local ____players = require("functions.players")
|
|
5
24
|
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}
|
|
6
83
|
--- Helper function to see if the given collectible is unlocked on the current save file. This
|
|
7
84
|
-- requires providing the corresponding item pool that the collectible is located in.
|
|
8
85
|
--
|
|
@@ -15,10 +92,42 @@ local anyPlayerHasCollectible = ____players.anyPlayerHasCollectible
|
|
|
15
92
|
-- - If the collectible is non-offensive, any Tainted Losts will be temporarily changed to Isaac and
|
|
16
93
|
-- then changed back. (This is because Tainted Lost is not able to retrieve non-offensive
|
|
17
94
|
-- 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.
|
|
18
100
|
function ____exports.isCollectibleUnlocked(self, collectibleType, itemPoolType)
|
|
19
101
|
if anyPlayerHasCollectible(nil, collectibleType) then
|
|
20
102
|
return true
|
|
21
103
|
end
|
|
22
|
-
|
|
104
|
+
local taintedLosts = getPlayersOfType(nil, PlayerType.THE_LOST_B)
|
|
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
|
|
23
132
|
end
|
|
24
133
|
return ____exports
|
package/dist/index.d.ts
CHANGED
|
@@ -74,7 +74,6 @@ 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";
|
|
78
77
|
export * from "./functions/jsonHelpers";
|
|
79
78
|
export * from "./functions/jsonRoom";
|
|
80
79
|
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,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
package/dist/index.lua
CHANGED
|
@@ -590,14 +590,6 @@ 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
|
|
601
593
|
do
|
|
602
594
|
local ____export = require("functions.jsonHelpers")
|
|
603
595
|
for ____exportKey, ____exportValue in pairs(____export) do
|
package/package.json
CHANGED
package/src/functions/rockAlt.ts
CHANGED
|
@@ -5,7 +5,6 @@ import {
|
|
|
5
5
|
EffectVariant,
|
|
6
6
|
EntityType,
|
|
7
7
|
HeartSubType,
|
|
8
|
-
ItemPoolType,
|
|
9
8
|
PillColor,
|
|
10
9
|
RoomType,
|
|
11
10
|
TrinketType,
|
|
@@ -15,7 +14,6 @@ import { DISTANCE_OF_GRID_TILE } from "../constants";
|
|
|
15
14
|
import { RockAltType } from "../enums/RockAltType";
|
|
16
15
|
import { BACKDROP_TYPE_TO_ROCK_ALT_TYPE } from "../objects/backdropTypeToRockAltType";
|
|
17
16
|
import { spawnEffectWithSeed, spawnNPCWithSeed } from "./entitiesSpecific";
|
|
18
|
-
import { isCollectibleInItemPool } from "./itemPool";
|
|
19
17
|
import {
|
|
20
18
|
spawnCardWithSeed,
|
|
21
19
|
spawnCoinWithSeed,
|
|
@@ -71,10 +69,10 @@ export function getRockAltType(): RockAltType {
|
|
|
71
69
|
* Most of the time, this function will do nothing, similar to how most of the time, when an
|
|
72
70
|
* individual urn is destroyed, nothing will spawn.
|
|
73
71
|
*
|
|
74
|
-
* Note that in vanilla, trinkets will not spawn if they have already been removed
|
|
75
|
-
* pool. This function cannot replicate that behavior because there is no way to
|
|
76
|
-
* trinket is still in the pool. Thus, it will always have a chance
|
|
77
|
-
* (e.g. Swallowed Penny from urns).
|
|
72
|
+
* Note that in vanilla, collectibles and trinkets will not spawn if they have already been removed
|
|
73
|
+
* from the respective pool. This function cannot replicate that behavior because there is no way to
|
|
74
|
+
* check to see if a collectible or trinket is still in the pool. Thus, it will always have a chance
|
|
75
|
+
* to spawn the respective collectible/trinket (e.g. Swallowed Penny from urns).
|
|
78
76
|
*
|
|
79
77
|
* The logic in this function is based on the rewards listed on the wiki:
|
|
80
78
|
* https://bindingofisaacrebirth.fandom.com/wiki/Rocks
|
|
@@ -152,16 +150,8 @@ function spawnRockAltRewardUrn(position: Vector, rng: RNG): boolean {
|
|
|
152
150
|
|
|
153
151
|
totalChance += ROCK_ALT_CHANCES.COLLECTIBLE;
|
|
154
152
|
if (chance < totalChance) {
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
ItemPoolType.DEVIL,
|
|
158
|
-
);
|
|
159
|
-
if (stillInPools) {
|
|
160
|
-
spawnCollectible(CollectibleType.QUARTER, position, rng);
|
|
161
|
-
return true;
|
|
162
|
-
}
|
|
163
|
-
|
|
164
|
-
return false;
|
|
153
|
+
spawnCollectible(CollectibleType.QUARTER, position, rng);
|
|
154
|
+
return true;
|
|
165
155
|
}
|
|
166
156
|
|
|
167
157
|
// Since the detrimental effect is the final option, we don't need to check the chance.
|
|
@@ -206,46 +196,18 @@ function spawnRockAltRewardMushroom(position: Vector, rng: RNG): boolean {
|
|
|
206
196
|
if (roomType === RoomType.SECRET) {
|
|
207
197
|
const wavyCapChance = getRandom(rng);
|
|
208
198
|
if (wavyCapChance < 0.0272) {
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
ItemPoolType.SECRET,
|
|
212
|
-
);
|
|
213
|
-
if (stillInPools) {
|
|
214
|
-
spawnCollectible(CollectibleType.WAVY_CAP, position, rng);
|
|
215
|
-
return true;
|
|
216
|
-
}
|
|
199
|
+
spawnCollectible(CollectibleType.WAVY_CAP, position, rng);
|
|
200
|
+
return true;
|
|
217
201
|
}
|
|
218
202
|
}
|
|
219
203
|
|
|
220
|
-
const
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
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;
|
|
204
|
+
const collectibleChance = getRandom(rng);
|
|
205
|
+
const collectibleType =
|
|
206
|
+
collectibleChance < 0.5
|
|
207
|
+
? CollectibleType.MAGIC_MUSHROOM // 12
|
|
208
|
+
: CollectibleType.MINI_MUSH; // 71
|
|
209
|
+
spawnCollectible(collectibleType, position, rng);
|
|
210
|
+
return true;
|
|
249
211
|
}
|
|
250
212
|
|
|
251
213
|
// Since the detrimental effect is the final option, we don't need to check the chance.
|
|
@@ -276,35 +238,13 @@ function spawnRockAltRewardSkull(position: Vector, rng: RNG): boolean {
|
|
|
276
238
|
|
|
277
239
|
totalChance += ROCK_ALT_CHANCES.COLLECTIBLE;
|
|
278
240
|
if (chance < totalChance) {
|
|
279
|
-
const
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
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;
|
|
241
|
+
const collectibleChance = getRandom(rng);
|
|
242
|
+
const collectibleType =
|
|
243
|
+
collectibleChance < 0.5
|
|
244
|
+
? CollectibleType.GHOST_BABY // 163
|
|
245
|
+
: CollectibleType.DRY_BABY; // 265
|
|
246
|
+
spawnCollectible(collectibleType, position, rng);
|
|
247
|
+
return true;
|
|
308
248
|
}
|
|
309
249
|
|
|
310
250
|
// Since the detrimental effect is the final option, we don't need to check the chance.
|
|
@@ -335,35 +275,13 @@ function spawnRockAltRewardPolyp(position: Vector, rng: RNG): boolean {
|
|
|
335
275
|
|
|
336
276
|
totalChance += ROCK_ALT_CHANCES.COLLECTIBLE;
|
|
337
277
|
if (chance < totalChance) {
|
|
338
|
-
const
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
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;
|
|
278
|
+
const collectibleChance = getRandom(rng);
|
|
279
|
+
const collectibleType =
|
|
280
|
+
collectibleChance < 0.5
|
|
281
|
+
? CollectibleType.PLACENTA // 218
|
|
282
|
+
: CollectibleType.BLOOD_CLOT; // 254
|
|
283
|
+
spawnCollectible(collectibleType, position, rng);
|
|
284
|
+
return true;
|
|
367
285
|
}
|
|
368
286
|
|
|
369
287
|
// Since the detrimental effect is the final option, we don't need to check the chance.
|
|
@@ -1,6 +1,28 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
3
|
-
|
|
1
|
+
import {
|
|
2
|
+
CollectibleType,
|
|
3
|
+
ItemConfigTag,
|
|
4
|
+
ItemPoolType,
|
|
5
|
+
PlayerType,
|
|
6
|
+
TrinketType,
|
|
7
|
+
} from "isaac-typescript-definitions";
|
|
8
|
+
import { game } from "../cachedClasses";
|
|
9
|
+
import { PlayerIndex } from "../types/PlayerIndex";
|
|
10
|
+
import { getCollectibleSet } from "./collectibleSet";
|
|
11
|
+
import { collectibleHasTag } from "./collectibleTag";
|
|
12
|
+
import { mapGetPlayer, mapSetPlayer } from "./playerDataStructures";
|
|
13
|
+
import { getPlayers } from "./playerIndex";
|
|
14
|
+
import { 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
|
+
];
|
|
4
26
|
|
|
5
27
|
/**
|
|
6
28
|
* Helper function to see if the given collectible is unlocked on the current save file. This
|
|
@@ -15,6 +37,11 @@ import { anyPlayerHasCollectible } from "./players";
|
|
|
15
37
|
* - If the collectible is non-offensive, any Tainted Losts will be temporarily changed to Isaac and
|
|
16
38
|
* then changed back. (This is because Tainted Lost is not able to retrieve non-offensive
|
|
17
39
|
* 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.
|
|
18
45
|
*/
|
|
19
46
|
export function isCollectibleUnlocked(
|
|
20
47
|
collectibleType: CollectibleType,
|
|
@@ -24,5 +51,120 @@ export function isCollectibleUnlocked(
|
|
|
24
51
|
return true;
|
|
25
52
|
}
|
|
26
53
|
|
|
27
|
-
|
|
54
|
+
// On Tainted Lost, it is impossible to retrieve non-offensive collectibles from pools, so we
|
|
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
|
+
}
|
|
28
170
|
}
|
package/src/index.ts
CHANGED
|
@@ -117,7 +117,6 @@ 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";
|
|
121
120
|
export * from "./functions/jsonHelpers";
|
|
122
121
|
export * from "./functions/jsonRoom";
|
|
123
122
|
export * from "./functions/kColor";
|
|
@@ -1,10 +0,0 @@
|
|
|
1
|
-
import { CollectibleType, ItemPoolType } from "isaac-typescript-definitions";
|
|
2
|
-
/**
|
|
3
|
-
* Helper function to see if the given collectible is still present in the given item pool.
|
|
4
|
-
*
|
|
5
|
-
* If the collectible is non-offensive, any Tainted Losts will be temporarily changed to Isaac and
|
|
6
|
-
* then changed back. (This is because Tainted Lost is not able to retrieve non-offensive
|
|
7
|
-
* collectibles from item pools).
|
|
8
|
-
*/
|
|
9
|
-
export declare function isCollectibleInItemPool(collectibleType: CollectibleType, itemPoolType: ItemPoolType): boolean;
|
|
10
|
-
//# sourceMappingURL=itemPool.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
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;AAoBtC;;;;;;GAMG;AACH,wBAAgB,uBAAuB,CACrC,eAAe,EAAE,eAAe,EAChC,YAAY,EAAE,YAAY,GACzB,OAAO,CAsDT"}
|
|
@@ -1,116 +0,0 @@
|
|
|
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
|
-
local ____exports = {}
|
|
6
|
-
local removeItemsAndTrinketsThatAffectItemPools, restoreItemsAndTrinketsThatAffectItemPools, COLLECTIBLES_THAT_AFFECT_ITEM_POOLS, TRINKETS_THAT_AFFECT_ITEM_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 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
|
|
23
|
-
local ____players = require("functions.players")
|
|
24
|
-
local getPlayersOfType = ____players.getPlayersOfType
|
|
25
|
-
local ____utils = require("functions.utils")
|
|
26
|
-
local ____repeat = ____utils["repeat"]
|
|
27
|
-
function removeItemsAndTrinketsThatAffectItemPools(self)
|
|
28
|
-
local removedItemsMap = __TS__New(Map)
|
|
29
|
-
local removedTrinketsMap = __TS__New(Map)
|
|
30
|
-
for ____, player in ipairs(getPlayers(nil)) do
|
|
31
|
-
local removedItems = {}
|
|
32
|
-
for ____, itemToRemove in ipairs(COLLECTIBLES_THAT_AFFECT_ITEM_POOLS) do
|
|
33
|
-
if player:HasCollectible(itemToRemove) then
|
|
34
|
-
local numCollectibles = player:GetCollectibleNum(itemToRemove)
|
|
35
|
-
____repeat(
|
|
36
|
-
nil,
|
|
37
|
-
numCollectibles,
|
|
38
|
-
function()
|
|
39
|
-
player:RemoveCollectible(itemToRemove)
|
|
40
|
-
removedItems[#removedItems + 1] = itemToRemove
|
|
41
|
-
end
|
|
42
|
-
)
|
|
43
|
-
end
|
|
44
|
-
end
|
|
45
|
-
mapSetPlayer(nil, removedItemsMap, player, removedItems)
|
|
46
|
-
local removedTrinkets = {}
|
|
47
|
-
for ____, trinketToRemove in ipairs(TRINKETS_THAT_AFFECT_ITEM_POOLS) do
|
|
48
|
-
if player:HasTrinket(trinketToRemove) then
|
|
49
|
-
local numTrinkets = player:GetTrinketMultiplier(trinketToRemove)
|
|
50
|
-
____repeat(
|
|
51
|
-
nil,
|
|
52
|
-
numTrinkets,
|
|
53
|
-
function()
|
|
54
|
-
player:TryRemoveTrinket(trinketToRemove)
|
|
55
|
-
removedTrinkets[#removedTrinkets + 1] = trinketToRemove
|
|
56
|
-
end
|
|
57
|
-
)
|
|
58
|
-
end
|
|
59
|
-
end
|
|
60
|
-
mapSetPlayer(nil, removedTrinketsMap, player, removedTrinkets)
|
|
61
|
-
end
|
|
62
|
-
return {removedItemsMap, removedTrinketsMap}
|
|
63
|
-
end
|
|
64
|
-
function restoreItemsAndTrinketsThatAffectItemPools(self, removedItemsMap, removedTrinketsMap)
|
|
65
|
-
for ____, player in ipairs(getPlayers(nil)) do
|
|
66
|
-
local removedItems = mapGetPlayer(nil, removedItemsMap, player)
|
|
67
|
-
if removedItems ~= nil then
|
|
68
|
-
for ____, collectibleType in ipairs(removedItems) do
|
|
69
|
-
player:AddCollectible(collectibleType, 0, false)
|
|
70
|
-
end
|
|
71
|
-
end
|
|
72
|
-
local removedTrinkets = mapGetPlayer(nil, removedTrinketsMap, player)
|
|
73
|
-
if removedTrinkets ~= nil then
|
|
74
|
-
for ____, trinketType in ipairs(removedTrinkets) do
|
|
75
|
-
player:AddTrinket(trinketType, false)
|
|
76
|
-
end
|
|
77
|
-
end
|
|
78
|
-
end
|
|
79
|
-
end
|
|
80
|
-
COLLECTIBLES_THAT_AFFECT_ITEM_POOLS = {CollectibleType.CHAOS, CollectibleType.SACRED_ORB, CollectibleType.TMTRAINER}
|
|
81
|
-
TRINKETS_THAT_AFFECT_ITEM_POOLS = {TrinketType.NO}
|
|
82
|
-
--- Helper function to see if the given collectible is still present in the given item pool.
|
|
83
|
-
--
|
|
84
|
-
-- If the collectible is non-offensive, any Tainted Losts will be temporarily changed to Isaac and
|
|
85
|
-
-- then changed back. (This is because Tainted Lost is not able to retrieve non-offensive
|
|
86
|
-
-- collectibles from item pools).
|
|
87
|
-
function ____exports.isCollectibleInItemPool(self, collectibleType, itemPoolType)
|
|
88
|
-
local taintedLosts = getPlayersOfType(nil, PlayerType.THE_LOST_B)
|
|
89
|
-
local isOffensive = collectibleHasTag(nil, collectibleType, ItemConfigTag.OFFENSIVE)
|
|
90
|
-
local changedPlayerTypes = false
|
|
91
|
-
if not isOffensive then
|
|
92
|
-
changedPlayerTypes = true
|
|
93
|
-
for ____, player in ipairs(taintedLosts) do
|
|
94
|
-
player:ChangePlayerType(PlayerType.ISAAC)
|
|
95
|
-
end
|
|
96
|
-
end
|
|
97
|
-
local removedItemsMap, removedTrinketsMap = table.unpack(removeItemsAndTrinketsThatAffectItemPools(nil))
|
|
98
|
-
local itemPool = game:GetItemPool()
|
|
99
|
-
local collectibleSet = getCollectibleSet(nil)
|
|
100
|
-
for ____, collectibleTypeInSet in __TS__Iterator(collectibleSet:values()) do
|
|
101
|
-
if collectibleTypeInSet ~= collectibleType then
|
|
102
|
-
itemPool:AddRoomBlacklist(collectibleTypeInSet)
|
|
103
|
-
end
|
|
104
|
-
end
|
|
105
|
-
local retrievedCollectibleType = itemPool:GetCollectible(itemPoolType, false, 1)
|
|
106
|
-
local collectibleUnlocked = retrievedCollectibleType == collectibleType
|
|
107
|
-
itemPool:ResetRoomBlacklist()
|
|
108
|
-
restoreItemsAndTrinketsThatAffectItemPools(nil, removedItemsMap, removedTrinketsMap)
|
|
109
|
-
if changedPlayerTypes then
|
|
110
|
-
for ____, player in ipairs(taintedLosts) do
|
|
111
|
-
player:ChangePlayerType(PlayerType.THE_LOST_B)
|
|
112
|
-
end
|
|
113
|
-
end
|
|
114
|
-
return collectibleUnlocked
|
|
115
|
-
end
|
|
116
|
-
return ____exports
|
|
@@ -1,153 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
CollectibleType,
|
|
3
|
-
ItemConfigTag,
|
|
4
|
-
ItemPoolType,
|
|
5
|
-
PlayerType,
|
|
6
|
-
TrinketType,
|
|
7
|
-
} from "isaac-typescript-definitions";
|
|
8
|
-
import { game } from "../cachedClasses";
|
|
9
|
-
import { PlayerIndex } from "../types/PlayerIndex";
|
|
10
|
-
import { getCollectibleSet } from "./collectibleSet";
|
|
11
|
-
import { collectibleHasTag } from "./collectibleTag";
|
|
12
|
-
import { mapGetPlayer, mapSetPlayer } from "./playerDataStructures";
|
|
13
|
-
import { getPlayers } from "./playerIndex";
|
|
14
|
-
import { getPlayersOfType } from "./players";
|
|
15
|
-
import { repeat } from "./utils";
|
|
16
|
-
|
|
17
|
-
const COLLECTIBLES_THAT_AFFECT_ITEM_POOLS: readonly CollectibleType[] = [
|
|
18
|
-
CollectibleType.CHAOS, // 402
|
|
19
|
-
CollectibleType.SACRED_ORB, // 691
|
|
20
|
-
CollectibleType.TMTRAINER, // 721
|
|
21
|
-
];
|
|
22
|
-
|
|
23
|
-
const TRINKETS_THAT_AFFECT_ITEM_POOLS: readonly TrinketType[] = [
|
|
24
|
-
TrinketType.NO,
|
|
25
|
-
];
|
|
26
|
-
|
|
27
|
-
/**
|
|
28
|
-
* Helper function to see if the given collectible is still present in the given item pool.
|
|
29
|
-
*
|
|
30
|
-
* If the collectible is non-offensive, any Tainted Losts will be temporarily changed to Isaac and
|
|
31
|
-
* then changed back. (This is because Tainted Lost is not able to retrieve non-offensive
|
|
32
|
-
* collectibles from item pools).
|
|
33
|
-
*/
|
|
34
|
-
export function isCollectibleInItemPool(
|
|
35
|
-
collectibleType: CollectibleType,
|
|
36
|
-
itemPoolType: ItemPoolType,
|
|
37
|
-
): boolean {
|
|
38
|
-
// On Tainted Lost, it is impossible to retrieve non-offensive collectibles from pools, so we
|
|
39
|
-
// temporarily change the character to Isaac.
|
|
40
|
-
const taintedLosts = getPlayersOfType(PlayerType.THE_LOST_B);
|
|
41
|
-
const isOffensive = collectibleHasTag(
|
|
42
|
-
collectibleType,
|
|
43
|
-
ItemConfigTag.OFFENSIVE,
|
|
44
|
-
);
|
|
45
|
-
let changedPlayerTypes = false;
|
|
46
|
-
if (!isOffensive) {
|
|
47
|
-
changedPlayerTypes = true;
|
|
48
|
-
for (const player of taintedLosts) {
|
|
49
|
-
player.ChangePlayerType(PlayerType.ISAAC);
|
|
50
|
-
}
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
const [removedItemsMap, removedTrinketsMap] =
|
|
54
|
-
removeItemsAndTrinketsThatAffectItemPools();
|
|
55
|
-
|
|
56
|
-
// Blacklist every collectible in the game except for the provided collectible.
|
|
57
|
-
const itemPool = game.GetItemPool();
|
|
58
|
-
const collectibleSet = getCollectibleSet();
|
|
59
|
-
for (const collectibleTypeInSet of collectibleSet.values()) {
|
|
60
|
-
if (collectibleTypeInSet !== collectibleType) {
|
|
61
|
-
itemPool.AddRoomBlacklist(collectibleTypeInSet);
|
|
62
|
-
}
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
// Get a collectible from the pool and see if it is the intended collectible. (We can use any
|
|
66
|
-
// arbitrary value as the seed since it should not influence the result.)
|
|
67
|
-
const retrievedCollectibleType = itemPool.GetCollectible(
|
|
68
|
-
itemPoolType,
|
|
69
|
-
false,
|
|
70
|
-
1 as Seed,
|
|
71
|
-
);
|
|
72
|
-
|
|
73
|
-
const collectibleUnlocked = retrievedCollectibleType === collectibleType;
|
|
74
|
-
|
|
75
|
-
// Reset the blacklist
|
|
76
|
-
itemPool.ResetRoomBlacklist();
|
|
77
|
-
|
|
78
|
-
restoreItemsAndTrinketsThatAffectItemPools(
|
|
79
|
-
removedItemsMap,
|
|
80
|
-
removedTrinketsMap,
|
|
81
|
-
);
|
|
82
|
-
|
|
83
|
-
// Change any players back to Tainted Lost, if necessary.
|
|
84
|
-
if (changedPlayerTypes) {
|
|
85
|
-
for (const player of taintedLosts) {
|
|
86
|
-
player.ChangePlayerType(PlayerType.THE_LOST_B);
|
|
87
|
-
}
|
|
88
|
-
}
|
|
89
|
-
|
|
90
|
-
return collectibleUnlocked;
|
|
91
|
-
}
|
|
92
|
-
|
|
93
|
-
/**
|
|
94
|
-
* Before checking the item pools, remove any collectibles or trinkets that would affect the
|
|
95
|
-
* retrieved collectible types.
|
|
96
|
-
*/
|
|
97
|
-
function removeItemsAndTrinketsThatAffectItemPools(): [
|
|
98
|
-
removedItemsMap: Map<PlayerIndex, CollectibleType[]>,
|
|
99
|
-
removedTrinketsMap: Map<PlayerIndex, TrinketType[]>,
|
|
100
|
-
] {
|
|
101
|
-
const removedItemsMap = new Map<PlayerIndex, CollectibleType[]>();
|
|
102
|
-
const removedTrinketsMap = new Map<PlayerIndex, TrinketType[]>();
|
|
103
|
-
for (const player of getPlayers()) {
|
|
104
|
-
const removedItems: CollectibleType[] = [];
|
|
105
|
-
for (const itemToRemove of COLLECTIBLES_THAT_AFFECT_ITEM_POOLS) {
|
|
106
|
-
if (player.HasCollectible(itemToRemove)) {
|
|
107
|
-
const numCollectibles = player.GetCollectibleNum(itemToRemove);
|
|
108
|
-
repeat(numCollectibles, () => {
|
|
109
|
-
player.RemoveCollectible(itemToRemove);
|
|
110
|
-
removedItems.push(itemToRemove);
|
|
111
|
-
});
|
|
112
|
-
}
|
|
113
|
-
}
|
|
114
|
-
|
|
115
|
-
mapSetPlayer(removedItemsMap, player, removedItems);
|
|
116
|
-
|
|
117
|
-
const removedTrinkets: TrinketType[] = [];
|
|
118
|
-
for (const trinketToRemove of TRINKETS_THAT_AFFECT_ITEM_POOLS) {
|
|
119
|
-
if (player.HasTrinket(trinketToRemove)) {
|
|
120
|
-
const numTrinkets = player.GetTrinketMultiplier(trinketToRemove);
|
|
121
|
-
repeat(numTrinkets, () => {
|
|
122
|
-
player.TryRemoveTrinket(trinketToRemove);
|
|
123
|
-
removedTrinkets.push(trinketToRemove);
|
|
124
|
-
});
|
|
125
|
-
}
|
|
126
|
-
}
|
|
127
|
-
|
|
128
|
-
mapSetPlayer(removedTrinketsMap, player, removedTrinkets);
|
|
129
|
-
}
|
|
130
|
-
|
|
131
|
-
return [removedItemsMap, removedTrinketsMap];
|
|
132
|
-
}
|
|
133
|
-
|
|
134
|
-
function restoreItemsAndTrinketsThatAffectItemPools(
|
|
135
|
-
removedItemsMap: Map<PlayerIndex, CollectibleType[]>,
|
|
136
|
-
removedTrinketsMap: Map<PlayerIndex, TrinketType[]>,
|
|
137
|
-
) {
|
|
138
|
-
for (const player of getPlayers()) {
|
|
139
|
-
const removedItems = mapGetPlayer(removedItemsMap, player);
|
|
140
|
-
if (removedItems !== undefined) {
|
|
141
|
-
for (const collectibleType of removedItems) {
|
|
142
|
-
player.AddCollectible(collectibleType, 0, false); // Prevent Chaos from spawning pickups
|
|
143
|
-
}
|
|
144
|
-
}
|
|
145
|
-
|
|
146
|
-
const removedTrinkets = mapGetPlayer(removedTrinketsMap, player);
|
|
147
|
-
if (removedTrinkets !== undefined) {
|
|
148
|
-
for (const trinketType of removedTrinkets) {
|
|
149
|
-
player.AddTrinket(trinketType, false);
|
|
150
|
-
}
|
|
151
|
-
}
|
|
152
|
-
}
|
|
153
|
-
}
|