From 5746c6d625f09ee0276a363bd85464d81d211301 Mon Sep 17 00:00:00 2001 From: gymnast86 Date: Thu, 8 May 2025 02:54:35 -0700 Subject: [PATCH] fix fill issue when starting with a lot of spoils --- logic/Fill.cpp | 21 ++++++++++++++++----- logic/GameItem.cpp | 10 ++++++++++ logic/GameItem.hpp | 34 ++++++++++++++++++++++++++++++++++ 3 files changed, 60 insertions(+), 5 deletions(-) diff --git a/logic/Fill.cpp b/logic/Fill.cpp index f15ccc27..a8adfcd0 100644 --- a/logic/Fill.cpp +++ b/logic/Fill.cpp @@ -54,17 +54,28 @@ static FillError fastFill(ItemPool& items, LocationPool& locations) static FillError fillTheRest(WorldPool& worlds, ItemPool& items, LocationPool& locations) { FillError err; - // First place the junk already in the pool + // First place the non consumable junk already in the pool + // Filter out the consumable junk to place afterwards + auto consumableJunk = filterAndEraseFromPool(items, [](const Item& i){return i.isConsumableJunkItem();}); FILL_ERROR_CHECK(fastFill(items, locations)); - // When the item pool is empty, get random junk for the remaining locations + // For the remaining locations, get items from the consumable junk. If the consumable junk runs out, just get more random + // consumable junk for (auto location : locations) { if (location->currentItem.getGameItemId() == GameItem::INVALID) { - auto item = getRandomJunk(); - location->currentItem = location->world->getItem(item); - LOG_TO_DEBUG("Placed " + item + " at " + location->getName() + " in world " + std::to_string(location->world->getWorldId() + 1)); + Item item; + if (!consumableJunk.empty()) + { + item = popRandomElement(consumableJunk); + } + else + { + item = location->world->getItem(getRandomJunk()); + } + location->currentItem = item; + LOG_TO_DEBUG("Placed " + item.getName() + " at " + location->getName() + " in world " + std::to_string(location->world->getWorldId() + 1)); } } return FillError::NONE; diff --git a/logic/GameItem.cpp b/logic/GameItem.cpp index 203e8ad8..7c99d24e 100644 --- a/logic/GameItem.cpp +++ b/logic/GameItem.cpp @@ -770,6 +770,11 @@ Item::Item(GameItem gameItemId_, World* world_) : gameItemId(gameItemId_), world(world_) { + if (junkConsumables.contains(gameItemId)) + { + junkConsumable = true; + } + if (junkItems.contains(gameItemId) || (isAnyOf(gameItemId, GameItem::HeartContainer, GameItem::PieceOfHeart) && world && world->getStartingHeartCount() >= 3)) { originallyJunk = true; @@ -891,6 +896,11 @@ bool Item::isJunkItem() const return junkItem; } +bool Item::isConsumableJunkItem() const +{ + return junkConsumable; +} + bool Item::wasAlwaysJunkItem() const { return originallyJunk; diff --git a/logic/GameItem.hpp b/logic/GameItem.hpp index 6bba6af8..9b4741fb 100644 --- a/logic/GameItem.hpp +++ b/logic/GameItem.hpp @@ -355,6 +355,38 @@ static const std::set junkItems = { GameItem::TinglesChart }; +static const std::set junkConsumables = { + GameItem::HeartDrop, + GameItem::GreenRupee, + GameItem::BlueRupee, + GameItem::YellowRupee, + GameItem::RedRupee, + GameItem::PurpleRupee, + GameItem::OrangeRupee, + GameItem::SmallMagicDrop, + GameItem::LargeMagicDrop, + GameItem::FiveBombs, + GameItem::TenBombs, + GameItem::TwentyBombs, + GameItem::ThirtyBombs, + GameItem::SilverRupee, + GameItem::TenArrows, + GameItem::TwentyArrows, + GameItem::ThirtyArrows, + GameItem::Fairy, + GameItem::YellowRupee2, //joke message + GameItem::ThreeHearts, + GameItem::JoyPendant, + GameItem::SkullNecklace, + GameItem::BokoBabaSeed, + GameItem::GoldenFeather, + GameItem::KnightsCrest, + GameItem::RedChuJelly, + GameItem::GreenChuJelly, + GameItem::AllPurposeBait, + GameItem::HyoiPear, +}; + static const std::set dungeonItems = { GameItem::DRCSmallKey, GameItem::DRCBigKey, @@ -406,6 +438,7 @@ class Item void setName(const std::string& language, const Text::Type& type, const std::string& name_); void setAsJunkItem(); bool isJunkItem() const; + bool isConsumableJunkItem() const; bool wasAlwaysJunkItem() const; bool isDungeonItem() const; bool isMap() const; @@ -425,6 +458,7 @@ class Item std::unordered_set chainLocations = {}; bool dungeonItem = false; bool junkItem = false; + bool junkConsumable = false; bool originallyJunk = false; World* world = nullptr; // The world that this item is *FOR* };