Try make item pool size match location pool size (#5181)

Also avoid putting random junk into the pool to begin with

When smaller, add junk from pending junk items

When larger, remove junk from the item pool

This avoids issue where shuffles which add items to pool (souls, overworld keys, triforce pieces) would hit assert about item pool size exceeding location pool size
This commit is contained in:
Philip Dubé 2025-03-25 19:00:32 +00:00 committed by GitHub
parent 364fec4d29
commit 8832bcaf12
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 20 additions and 32 deletions

View file

@ -453,7 +453,7 @@ static void ReplaceMaxItem(const RandomizerGet itemToReplace, int max) {
for (size_t i = 0; i < ItemPool.size(); i++) {
if (ItemPool[i] == itemToReplace) {
if (itemCount >= max) {
ItemPool[i] = GetJunkItem();
ItemPool[i] = RG_NONE;
}
itemCount++;
}
@ -703,19 +703,8 @@ void GenerateItemPool() {
if (ctx->GetOption(RSK_SHUFFLE_BEEHIVES)) {
//32 total beehive locations
AddItemToMainPool(RG_RED_RUPEE, 23);
AddItemToMainPool(RG_BLUE_RUPEE, 9);
}
if (ctx->GetOption(RSK_SHUFFLE_COWS)) {
//9 total cow locations
for (uint8_t i = 0; i < 9; i++) {
AddItemToMainPool(GetJunkItem());
}
//extra location for Jabu MQ
if (ctx->GetDungeon(Rando::JABU_JABUS_BELLY)->IsMQ()) {
AddItemToMainPool(GetJunkItem());
}
AddItemToPool(PendingJunkPool, RG_RED_RUPEE, 23);
AddItemToPool(PendingJunkPool, RG_BLUE_RUPEE, 9);
}
// Shuffle Pots
@ -1335,6 +1324,7 @@ void GenerateItemPool() {
}
//Replace all junk items with ice traps for onslaught mode
else if (ctx->GetOption(RSK_ICE_TRAPS).Is(RO_ICE_TRAPS_ONSLAUGHT)) {
PendingJunkPool.clear();
for (uint8_t i = 0; i < JunkPoolItems.size() - 3; i++) { // -3 Omits Huge Rupees and Deku Nuts 10
ReplaceMaxItem(JunkPoolItems[i], 0);
}
@ -1348,31 +1338,30 @@ void GenerateItemPool() {
ReplaceMaxItem(RG_DOUBLE_DEFENSE, 0);
}
//this feels ugly and there's probably a better way, but
//it replaces random junk with pending junk.
bool junkSet;
for (RandomizerGet pendingJunk : PendingJunkPool) {
junkSet = false;
for (RandomizerGet& item : ItemPool) {
for (RandomizerGet junk : JunkPoolItems) {
if (item == junk && item != RG_HUGE_RUPEE && item != RG_DEKU_NUTS_10) {
item = pendingJunk;
junkSet = true;
std::erase(ItemPool, RG_NONE);
if (ItemPool.size() < ctx->allLocations.size()) {
Shuffle(PendingJunkPool);
size_t junkNeeded = std::min(PendingJunkPool.size(), ctx->allLocations.size() - ItemPool.size());
ItemPool.insert(ItemPool.end(), PendingJunkPool.begin(), PendingJunkPool.begin() + junkNeeded);
PendingJunkPool.erase(PendingJunkPool.begin(), PendingJunkPool.begin() + junkNeeded);
} else if (ItemPool.size() > ctx->allLocations.size()) {
// RANDOTODO: all junk should be put in PendingJunkPool so this is never needed
size_t remove = ItemPool.size() - ctx->allLocations.size();
for (size_t i = 0; remove > 0 && i < ItemPool.size(); i++) {
for (size_t j = 0; j < JunkPoolItems.size(); j++) {
if (ItemPool[i] == JunkPoolItems[j]) {
ItemPool[i] = RG_NONE;
remove--;
break;
}
}
if (junkSet) break;
}
std::erase(ItemPool, RG_NONE);
}
PendingJunkPool.clear();
// RANDOTODO: Ideally this should be checking for equality, but that is not currently the case and has never been
// the case, and isn't even currently the case in the 3drando repo we inherited this from years ago, so it may
// be a large undertaking to fix.
assert(ItemPool.size() <= ctx->allLocations.size() || !"Item Pool larger than Location Pool");
}
void AddJunk() {
SPDLOG_DEBUG("HAD TO PLACE EXTRA JUNK ");
AddItemToMainPool(GetPendingJunkItem());
}

View file

@ -11,6 +11,5 @@ void AddItemToPool(std::vector<RandomizerGet>& pool, const RandomizerGet item, s
RandomizerGet GetJunkItem();
void PlaceJunkInExcludedLocation(const RandomizerCheck il);
void GenerateItemPool();
void AddJunk();
extern std::vector<RandomizerGet> ItemPool;