mirror of
https://github.com/TwilitRealm/dusklight
synced 2026-06-01 09:17:15 -04:00
384 lines
12 KiB
C++
384 lines
12 KiB
C++
#include "item_pool.hpp"
|
|
|
|
#include "world.hpp"
|
|
|
|
#include <map>
|
|
|
|
namespace randomizer::logic::item_pool
|
|
{
|
|
|
|
std::map<std::string, int> minimalItemPool = {
|
|
{"Shadow Crystal", 1},
|
|
{"Slingshot", 1},
|
|
{"Lantern", 1},
|
|
{"Gale Boomerang", 1},
|
|
{"Iron Boots", 1},
|
|
{"Bomb Bag", 1},
|
|
{"Spinner", 1},
|
|
{"Ball and Chain", 1},
|
|
|
|
{"Progressive Fishing Rod", 2},
|
|
{"Progressive Sword", 4},
|
|
{"Progressive Bow", 1},
|
|
{"Progressive Clawshot", 2},
|
|
{"Progressive Dominion Rod", 2},
|
|
{"Progressive Wallet", 2},
|
|
{"Progressive Sky Book", 7},
|
|
|
|
{"Aurus Memo", 1},
|
|
{"Asheis Sketch", 1},
|
|
{"Renados Letter", 1},
|
|
{"Zora Armor", 1},
|
|
{"Hylian Shield", 1},
|
|
{"Ordon Shield", 1},
|
|
{"Empty Bottle", 4},
|
|
{"Progressive Hidden Skill", 1},
|
|
{"Poe Soul", 60},
|
|
|
|
{"Progressive Fused Shadow", 3},
|
|
{"Progressive Mirror Shard", 4},
|
|
|
|
// Golden Bugs
|
|
{"Male Ant", 1},
|
|
{"Female Ant", 1},
|
|
{"Male Beetle", 1},
|
|
{"Female Beetle", 1},
|
|
{"Male Pill Bug", 1},
|
|
{"Female Pill Bug", 1},
|
|
{"Male Phasmid", 1},
|
|
{"Female Phasmid", 1},
|
|
{"Male Grasshopper", 1},
|
|
{"Female Grasshopper", 1},
|
|
{"Male Stag Beetle", 1},
|
|
{"Female Stag Beetle", 1},
|
|
{"Male Butterfly", 1},
|
|
{"Female Butterfly", 1},
|
|
{"Male Ladybug", 1},
|
|
{"Female Ladybug", 1},
|
|
{"Male Mantis", 1},
|
|
{"Female Mantis", 1},
|
|
{"Male Dragonfly", 1},
|
|
{"Female Dragonfly", 1},
|
|
{"Male Dayfly", 1},
|
|
{"Female Dayfly", 1},
|
|
{"Male Snail", 1},
|
|
{"Female Snail", 1},
|
|
|
|
// Keys
|
|
{"Gate Keys", 1},
|
|
{"Gerudo Desert Bulblin Camp Key", 1},
|
|
{"North Faron Woods Gate Key", 1},
|
|
{"Forest Temple Small Key", 4},
|
|
{"Goron Mines Small Key", 3},
|
|
{"Lakebed Temple Small Key", 3},
|
|
{"Arbiters Grounds Small Key", 5},
|
|
{"Snowpeak Ruins Small Key", 4},
|
|
{"Ordon Pumpkin", 1},
|
|
{"Ordon Cheese", 1},
|
|
{"Temple of Time Small Key", 3},
|
|
{"City in the Sky Small Key", 1},
|
|
{"Palace of Twilight Small Key", 7},
|
|
{"Hyrule Castle Small Key", 3},
|
|
|
|
// Big Keys
|
|
{"Forest Temple Big Key", 1},
|
|
{"Goron Mines Key Shard", 3},
|
|
{"Lakebed Temple Big Key", 1},
|
|
{"Arbiters Grounds Big Key", 1},
|
|
{"Snowpeak Ruins Bedroom Key", 1},
|
|
{"Temple of Time Big Key", 1},
|
|
{"City in the Sky Big Key", 1},
|
|
{"Palace of Twilight Big Key", 1},
|
|
{"Hyrule Castle Big Key", 1},
|
|
|
|
// Maps and Compasses
|
|
{"Forest Temple Compass", 1},
|
|
{"Goron Mines Compass", 1},
|
|
{"Lakebed Temple Compass", 1},
|
|
{"Arbiters Grounds Compass", 1},
|
|
{"Snowpeak Ruins Compass", 1},
|
|
{"Temple of Time Compass", 1},
|
|
{"City in the Sky Compass", 1},
|
|
{"Palace of Twilight Compass", 1},
|
|
{"Hyrule Castle Compass", 1},
|
|
{"Forest Temple Dungeon Map", 1},
|
|
{"Goron Mines Dungeon Map", 1},
|
|
{"Lakebed Temple Dungeon Map", 1},
|
|
{"Arbiters Grounds Dungeon Map", 1},
|
|
{"Snowpeak Ruins Dungeon Map", 1},
|
|
{"Temple of Time Dungeon Map", 1},
|
|
{"City in the Sky Dungeon Map", 1},
|
|
{"Palace of Twilight Dungeon Map", 1},
|
|
{"Hyrule Castle Dungeon Map", 1},
|
|
|
|
// Junk we should always have
|
|
{"Purple Rupee Links House", 1},
|
|
{"Green Rupee", 2},
|
|
{"Orange Rupee", 50},
|
|
{"Silver Rupee", 2},
|
|
};
|
|
|
|
// This is intended to be added on top of the minimal item pool
|
|
std::map<std::string, int> standardItemPool = {
|
|
{"Bomb Bag", 2},
|
|
{"Progressive Bow", 2},
|
|
{"Progressive Wallet", 1},
|
|
{"Magic Armor", 1},
|
|
{"Hawkeye", 1},
|
|
{"Giant Bomb Bag", 1},
|
|
{"Horse Call", 1},
|
|
// {"Bottle with Half Milk", 1}, // Special bottles replace Empty Bottles after the fill algorithm is done
|
|
// {"Bottle with Lantern Oil", 1},
|
|
// {"Bottle with Great Fairies Tears", 1},
|
|
{"Progressive Hidden Skill", 6},
|
|
|
|
{"Heart Container", 8},
|
|
{"Piece of Heart", 45},
|
|
};
|
|
|
|
// This is intended to be added on top of the minimal and standard pools
|
|
std::map<std::string, int> plentifulItemPool = {
|
|
{"Shadow Crystal", 1},
|
|
{"Slingshot", 1},
|
|
{"Lantern", 1},
|
|
{"Gale Boomerang", 1},
|
|
{"Iron Boots", 1},
|
|
{"Bomb Bag", 1},
|
|
{"Spinner", 1},
|
|
{"Ball and Chain", 1},
|
|
|
|
{"Progressive Fishing Rod", 1},
|
|
{"Progressive Sword", 4},
|
|
{"Progressive Bow", 1},
|
|
{"Progressive Clawshot", 1},
|
|
{"Progressive Dominion Rod", 1},
|
|
{"Progressive Wallet", 1},
|
|
{"Progressive Sky Book", 1},
|
|
|
|
{"Aurus Memo", 1},
|
|
{"Asheis Sketch", 1},
|
|
// {"Renados Letter", 1}, Vanilla until flag issues are figured out
|
|
{"Zora Armor", 1},
|
|
{"Magic Armor", 1},
|
|
{"Hylian Shield", 1},
|
|
{"Empty Bottle", 1},
|
|
{"Progressive Hidden Skill", 1},
|
|
|
|
// Keys
|
|
{"Gate Keys", 1},
|
|
{"Forest Temple Small Key", 1},
|
|
{"Goron Mines Small Key", 1},
|
|
{"Lakebed Temple Small Key", 1},
|
|
{"Arbiters Grounds Small Key", 1},
|
|
{"Snowpeak Ruins Small Key", 1},
|
|
{"Ordon Pumpkin", 1},
|
|
{"Ordon Cheese", 1},
|
|
{"Temple of Time Small Key", 1},
|
|
{"City in the Sky Small Key", 1},
|
|
{"Palace of Twilight Small Key", 1},
|
|
{"Hyrule Castle Small Key", 1},
|
|
|
|
// Big Keys
|
|
{"Forest Temple Big Key", 1},
|
|
{"Goron Mines Key Shard", 1},
|
|
{"Lakebed Temple Big Key", 1},
|
|
{"Arbiters Grounds Big Key", 1},
|
|
{"Snowpeak Ruins Bedroom Key", 1},
|
|
{"Temple of Time Big Key", 1},
|
|
{"City in the Sky Big Key", 1},
|
|
{"Palace of Twilight Big Key", 1},
|
|
{"Hyrule Castle Big Key", 1},
|
|
};
|
|
|
|
std::map<std::string, int> initialJunkPool = {
|
|
{"Bombs 5", 8},
|
|
{"Bombs 10", 2},
|
|
{"Bombs 20", 1},
|
|
{"Bombs 30", 1},
|
|
{"Arrows 10", 13},
|
|
{"Arrows 20", 6},
|
|
{"Arrows 30", 2},
|
|
{"Seeds 50", 2},
|
|
{"Water Bombs 5", 3},
|
|
{"Water Bombs 10", 5},
|
|
{"Water Bombs 15", 3},
|
|
{"Bomblings 5", 2},
|
|
{"Bomblings 10", 2},
|
|
{"Blue Rupee", 1},
|
|
{"Yellow Rupee", 6},
|
|
{"Red Rupee", 6},
|
|
{"Purple Rupee", 12},
|
|
};
|
|
|
|
void GenerateItemPool(world::World* world)
|
|
{
|
|
auto itemPool = minimalItemPool;
|
|
|
|
// Minimal item pool things
|
|
if (world->Setting("Item Scarcity") == "Minimal")
|
|
{
|
|
// If glitched logic, include magic armor
|
|
}
|
|
|
|
// Add the vanilla item pool if necessary
|
|
if (world->Setting("Item Scarcity").IsAnyOf("Vanilla", "Plentiful"))
|
|
{
|
|
for (const auto& [itemName, count] : standardItemPool)
|
|
{
|
|
itemPool[itemName] += count;
|
|
}
|
|
}
|
|
|
|
// Add the plentiful item pool if necessary
|
|
if (world->Setting("Item Scarcity") == "Plentiful")
|
|
{
|
|
for (const auto& [itemName, count] : plentifulItemPool)
|
|
{
|
|
itemPool[itemName] += count;
|
|
}
|
|
}
|
|
|
|
// Remove the North Faron Woods Gate Key if we're skipping prologue
|
|
if (world->Setting("Skip Prologue") == "On")
|
|
{
|
|
itemPool.at("North Faron Woods Gate Key") = 0;
|
|
}
|
|
|
|
// Remove the bulblin camp key if we're skipping bulblin camp
|
|
if (world->Setting("Arbiters Does Not Require Bulblin Camp") == "On")
|
|
{
|
|
itemPool.at("Gerudo Desert Bulblin Camp Key") = 0;
|
|
}
|
|
|
|
// Remove sky book characters if we're starting with the sky canon open
|
|
if (world->Setting("City Does Not Require Filled Skybook") == "On")
|
|
{
|
|
itemPool.at("Progressive Sky Book") = 0;
|
|
}
|
|
|
|
// Remove Small Keys if we're playing without them
|
|
if (world->Setting("Small Keys") == "Keysy")
|
|
{
|
|
std::list<std::string> smallKeys = {
|
|
{"Gate Keys"},
|
|
{"Forest Temple Small Key"},
|
|
{"Goron Mines Small Key"},
|
|
{"Lakebed Temple Small Key"},
|
|
{"Arbiters Grounds Small Key"},
|
|
{"Snowpeak Ruins Small Key"},
|
|
{"Ordon Pumpkin"},
|
|
{"Ordon Cheese"},
|
|
{"Temple of Time Small Key"},
|
|
{"City in the Sky Small Key"},
|
|
{"Palace of Twilight Small Key"},
|
|
{"Hyrule Castle Small Key"},
|
|
};
|
|
for (const auto& key : smallKeys)
|
|
{
|
|
itemPool.at(key) = 0;
|
|
}
|
|
}
|
|
|
|
// Remove Big Keys if we're playing without them
|
|
if (world->Setting("Big Keys") == "Keysy")
|
|
{
|
|
std::list<std::string> bigKeys = {
|
|
{"Forest Temple Big Key"},
|
|
{"Goron Mines Key Shard"},
|
|
{"Lakebed Temple Big Key"},
|
|
{"Arbiters Grounds Big Key"},
|
|
{"Snowpeak Ruins Bedroom Key"},
|
|
{"Temple of Time Big Key"},
|
|
{"City in the Sky Big Key"},
|
|
{"Palace of Twilight Big Key"},
|
|
};
|
|
|
|
if (world->Setting("Hyrule Castle Big Key Requirements") == "None")
|
|
{
|
|
bigKeys.emplace_back("Hyrule Castle Big Key");
|
|
}
|
|
|
|
for (const auto& key : bigKeys)
|
|
{
|
|
itemPool.at(key) = 0;
|
|
}
|
|
}
|
|
|
|
// Add items to the world's _itemPool
|
|
auto& worldItemPool = world->GetItemPool();
|
|
for (const auto& [itemName, count] : itemPool)
|
|
{
|
|
auto item = world->GetItem(itemName);
|
|
for (auto i = 0; i < count; i++)
|
|
{
|
|
worldItemPool.push_back(item);
|
|
}
|
|
}
|
|
}
|
|
|
|
void GenerateStartingItemPool(world::World* world)
|
|
{
|
|
auto startingItems = world->GetSettings().GetStartingInventory();
|
|
auto& startingItemPool = world->GetStartingItemPool();
|
|
auto& itemPool = world->GetItemPool();
|
|
|
|
// Add Maps and Compasses to starting items if we start with them
|
|
if (world->Setting("Maps and Compasses") == "Start With")
|
|
{
|
|
std::list<std::string> mapsAndCompasses = {
|
|
{"Forest Temple Compass"},
|
|
{"Goron Mines Compass"},
|
|
{"Lakebed Temple Compass"},
|
|
{"Arbiters Grounds Compass"},
|
|
{"Snowpeak Ruins Compass"},
|
|
{"Temple of Time Compass"},
|
|
{"City in the Sky Compass"},
|
|
{"Palace of Twilight Compass"},
|
|
{"Hyrule Castle Compass"},
|
|
{"Forest Temple Dungeon Map"},
|
|
{"Goron Mines Dungeon Map"},
|
|
{"Lakebed Temple Dungeon Map"},
|
|
{"Arbiters Grounds Dungeon Map"},
|
|
{"Snowpeak Ruins Dungeon Map"},
|
|
{"Temple of Time Dungeon Map"},
|
|
{"City in the Sky Dungeon Map"},
|
|
{"Palace of Twilight Dungeon Map"},
|
|
{"Hyrule Castle Dungeon Map"},
|
|
};
|
|
|
|
for (const auto& itemName : mapsAndCompasses)
|
|
{
|
|
startingItems[itemName] = 1;
|
|
}
|
|
}
|
|
|
|
// Add each item to the world's _startingItemPool and erase it from the regular _itemPool
|
|
for (const auto& [itemName, count] : startingItems)
|
|
{
|
|
auto item = world->GetItem(itemName);
|
|
for (auto i = 0; i < count; i++)
|
|
{
|
|
startingItemPool.push_back(item);
|
|
}
|
|
randomizer::utility::container::Erase(itemPool, item, count);
|
|
}
|
|
}
|
|
|
|
std::map<std::string, int> GetInitialJunkPool()
|
|
{
|
|
return initialJunkPool;
|
|
}
|
|
|
|
ItemPool GetCompleteItemPool(const world::WorldPool& worlds)
|
|
{
|
|
ItemPool completeItemPool = {};
|
|
for (const auto& world : worlds)
|
|
{
|
|
auto& worldItemPool = world->GetItemPool();
|
|
std::ranges::copy(worldItemPool, std::back_inserter(completeItemPool));
|
|
}
|
|
|
|
return completeItemPool;
|
|
}
|
|
} // namespace randomizer::logic::item_pool
|