Unify Shops, Scrubs and Merchants price and hinting code (#4321)

* commiting to branch switch

* shop,scrubs and merchant code unified

* last cleanups

* Update soh/soh/Enhancements/randomizer/hook_handlers.cpp

Co-authored-by: Pepe20129 <72659707+Pepe20129@users.noreply.github.com>

* attempt to fix reviews DOES NOT BUILD

* TIL include order matters

* Update soh/soh/Enhancements/randomizer/3drando/shops.cpp

Co-authored-by: Pepe20129 <72659707+Pepe20129@users.noreply.github.com>

* Update soh/soh/Enhancements/randomizer/3drando/shops.cpp

Note to self, Don't code tired. *proceeds to ignore note*

Co-authored-by: Angelo Bulfone <boomshroom@users.noreply.github.com>

* fix typos

* post merge

* commiting to check something

* probably cleaned up, needs a doublecheck

* fix presets

* address reviews

* fix small shopsanity count oversights

* undo rename

---------

Co-authored-by: Pepe20129 <72659707+Pepe20129@users.noreply.github.com>
Co-authored-by: Angelo Bulfone <boomshroom@users.noreply.github.com>
Co-authored-by: Malkierian <malkierian@gmail.com>
This commit is contained in:
Pepper0ni 2024-10-08 22:33:58 +01:00 committed by GitHub
parent a9fbd8243f
commit 10921b2ade
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
51 changed files with 1403 additions and 920 deletions

View File

@ -355,7 +355,7 @@ static size_t NextLineLength(const std::string* textStr, const size_t lastNewlin
} }
} }
void CustomMessage::AutoFormatString(std::string& str) const {// did I do this right? void CustomMessage::AutoFormatString(std::string& str) const {
ReplaceAltarIcons(str); ReplaceAltarIcons(str);
ReplaceColors(str); ReplaceColors(str);
// insert newlines either manually or when encountering a '&' // insert newlines either manually or when encountering a '&'
@ -363,60 +363,86 @@ void CustomMessage::AutoFormatString(std::string& str) const {// did I do this r
const bool hasIcon = str.find('$', 0) != std::string::npos; const bool hasIcon = str.find('$', 0) != std::string::npos;
size_t lineLength = NextLineLength(&str, lastNewline, hasIcon); size_t lineLength = NextLineLength(&str, lastNewline, hasIcon);
size_t lineCount = 1; size_t lineCount = 1;
while (lastNewline + lineLength < str.length()) { size_t yesNo = str.find("\x1B"s[0], lastNewline);
while (lastNewline + lineLength < str.length() || yesNo != std::string::npos) {
const size_t carrot = str.find('^', lastNewline); const size_t carrot = str.find('^', lastNewline);
const size_t ampersand = str.find('&', lastNewline); const size_t ampersand = str.find('&', lastNewline);
const size_t lastSpace = str.rfind(' ', lastNewline + lineLength); const size_t lastSpace = str.rfind(' ', lastNewline + lineLength);
if (lineCount < 4){ size_t waitForInput = str.find(WAIT_FOR_INPUT()[0], lastNewline);
// replace '&' first if it's within the newline range size_t newLine = str.find(NEWLINE()[0], lastNewline);
if (ampersand < lastNewline + lineLength) { if (carrot < waitForInput){
lastNewline = ampersand + 1; waitForInput = carrot;
// or move the lastNewline cursor to the next line if a '^' is encountered
} else if (carrot < lastNewline + lineLength) {
lastNewline = carrot + 1;
lineCount = 0;
// some lines need to be split but don't have spaces, look for periods instead
} else if (lastSpace == std::string::npos) {
const size_t lastPeriod = str.rfind('.', lastNewline + lineLength);
str.replace(lastPeriod, 1, ".&");
lastNewline = lastPeriod + 2;
} else {
str.replace(lastSpace, 1, "&");
lastNewline = lastSpace + 1;
}
lineCount += 1;
} else {
const size_t lastColor = str.rfind("\x05"s, lastNewline + lineLength);
std::string colorText = "";
//check if we are on a non default colour, as ^ resets it, and readd if needed
if (lastColor != std::string::npos && str[lastColor+1] != 0){
colorText = "\x05"s + str[lastColor+1];
}
// replace '&' first if it's within the newline range
if (ampersand < lastNewline + lineLength) {
str.replace(ampersand, 1, "^" + colorText);
lastNewline = ampersand + 1;
// or move the lastNewline cursor to the next line if a '^' is encountered.
} else if (carrot < lastNewline + lineLength) {
lastNewline = carrot + 1;
// some lines need to be split but don't have spaces, look for periods instead
} else if (lastSpace == std::string::npos) {
const size_t lastPeriod = str.rfind('.', lastNewline + lineLength);
str.replace(lastPeriod, 1, ".^" + colorText);
lastNewline = lastPeriod + 2;
} else {
str.replace(lastSpace, 1, "^" + colorText);
lastNewline = lastSpace + 1;
}
lineCount = 1;
} }
lineLength = NextLineLength(&str, lastNewline, hasIcon); if (ampersand < newLine){
newLine = ampersand;
}
if (lineCount != 3 && yesNo < lastNewline + lineLength && yesNo < waitForInput && yesNo < newLine){
if (lineCount >= 4){
str.replace(yesNo, 1, "^&&\x1B");
lineCount = 3;
lastNewline = yesNo + 3;
} else {
while(lineCount < 3){
str.replace(yesNo, 1, "&\x1B");
yesNo++;
lineCount++;
}
lastNewline = yesNo;
}
} else {
if (lineCount < 4){
// replace '&' first if it's within the newline range
if (newLine < lastNewline + lineLength) {
lastNewline = newLine + 1;
// or move the lastNewline cursor to the next line if a '^' is encountered
} else if (waitForInput < lastNewline + lineLength) {
lastNewline = waitForInput + 1;
lineCount = 0;
// some lines need to be split but don't have spaces, look for periods instead
} else if (lastSpace == std::string::npos) {
const size_t lastPeriod = str.rfind('.', lastNewline + lineLength);
str.replace(lastPeriod, 1, ".&");
lastNewline = lastPeriod + 2;
} else {
str.replace(lastSpace, 1, "&");
lastNewline = lastSpace + 1;
}
lineCount += 1;
} else {
const size_t lastColor = str.rfind("\x05"s, lastNewline + lineLength);
std::string colorText = "";
//check if we are on a non default colour, as ^ resets it, and readd if needed
if (lastColor != std::string::npos && str[lastColor+1] != 0){
colorText = "\x05"s + str[lastColor+1];
}
// replace '&' first if it's within the newline range
if (ampersand < lastNewline + lineLength) {
str.replace(ampersand, 1, "^" + colorText);
lastNewline = ampersand + 1;
// or move the lastNewline cursor to the next line if a '^' is encountered.
} else if (carrot < lastNewline + lineLength) {
lastNewline = carrot + 1;
// some lines need to be split but don't have spaces, look for periods instead
} else if (lastSpace == std::string::npos) {
const size_t lastPeriod = str.rfind('.', lastNewline + lineLength);
str.replace(lastPeriod, 1, ".^" + colorText);
lastNewline = lastPeriod + 2;
} else {
str.replace(lastSpace, 1, "^" + colorText);
lastNewline = lastSpace + 1;
}
lineCount = 1;
}
lineLength = NextLineLength(&str, lastNewline, hasIcon);
}
yesNo = str.find("\x1B"s[0], lastNewline);
} }
ReplaceSpecialCharacters(str); ReplaceSpecialCharacters(str);
ReplaceAltarIcons(str); ReplaceAltarIcons(str);
std::replace(str.begin(), str.end(), '&', NEWLINE()[0]); std::replace(str.begin(), str.end(), '&', NEWLINE()[0]);
std::replace(str.begin(), str.end(), '^', WAIT_FOR_INPUT()[0]); std::replace(str.begin(), str.end(), '^', WAIT_FOR_INPUT()[0]);
std::replace(str.begin(), str.end(), '@', PLAYER_NAME()[0]); std::replace(str.begin(), str.end(), '@', PLAYER_NAME()[0]);
std::replace(str.begin(), str.end(), '_', " "[0]);
str += MESSAGE_END(); str += MESSAGE_END();
} }
@ -572,11 +598,10 @@ bool CustomMessageManager::CreateGetItemMessage(std::string tableID, uint16_t gi
} }
bool CustomMessageManager::CreateMessage(std::string tableID, uint16_t textID, CustomMessage messageEntry) { bool CustomMessageManager::CreateMessage(std::string tableID, uint16_t textID, CustomMessage messageEntry) {
messageEntry.Format();
return InsertCustomMessage(tableID, textID, messageEntry); return InsertCustomMessage(tableID, textID, messageEntry);
} }
CustomMessage CustomMessageManager::RetrieveMessage(std::string tableID, uint16_t textID) { CustomMessage CustomMessageManager::RetrieveMessage(std::string tableID, uint16_t textID, MessageFormat format) {
std::unordered_map<std::string, CustomMessageTable>::const_iterator foundMessageTable = messageTables.find(tableID); std::unordered_map<std::string, CustomMessageTable>::const_iterator foundMessageTable = messageTables.find(tableID);
if (foundMessageTable == messageTables.end()) { if (foundMessageTable == messageTables.end()) {
throw(MessageNotFoundException(tableID, textID)); throw(MessageNotFoundException(tableID, textID));
@ -587,6 +612,15 @@ CustomMessage CustomMessageManager::RetrieveMessage(std::string tableID, uint16_
throw(MessageNotFoundException(tableID, textID)); throw(MessageNotFoundException(tableID, textID));
} }
CustomMessage message = foundMessage->second; CustomMessage message = foundMessage->second;
if (format == MF_FORMATTED){
message.Format();
} else if (format == MF_AUTO_FORMAT){
message.AutoFormat();
} else if (format == MF_CLEAN){
message.Clean();
}
return message; return message;
} }

View File

@ -242,9 +242,10 @@ class CustomMessageManager {
* *
* @param tableID the ID of the custom message table * @param tableID the ID of the custom message table
* @param textID the ID of the message you want to retrieve * @param textID the ID of the message you want to retrieve
* @param format the type of formatting to apply to the retrieved message
* @return CustomMessage * @return CustomMessage
*/ */
CustomMessage RetrieveMessage(std::string tableID, uint16_t textID); CustomMessage RetrieveMessage(std::string tableID, uint16_t textID, MessageFormat format = MF_RAW);
/** /**
* @brief Empties out the message table identified by tableID. * @brief Empties out the message table identified by tableID.

View File

@ -1,6 +1,10 @@
#pragma once #pragma once
#include "z64.h"
#include "../include/macros.h"
typedef enum { typedef enum {
TEXT_NONE = 0x000,
TEXT_SKULLTULA_PEOPLE_CURSE_BROKEN = 0x0021, TEXT_SKULLTULA_PEOPLE_CURSE_BROKEN = 0x0021,
TEXT_SKULLTULA_PEOPLE_IM_CURSED = 0x0022, TEXT_SKULLTULA_PEOPLE_IM_CURSED = 0x0022,
TEXT_SKULLTULA_PEOPLE_WELL_BE_CAREFUL = 0x0023, TEXT_SKULLTULA_PEOPLE_WELL_BE_CAREFUL = 0x0023,
@ -182,9 +186,12 @@ typedef enum {
TEXT_SCRUB_RANDOM = 0x9000, TEXT_SCRUB_RANDOM = 0x9000,
TEXT_SCRUB_RANDOM_FREE = 0x9001, TEXT_SCRUB_RANDOM_FREE = 0x9001,
TEXT_SHOP_ITEM_RANDOM = 0x9100, TEXT_SHOP_ITEM_RANDOM = 0x9100,
TEXT_SHOP_ITEM_RANDOM_CONFIRM = 0x9101, TEXT_SHOP_ITEM_RANDOM_CONFIRM = 0x9100 + NUM_SHOP_ITEMS,
TEXT_SHOP_ITEM_RANDOM_CONFIRM_END = 0x9100 + (NUM_SHOP_ITEMS * 2) - 1,
TEXT_WARP_RANDOM_REPLACED_TEXT = 0x9200, TEXT_WARP_RANDOM_REPLACED_TEXT = 0x9200,
TEXT_SHOOTING_GALLERY_MAN_COME_BACK_WITH_BOW = 0x9210, TEXT_SHOOTING_GALLERY_MAN_COME_BACK_WITH_BOW = 0x9210,
TEXT_CARPET_SALESMAN_MYSTERIOUS = 0x9211,
TEXT_CARPET_SALESMAN_ARMS_DEALER = 0x9212,
} TextIDs; } TextIDs;
#ifdef __cplusplus #ifdef __cplusplus

View File

@ -1320,16 +1320,7 @@ void DrawEquipmentTab() {
"Giant (500)", "Giant (500)",
}; };
// only display Tycoon wallet if you're in a save file that would allow it. // only display Tycoon wallet if you're in a save file that would allow it.
if ( if (IS_RANDO && OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_INCLUDE_TYCOON_WALLET)) {
IS_RANDO &&
!(
OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_SHOPSANITY) == RO_SHOPSANITY_OFF ||
(
OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_SHOPSANITY) == RO_SHOPSANITY_SPECIFIC_COUNT &&
OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_SHOPSANITY_COUNT) == RO_SHOPSANITY_COUNT_ZERO_ITEMS
)
)
) {
const std::string walletName = "Tycoon (999)"; const std::string walletName = "Tycoon (999)";
walletNamesImpl.push_back(walletName); walletNamesImpl.push_back(walletName);
} }

View File

@ -184,6 +184,8 @@ typedef enum {
// Opt: *EnMk // Opt: *EnMk
// Vanilla condition: Flags_GetItemGetInf(ITEMGETINF_30) // Vanilla condition: Flags_GetItemGetInf(ITEMGETINF_30)
VB_OFFER_BLUE_POTION, VB_OFFER_BLUE_POTION,
VB_GRANNY_SAY_INSUFFICIENT_RUPEES,
VB_GRANNY_TAKE_MONEY,
// Vanilla condition: Inventory_HasEmptyBottle() == 0 // Vanilla condition: Inventory_HasEmptyBottle() == 0
VB_NEED_BOTTLE_FOR_GRANNYS_ITEM, VB_NEED_BOTTLE_FOR_GRANNYS_ITEM,
// Opt: *EnNiwLady // Opt: *EnNiwLady
@ -369,9 +371,11 @@ typedef enum {
// Opt: *EnGo2 // Opt: *EnGo2
VB_GIVE_ITEM_FROM_GORON, VB_GIVE_ITEM_FROM_GORON,
// Opt: *EnJs // Opt: *EnJs
VB_CHECK_RANDO_PRICE_OF_CARPET_SALESMAN,
VB_GIVE_ITEM_FROM_CARPET_SALESMAN, VB_GIVE_ITEM_FROM_CARPET_SALESMAN,
VB_GIVE_BOMBCHUS_FROM_CARPET_SALESMAN, VB_GIVE_BOMBCHUS_FROM_CARPET_SALESMAN,
// Opt: *EnGm // Opt: *EnGm
VB_CHECK_RANDO_PRICE_OF_MEDIGORON,
VB_GIVE_ITEM_FROM_MEDIGORON, VB_GIVE_ITEM_FROM_MEDIGORON,
// Opt: *EnMs // Opt: *EnMs
VB_GIVE_ITEM_FROM_MAGIC_BEAN_SALESMAN, VB_GIVE_ITEM_FROM_MAGIC_BEAN_SALESMAN,

View File

@ -437,10 +437,18 @@ const std::vector<const char*> randomizerCvars = {
CVAR_RANDOMIZER_SETTING("RewardCount"), CVAR_RANDOMIZER_SETTING("RewardCount"),
CVAR_RANDOMIZER_SETTING("ScrubText"), CVAR_RANDOMIZER_SETTING("ScrubText"),
CVAR_RANDOMIZER_SETTING("Shopsanity"), CVAR_RANDOMIZER_SETTING("Shopsanity"),
CVAR_RANDOMIZER_SETTING("ShopsanityCount"),
CVAR_RANDOMIZER_SETTING("ShopsanityPrices"), CVAR_RANDOMIZER_SETTING("ShopsanityPrices"),
CVAR_RANDOMIZER_SETTING("ShopsanityFixedPrice"),
CVAR_RANDOMIZER_SETTING("ShopsanityPriceRange1"),
CVAR_RANDOMIZER_SETTING("ShopsanityPriceRange2"),
CVAR_RANDOMIZER_SETTING("ShopsanityNoWalletWeight"),
CVAR_RANDOMIZER_SETTING("ShopsanityChildWalletWeight"),
CVAR_RANDOMIZER_SETTING("ShopsanityAdultWalletWeight"),
CVAR_RANDOMIZER_SETTING("ShopsanityGiantWalletWeight"),
CVAR_RANDOMIZER_SETTING("ShopsanityTycoonWalletWeight"),
CVAR_RANDOMIZER_SETTING("ShopsanityPricesAffordable"), CVAR_RANDOMIZER_SETTING("ShopsanityPricesAffordable"),
CVAR_RANDOMIZER_SETTING("ShuffleAdultTrade"), CVAR_RANDOMIZER_SETTING("ShuffleAdultTrade"),
CVAR_RANDOMIZER_SETTING("ShuffleBeans"),
CVAR_RANDOMIZER_SETTING("ShuffleBossEntrances"), CVAR_RANDOMIZER_SETTING("ShuffleBossEntrances"),
CVAR_RANDOMIZER_SETTING("ShuffleCows"), CVAR_RANDOMIZER_SETTING("ShuffleCows"),
CVAR_RANDOMIZER_SETTING("ShuffleDungeonReward"), CVAR_RANDOMIZER_SETTING("ShuffleDungeonReward"),
@ -464,11 +472,29 @@ const std::vector<const char*> randomizerCvars = {
CVAR_RANDOMIZER_SETTING("ShuffleKeyRingsWaterTemple"), CVAR_RANDOMIZER_SETTING("ShuffleKeyRingsWaterTemple"),
CVAR_RANDOMIZER_SETTING("ShuffleKokiriSword"), CVAR_RANDOMIZER_SETTING("ShuffleKokiriSword"),
CVAR_RANDOMIZER_SETTING("ShuffleMerchants"), CVAR_RANDOMIZER_SETTING("ShuffleMerchants"),
CVAR_RANDOMIZER_SETTING("MerchantFixedPrice"),
CVAR_RANDOMIZER_SETTING("MerchantPriceRange1"),
CVAR_RANDOMIZER_SETTING("MerchantPriceRange2"),
CVAR_RANDOMIZER_SETTING("MerchantNoWalletWeight"),
CVAR_RANDOMIZER_SETTING("MerchantChildWalletWeight"),
CVAR_RANDOMIZER_SETTING("MerchantAdultWalletWeight"),
CVAR_RANDOMIZER_SETTING("MerchantGiantWalletWeight"),
CVAR_RANDOMIZER_SETTING("MerchantTycoonWalletWeight"),
CVAR_RANDOMIZER_SETTING("MerchantPricesAffordable"),
CVAR_RANDOMIZER_SETTING("ShuffleOcarinas"), CVAR_RANDOMIZER_SETTING("ShuffleOcarinas"),
CVAR_RANDOMIZER_SETTING("ShuffleOverworldEntrances"), CVAR_RANDOMIZER_SETTING("ShuffleOverworldEntrances"),
CVAR_RANDOMIZER_SETTING("ShuffleOverworldSpawns"), CVAR_RANDOMIZER_SETTING("ShuffleOverworldSpawns"),
CVAR_RANDOMIZER_SETTING("ShuffleOwlDrops"), CVAR_RANDOMIZER_SETTING("ShuffleOwlDrops"),
CVAR_RANDOMIZER_SETTING("ShuffleScrubs"), CVAR_RANDOMIZER_SETTING("ShuffleScrubs"),
CVAR_RANDOMIZER_SETTING("ScrubsFixedPrice"),
CVAR_RANDOMIZER_SETTING("ScrubsPriceRange1"),
CVAR_RANDOMIZER_SETTING("ScrubsPriceRange2"),
CVAR_RANDOMIZER_SETTING("ScrubsNoWalletWeight"),
CVAR_RANDOMIZER_SETTING("ScrubsChildWalletWeight"),
CVAR_RANDOMIZER_SETTING("ScrubsAdultWalletWeight"),
CVAR_RANDOMIZER_SETTING("ScrubstGiantWalletWeight"),
CVAR_RANDOMIZER_SETTING("ScrubsTycoonWalletWeight"),
CVAR_RANDOMIZER_SETTING("ScrubsPricesAffordable"),
CVAR_RANDOMIZER_SETTING("ShuffleSongs"), CVAR_RANDOMIZER_SETTING("ShuffleSongs"),
CVAR_RANDOMIZER_SETTING("ShuffleTokens"), CVAR_RANDOMIZER_SETTING("ShuffleTokens"),
CVAR_RANDOMIZER_SETTING("ShuffleWarpSongs"), CVAR_RANDOMIZER_SETTING("ShuffleWarpSongs"),
@ -955,12 +981,16 @@ const std::vector<PresetEntry> spockRacePresetEntries = {
PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("LacsRewardCount"), 5), PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("LacsRewardCount"), 5),
PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("RainbowBridge"), RO_BRIDGE_GREG), PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("RainbowBridge"), RO_BRIDGE_GREG),
PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("ScrubText"), 1), PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("ScrubText"), 1),
PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("IncludeTycoonWallet"), 1),
PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("Shopsanity"), RO_SHOPSANITY_RANDOM), PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("Shopsanity"), RO_SHOPSANITY_RANDOM),
PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("ShopsanityPrices"), RO_PRICE_BALANCED),
PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("ShuffleGanonBossKey"), RO_GANON_BOSS_KEY_LACS_REWARDS), PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("ShuffleGanonBossKey"), RO_GANON_BOSS_KEY_LACS_REWARDS),
PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("ShuffleKeyRings"), RO_KEYRINGS_COUNT), PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("ShuffleKeyRings"), RO_KEYRINGS_COUNT),
PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("ShuffleKokiriSword"), 1), PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("ShuffleKokiriSword"), 1),
PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("ShuffleOcarinas"), 1), PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("ShuffleOcarinas"), 1),
PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("ShuffleScrubs"), RO_SCRUBS_AFFORDABLE), PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("ShuffleScrubs"), RO_SCRUBS_ALL),
PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("ScrubsPrice"), RO_PRICE_FIXED),
PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("ScrubsFixedPrice"), 10),
PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("SkipChildStealth"), 1), PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("SkipChildStealth"), 1),
PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("SkipChildZelda"), 1), PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("SkipChildZelda"), 1),
PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("SkipEponaRace"), 1), PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("SkipEponaRace"), 1),
@ -1037,9 +1067,12 @@ const std::vector<PresetEntry> spockRaceNoLogicPresetEntries = {
PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("LogicRules"), RO_LOGIC_NO_LOGIC), PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("LogicRules"), RO_LOGIC_NO_LOGIC),
PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("RainbowBridge"), RO_BRIDGE_GREG), PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("RainbowBridge"), RO_BRIDGE_GREG),
PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("ScrubText"), 1), PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("ScrubText"), 1),
PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("IncludeTycoonWallet"), 1),
PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("Shopsanity"), RO_SHOPSANITY_RANDOM), PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("Shopsanity"), RO_SHOPSANITY_RANDOM),
PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("ShopsanityPrices"), RO_PRICE_BALANCED),
PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("ShuffleAdultTrade"), 0), PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("ShuffleAdultTrade"), 0),
PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("ShuffleBeans"), 1), PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("ShuffleMerchants"), RO_SHUFFLE_MERCHANTS_BEANS_ONLY),
PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("ShuffleMerchantPrices"), RO_PRICE_VANILLA),
PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("ShuffleGanonBossKey"), RO_GANON_BOSS_KEY_LACS_REWARDS), PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("ShuffleGanonBossKey"), RO_GANON_BOSS_KEY_LACS_REWARDS),
PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("ShuffleGerudoToken"), 1), PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("ShuffleGerudoToken"), 1),
PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("ShuffleKeyRings"), RO_KEYRINGS_COUNT), PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("ShuffleKeyRings"), RO_KEYRINGS_COUNT),
@ -1121,11 +1154,15 @@ const std::vector<PresetEntry> hellModePresetEntries = {
PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("LinksPocket"), RO_LINKS_POCKET_NOTHING), PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("LinksPocket"), RO_LINKS_POCKET_NOTHING),
PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("MQDungeons"), RO_MQ_DUNGEONS_RANDOM_NUMBER), PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("MQDungeons"), RO_MQ_DUNGEONS_RANDOM_NUMBER),
PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("RainbowBridge"), RO_BRIDGE_DUNGEON_REWARDS), PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("RainbowBridge"), RO_BRIDGE_DUNGEON_REWARDS),
PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("IncludeTycoonWallet"), 1),
PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("Shopsanity"), RO_SHOPSANITY_SPECIFIC_COUNT), PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("Shopsanity"), RO_SHOPSANITY_SPECIFIC_COUNT),
PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("ShopsanityCount"), RO_SHOPSANITY_COUNT_FOUR_ITEMS), PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("ShopsanityCount"), RO_SHOPSANITY_COUNT_FOUR_ITEMS),
PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("ShopsanityPrices"), RO_SHOPSANITY_PRICE_TYCOON), PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("ShopsanityPrices"), RO_PRICE_RANGE),
PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("ShopsanityPriceRange1"), 0),
PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("ShopsanityPriceRange2"), 999),
PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("ShuffleAdultTrade"), 1), PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("ShuffleAdultTrade"), 1),
PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("ShuffleBeans"), 1), PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("ShuffleMerchants"), RO_SHUFFLE_MERCHANTS_BEANS_ONLY),
PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("ShuffleMerchantPrices"), RO_PRICE_VANILLA),
PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("ShuffleCows"), 1), PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("ShuffleCows"), 1),
PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("ShuffleDungeonReward"), RO_DUNGEON_REWARDS_ANYWHERE), PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("ShuffleDungeonReward"), RO_DUNGEON_REWARDS_ANYWHERE),
PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("ShuffleFrogSongRupees"), 1), PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("ShuffleFrogSongRupees"), 1),
@ -1135,7 +1172,8 @@ const std::vector<PresetEntry> hellModePresetEntries = {
PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("ShuffleKokiriSword"), 1), PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("ShuffleKokiriSword"), 1),
PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("ShuffleMasterSword"), 1), PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("ShuffleMasterSword"), 1),
PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("ShuffleOcarinas"), 1), PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("ShuffleOcarinas"), 1),
PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("ShuffleScrubs"), RO_SCRUBS_RANDOM), PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("ShuffleScrubs"), RO_SCRUBS_ALL),
PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("ScrubsPrice"), RO_PRICE_CHEAP_BALANCED),
PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("ShuffleSongs"), RO_SONG_SHUFFLE_ANYWHERE), PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("ShuffleSongs"), RO_SONG_SHUFFLE_ANYWHERE),
PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("ShuffleTokens"), RO_TOKENSANITY_ALL), PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("ShuffleTokens"), RO_TOKENSANITY_ALL),
PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("ShuffleWeirdEgg"), 1), PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("ShuffleWeirdEgg"), 1),
@ -1178,7 +1216,8 @@ const std::vector<PresetEntry> BenchmarkPresetEntries = {
PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("ShuffleDungeonReward"), RO_DUNGEON_REWARDS_END_OF_DUNGEON), PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("ShuffleDungeonReward"), RO_DUNGEON_REWARDS_END_OF_DUNGEON),
PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("LinksPocket"), RO_LINKS_POCKET_DUNGEON_REWARD), PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("LinksPocket"), RO_LINKS_POCKET_DUNGEON_REWARD),
PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("ShuffleSongs"), RO_SONG_SHUFFLE_ANYWHERE), PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("ShuffleSongs"), RO_SONG_SHUFFLE_ANYWHERE),
PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("Shopsanity"), RO_SHOPSANITY_COUNT_FOUR_ITEMS), PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("Shopsanity"), RO_SHOPSANITY_SPECIFIC_COUNT),
PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("ShopsanityCount"), RO_SHOPSANITY_COUNT_FOUR_ITEMS),
//RANDOTODO add refactored price/scrub/merchant settings //RANDOTODO add refactored price/scrub/merchant settings
PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("ShuffleTokens"), RO_TOKENSANITY_OFF), PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("ShuffleTokens"), RO_TOKENSANITY_OFF),
PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("ShuffleBeehives"), RO_GENERIC_ON), PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("ShuffleBeehives"), RO_GENERIC_ON),

View File

@ -1,5 +1,5 @@
#include "custom_messages.hpp" #include "custom_messages.hpp"
#include "shops.hpp" #include "../../custom-message/CustomMessageManager.h"
#include "z64item.h" #include "z64item.h"
#include <array> #include <array>

View File

@ -24,6 +24,40 @@ using namespace Rando;
static bool placementFailure = false; static bool placementFailure = false;
PriceSettingsStruct shopsanityPrices = {RSK_SHOPSANITY_PRICES,
RSK_SHOPSANITY_PRICES_FIXED_PRICE,
RSK_SHOPSANITY_PRICES_RANGE_1,
RSK_SHOPSANITY_PRICES_RANGE_2,
RSK_SHOPSANITY_PRICES_NO_WALLET_WEIGHT,
RSK_SHOPSANITY_PRICES_CHILD_WALLET_WEIGHT,
RSK_SHOPSANITY_PRICES_ADULT_WALLET_WEIGHT,
RSK_SHOPSANITY_PRICES_GIANT_WALLET_WEIGHT,
RSK_SHOPSANITY_PRICES_TYCOON_WALLET_WEIGHT,
RSK_SHOPSANITY_PRICES_AFFORDABLE};
PriceSettingsStruct scrubPrices = {RSK_SCRUBS_PRICES,
RSK_SCRUBS_PRICES_FIXED_PRICE,
RSK_SCRUBS_PRICES_RANGE_1,
RSK_SCRUBS_PRICES_RANGE_2,
RSK_SCRUBS_PRICES_NO_WALLET_WEIGHT,
RSK_SCRUBS_PRICES_CHILD_WALLET_WEIGHT,
RSK_SCRUBS_PRICES_ADULT_WALLET_WEIGHT,
RSK_SCRUBS_PRICES_GIANT_WALLET_WEIGHT,
RSK_SCRUBS_PRICES_TYCOON_WALLET_WEIGHT,
RSK_SCRUBS_PRICES_AFFORDABLE};
PriceSettingsStruct merchantPrices = {RSK_MERCHANT_PRICES,
RSK_MERCHANT_PRICES_FIXED_PRICE,
RSK_MERCHANT_PRICES_RANGE_1,
RSK_MERCHANT_PRICES_RANGE_2,
RSK_MERCHANT_PRICES_NO_WALLET_WEIGHT,
RSK_MERCHANT_PRICES_CHILD_WALLET_WEIGHT,
RSK_MERCHANT_PRICES_ADULT_WALLET_WEIGHT,
RSK_MERCHANT_PRICES_GIANT_WALLET_WEIGHT,
RSK_MERCHANT_PRICES_TYCOON_WALLET_WEIGHT,
RSK_MERCHANT_PRICES_AFFORDABLE};
static void RemoveStartingItemsFromPool() { static void RemoveStartingItemsFromPool() {
for (RandomizerGet startingItem : StartingInventory) { for (RandomizerGet startingItem : StartingInventory) {
for (size_t i = 0; i < ItemPool.size(); i++) { for (size_t i = 0; i < ItemPool.size(); i++) {
@ -1133,7 +1167,6 @@ int Fill() {
//Place shop items first, since a buy shield is needed to place a dungeon reward on Gohma due to access //Place shop items first, since a buy shield is needed to place a dungeon reward on Gohma due to access
StartPerformanceTimer(PT_SHOPSANITY); StartPerformanceTimer(PT_SHOPSANITY);
NonShopItems.clear();
if (ctx->GetOption(RSK_SHOPSANITY).Is(RO_SHOPSANITY_OFF)) { if (ctx->GetOption(RSK_SHOPSANITY).Is(RO_SHOPSANITY_OFF)) {
SPDLOG_INFO("Placing Vanilla Shop Items..."); SPDLOG_INFO("Placing Vanilla Shop Items...");
PlaceVanillaShopItems(); //Place vanilla shop items in vanilla location PlaceVanillaShopItems(); //Place vanilla shop items in vanilla location
@ -1154,17 +1187,10 @@ int Fill() {
total_replaced += num_to_replace; total_replaced += num_to_replace;
for (int j = 0; j < num_to_replace; j++) { for (int j = 0; j < num_to_replace; j++) {
int itemindex = indices[j]; int itemindex = indices[j];
int shopsanityPrice = GetRandomShopPrice(); RandomizerCheck rc = Rando::StaticData::GetShopLocations()[i * LOCATIONS_PER_SHOP + itemindex - 1];
NonShopItems[Rando::StaticData::GetShopLocations()[i * LOCATIONS_PER_SHOP + itemindex - 1]].Price = shopsanityPrice; // Set price to be retrieved by the patch and textboxes Rando::ItemLocation* itemLoc = ctx->GetItemLocation(rc);
ctx->GetItemLocation(Rando::StaticData::GetShopLocations()[i * LOCATIONS_PER_SHOP + itemindex - 1])->SetCustomPrice(shopsanityPrice); uint16_t shopsanityPrice = GetRandomPrice(Rando::StaticData::GetLocation(rc), shopsanityPrices);
} itemLoc->SetCustomPrice(shopsanityPrice);
for (int j = num_to_replace; j < 8; j++) {
ItemAndPrice init;
init.Name = Text { "No Item", "Sin objeto", "Pas d'objet" };
init.Price = -1;
init.Repurchaseable = false;
int itemindex = indices[j];
NonShopItems[Rando::StaticData::GetShopLocations()[i * LOCATIONS_PER_SHOP + itemindex - 1]] = init; // Set price to be retrieved by the patch and textboxes
} }
} }
#undef LOCATIONS_PER_SHOP #undef LOCATIONS_PER_SHOP
@ -1183,6 +1209,51 @@ int Fill() {
//Place the shop items which will still be at shop locations //Place the shop items which will still be at shop locations
AssumedFill(shopItems, shopLocations); AssumedFill(shopItems, shopLocations);
} }
//Add prices to scrubs
auto scrubLoc = Rando::StaticData::GetScrubLocations();
if (ctx->GetOption(RSK_SHUFFLE_SCRUBS).Is(RO_SCRUBS_ALL)) {
for (size_t i = 0; i < scrubLoc.size(); i++) {
ctx->GetItemLocation(scrubLoc[i])->SetCustomPrice(
GetRandomPrice(Rando::StaticData::GetLocation(scrubLoc[i]), scrubPrices)
);
}
} else {
for (size_t i = 0; i < scrubLoc.size(); i++) {
ctx->GetItemLocation(scrubLoc[i])->SetCustomPrice(
Rando::StaticData::GetLocation(scrubLoc[i])->GetVanillaPrice()
);
}
}
//set merchant prices
if (ctx->GetOption(RSK_SHUFFLE_MERCHANTS).Is(RO_SHUFFLE_MERCHANTS_BEANS_ONLY) ||
ctx->GetOption(RSK_SHUFFLE_MERCHANTS).Is(RO_SHUFFLE_MERCHANTS_ALL)){
ctx->GetItemLocation(RC_ZR_MAGIC_BEAN_SALESMAN)->SetCustomPrice(
GetRandomPrice(Rando::StaticData::GetLocation(RC_ZR_MAGIC_BEAN_SALESMAN), merchantPrices)
);
} else {
ctx->GetItemLocation(RC_ZR_MAGIC_BEAN_SALESMAN)->SetCustomPrice(
Rando::StaticData::GetLocation(RC_ZR_MAGIC_BEAN_SALESMAN)->GetVanillaPrice()
);
}
auto merchantLoc = Rando::StaticData::GetMerchantLocations();
if (ctx->GetOption(RSK_SHUFFLE_MERCHANTS).Is(RO_SHUFFLE_MERCHANTS_ALL_BUT_BEANS) ||
ctx->GetOption(RSK_SHUFFLE_MERCHANTS).Is(RO_SHUFFLE_MERCHANTS_ALL)){
for (size_t i = 0; i < merchantLoc.size(); i++) {
ctx->GetItemLocation(merchantLoc[i])->SetCustomPrice(
GetRandomPrice(Rando::StaticData::GetLocation(merchantLoc[i]), merchantPrices)
);
}
} else {
for (size_t i = 0; i < merchantLoc.size(); i++) {
ctx->GetItemLocation(merchantLoc[i])->SetCustomPrice(
Rando::StaticData::GetLocation(merchantLoc[i])->GetVanillaPrice()
);
}
}
StopPerformanceTimer(PT_SHOPSANITY); StopPerformanceTimer(PT_SHOPSANITY);
StartPerformanceTimer(PT_OWN_DUNGEON); StartPerformanceTimer(PT_OWN_DUNGEON);
@ -1245,28 +1316,6 @@ int Fill() {
FastFill(remainingPool, GetAllEmptyLocations(), false); FastFill(remainingPool, GetAllEmptyLocations(), false);
StopPerformanceTimer(PT_REMAINING_ITEMS); StopPerformanceTimer(PT_REMAINING_ITEMS);
//Add default prices to scrubs
for (RandomizerCheck& randomizerCheck : Rando::StaticData::GetScrubLocations()) {
if (randomizerCheck == RC_LW_DEKU_SCRUB_NEAR_BRIDGE || randomizerCheck == RC_LW_DEKU_SCRUB_GROTTO_FRONT) {
ctx->GetItemLocation(randomizerCheck)->SetCustomPrice(40);
} else if (randomizerCheck == RC_HF_DEKU_SCRUB_GROTTO) {
ctx->GetItemLocation(randomizerCheck)->SetCustomPrice(10);
} else {
auto loc = Rando::StaticData::GetLocation(randomizerCheck);
auto item = Rando::StaticData::RetrieveItem(loc->GetVanillaItem());
ctx->GetItemLocation(randomizerCheck)->SetCustomPrice(item.GetPrice());
}
}
if (ctx->GetOption(RSK_SHUFFLE_SCRUBS).Is(RO_SCRUBS_AFFORDABLE)) {
for (RandomizerCheck& randomizerCheck : Rando::StaticData::GetScrubLocations()) {
ctx->GetItemLocation(randomizerCheck)->SetCustomPrice(10);
}
} else if (ctx->GetOption(RSK_SHUFFLE_SCRUBS).Is(RO_SCRUBS_RANDOM)) {
for (RandomizerCheck& randomizerCheck : Rando::StaticData::GetScrubLocations()) {
ctx->GetItemLocation(randomizerCheck)->SetCustomPrice(GetRandomScrubPrice());
}
}
StartPerformanceTimer(PT_PLAYTHROUGH_GENERATION); StartPerformanceTimer(PT_PLAYTHROUGH_GENERATION);
GeneratePlaythrough(); GeneratePlaythrough();

View File

@ -2769,49 +2769,6 @@ void StaticData::HintTable_Init() {
| STATIC LOCATION HINTS | | STATIC LOCATION HINTS |
---------------------------*/ ---------------------------*/
hintTextTable[RHT_MEDIGORON_HINT] = HintText(CustomMessage("How about buying #[[1]]# for #200 Rupees#?&" + TWO_WAY_CHOICE() + "#Buy&Don't buy#",
/*german*/ "Möchtest Du #[[1]]# für #200 Rubine# kaufen?&" + TWO_WAY_CHOICE() + "#Klar!&Nie im Leben!#",
/*french*/ "Veux-tu acheter #[[1]]# pour #200 rubis#?&" + TWO_WAY_CHOICE() + "#Acheter&Ne pas acheter#",
{QM_GREEN, QM_YELLOW, QM_GREEN}));
/*spanish*/ // ¿Me compras #[[1]]# por #200 rupias#?&" + TWO_WAY_CHOICE() + "#Comprar&No comprar#
hintTextTable[RHT_CARPET_SALESMAN_DIALOG_FIRST] = HintText(CustomMessage("Welcome!^I am selling stuff, strange and rare, from all over the world to everybody. Today's special is...^",
/*german*/ "Sei gegrüßt!^Ich verkaufe allerlei Kuriositäten. Stets sonderliche und seltene Ware aus "
"aller Welt für jedermann. Das heutige Angebot bleibt...^#",
/*french*/ "Bienvenue!^Je vends des objets rares et merveilleux du monde entier. En spécial aujourd'hui...^"));
/*spanish*/ // ¡Acércate!^Vendo productos extraños y difíciles de encontrar... De todo el mundo a todo el mundo. La oferta de hoy es...^#¡
hintTextTable[RHT_CARPET_SALESMAN_DIALOG_MYSTERIOUS] = HintText(CustomMessage("Terrifying! I won't tell you what it is until I see the #money#...^How about #200 Rupees#?&&" +
TWO_WAY_CHOICE() + "#Buy&Don't buy#",
/*german*/ "Furchterregend, oder? Ich erzähle Euch mehr, wenn ich #Geld# sehe...^Wie wär's mit #200 Rubinen#?&&" +
TWO_WAY_CHOICE() + "#Aber sicher!&Ich bin weg!#",
/*french*/ "Un concentré de puissance! Mais montre tes #rubis# avant que je te dise ce que c'est...^Disons #200 "
"rubis#?&&" + TWO_WAY_CHOICE() + "#Acheter&Ne pas acheter#",
{QM_RED, QM_YELLOW, QM_GREEN}));
/*spanish*/ // ¡Terrorífico! No te revelaré su nombre hasta que vea el #dinero#...^#200 rupias#, ¿qué te parece?&&" +
// TWO_WAY_CHOICE() + "#Comprar&No comprar#
hintTextTable[RHT_CARPET_SALESMAN_DIALOG_HINTED] = HintText(CustomMessage("#[[1]]!# It's real, I promise! A lonely man such as myself wouldn't #lie# to you, hmm?^"
"How about #200 Rupees#?&&" + TWO_WAY_CHOICE() + "#Buy&Don't buy#",
/*german*/ "#[[1]]#! Ich kann versichern, es ist ein aufrichtiges Angebot!^Ein einsamer Mann wie ich würde Dich doch "
"nicht #anlügen#, oder?^Wie wär's mit #200 Rubinen#?&&" + TWO_WAY_CHOICE() + "#Aber sicher!&Ich bin weg!#",
/*french*/ "#[[1]]!# C'est vrai! J'te jure! Un gars comme moi ne te #mentirai# pas tu ne crois pas?^Disons #200 "
"rubis#?&&" + TWO_WAY_CHOICE() + "#Acheter&Ne pas acheter#",
{QM_GREEN, QM_YELLOW, QM_GREEN}));
hintTextTable[RHT_BEAN_SALESMAN_HINT] = HintText(CustomMessage("I tried to be a #magic bean# salesman, but it turns out my marketing skills weren't worth "
"beans!^Anyway, want to buy #[[1]]# for #60 Rupees#?&" + TWO_WAY_CHOICE() + "#Yes&No#",
/*german*/ "Möchten Sie #[[1]]# für #60 Rubine# kaufen?&" + TWO_WAY_CHOICE() + "#Ja&Nein#",
/*french*/ "J'ai essayé d'être un vendeur de #haricots magiques#, mais j'étais mauvais au niveau du marketing et ça "
"me courait sur le haricot...^Enfin bref, ça te dirait de m'acheter #[[1]]# pour #60 Rubis#?&" + TWO_WAY_CHOICE() + "#Oui&Non#",
{QM_RED, QM_GREEN, QM_YELLOW, QM_GREEN}));
hintTextTable[RHT_GRANNY_HINT] = HintText(CustomMessage("#[[1]]#! How about #100 Rupees#?&" + TWO_WAY_CHOICE() + "#Buy&Don't buy#",
/*german*/ "#[[1]]#! Sagen wir #100 Rubine#?&" + TWO_WAY_CHOICE() + "#Gerne!&Auf keinen Fall!#",
/*french*/ "#[[1]]#! Que dis-tu de #100 rubis#?&" + TWO_WAY_CHOICE() + "#Acheter&Ne pas acheter#",
{QM_GREEN, QM_YELLOW, QM_GREEN}, {true}));
// /*spanish*/#[[1]]#. Vendo por #100 rupias#.&" + TWO_WAY_CHOICE() + "#Comprar&No comprar#
hintTextTable[RHT_HBA_HINT_SIGN] = HintText(CustomMessage("#Horseback Archery# Range Prizes:&1000: #[[1]]#&1500: #[[2]]#^@'s Record: #" + CustomMessage::POINTS(HS_HORSE_ARCHERY) + "#", hintTextTable[RHT_HBA_HINT_SIGN] = HintText(CustomMessage("#Horseback Archery# Range Prizes:&1000: #[[1]]#&1500: #[[2]]#^@'s Record: #" + CustomMessage::POINTS(HS_HORSE_ARCHERY) + "#",
{QM_RED, QM_GREEN, QM_GREEN, QM_GREEN}, {}, TEXTBOX_TYPE_WOODEN)); {QM_RED, QM_GREEN, QM_GREEN, QM_GREEN}, {}, TEXTBOX_TYPE_WOODEN));

View File

@ -2128,5 +2128,8 @@ void StaticData::HintTable_Init_Item() {
hintTextTable[RHT_MYSTERIOUS_ITEM] = HintText(CustomMessage("mysterious item", /*german*/"mysteriöser Gegenstand", /*french*/"objet mystérieux")); hintTextTable[RHT_MYSTERIOUS_ITEM] = HintText(CustomMessage("mysterious item", /*german*/"mysteriöser Gegenstand", /*french*/"objet mystérieux"));
// /*spanish*/algo misterioso // /*spanish*/algo misterioso
hintTextTable[RHT_MYSTERIOUS_ITEM_CAPITAL] = HintText(CustomMessage("Mysterious Item", /*german*/"Mysteriöser Gegenstand", /*french*/"Objet Mystérieux"));
// /*spanish*/Algo Misterioso
} }
} }

View File

@ -533,7 +533,7 @@ int32_t getRandomWeight(int32_t totalWeight){
static void DistributeHints(std::vector<uint8_t>& selected, size_t stoneCount, std::vector<HintDistributionSetting> distTable, uint8_t junkWieght, bool addFixed = true){ static void DistributeHints(std::vector<uint8_t>& selected, size_t stoneCount, std::vector<HintDistributionSetting> distTable, uint8_t junkWieght, bool addFixed = true){
int32_t totalWeight = junkWieght; //Start with our Junk Weight, the natural chance of a junk hint int32_t totalWeight = junkWieght; //Start with our Junk Weight, the natural chance of a junk hint
for (size_t c=0; c < distTable.size(); c++){ //Gather the wieghts of each distribution and, if it's the first pass, apply fixed hints for (size_t c=0; c < distTable.size(); c++){ //Gather the weights of each distribution and, if it's the first pass, apply fixed hints
totalWeight += distTable[c].weight; //Note that PlaceHints will set weights of distributions to zero if it can't place anything from them totalWeight += distTable[c].weight; //Note that PlaceHints will set weights of distributions to zero if it can't place anything from them
if (addFixed){ if (addFixed){
selected[c] += distTable[c].fixed; selected[c] += distTable[c].fixed;

View File

@ -358,7 +358,7 @@ const std::array<RandomizerGet, 28> shopsanityRupees = {
RG_HUGE_RUPEE, RG_HUGE_RUPEE,
RG_HUGE_RUPEE, RG_HUGE_RUPEE,
RG_HUGE_RUPEE, RG_HUGE_RUPEE,
RG_PROGRESSIVE_WALLET, RG_HUGE_RUPEE,
}; };
const std::array<RandomizerGet, 19> dekuScrubItems = { const std::array<RandomizerGet, 19> dekuScrubItems = {
RG_DEKU_NUTS_5, RG_DEKU_NUTS_5,
@ -471,61 +471,67 @@ void PlaceJunkInExcludedLocation(const RandomizerCheck il) {
SPDLOG_ERROR("ERROR: No Junk to Place!!!"); SPDLOG_ERROR("ERROR: No Junk to Place!!!");
} }
static void PlaceVanillaDekuScrubItems() { static void PlaceVanillaDekuScrubItems(bool junkOneTimeScrubs) {
auto ctx = Rando::Context::GetInstance(); auto ctx = Rando::Context::GetInstance();
if (junkOneTimeScrubs){
ctx->PlaceItemInLocation(RC_LW_DEKU_SCRUB_GROTTO_FRONT, RG_BLUE_RUPEE, false, true);
ctx->PlaceItemInLocation(RC_LW_DEKU_SCRUB_NEAR_BRIDGE, RG_BLUE_RUPEE, false, true);
ctx->PlaceItemInLocation(RC_HF_DEKU_SCRUB_GROTTO, RG_BLUE_RUPEE, false, true);
}
ctx->PlaceItemInLocation(RC_ZR_DEKU_SCRUB_GROTTO_REAR, RG_RED_POTION_REFILL, false, true); ctx->PlaceItemInLocation(RC_ZR_DEKU_SCRUB_GROTTO_REAR, RG_RED_POTION_REFILL, false, true);
ctx->PlaceItemInLocation(RC_ZR_DEKU_SCRUB_GROTTO_FRONT, RG_GREEN_POTION_REFILL, false, true); ctx->PlaceItemInLocation(RC_ZR_DEKU_SCRUB_GROTTO_FRONT, RG_GREEN_POTION_REFILL, false, true);
ctx->PlaceItemInLocation(RC_SFM_DEKU_SCRUB_GROTTO_REAR, RG_RED_POTION_REFILL, false, true); ctx->PlaceItemInLocation(RC_SFM_DEKU_SCRUB_GROTTO_REAR, RG_RED_POTION_REFILL, false, true);
ctx->PlaceItemInLocation(RC_SFM_DEKU_SCRUB_GROTTO_FRONT, RG_GREEN_POTION_REFILL, false, true); ctx->PlaceItemInLocation(RC_SFM_DEKU_SCRUB_GROTTO_FRONT, RG_GREEN_POTION_REFILL, false, true);
ctx->PlaceItemInLocation(RC_LH_DEKU_SCRUB_GROTTO_LEFT, RG_DEKU_NUTS_5, false, true); ctx->PlaceItemInLocation(RC_LH_DEKU_SCRUB_GROTTO_LEFT, RG_BUY_DEKU_NUTS_5, false, true);
ctx->PlaceItemInLocation(RC_LH_DEKU_SCRUB_GROTTO_RIGHT, RG_BOMBS_5, false, true); ctx->PlaceItemInLocation(RC_LH_DEKU_SCRUB_GROTTO_RIGHT, RG_BUY_BOMBS_535, false, true);
ctx->PlaceItemInLocation(RC_LH_DEKU_SCRUB_GROTTO_CENTER, RG_DEKU_SEEDS_30, false, true); ctx->PlaceItemInLocation(RC_LH_DEKU_SCRUB_GROTTO_CENTER, RG_BUY_DEKU_SEEDS_30, false, true);
ctx->PlaceItemInLocation(RC_GV_DEKU_SCRUB_GROTTO_REAR, RG_RED_POTION_REFILL, false, true); ctx->PlaceItemInLocation(RC_GV_DEKU_SCRUB_GROTTO_REAR, RG_RED_POTION_REFILL, false, true);
ctx->PlaceItemInLocation(RC_GV_DEKU_SCRUB_GROTTO_FRONT, RG_GREEN_POTION_REFILL, false, true); ctx->PlaceItemInLocation(RC_GV_DEKU_SCRUB_GROTTO_FRONT, RG_GREEN_POTION_REFILL, false, true);
ctx->PlaceItemInLocation(RC_LW_DEKU_SCRUB_NEAR_DEKU_THEATER_RIGHT, RG_DEKU_NUTS_5, false, true); ctx->PlaceItemInLocation(RC_LW_DEKU_SCRUB_NEAR_DEKU_THEATER_RIGHT, RG_BUY_DEKU_NUTS_5, false, true);
ctx->PlaceItemInLocation(RC_LW_DEKU_SCRUB_NEAR_DEKU_THEATER_LEFT, RG_DEKU_STICK_1, false, true); ctx->PlaceItemInLocation(RC_LW_DEKU_SCRUB_NEAR_DEKU_THEATER_LEFT, RG_BUY_DEKU_STICK_1, false, true);
ctx->PlaceItemInLocation(RC_LW_DEKU_SCRUB_GROTTO_REAR, RG_DEKU_SEEDS_30, false, true); ctx->PlaceItemInLocation(RC_LW_DEKU_SCRUB_GROTTO_REAR, RG_BUY_DEKU_SEEDS_30, false, true);
ctx->PlaceItemInLocation(RC_COLOSSUS_DEKU_SCRUB_GROTTO_REAR, RG_RED_POTION_REFILL, false, true); ctx->PlaceItemInLocation(RC_COLOSSUS_DEKU_SCRUB_GROTTO_REAR, RG_RED_POTION_REFILL, false, true);
ctx->PlaceItemInLocation(RC_COLOSSUS_DEKU_SCRUB_GROTTO_FRONT, RG_GREEN_POTION_REFILL, false, true); ctx->PlaceItemInLocation(RC_COLOSSUS_DEKU_SCRUB_GROTTO_FRONT, RG_GREEN_POTION_REFILL, false, true);
ctx->PlaceItemInLocation(RC_DMC_DEKU_SCRUB, RG_BOMBS_5, false, true); ctx->PlaceItemInLocation(RC_DMC_DEKU_SCRUB, RG_BUY_BOMBS_535, false, true);
ctx->PlaceItemInLocation(RC_DMC_DEKU_SCRUB_GROTTO_LEFT, RG_DEKU_NUTS_5, false, true); ctx->PlaceItemInLocation(RC_DMC_DEKU_SCRUB_GROTTO_LEFT, RG_BUY_DEKU_NUTS_5, false, true);
ctx->PlaceItemInLocation(RC_DMC_DEKU_SCRUB_GROTTO_RIGHT, RG_BOMBS_5, false, true); ctx->PlaceItemInLocation(RC_DMC_DEKU_SCRUB_GROTTO_RIGHT, RG_BUY_BOMBS_535, false, true);
ctx->PlaceItemInLocation(RC_DMC_DEKU_SCRUB_GROTTO_CENTER, RG_DEKU_SEEDS_30, false, true); ctx->PlaceItemInLocation(RC_DMC_DEKU_SCRUB_GROTTO_CENTER, RG_BUY_DEKU_SEEDS_30, false, true);
ctx->PlaceItemInLocation(RC_GC_DEKU_SCRUB_GROTTO_LEFT, RG_DEKU_NUTS_5, false, true); ctx->PlaceItemInLocation(RC_GC_DEKU_SCRUB_GROTTO_LEFT, RG_BUY_DEKU_NUTS_5, false, true);
ctx->PlaceItemInLocation(RC_GC_DEKU_SCRUB_GROTTO_RIGHT, RG_BOMBS_5, false, true); ctx->PlaceItemInLocation(RC_GC_DEKU_SCRUB_GROTTO_RIGHT, RG_BUY_BOMBS_535, false, true);
ctx->PlaceItemInLocation(RC_GC_DEKU_SCRUB_GROTTO_CENTER, RG_DEKU_SEEDS_30, false, true); ctx->PlaceItemInLocation(RC_GC_DEKU_SCRUB_GROTTO_CENTER, RG_BUY_DEKU_SEEDS_30, false, true);
ctx->PlaceItemInLocation(RC_LLR_DEKU_SCRUB_GROTTO_LEFT, RG_DEKU_NUTS_5, false, true); ctx->PlaceItemInLocation(RC_LLR_DEKU_SCRUB_GROTTO_LEFT, RG_BUY_DEKU_NUTS_5, false, true);
ctx->PlaceItemInLocation(RC_LLR_DEKU_SCRUB_GROTTO_RIGHT, RG_BOMBS_5, false, true); ctx->PlaceItemInLocation(RC_LLR_DEKU_SCRUB_GROTTO_RIGHT, RG_BUY_BOMBS_535, false, true);
ctx->PlaceItemInLocation(RC_LLR_DEKU_SCRUB_GROTTO_CENTER, RG_DEKU_SEEDS_30, false, true); ctx->PlaceItemInLocation(RC_LLR_DEKU_SCRUB_GROTTO_CENTER, RG_BUY_DEKU_SEEDS_30, false, true);
//Dungeon Scrubs //Dungeon Scrubs
if (ctx->GetDungeon(Rando::DEKU_TREE)->IsMQ()) { if (ctx->GetDungeon(Rando::DEKU_TREE)->IsMQ()) {
ctx->PlaceItemInLocation(RC_DEKU_TREE_MQ_DEKU_SCRUB, RG_DEKU_SHIELD, false, true); ctx->PlaceItemInLocation(RC_DEKU_TREE_MQ_DEKU_SCRUB, RG_BUY_DEKU_SHIELD, false, true);
} }
if (ctx->GetDungeon(Rando::DODONGOS_CAVERN)->IsMQ()) { if (ctx->GetDungeon(Rando::DODONGOS_CAVERN)->IsMQ()) {
ctx->PlaceItemInLocation(RC_DODONGOS_CAVERN_MQ_DEKU_SCRUB_LOBBY_REAR, RG_DEKU_STICK_1, false, true); ctx->PlaceItemInLocation(RC_DODONGOS_CAVERN_MQ_DEKU_SCRUB_LOBBY_REAR, RG_BUY_DEKU_STICK_1, false, true);
ctx->PlaceItemInLocation(RC_DODONGOS_CAVERN_MQ_DEKU_SCRUB_LOBBY_FRONT, RG_DEKU_SEEDS_30, false, true); ctx->PlaceItemInLocation(RC_DODONGOS_CAVERN_MQ_DEKU_SCRUB_LOBBY_FRONT, RG_BUY_DEKU_SEEDS_30, false, true);
ctx->PlaceItemInLocation(RC_DODONGOS_CAVERN_MQ_DEKU_SCRUB_STAIRCASE, RG_DEKU_SHIELD, false, true); ctx->PlaceItemInLocation(RC_DODONGOS_CAVERN_MQ_DEKU_SCRUB_STAIRCASE, RG_BUY_DEKU_SHIELD, false, true);
ctx->PlaceItemInLocation(RC_DODONGOS_CAVERN_MQ_DEKU_SCRUB_SIDE_ROOM_NEAR_LOWER_LIZALFOS, RG_RED_POTION_REFILL, ctx->PlaceItemInLocation(RC_DODONGOS_CAVERN_MQ_DEKU_SCRUB_SIDE_ROOM_NEAR_LOWER_LIZALFOS, RG_RED_POTION_REFILL,
false, true); false, true);
} else { } else {
ctx->PlaceItemInLocation(RC_DODONGOS_CAVERN_DEKU_SCRUB_NEAR_BOMB_BAG_LEFT, RG_DEKU_NUTS_5, false, true); ctx->PlaceItemInLocation(RC_DODONGOS_CAVERN_DEKU_SCRUB_NEAR_BOMB_BAG_LEFT, RG_BUY_DEKU_NUTS_5, false, true);
ctx->PlaceItemInLocation(RC_DODONGOS_CAVERN_DEKU_SCRUB_SIDE_ROOM_NEAR_DODONGOS, RG_DEKU_STICK_1, false, true); ctx->PlaceItemInLocation(RC_DODONGOS_CAVERN_DEKU_SCRUB_SIDE_ROOM_NEAR_DODONGOS, RG_BUY_DEKU_STICK_1, false, true);
ctx->PlaceItemInLocation(RC_DODONGOS_CAVERN_DEKU_SCRUB_NEAR_BOMB_BAG_RIGHT, RG_DEKU_SEEDS_30, false, true); ctx->PlaceItemInLocation(RC_DODONGOS_CAVERN_DEKU_SCRUB_NEAR_BOMB_BAG_RIGHT, RG_BUY_DEKU_SEEDS_30, false, true);
ctx->PlaceItemInLocation(RC_DODONGOS_CAVERN_DEKU_SCRUB_LOBBY, RG_DEKU_SHIELD, false, true); ctx->PlaceItemInLocation(RC_DODONGOS_CAVERN_DEKU_SCRUB_LOBBY, RG_BUY_DEKU_SHIELD, false, true);
} }
if (ctx->GetDungeon(Rando::JABU_JABUS_BELLY)->IsVanilla()) { if (ctx->GetDungeon(Rando::JABU_JABUS_BELLY)->IsVanilla()) {
ctx->PlaceItemInLocation(RC_JABU_JABUS_BELLY_DEKU_SCRUB, RG_DEKU_NUTS_5, false, true); ctx->PlaceItemInLocation(RC_JABU_JABUS_BELLY_DEKU_SCRUB, RG_BUY_DEKU_NUTS_5, false, true);
} }
if (ctx->GetDungeon(Rando::GANONS_CASTLE)->IsMQ()) { if (ctx->GetDungeon(Rando::GANONS_CASTLE)->IsMQ()) {
ctx->PlaceItemInLocation(RC_GANONS_CASTLE_MQ_DEKU_SCRUB_LEFT, RG_GREEN_POTION_REFILL, false, true); ctx->PlaceItemInLocation(RC_GANONS_CASTLE_MQ_DEKU_SCRUB_LEFT, RG_GREEN_POTION_REFILL, false, true);
ctx->PlaceItemInLocation(RC_GANONS_CASTLE_MQ_DEKU_SCRUB_CENTER_LEFT, RG_BOMBS_5, false, true); ctx->PlaceItemInLocation(RC_GANONS_CASTLE_MQ_DEKU_SCRUB_CENTER_LEFT, RG_BUY_BOMBS_535, false, true);
ctx->PlaceItemInLocation(RC_GANONS_CASTLE_MQ_DEKU_SCRUB_CENTER, RG_ARROWS_30, false, true); ctx->PlaceItemInLocation(RC_GANONS_CASTLE_MQ_DEKU_SCRUB_CENTER, RG_BUY_ARROWS_30, false, true);
ctx->PlaceItemInLocation(RC_GANONS_CASTLE_MQ_DEKU_SCRUB_CENTER_RIGHT, RG_RED_POTION_REFILL, false, true); ctx->PlaceItemInLocation(RC_GANONS_CASTLE_MQ_DEKU_SCRUB_CENTER_RIGHT, RG_RED_POTION_REFILL, false, true);
ctx->PlaceItemInLocation(RC_GANONS_CASTLE_MQ_DEKU_SCRUB_RIGHT, RG_DEKU_NUTS_5, false, true); ctx->PlaceItemInLocation(RC_GANONS_CASTLE_MQ_DEKU_SCRUB_RIGHT, RG_BUY_DEKU_NUTS_5, false, true);
} else { } else {
ctx->PlaceItemInLocation(RC_GANONS_CASTLE_DEKU_SCRUB_CENTER_LEFT, RG_BOMBS_5, false, true); ctx->PlaceItemInLocation(RC_GANONS_CASTLE_DEKU_SCRUB_CENTER_LEFT, RG_BUY_BOMBS_535, false, true);
ctx->PlaceItemInLocation(RC_GANONS_CASTLE_DEKU_SCRUB_CENTER_RIGHT, RG_DEKU_SEEDS_30, false, true); ctx->PlaceItemInLocation(RC_GANONS_CASTLE_DEKU_SCRUB_CENTER_RIGHT, RG_BUY_DEKU_SEEDS_30, false, true);
ctx->PlaceItemInLocation(RC_GANONS_CASTLE_DEKU_SCRUB_RIGHT, RG_RED_POTION_REFILL, false, true); ctx->PlaceItemInLocation(RC_GANONS_CASTLE_DEKU_SCRUB_RIGHT, RG_RED_POTION_REFILL, false, true);
ctx->PlaceItemInLocation(RC_GANONS_CASTLE_DEKU_SCRUB_LEFT, RG_GREEN_POTION_REFILL, false, true); ctx->PlaceItemInLocation(RC_GANONS_CASTLE_DEKU_SCRUB_LEFT, RG_GREEN_POTION_REFILL, false, true);
} }
@ -653,6 +659,7 @@ static void SetMinimalItemPool() {
} }
void GenerateItemPool() { void GenerateItemPool() {
//RANDOTODO proper removal of items not in pool or logically relevant instead of dummy checks.
auto ctx = Rando::Context::GetInstance(); auto ctx = Rando::Context::GetInstance();
ItemPool.clear(); ItemPool.clear();
PendingJunkPool.clear(); PendingJunkPool.clear();
@ -860,7 +867,8 @@ void GenerateItemPool() {
AddItemToMainPool(RG_PROGRESSIVE_WALLET); AddItemToMainPool(RG_PROGRESSIVE_WALLET);
} }
if (ctx->GetOption(RSK_SHUFFLE_MAGIC_BEANS)) { if (ctx->GetOption(RSK_SHUFFLE_MERCHANTS).Is(RO_SHUFFLE_MERCHANTS_BEANS_ONLY) ||
ctx->GetOption(RSK_SHUFFLE_MERCHANTS).Is(RO_SHUFFLE_MERCHANTS_ALL)) {
AddItemToMainPool(RG_MAGIC_BEAN_PACK); AddItemToMainPool(RG_MAGIC_BEAN_PACK);
if (ctx->GetOption(RSK_ITEM_POOL).Is(RO_ITEM_POOL_PLENTIFUL)) { if (ctx->GetOption(RSK_ITEM_POOL).Is(RO_ITEM_POOL_PLENTIFUL)) {
AddItemToPool(PendingJunkPool, RG_MAGIC_BEAN_PACK); AddItemToPool(PendingJunkPool, RG_MAGIC_BEAN_PACK);
@ -870,7 +878,8 @@ void GenerateItemPool() {
ctx->PlaceItemInLocation(RC_ZR_MAGIC_BEAN_SALESMAN, RG_MAGIC_BEAN, false, true); ctx->PlaceItemInLocation(RC_ZR_MAGIC_BEAN_SALESMAN, RG_MAGIC_BEAN, false, true);
} }
if (ctx->GetOption(RSK_SHUFFLE_MERCHANTS).IsNot(RO_SHUFFLE_MERCHANTS_OFF)) { 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*/true) {
AddItemToMainPool(RG_GIANTS_KNIFE); AddItemToMainPool(RG_GIANTS_KNIFE);
} }
@ -986,6 +995,10 @@ void GenerateItemPool() {
AddItemToMainPool(RG_PROGRESSIVE_WALLET); AddItemToMainPool(RG_PROGRESSIVE_WALLET);
} }
if (ctx->GetOption(RSK_INCLUDE_TYCOON_WALLET)) {
AddItemToMainPool(RG_PROGRESSIVE_WALLET);
}
if (ctx->GetOption(RSK_SHUFFLE_DEKU_STICK_BAG)) { if (ctx->GetOption(RSK_SHUFFLE_DEKU_STICK_BAG)) {
AddItemToMainPool(RG_PROGRESSIVE_STICK_UPGRADE); AddItemToMainPool(RG_PROGRESSIVE_STICK_UPGRADE);
} }
@ -1162,7 +1175,7 @@ void GenerateItemPool() {
} }
//Scrubsanity //Scrubsanity
if (ctx->GetOption(RSK_SHUFFLE_SCRUBS).IsNot(RO_SCRUBS_OFF)) { if (ctx->GetOption(RSK_SHUFFLE_SCRUBS).Is(RO_SCRUBS_ALL)) {
//Deku Tree //Deku Tree
if (ctx->GetDungeon(Rando::DEKU_TREE)->IsMQ()) { if (ctx->GetDungeon(Rando::DEKU_TREE)->IsMQ()) {
AddItemToMainPool(RG_DEKU_SHIELD); AddItemToMainPool(RG_DEKU_SHIELD);
@ -1202,7 +1215,7 @@ void GenerateItemPool() {
} }
} }
} else { } else {
PlaceVanillaDekuScrubItems(); PlaceVanillaDekuScrubItems(ctx->GetOption(RSK_SHUFFLE_SCRUBS).Is(RO_SCRUBS_OFF));
} }
AddItemsToPool(ItemPool, alwaysItems); AddItemsToPool(ItemPool, alwaysItems);
@ -1269,7 +1282,9 @@ void GenerateItemPool() {
Rando::StaticData::RetrieveItem(RandomElement(bottles)).GetRandomizerGet()); // Get one random bottle type for ice traps Rando::StaticData::RetrieveItem(RandomElement(bottles)).GetRandomizerGet()); // Get one random bottle type for ice traps
for (uint8_t i = 0; i < bottleCount; i++) { for (uint8_t i = 0; i < bottleCount; i++) {
if (i >= rutoBottles) { if (i >= rutoBottles) {
if ((i == bottleCount - 1) && ctx->GetOption(RSK_SHUFFLE_MERCHANTS).IsNot(RO_SHUFFLE_MERCHANTS_OFF)) { if ((i == bottleCount - 1) &&
(ctx->GetOption(RSK_SHUFFLE_MERCHANTS).Is(RO_SHUFFLE_MERCHANTS_BEANS_ONLY) ||
ctx->GetOption(RSK_SHUFFLE_MERCHANTS).Is(RO_SHUFFLE_MERCHANTS_ALL))) {
AddItemToMainPool(RG_BOTTLE_WITH_BLUE_POTION); AddItemToMainPool(RG_BOTTLE_WITH_BLUE_POTION);
} else { } else {
AddRandomBottle(bottles); AddRandomBottle(bottles);

View File

@ -46,33 +46,22 @@ bool LocationAccess::ConditionsMet() const {
} }
bool LocationAccess::CanBuy() const { bool LocationAccess::CanBuy() const {
auto ctx = Rando::Context::GetInstance(); return CanBuyAnother(location);
//Not a shop or scrub location, don't need to check if buyable }
if (Rando::StaticData::GetLocation(location)->GetRCType() != RCTYPE_SHOP && Rando::StaticData::GetLocation(location)->GetRCType() != RCTYPE_SCRUB) {
return true;
}
//Check if wallet is large enough to buy item bool CanBuyAnother(RandomizerCheck rc) {
bool SufficientWallet = true; uint16_t price = ctx->GetItemLocation(rc)->GetPrice();
if (ctx->GetItemLocation(location)->GetPrice() > 500) {
SufficientWallet = logic->HasItem(RG_TYCOON_WALLET);
} else if (ctx->GetItemLocation(location)->GetPrice() > 200) {
SufficientWallet = logic->HasItem(RG_GIANT_WALLET);
} else if (ctx->GetItemLocation(location)->GetPrice() > 99) {
SufficientWallet = logic->HasItem(RG_ADULT_WALLET);
} else if (ctx->GetItemLocation(location)->GetPrice() > 0) {
SufficientWallet = logic->HasItem(RG_CHILD_WALLET);
}
bool OtherCondition = true; if (price > 500) {
RandomizerGet placed = ctx->GetItemLocation(location)->GetPlacedRandomizerGet(); return logic->HasItem(RG_TYCOON_WALLET);
//Need bottle to buy bottle items, only logically relevant bottle items included here } else if (price > 200) {
if (placed == RG_BUY_BLUE_FIRE || placed == RG_BUY_BOTTLE_BUG || placed == RG_BUY_FISH || return logic->HasItem(RG_GIANT_WALLET);
placed == RG_BUY_FAIRYS_SPIRIT) { } else if (price > 99) {
OtherCondition = logic->HasBottle(); return logic->HasItem(RG_ADULT_WALLET);
} else if (price > 0) {
return logic->HasItem(RG_CHILD_WALLET);
} }
return true;
return SufficientWallet && OtherCondition;
} }
Region::Region() = default; Region::Region() = default;

View File

@ -128,6 +128,8 @@ protected:
bool CanBuy() const; bool CanBuy() const;
}; };
bool CanBuyAnother(RandomizerCheck rc);
namespace Rando { namespace Rando {
class Entrance; class Entrance;
enum class EntranceType; enum class EntranceType;

View File

@ -97,7 +97,7 @@ void RegionTable_Init_DeathMountain() {
LOCATION(RC_GC_ROLLING_GORON_AS_ADULT, logic->StopGCRollingGoronAsAdult), LOCATION(RC_GC_ROLLING_GORON_AS_ADULT, logic->StopGCRollingGoronAsAdult),
LOCATION(RC_GC_GS_BOULDER_MAZE, logic->IsChild && logic->BlastOrSmash()), LOCATION(RC_GC_GS_BOULDER_MAZE, logic->IsChild && logic->BlastOrSmash()),
LOCATION(RC_GC_GS_CENTER_PLATFORM, logic->IsAdult && logic->CanAttack()), LOCATION(RC_GC_GS_CENTER_PLATFORM, logic->IsAdult && logic->CanAttack()),
LOCATION(RC_GC_MEDIGORON, logic->IsAdult && logic->HasItem(RG_ADULT_WALLET) && (logic->BlastOrSmash() || logic->HasItem(RG_GORONS_BRACELET))), LOCATION(RC_GC_MEDIGORON, logic->IsAdult && (logic->BlastOrSmash() || logic->HasItem(RG_GORONS_BRACELET))),
LOCATION(RC_GC_MAZE_GOSSIP_STONE, logic->BlastOrSmash() || logic->CanUse(RG_SILVER_GAUNTLETS)), LOCATION(RC_GC_MAZE_GOSSIP_STONE, logic->BlastOrSmash() || logic->CanUse(RG_SILVER_GAUNTLETS)),
LOCATION(RC_GC_MEDIGORON_GOSSIP_STONE, logic->BlastOrSmash() || logic->HasItem(RG_GORONS_BRACELET)), LOCATION(RC_GC_MEDIGORON_GOSSIP_STONE, logic->BlastOrSmash() || logic->HasItem(RG_GORONS_BRACELET)),
}, { }, {

View File

@ -142,11 +142,11 @@ void RegionTable_Init_GerudoValley() {
//Events //Events
EventAccess(&logic->FairyPot, {[]{return true;}}), EventAccess(&logic->FairyPot, {[]{return true;}}),
EventAccess(&logic->NutPot, {[]{return true;}}), EventAccess(&logic->NutPot, {[]{return true;}}),
EventAccess(&logic->CarpetMerchant, {[]{return logic->HasItem(RG_ADULT_WALLET) && (logic->CanJumpslash() || logic->CanUse(RG_HOVER_BOOTS));}}), EventAccess(&logic->CarpetMerchant, {[]{return logic->HasItem(RG_ADULT_WALLET) && CanBuyAnother(RC_WASTELAND_BOMBCHU_SALESMAN) && (logic->CanJumpslash() || logic->CanUse(RG_HOVER_BOOTS));}}),
}, { }, {
//Locations //Locations
LOCATION(RC_WASTELAND_CHEST, logic->HasFireSource()), LOCATION(RC_WASTELAND_CHEST, logic->HasFireSource()),
LOCATION(RC_WASTELAND_BOMBCHU_SALESMAN, logic->CarpetMerchant), LOCATION(RC_WASTELAND_BOMBCHU_SALESMAN, logic->CanJumpslash() || logic->CanUse(RG_HOVER_BOOTS)),
LOCATION(RC_WASTELAND_GS, logic->HookshotOrBoomerang()), LOCATION(RC_WASTELAND_GS, logic->HookshotOrBoomerang()),
}, { }, {
//Exits //Exits

View File

@ -170,13 +170,14 @@ void RegionTable_Init_Kakariko() {
areaTable[RR_KAK_ODD_POTION_BUILDING] = areaTable[RR_KAK_ODD_POTION_BUILDING] =
Region("Kak Granny's Potion Shop", "Kak Granny's Potion Shop", RA_NONE, NO_DAY_NIGHT_CYCLE, {}, Region("Kak Granny's Potion Shop", "Kak Granny's Potion Shop", RA_NONE, NO_DAY_NIGHT_CYCLE, {},
// RANDOTODO blue pot access
{ {
LOCATION(RC_KAK_TRADE_ODD_MUSHROOM, logic->IsAdult && logic->CanUse(RG_ODD_MUSHROOM)), LOCATION(RC_KAK_TRADE_ODD_MUSHROOM, logic->IsAdult && logic->CanUse(RG_ODD_MUSHROOM)),
LOCATION(RC_KAK_GRANNYS_SHOP, logic->IsAdult && (logic->CanUse(RG_ODD_MUSHROOM) || logic->TradeQuestStep(RG_ODD_MUSHROOM)) && logic->HasItem(RG_ADULT_WALLET)), LOCATION(RC_KAK_GRANNYS_SHOP, logic->IsAdult && (logic->CanUse(RG_ODD_MUSHROOM) || logic->TradeQuestStep(RG_ODD_MUSHROOM))),
}, },
{ {
// Exits // Exits
Entrance(RR_KAK_BACKYARD, { [] { return true; } }), Entrance(RR_KAK_BACKYARD, { [] { return true; } }),
}); });
areaTable[RR_KAK_REDEAD_GROTTO] = Region("Kak Redead Grotto", "Kak Redead Grotto", RA_NONE, NO_DAY_NIGHT_CYCLE, {}, { areaTable[RR_KAK_REDEAD_GROTTO] = Region("Kak Redead Grotto", "Kak Redead Grotto", RA_NONE, NO_DAY_NIGHT_CYCLE, {}, {

View File

@ -67,7 +67,6 @@ int Playthrough_Init(uint32_t seed, std::set<RandomizerCheck> excludedLocations,
} }
GenerateHash(); GenerateHash();
WriteIngameSpoilerLog();
if (true) { if (true) {
//TODO: Handle different types of file output (i.e. Spoiler Log, Plando Template, Patch Files, Race Files, etc.) //TODO: Handle different types of file output (i.e. Spoiler Log, Plando Template, Patch Files, Race Files, etc.)

View File

@ -2,13 +2,36 @@
#include "location_access.hpp" #include "location_access.hpp"
#include "random.hpp" #include "random.hpp"
#include "shops.hpp" #include "shops.hpp"
#include "../location.h"
#include <array> #include <array>
#include <math.h> #include <math.h>
#include <map> #include <map>
#include <spdlog/spdlog.h>
#include "z64item.h" #include "z64item.h"
std::map<RandomizerCheck, ItemAndPrice> NonShopItems = {}; PriceSettingsStruct::PriceSettingsStruct(RandomizerSettingKey _main,
RandomizerSettingKey _fixedPrice,
RandomizerSettingKey _range1,
RandomizerSettingKey _range2,
RandomizerSettingKey _noWallet,
RandomizerSettingKey _childWallet,
RandomizerSettingKey _adultWallet,
RandomizerSettingKey _giantWallet,
RandomizerSettingKey _tycoonWallet,
RandomizerSettingKey _affordable){
main = _main;
fixedPrice = _fixedPrice;
range1 = _range1;
range2 = _range2;
noWallet = _noWallet;
childWallet = _childWallet;
adultWallet = _adultWallet;
giantWallet= _giantWallet;
tycoonWallet= _tycoonWallet;
affordable= _affordable;
}
static std::array<std::vector<Text>, 0xF1> trickNameTable; // Table of trick names for ice traps static std::array<std::vector<Text>, 0xF1> trickNameTable; // Table of trick names for ice traps
bool initTrickNames = false; //Indicates if trick ice trap names have been initialized yet bool initTrickNames = false; //Indicates if trick ice trap names have been initialized yet
@ -131,71 +154,97 @@ int GetPriceFromMax(int max) {
return Random(1, max) * 5; // random range of 1 - wallet max / 5, where wallet max is the highest it goes as a multiple of 5 return Random(1, max) * 5; // random range of 1 - wallet max / 5, where wallet max is the highest it goes as a multiple of 5
} }
// Get random price out of available "affordable prices", or just return 10 if Starter wallet is selected (no need to randomly select uint16_t GetPriceFromSettings(Rando::Location *loc, PriceSettingsStruct priceSettings) {
// from a single element) auto ctx = Rando::Context::GetInstance();
int GetPriceAffordable() { switch (ctx->GetOption(priceSettings.main).Value<uint8_t>()){
auto ctx = Rando::Context::GetInstance(); case RO_PRICE_VANILLA:
if (ctx->GetOption(RSK_SHOPSANITY_PRICES).Is(RO_SHOPSANITY_PRICE_STARTER)) { return loc->GetVanillaPrice();
return 10; case RO_PRICE_CHEAP_BALANCED:
} return GetCheapBalancedPrice();
case RO_PRICE_BALANCED:{
static const std::vector<int> affordablePrices = { 10, 105, 205, 505 }; double random = RandomDouble(); //Randomly generated probability value
std::vector<int> priceList; for (size_t i = 0; i < ShopPriceProbability.size(); i++) {
uint8_t maxElements = ctx->GetOption(RSK_SHOPSANITY_PRICES).Value<uint8_t>(); if (random < ShopPriceProbability[i]) {
for (int i = 0; i < maxElements; i++) { //The randomly generated value has surpassed the total probability up to this point, so this is the generated price
priceList.push_back(affordablePrices.at(i)); return i * 5; //i in range [0, 59], output in range [0, 295] in increments of 5
} }
return RandomElement(priceList); }
return 150;
}
case RO_PRICE_FIXED:
return (uint16_t)ctx->GetOption(priceSettings.fixedPrice).Value<uint8_t>() * 5;
case RO_PRICE_RANGE:{
uint16_t range1 = (uint16_t)ctx->GetOption(priceSettings.range1).Value<uint8_t>() * 5;
uint16_t range2 = (uint16_t)ctx->GetOption(priceSettings.range2).Value<uint8_t>() * 5;
return range1 < range2 ? Random(range1, range2+1) : Random(range2, range1+1);
}
case RO_PRICE_SET_BY_WALLET:{
bool isTycoon = ctx->GetOption(RSK_INCLUDE_TYCOON_WALLET).Value<bool>();
uint16_t noWeight = ctx->GetOption(priceSettings.noWallet).Value<uint8_t>();
uint16_t childWeight = ctx->GetOption(priceSettings.childWallet).Value<uint8_t>();
uint16_t adultWeight = ctx->GetOption(priceSettings.adultWallet).Value<uint8_t>();
uint16_t giantWeight = ctx->GetOption(priceSettings.giantWallet).Value<uint8_t>();
uint16_t tycoonWeight = isTycoon ? ctx->GetOption(priceSettings.tycoonWallet).Value<uint8_t>() : 0;
uint16_t totalWeight = noWeight + childWeight + adultWeight + giantWeight + tycoonWeight;
if (totalWeight == 0){ //if no weight, return from sane range
return Random(0, 501);
}
int16_t selected = Random(1, totalWeight + 1);
selected = selected - noWeight;
if (selected <= 0){
return 0;
}
selected = selected - childWeight;
if (selected <= 0){
return Random(1, 100);
}
selected = selected - adultWeight;
if (selected <= 0){
return Random(100, 201);
}
selected = selected - giantWeight;
if (selected <= 0){
return Random(201, 501);
}
return Random(501, 999);
}
}
SPDLOG_ERROR("GetPriceFromSettings has failed to return a price for location {}, assigning a default value.", loc->GetName());
assert(false);
return 69; //this should never happen, if it does, EASTER EGG that tells us something is wrong
} }
int GetRandomShopPrice() { uint16_t GetRandomPrice(Rando::Location *loc, PriceSettingsStruct priceSettings) {
auto ctx = Rando::Context::GetInstance(); uint16_t initialPrice = GetPriceFromSettings(loc, priceSettings);
// If Shopsanity prices aren't Balanced, but Affordable is on, don't GetPriceFromMax auto ctx = Rando::Context::GetInstance();
if (ctx->GetOption(RSK_SHOPSANITY_PRICES_AFFORDABLE).Is(true) && ctx->GetOption(RSK_SHOPSANITY_PRICES).IsNot(RO_SHOPSANITY_PRICE_BALANCED)) { if (ctx->GetOption(priceSettings.affordable) && !ctx->GetOption(priceSettings.main).Is(RO_PRICE_FIXED)){
return GetPriceAffordable(); if (initialPrice > 500) {
} return 505;
} else if (initialPrice > 200) {
// max 0 means Balanced is selected, and thus shouldn't trigger GetPriceFromMax return 205;
int max = 0; } else if (initialPrice > 99) {
return 100;
// check settings for a wallet tier selection and set max amount as method for setting true randomization } else if (initialPrice > 0) {
if (ctx->GetOption(RSK_SHOPSANITY_PRICES).Is(RO_SHOPSANITY_PRICE_STARTER)) { return 5;
max = 19; // 95/5 }
} else if (ctx->GetOption(RSK_SHOPSANITY_PRICES).Is(RO_SHOPSANITY_PRICE_ADULT)) { return 0;
max = 40; // 200/5 } else {
} else if (ctx->GetOption(RSK_SHOPSANITY_PRICES).Is(RO_SHOPSANITY_PRICE_GIANT)) { return initialPrice;
max = 100; // 500/5 }
} else if (ctx->GetOption(RSK_SHOPSANITY_PRICES).Is(RO_SHOPSANITY_PRICE_TYCOON)) {
max = 199; // 995/5
}
if (max != 0) {
return GetPriceFromMax(max);
}
// Balanced is default, so if all other known cases fail, fall back to Balanced
int price = 150; // JUST in case something fails with the randomization, return sane price for balanced
double random = RandomDouble(); //Randomly generated probability value
for (size_t i = 0; i < ShopPriceProbability.size(); i++) {
//The randomly generated value has surpassed the total probability up to this point, so this is the generated price
if (random < ShopPriceProbability[i]) {
price = i * 5; //i in range [0, 59], output in range [0, 295] in increments of 5
break;
}
}
return price;
} }
//Similar to above, beta distribution with alpha = 1, beta = 2, //Similar to above, beta distribution with alpha = 1, beta = 2,
// multiplied by 20 instead of 60 to give values in rage [0, 95] in increments of 5 // multiplied by 20 instead of 60 to give values in rage [0, 95] in increments of 5
//Average price ~31 //Average price ~31
static constexpr std::array<double, 20> ScrubPriceProbability = { static constexpr std::array<double, 20> CheapPriceProbability = {
0.097500187, 0.190002748, 0.277509301, 0.360018376, 0.437522571, 0.510021715, 0.577520272, 0.640029304, 0.697527584, 0.750024535, 0.097500187, 0.190002748, 0.277509301, 0.360018376, 0.437522571, 0.510021715, 0.577520272, 0.640029304, 0.697527584, 0.750024535,
0.797518749, 0.840011707, 0.877508776, 0.910010904, 0.937504342, 0.960004661, 0.977502132, 0.989998967, 0.997500116, 1.000000000, 0.797518749, 0.840011707, 0.877508776, 0.910010904, 0.937504342, 0.960004661, 0.977502132, 0.989998967, 0.997500116, 1.000000000,
}; };
int16_t GetRandomScrubPrice() { uint16_t GetCheapBalancedPrice() {
double random = RandomDouble(); double random = RandomDouble();
for (size_t i = 0; i < ScrubPriceProbability.size(); i++) { for (size_t i = 0; i < CheapPriceProbability.size(); i++) {
if (random < ScrubPriceProbability[i]) { if (random < CheapPriceProbability[i]) {
return i * 5; // i in range [0, 19], output in range [0, 95] in increments of 5 return i * 5; // i in range [0, 19], output in range [0, 95] in increments of 5
} }
} }

View File

@ -2,18 +2,37 @@
#include "../context.h" #include "../context.h"
#include <vector> #include <vector>
#include <array>
struct ItemAndPrice { struct PriceSettingsStruct {
Text Name; RandomizerSettingKey main;
int Price; RandomizerSettingKey fixedPrice;
bool Repurchaseable; RandomizerSettingKey range1;
RandomizerSettingKey range2;
RandomizerSettingKey noWallet;
RandomizerSettingKey childWallet;
RandomizerSettingKey adultWallet;
RandomizerSettingKey giantWallet;
RandomizerSettingKey tycoonWallet;
RandomizerSettingKey affordable;
PriceSettingsStruct(RandomizerSettingKey _main,
RandomizerSettingKey _fixedPrice,
RandomizerSettingKey _range1,
RandomizerSettingKey _range2,
RandomizerSettingKey _noWallet,
RandomizerSettingKey _childWallet,
RandomizerSettingKey _adultWallet,
RandomizerSettingKey _giantWallet,
RandomizerSettingKey _tycoonWallet,
RandomizerSettingKey _affordable);
}; };
extern void PlaceVanillaShopItems(); extern void PlaceVanillaShopItems();
extern std::vector<RandomizerGet> GetMinVanillaShopItems(int total_replaced); extern std::vector<RandomizerGet> GetMinVanillaShopItems(int total_replaced);
extern int GetRandomShopPrice(); extern uint16_t GetRandomPrice(Rando::Location* loc, PriceSettingsStruct priceSettings);
extern int16_t GetRandomScrubPrice(); extern uint16_t GetCheapBalancedPrice();
extern int GetShopsanityReplaceAmount(); extern int GetShopsanityReplaceAmount();
extern Text GetIceTrapName(uint8_t id); extern Text GetIceTrapName(uint8_t id);
extern std::map<RandomizerCheck, ItemAndPrice> NonShopItems;

View File

@ -8,7 +8,6 @@
#include "../trial.h" #include "../trial.h"
#include "tinyxml2.h" #include "tinyxml2.h"
#include "utils.hpp" #include "utils.hpp"
#include "shops.hpp"
#include "hints.hpp" #include "hints.hpp"
#include "pool_functions.hpp" #include "pool_functions.hpp"
#include "soh/Enhancements/randomizer/randomizer_check_objects.h" #include "soh/Enhancements/randomizer/randomizer_check_objects.h"
@ -46,8 +45,6 @@ namespace {
std::string placementtxt; std::string placementtxt;
} // namespace } // namespace
static SpoilerData spoilerData;
void GenerateHash() { void GenerateHash() {
auto ctx = Rando::Context::GetInstance(); auto ctx = Rando::Context::GetInstance();
std::string hash = ctx->GetSettings()->GetHash(); std::string hash = ctx->GetSettings()->GetHash();
@ -64,10 +61,6 @@ void GenerateHash() {
// spoilerData = { 0 }; // spoilerData = { 0 };
} }
const SpoilerData& GetSpoilerData() {
return spoilerData;
}
static auto GetGeneralPath() { static auto GetGeneralPath() {
return "./randomizer/haha.xml"; return "./randomizer/haha.xml";
} }
@ -80,195 +73,6 @@ static auto GetPlacementLogPath() {
return GetGeneralPath(); return GetGeneralPath();
} }
void WriteIngameSpoilerLog() {
auto ctx = Rando::Context::GetInstance();
uint16_t spoilerItemIndex = 0;
uint32_t spoilerStringOffset = 0;
uint16_t spoilerSphereItemoffset = 0;
uint16_t spoilerAreaOffset = 0;
// Intentionally junk value so we trigger the 'new area, record some stuff' code
RandomizerCheckArea currentArea = RandomizerCheckArea::RCAREA_INVALID;
bool spoilerOutOfSpace = false;
// Create map of string data offsets for all _unique_ item locations and names in the playthrough
// Some item names, like gold skulltula tokens, can appear many times in a playthrough
std::unordered_map<uint32_t, uint16_t>
itemLocationsMap; // Map of LocationKey to an index into spoiler data item locations
itemLocationsMap.reserve(ctx->allLocations.size());
std::unordered_map<std::string, uint16_t>
stringOffsetMap; // Map of strings to their offset into spoiler string data array
stringOffsetMap.reserve(ctx->allLocations.size() * 2);
// Sort all locations by their area, so the in-game log can show a area of items by simply starting/ending at
// certain indices
std::stable_sort(ctx->allLocations.begin(), ctx->allLocations.end(), [](const RandomizerCheck& a, const RandomizerCheck& b) {
RandomizerCheckArea areaA = Rando::StaticData::GetLocation(a)->GetArea();
RandomizerCheckArea areaB = Rando::StaticData::GetLocation(b)->GetArea();
return areaA < areaB;
});
for (const RandomizerCheck key : ctx->allLocations) {
auto loc = Rando::StaticData::GetLocation(key);
auto itemLocation = ctx->GetItemLocation(key);
// Hide excluded locations from ingame tracker
// if (loc->IsExcluded()) {
// continue;
// }
// Beehives
if (!ctx->GetOption(RSK_SHUFFLE_BEEHIVES) && loc->GetRCType() == RCTYPE_BEEHIVE) {
continue;
}
// Cows
else if (!ctx->GetOption(RSK_SHUFFLE_COWS) && loc->GetRCType() == RCTYPE_COW) {
continue;
}
// Merchants
else if (ctx->GetOption(RSK_SHUFFLE_MERCHANTS).Is(RO_SHUFFLE_MERCHANTS_OFF) && loc->GetRCType() == RCTYPE_MERCHANT) {
continue;
}
// Adult Trade
else if (!ctx->GetOption(RSK_SHUFFLE_ADULT_TRADE) && loc->GetRCType() == RCTYPE_ADULT_TRADE) {
continue;
}
// Chest Minigame
else if (ctx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME).Is(RO_GENERIC_OFF) && loc->GetRCType() == RCTYPE_CHEST_GAME) {
continue;
}
// Gerudo Fortress
else if ((ctx->GetOption(RSK_GERUDO_FORTRESS).Is(RO_GF_NORMAL) &&
(loc->GetRCType() == RCTYPE_GF_KEY || loc->GetHintKey() == RHT_GF_GERUDO_MEMBERSHIP_CARD)) ||
(ctx->GetOption(RSK_GERUDO_FORTRESS).Is(RO_GF_FAST) && loc->GetRCType() == RCTYPE_GF_KEY &&
loc->GetHintKey() != RHT_GF_NORTH_F1_CARPENTER)) {
continue;
}
// Copy at most 51 chars from the name and location name to avoid issues with names that don't fit on screen
const char* nameFormatStr = "%.51s";
auto locName = loc->GetName();
if (stringOffsetMap.find(locName) == stringOffsetMap.end()) {
if (spoilerStringOffset + locName.size() + 1 >= SPOILER_STRING_DATA_SIZE) {
spoilerOutOfSpace = true;
break;
} else {
stringOffsetMap[locName] = spoilerStringOffset;
spoilerStringOffset +=
sprintf(&spoilerData.StringData[spoilerStringOffset], nameFormatStr, locName.c_str()) + 1;
}
}
// PURPLE TODO: LOCALIZATION
auto locItem = itemLocation->GetPlacedItemName().GetEnglish();
if (itemLocation->GetPlacedRandomizerGet() == RG_ICE_TRAP && loc->GetRCType() == RCTYPE_SHOP) {
locItem = NonShopItems[key].Name.GetEnglish();
}
if (stringOffsetMap.find(locItem) == stringOffsetMap.end()) {
if (spoilerStringOffset + locItem.size() + 1 >= SPOILER_STRING_DATA_SIZE) {
spoilerOutOfSpace = true;
break;
} else {
stringOffsetMap[locItem] = spoilerStringOffset;
spoilerStringOffset +=
sprintf(&spoilerData.StringData[spoilerStringOffset], nameFormatStr, locItem.c_str()) + 1;
}
}
spoilerData.ItemLocations[spoilerItemIndex].LocationStrOffset = stringOffsetMap[locName];
spoilerData.ItemLocations[spoilerItemIndex].ItemStrOffset = stringOffsetMap[locItem];
spoilerData.ItemLocations[spoilerItemIndex].LocationStr = locName;
spoilerData.ItemLocations[spoilerItemIndex].ItemStr = locItem;
spoilerData.ItemLocations[spoilerItemIndex].CollectionCheckType = loc->GetCollectionCheck().type;
spoilerData.ItemLocations[spoilerItemIndex].LocationScene = loc->GetCollectionCheck().scene;
spoilerData.ItemLocations[spoilerItemIndex].LocationFlag = loc->GetCollectionCheck().flag;
// Collect Type and Reveal Type
if (key == RC_GANON) {
spoilerData.ItemLocations[spoilerItemIndex].CollectType = COLLECTTYPE_NEVER;
spoilerData.ItemLocations[spoilerItemIndex].RevealType = REVEALTYPE_ALWAYS;
}
// Shops
else if (loc->IsShop()) {
if (ctx->GetOption(RSK_SHOPSANITY).Is(RO_SHOPSANITY_OFF)) {
spoilerData.ItemLocations[spoilerItemIndex].RevealType = REVEALTYPE_ALWAYS;
} else {
spoilerData.ItemLocations[spoilerItemIndex].RevealType = REVEALTYPE_SCENE;
}
if (itemLocation->GetPlacedItem().GetItemType() == ITEMTYPE_REFILL ||
itemLocation->GetPlacedItem().GetItemType() == ITEMTYPE_SHOP ||
itemLocation->GetPlacedItem().GetHintKey() == RHT_PROGRESSIVE_BOMBCHUS) {
spoilerData.ItemLocations[spoilerItemIndex].CollectType = COLLECTTYPE_REPEATABLE;
}
}
// Gold Skulltulas
else if (loc->GetRCType() == RCTYPE_SKULL_TOKEN &&
((ctx->GetOption(RSK_SHUFFLE_TOKENS).Is(RO_TOKENSANITY_OFF)) ||
(ctx->GetOption(RSK_SHUFFLE_TOKENS).Is(RO_TOKENSANITY_DUNGEONS) && !loc->IsDungeon()) ||
(ctx->GetOption(RSK_SHUFFLE_TOKENS).Is(RO_TOKENSANITY_OVERWORLD) && loc->IsDungeon()))) {
spoilerData.ItemLocations[spoilerItemIndex].RevealType = REVEALTYPE_ALWAYS;
}
// Deku Scrubs
else if (
loc->GetRCType() == RCTYPE_SCRUB &&
// these 3 scrubs are always randomized
!(
loc->GetRandomizerCheck() == RC_LW_DEKU_SCRUB_NEAR_BRIDGE ||
loc->GetRandomizerCheck() == RC_LW_DEKU_SCRUB_GROTTO_FRONT ||
loc->GetRandomizerCheck() == RC_HF_DEKU_SCRUB_GROTTO
) &&
ctx->GetOption(RSK_SHUFFLE_SCRUBS).Is(RO_SCRUBS_OFF)
) {
spoilerData.ItemLocations[spoilerItemIndex].CollectType = COLLECTTYPE_REPEATABLE;
spoilerData.ItemLocations[spoilerItemIndex].RevealType = REVEALTYPE_ALWAYS;
}
RandomizerCheckArea checkArea = loc->GetArea();
spoilerData.ItemLocations[spoilerItemIndex].Area = checkArea;
// Area setup
if (checkArea != currentArea) {
currentArea = checkArea;
spoilerData.AreaOffsets[currentArea] = spoilerAreaOffset;
}
++spoilerData.AreaItemCounts[currentArea];
++spoilerAreaOffset;
itemLocationsMap[key] = spoilerItemIndex++;
}
spoilerData.ItemLocationsCount = spoilerItemIndex;
if (/*Settings::IngameSpoilers TODO: Remove: don't think we have any need for this*/ false) {
bool playthroughItemNotFound = false;
// Write playthrough data to in-game spoiler log
if (!spoilerOutOfSpace) {
for (uint32_t i = 0; i < ctx->playthroughLocations.size(); i++) {
if (i >= SPOILER_SPHERES_MAX) {
spoilerOutOfSpace = true;
break;
}
spoilerData.Spheres[i].ItemLocationsOffset = spoilerSphereItemoffset;
for (uint32_t loc = 0; loc < ctx->playthroughLocations[i].size(); ++loc) {
if (spoilerSphereItemoffset >= SPOILER_ITEMS_MAX) {
spoilerOutOfSpace = true;
break;
}
const auto foundItemLoc = itemLocationsMap.find(ctx->playthroughLocations[i][loc]);
if (foundItemLoc != itemLocationsMap.end()) {
spoilerData.SphereItemLocations[spoilerSphereItemoffset++] = foundItemLoc->second;
} else {
playthroughItemNotFound = true;
}
++spoilerData.Spheres[i].ItemCount;
}
++spoilerData.SphereCount;
}
}
if (spoilerOutOfSpace || playthroughItemNotFound) {
SPDLOG_ERROR("In-game spoiler log is out of space, playthrough data will not be written");
}
}
}
// Writes the location to the specified node. // Writes the location to the specified node.
static void WriteLocation( static void WriteLocation(
std::string sphere, const RandomizerCheck locationKey, const bool withPadding = false) { std::string sphere, const RandomizerCheck locationKey, const bool withPadding = false) {
@ -683,6 +487,7 @@ void PlacementLog_Clear() {
placementtxt = ""; placementtxt = "";
} }
// RANDOTODO: Do we even use this?
bool PlacementLog_Write() { bool PlacementLog_Write() {
auto placementLog = tinyxml2::XMLDocument(false); auto placementLog = tinyxml2::XMLDocument(false);
placementLog.InsertEndChild(placementLog.NewDeclaration()); placementLog.InsertEndChild(placementLog.NewDeclaration());
@ -692,7 +497,6 @@ bool PlacementLog_Write() {
// rootNode->SetAttribute("version", Settings::version.c_str()); // rootNode->SetAttribute("version", Settings::version.c_str());
// rootNode->SetAttribute("seed", Settings::seed); // rootNode->SetAttribute("seed", Settings::seed);
// TODO: Do we even use this?
// WriteSettings(placementLog, true); // Include hidden settings. // WriteSettings(placementLog, true); // Include hidden settings.
// WriteExcludedLocations(placementLog); // WriteExcludedLocations(placementLog);

View File

@ -8,7 +8,7 @@
using RandomizerHash = std::array<std::string, 5>; using RandomizerHash = std::array<std::string, 5>;
// RANDOTODO this is primarily used by the check tracker now, and should probably be moved
typedef enum { typedef enum {
SPOILER_CHK_NONE, SPOILER_CHK_NONE,
SPOILER_CHK_CHEST, SPOILER_CHK_CHEST,
@ -21,55 +21,6 @@ typedef enum {
SPOILER_CHK_RANDOMIZER_INF, SPOILER_CHK_RANDOMIZER_INF,
} SpoilerCollectionCheckType; } SpoilerCollectionCheckType;
typedef enum {
COLLECTTYPE_NORMAL,
COLLECTTYPE_REPEATABLE,
COLLECTTYPE_NEVER,
} SpoilerItemCollectType;
typedef enum {
REVEALTYPE_NORMAL,
REVEALTYPE_SCENE,
REVEALTYPE_ALWAYS,
} SpoilerItemRevealType;
#define SPOILER_SPHERES_MAX 50
#define SPOILER_ITEMS_MAX RC_MAX
#define SPOILER_STRING_DATA_SIZE 16384
typedef struct {
std::string LocationStr;
std::string ItemStr;
uint16_t LocationStrOffset;
uint16_t ItemStrOffset;
SpoilerCollectionCheckType CollectionCheckType;
uint8_t LocationScene;
uint8_t LocationFlag;
RandomizerCheckArea Area;
SpoilerItemCollectType CollectType;
SpoilerItemRevealType RevealType;
} SpoilerItemLocation;
typedef struct {
uint8_t ItemCount;
uint16_t ItemLocationsOffset;
} SpoilerSphere;
typedef struct {
uint8_t SphereCount;
uint16_t ItemLocationsCount;
SpoilerSphere Spheres[SPOILER_SPHERES_MAX];
SpoilerItemLocation ItemLocations[SPOILER_ITEMS_MAX];
uint16_t SphereItemLocations[SPOILER_ITEMS_MAX];
char StringData[SPOILER_STRING_DATA_SIZE];
uint16_t AreaItemCounts[RCAREA_INVALID];
uint16_t AreaOffsets[RCAREA_INVALID];
} SpoilerData;
void GenerateHash(); void GenerateHash();
const RandomizerHash& GetRandomizerHash();
void WriteIngameSpoilerLog();
const char* SpoilerLog_Write(); const char* SpoilerLog_Write();
const SpoilerData& GetSpoilerData();

View File

@ -104,15 +104,6 @@ void Context::PlaceItemInLocation(const RandomizerCheck locKey, const Randomizer
// TODO? Show Progress // TODO? Show Progress
// If we're placing a non-shop item in a shop location, we want to record it for custom messages
if (StaticData::RetrieveItem(item).GetItemType() != ITEMTYPE_SHOP &&
StaticData::GetLocation(locKey)->GetRCType() == RCTYPE_SHOP) {
NonShopItems[locKey].Name = StaticData::RetrieveItem(item).GetName();
NonShopItems[locKey].Repurchaseable =
StaticData::RetrieveItem(item).GetItemType() == ITEMTYPE_REFILL ||
StaticData::RetrieveItem(item).GetHintKey() == RHT_PROGRESSIVE_BOMBCHUS;
}
loc->SetPlacedItem(item); loc->SetPlacedItem(item);
if (setHidden) { if (setHidden) {
loc->SetHidden(true); loc->SetHidden(true);
@ -213,9 +204,6 @@ void Context::CreateItemOverrides() {
iceTrapModels[locKey] = val.LooksLike(); iceTrapModels[locKey] = val.LooksLike();
val.SetTrickName(GetIceTrapName(val.LooksLike())); val.SetTrickName(GetIceTrapName(val.LooksLike()));
// If this is ice trap is in a shop, change the name based on what the model will look like // If this is ice trap is in a shop, change the name based on what the model will look like
if (loc->GetRCType() == RCTYPE_SHOP) {
NonShopItems[locKey].Name = val.GetTrickName();
}
overrides[locKey] = val; overrides[locKey] = val;
} }
SPDLOG_DEBUG(loc->GetName()); SPDLOG_DEBUG(loc->GetName());

View File

@ -192,12 +192,11 @@ void Hint::NamesChosen(){
hintTextsChosen = namesTemp; hintTextsChosen = namesTemp;
} }
if (hintType == HINT_TYPE_ITEM || hintType == HINT_TYPE_ITEM_AREA || hintType == HINT_TYPE_MERCHANT){ if (hintType == HINT_TYPE_ITEM || hintType == HINT_TYPE_ITEM_AREA){
bool mysterious = hintType == HINT_TYPE_MERCHANT && ctx->GetOption(RSK_SHUFFLE_MERCHANTS).Is(RO_SHUFFLE_MERCHANTS_ON_NO_HINT);
for(uint8_t c = 0; c < locations.size(); c++){ for(uint8_t c = 0; c < locations.size(); c++){
namesTemp = {}; namesTemp = {};
saveNames = false; saveNames = false;
uint8_t selection = GetRandomHintTextEntry(GetItemHintText(c, mysterious)); uint8_t selection = GetRandomHintTextEntry(GetItemHintText(c));
if (selection > 0){ if (selection > 0){
saveNames = true; saveNames = true;
} }
@ -332,13 +331,6 @@ const CustomMessage Hint::GetHintMessage(MessageFormat format, uint8_t id) const
toInsert.push_back(GetItemName(b)); toInsert.push_back(GetItemName(b));
} }
break;} break;}
case HINT_TYPE_MERCHANT:{
//if we write items, but need to adjust for merchants
bool mysterious = hintType == HINT_TYPE_MERCHANT && ctx->GetOption(RSK_SHUFFLE_MERCHANTS).Is(RO_SHUFFLE_MERCHANTS_ON_NO_HINT);
for(uint8_t b = 0; b < locations.size(); b++){
toInsert.push_back(GetItemName(b, mysterious));
}
break;}
case HINT_TYPE_TRIAL:{ case HINT_TYPE_TRIAL:{
//If we write trials //If we write trials
for(uint8_t b = 0; b < trials.size(); b++){ for(uint8_t b = 0; b < trials.size(); b++){
@ -507,7 +499,7 @@ void Hint::logHint(oJson& jsonData){
staticHint = false; staticHint = false;
} }
if (enabled && if (enabled &&
(!(staticHint && (hintType == HINT_TYPE_ITEM || hintType == HINT_TYPE_MERCHANT) && ctx->GetOption(RSK_HINT_CLARITY).Is(RO_HINT_CLARITY_CLEAR)))){ (!(staticHint && (hintType == HINT_TYPE_ITEM) && ctx->GetOption(RSK_HINT_CLARITY).Is(RO_HINT_CLARITY_CLEAR)))){
//skip if not enabled or if a static hint with no possible variance //skip if not enabled or if a static hint with no possible variance
jsonData[logMap][Rando::StaticData::hintNames[ownKey].GetForCurrentLanguage(MF_CLEAN)] = toJSON(); jsonData[logMap][Rando::StaticData::hintNames[ownKey].GetForCurrentLanguage(MF_CLEAN)] = toJSON();
} }

View File

@ -38,7 +38,7 @@ class Hint {
const HintText GetHintText(uint8_t id = 0) const; const HintText GetHintText(uint8_t id = 0) const;
oJson toJSON(); oJson toJSON();
void logHint(oJson& jsonData); void logHint(oJson& jsonData);
const HintText GetItemHintText(uint8_t slot, bool mysterious) const; const HintText GetItemHintText(uint8_t slot, bool mysterious = false) const;
const HintText GetAreaHintText(uint8_t slot) const; const HintText GetAreaHintText(uint8_t slot) const;
const CustomMessage GetItemName(uint8_t slot, bool mysterious = false) const; const CustomMessage GetItemName(uint8_t slot, bool mysterious = false) const;
const CustomMessage GetAreaName(uint8_t slot) const; const CustomMessage GetAreaName(uint8_t slot) const;

View File

@ -36,6 +36,9 @@ extern "C" {
#include "src/overlays/actors/ovl_Obj_Comb/z_obj_comb.h" #include "src/overlays/actors/ovl_Obj_Comb/z_obj_comb.h"
#include "src/overlays/actors/ovl_En_Bom_Bowl_Pit/z_en_bom_bowl_pit.h" #include "src/overlays/actors/ovl_En_Bom_Bowl_Pit/z_en_bom_bowl_pit.h"
#include "src/overlays/actors/ovl_En_Ge1/z_en_ge1.h" #include "src/overlays/actors/ovl_En_Ge1/z_en_ge1.h"
#include "src/overlays/actors/ovl_En_Ds/z_en_ds.h"
#include "src/overlays/actors/ovl_En_Gm/z_en_gm.h"
#include "src/overlays/actors/ovl_En_Js/z_en_js.h"
#include "src/overlays/actors/ovl_En_Door/z_en_door.h" #include "src/overlays/actors/ovl_En_Door/z_en_door.h"
#include "src/overlays/actors/ovl_Door_Shutter/z_door_shutter.h" #include "src/overlays/actors/ovl_Door_Shutter/z_door_shutter.h"
#include "src/overlays/actors/ovl_Door_Gerudo/z_door_gerudo.h" #include "src/overlays/actors/ovl_Door_Gerudo/z_door_gerudo.h"
@ -512,7 +515,8 @@ void EnCow_MoveForRandomizer(EnCow* enCow, PlayState* play) {
} }
u8 EnDs_RandoCanGetGrannyItem() { u8 EnDs_RandoCanGetGrannyItem() {
return RAND_GET_OPTION(RSK_SHUFFLE_MERCHANTS) != RO_SHUFFLE_MERCHANTS_OFF && return (RAND_GET_OPTION(RSK_SHUFFLE_MERCHANTS) == RO_SHUFFLE_MERCHANTS_ALL_BUT_BEANS ||
RAND_GET_OPTION(RSK_SHUFFLE_MERCHANTS) == RO_SHUFFLE_MERCHANTS_ALL) &&
!Flags_GetRandomizerInf(RAND_INF_MERCHANTS_GRANNYS_SHOP) && !Flags_GetRandomizerInf(RAND_INF_MERCHANTS_GRANNYS_SHOP) &&
// Traded odd mushroom when adult trade is on // Traded odd mushroom when adult trade is on
((RAND_GET_OPTION(RSK_SHUFFLE_ADULT_TRADE) && Flags_GetItemGetInf(ITEMGETINF_30)) || ((RAND_GET_OPTION(RSK_SHUFFLE_ADULT_TRADE) && Flags_GetItemGetInf(ITEMGETINF_30)) ||
@ -521,6 +525,20 @@ u8 EnDs_RandoCanGetGrannyItem() {
INV_CONTENT(ITEM_CLAIM_CHECK) == ITEM_CLAIM_CHECK)); INV_CONTENT(ITEM_CLAIM_CHECK) == ITEM_CLAIM_CHECK));
} }
u8 EnJs_RandoCanGetCarpetMerchantItem() {
return (RAND_GET_OPTION(RSK_SHUFFLE_MERCHANTS) == RO_SHUFFLE_MERCHANTS_ALL ||
RAND_GET_OPTION(RSK_SHUFFLE_MERCHANTS) == RO_SHUFFLE_MERCHANTS_ALL_BUT_BEANS) &&
// If the rando check has already been awarded, use vanilla behavior.
!Flags_GetRandomizerInf(RAND_INF_MERCHANTS_CARPET_SALESMAN);
}
u8 EnGm_RandoCanGetMedigoronItem() {
return (RAND_GET_OPTION(RSK_SHUFFLE_MERCHANTS) == RO_SHUFFLE_MERCHANTS_ALL ||
RAND_GET_OPTION(RSK_SHUFFLE_MERCHANTS) == RO_SHUFFLE_MERCHANTS_ALL_BUT_BEANS) &&
// If the rando check has already been awarded, use vanilla behavior.
!Flags_GetRandomizerInf(RAND_INF_MERCHANTS_MEDIGORON);
}
RandomizerCheck EnFr_RandomizerCheckFromSongIndex(u16 songIndex) { RandomizerCheck EnFr_RandomizerCheckFromSongIndex(u16 songIndex) {
switch (songIndex) { switch (songIndex) {
case FROG_ZL: case FROG_ZL:
@ -574,6 +592,8 @@ void RandomizerSetChestGameRandomizerInf(RandomizerCheck rc) {
case RC_MARKET_TREASURE_CHEST_GAME_KEY_5: case RC_MARKET_TREASURE_CHEST_GAME_KEY_5:
Flags_SetRandomizerInf(RAND_INF_MARKET_TREASURE_CHEST_GAME_KEY_5); Flags_SetRandomizerInf(RAND_INF_MARKET_TREASURE_CHEST_GAME_KEY_5);
break; break;
default:
break;
} }
} }
@ -681,8 +701,9 @@ void RandomizerOnVanillaBehaviorHandler(GIVanillaBehavior id, bool* should, void
break; break;
} }
case VB_BE_ELIGIBLE_FOR_MAGIC_BEANS_PURCHASE: { case VB_BE_ELIGIBLE_FOR_MAGIC_BEANS_PURCHASE: {
if (RAND_GET_OPTION(RSK_SHUFFLE_MAGIC_BEANS)) { if (RAND_GET_OPTION(RSK_SHUFFLE_MERCHANTS) == RO_SHUFFLE_MERCHANTS_BEANS_ONLY ||
*should = gSaveContext.rupees >= 60; RAND_GET_OPTION(RSK_SHUFFLE_MERCHANTS) == RO_SHUFFLE_MERCHANTS_ALL) {
*should = gSaveContext.rupees >= OTRGlobals::Instance->gRandoContext->GetItemLocation(RC_ZR_MAGIC_BEAN_SALESMAN)->GetPrice();
} }
break; break;
} }
@ -852,8 +873,11 @@ void RandomizerOnVanillaBehaviorHandler(GIVanillaBehavior id, bool* should, void
if (!EnDs_RandoCanGetGrannyItem()) { if (!EnDs_RandoCanGetGrannyItem()) {
break; break;
} }
EnDs* granny = static_cast<EnDs*>(optionalArg);
// Only setting the inf if we've actually gotten the rando item and not the vanilla blue potion // Only setting the inf if we've actually gotten the rando item and not the vanilla blue potion
Flags_SetRandomizerInf(RAND_INF_MERCHANTS_GRANNYS_SHOP); Flags_SetRandomizerInf(RAND_INF_MERCHANTS_GRANNYS_SHOP);
granny->actor.parent = NULL;
granny->actionFunc = EnDs_Talk;
*should = false; *should = false;
break; break;
} }
@ -878,23 +902,47 @@ void RandomizerOnVanillaBehaviorHandler(GIVanillaBehavior id, bool* should, void
*should = false; *should = false;
break; break;
} }
case VB_CHECK_RANDO_PRICE_OF_CARPET_SALESMAN: {
if (EnJs_RandoCanGetCarpetMerchantItem()){
*should = gSaveContext.rupees < OTRGlobals::Instance->gRandoContext->GetItemLocation(RC_WASTELAND_BOMBCHU_SALESMAN)->GetPrice();
}
break;
}
case VB_GIVE_ITEM_FROM_CARPET_SALESMAN: { case VB_GIVE_ITEM_FROM_CARPET_SALESMAN: {
*should = RAND_GET_OPTION(RSK_SHUFFLE_MERCHANTS) == RO_SHUFFLE_MERCHANTS_OFF || EnJs* enJs = static_cast<EnJs*>(optionalArg);
// If the rando check has already been awarded, use vanilla behavior. if (EnJs_RandoCanGetCarpetMerchantItem()){
Flags_GetRandomizerInf(RAND_INF_MERCHANTS_CARPET_SALESMAN); Rupees_ChangeBy(OTRGlobals::Instance->gRandoContext->GetItemLocation(RC_WASTELAND_BOMBCHU_SALESMAN)->GetPrice() * -1);
enJs->actor.parent = NULL;
enJs->actor.textId = TEXT_CARPET_SALESMAN_ARMS_DEALER;
enJs->actionFunc = (EnJsActionFunc)func_80A890C0;
enJs->actor.flags |= ACTOR_FLAG_WILL_TALK;
Flags_SetRandomizerInf(RAND_INF_MERCHANTS_CARPET_SALESMAN);
*should = true;
}
break; break;
} }
case VB_GIVE_BOMBCHUS_FROM_CARPET_SALESMAN: { case VB_GIVE_BOMBCHUS_FROM_CARPET_SALESMAN: {
*should = RAND_GET_OPTION(RSK_BOMBCHUS_IN_LOGIC) == false || INV_CONTENT(ITEM_BOMBCHU) == ITEM_BOMBCHU; *should = RAND_GET_OPTION(RSK_BOMBCHUS_IN_LOGIC) == false || INV_CONTENT(ITEM_BOMBCHU) == ITEM_BOMBCHU;
break; break;
} }
case VB_CHECK_RANDO_PRICE_OF_MEDIGORON: {
if (EnGm_RandoCanGetMedigoronItem()){
*should = gSaveContext.rupees < OTRGlobals::Instance->gRandoContext->GetItemLocation(RC_GC_MEDIGORON)->GetPrice();
}
break;
}
case VB_GIVE_ITEM_FROM_MEDIGORON: { case VB_GIVE_ITEM_FROM_MEDIGORON: {
// fallthrough // fallthrough
case VB_BE_ELIGIBLE_FOR_GIANTS_KNIFE_PURCHASE: case VB_BE_ELIGIBLE_FOR_GIANTS_KNIFE_PURCHASE:
if (RAND_GET_OPTION(RSK_SHUFFLE_MERCHANTS) != RO_SHUFFLE_MERCHANTS_OFF && if (EnGm_RandoCanGetMedigoronItem()) {
!Flags_GetRandomizerInf(RAND_INF_MERCHANTS_MEDIGORON)) {
if (id == VB_GIVE_ITEM_FROM_MEDIGORON) { if (id == VB_GIVE_ITEM_FROM_MEDIGORON) {
EnGm* enGm = static_cast<EnGm*>(optionalArg);
Flags_SetInfTable(INFTABLE_B1); Flags_SetInfTable(INFTABLE_B1);
Flags_SetRandomizerInf(RAND_INF_MERCHANTS_MEDIGORON);
enGm->actor.parent = NULL;
enGm->actionFunc = (EnGmActionFunc)func_80A3DC44;
Rupees_ChangeBy(OTRGlobals::Instance->gRandoContext->GetItemLocation(RC_GC_MEDIGORON)->GetPrice() * -1);
*should = false; *should = false;
} else { } else {
// Resets "Talked to Medigoron" flag in infTable to restore initial conversation state // Resets "Talked to Medigoron" flag in infTable to restore initial conversation state
@ -906,8 +954,9 @@ void RandomizerOnVanillaBehaviorHandler(GIVanillaBehavior id, bool* should, void
} }
case VB_GIVE_ITEM_FROM_MAGIC_BEAN_SALESMAN: { case VB_GIVE_ITEM_FROM_MAGIC_BEAN_SALESMAN: {
EnMs* enMs = static_cast<EnMs*>(optionalArg); EnMs* enMs = static_cast<EnMs*>(optionalArg);
if (RAND_GET_OPTION(RSK_SHUFFLE_MAGIC_BEANS)) { if (RAND_GET_OPTION(RSK_SHUFFLE_MERCHANTS) == RO_SHUFFLE_MERCHANTS_BEANS_ONLY ||
Rupees_ChangeBy(-60); RAND_GET_OPTION(RSK_SHUFFLE_MERCHANTS) == RO_SHUFFLE_MERCHANTS_ALL) {
Rupees_ChangeBy(OTRGlobals::Instance->gRandoContext->GetItemLocation(RC_ZR_MAGIC_BEAN_SALESMAN)->GetPrice() * -1);
BEANS_BOUGHT = 10; BEANS_BOUGHT = 10;
// Only set inf for buying rando check // Only set inf for buying rando check
Flags_SetRandomizerInf(RAND_INF_MERCHANTS_MAGIC_BEAN_SALESMAN); Flags_SetRandomizerInf(RAND_INF_MERCHANTS_MAGIC_BEAN_SALESMAN);
@ -944,9 +993,13 @@ void RandomizerOnVanillaBehaviorHandler(GIVanillaBehavior id, bool* should, void
break; break;
} }
case VB_TRADE_ODD_MUSHROOM: { case VB_TRADE_ODD_MUSHROOM: {
EnDs* granny = static_cast<EnDs*>(optionalArg);
Randomizer_ConsumeAdultTradeItem(gPlayState, ITEM_ODD_MUSHROOM); Randomizer_ConsumeAdultTradeItem(gPlayState, ITEM_ODD_MUSHROOM);
// Trigger the reward now // Trigger the reward now
Flags_SetItemGetInf(ITEMGETINF_30); Flags_SetItemGetInf(ITEMGETINF_30);
granny->actor.textId = 0x504F;
granny->actionFunc = (EnDsActionFunc)EnDs_TalkAfterGiveOddPotion;
granny->actor.flags &= ~ACTOR_FLAG_PLAYER_TALKED_TO;
*should = false; *should = false;
break; break;
} }
@ -1045,6 +1098,19 @@ void RandomizerOnVanillaBehaviorHandler(GIVanillaBehavior id, bool* should, void
*should |= RAND_GET_OPTION(RSK_SHUFFLE_ADULT_TRADE) == RO_GENERIC_OFF; *should |= RAND_GET_OPTION(RSK_SHUFFLE_ADULT_TRADE) == RO_GENERIC_OFF;
break; break;
} }
case VB_GRANNY_SAY_INSUFFICIENT_RUPEES: {
if (EnDs_RandoCanGetGrannyItem()){
*should = gSaveContext.rupees < OTRGlobals::Instance->gRandoContext->GetItemLocation(RC_KAK_GRANNYS_SHOP)->GetPrice();
}
break;
}
case VB_GRANNY_TAKE_MONEY: {
if (EnDs_RandoCanGetGrannyItem()){
*should = false;
Rupees_ChangeBy(OTRGlobals::Instance->gRandoContext->GetItemLocation(RC_KAK_GRANNYS_SHOP)->GetPrice() * -1);
}
break;
}
case VB_NEED_BOTTLE_FOR_GRANNYS_ITEM: { case VB_NEED_BOTTLE_FOR_GRANNYS_ITEM: {
// Allow buying the rando item regardless of having a bottle // Allow buying the rando item regardless of having a bottle
*should &= !EnDs_RandoCanGetGrannyItem(); *should &= !EnDs_RandoCanGetGrannyItem();
@ -1333,6 +1399,8 @@ void RandomizerOnVanillaBehaviorHandler(GIVanillaBehavior id, bool* should, void
case VB_GIVE_ITEM_SHADOW_MEDALLION: case VB_GIVE_ITEM_SHADOW_MEDALLION:
*should = false; *should = false;
break; break;
default:
break;
} }
} }

View File

@ -84,14 +84,8 @@ std::shared_ptr<GetItemEntry> Item::GetGIEntry() const { // NOLINT(*-no-recursio
std::shared_ptr<Rando::Context> ctx = Rando::Context::GetInstance(); std::shared_ptr<Rando::Context> ctx = Rando::Context::GetInstance();
auto logic = ctx->GetLogic(); auto logic = ctx->GetLogic();
RandomizerGet actual = RG_NONE; RandomizerGet actual = RG_NONE;
const bool tycoonWallet = !( const bool tycoonWallet = OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_INCLUDE_TYCOON_WALLET);
ctx->GetOption(RSK_SHOPSANITY).Is(RO_SHOPSANITY_OFF) || const u8 infiniteUpgrades = OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_INFINITE_UPGRADES);
(
ctx->GetOption(RSK_SHOPSANITY).Is(RO_SHOPSANITY_SPECIFIC_COUNT) &&
ctx->GetOption(RSK_SHOPSANITY_COUNT).Is(RO_SHOPSANITY_COUNT_ZERO_ITEMS)
)
);
const u8 infiniteUpgrades = ctx->GetOption(RSK_INFINITE_UPGRADES).Value<u8>();
switch (randomizerGet) { switch (randomizerGet) {
case RG_PROGRESSIVE_STICK_UPGRADE: case RG_PROGRESSIVE_STICK_UPGRADE:
switch (logic->CurrentUpgrade(UPG_STICKS)) { switch (logic->CurrentUpgrade(UPG_STICKS)) {
@ -287,8 +281,11 @@ std::shared_ptr<GetItemEntry> Item::GetGIEntry() const { // NOLINT(*-no-recursio
actual = RG_GIANT_WALLET; actual = RG_GIANT_WALLET;
break; break;
case 2: case 2:
actual = tycoonWallet ? RG_TYCOON_WALLET : RG_GIANT_WALLET; if(tycoonWallet){
break; actual = RG_TYCOON_WALLET;
break;
}
//fallthrough
case 3: case 3:
case 4: case 4:
if (infiniteUpgrades != RO_INF_UPGRADES_OFF) { if (infiniteUpgrades != RO_INF_UPGRADES_OFF) {

View File

@ -77,6 +77,7 @@ void ItemLocation::ApplyPlacedItemEffect() const {
} }
uint16_t ItemLocation::GetPrice() const { uint16_t ItemLocation::GetPrice() const {
//RANDOTODO if we ever change price of shop items, this needs replacing with proper price assignment in Fill
if (StaticData::RetrieveItem(placedItem).GetItemType() == ITEMTYPE_SHOP) { if (StaticData::RetrieveItem(placedItem).GetItemType() == ITEMTYPE_SHOP) {
return StaticData::RetrieveItem(placedItem).GetPrice(); return StaticData::RetrieveItem(placedItem).GetPrice();
} }

View File

@ -82,6 +82,10 @@ RandomizerGet Rando::Location::GetVanillaItem() const {
return vanillaItem; return vanillaItem;
} }
int16_t Rando::Location::GetVanillaPrice() const {
return vanillaPrice;
}
RandomizerCheckArea GetAreaFromScene(uint8_t scene) { RandomizerCheckArea GetAreaFromScene(uint8_t scene) {
switch (scene) { switch (scene) {
case SCENE_LINKS_HOUSE: case SCENE_LINKS_HOUSE:
@ -243,29 +247,30 @@ RandomizerCheckArea GetAreaFromScene(uint8_t scene) {
} }
} }
Rando::Location Rando::Location::Base(RandomizerCheck rc, RandomizerCheckQuest quest_, RandomizerCheckType checkType_, ActorID actorId_, SceneID scene_, int32_t actorParams_, Rando::Location Rando::Location::Base(RandomizerCheck rc, RandomizerCheckQuest quest_, RandomizerCheckType checkType_, ActorID actorId_, SceneID scene_, int32_t actorParams_,
std::string&& shortName_, std::string&& spoilerName_, const RandomizerHintTextKey hintKey, const RandomizerGet vanillaItem, std::string&& shortName_, std::string&& spoilerName_, const RandomizerHintTextKey hintKey, const RandomizerGet vanillaItem,
SpoilerCollectionCheck collectionCheck, bool isVanillaCompletion_) { SpoilerCollectionCheck collectionCheck, bool isVanillaCompletion_, uint16_t vanillaPrice_) {
return { rc, quest_, checkType_, GetAreaFromScene(scene_), actorId_, scene_, actorParams_, std::move(shortName_), std::move(spoilerName_), hintKey, vanillaItem, return { rc, quest_, checkType_, GetAreaFromScene(scene_), actorId_, scene_, actorParams_, std::move(shortName_), std::move(spoilerName_), hintKey, vanillaItem,
isVanillaCompletion_, collectionCheck }; isVanillaCompletion_, collectionCheck, vanillaPrice_ };
} }
Rando::Location Rando::Location::Base(RandomizerCheck rc, RandomizerCheckQuest quest_, RandomizerCheckType checkType_, RandomizerCheckArea area_, ActorID actorId_, SceneID scene_, Rando::Location Rando::Location::Base(RandomizerCheck rc, RandomizerCheckQuest quest_, RandomizerCheckType checkType_, RandomizerCheckArea area_, ActorID actorId_, SceneID scene_,
int32_t actorParams_, std::string&& shortName_, std::string&& spoilerName_, const RandomizerHintTextKey hintKey, const RandomizerGet vanillaItem, int32_t actorParams_, std::string&& shortName_, std::string&& spoilerName_, const RandomizerHintTextKey hintKey, const RandomizerGet vanillaItem,
SpoilerCollectionCheck collectionCheck, bool isVanillaCompletion_) { SpoilerCollectionCheck collectionCheck, bool isVanillaCompletion_, uint16_t vanillaPrice_) {
return { rc, quest_, checkType_, area_, actorId_, scene_, actorParams_, std::move(shortName_), std::move(spoilerName_), hintKey, vanillaItem, isVanillaCompletion_, collectionCheck }; return { rc, quest_, checkType_, area_, actorId_, scene_, actorParams_, std::move(shortName_), std::move(spoilerName_), hintKey, vanillaItem, isVanillaCompletion_, collectionCheck, vanillaPrice_ };
} }
Rando::Location Rando::Location::Base(RandomizerCheck rc, RandomizerCheckQuest quest_, RandomizerCheckType checkType_, ActorID actorId_, SceneID scene_, int32_t actorParams_, Rando::Location Rando::Location::Base(RandomizerCheck rc, RandomizerCheckQuest quest_, RandomizerCheckType checkType_, ActorID actorId_, SceneID scene_, int32_t actorParams_,
std::string&& shortName_, const RandomizerHintTextKey hintKey, const RandomizerGet vanillaItem, SpoilerCollectionCheck collectionCheck, std::string&& shortName_, const RandomizerHintTextKey hintKey, const RandomizerGet vanillaItem, SpoilerCollectionCheck collectionCheck,
bool isVanillaCompletion_) { bool isVanillaCompletion_, uint16_t vanillaPrice_) {
return { rc, quest_, checkType_, GetAreaFromScene(scene_), actorId_, scene_, actorParams_, std::move(shortName_), hintKey, vanillaItem, isVanillaCompletion_, collectionCheck }; return { rc, quest_, checkType_, GetAreaFromScene(scene_), actorId_, scene_, actorParams_, std::move(shortName_), hintKey, vanillaItem, isVanillaCompletion_, collectionCheck , vanillaPrice_ };
} }
Rando::Location Rando::Location::Base(RandomizerCheck rc, RandomizerCheckQuest quest_, RandomizerCheckType checkType_, RandomizerCheckArea area_, ActorID actorId_, SceneID scene_, Rando::Location Rando::Location::Base(RandomizerCheck rc, RandomizerCheckQuest quest_, RandomizerCheckType checkType_, RandomizerCheckArea area_, ActorID actorId_, SceneID scene_,
int32_t actorParams_, std::string&& shortName_, const RandomizerHintTextKey hintKey, const RandomizerGet vanillaItem, int32_t actorParams_, std::string&& shortName_, const RandomizerHintTextKey hintKey, const RandomizerGet vanillaItem,
SpoilerCollectionCheck collectionCheck, bool isVanillaCompletion_) { SpoilerCollectionCheck collectionCheck, bool isVanillaCompletion_, uint16_t vanillaPrice_) {
return { rc, quest_, checkType_, area_, actorId_, scene_, actorParams_, std::move(shortName_), hintKey, vanillaItem, isVanillaCompletion_, collectionCheck }; return { rc, quest_, checkType_, area_, actorId_, scene_, actorParams_, std::move(shortName_), hintKey, vanillaItem, isVanillaCompletion_, collectionCheck, vanillaPrice_ };
} }
Rando::Location Rando::Location::Chest(RandomizerCheck rc, RandomizerCheckQuest quest_, RandomizerCheckType checkType_, ActorID actorId_, SceneID scene_, int32_t actorParams_, Rando::Location Rando::Location::Chest(RandomizerCheck rc, RandomizerCheckQuest quest_, RandomizerCheckType checkType_, ActorID actorId_, SceneID scene_, int32_t actorParams_,

View File

@ -53,18 +53,20 @@ class Location {
Location(const RandomizerCheck rc_, const RandomizerCheckQuest quest_, const RandomizerCheckType checkType_, const RandomizerCheckArea area_, const ActorID actorId_, Location(const RandomizerCheck rc_, const RandomizerCheckQuest quest_, const RandomizerCheckType checkType_, const RandomizerCheckArea area_, const ActorID actorId_,
const SceneID scene_, const int32_t actorParams_, std::string shortName_, std::string spoilerName_, const RandomizerHintTextKey hintKey_, const SceneID scene_, const int32_t actorParams_, std::string shortName_, std::string spoilerName_, const RandomizerHintTextKey hintKey_,
const RandomizerGet vanillaItem_, const bool isVanillaCompletion_ = false, const SpoilerCollectionCheck collectionCheck_ = SpoilerCollectionCheck()) const RandomizerGet vanillaItem_, const bool isVanillaCompletion_ = false, const SpoilerCollectionCheck collectionCheck_ = SpoilerCollectionCheck(),
const int vanillaPrice_ = 0)
: rc(rc_), quest(quest_), checkType(checkType_), area(area_), actorId(actorId_), : rc(rc_), quest(quest_), checkType(checkType_), area(area_), actorId(actorId_),
scene(scene_), actorParams(actorParams_), shortName(std::move(shortName_)), scene(scene_), actorParams(actorParams_), shortName(std::move(shortName_)),
spoilerName(std::move(spoilerName_)), hintKey(hintKey_), vanillaItem(vanillaItem_), spoilerName(std::move(spoilerName_)), hintKey(hintKey_), vanillaItem(vanillaItem_),
isVanillaCompletion(isVanillaCompletion_), collectionCheck(collectionCheck_) {} isVanillaCompletion(isVanillaCompletion_), collectionCheck(collectionCheck_), vanillaPrice(vanillaPrice_) {}
Location(const RandomizerCheck rc_, const RandomizerCheckQuest quest_, const RandomizerCheckType checkType_, const RandomizerCheckArea area_, const ActorID actorId_, Location(const RandomizerCheck rc_, const RandomizerCheckQuest quest_, const RandomizerCheckType checkType_, const RandomizerCheckArea area_, const ActorID actorId_,
const SceneID scene_, const int32_t actorParams_, std::string shortName_, const RandomizerHintTextKey hintKey_, const RandomizerGet vanillaItem_, const SceneID scene_, const int32_t actorParams_, std::string shortName_, const RandomizerHintTextKey hintKey_, const RandomizerGet vanillaItem_,
const bool isVanillaCompletion_ = false, const SpoilerCollectionCheck collectionCheck_ = SpoilerCollectionCheck()) const bool isVanillaCompletion_ = false, const SpoilerCollectionCheck collectionCheck_ = SpoilerCollectionCheck(),
const int vanillaPrice_ = 0)
: rc(rc_), quest(quest_), checkType(checkType_), area(area_), actorId(actorId_), scene(scene_), actorParams(actorParams_), shortName(shortName_), : rc(rc_), quest(quest_), checkType(checkType_), area(area_), actorId(actorId_), scene(scene_), actorParams(actorParams_), shortName(shortName_),
spoilerName(SpoilerNameFromShortName(shortName_, area_)), hintKey(hintKey_), vanillaItem(vanillaItem_), isVanillaCompletion(isVanillaCompletion_), spoilerName(SpoilerNameFromShortName(shortName_, area_)), hintKey(hintKey_), vanillaItem(vanillaItem_), isVanillaCompletion(isVanillaCompletion_),
collectionCheck(collectionCheck_) {} collectionCheck(collectionCheck_), vanillaPrice(vanillaPrice_) {}
static std::string SpoilerNameFromShortName(std::string shortName, RandomizerCheckArea area) { static std::string SpoilerNameFromShortName(std::string shortName, RandomizerCheckArea area) {
if (area < 0 || area >= RCAREA_INVALID) { if (area < 0 || area >= RCAREA_INVALID) {
@ -92,22 +94,23 @@ class Location {
uint32_t Getuint32_t() const; uint32_t Getuint32_t() const;
const HintText& GetHint() const; const HintText& GetHint() const;
RandomizerGet GetVanillaItem() const; RandomizerGet GetVanillaItem() const;
int16_t GetVanillaPrice() const;
static Location Base(RandomizerCheck rc, RandomizerCheckQuest quest_, RandomizerCheckType checkType_, ActorID actorId_, SceneID scene_, int32_t actorParams_, static Location Base(RandomizerCheck rc, RandomizerCheckQuest quest_, RandomizerCheckType checkType_, ActorID actorId_, SceneID scene_, int32_t actorParams_,
std::string&& shortName_, std::string&& spoilerName_, RandomizerHintTextKey hintKey, RandomizerGet vanillaItem, std::string&& shortName_, std::string&& spoilerName_, RandomizerHintTextKey hintKey, RandomizerGet vanillaItem,
SpoilerCollectionCheck collectionCheck = SpoilerCollectionCheck(), bool isVanillaCompletion_ = false); SpoilerCollectionCheck collectionCheck = SpoilerCollectionCheck(), bool isVanillaCompletion_ = false, uint16_t vanillaPrice_ = 0);
static Location Base(RandomizerCheck rc, RandomizerCheckQuest quest_, RandomizerCheckType checkType_, ActorID actorId_, SceneID scene_, int32_t actorParams_, static Location Base(RandomizerCheck rc, RandomizerCheckQuest quest_, RandomizerCheckType checkType_, ActorID actorId_, SceneID scene_, int32_t actorParams_,
std::string&& shortName_, RandomizerHintTextKey hintKey, RandomizerGet vanillaItem, SpoilerCollectionCheck collectionCheck = SpoilerCollectionCheck(), std::string&& shortName_, RandomizerHintTextKey hintKey, RandomizerGet vanillaItem, SpoilerCollectionCheck collectionCheck = SpoilerCollectionCheck(),
bool isVanillaCompletion_ = false); bool isVanillaCompletion_ = false, uint16_t vanillaPrice_ = 0);
static Location Base(RandomizerCheck rc, RandomizerCheckQuest quest_, RandomizerCheckType checkType_, RandomizerCheckArea area_, ActorID actorId_, SceneID scene_, static Location Base(RandomizerCheck rc, RandomizerCheckQuest quest_, RandomizerCheckType checkType_, RandomizerCheckArea area_, ActorID actorId_, SceneID scene_,
int32_t actorParams_, std::string&& shortName_, std::string&& spoilerName_, RandomizerHintTextKey hintKey, RandomizerGet vanillaItem, int32_t actorParams_, std::string&& shortName_, std::string&& spoilerName_, RandomizerHintTextKey hintKey, RandomizerGet vanillaItem,
SpoilerCollectionCheck collectionCheck = SpoilerCollectionCheck(), bool isVanillaCompletion_ = false); SpoilerCollectionCheck collectionCheck = SpoilerCollectionCheck(), bool isVanillaCompletion_ = false, uint16_t vanillaPrice_ = 0);
static Location Base(RandomizerCheck rc, RandomizerCheckQuest quest_, RandomizerCheckType checkType_, RandomizerCheckArea area_, ActorID actorId_, SceneID scene_, static Location Base(RandomizerCheck rc, RandomizerCheckQuest quest_, RandomizerCheckType checkType_, RandomizerCheckArea area_, ActorID actorId_, SceneID scene_,
int32_t actorParams_, std::string&& shortName_, RandomizerHintTextKey hintKey, RandomizerGet vanillaItem, int32_t actorParams_, std::string&& shortName_, RandomizerHintTextKey hintKey, RandomizerGet vanillaItem,
SpoilerCollectionCheck collectionCheck = SpoilerCollectionCheck(), bool isVanillaCompletion_ = false); SpoilerCollectionCheck collectionCheck = SpoilerCollectionCheck(), bool isVanillaCompletion_ = false, uint16_t vanillaPrice_ = 0);
static Location Chest(RandomizerCheck rc, RandomizerCheckQuest quest_, RandomizerCheckType checkType_, RandomizerCheckArea area_, ActorID actorId_, SceneID scene_, static Location Chest(RandomizerCheck rc, RandomizerCheckQuest quest_, RandomizerCheckType checkType_, RandomizerCheckArea area_, ActorID actorId_, SceneID scene_,
int32_t actorParams_, uint8_t flag_, std::string&& shortName_, RandomizerHintTextKey hintKey, RandomizerGet vanillaItem, bool isVanillaCompletion_ = false); int32_t actorParams_, uint8_t flag_, std::string&& shortName_, RandomizerHintTextKey hintKey, RandomizerGet vanillaItem, bool isVanillaCompletion_ = false);
@ -192,6 +195,7 @@ class Location {
RandomizerGet vanillaItem; RandomizerGet vanillaItem;
bool isVanillaCompletion; bool isVanillaCompletion;
SpoilerCollectionCheck collectionCheck; SpoilerCollectionCheck collectionCheck;
int16_t vanillaPrice;
bool isHintable = false; bool isHintable = false;
}; };
} // namespace Rando } // namespace Rando

View File

@ -55,6 +55,16 @@ std::vector<RandomizerCheck> Rando::StaticData::GetScrubLocations() {
return scrubLocations; return scrubLocations;
} }
std::vector<RandomizerCheck> Rando::StaticData::GetMerchantLocations() {
std::vector<RandomizerCheck> scrubLocations = {};
for (Location& location : locationTable) {
if (location.GetRCType() == RCTYPE_MERCHANT && location.GetRandomizerCheck() != RC_UNKNOWN_CHECK) {
scrubLocations.push_back(location.GetRandomizerCheck());
}
}
return scrubLocations;
}
std::vector<RandomizerCheck> Rando::StaticData::GetAdultTradeLocations() { std::vector<RandomizerCheck> Rando::StaticData::GetAdultTradeLocations() {
std::vector<RandomizerCheck> tradeLocations = {}; std::vector<RandomizerCheck> tradeLocations = {};
for (Location& location : locationTable) { for (Location& location : locationTable) {
@ -138,24 +148,24 @@ void Rando::StaticData::InitLocationTable() { //
locationTable[RC_LW_TRADE_ODD_POTION] = Location::Base(RC_LW_TRADE_ODD_POTION, RCQUEST_BOTH, RCTYPE_ADULT_TRADE, ACTOR_ID_MAX, SCENE_LOST_WOODS, 0x00, "Trade Odd Potion", RHT_LW_TRADE_COJIRO, RG_POACHERS_SAW, SpoilerCollectionCheck::ItemGetInf(49), true); locationTable[RC_LW_TRADE_ODD_POTION] = Location::Base(RC_LW_TRADE_ODD_POTION, RCQUEST_BOTH, RCTYPE_ADULT_TRADE, ACTOR_ID_MAX, SCENE_LOST_WOODS, 0x00, "Trade Odd Potion", RHT_LW_TRADE_COJIRO, RG_POACHERS_SAW, SpoilerCollectionCheck::ItemGetInf(49), true);
locationTable[RC_LW_OCARINA_MEMORY_GAME] = Location::Base(RC_LW_OCARINA_MEMORY_GAME, RCQUEST_BOTH, RCTYPE_STANDARD, ACTOR_ID_MAX, SCENE_LOST_WOODS, 0x00, "Ocarina Memory Game", RHT_LW_OCARINA_MEMORY_GAME, RG_PIECE_OF_HEART, SpoilerCollectionCheck::ItemGetInf(23), true); locationTable[RC_LW_OCARINA_MEMORY_GAME] = Location::Base(RC_LW_OCARINA_MEMORY_GAME, RCQUEST_BOTH, RCTYPE_STANDARD, ACTOR_ID_MAX, SCENE_LOST_WOODS, 0x00, "Ocarina Memory Game", RHT_LW_OCARINA_MEMORY_GAME, RG_PIECE_OF_HEART, SpoilerCollectionCheck::ItemGetInf(23), true);
locationTable[RC_LW_TARGET_IN_WOODS] = Location::Base(RC_LW_TARGET_IN_WOODS, RCQUEST_BOTH, RCTYPE_STANDARD, ACTOR_ID_MAX, SCENE_LOST_WOODS, 0x00, "Target in Woods", RHT_LW_TARGET_IN_WOODS, RG_PROGRESSIVE_SLINGSHOT, SpoilerCollectionCheck::ItemGetInf(29), true); locationTable[RC_LW_TARGET_IN_WOODS] = Location::Base(RC_LW_TARGET_IN_WOODS, RCQUEST_BOTH, RCTYPE_STANDARD, ACTOR_ID_MAX, SCENE_LOST_WOODS, 0x00, "Target in Woods", RHT_LW_TARGET_IN_WOODS, RG_PROGRESSIVE_SLINGSHOT, SpoilerCollectionCheck::ItemGetInf(29), true);
locationTable[RC_LW_DEKU_SCRUB_NEAR_DEKU_THEATER_RIGHT] = Location::Base(RC_LW_DEKU_SCRUB_NEAR_DEKU_THEATER_RIGHT, RCQUEST_BOTH, RCTYPE_SCRUB, ACTOR_EN_DNS, SCENE_LOST_WOODS, 0x00, "Deku Scrub Near Deku Theater Right", RHT_LW_DEKU_SCRUB_NEAR_DEKU_THEATER_RIGHT, RG_BUY_DEKU_NUTS_5, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SCRUBS_PURCHASED_LW_DEKU_SCRUB_NEAR_DEKU_THEATER_RIGHT)); locationTable[RC_LW_DEKU_SCRUB_NEAR_DEKU_THEATER_RIGHT] = Location::Base(RC_LW_DEKU_SCRUB_NEAR_DEKU_THEATER_RIGHT, RCQUEST_BOTH, RCTYPE_SCRUB, ACTOR_EN_DNS, SCENE_LOST_WOODS, 0x00, "Deku Scrub Near Deku Theater Right", RHT_LW_DEKU_SCRUB_NEAR_DEKU_THEATER_RIGHT, RG_BUY_DEKU_NUTS_5, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SCRUBS_PURCHASED_LW_DEKU_SCRUB_NEAR_DEKU_THEATER_RIGHT), false, 20);
locationTable[RC_LW_DEKU_SCRUB_NEAR_DEKU_THEATER_LEFT] = Location::Base(RC_LW_DEKU_SCRUB_NEAR_DEKU_THEATER_LEFT, RCQUEST_BOTH, RCTYPE_SCRUB, ACTOR_EN_DNS, SCENE_LOST_WOODS, 0x01, "Deku Scrub Near Deku Theater Left", RHT_LW_DEKU_SCRUB_NEAR_DEKU_THEATER_LEFT, RG_BUY_DEKU_STICK_1, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SCRUBS_PURCHASED_LW_DEKU_SCRUB_NEAR_DEKU_THEATER_LEFT)); locationTable[RC_LW_DEKU_SCRUB_NEAR_DEKU_THEATER_LEFT] = Location::Base(RC_LW_DEKU_SCRUB_NEAR_DEKU_THEATER_LEFT, RCQUEST_BOTH, RCTYPE_SCRUB, ACTOR_EN_DNS, SCENE_LOST_WOODS, 0x01, "Deku Scrub Near Deku Theater Left", RHT_LW_DEKU_SCRUB_NEAR_DEKU_THEATER_LEFT, RG_BUY_DEKU_STICK_1, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SCRUBS_PURCHASED_LW_DEKU_SCRUB_NEAR_DEKU_THEATER_LEFT), false, 15);
locationTable[RC_LW_DEKU_SCRUB_NEAR_BRIDGE] = Location::Base(RC_LW_DEKU_SCRUB_NEAR_BRIDGE, RCQUEST_BOTH, RCTYPE_SCRUB, ACTOR_EN_DNS, SCENE_LOST_WOODS, 0x09, "Deku Scrub Near Bridge", RHT_LW_DEKU_SCRUB_NEAR_BRIDGE, RG_PROGRESSIVE_STICK_UPGRADE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SCRUBS_PURCHASED_LW_DEKU_SCRUB_NEAR_BRIDGE), true); locationTable[RC_LW_DEKU_SCRUB_NEAR_BRIDGE] = Location::Base(RC_LW_DEKU_SCRUB_NEAR_BRIDGE, RCQUEST_BOTH, RCTYPE_SCRUB, ACTOR_EN_DNS, SCENE_LOST_WOODS, 0x09, "Deku Scrub Near Bridge", RHT_LW_DEKU_SCRUB_NEAR_BRIDGE, RG_PROGRESSIVE_STICK_UPGRADE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SCRUBS_PURCHASED_LW_DEKU_SCRUB_NEAR_BRIDGE), true, 40);
locationTable[RC_LW_DEKU_SCRUB_GROTTO_REAR] = Location::Base(RC_LW_DEKU_SCRUB_GROTTO_REAR, RCQUEST_BOTH, RCTYPE_SCRUB, RCAREA_LOST_WOODS, ACTOR_EN_DNS, SCENE_GROTTOS, TWO_ACTOR_PARAMS(0x03, 0xF5), "Deku Scrub Grotto Rear", RHT_LW_DEKU_SCRUB_GROTTO_REAR, RG_BUY_DEKU_SEEDS_30, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SCRUBS_PURCHASED_LW_DEKU_SCRUB_GROTTO_REAR)); locationTable[RC_LW_DEKU_SCRUB_GROTTO_REAR] = Location::Base(RC_LW_DEKU_SCRUB_GROTTO_REAR, RCQUEST_BOTH, RCTYPE_SCRUB, RCAREA_LOST_WOODS, ACTOR_EN_DNS, SCENE_GROTTOS, TWO_ACTOR_PARAMS(0x03, 0xF5), "Deku Scrub Grotto Rear", RHT_LW_DEKU_SCRUB_GROTTO_REAR, RG_BUY_DEKU_SEEDS_30, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SCRUBS_PURCHASED_LW_DEKU_SCRUB_GROTTO_REAR), false, 40);
locationTable[RC_LW_DEKU_SCRUB_GROTTO_FRONT] = Location::Base(RC_LW_DEKU_SCRUB_GROTTO_FRONT, RCQUEST_BOTH, RCTYPE_SCRUB, RCAREA_LOST_WOODS, ACTOR_EN_DNS, SCENE_GROTTOS, TWO_ACTOR_PARAMS(0x0A, 0xF5), "Deku Scrub Grotto Front", RHT_LW_DEKU_SCRUB_GROTTO_FRONT, RG_PROGRESSIVE_NUT_UPGRADE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SCRUBS_PURCHASED_LW_DEKU_SCRUB_GROTTO_FRONT)); locationTable[RC_LW_DEKU_SCRUB_GROTTO_FRONT] = Location::Base(RC_LW_DEKU_SCRUB_GROTTO_FRONT, RCQUEST_BOTH, RCTYPE_SCRUB, RCAREA_LOST_WOODS, ACTOR_EN_DNS, SCENE_GROTTOS, TWO_ACTOR_PARAMS(0x0A, 0xF5), "Deku Scrub Grotto Front", RHT_LW_DEKU_SCRUB_GROTTO_FRONT, RG_PROGRESSIVE_NUT_UPGRADE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SCRUBS_PURCHASED_LW_DEKU_SCRUB_GROTTO_FRONT), false, 40);
locationTable[RC_DEKU_THEATER_SKULL_MASK] = Location::Base(RC_DEKU_THEATER_SKULL_MASK, RCQUEST_BOTH, RCTYPE_STANDARD, RCAREA_LOST_WOODS, ACTOR_ID_MAX, SCENE_GROTTOS, 0x00, "Deku Theater Skull Mask", RHT_DEKU_THEATER_SKULL_MASK, RG_PROGRESSIVE_STICK_UPGRADE, SpoilerCollectionCheck::ItemGetInf(ITEMGETINF_OBTAINED_STICK_UPGRADE_FROM_STAGE), true); locationTable[RC_DEKU_THEATER_SKULL_MASK] = Location::Base(RC_DEKU_THEATER_SKULL_MASK, RCQUEST_BOTH, RCTYPE_STANDARD, RCAREA_LOST_WOODS, ACTOR_ID_MAX, SCENE_GROTTOS, 0x00, "Deku Theater Skull Mask", RHT_DEKU_THEATER_SKULL_MASK, RG_PROGRESSIVE_STICK_UPGRADE, SpoilerCollectionCheck::ItemGetInf(ITEMGETINF_OBTAINED_STICK_UPGRADE_FROM_STAGE), true);
locationTable[RC_DEKU_THEATER_MASK_OF_TRUTH] = Location::Base(RC_DEKU_THEATER_MASK_OF_TRUTH, RCQUEST_BOTH, RCTYPE_STANDARD, RCAREA_LOST_WOODS, ACTOR_ID_MAX, SCENE_GROTTOS, 0x00, "Deku Theater Mask of Truth", RHT_DEKU_THEATER_MASK_OF_TRUTH, RG_PROGRESSIVE_NUT_UPGRADE, SpoilerCollectionCheck::ItemGetInf(ITEMGETINF_OBTAINED_NUT_UPGRADE_FROM_STAGE), true); locationTable[RC_DEKU_THEATER_MASK_OF_TRUTH] = Location::Base(RC_DEKU_THEATER_MASK_OF_TRUTH, RCQUEST_BOTH, RCTYPE_STANDARD, RCAREA_LOST_WOODS, ACTOR_ID_MAX, SCENE_GROTTOS, 0x00, "Deku Theater Mask of Truth", RHT_DEKU_THEATER_MASK_OF_TRUTH, RG_PROGRESSIVE_NUT_UPGRADE, SpoilerCollectionCheck::ItemGetInf(ITEMGETINF_OBTAINED_NUT_UPGRADE_FROM_STAGE), true);
// Sacred Forest Meadow // Sacred Forest Meadow
locationTable[RC_SFM_WOLFOS_GROTTO_CHEST] = Location::Chest(RC_SFM_WOLFOS_GROTTO_CHEST, RCQUEST_BOTH, RCTYPE_STANDARD, RCAREA_SACRED_FOREST_MEADOW, ACTOR_EN_BOX, SCENE_GROTTOS, 31409, 0x11, "Wolfos Grotto Chest", RHT_SFM_WOLFOS_GROTTO_CHEST, RG_PURPLE_RUPEE); locationTable[RC_SFM_WOLFOS_GROTTO_CHEST] = Location::Chest(RC_SFM_WOLFOS_GROTTO_CHEST, RCQUEST_BOTH, RCTYPE_STANDARD, RCAREA_SACRED_FOREST_MEADOW, ACTOR_EN_BOX, SCENE_GROTTOS, 31409, 0x11, "Wolfos Grotto Chest", RHT_SFM_WOLFOS_GROTTO_CHEST, RG_PURPLE_RUPEE);
locationTable[RC_SFM_DEKU_SCRUB_GROTTO_REAR] = Location::Base(RC_SFM_DEKU_SCRUB_GROTTO_REAR, RCQUEST_BOTH, RCTYPE_SCRUB, RCAREA_SACRED_FOREST_MEADOW, ACTOR_EN_DNS, SCENE_GROTTOS, TWO_ACTOR_PARAMS(0x07, 0xEE), "Deku Scrub Grotto Rear", RHT_SFM_DEKU_SCRUB_GROTTO_REAR, RG_BUY_RED_POTION_30, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SCRUBS_PURCHASED_SFM_DEKU_SCRUB_GROTTO_REAR)); locationTable[RC_SFM_DEKU_SCRUB_GROTTO_REAR] = Location::Base(RC_SFM_DEKU_SCRUB_GROTTO_REAR, RCQUEST_BOTH, RCTYPE_SCRUB, RCAREA_SACRED_FOREST_MEADOW, ACTOR_EN_DNS, SCENE_GROTTOS, TWO_ACTOR_PARAMS(0x07, 0xEE), "Deku Scrub Grotto Rear", RHT_SFM_DEKU_SCRUB_GROTTO_REAR, RG_BUY_RED_POTION_40, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SCRUBS_PURCHASED_SFM_DEKU_SCRUB_GROTTO_REAR), false, 40);
locationTable[RC_SFM_DEKU_SCRUB_GROTTO_FRONT] = Location::Base(RC_SFM_DEKU_SCRUB_GROTTO_FRONT, RCQUEST_BOTH, RCTYPE_SCRUB, RCAREA_SACRED_FOREST_MEADOW, ACTOR_EN_DNS, SCENE_GROTTOS, TWO_ACTOR_PARAMS(0x08, 0xEE), "Deku Scrub Grotto Front", RHT_SFM_DEKU_SCRUB_GROTTO_FRONT, RG_BUY_GREEN_POTION, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SCRUBS_PURCHASED_SFM_DEKU_SCRUB_GROTTO_FRONT)); locationTable[RC_SFM_DEKU_SCRUB_GROTTO_FRONT] = Location::Base(RC_SFM_DEKU_SCRUB_GROTTO_FRONT, RCQUEST_BOTH, RCTYPE_SCRUB, RCAREA_SACRED_FOREST_MEADOW, ACTOR_EN_DNS, SCENE_GROTTOS, TWO_ACTOR_PARAMS(0x08, 0xEE), "Deku Scrub Grotto Front", RHT_SFM_DEKU_SCRUB_GROTTO_FRONT, RG_BUY_GREEN_POTION, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SCRUBS_PURCHASED_SFM_DEKU_SCRUB_GROTTO_FRONT), false, 40);
// Hyrule Field // Hyrule Field
locationTable[RC_HF_SOUTHEAST_GROTTO_CHEST] = Location::Chest(RC_HF_SOUTHEAST_GROTTO_CHEST, RCQUEST_BOTH, RCTYPE_STANDARD, RCAREA_HYRULE_FIELD, ACTOR_EN_BOX, SCENE_GROTTOS, 22978, 0x02, "Southeast Grotto Chest", RHT_HF_SOUTHEAST_GROTTO_CHEST, RG_RED_RUPEE); locationTable[RC_HF_SOUTHEAST_GROTTO_CHEST] = Location::Chest(RC_HF_SOUTHEAST_GROTTO_CHEST, RCQUEST_BOTH, RCTYPE_STANDARD, RCAREA_HYRULE_FIELD, ACTOR_EN_BOX, SCENE_GROTTOS, 22978, 0x02, "Southeast Grotto Chest", RHT_HF_SOUTHEAST_GROTTO_CHEST, RG_RED_RUPEE);
locationTable[RC_HF_OPEN_GROTTO_CHEST] = Location::Chest(RC_HF_OPEN_GROTTO_CHEST, RCQUEST_BOTH, RCTYPE_STANDARD, RCAREA_HYRULE_FIELD, ACTOR_EN_BOX, SCENE_GROTTOS, 22947, 0x03, "Open Grotto Chest", RHT_HF_OPEN_GROTTO_CHEST, RG_BLUE_RUPEE); locationTable[RC_HF_OPEN_GROTTO_CHEST] = Location::Chest(RC_HF_OPEN_GROTTO_CHEST, RCQUEST_BOTH, RCTYPE_STANDARD, RCAREA_HYRULE_FIELD, ACTOR_EN_BOX, SCENE_GROTTOS, 22947, 0x03, "Open Grotto Chest", RHT_HF_OPEN_GROTTO_CHEST, RG_BLUE_RUPEE);
locationTable[RC_HF_NEAR_MARKET_GROTTO_CHEST] = Location::Chest(RC_HF_NEAR_MARKET_GROTTO_CHEST, RCQUEST_BOTH, RCTYPE_STANDARD, RCAREA_HYRULE_FIELD, ACTOR_EN_BOX, SCENE_GROTTOS, 22944, 0x00, "Near Market Grotto Chest", RHT_HF_NEAR_MARKET_GROTTO_CHEST, RG_BLUE_RUPEE); locationTable[RC_HF_NEAR_MARKET_GROTTO_CHEST] = Location::Chest(RC_HF_NEAR_MARKET_GROTTO_CHEST, RCQUEST_BOTH, RCTYPE_STANDARD, RCAREA_HYRULE_FIELD, ACTOR_EN_BOX, SCENE_GROTTOS, 22944, 0x00, "Near Market Grotto Chest", RHT_HF_NEAR_MARKET_GROTTO_CHEST, RG_BLUE_RUPEE);
locationTable[RC_HF_OCARINA_OF_TIME_ITEM] = Location::Base(RC_HF_OCARINA_OF_TIME_ITEM, RCQUEST_BOTH, RCTYPE_OCARINA, ACTOR_ID_MAX, SCENE_HYRULE_FIELD, 0x00, "Ocarina of Time Item", RHT_HF_OCARINA_OF_TIME_ITEM, RG_PROGRESSIVE_OCARINA, SpoilerCollectionCheck::EventChkInf(0x43)); locationTable[RC_HF_OCARINA_OF_TIME_ITEM] = Location::Base(RC_HF_OCARINA_OF_TIME_ITEM, RCQUEST_BOTH, RCTYPE_OCARINA, ACTOR_ID_MAX, SCENE_HYRULE_FIELD, 0x00, "Ocarina of Time Item", RHT_HF_OCARINA_OF_TIME_ITEM, RG_PROGRESSIVE_OCARINA, SpoilerCollectionCheck::EventChkInf(0x43));
locationTable[RC_HF_TEKTITE_GROTTO_FREESTANDING_POH] = Location::Collectable(RC_HF_TEKTITE_GROTTO_FREESTANDING_POH, RCQUEST_BOTH, RCTYPE_STANDARD, RCAREA_HYRULE_FIELD, ACTOR_EN_ITEM00, SCENE_GROTTOS, 262, 0x01, "Tektite Grotto Freestanding PoH", RHT_HF_TEKTITE_GROTTO_FREESTANDING_POH, RG_PIECE_OF_HEART, true); locationTable[RC_HF_TEKTITE_GROTTO_FREESTANDING_POH] = Location::Collectable(RC_HF_TEKTITE_GROTTO_FREESTANDING_POH, RCQUEST_BOTH, RCTYPE_STANDARD, RCAREA_HYRULE_FIELD, ACTOR_EN_ITEM00, SCENE_GROTTOS, 262, 0x01, "Tektite Grotto Freestanding PoH", RHT_HF_TEKTITE_GROTTO_FREESTANDING_POH, RG_PIECE_OF_HEART, true);
locationTable[RC_HF_DEKU_SCRUB_GROTTO] = Location::Base(RC_HF_DEKU_SCRUB_GROTTO, RCQUEST_BOTH, RCTYPE_SCRUB, RCAREA_HYRULE_FIELD, ACTOR_EN_DNS, SCENE_GROTTOS, TWO_ACTOR_PARAMS(0x02, 0xE6), "Deku Scrub Grotto", RHT_HF_DEKU_SCRUB_GROTTO, RG_PIECE_OF_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SCRUBS_PURCHASED_HF_DEKU_SCRUB_GROTTO), true); locationTable[RC_HF_DEKU_SCRUB_GROTTO] = Location::Base(RC_HF_DEKU_SCRUB_GROTTO, RCQUEST_BOTH, RCTYPE_SCRUB, RCAREA_HYRULE_FIELD, ACTOR_EN_DNS, SCENE_GROTTOS, TWO_ACTOR_PARAMS(0x02, 0xE6), "Deku Scrub Grotto", RHT_HF_DEKU_SCRUB_GROTTO, RG_PIECE_OF_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SCRUBS_PURCHASED_HF_DEKU_SCRUB_GROTTO), true, 10);
// Lake Hylia // Lake Hylia
locationTable[RC_LH_CHILD_FISHING] = Location::Base(RC_LH_CHILD_FISHING, RCQUEST_BOTH, RCTYPE_STANDARD, ACTOR_ID_MAX, SCENE_FISHING_POND, 0x00, "Child Fishing", RHT_LH_CHILD_FISHING, RG_PIECE_OF_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_CHILD_FISHING), true); locationTable[RC_LH_CHILD_FISHING] = Location::Base(RC_LH_CHILD_FISHING, RCQUEST_BOTH, RCTYPE_STANDARD, ACTOR_ID_MAX, SCENE_FISHING_POND, 0x00, "Child Fishing", RHT_LH_CHILD_FISHING, RG_PIECE_OF_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_CHILD_FISHING), true);
locationTable[RC_LH_ADULT_FISHING] = Location::Base(RC_LH_ADULT_FISHING, RCQUEST_BOTH, RCTYPE_STANDARD, ACTOR_ID_MAX, SCENE_FISHING_POND, 0x00, "Adult Fishing", RHT_LH_ADULT_FISHING, RG_PROGRESSIVE_SCALE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ADULT_FISHING), true); locationTable[RC_LH_ADULT_FISHING] = Location::Base(RC_LH_ADULT_FISHING, RCQUEST_BOTH, RCTYPE_STANDARD, ACTOR_ID_MAX, SCENE_FISHING_POND, 0x00, "Adult Fishing", RHT_LH_ADULT_FISHING, RG_PROGRESSIVE_SCALE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ADULT_FISHING), true);
@ -165,16 +175,16 @@ void Rando::StaticData::InitLocationTable() { //
locationTable[RC_LH_UNDERWATER_ITEM] = Location::Base(RC_LH_UNDERWATER_ITEM, RCQUEST_BOTH, RCTYPE_STANDARD, ACTOR_ID_MAX, SCENE_LAKE_HYLIA, 0x00, "Underwater Item", RHT_LH_UNDERWATER_ITEM, RG_RUTOS_LETTER, SpoilerCollectionCheck::EventChkInf(0x31), true); locationTable[RC_LH_UNDERWATER_ITEM] = Location::Base(RC_LH_UNDERWATER_ITEM, RCQUEST_BOTH, RCTYPE_STANDARD, ACTOR_ID_MAX, SCENE_LAKE_HYLIA, 0x00, "Underwater Item", RHT_LH_UNDERWATER_ITEM, RG_RUTOS_LETTER, SpoilerCollectionCheck::EventChkInf(0x31), true);
locationTable[RC_LH_SUN] = Location::Base(RC_LH_SUN, RCQUEST_BOTH, RCTYPE_STANDARD, ACTOR_ID_MAX, SCENE_LAKE_HYLIA, 0x00, "Sun", RHT_LH_SUN, RG_FIRE_ARROWS, SpoilerCollectionCheck::Chest(0x57, 0x1F), true); locationTable[RC_LH_SUN] = Location::Base(RC_LH_SUN, RCQUEST_BOTH, RCTYPE_STANDARD, ACTOR_ID_MAX, SCENE_LAKE_HYLIA, 0x00, "Sun", RHT_LH_SUN, RG_FIRE_ARROWS, SpoilerCollectionCheck::Chest(0x57, 0x1F), true);
locationTable[RC_LH_FREESTANDING_POH] = Location::Collectable(RC_LH_FREESTANDING_POH, RCQUEST_BOTH, RCTYPE_STANDARD, ACTOR_EN_ITEM00, SCENE_LAKE_HYLIA, 7686, 0x1E, "Freestanding PoH", RHT_LH_FREESTANDING_POH, RG_PIECE_OF_HEART, true); locationTable[RC_LH_FREESTANDING_POH] = Location::Collectable(RC_LH_FREESTANDING_POH, RCQUEST_BOTH, RCTYPE_STANDARD, ACTOR_EN_ITEM00, SCENE_LAKE_HYLIA, 7686, 0x1E, "Freestanding PoH", RHT_LH_FREESTANDING_POH, RG_PIECE_OF_HEART, true);
locationTable[RC_LH_DEKU_SCRUB_GROTTO_LEFT] = Location::Base(RC_LH_DEKU_SCRUB_GROTTO_LEFT, RCQUEST_BOTH, RCTYPE_SCRUB, RCAREA_LAKE_HYLIA, ACTOR_EN_DNS, SCENE_GROTTOS, TWO_ACTOR_PARAMS(0x00, 0xEF), "Deku Scrub Grotto Left", RHT_LH_DEKU_SCRUB_GROTTO_LEFT, RG_BUY_DEKU_NUTS_5, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SCRUBS_PURCHASED_LH_DEKU_SCRUB_GROTTO_LEFT)); locationTable[RC_LH_DEKU_SCRUB_GROTTO_LEFT] = Location::Base(RC_LH_DEKU_SCRUB_GROTTO_LEFT, RCQUEST_BOTH, RCTYPE_SCRUB, RCAREA_LAKE_HYLIA, ACTOR_EN_DNS, SCENE_GROTTOS, TWO_ACTOR_PARAMS(0x00, 0xEF), "Deku Scrub Grotto Left", RHT_LH_DEKU_SCRUB_GROTTO_LEFT, RG_BUY_DEKU_NUTS_5, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SCRUBS_PURCHASED_LH_DEKU_SCRUB_GROTTO_LEFT), false, 20);
locationTable[RC_LH_DEKU_SCRUB_GROTTO_RIGHT] = Location::Base(RC_LH_DEKU_SCRUB_GROTTO_RIGHT, RCQUEST_BOTH, RCTYPE_SCRUB, RCAREA_LAKE_HYLIA, ACTOR_EN_DNS, SCENE_GROTTOS, TWO_ACTOR_PARAMS(0x05, 0xEF), "Deku Scrub Grotto Right", RHT_LH_DEKU_SCRUB_GROTTO_RIGHT, RG_BUY_BOMBS_535, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SCRUBS_PURCHASED_LH_DEKU_SCRUB_GROTTO_RIGHT)); locationTable[RC_LH_DEKU_SCRUB_GROTTO_RIGHT] = Location::Base(RC_LH_DEKU_SCRUB_GROTTO_RIGHT, RCQUEST_BOTH, RCTYPE_SCRUB, RCAREA_LAKE_HYLIA, ACTOR_EN_DNS, SCENE_GROTTOS, TWO_ACTOR_PARAMS(0x05, 0xEF), "Deku Scrub Grotto Right", RHT_LH_DEKU_SCRUB_GROTTO_RIGHT, RG_BUY_BOMBS_535, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SCRUBS_PURCHASED_LH_DEKU_SCRUB_GROTTO_RIGHT), false, 40);
locationTable[RC_LH_DEKU_SCRUB_GROTTO_CENTER] = Location::Base(RC_LH_DEKU_SCRUB_GROTTO_CENTER, RCQUEST_BOTH, RCTYPE_SCRUB, RCAREA_LAKE_HYLIA, ACTOR_EN_DNS, SCENE_GROTTOS, TWO_ACTOR_PARAMS(0x03, 0xEF), "Deku Scrub Grotto Center", RHT_LH_DEKU_SCRUB_GROTTO_CENTER, RG_BUY_DEKU_SEEDS_30, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SCRUBS_PURCHASED_LH_DEKU_SCRUB_GROTTO_CENTER)); locationTable[RC_LH_DEKU_SCRUB_GROTTO_CENTER] = Location::Base(RC_LH_DEKU_SCRUB_GROTTO_CENTER, RCQUEST_BOTH, RCTYPE_SCRUB, RCAREA_LAKE_HYLIA, ACTOR_EN_DNS, SCENE_GROTTOS, TWO_ACTOR_PARAMS(0x03, 0xEF), "Deku Scrub Grotto Center", RHT_LH_DEKU_SCRUB_GROTTO_CENTER, RG_BUY_DEKU_SEEDS_30, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SCRUBS_PURCHASED_LH_DEKU_SCRUB_GROTTO_CENTER), false, 40);
// Gerudo Valley // Gerudo Valley
locationTable[RC_GV_CHEST] = Location::Chest(RC_GV_CHEST, RCQUEST_BOTH, RCTYPE_STANDARD, ACTOR_EN_BOX, SCENE_GERUDO_VALLEY, 23200, 0x00, "Chest", RHT_GV_CHEST, RG_PURPLE_RUPEE); locationTable[RC_GV_CHEST] = Location::Chest(RC_GV_CHEST, RCQUEST_BOTH, RCTYPE_STANDARD, ACTOR_EN_BOX, SCENE_GERUDO_VALLEY, 23200, 0x00, "Chest", RHT_GV_CHEST, RG_PURPLE_RUPEE);
locationTable[RC_GV_TRADE_SAW] = Location::Base(RC_GV_TRADE_SAW, RCQUEST_BOTH, RCTYPE_ADULT_TRADE, ACTOR_ID_MAX, SCENE_GERUDO_VALLEY, 0x00, "Trade Saw", RHT_GV_TRADE_SAW, RG_BROKEN_SWORD, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ADULT_TRADES_GV_TRADE_SAW), true); locationTable[RC_GV_TRADE_SAW] = Location::Base(RC_GV_TRADE_SAW, RCQUEST_BOTH, RCTYPE_ADULT_TRADE, ACTOR_ID_MAX, SCENE_GERUDO_VALLEY, 0x00, "Trade Saw", RHT_GV_TRADE_SAW, RG_BROKEN_SWORD, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ADULT_TRADES_GV_TRADE_SAW), true);
locationTable[RC_GV_WATERFALL_FREESTANDING_POH] = Location::Collectable(RC_GV_WATERFALL_FREESTANDING_POH, RCQUEST_BOTH, RCTYPE_STANDARD, ACTOR_EN_ITEM00, SCENE_GERUDO_VALLEY, 262, 0x01, "Waterfall Freestanding PoH", RHT_GV_WATERFALL_FREESTANDING_POH, RG_PIECE_OF_HEART, true); locationTable[RC_GV_WATERFALL_FREESTANDING_POH] = Location::Collectable(RC_GV_WATERFALL_FREESTANDING_POH, RCQUEST_BOTH, RCTYPE_STANDARD, ACTOR_EN_ITEM00, SCENE_GERUDO_VALLEY, 262, 0x01, "Waterfall Freestanding PoH", RHT_GV_WATERFALL_FREESTANDING_POH, RG_PIECE_OF_HEART, true);
locationTable[RC_GV_CRATE_FREESTANDING_POH] = Location::Collectable(RC_GV_CRATE_FREESTANDING_POH, RCQUEST_BOTH, RCTYPE_STANDARD, ACTOR_EN_ITEM00, SCENE_GERUDO_VALLEY, 518, 0x02, "Crate Freestanding PoH", RHT_GV_CRATE_FREESTANDING_POH, RG_PIECE_OF_HEART, true); locationTable[RC_GV_CRATE_FREESTANDING_POH] = Location::Collectable(RC_GV_CRATE_FREESTANDING_POH, RCQUEST_BOTH, RCTYPE_STANDARD, ACTOR_EN_ITEM00, SCENE_GERUDO_VALLEY, 518, 0x02, "Crate Freestanding PoH", RHT_GV_CRATE_FREESTANDING_POH, RG_PIECE_OF_HEART, true);
locationTable[RC_GV_DEKU_SCRUB_GROTTO_REAR] = Location::Base(RC_GV_DEKU_SCRUB_GROTTO_REAR, RCQUEST_BOTH, RCTYPE_SCRUB, RCAREA_GERUDO_VALLEY, ACTOR_EN_DNS, SCENE_GROTTOS, TWO_ACTOR_PARAMS(0x07, 0xF0), "Deku Scrub Grotto Rear", RHT_GV_DEKU_SCRUB_GROTTO_FRONT, RG_BUY_GREEN_POTION, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SCRUBS_PURCHASED_GV_DEKU_SCRUB_GROTTO_REAR)); locationTable[RC_GV_DEKU_SCRUB_GROTTO_REAR] = Location::Base(RC_GV_DEKU_SCRUB_GROTTO_REAR, RCQUEST_BOTH, RCTYPE_SCRUB, RCAREA_GERUDO_VALLEY, ACTOR_EN_DNS, SCENE_GROTTOS, TWO_ACTOR_PARAMS(0x07, 0xF0), "Deku Scrub Grotto Rear", RHT_GV_DEKU_SCRUB_GROTTO_REAR, RG_BUY_RED_POTION_40, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SCRUBS_PURCHASED_GV_DEKU_SCRUB_GROTTO_REAR), false, 40);
locationTable[RC_GV_DEKU_SCRUB_GROTTO_FRONT] = Location::Base(RC_GV_DEKU_SCRUB_GROTTO_FRONT, RCQUEST_BOTH, RCTYPE_SCRUB, RCAREA_GERUDO_VALLEY, ACTOR_EN_DNS, SCENE_GROTTOS, TWO_ACTOR_PARAMS(0x08, 0xF0), "Deku Scrub Grotto Front", RHT_GV_DEKU_SCRUB_GROTTO_FRONT, RG_BUY_GREEN_POTION, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SCRUBS_PURCHASED_GV_DEKU_SCRUB_GROTTO_FRONT)); locationTable[RC_GV_DEKU_SCRUB_GROTTO_FRONT] = Location::Base(RC_GV_DEKU_SCRUB_GROTTO_FRONT, RCQUEST_BOTH, RCTYPE_SCRUB, RCAREA_GERUDO_VALLEY, ACTOR_EN_DNS, SCENE_GROTTOS, TWO_ACTOR_PARAMS(0x08, 0xF0), "Deku Scrub Grotto Front", RHT_GV_DEKU_SCRUB_GROTTO_FRONT, RG_BUY_GREEN_POTION, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SCRUBS_PURCHASED_GV_DEKU_SCRUB_GROTTO_FRONT), false, 40);
// Gerudo Fortress // Gerudo Fortress
locationTable[RC_GF_CHEST] = Location::Chest(RC_GF_CHEST, RCQUEST_BOTH, RCTYPE_STANDARD, ACTOR_EN_BOX, SCENE_GERUDOS_FORTRESS, 1984, 0x00, "Chest", RHT_GF_CHEST, RG_PIECE_OF_HEART, true); locationTable[RC_GF_CHEST] = Location::Chest(RC_GF_CHEST, RCQUEST_BOTH, RCTYPE_STANDARD, ACTOR_EN_BOX, SCENE_GERUDOS_FORTRESS, 1984, 0x00, "Chest", RHT_GF_CHEST, RG_PIECE_OF_HEART, true);
locationTable[RC_GF_HBA_1000_POINTS] = Location::Base(RC_GF_HBA_1000_POINTS, RCQUEST_BOTH, RCTYPE_STANDARD, ACTOR_ID_MAX, SCENE_GERUDOS_FORTRESS, 0x00, "GF HBA 1000 Points", RHT_GF_HBA_1000_POINTS, RG_PIECE_OF_HEART, SpoilerCollectionCheck::InfTable(INFTABLE_190), true); locationTable[RC_GF_HBA_1000_POINTS] = Location::Base(RC_GF_HBA_1000_POINTS, RCQUEST_BOTH, RCTYPE_STANDARD, ACTOR_ID_MAX, SCENE_GERUDOS_FORTRESS, 0x00, "GF HBA 1000 Points", RHT_GF_HBA_1000_POINTS, RG_PIECE_OF_HEART, SpoilerCollectionCheck::InfTable(INFTABLE_190), true);
@ -190,8 +200,8 @@ void Rando::StaticData::InitLocationTable() { //
locationTable[RC_WASTELAND_BOMBCHU_SALESMAN] = Location::Base(RC_WASTELAND_BOMBCHU_SALESMAN, RCQUEST_BOTH, RCTYPE_MERCHANT, RCAREA_WASTELAND, ACTOR_ID_MAX, SCENE_HAUNTED_WASTELAND, 0x00, "Carpet Salesman", RHT_WASTELAND_BOMBCHU_SALESMAN, RG_BUY_BOMBCHUS_10, SpoilerCollectionCheck::RandomizerInf(RAND_INF_MERCHANTS_CARPET_SALESMAN)); locationTable[RC_WASTELAND_BOMBCHU_SALESMAN] = Location::Base(RC_WASTELAND_BOMBCHU_SALESMAN, RCQUEST_BOTH, RCTYPE_MERCHANT, RCAREA_WASTELAND, ACTOR_ID_MAX, SCENE_HAUNTED_WASTELAND, 0x00, "Carpet Salesman", RHT_WASTELAND_BOMBCHU_SALESMAN, RG_BUY_BOMBCHUS_10, SpoilerCollectionCheck::RandomizerInf(RAND_INF_MERCHANTS_CARPET_SALESMAN));
// Desert Colossus // Desert Colossus
locationTable[RC_COLOSSUS_FREESTANDING_POH] = Location::Collectable(RC_COLOSSUS_FREESTANDING_POH, RCQUEST_BOTH, RCTYPE_STANDARD, ACTOR_EN_ITEM00, SCENE_DESERT_COLOSSUS, 3334, 0x0D, "Freestanding PoH", RHT_COLOSSUS_FREESTANDING_POH, RG_PIECE_OF_HEART, true); locationTable[RC_COLOSSUS_FREESTANDING_POH] = Location::Collectable(RC_COLOSSUS_FREESTANDING_POH, RCQUEST_BOTH, RCTYPE_STANDARD, ACTOR_EN_ITEM00, SCENE_DESERT_COLOSSUS, 3334, 0x0D, "Freestanding PoH", RHT_COLOSSUS_FREESTANDING_POH, RG_PIECE_OF_HEART, true);
locationTable[RC_COLOSSUS_DEKU_SCRUB_GROTTO_REAR] = Location::Base(RC_COLOSSUS_DEKU_SCRUB_GROTTO_REAR, RCQUEST_BOTH, RCTYPE_SCRUB, RCAREA_DESERT_COLOSSUS, ACTOR_EN_DNS, SCENE_GROTTOS, TWO_ACTOR_PARAMS(0x07, 0xFD), "Deku Scrub Grotto Rear", RHT_COLOSSUS_DEKU_SCRUB_GROTTO_REAR, RG_BUY_RED_POTION_30, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SCRUBS_PURCHASED_COLOSSUS_DEKU_SCRUB_GROTTO_REAR)); locationTable[RC_COLOSSUS_DEKU_SCRUB_GROTTO_REAR] = Location::Base(RC_COLOSSUS_DEKU_SCRUB_GROTTO_REAR, RCQUEST_BOTH, RCTYPE_SCRUB, RCAREA_DESERT_COLOSSUS, ACTOR_EN_DNS, SCENE_GROTTOS, TWO_ACTOR_PARAMS(0x07, 0xFD), "Deku Scrub Grotto Rear", RHT_COLOSSUS_DEKU_SCRUB_GROTTO_REAR, RG_BUY_RED_POTION_40, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SCRUBS_PURCHASED_COLOSSUS_DEKU_SCRUB_GROTTO_REAR), false, 40);
locationTable[RC_COLOSSUS_DEKU_SCRUB_GROTTO_FRONT] = Location::Base(RC_COLOSSUS_DEKU_SCRUB_GROTTO_FRONT, RCQUEST_BOTH, RCTYPE_SCRUB, RCAREA_DESERT_COLOSSUS, ACTOR_EN_DNS, SCENE_GROTTOS, TWO_ACTOR_PARAMS(0x08, 0xFD), "Deku Scrub Grotto Front", RHT_COLOSSUS_DEKU_SCRUB_GROTTO_FRONT, RG_BUY_GREEN_POTION, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SCRUBS_PURCHASED_COLOSSUS_DEKU_SCRUB_GROTTO_FRONT)); locationTable[RC_COLOSSUS_DEKU_SCRUB_GROTTO_FRONT] = Location::Base(RC_COLOSSUS_DEKU_SCRUB_GROTTO_FRONT, RCQUEST_BOTH, RCTYPE_SCRUB, RCAREA_DESERT_COLOSSUS, ACTOR_EN_DNS, SCENE_GROTTOS, TWO_ACTOR_PARAMS(0x08, 0xFD), "Deku Scrub Grotto Front", RHT_COLOSSUS_DEKU_SCRUB_GROTTO_FRONT, RG_BUY_GREEN_POTION, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SCRUBS_PURCHASED_COLOSSUS_DEKU_SCRUB_GROTTO_FRONT), false, 40);
// Market // Market
locationTable[RC_MARKET_TREASURE_CHEST_GAME_REWARD] = Location::Chest(RC_MARKET_TREASURE_CHEST_GAME_REWARD, RCQUEST_BOTH, RCTYPE_STANDARD, ACTOR_EN_BOX, SCENE_TREASURE_BOX_SHOP, 0x00, "Treasure Chest Game Reward", RHT_MARKET_TREASURE_CHEST_GAME_REWARD, RG_TREASURE_GAME_HEART, SpoilerCollectionCheck::ItemGetInf(27), true); locationTable[RC_MARKET_TREASURE_CHEST_GAME_REWARD] = Location::Chest(RC_MARKET_TREASURE_CHEST_GAME_REWARD, RCQUEST_BOTH, RCTYPE_STANDARD, ACTOR_EN_BOX, SCENE_TREASURE_BOX_SHOP, 0x00, "Treasure Chest Game Reward", RHT_MARKET_TREASURE_CHEST_GAME_REWARD, RG_TREASURE_GAME_HEART, SpoilerCollectionCheck::ItemGetInf(27), true);
locationTable[RC_MARKET_BOMBCHU_BOWLING_FIRST_PRIZE] = Location::Base(RC_MARKET_BOMBCHU_BOWLING_FIRST_PRIZE, RCQUEST_BOTH, RCTYPE_STANDARD, ACTOR_ID_MAX, SCENE_BOMBCHU_BOWLING_ALLEY, 0x00, "Bombchu Bowling First Prize", RHT_MARKET_BOMBCHU_BOWLING_FIRST_PRIZE, RG_PROGRESSIVE_BOMB_BAG, SpoilerCollectionCheck::ItemGetInf(17), true); locationTable[RC_MARKET_BOMBCHU_BOWLING_FIRST_PRIZE] = Location::Base(RC_MARKET_BOMBCHU_BOWLING_FIRST_PRIZE, RCQUEST_BOTH, RCTYPE_STANDARD, ACTOR_ID_MAX, SCENE_BOMBCHU_BOWLING_ALLEY, 0x00, "Bombchu Bowling First Prize", RHT_MARKET_BOMBCHU_BOWLING_FIRST_PRIZE, RG_PROGRESSIVE_BOMB_BAG, SpoilerCollectionCheck::ItemGetInf(17), true);
@ -224,7 +234,7 @@ void Rando::StaticData::InitLocationTable() { //
locationTable[RC_KAK_MAN_ON_ROOF] = Location::Base(RC_KAK_MAN_ON_ROOF, RCQUEST_BOTH, RCTYPE_STANDARD, ACTOR_ID_MAX, SCENE_KAKARIKO_VILLAGE, 0x00, "Man on Roof", RHT_KAK_MAN_ON_ROOF, RG_PIECE_OF_HEART, SpoilerCollectionCheck::ItemGetInf(21), true); locationTable[RC_KAK_MAN_ON_ROOF] = Location::Base(RC_KAK_MAN_ON_ROOF, RCQUEST_BOTH, RCTYPE_STANDARD, ACTOR_ID_MAX, SCENE_KAKARIKO_VILLAGE, 0x00, "Man on Roof", RHT_KAK_MAN_ON_ROOF, RG_PIECE_OF_HEART, SpoilerCollectionCheck::ItemGetInf(21), true);
locationTable[RC_KAK_SHOOTING_GALLERY_REWARD] = Location::Base(RC_KAK_SHOOTING_GALLERY_REWARD, RCQUEST_BOTH, RCTYPE_STANDARD, RCAREA_KAKARIKO_VILLAGE, ACTOR_ID_MAX, SCENE_SHOOTING_GALLERY, 0x00, "Shooting Gallery Reward", RHT_KAK_SHOOTING_GALLERY_REWARD, RG_PROGRESSIVE_BOW, SpoilerCollectionCheck::ItemGetInf(ITEMGETINF_0E), true); locationTable[RC_KAK_SHOOTING_GALLERY_REWARD] = Location::Base(RC_KAK_SHOOTING_GALLERY_REWARD, RCQUEST_BOTH, RCTYPE_STANDARD, RCAREA_KAKARIKO_VILLAGE, ACTOR_ID_MAX, SCENE_SHOOTING_GALLERY, 0x00, "Shooting Gallery Reward", RHT_KAK_SHOOTING_GALLERY_REWARD, RG_PROGRESSIVE_BOW, SpoilerCollectionCheck::ItemGetInf(ITEMGETINF_0E), true);
locationTable[RC_KAK_TRADE_ODD_MUSHROOM] = Location::Base(RC_KAK_TRADE_ODD_MUSHROOM, RCQUEST_BOTH, RCTYPE_ADULT_TRADE, ACTOR_ID_MAX, SCENE_POTION_SHOP_GRANNY, 0x00, "Trade Odd Mushroom", RHT_KAK_TRADE_ODD_MUSHROOM, RG_ODD_POTION, SpoilerCollectionCheck::ItemGetInf(48), true); locationTable[RC_KAK_TRADE_ODD_MUSHROOM] = Location::Base(RC_KAK_TRADE_ODD_MUSHROOM, RCQUEST_BOTH, RCTYPE_ADULT_TRADE, ACTOR_ID_MAX, SCENE_POTION_SHOP_GRANNY, 0x00, "Trade Odd Mushroom", RHT_KAK_TRADE_ODD_MUSHROOM, RG_ODD_POTION, SpoilerCollectionCheck::ItemGetInf(48), true);
locationTable[RC_KAK_GRANNYS_SHOP] = Location::Base(RC_KAK_GRANNYS_SHOP, RCQUEST_BOTH, RCTYPE_MERCHANT, ACTOR_ID_MAX, SCENE_POTION_SHOP_GRANNY, 0x00, "Granny's Shop", RHT_KAK_GRANNYS_SHOP, RG_BUY_BLUE_POTION, SpoilerCollectionCheck::RandomizerInf(RAND_INF_MERCHANTS_GRANNYS_SHOP), true); locationTable[RC_KAK_GRANNYS_SHOP] = Location::Base(RC_KAK_GRANNYS_SHOP, RCQUEST_BOTH, RCTYPE_MERCHANT, ACTOR_ID_MAX, SCENE_POTION_SHOP_GRANNY, 0x00, "Granny's Shop", RHT_KAK_GRANNYS_SHOP, RG_BUY_BLUE_POTION, SpoilerCollectionCheck::RandomizerInf(RAND_INF_MERCHANTS_GRANNYS_SHOP), true, 100);
locationTable[RC_KAK_ANJU_AS_ADULT] = Location::Base(RC_KAK_ANJU_AS_ADULT, RCQUEST_BOTH, RCTYPE_STANDARD, ACTOR_ID_MAX, SCENE_KAKARIKO_VILLAGE, 0x00, "Anju as Adult", RHT_KAK_ANJU_AS_ADULT, RG_CLAIM_CHECK, SpoilerCollectionCheck::ItemGetInf(44), true); locationTable[RC_KAK_ANJU_AS_ADULT] = Location::Base(RC_KAK_ANJU_AS_ADULT, RCQUEST_BOTH, RCTYPE_STANDARD, ACTOR_ID_MAX, SCENE_KAKARIKO_VILLAGE, 0x00, "Anju as Adult", RHT_KAK_ANJU_AS_ADULT, RG_CLAIM_CHECK, SpoilerCollectionCheck::ItemGetInf(44), true);
locationTable[RC_KAK_ANJU_AS_CHILD] = Location::Base(RC_KAK_ANJU_AS_CHILD, RCQUEST_BOTH, RCTYPE_STANDARD, ACTOR_ID_MAX, SCENE_KAKARIKO_VILLAGE, 0x00, "Anju as Child", RHT_KAK_ANJU_AS_CHILD, RG_EMPTY_BOTTLE, SpoilerCollectionCheck::ItemGetInf(12), true); locationTable[RC_KAK_ANJU_AS_CHILD] = Location::Base(RC_KAK_ANJU_AS_CHILD, RCQUEST_BOTH, RCTYPE_STANDARD, ACTOR_ID_MAX, SCENE_KAKARIKO_VILLAGE, 0x00, "Anju as Child", RHT_KAK_ANJU_AS_CHILD, RG_EMPTY_BOTTLE, SpoilerCollectionCheck::ItemGetInf(12), true);
locationTable[RC_KAK_TRADE_POCKET_CUCCO] = Location::Base(RC_KAK_TRADE_POCKET_CUCCO, RCQUEST_BOTH, RCTYPE_ADULT_TRADE, ACTOR_ID_MAX, SCENE_KAKARIKO_VILLAGE, 0x00, "Trade Pocket Cucco", RHT_KAK_TRADE_POCKET_CUCCO, RG_COJIRO, SpoilerCollectionCheck::ItemGetInf(46), true); locationTable[RC_KAK_TRADE_POCKET_CUCCO] = Location::Base(RC_KAK_TRADE_POCKET_CUCCO, RCQUEST_BOTH, RCTYPE_ADULT_TRADE, ACTOR_ID_MAX, SCENE_KAKARIKO_VILLAGE, 0x00, "Trade Pocket Cucco", RHT_KAK_TRADE_POCKET_CUCCO, RG_COJIRO, SpoilerCollectionCheck::ItemGetInf(46), true);
@ -253,21 +263,21 @@ void Rando::StaticData::InitLocationTable() { //
locationTable[RC_GC_ROLLING_GORON_AS_ADULT] = Location::Base(RC_GC_ROLLING_GORON_AS_ADULT, RCQUEST_BOTH, RCTYPE_STANDARD, ACTOR_ID_MAX, SCENE_GORON_CITY, 0x00, "Rolling Goron as Adult", RHT_GC_ROLLING_GORON_AS_ADULT, RG_GORON_TUNIC, SpoilerCollectionCheck::InfTable(INFTABLE_GORON_CITY_DOORS_UNLOCKED), true); locationTable[RC_GC_ROLLING_GORON_AS_ADULT] = Location::Base(RC_GC_ROLLING_GORON_AS_ADULT, RCQUEST_BOTH, RCTYPE_STANDARD, ACTOR_ID_MAX, SCENE_GORON_CITY, 0x00, "Rolling Goron as Adult", RHT_GC_ROLLING_GORON_AS_ADULT, RG_GORON_TUNIC, SpoilerCollectionCheck::InfTable(INFTABLE_GORON_CITY_DOORS_UNLOCKED), true);
locationTable[RC_GC_DARUNIAS_JOY] = Location::Base(RC_GC_DARUNIAS_JOY, RCQUEST_BOTH, RCTYPE_STANDARD, ACTOR_ID_MAX, SCENE_GORON_CITY, 0x00, "Darunias Joy", RHT_GC_DARUNIAS_JOY, RG_PROGRESSIVE_STRENGTH, SpoilerCollectionCheck::RandomizerInf(RAND_INF_DARUNIAS_JOY), true); locationTable[RC_GC_DARUNIAS_JOY] = Location::Base(RC_GC_DARUNIAS_JOY, RCQUEST_BOTH, RCTYPE_STANDARD, ACTOR_ID_MAX, SCENE_GORON_CITY, 0x00, "Darunias Joy", RHT_GC_DARUNIAS_JOY, RG_PROGRESSIVE_STRENGTH, SpoilerCollectionCheck::RandomizerInf(RAND_INF_DARUNIAS_JOY), true);
locationTable[RC_GC_POT_FREESTANDING_POH] = Location::Collectable(RC_GC_POT_FREESTANDING_POH, RCQUEST_BOTH, RCTYPE_STANDARD, ACTOR_EN_ITEM00, SCENE_GORON_CITY, 7942, 0x1F, "Pot Freestanding PoH", RHT_GC_POT_FREESTANDING_POH, RG_PIECE_OF_HEART, true); locationTable[RC_GC_POT_FREESTANDING_POH] = Location::Collectable(RC_GC_POT_FREESTANDING_POH, RCQUEST_BOTH, RCTYPE_STANDARD, ACTOR_EN_ITEM00, SCENE_GORON_CITY, 7942, 0x1F, "Pot Freestanding PoH", RHT_GC_POT_FREESTANDING_POH, RG_PIECE_OF_HEART, true);
locationTable[RC_GC_DEKU_SCRUB_GROTTO_LEFT] = Location::Base(RC_GC_DEKU_SCRUB_GROTTO_LEFT, RCQUEST_BOTH, RCTYPE_SCRUB, RCAREA_GORON_CITY, ACTOR_EN_DNS, SCENE_GROTTOS, TWO_ACTOR_PARAMS(0x00, 0xFB), "Deku Scrub Grotto Left", RHT_GC_DEKU_SCRUB_GROTTO_LEFT, RG_BUY_DEKU_NUTS_5, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SCRUBS_PURCHASED_GC_DEKU_SCRUB_GROTTO_LEFT)); locationTable[RC_GC_DEKU_SCRUB_GROTTO_LEFT] = Location::Base(RC_GC_DEKU_SCRUB_GROTTO_LEFT, RCQUEST_BOTH, RCTYPE_SCRUB, RCAREA_GORON_CITY, ACTOR_EN_DNS, SCENE_GROTTOS, TWO_ACTOR_PARAMS(0x00, 0xFB), "Deku Scrub Grotto Left", RHT_GC_DEKU_SCRUB_GROTTO_LEFT, RG_BUY_DEKU_NUTS_5, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SCRUBS_PURCHASED_GC_DEKU_SCRUB_GROTTO_LEFT), false, 20);
locationTable[RC_GC_DEKU_SCRUB_GROTTO_RIGHT] = Location::Base(RC_GC_DEKU_SCRUB_GROTTO_RIGHT, RCQUEST_BOTH, RCTYPE_SCRUB, RCAREA_GORON_CITY, ACTOR_EN_DNS, SCENE_GROTTOS, TWO_ACTOR_PARAMS(0x05, 0xFB), "Deku Scrub Grotto Right", RHT_GC_DEKU_SCRUB_GROTTO_RIGHT, RG_BUY_BOMBS_535, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SCRUBS_PURCHASED_GC_DEKU_SCRUB_GROTTO_RIGHT)); locationTable[RC_GC_DEKU_SCRUB_GROTTO_RIGHT] = Location::Base(RC_GC_DEKU_SCRUB_GROTTO_RIGHT, RCQUEST_BOTH, RCTYPE_SCRUB, RCAREA_GORON_CITY, ACTOR_EN_DNS, SCENE_GROTTOS, TWO_ACTOR_PARAMS(0x05, 0xFB), "Deku Scrub Grotto Right", RHT_GC_DEKU_SCRUB_GROTTO_RIGHT, RG_BUY_BOMBS_535, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SCRUBS_PURCHASED_GC_DEKU_SCRUB_GROTTO_RIGHT), false, 40);
locationTable[RC_GC_DEKU_SCRUB_GROTTO_CENTER] = Location::Base(RC_GC_DEKU_SCRUB_GROTTO_CENTER, RCQUEST_BOTH, RCTYPE_SCRUB, RCAREA_GORON_CITY, ACTOR_EN_DNS, SCENE_GROTTOS, TWO_ACTOR_PARAMS(0x03, 0xFB), "Deku Scrub Grotto Center", RHT_GC_DEKU_SCRUB_GROTTO_CENTER, RG_BUY_ARROWS_30, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SCRUBS_PURCHASED_GC_DEKU_SCRUB_GROTTO_CENTER)); locationTable[RC_GC_DEKU_SCRUB_GROTTO_CENTER] = Location::Base(RC_GC_DEKU_SCRUB_GROTTO_CENTER, RCQUEST_BOTH, RCTYPE_SCRUB, RCAREA_GORON_CITY, ACTOR_EN_DNS, SCENE_GROTTOS, TWO_ACTOR_PARAMS(0x03, 0xFB), "Deku Scrub Grotto Center", RHT_GC_DEKU_SCRUB_GROTTO_CENTER, RG_BUY_ARROWS_30, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SCRUBS_PURCHASED_GC_DEKU_SCRUB_GROTTO_CENTER), false, 70);
locationTable[RC_GC_MEDIGORON] = Location::Base(RC_GC_MEDIGORON, RCQUEST_BOTH, RCTYPE_MERCHANT, ACTOR_ID_MAX, SCENE_GORON_CITY, 0x00, "Medigoron", RHT_GC_MEDIGORON, RG_GIANTS_KNIFE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_MERCHANTS_MEDIGORON)); locationTable[RC_GC_MEDIGORON] = Location::Base(RC_GC_MEDIGORON, RCQUEST_BOTH, RCTYPE_MERCHANT, ACTOR_ID_MAX, SCENE_GORON_CITY, 0x00, "Medigoron", RHT_GC_MEDIGORON, RG_GIANTS_KNIFE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_MERCHANTS_MEDIGORON), false, 200);
// Death Mountain Crater // Death Mountain Crater
locationTable[RC_DMC_UPPER_GROTTO_CHEST] = Location::Chest(RC_DMC_UPPER_GROTTO_CHEST, RCQUEST_BOTH, RCTYPE_STANDARD, RCAREA_DEATH_MOUNTAIN_CRATER, ACTOR_EN_BOX, SCENE_GROTTOS, 23802, 0x1A, "Upper Grotto Chest", RHT_DMC_UPPER_GROTTO_CHEST, RG_BOMBS_20); locationTable[RC_DMC_UPPER_GROTTO_CHEST] = Location::Chest(RC_DMC_UPPER_GROTTO_CHEST, RCQUEST_BOTH, RCTYPE_STANDARD, RCAREA_DEATH_MOUNTAIN_CRATER, ACTOR_EN_BOX, SCENE_GROTTOS, 23802, 0x1A, "Upper Grotto Chest", RHT_DMC_UPPER_GROTTO_CHEST, RG_BOMBS_20);
locationTable[RC_DMC_WALL_FREESTANDING_POH] = Location::Collectable(RC_DMC_WALL_FREESTANDING_POH, RCQUEST_BOTH, RCTYPE_STANDARD, ACTOR_EN_ITEM00, SCENE_DEATH_MOUNTAIN_CRATER, 518, 0x02, "Wall Freestanding PoH", RHT_DMC_WALL_FREESTANDING_POH, RG_PIECE_OF_HEART, true); locationTable[RC_DMC_WALL_FREESTANDING_POH] = Location::Collectable(RC_DMC_WALL_FREESTANDING_POH, RCQUEST_BOTH, RCTYPE_STANDARD, ACTOR_EN_ITEM00, SCENE_DEATH_MOUNTAIN_CRATER, 518, 0x02, "Wall Freestanding PoH", RHT_DMC_WALL_FREESTANDING_POH, RG_PIECE_OF_HEART, true);
locationTable[RC_DMC_VOLCANO_FREESTANDING_POH] = Location::Collectable(RC_DMC_VOLCANO_FREESTANDING_POH, RCQUEST_BOTH, RCTYPE_STANDARD, ACTOR_EN_ITEM00, SCENE_DEATH_MOUNTAIN_CRATER, 2054, 0x08, "Volcano Freestanding PoH", RHT_DMC_WALL_FREESTANDING_POH, RG_PIECE_OF_HEART, true); locationTable[RC_DMC_VOLCANO_FREESTANDING_POH] = Location::Collectable(RC_DMC_VOLCANO_FREESTANDING_POH, RCQUEST_BOTH, RCTYPE_STANDARD, ACTOR_EN_ITEM00, SCENE_DEATH_MOUNTAIN_CRATER, 2054, 0x08, "Volcano Freestanding PoH", RHT_DMC_WALL_FREESTANDING_POH, RG_PIECE_OF_HEART, true);
locationTable[RC_DMC_DEKU_SCRUB] = Location::Base(RC_DMC_DEKU_SCRUB, RCQUEST_BOTH, RCTYPE_SCRUB, ACTOR_EN_DNS, SCENE_DEATH_MOUNTAIN_CRATER, 0x05, "Deku Scrub", RHT_DMC_DEKU_SCRUB, RG_BUY_BOMBS_535, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SCRUBS_PURCHASED_DMC_DEKU_SCRUB)); locationTable[RC_DMC_DEKU_SCRUB] = Location::Base(RC_DMC_DEKU_SCRUB, RCQUEST_BOTH, RCTYPE_SCRUB, ACTOR_EN_DNS, SCENE_DEATH_MOUNTAIN_CRATER, 0x05, "Deku Scrub", RHT_DMC_DEKU_SCRUB, RG_BUY_BOMBS_535, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SCRUBS_PURCHASED_DMC_DEKU_SCRUB), false, 40);
locationTable[RC_DMC_DEKU_SCRUB_GROTTO_LEFT] = Location::Base(RC_DMC_DEKU_SCRUB_GROTTO_LEFT, RCQUEST_BOTH, RCTYPE_SCRUB, RCAREA_DEATH_MOUNTAIN_CRATER, ACTOR_EN_DNS, SCENE_GROTTOS, TWO_ACTOR_PARAMS(0x00, 0xF9), "Deku Scrub Grotto Left", RHT_DMC_DEKU_SCRUB_GROTTO_LEFT, RG_BUY_DEKU_NUTS_5, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SCRUBS_PURCHASED_DMC_DEKU_SCRUB_GROTTO_LEFT)); locationTable[RC_DMC_DEKU_SCRUB_GROTTO_LEFT] = Location::Base(RC_DMC_DEKU_SCRUB_GROTTO_LEFT, RCQUEST_BOTH, RCTYPE_SCRUB, RCAREA_DEATH_MOUNTAIN_CRATER, ACTOR_EN_DNS, SCENE_GROTTOS, TWO_ACTOR_PARAMS(0x00, 0xF9), "Deku Scrub Grotto Left", RHT_DMC_DEKU_SCRUB_GROTTO_LEFT, RG_BUY_DEKU_NUTS_5, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SCRUBS_PURCHASED_DMC_DEKU_SCRUB_GROTTO_LEFT), false, 20);
locationTable[RC_DMC_DEKU_SCRUB_GROTTO_RIGHT] = Location::Base(RC_DMC_DEKU_SCRUB_GROTTO_RIGHT, RCQUEST_BOTH, RCTYPE_SCRUB, RCAREA_DEATH_MOUNTAIN_CRATER, ACTOR_EN_DNS, SCENE_GROTTOS, TWO_ACTOR_PARAMS(0x05, 0xF9), "Deku Scrub Grotto Right", RHT_DMC_DEKU_SCRUB_GROTTO_RIGHT, RG_BUY_BOMBS_535, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SCRUBS_PURCHASED_DMC_DEKU_SCRUB_GROTTO_RIGHT)); locationTable[RC_DMC_DEKU_SCRUB_GROTTO_RIGHT] = Location::Base(RC_DMC_DEKU_SCRUB_GROTTO_RIGHT, RCQUEST_BOTH, RCTYPE_SCRUB, RCAREA_DEATH_MOUNTAIN_CRATER, ACTOR_EN_DNS, SCENE_GROTTOS, TWO_ACTOR_PARAMS(0x05, 0xF9), "Deku Scrub Grotto Right", RHT_DMC_DEKU_SCRUB_GROTTO_RIGHT, RG_BUY_BOMBS_535, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SCRUBS_PURCHASED_DMC_DEKU_SCRUB_GROTTO_RIGHT), false, 40);
locationTable[RC_DMC_DEKU_SCRUB_GROTTO_CENTER] = Location::Base(RC_DMC_DEKU_SCRUB_GROTTO_CENTER, RCQUEST_BOTH, RCTYPE_SCRUB, RCAREA_DEATH_MOUNTAIN_CRATER, ACTOR_EN_DNS, SCENE_GROTTOS, TWO_ACTOR_PARAMS(0x03, 0xF9), "Deku Scrub Grotto Center", RHT_DMC_DEKU_SCRUB_GROTTO_CENTER, RG_BUY_ARROWS_30, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SCRUBS_PURCHASED_DMC_DEKU_SCRUB_GROTTO_CENTER)); locationTable[RC_DMC_DEKU_SCRUB_GROTTO_CENTER] = Location::Base(RC_DMC_DEKU_SCRUB_GROTTO_CENTER, RCQUEST_BOTH, RCTYPE_SCRUB, RCAREA_DEATH_MOUNTAIN_CRATER, ACTOR_EN_DNS, SCENE_GROTTOS, TWO_ACTOR_PARAMS(0x03, 0xF9), "Deku Scrub Grotto Center", RHT_DMC_DEKU_SCRUB_GROTTO_CENTER, RG_BUY_ARROWS_30, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SCRUBS_PURCHASED_DMC_DEKU_SCRUB_GROTTO_CENTER), false, 70);
// Zoras River // Zoras River
locationTable[RC_ZR_OPEN_GROTTO_CHEST] = Location::Chest(RC_ZR_OPEN_GROTTO_CHEST, RCQUEST_BOTH, RCTYPE_STANDARD, RCAREA_ZORAS_RIVER, ACTOR_EN_BOX, SCENE_GROTTOS, 22985, 0x09, "Open Grotto Chest", RHT_ZR_OPEN_GROTTO_CHEST, RG_RED_RUPEE); locationTable[RC_ZR_OPEN_GROTTO_CHEST] = Location::Chest(RC_ZR_OPEN_GROTTO_CHEST, RCQUEST_BOTH, RCTYPE_STANDARD, RCAREA_ZORAS_RIVER, ACTOR_EN_BOX, SCENE_GROTTOS, 22985, 0x09, "Open Grotto Chest", RHT_ZR_OPEN_GROTTO_CHEST, RG_RED_RUPEE);
locationTable[RC_ZR_MAGIC_BEAN_SALESMAN] = Location::Base(RC_ZR_MAGIC_BEAN_SALESMAN, RCQUEST_BOTH, RCTYPE_STANDARD, ACTOR_ID_MAX, SCENE_ZORAS_RIVER, 0x00, "Magic Bean Salesman", RHT_ZR_MAGIC_BEAN_SALESMAN, RG_MAGIC_BEAN, SpoilerCollectionCheck::RandomizerInf(RAND_INF_MERCHANTS_MAGIC_BEAN_SALESMAN), true); locationTable[RC_ZR_MAGIC_BEAN_SALESMAN] = Location::Base(RC_ZR_MAGIC_BEAN_SALESMAN, RCQUEST_BOTH, RCTYPE_STANDARD, ACTOR_ID_MAX, SCENE_ZORAS_RIVER, 0x00, "Magic Bean Salesman", RHT_ZR_MAGIC_BEAN_SALESMAN, RG_MAGIC_BEAN, SpoilerCollectionCheck::RandomizerInf(RAND_INF_MERCHANTS_MAGIC_BEAN_SALESMAN), true, 60);
locationTable[RC_ZR_FROGS_ZELDAS_LULLABY] = Location::Base(RC_ZR_FROGS_ZELDAS_LULLABY, RCQUEST_BOTH, RCTYPE_FROG_SONG, ACTOR_EN_FR, SCENE_ZORAS_RIVER, 0x00, "Frogs Zelda's Lullaby", RHT_ZR_FROGS_ZELDAS_LULLABY, RG_PURPLE_RUPEE, SpoilerCollectionCheck::EventChkInf(0xD1)); locationTable[RC_ZR_FROGS_ZELDAS_LULLABY] = Location::Base(RC_ZR_FROGS_ZELDAS_LULLABY, RCQUEST_BOTH, RCTYPE_FROG_SONG, ACTOR_EN_FR, SCENE_ZORAS_RIVER, 0x00, "Frogs Zelda's Lullaby", RHT_ZR_FROGS_ZELDAS_LULLABY, RG_PURPLE_RUPEE, SpoilerCollectionCheck::EventChkInf(0xD1));
locationTable[RC_ZR_FROGS_EPONAS_SONG] = Location::Base(RC_ZR_FROGS_EPONAS_SONG, RCQUEST_BOTH, RCTYPE_FROG_SONG, ACTOR_EN_FR, SCENE_ZORAS_RIVER, 0x00, "Frogs Epona's Song", RHT_ZR_FROGS_EPONAS_SONG, RG_PURPLE_RUPEE, SpoilerCollectionCheck::EventChkInf(0xD2)); locationTable[RC_ZR_FROGS_EPONAS_SONG] = Location::Base(RC_ZR_FROGS_EPONAS_SONG, RCQUEST_BOTH, RCTYPE_FROG_SONG, ACTOR_EN_FR, SCENE_ZORAS_RIVER, 0x00, "Frogs Epona's Song", RHT_ZR_FROGS_EPONAS_SONG, RG_PURPLE_RUPEE, SpoilerCollectionCheck::EventChkInf(0xD2));
locationTable[RC_ZR_FROGS_SARIAS_SONG] = Location::Base(RC_ZR_FROGS_SARIAS_SONG, RCQUEST_BOTH, RCTYPE_FROG_SONG, ACTOR_EN_FR, SCENE_ZORAS_RIVER, 0x00, "Frogs Saria's Song", RHT_ZR_FROGS_SARIAS_SONG, RG_PURPLE_RUPEE, SpoilerCollectionCheck::EventChkInf(0xD4)); locationTable[RC_ZR_FROGS_SARIAS_SONG] = Location::Base(RC_ZR_FROGS_SARIAS_SONG, RCQUEST_BOTH, RCTYPE_FROG_SONG, ACTOR_EN_FR, SCENE_ZORAS_RIVER, 0x00, "Frogs Saria's Song", RHT_ZR_FROGS_SARIAS_SONG, RG_PURPLE_RUPEE, SpoilerCollectionCheck::EventChkInf(0xD4));
@ -277,8 +287,8 @@ void Rando::StaticData::InitLocationTable() { //
locationTable[RC_ZR_FROGS_OCARINA_GAME] = Location::Base(RC_ZR_FROGS_OCARINA_GAME, RCQUEST_BOTH, RCTYPE_STANDARD, ACTOR_EN_FR, SCENE_ZORAS_RIVER, 0x00, "Frogs Ocarina Game", RHT_ZR_FROGS_OCARINA_GAME, RG_PIECE_OF_HEART, SpoilerCollectionCheck::EventChkInf(0xD0), true); locationTable[RC_ZR_FROGS_OCARINA_GAME] = Location::Base(RC_ZR_FROGS_OCARINA_GAME, RCQUEST_BOTH, RCTYPE_STANDARD, ACTOR_EN_FR, SCENE_ZORAS_RIVER, 0x00, "Frogs Ocarina Game", RHT_ZR_FROGS_OCARINA_GAME, RG_PIECE_OF_HEART, SpoilerCollectionCheck::EventChkInf(0xD0), true);
locationTable[RC_ZR_NEAR_OPEN_GROTTO_FREESTANDING_POH] = Location::Collectable(RC_ZR_NEAR_OPEN_GROTTO_FREESTANDING_POH, RCQUEST_BOTH, RCTYPE_STANDARD, ACTOR_EN_ITEM00, SCENE_ZORAS_RIVER, 1030, 0x04, "Near Open Grotto Freestanding PoH", RHT_ZR_NEAR_OPEN_GROTTO_FREESTANDING_POH, RG_PIECE_OF_HEART, true); locationTable[RC_ZR_NEAR_OPEN_GROTTO_FREESTANDING_POH] = Location::Collectable(RC_ZR_NEAR_OPEN_GROTTO_FREESTANDING_POH, RCQUEST_BOTH, RCTYPE_STANDARD, ACTOR_EN_ITEM00, SCENE_ZORAS_RIVER, 1030, 0x04, "Near Open Grotto Freestanding PoH", RHT_ZR_NEAR_OPEN_GROTTO_FREESTANDING_POH, RG_PIECE_OF_HEART, true);
locationTable[RC_ZR_NEAR_DOMAIN_FREESTANDING_POH] = Location::Collectable(RC_ZR_NEAR_DOMAIN_FREESTANDING_POH, RCQUEST_BOTH, RCTYPE_STANDARD, ACTOR_EN_ITEM00, SCENE_ZORAS_RIVER, 2822, 0x0B, "Near Domain Freestanding PoH", RHT_ZR_NEAR_DOMAIN_FREESTANDING_POH, RG_PIECE_OF_HEART, true); locationTable[RC_ZR_NEAR_DOMAIN_FREESTANDING_POH] = Location::Collectable(RC_ZR_NEAR_DOMAIN_FREESTANDING_POH, RCQUEST_BOTH, RCTYPE_STANDARD, ACTOR_EN_ITEM00, SCENE_ZORAS_RIVER, 2822, 0x0B, "Near Domain Freestanding PoH", RHT_ZR_NEAR_DOMAIN_FREESTANDING_POH, RG_PIECE_OF_HEART, true);
locationTable[RC_ZR_DEKU_SCRUB_GROTTO_REAR] = Location::Base(RC_ZR_DEKU_SCRUB_GROTTO_REAR, RCQUEST_BOTH, RCTYPE_SCRUB, RCAREA_ZORAS_RIVER, ACTOR_EN_DNS, SCENE_GROTTOS, TWO_ACTOR_PARAMS(0x07, 0xEB), "Deku Scrub Grotto Rear", RHT_ZR_DEKU_SCRUB_GROTTO_REAR, RG_BUY_RED_POTION_30, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SCRUBS_PURCHASED_ZR_DEKU_SCRUB_GROTTO_REAR)); locationTable[RC_ZR_DEKU_SCRUB_GROTTO_REAR] = Location::Base(RC_ZR_DEKU_SCRUB_GROTTO_REAR, RCQUEST_BOTH, RCTYPE_SCRUB, RCAREA_ZORAS_RIVER, ACTOR_EN_DNS, SCENE_GROTTOS, TWO_ACTOR_PARAMS(0x07, 0xEB), "Deku Scrub Grotto Rear", RHT_ZR_DEKU_SCRUB_GROTTO_REAR, RG_BUY_RED_POTION_40, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SCRUBS_PURCHASED_ZR_DEKU_SCRUB_GROTTO_REAR), false, 40);
locationTable[RC_ZR_DEKU_SCRUB_GROTTO_FRONT] = Location::Base(RC_ZR_DEKU_SCRUB_GROTTO_FRONT, RCQUEST_BOTH, RCTYPE_SCRUB, RCAREA_ZORAS_RIVER, ACTOR_EN_DNS, SCENE_GROTTOS, TWO_ACTOR_PARAMS(0x08, 0xEB), "Deku Scrub Grotto Front", RHT_ZR_DEKU_SCRUB_GROTTO_FRONT, RG_BUY_GREEN_POTION, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SCRUBS_PURCHASED_ZR_DEKU_SCRUB_GROTTO_FRONT)); locationTable[RC_ZR_DEKU_SCRUB_GROTTO_FRONT] = Location::Base(RC_ZR_DEKU_SCRUB_GROTTO_FRONT, RCQUEST_BOTH, RCTYPE_SCRUB, RCAREA_ZORAS_RIVER, ACTOR_EN_DNS, SCENE_GROTTOS, TWO_ACTOR_PARAMS(0x08, 0xEB), "Deku Scrub Grotto Front", RHT_ZR_DEKU_SCRUB_GROTTO_FRONT, RG_BUY_GREEN_POTION, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SCRUBS_PURCHASED_ZR_DEKU_SCRUB_GROTTO_FRONT), false, 40);
// Zoras Domain // Zoras Domain
locationTable[RC_ZD_CHEST] = Location::Chest(RC_ZD_CHEST, RCQUEST_BOTH, RCTYPE_STANDARD, ACTOR_EN_BOX, SCENE_ZORAS_DOMAIN, -18496, 0x00, "Chest", RHT_ZD_CHEST, RG_PIECE_OF_HEART, true); locationTable[RC_ZD_CHEST] = Location::Chest(RC_ZD_CHEST, RCQUEST_BOTH, RCTYPE_STANDARD, ACTOR_EN_BOX, SCENE_ZORAS_DOMAIN, -18496, 0x00, "Chest", RHT_ZD_CHEST, RG_PIECE_OF_HEART, true);
locationTable[RC_ZD_DIVING_MINIGAME] = Location::Base(RC_ZD_DIVING_MINIGAME, RCQUEST_BOTH, RCTYPE_STANDARD, ACTOR_ID_MAX, SCENE_ZORAS_DOMAIN, 0x00, "Diving Minigame", RHT_ZD_DIVING_MINIGAME, RG_PROGRESSIVE_SCALE, SpoilerCollectionCheck::EventChkInf(0x38), true); locationTable[RC_ZD_DIVING_MINIGAME] = Location::Base(RC_ZD_DIVING_MINIGAME, RCQUEST_BOTH, RCTYPE_STANDARD, ACTOR_ID_MAX, SCENE_ZORAS_DOMAIN, 0x00, "Diving Minigame", RHT_ZD_DIVING_MINIGAME, RG_PROGRESSIVE_SCALE, SpoilerCollectionCheck::EventChkInf(0x38), true);
@ -290,9 +300,9 @@ void Rando::StaticData::InitLocationTable() { //
// Lon Lon Ranch // Lon Lon Ranch
locationTable[RC_LLR_TALONS_CHICKENS] = Location::Base(RC_LLR_TALONS_CHICKENS, RCQUEST_BOTH, RCTYPE_STANDARD, ACTOR_ID_MAX, SCENE_LON_LON_BUILDINGS, 0x00, "Talons Chickens", RHT_LLR_TALONS_CHICKENS, RG_BOTTLE_WITH_MILK, SpoilerCollectionCheck::ItemGetInf(2), true); locationTable[RC_LLR_TALONS_CHICKENS] = Location::Base(RC_LLR_TALONS_CHICKENS, RCQUEST_BOTH, RCTYPE_STANDARD, ACTOR_ID_MAX, SCENE_LON_LON_BUILDINGS, 0x00, "Talons Chickens", RHT_LLR_TALONS_CHICKENS, RG_BOTTLE_WITH_MILK, SpoilerCollectionCheck::ItemGetInf(2), true);
locationTable[RC_LLR_FREESTANDING_POH] = Location::Collectable(RC_LLR_FREESTANDING_POH, RCQUEST_BOTH, RCTYPE_STANDARD, ACTOR_EN_ITEM00, SCENE_LON_LON_BUILDINGS, 262, 0x01, "Freestanding PoH", RHT_LLR_FREESTANDING_POH, RG_PIECE_OF_HEART, true); locationTable[RC_LLR_FREESTANDING_POH] = Location::Collectable(RC_LLR_FREESTANDING_POH, RCQUEST_BOTH, RCTYPE_STANDARD, ACTOR_EN_ITEM00, SCENE_LON_LON_BUILDINGS, 262, 0x01, "Freestanding PoH", RHT_LLR_FREESTANDING_POH, RG_PIECE_OF_HEART, true);
locationTable[RC_LLR_DEKU_SCRUB_GROTTO_LEFT] = Location::Base(RC_LLR_DEKU_SCRUB_GROTTO_LEFT, RCQUEST_BOTH, RCTYPE_SCRUB, RCAREA_LON_LON_RANCH, ACTOR_EN_DNS, SCENE_GROTTOS, TWO_ACTOR_PARAMS(0x00, 0xFC), "Deku Scrub Grotto Left", RHT_LLR_DEKU_SCRUB_GROTTO_LEFT, RG_BUY_DEKU_NUTS_5, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SCRUBS_PURCHASED_LLR_DEKU_SCRUB_GROTTO_LEFT)); locationTable[RC_LLR_DEKU_SCRUB_GROTTO_LEFT] = Location::Base(RC_LLR_DEKU_SCRUB_GROTTO_LEFT, RCQUEST_BOTH, RCTYPE_SCRUB, RCAREA_LON_LON_RANCH, ACTOR_EN_DNS, SCENE_GROTTOS, TWO_ACTOR_PARAMS(0x00, 0xFC), "Deku Scrub Grotto Left", RHT_LLR_DEKU_SCRUB_GROTTO_LEFT, RG_BUY_DEKU_NUTS_5, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SCRUBS_PURCHASED_LLR_DEKU_SCRUB_GROTTO_LEFT), false, 20);
locationTable[RC_LLR_DEKU_SCRUB_GROTTO_RIGHT] = Location::Base(RC_LLR_DEKU_SCRUB_GROTTO_RIGHT, RCQUEST_BOTH, RCTYPE_SCRUB, RCAREA_LON_LON_RANCH, ACTOR_EN_DNS, SCENE_GROTTOS, TWO_ACTOR_PARAMS(0x05, 0xFC), "Deku Scrub Grotto Right", RHT_LLR_DEKU_SCRUB_GROTTO_RIGHT, RG_BUY_BOMBS_535, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SCRUBS_PURCHASED_LLR_DEKU_SCRUB_GROTTO_RIGHT)); locationTable[RC_LLR_DEKU_SCRUB_GROTTO_RIGHT] = Location::Base(RC_LLR_DEKU_SCRUB_GROTTO_RIGHT, RCQUEST_BOTH, RCTYPE_SCRUB, RCAREA_LON_LON_RANCH, ACTOR_EN_DNS, SCENE_GROTTOS, TWO_ACTOR_PARAMS(0x05, 0xFC), "Deku Scrub Grotto Right", RHT_LLR_DEKU_SCRUB_GROTTO_RIGHT, RG_BUY_BOMBS_535, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SCRUBS_PURCHASED_LLR_DEKU_SCRUB_GROTTO_RIGHT), false, 40);
locationTable[RC_LLR_DEKU_SCRUB_GROTTO_CENTER] = Location::Base(RC_LLR_DEKU_SCRUB_GROTTO_CENTER, RCQUEST_BOTH, RCTYPE_SCRUB, RCAREA_LON_LON_RANCH, ACTOR_EN_DNS, SCENE_GROTTOS, TWO_ACTOR_PARAMS(0x03, 0xFC), "Deku Scrub Grotto Center", RHT_LLR_DEKU_SCRUB_GROTTO_CENTER, RG_BUY_DEKU_SEEDS_30, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SCRUBS_PURCHASED_LLR_DEKU_SCRUB_GROTTO_CENTER)); locationTable[RC_LLR_DEKU_SCRUB_GROTTO_CENTER] = Location::Base(RC_LLR_DEKU_SCRUB_GROTTO_CENTER, RCQUEST_BOTH, RCTYPE_SCRUB, RCAREA_LON_LON_RANCH, ACTOR_EN_DNS, SCENE_GROTTOS, TWO_ACTOR_PARAMS(0x03, 0xFC), "Deku Scrub Grotto Center", RHT_LLR_DEKU_SCRUB_GROTTO_CENTER, RG_BUY_DEKU_SEEDS_30, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SCRUBS_PURCHASED_LLR_DEKU_SCRUB_GROTTO_CENTER), false, 40);
// Dungeons // Dungeons
// Deku Tree Vanilla // Deku Tree Vanilla
@ -310,7 +320,7 @@ void Rando::StaticData::InitLocationTable() { //
locationTable[RC_DEKU_TREE_MQ_BASEMENT_CHEST] = Location::Chest(RC_DEKU_TREE_MQ_BASEMENT_CHEST, RCQUEST_MQ, RCTYPE_STANDARD, ACTOR_EN_BOX, SCENE_DEKU_TREE, -31452, 0x04, "MQ Basement Chest", RHT_DEKU_TREE_MQ_BASEMENT_CHEST, RG_DEKU_SHIELD); locationTable[RC_DEKU_TREE_MQ_BASEMENT_CHEST] = Location::Chest(RC_DEKU_TREE_MQ_BASEMENT_CHEST, RCQUEST_MQ, RCTYPE_STANDARD, ACTOR_EN_BOX, SCENE_DEKU_TREE, -31452, 0x04, "MQ Basement Chest", RHT_DEKU_TREE_MQ_BASEMENT_CHEST, RG_DEKU_SHIELD);
locationTable[RC_DEKU_TREE_MQ_BEFORE_SPINNING_LOG_CHEST] = Location::Chest(RC_DEKU_TREE_MQ_BEFORE_SPINNING_LOG_CHEST, RCQUEST_MQ, RCTYPE_STANDARD, ACTOR_EN_BOX, SCENE_DEKU_TREE, 22789, 0x05, "MQ Before Spinning Log Chest", RHT_DEKU_TREE_MQ_BEFORE_SPINNING_LOG_CHEST, RG_RECOVERY_HEART); locationTable[RC_DEKU_TREE_MQ_BEFORE_SPINNING_LOG_CHEST] = Location::Chest(RC_DEKU_TREE_MQ_BEFORE_SPINNING_LOG_CHEST, RCQUEST_MQ, RCTYPE_STANDARD, ACTOR_EN_BOX, SCENE_DEKU_TREE, 22789, 0x05, "MQ Before Spinning Log Chest", RHT_DEKU_TREE_MQ_BEFORE_SPINNING_LOG_CHEST, RG_RECOVERY_HEART);
locationTable[RC_DEKU_TREE_MQ_AFTER_SPINNING_LOG_CHEST] = Location::Chest(RC_DEKU_TREE_MQ_AFTER_SPINNING_LOG_CHEST, RCQUEST_MQ, RCTYPE_STANDARD, ACTOR_EN_BOX, SCENE_DEKU_TREE, 23200, 0x00, "MQ After Spinning Log Chest", RHT_DEKU_TREE_MQ_AFTER_SPINNING_LOG_CHEST, RG_PURPLE_RUPEE); locationTable[RC_DEKU_TREE_MQ_AFTER_SPINNING_LOG_CHEST] = Location::Chest(RC_DEKU_TREE_MQ_AFTER_SPINNING_LOG_CHEST, RCQUEST_MQ, RCTYPE_STANDARD, ACTOR_EN_BOX, SCENE_DEKU_TREE, 23200, 0x00, "MQ After Spinning Log Chest", RHT_DEKU_TREE_MQ_AFTER_SPINNING_LOG_CHEST, RG_PURPLE_RUPEE);
locationTable[RC_DEKU_TREE_MQ_DEKU_SCRUB] = Location::Base(RC_DEKU_TREE_MQ_DEKU_SCRUB, RCQUEST_MQ, RCTYPE_SCRUB, ACTOR_EN_DNS, SCENE_DEKU_TREE, 0x04, "MQ Deku Scrub", RHT_DEKU_TREE_MQ_DEKU_SCRUB, RG_BUY_DEKU_SHIELD, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SCRUBS_PURCHASED_DEKU_TREE_MQ_DEKU_SCRUB)); locationTable[RC_DEKU_TREE_MQ_DEKU_SCRUB] = Location::Base(RC_DEKU_TREE_MQ_DEKU_SCRUB, RCQUEST_MQ, RCTYPE_SCRUB, ACTOR_EN_DNS, SCENE_DEKU_TREE, 0x04, "MQ Deku Scrub", RHT_DEKU_TREE_MQ_DEKU_SCRUB, RG_BUY_DEKU_SHIELD, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SCRUBS_PURCHASED_DEKU_TREE_MQ_DEKU_SCRUB), false, 50);
// Dodongo's Cavern Shared // Dodongo's Cavern Shared
locationTable[RC_DODONGOS_CAVERN_BOSS_ROOM_CHEST] = Location::Chest(RC_DODONGOS_CAVERN_BOSS_ROOM_CHEST, RCQUEST_BOTH, RCTYPE_STANDARD, ACTOR_EN_BOX, SCENE_DODONGOS_CAVERN_BOSS, 20512, 0x00, "Boss Room Chest", RHT_DODONGOS_CAVERN_BOSS_ROOM_CHEST, RG_BOMBS_5); locationTable[RC_DODONGOS_CAVERN_BOSS_ROOM_CHEST] = Location::Chest(RC_DODONGOS_CAVERN_BOSS_ROOM_CHEST, RCQUEST_BOTH, RCTYPE_STANDARD, ACTOR_EN_BOX, SCENE_DODONGOS_CAVERN_BOSS, 20512, 0x00, "Boss Room Chest", RHT_DODONGOS_CAVERN_BOSS_ROOM_CHEST, RG_BOMBS_5);
@ -320,10 +330,10 @@ void Rando::StaticData::InitLocationTable() { //
locationTable[RC_DODONGOS_CAVERN_BOMB_FLOWER_PLATFORM_CHEST] = Location::Chest(RC_DODONGOS_CAVERN_BOMB_FLOWER_PLATFORM_CHEST, RCQUEST_VANILLA, RCTYPE_STANDARD, ACTOR_EN_BOX, SCENE_DODONGOS_CAVERN, 22982, 0x06, "Bomb Flower Platform Chest", RHT_DODONGOS_CAVERN_BOMB_FLOWER_PLATFORM_CHEST, RG_RED_RUPEE); locationTable[RC_DODONGOS_CAVERN_BOMB_FLOWER_PLATFORM_CHEST] = Location::Chest(RC_DODONGOS_CAVERN_BOMB_FLOWER_PLATFORM_CHEST, RCQUEST_VANILLA, RCTYPE_STANDARD, ACTOR_EN_BOX, SCENE_DODONGOS_CAVERN, 22982, 0x06, "Bomb Flower Platform Chest", RHT_DODONGOS_CAVERN_BOMB_FLOWER_PLATFORM_CHEST, RG_RED_RUPEE);
locationTable[RC_DODONGOS_CAVERN_BOMB_BAG_CHEST] = Location::Chest(RC_DODONGOS_CAVERN_BOMB_BAG_CHEST, RCQUEST_VANILLA, RCTYPE_STANDARD, ACTOR_EN_BOX, SCENE_DODONGOS_CAVERN, 1604, 0x04, "Bomb Bag Chest", RHT_DODONGOS_CAVERN_BOMB_BAG_CHEST, RG_PROGRESSIVE_BOMB_BAG, true); locationTable[RC_DODONGOS_CAVERN_BOMB_BAG_CHEST] = Location::Chest(RC_DODONGOS_CAVERN_BOMB_BAG_CHEST, RCQUEST_VANILLA, RCTYPE_STANDARD, ACTOR_EN_BOX, SCENE_DODONGOS_CAVERN, 1604, 0x04, "Bomb Bag Chest", RHT_DODONGOS_CAVERN_BOMB_BAG_CHEST, RG_PROGRESSIVE_BOMB_BAG, true);
locationTable[RC_DODONGOS_CAVERN_END_OF_BRIDGE_CHEST] = Location::Chest(RC_DODONGOS_CAVERN_END_OF_BRIDGE_CHEST, RCQUEST_VANILLA, RCTYPE_STANDARD, ACTOR_EN_BOX, SCENE_DODONGOS_CAVERN, 21802, 0x0A, "End Of Bridge Chest", RHT_DODONGOS_CAVERN_END_OF_BRIDGE_CHEST, RG_DEKU_SHIELD); locationTable[RC_DODONGOS_CAVERN_END_OF_BRIDGE_CHEST] = Location::Chest(RC_DODONGOS_CAVERN_END_OF_BRIDGE_CHEST, RCQUEST_VANILLA, RCTYPE_STANDARD, ACTOR_EN_BOX, SCENE_DODONGOS_CAVERN, 21802, 0x0A, "End Of Bridge Chest", RHT_DODONGOS_CAVERN_END_OF_BRIDGE_CHEST, RG_DEKU_SHIELD);
locationTable[RC_DODONGOS_CAVERN_DEKU_SCRUB_NEAR_BOMB_BAG_LEFT] = Location::Base(RC_DODONGOS_CAVERN_DEKU_SCRUB_NEAR_BOMB_BAG_LEFT, RCQUEST_VANILLA, RCTYPE_SCRUB, ACTOR_EN_DNS, SCENE_DODONGOS_CAVERN, 0x00, "Deku Scrub Near Bomb Bag Left", RHT_DODONGOS_CAVERN_DEKU_SCRUB_NEAR_BOMB_BAG_LEFT, RG_BUY_DEKU_NUTS_5, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SCRUBS_PURCHASED_DODONGOS_CAVERN_DEKU_SCRUB_NEAR_BOMB_BAG_LEFT)); locationTable[RC_DODONGOS_CAVERN_DEKU_SCRUB_NEAR_BOMB_BAG_LEFT] = Location::Base(RC_DODONGOS_CAVERN_DEKU_SCRUB_NEAR_BOMB_BAG_LEFT, RCQUEST_VANILLA, RCTYPE_SCRUB, ACTOR_EN_DNS, SCENE_DODONGOS_CAVERN, 0x00, "Deku Scrub Near Bomb Bag Left", RHT_DODONGOS_CAVERN_DEKU_SCRUB_NEAR_BOMB_BAG_LEFT, RG_BUY_DEKU_NUTS_5, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SCRUBS_PURCHASED_DODONGOS_CAVERN_DEKU_SCRUB_NEAR_BOMB_BAG_LEFT), false, 20);
locationTable[RC_DODONGOS_CAVERN_DEKU_SCRUB_SIDE_ROOM_NEAR_DODONGOS] = Location::Base(RC_DODONGOS_CAVERN_DEKU_SCRUB_SIDE_ROOM_NEAR_DODONGOS, RCQUEST_VANILLA, RCTYPE_SCRUB, ACTOR_EN_DNS, SCENE_DODONGOS_CAVERN, 0x01, "Deku Scrub Side Room Near Dodongos", RHT_DODONGOS_CAVERN_DEKU_SCRUB_SIDE_ROOM_NEAR_DODONGOS, RG_BUY_DEKU_STICK_1, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SCRUBS_PURCHASED_DODONGOS_CAVERN_DEKU_SCRUB_SIDE_ROOM_NEAR_DODONGOS)); locationTable[RC_DODONGOS_CAVERN_DEKU_SCRUB_SIDE_ROOM_NEAR_DODONGOS] = Location::Base(RC_DODONGOS_CAVERN_DEKU_SCRUB_SIDE_ROOM_NEAR_DODONGOS, RCQUEST_VANILLA, RCTYPE_SCRUB, ACTOR_EN_DNS, SCENE_DODONGOS_CAVERN, 0x01, "Deku Scrub Side Room Near Dodongos", RHT_DODONGOS_CAVERN_DEKU_SCRUB_SIDE_ROOM_NEAR_DODONGOS, RG_BUY_DEKU_STICK_1, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SCRUBS_PURCHASED_DODONGOS_CAVERN_DEKU_SCRUB_SIDE_ROOM_NEAR_DODONGOS), false, 15);
locationTable[RC_DODONGOS_CAVERN_DEKU_SCRUB_NEAR_BOMB_BAG_RIGHT] = Location::Base(RC_DODONGOS_CAVERN_DEKU_SCRUB_NEAR_BOMB_BAG_RIGHT, RCQUEST_VANILLA, RCTYPE_SCRUB, ACTOR_EN_DNS, SCENE_DODONGOS_CAVERN, 0x03, "Deku Scrub Near Bomb Bag Right", RHT_DODONGOS_CAVERN_DEKU_SCRUB_NEAR_BOMB_BAG_RIGHT, RG_BUY_DEKU_SEEDS_30, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SCRUBS_PURCHASED_DODONGOS_CAVERN_DEKU_SCRUB_NEAR_BOMB_BAG_RIGHT)); locationTable[RC_DODONGOS_CAVERN_DEKU_SCRUB_NEAR_BOMB_BAG_RIGHT] = Location::Base(RC_DODONGOS_CAVERN_DEKU_SCRUB_NEAR_BOMB_BAG_RIGHT, RCQUEST_VANILLA, RCTYPE_SCRUB, ACTOR_EN_DNS, SCENE_DODONGOS_CAVERN, 0x03, "Deku Scrub Near Bomb Bag Right", RHT_DODONGOS_CAVERN_DEKU_SCRUB_NEAR_BOMB_BAG_RIGHT, RG_BUY_DEKU_SEEDS_30, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SCRUBS_PURCHASED_DODONGOS_CAVERN_DEKU_SCRUB_NEAR_BOMB_BAG_RIGHT), false, 40);
locationTable[RC_DODONGOS_CAVERN_DEKU_SCRUB_LOBBY] = Location::Base(RC_DODONGOS_CAVERN_DEKU_SCRUB_LOBBY, RCQUEST_VANILLA, RCTYPE_SCRUB, ACTOR_EN_DNS, SCENE_DODONGOS_CAVERN, 0x04, "Deku Scrub Lobby", RHT_DODONGOS_CAVERN_DEKU_SCRUB_LOBBY, RG_BUY_DEKU_SHIELD, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SCRUBS_PURCHASED_DODONGOS_CAVERN_DEKU_SCRUB_LOBBY)); locationTable[RC_DODONGOS_CAVERN_DEKU_SCRUB_LOBBY] = Location::Base(RC_DODONGOS_CAVERN_DEKU_SCRUB_LOBBY, RCQUEST_VANILLA, RCTYPE_SCRUB, ACTOR_EN_DNS, SCENE_DODONGOS_CAVERN, 0x04, "Deku Scrub Lobby", RHT_DODONGOS_CAVERN_DEKU_SCRUB_LOBBY, RG_BUY_DEKU_SHIELD, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SCRUBS_PURCHASED_DODONGOS_CAVERN_DEKU_SCRUB_LOBBY), false, 50);
// Dodongo's Cavern MQ // Dodongo's Cavern MQ
locationTable[RC_DODONGOS_CAVERN_MQ_MAP_CHEST] = Location::Chest(RC_DODONGOS_CAVERN_MQ_MAP_CHEST, RCQUEST_MQ, RCTYPE_MAP, ACTOR_EN_BOX, SCENE_DODONGOS_CAVERN, 2080, 0x00, "MQ Map Chest", RHT_DODONGOS_CAVERN_MQ_MAP_CHEST, RG_DODONGOS_CAVERN_MAP, true); locationTable[RC_DODONGOS_CAVERN_MQ_MAP_CHEST] = Location::Chest(RC_DODONGOS_CAVERN_MQ_MAP_CHEST, RCQUEST_MQ, RCTYPE_MAP, ACTOR_EN_BOX, SCENE_DODONGOS_CAVERN, 2080, 0x00, "MQ Map Chest", RHT_DODONGOS_CAVERN_MQ_MAP_CHEST, RG_DODONGOS_CAVERN_MAP, true);
locationTable[RC_DODONGOS_CAVERN_MQ_BOMB_BAG_CHEST] = Location::Chest(RC_DODONGOS_CAVERN_MQ_BOMB_BAG_CHEST, RCQUEST_MQ, RCTYPE_STANDARD, ACTOR_EN_BOX, SCENE_DODONGOS_CAVERN, 1604, 0x04, "MQ Bomb Bag Chest", RHT_DODONGOS_CAVERN_MQ_BOMB_BAG_CHEST, RG_PROGRESSIVE_BOMB_BAG, true); locationTable[RC_DODONGOS_CAVERN_MQ_BOMB_BAG_CHEST] = Location::Chest(RC_DODONGOS_CAVERN_MQ_BOMB_BAG_CHEST, RCQUEST_MQ, RCTYPE_STANDARD, ACTOR_EN_BOX, SCENE_DODONGOS_CAVERN, 1604, 0x04, "MQ Bomb Bag Chest", RHT_DODONGOS_CAVERN_MQ_BOMB_BAG_CHEST, RG_PROGRESSIVE_BOMB_BAG, true);
@ -331,16 +341,16 @@ void Rando::StaticData::InitLocationTable() { //
locationTable[RC_DODONGOS_CAVERN_MQ_LARVAE_ROOM_CHEST] = Location::Chest(RC_DODONGOS_CAVERN_MQ_LARVAE_ROOM_CHEST, RCQUEST_MQ, RCTYPE_STANDARD, ACTOR_EN_BOX, SCENE_DODONGOS_CAVERN, 29986, 0x02, "MQ Larvae Room Chest", RHT_DODONGOS_CAVERN_MQ_LARVAE_ROOM_CHEST, RG_DEKU_SHIELD); locationTable[RC_DODONGOS_CAVERN_MQ_LARVAE_ROOM_CHEST] = Location::Chest(RC_DODONGOS_CAVERN_MQ_LARVAE_ROOM_CHEST, RCQUEST_MQ, RCTYPE_STANDARD, ACTOR_EN_BOX, SCENE_DODONGOS_CAVERN, 29986, 0x02, "MQ Larvae Room Chest", RHT_DODONGOS_CAVERN_MQ_LARVAE_ROOM_CHEST, RG_DEKU_SHIELD);
locationTable[RC_DODONGOS_CAVERN_MQ_TORCH_PUZZLE_ROOM_CHEST] = Location::Chest(RC_DODONGOS_CAVERN_MQ_TORCH_PUZZLE_ROOM_CHEST, RCQUEST_MQ, RCTYPE_STANDARD, ACTOR_EN_BOX, SCENE_DODONGOS_CAVERN, 22947, 0x03, "MQ Torch Puzzle Room Chest", RHT_DODONGOS_CAVERN_MQ_TORCH_PUZZLE_ROOM_CHEST, RG_BLUE_RUPEE); locationTable[RC_DODONGOS_CAVERN_MQ_TORCH_PUZZLE_ROOM_CHEST] = Location::Chest(RC_DODONGOS_CAVERN_MQ_TORCH_PUZZLE_ROOM_CHEST, RCQUEST_MQ, RCTYPE_STANDARD, ACTOR_EN_BOX, SCENE_DODONGOS_CAVERN, 22947, 0x03, "MQ Torch Puzzle Room Chest", RHT_DODONGOS_CAVERN_MQ_TORCH_PUZZLE_ROOM_CHEST, RG_BLUE_RUPEE);
locationTable[RC_DODONGOS_CAVERN_MQ_UNDER_GRAVE_CHEST] = Location::Chest(RC_DODONGOS_CAVERN_MQ_UNDER_GRAVE_CHEST, RCQUEST_MQ, RCTYPE_STANDARD, ACTOR_EN_BOX, SCENE_DODONGOS_CAVERN, 21825, 0x01, "MQ Under Grave Chest", RHT_DODONGOS_CAVERN_MQ_UNDER_GRAVE_CHEST, RG_HYLIAN_SHIELD); locationTable[RC_DODONGOS_CAVERN_MQ_UNDER_GRAVE_CHEST] = Location::Chest(RC_DODONGOS_CAVERN_MQ_UNDER_GRAVE_CHEST, RCQUEST_MQ, RCTYPE_STANDARD, ACTOR_EN_BOX, SCENE_DODONGOS_CAVERN, 21825, 0x01, "MQ Under Grave Chest", RHT_DODONGOS_CAVERN_MQ_UNDER_GRAVE_CHEST, RG_HYLIAN_SHIELD);
locationTable[RC_DODONGOS_CAVERN_MQ_DEKU_SCRUB_LOBBY_REAR] = Location::Base(RC_DODONGOS_CAVERN_MQ_DEKU_SCRUB_LOBBY_REAR, RCQUEST_MQ, RCTYPE_SCRUB, ACTOR_EN_DNS, SCENE_DODONGOS_CAVERN, 0x01, "MQ Deku Scrub Lobby Rear", RHT_DODONGOS_CAVERN_MQ_DEKU_SCRUB_LOBBY_REAR, RG_BUY_DEKU_STICK_1, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SCRUBS_PURCHASED_DODONGOS_CAVERN_MQ_DEKU_SCRUB_LOBBY_REAR)); locationTable[RC_DODONGOS_CAVERN_MQ_DEKU_SCRUB_LOBBY_REAR] = Location::Base(RC_DODONGOS_CAVERN_MQ_DEKU_SCRUB_LOBBY_REAR, RCQUEST_MQ, RCTYPE_SCRUB, ACTOR_EN_DNS, SCENE_DODONGOS_CAVERN, 0x01, "MQ Deku Scrub Lobby Rear", RHT_DODONGOS_CAVERN_MQ_DEKU_SCRUB_LOBBY_REAR, RG_BUY_DEKU_STICK_1, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SCRUBS_PURCHASED_DODONGOS_CAVERN_MQ_DEKU_SCRUB_LOBBY_REAR), false, 15);
locationTable[RC_DODONGOS_CAVERN_MQ_DEKU_SCRUB_LOBBY_FRONT] = Location::Base(RC_DODONGOS_CAVERN_MQ_DEKU_SCRUB_LOBBY_FRONT, RCQUEST_MQ, RCTYPE_SCRUB, ACTOR_EN_DNS, SCENE_DODONGOS_CAVERN, 0x03, "MQ Deku Scrub Lobby Front", RHT_DODONGOS_CAVERN_MQ_DEKU_SCRUB_LOBBY_FRONT, RG_BUY_DEKU_SEEDS_30, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SCRUBS_PURCHASED_DODONGOS_CAVERN_MQ_DEKU_SCRUB_LOBBY_FRONT)); locationTable[RC_DODONGOS_CAVERN_MQ_DEKU_SCRUB_LOBBY_FRONT] = Location::Base(RC_DODONGOS_CAVERN_MQ_DEKU_SCRUB_LOBBY_FRONT, RCQUEST_MQ, RCTYPE_SCRUB, ACTOR_EN_DNS, SCENE_DODONGOS_CAVERN, 0x03, "MQ Deku Scrub Lobby Front", RHT_DODONGOS_CAVERN_MQ_DEKU_SCRUB_LOBBY_FRONT, RG_BUY_DEKU_SEEDS_30, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SCRUBS_PURCHASED_DODONGOS_CAVERN_MQ_DEKU_SCRUB_LOBBY_FRONT), false, 40);
locationTable[RC_DODONGOS_CAVERN_MQ_DEKU_SCRUB_STAIRCASE] = Location::Base(RC_DODONGOS_CAVERN_MQ_DEKU_SCRUB_STAIRCASE, RCQUEST_MQ, RCTYPE_SCRUB, ACTOR_EN_DNS, SCENE_DODONGOS_CAVERN, 0x04, "MQ Deku Scrub Staircase", RHT_DODONGOS_CAVERN_MQ_DEKU_SCRUB_STAIRCASE, RG_BUY_DEKU_SHIELD, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SCRUBS_PURCHASED_DODONGOS_CAVERN_MQ_DEKU_SCRUB_STAIRCASE)); locationTable[RC_DODONGOS_CAVERN_MQ_DEKU_SCRUB_STAIRCASE] = Location::Base(RC_DODONGOS_CAVERN_MQ_DEKU_SCRUB_STAIRCASE, RCQUEST_MQ, RCTYPE_SCRUB, ACTOR_EN_DNS, SCENE_DODONGOS_CAVERN, 0x04, "MQ Deku Scrub Staircase", RHT_DODONGOS_CAVERN_MQ_DEKU_SCRUB_STAIRCASE, RG_BUY_DEKU_SHIELD, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SCRUBS_PURCHASED_DODONGOS_CAVERN_MQ_DEKU_SCRUB_STAIRCASE), false, 50);
locationTable[RC_DODONGOS_CAVERN_MQ_DEKU_SCRUB_SIDE_ROOM_NEAR_LOWER_LIZALFOS] = Location::Base(RC_DODONGOS_CAVERN_MQ_DEKU_SCRUB_SIDE_ROOM_NEAR_LOWER_LIZALFOS, RCQUEST_MQ, RCTYPE_SCRUB, ACTOR_EN_DNS, SCENE_DODONGOS_CAVERN, 0x07, "MQ Deku Scrub Side Room Near Lower Lizalfos", RHT_DODONGOS_CAVERN_MQ_DEKU_SCRUB_SIDE_ROOM_NEAR_LOWER_LIZALFOS, RG_BUY_RED_POTION_30, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SCRUBS_PURCHASED_DODONGOS_CAVERN_MQ_DEKU_SCRUB_SIDE_ROOM_NEAR_LOWER_LIZALFOS)); locationTable[RC_DODONGOS_CAVERN_MQ_DEKU_SCRUB_SIDE_ROOM_NEAR_LOWER_LIZALFOS] = Location::Base(RC_DODONGOS_CAVERN_MQ_DEKU_SCRUB_SIDE_ROOM_NEAR_LOWER_LIZALFOS, RCQUEST_MQ, RCTYPE_SCRUB, ACTOR_EN_DNS, SCENE_DODONGOS_CAVERN, 0x07, "MQ Deku Scrub Side Room Near Lower Lizalfos", RHT_DODONGOS_CAVERN_MQ_DEKU_SCRUB_SIDE_ROOM_NEAR_LOWER_LIZALFOS, RG_BUY_RED_POTION_40, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SCRUBS_PURCHASED_DODONGOS_CAVERN_MQ_DEKU_SCRUB_SIDE_ROOM_NEAR_LOWER_LIZALFOS), false, 40);
// Jabu-Jabu's Belly Vanilla // Jabu-Jabu's Belly Vanilla
locationTable[RC_JABU_JABUS_BELLY_MAP_CHEST] = Location::Chest(RC_JABU_JABUS_BELLY_MAP_CHEST, RCQUEST_VANILLA, RCTYPE_MAP, ACTOR_EN_BOX, SCENE_JABU_JABU, 6178, 0x02, "Map Chest", RHT_JABU_JABUS_BELLY_MAP_CHEST, RG_JABU_JABUS_BELLY_MAP, true); locationTable[RC_JABU_JABUS_BELLY_MAP_CHEST] = Location::Chest(RC_JABU_JABUS_BELLY_MAP_CHEST, RCQUEST_VANILLA, RCTYPE_MAP, ACTOR_EN_BOX, SCENE_JABU_JABU, 6178, 0x02, "Map Chest", RHT_JABU_JABUS_BELLY_MAP_CHEST, RG_JABU_JABUS_BELLY_MAP, true);
locationTable[RC_JABU_JABUS_BELLY_COMPASS_CHEST] = Location::Chest(RC_JABU_JABUS_BELLY_COMPASS_CHEST, RCQUEST_VANILLA, RCTYPE_COMPASS, ACTOR_EN_BOX, SCENE_JABU_JABU, -18428, 0x04, "Compass Chest", RHT_JABU_JABUS_BELLY_COMPASS_CHEST, RG_JABU_JABUS_BELLY_COMPASS, true); locationTable[RC_JABU_JABUS_BELLY_COMPASS_CHEST] = Location::Chest(RC_JABU_JABUS_BELLY_COMPASS_CHEST, RCQUEST_VANILLA, RCTYPE_COMPASS, ACTOR_EN_BOX, SCENE_JABU_JABU, -18428, 0x04, "Compass Chest", RHT_JABU_JABUS_BELLY_COMPASS_CHEST, RG_JABU_JABUS_BELLY_COMPASS, true);
locationTable[RC_JABU_JABUS_BELLY_BOOMERANG_CHEST] = Location::Chest(RC_JABU_JABUS_BELLY_BOOMERANG_CHEST, RCQUEST_VANILLA, RCTYPE_STANDARD, ACTOR_EN_BOX, SCENE_JABU_JABU, 4289, 0x01, "Boomerang Chest", RHT_JABU_JABUS_BELLY_BOOMERANG_CHEST, RG_BOOMERANG, true); locationTable[RC_JABU_JABUS_BELLY_BOOMERANG_CHEST] = Location::Chest(RC_JABU_JABUS_BELLY_BOOMERANG_CHEST, RCQUEST_VANILLA, RCTYPE_STANDARD, ACTOR_EN_BOX, SCENE_JABU_JABU, 4289, 0x01, "Boomerang Chest", RHT_JABU_JABUS_BELLY_BOOMERANG_CHEST, RG_BOOMERANG, true);
locationTable[RC_JABU_JABUS_BELLY_DEKU_SCRUB] = Location::Base(RC_JABU_JABUS_BELLY_DEKU_SCRUB, RCQUEST_VANILLA, RCTYPE_SCRUB, ACTOR_EN_DNS, SCENE_JABU_JABU, 0x00, "Deku Scrub", RHT_JABU_JABUS_BELLY_DEKU_SCRUB, RG_BUY_DEKU_NUTS_5, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SCRUBS_PURCHASED_JABU_JABUS_BELLY_DEKU_SCRUB)); locationTable[RC_JABU_JABUS_BELLY_DEKU_SCRUB] = Location::Base(RC_JABU_JABUS_BELLY_DEKU_SCRUB, RCQUEST_VANILLA, RCTYPE_SCRUB, ACTOR_EN_DNS, SCENE_JABU_JABU, 0x00, "Deku Scrub", RHT_JABU_JABUS_BELLY_DEKU_SCRUB, RG_BUY_DEKU_NUTS_5, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SCRUBS_PURCHASED_JABU_JABUS_BELLY_DEKU_SCRUB), false, 20);
// Jabu-Jabu's Belly MQ // Jabu-Jabu's Belly MQ
locationTable[RC_JABU_JABUS_BELLY_MQ_FIRST_ROOM_SIDE_CHEST] = Location::Chest(RC_JABU_JABUS_BELLY_MQ_FIRST_ROOM_SIDE_CHEST, RCQUEST_MQ, RCTYPE_STANDARD, ACTOR_EN_BOX, SCENE_JABU_JABU, -32699, 0x05, "MQ First Room Side Chest", RHT_JABU_JABUS_BELLY_MQ_FIRST_ROOM_SIDE_CHEST, RG_DEKU_NUTS_5); locationTable[RC_JABU_JABUS_BELLY_MQ_FIRST_ROOM_SIDE_CHEST] = Location::Chest(RC_JABU_JABUS_BELLY_MQ_FIRST_ROOM_SIDE_CHEST, RCQUEST_MQ, RCTYPE_STANDARD, ACTOR_EN_BOX, SCENE_JABU_JABU, -32699, 0x05, "MQ First Room Side Chest", RHT_JABU_JABUS_BELLY_MQ_FIRST_ROOM_SIDE_CHEST, RG_DEKU_NUTS_5);
locationTable[RC_JABU_JABUS_BELLY_MQ_MAP_CHEST] = Location::Chest(RC_JABU_JABUS_BELLY_MQ_MAP_CHEST, RCQUEST_MQ, RCTYPE_MAP, ACTOR_EN_BOX, SCENE_JABU_JABU, -18397, 0x03, "MQ Map Chest", RHT_JABU_JABUS_BELLY_MQ_MAP_CHEST, RG_JABU_JABUS_BELLY_MAP, true); locationTable[RC_JABU_JABUS_BELLY_MQ_MAP_CHEST] = Location::Chest(RC_JABU_JABUS_BELLY_MQ_MAP_CHEST, RCQUEST_MQ, RCTYPE_MAP, ACTOR_EN_BOX, SCENE_JABU_JABU, -18397, 0x03, "MQ Map Chest", RHT_JABU_JABUS_BELLY_MQ_MAP_CHEST, RG_JABU_JABUS_BELLY_MAP, true);
@ -606,10 +616,10 @@ void Rando::StaticData::InitLocationTable() { //
locationTable[RC_GANONS_CASTLE_LIGHT_TRIAL_THIRD_RIGHT_CHEST] = Location::Chest(RC_GANONS_CASTLE_LIGHT_TRIAL_THIRD_RIGHT_CHEST, RCQUEST_VANILLA, RCTYPE_STANDARD, ACTOR_EN_BOX, SCENE_INSIDE_GANONS_CASTLE, 24463, 0x0F, "Light Trial Third Right Chest", RHT_GANONS_CASTLE_LIGHT_TRIAL_THIRD_RIGHT_CHEST, RG_ICE_TRAP); locationTable[RC_GANONS_CASTLE_LIGHT_TRIAL_THIRD_RIGHT_CHEST] = Location::Chest(RC_GANONS_CASTLE_LIGHT_TRIAL_THIRD_RIGHT_CHEST, RCQUEST_VANILLA, RCTYPE_STANDARD, ACTOR_EN_BOX, SCENE_INSIDE_GANONS_CASTLE, 24463, 0x0F, "Light Trial Third Right Chest", RHT_GANONS_CASTLE_LIGHT_TRIAL_THIRD_RIGHT_CHEST, RG_ICE_TRAP);
locationTable[RC_GANONS_CASTLE_LIGHT_TRIAL_INVISIBLE_ENEMIES_CHEST] = Location::Chest(RC_GANONS_CASTLE_LIGHT_TRIAL_INVISIBLE_ENEMIES_CHEST, RCQUEST_VANILLA, RCTYPE_SMALL_KEY, ACTOR_EN_BOX, SCENE_INSIDE_GANONS_CASTLE, 30800, 0x10, "Light Trial Invisible Enemies Chest", RHT_GANONS_CASTLE_LIGHT_TRIAL_INVISIBLE_ENEMIES_CHEST, RG_GANONS_CASTLE_SMALL_KEY, true); locationTable[RC_GANONS_CASTLE_LIGHT_TRIAL_INVISIBLE_ENEMIES_CHEST] = Location::Chest(RC_GANONS_CASTLE_LIGHT_TRIAL_INVISIBLE_ENEMIES_CHEST, RCQUEST_VANILLA, RCTYPE_SMALL_KEY, ACTOR_EN_BOX, SCENE_INSIDE_GANONS_CASTLE, 30800, 0x10, "Light Trial Invisible Enemies Chest", RHT_GANONS_CASTLE_LIGHT_TRIAL_INVISIBLE_ENEMIES_CHEST, RG_GANONS_CASTLE_SMALL_KEY, true);
locationTable[RC_GANONS_CASTLE_LIGHT_TRIAL_LULLABY_CHEST] = Location::Chest(RC_GANONS_CASTLE_LIGHT_TRIAL_LULLABY_CHEST, RCQUEST_VANILLA, RCTYPE_SMALL_KEY, ACTOR_EN_BOX, SCENE_INSIDE_GANONS_CASTLE, -30639, 0x11, "Light Trial Lullaby Chest", RHT_GANONS_CASTLE_LIGHT_TRIAL_LULLABY_CHEST, RG_GANONS_CASTLE_SMALL_KEY, true); locationTable[RC_GANONS_CASTLE_LIGHT_TRIAL_LULLABY_CHEST] = Location::Chest(RC_GANONS_CASTLE_LIGHT_TRIAL_LULLABY_CHEST, RCQUEST_VANILLA, RCTYPE_SMALL_KEY, ACTOR_EN_BOX, SCENE_INSIDE_GANONS_CASTLE, -30639, 0x11, "Light Trial Lullaby Chest", RHT_GANONS_CASTLE_LIGHT_TRIAL_LULLABY_CHEST, RG_GANONS_CASTLE_SMALL_KEY, true);
locationTable[RC_GANONS_CASTLE_DEKU_SCRUB_CENTER_LEFT] = Location::Base(RC_GANONS_CASTLE_DEKU_SCRUB_CENTER_LEFT, RCQUEST_VANILLA, RCTYPE_SCRUB, ACTOR_EN_DNS, SCENE_INSIDE_GANONS_CASTLE, 0x05, "Deku Scrub Center-Left", RHT_GANONS_CASTLE_DEKU_SCRUB_CENTER_LEFT, RG_BUY_BOMBS_535, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SCRUBS_PURCHASED_GANONS_CASTLE_DEKU_SCRUB_CENTER_LEFT)); locationTable[RC_GANONS_CASTLE_DEKU_SCRUB_CENTER_LEFT] = Location::Base(RC_GANONS_CASTLE_DEKU_SCRUB_CENTER_LEFT, RCQUEST_VANILLA, RCTYPE_SCRUB, ACTOR_EN_DNS, SCENE_INSIDE_GANONS_CASTLE, 0x05, "Deku Scrub Center-Left", RHT_GANONS_CASTLE_DEKU_SCRUB_CENTER_LEFT, RG_BUY_BOMBS_535, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SCRUBS_PURCHASED_GANONS_CASTLE_DEKU_SCRUB_CENTER_LEFT), false, 40);
locationTable[RC_GANONS_CASTLE_DEKU_SCRUB_CENTER_RIGHT] = Location::Base(RC_GANONS_CASTLE_DEKU_SCRUB_CENTER_RIGHT, RCQUEST_VANILLA, RCTYPE_SCRUB, ACTOR_EN_DNS, SCENE_INSIDE_GANONS_CASTLE, 0x03, "Deku Scrub Center-Right", RHT_GANONS_CASTLE_DEKU_SCRUB_CENTER_RIGHT, RG_BUY_ARROWS_30, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SCRUBS_PURCHASED_GANONS_CASTLE_DEKU_SCRUB_CENTER_RIGHT)); locationTable[RC_GANONS_CASTLE_DEKU_SCRUB_CENTER_RIGHT] = Location::Base(RC_GANONS_CASTLE_DEKU_SCRUB_CENTER_RIGHT, RCQUEST_VANILLA, RCTYPE_SCRUB, ACTOR_EN_DNS, SCENE_INSIDE_GANONS_CASTLE, 0x03, "Deku Scrub Center-Right", RHT_GANONS_CASTLE_DEKU_SCRUB_CENTER_RIGHT, RG_BUY_ARROWS_30, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SCRUBS_PURCHASED_GANONS_CASTLE_DEKU_SCRUB_CENTER_RIGHT), false, 70);
locationTable[RC_GANONS_CASTLE_DEKU_SCRUB_RIGHT] = Location::Base(RC_GANONS_CASTLE_DEKU_SCRUB_RIGHT, RCQUEST_VANILLA, RCTYPE_SCRUB, ACTOR_EN_DNS, SCENE_INSIDE_GANONS_CASTLE, 0x07, "Deku Scrub Right", RHT_GANONS_CASTLE_DEKU_SCRUB_RIGHT, RG_BUY_RED_POTION_30, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SCRUBS_PURCHASED_GANONS_CASTLE_DEKU_SCRUB_RIGHT)); locationTable[RC_GANONS_CASTLE_DEKU_SCRUB_RIGHT] = Location::Base(RC_GANONS_CASTLE_DEKU_SCRUB_RIGHT, RCQUEST_VANILLA, RCTYPE_SCRUB, ACTOR_EN_DNS, SCENE_INSIDE_GANONS_CASTLE, 0x07, "Deku Scrub Right", RHT_GANONS_CASTLE_DEKU_SCRUB_RIGHT, RG_BUY_RED_POTION_40, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SCRUBS_PURCHASED_GANONS_CASTLE_DEKU_SCRUB_RIGHT), false, 20);
locationTable[RC_GANONS_CASTLE_DEKU_SCRUB_LEFT] = Location::Base(RC_GANONS_CASTLE_DEKU_SCRUB_LEFT, RCQUEST_VANILLA, RCTYPE_SCRUB, ACTOR_EN_DNS, SCENE_INSIDE_GANONS_CASTLE, 0x08, "Deku Scrub Left", RHT_GANONS_CASTLE_DEKU_SCRUB_LEFT, RG_BUY_GREEN_POTION, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SCRUBS_PURCHASED_GANONS_CASTLE_DEKU_SCRUB_LEFT)); locationTable[RC_GANONS_CASTLE_DEKU_SCRUB_LEFT] = Location::Base(RC_GANONS_CASTLE_DEKU_SCRUB_LEFT, RCQUEST_VANILLA, RCTYPE_SCRUB, ACTOR_EN_DNS, SCENE_INSIDE_GANONS_CASTLE, 0x08, "Deku Scrub Left", RHT_GANONS_CASTLE_DEKU_SCRUB_LEFT, RG_BUY_GREEN_POTION, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SCRUBS_PURCHASED_GANONS_CASTLE_DEKU_SCRUB_LEFT), false, 40);
// Ganon's Castle MQ // Ganon's Castle MQ
locationTable[RC_GANONS_CASTLE_MQ_WATER_TRIAL_CHEST] = Location::Chest(RC_GANONS_CASTLE_MQ_WATER_TRIAL_CHEST, RCQUEST_MQ, RCTYPE_STANDARD, ACTOR_EN_BOX, SCENE_INSIDE_GANONS_CASTLE, 22977, 0x01, "MQ Water Trial Chest", RHT_GANONS_CASTLE_MQ_WATER_TRIAL_CHEST, RG_RED_RUPEE); locationTable[RC_GANONS_CASTLE_MQ_WATER_TRIAL_CHEST] = Location::Chest(RC_GANONS_CASTLE_MQ_WATER_TRIAL_CHEST, RCQUEST_MQ, RCTYPE_STANDARD, ACTOR_EN_BOX, SCENE_INSIDE_GANONS_CASTLE, 22977, 0x01, "MQ Water Trial Chest", RHT_GANONS_CASTLE_MQ_WATER_TRIAL_CHEST, RG_RED_RUPEE);
locationTable[RC_GANONS_CASTLE_MQ_FOREST_TRIAL_EYE_SWITCH_CHEST] = Location::Chest(RC_GANONS_CASTLE_MQ_FOREST_TRIAL_EYE_SWITCH_CHEST, RCQUEST_MQ, RCTYPE_STANDARD, ACTOR_EN_BOX, SCENE_INSIDE_GANONS_CASTLE, -30398, 0x02, "MQ Forest Trial Eye Switch Chest", RHT_GANONS_CASTLE_MQ_FOREST_TRIAL_EYE_SWITCH_CHEST, RG_ARROWS_10); locationTable[RC_GANONS_CASTLE_MQ_FOREST_TRIAL_EYE_SWITCH_CHEST] = Location::Chest(RC_GANONS_CASTLE_MQ_FOREST_TRIAL_EYE_SWITCH_CHEST, RCQUEST_MQ, RCTYPE_STANDARD, ACTOR_EN_BOX, SCENE_INSIDE_GANONS_CASTLE, -30398, 0x02, "MQ Forest Trial Eye Switch Chest", RHT_GANONS_CASTLE_MQ_FOREST_TRIAL_EYE_SWITCH_CHEST, RG_ARROWS_10);
@ -624,11 +634,11 @@ void Rando::StaticData::InitLocationTable() { //
locationTable[RC_GANONS_CASTLE_MQ_SPIRIT_TRIAL_FIRST_CHEST] = Location::Chest(RC_GANONS_CASTLE_MQ_SPIRIT_TRIAL_FIRST_CHEST, RCQUEST_MQ, RCTYPE_STANDARD, ACTOR_EN_BOX, SCENE_INSIDE_GANONS_CASTLE, 20586, 0x0A, "MQ Spirit Trial First Chest", RHT_GANONS_CASTLE_MQ_SPIRIT_TRIAL_FIRST_CHEST, RG_BOMBCHU_10); locationTable[RC_GANONS_CASTLE_MQ_SPIRIT_TRIAL_FIRST_CHEST] = Location::Chest(RC_GANONS_CASTLE_MQ_SPIRIT_TRIAL_FIRST_CHEST, RCQUEST_MQ, RCTYPE_STANDARD, ACTOR_EN_BOX, SCENE_INSIDE_GANONS_CASTLE, 20586, 0x0A, "MQ Spirit Trial First Chest", RHT_GANONS_CASTLE_MQ_SPIRIT_TRIAL_FIRST_CHEST, RG_BOMBCHU_10);
locationTable[RC_GANONS_CASTLE_MQ_SPIRIT_TRIAL_INVISIBLE_CHEST] = Location::Chest(RC_GANONS_CASTLE_MQ_SPIRIT_TRIAL_INVISIBLE_CHEST, RCQUEST_MQ, RCTYPE_STANDARD, ACTOR_EN_BOX, SCENE_INSIDE_GANONS_CASTLE, 26964, 0x14, "MQ Spirit Trial Invisible Chest", RHT_GANONS_CASTLE_MQ_SPIRIT_TRIAL_INVISIBLE_CHEST, RG_ARROWS_10); locationTable[RC_GANONS_CASTLE_MQ_SPIRIT_TRIAL_INVISIBLE_CHEST] = Location::Chest(RC_GANONS_CASTLE_MQ_SPIRIT_TRIAL_INVISIBLE_CHEST, RCQUEST_MQ, RCTYPE_STANDARD, ACTOR_EN_BOX, SCENE_INSIDE_GANONS_CASTLE, 26964, 0x14, "MQ Spirit Trial Invisible Chest", RHT_GANONS_CASTLE_MQ_SPIRIT_TRIAL_INVISIBLE_CHEST, RG_ARROWS_10);
locationTable[RC_GANONS_CASTLE_MQ_FOREST_TRIAL_FREESTANDING_KEY] = Location::Collectable(RC_GANONS_CASTLE_MQ_FOREST_TRIAL_FREESTANDING_KEY, RCQUEST_MQ, RCTYPE_SMALL_KEY, ACTOR_EN_ITEM00, SCENE_INSIDE_GANONS_CASTLE, 273, 0x01, "MQ Forest Trial Freestanding Key", RHT_GANONS_CASTLE_MQ_FOREST_TRIAL_FREESTANDING_KEY, RG_GANONS_CASTLE_SMALL_KEY, true); locationTable[RC_GANONS_CASTLE_MQ_FOREST_TRIAL_FREESTANDING_KEY] = Location::Collectable(RC_GANONS_CASTLE_MQ_FOREST_TRIAL_FREESTANDING_KEY, RCQUEST_MQ, RCTYPE_SMALL_KEY, ACTOR_EN_ITEM00, SCENE_INSIDE_GANONS_CASTLE, 273, 0x01, "MQ Forest Trial Freestanding Key", RHT_GANONS_CASTLE_MQ_FOREST_TRIAL_FREESTANDING_KEY, RG_GANONS_CASTLE_SMALL_KEY, true);
locationTable[RC_GANONS_CASTLE_MQ_DEKU_SCRUB_RIGHT] = Location::Base(RC_GANONS_CASTLE_MQ_DEKU_SCRUB_RIGHT, RCQUEST_MQ, RCTYPE_SCRUB, ACTOR_EN_DNS, SCENE_INSIDE_GANONS_CASTLE, 0x00, "MQ Deku Scrub Right", RHT_GANONS_CASTLE_MQ_DEKU_SCRUB_RIGHT, RG_BUY_DEKU_NUTS_5, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SCRUBS_PURCHASED_GANONS_CASTLE_MQ_DEKU_SCRUB_RIGHT)); locationTable[RC_GANONS_CASTLE_MQ_DEKU_SCRUB_RIGHT] = Location::Base(RC_GANONS_CASTLE_MQ_DEKU_SCRUB_RIGHT, RCQUEST_MQ, RCTYPE_SCRUB, ACTOR_EN_DNS, SCENE_INSIDE_GANONS_CASTLE, 0x00, "MQ Deku Scrub Right", RHT_GANONS_CASTLE_MQ_DEKU_SCRUB_RIGHT, RG_BUY_DEKU_NUTS_5, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SCRUBS_PURCHASED_GANONS_CASTLE_MQ_DEKU_SCRUB_RIGHT), false, 20);
locationTable[RC_GANONS_CASTLE_MQ_DEKU_SCRUB_CENTER_LEFT] = Location::Base(RC_GANONS_CASTLE_MQ_DEKU_SCRUB_CENTER_LEFT, RCQUEST_MQ, RCTYPE_SCRUB, ACTOR_EN_DNS, SCENE_INSIDE_GANONS_CASTLE, 0x05, "MQ Deku Scrub Center-Left", RHT_GANONS_CASTLE_MQ_DEKU_SCRUB_CENTER_LEFT, RG_BUY_BOMBS_535, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SCRUBS_PURCHASED_GANONS_CASTLE_MQ_DEKU_SCRUB_CENTER_LEFT)); locationTable[RC_GANONS_CASTLE_MQ_DEKU_SCRUB_CENTER_LEFT] = Location::Base(RC_GANONS_CASTLE_MQ_DEKU_SCRUB_CENTER_LEFT, RCQUEST_MQ, RCTYPE_SCRUB, ACTOR_EN_DNS, SCENE_INSIDE_GANONS_CASTLE, 0x05, "MQ Deku Scrub Center-Left", RHT_GANONS_CASTLE_MQ_DEKU_SCRUB_CENTER_LEFT, RG_BUY_BOMBS_535, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SCRUBS_PURCHASED_GANONS_CASTLE_MQ_DEKU_SCRUB_CENTER_LEFT), false, 40);
locationTable[RC_GANONS_CASTLE_MQ_DEKU_SCRUB_CENTER] = Location::Base(RC_GANONS_CASTLE_MQ_DEKU_SCRUB_CENTER, RCQUEST_MQ, RCTYPE_SCRUB, ACTOR_EN_DNS, SCENE_INSIDE_GANONS_CASTLE, 0x03, "MQ Deku Scrub Center", RHT_GANONS_CASTLE_MQ_DEKU_SCRUB_CENTER, RG_BUY_ARROWS_30, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SCRUBS_PURCHASED_GANONS_CASTLE_MQ_DEKU_SCRUB_CENTER)); locationTable[RC_GANONS_CASTLE_MQ_DEKU_SCRUB_CENTER] = Location::Base(RC_GANONS_CASTLE_MQ_DEKU_SCRUB_CENTER, RCQUEST_MQ, RCTYPE_SCRUB, ACTOR_EN_DNS, SCENE_INSIDE_GANONS_CASTLE, 0x03, "MQ Deku Scrub Center", RHT_GANONS_CASTLE_MQ_DEKU_SCRUB_CENTER, RG_BUY_ARROWS_30, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SCRUBS_PURCHASED_GANONS_CASTLE_MQ_DEKU_SCRUB_CENTER), false, 70);
locationTable[RC_GANONS_CASTLE_MQ_DEKU_SCRUB_CENTER_RIGHT] = Location::Base(RC_GANONS_CASTLE_MQ_DEKU_SCRUB_CENTER_RIGHT, RCQUEST_MQ, RCTYPE_SCRUB, ACTOR_EN_DNS, SCENE_INSIDE_GANONS_CASTLE, 0x07, "MQ Deku Scrub Center-Right", RHT_GANONS_CASTLE_MQ_DEKU_SCRUB_CENTER_RIGHT, RG_BUY_RED_POTION_30, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SCRUBS_PURCHASED_GANONS_CASTLE_MQ_DEKU_SCRUB_CENTER_RIGHT)); locationTable[RC_GANONS_CASTLE_MQ_DEKU_SCRUB_CENTER_RIGHT] = Location::Base(RC_GANONS_CASTLE_MQ_DEKU_SCRUB_CENTER_RIGHT, RCQUEST_MQ, RCTYPE_SCRUB, ACTOR_EN_DNS, SCENE_INSIDE_GANONS_CASTLE, 0x07, "MQ Deku Scrub Center-Right", RHT_GANONS_CASTLE_MQ_DEKU_SCRUB_CENTER_RIGHT, RG_BUY_RED_POTION_40, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SCRUBS_PURCHASED_GANONS_CASTLE_MQ_DEKU_SCRUB_CENTER_RIGHT), false, 40);
locationTable[RC_GANONS_CASTLE_MQ_DEKU_SCRUB_LEFT] = Location::Base(RC_GANONS_CASTLE_MQ_DEKU_SCRUB_LEFT, RCQUEST_MQ, RCTYPE_SCRUB, ACTOR_EN_DNS, SCENE_INSIDE_GANONS_CASTLE, 0x08, "MQ Deku Scrub Left", RHT_GANONS_CASTLE_MQ_DEKU_SCRUB_LEFT, RG_BUY_GREEN_POTION, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SCRUBS_PURCHASED_GANONS_CASTLE_MQ_DEKU_SCRUB_LEFT)); locationTable[RC_GANONS_CASTLE_MQ_DEKU_SCRUB_LEFT] = Location::Base(RC_GANONS_CASTLE_MQ_DEKU_SCRUB_LEFT, RCQUEST_MQ, RCTYPE_SCRUB, ACTOR_EN_DNS, SCENE_INSIDE_GANONS_CASTLE, 0x08, "MQ Deku Scrub Left", RHT_GANONS_CASTLE_MQ_DEKU_SCRUB_LEFT, RG_BUY_GREEN_POTION, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SCRUBS_PURCHASED_GANONS_CASTLE_MQ_DEKU_SCRUB_LEFT), false, 40);
// Gold Skulltula Tokens // Gold Skulltula Tokens
@ -901,78 +911,78 @@ void Rando::StaticData::InitLocationTable() { //
7 5 1 3 7 5 1 3
-------------------------------*/ -------------------------------*/
// Kokiri Forest // Kokiri Forest
locationTable[RC_KF_SHOP_ITEM_1] = Location::Base(RC_KF_SHOP_ITEM_1, RCQUEST_BOTH, RCTYPE_SHOP, ACTOR_EN_GIRLA, SCENE_KOKIRI_SHOP, 0x00, "Shop Item 1", RHT_KF_SHOP_ITEM_1, RG_BUY_DEKU_SHIELD); locationTable[RC_KF_SHOP_ITEM_1] = Location::Base(RC_KF_SHOP_ITEM_1, RCQUEST_BOTH, RCTYPE_SHOP, ACTOR_EN_GIRLA, SCENE_KOKIRI_SHOP, 0x00, "Shop Item 1", RHT_KF_SHOP_ITEM_1, RG_BUY_DEKU_SHIELD, SpoilerCollectionCheck(), false, 40);
locationTable[RC_KF_SHOP_ITEM_2] = Location::Base(RC_KF_SHOP_ITEM_2, RCQUEST_BOTH, RCTYPE_SHOP, ACTOR_EN_GIRLA, SCENE_KOKIRI_SHOP, 0x01, "Shop Item 2", RHT_KF_SHOP_ITEM_2, RG_BUY_DEKU_NUTS_5); locationTable[RC_KF_SHOP_ITEM_2] = Location::Base(RC_KF_SHOP_ITEM_2, RCQUEST_BOTH, RCTYPE_SHOP, ACTOR_EN_GIRLA, SCENE_KOKIRI_SHOP, 0x01, "Shop Item 2", RHT_KF_SHOP_ITEM_2, RG_BUY_DEKU_NUTS_5, SpoilerCollectionCheck(), false, 15);
locationTable[RC_KF_SHOP_ITEM_3] = Location::Base(RC_KF_SHOP_ITEM_3, RCQUEST_BOTH, RCTYPE_SHOP, ACTOR_EN_GIRLA, SCENE_KOKIRI_SHOP, 0x02, "Shop Item 3", RHT_KF_SHOP_ITEM_3, RG_BUY_DEKU_NUTS_10); locationTable[RC_KF_SHOP_ITEM_3] = Location::Base(RC_KF_SHOP_ITEM_3, RCQUEST_BOTH, RCTYPE_SHOP, ACTOR_EN_GIRLA, SCENE_KOKIRI_SHOP, 0x02, "Shop Item 3", RHT_KF_SHOP_ITEM_3, RG_BUY_DEKU_NUTS_10, SpoilerCollectionCheck(), false, 30);
locationTable[RC_KF_SHOP_ITEM_4] = Location::Base(RC_KF_SHOP_ITEM_4, RCQUEST_BOTH, RCTYPE_SHOP, ACTOR_EN_GIRLA, SCENE_KOKIRI_SHOP, 0x03, "Shop Item 4", RHT_KF_SHOP_ITEM_4, RG_BUY_DEKU_STICK_1); locationTable[RC_KF_SHOP_ITEM_4] = Location::Base(RC_KF_SHOP_ITEM_4, RCQUEST_BOTH, RCTYPE_SHOP, ACTOR_EN_GIRLA, SCENE_KOKIRI_SHOP, 0x03, "Shop Item 4", RHT_KF_SHOP_ITEM_4, RG_BUY_DEKU_STICK_1, SpoilerCollectionCheck(), false, 10);
locationTable[RC_KF_SHOP_ITEM_5] = Location::Base(RC_KF_SHOP_ITEM_5, RCQUEST_BOTH, RCTYPE_SHOP, ACTOR_EN_GIRLA, SCENE_KOKIRI_SHOP, 0x04, "Shop Item 5", RHT_KF_SHOP_ITEM_5, RG_BUY_DEKU_SEEDS_30); locationTable[RC_KF_SHOP_ITEM_5] = Location::Base(RC_KF_SHOP_ITEM_5, RCQUEST_BOTH, RCTYPE_SHOP, ACTOR_EN_GIRLA, SCENE_KOKIRI_SHOP, 0x04, "Shop Item 5", RHT_KF_SHOP_ITEM_5, RG_BUY_DEKU_SEEDS_30, SpoilerCollectionCheck(), false, 30);
locationTable[RC_KF_SHOP_ITEM_6] = Location::Base(RC_KF_SHOP_ITEM_6, RCQUEST_BOTH, RCTYPE_SHOP, ACTOR_EN_GIRLA, SCENE_KOKIRI_SHOP, 0x05, "Shop Item 6", RHT_KF_SHOP_ITEM_6, RG_BUY_ARROWS_10); locationTable[RC_KF_SHOP_ITEM_6] = Location::Base(RC_KF_SHOP_ITEM_6, RCQUEST_BOTH, RCTYPE_SHOP, ACTOR_EN_GIRLA, SCENE_KOKIRI_SHOP, 0x05, "Shop Item 6", RHT_KF_SHOP_ITEM_6, RG_BUY_ARROWS_10, SpoilerCollectionCheck(), false, 20);
locationTable[RC_KF_SHOP_ITEM_7] = Location::Base(RC_KF_SHOP_ITEM_7, RCQUEST_BOTH, RCTYPE_SHOP, ACTOR_EN_GIRLA, SCENE_KOKIRI_SHOP, 0x06, "Shop Item 7", RHT_KF_SHOP_ITEM_7, RG_BUY_ARROWS_30); locationTable[RC_KF_SHOP_ITEM_7] = Location::Base(RC_KF_SHOP_ITEM_7, RCQUEST_BOTH, RCTYPE_SHOP, ACTOR_EN_GIRLA, SCENE_KOKIRI_SHOP, 0x06, "Shop Item 7", RHT_KF_SHOP_ITEM_7, RG_BUY_ARROWS_30, SpoilerCollectionCheck(), false, 60);
locationTable[RC_KF_SHOP_ITEM_8] = Location::Base(RC_KF_SHOP_ITEM_8, RCQUEST_BOTH, RCTYPE_SHOP, ACTOR_EN_GIRLA, SCENE_KOKIRI_SHOP, 0x07, "Shop Item 8", RHT_KF_SHOP_ITEM_8, RG_BUY_HEART); locationTable[RC_KF_SHOP_ITEM_8] = Location::Base(RC_KF_SHOP_ITEM_8, RCQUEST_BOTH, RCTYPE_SHOP, ACTOR_EN_GIRLA, SCENE_KOKIRI_SHOP, 0x07, "Shop Item 8", RHT_KF_SHOP_ITEM_8, RG_BUY_HEART, SpoilerCollectionCheck(), false, 10);
// Kakariko Village // Kakariko Village
locationTable[RC_KAK_POTION_SHOP_ITEM_1] = Location::Base(RC_KAK_POTION_SHOP_ITEM_1, RCQUEST_BOTH, RCTYPE_SHOP, ACTOR_EN_GIRLA, SCENE_POTION_SHOP_KAKARIKO, 0x00, "Potion Shop Item 1", RHT_KAK_POTION_SHOP_ITEM_1, RG_BUY_GREEN_POTION); locationTable[RC_KAK_POTION_SHOP_ITEM_1] = Location::Base(RC_KAK_POTION_SHOP_ITEM_1, RCQUEST_BOTH, RCTYPE_SHOP, ACTOR_EN_GIRLA, SCENE_POTION_SHOP_KAKARIKO, 0x00, "Potion Shop Item 1", RHT_KAK_POTION_SHOP_ITEM_1, RG_BUY_GREEN_POTION, SpoilerCollectionCheck(), false, 30);
locationTable[RC_KAK_POTION_SHOP_ITEM_2] = Location::Base(RC_KAK_POTION_SHOP_ITEM_2, RCQUEST_BOTH, RCTYPE_SHOP, ACTOR_EN_GIRLA, SCENE_POTION_SHOP_KAKARIKO, 0x01, "Potion Shop Item 2", RHT_KAK_POTION_SHOP_ITEM_2, RG_BUY_BLUE_FIRE); locationTable[RC_KAK_POTION_SHOP_ITEM_2] = Location::Base(RC_KAK_POTION_SHOP_ITEM_2, RCQUEST_BOTH, RCTYPE_SHOP, ACTOR_EN_GIRLA, SCENE_POTION_SHOP_KAKARIKO, 0x01, "Potion Shop Item 2", RHT_KAK_POTION_SHOP_ITEM_2, RG_BUY_BLUE_FIRE, SpoilerCollectionCheck(), false, 300);
locationTable[RC_KAK_POTION_SHOP_ITEM_3] = Location::Base(RC_KAK_POTION_SHOP_ITEM_3, RCQUEST_BOTH, RCTYPE_SHOP, ACTOR_EN_GIRLA, SCENE_POTION_SHOP_KAKARIKO, 0x02, "Potion Shop Item 3", RHT_KAK_POTION_SHOP_ITEM_3, RG_BUY_RED_POTION_30); locationTable[RC_KAK_POTION_SHOP_ITEM_3] = Location::Base(RC_KAK_POTION_SHOP_ITEM_3, RCQUEST_BOTH, RCTYPE_SHOP, ACTOR_EN_GIRLA, SCENE_POTION_SHOP_KAKARIKO, 0x02, "Potion Shop Item 3", RHT_KAK_POTION_SHOP_ITEM_3, RG_BUY_RED_POTION_30, SpoilerCollectionCheck(), false, 30);
locationTable[RC_KAK_POTION_SHOP_ITEM_4] = Location::Base(RC_KAK_POTION_SHOP_ITEM_4, RCQUEST_BOTH, RCTYPE_SHOP, ACTOR_EN_GIRLA, SCENE_POTION_SHOP_KAKARIKO, 0x03, "Potion Shop Item 4", RHT_KAK_POTION_SHOP_ITEM_4, RG_BUY_FAIRYS_SPIRIT); locationTable[RC_KAK_POTION_SHOP_ITEM_4] = Location::Base(RC_KAK_POTION_SHOP_ITEM_4, RCQUEST_BOTH, RCTYPE_SHOP, ACTOR_EN_GIRLA, SCENE_POTION_SHOP_KAKARIKO, 0x03, "Potion Shop Item 4", RHT_KAK_POTION_SHOP_ITEM_4, RG_BUY_FAIRYS_SPIRIT, SpoilerCollectionCheck(), false, 50);
locationTable[RC_KAK_POTION_SHOP_ITEM_5] = Location::Base(RC_KAK_POTION_SHOP_ITEM_5, RCQUEST_BOTH, RCTYPE_SHOP, ACTOR_EN_GIRLA, SCENE_POTION_SHOP_KAKARIKO, 0x04, "Potion Shop Item 5", RHT_KAK_POTION_SHOP_ITEM_5, RG_BUY_DEKU_NUTS_5); locationTable[RC_KAK_POTION_SHOP_ITEM_5] = Location::Base(RC_KAK_POTION_SHOP_ITEM_5, RCQUEST_BOTH, RCTYPE_SHOP, ACTOR_EN_GIRLA, SCENE_POTION_SHOP_KAKARIKO, 0x04, "Potion Shop Item 5", RHT_KAK_POTION_SHOP_ITEM_5, RG_BUY_DEKU_NUTS_5, SpoilerCollectionCheck(), false, 15);
locationTable[RC_KAK_POTION_SHOP_ITEM_6] = Location::Base(RC_KAK_POTION_SHOP_ITEM_6, RCQUEST_BOTH, RCTYPE_SHOP, ACTOR_EN_GIRLA, SCENE_POTION_SHOP_KAKARIKO, 0x05, "Potion Shop Item 6", RHT_KAK_POTION_SHOP_ITEM_6, RG_BUY_BOTTLE_BUG); locationTable[RC_KAK_POTION_SHOP_ITEM_6] = Location::Base(RC_KAK_POTION_SHOP_ITEM_6, RCQUEST_BOTH, RCTYPE_SHOP, ACTOR_EN_GIRLA, SCENE_POTION_SHOP_KAKARIKO, 0x05, "Potion Shop Item 6", RHT_KAK_POTION_SHOP_ITEM_6, RG_BUY_BOTTLE_BUG, SpoilerCollectionCheck(), false, 50);
locationTable[RC_KAK_POTION_SHOP_ITEM_7] = Location::Base(RC_KAK_POTION_SHOP_ITEM_7, RCQUEST_BOTH, RCTYPE_SHOP, ACTOR_EN_GIRLA, SCENE_POTION_SHOP_KAKARIKO, 0x06, "Potion Shop Item 7", RHT_KAK_POTION_SHOP_ITEM_7, RG_BUY_POE); locationTable[RC_KAK_POTION_SHOP_ITEM_7] = Location::Base(RC_KAK_POTION_SHOP_ITEM_7, RCQUEST_BOTH, RCTYPE_SHOP, ACTOR_EN_GIRLA, SCENE_POTION_SHOP_KAKARIKO, 0x06, "Potion Shop Item 7", RHT_KAK_POTION_SHOP_ITEM_7, RG_BUY_POE, SpoilerCollectionCheck(), false, 30);
locationTable[RC_KAK_POTION_SHOP_ITEM_8] = Location::Base(RC_KAK_POTION_SHOP_ITEM_8, RCQUEST_BOTH, RCTYPE_SHOP, ACTOR_EN_GIRLA, SCENE_POTION_SHOP_KAKARIKO, 0x07, "Potion Shop Item 8", RHT_KAK_POTION_SHOP_ITEM_8, RG_BUY_FISH); locationTable[RC_KAK_POTION_SHOP_ITEM_8] = Location::Base(RC_KAK_POTION_SHOP_ITEM_8, RCQUEST_BOTH, RCTYPE_SHOP, ACTOR_EN_GIRLA, SCENE_POTION_SHOP_KAKARIKO, 0x07, "Potion Shop Item 8", RHT_KAK_POTION_SHOP_ITEM_8, RG_BUY_FISH, SpoilerCollectionCheck(), false, 200);
locationTable[RC_KAK_BAZAAR_ITEM_1] = Location::Base(RC_KAK_BAZAAR_ITEM_1, RCQUEST_BOTH, RCTYPE_SHOP, ACTOR_EN_GIRLA, SCENE_TEST01, 0x00, "Bazaar Item 1", RHT_KAK_BAZAAR_ITEM_1, RG_BUY_HYLIAN_SHIELD); locationTable[RC_KAK_BAZAAR_ITEM_1] = Location::Base(RC_KAK_BAZAAR_ITEM_1, RCQUEST_BOTH, RCTYPE_SHOP, ACTOR_EN_GIRLA, SCENE_TEST01, 0x00, "Bazaar Item 1", RHT_KAK_BAZAAR_ITEM_1, RG_BUY_HYLIAN_SHIELD, SpoilerCollectionCheck(), false, 80);
locationTable[RC_KAK_BAZAAR_ITEM_2] = Location::Base(RC_KAK_BAZAAR_ITEM_2, RCQUEST_BOTH, RCTYPE_SHOP, ACTOR_EN_GIRLA, SCENE_TEST01, 0x01, "Bazaar Item 2", RHT_KAK_BAZAAR_ITEM_2, RG_BUY_BOMBS_535); locationTable[RC_KAK_BAZAAR_ITEM_2] = Location::Base(RC_KAK_BAZAAR_ITEM_2, RCQUEST_BOTH, RCTYPE_SHOP, ACTOR_EN_GIRLA, SCENE_TEST01, 0x01, "Bazaar Item 2", RHT_KAK_BAZAAR_ITEM_2, RG_BUY_BOMBS_535, SpoilerCollectionCheck(), false, 35);
locationTable[RC_KAK_BAZAAR_ITEM_3] = Location::Base(RC_KAK_BAZAAR_ITEM_3, RCQUEST_BOTH, RCTYPE_SHOP, ACTOR_EN_GIRLA, SCENE_TEST01, 0x02, "Bazaar Item 3", RHT_KAK_BAZAAR_ITEM_3, RG_BUY_DEKU_NUTS_5); locationTable[RC_KAK_BAZAAR_ITEM_3] = Location::Base(RC_KAK_BAZAAR_ITEM_3, RCQUEST_BOTH, RCTYPE_SHOP, ACTOR_EN_GIRLA, SCENE_TEST01, 0x02, "Bazaar Item 3", RHT_KAK_BAZAAR_ITEM_3, RG_BUY_DEKU_NUTS_5, SpoilerCollectionCheck(), false, 10);
locationTable[RC_KAK_BAZAAR_ITEM_4] = Location::Base(RC_KAK_BAZAAR_ITEM_4, RCQUEST_BOTH, RCTYPE_SHOP, ACTOR_EN_GIRLA, SCENE_TEST01, 0x03, "Bazaar Item 4", RHT_KAK_BAZAAR_ITEM_4, RG_BUY_HEART); locationTable[RC_KAK_BAZAAR_ITEM_4] = Location::Base(RC_KAK_BAZAAR_ITEM_4, RCQUEST_BOTH, RCTYPE_SHOP, ACTOR_EN_GIRLA, SCENE_TEST01, 0x03, "Bazaar Item 4", RHT_KAK_BAZAAR_ITEM_4, RG_BUY_HEART, SpoilerCollectionCheck(), false, 20);
locationTable[RC_KAK_BAZAAR_ITEM_5] = Location::Base(RC_KAK_BAZAAR_ITEM_5, RCQUEST_BOTH, RCTYPE_SHOP, ACTOR_EN_GIRLA, SCENE_TEST01, 0x04, "Bazaar Item 5", RHT_KAK_BAZAAR_ITEM_5, RG_BUY_ARROWS_10); locationTable[RC_KAK_BAZAAR_ITEM_5] = Location::Base(RC_KAK_BAZAAR_ITEM_5, RCQUEST_BOTH, RCTYPE_SHOP, ACTOR_EN_GIRLA, SCENE_TEST01, 0x04, "Bazaar Item 5", RHT_KAK_BAZAAR_ITEM_5, RG_BUY_ARROWS_10, SpoilerCollectionCheck(), false, 20);
locationTable[RC_KAK_BAZAAR_ITEM_6] = Location::Base(RC_KAK_BAZAAR_ITEM_6, RCQUEST_BOTH, RCTYPE_SHOP, ACTOR_EN_GIRLA, SCENE_TEST01, 0x05, "Bazaar Item 6", RHT_KAK_BAZAAR_ITEM_6, RG_BUY_ARROWS_50); locationTable[RC_KAK_BAZAAR_ITEM_6] = Location::Base(RC_KAK_BAZAAR_ITEM_6, RCQUEST_BOTH, RCTYPE_SHOP, ACTOR_EN_GIRLA, SCENE_TEST01, 0x05, "Bazaar Item 6", RHT_KAK_BAZAAR_ITEM_6, RG_BUY_ARROWS_50, SpoilerCollectionCheck(), false, 90);
locationTable[RC_KAK_BAZAAR_ITEM_7] = Location::Base(RC_KAK_BAZAAR_ITEM_7, RCQUEST_BOTH, RCTYPE_SHOP, ACTOR_EN_GIRLA, SCENE_TEST01, 0x06, "Bazaar Item 7", RHT_KAK_BAZAAR_ITEM_7, RG_BUY_DEKU_STICK_1); locationTable[RC_KAK_BAZAAR_ITEM_7] = Location::Base(RC_KAK_BAZAAR_ITEM_7, RCQUEST_BOTH, RCTYPE_SHOP, ACTOR_EN_GIRLA, SCENE_TEST01, 0x06, "Bazaar Item 7", RHT_KAK_BAZAAR_ITEM_7, RG_BUY_DEKU_STICK_1, SpoilerCollectionCheck(), false, 10);
locationTable[RC_KAK_BAZAAR_ITEM_8] = Location::Base(RC_KAK_BAZAAR_ITEM_8, RCQUEST_BOTH, RCTYPE_SHOP, ACTOR_EN_GIRLA, SCENE_TEST01, 0x07, "Bazaar Item 8", RHT_KAK_BAZAAR_ITEM_8, RG_BUY_ARROWS_30); locationTable[RC_KAK_BAZAAR_ITEM_8] = Location::Base(RC_KAK_BAZAAR_ITEM_8, RCQUEST_BOTH, RCTYPE_SHOP, ACTOR_EN_GIRLA, SCENE_TEST01, 0x07, "Bazaar Item 8", RHT_KAK_BAZAAR_ITEM_8, RG_BUY_ARROWS_30, SpoilerCollectionCheck(), false, 60);
// Market // Market
locationTable[RC_MARKET_BOMBCHU_SHOP_ITEM_1] = Location::Base(RC_MARKET_BOMBCHU_SHOP_ITEM_1, RCQUEST_BOTH, RCTYPE_SHOP, ACTOR_EN_GIRLA, SCENE_BOMBCHU_SHOP, 0x00, "Bombchu Shop Item 1", RHT_MARKET_BOMBCHU_SHOP_ITEM_1, RG_BUY_BOMBCHUS_10); locationTable[RC_MARKET_BOMBCHU_SHOP_ITEM_1] = Location::Base(RC_MARKET_BOMBCHU_SHOP_ITEM_1, RCQUEST_BOTH, RCTYPE_SHOP, ACTOR_EN_GIRLA, SCENE_BOMBCHU_SHOP, 0x00, "Bombchu Shop Item 1", RHT_MARKET_BOMBCHU_SHOP_ITEM_1, RG_BUY_BOMBCHUS_10, SpoilerCollectionCheck(), false, 99);
locationTable[RC_MARKET_BOMBCHU_SHOP_ITEM_2] = Location::Base(RC_MARKET_BOMBCHU_SHOP_ITEM_2, RCQUEST_BOTH, RCTYPE_SHOP, ACTOR_EN_GIRLA, SCENE_BOMBCHU_SHOP, 0x01, "Bombchu Shop Item 2", RHT_MARKET_BOMBCHU_SHOP_ITEM_2, RG_BUY_BOMBCHUS_10); locationTable[RC_MARKET_BOMBCHU_SHOP_ITEM_2] = Location::Base(RC_MARKET_BOMBCHU_SHOP_ITEM_2, RCQUEST_BOTH, RCTYPE_SHOP, ACTOR_EN_GIRLA, SCENE_BOMBCHU_SHOP, 0x01, "Bombchu Shop Item 2", RHT_MARKET_BOMBCHU_SHOP_ITEM_2, RG_BUY_BOMBCHUS_10, SpoilerCollectionCheck(), false, 99);
locationTable[RC_MARKET_BOMBCHU_SHOP_ITEM_3] = Location::Base(RC_MARKET_BOMBCHU_SHOP_ITEM_3, RCQUEST_BOTH, RCTYPE_SHOP, ACTOR_EN_GIRLA, SCENE_BOMBCHU_SHOP, 0x02, "Bombchu Shop Item 3", RHT_MARKET_BOMBCHU_SHOP_ITEM_3, RG_BUY_BOMBCHUS_10); locationTable[RC_MARKET_BOMBCHU_SHOP_ITEM_3] = Location::Base(RC_MARKET_BOMBCHU_SHOP_ITEM_3, RCQUEST_BOTH, RCTYPE_SHOP, ACTOR_EN_GIRLA, SCENE_BOMBCHU_SHOP, 0x02, "Bombchu Shop Item 3", RHT_MARKET_BOMBCHU_SHOP_ITEM_3, RG_BUY_BOMBCHUS_10, SpoilerCollectionCheck(), false, 99);
locationTable[RC_MARKET_BOMBCHU_SHOP_ITEM_4] = Location::Base(RC_MARKET_BOMBCHU_SHOP_ITEM_4, RCQUEST_BOTH, RCTYPE_SHOP, ACTOR_EN_GIRLA, SCENE_BOMBCHU_SHOP, 0x03, "Bombchu Shop Item 4", RHT_MARKET_BOMBCHU_SHOP_ITEM_4, RG_BUY_BOMBCHUS_10); locationTable[RC_MARKET_BOMBCHU_SHOP_ITEM_4] = Location::Base(RC_MARKET_BOMBCHU_SHOP_ITEM_4, RCQUEST_BOTH, RCTYPE_SHOP, ACTOR_EN_GIRLA, SCENE_BOMBCHU_SHOP, 0x03, "Bombchu Shop Item 4", RHT_MARKET_BOMBCHU_SHOP_ITEM_4, RG_BUY_BOMBCHUS_10, SpoilerCollectionCheck(), false, 99);
locationTable[RC_MARKET_BOMBCHU_SHOP_ITEM_5] = Location::Base(RC_MARKET_BOMBCHU_SHOP_ITEM_5, RCQUEST_BOTH, RCTYPE_SHOP, ACTOR_EN_GIRLA, SCENE_BOMBCHU_SHOP, 0x04, "Bombchu Shop Item 5", RHT_MARKET_BOMBCHU_SHOP_ITEM_5, RG_BUY_BOMBCHUS_20); locationTable[RC_MARKET_BOMBCHU_SHOP_ITEM_5] = Location::Base(RC_MARKET_BOMBCHU_SHOP_ITEM_5, RCQUEST_BOTH, RCTYPE_SHOP, ACTOR_EN_GIRLA, SCENE_BOMBCHU_SHOP, 0x04, "Bombchu Shop Item 5", RHT_MARKET_BOMBCHU_SHOP_ITEM_5, RG_BUY_BOMBCHUS_20, SpoilerCollectionCheck(), false, 180);
locationTable[RC_MARKET_BOMBCHU_SHOP_ITEM_6] = Location::Base(RC_MARKET_BOMBCHU_SHOP_ITEM_6, RCQUEST_BOTH, RCTYPE_SHOP, ACTOR_EN_GIRLA, SCENE_BOMBCHU_SHOP, 0x05, "Bombchu Shop Item 6", RHT_MARKET_BOMBCHU_SHOP_ITEM_6, RG_BUY_BOMBCHUS_20); locationTable[RC_MARKET_BOMBCHU_SHOP_ITEM_6] = Location::Base(RC_MARKET_BOMBCHU_SHOP_ITEM_6, RCQUEST_BOTH, RCTYPE_SHOP, ACTOR_EN_GIRLA, SCENE_BOMBCHU_SHOP, 0x05, "Bombchu Shop Item 6", RHT_MARKET_BOMBCHU_SHOP_ITEM_6, RG_BUY_BOMBCHUS_20, SpoilerCollectionCheck(), false, 180);
locationTable[RC_MARKET_BOMBCHU_SHOP_ITEM_7] = Location::Base(RC_MARKET_BOMBCHU_SHOP_ITEM_7, RCQUEST_BOTH, RCTYPE_SHOP, ACTOR_EN_GIRLA, SCENE_BOMBCHU_SHOP, 0x06, "Bombchu Shop Item 7", RHT_MARKET_BOMBCHU_SHOP_ITEM_7, RG_BUY_BOMBCHUS_20); locationTable[RC_MARKET_BOMBCHU_SHOP_ITEM_7] = Location::Base(RC_MARKET_BOMBCHU_SHOP_ITEM_7, RCQUEST_BOTH, RCTYPE_SHOP, ACTOR_EN_GIRLA, SCENE_BOMBCHU_SHOP, 0x06, "Bombchu Shop Item 7", RHT_MARKET_BOMBCHU_SHOP_ITEM_7, RG_BUY_BOMBCHUS_20, SpoilerCollectionCheck(), false, 180);
locationTable[RC_MARKET_BOMBCHU_SHOP_ITEM_8] = Location::Base(RC_MARKET_BOMBCHU_SHOP_ITEM_8, RCQUEST_BOTH, RCTYPE_SHOP, ACTOR_EN_GIRLA, SCENE_BOMBCHU_SHOP, 0x07, "Bombchu Shop Item 8", RHT_MARKET_BOMBCHU_SHOP_ITEM_8, RG_BUY_BOMBCHUS_20); locationTable[RC_MARKET_BOMBCHU_SHOP_ITEM_8] = Location::Base(RC_MARKET_BOMBCHU_SHOP_ITEM_8, RCQUEST_BOTH, RCTYPE_SHOP, ACTOR_EN_GIRLA, SCENE_BOMBCHU_SHOP, 0x07, "Bombchu Shop Item 8", RHT_MARKET_BOMBCHU_SHOP_ITEM_8, RG_BUY_BOMBCHUS_20, SpoilerCollectionCheck(), false, 180);
locationTable[RC_MARKET_POTION_SHOP_ITEM_1] = Location::Base(RC_MARKET_POTION_SHOP_ITEM_1, RCQUEST_BOTH, RCTYPE_SHOP, ACTOR_EN_GIRLA, SCENE_POTION_SHOP_MARKET, 0x00, "Potion Shop Item 1", RHT_MARKET_POTION_SHOP_ITEM_1, RG_BUY_GREEN_POTION); locationTable[RC_MARKET_POTION_SHOP_ITEM_1] = Location::Base(RC_MARKET_POTION_SHOP_ITEM_1, RCQUEST_BOTH, RCTYPE_SHOP, ACTOR_EN_GIRLA, SCENE_POTION_SHOP_MARKET, 0x00, "Potion Shop Item 1", RHT_MARKET_POTION_SHOP_ITEM_1, RG_BUY_GREEN_POTION, SpoilerCollectionCheck(), false, 30);
locationTable[RC_MARKET_POTION_SHOP_ITEM_2] = Location::Base(RC_MARKET_POTION_SHOP_ITEM_2, RCQUEST_BOTH, RCTYPE_SHOP, ACTOR_EN_GIRLA, SCENE_POTION_SHOP_MARKET, 0x01, "Potion Shop Item 2", RHT_MARKET_POTION_SHOP_ITEM_2, RG_BUY_BLUE_FIRE); locationTable[RC_MARKET_POTION_SHOP_ITEM_2] = Location::Base(RC_MARKET_POTION_SHOP_ITEM_2, RCQUEST_BOTH, RCTYPE_SHOP, ACTOR_EN_GIRLA, SCENE_POTION_SHOP_MARKET, 0x01, "Potion Shop Item 2", RHT_MARKET_POTION_SHOP_ITEM_2, RG_BUY_BLUE_FIRE, SpoilerCollectionCheck(), false, 300);
locationTable[RC_MARKET_POTION_SHOP_ITEM_3] = Location::Base(RC_MARKET_POTION_SHOP_ITEM_3, RCQUEST_BOTH, RCTYPE_SHOP, ACTOR_EN_GIRLA, SCENE_POTION_SHOP_MARKET, 0x02, "Potion Shop Item 3", RHT_MARKET_POTION_SHOP_ITEM_3, RG_BUY_RED_POTION_30); locationTable[RC_MARKET_POTION_SHOP_ITEM_3] = Location::Base(RC_MARKET_POTION_SHOP_ITEM_3, RCQUEST_BOTH, RCTYPE_SHOP, ACTOR_EN_GIRLA, SCENE_POTION_SHOP_MARKET, 0x02, "Potion Shop Item 3", RHT_MARKET_POTION_SHOP_ITEM_3, RG_BUY_RED_POTION_30, SpoilerCollectionCheck(), false, 30);
locationTable[RC_MARKET_POTION_SHOP_ITEM_4] = Location::Base(RC_MARKET_POTION_SHOP_ITEM_4, RCQUEST_BOTH, RCTYPE_SHOP, ACTOR_EN_GIRLA, SCENE_POTION_SHOP_MARKET, 0x03, "Potion Shop Item 4", RHT_MARKET_POTION_SHOP_ITEM_4, RG_BUY_FAIRYS_SPIRIT); locationTable[RC_MARKET_POTION_SHOP_ITEM_4] = Location::Base(RC_MARKET_POTION_SHOP_ITEM_4, RCQUEST_BOTH, RCTYPE_SHOP, ACTOR_EN_GIRLA, SCENE_POTION_SHOP_MARKET, 0x03, "Potion Shop Item 4", RHT_MARKET_POTION_SHOP_ITEM_4, RG_BUY_FAIRYS_SPIRIT, SpoilerCollectionCheck(), false, 50);
locationTable[RC_MARKET_POTION_SHOP_ITEM_5] = Location::Base(RC_MARKET_POTION_SHOP_ITEM_5, RCQUEST_BOTH, RCTYPE_SHOP, ACTOR_EN_GIRLA, SCENE_POTION_SHOP_MARKET, 0x04, "Potion Shop Item 5", RHT_MARKET_POTION_SHOP_ITEM_5, RG_BUY_DEKU_NUTS_5); locationTable[RC_MARKET_POTION_SHOP_ITEM_5] = Location::Base(RC_MARKET_POTION_SHOP_ITEM_5, RCQUEST_BOTH, RCTYPE_SHOP, ACTOR_EN_GIRLA, SCENE_POTION_SHOP_MARKET, 0x04, "Potion Shop Item 5", RHT_MARKET_POTION_SHOP_ITEM_5, RG_BUY_DEKU_NUTS_5, SpoilerCollectionCheck(), false, 15);
locationTable[RC_MARKET_POTION_SHOP_ITEM_6] = Location::Base(RC_MARKET_POTION_SHOP_ITEM_6, RCQUEST_BOTH, RCTYPE_SHOP, ACTOR_EN_GIRLA, SCENE_POTION_SHOP_MARKET, 0x05, "Potion Shop Item 6", RHT_MARKET_POTION_SHOP_ITEM_6, RG_BUY_BOTTLE_BUG); locationTable[RC_MARKET_POTION_SHOP_ITEM_6] = Location::Base(RC_MARKET_POTION_SHOP_ITEM_6, RCQUEST_BOTH, RCTYPE_SHOP, ACTOR_EN_GIRLA, SCENE_POTION_SHOP_MARKET, 0x05, "Potion Shop Item 6", RHT_MARKET_POTION_SHOP_ITEM_6, RG_BUY_BOTTLE_BUG, SpoilerCollectionCheck(), false, 50);
locationTable[RC_MARKET_POTION_SHOP_ITEM_7] = Location::Base(RC_MARKET_POTION_SHOP_ITEM_7, RCQUEST_BOTH, RCTYPE_SHOP, ACTOR_EN_GIRLA, SCENE_POTION_SHOP_MARKET, 0x06, "Potion Shop Item 7", RHT_MARKET_POTION_SHOP_ITEM_7, RG_BUY_POE); locationTable[RC_MARKET_POTION_SHOP_ITEM_7] = Location::Base(RC_MARKET_POTION_SHOP_ITEM_7, RCQUEST_BOTH, RCTYPE_SHOP, ACTOR_EN_GIRLA, SCENE_POTION_SHOP_MARKET, 0x06, "Potion Shop Item 7", RHT_MARKET_POTION_SHOP_ITEM_7, RG_BUY_POE, SpoilerCollectionCheck(), false, 30);
locationTable[RC_MARKET_POTION_SHOP_ITEM_8] = Location::Base(RC_MARKET_POTION_SHOP_ITEM_8, RCQUEST_BOTH, RCTYPE_SHOP, ACTOR_EN_GIRLA, SCENE_POTION_SHOP_MARKET, 0x07, "Potion Shop Item 8", RHT_MARKET_POTION_SHOP_ITEM_8, RG_BUY_FISH); locationTable[RC_MARKET_POTION_SHOP_ITEM_8] = Location::Base(RC_MARKET_POTION_SHOP_ITEM_8, RCQUEST_BOTH, RCTYPE_SHOP, ACTOR_EN_GIRLA, SCENE_POTION_SHOP_MARKET, 0x07, "Potion Shop Item 8", RHT_MARKET_POTION_SHOP_ITEM_8, RG_BUY_FISH, SpoilerCollectionCheck(), false, 200);
locationTable[RC_MARKET_BAZAAR_ITEM_1] = Location::Base(RC_MARKET_BAZAAR_ITEM_1, RCQUEST_BOTH, RCTYPE_SHOP, RCAREA_MARKET, ACTOR_EN_GIRLA, SCENE_BAZAAR, 0x00, "Bazaar Item 1", RHT_MARKET_BAZAAR_ITEM_1, RG_BUY_HYLIAN_SHIELD); locationTable[RC_MARKET_BAZAAR_ITEM_1] = Location::Base(RC_MARKET_BAZAAR_ITEM_1, RCQUEST_BOTH, RCTYPE_SHOP, RCAREA_MARKET, ACTOR_EN_GIRLA, SCENE_BAZAAR, 0x00, "Bazaar Item 1", RHT_MARKET_BAZAAR_ITEM_1, RG_BUY_HYLIAN_SHIELD, SpoilerCollectionCheck(), false, 80);
locationTable[RC_MARKET_BAZAAR_ITEM_2] = Location::Base(RC_MARKET_BAZAAR_ITEM_2, RCQUEST_BOTH, RCTYPE_SHOP, RCAREA_MARKET, ACTOR_EN_GIRLA, SCENE_BAZAAR, 0x01, "Bazaar Item 2", RHT_MARKET_BAZAAR_ITEM_2, RG_BUY_BOMBS_535); locationTable[RC_MARKET_BAZAAR_ITEM_2] = Location::Base(RC_MARKET_BAZAAR_ITEM_2, RCQUEST_BOTH, RCTYPE_SHOP, RCAREA_MARKET, ACTOR_EN_GIRLA, SCENE_BAZAAR, 0x01, "Bazaar Item 2", RHT_MARKET_BAZAAR_ITEM_2, RG_BUY_BOMBS_535, SpoilerCollectionCheck(), false, 35);
locationTable[RC_MARKET_BAZAAR_ITEM_3] = Location::Base(RC_MARKET_BAZAAR_ITEM_3, RCQUEST_BOTH, RCTYPE_SHOP, RCAREA_MARKET, ACTOR_EN_GIRLA, SCENE_BAZAAR, 0x02, "Bazaar Item 3", RHT_MARKET_BAZAAR_ITEM_3, RG_BUY_DEKU_NUTS_5); locationTable[RC_MARKET_BAZAAR_ITEM_3] = Location::Base(RC_MARKET_BAZAAR_ITEM_3, RCQUEST_BOTH, RCTYPE_SHOP, RCAREA_MARKET, ACTOR_EN_GIRLA, SCENE_BAZAAR, 0x02, "Bazaar Item 3", RHT_MARKET_BAZAAR_ITEM_3, RG_BUY_DEKU_NUTS_5, SpoilerCollectionCheck(), false, 15);
locationTable[RC_MARKET_BAZAAR_ITEM_4] = Location::Base(RC_MARKET_BAZAAR_ITEM_4, RCQUEST_BOTH, RCTYPE_SHOP, RCAREA_MARKET, ACTOR_EN_GIRLA, SCENE_BAZAAR, 0x03, "Bazaar Item 4", RHT_MARKET_BAZAAR_ITEM_4, RG_BUY_HEART); locationTable[RC_MARKET_BAZAAR_ITEM_4] = Location::Base(RC_MARKET_BAZAAR_ITEM_4, RCQUEST_BOTH, RCTYPE_SHOP, RCAREA_MARKET, ACTOR_EN_GIRLA, SCENE_BAZAAR, 0x03, "Bazaar Item 4", RHT_MARKET_BAZAAR_ITEM_4, RG_BUY_HEART, SpoilerCollectionCheck(), false, 10);
locationTable[RC_MARKET_BAZAAR_ITEM_5] = Location::Base(RC_MARKET_BAZAAR_ITEM_5, RCQUEST_BOTH, RCTYPE_SHOP, RCAREA_MARKET, ACTOR_EN_GIRLA, SCENE_BAZAAR, 0x04, "Bazaar Item 5", RHT_MARKET_BAZAAR_ITEM_5, RG_BUY_ARROWS_10); locationTable[RC_MARKET_BAZAAR_ITEM_5] = Location::Base(RC_MARKET_BAZAAR_ITEM_5, RCQUEST_BOTH, RCTYPE_SHOP, RCAREA_MARKET, ACTOR_EN_GIRLA, SCENE_BAZAAR, 0x04, "Bazaar Item 5", RHT_MARKET_BAZAAR_ITEM_5, RG_BUY_ARROWS_10, SpoilerCollectionCheck(), false, 20);
locationTable[RC_MARKET_BAZAAR_ITEM_6] = Location::Base(RC_MARKET_BAZAAR_ITEM_6, RCQUEST_BOTH, RCTYPE_SHOP, RCAREA_MARKET, ACTOR_EN_GIRLA, SCENE_BAZAAR, 0x05, "Bazaar Item 6", RHT_MARKET_BAZAAR_ITEM_6, RG_BUY_ARROWS_50); locationTable[RC_MARKET_BAZAAR_ITEM_6] = Location::Base(RC_MARKET_BAZAAR_ITEM_6, RCQUEST_BOTH, RCTYPE_SHOP, RCAREA_MARKET, ACTOR_EN_GIRLA, SCENE_BAZAAR, 0x05, "Bazaar Item 6", RHT_MARKET_BAZAAR_ITEM_6, RG_BUY_ARROWS_50, SpoilerCollectionCheck(), false, 90);
locationTable[RC_MARKET_BAZAAR_ITEM_7] = Location::Base(RC_MARKET_BAZAAR_ITEM_7, RCQUEST_BOTH, RCTYPE_SHOP, RCAREA_MARKET, ACTOR_EN_GIRLA, SCENE_BAZAAR, 0x06, "Bazaar Item 7", RHT_MARKET_BAZAAR_ITEM_7, RG_BUY_DEKU_STICK_1); locationTable[RC_MARKET_BAZAAR_ITEM_7] = Location::Base(RC_MARKET_BAZAAR_ITEM_7, RCQUEST_BOTH, RCTYPE_SHOP, RCAREA_MARKET, ACTOR_EN_GIRLA, SCENE_BAZAAR, 0x06, "Bazaar Item 7", RHT_MARKET_BAZAAR_ITEM_7, RG_BUY_DEKU_STICK_1, SpoilerCollectionCheck(), false, 10);
locationTable[RC_MARKET_BAZAAR_ITEM_8] = Location::Base(RC_MARKET_BAZAAR_ITEM_8, RCQUEST_BOTH, RCTYPE_SHOP, RCAREA_MARKET, ACTOR_EN_GIRLA, SCENE_BAZAAR, 0x07, "Bazaar Item 8", RHT_MARKET_BAZAAR_ITEM_8, RG_BUY_ARROWS_30); locationTable[RC_MARKET_BAZAAR_ITEM_8] = Location::Base(RC_MARKET_BAZAAR_ITEM_8, RCQUEST_BOTH, RCTYPE_SHOP, RCAREA_MARKET, ACTOR_EN_GIRLA, SCENE_BAZAAR, 0x07, "Bazaar Item 8", RHT_MARKET_BAZAAR_ITEM_8, RG_BUY_ARROWS_30, SpoilerCollectionCheck(), false, 60);
// Zora's Domain // Zora's Domain
locationTable[RC_ZD_SHOP_ITEM_1] = Location::Base(RC_ZD_SHOP_ITEM_1, RCQUEST_BOTH, RCTYPE_SHOP, ACTOR_EN_GIRLA, SCENE_ZORA_SHOP, 0x00, "Shop Item 1", RHT_ZD_SHOP_ITEM_1, RG_BUY_ZORA_TUNIC); locationTable[RC_ZD_SHOP_ITEM_1] = Location::Base(RC_ZD_SHOP_ITEM_1, RCQUEST_BOTH, RCTYPE_SHOP, ACTOR_EN_GIRLA, SCENE_ZORA_SHOP, 0x00, "Shop Item 1", RHT_ZD_SHOP_ITEM_1, RG_BUY_ZORA_TUNIC, SpoilerCollectionCheck(), false, 200);
locationTable[RC_ZD_SHOP_ITEM_2] = Location::Base(RC_ZD_SHOP_ITEM_2, RCQUEST_BOTH, RCTYPE_SHOP, ACTOR_EN_GIRLA, SCENE_ZORA_SHOP, 0x01, "Shop Item 2", RHT_ZD_SHOP_ITEM_2, RG_BUY_ARROWS_10); locationTable[RC_ZD_SHOP_ITEM_2] = Location::Base(RC_ZD_SHOP_ITEM_2, RCQUEST_BOTH, RCTYPE_SHOP, ACTOR_EN_GIRLA, SCENE_ZORA_SHOP, 0x01, "Shop Item 2", RHT_ZD_SHOP_ITEM_2, RG_BUY_ARROWS_10, SpoilerCollectionCheck(), false, 20);
locationTable[RC_ZD_SHOP_ITEM_3] = Location::Base(RC_ZD_SHOP_ITEM_3, RCQUEST_BOTH, RCTYPE_SHOP, ACTOR_EN_GIRLA, SCENE_ZORA_SHOP, 0x02, "Shop Item 3", RHT_ZD_SHOP_ITEM_3, RG_BUY_HEART); locationTable[RC_ZD_SHOP_ITEM_3] = Location::Base(RC_ZD_SHOP_ITEM_3, RCQUEST_BOTH, RCTYPE_SHOP, ACTOR_EN_GIRLA, SCENE_ZORA_SHOP, 0x02, "Shop Item 3", RHT_ZD_SHOP_ITEM_3, RG_BUY_HEART, SpoilerCollectionCheck(), false, 10);
locationTable[RC_ZD_SHOP_ITEM_4] = Location::Base(RC_ZD_SHOP_ITEM_4, RCQUEST_BOTH, RCTYPE_SHOP, ACTOR_EN_GIRLA, SCENE_ZORA_SHOP, 0x03, "Shop Item 4", RHT_ZD_SHOP_ITEM_4, RG_BUY_ARROWS_30); locationTable[RC_ZD_SHOP_ITEM_4] = Location::Base(RC_ZD_SHOP_ITEM_4, RCQUEST_BOTH, RCTYPE_SHOP, ACTOR_EN_GIRLA, SCENE_ZORA_SHOP, 0x03, "Shop Item 4", RHT_ZD_SHOP_ITEM_4, RG_BUY_ARROWS_30, SpoilerCollectionCheck(), false, 60);
locationTable[RC_ZD_SHOP_ITEM_5] = Location::Base(RC_ZD_SHOP_ITEM_5, RCQUEST_BOTH, RCTYPE_SHOP, ACTOR_EN_GIRLA, SCENE_ZORA_SHOP, 0x04, "Shop Item 5", RHT_ZD_SHOP_ITEM_5, RG_BUY_DEKU_NUTS_5); locationTable[RC_ZD_SHOP_ITEM_5] = Location::Base(RC_ZD_SHOP_ITEM_5, RCQUEST_BOTH, RCTYPE_SHOP, ACTOR_EN_GIRLA, SCENE_ZORA_SHOP, 0x04, "Shop Item 5", RHT_ZD_SHOP_ITEM_5, RG_BUY_DEKU_NUTS_5, SpoilerCollectionCheck(), false, 15);
locationTable[RC_ZD_SHOP_ITEM_6] = Location::Base(RC_ZD_SHOP_ITEM_6, RCQUEST_BOTH, RCTYPE_SHOP, ACTOR_EN_GIRLA, SCENE_ZORA_SHOP, 0x05, "Shop Item 6", RHT_ZD_SHOP_ITEM_6, RG_BUY_ARROWS_50); locationTable[RC_ZD_SHOP_ITEM_6] = Location::Base(RC_ZD_SHOP_ITEM_6, RCQUEST_BOTH, RCTYPE_SHOP, ACTOR_EN_GIRLA, SCENE_ZORA_SHOP, 0x05, "Shop Item 6", RHT_ZD_SHOP_ITEM_6, RG_BUY_ARROWS_50, SpoilerCollectionCheck(), false, 90);
locationTable[RC_ZD_SHOP_ITEM_7] = Location::Base(RC_ZD_SHOP_ITEM_7, RCQUEST_BOTH, RCTYPE_SHOP, ACTOR_EN_GIRLA, SCENE_ZORA_SHOP, 0x06, "Shop Item 7", RHT_ZD_SHOP_ITEM_7, RG_BUY_FISH); locationTable[RC_ZD_SHOP_ITEM_7] = Location::Base(RC_ZD_SHOP_ITEM_7, RCQUEST_BOTH, RCTYPE_SHOP, ACTOR_EN_GIRLA, SCENE_ZORA_SHOP, 0x06, "Shop Item 7", RHT_ZD_SHOP_ITEM_7, RG_BUY_FISH, SpoilerCollectionCheck(), false, 200);
locationTable[RC_ZD_SHOP_ITEM_8] = Location::Base(RC_ZD_SHOP_ITEM_8, RCQUEST_BOTH, RCTYPE_SHOP, ACTOR_EN_GIRLA, SCENE_ZORA_SHOP, 0x07, "Shop Item 8", RHT_ZD_SHOP_ITEM_8, RG_BUY_RED_POTION_50); locationTable[RC_ZD_SHOP_ITEM_8] = Location::Base(RC_ZD_SHOP_ITEM_8, RCQUEST_BOTH, RCTYPE_SHOP, ACTOR_EN_GIRLA, SCENE_ZORA_SHOP, 0x07, "Shop Item 8", RHT_ZD_SHOP_ITEM_8, RG_BUY_RED_POTION_50, SpoilerCollectionCheck(), false, 50);
// Goron City // Goron City
locationTable[RC_GC_SHOP_ITEM_1] = Location::Base(RC_GC_SHOP_ITEM_1, RCQUEST_BOTH, RCTYPE_SHOP, ACTOR_EN_GIRLA, SCENE_GORON_SHOP, 0x00, "Shop Item 1", RHT_GC_SHOP_ITEM_1, RG_BUY_BOMBS_525); locationTable[RC_GC_SHOP_ITEM_1] = Location::Base(RC_GC_SHOP_ITEM_1, RCQUEST_BOTH, RCTYPE_SHOP, ACTOR_EN_GIRLA, SCENE_GORON_SHOP, 0x00, "Shop Item 1", RHT_GC_SHOP_ITEM_1, RG_BUY_BOMBS_525, SpoilerCollectionCheck(), false, 25);
locationTable[RC_GC_SHOP_ITEM_2] = Location::Base(RC_GC_SHOP_ITEM_2, RCQUEST_BOTH, RCTYPE_SHOP, ACTOR_EN_GIRLA, SCENE_GORON_SHOP, 0x01, "Shop Item 2", RHT_GC_SHOP_ITEM_2, RG_BUY_BOMBS_10); locationTable[RC_GC_SHOP_ITEM_2] = Location::Base(RC_GC_SHOP_ITEM_2, RCQUEST_BOTH, RCTYPE_SHOP, ACTOR_EN_GIRLA, SCENE_GORON_SHOP, 0x01, "Shop Item 2", RHT_GC_SHOP_ITEM_2, RG_BUY_BOMBS_10, SpoilerCollectionCheck(), false, 50);
locationTable[RC_GC_SHOP_ITEM_3] = Location::Base(RC_GC_SHOP_ITEM_3, RCQUEST_BOTH, RCTYPE_SHOP, ACTOR_EN_GIRLA, SCENE_GORON_SHOP, 0x02, "Shop Item 3", RHT_GC_SHOP_ITEM_3, RG_BUY_BOMBS_20); locationTable[RC_GC_SHOP_ITEM_3] = Location::Base(RC_GC_SHOP_ITEM_3, RCQUEST_BOTH, RCTYPE_SHOP, ACTOR_EN_GIRLA, SCENE_GORON_SHOP, 0x02, "Shop Item 3", RHT_GC_SHOP_ITEM_3, RG_BUY_BOMBS_20, SpoilerCollectionCheck(), false, 80);
locationTable[RC_GC_SHOP_ITEM_4] = Location::Base(RC_GC_SHOP_ITEM_4, RCQUEST_BOTH, RCTYPE_SHOP, ACTOR_EN_GIRLA, SCENE_GORON_SHOP, 0x03, "Shop Item 4", RHT_GC_SHOP_ITEM_4, RG_BUY_BOMBS_30); locationTable[RC_GC_SHOP_ITEM_4] = Location::Base(RC_GC_SHOP_ITEM_4, RCQUEST_BOTH, RCTYPE_SHOP, ACTOR_EN_GIRLA, SCENE_GORON_SHOP, 0x03, "Shop Item 4", RHT_GC_SHOP_ITEM_4, RG_BUY_BOMBS_30, SpoilerCollectionCheck(), false, 120);
locationTable[RC_GC_SHOP_ITEM_5] = Location::Base(RC_GC_SHOP_ITEM_5, RCQUEST_BOTH, RCTYPE_SHOP, ACTOR_EN_GIRLA, SCENE_GORON_SHOP, 0x04, "Shop Item 5", RHT_GC_SHOP_ITEM_5, RG_BUY_GORON_TUNIC); locationTable[RC_GC_SHOP_ITEM_5] = Location::Base(RC_GC_SHOP_ITEM_5, RCQUEST_BOTH, RCTYPE_SHOP, ACTOR_EN_GIRLA, SCENE_GORON_SHOP, 0x04, "Shop Item 5", RHT_GC_SHOP_ITEM_5, RG_BUY_GORON_TUNIC, SpoilerCollectionCheck(), false, 200);
locationTable[RC_GC_SHOP_ITEM_6] = Location::Base(RC_GC_SHOP_ITEM_6, RCQUEST_BOTH, RCTYPE_SHOP, ACTOR_EN_GIRLA, SCENE_GORON_SHOP, 0x05, "Shop Item 6", RHT_GC_SHOP_ITEM_6, RG_BUY_HEART); locationTable[RC_GC_SHOP_ITEM_6] = Location::Base(RC_GC_SHOP_ITEM_6, RCQUEST_BOTH, RCTYPE_SHOP, ACTOR_EN_GIRLA, SCENE_GORON_SHOP, 0x05, "Shop Item 6", RHT_GC_SHOP_ITEM_6, RG_BUY_HEART, SpoilerCollectionCheck(), false, 10);
locationTable[RC_GC_SHOP_ITEM_7] = Location::Base(RC_GC_SHOP_ITEM_7, RCQUEST_BOTH, RCTYPE_SHOP, ACTOR_EN_GIRLA, SCENE_GORON_SHOP, 0x06, "Shop Item 7", RHT_GC_SHOP_ITEM_7, RG_BUY_RED_POTION_40); locationTable[RC_GC_SHOP_ITEM_7] = Location::Base(RC_GC_SHOP_ITEM_7, RCQUEST_BOTH, RCTYPE_SHOP, ACTOR_EN_GIRLA, SCENE_GORON_SHOP, 0x06, "Shop Item 7", RHT_GC_SHOP_ITEM_7, RG_BUY_RED_POTION_40, SpoilerCollectionCheck(), false, 40);
locationTable[RC_GC_SHOP_ITEM_8] = Location::Base(RC_GC_SHOP_ITEM_8, RCQUEST_BOTH, RCTYPE_SHOP, ACTOR_EN_GIRLA, SCENE_GORON_SHOP, 0x07, "Shop Item 8", RHT_GC_SHOP_ITEM_8, RG_BUY_HEART); locationTable[RC_GC_SHOP_ITEM_8] = Location::Base(RC_GC_SHOP_ITEM_8, RCQUEST_BOTH, RCTYPE_SHOP, ACTOR_EN_GIRLA, SCENE_GORON_SHOP, 0x07, "Shop Item 8", RHT_GC_SHOP_ITEM_8, RG_BUY_HEART, SpoilerCollectionCheck(), false, 10);
/* +--------------+ /* +--------------+
| FISHSANITY | | FISHSANITY |
@ -1084,7 +1094,7 @@ void Rando::StaticData::InitLocationTable() { //
locationTable[RC_TOT_SHEIK_HINT] = Location::OtherHint(RC_TOT_SHEIK_HINT, RCQUEST_BOTH, ACTOR_EN_XC, SCENE_TEMPLE_OF_TIME, "Ocarina of Time Hint"); locationTable[RC_TOT_SHEIK_HINT] = Location::OtherHint(RC_TOT_SHEIK_HINT, RCQUEST_BOTH, ACTOR_EN_XC, SCENE_TEMPLE_OF_TIME, "Ocarina of Time Hint");
locationTable[RC_MASK_SHOP_HINT] = Location::OtherHint(RC_MASK_SHOP_HINT, RCQUEST_BOTH, ACTOR_ID_MAX, SCENE_HAPPY_MASK_SHOP, "Mask Shop Hint"); locationTable[RC_MASK_SHOP_HINT] = Location::OtherHint(RC_MASK_SHOP_HINT, RCQUEST_BOTH, ACTOR_ID_MAX, SCENE_HAPPY_MASK_SHOP, "Mask Shop Hint");
locationTable[RC_TRIFORCE_COMPLETED] = Location::Base(RC_TRIFORCE_COMPLETED, RCQUEST_BOTH, RCTYPE_STANDARD, RCAREA_MARKET, ACTOR_ID_MAX, SCENE_ID_MAX, 0x00, "Completed Triforce", "Completed Triforce", RHT_NONE, RG_NONE); locationTable[RC_TRIFORCE_COMPLETED] = Location::Base(RC_TRIFORCE_COMPLETED, RCQUEST_BOTH, RCTYPE_STANDARD, RCAREA_MARKET, ACTOR_ID_MAX, SCENE_ID_MAX, 0x00, "Completed Triforce", "Completed Triforce", RHT_NONE, RG_NONE);
// clang-format on // clang-format on
// Init locationNameToEnum // Init locationNameToEnum

View File

@ -218,6 +218,8 @@ void Settings::CreateOptionDescriptions() {
"Enabling this shuffles the Child's Wallet into the item pool.\n" "Enabling this shuffles the Child's Wallet into the item pool.\n"
"\n" "\n"
"You will not be able to carry any rupees until you find a wallet."; "You will not be able to carry any rupees until you find a wallet.";
mOptionDescriptions[RSK_INCLUDE_TYCOON_WALLET] =
"Enabling this adds an extra Progressive Wallet to the pool and adds a new 999 capacity tier after Giant's Wallet.\n";
mOptionDescriptions[RSK_SHUFFLE_OCARINA] = mOptionDescriptions[RSK_SHUFFLE_OCARINA] =
"Enabling this shuffles the Fairy Ocarina and the Ocarina of Time into the item pool.\n" "Enabling this shuffles the Fairy Ocarina and the Ocarina of Time into the item pool.\n"
"\n" "\n"
@ -277,12 +279,31 @@ void Settings::CreateOptionDescriptions() {
"8 Items - All shops will contain 8 non-vanilla shop items.\n" "8 Items - All shops will contain 8 non-vanilla shop items.\n"
*/; */;
mOptionDescriptions[RSK_SHOPSANITY_PRICES] = mOptionDescriptions[RSK_SHOPSANITY_PRICES] =
"Balanced - The default randomization. Shop prices for shopsanity items will range between 0 to 300 rupees, " "Vanilla - The same price as the item it replaced\n"
"with a bias towards values slightly below the middle of the range, in multiples of 5.\n " "Cheap Balanced - Prices will range between 0 to 95 rupees, favoring lower numbers\n"
"\n" "Balanced - Prices will range between 0 to 300 rupees, favoring lower numbers\n"
"X Wallet - Randomized between 5 and the wallet's max size, in multiples of 5"; "Fixed - A fixed number\n"
"Range - A random point between specific ranges\n"
"Set By Wallet - Set weights that decide the choice of each wallet, and get a random price in that range if that wallet is chosen";
mOptionDescriptions[RSK_SHOPSANITY_PRICES_FIXED_PRICE] =
"The price for Shopsanity checks.";
mOptionDescriptions[RSK_SHOPSANITY_PRICES_RANGE_1] =
"The first part of the inclusive range of prices to allow for Shopsanity checks.";
mOptionDescriptions[RSK_SHOPSANITY_PRICES_RANGE_2] =
"The second part of the inclusive range of prices to allow for Shopsanity checks.";
mOptionDescriptions[RSK_SHOPSANITY_PRICES_NO_WALLET_WEIGHT] =
"The chance for Shopsanity checks to be free.";
mOptionDescriptions[RSK_SHOPSANITY_PRICES_CHILD_WALLET_WEIGHT] =
"The chance for Shopsanity checks to be purchasable with Child's Wallet (1-99).";
mOptionDescriptions[RSK_SHOPSANITY_PRICES_ADULT_WALLET_WEIGHT] =
"The chance for Shopsanity checks to be purchasable with Adult's Wallet (100-200).";
mOptionDescriptions[RSK_SHOPSANITY_PRICES_GIANT_WALLET_WEIGHT] =
"The chance for Shopsanity checks to be purchasable with Giant's Wallet (201-500).";
mOptionDescriptions[RSK_SHOPSANITY_PRICES_TYCOON_WALLET_WEIGHT] =
"The chance for Shopsanity checks to be purchasable with Tycoon Wallet. (500+)";
mOptionDescriptions[RSK_SHOPSANITY_PRICES_AFFORDABLE] = mOptionDescriptions[RSK_SHOPSANITY_PRICES_AFFORDABLE] =
"Affordable prices per tier: starter = 10, adult = 105, giant = 205, tycoon = 505\n\n" "After choosing a price, set it to the affordable amount based on the wallet required.\n\n"
"Affordable prices per tier: starter = 1, adult = 100, giant = 201, tycoon = 501\n\n"
"Use this to enable wallet tier locking, but make shop items not as expensive as they could be."; "Use this to enable wallet tier locking, but make shop items not as expensive as they could be.";
mOptionDescriptions[RSK_FISHSANITY] = "Off - Fish will not be shuffled. No changes will be made to fishing behavior.\n\n" mOptionDescriptions[RSK_FISHSANITY] = "Off - Fish will not be shuffled. No changes will be made to fishing behavior.\n\n"
"Shuffle only Hyrule Loach - Allows you to earn an item by catching the hyrule loach at the fishing pond and giving it to the owner.\n\n" "Shuffle only Hyrule Loach - Allows you to earn an item by catching the hyrule loach at the fishing pond and giving it to the owner.\n\n"
@ -297,32 +318,84 @@ void Settings::CreateOptionDescriptions() {
"If disabled, then the child pond will be shuffled and shared between both ages.\n\n" "If disabled, then the child pond will be shuffled and shared between both ages.\n\n"
"Note that, as child, there is a second loach available in the pond!"; "Note that, as child, there is a second loach available in the pond!";
mOptionDescriptions[RSK_SHUFFLE_SCRUBS] = mOptionDescriptions[RSK_SHUFFLE_SCRUBS] =
"Off - Scrubs will not be shuffled. The 3 Scrubs that give one-time items in the vanilla game " "Off - Scrubs will not be shuffled. The 3 Scrubs that give one-time items in the "
"(PoH, Deku Nut capacity, and Deku Stick capacity) will have random items.\n" "vanilla game (PoH, Deku Nut capacity, and Deku Stick capacity) will not spawn."
"\n" "\n"
"Affordable - Scrubs will be shuffled and their item will cost 10 rupees.\n" "One-Time Only - Only the 3 Scrubs that give one-time items in the "
"vanilla game are shuffled.\n"
"\n" "\n"
"Expensive - Scrubs will be shuffled and their item will cost the vanilla price.\n" "All - All Scrubs are shuffled.";
"\n" mOptionDescriptions[RSK_SCRUBS_PRICES] =
"Random - Scrubs will be shuffled and their item will cost will be between 0-95 rupees.\n"; "Vanilla - The same price as the item it replaced\n"
"Cheap Balanced - Prices will range between 0 to 95 rupees, favoring lower numbers\n"
"Balanced - Prices will range between 0 to 300 rupees, favoring lower numbers\n"
"Fixed - A fixed number\n"
"Range - A random point between specific ranges\n"
"Set By Wallet - Set weights that decide the choice of each wallet, and get a random price in that range if that wallet is chosen";
mOptionDescriptions[RSK_SCRUBS_PRICES_FIXED_PRICE] =
"The price for Scrub checks.";
mOptionDescriptions[RSK_SCRUBS_PRICES_RANGE_1] =
"The first part of the inclusive range of prices to allow for Scrub checks.";
mOptionDescriptions[RSK_SCRUBS_PRICES_RANGE_2] =
"The second part of the inclusive range of prices to allow for Scrub checks.";
mOptionDescriptions[RSK_SCRUBS_PRICES_NO_WALLET_WEIGHT] =
"The chance for Scrub checks to be free.";
mOptionDescriptions[RSK_SCRUBS_PRICES_CHILD_WALLET_WEIGHT] =
"The chance for Scrub checks to be purchasable with Child's Wallet (1-99).";
mOptionDescriptions[RSK_SCRUBS_PRICES_ADULT_WALLET_WEIGHT] =
"The chance for Scrub checks to be purchasable with Adult's Wallet (100-200).";
mOptionDescriptions[RSK_SCRUBS_PRICES_GIANT_WALLET_WEIGHT] =
"The chance for Scrub checks to be purchasable with Giant's Wallet (201-500).";
mOptionDescriptions[RSK_SCRUBS_PRICES_TYCOON_WALLET_WEIGHT] =
"The chance for Scrub checks to be purchasable with Tycoon Wallet. (500+)";
mOptionDescriptions[RSK_SCRUBS_PRICES_AFFORDABLE] =
"After choosing a price, set it to the affordable amount based on the wallet required.\n\n"
"Affordable prices per tier: starter = 1, adult = 100, giant = 201, tycoon = 501\n\n"
"Use this to enable wallet tier locking, but make scrub items not as expensive as they could be.";
mOptionDescriptions[RSK_SHUFFLE_BEEHIVES] = mOptionDescriptions[RSK_SHUFFLE_BEEHIVES] =
"Beehives give a randomized item from the pool when broken."; "Beehives give a randomized item from the pool when broken.";
mOptionDescriptions[RSK_SHUFFLE_COWS] = mOptionDescriptions[RSK_SHUFFLE_COWS] =
"Cows give a randomized item from the pool upon performing Epona's Song in front of them."; "Cows give a randomized item from the pool upon performing Epona's Song in front of them.";
mOptionDescriptions[RSK_SHUFFLE_MAGIC_BEANS] =
"Enabling this adds a pack of 10 beans to the item pool and changes the Magic Bean "
"Salesman to sell a random item at a price of 60 rupees.";
mOptionDescriptions[RSK_SHUFFLE_MERCHANTS] = mOptionDescriptions[RSK_SHUFFLE_MERCHANTS] =
"Enabling this changes Medigoron, Granny and the Carpet Salesman to sell a random item " "This setting governs if the Bean Salesman, Medigoron, Granny and the Carpet Salesman "
"once at a high price (100 for Granny, 200 for the others).\n" "sell a random item.\n"
"Beans Only - Only the Bean Salesman will have a check, and a pack of Magic Beans will be added "
" to the item pool."
"All But Beans - Medigoron, Granny and the Carpet Salesman will have checks, "
"A Giant's Knife and a pack of Bombchus will be added to the item pool, and " "A Giant's Knife and a pack of Bombchus will be added to the item pool, and "
"one of the bottles will contain a Blue Potion.\n\n" "one of the bottles will contain a Blue Potion.\n\n"
"On (no hints) - Salesmen will be included but won't tell you what you'll get.\n" "All - Apply both effects.\n"
"On (with hints) - Salesmen will be included and you'll know what you're buying.\n"
"\n" "\n"
"Granny's item will only be offered after you have traded in the Odd Mushroom when Shuffle Adult Trade is on. " "Granny's item will only be offered after you have traded in the Odd Mushroom when Shuffle Adult Trade is on. "
"Otherwise when off, you will need to have found the Claim Check to buy her item (simulating the trade quest " "Otherwise when off, you will need to have found the Claim Check to buy her item (simulating the trade quest "
"is complete)."; "is complete).";
mOptionDescriptions[RSK_MERCHANT_PRICES] =
"Vanilla - The same price as the Check in vanilla, 60 for the Bean Salesman\n"
"Cheap Balanced - Prices will range between 0 to 95 rupees, favoring lower numbers\n"
"Balanced - Prices will range between 0 to 300 rupees, favoring lower numbers\n"
"Fixed - A fixed number\n"
"Range - A random point between specific ranges\n"
"Set By Wallet - Set weights that decide the choice of each wallet, and get a random price in that range if that wallet is chosen";
mOptionDescriptions[RSK_MERCHANT_PRICES_FIXED_PRICE] =
"The price for Merchant checks.";
mOptionDescriptions[RSK_MERCHANT_PRICES_RANGE_1] =
"The first part of the inclusive range of prices to allow for Merchant checks.";
mOptionDescriptions[RSK_MERCHANT_PRICES_RANGE_2] =
"The second part of the inclusive range of prices to allow for Merchant checks.";
mOptionDescriptions[RSK_MERCHANT_PRICES_NO_WALLET_WEIGHT] =
"The chance for Merchant checks to be free.";
mOptionDescriptions[RSK_MERCHANT_PRICES_CHILD_WALLET_WEIGHT] =
"The chance for Merchant checks to be purchasable with Child's Wallet (1-99).";
mOptionDescriptions[RSK_MERCHANT_PRICES_ADULT_WALLET_WEIGHT] =
"The chance for Merchant checks to be purchasable with Adult's Wallet (100-200).";
mOptionDescriptions[RSK_MERCHANT_PRICES_GIANT_WALLET_WEIGHT] =
"The chance for Merchant checks to be purchasable with Giant's Wallet (201-500).";
mOptionDescriptions[RSK_MERCHANT_PRICES_TYCOON_WALLET_WEIGHT] =
"The chance for Merchant checks to be purchasable with Tycoon Wallet. (500+)";
mOptionDescriptions[RSK_MERCHANT_PRICES_AFFORDABLE] =
"After choosing a price, set it to the affordable amount based on the wallet required.\n\n"
"Affordable prices per tier: starter = 1, adult = 100, giant = 201, tycoon = 501\n\n"
"Use this to enable wallet tier locking, but make merchant items not as expensive as they could be.";
mOptionDescriptions[RSK_SHUFFLE_FROG_SONG_RUPEES] = "Shuffles 5 Purple Rupees into to the item pool, and allows\n" mOptionDescriptions[RSK_SHUFFLE_FROG_SONG_RUPEES] = "Shuffles 5 Purple Rupees into to the item pool, and allows\n"
"you to earn items by playing songs at the Frog Choir.\n" "you to earn items by playing songs at the Frog Choir.\n"
"\n" "\n"
@ -546,9 +619,9 @@ void Settings::CreateOptionDescriptions() {
mOptionDescriptions[RSK_CHICKENS_HINT] = "Talking to Anju as a child will tell you the item she will give you for delivering her Cuccos to the pen"; mOptionDescriptions[RSK_CHICKENS_HINT] = "Talking to Anju as a child will tell you the item she will give you for delivering her Cuccos to the pen";
mOptionDescriptions[RSK_MALON_HINT] = "Talking to Malon as adult will tell you the item on \"Link's cow\", the cow you win from beating her time on the Lon Lon Obsticle Course."; mOptionDescriptions[RSK_MALON_HINT] = "Talking to Malon as adult will tell you the item on \"Link's cow\", the cow you win from beating her time on the Lon Lon Obsticle Course.";
mOptionDescriptions[RSK_HBA_HINT] = "Talking to the Horseback Archery gerudo in Gerudo Fortress, or the nearby sign, will tell you what you win for scoring 1000 and 1500 points on Horseback Archery."; mOptionDescriptions[RSK_HBA_HINT] = "Talking to the Horseback Archery gerudo in Gerudo Fortress, or the nearby sign, will tell you what you win for scoring 1000 and 1500 points on Horseback Archery.";
mOptionDescriptions[RSK_WARP_SONG_HINTS] = "Standing near the pedestal for the frogs in Zora's River will tell you " mOptionDescriptions[RSK_WARP_SONG_HINTS] = "Playing a warp song will tell you where it leads. (If warp song destinations are vanilla, this is always enabled.)";
"the reward for the frogs' ocarina game."; //RANDOTODO fix this, I can't find the original right now because github search sucks
mOptionDescriptions[RSK_SCRUB_TEXT_HINT] = "Business scrubs will reveal the identity of what they're selling."; mOptionDescriptions[RSK_SCRUB_TEXT_HINT] = "Business scrubs will reveal the identity of what they're selling.";
mOptionDescriptions[RSK_MERCHANT_TEXT_HINT] = "Merchants will reveal the identity of what they're selling (Shops are not affected by this setting).";
mOptionDescriptions[RSK_KAK_10_SKULLS_HINT] = "Talking to the Cursed Resident in the Skultulla House who is saved after 10 tokens will tell you the reward"; mOptionDescriptions[RSK_KAK_10_SKULLS_HINT] = "Talking to the Cursed Resident in the Skultulla House who is saved after 10 tokens will tell you the reward";
mOptionDescriptions[RSK_KAK_20_SKULLS_HINT] = "Talking to the Cursed Resident in the Skultulla House who is saved after 20 tokens will tell you the reward"; mOptionDescriptions[RSK_KAK_20_SKULLS_HINT] = "Talking to the Cursed Resident in the Skultulla House who is saved after 20 tokens will tell you the reward";
mOptionDescriptions[RSK_KAK_30_SKULLS_HINT] = "Talking to the Cursed Resident in the Skultulla House who is saved after 30 tokens will tell you the reward"; mOptionDescriptions[RSK_KAK_30_SKULLS_HINT] = "Talking to the Cursed Resident in the Skultulla House who is saved after 30 tokens will tell you the reward";

View File

@ -242,9 +242,10 @@ void Randomizer::LoadHintMessages() {
// Bow Shooting Gallery reminder // Bow Shooting Gallery reminder
CustomMessageManager::Instance->CreateMessage(Randomizer::hintMessageTableID, TEXT_SHOOTING_GALLERY_MAN_COME_BACK_WITH_BOW, CustomMessageManager::Instance->CreateMessage(Randomizer::hintMessageTableID, TEXT_SHOOTING_GALLERY_MAN_COME_BACK_WITH_BOW,
CustomMessage("Come back when you have your own&bow and you'll get a %rdifferent prize%w!", CustomMessage("Come back when you have your own bow and you'll get a #different prize#!",
"Komm wieder sobald Du Deinen eigenen&Bogen hast, um einen %rspeziellen Preis%w zu&erhalten!", "Komm wieder sobald Du Deinen eigenen Bogen hast, um einen #speziellen Preis# zu erhalten!",
"J'aurai %rune autre récompense%w pour toi&lorsque tu auras ton propre arc.")); "J'aurai #une autre récompense# pour toi lorsque tu auras ton propre arc.",
{QM_RED}));
// Warp Song Mysterious text // Warp Song Mysterious text
CustomMessageManager::Instance->CreateMessage(Randomizer::hintMessageTableID, TEXT_WARP_MINUET_OF_FOREST, CustomMessageManager::Instance->CreateMessage(Randomizer::hintMessageTableID, TEXT_WARP_MINUET_OF_FOREST,
@ -259,9 +260,9 @@ void Randomizer::LoadHintMessages() {
"Wasserstand Kontrollsystem&Finger weg!", "Wasserstand Kontrollsystem&Finger weg!",
"Système de contrôle du niveau&d'eau.&Ne pas toucher!")); "Système de contrôle du niveau&d'eau.&Ne pas toucher!"));
CustomMessageManager::Instance->CreateMessage(Randomizer::hintMessageTableID, TEXT_LAKE_HYLIA_WATER_SWITCH_NAVI, CustomMessageManager::Instance->CreateMessage(Randomizer::hintMessageTableID, TEXT_LAKE_HYLIA_WATER_SWITCH_NAVI,
CustomMessage("%cThis switch is rustier than you think.^%cSomething must be wrong with the&pipe system in the %bWater Temple%c.", CustomMessage("%cThis switch is rustier than you think.^%cSomething must be wrong with the pipe system in the %bWater Temple%c.",
"%cDieser Schalter scheint rostiger zu&sein als er aussieht.^%cEtwas muss mit dem Leitungssystem&im %bWassertempel%c nicht stimmen.", "%cDieser Schalter scheint rostiger zu sein als er aussieht.^%cEtwas muss mit dem Leitungssystem im %bWassertempel%c nicht stimmen.",
"%cCet interrupteur est très rouillé.^%cIl doit y avoir un problème avec&la tuyauterie du %bTemple de l'Eau%c.")); "%cCet interrupteur est très rouillé.^%cIl doit y avoir un problème avec la tuyauterie du %bTemple de l'Eau%c."));
} }
// Reference soh/src/overlays/actors/ovl_En_GirlA/z_en_girla.h // Reference soh/src/overlays/actors/ovl_En_GirlA/z_en_girla.h
@ -304,38 +305,101 @@ void Randomizer::LoadMerchantMessages() {
// Prices have a chance of being 0, and the "sell" message below doesn't really make sense for a free item, so adding a "free" variation here // Prices have a chance of being 0, and the "sell" message below doesn't really make sense for a free item, so adding a "free" variation here
CustomMessageManager::Instance->CreateMessage(Randomizer::merchantMessageTableID, TEXT_SCRUB_RANDOM_FREE, CustomMessageManager::Instance->CreateMessage(Randomizer::merchantMessageTableID, TEXT_SCRUB_RANDOM_FREE,
CustomMessage("\x12\x38\x82" "All right! You win! In return for&sparing me, I will give you a&%g[[item]]%w!&Please, take it!\x07\x10\xA3", CustomMessage("\x12\x38\x82" "All right! You win! In return for sparing me, I will give you a #[[1]]#!&Please, take it!\x07\x10\xA3",
"\x12\x38\x82" "In Ordnung! Du gewinnst! Im Austausch&dafür, dass Du mich verschont hast,&werde ich Dir einen &%g[[item]]%w geben!\x07\x10\xA3", "\x12\x38\x82" "In Ordnung! Du gewinnst! Im Austausch dafür, dass Du mich verschont hast, werde ich Dir einen #[[1]]# geben!\x07\x10\xA3",
"\x12\x38\x82" "J'me rends! Laisse-moi partir et en&échange, je te donne un &%g[[item]]%w! Vas-y prends le!\x07\x10\xA3")); "\x12\x38\x82" "J'me rends! Laisse-moi partir et en échange, je te donne un #[[1]]#! Vas-y prends le!\x07\x10\xA3",
{QM_GREEN}));
CustomMessageManager::Instance->CreateMessage(Randomizer::merchantMessageTableID, TEXT_SCRUB_RANDOM, CustomMessageManager::Instance->CreateMessage(Randomizer::merchantMessageTableID, TEXT_SCRUB_RANDOM,
CustomMessage("\x12\x38\x82" "All right! You win! In return for&sparing me, I will sell you a&%g[[item]]%w!&%r[[price]] Rupees%w it is!\x07\x10\xA3", CustomMessage("\x12\x38\x82" "All right! You win! In return for sparing me, I will sell you a #[[1]]#! #[[2]] Rupees# it is!\x07\x10\xA3",
"\x12\x38\x82" "Ich gebe auf! Ich verkaufe Dir einen&%g[[item]]%w&für %r[[price]] Rubine%w!\x07\x10\xA3", "\x12\x38\x82" "Ich gebe auf! Ich verkaufe Dir einen #[[1]]# für #[[2]] Rubine#!\x07\x10\xA3",
"\x12\x38\x82" "J'abandonne! Tu veux bien m'acheter&un %g[[item]]%w?&Ça fera %r[[price]] Rubis%w!\x07\x10\xA3")); "\x12\x38\x82" "J'abandonne! Tu veux bien m'acheter un #[[1]]#? Ça fera #[[2]] Rubis#!\x07\x10\xA3",
{QM_GREEN, QM_YELLOW}));
//Carpet Salesman //Carpet Salesman
CustomMessageManager::Instance->CreateMessage( CustomMessageManager::Instance->CreateMessage(
Randomizer::merchantMessageTableID, TEXT_CARPET_SALESMAN_2, Randomizer::merchantMessageTableID, TEXT_CARPET_SALESMAN_ARMS_DEALER,
CustomMessage("Finally! Now I can go back to being &an %rarms dealer%w!", CustomMessage("Finally! Now I can go back to being an #arms dealer#!",
/*german*/"Endlich! Schon bald kann ich wieder &%rKrabbelminen-Händler%w sein!", /*german*/"Endlich! Schon bald kann ich wieder #Krabbelminen-Händler# sein!",
/*french*/ "Squalala! Je vais enfin pouvoir &%rprendre des vacances%w!")); /*french*/"Squalala! Je vais enfin pouvoir #prendre des vacances#!",
{QM_RED}));
// Each shop item has two messages, one for when the cursor is over it, and one for when you select it and are // Each shop item has two messages, one for when the cursor is over it, and one for when you select it and are
// prompted buy/don't buy // prompted buy/don't buy
CustomMessageManager::Instance->CreateMessage( CustomMessageManager::Instance->CreateMessage(
Randomizer::merchantMessageTableID, TEXT_SHOP_ITEM_RANDOM, Randomizer::merchantMessageTableID, TEXT_SHOP_ITEM_RANDOM,
CustomMessage("\x08%r[[item]] [[price]] Rupees&%wSpecial deal! ONE LEFT!&Get it while it lasts!\x0A\x02", CustomMessage("\x08#[[1]]# #[[2]]_Rupees#&Special deal! #ONE LEFT#!&Get it while it lasts!\x0A\x02",
"\x08%r[[item]] [[price]] Rubine&%wSonderangebot! NUR NOCH EINES VERFÜGBAR!&Beeilen Sie sich!\x0A\x02", "\x08#[[1]]# #[[2]]_Rubine#&Sonderangebot! #NUR NOCH EINES VERFÜGBAR#!&Beeilen Sie sich!\x0A\x02",
"\x08%r[[item]] [[price]] Rubis&%wOffre spéciale! DERNIER EN STOCK!&Faites vite!\x0A\x02")); "\x08#[[1]]# #[[2]]_Rubis#&Offre spéciale! #DERNIER EN STOCK#!&Faites vite!\x0A\x02",
{QM_GREEN, QM_YELLOW, QM_RED}));
CustomMessageManager::Instance->CreateMessage( CustomMessageManager::Instance->CreateMessage(
Randomizer::merchantMessageTableID, TEXT_SHOP_ITEM_RANDOM_CONFIRM, Randomizer::merchantMessageTableID, TEXT_SHOP_ITEM_RANDOM_CONFIRM,
CustomMessage("\x08[[item]] [[price]] Rupees\x09&&\x1B%gBuy&Don't buy%w\x09\x02", CustomMessage("\x08#[[1]]# #[[2]]_Rupees#\x09\x1B#Buy&Don't buy#\x09\x02",
"\x08[[item]] [[price]] Rubine\x09&&\x1B%gKaufen&Nicht kaufen%w\x09\x02", "\x08#[[1]]# #[[2]]_Rubine#\x09\x1B#Kaufen&Nicht kaufen#\x09\x02",
"\x08[[item]] [[price]] Rubis\x09&&\x1B%gAcheter&Ne pas acheter%w\x09\x02")); "\x08#[[1]]# #[[2]]_Rubis#\x09\x1B#Acheter&Ne pas acheter#\x09\x02",
{QM_GREEN, QM_YELLOW, QM_GREEN}));
CustomMessageManager::Instance->CreateMessage(
Randomizer::merchantMessageTableID, TEXT_BEAN_SALESMAN_BUY_FOR_10,
CustomMessage("I tried to be a #magic bean# salesman, but it turns out my marketing skills weren't worth "
"beans!^Anyway, want to buy #[[1]]# for #[[2]] Rupees#?\x1B#Yes&No#",
/*german*/ "Möchten Sie #[[1]]# für #[[2]] Rubine# kaufen?\x1B#Ja&Nein#",
/*french*/ "J'ai essayé d'être un vendeur de #haricots magiques#, mais j'étais mauvais au niveau du marketing et ça "
"me courait sur le haricot...^Enfin bref, ça te dirait de m'acheter #[[1]]# pour #[[2]] Rubis#?\x1B#Oui&Non#",
{QM_RED, QM_GREEN, QM_YELLOW, QM_GREEN}));
CustomMessageManager::Instance->CreateMessage( CustomMessageManager::Instance->CreateMessage(
Randomizer::merchantMessageTableID, TEXT_BEAN_SALESMAN_BUY_FOR_100, Randomizer::merchantMessageTableID, TEXT_BEAN_SALESMAN_BUY_FOR_100,
CustomMessage("I never thought I'd say this, but I'm &selling the last %rMagic Bean%w. %r99%w Rupees...\x1B&%gYes&No%w", CustomMessage("I never thought I'd say this, but I'm selling the last #Magic Bean#. #99 Rupees#...\x1B#Yes&No#",
"Ich hätte nie gedacht, daß ich das&sage, aber ich verkaufe die letzte^%rWundererbse%w für %r99%w Rubine.&\x1B&%gJa&Nein%w", "Ich hätte nie gedacht, daß ich das sage, aber ich verkaufe die letzte^#Wundererbse# für #99 Rubine#.\x1B&#Ja&Nein#",
"Je te vends mon dernier %rHaricot&magique%w pour %r99 Rubis%w.\x1B&%gAcheter&Ne pas acheter%w")); "Je te vends mon dernier #Haricot&magique# pour #99 Rubis#.\x1B&#AcheterNe pas acheter#",
{QM_RED, QM_YELLOW, QM_GREEN}));
CustomMessageManager::Instance->CreateMessage(
Randomizer::merchantMessageTableID, TEXT_MEDIGORON,
CustomMessage("How about buying #[[1]]# for #[[2]] Rupees#?\x1B#Buy&Don't buy#",
/*german*/ "Möchtest Du #[[1]]# für #[[2]] Rubine# kaufen?\x1B#Klar!&Nie im Leben!#",
/*french*/ "Veux-tu acheter #[[1]]# pour #[[2]] rubis#?\x1B#Acheter&Ne pas acheter#",
{QM_GREEN, QM_YELLOW, QM_GREEN}));
/*spanish*/ // ¿Me compras #[[1]]# por #[[2]] rupias#?\x1B#Comprar&No comprar#
CustomMessage firstCarpet = CustomMessage("Welcome!^I am selling stuff, strange and rare, from all over the world to everybody. Today's special is...^",
/*german*/ "Sei gegrüßt!^Ich verkaufe allerlei Kuriositäten. Stets sonderliche und seltene Ware aus "
"aller Welt für jedermann. Das heutige Angebot bleibt...^",
/*french*/ "Bienvenue!^Je vends des objets rares et merveilleux du monde entier. En spécial aujourd'hui...^");
/*spanish*/ // ¡Acércate!^Vendo productos extraños y difíciles de encontrar... De todo el mundo a todo el mundo. La oferta de hoy es...^#¡
CustomMessageManager::Instance->CreateMessage(
Randomizer::merchantMessageTableID, TEXT_CARPET_SALESMAN_MYSTERIOUS,
firstCarpet +
CustomMessage("Terrifying! I won't tell you what it is until I see the #money#...^How about #[[2]] Rupees#?&&"
"\x1B#Buy&Don't buy#",
/*german*/ "Furchterregend, oder? Ich erzähle Euch mehr, wenn ich #Geld# sehe...^Wie wär's mit #[[2]] Rubinen#?&&"
"\x1B#Aber sicher!&Ich bin weg!#",
/*french*/ "Un concentré de puissance! Mais montre tes #rubis# avant que je te dise ce que c'est...^Disons #[[2]] "
"rubis#?&&\x1B#Acheter&Ne pas acheter#",
{QM_RED, QM_YELLOW, QM_GREEN}));
/*spanish*/ // ¡Terrorífico! No te revelaré su nombre hasta que vea el #dinero#...^#[[2]] rupias#, ¿qué te parece?&&"
// "\x1B#Comprar&No comprar#
CustomMessageManager::Instance->CreateMessage(
Randomizer::merchantMessageTableID, TEXT_CARPET_SALESMAN_1,
firstCarpet +
CustomMessage("#[[1]]!# It's real, I promise! A lonely man such as myself wouldn't #lie# to you, hmm?^"
"How about #[[2]] Rupees#?\x1B#Buy&Don't buy#",
/*german*/ "#[[1]]#! Ich kann versichern, es ist ein aufrichtiges Angebot!^Ein einsamer Mann wie ich würde Dich doch "
"nicht #anlügen#, oder?^Wie wär's mit #[[2]] Rubinen#?\x1B#Aber sicher!&Ich bin weg!#",
/*french*/ "#[[1]]!# C'est vrai! J'te jure! Un gars comme moi ne te #mentirai# pas tu ne crois pas?^Disons #[[2]] "
"rubis#?\x1B#Acheter&Ne pas acheter#",
{QM_GREEN, QM_RED, QM_YELLOW}));
CustomMessageManager::Instance->CreateMessage(
Randomizer::merchantMessageTableID, TEXT_GRANNYS_SHOP,
CustomMessage("#[[1]]#! How about #[[2]] Rupees#?\x1B#Buy&Don't buy#",
/*german*/ "#[[1]]#! Sagen wir #[[2]] Rubine#?\x1B#Gerne!&Auf keinen Fall!#",
/*french*/ "#[[1]]#! Que dis-tu de #[[2]] rubis#?\x1B#Acheter&Ne pas acheter#",
{QM_GREEN, QM_YELLOW, QM_GREEN}, {true}));
// /*spanish*/#[[1]]#. Vendo por #[[2]] rupias#.&\x1B#Comprar&No comprar#
} }
std::map<s32, TrialKey> trialFlagToTrialKey = { std::map<s32, TrialKey> trialFlagToTrialKey = {
@ -364,16 +428,9 @@ ItemObtainability Randomizer::GetItemObtainabilityFromRandomizerCheck(Randomizer
ItemObtainability Randomizer::GetItemObtainabilityFromRandomizerGet(RandomizerGet randoGet) { ItemObtainability Randomizer::GetItemObtainabilityFromRandomizerGet(RandomizerGet randoGet) {
// Shopsanity with at least one item shuffled allows for a third wallet upgrade.
// This is needed since Plentiful item pool also adds a third progressive wallet // This is needed since Plentiful item pool also adds a third progressive wallet
// but we should *not* get Tycoon's Wallet in that mode. // but we should not get Tycoon's Wallet from it if it is off.
bool tycoonWallet = !( bool tycoonWallet = GetRandoSettingValue(RSK_INCLUDE_TYCOON_WALLET);
GetRandoSettingValue(RSK_SHOPSANITY) == RO_SHOPSANITY_OFF ||
(
GetRandoSettingValue(RSK_SHOPSANITY) == RO_SHOPSANITY_SPECIFIC_COUNT &&
GetRandoSettingValue(RSK_SHOPSANITY_COUNT) == RO_SHOPSANITY_COUNT_ZERO_ITEMS
)
);
// Same thing with the infinite upgrades, if we're not shuffling them // Same thing with the infinite upgrades, if we're not shuffling them
// and we're using the Plentiful item pool, we should prevent the infinite // and we're using the Plentiful item pool, we should prevent the infinite
@ -2006,23 +2063,15 @@ CustomMessage Randomizer::GetFishingPondOwnerMessage(u16 originalTextId) {
return messageEntry; return messageEntry;
} }
CustomMessage Randomizer::GetMerchantMessage(RandomizerInf randomizerInf, u16 textId, bool mysterious) { CustomMessage Randomizer::GetMerchantMessage(RandomizerCheck rc, TextIDs textId, TextIDs freeTextId, bool mysterious) {
auto ctx = Rando::Context::GetInstance(); //RANDOTODO If scrubs are allowed to have ambiguous hints, they need to be RandomiserHint objects for logging auto ctx = Rando::Context::GetInstance();
CustomMessage messageEntry = CustomMessageManager::Instance->RetrieveMessage(Randomizer::merchantMessageTableID, textId); CustomMessage messageEntry;
RandomizerCheck rc = GetCheckFromRandomizerInf(randomizerInf);
RandomizerGet shopItemGet = ctx->GetItemLocation(rc)->GetPlacedRandomizerGet(); RandomizerGet shopItemGet = ctx->GetItemLocation(rc)->GetPlacedRandomizerGet();
CustomMessage shopItemName; CustomMessage shopItemName;
u16 shopItemPrice = ctx->GetItemLocation(rc)->GetPrice();
if (mysterious || CVarGetInteger(CVAR_RANDOMIZER_ENHANCEMENT("MysteriousShuffle"), 0)) { if (mysterious || CVarGetInteger(CVAR_RANDOMIZER_ENHANCEMENT("MysteriousShuffle"), 0)) {
if (randomizerInf >= RAND_INF_SHOP_ITEMS_KF_SHOP_ITEM_1 && randomizerInf <= RAND_INF_SHOP_ITEMS_MARKET_BOMBCHU_SHOP_ITEM_8) { shopItemName = Rando::StaticData::hintTextTable[RHT_MYSTERIOUS_ITEM_CAPITAL].GetHintMessage();
shopItemName = {
"Mysterious Item",
"Mysteriöser Gegenstand",
"Objet Mystérieux"
};
} else {
shopItemName = Rando::StaticData::hintTextTable[RHT_MYSTERIOUS_ITEM].GetHintMessage();
}
// TODO: This should eventually be replaced with a full fledged trick model & trick name system
} else if (shopItemGet == RG_ICE_TRAP) { } else if (shopItemGet == RG_ICE_TRAP) {
shopItemGet = ctx->overrides[rc].LooksLike(); shopItemGet = ctx->overrides[rc].LooksLike();
shopItemName = CustomMessage(ctx->overrides[rc].GetTrickName()); shopItemName = CustomMessage(ctx->overrides[rc].GetTrickName());
@ -2030,14 +2079,15 @@ CustomMessage Randomizer::GetMerchantMessage(RandomizerInf randomizerInf, u16 te
auto shopItem = Rando::StaticData::RetrieveItem(shopItemGet); auto shopItem = Rando::StaticData::RetrieveItem(shopItemGet);
shopItemName = {shopItem.GetName()}; shopItemName = {shopItem.GetName()};
} }
u16 shopItemPrice = ctx->GetItemLocation(rc)->GetPrice();
if (textId == TEXT_SCRUB_RANDOM && shopItemPrice == 0) { if (freeTextId != TEXT_NONE && shopItemPrice == 0) {
messageEntry = CustomMessageManager::Instance->RetrieveMessage(Randomizer::merchantMessageTableID, TEXT_SCRUB_RANDOM_FREE); messageEntry = CustomMessageManager::Instance->RetrieveMessage(Randomizer::merchantMessageTableID, freeTextId, MF_RAW);
} else {
messageEntry = CustomMessageManager::Instance->RetrieveMessage(Randomizer::merchantMessageTableID, textId, MF_RAW);
} }
messageEntry.Replace("[[item]]", shopItemName); messageEntry.InsertNames({shopItemName, {std::to_string(shopItemPrice)}});
messageEntry.Replace("[[price]]", std::to_string(shopItemPrice)); messageEntry.AutoFormat();
return messageEntry; return messageEntry;
} }
@ -2199,6 +2249,7 @@ CustomMessage Randomizer::GetTriforcePieceMessage() {
messageEntry.Replace("[[current]]", std::to_string(current)); messageEntry.Replace("[[current]]", std::to_string(current));
messageEntry.Replace("[[remaining]]", std::to_string(remaining)); messageEntry.Replace("[[remaining]]", std::to_string(remaining));
messageEntry.Replace("[[required]]", std::to_string(required)); messageEntry.Replace("[[required]]", std::to_string(required));
messageEntry.Format();
return messageEntry; return messageEntry;
} }
@ -2213,11 +2264,6 @@ void CreateNaviRandoMessages() {
"%cManchmal kannst Du den %rStahlhammer&%cstatt Bomben verwenden!", "%cManchmal kannst Du den %rStahlhammer&%cstatt Bomben verwenden!",
"%cParfois, tu peux utiliser la %rMasse&des Titans %cau lieu de tes bombes!" }, "%cParfois, tu peux utiliser la %rMasse&des Titans %cau lieu de tes bombes!" },
{ "%cThere are three %gbusiness scrubs %cin &Hyrule who sell %wmysterious items%c. Do&you know where they are?",
"%cEs gibt drei %gDeku-Händler %cin Hyrule&die mysteriöse Gegenstände&verkaufen. Weißt Du wo sie sind?",
"%cIl y a trois %gPestes Marchandes%c en&Hyrule qui vendent des %wobjets&mystérieux%c. Tu sais où elles "
"sont?" },
{ "%cStuck on this seed? You could &throw in the towel and check the&%wspoiler log%c...", { "%cStuck on this seed? You could &throw in the towel and check the&%wspoiler log%c...",
"%cHängst Du bei diesem Seed fest?&Du könntest die Flinte ins Korn&werfen und ins %wSpoiler Log %cschauen...", "%cHängst Du bei diesem Seed fest?&Du könntest die Flinte ins Korn&werfen und ins %wSpoiler Log %cschauen...",
"%cSi tu es coincé sur cette seed,&tu peux toujours jeter l'éponge&et regader le %wSpoiler log%c..." }, "%cSi tu es coincé sur cette seed,&tu peux toujours jeter l'éponge&et regader le %wSpoiler log%c..." },
@ -2566,7 +2612,15 @@ CustomMessage Randomizer::GetIceTrapMessage() {
return msg; return msg;
} }
static int goronIDs[9] = { 0x3052, 0x3069, 0x306A, 0x306B, 0x306C, 0x306D, 0x306E, 0x306F, 0x3070 }; static int goronIDs[9] = { TEXT_FIRE_TEMPLE_GORON_OWE_YOU_BIG_TIME,
TEXT_FIRE_TEMPLE_GORON_FALLING_DOORS_SECRET,
TEXT_FIRE_TEMPLE_GORON_FIRE_SECRET,
TEXT_FIRE_TEMPLE_GORON_FLAME_DANCER_SECRET,
TEXT_FIRE_TEMPLE_GORON_SWITCH_SECRET,
TEXT_FIRE_TEMPLE_GORON_OCARINA_SECRET,
TEXT_FIRE_TEMPLE_GORON_PILLAR_SECRET,
TEXT_FIRE_TEMPLE_GORON_HIDDEN_DOOR_SECRET,
TEXT_FIRE_TEMPLE_GORON_SOUNDS_DIFFERENT_SECRET};
void CreateFireTempleGoronMessages() { void CreateFireTempleGoronMessages() {
CustomMessage FireTempleGoronMessages[NUM_GORON_MESSAGES] = { CustomMessage FireTempleGoronMessages[NUM_GORON_MESSAGES] = {
@ -2654,6 +2708,7 @@ CustomMessage Randomizer::GetGoronMessage(u16 index) {
CustomMessage messageEntry = CustomMessageManager::Instance->RetrieveMessage(customMessageTableID, goronIDs[index]); CustomMessage messageEntry = CustomMessageManager::Instance->RetrieveMessage(customMessageTableID, goronIDs[index]);
messageEntry.Replace("[[days]]", std::to_string(gSaveContext.totalDays)); messageEntry.Replace("[[days]]", std::to_string(gSaveContext.totalDays));
messageEntry.Replace("[[a_btn]]", std::to_string(gSaveContext.sohStats.count[COUNT_BUTTON_PRESSES_A])); messageEntry.Replace("[[a_btn]]", std::to_string(gSaveContext.sohStats.count[COUNT_BUTTON_PRESSES_A]));
messageEntry.Format();
return messageEntry; return messageEntry;
} }

View File

@ -19,7 +19,7 @@
#define MAX_SEED_STRING_SIZE 1024 #define MAX_SEED_STRING_SIZE 1024
#define NUM_TRIFORCE_PIECE_MESSAGES 6 #define NUM_TRIFORCE_PIECE_MESSAGES 6
#define NUM_NAVI_MESSAGES 19 #define NUM_NAVI_MESSAGES 18
#define NUM_GORON_MESSAGES 9 #define NUM_GORON_MESSAGES 9
class Randomizer { class Randomizer {
@ -59,7 +59,7 @@ class Randomizer {
ItemObtainability GetItemObtainabilityFromRandomizerGet(RandomizerGet randomizerCheck); ItemObtainability GetItemObtainabilityFromRandomizerGet(RandomizerGet randomizerCheck);
CustomMessage GetSheikMessage(s16 scene, u16 originalTextId); CustomMessage GetSheikMessage(s16 scene, u16 originalTextId);
CustomMessage GetFishingPondOwnerMessage(u16 originalTextId); CustomMessage GetFishingPondOwnerMessage(u16 originalTextId);
CustomMessage GetMerchantMessage(RandomizerInf randomizerInf, u16 textId, bool mysterious = false); CustomMessage GetMerchantMessage(RandomizerCheck rc, TextIDs textId, TextIDs freeTextId = TEXT_NONE, bool mysterious = false);
RandomizerCheck GetCheckFromActor(s16 actorId, s16 sceneNum, s16 actorParams); RandomizerCheck GetCheckFromActor(s16 actorId, s16 sceneNum, s16 actorParams);
CustomMessage GetGoronMessage(u16 index); CustomMessage GetGoronMessage(u16 index);
CustomMessage GetMapGetItemMessageWithHint(GetItemEntry itemEntry); CustomMessage GetMapGetItemMessageWithHint(GetItemEntry itemEntry);

View File

@ -34,7 +34,6 @@ typedef enum {
HINT_TYPE_TRIAL, HINT_TYPE_TRIAL,
HINT_TYPE_ENTRANCE, HINT_TYPE_ENTRANCE,
HINT_TYPE_ITEM_AREA, HINT_TYPE_ITEM_AREA,
HINT_TYPE_MERCHANT,
HINT_TYPE_ALTAR_CHILD, HINT_TYPE_ALTAR_CHILD,
HINT_TYPE_ALTAR_ADULT, HINT_TYPE_ALTAR_ADULT,
HINT_TYPE_WOTH, // Way of the Hero HINT_TYPE_WOTH, // Way of the Hero
@ -2248,10 +2247,6 @@ typedef enum {
RH_REQUIEM_WARP_LOC, RH_REQUIEM_WARP_LOC,
RH_NOCTURNE_WARP_LOC, RH_NOCTURNE_WARP_LOC,
RH_PRELUDE_WARP_LOC, RH_PRELUDE_WARP_LOC,
RH_MEDIGORON,
RH_CARPET_SALESMAN,
RH_BEAN_SALESMAN,
RH_GRANNY,
RH_HBA_HINT, RH_HBA_HINT,
RH_MALON_HINT, RH_MALON_HINT,
RH_CHICKENS_HINT, RH_CHICKENS_HINT,
@ -3429,6 +3424,7 @@ typedef enum {
RHT_EPONA, RHT_EPONA,
RHT_HINT_MYSTERIOUS, RHT_HINT_MYSTERIOUS,
RHT_MYSTERIOUS_ITEM, RHT_MYSTERIOUS_ITEM,
RHT_MYSTERIOUS_ITEM_CAPITAL,
// Entrances // Entrances
RHT_DESERT_COLOSSUS_TO_COLOSSUS_GROTTO, RHT_DESERT_COLOSSUS_TO_COLOSSUS_GROTTO,
RHT_GV_GROTTO_LEDGE_TO_GV_OCTOROK_GROTTO, RHT_GV_GROTTO_LEDGE_TO_GV_OCTOROK_GROTTO,
@ -3617,12 +3613,8 @@ typedef enum {
// Static Entrance Hints // Static Entrance Hints
RHT_WARP_SONG, RHT_WARP_SONG,
// Static Location Hints // Static Location Hints
RHT_MEDIGORON_HINT,
RHT_CARPET_SALESMAN_DIALOG_FIRST, RHT_CARPET_SALESMAN_DIALOG_FIRST,
RHT_CARPET_SALESMAN_DIALOG_MYSTERIOUS, RHT_CARPET_SALESMAN_DIALOG_MYSTERIOUS,
RHT_CARPET_SALESMAN_DIALOG_HINTED,
RHT_BEAN_SALESMAN_HINT,
RHT_GRANNY_HINT,
RHT_HBA_HINT_SIGN, RHT_HBA_HINT_SIGN,
RHT_HBA_HINT_NOT_ON_HORSE, RHT_HBA_HINT_NOT_ON_HORSE,
RHT_HBA_HINT_INITIAL, RHT_HBA_HINT_INITIAL,
@ -3778,14 +3770,33 @@ typedef enum {
RSK_SHUFFLE_KOKIRI_SWORD, RSK_SHUFFLE_KOKIRI_SWORD,
RSK_SHUFFLE_MASTER_SWORD, RSK_SHUFFLE_MASTER_SWORD,
RSK_SHUFFLE_CHILD_WALLET, RSK_SHUFFLE_CHILD_WALLET,
RSK_INCLUDE_TYCOON_WALLET,
RSK_SHUFFLE_DUNGEON_REWARDS, RSK_SHUFFLE_DUNGEON_REWARDS,
RSK_SHUFFLE_SONGS, RSK_SHUFFLE_SONGS,
RSK_SHUFFLE_TOKENS, RSK_SHUFFLE_TOKENS,
RSK_SHOPSANITY, RSK_SHOPSANITY,
RSK_SHOPSANITY_COUNT, RSK_SHOPSANITY_COUNT,
RSK_SHOPSANITY_PRICES, RSK_SHOPSANITY_PRICES,
RSK_SHOPSANITY_PRICES_FIXED_PRICE,
RSK_SHOPSANITY_PRICES_RANGE_1,
RSK_SHOPSANITY_PRICES_RANGE_2,
RSK_SHOPSANITY_PRICES_NO_WALLET_WEIGHT,
RSK_SHOPSANITY_PRICES_CHILD_WALLET_WEIGHT,
RSK_SHOPSANITY_PRICES_ADULT_WALLET_WEIGHT,
RSK_SHOPSANITY_PRICES_GIANT_WALLET_WEIGHT,
RSK_SHOPSANITY_PRICES_TYCOON_WALLET_WEIGHT,
RSK_SHOPSANITY_PRICES_AFFORDABLE, RSK_SHOPSANITY_PRICES_AFFORDABLE,
RSK_SHUFFLE_SCRUBS, RSK_SHUFFLE_SCRUBS,
RSK_SCRUBS_PRICES,
RSK_SCRUBS_PRICES_FIXED_PRICE,
RSK_SCRUBS_PRICES_RANGE_1,
RSK_SCRUBS_PRICES_RANGE_2,
RSK_SCRUBS_PRICES_NO_WALLET_WEIGHT,
RSK_SCRUBS_PRICES_CHILD_WALLET_WEIGHT,
RSK_SCRUBS_PRICES_ADULT_WALLET_WEIGHT,
RSK_SCRUBS_PRICES_GIANT_WALLET_WEIGHT,
RSK_SCRUBS_PRICES_TYCOON_WALLET_WEIGHT,
RSK_SCRUBS_PRICES_AFFORDABLE,
RSK_SHUFFLE_BEEHIVES, RSK_SHUFFLE_BEEHIVES,
RSK_SHUFFLE_COWS, RSK_SHUFFLE_COWS,
RSK_SHUFFLE_WEIRD_EGG, RSK_SHUFFLE_WEIRD_EGG,
@ -3817,6 +3828,7 @@ typedef enum {
RSK_HBA_HINT, RSK_HBA_HINT,
RSK_WARP_SONG_HINTS, RSK_WARP_SONG_HINTS,
RSK_SCRUB_TEXT_HINT, RSK_SCRUB_TEXT_HINT,
RSK_MERCHANT_TEXT_HINT,
RSK_FISHING_POLE_HINT, RSK_FISHING_POLE_HINT,
RSK_HINT_CLARITY, RSK_HINT_CLARITY,
RSK_HINT_DISTRIBUTION, RSK_HINT_DISTRIBUTION,
@ -3838,8 +3850,17 @@ typedef enum {
RSK_ENABLE_GLITCH_CUTSCENES, RSK_ENABLE_GLITCH_CUTSCENES,
RSK_SKULLS_SUNS_SONG, RSK_SKULLS_SUNS_SONG,
RSK_SHUFFLE_ADULT_TRADE, RSK_SHUFFLE_ADULT_TRADE,
RSK_SHUFFLE_MAGIC_BEANS,
RSK_SHUFFLE_MERCHANTS, RSK_SHUFFLE_MERCHANTS,
RSK_MERCHANT_PRICES,
RSK_MERCHANT_PRICES_FIXED_PRICE,
RSK_MERCHANT_PRICES_RANGE_1,
RSK_MERCHANT_PRICES_RANGE_2,
RSK_MERCHANT_PRICES_NO_WALLET_WEIGHT,
RSK_MERCHANT_PRICES_CHILD_WALLET_WEIGHT,
RSK_MERCHANT_PRICES_ADULT_WALLET_WEIGHT,
RSK_MERCHANT_PRICES_GIANT_WALLET_WEIGHT,
RSK_MERCHANT_PRICES_TYCOON_WALLET_WEIGHT,
RSK_MERCHANT_PRICES_AFFORDABLE,
RSK_BLUE_FIRE_ARROWS, RSK_BLUE_FIRE_ARROWS,
RSK_SUNLIGHT_ARROWS, RSK_SUNLIGHT_ARROWS,
RSK_ENABLE_BOMBCHU_DROPS, RSK_ENABLE_BOMBCHU_DROPS,
@ -4014,19 +4035,19 @@ typedef enum {
//Shopsanity price ranges //Shopsanity price ranges
typedef enum { typedef enum {
RO_SHOPSANITY_PRICE_BALANCED, //Balanced random from 0-300 RO_PRICE_VANILLA,
RO_SHOPSANITY_PRICE_STARTER, //Wallets are random within their range, in increments of 5 rupees RO_PRICE_CHEAP_BALANCED, //Balanced random from 0-95, favoring lower numbers
RO_SHOPSANITY_PRICE_ADULT, RO_PRICE_BALANCED, //Random from 0-300, favoring lower numbers
RO_SHOPSANITY_PRICE_GIANT, RO_PRICE_FIXED,
RO_SHOPSANITY_PRICE_TYCOON, RO_PRICE_RANGE,
} RandoOptionShopsanityPrices; RO_PRICE_SET_BY_WALLET,
} RandoOptionPrices;
//Scrubsanity settings (off, affordable, expensive, random) //Scrubsanity settings (off, affordable, expensive, random)
typedef enum { typedef enum {
RO_SCRUBS_OFF, RO_SCRUBS_OFF,
RO_SCRUBS_AFFORDABLE, RO_SCRUBS_MAJOR_ONLY,
RO_SCRUBS_EXPENSIVE, RO_SCRUBS_ALL,
RO_SCRUBS_RANDOM,
} RandoOptionScrubsanity; } RandoOptionScrubsanity;
//Ammo drop settings (on, "on+bombchu", off) //Ammo drop settings (on, "on+bombchu", off)
@ -4161,11 +4182,12 @@ typedef enum {
RO_SONG_SHUFFLE_ANYWHERE, RO_SONG_SHUFFLE_ANYWHERE,
} RandoOptionSongShuffle; } RandoOptionSongShuffle;
//Shuffle Merchants Settings (Off, On no hint, on with wint) //Shuffle Merchants Settings (Off, Beans Only, All but Beans, All)
typedef enum { typedef enum {
RO_SHUFFLE_MERCHANTS_OFF, RO_SHUFFLE_MERCHANTS_OFF,
RO_SHUFFLE_MERCHANTS_ON_NO_HINT, RO_SHUFFLE_MERCHANTS_BEANS_ONLY,
RO_SHUFFLE_MERCHANTS_ON_HINT, RO_SHUFFLE_MERCHANTS_ALL_BUT_BEANS,
RO_SHUFFLE_MERCHANTS_ALL
} RandoOptionShuffleMerchants; } RandoOptionShuffleMerchants;
//Starting Ocarina Settings (off, fairy) //Starting Ocarina Settings (off, fairy)

View File

@ -172,7 +172,7 @@ void RandomizerCheckObjects::UpdateImGuiVisibility() {
(location.GetRandomizerCheck() != RC_LH_HYRULE_LOACH || (location.GetRandomizerCheck() != RC_LH_HYRULE_LOACH ||
CVarGetInteger(CVAR_RANDOMIZER_SETTING("Fishsanity"), RO_GENERIC_NO) == RO_FISHSANITY_HYRULE_LOACH) && CVarGetInteger(CVAR_RANDOMIZER_SETTING("Fishsanity"), RO_GENERIC_NO) == RO_FISHSANITY_HYRULE_LOACH) &&
(location.GetRandomizerCheck() != RC_ZR_MAGIC_BEAN_SALESMAN || (location.GetRandomizerCheck() != RC_ZR_MAGIC_BEAN_SALESMAN ||
CVarGetInteger(CVAR_RANDOMIZER_SETTING("ShuffleBeans"), RO_GENERIC_NO)) && CVarGetInteger(CVAR_RANDOMIZER_SETTING("ShuffleMerchants"), RO_SHUFFLE_MERCHANTS_OFF) % 2) &&
(location.GetRandomizerCheck() != RC_HC_MALON_EGG || (location.GetRandomizerCheck() != RC_HC_MALON_EGG ||
CVarGetInteger(CVAR_RANDOMIZER_SETTING("ShuffleWeirdEgg"), RO_GENERIC_NO)) && CVarGetInteger(CVAR_RANDOMIZER_SETTING("ShuffleWeirdEgg"), RO_GENERIC_NO)) &&
(location.GetRCType() != RCTYPE_FROG_SONG || (location.GetRCType() != RCTYPE_FROG_SONG ||

View File

@ -1108,13 +1108,15 @@ void LoadSettings() {
OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_SHOPSANITY) != RO_SHOPSANITY_OFF OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_SHOPSANITY) != RO_SHOPSANITY_OFF
: false; : false;
showBeans = IS_RANDO ? showBeans = IS_RANDO ?
OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_SHUFFLE_MAGIC_BEANS) == RO_GENERIC_YES OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_SHUFFLE_MERCHANTS) == RO_SHUFFLE_MERCHANTS_BEANS_ONLY ||
OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_SHUFFLE_MERCHANTS) == RO_SHUFFLE_MERCHANTS_ALL
: true; : true;
showScrubs = IS_RANDO ? showScrubs = IS_RANDO ?
OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_SHUFFLE_SCRUBS) != RO_SCRUBS_OFF OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_SHUFFLE_SCRUBS) != RO_SCRUBS_OFF
: false; : false;
showMerchants = IS_RANDO ? showMerchants = IS_RANDO ?
OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_SHUFFLE_MERCHANTS) != RO_SHUFFLE_MERCHANTS_OFF OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_SHUFFLE_MERCHANTS) == RO_SHUFFLE_MERCHANTS_ALL_BUT_BEANS ||
OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_SHUFFLE_MERCHANTS) == RO_SHUFFLE_MERCHANTS_ALL
: true; : true;
showBeehives = IS_RANDO ? showBeehives = IS_RANDO ?
OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_SHUFFLE_BEEHIVES) == RO_GENERIC_YES OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_SHUFFLE_BEEHIVES) == RO_GENERIC_YES

View File

@ -390,13 +390,7 @@ ItemTrackerNumbers GetItemCurrentAndMax(ItemTrackerItem item) {
case ITEM_WALLET_ADULT: case ITEM_WALLET_ADULT:
case ITEM_WALLET_GIANT: case ITEM_WALLET_GIANT:
result.currentCapacity = IS_RANDO && !Flags_GetRandomizerInf(RAND_INF_HAS_WALLET) ? 0 : CUR_CAPACITY(UPG_WALLET); result.currentCapacity = IS_RANDO && !Flags_GetRandomizerInf(RAND_INF_HAS_WALLET) ? 0 : CUR_CAPACITY(UPG_WALLET);
result.maxCapacity = !IS_RANDO || ( result.maxCapacity = OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_INCLUDE_TYCOON_WALLET) ? 999 : 500;
OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_SHOPSANITY) == RO_SHOPSANITY_OFF ||
(
OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_SHOPSANITY) == RO_SHOPSANITY_SPECIFIC_COUNT &&
OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_SHOPSANITY_COUNT) == RO_SHOPSANITY_COUNT_ZERO_ITEMS
)
) ? 500 : 999;
result.currentAmmo = gSaveContext.rupees; result.currentAmmo = gSaveContext.rupees;
break; break;
case ITEM_BOMBCHU: case ITEM_BOMBCHU:

View File

@ -339,6 +339,13 @@ extern "C" void Randomizer_InitSaveFile() {
gSaveContext.adultTradeItems = 0; gSaveContext.adultTradeItems = 0;
} }
// remove One Time scrubs with scrubsanity off
if (Randomizer_GetSettingValue(RSK_SHUFFLE_SCRUBS) == RO_SCRUBS_OFF) {
Flags_SetRandomizerInf(RAND_INF_SCRUBS_PURCHASED_LW_DEKU_SCRUB_NEAR_BRIDGE);
Flags_SetRandomizerInf(RAND_INF_SCRUBS_PURCHASED_LW_DEKU_SCRUB_GROTTO_FRONT);
Flags_SetRandomizerInf(RAND_INF_SCRUBS_PURCHASED_HF_DEKU_SCRUB_GROTTO);
}
int startingAge = OTRGlobals::Instance->gRandoContext->GetSettings()->ResolvedStartingAge(); int startingAge = OTRGlobals::Instance->gRandoContext->GetSettings()->ResolvedStartingAge();
switch (startingAge) { switch (startingAge) {
case RO_AGE_ADULT: // Adult case RO_AGE_ADULT: // Adult

View File

@ -36,6 +36,69 @@ std::vector<std::string> MultiVecOpts(const std::vector<std::vector<std::string>
return options; return options;
} }
void Settings::HandleShopsanityPriceUI(){
bool isTycoon = CVarGetInteger(CVAR_RANDOMIZER_SETTING("IncludeTycoonWallet"), RO_GENERIC_OFF);
mOptions[RSK_SHOPSANITY].RemoveFlag(IMFLAG_SEPARATOR_BOTTOM);
mOptions[RSK_SHOPSANITY_PRICES].Unhide();
switch (CVarGetInteger(CVAR_RANDOMIZER_SETTING("ShopsanityPrices"), RO_PRICE_VANILLA)){
case RO_PRICE_FIXED:
mOptions[RSK_SHOPSANITY_PRICES_FIXED_PRICE].Unhide();
mOptions[RSK_SHOPSANITY_PRICES_RANGE_1].Hide();
mOptions[RSK_SHOPSANITY_PRICES_RANGE_2].Hide();
mOptions[RSK_SHOPSANITY_PRICES_NO_WALLET_WEIGHT].Hide();
mOptions[RSK_SHOPSANITY_PRICES_CHILD_WALLET_WEIGHT].Hide();
mOptions[RSK_SHOPSANITY_PRICES_ADULT_WALLET_WEIGHT].Hide();
mOptions[RSK_SHOPSANITY_PRICES_GIANT_WALLET_WEIGHT].Hide();
mOptions[RSK_SHOPSANITY_PRICES_TYCOON_WALLET_WEIGHT].Hide();
if (isTycoon ? mOptions[RSK_SHOPSANITY_PRICES_FIXED_PRICE].GetOptionCount() == 501 : mOptions[RSK_SHOPSANITY_PRICES_FIXED_PRICE].GetOptionCount() == 1000) {
mOptions[RSK_SHOPSANITY_PRICES_FIXED_PRICE].ChangeOptions(isTycoon ? NumOpts(0, 999) : NumOpts(0, 500));
}
mOptions[RSK_SHOPSANITY_PRICES_AFFORDABLE].Hide();
break;
case RO_PRICE_RANGE:
mOptions[RSK_SHOPSANITY_PRICES_FIXED_PRICE].Hide();
mOptions[RSK_SHOPSANITY_PRICES_RANGE_1].Unhide();
mOptions[RSK_SHOPSANITY_PRICES_RANGE_2].Unhide();
mOptions[RSK_SHOPSANITY_PRICES_NO_WALLET_WEIGHT].Hide();
mOptions[RSK_SHOPSANITY_PRICES_CHILD_WALLET_WEIGHT].Hide();
mOptions[RSK_SHOPSANITY_PRICES_ADULT_WALLET_WEIGHT].Hide();
mOptions[RSK_SHOPSANITY_PRICES_GIANT_WALLET_WEIGHT].Hide();
mOptions[RSK_SHOPSANITY_PRICES_TYCOON_WALLET_WEIGHT].Hide();
if (isTycoon ? mOptions[RSK_SHOPSANITY_PRICES_RANGE_1].GetOptionCount() == 101 : mOptions[RSK_SHOPSANITY_PRICES_RANGE_1].GetOptionCount() == 200) {
mOptions[RSK_SHOPSANITY_PRICES_RANGE_1].ChangeOptions(isTycoon ? NumOpts(0, 995, 5) : NumOpts(0, 500, 5));
mOptions[RSK_SHOPSANITY_PRICES_RANGE_2].ChangeOptions(isTycoon ? NumOpts(0, 995, 5) : NumOpts(0, 500, 5));
}
mOptions[RSK_SHOPSANITY_PRICES_AFFORDABLE].Unhide();
break;
case RO_PRICE_SET_BY_WALLET:
mOptions[RSK_SHOPSANITY_PRICES_FIXED_PRICE].Hide();
mOptions[RSK_SHOPSANITY_PRICES_RANGE_1].Hide();
mOptions[RSK_SHOPSANITY_PRICES_RANGE_2].Hide();
mOptions[RSK_SHOPSANITY_PRICES_NO_WALLET_WEIGHT].Unhide();
mOptions[RSK_SHOPSANITY_PRICES_CHILD_WALLET_WEIGHT].Unhide();
mOptions[RSK_SHOPSANITY_PRICES_ADULT_WALLET_WEIGHT].Unhide();
mOptions[RSK_SHOPSANITY_PRICES_GIANT_WALLET_WEIGHT].Unhide();
if (isTycoon){
mOptions[RSK_SHOPSANITY_PRICES_TYCOON_WALLET_WEIGHT].Unhide();
} else {
mOptions[RSK_SHOPSANITY_PRICES_TYCOON_WALLET_WEIGHT].Hide();
}
mOptions[RSK_SHOPSANITY_PRICES_AFFORDABLE].Unhide();
break;
default:
mOptions[RSK_SHOPSANITY_PRICES_FIXED_PRICE].Hide();
mOptions[RSK_SHOPSANITY_PRICES_RANGE_1].Hide();
mOptions[RSK_SHOPSANITY_PRICES_RANGE_2].Hide();
mOptions[RSK_SHOPSANITY_PRICES_NO_WALLET_WEIGHT].Hide();
mOptions[RSK_SHOPSANITY_PRICES_CHILD_WALLET_WEIGHT].Hide();
mOptions[RSK_SHOPSANITY_PRICES_ADULT_WALLET_WEIGHT].Hide();
mOptions[RSK_SHOPSANITY_PRICES_GIANT_WALLET_WEIGHT].Hide();
mOptions[RSK_SHOPSANITY_PRICES_TYCOON_WALLET_WEIGHT].Hide();
mOptions[RSK_SHOPSANITY_PRICES_AFFORDABLE].Unhide();
break;
}
}
Settings::Settings() : mExcludeLocationsOptionsAreas(RCAREA_INVALID) { Settings::Settings() : mExcludeLocationsOptionsAreas(RCAREA_INVALID) {
} }
@ -99,23 +162,51 @@ void Settings::CreateOptions() {
mOptions[RSK_SHUFFLE_SONGS] = Option::U8("Shuffle Songs", {"Song Locations", "Dungeon Rewards", "Anywhere"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("ShuffleSongs"), mOptionDescriptions[RSK_SHUFFLE_SONGS], WidgetType::Combobox, RO_SONG_SHUFFLE_SONG_LOCATIONS); mOptions[RSK_SHUFFLE_SONGS] = Option::U8("Shuffle Songs", {"Song Locations", "Dungeon Rewards", "Anywhere"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("ShuffleSongs"), mOptionDescriptions[RSK_SHUFFLE_SONGS], WidgetType::Combobox, RO_SONG_SHUFFLE_SONG_LOCATIONS);
mOptions[RSK_SHOPSANITY] = Option::U8("Shopsanity", {"Off", "Specific Count", "Random"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("Shopsanity"), mOptionDescriptions[RSK_SHOPSANITY], WidgetType::Combobox, RO_SHOPSANITY_OFF); mOptions[RSK_SHOPSANITY] = Option::U8("Shopsanity", {"Off", "Specific Count", "Random"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("Shopsanity"), mOptionDescriptions[RSK_SHOPSANITY], WidgetType::Combobox, RO_SHOPSANITY_OFF);
mOptions[RSK_SHOPSANITY_COUNT] = Option::U8("Shopsanity Item Count", {NumOpts(0, 7/*8*/)}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("ShopsanityCount"), mOptionDescriptions[RSK_SHOPSANITY_COUNT], WidgetType::Slider, 0, false, IMFLAG_NONE); mOptions[RSK_SHOPSANITY_COUNT] = Option::U8("Shopsanity Item Count", {NumOpts(0, 7/*8*/)}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("ShopsanityCount"), mOptionDescriptions[RSK_SHOPSANITY_COUNT], WidgetType::Slider, 0, false, IMFLAG_NONE);
mOptions[RSK_SHOPSANITY_PRICES] = Option::U8("Shopsanity Prices", {"Balanced", "Starting Wallet", "Adult Wallet", "Giant's Wallet", "Tycoon's Wallet"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("ShopsanityPrices"), mOptionDescriptions[RSK_SHOPSANITY_PRICES], WidgetType::Combobox, RO_SHOPSANITY_PRICE_BALANCED, false, IMFLAG_NONE); mOptions[RSK_SHOPSANITY_PRICES] = Option::U8("Shopsanity Prices", {"Vanilla", "Cheap Balanced", "Balanced", "Fixed", "Range", "Set By Wallet"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("ShopsanityPrices"), mOptionDescriptions[RSK_SHOPSANITY_PRICES], WidgetType::Combobox, RO_PRICE_VANILLA, false, IMFLAG_NONE);
mOptions[RSK_SHOPSANITY_PRICES_AFFORDABLE] = Option::Bool("Affordable Prices", CVAR_RANDOMIZER_SETTING("ShopsanityPricesAffordable"), mOptionDescriptions[RSK_SHOPSANITY_PRICES_AFFORDABLE]); mOptions[RSK_SHOPSANITY_PRICES_FIXED_PRICE] = Option::U8("Fixed Price", {NumOpts(0, 995, 5)}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("ShopsanityFixedPrice"), mOptionDescriptions[RSK_SHOPSANITY_PRICES_FIXED_PRICE], WidgetType::Slider, 10, true);
mOptions[RSK_SHOPSANITY_PRICES_RANGE_1] = Option::U8("Lower Bound", {NumOpts(0, 995, 5)}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("ShopsanityPriceRange1"), mOptionDescriptions[RSK_SHOPSANITY_PRICES_RANGE_1], WidgetType::Slider, 10, true, IMFLAG_NONE);
mOptions[RSK_SHOPSANITY_PRICES_RANGE_2] = Option::U8("Upper Bound", {NumOpts(0, 995, 5)}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("ShopsanityPriceRange2"), mOptionDescriptions[RSK_SHOPSANITY_PRICES_RANGE_2], WidgetType::Slider, 100, true, IMFLAG_NONE);
mOptions[RSK_SHOPSANITY_PRICES_NO_WALLET_WEIGHT] = Option::U8("No Wallet Weight", {NumOpts(0, 100)}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("ShopsanityNoWalletWeight"), mOptionDescriptions[RSK_SHOPSANITY_PRICES_NO_WALLET_WEIGHT], WidgetType::Slider, 10, true, IMFLAG_NONE);
mOptions[RSK_SHOPSANITY_PRICES_CHILD_WALLET_WEIGHT] = Option::U8("Child Wallet Weight", {NumOpts(0, 100)}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("ShopsanityChildWalletWeight"), mOptionDescriptions[RSK_SHOPSANITY_PRICES_CHILD_WALLET_WEIGHT], WidgetType::Slider, 10, true, IMFLAG_NONE);
mOptions[RSK_SHOPSANITY_PRICES_ADULT_WALLET_WEIGHT] = Option::U8("Adult Wallet Weight", {NumOpts(0, 100)}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("ShopsanityAdultWalletWeight"), mOptionDescriptions[RSK_SHOPSANITY_PRICES_ADULT_WALLET_WEIGHT], WidgetType::Slider, 10, true, IMFLAG_NONE);
mOptions[RSK_SHOPSANITY_PRICES_GIANT_WALLET_WEIGHT] = Option::U8("Giant Wallet Weight", {NumOpts(0, 100)}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("ShopsanityGiantWalletWeight"), mOptionDescriptions[RSK_SHOPSANITY_PRICES_GIANT_WALLET_WEIGHT], WidgetType::Slider, 10, true, IMFLAG_NONE);
mOptions[RSK_SHOPSANITY_PRICES_TYCOON_WALLET_WEIGHT] = Option::U8("Tycoon Wallet Weight", {NumOpts(0, 100)}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("ShopsanityTycoonWalletWeight"), mOptionDescriptions[RSK_SHOPSANITY_PRICES_TYCOON_WALLET_WEIGHT], WidgetType::Slider, 10, true, IMFLAG_NONE);
mOptions[RSK_SHOPSANITY_PRICES_AFFORDABLE] = Option::Bool("Shops Affordable Prices", CVAR_RANDOMIZER_SETTING("ShopsanityPricesAffordable"), mOptionDescriptions[RSK_SHOPSANITY_PRICES_AFFORDABLE]);
mOptions[RSK_SHUFFLE_TOKENS] = Option::U8("Tokensanity", {"Off", "Dungeons", "Overworld", "All Tokens"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("ShuffleTokens"), mOptionDescriptions[RSK_SHUFFLE_TOKENS], WidgetType::Combobox, RO_TOKENSANITY_OFF); mOptions[RSK_SHUFFLE_TOKENS] = Option::U8("Tokensanity", {"Off", "Dungeons", "Overworld", "All Tokens"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("ShuffleTokens"), mOptionDescriptions[RSK_SHUFFLE_TOKENS], WidgetType::Combobox, RO_TOKENSANITY_OFF);
mOptions[RSK_SHUFFLE_SCRUBS] = Option::U8("Scrub Shuffle", {"Off", "Affordable", "Expensive", "Random Prices"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("ShuffleScrubs"), mOptionDescriptions[RSK_SHUFFLE_SCRUBS], WidgetType::Combobox, RO_SCRUBS_OFF); mOptions[RSK_SHUFFLE_SCRUBS] = Option::U8("Scrub Shuffle", {"Off", "One-Time Only", "All"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("ShuffleScrubs"), mOptionDescriptions[RSK_SHUFFLE_SCRUBS], WidgetType::Combobox, RO_SCRUBS_OFF);
mOptions[RSK_SCRUBS_PRICES] = Option::U8("Scrub Prices", {"Vanilla", "Cheap Balanced", "Balanced", "Fixed", "Range", "Set By Wallet"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("ScrubsPrices"), mOptionDescriptions[RSK_SCRUBS_PRICES], WidgetType::Combobox, RO_PRICE_VANILLA, false, IMFLAG_NONE);
mOptions[RSK_SCRUBS_PRICES_FIXED_PRICE] = Option::U8("Fixed Price", {NumOpts(0, 995, 5)}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("ScrubsFixedPrice"), mOptionDescriptions[RSK_SCRUBS_PRICES_FIXED_PRICE], WidgetType::Slider, 10, true);
mOptions[RSK_SCRUBS_PRICES_RANGE_1] = Option::U8("Lower Bound", {NumOpts(0, 995, 5)}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("ScrubsPriceRange1"), mOptionDescriptions[RSK_SCRUBS_PRICES_RANGE_1], WidgetType::Slider, 10, true, IMFLAG_NONE);
mOptions[RSK_SCRUBS_PRICES_RANGE_2] = Option::U8("Upper Bound", {NumOpts(0, 995, 5)}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("ScrubsPriceRange2"), mOptionDescriptions[RSK_SCRUBS_PRICES_RANGE_2], WidgetType::Slider, 100, true, IMFLAG_NONE);
mOptions[RSK_SCRUBS_PRICES_NO_WALLET_WEIGHT] = Option::U8("No Wallet Weight", {NumOpts(0, 100)}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("ScrubsNoWalletWeight"), mOptionDescriptions[RSK_SCRUBS_PRICES_NO_WALLET_WEIGHT], WidgetType::Slider, 10, true, IMFLAG_NONE);
mOptions[RSK_SCRUBS_PRICES_CHILD_WALLET_WEIGHT] = Option::U8("Child Wallet Weight", {NumOpts(0, 100)}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("ScrubsChildWalletWeight"), mOptionDescriptions[RSK_SCRUBS_PRICES_CHILD_WALLET_WEIGHT], WidgetType::Slider, 10, true, IMFLAG_NONE);
mOptions[RSK_SCRUBS_PRICES_ADULT_WALLET_WEIGHT] = Option::U8("Adult Wallet Weight", {NumOpts(0, 100)}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("ScrubsAdultWalletWeight"), mOptionDescriptions[RSK_SCRUBS_PRICES_ADULT_WALLET_WEIGHT], WidgetType::Slider, 10, true, IMFLAG_NONE);
mOptions[RSK_SCRUBS_PRICES_GIANT_WALLET_WEIGHT] = Option::U8("Giant Wallet Weight", {NumOpts(0, 100)}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("ScrubsGiantWalletWeight"), mOptionDescriptions[RSK_SCRUBS_PRICES_GIANT_WALLET_WEIGHT], WidgetType::Slider, 10, true, IMFLAG_NONE);
mOptions[RSK_SCRUBS_PRICES_TYCOON_WALLET_WEIGHT] = Option::U8("Tycoon Wallet Weight", {NumOpts(0, 100)}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("ScrubsTycoonWalletWeight"), mOptionDescriptions[RSK_SCRUBS_PRICES_TYCOON_WALLET_WEIGHT], WidgetType::Slider, 10, true, IMFLAG_NONE);
mOptions[RSK_SCRUBS_PRICES_AFFORDABLE] = Option::Bool("Scrubs Affordable Prices", CVAR_RANDOMIZER_SETTING("ScrubsPricesAffordable"), mOptionDescriptions[RSK_SCRUBS_PRICES_AFFORDABLE]);
mOptions[RSK_SHUFFLE_BEEHIVES] = Option::Bool("Shuffle Beehives", CVAR_RANDOMIZER_SETTING("ShuffleBeehives"), mOptionDescriptions[RSK_SHUFFLE_BEEHIVES]); mOptions[RSK_SHUFFLE_BEEHIVES] = Option::Bool("Shuffle Beehives", CVAR_RANDOMIZER_SETTING("ShuffleBeehives"), mOptionDescriptions[RSK_SHUFFLE_BEEHIVES]);
mOptions[RSK_SHUFFLE_COWS] = Option::Bool("Shuffle Cows", CVAR_RANDOMIZER_SETTING("ShuffleCows"), mOptionDescriptions[RSK_SHUFFLE_COWS]); mOptions[RSK_SHUFFLE_COWS] = Option::Bool("Shuffle Cows", CVAR_RANDOMIZER_SETTING("ShuffleCows"), mOptionDescriptions[RSK_SHUFFLE_COWS]);
mOptions[RSK_SHUFFLE_KOKIRI_SWORD] = Option::Bool("Shuffle Kokiri Sword", CVAR_RANDOMIZER_SETTING("ShuffleKokiriSword"), mOptionDescriptions[RSK_SHUFFLE_KOKIRI_SWORD]); mOptions[RSK_SHUFFLE_KOKIRI_SWORD] = Option::Bool("Shuffle Kokiri Sword", CVAR_RANDOMIZER_SETTING("ShuffleKokiriSword"), mOptionDescriptions[RSK_SHUFFLE_KOKIRI_SWORD]);
mOptions[RSK_SHUFFLE_MASTER_SWORD] = Option::Bool("Shuffle Master Sword", CVAR_RANDOMIZER_SETTING("ShuffleMasterSword"), mOptionDescriptions[RSK_SHUFFLE_MASTER_SWORD]); mOptions[RSK_SHUFFLE_MASTER_SWORD] = Option::Bool("Shuffle Master Sword", CVAR_RANDOMIZER_SETTING("ShuffleMasterSword"), mOptionDescriptions[RSK_SHUFFLE_MASTER_SWORD]);
mOptions[RSK_SHUFFLE_CHILD_WALLET] = Option::Bool("Shuffle Child's Wallet", CVAR_RANDOMIZER_SETTING("ShuffleChildWallet"), mOptionDescriptions[RSK_SHUFFLE_CHILD_WALLET]); mOptions[RSK_SHUFFLE_CHILD_WALLET] = Option::Bool("Shuffle Child's Wallet", CVAR_RANDOMIZER_SETTING("ShuffleChildWallet"), mOptionDescriptions[RSK_SHUFFLE_CHILD_WALLET], IMFLAG_NONE);
mOptions[RSK_INCLUDE_TYCOON_WALLET] = Option::Bool("Include Tycoon Wallet", CVAR_RANDOMIZER_SETTING("IncludeTycoonWallet"), mOptionDescriptions[RSK_INCLUDE_TYCOON_WALLET]);
mOptions[RSK_SHUFFLE_OCARINA] = Option::Bool("Shuffle Ocarinas", CVAR_RANDOMIZER_SETTING("ShuffleOcarinas"), mOptionDescriptions[RSK_SHUFFLE_OCARINA]); mOptions[RSK_SHUFFLE_OCARINA] = Option::Bool("Shuffle Ocarinas", CVAR_RANDOMIZER_SETTING("ShuffleOcarinas"), mOptionDescriptions[RSK_SHUFFLE_OCARINA]);
mOptions[RSK_SHUFFLE_OCARINA_BUTTONS] = Option::Bool("Shuffle Ocarina Buttons", CVAR_RANDOMIZER_SETTING("ShuffleOcarinaButtons"), mOptionDescriptions[RSK_SHUFFLE_OCARINA_BUTTONS]); mOptions[RSK_SHUFFLE_OCARINA_BUTTONS] = Option::Bool("Shuffle Ocarina Buttons", CVAR_RANDOMIZER_SETTING("ShuffleOcarinaButtons"), mOptionDescriptions[RSK_SHUFFLE_OCARINA_BUTTONS]);
mOptions[RSK_SHUFFLE_SWIM] = Option::Bool("Shuffle Swim", CVAR_RANDOMIZER_SETTING("ShuffleSwim"), mOptionDescriptions[RSK_SHUFFLE_SWIM]); mOptions[RSK_SHUFFLE_SWIM] = Option::Bool("Shuffle Swim", CVAR_RANDOMIZER_SETTING("ShuffleSwim"), mOptionDescriptions[RSK_SHUFFLE_SWIM]);
mOptions[RSK_SHUFFLE_WEIRD_EGG] = Option::Bool("Shuffle Weird Egg", CVAR_RANDOMIZER_SETTING("ShuffleWeirdEgg"), mOptionDescriptions[RSK_SHUFFLE_WEIRD_EGG]); mOptions[RSK_SHUFFLE_WEIRD_EGG] = Option::Bool("Shuffle Weird Egg", CVAR_RANDOMIZER_SETTING("ShuffleWeirdEgg"), mOptionDescriptions[RSK_SHUFFLE_WEIRD_EGG]);
mOptions[RSK_SHUFFLE_GERUDO_MEMBERSHIP_CARD] = Option::Bool("Shuffle Gerudo Membership Card", CVAR_RANDOMIZER_SETTING("ShuffleGerudoToken"), mOptionDescriptions[RSK_SHUFFLE_GERUDO_MEMBERSHIP_CARD]); mOptions[RSK_SHUFFLE_GERUDO_MEMBERSHIP_CARD] = Option::Bool("Shuffle Gerudo Membership Card", CVAR_RANDOMIZER_SETTING("ShuffleGerudoToken"), mOptionDescriptions[RSK_SHUFFLE_GERUDO_MEMBERSHIP_CARD]);
mOptions[RSK_SHUFFLE_FISHING_POLE] = Option::Bool("Shuffle Fishing Pole", CVAR_RANDOMIZER_SETTING("ShuffleFishingPole"), mOptionDescriptions[RSK_SHUFFLE_FISHING_POLE]); mOptions[RSK_SHUFFLE_FISHING_POLE] = Option::Bool("Shuffle Fishing Pole", CVAR_RANDOMIZER_SETTING("ShuffleFishingPole"), mOptionDescriptions[RSK_SHUFFLE_FISHING_POLE]);
mOptions[RSK_SHUFFLE_MAGIC_BEANS] = Option::Bool("Shuffle Magic Beans", CVAR_RANDOMIZER_SETTING("ShuffleBeans"), mOptionDescriptions[RSK_SHUFFLE_MAGIC_BEANS]); mOptions[RSK_SHUFFLE_MERCHANTS] = Option::U8("Shuffle Merchants", {"Off", "Bean Merchant Only", "All But Beans", "All"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("ShuffleMerchants"), mOptionDescriptions[RSK_SHUFFLE_MERCHANTS], WidgetType::Combobox, RO_SHUFFLE_MERCHANTS_OFF, IMFLAG_NONE);
mOptions[RSK_SHUFFLE_MERCHANTS] = Option::U8("Shuffle Merchants", {"Off", "On (No Hints)", "On (With Hints)"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("ShuffleMerchants"), mOptionDescriptions[RSK_SHUFFLE_MERCHANTS], WidgetType::Combobox, RO_SHUFFLE_MERCHANTS_OFF); mOptions[RSK_MERCHANT_PRICES] = Option::U8("Merchant Prices", {"Vanilla", "Cheap Balanced", "Balanced", "Fixed", "Range", "Set By Wallet"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("MerchantPrices"), mOptionDescriptions[RSK_MERCHANT_PRICES], WidgetType::Combobox, RO_PRICE_VANILLA, false, IMFLAG_NONE);
mOptions[RSK_MERCHANT_PRICES_FIXED_PRICE] = Option::U8("Fixed Price", {NumOpts(0, 995, 5)}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("MerchantFixedPrice"), mOptionDescriptions[RSK_MERCHANT_PRICES_FIXED_PRICE], WidgetType::Slider, 10, true);
mOptions[RSK_MERCHANT_PRICES_RANGE_1] = Option::U8("Lower Bound", {NumOpts(0, 995, 5)}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("MerchantPriceRange1"), mOptionDescriptions[RSK_MERCHANT_PRICES_RANGE_1], WidgetType::Slider, 10, true, IMFLAG_NONE);
mOptions[RSK_MERCHANT_PRICES_RANGE_2] = Option::U8("Upper Bound", {NumOpts(0, 995, 5)}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("MerchantPriceRange2"), mOptionDescriptions[RSK_MERCHANT_PRICES_RANGE_2], WidgetType::Slider, 100, true, IMFLAG_NONE);
mOptions[RSK_MERCHANT_PRICES_NO_WALLET_WEIGHT] = Option::U8("No Wallet Weight", {NumOpts(0, 100)}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("MerchantNoWalletWeight"), mOptionDescriptions[RSK_MERCHANT_PRICES_NO_WALLET_WEIGHT], WidgetType::Slider, 10, true, IMFLAG_NONE);
mOptions[RSK_MERCHANT_PRICES_CHILD_WALLET_WEIGHT] = Option::U8("Child Wallet Weight", {NumOpts(0, 100)}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("MerchantChildWalletWeight"), mOptionDescriptions[RSK_MERCHANT_PRICES_CHILD_WALLET_WEIGHT], WidgetType::Slider, 10, true, IMFLAG_NONE);
mOptions[RSK_MERCHANT_PRICES_ADULT_WALLET_WEIGHT] = Option::U8("Adult Wallet Weight", {NumOpts(0, 100)}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("MerchantAdultWalletWeight"), mOptionDescriptions[RSK_MERCHANT_PRICES_ADULT_WALLET_WEIGHT], WidgetType::Slider, 10, true, IMFLAG_NONE);
mOptions[RSK_MERCHANT_PRICES_GIANT_WALLET_WEIGHT] = Option::U8("Giant Wallet Weight", {NumOpts(0, 100)}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("MerchantGiantWalletWeight"), mOptionDescriptions[RSK_MERCHANT_PRICES_GIANT_WALLET_WEIGHT], WidgetType::Slider, 10, true, IMFLAG_NONE);
mOptions[RSK_MERCHANT_PRICES_TYCOON_WALLET_WEIGHT] = Option::U8("Tycoon Wallet Weight", {NumOpts(0, 100)}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("MerchantTycoonWalletWeight"), mOptionDescriptions[RSK_MERCHANT_PRICES_TYCOON_WALLET_WEIGHT], WidgetType::Slider, 10, true, IMFLAG_NONE);
mOptions[RSK_MERCHANT_PRICES_AFFORDABLE] = Option::Bool("Merchant Affordable Prices", CVAR_RANDOMIZER_SETTING("MerchantPricesAffordable"), mOptionDescriptions[RSK_MERCHANT_PRICES_AFFORDABLE]);
mOptions[RSK_SHUFFLE_FROG_SONG_RUPEES] = Option::Bool("Shuffle Frog Song Rupees", CVAR_RANDOMIZER_SETTING("ShuffleFrogSongRupees"), mOptionDescriptions[RSK_SHUFFLE_FROG_SONG_RUPEES]); mOptions[RSK_SHUFFLE_FROG_SONG_RUPEES] = Option::Bool("Shuffle Frog Song Rupees", CVAR_RANDOMIZER_SETTING("ShuffleFrogSongRupees"), mOptionDescriptions[RSK_SHUFFLE_FROG_SONG_RUPEES]);
mOptions[RSK_SHUFFLE_ADULT_TRADE] = Option::Bool("Shuffle Adult Trade", CVAR_RANDOMIZER_SETTING("ShuffleAdultTrade"), mOptionDescriptions[RSK_SHUFFLE_ADULT_TRADE]); mOptions[RSK_SHUFFLE_ADULT_TRADE] = Option::Bool("Shuffle Adult Trade", CVAR_RANDOMIZER_SETTING("ShuffleAdultTrade"), mOptionDescriptions[RSK_SHUFFLE_ADULT_TRADE]);
mOptions[RSK_SHUFFLE_CHEST_MINIGAME] = Option::U8("Shuffle Chest Minigame", {"Off", "On (Separate)", "On (Pack)"}); mOptions[RSK_SHUFFLE_CHEST_MINIGAME] = Option::U8("Shuffle Chest Minigame", {"Off", "On (Separate)", "On (Pack)"});
@ -176,6 +267,7 @@ void Settings::CreateOptions() {
mOptions[RSK_HBA_HINT] = Option::Bool("Horseback Archery Hint", CVAR_RANDOMIZER_SETTING("HBAHint"), mOptionDescriptions[RSK_HBA_HINT], IMFLAG_NONE); mOptions[RSK_HBA_HINT] = Option::Bool("Horseback Archery Hint", CVAR_RANDOMIZER_SETTING("HBAHint"), mOptionDescriptions[RSK_HBA_HINT], IMFLAG_NONE);
mOptions[RSK_WARP_SONG_HINTS] = Option::Bool("Warp Song Hints", CVAR_RANDOMIZER_SETTING("WarpSongText"), mOptionDescriptions[RSK_WARP_SONG_HINTS], IMFLAG_NONE, WidgetType::Checkbox, RO_GENERIC_ON); mOptions[RSK_WARP_SONG_HINTS] = Option::Bool("Warp Song Hints", CVAR_RANDOMIZER_SETTING("WarpSongText"), mOptionDescriptions[RSK_WARP_SONG_HINTS], IMFLAG_NONE, WidgetType::Checkbox, RO_GENERIC_ON);
mOptions[RSK_SCRUB_TEXT_HINT] = Option::Bool("Scrub Hint Text", CVAR_RANDOMIZER_SETTING("ScrubText"), mOptionDescriptions[RSK_SCRUB_TEXT_HINT], IMFLAG_NONE); mOptions[RSK_SCRUB_TEXT_HINT] = Option::Bool("Scrub Hint Text", CVAR_RANDOMIZER_SETTING("ScrubText"), mOptionDescriptions[RSK_SCRUB_TEXT_HINT], IMFLAG_NONE);
mOptions[RSK_MERCHANT_TEXT_HINT] = Option::Bool("Merchant Hint Text", CVAR_RANDOMIZER_SETTING("MerchantText"), mOptionDescriptions[RSK_MERCHANT_TEXT_HINT], IMFLAG_NONE);
mOptions[RSK_KAK_10_SKULLS_HINT] = Option::Bool("10 GS Hint", CVAR_RANDOMIZER_SETTING("10GSHint"), mOptionDescriptions[RSK_KAK_10_SKULLS_HINT], IMFLAG_NONE); mOptions[RSK_KAK_10_SKULLS_HINT] = Option::Bool("10 GS Hint", CVAR_RANDOMIZER_SETTING("10GSHint"), mOptionDescriptions[RSK_KAK_10_SKULLS_HINT], IMFLAG_NONE);
mOptions[RSK_KAK_20_SKULLS_HINT] = Option::Bool("20 GS Hint", CVAR_RANDOMIZER_SETTING("20GSHint"), mOptionDescriptions[RSK_KAK_20_SKULLS_HINT], IMFLAG_NONE); mOptions[RSK_KAK_20_SKULLS_HINT] = Option::Bool("20 GS Hint", CVAR_RANDOMIZER_SETTING("20GSHint"), mOptionDescriptions[RSK_KAK_20_SKULLS_HINT], IMFLAG_NONE);
mOptions[RSK_KAK_30_SKULLS_HINT] = Option::Bool("30 GS Hint", CVAR_RANDOMIZER_SETTING("30GSHint"), mOptionDescriptions[RSK_KAK_30_SKULLS_HINT], IMFLAG_NONE); mOptions[RSK_KAK_30_SKULLS_HINT] = Option::Bool("30 GS Hint", CVAR_RANDOMIZER_SETTING("30GSHint"), mOptionDescriptions[RSK_KAK_30_SKULLS_HINT], IMFLAG_NONE);
@ -662,6 +754,7 @@ void Settings::CreateOptions() {
&mOptions[RSK_SHUFFLE_KOKIRI_SWORD], &mOptions[RSK_SHUFFLE_KOKIRI_SWORD],
&mOptions[RSK_SHUFFLE_MASTER_SWORD], &mOptions[RSK_SHUFFLE_MASTER_SWORD],
&mOptions[RSK_SHUFFLE_CHILD_WALLET], &mOptions[RSK_SHUFFLE_CHILD_WALLET],
&mOptions[RSK_INCLUDE_TYCOON_WALLET],
&mOptions[RSK_SHUFFLE_OCARINA], &mOptions[RSK_SHUFFLE_OCARINA],
&mOptions[RSK_SHUFFLE_OCARINA_BUTTONS], &mOptions[RSK_SHUFFLE_OCARINA_BUTTONS],
&mOptions[RSK_SHUFFLE_SWIM], &mOptions[RSK_SHUFFLE_SWIM],
@ -675,15 +768,42 @@ void Settings::CreateOptions() {
&mOptions[RSK_SHOPSANITY], &mOptions[RSK_SHOPSANITY],
&mOptions[RSK_SHOPSANITY_COUNT], &mOptions[RSK_SHOPSANITY_COUNT],
&mOptions[RSK_SHOPSANITY_PRICES], &mOptions[RSK_SHOPSANITY_PRICES],
&mOptions[RSK_SHOPSANITY_PRICES_FIXED_PRICE],
&mOptions[RSK_SHOPSANITY_PRICES_RANGE_1],
&mOptions[RSK_SHOPSANITY_PRICES_RANGE_2],
&mOptions[RSK_SHOPSANITY_PRICES_NO_WALLET_WEIGHT],
&mOptions[RSK_SHOPSANITY_PRICES_CHILD_WALLET_WEIGHT],
&mOptions[RSK_SHOPSANITY_PRICES_ADULT_WALLET_WEIGHT],
&mOptions[RSK_SHOPSANITY_PRICES_GIANT_WALLET_WEIGHT],
&mOptions[RSK_SHOPSANITY_PRICES_TYCOON_WALLET_WEIGHT],
&mOptions[RSK_SHOPSANITY_PRICES_AFFORDABLE], &mOptions[RSK_SHOPSANITY_PRICES_AFFORDABLE],
&mOptions[RSK_FISHSANITY], &mOptions[RSK_FISHSANITY],
&mOptions[RSK_FISHSANITY_POND_COUNT], &mOptions[RSK_FISHSANITY_POND_COUNT],
&mOptions[RSK_FISHSANITY_AGE_SPLIT], &mOptions[RSK_FISHSANITY_AGE_SPLIT],
&mOptions[RSK_SHUFFLE_SCRUBS], &mOptions[RSK_SHUFFLE_SCRUBS],
&mOptions[RSK_SCRUBS_PRICES],
&mOptions[RSK_SCRUBS_PRICES_FIXED_PRICE],
&mOptions[RSK_SCRUBS_PRICES_RANGE_1],
&mOptions[RSK_SCRUBS_PRICES_RANGE_2],
&mOptions[RSK_SCRUBS_PRICES_NO_WALLET_WEIGHT],
&mOptions[RSK_SCRUBS_PRICES_CHILD_WALLET_WEIGHT],
&mOptions[RSK_SCRUBS_PRICES_ADULT_WALLET_WEIGHT],
&mOptions[RSK_SCRUBS_PRICES_GIANT_WALLET_WEIGHT],
&mOptions[RSK_SCRUBS_PRICES_TYCOON_WALLET_WEIGHT],
&mOptions[RSK_SCRUBS_PRICES_AFFORDABLE],
&mOptions[RSK_SHUFFLE_BEEHIVES], &mOptions[RSK_SHUFFLE_BEEHIVES],
&mOptions[RSK_SHUFFLE_COWS], &mOptions[RSK_SHUFFLE_COWS],
&mOptions[RSK_SHUFFLE_MAGIC_BEANS],
&mOptions[RSK_SHUFFLE_MERCHANTS], &mOptions[RSK_SHUFFLE_MERCHANTS],
&mOptions[RSK_MERCHANT_PRICES],
&mOptions[RSK_MERCHANT_PRICES_FIXED_PRICE],
&mOptions[RSK_MERCHANT_PRICES_RANGE_1],
&mOptions[RSK_MERCHANT_PRICES_RANGE_2],
&mOptions[RSK_MERCHANT_PRICES_NO_WALLET_WEIGHT],
&mOptions[RSK_MERCHANT_PRICES_CHILD_WALLET_WEIGHT],
&mOptions[RSK_MERCHANT_PRICES_ADULT_WALLET_WEIGHT],
&mOptions[RSK_MERCHANT_PRICES_GIANT_WALLET_WEIGHT],
&mOptions[RSK_MERCHANT_PRICES_TYCOON_WALLET_WEIGHT],
&mOptions[RSK_MERCHANT_PRICES_AFFORDABLE],
&mOptions[RSK_SHUFFLE_FROG_SONG_RUPEES], &mOptions[RSK_SHUFFLE_FROG_SONG_RUPEES],
&mOptions[RSK_SHUFFLE_ADULT_TRADE], &mOptions[RSK_SHUFFLE_ADULT_TRADE],
&mOptions[RSK_SHUFFLE_100_GS_REWARD], &mOptions[RSK_SHUFFLE_100_GS_REWARD],
@ -753,6 +873,7 @@ void Settings::CreateOptions() {
&mOptions[RSK_FISHING_POLE_HINT], &mOptions[RSK_FISHING_POLE_HINT],
&mOptions[RSK_WARP_SONG_HINTS], &mOptions[RSK_WARP_SONG_HINTS],
&mOptions[RSK_SCRUB_TEXT_HINT], &mOptions[RSK_SCRUB_TEXT_HINT],
&mOptions[RSK_MERCHANT_TEXT_HINT],
&mOptions[RSK_KAK_10_SKULLS_HINT], &mOptions[RSK_KAK_10_SKULLS_HINT],
&mOptions[RSK_KAK_20_SKULLS_HINT], &mOptions[RSK_KAK_20_SKULLS_HINT],
&mOptions[RSK_KAK_30_SKULLS_HINT], &mOptions[RSK_KAK_30_SKULLS_HINT],
@ -880,6 +1001,14 @@ void Settings::CreateOptions() {
&mOptions[RSK_SHOPSANITY], &mOptions[RSK_SHOPSANITY],
&mOptions[RSK_SHOPSANITY_COUNT], &mOptions[RSK_SHOPSANITY_COUNT],
&mOptions[RSK_SHOPSANITY_PRICES], &mOptions[RSK_SHOPSANITY_PRICES],
&mOptions[RSK_SHOPSANITY_PRICES_FIXED_PRICE],
&mOptions[RSK_SHOPSANITY_PRICES_RANGE_1],
&mOptions[RSK_SHOPSANITY_PRICES_RANGE_2],
&mOptions[RSK_SHOPSANITY_PRICES_NO_WALLET_WEIGHT],
&mOptions[RSK_SHOPSANITY_PRICES_CHILD_WALLET_WEIGHT],
&mOptions[RSK_SHOPSANITY_PRICES_ADULT_WALLET_WEIGHT],
&mOptions[RSK_SHOPSANITY_PRICES_GIANT_WALLET_WEIGHT],
&mOptions[RSK_SHOPSANITY_PRICES_TYCOON_WALLET_WEIGHT],
&mOptions[RSK_SHOPSANITY_PRICES_AFFORDABLE], &mOptions[RSK_SHOPSANITY_PRICES_AFFORDABLE],
&mOptions[RSK_FISHSANITY], &mOptions[RSK_FISHSANITY],
&mOptions[RSK_FISHSANITY_POND_COUNT], &mOptions[RSK_FISHSANITY_POND_COUNT],
@ -887,6 +1016,16 @@ void Settings::CreateOptions() {
&mOptions[RSK_SHUFFLE_FISHING_POLE], &mOptions[RSK_SHUFFLE_FISHING_POLE],
&mOptions[RSK_SHUFFLE_TOKENS], &mOptions[RSK_SHUFFLE_TOKENS],
&mOptions[RSK_SHUFFLE_SCRUBS], &mOptions[RSK_SHUFFLE_SCRUBS],
&mOptions[RSK_SCRUBS_PRICES],
&mOptions[RSK_SCRUBS_PRICES_FIXED_PRICE],
&mOptions[RSK_SCRUBS_PRICES_RANGE_1],
&mOptions[RSK_SCRUBS_PRICES_RANGE_2],
&mOptions[RSK_SCRUBS_PRICES_NO_WALLET_WEIGHT],
&mOptions[RSK_SCRUBS_PRICES_CHILD_WALLET_WEIGHT],
&mOptions[RSK_SCRUBS_PRICES_ADULT_WALLET_WEIGHT],
&mOptions[RSK_SCRUBS_PRICES_GIANT_WALLET_WEIGHT],
&mOptions[RSK_SCRUBS_PRICES_TYCOON_WALLET_WEIGHT],
&mOptions[RSK_SCRUBS_PRICES_AFFORDABLE],
&mOptions[RSK_SHUFFLE_BEEHIVES], &mOptions[RSK_SHUFFLE_BEEHIVES],
&mOptions[RSK_SHUFFLE_COWS], &mOptions[RSK_SHUFFLE_COWS],
&mOptions[RSK_SHUFFLE_KOKIRI_SWORD], &mOptions[RSK_SHUFFLE_KOKIRI_SWORD],
@ -895,8 +1034,17 @@ void Settings::CreateOptions() {
&mOptions[RSK_SHUFFLE_SWIM], &mOptions[RSK_SHUFFLE_SWIM],
&mOptions[RSK_SHUFFLE_WEIRD_EGG], &mOptions[RSK_SHUFFLE_WEIRD_EGG],
&mOptions[RSK_SHUFFLE_GERUDO_MEMBERSHIP_CARD], &mOptions[RSK_SHUFFLE_GERUDO_MEMBERSHIP_CARD],
&mOptions[RSK_SHUFFLE_MAGIC_BEANS],
&mOptions[RSK_SHUFFLE_MERCHANTS], &mOptions[RSK_SHUFFLE_MERCHANTS],
&mOptions[RSK_MERCHANT_PRICES],
&mOptions[RSK_MERCHANT_PRICES_FIXED_PRICE],
&mOptions[RSK_MERCHANT_PRICES_RANGE_1],
&mOptions[RSK_MERCHANT_PRICES_RANGE_2],
&mOptions[RSK_MERCHANT_PRICES_NO_WALLET_WEIGHT],
&mOptions[RSK_MERCHANT_PRICES_CHILD_WALLET_WEIGHT],
&mOptions[RSK_MERCHANT_PRICES_ADULT_WALLET_WEIGHT],
&mOptions[RSK_MERCHANT_PRICES_GIANT_WALLET_WEIGHT],
&mOptions[RSK_MERCHANT_PRICES_TYCOON_WALLET_WEIGHT],
&mOptions[RSK_MERCHANT_PRICES_AFFORDABLE],
&mOptions[RSK_SHUFFLE_FROG_SONG_RUPEES], &mOptions[RSK_SHUFFLE_FROG_SONG_RUPEES],
&mOptions[RSK_SHUFFLE_ADULT_TRADE], &mOptions[RSK_SHUFFLE_ADULT_TRADE],
&mOptions[RSK_SHUFFLE_CHEST_MINIGAME], &mOptions[RSK_SHUFFLE_CHEST_MINIGAME],
@ -997,6 +1145,7 @@ void Settings::CreateOptions() {
&mOptions[RSK_KAK_100_SKULLS_HINT], &mOptions[RSK_KAK_100_SKULLS_HINT],
&mOptions[RSK_MASK_SHOP_HINT], &mOptions[RSK_MASK_SHOP_HINT],
&mOptions[RSK_SCRUB_TEXT_HINT], &mOptions[RSK_SCRUB_TEXT_HINT],
&mOptions[RSK_MERCHANT_TEXT_HINT],
&mOptions[RSK_FISHING_POLE_HINT], &mOptions[RSK_FISHING_POLE_HINT],
// TODO: Compasses show Reward/WOTH, Maps show Dungeon Mode, Starting Time // TODO: Compasses show Reward/WOTH, Maps show Dungeon Mode, Starting Time
&mOptions[RSK_DAMAGE_MULTIPLIER], &mOptions[RSK_DAMAGE_MULTIPLIER],
@ -1082,7 +1231,7 @@ void Settings::CreateOptions() {
&mOptionGroups[RSG_EXCLUDES] &mOptionGroups[RSG_EXCLUDES]
}); });
VanillaLogicDefaults = { VanillaLogicDefaults = {//RANDOTODO check what this does
&mOptions[RSK_LINKS_POCKET], &mOptions[RSK_LINKS_POCKET],
&mOptions[RSK_SHUFFLE_DUNGEON_REWARDS], &mOptions[RSK_SHUFFLE_DUNGEON_REWARDS],
&mOptions[RSK_SHUFFLE_SONGS], &mOptions[RSK_SHUFFLE_SONGS],
@ -1096,7 +1245,6 @@ void Settings::CreateOptions() {
&mOptions[RSK_SHUFFLE_SCRUBS], &mOptions[RSK_SHUFFLE_SCRUBS],
&mOptions[RSK_SHUFFLE_BEEHIVES], &mOptions[RSK_SHUFFLE_BEEHIVES],
&mOptions[RSK_SHUFFLE_COWS], &mOptions[RSK_SHUFFLE_COWS],
&mOptions[RSK_SHUFFLE_MAGIC_BEANS],
&mOptions[RSK_SHUFFLE_MERCHANTS], &mOptions[RSK_SHUFFLE_MERCHANTS],
&mOptions[RSK_SHUFFLE_FROG_SONG_RUPEES], &mOptions[RSK_SHUFFLE_FROG_SONG_RUPEES],
&mOptions[RSK_SHUFFLE_ADULT_TRADE], &mOptions[RSK_SHUFFLE_ADULT_TRADE],
@ -1131,12 +1279,30 @@ void Settings::CreateOptions() {
{ "Shuffle Settings:Shopsanity", RSK_SHOPSANITY }, { "Shuffle Settings:Shopsanity", RSK_SHOPSANITY },
{ "Shuffle Settings:Shopsanity Specific Count", RSK_SHOPSANITY_COUNT }, { "Shuffle Settings:Shopsanity Specific Count", RSK_SHOPSANITY_COUNT },
{ "Shuffle Settings:Shopsanity Prices", RSK_SHOPSANITY_PRICES }, { "Shuffle Settings:Shopsanity Prices", RSK_SHOPSANITY_PRICES },
{ "Shuffle Settings:Affordable Prices", RSK_SHOPSANITY_PRICES_AFFORDABLE }, { "Shuffle Settings:Shopsanity Fixed Amount", RSK_SHOPSANITY_PRICES_FIXED_PRICE },
{ "Shuffle Settings:Shopsanity Range 1", RSK_SHOPSANITY_PRICES_RANGE_1 },
{ "Shuffle Settings:Shopsanity Range 2", RSK_SHOPSANITY_PRICES_RANGE_2 },
{ "Shuffle Settings:Shopsanity No Wallet Weight", RSK_SHOPSANITY_PRICES_NO_WALLET_WEIGHT },
{ "Shuffle Settings:Shopsanity Child Wallet Weight", RSK_SHOPSANITY_PRICES_CHILD_WALLET_WEIGHT },
{ "Shuffle Settings:Shopsanity Adult Wallet Weight", RSK_SHOPSANITY_PRICES_ADULT_WALLET_WEIGHT },
{ "Shuffle Settings:Shopsanity Giants Wallet Weight", RSK_SHOPSANITY_PRICES_GIANT_WALLET_WEIGHT },
{ "Shuffle Settings:Shopsanity Tycoon Wallet Weight", RSK_SHOPSANITY_PRICES_TYCOON_WALLET_WEIGHT },
{ "Shuffle Settings:Shopsanity Affordable Prices", RSK_SHOPSANITY_PRICES_AFFORDABLE },
{ "Shuffle Settings:Fishsanity", RSK_FISHSANITY }, { "Shuffle Settings:Fishsanity", RSK_FISHSANITY },
{ "Shuffle Settings:Pond Fish Count", RSK_FISHSANITY_POND_COUNT }, { "Shuffle Settings:Pond Fish Count", RSK_FISHSANITY_POND_COUNT },
{ "Shuffle Settings:Split Pond Fish", RSK_FISHSANITY_AGE_SPLIT }, { "Shuffle Settings:Split Pond Fish", RSK_FISHSANITY_AGE_SPLIT },
{ "Shuffle Settings:Shuffle Fishing Pole", RSK_SHUFFLE_FISHING_POLE }, { "Shuffle Settings:Shuffle Fishing Pole", RSK_SHUFFLE_FISHING_POLE },
{ "Shuffle Settings:Scrub Shuffle", RSK_SHUFFLE_SCRUBS }, { "Shuffle Settings:Scrub Shuffle", RSK_SHUFFLE_SCRUBS },
{ "Shuffle Settings:Scrubs Prices", RSK_SCRUBS_PRICES },
{ "Shuffle Settings:Scrubs Fixed Amount", RSK_SCRUBS_PRICES_FIXED_PRICE },
{ "Shuffle Settings:Scrubs Range 1", RSK_SCRUBS_PRICES_RANGE_1 },
{ "Shuffle Settings:Scrubs Range 2", RSK_SCRUBS_PRICES_RANGE_2 },
{ "Shuffle Settings:Scrubs No Wallet Weight", RSK_SCRUBS_PRICES_NO_WALLET_WEIGHT },
{ "Shuffle Settings:Scrubs Child Wallet Weight", RSK_SCRUBS_PRICES_CHILD_WALLET_WEIGHT },
{ "Shuffle Settings:Scrubs Adult Wallet Weight", RSK_SCRUBS_PRICES_ADULT_WALLET_WEIGHT },
{ "Shuffle Settings:Scrubs Giants Wallet Weight", RSK_SCRUBS_PRICES_GIANT_WALLET_WEIGHT },
{ "Shuffle Settings:Scrubs Tycoon Wallet Weight", RSK_SCRUBS_PRICES_TYCOON_WALLET_WEIGHT },
{ "Shuffle Settings:Scrubs Affordable Prices", RSK_SCRUBS_PRICES_AFFORDABLE },
{ "Shuffle Settings:Beehive Shuffle", RSK_SHUFFLE_BEEHIVES }, { "Shuffle Settings:Beehive Shuffle", RSK_SHUFFLE_BEEHIVES },
{ "Shuffle Settings:Shuffle Cows", RSK_SHUFFLE_COWS }, { "Shuffle Settings:Shuffle Cows", RSK_SHUFFLE_COWS },
{ "Shuffle Settings:Tokensanity", RSK_SHUFFLE_TOKENS }, { "Shuffle Settings:Tokensanity", RSK_SHUFFLE_TOKENS },
@ -1144,13 +1310,23 @@ void Settings::CreateOptions() {
{ "Shuffle Settings:Shuffle Ocarina Buttons", RSK_SHUFFLE_OCARINA_BUTTONS }, { "Shuffle Settings:Shuffle Ocarina Buttons", RSK_SHUFFLE_OCARINA_BUTTONS },
{ "Shuffle Settings:Shuffle Swim", RSK_SHUFFLE_SWIM }, { "Shuffle Settings:Shuffle Swim", RSK_SHUFFLE_SWIM },
{ "Shuffle Settings:Shuffle Adult Trade", RSK_SHUFFLE_ADULT_TRADE }, { "Shuffle Settings:Shuffle Adult Trade", RSK_SHUFFLE_ADULT_TRADE },
{ "Shuffle Settings:Shuffle Magic Beans", RSK_SHUFFLE_MAGIC_BEANS },
{ "Shuffle Settings:Shuffle Kokiri Sword", RSK_SHUFFLE_KOKIRI_SWORD }, { "Shuffle Settings:Shuffle Kokiri Sword", RSK_SHUFFLE_KOKIRI_SWORD },
{ "Shuffle Settings:Shuffle Master Sword", RSK_SHUFFLE_MASTER_SWORD }, { "Shuffle Settings:Shuffle Master Sword", RSK_SHUFFLE_MASTER_SWORD },
{ "Shuffle Settings:Shuffle Child's Wallet", RSK_SHUFFLE_CHILD_WALLET }, { "Shuffle Settings:Shuffle Child's Wallet", RSK_SHUFFLE_CHILD_WALLET },
{ "Shuffle Settings:Include Tycoon Wallet", RSK_INCLUDE_TYCOON_WALLET },
{ "Shuffle Settings:Shuffle Weird Egg", RSK_SHUFFLE_WEIRD_EGG }, { "Shuffle Settings:Shuffle Weird Egg", RSK_SHUFFLE_WEIRD_EGG },
{ "Shuffle Settings:Shuffle Frog Song Rupees", RSK_SHUFFLE_FROG_SONG_RUPEES }, { "Shuffle Settings:Shuffle Frog Song Rupees", RSK_SHUFFLE_FROG_SONG_RUPEES },
{ "Shuffle Settings:Shuffle Merchants", RSK_SHUFFLE_MERCHANTS }, { "Shuffle Settings:Shuffle Merchants", RSK_SHUFFLE_MERCHANTS },
{ "Shuffle Settings:Merchant Prices", RSK_MERCHANT_PRICES },
{ "Shuffle Settings:Merchant Fixed Amount", RSK_MERCHANT_PRICES_FIXED_PRICE },
{ "Shuffle Settings:Merchant Range 1", RSK_MERCHANT_PRICES_RANGE_1 },
{ "Shuffle Settings:Merchant Range 2", RSK_MERCHANT_PRICES_RANGE_2 },
{ "Shuffle Settings:Merchant No Wallet Weight", RSK_MERCHANT_PRICES_NO_WALLET_WEIGHT },
{ "Shuffle Settings:Merchant Child Wallet Weight", RSK_MERCHANT_PRICES_CHILD_WALLET_WEIGHT },
{ "Shuffle Settings:Merchant Adult Wallet Weight", RSK_MERCHANT_PRICES_ADULT_WALLET_WEIGHT },
{ "Shuffle Settings:Merchant Giants Wallet Weight", RSK_MERCHANT_PRICES_GIANT_WALLET_WEIGHT },
{ "Shuffle Settings:Merchant Tycoon Wallet Weight", RSK_MERCHANT_PRICES_TYCOON_WALLET_WEIGHT },
{ "Shuffle Settings:Merchant Affordable Prices", RSK_MERCHANT_PRICES_AFFORDABLE },
{ "Shuffle Settings:Shuffle 100 GS Reward", RSK_SHUFFLE_100_GS_REWARD }, { "Shuffle Settings:Shuffle 100 GS Reward", RSK_SHUFFLE_100_GS_REWARD },
{ "Shuffle Settings:Shuffle Boss Souls", RSK_SHUFFLE_BOSS_SOULS }, { "Shuffle Settings:Shuffle Boss Souls", RSK_SHUFFLE_BOSS_SOULS },
{ "Shuffle Settings:Shuffle Deku Stick Bag", RSK_SHUFFLE_DEKU_STICK_BAG }, { "Shuffle Settings:Shuffle Deku Stick Bag", RSK_SHUFFLE_DEKU_STICK_BAG },
@ -1237,6 +1413,7 @@ void Settings::CreateOptions() {
{ "Miscellaneous Settings:Big Poes Hint", RSK_BIG_POES_HINT }, { "Miscellaneous Settings:Big Poes Hint", RSK_BIG_POES_HINT },
{ "Miscellaneous Settings:Warp Song Hints", RSK_WARP_SONG_HINTS }, { "Miscellaneous Settings:Warp Song Hints", RSK_WARP_SONG_HINTS },
{ "Miscellaneous Settings:Scrub Hint Text", RSK_SCRUB_TEXT_HINT }, { "Miscellaneous Settings:Scrub Hint Text", RSK_SCRUB_TEXT_HINT },
{ "Miscellaneous Settings:Merchant Hint Text", RSK_MERCHANT_TEXT_HINT },
{ "Miscellaneous Settings:Fishing Pole Hint", RSK_FISHING_POLE_HINT }, { "Miscellaneous Settings:Fishing Pole Hint", RSK_FISHING_POLE_HINT },
{ "Miscellaneous Settings:Hint Distribution", RSK_HINT_DISTRIBUTION }, { "Miscellaneous Settings:Hint Distribution", RSK_HINT_DISTRIBUTION },
{ "Miscellaneous Settings:Blue Fire Arrows", RSK_BLUE_FIRE_ARROWS }, { "Miscellaneous Settings:Blue Fire Arrows", RSK_BLUE_FIRE_ARROWS },
@ -1607,25 +1784,183 @@ void Settings::UpdateOptionProperties() {
} else { } else {
mOptions[RSK_SHUFFLE_WEIRD_EGG].Enable(); mOptions[RSK_SHUFFLE_WEIRD_EGG].Enable();
} }
bool isTycoon = CVarGetInteger(CVAR_RANDOMIZER_SETTING("IncludeTycoonWallet"), RO_GENERIC_OFF);
// Hide shopsanity prices if shopsanity is off or zero // Hide shopsanity prices if shopsanity is off or zero
switch (CVarGetInteger(CVAR_RANDOMIZER_SETTING("Shopsanity"), RO_SHOPSANITY_OFF)) { switch (CVarGetInteger(CVAR_RANDOMIZER_SETTING("Shopsanity"), RO_SHOPSANITY_OFF)) {
case RO_SHOPSANITY_OFF: case RO_SHOPSANITY_OFF:
mOptions[RSK_SHOPSANITY].AddFlag(IMFLAG_SEPARATOR_BOTTOM); mOptions[RSK_SHOPSANITY].AddFlag(IMFLAG_SEPARATOR_BOTTOM);
mOptions[RSK_SHOPSANITY_COUNT].Hide(); mOptions[RSK_SHOPSANITY_COUNT].Hide();
mOptions[RSK_SHOPSANITY_COUNT].Hide();
mOptions[RSK_SHOPSANITY_PRICES].Hide(); mOptions[RSK_SHOPSANITY_PRICES].Hide();
mOptions[RSK_SHOPSANITY_PRICES_AFFORDABLE].Hide(); mOptions[RSK_SHOPSANITY_PRICES_AFFORDABLE].Hide();
mOptions[RSK_SHOPSANITY_PRICES_FIXED_PRICE].Hide();
mOptions[RSK_SHOPSANITY_PRICES_RANGE_1].Hide();
mOptions[RSK_SHOPSANITY_PRICES_RANGE_2].Hide();
mOptions[RSK_SHOPSANITY_PRICES_NO_WALLET_WEIGHT].Hide();
mOptions[RSK_SHOPSANITY_PRICES_CHILD_WALLET_WEIGHT].Hide();
mOptions[RSK_SHOPSANITY_PRICES_ADULT_WALLET_WEIGHT].Hide();
mOptions[RSK_SHOPSANITY_PRICES_GIANT_WALLET_WEIGHT].Hide();
mOptions[RSK_SHOPSANITY_PRICES_TYCOON_WALLET_WEIGHT].Hide();
break; break;
case RO_SHOPSANITY_SPECIFIC_COUNT: case RO_SHOPSANITY_SPECIFIC_COUNT:
mOptions[RSK_SHOPSANITY].RemoveFlag(IMFLAG_SEPARATOR_BOTTOM);
mOptions[RSK_SHOPSANITY_COUNT].Unhide(); mOptions[RSK_SHOPSANITY_COUNT].Unhide();
mOptions[RSK_SHOPSANITY_PRICES].Unhide(); HandleShopsanityPriceUI();
mOptions[RSK_SHOPSANITY_PRICES_AFFORDABLE].Unhide(); break;
case RO_SHOPSANITY_RANDOM:
mOptions[RSK_SHOPSANITY_COUNT].Hide();
HandleShopsanityPriceUI();
break;
}
switch (CVarGetInteger(CVAR_RANDOMIZER_SETTING("ShuffleScrubs"), RO_SCRUBS_OFF)) {
case RO_SCRUBS_OFF:
mOptions[RSK_SHUFFLE_SCRUBS].AddFlag(IMFLAG_SEPARATOR_BOTTOM);
mOptions[RSK_SCRUBS_PRICES].Hide();
mOptions[RSK_SCRUBS_PRICES_AFFORDABLE].Hide();
mOptions[RSK_SCRUBS_PRICES_FIXED_PRICE].Hide();
mOptions[RSK_SCRUBS_PRICES_RANGE_1].Hide();
mOptions[RSK_SCRUBS_PRICES_RANGE_2].Hide();
mOptions[RSK_SCRUBS_PRICES_NO_WALLET_WEIGHT].Hide();
mOptions[RSK_SCRUBS_PRICES_CHILD_WALLET_WEIGHT].Hide();
mOptions[RSK_SCRUBS_PRICES_ADULT_WALLET_WEIGHT].Hide();
mOptions[RSK_SCRUBS_PRICES_GIANT_WALLET_WEIGHT].Hide();
mOptions[RSK_SCRUBS_PRICES_TYCOON_WALLET_WEIGHT].Hide();
break; break;
default: default:
mOptions[RSK_SHOPSANITY].RemoveFlag(IMFLAG_SEPARATOR_BOTTOM); mOptions[RSK_SHUFFLE_SCRUBS].RemoveFlag(IMFLAG_SEPARATOR_BOTTOM);
mOptions[RSK_SHOPSANITY_COUNT].Hide(); mOptions[RSK_SCRUBS_PRICES].Unhide();
mOptions[RSK_SHOPSANITY_PRICES].Unhide(); switch (CVarGetInteger(CVAR_RANDOMIZER_SETTING("ScrubsPrices"), RO_PRICE_VANILLA)){
mOptions[RSK_SHOPSANITY_PRICES_AFFORDABLE].Unhide(); case RO_PRICE_FIXED:
mOptions[RSK_SCRUBS_PRICES_FIXED_PRICE].Unhide();
mOptions[RSK_SCRUBS_PRICES_RANGE_1].Hide();
mOptions[RSK_SCRUBS_PRICES_RANGE_2].Hide();
mOptions[RSK_SCRUBS_PRICES_NO_WALLET_WEIGHT].Hide();
mOptions[RSK_SCRUBS_PRICES_CHILD_WALLET_WEIGHT].Hide();
mOptions[RSK_SCRUBS_PRICES_ADULT_WALLET_WEIGHT].Hide();
mOptions[RSK_SCRUBS_PRICES_GIANT_WALLET_WEIGHT].Hide();
mOptions[RSK_SCRUBS_PRICES_TYCOON_WALLET_WEIGHT].Hide();
if (isTycoon ? mOptions[RSK_SCRUBS_PRICES_FIXED_PRICE].GetOptionCount() == 501 : mOptions[RSK_SCRUBS_PRICES_FIXED_PRICE].GetOptionCount() == 1000) {
mOptions[RSK_SCRUBS_PRICES_FIXED_PRICE].ChangeOptions(isTycoon ? NumOpts(0, 999) : NumOpts(0, 500));
}
mOptions[RSK_SCRUBS_PRICES_AFFORDABLE].Hide();
break;
case RO_PRICE_RANGE:
mOptions[RSK_SCRUBS_PRICES_FIXED_PRICE].Hide();
mOptions[RSK_SCRUBS_PRICES_RANGE_1].Unhide();
mOptions[RSK_SCRUBS_PRICES_RANGE_2].Unhide();
mOptions[RSK_SCRUBS_PRICES_NO_WALLET_WEIGHT].Hide();
mOptions[RSK_SCRUBS_PRICES_CHILD_WALLET_WEIGHT].Hide();
mOptions[RSK_SCRUBS_PRICES_ADULT_WALLET_WEIGHT].Hide();
mOptions[RSK_SCRUBS_PRICES_GIANT_WALLET_WEIGHT].Hide();
mOptions[RSK_SCRUBS_PRICES_TYCOON_WALLET_WEIGHT].Hide();
if (isTycoon ? mOptions[RSK_SCRUBS_PRICES_RANGE_1].GetOptionCount() == 101 : mOptions[RSK_SCRUBS_PRICES_RANGE_1].GetOptionCount() == 200) {
mOptions[RSK_SCRUBS_PRICES_RANGE_1].ChangeOptions(isTycoon ? NumOpts(0, 995, 5) : NumOpts(0, 500, 5));
mOptions[RSK_SCRUBS_PRICES_RANGE_2].ChangeOptions(isTycoon ? NumOpts(0, 995, 5) : NumOpts(0, 500, 5));
}
mOptions[RSK_SCRUBS_PRICES_AFFORDABLE].Unhide();
break;
case RO_PRICE_SET_BY_WALLET:
mOptions[RSK_SCRUBS_PRICES_FIXED_PRICE].Hide();
mOptions[RSK_SCRUBS_PRICES_RANGE_1].Hide();
mOptions[RSK_SCRUBS_PRICES_RANGE_2].Hide();
mOptions[RSK_SCRUBS_PRICES_NO_WALLET_WEIGHT].Unhide();
mOptions[RSK_SCRUBS_PRICES_CHILD_WALLET_WEIGHT].Unhide();
mOptions[RSK_SCRUBS_PRICES_ADULT_WALLET_WEIGHT].Unhide();
mOptions[RSK_SCRUBS_PRICES_GIANT_WALLET_WEIGHT].Unhide();
if (isTycoon){
mOptions[RSK_SCRUBS_PRICES_TYCOON_WALLET_WEIGHT].Unhide();
} else {
mOptions[RSK_SCRUBS_PRICES_TYCOON_WALLET_WEIGHT].Hide();
}
mOptions[RSK_SCRUBS_PRICES_AFFORDABLE].Unhide();
break;
default:
mOptions[RSK_SCRUBS_PRICES_FIXED_PRICE].Hide();
mOptions[RSK_SCRUBS_PRICES_RANGE_1].Hide();
mOptions[RSK_SCRUBS_PRICES_RANGE_2].Hide();
mOptions[RSK_SCRUBS_PRICES_NO_WALLET_WEIGHT].Hide();
mOptions[RSK_SCRUBS_PRICES_CHILD_WALLET_WEIGHT].Hide();
mOptions[RSK_SCRUBS_PRICES_ADULT_WALLET_WEIGHT].Hide();
mOptions[RSK_SCRUBS_PRICES_GIANT_WALLET_WEIGHT].Hide();
mOptions[RSK_SCRUBS_PRICES_TYCOON_WALLET_WEIGHT].Hide();
mOptions[RSK_SCRUBS_PRICES_AFFORDABLE].Unhide();
break;
}
break;
}
switch (CVarGetInteger(CVAR_RANDOMIZER_SETTING("ShuffleMerchants"), RO_SHUFFLE_MERCHANTS_OFF)) {
case RO_SHUFFLE_MERCHANTS_OFF:
mOptions[RSK_SHUFFLE_MERCHANTS].AddFlag(IMFLAG_SEPARATOR_BOTTOM);
mOptions[RSK_MERCHANT_PRICES].Hide();
mOptions[RSK_MERCHANT_PRICES_AFFORDABLE].Hide();
mOptions[RSK_MERCHANT_PRICES_FIXED_PRICE].Hide();
mOptions[RSK_MERCHANT_PRICES_RANGE_1].Hide();
mOptions[RSK_MERCHANT_PRICES_RANGE_2].Hide();
mOptions[RSK_MERCHANT_PRICES_NO_WALLET_WEIGHT].Hide();
mOptions[RSK_MERCHANT_PRICES_CHILD_WALLET_WEIGHT].Hide();
mOptions[RSK_MERCHANT_PRICES_ADULT_WALLET_WEIGHT].Hide();
mOptions[RSK_MERCHANT_PRICES_GIANT_WALLET_WEIGHT].Hide();
mOptions[RSK_MERCHANT_PRICES_TYCOON_WALLET_WEIGHT].Hide();
break;
default:
mOptions[RSK_SHUFFLE_MERCHANTS].RemoveFlag(IMFLAG_SEPARATOR_BOTTOM);
mOptions[RSK_MERCHANT_PRICES].Unhide();
switch (CVarGetInteger(CVAR_RANDOMIZER_SETTING("MerchantPrices"), RO_PRICE_VANILLA)){
case RO_PRICE_FIXED:
mOptions[RSK_MERCHANT_PRICES_FIXED_PRICE].Unhide();
mOptions[RSK_MERCHANT_PRICES_RANGE_1].Hide();
mOptions[RSK_MERCHANT_PRICES_RANGE_2].Hide();
mOptions[RSK_MERCHANT_PRICES_NO_WALLET_WEIGHT].Hide();
mOptions[RSK_MERCHANT_PRICES_CHILD_WALLET_WEIGHT].Hide();
mOptions[RSK_MERCHANT_PRICES_ADULT_WALLET_WEIGHT].Hide();
mOptions[RSK_MERCHANT_PRICES_GIANT_WALLET_WEIGHT].Hide();
mOptions[RSK_MERCHANT_PRICES_TYCOON_WALLET_WEIGHT].Hide();
if (isTycoon ? mOptions[RSK_MERCHANT_PRICES_FIXED_PRICE].GetOptionCount() == 501 : mOptions[RSK_MERCHANT_PRICES_FIXED_PRICE].GetOptionCount() == 1000) {
mOptions[RSK_MERCHANT_PRICES_FIXED_PRICE].ChangeOptions(isTycoon ? NumOpts(0, 999) : NumOpts(0, 500));
}
mOptions[RSK_MERCHANT_PRICES_AFFORDABLE].Hide();
break;
case RO_PRICE_RANGE:
mOptions[RSK_MERCHANT_PRICES_FIXED_PRICE].Hide();
mOptions[RSK_MERCHANT_PRICES_RANGE_1].Unhide();
mOptions[RSK_MERCHANT_PRICES_RANGE_2].Unhide();
mOptions[RSK_MERCHANT_PRICES_NO_WALLET_WEIGHT].Hide();
mOptions[RSK_MERCHANT_PRICES_CHILD_WALLET_WEIGHT].Hide();
mOptions[RSK_MERCHANT_PRICES_ADULT_WALLET_WEIGHT].Hide();
mOptions[RSK_MERCHANT_PRICES_GIANT_WALLET_WEIGHT].Hide();
mOptions[RSK_MERCHANT_PRICES_TYCOON_WALLET_WEIGHT].Hide();
if (isTycoon ? mOptions[RSK_MERCHANT_PRICES_RANGE_1].GetOptionCount() == 101 : mOptions[RSK_MERCHANT_PRICES_RANGE_1].GetOptionCount() == 200) {
mOptions[RSK_MERCHANT_PRICES_RANGE_1].ChangeOptions(isTycoon ? NumOpts(0, 995, 5) : NumOpts(0, 500, 5));
mOptions[RSK_MERCHANT_PRICES_RANGE_2].ChangeOptions(isTycoon ? NumOpts(0, 995, 5) : NumOpts(0, 500, 5));
}
mOptions[RSK_MERCHANT_PRICES_AFFORDABLE].Unhide();
break;
case RO_PRICE_SET_BY_WALLET:
mOptions[RSK_MERCHANT_PRICES_FIXED_PRICE].Hide();
mOptions[RSK_MERCHANT_PRICES_RANGE_1].Hide();
mOptions[RSK_MERCHANT_PRICES_RANGE_2].Hide();
mOptions[RSK_MERCHANT_PRICES_NO_WALLET_WEIGHT].Unhide();
mOptions[RSK_MERCHANT_PRICES_CHILD_WALLET_WEIGHT].Unhide();
mOptions[RSK_MERCHANT_PRICES_ADULT_WALLET_WEIGHT].Unhide();
mOptions[RSK_MERCHANT_PRICES_GIANT_WALLET_WEIGHT].Unhide();
if (isTycoon){
mOptions[RSK_MERCHANT_PRICES_TYCOON_WALLET_WEIGHT].Unhide();
} else {
mOptions[RSK_MERCHANT_PRICES_TYCOON_WALLET_WEIGHT].Hide();
}
mOptions[RSK_MERCHANT_PRICES_AFFORDABLE].Unhide();
break;
default:
mOptions[RSK_MERCHANT_PRICES_FIXED_PRICE].Hide();
mOptions[RSK_MERCHANT_PRICES_RANGE_1].Hide();
mOptions[RSK_MERCHANT_PRICES_RANGE_2].Hide();
mOptions[RSK_MERCHANT_PRICES_NO_WALLET_WEIGHT].Hide();
mOptions[RSK_MERCHANT_PRICES_CHILD_WALLET_WEIGHT].Hide();
mOptions[RSK_MERCHANT_PRICES_ADULT_WALLET_WEIGHT].Hide();
mOptions[RSK_MERCHANT_PRICES_GIANT_WALLET_WEIGHT].Hide();
mOptions[RSK_MERCHANT_PRICES_TYCOON_WALLET_WEIGHT].Hide();
mOptions[RSK_MERCHANT_PRICES_AFFORDABLE].Unhide();
break;
}
break; break;
} }
// Hide fishing pond settings if we aren't shuffling the fishing pond // Hide fishing pond settings if we aren't shuffling the fishing pond
@ -2347,27 +2682,29 @@ void Settings::ParseJson(nlohmann::json spoilerFileJson) {
} }
break; break;
case RSK_SHOPSANITY_PRICES: case RSK_SHOPSANITY_PRICES:
if (it.value() == "Random") { case RSK_SCRUBS_PRICES:
mOptions[index].SetSelectedIndex(RO_SHOPSANITY_PRICE_BALANCED); case RSK_MERCHANT_PRICES:
} else if (it.value() == "Starter Wallet") { if (it.value() == "Vanilla") {
mOptions[index].SetSelectedIndex(RO_SHOPSANITY_PRICE_STARTER); mOptions[index].SetSelectedIndex(RO_PRICE_VANILLA);
} else if (it.value() == "Adult's Wallet") { } else if (it.value() == "Cheap Balanced") {
mOptions[index].SetSelectedIndex(RO_SHOPSANITY_PRICE_ADULT); mOptions[index].SetSelectedIndex(RO_PRICE_CHEAP_BALANCED);
} else if (it.value() == "Giant's Wallet") { } else if (it.value() == "Balanced") {
mOptions[index].SetSelectedIndex(RO_SHOPSANITY_PRICE_GIANT); mOptions[index].SetSelectedIndex(RO_PRICE_BALANCED);
} else if (it.value() == "Tycoon's Wallet") { } else if (it.value() == "Fixed") {
mOptions[index].SetSelectedIndex(RO_SHOPSANITY_PRICE_TYCOON); mOptions[index].SetSelectedIndex(RO_PRICE_FIXED);
} else if (it.value() == "Range") {
mOptions[index].SetSelectedIndex(RO_PRICE_RANGE);
} else if (it.value() == "Set By Wallet") {
mOptions[index].SetSelectedIndex(RO_PRICE_SET_BY_WALLET);
} }
break; break;
case RSK_SHUFFLE_SCRUBS: case RSK_SHUFFLE_SCRUBS:
if (it.value() == "Off") { if (it.value() == "Off") {
mOptions[index].SetSelectedIndex(RO_SCRUBS_OFF); mOptions[index].SetSelectedIndex(RO_SCRUBS_OFF);
} else if (it.value() == "Affordable") { } else if (it.value() == "Major Items Only") {
mOptions[index].SetSelectedIndex(RO_SCRUBS_AFFORDABLE); mOptions[index].SetSelectedIndex(RO_SCRUBS_MAJOR_ONLY);
} else if (it.value() == "Expensive") { } else if (it.value() == "All") {
mOptions[index].SetSelectedIndex(RO_SCRUBS_EXPENSIVE); mOptions[index].SetSelectedIndex(RO_SCRUBS_ALL);
} else if (it.value() == "Random Prices") {
mOptions[index].SetSelectedIndex(RO_SCRUBS_RANDOM);
} }
break; break;
case RSK_SHUFFLE_FISHING_POLE: case RSK_SHUFFLE_FISHING_POLE:
@ -2377,7 +2714,6 @@ void Settings::ParseJson(nlohmann::json spoilerFileJson) {
case RSK_SHUFFLE_BEEHIVES: case RSK_SHUFFLE_BEEHIVES:
case RSK_SHUFFLE_COWS: case RSK_SHUFFLE_COWS:
case RSK_SHUFFLE_ADULT_TRADE: case RSK_SHUFFLE_ADULT_TRADE:
case RSK_SHUFFLE_MAGIC_BEANS:
case RSK_SHUFFLE_KOKIRI_SWORD: case RSK_SHUFFLE_KOKIRI_SWORD:
case RSK_SHUFFLE_WEIRD_EGG: case RSK_SHUFFLE_WEIRD_EGG:
case RSK_SHUFFLE_FROG_SONG_RUPEES: case RSK_SHUFFLE_FROG_SONG_RUPEES:
@ -2386,6 +2722,7 @@ void Settings::ParseJson(nlohmann::json spoilerFileJson) {
case RSK_SHUFFLE_OCARINA_BUTTONS: case RSK_SHUFFLE_OCARINA_BUTTONS:
case RSK_SHUFFLE_SWIM: case RSK_SHUFFLE_SWIM:
case RSK_SHUFFLE_CHILD_WALLET: case RSK_SHUFFLE_CHILD_WALLET:
case RSK_INCLUDE_TYCOON_WALLET:
case RSK_STARTING_DEKU_SHIELD: case RSK_STARTING_DEKU_SHIELD:
case RSK_STARTING_KOKIRI_SWORD: case RSK_STARTING_KOKIRI_SWORD:
case RSK_STARTING_ZELDAS_LULLABY: case RSK_STARTING_ZELDAS_LULLABY:
@ -2432,6 +2769,7 @@ void Settings::ParseJson(nlohmann::json spoilerFileJson) {
case RSK_HBA_HINT: case RSK_HBA_HINT:
case RSK_WARP_SONG_HINTS: case RSK_WARP_SONG_HINTS:
case RSK_SCRUB_TEXT_HINT: case RSK_SCRUB_TEXT_HINT:
case RSK_MERCHANT_TEXT_HINT:
case RSK_SHUFFLE_ENTRANCES: case RSK_SHUFFLE_ENTRANCES:
case RSK_SHUFFLE_OVERWORLD_ENTRANCES: case RSK_SHUFFLE_OVERWORLD_ENTRANCES:
case RSK_SHUFFLE_GROTTO_ENTRANCES: case RSK_SHUFFLE_GROTTO_ENTRANCES:
@ -2446,6 +2784,8 @@ void Settings::ParseJson(nlohmann::json spoilerFileJson) {
case RSK_MIX_GROTTO_ENTRANCES: case RSK_MIX_GROTTO_ENTRANCES:
case RSK_DECOUPLED_ENTRANCES: case RSK_DECOUPLED_ENTRANCES:
case RSK_SHOPSANITY_PRICES_AFFORDABLE: case RSK_SHOPSANITY_PRICES_AFFORDABLE:
case RSK_SCRUBS_PRICES_AFFORDABLE:
case RSK_MERCHANT_PRICES_AFFORDABLE:
case RSK_ALL_LOCATIONS_REACHABLE: case RSK_ALL_LOCATIONS_REACHABLE:
case RSK_TRIFORCE_HUNT: case RSK_TRIFORCE_HUNT:
case RSK_MQ_DUNGEON_SET: case RSK_MQ_DUNGEON_SET:
@ -2486,10 +2826,12 @@ void Settings::ParseJson(nlohmann::json spoilerFileJson) {
case RSK_SHUFFLE_MERCHANTS: case RSK_SHUFFLE_MERCHANTS:
if (it.value() == "Off") { if (it.value() == "Off") {
mOptions[index].SetSelectedIndex(RO_SHUFFLE_MERCHANTS_OFF); mOptions[index].SetSelectedIndex(RO_SHUFFLE_MERCHANTS_OFF);
} else if (it.value() == "On (No Hints)") { } else if (it.value() == "Beans Only") {
mOptions[index].SetSelectedIndex(RO_SHUFFLE_MERCHANTS_ON_NO_HINT); mOptions[index].SetSelectedIndex(RO_SHUFFLE_MERCHANTS_BEANS_ONLY);
} else if (it.value() == "On (With Hints)") { } else if (it.value() == "All but Beans") {
mOptions[index].SetSelectedIndex(RO_SHUFFLE_MERCHANTS_ON_HINT); mOptions[index].SetSelectedIndex(RO_SHUFFLE_MERCHANTS_ALL_BUT_BEANS);
} else if (it.value() == "All") {
mOptions[index].SetSelectedIndex(RO_SHUFFLE_MERCHANTS_ALL);
} }
break; break;
// Uses Ammo Drops option for now. "Off" not yet implemented // Uses Ammo Drops option for now. "Off" not yet implemented

View File

@ -14,6 +14,11 @@ class Settings {
public: public:
Settings(); Settings();
/**
* @brief Hides or Unhides the price UI of Shopsanity based on settings.
*/
void HandleShopsanityPriceUI();
/** /**
* @brief Creates the `Option` and `OptionGroup` objects. This happens after construction because certain * @brief Creates the `Option` and `OptionGroup` objects. This happens after construction because certain
* other events in the codebase need to happen before all of the `Option`s can be created. * other events in the codebase need to happen before all of the `Option`s can be created.

View File

@ -11,7 +11,6 @@ std::unordered_map<uint32_t, CustomMessage> StaticData::hintTypeNames = {
{HINT_TYPE_TRIAL, CustomMessage("Trial")}, {HINT_TYPE_TRIAL, CustomMessage("Trial")},
{HINT_TYPE_ENTRANCE, CustomMessage("Entrance")}, {HINT_TYPE_ENTRANCE, CustomMessage("Entrance")},
{HINT_TYPE_ITEM_AREA, CustomMessage("Item Area")}, {HINT_TYPE_ITEM_AREA, CustomMessage("Item Area")},
{HINT_TYPE_MERCHANT, CustomMessage("Merchant")},
{HINT_TYPE_ALTAR_CHILD, CustomMessage("Child Altar")}, {HINT_TYPE_ALTAR_CHILD, CustomMessage("Child Altar")},
{HINT_TYPE_ALTAR_ADULT, CustomMessage("Adult Altar")}, {HINT_TYPE_ALTAR_ADULT, CustomMessage("Adult Altar")},
{HINT_TYPE_WOTH, CustomMessage("Way of the Hero")}, {HINT_TYPE_WOTH, CustomMessage("Way of the Hero")},
@ -79,10 +78,6 @@ std::unordered_map<uint32_t, CustomMessage> StaticData::hintNames = {
{RH_REQUIEM_WARP_LOC, CustomMessage("Requiem of Spirit Destination")}, {RH_REQUIEM_WARP_LOC, CustomMessage("Requiem of Spirit Destination")},
{RH_NOCTURNE_WARP_LOC, CustomMessage("Nocturne of Shadow Destination")}, {RH_NOCTURNE_WARP_LOC, CustomMessage("Nocturne of Shadow Destination")},
{RH_PRELUDE_WARP_LOC, CustomMessage("Prelude of Light Destination")}, {RH_PRELUDE_WARP_LOC, CustomMessage("Prelude of Light Destination")},
{RH_MEDIGORON, CustomMessage("Medigoron Hint")},
{RH_CARPET_SALESMAN, CustomMessage("Carpet Salseman Hint")},
{RH_BEAN_SALESMAN, CustomMessage("Bean Salseman Hint")},
{RH_GRANNY, CustomMessage("Granny Hint")},
{RH_HBA_HINT, CustomMessage("Horseback Archery Hint")}, {RH_HBA_HINT, CustomMessage("Horseback Archery Hint")},
{RH_MALON_HINT, CustomMessage("Malon Hint")}, {RH_MALON_HINT, CustomMessage("Malon Hint")},
{RH_CHICKENS_HINT, CustomMessage("Anju's Child Chickens Hint")}, {RH_CHICKENS_HINT, CustomMessage("Anju's Child Chickens Hint")},
@ -194,18 +189,14 @@ std::unordered_map<uint32_t, RandomizerHintTextKey> StaticData::trialData = {
std::unordered_map<RandomizerHint, StaticHintInfo> StaticData::staticHintInfoMap = { std::unordered_map<RandomizerHint, StaticHintInfo> StaticData::staticHintInfoMap = {
// RH_GANONDORF_HINT is special cased due to being different based on master sword shuffle // RH_GANONDORF_HINT is special cased due to being different based on master sword shuffle
// Altar hints are special cased due to special hint marking rules // Altar hints are special cased due to special hint marking rules
// warp song hints are special cased due to entrances not being done properly yet // warp song hints are special cased due to entrences not being done properly yet
// Ganondorf Joke is special Cased as the text is random // Ganondorf Joke is special cased as the text is random
{RH_SHEIK_HINT, StaticHintInfo(HINT_TYPE_AREA, {RHT_SHEIK_HINT_LA_ONLY}, RSK_SHEIK_LA_HINT, true, {}, {RG_LIGHT_ARROWS}, {RC_SHEIK_HINT_GC, RC_SHEIK_HINT_MQ_GC}, true)}, {RH_SHEIK_HINT, StaticHintInfo(HINT_TYPE_AREA, {RHT_SHEIK_HINT_LA_ONLY}, RSK_SHEIK_LA_HINT, true, {}, {RG_LIGHT_ARROWS}, {RC_SHEIK_HINT_GC, RC_SHEIK_HINT_MQ_GC}, true)},
{RH_DAMPES_DIARY, StaticHintInfo(HINT_TYPE_AREA, {RHT_DAMPE_DIARY}, RSK_DAMPES_DIARY_HINT, true, {}, {RG_PROGRESSIVE_HOOKSHOT}, {RC_DAMPE_HINT})}, {RH_DAMPES_DIARY, StaticHintInfo(HINT_TYPE_AREA, {RHT_DAMPE_DIARY}, RSK_DAMPES_DIARY_HINT, true, {}, {RG_PROGRESSIVE_HOOKSHOT}, {RC_DAMPE_HINT})},
{RH_GREG_RUPEE, StaticHintInfo(HINT_TYPE_AREA, {RHT_GREG_HINT}, RSK_GREG_HINT, true, {}, {RG_GREG_RUPEE}, {RC_GREG_HINT})}, {RH_GREG_RUPEE, StaticHintInfo(HINT_TYPE_AREA, {RHT_GREG_HINT}, RSK_GREG_HINT, true, {}, {RG_GREG_RUPEE}, {RC_GREG_HINT})},
{RH_SARIA_HINT, StaticHintInfo(HINT_TYPE_AREA, {RHT_SARIA_TALK_HINT, RHT_SARIA_SONG_HINT}, RSK_SARIA_HINT, true, {}, {RG_PROGRESSIVE_MAGIC_METER}, {RC_SARIA_SONG_HINT, RC_SONG_FROM_SARIA}, true)}, {RH_SARIA_HINT, StaticHintInfo(HINT_TYPE_AREA, {RHT_SARIA_TALK_HINT, RHT_SARIA_SONG_HINT}, RSK_SARIA_HINT, true, {}, {RG_PROGRESSIVE_MAGIC_METER}, {RC_SARIA_SONG_HINT, RC_SONG_FROM_SARIA}, true)},
{RH_LOACH_HINT, StaticHintInfo(HINT_TYPE_ITEM, {RHT_LOACH_HINT}, RSK_LOACH_HINT, true, {RC_LH_HYRULE_LOACH})}, {RH_LOACH_HINT, StaticHintInfo(HINT_TYPE_ITEM, {RHT_LOACH_HINT}, RSK_LOACH_HINT, true, {RC_LH_HYRULE_LOACH})},
{RH_FISHING_POLE, StaticHintInfo(HINT_TYPE_AREA, {RHT_FISHING_POLE_HINT}, RSK_FISHING_POLE_HINT, true, {}, {RG_FISHING_POLE}, {RC_FISHING_POLE_HINT}, true)}, {RH_FISHING_POLE, StaticHintInfo(HINT_TYPE_AREA, {RHT_FISHING_POLE_HINT}, RSK_FISHING_POLE_HINT, true, {}, {RG_FISHING_POLE}, {RC_FISHING_POLE_HINT}, true)},
{RH_MEDIGORON, StaticHintInfo(HINT_TYPE_MERCHANT, {RHT_MEDIGORON_HINT}, RSK_SHUFFLE_MERCHANTS, (uint8_t)RO_SHUFFLE_MERCHANTS_ON_HINT, {RC_GC_MEDIGORON})},
{RH_GRANNY, StaticHintInfo(HINT_TYPE_MERCHANT, {RHT_GRANNY_HINT}, RSK_SHUFFLE_MERCHANTS, (uint8_t)RO_SHUFFLE_MERCHANTS_ON_HINT, {RC_KAK_GRANNYS_SHOP})},
{RH_CARPET_SALESMAN, StaticHintInfo(HINT_TYPE_MERCHANT, {RHT_CARPET_SALESMAN_DIALOG_HINTED}, RSK_SHUFFLE_MERCHANTS, (uint8_t)RO_SHUFFLE_MERCHANTS_ON_HINT, {RC_WASTELAND_BOMBCHU_SALESMAN})},
{RH_BEAN_SALESMAN, StaticHintInfo(HINT_TYPE_MERCHANT, {RHT_BEAN_SALESMAN_HINT}, RSK_SHUFFLE_MAGIC_BEANS, true, {RC_ZR_MAGIC_BEAN_SALESMAN})},
{RH_HBA_HINT, StaticHintInfo(HINT_TYPE_ITEM, {RHT_HBA_HINT_SIGN, RHT_HBA_HINT_NOT_ON_HORSE, RHT_HBA_HINT_INITIAL, RHT_HBA_HINT_HAVE_1000}, RSK_HBA_HINT, true, {RC_GF_HBA_1000_POINTS, RC_GF_HBA_1500_POINTS})}, {RH_HBA_HINT, StaticHintInfo(HINT_TYPE_ITEM, {RHT_HBA_HINT_SIGN, RHT_HBA_HINT_NOT_ON_HORSE, RHT_HBA_HINT_INITIAL, RHT_HBA_HINT_HAVE_1000}, RSK_HBA_HINT, true, {RC_GF_HBA_1000_POINTS, RC_GF_HBA_1500_POINTS})},
{RH_MALON_HINT, StaticHintInfo(HINT_TYPE_ITEM, {RHT_MALON_HINT_TURNING_EVIL, RHT_MALON_HINT_HOW_IS_EPONA, RHT_MALON_HINT_OBSTICLE_COURSE, RHT_MALON_HINT_INGO_TEMPTED}, RSK_MALON_HINT, true, {RC_KF_LINKS_HOUSE_COW})}, {RH_MALON_HINT, StaticHintInfo(HINT_TYPE_ITEM, {RHT_MALON_HINT_TURNING_EVIL, RHT_MALON_HINT_HOW_IS_EPONA, RHT_MALON_HINT_OBSTICLE_COURSE, RHT_MALON_HINT_INGO_TEMPTED}, RSK_MALON_HINT, true, {RC_KF_LINKS_HOUSE_COW})},
{RH_BIG_POES_HINT, StaticHintInfo(HINT_TYPE_ITEM, {RHT_BIG_POES_HINT}, RSK_BIG_POES_HINT, true, {RC_MARKET_10_BIG_POES})}, {RH_BIG_POES_HINT, StaticHintInfo(HINT_TYPE_ITEM, {RHT_BIG_POES_HINT}, RSK_BIG_POES_HINT, true, {RC_MARKET_10_BIG_POES})},

View File

@ -40,6 +40,7 @@ class StaticData {
static std::vector<RandomizerCheck> dungeonRewardLocations; static std::vector<RandomizerCheck> dungeonRewardLocations;
static std::vector<RandomizerCheck> GetShopLocations(); static std::vector<RandomizerCheck> GetShopLocations();
static std::vector<RandomizerCheck> GetScrubLocations(); static std::vector<RandomizerCheck> GetScrubLocations();
static std::vector<RandomizerCheck> GetMerchantLocations();
static std::vector<RandomizerCheck> GetAdultTradeLocations(); static std::vector<RandomizerCheck> GetAdultTradeLocations();
static std::vector<RandomizerCheck> GetGossipStoneLocations(); static std::vector<RandomizerCheck> GetGossipStoneLocations();
static std::vector<RandomizerCheck> GetStaticHintLocations(); static std::vector<RandomizerCheck> GetStaticHintLocations();

View File

@ -2516,6 +2516,8 @@ extern "C" int CustomMessage_RetrieveIfExists(PlayState* play) {
s16 actorParams = 0; s16 actorParams = 0;
if (IS_RANDO) { if (IS_RANDO) {
auto ctx = Rando::Context::GetInstance(); auto ctx = Rando::Context::GetInstance();
bool nonBeanMerchants = ctx->GetOption(RSK_SHUFFLE_MERCHANTS).Is(RO_SHUFFLE_MERCHANTS_ALL_BUT_BEANS) ||
ctx->GetOption(RSK_SHUFFLE_MERCHANTS).Is(RO_SHUFFLE_MERCHANTS_ALL);
Player* player = GET_PLAYER(play); Player* player = GET_PLAYER(play);
if (textId == TEXT_RANDOMIZER_CUSTOM_ITEM) { if (textId == TEXT_RANDOMIZER_CUSTOM_ITEM) {
if (player->getItemEntry.getItemId == RG_ICE_TRAP) { if (player->getItemEntry.getItemId == RG_ICE_TRAP) {
@ -2602,21 +2604,20 @@ extern "C" int CustomMessage_RetrieveIfExists(PlayState* play) {
} }
} else if (textId == TEXT_SHEIK_NEED_HOOK || textId == TEXT_SHEIK_HAVE_HOOK) { } else if (textId == TEXT_SHEIK_NEED_HOOK || textId == TEXT_SHEIK_HAVE_HOOK) {
messageEntry = OTRGlobals::Instance->gRandomizer->GetSheikMessage(gPlayState->sceneNum, textId); messageEntry = OTRGlobals::Instance->gRandomizer->GetSheikMessage(gPlayState->sceneNum, textId);
// textId: TEXT_SCRUB_RANDOM + (randomizerInf - RAND_INF_SCRUBS_PURCHASED_DODONGOS_CAVERN_DEKU_SCRUB_NEAR_BOMB_BAG_LEFT)
} else if (textId == TEXT_SCRUB_RANDOM) {
EnDns* enDns = (EnDns*)GET_PLAYER(play)->targetActor;
messageEntry = OTRGlobals::Instance->gRandomizer->GetMerchantMessage(enDns->sohScrubIdentity.randomizerInf, TEXT_SCRUB_RANDOM, Randomizer_GetSettingValue(RSK_SCRUB_TEXT_HINT) == RO_GENERIC_OFF);
// Shop items each have two message entries, second one offset by NUM_SHOP_ITEMS // Shop items each have two message entries, second one offset by NUM_SHOP_ITEMS
// textId: TEXT_SHOP_ITEM_RANDOM + (randomizerInf - RAND_INF_SHOP_ITEMS_KF_SHOP_ITEM_1) // textId: TEXT_SHOP_ITEM_RANDOM + (randomizerInf - RAND_INF_SHOP_ITEMS_KF_SHOP_ITEM_1)
// textId: TEXT_SHOP_ITEM_RANDOM + ((randomizerInf - RAND_INF_SHOP_ITEMS_KF_SHOP_ITEM_1) + NUM_SHOP_ITEMS) // textId: TEXT_SHOP_ITEM_RANDOM + ((randomizerInf - RAND_INF_SHOP_ITEMS_KF_SHOP_ITEM_1) + NUM_SHOP_ITEMS)
} else if (textId >= TEXT_SHOP_ITEM_RANDOM && textId <= TEXT_SHOP_ITEM_RANDOM + (NUM_SHOP_ITEMS * 2)) { } else if (textId >= TEXT_SHOP_ITEM_RANDOM && textId < TEXT_SHOP_ITEM_RANDOM_CONFIRM) {
if (textId < TEXT_SHOP_ITEM_RANDOM + NUM_SHOP_ITEMS) { RandomizerCheck rc = OTRGlobals::Instance->gRandomizer->GetCheckFromRandomizerInf((RandomizerInf)((textId - TEXT_SHOP_ITEM_RANDOM) + RAND_INF_SHOP_ITEMS_KF_SHOP_ITEM_1));
RandomizerInf randoInf = (RandomizerInf)((textId - TEXT_SHOP_ITEM_RANDOM) + RAND_INF_SHOP_ITEMS_KF_SHOP_ITEM_1); messageEntry = OTRGlobals::Instance->gRandomizer->GetMerchantMessage(rc, TEXT_SHOP_ITEM_RANDOM);
messageEntry = OTRGlobals::Instance->gRandomizer->GetMerchantMessage(randoInf, TEXT_SHOP_ITEM_RANDOM); } else if (textId >= TEXT_SHOP_ITEM_RANDOM_CONFIRM && textId <= TEXT_SHOP_ITEM_RANDOM_CONFIRM_END){
} else { RandomizerCheck rc = OTRGlobals::Instance->gRandomizer->GetCheckFromRandomizerInf((RandomizerInf)((textId - TEXT_SHOP_ITEM_RANDOM_CONFIRM) + RAND_INF_SHOP_ITEMS_KF_SHOP_ITEM_1));
RandomizerInf randoInf = (RandomizerInf)((textId - (TEXT_SHOP_ITEM_RANDOM + NUM_SHOP_ITEMS)) + RAND_INF_SHOP_ITEMS_KF_SHOP_ITEM_1); messageEntry = OTRGlobals::Instance->gRandomizer->GetMerchantMessage(rc, TEXT_SHOP_ITEM_RANDOM_CONFIRM);
messageEntry = OTRGlobals::Instance->gRandomizer->GetMerchantMessage(randoInf, TEXT_SHOP_ITEM_RANDOM_CONFIRM); // textId: TEXT_SCRUB_RANDOM + (randomizerInf - RAND_INF_SCRUBS_PURCHASED_DODONGOS_CAVERN_DEKU_SCRUB_NEAR_BOMB_BAG_LEFT)
} } else if (textId == TEXT_SCRUB_RANDOM) {
EnDns* enDns = (EnDns*)GET_PLAYER(play)->targetActor;
RandomizerCheck rc = OTRGlobals::Instance->gRandomizer->GetCheckFromRandomizerInf((RandomizerInf)enDns->sohScrubIdentity.randomizerInf);
messageEntry = OTRGlobals::Instance->gRandomizer->GetMerchantMessage(rc, TEXT_SCRUB_RANDOM, TEXT_SCRUB_RANDOM_FREE, Randomizer_GetSettingValue(RSK_SCRUB_TEXT_HINT) == RO_GENERIC_OFF);
} else if (CVarGetInteger(CVAR_RANDOMIZER_ENHANCEMENT("RandomizeRupeeNames"), 1) && } else if (CVarGetInteger(CVAR_RANDOMIZER_ENHANCEMENT("RandomizeRupeeNames"), 1) &&
(textId == TEXT_BLUE_RUPEE || textId == TEXT_RED_RUPEE || textId == TEXT_PURPLE_RUPEE || (textId == TEXT_BLUE_RUPEE || textId == TEXT_RED_RUPEE || textId == TEXT_PURPLE_RUPEE ||
textId == TEXT_HUGE_RUPEE)) { textId == TEXT_HUGE_RUPEE)) {
@ -2624,27 +2625,32 @@ extern "C" int CustomMessage_RetrieveIfExists(PlayState* play) {
// In rando, replace Navi's general overworld hints with rando-related gameplay tips // In rando, replace Navi's general overworld hints with rando-related gameplay tips
} else if (CVarGetInteger(CVAR_RANDOMIZER_ENHANCEMENT("RandoRelevantNavi"), 1) && textId >= TEXT_NAVI_DEKU_TREE_SUMMONS && textId <= TEXT_NAVI_TRY_TO_KEEP_MOVING) { } else if (CVarGetInteger(CVAR_RANDOMIZER_ENHANCEMENT("RandoRelevantNavi"), 1) && textId >= TEXT_NAVI_DEKU_TREE_SUMMONS && textId <= TEXT_NAVI_TRY_TO_KEEP_MOVING) {
u16 naviTextId = Random(0, NUM_NAVI_MESSAGES); u16 naviTextId = Random(0, NUM_NAVI_MESSAGES);
messageEntry = CustomMessageManager::Instance->RetrieveMessage(Randomizer::NaviRandoMessageTableID, naviTextId); messageEntry = CustomMessageManager::Instance->RetrieveMessage(Randomizer::NaviRandoMessageTableID, naviTextId, MF_FORMATTED);
} }
else if (textId == TEXT_BEAN_SALESMAN_BUY_FOR_10 && ctx->GetOption(RSK_SHUFFLE_MAGIC_BEANS)) { else if (textId == TEXT_BEAN_SALESMAN_BUY_FOR_10 &&
messageEntry = ctx->GetHint(RH_BEAN_SALESMAN)->GetHintMessage(MF_AUTO_FORMAT); (ctx->GetOption(RSK_SHUFFLE_MERCHANTS).Is(RO_SHUFFLE_MERCHANTS_BEANS_ONLY) ||
ctx->GetOption(RSK_SHUFFLE_MERCHANTS).Is(RO_SHUFFLE_MERCHANTS_ALL))) {
messageEntry = OTRGlobals::Instance->gRandomizer->GetMerchantMessage(RC_ZR_MAGIC_BEAN_SALESMAN, TEXT_BEAN_SALESMAN_BUY_FOR_10, TEXT_NONE, Randomizer_GetSettingValue(RSK_MERCHANT_TEXT_HINT) == RO_GENERIC_OFF);
} }
else if (textId == TEXT_BEAN_SALESMAN_BUY_FOR_100) { else if (textId == TEXT_BEAN_SALESMAN_BUY_FOR_100) {
messageEntry = CustomMessageManager::Instance->RetrieveMessage(Randomizer::merchantMessageTableID, TEXT_BEAN_SALESMAN_BUY_FOR_100); messageEntry = CustomMessageManager::Instance->RetrieveMessage(Randomizer::merchantMessageTableID, TEXT_BEAN_SALESMAN_BUY_FOR_100);
} }
else if (textId == TEXT_GRANNYS_SHOP && !Flags_GetRandomizerInf(RAND_INF_MERCHANTS_GRANNYS_SHOP) && Randomizer_GetSettingValue(RSK_SHUFFLE_MERCHANTS) != RO_SHUFFLE_MERCHANTS_OFF && else if (textId == TEXT_GRANNYS_SHOP && !Flags_GetRandomizerInf(RAND_INF_MERCHANTS_GRANNYS_SHOP) && nonBeanMerchants &&
(ctx->GetOption(RSK_SHUFFLE_ADULT_TRADE) || INV_CONTENT(ITEM_CLAIM_CHECK) == ITEM_CLAIM_CHECK)){ (ctx->GetOption(RSK_SHUFFLE_ADULT_TRADE) || INV_CONTENT(ITEM_CLAIM_CHECK) == ITEM_CLAIM_CHECK)){
messageEntry = messageEntry = ctx->GetHint(RH_GRANNY)->GetHintMessage(MF_AUTO_FORMAT); messageEntry = OTRGlobals::Instance->gRandomizer->GetMerchantMessage(RC_KAK_GRANNYS_SHOP, TEXT_GRANNYS_SHOP, TEXT_NONE, Randomizer_GetSettingValue(RSK_MERCHANT_TEXT_HINT) == RO_GENERIC_OFF);
} }
else if (textId == TEXT_MEDIGORON && Randomizer_GetSettingValue(RSK_SHUFFLE_MERCHANTS) != RO_SHUFFLE_MERCHANTS_OFF){ else if (textId == TEXT_MEDIGORON && nonBeanMerchants){
messageEntry = messageEntry = ctx->GetHint(RH_MEDIGORON)->GetHintMessage(MF_AUTO_FORMAT); messageEntry = OTRGlobals::Instance->gRandomizer->GetMerchantMessage(RC_GC_MEDIGORON, TEXT_MEDIGORON, TEXT_NONE, Randomizer_GetSettingValue(RSK_MERCHANT_TEXT_HINT) == RO_GENERIC_OFF);
} }
else if (textId == TEXT_CARPET_SALESMAN_1 && !Flags_GetRandomizerInf(RAND_INF_MERCHANTS_CARPET_SALESMAN) && Randomizer_GetSettingValue(RSK_SHUFFLE_MERCHANTS) != RO_SHUFFLE_MERCHANTS_OFF){ else if (textId == TEXT_CARPET_SALESMAN_1 && !Flags_GetRandomizerInf(RAND_INF_MERCHANTS_CARPET_SALESMAN) && nonBeanMerchants){
messageEntry = ctx->GetHint(RH_CARPET_SALESMAN)->GetHintMessage(MF_AUTO_FORMAT); if (Randomizer_GetSettingValue(RSK_MERCHANT_TEXT_HINT)){
messageEntry = OTRGlobals::Instance->gRandomizer->GetMerchantMessage(RC_WASTELAND_BOMBCHU_SALESMAN, TEXT_CARPET_SALESMAN_1, TEXT_NONE, Randomizer_GetSettingValue(RSK_MERCHANT_TEXT_HINT) == RO_GENERIC_OFF);
} else {
messageEntry = OTRGlobals::Instance->gRandomizer->GetMerchantMessage(RC_WASTELAND_BOMBCHU_SALESMAN, TEXT_CARPET_SALESMAN_MYSTERIOUS, TEXT_NONE, Randomizer_GetSettingValue(RSK_MERCHANT_TEXT_HINT) == RO_GENERIC_OFF);
}
} }
else if (textId == TEXT_CARPET_SALESMAN_2 && !Flags_GetRandomizerInf(RAND_INF_MERCHANTS_CARPET_SALESMAN) && Randomizer_GetSettingValue(RSK_SHUFFLE_MERCHANTS) != RO_SHUFFLE_MERCHANTS_OFF){ else if (textId == TEXT_CARPET_SALESMAN_ARMS_DEALER){
messageEntry = CustomMessageManager::Instance->RetrieveMessage(Randomizer::merchantMessageTableID, textId); messageEntry = CustomMessageManager::Instance->RetrieveMessage(Randomizer::merchantMessageTableID, textId, MF_AUTO_FORMAT);
Flags_SetRandomizerInf(RAND_INF_MERCHANTS_CARPET_SALESMAN);//set here so we can actually check if the text is run, not a good solution
} else if (textId == TEXT_SKULLTULA_PEOPLE_IM_CURSED) { } else if (textId == TEXT_SKULLTULA_PEOPLE_IM_CURSED) {
actorParams = GET_PLAYER(play)->targetActor->params; actorParams = GET_PLAYER(play)->targetActor->params;
if (actorParams == 1 && ctx->GetOption(RSK_KAK_10_SKULLS_HINT)){ if (actorParams == 1 && ctx->GetOption(RSK_KAK_10_SKULLS_HINT)){
@ -2688,10 +2694,10 @@ extern "C" int CustomMessage_RetrieveIfExists(PlayState* play) {
messageEntry = CustomMessageManager::Instance->RetrieveMessage(Randomizer::hintMessageTableID, TEXT_WARP_MINUET_OF_FOREST); messageEntry = CustomMessageManager::Instance->RetrieveMessage(Randomizer::hintMessageTableID, TEXT_WARP_MINUET_OF_FOREST);
} }
else if (textId == TEXT_LAKE_HYLIA_WATER_SWITCH_NAVI || textId == TEXT_LAKE_HYLIA_WATER_SWITCH_SIGN) { else if (textId == TEXT_LAKE_HYLIA_WATER_SWITCH_NAVI || textId == TEXT_LAKE_HYLIA_WATER_SWITCH_SIGN) {
messageEntry = CustomMessageManager::Instance->RetrieveMessage(Randomizer::hintMessageTableID, textId); messageEntry = CustomMessageManager::Instance->RetrieveMessage(Randomizer::hintMessageTableID, textId, MF_AUTO_FORMAT);
} }
else if (textId == TEXT_SHOOTING_GALLERY_MAN_COME_BACK_WITH_BOW) { else if (textId == TEXT_SHOOTING_GALLERY_MAN_COME_BACK_WITH_BOW) {
messageEntry = CustomMessageManager::Instance->RetrieveMessage(Randomizer::hintMessageTableID, TEXT_SHOOTING_GALLERY_MAN_COME_BACK_WITH_BOW); messageEntry = CustomMessageManager::Instance->RetrieveMessage(Randomizer::hintMessageTableID, TEXT_SHOOTING_GALLERY_MAN_COME_BACK_WITH_BOW, MF_AUTO_FORMAT);
} }
else if (textId == TEXT_FIRE_TEMPLE_GORON_OWE_YOU_BIG_TIME || (textId >= TEXT_FIRE_TEMPLE_GORON_FALLING_DOORS_SECRET && textId <= TEXT_FIRE_TEMPLE_GORON_SOUNDS_DIFFERENT_SECRET)) { else if (textId == TEXT_FIRE_TEMPLE_GORON_OWE_YOU_BIG_TIME || (textId >= TEXT_FIRE_TEMPLE_GORON_FALLING_DOORS_SECRET && textId <= TEXT_FIRE_TEMPLE_GORON_SOUNDS_DIFFERENT_SECRET)) {
u16 choice = Random(0, NUM_GORON_MESSAGES); u16 choice = Random(0, NUM_GORON_MESSAGES);
@ -2762,7 +2768,7 @@ extern "C" int CustomMessage_RetrieveIfExists(PlayState* play) {
messageEntry = ctx->GetHint(RH_HBA_HINT)->GetHintMessage(MF_AUTO_FORMAT, 3); messageEntry = ctx->GetHint(RH_HBA_HINT)->GetHintMessage(MF_AUTO_FORMAT, 3);
} }
else if (textId == TEXT_CARPET_SALESMAN_CUSTOM_FAIL_TO_BUY){ else if (textId == TEXT_CARPET_SALESMAN_CUSTOM_FAIL_TO_BUY){
messageEntry = CustomMessageManager::Instance->RetrieveMessage(customMessageTableID, textId); messageEntry = CustomMessageManager::Instance->RetrieveMessage(customMessageTableID, textId, MF_AUTO_FORMAT);
} }
else if (textId == TEXT_MASK_SHOP_SIGN && ctx->GetOption(RSK_MASK_SHOP_HINT)) { else if (textId == TEXT_MASK_SHOP_SIGN && ctx->GetOption(RSK_MASK_SHOP_HINT)) {
messageEntry = ctx->GetHint(RH_MASK_SHOP_HINT)->GetHintMessage(MF_AUTO_FORMAT); messageEntry = ctx->GetHint(RH_MASK_SHOP_HINT)->GetHintMessage(MF_AUTO_FORMAT);
@ -2786,23 +2792,23 @@ extern "C" int CustomMessage_RetrieveIfExists(PlayState* play) {
// In vanilla, GS token count is incremented prior to the text box displaying // In vanilla, GS token count is incremented prior to the text box displaying
// In rando we need to bump the token count by one to show the correct count // In rando we need to bump the token count by one to show the correct count
s16 gsCount = gSaveContext.inventory.gsTokens + (IS_RANDO ? 1 : 0); s16 gsCount = gSaveContext.inventory.gsTokens + (IS_RANDO ? 1 : 0);
messageEntry = CustomMessageManager::Instance->RetrieveMessage(customMessageTableID, textId); messageEntry = CustomMessageManager::Instance->RetrieveMessage(customMessageTableID, textId, MF_FORMATTED);
messageEntry.Replace("[[gsCount]]", std::to_string(gsCount)); messageEntry.Replace("[[gsCount]]", std::to_string(gsCount));
} }
} else if ((IS_RANDO || CVarGetInteger(CVAR_ENHANCEMENT("BetterBombchuShopping"), 0)) && } else if ((IS_RANDO || CVarGetInteger(CVAR_ENHANCEMENT("BetterBombchuShopping"), 0)) &&
(textId == TEXT_BUY_BOMBCHUS_10_DESC || textId == TEXT_BUY_BOMBCHUS_10_PROMPT)) { (textId == TEXT_BUY_BOMBCHUS_10_DESC || textId == TEXT_BUY_BOMBCHUS_10_PROMPT)) {
messageEntry = CustomMessageManager::Instance->RetrieveMessage(customMessageTableID, textId); messageEntry = CustomMessageManager::Instance->RetrieveMessage(customMessageTableID, textId, MF_FORMATTED);
} else if (textId == TEXT_HEART_CONTAINER && CVarGetInteger(CVAR_ENHANCEMENT("InjectItemCounts"), 0)) { } else if (textId == TEXT_HEART_CONTAINER && CVarGetInteger(CVAR_ENHANCEMENT("InjectItemCounts"), 0)) {
messageEntry = CustomMessageManager::Instance->RetrieveMessage(customMessageTableID, TEXT_HEART_CONTAINER); messageEntry = CustomMessageManager::Instance->RetrieveMessage(customMessageTableID, TEXT_HEART_CONTAINER, MF_FORMATTED);
messageEntry.Replace("[[heartContainerCount]]", std::to_string(gSaveContext.sohStats.heartContainers + 1)); messageEntry.Replace("[[heartContainerCount]]", std::to_string(gSaveContext.sohStats.heartContainers + 1));
} else if (textId == TEXT_HEART_PIECE && CVarGetInteger(CVAR_ENHANCEMENT("InjectItemCounts"), 0)) { } else if (textId == TEXT_HEART_PIECE && CVarGetInteger(CVAR_ENHANCEMENT("InjectItemCounts"), 0)) {
messageEntry = CustomMessageManager::Instance->RetrieveMessage(customMessageTableID, TEXT_HEART_PIECE); messageEntry = CustomMessageManager::Instance->RetrieveMessage(customMessageTableID, TEXT_HEART_PIECE, MF_FORMATTED);
messageEntry.Replace("[[heartPieceCount]]", std::to_string(gSaveContext.sohStats.heartPieces + 1)); messageEntry.Replace("[[heartPieceCount]]", std::to_string(gSaveContext.sohStats.heartPieces + 1));
} else if (textId == TEXT_MARKET_GUARD_NIGHT && CVarGetInteger(CVAR_ENHANCEMENT("MarketSneak"), 0) && play->sceneNum == SCENE_MARKET_ENTRANCE_NIGHT) { } else if (textId == TEXT_MARKET_GUARD_NIGHT && CVarGetInteger(CVAR_ENHANCEMENT("MarketSneak"), 0) && play->sceneNum == SCENE_MARKET_ENTRANCE_NIGHT) {
messageEntry = CustomMessageManager::Instance->RetrieveMessage(customMessageTableID, TEXT_MARKET_GUARD_NIGHT); messageEntry = CustomMessageManager::Instance->RetrieveMessage(customMessageTableID, TEXT_MARKET_GUARD_NIGHT, MF_FORMATTED);
} }
if (textId == TEXT_FISHERMAN_LEAVE && CVarGetInteger(CVAR_ENHANCEMENT("QuitFishingAtDoor"), 0)) { if (textId == TEXT_FISHERMAN_LEAVE && CVarGetInteger(CVAR_ENHANCEMENT("QuitFishingAtDoor"), 0)) {
messageEntry = CustomMessageManager::Instance->RetrieveMessage(customMessageTableID, TEXT_FISHERMAN_LEAVE); messageEntry = CustomMessageManager::Instance->RetrieveMessage(customMessageTableID, TEXT_FISHERMAN_LEAVE, MF_FORMATTED);
} }
font->charTexBuf[0] = (messageEntry.GetTextBoxType() << 4) | messageEntry.GetTextBoxPosition(); font->charTexBuf[0] = (messageEntry.GetTextBoxType() << 4) | messageEntry.GetTextBoxPosition();
switch (gSaveContext.language) { switch (gSaveContext.language) {

View File

@ -189,8 +189,6 @@ extern "C" void OTRMessage_Init()
"Holà! Holà!&Les cannes ne sortent pas d'ici!&Je suis sérieux!^Voulez-vous arrêter?&\x1B&%gOui&Non%w")); //TODO Used AI translation as placeholder "Holà! Holà!&Les cannes ne sortent pas d'ici!&Je suis sérieux!^Voulez-vous arrêter?&\x1B&%gOui&Non%w")); //TODO Used AI translation as placeholder
CustomMessageManager::Instance->CreateMessage( CustomMessageManager::Instance->CreateMessage(
customMessageTableID, TEXT_CARPET_SALESMAN_CUSTOM_FAIL_TO_BUY, customMessageTableID, TEXT_CARPET_SALESMAN_CUSTOM_FAIL_TO_BUY,
CustomMessage("I'm sorry I can't sell you&these fine specimens,&they need an %rexperienced owner%w.^" CustomMessage("I'm sorry I can't sell you these fine specimens, they need an #experienced owner#.^"
"Come back when you have&had %gBombchus%w of your own.", "Come back when you have had #Bombchus# of your own.", {QM_RED, QM_GREEN}));
"",
""));
} }

View File

@ -164,7 +164,7 @@ void EnDs_OfferOddPotion(EnDs* this, PlayState* play) {
} }
s32 EnDs_CheckRupeesAndBottle() { s32 EnDs_CheckRupeesAndBottle() {
if (gSaveContext.rupees < 100) { if (GameInteractor_Should(VB_GRANNY_SAY_INSUFFICIENT_RUPEES, gSaveContext.rupees < 100, NULL)) {
return 0; return 0;
} else if (GameInteractor_Should(VB_NEED_BOTTLE_FOR_GRANNYS_ITEM, Inventory_HasEmptyBottle() == 0, NULL)) { } else if (GameInteractor_Should(VB_NEED_BOTTLE_FOR_GRANNYS_ITEM, Inventory_HasEmptyBottle() == 0, NULL)) {
return 1; return 1;
@ -174,7 +174,7 @@ s32 EnDs_CheckRupeesAndBottle() {
} }
void EnDs_GiveBluePotion(EnDs* this, PlayState* play) { void EnDs_GiveBluePotion(EnDs* this, PlayState* play) {
if (Actor_HasParent(&this->actor, play) || !GameInteractor_Should(VB_GIVE_ITEM_FROM_GRANNYS_SHOP, true, this)) { if (Actor_HasParent(&this->actor, play)) {
this->actor.parent = NULL; this->actor.parent = NULL;
this->actionFunc = EnDs_Talk; this->actionFunc = EnDs_Talk;
} else { } else {
@ -195,7 +195,9 @@ void EnDs_OfferBluePotion(EnDs* this, PlayState* play) {
this->actionFunc = EnDs_TalkNoEmptyBottle; this->actionFunc = EnDs_TalkNoEmptyBottle;
return; return;
case 2: // have 100 rupees and empty bottle case 2: // have 100 rupees and empty bottle
Rupees_ChangeBy(-100); if(GameInteractor_Should(VB_GRANNY_TAKE_MONEY, true, this)){
Rupees_ChangeBy(-100);
}
this->actor.flags &= ~ACTOR_FLAG_WILL_TALK; this->actor.flags &= ~ACTOR_FLAG_WILL_TALK;
if (GameInteractor_Should(VB_GIVE_ITEM_FROM_GRANNYS_SHOP, true, this)) { if (GameInteractor_Should(VB_GIVE_ITEM_FROM_GRANNYS_SHOP, true, this)) {
@ -203,9 +205,9 @@ void EnDs_OfferBluePotion(EnDs* this, PlayState* play) {
Actor_OfferGetItem(&this->actor, play, GI_POTION_BLUE, 10000.0f, 50.0f); Actor_OfferGetItem(&this->actor, play, GI_POTION_BLUE, 10000.0f, 50.0f);
gSaveContext.pendingSale = itemEntry.itemId; gSaveContext.pendingSale = itemEntry.itemId;
gSaveContext.pendingSaleMod = itemEntry.modIndex; gSaveContext.pendingSaleMod = itemEntry.modIndex;
this->actionFunc = EnDs_GiveBluePotion;
} }
this->actionFunc = EnDs_GiveBluePotion;
return; return;
} }
break; break;

View File

@ -21,4 +21,8 @@ typedef struct EnDs {
/* 0x01EC */ EnDsActionFunc actionFunc; /* 0x01EC */ EnDsActionFunc actionFunc;
} EnDs; // size = 0x01F0 } EnDs; // size = 0x01F0
void EnDs_Talk(EnDs* actor, PlayState* play);
void EnDs_TalkAfterGiveOddPotion(EnDs* actor, PlayState* play);
#endif #endif

View File

@ -245,15 +245,15 @@ void EnGm_ProcessChoiceIndex(EnGm* this, PlayState* play) {
if (Message_GetState(&play->msgCtx) == TEXT_STATE_CHOICE && Message_ShouldAdvance(play)) { if (Message_GetState(&play->msgCtx) == TEXT_STATE_CHOICE && Message_ShouldAdvance(play)) {
switch (play->msgCtx.choiceIndex) { switch (play->msgCtx.choiceIndex) {
case 0: // yes case 0: // yes
if (gSaveContext.rupees < 200) { if (GameInteractor_Should(VB_CHECK_RANDO_PRICE_OF_MEDIGORON, gSaveContext.rupees < 200, this)) {
Message_ContinueTextbox(play, 0xC8); Message_ContinueTextbox(play, 0xC8);
this->actionFunc = func_80A3DD7C; this->actionFunc = func_80A3DD7C;
} else { } else {
if (GameInteractor_Should(VB_GIVE_ITEM_FROM_MEDIGORON, true, this)) { if (GameInteractor_Should(VB_GIVE_ITEM_FROM_MEDIGORON, true, this)) {
Actor_OfferGetItem(&this->actor, play, GI_SWORD_KNIFE, 415.0f, 10.0f); Actor_OfferGetItem(&this->actor, play, GI_SWORD_KNIFE, 415.0f, 10.0f);
this->actionFunc = func_80A3DF00;
} }
this->actionFunc = func_80A3DF00;
} }
break; break;
case 1: // no case 1: // no
@ -265,8 +265,7 @@ void EnGm_ProcessChoiceIndex(EnGm* this, PlayState* play) {
} }
void func_80A3DF00(EnGm* this, PlayState* play) { void func_80A3DF00(EnGm* this, PlayState* play) {
if (Actor_HasParent(&this->actor, play) || !GameInteractor_Should(VB_GIVE_ITEM_FROM_MEDIGORON, true, this)) { if (Actor_HasParent(&this->actor, play)) {
Flags_SetRandomizerInf(RAND_INF_MERCHANTS_MEDIGORON);
this->actor.parent = NULL; this->actor.parent = NULL;
this->actionFunc = func_80A3DF60; this->actionFunc = func_80A3DF60;
} else { } else {

View File

@ -24,4 +24,6 @@ typedef struct EnGm {
/* 0x02C4 */ Vec3f talkPos; /* 0x02C4 */ Vec3f talkPos;
} EnGm; // size = 0x02D0 } EnGm; // size = 0x02D0
void func_80A3DC44(EnGm* actor, PlayState* play);
#endif #endif

View File

@ -128,11 +128,9 @@ void func_80A8910C(EnJs* this, PlayState* play) {
} }
void func_80A89160(EnJs* this, PlayState* play) { void func_80A89160(EnJs* this, PlayState* play) {
if (Actor_HasParent(&this->actor, play) || !GameInteractor_Should(VB_GIVE_ITEM_FROM_CARPET_SALESMAN, true, this)) { if (Actor_HasParent(&this->actor, play)) {
this->actor.parent = NULL; this->actor.parent = NULL;
En_Js_SetupAction(this, func_80A8910C); En_Js_SetupAction(this, func_80A8910C);
// Moved into the text handling to patch a text bug, not a great solution though
// Flags_SetRandomizerInf(RAND_INF_MERCHANTS_CARPET_SALESMAN);
} else { } else {
GetItemEntry itemEntry = ItemTable_Retrieve(GI_BOMBCHUS_10); GetItemEntry itemEntry = ItemTable_Retrieve(GI_BOMBCHUS_10);
gSaveContext.pendingSale = itemEntry.itemId; gSaveContext.pendingSale = itemEntry.itemId;
@ -145,17 +143,18 @@ void func_80A891C4(EnJs* this, PlayState* play) {
if (Message_GetState(&play->msgCtx) == TEXT_STATE_CHOICE && Message_ShouldAdvance(play)) { if (Message_GetState(&play->msgCtx) == TEXT_STATE_CHOICE && Message_ShouldAdvance(play)) {
switch (play->msgCtx.choiceIndex) { switch (play->msgCtx.choiceIndex) {
case 0: // yes case 0: // yes
if (gSaveContext.rupees < 200) { if (GameInteractor_Should(VB_CHECK_RANDO_PRICE_OF_CARPET_SALESMAN, gSaveContext.rupees < 200, this)) {
Message_ContinueTextbox(play, 0x6075); Message_ContinueTextbox(play, 0x6075);
func_80A89008(this); func_80A89008(this);
} else { } else {
if (GameInteractor_Should(VB_GIVE_BOMBCHUS_FROM_CARPET_SALESMAN, true, this) || if (!GameInteractor_Should(VB_GIVE_ITEM_FROM_CARPET_SALESMAN, false, this)) {
(Actor_HasParent(&this->actor, play) || !GameInteractor_Should(VB_GIVE_ITEM_FROM_CARPET_SALESMAN, true, this))){ if (GameInteractor_Should(VB_GIVE_BOMBCHUS_FROM_CARPET_SALESMAN, true, this) || Actor_HasParent(&this->actor, play)){
Rupees_ChangeBy(-200); Rupees_ChangeBy(-200);
En_Js_SetupAction(this, func_80A89160); En_Js_SetupAction(this, func_80A89160);
} else{ } else{
Message_ContinueTextbox(play, 0x6073); Message_ContinueTextbox(play, 0x6073);
func_80A89008(this); func_80A89008(this);
}
} }
} }
break; break;

View File

@ -22,4 +22,6 @@ typedef struct EnJs {
/* 0x028C */ EnJsActionFunc actionFunc; /* 0x028C */ EnJsActionFunc actionFunc;
} EnJs; // size = 0x0290 } EnJs; // size = 0x0290
void func_80A890C0(EnJs* actor, PlayState* play);
#endif #endif