Choose Link's Pocket Dungeon Reward Type (#6213)
This commit is contained in:
@@ -944,24 +944,21 @@ static void AssumedFill(const std::vector<RandomizerGet>& items, const std::vect
|
||||
// setting, or randomize one dungeon reward to Link's Pocket if that setting is on
|
||||
static void RandomizeDungeonRewards() {
|
||||
auto ctx = Rando::Context::GetInstance();
|
||||
// quest item bit mask of each stone/medallion for the savefile
|
||||
// static constexpr std::array<uint32_t, 9> bitMaskTable = {
|
||||
// 0x00040000, //Kokiri Emerald
|
||||
// 0x00080000, //Goron Ruby
|
||||
// 0x00100000, //Zora Sapphire
|
||||
// 0x00000001, //Forest Medallion
|
||||
// 0x00000002, //Fire Medallion
|
||||
// 0x00000004, //Water Medallion
|
||||
// 0x00000008, //Spirit Medallion
|
||||
// 0x00000010, //Shadow Medallion
|
||||
// 0x00000020, //Light Medallion
|
||||
// };
|
||||
int baseOffset = Rando::StaticData::RetrieveItem(RG_KOKIRI_EMERALD).GetItemID();
|
||||
|
||||
// End of Dungeons includes Link's Pocket
|
||||
if (ctx->GetOption(RSK_SHUFFLE_DUNGEON_REWARDS).Is(RO_DUNGEON_REWARDS_END_OF_DUNGEON) ||
|
||||
ctx->GetOption(RSK_SHUFFLE_DUNGEON_REWARDS).Is(RO_DUNGEON_REWARDS_VANILLA)) {
|
||||
// get stones and medallions
|
||||
// make temporary pools of stones and medallions, get rewards
|
||||
std::vector<RandomizerGet> stones = FilterFromPool(itemPool, [](const auto i) {
|
||||
return Rando::StaticData::RetrieveItem(i).GetItemType() == ITEMTYPE_DUNGEONREWARD &&
|
||||
Rando::StaticData::RetrieveItem(i).GetRandomizerGet() >= RG_KOKIRI_EMERALD &&
|
||||
Rando::StaticData::RetrieveItem(i).GetRandomizerGet() <= RG_ZORA_SAPPHIRE;
|
||||
});
|
||||
std::vector<RandomizerGet> medallions = FilterFromPool(itemPool, [](const auto i) {
|
||||
return Rando::StaticData::RetrieveItem(i).GetItemType() == ITEMTYPE_DUNGEONREWARD &&
|
||||
Rando::StaticData::RetrieveItem(i).GetRandomizerGet() >= RG_FOREST_MEDALLION &&
|
||||
Rando::StaticData::RetrieveItem(i).GetRandomizerGet() <= RG_LIGHT_MEDALLION;
|
||||
});
|
||||
std::vector<RandomizerGet> rewards = FilterAndEraseFromPool(itemPool, [](const auto i) {
|
||||
return Rando::StaticData::RetrieveItem(i).GetItemType() == ITEMTYPE_DUNGEONREWARD;
|
||||
});
|
||||
@@ -978,12 +975,38 @@ static void RandomizeDungeonRewards() {
|
||||
if (rewards.size() < 9) {
|
||||
ctx->PlaceItemInLocation(RC_LINKS_POCKET, RG_GREEN_RUPEE);
|
||||
} else {
|
||||
rewardLocations.push_back(RC_LINKS_POCKET);
|
||||
if (ctx->GetOption(RSK_LINKS_POCKET_REWARD).IsNot(RO_LINKS_POCKET_REWARD)) {
|
||||
if (ctx->GetOption(RSK_LINKS_POCKET_REWARD).Is(RO_LINKS_POCKET_STONE)) {
|
||||
// get one stone
|
||||
RandomizerGet startingStone = RandomElement(stones, true);
|
||||
// erase from rewards so remaining are placed
|
||||
erase_if(rewards, [&](RandomizerGet r) { return r == startingStone; });
|
||||
ctx->PlaceItemInLocation(RC_LINKS_POCKET, startingStone);
|
||||
} else {
|
||||
// get one medallion
|
||||
RandomizerGet startingMedallion = RandomElement(medallions, true);
|
||||
// erase from rewards so remaining are placed
|
||||
erase_if(rewards, [&](RandomizerGet r) { return r == startingMedallion; });
|
||||
ctx->PlaceItemInLocation(RC_LINKS_POCKET, startingMedallion);
|
||||
}
|
||||
} else {
|
||||
rewardLocations.push_back(RC_LINKS_POCKET);
|
||||
}
|
||||
}
|
||||
AssumedFill(rewards, rewardLocations);
|
||||
}
|
||||
} else if (ctx->GetOption(RSK_LINKS_POCKET).Is(RO_LINKS_POCKET_DUNGEON_REWARD)) {
|
||||
// get 1 stone/medallion
|
||||
// make temporary pools of stones, medallions, and rewards
|
||||
std::vector<RandomizerGet> stones = FilterFromPool(itemPool, [](const auto i) {
|
||||
return Rando::StaticData::RetrieveItem(i).GetItemType() == ITEMTYPE_DUNGEONREWARD &&
|
||||
Rando::StaticData::RetrieveItem(i).GetRandomizerGet() >= RG_KOKIRI_EMERALD &&
|
||||
Rando::StaticData::RetrieveItem(i).GetRandomizerGet() <= RG_ZORA_SAPPHIRE;
|
||||
});
|
||||
std::vector<RandomizerGet> medallions = FilterFromPool(itemPool, [](const auto i) {
|
||||
return Rando::StaticData::RetrieveItem(i).GetItemType() == ITEMTYPE_DUNGEONREWARD &&
|
||||
Rando::StaticData::RetrieveItem(i).GetRandomizerGet() >= RG_FOREST_MEDALLION &&
|
||||
Rando::StaticData::RetrieveItem(i).GetRandomizerGet() <= RG_LIGHT_MEDALLION;
|
||||
});
|
||||
std::vector<RandomizerGet> rewards = FilterFromPool(itemPool, [](const auto i) {
|
||||
return Rando::StaticData::RetrieveItem(i).GetItemType() == ITEMTYPE_DUNGEONREWARD;
|
||||
});
|
||||
@@ -992,13 +1015,27 @@ static void RandomizeDungeonRewards() {
|
||||
ctx->PlaceItemInLocation(RC_LINKS_POCKET, RG_GREEN_RUPEE);
|
||||
return;
|
||||
}
|
||||
RandomizerGet startingReward = RandomElement(rewards, true);
|
||||
if (ctx->GetOption(RSK_LINKS_POCKET_REWARD).Is(RO_LINKS_POCKET_STONE)) {
|
||||
// get one stone
|
||||
RandomizerGet startingStone = RandomElement(stones, true);
|
||||
ctx->PlaceItemInLocation(RC_LINKS_POCKET, startingStone);
|
||||
// erase stone from item pool
|
||||
FilterAndEraseFromPool(itemPool, [startingStone](const RandomizerGet i) { return i == startingStone; });
|
||||
} else if (ctx->GetOption(RSK_LINKS_POCKET_REWARD).Is(RO_LINKS_POCKET_MEDALLION)) {
|
||||
// get one medallion
|
||||
RandomizerGet startingMedallion = RandomElement(medallions, true);
|
||||
ctx->PlaceItemInLocation(RC_LINKS_POCKET, startingMedallion);
|
||||
// erase medallion from item pool
|
||||
FilterAndEraseFromPool(itemPool,
|
||||
[startingMedallion](const RandomizerGet i) { return i == startingMedallion; });
|
||||
} else {
|
||||
// get one reward
|
||||
RandomizerGet startingReward = RandomElement(rewards, true);
|
||||
|
||||
// LinksPocketRewardBitMask = bitMaskTable[Rando::StaticData::RetrieveItem(startingReward).GetItemID() -
|
||||
// baseOffset];
|
||||
ctx->PlaceItemInLocation(RC_LINKS_POCKET, startingReward);
|
||||
// erase the stone/medallion from the Item Pool
|
||||
FilterAndEraseFromPool(itemPool, [startingReward](const RandomizerGet i) { return i == startingReward; });
|
||||
ctx->PlaceItemInLocation(RC_LINKS_POCKET, startingReward);
|
||||
// erase the stone/medallion from the Item Pool
|
||||
FilterAndEraseFromPool(itemPool, [startingReward](const RandomizerGet i) { return i == startingReward; });
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -397,6 +397,13 @@ RANDO_ENUM_ITEM(RO_LINKS_POCKET_ANYTHING)
|
||||
RANDO_ENUM_ITEM(RO_LINKS_POCKET_NOTHING)
|
||||
RANDO_ENUM_END(RandoOptionLinksPocket)
|
||||
|
||||
// Link's Pocket Dungeon Reward Settings (dungeon reward, stone, medallion)
|
||||
RANDO_ENUM_BEGIN(RandoOptionLinksPocketReward)
|
||||
RANDO_ENUM_ITEM(RO_LINKS_POCKET_REWARD)
|
||||
RANDO_ENUM_ITEM(RO_LINKS_POCKET_STONE)
|
||||
RANDO_ENUM_ITEM(RO_LINKS_POCKET_MEDALLION)
|
||||
RANDO_ENUM_END(RandoOptionLinksPocketReward)
|
||||
|
||||
// Logic (glitchless/no logic)
|
||||
RANDO_ENUM_BEGIN(RandoOptionLogic)
|
||||
RANDO_ENUM_ITEM(RO_LOGIC_GLITCHLESS)
|
||||
|
||||
@@ -166,6 +166,7 @@ RANDO_ENUM_ITEM(RSK_SLINGBOW_BREAK_BEEHIVES)
|
||||
RANDO_ENUM_ITEM(RSK_ENABLE_BOMBCHU_DROPS)
|
||||
RANDO_ENUM_ITEM(RSK_BOMBCHU_BAG)
|
||||
RANDO_ENUM_ITEM(RSK_LINKS_POCKET)
|
||||
RANDO_ENUM_ITEM(RSK_LINKS_POCKET_REWARD)
|
||||
RANDO_ENUM_ITEM(RSK_MQ_DUNGEON_RANDOM)
|
||||
RANDO_ENUM_ITEM(RSK_MQ_DUNGEON_COUNT)
|
||||
RANDO_ENUM_ITEM(RSK_MQ_DUNGEON_SET)
|
||||
|
||||
@@ -574,11 +574,34 @@ void Settings::CreateOptions() {
|
||||
RO_DUNGEON_REWARDS_END_OF_DUNGEON) {
|
||||
mOptions[RSK_LINKS_POCKET].Disable(
|
||||
"This option is disabled because \"Dungeon Rewards\" are shuffled to \"End of Dungeons\".");
|
||||
mOptions[RSK_LINKS_POCKET_REWARD].Enable();
|
||||
mOptions[RSK_LINKS_POCKET_REWARD].Unhide();
|
||||
} else if (CVarGetInteger(CVAR_RANDOMIZER_SETTING("ShuffleDungeonReward"), RO_DUNGEON_REWARDS_END_OF_DUNGEON) ==
|
||||
RO_DUNGEON_REWARDS_VANILLA) {
|
||||
mOptions[RSK_LINKS_POCKET_REWARD].Disable("This option is disabled because \"Dungeon Rewards\" are shuffled to \"Vanilla\".");
|
||||
mOptions[RSK_LINKS_POCKET_REWARD].Hide();
|
||||
mOptions[RSK_LINKS_POCKET].Enable();
|
||||
} else {
|
||||
mOptions[RSK_LINKS_POCKET].Enable();
|
||||
mOptions[RSK_LINKS_POCKET_REWARD].Enable();
|
||||
if (CVarGetInteger(CVAR_RANDOMIZER_SETTING("LinksPocket"), RO_LINKS_POCKET_DUNGEON_REWARD) == RO_LINKS_POCKET_DUNGEON_REWARD) {
|
||||
mOptions[RSK_LINKS_POCKET_REWARD].Unhide();
|
||||
}
|
||||
}
|
||||
});
|
||||
OPT_U8(RSK_LINKS_POCKET, "Link's Pocket", {"Dungeon Reward", "Advancement", "Anything", "Nothing"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("LinksPocket"), "", WIDGET_CVAR_COMBOBOX, RO_LINKS_POCKET_DUNGEON_REWARD);
|
||||
OPT_CALLBACK(RSK_LINKS_POCKET, {
|
||||
// Only show the dungeon reward type if Link's Pocket is set to Dungeon Reward and Dungeon Rewards are not Vanilla, OR Dungeon Rewards are end of dungeon
|
||||
if ((CVarGetInteger(CVAR_RANDOMIZER_SETTING("LinksPocket"), RO_LINKS_POCKET_DUNGEON_REWARD) ==
|
||||
RO_LINKS_POCKET_DUNGEON_REWARD && CVarGetInteger(CVAR_RANDOMIZER_SETTING("ShuffleDungeonReward"), RO_DUNGEON_REWARDS_END_OF_DUNGEON) !=
|
||||
RO_DUNGEON_REWARDS_VANILLA) || CVarGetInteger(CVAR_RANDOMIZER_SETTING("ShuffleDungeonReward"), RO_DUNGEON_REWARDS_END_OF_DUNGEON) ==
|
||||
RO_DUNGEON_REWARDS_END_OF_DUNGEON) {
|
||||
mOptions[RSK_LINKS_POCKET_REWARD].Unhide();
|
||||
} else {
|
||||
mOptions[RSK_LINKS_POCKET_REWARD].Hide();
|
||||
}
|
||||
});
|
||||
OPT_U8(RSK_LINKS_POCKET_REWARD, "Link's Pocket Reward Type", {"Dungeon Reward", "Stone", "Medallion"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("LinksPocketReward"), "", WIDGET_CVAR_COMBOBOX, RO_LINKS_POCKET_REWARD);
|
||||
OPT_U8(RSK_SHUFFLE_SONGS, "Shuffle Songs", {"Off", "Song Locations", "Dungeon Rewards", "Anywhere"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("ShuffleSongs"), mOptionDescriptions[RSK_SHUFFLE_SONGS], WIDGET_CVAR_COMBOBOX, RO_SONG_SHUFFLE_SONG_LOCATIONS);
|
||||
OPT_U8(RSK_SHOPSANITY, "Shop Shuffle", {"Off", "Specific Count", "Random"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("Shopsanity"), mOptionDescriptions[RSK_SHOPSANITY], WIDGET_CVAR_COMBOBOX, RO_SHOPSANITY_OFF);
|
||||
OPT_CALLBACK(RSK_SHOPSANITY, {
|
||||
@@ -2547,11 +2570,11 @@ void Settings::CreateOptions() {
|
||||
&mOptionGroups[RSG_MENU_COLUMN_STATIC_HINTS],
|
||||
},
|
||||
WidgetContainerType::TABLE);
|
||||
mOptionGroups[RSG_MENU_SECTION_STARTING_EQUIPS] =
|
||||
OptionGroup::SubGroup("Equips",
|
||||
{ &mOptions[RSK_LINKS_POCKET], &mOptions[RSK_STARTING_KOKIRI_SWORD],
|
||||
&mOptions[RSK_STARTING_MASTER_SWORD], &mOptions[RSK_STARTING_DEKU_SHIELD] },
|
||||
WidgetContainerType::SECTION);
|
||||
mOptionGroups[RSG_MENU_SECTION_STARTING_EQUIPS] = OptionGroup::SubGroup(
|
||||
"Equips",
|
||||
{ &mOptions[RSK_LINKS_POCKET], &mOptions[RSK_LINKS_POCKET_REWARD], &mOptions[RSK_STARTING_KOKIRI_SWORD],
|
||||
&mOptions[RSK_STARTING_MASTER_SWORD], &mOptions[RSK_STARTING_DEKU_SHIELD] },
|
||||
WidgetContainerType::SECTION);
|
||||
mOptionGroups[RSG_MENU_SECTION_STARTING_ITEMS] = OptionGroup::SubGroup("Items",
|
||||
{
|
||||
&mOptions[RSK_STARTING_OCARINA],
|
||||
|
||||
Reference in New Issue
Block a user