mirror of
https://github.com/HarbourMasters/Shipwright
synced 2026-06-20 16:21:55 -04:00
Complete rando starting items, make icon based like save editor (#6723)
This commit is contained in:
@@ -1242,19 +1242,13 @@ void DrawUpgradeIcon(const std::string& categoryName, int32_t categoryId, const
|
||||
PushStyleButton(Colors::DarkGray);
|
||||
auto value = (size_t)CUR_UPG_VALUE(categoryId);
|
||||
uint8_t item = value < items.size() ? items[value] : ITEM_NONE;
|
||||
if (item != ITEM_NONE) {
|
||||
const ItemMapEntry& slotEntry = itemMapping[item];
|
||||
if (ImGui::ImageButton(
|
||||
slotEntry.name.c_str(),
|
||||
std::dynamic_pointer_cast<Fast::Fast3dGui>(Ship::Context::GetRawInstance()->GetWindow()->GetGui())
|
||||
->GetTextureByName(slotEntry.name),
|
||||
ImVec2(IMAGE_SIZE, IMAGE_SIZE), ImVec2(0, 0), ImVec2(1, 1))) {
|
||||
ImGui::OpenPopup(upgradePopupPicker);
|
||||
}
|
||||
} else {
|
||||
if (ImGui::Button("##itemNone", ImVec2(IMAGE_SIZE, IMAGE_SIZE) + ImGui::GetStyle().FramePadding * 2)) {
|
||||
ImGui::OpenPopup(upgradePopupPicker);
|
||||
}
|
||||
const ItemMapEntry& slotEntry = itemMapping[item];
|
||||
if (ImGui::ImageButton(
|
||||
slotEntry.name.c_str(),
|
||||
std::dynamic_pointer_cast<Fast::Fast3dGui>(Ship::Context::GetRawInstance()->GetWindow()->GetGui())
|
||||
->GetTextureByName(item != ITEM_NONE ? slotEntry.name : itemMapping[items[1]].nameFaded),
|
||||
ImVec2(IMAGE_SIZE, IMAGE_SIZE), ImVec2(0, 0), ImVec2(1, 1))) {
|
||||
ImGui::OpenPopup(upgradePopupPicker);
|
||||
}
|
||||
PopStyleButton();
|
||||
Tooltip(categoryName.c_str());
|
||||
|
||||
@@ -757,7 +757,10 @@ void CreateStaticItemHint(RandomizerHint hintKey, std::vector<RandomizerHintText
|
||||
// RANDOTODO choose area in case there are multiple
|
||||
auto ctx = Rando::Context::GetInstance();
|
||||
std::vector<RandomizerCheck> locations = FindItemsAndMarkHinted(items, hintChecks);
|
||||
std::vector<RandomizerArea> areas = {};
|
||||
locations.erase(
|
||||
std::remove_if(locations.begin(), locations.end(), [](const auto rc) { return rc == RC_UNKNOWN_CHECK; }));
|
||||
std::vector<RandomizerArea> areas;
|
||||
areas.reserve(locations.size());
|
||||
for (auto loc : locations) {
|
||||
areas.push_back(ctx->GetItemLocation(loc)->GetRandomArea());
|
||||
}
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
#include "spoiler_log.hpp"
|
||||
#include "soh/Enhancements/randomizer/Traps.h"
|
||||
#include "z64item.h"
|
||||
#include <algorithm>
|
||||
#include <spdlog/spdlog.h>
|
||||
|
||||
std::vector<RandomizerGet> itemPool = {};
|
||||
@@ -157,26 +158,29 @@ void GenerateItemPool() {
|
||||
int reservedSlots = 0;
|
||||
|
||||
// clang-format off
|
||||
AddItemToPool(RG_BOOMERANG, 2, 1, 1, 1);
|
||||
AddItemToPool(RG_LENS_OF_TRUTH, 2, 1, 1, 1);
|
||||
AddItemToPool(RG_MEGATON_HAMMER, 2, 1, 1, 1);
|
||||
AddItemToPool(RG_IRON_BOOTS, 2, 1, 1, 1);
|
||||
AddItemToPool(RG_GORON_TUNIC, 2, 1, 1, 1);
|
||||
AddItemToPool(RG_ZORA_TUNIC, 2, 1, 1, 1);
|
||||
AddItemToPool(RG_HOVER_BOOTS, 2, 1, 1, 1);
|
||||
AddItemToPool(RG_MIRROR_SHIELD, 2, 1, 1, 1);
|
||||
AddItemToPool(RG_STONE_OF_AGONY, 2, 1, 1, 1);
|
||||
AddItemToPool(RG_FIRE_ARROWS, 2, 1, 1, 1);
|
||||
AddItemToPool(RG_ICE_ARROWS, 2, 1, 1, 1);
|
||||
AddItemToPool(RG_LIGHT_ARROWS, 2, 1, 1, 1);
|
||||
AddItemToPool(RG_DINS_FIRE, 2, 1, 1, 1);
|
||||
AddItemToPool(RG_FARORES_WIND, 2, 1, 1, 0);
|
||||
AddItemToPool(RG_NAYRUS_LOVE, 2, 1, 1, 0);
|
||||
// Items the player can start with are removed from the pool so a started copy isn't also shuffled.
|
||||
if (!ctx->GetOption(RSK_STARTING_BOOMERANG)) AddItemToPool(RG_BOOMERANG, 2, 1, 1, 1);
|
||||
if (!ctx->GetOption(RSK_STARTING_LENS_OF_TRUTH)) AddItemToPool(RG_LENS_OF_TRUTH, 2, 1, 1, 1);
|
||||
if (!ctx->GetOption(RSK_STARTING_MEGATON_HAMMER)) AddItemToPool(RG_MEGATON_HAMMER, 2, 1, 1, 1);
|
||||
if (!ctx->GetOption(RSK_STARTING_IRON_BOOTS)) AddItemToPool(RG_IRON_BOOTS, 2, 1, 1, 1);
|
||||
if (!ctx->GetOption(RSK_STARTING_GORON_TUNIC)) AddItemToPool(RG_GORON_TUNIC, 2, 1, 1, 1);
|
||||
if (!ctx->GetOption(RSK_STARTING_ZORA_TUNIC)) AddItemToPool(RG_ZORA_TUNIC, 2, 1, 1, 1);
|
||||
if (!ctx->GetOption(RSK_STARTING_HOVER_BOOTS)) AddItemToPool(RG_HOVER_BOOTS, 2, 1, 1, 1);
|
||||
if (!ctx->GetOption(RSK_STARTING_MIRROR_SHIELD)) AddItemToPool(RG_MIRROR_SHIELD, 2, 1, 1, 1);
|
||||
if (!ctx->GetOption(RSK_STARTING_STONE_OF_AGONY)) AddItemToPool(RG_STONE_OF_AGONY, 2, 1, 1, 1);
|
||||
if (!ctx->GetOption(RSK_STARTING_FIRE_ARROWS)) AddItemToPool(RG_FIRE_ARROWS, 2, 1, 1, 1);
|
||||
if (!ctx->GetOption(RSK_STARTING_ICE_ARROWS)) AddItemToPool(RG_ICE_ARROWS, 2, 1, 1, 1);
|
||||
if (!ctx->GetOption(RSK_STARTING_LIGHT_ARROWS)) AddItemToPool(RG_LIGHT_ARROWS, 2, 1, 1, 1);
|
||||
if (!ctx->GetOption(RSK_STARTING_DINS_FIRE)) AddItemToPool(RG_DINS_FIRE, 2, 1, 1, 1);
|
||||
if (!ctx->GetOption(RSK_STARTING_FARORES_WIND)) AddItemToPool(RG_FARORES_WIND, 2, 1, 1, 0);
|
||||
if (!ctx->GetOption(RSK_STARTING_NAYRUS_LOVE)) AddItemToPool(RG_NAYRUS_LOVE, 2, 1, 1, 0);
|
||||
AddItemToPool(RG_GREG_RUPEE, 1, 1, 1, 1);
|
||||
AddItemToPool(RG_PROGRESSIVE_HOOKSHOT, 2, 2, 2, 2);
|
||||
AddItemToPool(RG_HYLIAN_SHIELD, 1, 1, 1, 1);
|
||||
AddFixedItemToPool(RG_PROGRESSIVE_HOOKSHOT, 2 - ctx->GetOption(RSK_STARTING_HOOKSHOT).Get());
|
||||
if (!ctx->GetOption(RSK_STARTING_HYLIAN_SHIELD)) AddItemToPool(RG_HYLIAN_SHIELD, 1, 1, 1, 1);
|
||||
AddItemToPool(RG_DOUBLE_DEFENSE, 2, 1, 0, 0);
|
||||
AddItemToPool(RG_BIGGORON_SWORD, 2, 1, 1, 0);
|
||||
if (ctx->GetOption(RSK_STARTING_BIGGORON_SWORD).IsNot(RO_STARTING_BGS_BIGGORON_SWORD)) {
|
||||
AddItemToPool(RG_BIGGORON_SWORD, 2, 1, 1, 0);
|
||||
}
|
||||
bool isScrubs = ctx->GetOption(RSK_SHUFFLE_SCRUBS).Is(RO_SCRUBS_ALL);
|
||||
AddFixedItemToPool(RG_DEKU_SHIELD, isScrubs ? 1 : 2);
|
||||
AddFixedItemToPool(RG_RECOVERY_HEART, isScrubs ? 6 : 11);
|
||||
@@ -199,30 +203,37 @@ void GenerateItemPool() {
|
||||
}
|
||||
}
|
||||
|
||||
// Progressive items the player starts with are removed from the pool, subtracting the starting
|
||||
// tier from each count (clamped to 0 so smaller pools don't underflow).
|
||||
int infiniteProgressive = ctx->GetOption(RSK_INFINITE_UPGRADES).Is(RO_INF_UPGRADES_PROGRESSIVE) ? 1 : 0;
|
||||
AddItemToPool(RG_PROGRESSIVE_BOW, 4 + infiniteProgressive,
|
||||
3 + infiniteProgressive,
|
||||
2 + infiniteProgressive,
|
||||
1 + infiniteProgressive);
|
||||
AddItemToPool(RG_PROGRESSIVE_SLINGSHOT, 4 + infiniteProgressive,
|
||||
3 + infiniteProgressive,
|
||||
2 + infiniteProgressive,
|
||||
1 + infiniteProgressive);
|
||||
AddItemToPool(RG_PROGRESSIVE_BOMB_BAG, 4 + infiniteProgressive,
|
||||
3 + infiniteProgressive,
|
||||
2 + infiniteProgressive,
|
||||
1 + infiniteProgressive);
|
||||
AddItemToPool(RG_PROGRESSIVE_MAGIC_METER, 3 + infiniteProgressive,
|
||||
2 + infiniteProgressive,
|
||||
1 + infiniteProgressive,
|
||||
1 + infiniteProgressive);
|
||||
int startBow = ctx->GetOption(RSK_STARTING_BOW).Get();
|
||||
AddItemToPool(RG_PROGRESSIVE_BOW, std::max(0, 4 + infiniteProgressive - startBow),
|
||||
std::max(0, 3 + infiniteProgressive - startBow),
|
||||
std::max(0, 2 + infiniteProgressive - startBow),
|
||||
std::max(0, 1 + infiniteProgressive - startBow));
|
||||
int startSlingshot = ctx->GetOption(RSK_STARTING_SLINGSHOT).Get();
|
||||
AddItemToPool(RG_PROGRESSIVE_SLINGSHOT, std::max(0, 4 + infiniteProgressive - startSlingshot),
|
||||
std::max(0, 3 + infiniteProgressive - startSlingshot),
|
||||
std::max(0, 2 + infiniteProgressive - startSlingshot),
|
||||
std::max(0, 1 + infiniteProgressive - startSlingshot));
|
||||
int startBombBag = ctx->GetOption(RSK_STARTING_BOMB_BAG).Get();
|
||||
AddItemToPool(RG_PROGRESSIVE_BOMB_BAG, std::max(0, 4 + infiniteProgressive - startBombBag),
|
||||
std::max(0, 3 + infiniteProgressive - startBombBag),
|
||||
std::max(0, 2 + infiniteProgressive - startBombBag),
|
||||
std::max(0, 1 + infiniteProgressive - startBombBag));
|
||||
int startMagic = ctx->GetOption(RSK_STARTING_MAGIC_METER).Get();
|
||||
AddItemToPool(RG_PROGRESSIVE_MAGIC_METER, std::max(0, 3 + infiniteProgressive - startMagic),
|
||||
std::max(0, 2 + infiniteProgressive - startMagic),
|
||||
std::max(0, 1 + infiniteProgressive - startMagic),
|
||||
std::max(0, 1 + infiniteProgressive - startMagic));
|
||||
//clang-format on
|
||||
|
||||
int extraWallets =(ctx->GetOption(RSK_SHUFFLE_CHILD_WALLET) ? 1 : 0) + (ctx->GetOption(RSK_INCLUDE_TYCOON_WALLET) ? 1 : 0);
|
||||
AddItemToPool(RG_PROGRESSIVE_WALLET, 3 + infiniteProgressive + extraWallets,
|
||||
2 + infiniteProgressive + extraWallets,
|
||||
2 + infiniteProgressive + extraWallets,
|
||||
2 + infiniteProgressive + extraWallets);
|
||||
int startWallet = ctx->GetOption(RSK_STARTING_WALLET).Get();
|
||||
AddItemToPool(RG_PROGRESSIVE_WALLET, std::max(0, 3 + infiniteProgressive + extraWallets - startWallet),
|
||||
std::max(0, 2 + infiniteProgressive + extraWallets - startWallet),
|
||||
std::max(0, 2 + infiniteProgressive + extraWallets - startWallet),
|
||||
std::max(0, 2 + infiniteProgressive + extraWallets - startWallet));
|
||||
|
||||
int stickShuffle = ctx->GetOption(RSK_SHUFFLE_DEKU_STICK_BAG) ? 1 : 0;
|
||||
AddItemToPool(RG_PROGRESSIVE_STICK_UPGRADE, 3 + infiniteProgressive + stickShuffle,
|
||||
@@ -236,13 +247,17 @@ void GenerateItemPool() {
|
||||
1 + infiniteProgressive + nutShuffle,
|
||||
0 + infiniteProgressive + nutShuffle);
|
||||
|
||||
int startBombchu = ctx->GetOption(RSK_STARTING_BOMBCHU_BAG).Get();
|
||||
if (ctx->GetOption(RSK_BOMBCHU_BAG).Is(RO_BOMBCHU_BAG_SINGLE)) {
|
||||
AddItemToPool(RG_PROGRESSIVE_BOMBCHU_BAG, 6, 5, 3, 1);
|
||||
// Single mode has only one bag; starting with it removes one copy from the pool.
|
||||
int startSingle = startBombchu > 0 ? 1 : 0;
|
||||
AddItemToPool(RG_PROGRESSIVE_BOMBCHU_BAG, std::max(0, 6 - startSingle), std::max(0, 5 - startSingle),
|
||||
std::max(0, 3 - startSingle), std::max(0, 1 - startSingle));
|
||||
} else if (ctx->GetOption(RSK_BOMBCHU_BAG).Is(RO_BOMBCHU_BAG_PROGRESSIVE)) {
|
||||
AddItemToPool(RG_PROGRESSIVE_BOMBCHU_BAG, 4 + infiniteProgressive,
|
||||
3 + infiniteProgressive,
|
||||
2 + infiniteProgressive,
|
||||
1 + infiniteProgressive);
|
||||
AddItemToPool(RG_PROGRESSIVE_BOMBCHU_BAG, std::max(0, 4 + infiniteProgressive - startBombchu),
|
||||
std::max(0, 3 + infiniteProgressive - startBombchu),
|
||||
std::max(0, 2 + infiniteProgressive - startBombchu),
|
||||
std::max(0, 1 + infiniteProgressive - startBombchu));
|
||||
} else {
|
||||
AddItemToPool(RG_BOMBCHU_20, 2, 1, 0, 0);
|
||||
AddItemToPool(RG_BOMBCHU_10, 3, 3, 2, 0);
|
||||
@@ -353,7 +368,9 @@ void GenerateItemPool() {
|
||||
}
|
||||
|
||||
if (ctx->GetOption(RSK_SHUFFLE_WEIRD_EGG)) {
|
||||
AddItemToPool(RG_WEIRD_EGG, 2, 1, 1, 1);
|
||||
if (!ctx->GetOption(RSK_STARTING_WEIRD_EGG)) {
|
||||
AddItemToPool(RG_WEIRD_EGG, 2, 1, 1, 1);
|
||||
}
|
||||
} else {
|
||||
ctx->PlaceItemInLocation(RC_HC_MALON_EGG, RG_WEIRD_EGG, false, true);
|
||||
}
|
||||
@@ -390,7 +407,7 @@ void GenerateItemPool() {
|
||||
AddItemToPool(RG_KEATON_MASK, 2, 1, 1, 1);
|
||||
AddItemToPool(RG_SKULL_MASK, 2, 1, 1, 1);
|
||||
AddItemToPool(RG_SPOOKY_MASK, 2, 1, 1, 1);
|
||||
AddItemToPool(RG_BUNNY_HOOD, 2, 1, 1, 1);
|
||||
if (!ctx->GetOption(RSK_STARTING_BUNNY_HOOD)) AddItemToPool(RG_BUNNY_HOOD, 2, 1, 1, 1);
|
||||
AddItemToPool(RG_GORON_MASK, 2, 1, 1, 1);
|
||||
AddItemToPool(RG_ZORA_MASK, 2, 1, 1, 1);
|
||||
AddItemToPool(RG_GERUDO_MASK, 2, 1, 1, 1);
|
||||
@@ -402,9 +419,13 @@ void GenerateItemPool() {
|
||||
}
|
||||
|
||||
int bronzeScale = ctx->GetOption(RSK_SHUFFLE_SWIM) ? 1 : 0;
|
||||
AddItemToPool(RG_PROGRESSIVE_SCALE, 3 + bronzeScale, 2 + bronzeScale, 2 + bronzeScale, 2 + bronzeScale);
|
||||
int startScale = ctx->GetOption(RSK_STARTING_SCALE).Get();
|
||||
AddItemToPool(RG_PROGRESSIVE_SCALE, std::max(0, 3 + bronzeScale - startScale), std::max(0, 2 + bronzeScale - startScale),
|
||||
std::max(0, 2 + bronzeScale - startScale), std::max(0, 2 + bronzeScale - startScale));
|
||||
int powerBracelet = ctx->GetOption(RSK_SHUFFLE_GRAB) ? 1 : 0;
|
||||
AddItemToPool(RG_PROGRESSIVE_STRENGTH, 4 + powerBracelet, 3 + powerBracelet, 3 + powerBracelet, 3 + powerBracelet);
|
||||
int startStrength = ctx->GetOption(RSK_STARTING_STRENGTH).Get();
|
||||
AddItemToPool(RG_PROGRESSIVE_STRENGTH, std::max(0, 4 + powerBracelet - startStrength), std::max(0, 3 + powerBracelet - startStrength),
|
||||
std::max(0, 3 + powerBracelet - startStrength), std::max(0, 3 + powerBracelet - startStrength));
|
||||
|
||||
if (ctx->GetOption(RSK_SHUFFLE_CLIMB)) {
|
||||
AddItemToPool(RG_CLIMB, 2, 1, 1, 1);
|
||||
@@ -494,7 +515,8 @@ void GenerateItemPool() {
|
||||
|
||||
if (ctx->GetOption(RSK_SHUFFLE_MERCHANTS).Is(RO_SHUFFLE_MERCHANTS_ALL_BUT_BEANS) ||
|
||||
ctx->GetOption(RSK_SHUFFLE_MERCHANTS).Is(RO_SHUFFLE_MERCHANTS_ALL)) {
|
||||
if (/*!ProgressiveGoronSword TODO: Implement Progressive Goron Sword*/ true) {
|
||||
if (/*!ProgressiveGoronSword TODO: Implement Progressive Goron Sword*/
|
||||
ctx->GetOption(RSK_STARTING_BIGGORON_SWORD).Is(RO_STARTING_BGS_OFF)) {
|
||||
AddFixedItemToPool(RG_GIANTS_KNIFE, 1);
|
||||
}
|
||||
if (ctx->GetOption(RSK_BOMBCHU_BAG).Is(RO_BOMBCHU_BAG_SINGLE)) {
|
||||
@@ -533,7 +555,9 @@ void GenerateItemPool() {
|
||||
AddItemToPool(RG_EYEBALL_FROG, 2, 1, 1, 1);
|
||||
AddItemToPool(RG_EYEDROPS, 2, 1, 1, 1);
|
||||
}
|
||||
AddItemToPool(RG_CLAIM_CHECK, 2, 1, 1, 1);
|
||||
if (!ctx->GetOption(RSK_STARTING_CLAIM_CHECK)) {
|
||||
AddItemToPool(RG_CLAIM_CHECK, 2, 1, 1, 1);
|
||||
}
|
||||
|
||||
if (ctx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME).Is(RO_CHEST_GAME_SINGLE_KEYS)) {
|
||||
AddItemToPool(RG_TREASURE_GAME_SMALL_KEY, 7, 6, 6, 6);
|
||||
@@ -646,7 +670,9 @@ void GenerateItemPool() {
|
||||
|
||||
// Gerudo Membership Card
|
||||
if (ctx->GetOption(RSK_SHUFFLE_GERUDO_MEMBERSHIP_CARD)) {
|
||||
AddItemToPool(RG_GERUDO_MEMBERSHIP_CARD, 2, 1, 1, 1);
|
||||
if (!ctx->GetOption(RSK_STARTING_GERUDO_CARD)) {
|
||||
AddItemToPool(RG_GERUDO_MEMBERSHIP_CARD, 2, 1, 1, 1);
|
||||
}
|
||||
} else {
|
||||
ctx->PlaceItemInLocation(RC_TH_FREED_CARPENTERS, RG_GERUDO_MEMBERSHIP_CARD, false, true);
|
||||
}
|
||||
@@ -829,15 +855,25 @@ void GenerateItemPool() {
|
||||
// Add 4 total bottles
|
||||
uint8_t bottleCount = 4;
|
||||
if (ctx->GetOption(RSK_ZORAS_FOUNTAIN).IsNot(RO_ZF_OPEN)) {
|
||||
AddFixedItemToPool(RG_RUTOS_LETTER);
|
||||
bottleCount--;
|
||||
// When the letter is started with, a normal bottle takes its pool slot instead.
|
||||
if (ctx->GetOption(RSK_STARTING_BOTTLE_1).IsNot(RO_STARTING_BOTTLE_RUTOS_LETTER)) {
|
||||
AddFixedItemToPool(RG_RUTOS_LETTER);
|
||||
bottleCount--;
|
||||
}
|
||||
}
|
||||
// Bottles the player starts with are removed from the pool.
|
||||
for (RandomizerSettingKey bottleKey :
|
||||
{ RSK_STARTING_BOTTLE_1, RSK_STARTING_BOTTLE_2, RSK_STARTING_BOTTLE_3, RSK_STARTING_BOTTLE_4 }) {
|
||||
if (bottleCount > 0 && ctx->GetOption(bottleKey).IsNot(RO_STARTING_BOTTLE_OFF)) {
|
||||
bottleCount--;
|
||||
}
|
||||
}
|
||||
|
||||
if ((ctx->GetOption(RSK_SHUFFLE_MERCHANTS).Is(RO_SHUFFLE_MERCHANTS_ALL_BUT_BEANS) ||
|
||||
ctx->GetOption(RSK_SHUFFLE_MERCHANTS).Is(RO_SHUFFLE_MERCHANTS_ALL))) {
|
||||
ctx->GetOption(RSK_SHUFFLE_MERCHANTS).Is(RO_SHUFFLE_MERCHANTS_ALL)) && bottleCount > 0) {
|
||||
AddFixedItemToPool(RG_BOTTLE_WITH_BLUE_POTION);
|
||||
bottleCount--;
|
||||
}
|
||||
|
||||
ctx->possibleIceTrapModels.insert(RG_EMPTY_BOTTLE); // ice traps reroll this into a random normal bottle in Rando::Traps::GetTrapTrickModel
|
||||
for (uint8_t i = 0; i < bottleCount; i++) {
|
||||
AddFixedItemToPool(RandomElement(Rando::StaticData::normalBottles), 1, false);
|
||||
|
||||
@@ -60,8 +60,8 @@ void GenerateStartingInventory() {
|
||||
AddItemToInventory(RG_GANONS_CASTLE_BOSS_KEY);
|
||||
}
|
||||
|
||||
if (ctx->GetOption(RSK_GERUDO_FORTRESS).Is(RO_GF_CARPENTERS_FREE) &&
|
||||
!ctx->GetOption(RSK_SHUFFLE_GERUDO_MEMBERSHIP_CARD)) {
|
||||
if (ctx->GetOption(RSK_STARTING_GERUDO_CARD) || (ctx->GetOption(RSK_GERUDO_FORTRESS).Is(RO_GF_CARPENTERS_FREE) &&
|
||||
!ctx->GetOption(RSK_SHUFFLE_GERUDO_MEMBERSHIP_CARD))) {
|
||||
AddItemToInventory(RG_GERUDO_MEMBERSHIP_CARD);
|
||||
}
|
||||
|
||||
@@ -72,46 +72,51 @@ void GenerateStartingInventory() {
|
||||
// TODO: Uncomment when these options are implemented.
|
||||
// AddItemToInventory(RG_PROGRESSIVE_STICK_UPGRADE, StartingStickCapacity.Value<uint8_t>());
|
||||
// AddItemToInventory(RG_PROGRESSIVE_NUT_UPGRADE, StartingNutCapacity.Value<uint8_t>());
|
||||
// AddItemToInventory(RG_PROGRESSIVE_BOMB_BAG, StartingBombBag.Value<uint8_t>());
|
||||
// AddItemToInventory((BombchuBag ? RG_PROGRESSIVE_BOMBCHU_BAG : RG_BOMBCHU_20),
|
||||
// StartingBombchus.Value<uint8_t>()); AddItemToInventory(RG_PROGRESSIVE_BOW, StartingBow.Value<uint8_t>());
|
||||
// AddItemToInventory(RG_FIRE_ARROWS, StartingFireArrows.Value<uint8_t>());
|
||||
// AddItemToInventory(RG_ICE_ARROWS, StartingIceArrows.Value<uint8_t>());
|
||||
// AddItemToInventory(RG_LIGHT_ARROWS, StartingLightArrows.Value<uint8_t>());
|
||||
// AddItemToInventory(RG_DINS_FIRE, StartingDinsFire.Value<uint8_t>());
|
||||
// AddItemToInventory(RG_FARORES_WIND, StartingFaroresWind.Value<uint8_t>());
|
||||
// AddItemToInventory(RG_NAYRUS_LOVE, StartingNayrusLove.Value<uint8_t>());
|
||||
// AddItemToInventory(RG_PROGRESSIVE_SLINGSHOT, StartingSlingshot.Value<uint8_t>());
|
||||
// AddItemToInventory(RG_BOOMERANG, StartingBoomerang.Value<uint8_t>());
|
||||
// AddItemToInventory(RG_LENS_OF_TRUTH, StartingLensOfTruth.Value<uint8_t>());
|
||||
// AddItemToInventory(RG_MAGIC_BEAN_PACK, StartingMagicBean.Value<uint8_t>());
|
||||
// AddItemToInventory(RG_MEGATON_HAMMER, StartingMegatonHammer.Value<uint8_t>());
|
||||
// AddItemToInventory(RG_PROGRESSIVE_HOOKSHOT, StartingHookshot.Value<uint8_t>());
|
||||
// AddItemToInventory(RG_IRON_BOOTS, StartingIronBoots.Value<uint8_t>());
|
||||
// AddItemToInventory(RG_HOVER_BOOTS, StartingHoverBoots.Value<uint8_t>());
|
||||
// For starting bottles, we need to check if they are a big poe and add that if so
|
||||
// since a big poe bottle is not logically equivalent to an empty bottle.
|
||||
// if (StartingBottle1.Value<uint8_t>() == STARTINGBOTTLE_BIG_POE) {
|
||||
// AddItemToInventory(RG_BOTTLE_WITH_BIG_POE, 1);
|
||||
// } else if (StartingBottle1.Value<uint8_t>()) {
|
||||
// AddItemToInventory(RG_EMPTY_BOTTLE, 1);
|
||||
// }
|
||||
// if (StartingBottle2.Value<uint8_t>() == STARTINGBOTTLE_BIG_POE) {
|
||||
// AddItemToInventory(RG_BOTTLE_WITH_BIG_POE, 1);
|
||||
// } else if (StartingBottle2.Value<uint8_t>()) {
|
||||
// AddItemToInventory(RG_EMPTY_BOTTLE, 1);
|
||||
// }
|
||||
// if (StartingBottle3.Value<uint8_t>() == STARTINGBOTTLE_BIG_POE) {
|
||||
// AddItemToInventory(RG_BOTTLE_WITH_BIG_POE, 1);
|
||||
// } else if (StartingBottle3.Value<uint8_t>()) {
|
||||
// AddItemToInventory(RG_EMPTY_BOTTLE, 1);
|
||||
// }
|
||||
// if (StartingBottle4.Value<uint8_t>() == STARTINGBOTTLE_BIG_POE) {
|
||||
// AddItemToInventory(RG_BOTTLE_WITH_BIG_POE, 1);
|
||||
// } else if (StartingBottle4.Value<uint8_t>()) {
|
||||
// AddItemToInventory(RG_EMPTY_BOTTLE, 1);
|
||||
// }
|
||||
// AddItemToInventory(RG_RUTOS_LETTER, StartingRutoBottle.Value<uint8_t>());
|
||||
AddItemToInventory(RG_PROGRESSIVE_BOMB_BAG, ctx->GetOption(RSK_STARTING_BOMB_BAG).Get());
|
||||
AddItemToInventory(RG_PROGRESSIVE_BOW, ctx->GetOption(RSK_STARTING_BOW).Get());
|
||||
AddItemToInventory(RG_PROGRESSIVE_SLINGSHOT, ctx->GetOption(RSK_STARTING_SLINGSHOT).Get());
|
||||
AddItemToInventory(RG_BOOMERANG, ctx->GetOption(RSK_STARTING_BOOMERANG) ? 1 : 0);
|
||||
AddItemToInventory(RG_LENS_OF_TRUTH, ctx->GetOption(RSK_STARTING_LENS_OF_TRUTH) ? 1 : 0);
|
||||
AddItemToInventory(RG_PROGRESSIVE_HOOKSHOT, ctx->GetOption(RSK_STARTING_HOOKSHOT).Get());
|
||||
// Bombchu bags only exist when the bombchu bag setting enables them; a single bag is one item,
|
||||
// progressive bags are added per starting tier.
|
||||
if (ctx->GetOption(RSK_BOMBCHU_BAG).Is(RO_BOMBCHU_BAG_SINGLE)) {
|
||||
AddItemToInventory(RG_PROGRESSIVE_BOMBCHU_BAG, ctx->GetOption(RSK_STARTING_BOMBCHU_BAG).Get() ? 1 : 0);
|
||||
} else if (ctx->GetOption(RSK_BOMBCHU_BAG).Is(RO_BOMBCHU_BAG_PROGRESSIVE)) {
|
||||
AddItemToInventory(RG_PROGRESSIVE_BOMBCHU_BAG, ctx->GetOption(RSK_STARTING_BOMBCHU_BAG).Get());
|
||||
}
|
||||
AddItemToInventory(RG_MEGATON_HAMMER, ctx->GetOption(RSK_STARTING_MEGATON_HAMMER) ? 1 : 0);
|
||||
AddItemToInventory(RG_IRON_BOOTS, ctx->GetOption(RSK_STARTING_IRON_BOOTS) ? 1 : 0);
|
||||
AddItemToInventory(RG_HOVER_BOOTS, ctx->GetOption(RSK_STARTING_HOVER_BOOTS) ? 1 : 0);
|
||||
AddItemToInventory(RG_DINS_FIRE, ctx->GetOption(RSK_STARTING_DINS_FIRE) ? 1 : 0);
|
||||
AddItemToInventory(RG_FARORES_WIND, ctx->GetOption(RSK_STARTING_FARORES_WIND) ? 1 : 0);
|
||||
AddItemToInventory(RG_NAYRUS_LOVE, ctx->GetOption(RSK_STARTING_NAYRUS_LOVE) ? 1 : 0);
|
||||
AddItemToInventory(RG_FIRE_ARROWS, ctx->GetOption(RSK_STARTING_FIRE_ARROWS) ? 1 : 0);
|
||||
AddItemToInventory(RG_ICE_ARROWS, ctx->GetOption(RSK_STARTING_ICE_ARROWS) ? 1 : 0);
|
||||
AddItemToInventory(RG_LIGHT_ARROWS, ctx->GetOption(RSK_STARTING_LIGHT_ARROWS) ? 1 : 0);
|
||||
AddItemToInventory(RG_HYLIAN_SHIELD, ctx->GetOption(RSK_STARTING_HYLIAN_SHIELD) ? 1 : 0);
|
||||
AddItemToInventory(RG_MIRROR_SHIELD, ctx->GetOption(RSK_STARTING_MIRROR_SHIELD) ? 1 : 0);
|
||||
AddItemToInventory(RG_GORON_TUNIC, ctx->GetOption(RSK_STARTING_GORON_TUNIC) ? 1 : 0);
|
||||
AddItemToInventory(RG_ZORA_TUNIC, ctx->GetOption(RSK_STARTING_ZORA_TUNIC) ? 1 : 0);
|
||||
AddItemToInventory(RG_STONE_OF_AGONY, ctx->GetOption(RSK_STARTING_STONE_OF_AGONY) ? 1 : 0);
|
||||
// A big poe bottle is not logically equivalent to an empty bottle, so it's a distinct item.
|
||||
for (RandomizerSettingKey bottleKey :
|
||||
{ RSK_STARTING_BOTTLE_1, RSK_STARTING_BOTTLE_2, RSK_STARTING_BOTTLE_3, RSK_STARTING_BOTTLE_4 }) {
|
||||
uint8_t bottle = ctx->GetOption(bottleKey).Get();
|
||||
if (bottle == RO_STARTING_BOTTLE_BIG_POE) {
|
||||
AddItemToInventory(RG_BOTTLE_WITH_BIG_POE);
|
||||
} else if (bottle == RO_STARTING_BOTTLE_RUTOS_LETTER) {
|
||||
AddItemToInventory(RG_RUTOS_LETTER);
|
||||
} else if (bottle != RO_STARTING_BOTTLE_OFF) {
|
||||
AddItemToInventory(RG_EMPTY_BOTTLE);
|
||||
}
|
||||
}
|
||||
// The weird egg only exists as an item when it's shuffled; vanilla gives it through the cutscene.
|
||||
if (ctx->GetOption(RSK_SHUFFLE_WEIRD_EGG)) {
|
||||
AddItemToInventory(RG_WEIRD_EGG, ctx->GetOption(RSK_STARTING_WEIRD_EGG) ? 1 : 0);
|
||||
}
|
||||
AddItemToInventory(RG_BUNNY_HOOD, ctx->GetOption(RSK_STARTING_BUNNY_HOOD) ? 1 : 0);
|
||||
AddItemToInventory(RG_CLAIM_CHECK, ctx->GetOption(RSK_STARTING_CLAIM_CHECK) ? 1 : 0);
|
||||
AddItemToInventory(RG_PROGRESSIVE_OCARINA, ctx->GetOption(RSK_STARTING_OCARINA).Get());
|
||||
AddItemToInventory(RG_ZELDAS_LULLABY, ctx->GetOption(RSK_STARTING_ZELDAS_LULLABY) ? 1 : 0);
|
||||
AddItemToInventory(RG_EPONAS_SONG, ctx->GetOption(RSK_STARTING_EPONAS_SONG) ? 1 : 0);
|
||||
@@ -127,23 +132,16 @@ void GenerateStartingInventory() {
|
||||
AddItemToInventory(RG_PRELUDE_OF_LIGHT, ctx->GetOption(RSK_STARTING_PRELUDE_OF_LIGHT) ? 1 : 0);
|
||||
AddItemToInventory(RG_KOKIRI_SWORD, ctx->GetOption(RSK_STARTING_KOKIRI_SWORD) ? 1 : 0);
|
||||
AddItemToInventory(RG_MAGIC_BEAN_PACK, ctx->GetOption(RSK_STARTING_BEANS) ? 1 : 0);
|
||||
// if (ProgressiveGoronSword) {
|
||||
// AddItemToInventory(RG_PROGRESSIVE_GORONSWORD, StartingBiggoronSword.Value<uint8_t>());
|
||||
// } else {
|
||||
// AddItemToInventory(RG_GIANTS_KNIFE, (StartingBiggoronSword.Is(STARTINGBGS_GIANTS_KNIFE)) ? 1 : 0);
|
||||
// AddItemToInventory(RG_BIGGORON_SWORD, (StartingBiggoronSword.Is(STARTINGBGS_BIGGORON_SWORD)) ? 1 : 0);
|
||||
// }
|
||||
AddItemToInventory(RG_GIANTS_KNIFE,
|
||||
ctx->GetOption(RSK_STARTING_BIGGORON_SWORD).Is(RO_STARTING_BGS_GIANTS_KNIFE) ? 1 : 0);
|
||||
AddItemToInventory(RG_BIGGORON_SWORD,
|
||||
ctx->GetOption(RSK_STARTING_BIGGORON_SWORD).Is(RO_STARTING_BGS_BIGGORON_SWORD) ? 1 : 0);
|
||||
AddItemToInventory(RG_MASTER_SWORD, ctx->GetOption(RSK_STARTING_MASTER_SWORD) ? 1 : 0);
|
||||
AddItemToInventory(RG_DEKU_SHIELD, ctx->GetOption(RSK_STARTING_DEKU_SHIELD) ? 1 : 0);
|
||||
// AddItemToInventory(RG_HYLIAN_SHIELD, StartingHylianShield.Value<uint8_t>());
|
||||
// AddItemToInventory(RG_MIRROR_SHIELD, StartingMirrorShield.Value<uint8_t>());
|
||||
// AddItemToInventory(RG_GORON_TUNIC, StartingGoronTunic.Value<uint8_t>());
|
||||
// AddItemToInventory(RG_ZORA_TUNIC, StartingZoraTunic.Value<uint8_t>());
|
||||
// AddItemToInventory(RG_PROGRESSIVE_MAGIC_METER, StartingMagicMeter.Value<uint8_t>());
|
||||
// AddItemToInventory(RG_PROGRESSIVE_STRENGTH, StartingStrength.Value<uint8_t>());
|
||||
// AddItemToInventory(RG_PROGRESSIVE_SCALE, StartingScale.Value<uint8_t>());
|
||||
// AddItemToInventory(RG_PROGRESSIVE_WALLET, StartingWallet.Value<uint8_t>());
|
||||
// AddItemToInventory(RG_STONE_OF_AGONY, StartingShardOfAgony.Value<uint8_t>());
|
||||
AddItemToInventory(RG_PROGRESSIVE_MAGIC_METER, ctx->GetOption(RSK_STARTING_MAGIC_METER).Get());
|
||||
AddItemToInventory(RG_PROGRESSIVE_STRENGTH, ctx->GetOption(RSK_STARTING_STRENGTH).Get());
|
||||
AddItemToInventory(RG_PROGRESSIVE_SCALE, ctx->GetOption(RSK_STARTING_SCALE).Get());
|
||||
AddItemToInventory(RG_PROGRESSIVE_WALLET, ctx->GetOption(RSK_STARTING_WALLET).Get());
|
||||
// AddItemToInventory(RG_DOUBLE_DEFENSE, StartingDoubleDefense.Value<uint8_t>());
|
||||
// AddItemToInventory(RG_KOKIRI_EMERALD, StartingKokiriEmerald.Value<uint8_t>());
|
||||
// AddItemToInventory(RG_GORON_RUBY, StartingGoronRuby.Value<uint8_t>());
|
||||
|
||||
@@ -94,6 +94,10 @@ uint8_t Option::GetOptionIndex() const {
|
||||
return CVarGetInteger(cvarName.c_str(), defaultOption);
|
||||
}
|
||||
|
||||
uint8_t Option::GetMenuOptionDefault() const {
|
||||
return defaultOption;
|
||||
}
|
||||
|
||||
const std::string& Option::GetOptionText(size_t index) const {
|
||||
return options[index];
|
||||
}
|
||||
|
||||
@@ -225,6 +225,13 @@ class Option {
|
||||
*/
|
||||
uint8_t GetOptionIndex() const;
|
||||
|
||||
/**
|
||||
* @brief Get the default menu index for this Option.
|
||||
*
|
||||
* @return uint8_t
|
||||
*/
|
||||
uint8_t GetMenuOptionDefault() const;
|
||||
|
||||
/**
|
||||
* @brief Set the rando context index for this Option.
|
||||
*
|
||||
|
||||
@@ -334,13 +334,6 @@ RANDO_ENUM_ITEM(RSG_MENU_SECTION_HINTS)
|
||||
RANDO_ENUM_ITEM(RSG_MENU_SECTION_TRAPS)
|
||||
RANDO_ENUM_ITEM(RSG_MENU_COLUMN_STATIC_HINTS)
|
||||
RANDO_ENUM_ITEM(RSG_MENU_SECTION_STATIC_HINTS)
|
||||
RANDO_ENUM_ITEM(RSG_MENU_SIDEBAR_STARTING_ITEMS)
|
||||
RANDO_ENUM_ITEM(RSG_MENU_COLUMN_STARTING_EQUIPMENT)
|
||||
RANDO_ENUM_ITEM(RSG_MENU_SECTION_STARTING_EQUIPS)
|
||||
RANDO_ENUM_ITEM(RSG_MENU_SECTION_STARTING_ITEMS)
|
||||
RANDO_ENUM_ITEM(RSG_MENU_COLUMN_STARTING_SONGS)
|
||||
RANDO_ENUM_ITEM(RSG_MENU_SECTION_NORMAL_SONGS)
|
||||
RANDO_ENUM_ITEM(RSG_MENU_SECTION_WARP_SONGS)
|
||||
RANDO_ENUM_ITEM(RSG_OPEN)
|
||||
RANDO_ENUM_ITEM(RSG_WORLD)
|
||||
RANDO_ENUM_ITEM(RSG_SHUFFLE)
|
||||
|
||||
@@ -294,6 +294,21 @@ RANDO_ENUM_ITEM(RO_STARTING_OCARINA_FAIRY)
|
||||
RANDO_ENUM_ITEM(RO_STARTING_OCARINA_TIME)
|
||||
RANDO_ENUM_END(RandoOptionStartingOcarina)
|
||||
|
||||
// Starting Bottle Settings (off, empty bottle, bottle with big poe, ruto's letter (bottle 1 only))
|
||||
RANDO_ENUM_BEGIN(RandoOptionStartingBottle)
|
||||
RANDO_ENUM_ITEM(RO_STARTING_BOTTLE_OFF)
|
||||
RANDO_ENUM_ITEM(RO_STARTING_BOTTLE_EMPTY)
|
||||
RANDO_ENUM_ITEM(RO_STARTING_BOTTLE_BIG_POE)
|
||||
RANDO_ENUM_ITEM(RO_STARTING_BOTTLE_RUTOS_LETTER)
|
||||
RANDO_ENUM_END(RandoOptionStartingBottle)
|
||||
|
||||
// Starting Biggoron's Sword Settings (off, giant's knife, biggoron's sword)
|
||||
RANDO_ENUM_BEGIN(RandoOptionStartingBiggoronSword)
|
||||
RANDO_ENUM_ITEM(RO_STARTING_BGS_OFF)
|
||||
RANDO_ENUM_ITEM(RO_STARTING_BGS_GIANTS_KNIFE)
|
||||
RANDO_ENUM_ITEM(RO_STARTING_BGS_BIGGORON_SWORD)
|
||||
RANDO_ENUM_END(RandoOptionStartingBiggoronSword)
|
||||
|
||||
// Mask Quest Settings (vanilla, completed, shuffle)
|
||||
RANDO_ENUM_BEGIN(RandoOptionMaskQuest)
|
||||
RANDO_ENUM_ITEM(RO_MASK_QUEST_VANILLA)
|
||||
|
||||
@@ -144,6 +144,39 @@ RANDO_ENUM_ITEM(RSK_SKIP_CHILD_ZELDA)
|
||||
RANDO_ENUM_ITEM(RSK_STARTING_STICKS)
|
||||
RANDO_ENUM_ITEM(RSK_STARTING_NUTS)
|
||||
RANDO_ENUM_ITEM(RSK_STARTING_BEANS)
|
||||
RANDO_ENUM_ITEM(RSK_STARTING_MEGATON_HAMMER)
|
||||
RANDO_ENUM_ITEM(RSK_STARTING_BOOMERANG)
|
||||
RANDO_ENUM_ITEM(RSK_STARTING_LENS_OF_TRUTH)
|
||||
RANDO_ENUM_ITEM(RSK_STARTING_DINS_FIRE)
|
||||
RANDO_ENUM_ITEM(RSK_STARTING_FARORES_WIND)
|
||||
RANDO_ENUM_ITEM(RSK_STARTING_NAYRUS_LOVE)
|
||||
RANDO_ENUM_ITEM(RSK_STARTING_FIRE_ARROWS)
|
||||
RANDO_ENUM_ITEM(RSK_STARTING_ICE_ARROWS)
|
||||
RANDO_ENUM_ITEM(RSK_STARTING_LIGHT_ARROWS)
|
||||
RANDO_ENUM_ITEM(RSK_STARTING_IRON_BOOTS)
|
||||
RANDO_ENUM_ITEM(RSK_STARTING_HOVER_BOOTS)
|
||||
RANDO_ENUM_ITEM(RSK_STARTING_HYLIAN_SHIELD)
|
||||
RANDO_ENUM_ITEM(RSK_STARTING_MIRROR_SHIELD)
|
||||
RANDO_ENUM_ITEM(RSK_STARTING_GORON_TUNIC)
|
||||
RANDO_ENUM_ITEM(RSK_STARTING_ZORA_TUNIC)
|
||||
RANDO_ENUM_ITEM(RSK_STARTING_STONE_OF_AGONY)
|
||||
RANDO_ENUM_ITEM(RSK_STARTING_HOOKSHOT)
|
||||
RANDO_ENUM_ITEM(RSK_STARTING_BOW)
|
||||
RANDO_ENUM_ITEM(RSK_STARTING_SLINGSHOT)
|
||||
RANDO_ENUM_ITEM(RSK_STARTING_BOMB_BAG)
|
||||
RANDO_ENUM_ITEM(RSK_STARTING_STRENGTH)
|
||||
RANDO_ENUM_ITEM(RSK_STARTING_SCALE)
|
||||
RANDO_ENUM_ITEM(RSK_STARTING_WALLET)
|
||||
RANDO_ENUM_ITEM(RSK_STARTING_MAGIC_METER)
|
||||
RANDO_ENUM_ITEM(RSK_STARTING_BOMBCHU_BAG)
|
||||
RANDO_ENUM_ITEM(RSK_STARTING_BOTTLE_1)
|
||||
RANDO_ENUM_ITEM(RSK_STARTING_BOTTLE_2)
|
||||
RANDO_ENUM_ITEM(RSK_STARTING_BOTTLE_3)
|
||||
RANDO_ENUM_ITEM(RSK_STARTING_BOTTLE_4)
|
||||
RANDO_ENUM_ITEM(RSK_STARTING_WEIRD_EGG)
|
||||
RANDO_ENUM_ITEM(RSK_STARTING_CLAIM_CHECK)
|
||||
RANDO_ENUM_ITEM(RSK_STARTING_GERUDO_CARD)
|
||||
RANDO_ENUM_ITEM(RSK_STARTING_BIGGORON_SWORD)
|
||||
RANDO_ENUM_ITEM(RSK_FULL_WALLETS)
|
||||
RANDO_ENUM_ITEM(RSK_SHUFFLE_CHEST_MINIGAME)
|
||||
RANDO_ENUM_ITEM(RSK_BIG_POE_COUNT)
|
||||
@@ -256,6 +289,7 @@ RANDO_ENUM_ITEM(RSK_SHUFFLE_SIGNS)
|
||||
RANDO_ENUM_ITEM(RSK_ROCS_FEATHER)
|
||||
RANDO_ENUM_ITEM(RSK_SHUFFLE_ICICLES)
|
||||
RANDO_ENUM_ITEM(RSK_SHUFFLE_RED_ICE)
|
||||
RANDO_ENUM_ITEM(RSK_STARTING_BUNNY_HOOD)
|
||||
RANDO_ENUM_ITEM(RSK_MAX)
|
||||
RANDO_ENUM_END(RandomizerSettingKey)
|
||||
|
||||
|
||||
@@ -125,6 +125,38 @@ void SetStartingItems() {
|
||||
Item_Give(NULL, ITEM_SWORD_KOKIRI);
|
||||
if (Randomizer_GetSettingValue(RSK_STARTING_DEKU_SHIELD))
|
||||
Item_Give(NULL, ITEM_SHIELD_DEKU);
|
||||
if (Randomizer_GetSettingValue(RSK_STARTING_HYLIAN_SHIELD))
|
||||
Item_Give(NULL, ITEM_SHIELD_HYLIAN);
|
||||
if (Randomizer_GetSettingValue(RSK_STARTING_MIRROR_SHIELD))
|
||||
Item_Give(NULL, ITEM_SHIELD_MIRROR);
|
||||
if (Randomizer_GetSettingValue(RSK_STARTING_GORON_TUNIC))
|
||||
Item_Give(NULL, ITEM_TUNIC_GORON);
|
||||
if (Randomizer_GetSettingValue(RSK_STARTING_ZORA_TUNIC))
|
||||
Item_Give(NULL, ITEM_TUNIC_ZORA);
|
||||
if (Randomizer_GetSettingValue(RSK_STARTING_IRON_BOOTS))
|
||||
Item_Give(NULL, ITEM_BOOTS_IRON);
|
||||
if (Randomizer_GetSettingValue(RSK_STARTING_HOVER_BOOTS))
|
||||
Item_Give(NULL, ITEM_BOOTS_HOVER);
|
||||
if (Randomizer_GetSettingValue(RSK_STARTING_MEGATON_HAMMER))
|
||||
Item_Give(NULL, ITEM_HAMMER);
|
||||
if (Randomizer_GetSettingValue(RSK_STARTING_BOOMERANG))
|
||||
Item_Give(NULL, ITEM_BOOMERANG);
|
||||
if (Randomizer_GetSettingValue(RSK_STARTING_LENS_OF_TRUTH))
|
||||
Item_Give(NULL, ITEM_LENS);
|
||||
if (Randomizer_GetSettingValue(RSK_STARTING_DINS_FIRE))
|
||||
Item_Give(NULL, ITEM_DINS_FIRE);
|
||||
if (Randomizer_GetSettingValue(RSK_STARTING_FARORES_WIND))
|
||||
Item_Give(NULL, ITEM_FARORES_WIND);
|
||||
if (Randomizer_GetSettingValue(RSK_STARTING_NAYRUS_LOVE))
|
||||
Item_Give(NULL, ITEM_NAYRUS_LOVE);
|
||||
if (Randomizer_GetSettingValue(RSK_STARTING_FIRE_ARROWS))
|
||||
Item_Give(NULL, ITEM_ARROW_FIRE);
|
||||
if (Randomizer_GetSettingValue(RSK_STARTING_ICE_ARROWS))
|
||||
Item_Give(NULL, ITEM_ARROW_ICE);
|
||||
if (Randomizer_GetSettingValue(RSK_STARTING_LIGHT_ARROWS))
|
||||
Item_Give(NULL, ITEM_ARROW_LIGHT);
|
||||
if (Randomizer_GetSettingValue(RSK_STARTING_STONE_OF_AGONY))
|
||||
Item_Give(NULL, ITEM_STONE_OF_AGONY);
|
||||
|
||||
// Songs
|
||||
if (Randomizer_GetSettingValue(RSK_STARTING_ZELDAS_LULLABY))
|
||||
@@ -182,6 +214,151 @@ void SetStartingItems() {
|
||||
}
|
||||
}
|
||||
|
||||
// Tiered/progressive starting items. The upgrade items are given cumulatively where Item_Give
|
||||
// only sets the base inventory content on the first tier.
|
||||
switch (Randomizer_GetSettingValue(RSK_STARTING_HOOKSHOT)) {
|
||||
case 2:
|
||||
Item_Give(NULL, ITEM_LONGSHOT);
|
||||
break;
|
||||
case 1:
|
||||
Item_Give(NULL, ITEM_HOOKSHOT);
|
||||
break;
|
||||
}
|
||||
|
||||
uint8_t startBow = Randomizer_GetSettingValue(RSK_STARTING_BOW);
|
||||
if (startBow >= 1)
|
||||
Item_Give(NULL, ITEM_QUIVER_30);
|
||||
if (startBow >= 2)
|
||||
Item_Give(NULL, ITEM_QUIVER_40);
|
||||
if (startBow >= 3)
|
||||
Item_Give(NULL, ITEM_QUIVER_50);
|
||||
|
||||
uint8_t startSlingshot = Randomizer_GetSettingValue(RSK_STARTING_SLINGSHOT);
|
||||
if (startSlingshot >= 1)
|
||||
Item_Give(NULL, ITEM_SLINGSHOT);
|
||||
if (startSlingshot >= 2)
|
||||
Item_Give(NULL, ITEM_BULLET_BAG_40);
|
||||
if (startSlingshot >= 3)
|
||||
Item_Give(NULL, ITEM_BULLET_BAG_50);
|
||||
|
||||
uint8_t startBombBag = Randomizer_GetSettingValue(RSK_STARTING_BOMB_BAG);
|
||||
if (startBombBag >= 1)
|
||||
Item_Give(NULL, ITEM_BOMB_BAG_20);
|
||||
if (startBombBag >= 2)
|
||||
Item_Give(NULL, ITEM_BOMB_BAG_30);
|
||||
if (startBombBag >= 3)
|
||||
Item_Give(NULL, ITEM_BOMB_BAG_40);
|
||||
|
||||
switch (Randomizer_GetSettingValue(RSK_STARTING_STRENGTH)) {
|
||||
case 3:
|
||||
Item_Give(NULL, ITEM_GAUNTLETS_GOLD);
|
||||
break;
|
||||
case 2:
|
||||
Item_Give(NULL, ITEM_GAUNTLETS_SILVER);
|
||||
break;
|
||||
case 1:
|
||||
Item_Give(NULL, ITEM_BRACELET);
|
||||
break;
|
||||
}
|
||||
|
||||
switch (Randomizer_GetSettingValue(RSK_STARTING_SCALE)) {
|
||||
case 2:
|
||||
Item_Give(NULL, ITEM_SCALE_GOLDEN);
|
||||
break;
|
||||
case 1:
|
||||
Item_Give(NULL, ITEM_SCALE_SILVER);
|
||||
break;
|
||||
}
|
||||
|
||||
switch (Randomizer_GetSettingValue(RSK_STARTING_WALLET)) {
|
||||
case 2:
|
||||
Item_Give(NULL, ITEM_WALLET_GIANT);
|
||||
break;
|
||||
case 1:
|
||||
Item_Give(NULL, ITEM_WALLET_ADULT);
|
||||
break;
|
||||
}
|
||||
|
||||
uint8_t startMagic = Randomizer_GetSettingValue(RSK_STARTING_MAGIC_METER);
|
||||
if (startMagic > 0) {
|
||||
gSaveContext.isMagicAcquired = true;
|
||||
gSaveContext.isDoubleMagicAcquired = startMagic >= 2;
|
||||
gSaveContext.magicLevel = startMagic;
|
||||
gSaveContext.magicCapacity = startMagic * MAGIC_NORMAL_METER;
|
||||
gSaveContext.magic = gSaveContext.magicCapacity;
|
||||
}
|
||||
|
||||
uint8_t startBombchu = Randomizer_GetSettingValue(RSK_STARTING_BOMBCHU_BAG);
|
||||
if (startBombchu > 0) {
|
||||
uint8_t bombchuMode = Randomizer_GetSettingValue(RSK_BOMBCHU_BAG);
|
||||
if (bombchuMode == RO_BOMBCHU_BAG_SINGLE) {
|
||||
INV_CONTENT(ITEM_BOMBCHU) = ITEM_BOMBCHU;
|
||||
AMMO(ITEM_BOMBCHU) = 20;
|
||||
} else if (bombchuMode == RO_BOMBCHU_BAG_PROGRESSIVE) {
|
||||
static const uint8_t bombchuCapacities[] = { 0, 20, 30, 50 };
|
||||
gSaveContext.ship.quest.data.randomizer.bombchuUpgradeLevel = startBombchu;
|
||||
INV_CONTENT(ITEM_BOMBCHU) = ITEM_BOMBCHU;
|
||||
AMMO(ITEM_BOMBCHU) = bombchuCapacities[startBombchu];
|
||||
}
|
||||
}
|
||||
|
||||
// Big poe bottles first: Item_Give for a bottled content fills the first empty-bottle
|
||||
// slot, so each poe is paired with the bottle given right before it. Ruto's Letter fills
|
||||
// an empty inventory slot on its own. The remaining plain empty bottles follow.
|
||||
uint8_t emptyBottles = 0;
|
||||
for (RandomizerSettingKey bottleKey :
|
||||
{ RSK_STARTING_BOTTLE_1, RSK_STARTING_BOTTLE_2, RSK_STARTING_BOTTLE_3, RSK_STARTING_BOTTLE_4 }) {
|
||||
uint8_t bottle = Randomizer_GetSettingValue(bottleKey);
|
||||
switch (bottle) {
|
||||
case RO_STARTING_BOTTLE_OFF:
|
||||
break;
|
||||
case RO_STARTING_BOTTLE_EMPTY:
|
||||
emptyBottles++;
|
||||
break;
|
||||
case RO_STARTING_BOTTLE_BIG_POE:
|
||||
Item_Give(NULL, ITEM_BOTTLE);
|
||||
Item_Give(NULL, ITEM_BIG_POE);
|
||||
break;
|
||||
case RO_STARTING_BOTTLE_RUTOS_LETTER:
|
||||
Item_Give(NULL, ITEM_LETTER_RUTO);
|
||||
break;
|
||||
default:
|
||||
SPDLOG_ERROR("[SetStartingItems] Unhandled value for bottleKey {}: {}", (int)bottleKey, bottle);
|
||||
assert(false);
|
||||
break;
|
||||
}
|
||||
}
|
||||
for (uint8_t i = 0; i < emptyBottles; i++) {
|
||||
Item_Give(NULL, ITEM_BOTTLE);
|
||||
}
|
||||
|
||||
if (Randomizer_GetSettingValue(RSK_STARTING_WEIRD_EGG) && Randomizer_GetSettingValue(RSK_SHUFFLE_WEIRD_EGG)) {
|
||||
Item_Give(NULL, ITEM_WEIRD_EGG);
|
||||
}
|
||||
if (Randomizer_GetSettingValue(RSK_STARTING_CLAIM_CHECK)) {
|
||||
Item_Give(NULL, ITEM_CLAIM_CHECK);
|
||||
}
|
||||
if (Randomizer_GetSettingValue(RSK_STARTING_GERUDO_CARD)) {
|
||||
Item_Give(NULL, ITEM_GERUDO_CARD);
|
||||
}
|
||||
|
||||
if (Randomizer_GetSettingValue(RSK_STARTING_BUNNY_HOOD)) {
|
||||
Flags_SetRandomizerInf(RAND_INF_CHILD_TRADES_HAS_MASK_BUNNY);
|
||||
if (INV_CONTENT(ITEM_TRADE_CHILD) == ITEM_NONE) {
|
||||
INV_CONTENT(ITEM_TRADE_CHILD) = ITEM_MASK_BUNNY;
|
||||
}
|
||||
}
|
||||
|
||||
// Giant's Knife and Biggoron's Sword share an item slot, bgsFlag marks unbreakable
|
||||
switch (Randomizer_GetSettingValue(RSK_STARTING_BIGGORON_SWORD)) {
|
||||
case RO_STARTING_BGS_BIGGORON_SWORD:
|
||||
gSaveContext.bgsFlag = true;
|
||||
[[fallthrough]];
|
||||
case RO_STARTING_BGS_GIANTS_KNIFE:
|
||||
Item_Give(NULL, ITEM_SWORD_BGS);
|
||||
break;
|
||||
}
|
||||
|
||||
if (Randomizer_GetSettingValue(RSK_FULL_WALLETS)) {
|
||||
GiveLinkRupees(9001);
|
||||
}
|
||||
|
||||
@@ -839,9 +839,25 @@ void Settings::CreateOptions() {
|
||||
});
|
||||
OPT_BOOL(RSK_SHUFFLE_OCARINA_BUTTONS, "Shuffle Ocarina Buttons", CVAR_RANDOMIZER_SETTING("ShuffleOcarinaButtons"), mOptionDescriptions[RSK_SHUFFLE_OCARINA_BUTTONS]);
|
||||
OPT_BOOL(RSK_SHUFFLE_SWIM, "Shuffle Swim", CVAR_RANDOMIZER_SETTING("ShuffleSwim"), mOptionDescriptions[RSK_SHUFFLE_SWIM]);
|
||||
OPT_CALLBACK(RSK_SHUFFLE_SWIM, {
|
||||
if (CVarGetInteger(CVAR_RANDOMIZER_SETTING("ShuffleSwim"), 0)) {
|
||||
CVarSetInteger(CVAR_RANDOMIZER_SETTING("StartingScale"), 0);
|
||||
mOptions[RSK_STARTING_SCALE].Disable("Disabled because Shuffle Swim is on.");
|
||||
} else {
|
||||
mOptions[RSK_STARTING_SCALE].Enable();
|
||||
}
|
||||
});
|
||||
OPT_BOOL(RSK_SHUFFLE_CLIMB, "Shuffle Climb", CVAR_RANDOMIZER_SETTING("ShuffleClimb"), mOptionDescriptions[RSK_SHUFFLE_CLIMB]);
|
||||
OPT_BOOL(RSK_SHUFFLE_CRAWL, "Shuffle Crawl", CVAR_RANDOMIZER_SETTING("ShuffleCrawl"), mOptionDescriptions[RSK_SHUFFLE_CRAWL]);
|
||||
OPT_BOOL(RSK_SHUFFLE_GRAB, "Shuffle Grab", CVAR_RANDOMIZER_SETTING("ShuffleGrab"), mOptionDescriptions[RSK_SHUFFLE_GRAB]);
|
||||
OPT_CALLBACK(RSK_SHUFFLE_GRAB, {
|
||||
if (CVarGetInteger(CVAR_RANDOMIZER_SETTING("ShuffleGrab"), 0)) {
|
||||
CVarSetInteger(CVAR_RANDOMIZER_SETTING("StartingStrength"), 0);
|
||||
mOptions[RSK_STARTING_STRENGTH].Disable("Disabled because Shuffle Grab is on.");
|
||||
} else {
|
||||
mOptions[RSK_STARTING_STRENGTH].Enable();
|
||||
}
|
||||
});
|
||||
OPT_BOOL(RSK_SHUFFLE_SPEAK, "Shuffle Jabber Nuts", CVAR_RANDOMIZER_SETTING("ShuffleSpeak"), mOptionDescriptions[RSK_SHUFFLE_SPEAK]);
|
||||
OPT_BOOL(RSK_SHUFFLE_OPEN_CHEST, "Shuffle Open Chest", CVAR_RANDOMIZER_SETTING("ShuffleOpenChest"), mOptionDescriptions[RSK_SHUFFLE_OPEN_CHEST]);
|
||||
OPT_BOOL(RSK_SHUFFLE_WEIRD_EGG, "Shuffle Weird Egg", CVAR_RANDOMIZER_SETTING("ShuffleWeirdEgg"), mOptionDescriptions[RSK_SHUFFLE_WEIRD_EGG]);
|
||||
@@ -1328,6 +1344,40 @@ void Settings::CreateOptions() {
|
||||
OPT_BOOL(RSK_STARTING_STICKS, "Start with Stick Ammo", {"No", "Yes"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("StartingSticks"), "", WIDGET_CVAR_CHECKBOX, RO_GENERIC_OFF);
|
||||
OPT_BOOL(RSK_STARTING_NUTS, "Start with Nut Ammo", {"No", "Yes"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("StartingNuts"), "", WIDGET_CVAR_CHECKBOX, RO_GENERIC_OFF);
|
||||
OPT_BOOL(RSK_STARTING_BEANS, "Start with Magic Beans", {"No", "Yes"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("StartingBeans"), "", WIDGET_CVAR_CHECKBOX, RO_GENERIC_OFF);
|
||||
OPT_BOOL(RSK_STARTING_MEGATON_HAMMER, "Start with Megaton Hammer", CVAR_RANDOMIZER_SETTING("StartingMegatonHammer"));
|
||||
OPT_BOOL(RSK_STARTING_BOOMERANG, "Start with Boomerang", CVAR_RANDOMIZER_SETTING("StartingBoomerang"));
|
||||
OPT_BOOL(RSK_STARTING_LENS_OF_TRUTH, "Start with Lens of Truth", CVAR_RANDOMIZER_SETTING("StartingLensOfTruth"));
|
||||
OPT_BOOL(RSK_STARTING_DINS_FIRE, "Start with Din's Fire", CVAR_RANDOMIZER_SETTING("StartingDinsFire"));
|
||||
OPT_BOOL(RSK_STARTING_FARORES_WIND, "Start with Farore's Wind", CVAR_RANDOMIZER_SETTING("StartingFaroresWind"));
|
||||
OPT_BOOL(RSK_STARTING_NAYRUS_LOVE, "Start with Nayru's Love", CVAR_RANDOMIZER_SETTING("StartingNayrusLove"));
|
||||
OPT_BOOL(RSK_STARTING_FIRE_ARROWS, "Start with Fire Arrows", CVAR_RANDOMIZER_SETTING("StartingFireArrows"));
|
||||
OPT_BOOL(RSK_STARTING_ICE_ARROWS, "Start with Ice Arrows", CVAR_RANDOMIZER_SETTING("StartingIceArrows"));
|
||||
OPT_BOOL(RSK_STARTING_LIGHT_ARROWS, "Start with Light Arrows", CVAR_RANDOMIZER_SETTING("StartingLightArrows"));
|
||||
OPT_BOOL(RSK_STARTING_IRON_BOOTS, "Start with Iron Boots", CVAR_RANDOMIZER_SETTING("StartingIronBoots"));
|
||||
OPT_BOOL(RSK_STARTING_HOVER_BOOTS, "Start with Hover Boots", CVAR_RANDOMIZER_SETTING("StartingHoverBoots"));
|
||||
OPT_BOOL(RSK_STARTING_HYLIAN_SHIELD, "Start with Hylian Shield", CVAR_RANDOMIZER_SETTING("StartingHylianShield"));
|
||||
OPT_BOOL(RSK_STARTING_MIRROR_SHIELD, "Start with Mirror Shield", CVAR_RANDOMIZER_SETTING("StartingMirrorShield"));
|
||||
OPT_BOOL(RSK_STARTING_GORON_TUNIC, "Start with Goron Tunic", CVAR_RANDOMIZER_SETTING("StartingGoronTunic"));
|
||||
OPT_BOOL(RSK_STARTING_ZORA_TUNIC, "Start with Zora Tunic", CVAR_RANDOMIZER_SETTING("StartingZoraTunic"));
|
||||
OPT_BOOL(RSK_STARTING_STONE_OF_AGONY, "Start with Stone of Agony", CVAR_RANDOMIZER_SETTING("StartingStoneOfAgony"));
|
||||
OPT_U8(RSK_STARTING_HOOKSHOT, "Start with Hookshot", {"Off", "Hookshot", "Longshot"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("StartingHookshot"), "", WIDGET_CVAR_COMBOBOX, 0);
|
||||
OPT_U8(RSK_STARTING_BOW, "Start with Bow", {"Off", "Bow (Quiver 30)", "Bow (Quiver 40)", "Bow (Quiver 50)"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("StartingBow"), "", WIDGET_CVAR_COMBOBOX, 0);
|
||||
OPT_U8(RSK_STARTING_SLINGSHOT, "Start with Slingshot", {"Off", "Slingshot (30)", "Slingshot (40)", "Slingshot (50)"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("StartingSlingshot"), "", WIDGET_CVAR_COMBOBOX, 0);
|
||||
OPT_U8(RSK_STARTING_BOMB_BAG, "Start with Bomb Bag", {"Off", "Bomb Bag (20)", "Bomb Bag (30)", "Bomb Bag (40)"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("StartingBombBag"), "", WIDGET_CVAR_COMBOBOX, 0);
|
||||
OPT_U8(RSK_STARTING_STRENGTH, "Start with Strength Upgrade", {"Off", "Goron's Bracelet", "Silver Gauntlets", "Golden Gauntlets"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("StartingStrength"), "", WIDGET_CVAR_COMBOBOX, 0);
|
||||
OPT_U8(RSK_STARTING_SCALE, "Start with Diving Scale", {"Off", "Silver Scale", "Golden Scale"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("StartingScale"), "", WIDGET_CVAR_COMBOBOX, 0);
|
||||
OPT_U8(RSK_STARTING_WALLET, "Start with Wallet Upgrade", {"Off", "Adult's Wallet", "Giant's Wallet"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("StartingWallet"), "", WIDGET_CVAR_COMBOBOX, 0);
|
||||
OPT_U8(RSK_STARTING_MAGIC_METER, "Start with Magic Meter", {"Off", "Single Magic", "Double Magic"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("StartingMagicMeter"), "", WIDGET_CVAR_COMBOBOX, 0);
|
||||
OPT_U8(RSK_STARTING_BOMBCHU_BAG, "Start with Bombchu Bag", {"Off", "Bombchu Bag (20)", "Bombchu Bag (30)", "Bombchu Bag (50)"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("StartingBombchuBag"), "", WIDGET_CVAR_COMBOBOX, 0);
|
||||
OPT_U8(RSK_STARTING_BOTTLE_1, "Starting Bottle 1", {"Off", "Empty Bottle", "Bottle with Big Poe", "Ruto's Letter"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("StartingBottle1"), "", WIDGET_CVAR_COMBOBOX, 0);
|
||||
OPT_U8(RSK_STARTING_BOTTLE_2, "Starting Bottle 2", {"Off", "Empty Bottle", "Bottle with Big Poe"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("StartingBottle2"), "", WIDGET_CVAR_COMBOBOX, 0);
|
||||
OPT_U8(RSK_STARTING_BOTTLE_3, "Starting Bottle 3", {"Off", "Empty Bottle", "Bottle with Big Poe"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("StartingBottle3"), "", WIDGET_CVAR_COMBOBOX, 0);
|
||||
OPT_U8(RSK_STARTING_BOTTLE_4, "Starting Bottle 4", {"Off", "Empty Bottle", "Bottle with Big Poe"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("StartingBottle4"), "", WIDGET_CVAR_COMBOBOX, 0);
|
||||
OPT_BOOL(RSK_STARTING_WEIRD_EGG, "Start with Weird Egg", CVAR_RANDOMIZER_SETTING("StartingWeirdEgg"));
|
||||
OPT_BOOL(RSK_STARTING_CLAIM_CHECK, "Start with Claim Check", CVAR_RANDOMIZER_SETTING("StartingClaimCheck"));
|
||||
OPT_BOOL(RSK_STARTING_GERUDO_CARD, "Start with Gerudo Card", CVAR_RANDOMIZER_SETTING("StartingGerudoCard"));
|
||||
OPT_BOOL(RSK_STARTING_BUNNY_HOOD, "Start with Bunny Hood", CVAR_RANDOMIZER_SETTING("StartingBunnyHood"));
|
||||
OPT_U8(RSK_STARTING_BIGGORON_SWORD, "Start with Biggoron's Sword", {"Off", "Giant's Knife", "Biggoron's Sword"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("StartingBiggoronSword"), "", WIDGET_CVAR_COMBOBOX, 0);
|
||||
OPT_BOOL(RSK_FULL_WALLETS, "Full Wallets", {"No", "Yes"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("FullWallets"), mOptionDescriptions[RSK_FULL_WALLETS], WIDGET_CVAR_CHECKBOX, RO_GENERIC_OFF);
|
||||
OPT_BOOL(RSK_STARTING_ZELDAS_LULLABY, "Start with Zelda's Lullaby", CVAR_RANDOMIZER_SETTING("StartingZeldasLullaby"), "", IMFLAG_NONE);
|
||||
OPT_BOOL(RSK_STARTING_EPONAS_SONG, "Start with Epona's Song", CVAR_RANDOMIZER_SETTING("StartingEponasSong"), "", IMFLAG_NONE);
|
||||
@@ -2028,62 +2078,6 @@ 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_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],
|
||||
&mOptions[RSK_STARTING_STICKS],
|
||||
&mOptions[RSK_STARTING_NUTS],
|
||||
&mOptions[RSK_STARTING_BEANS],
|
||||
&mOptions[RSK_STARTING_SKULLTULA_TOKEN],
|
||||
&mOptions[RSK_STARTING_HEARTS],
|
||||
},
|
||||
WidgetContainerType::SECTION);
|
||||
mOptionGroups[RSG_MENU_COLUMN_STARTING_EQUIPMENT] =
|
||||
OptionGroup::SubGroup("",
|
||||
std::initializer_list<OptionGroup*>{
|
||||
&mOptionGroups[RSG_MENU_SECTION_STARTING_EQUIPS],
|
||||
&mOptionGroups[RSG_MENU_SECTION_STARTING_ITEMS],
|
||||
},
|
||||
WidgetContainerType::COLUMN);
|
||||
mOptionGroups[RSG_MENU_SECTION_NORMAL_SONGS] = OptionGroup::SubGroup("Normal Songs",
|
||||
{
|
||||
&mOptions[RSK_STARTING_ZELDAS_LULLABY],
|
||||
&mOptions[RSK_STARTING_EPONAS_SONG],
|
||||
&mOptions[RSK_STARTING_SARIAS_SONG],
|
||||
&mOptions[RSK_STARTING_SUNS_SONG],
|
||||
&mOptions[RSK_STARTING_SONG_OF_TIME],
|
||||
&mOptions[RSK_STARTING_SONG_OF_STORMS],
|
||||
},
|
||||
WidgetContainerType::SECTION);
|
||||
mOptionGroups[RSG_MENU_SECTION_WARP_SONGS] = OptionGroup::SubGroup("Warp Songs",
|
||||
{
|
||||
&mOptions[RSK_STARTING_MINUET_OF_FOREST],
|
||||
&mOptions[RSK_STARTING_BOLERO_OF_FIRE],
|
||||
&mOptions[RSK_STARTING_SERENADE_OF_WATER],
|
||||
&mOptions[RSK_STARTING_REQUIEM_OF_SPIRIT],
|
||||
&mOptions[RSK_STARTING_NOCTURNE_OF_SHADOW],
|
||||
&mOptions[RSK_STARTING_PRELUDE_OF_LIGHT],
|
||||
},
|
||||
WidgetContainerType::SECTION);
|
||||
mOptionGroups[RSG_MENU_COLUMN_STARTING_SONGS] =
|
||||
OptionGroup::SubGroup("",
|
||||
std::initializer_list<OptionGroup*>{
|
||||
&mOptionGroups[RSG_MENU_SECTION_NORMAL_SONGS],
|
||||
&mOptionGroups[RSG_MENU_SECTION_WARP_SONGS],
|
||||
},
|
||||
WidgetContainerType::COLUMN);
|
||||
mOptionGroups[RSG_MENU_SIDEBAR_STARTING_ITEMS] =
|
||||
OptionGroup::SubGroup("Starting Items",
|
||||
std::initializer_list<OptionGroup*>{
|
||||
&mOptionGroups[RSG_MENU_COLUMN_STARTING_EQUIPMENT],
|
||||
&mOptionGroups[RSG_MENU_COLUMN_STARTING_SONGS],
|
||||
},
|
||||
WidgetContainerType::TABLE);
|
||||
mOptionGroups[RSG_OPEN] = OptionGroup("Open Settings", {
|
||||
&mOptions[RSK_FOREST],
|
||||
&mOptions[RSK_KAK_GATE],
|
||||
@@ -2253,8 +2247,25 @@ void Settings::CreateOptions() {
|
||||
&mOptions[RSK_KEYRINGS_GANONS_CASTLE],
|
||||
});
|
||||
mOptionGroups[RSG_STARTING_ITEMS] =
|
||||
OptionGroup::SubGroup("Items", { &mOptions[RSK_STARTING_OCARINA], &mOptions[RSK_STARTING_KOKIRI_SWORD],
|
||||
&mOptions[RSK_STARTING_DEKU_SHIELD] });
|
||||
OptionGroup::SubGroup("Items", { &mOptions[RSK_STARTING_OCARINA], &mOptions[RSK_STARTING_KOKIRI_SWORD],
|
||||
&mOptions[RSK_STARTING_MASTER_SWORD], &mOptions[RSK_STARTING_DEKU_SHIELD],
|
||||
&mOptions[RSK_STARTING_HYLIAN_SHIELD], &mOptions[RSK_STARTING_MIRROR_SHIELD],
|
||||
&mOptions[RSK_STARTING_GORON_TUNIC], &mOptions[RSK_STARTING_ZORA_TUNIC],
|
||||
&mOptions[RSK_STARTING_IRON_BOOTS], &mOptions[RSK_STARTING_HOVER_BOOTS],
|
||||
&mOptions[RSK_STARTING_MEGATON_HAMMER], &mOptions[RSK_STARTING_BOOMERANG],
|
||||
&mOptions[RSK_STARTING_LENS_OF_TRUTH], &mOptions[RSK_STARTING_DINS_FIRE],
|
||||
&mOptions[RSK_STARTING_FARORES_WIND], &mOptions[RSK_STARTING_NAYRUS_LOVE],
|
||||
&mOptions[RSK_STARTING_FIRE_ARROWS], &mOptions[RSK_STARTING_ICE_ARROWS],
|
||||
&mOptions[RSK_STARTING_LIGHT_ARROWS], &mOptions[RSK_STARTING_STONE_OF_AGONY],
|
||||
&mOptions[RSK_STARTING_HOOKSHOT], &mOptions[RSK_STARTING_BOW],
|
||||
&mOptions[RSK_STARTING_SLINGSHOT], &mOptions[RSK_STARTING_BOMB_BAG],
|
||||
&mOptions[RSK_STARTING_STRENGTH], &mOptions[RSK_STARTING_SCALE],
|
||||
&mOptions[RSK_STARTING_WALLET], &mOptions[RSK_STARTING_MAGIC_METER],
|
||||
&mOptions[RSK_STARTING_BOMBCHU_BAG], &mOptions[RSK_STARTING_BOTTLE_1],
|
||||
&mOptions[RSK_STARTING_BOTTLE_2], &mOptions[RSK_STARTING_BOTTLE_3],
|
||||
&mOptions[RSK_STARTING_BOTTLE_4], &mOptions[RSK_STARTING_WEIRD_EGG],
|
||||
&mOptions[RSK_STARTING_CLAIM_CHECK], &mOptions[RSK_STARTING_GERUDO_CARD],
|
||||
&mOptions[RSK_STARTING_BIGGORON_SWORD], &mOptions[RSK_STARTING_BUNNY_HOOD] });
|
||||
mOptionGroups[RSG_STARTING_SONGS] =
|
||||
OptionGroup::SubGroup("Ocarina Songs", {
|
||||
&mOptions[RSK_STARTING_ZELDAS_LULLABY],
|
||||
@@ -2263,7 +2274,6 @@ void Settings::CreateOptions() {
|
||||
&mOptions[RSK_STARTING_SUNS_SONG],
|
||||
&mOptions[RSK_STARTING_SONG_OF_TIME],
|
||||
&mOptions[RSK_STARTING_SONG_OF_STORMS],
|
||||
&mOptions[RSK_STARTING_SONG_OF_TIME],
|
||||
&mOptions[RSK_STARTING_MINUET_OF_FOREST],
|
||||
&mOptions[RSK_STARTING_BOLERO_OF_FIRE],
|
||||
&mOptions[RSK_STARTING_SERENADE_OF_WATER],
|
||||
@@ -2601,6 +2611,17 @@ void Context::FinalizeSettings(const std::set<RandomizerCheck>& excludedLocation
|
||||
if (mOptions[RSK_SHUFFLE_DEKU_NUT_BAG]) {
|
||||
mOptions[RSK_STARTING_NUTS].Set(false);
|
||||
}
|
||||
if (mOptions[RSK_SHUFFLE_SWIM]) {
|
||||
mOptions[RSK_STARTING_SCALE].Set(0);
|
||||
}
|
||||
if (mOptions[RSK_SHUFFLE_GRAB]) {
|
||||
mOptions[RSK_STARTING_STRENGTH].Set(0);
|
||||
}
|
||||
|
||||
if (mOptions[RSK_ZORAS_FOUNTAIN].IsNot(RO_ZF_OPEN) &&
|
||||
mOptions[RSK_STARTING_BOTTLE_1].IsNot(RO_STARTING_BOTTLE_RUTOS_LETTER)) {
|
||||
mOptions[RSK_STARTING_BOTTLE_4].Set(RO_STARTING_BOTTLE_OFF);
|
||||
}
|
||||
|
||||
// RANDOTODO implement chest shuffle with keysanity
|
||||
// ShuffleChestMinigame.Set(cvarSettings[RSK_SHUFFLE_CHEST_MINIGAME]);
|
||||
@@ -2957,6 +2978,40 @@ void Settings::RandomizeAllSettings() {
|
||||
case RSK_STARTING_REQUIEM_OF_SPIRIT:
|
||||
case RSK_STARTING_NOCTURNE_OF_SHADOW:
|
||||
case RSK_STARTING_PRELUDE_OF_LIGHT:
|
||||
case RSK_STARTING_MEGATON_HAMMER:
|
||||
case RSK_STARTING_BOOMERANG:
|
||||
case RSK_STARTING_LENS_OF_TRUTH:
|
||||
case RSK_STARTING_DINS_FIRE:
|
||||
case RSK_STARTING_FARORES_WIND:
|
||||
case RSK_STARTING_NAYRUS_LOVE:
|
||||
case RSK_STARTING_FIRE_ARROWS:
|
||||
case RSK_STARTING_ICE_ARROWS:
|
||||
case RSK_STARTING_LIGHT_ARROWS:
|
||||
case RSK_STARTING_IRON_BOOTS:
|
||||
case RSK_STARTING_HOVER_BOOTS:
|
||||
case RSK_STARTING_HYLIAN_SHIELD:
|
||||
case RSK_STARTING_MIRROR_SHIELD:
|
||||
case RSK_STARTING_GORON_TUNIC:
|
||||
case RSK_STARTING_ZORA_TUNIC:
|
||||
case RSK_STARTING_STONE_OF_AGONY:
|
||||
case RSK_STARTING_HOOKSHOT:
|
||||
case RSK_STARTING_BOW:
|
||||
case RSK_STARTING_SLINGSHOT:
|
||||
case RSK_STARTING_BOMB_BAG:
|
||||
case RSK_STARTING_STRENGTH:
|
||||
case RSK_STARTING_SCALE:
|
||||
case RSK_STARTING_WALLET:
|
||||
case RSK_STARTING_MAGIC_METER:
|
||||
case RSK_STARTING_BOMBCHU_BAG:
|
||||
case RSK_STARTING_BOTTLE_1:
|
||||
case RSK_STARTING_BOTTLE_2:
|
||||
case RSK_STARTING_BOTTLE_3:
|
||||
case RSK_STARTING_BOTTLE_4:
|
||||
case RSK_STARTING_WEIRD_EGG:
|
||||
case RSK_STARTING_CLAIM_CHECK:
|
||||
case RSK_STARTING_GERUDO_CARD:
|
||||
case RSK_STARTING_BIGGORON_SWORD:
|
||||
case RSK_STARTING_BUNNY_HOOD:
|
||||
continue;
|
||||
default:
|
||||
break;
|
||||
|
||||
@@ -45,6 +45,7 @@ void ShowRandomizerSettingsMenu();
|
||||
void ShowEscMenu();
|
||||
UIWidgets::Colors GetMenuThemeColor();
|
||||
std::shared_ptr<SohMenu> GetSohMenu();
|
||||
void DrawStartingItemsMenu(WidgetInfo& info);
|
||||
} // namespace SohGui
|
||||
|
||||
#define THEME_COLOR SohGui::GetMenuThemeColor()
|
||||
|
||||
@@ -691,7 +691,9 @@ void SohMenu::AddMenuRandomizer() {
|
||||
randoSettings->GetOptionGroup(RSG_MENU_SIDEBAR_DUNGEONS).AddWidgets(path);
|
||||
randoSettings->GetOptionGroup(RSG_MENU_SIDEBAR_SHUFFLES).AddWidgets(path);
|
||||
randoSettings->GetOptionGroup(RSG_MENU_SIDEBAR_HINTS_TRAPS).AddWidgets(path);
|
||||
randoSettings->GetOptionGroup(RSG_MENU_SIDEBAR_STARTING_ITEMS).AddWidgets(path);
|
||||
path.sidebarName = "Starting Items";
|
||||
AddSidebarEntry("Randomizer", path.sidebarName, 1);
|
||||
AddWidget(path, "Starting Items", WIDGET_CUSTOM).CustomFunction(DrawStartingItemsMenu);
|
||||
path.sidebarName = "Locations";
|
||||
AddSidebarEntry("Randomizer", path.sidebarName, 1);
|
||||
AddWidget(path, "Excluded Locations", WIDGET_CUSTOM).CustomFunction(DrawLocationsMenu);
|
||||
|
||||
@@ -0,0 +1,336 @@
|
||||
#include "SohMenu.h"
|
||||
#include "soh/SohGui/SohGui.hpp"
|
||||
#include "soh/SohGui/UIWidgets.hpp"
|
||||
#include "soh/SohGui/ImGuiUtils.h"
|
||||
#include "soh/OTRGlobals.h"
|
||||
#include "soh/cvar_prefixes.h"
|
||||
#include "soh/Enhancements/game-interactor/GameInteractor.h"
|
||||
#include "soh/Enhancements/randomizer/settings.h"
|
||||
|
||||
#include <vector>
|
||||
#include <fast/Fast3dGui.h>
|
||||
#include <libultraship/libultraship.h>
|
||||
|
||||
extern "C" {
|
||||
#include "variables.h"
|
||||
#include "z64.h"
|
||||
}
|
||||
|
||||
namespace SohGui {
|
||||
|
||||
using namespace UIWidgets;
|
||||
|
||||
static constexpr float kIconSize = 48.0f;
|
||||
static const ImVec2 kSongSize = ImVec2(32.0f, 48.0f);
|
||||
|
||||
static std::shared_ptr<Fast::Fast3dGui> GetFast3dGui() {
|
||||
return std::dynamic_pointer_cast<Fast::Fast3dGui>(Ship::Context::GetRawInstance()->GetWindow()->GetGui());
|
||||
}
|
||||
|
||||
static void SaveStartingItemCVars() {
|
||||
Ship::Context::GetRawInstance()->GetWindow()->GetGui()->SaveConsoleVariablesNextFrame();
|
||||
}
|
||||
|
||||
// Toggleable item icon (lit when the starting CVar is set, faded when not), mirroring
|
||||
// DrawQuestItemButton in the save editor. The CVar name and tooltip come from the Option itself.
|
||||
static void StartingItemToggle(RandomizerSettingKey rsk, uint32_t itemId, bool forceFaded = false) {
|
||||
Rando::Option& option = Rando::Settings::GetInstance()->GetOption(rsk);
|
||||
const char* cvar = option.GetCVarName().c_str();
|
||||
const ItemMapEntry& entry = itemMapping[itemId];
|
||||
bool on = !forceFaded && CVarGetInteger(cvar, 0) != 0;
|
||||
|
||||
ImGui::PushID(static_cast<int32_t>(rsk));
|
||||
PushStyleButton(Colors::DarkGray);
|
||||
if (ImGui::ImageButton(entry.name.c_str(), GetFast3dGui()->GetTextureByName(on ? entry.name : entry.nameFaded),
|
||||
ImVec2(kIconSize, kIconSize), ImVec2(0, 0), ImVec2(1, 1))) {
|
||||
CVarSetInteger(cvar, on ? 0 : 1);
|
||||
SaveStartingItemCVars();
|
||||
}
|
||||
PopStyleButton();
|
||||
Tooltip(option.GetName().c_str());
|
||||
ImGui::PopID();
|
||||
}
|
||||
|
||||
// Tiered item icon with a popup picker (None + one icon per tier), mirroring DrawUpgradeIcon.
|
||||
// `itemIds[i]` is the icon shown for CVar value `i + 1`; value 0 shows itemIds[0] faded.
|
||||
static void StartingItemTiered(RandomizerSettingKey rsk, const std::vector<uint32_t>& itemIds) {
|
||||
Rando::Option& option = Rando::Settings::GetInstance()->GetOption(rsk);
|
||||
const char* cvar = option.GetCVarName().c_str();
|
||||
int32_t value = CVarGetInteger(cvar, 0);
|
||||
|
||||
ImGui::PushID(static_cast<int32_t>(rsk));
|
||||
const ItemMapEntry& displayEntry = itemMapping[itemIds[value > 0 ? value - 1 : 0]];
|
||||
bool lit = value > 0;
|
||||
PushStyleButton(Colors::DarkGray);
|
||||
if (ImGui::ImageButton(displayEntry.name.c_str(),
|
||||
GetFast3dGui()->GetTextureByName(lit ? displayEntry.name : displayEntry.nameFaded),
|
||||
ImVec2(kIconSize, kIconSize), ImVec2(0, 0), ImVec2(1, 1))) {
|
||||
ImGui::OpenPopup("tieredPicker");
|
||||
}
|
||||
PopStyleButton();
|
||||
Tooltip(option.GetName().c_str());
|
||||
|
||||
if (ImGui::BeginPopup("tieredPicker")) {
|
||||
PushStyleButton(Colors::DarkGray);
|
||||
if (ImGui::Button("##none", ImVec2(kIconSize, kIconSize) + ImGui::GetStyle().FramePadding * 2)) {
|
||||
CVarSetInteger(cvar, 0);
|
||||
SaveStartingItemCVars();
|
||||
ImGui::CloseCurrentPopup();
|
||||
}
|
||||
PopStyleButton();
|
||||
Tooltip("None");
|
||||
for (size_t i = 0; i < itemIds.size(); i++) {
|
||||
ImGui::SameLine();
|
||||
const ItemMapEntry& entry = itemMapping[itemIds[i]];
|
||||
PushStyleButton(Colors::DarkGray);
|
||||
if (ImGui::ImageButton(entry.name.c_str(), GetFast3dGui()->GetTextureByName(entry.name),
|
||||
ImVec2(kIconSize, kIconSize), ImVec2(0, 0), ImVec2(1, 1))) {
|
||||
CVarSetInteger(cvar, static_cast<int32_t>(i) + 1);
|
||||
SaveStartingItemCVars();
|
||||
ImGui::CloseCurrentPopup();
|
||||
}
|
||||
PopStyleButton();
|
||||
Tooltip(option.GetOptionText(i + 1).c_str());
|
||||
}
|
||||
ImGui::EndPopup();
|
||||
}
|
||||
ImGui::PopID();
|
||||
}
|
||||
|
||||
// Toggleable 32x48 song icon, mirroring the songMapping loop in DrawQuestStatusTab.
|
||||
static void StartingSongToggle(RandomizerSettingKey rsk, QuestItem song) {
|
||||
Rando::Option& option = Rando::Settings::GetInstance()->GetOption(rsk);
|
||||
const char* cvar = option.GetCVarName().c_str();
|
||||
const SongMapEntry& entry = songMapping[song];
|
||||
bool on = CVarGetInteger(cvar, 0) != 0;
|
||||
|
||||
ImGui::PushID(static_cast<int32_t>(rsk));
|
||||
PushStyleButton(Colors::DarkGray);
|
||||
if (ImGui::ImageButton(entry.name.c_str(), GetFast3dGui()->GetTextureByName(on ? entry.name : entry.nameFaded),
|
||||
kSongSize, ImVec2(0, 0), ImVec2(1, 1))) {
|
||||
CVarSetInteger(cvar, on ? 0 : 1);
|
||||
SaveStartingItemCVars();
|
||||
}
|
||||
PopStyleButton();
|
||||
Tooltip(option.GetName().c_str());
|
||||
ImGui::PopID();
|
||||
}
|
||||
|
||||
// Item icon followed by a count slider, like the ammo rows in DrawInventoryTab. The slider
|
||||
// mirrors the Option's own semantics: the CVar stores the option index and the displayed
|
||||
// number comes from the option text (matching how WIDGET_CVAR_SLIDER_INT renders these).
|
||||
static void StartingItemCount(RandomizerSettingKey rsk, uint32_t itemId) {
|
||||
Rando::Option& option = Rando::Settings::GetInstance()->GetOption(rsk);
|
||||
const char* cvar = option.GetCVarName().c_str();
|
||||
const ItemMapEntry& entry = itemMapping[itemId];
|
||||
|
||||
ImGui::PushID(static_cast<int32_t>(rsk));
|
||||
ImGui::Image(GetFast3dGui()->GetTextureByName(entry.name), ImVec2(kIconSize, kIconSize));
|
||||
ImGui::SameLine();
|
||||
int32_t value = CVarGetInteger(cvar, option.GetMenuOptionDefault());
|
||||
CVarSliderInt(option.GetName().c_str(), cvar,
|
||||
IntSliderOptions()
|
||||
.Color(THEME_COLOR)
|
||||
.Min(0)
|
||||
.Max(static_cast<int32_t>(option.GetOptionCount()) - 1)
|
||||
.DefaultValue(option.GetMenuOptionDefault())
|
||||
.Format(option.GetOptionText(value).c_str())
|
||||
.LabelPosition(LabelPositions::Near));
|
||||
ImGui::PopID();
|
||||
}
|
||||
|
||||
// Plain combobox bound to an Option's CVar, with option text pulled from the Option.
|
||||
static void StartingItemCombobox(RandomizerSettingKey rsk) {
|
||||
Rando::Option& option = Rando::Settings::GetInstance()->GetOption(rsk);
|
||||
std::vector<const char*> entries;
|
||||
for (size_t i = 0; i < option.GetOptionCount(); i++) {
|
||||
entries.push_back(option.GetOptionText(i).c_str());
|
||||
}
|
||||
CVarCombobox(option.GetName().c_str(), option.GetCVarName().c_str(), entries,
|
||||
ComboboxOptions().Color(THEME_COLOR).LabelPosition(LabelPositions::Above));
|
||||
}
|
||||
|
||||
void DrawStartingItemsMenu(WidgetInfo& info) {
|
||||
bool generating = CVarGetInteger(CVAR_GENERAL("RandoGenerating"), 0);
|
||||
bool disableEditingRandoSettings = generating || CVarGetInteger(CVAR_GENERAL("OnFileSelectNameEntry"), 0);
|
||||
ImGui::BeginDisabled(CVarGetInteger(CVAR_SETTING("DisableChanges"), 0) || disableEditingRandoSettings);
|
||||
|
||||
ImGui::SeparatorText("Equipment");
|
||||
StartingItemToggle(RSK_STARTING_KOKIRI_SWORD, ITEM_SWORD_KOKIRI);
|
||||
ImGui::SameLine();
|
||||
StartingItemToggle(RSK_STARTING_MASTER_SWORD, ITEM_SWORD_MASTER);
|
||||
ImGui::SameLine();
|
||||
StartingItemTiered(RSK_STARTING_BIGGORON_SWORD, { ITEM_SWORD_KNIFE, ITEM_SWORD_BGS });
|
||||
ImGui::SameLine();
|
||||
StartingItemToggle(RSK_STARTING_DEKU_SHIELD, ITEM_SHIELD_DEKU);
|
||||
ImGui::SameLine();
|
||||
StartingItemToggle(RSK_STARTING_HYLIAN_SHIELD, ITEM_SHIELD_HYLIAN);
|
||||
ImGui::SameLine();
|
||||
StartingItemToggle(RSK_STARTING_MIRROR_SHIELD, ITEM_SHIELD_MIRROR);
|
||||
|
||||
StartingItemToggle(RSK_STARTING_GORON_TUNIC, ITEM_TUNIC_GORON);
|
||||
ImGui::SameLine();
|
||||
StartingItemToggle(RSK_STARTING_ZORA_TUNIC, ITEM_TUNIC_ZORA);
|
||||
ImGui::SameLine();
|
||||
StartingItemToggle(RSK_STARTING_IRON_BOOTS, ITEM_BOOTS_IRON);
|
||||
ImGui::SameLine();
|
||||
StartingItemToggle(RSK_STARTING_HOVER_BOOTS, ITEM_BOOTS_HOVER);
|
||||
ImGui::SameLine();
|
||||
StartingItemToggle(RSK_STARTING_STONE_OF_AGONY, ITEM_STONE_OF_AGONY);
|
||||
ImGui::SameLine();
|
||||
StartingItemToggle(RSK_STARTING_GERUDO_CARD, ITEM_GERUDO_CARD);
|
||||
|
||||
// Starting Strength/Scale have no effect when Grab/Swim are shuffled; the generator
|
||||
// force-disables them (settings.cpp), so gray them out to match.
|
||||
bool grabShuffled =
|
||||
CVarGetInteger(Rando::Settings::GetInstance()->GetOption(RSK_SHUFFLE_GRAB).GetCVarName().c_str(), 0) != 0;
|
||||
ImGui::BeginDisabled(grabShuffled);
|
||||
StartingItemTiered(RSK_STARTING_STRENGTH, { ITEM_BRACELET, ITEM_GAUNTLETS_SILVER, ITEM_GAUNTLETS_GOLD });
|
||||
ImGui::EndDisabled();
|
||||
if (grabShuffled && ImGui::IsItemHovered(ImGuiHoveredFlags_AllowWhenDisabled)) {
|
||||
ImGui::SetTooltip("Disabled because Shuffle Grab is on.");
|
||||
}
|
||||
ImGui::SameLine();
|
||||
bool swimShuffled =
|
||||
CVarGetInteger(Rando::Settings::GetInstance()->GetOption(RSK_SHUFFLE_SWIM).GetCVarName().c_str(), 0) != 0;
|
||||
ImGui::BeginDisabled(swimShuffled);
|
||||
StartingItemTiered(RSK_STARTING_SCALE, { ITEM_SCALE_SILVER, ITEM_SCALE_GOLDEN });
|
||||
ImGui::EndDisabled();
|
||||
if (swimShuffled && ImGui::IsItemHovered(ImGuiHoveredFlags_AllowWhenDisabled)) {
|
||||
ImGui::SetTooltip("Disabled because Shuffle Swim is on.");
|
||||
}
|
||||
ImGui::SameLine();
|
||||
StartingItemTiered(RSK_STARTING_MAGIC_METER, { ITEM_MAGIC_SMALL, ITEM_MAGIC_LARGE });
|
||||
ImGui::SameLine();
|
||||
StartingItemTiered(RSK_STARTING_WALLET, { ITEM_WALLET_ADULT, ITEM_WALLET_GIANT });
|
||||
|
||||
ImGui::SeparatorText("Items");
|
||||
bool stickBagShuffled =
|
||||
CVarGetInteger(Rando::Settings::GetInstance()->GetOption(RSK_SHUFFLE_DEKU_STICK_BAG).GetCVarName().c_str(),
|
||||
0) != 0;
|
||||
ImGui::BeginDisabled(stickBagShuffled);
|
||||
StartingItemToggle(RSK_STARTING_STICKS, ITEM_STICK, stickBagShuffled);
|
||||
ImGui::EndDisabled();
|
||||
if (stickBagShuffled && ImGui::IsItemHovered(ImGuiHoveredFlags_AllowWhenDisabled)) {
|
||||
ImGui::SetTooltip("Disabled because the Deku Stick Bag is being shuffled.");
|
||||
}
|
||||
ImGui::SameLine();
|
||||
bool nutBagShuffled =
|
||||
CVarGetInteger(Rando::Settings::GetInstance()->GetOption(RSK_SHUFFLE_DEKU_NUT_BAG).GetCVarName().c_str(), 0) !=
|
||||
0;
|
||||
ImGui::BeginDisabled(nutBagShuffled);
|
||||
StartingItemToggle(RSK_STARTING_NUTS, ITEM_NUT, nutBagShuffled);
|
||||
ImGui::EndDisabled();
|
||||
if (nutBagShuffled && ImGui::IsItemHovered(ImGuiHoveredFlags_AllowWhenDisabled)) {
|
||||
ImGui::SetTooltip("Disabled because the Deku Nut Bag is being shuffled.");
|
||||
}
|
||||
ImGui::SameLine();
|
||||
StartingItemTiered(RSK_STARTING_BOMB_BAG, { ITEM_BOMB_BAG_20, ITEM_BOMB_BAG_30, ITEM_BOMB_BAG_40 });
|
||||
ImGui::SameLine();
|
||||
StartingItemTiered(RSK_STARTING_BOW, { ITEM_QUIVER_30, ITEM_QUIVER_40, ITEM_QUIVER_50 });
|
||||
ImGui::SameLine();
|
||||
StartingItemToggle(RSK_STARTING_FIRE_ARROWS, ITEM_ARROW_FIRE);
|
||||
ImGui::SameLine();
|
||||
StartingItemToggle(RSK_STARTING_DINS_FIRE, ITEM_DINS_FIRE);
|
||||
|
||||
StartingItemTiered(RSK_STARTING_SLINGSHOT, { ITEM_BULLET_BAG_30, ITEM_BULLET_BAG_40, ITEM_BULLET_BAG_50 });
|
||||
ImGui::SameLine();
|
||||
StartingItemTiered(RSK_STARTING_OCARINA, { ITEM_OCARINA_FAIRY, ITEM_OCARINA_TIME });
|
||||
ImGui::SameLine();
|
||||
// The bombchu bag start option only makes sense when the bombchu bag setting enables bombchu bags;
|
||||
// single-bag mode is a simple toggle, progressive mode is tiered, and None disables it entirely.
|
||||
{
|
||||
Rando::Option& bombchuOption = Rando::Settings::GetInstance()->GetOption(RSK_BOMBCHU_BAG);
|
||||
int32_t bombchuMode = CVarGetInteger(bombchuOption.GetCVarName().c_str(), RO_BOMBCHU_BAG_NONE);
|
||||
if (bombchuMode == RO_BOMBCHU_BAG_PROGRESSIVE) {
|
||||
StartingItemTiered(RSK_STARTING_BOMBCHU_BAG, { ITEM_BOMBCHU, ITEM_BOMBCHU, ITEM_BOMBCHU });
|
||||
} else if (bombchuMode == RO_BOMBCHU_BAG_SINGLE) {
|
||||
StartingItemToggle(RSK_STARTING_BOMBCHU_BAG, ITEM_BOMBCHU);
|
||||
} else {
|
||||
ImGui::BeginDisabled();
|
||||
StartingItemToggle(RSK_STARTING_BOMBCHU_BAG, ITEM_BOMBCHU, true);
|
||||
ImGui::EndDisabled();
|
||||
if (ImGui::IsItemHovered(ImGuiHoveredFlags_AllowWhenDisabled)) {
|
||||
ImGui::SetTooltip("Enable the Bombchu Bag setting to start with bombchus.");
|
||||
}
|
||||
}
|
||||
}
|
||||
ImGui::SameLine();
|
||||
StartingItemTiered(RSK_STARTING_HOOKSHOT, { ITEM_HOOKSHOT, ITEM_LONGSHOT });
|
||||
ImGui::SameLine();
|
||||
StartingItemToggle(RSK_STARTING_ICE_ARROWS, ITEM_ARROW_ICE);
|
||||
ImGui::SameLine();
|
||||
StartingItemToggle(RSK_STARTING_FARORES_WIND, ITEM_FARORES_WIND);
|
||||
|
||||
StartingItemToggle(RSK_STARTING_BOOMERANG, ITEM_BOOMERANG);
|
||||
ImGui::SameLine();
|
||||
StartingItemToggle(RSK_STARTING_LENS_OF_TRUTH, ITEM_LENS);
|
||||
ImGui::SameLine();
|
||||
StartingItemToggle(RSK_STARTING_BEANS, ITEM_BEAN);
|
||||
ImGui::SameLine();
|
||||
StartingItemToggle(RSK_STARTING_MEGATON_HAMMER, ITEM_HAMMER);
|
||||
ImGui::SameLine();
|
||||
StartingItemToggle(RSK_STARTING_LIGHT_ARROWS, ITEM_ARROW_LIGHT);
|
||||
ImGui::SameLine();
|
||||
StartingItemToggle(RSK_STARTING_NAYRUS_LOVE, ITEM_NAYRUS_LOVE);
|
||||
|
||||
StartingItemTiered(RSK_STARTING_BOTTLE_1, { ITEM_BOTTLE, ITEM_BIG_POE, ITEM_LETTER_RUTO });
|
||||
ImGui::SameLine();
|
||||
StartingItemTiered(RSK_STARTING_BOTTLE_2, { ITEM_BOTTLE, ITEM_BIG_POE });
|
||||
ImGui::SameLine();
|
||||
StartingItemTiered(RSK_STARTING_BOTTLE_3, { ITEM_BOTTLE, ITEM_BIG_POE });
|
||||
ImGui::SameLine();
|
||||
StartingItemTiered(RSK_STARTING_BOTTLE_4, { ITEM_BOTTLE, ITEM_BIG_POE });
|
||||
ImGui::SameLine();
|
||||
StartingItemToggle(RSK_STARTING_CLAIM_CHECK, ITEM_CLAIM_CHECK);
|
||||
ImGui::SameLine();
|
||||
bool weirdEggShuffled =
|
||||
CVarGetInteger(Rando::Settings::GetInstance()->GetOption(RSK_SHUFFLE_WEIRD_EGG).GetCVarName().c_str(), 0) != 0;
|
||||
ImGui::BeginDisabled(!weirdEggShuffled);
|
||||
StartingItemToggle(RSK_STARTING_WEIRD_EGG, ITEM_WEIRD_EGG, !weirdEggShuffled);
|
||||
ImGui::EndDisabled();
|
||||
if (!weirdEggShuffled && ImGui::IsItemHovered(ImGuiHoveredFlags_AllowWhenDisabled)) {
|
||||
ImGui::SetTooltip("Enable Shuffle Weird Egg to start with the Weird Egg.");
|
||||
}
|
||||
ImGui::SameLine();
|
||||
StartingItemToggle(RSK_STARTING_BUNNY_HOOD, ITEM_MASK_BUNNY);
|
||||
|
||||
ImGui::SeparatorText("Songs");
|
||||
StartingSongToggle(RSK_STARTING_ZELDAS_LULLABY, QUEST_SONG_LULLABY);
|
||||
ImGui::SameLine();
|
||||
StartingSongToggle(RSK_STARTING_EPONAS_SONG, QUEST_SONG_EPONA);
|
||||
ImGui::SameLine();
|
||||
StartingSongToggle(RSK_STARTING_SARIAS_SONG, QUEST_SONG_SARIA);
|
||||
ImGui::SameLine();
|
||||
StartingSongToggle(RSK_STARTING_SUNS_SONG, QUEST_SONG_SUN);
|
||||
ImGui::SameLine();
|
||||
StartingSongToggle(RSK_STARTING_SONG_OF_TIME, QUEST_SONG_TIME);
|
||||
ImGui::SameLine();
|
||||
StartingSongToggle(RSK_STARTING_SONG_OF_STORMS, QUEST_SONG_STORMS);
|
||||
|
||||
StartingSongToggle(RSK_STARTING_MINUET_OF_FOREST, QUEST_SONG_MINUET);
|
||||
ImGui::SameLine();
|
||||
StartingSongToggle(RSK_STARTING_BOLERO_OF_FIRE, QUEST_SONG_BOLERO);
|
||||
ImGui::SameLine();
|
||||
StartingSongToggle(RSK_STARTING_SERENADE_OF_WATER, QUEST_SONG_SERENADE);
|
||||
ImGui::SameLine();
|
||||
StartingSongToggle(RSK_STARTING_REQUIEM_OF_SPIRIT, QUEST_SONG_REQUIEM);
|
||||
ImGui::SameLine();
|
||||
StartingSongToggle(RSK_STARTING_NOCTURNE_OF_SHADOW, QUEST_SONG_NOCTURNE);
|
||||
ImGui::SameLine();
|
||||
StartingSongToggle(RSK_STARTING_PRELUDE_OF_LIGHT, QUEST_SONG_PRELUDE);
|
||||
|
||||
ImGui::SeparatorText("Other");
|
||||
StartingItemCombobox(RSK_LINKS_POCKET);
|
||||
// The reward type only applies when Link's Pocket grants a dungeon reward.
|
||||
if (CVarGetInteger(Rando::Settings::GetInstance()->GetOption(RSK_LINKS_POCKET).GetCVarName().c_str(),
|
||||
RO_LINKS_POCKET_DUNGEON_REWARD) == RO_LINKS_POCKET_DUNGEON_REWARD) {
|
||||
StartingItemCombobox(RSK_LINKS_POCKET_REWARD);
|
||||
}
|
||||
StartingItemCount(RSK_STARTING_SKULLTULA_TOKEN, ITEM_SKULL_TOKEN);
|
||||
StartingItemCount(RSK_STARTING_HEARTS, ITEM_HEART_CONTAINER);
|
||||
|
||||
ImGui::EndDisabled();
|
||||
}
|
||||
|
||||
} // namespace SohGui
|
||||
Reference in New Issue
Block a user