Rando: Add Granny's Potion Shop to Merchant Shuffle (#2723)

* add granny shuffle to 3ds code

* add granny shuffle to soh randomizer

* make granny hand out merchant check

* have medigoron set pending sale mod

* capitalize granny shop item
This commit is contained in:
Adam Bird 2023-04-20 21:25:11 -04:00 committed by GitHub
parent 1b63f4ca1a
commit 8f0f8c7644
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
19 changed files with 156 additions and 34 deletions

View File

@ -25,6 +25,7 @@ typedef enum {
TEXT_HUGE_RUPEE = 0xF2,
TEXT_BEAN_SALESMAN = 0x405E,
TEXT_MEDIGORON = 0x304C,
TEXT_GRANNYS_SHOP = 0x500C,
TEXT_CARPET_SALESMAN_1 = 0x6077,
TEXT_CARPET_SALESMAN_2 = 0x6078,
TEXT_MARKET_GUARD_NIGHT = 0x7003,

View File

@ -488,8 +488,9 @@ const std::vector<FlagTable> flagTables = {
{ RAND_INF_SHOP_ITEMS_MARKET_BOMBCHU_SHOP_ITEM_7, "SHOP_ITEMS_MARKET_BOMBCHU_SHOP_ITEM_7" },
{ RAND_INF_SHOP_ITEMS_MARKET_BOMBCHU_SHOP_ITEM_8, "SHOP_ITEMS_MARKET_BOMBCHU_SHOP_ITEM_8" },
{ RAND_INF_MERCHANTS_MEDIGORON, "RAND_INF_MERCHANTS_MEDIGORON" },
{ RAND_INF_MERCHANTS_CARPET_SALESMAN, "RAND_INF_MERCHANTS_CARPET_SALESMAN" },
{ RAND_INF_MERCHANTS_MEDIGORON, "RAND_INF_MERCHANTS_MEDIGORON" },
{ RAND_INF_MERCHANTS_GRANNYS_SHOP, "RAND_INF_MERCHANTS_GRANNY_SHOP"},
{ RAND_INF_ADULT_TRADES_LW_TRADE_COJIRO, "ADULT_TRADES_LW_TRADE_COJIRO" },
{ RAND_INF_ADULT_TRADES_GV_TRADE_SAW, "ADULT_TRADES_GV_TRADE_SAW" },
@ -498,5 +499,6 @@ const std::vector<FlagTable> flagTables = {
{ RAND_INF_ADULT_TRADES_DMT_TRADE_EYEDROPS, "ADULT_TRADES_DMT_TRADE_EYEDROPS" },
{ RAND_INF_KAK_100_GOLD_SKULLTULA_REWARD, "KAK_100_GOLD_SKULLTULA_REWARD" },
{ RAND_INF_GREG_FOUND, "RAND_INF_GREG_FOUND" },
} },
};
};

View File

@ -432,6 +432,32 @@ constexpr std::array DungeonColors = {
textStr->replace(carrotSymbol, 1, INSTANT_TEXT_OFF()+WAIT_FOR_INPUT()+INSTANT_TEXT_ON());
carrotSymbol = textStr->find('^');
}
//If there's a two-way choice and only 1 newline before it in the same text box, add another one
size_t choice = textStr->find(TWO_WAY_CHOICE());
if (choice != std::string::npos) {
size_t newLinesCount = 0;
size_t lastBoxBreak = textStr->rfind(WAIT_FOR_INPUT(), choice);
lastNewline = choice;
if (lastBoxBreak == std::string::npos) {
lastBoxBreak = 0;
}
while ((lastNewline != std::string::npos)) {
lastNewline = textStr->rfind(NEWLINE(), lastNewline - 1);
if (lastNewline != std::string::npos && lastNewline > lastBoxBreak) {
newLinesCount++;
} else {
break;
}
}
if (newLinesCount <= 1) {
textStr->replace(choice, TWO_WAY_CHOICE().length(), NEWLINE()+TWO_WAY_CHOICE());
}
}
//add colors
for (auto color : colors) {
size_t firstHashtag = textStr->find('#');

View File

@ -3126,6 +3126,13 @@ void HintTable_Init() {
/*spanish*/ "!#^La marca que te guiará al #Templo del&Espíritu# es la #bandera que está a la&" +
IF_NOT_MQ() + "izquierda" + MQ_ELSE() + "derecha" + MQ_END() + "# al salir de aquí. ¡Nos vemos!" },
});
hintTable[GRANNY_DIALOG] = HintText::MerchantsDialogs({
// obscure text
Text{ "! How about #100 Rupees#?&" + TWO_WAY_CHOICE() + "#Buy&Don't buy#",
/*french*/ "! Que dis-tu de #100 rubis#?&" + TWO_WAY_CHOICE() + "#Acheter&Ne pas acheter#",
/*spanish*/ ". Vendo por #100 rupias#.&" + TWO_WAY_CHOICE() + "#Comprar&No comprar#" },
});
}
int32_t StonesRequiredBySettings() {

View File

@ -739,14 +739,19 @@ void CreateAltarText() {
void CreateMerchantsHints() {
Text medigoronItemText = Location(GC_MEDIGORON)->GetPlacedItem().GetHint().GetText();
Text grannyItemText = Location(KAK_GRANNYS_SHOP)->GetPlacedItem().GetHint().GetText();
Text carpetSalesmanItemText = Location(WASTELAND_BOMBCHU_SALESMAN)->GetPlacedItem().GetHint().GetText();
Text carpetSalesmanItemClearText = Location(WASTELAND_BOMBCHU_SALESMAN)->GetPlacedItem().GetHint().GetClear();
Text grannyCapitalItemText = grannyItemText.Capitalize();
Text medigoronText = Hint(MEDIGORON_DIALOG_FIRST).GetText()+medigoronItemText+Hint(MEDIGORON_DIALOG_SECOND).GetText();
Text grannyText = grannyCapitalItemText+Hint(GRANNY_DIALOG).GetText();
Text carpetSalesmanTextOne = Hint(CARPET_SALESMAN_DIALOG_FIRST).GetText()+carpetSalesmanItemText+Hint(CARPET_SALESMAN_DIALOG_SECOND).GetText();
Text carpetSalesmanTextTwo = Hint(CARPET_SALESMAN_DIALOG_THIRD).GetText()+carpetSalesmanItemClearText+Hint(CARPET_SALESMAN_DIALOG_FOURTH).GetText();
CreateMessageFromTextObject(0x9120, 0, 2, 3, AddColorsAndFormat(medigoronText, {QM_RED, QM_GREEN}));
CreateMessageFromTextObject(0x9121, 0, 2, 3, AddColorsAndFormat(grannyText, {QM_RED, QM_GREEN}));
CreateMessageFromTextObject(0x6077, 0, 2, 3, AddColorsAndFormat(carpetSalesmanTextOne, {QM_RED, QM_GREEN}));
CreateMessageFromTextObject(0x6078, 0, 2, 3, AddColorsAndFormat(carpetSalesmanTextTwo, {QM_RED, QM_YELLOW, QM_RED}));
}

View File

@ -120,6 +120,7 @@ void LocationTable_Init() {
locationTable[KAK_MAN_ON_ROOF] = ItemLocation::Base (RC_KAK_MAN_ON_ROOF, 0x52, 0x3E, "Kak Man on Roof", KAK_MAN_ON_ROOF, PIECE_OF_HEART, {Category::cKakarikoVillage, Category::cKakariko,}, SpoilerCollectionCheck::ItemGetInf(29), SpoilerCollectionCheckGroup::GROUP_KAKARIKO);
locationTable[KAK_SHOOTING_GALLERY_REWARD] = ItemLocation::Base (RC_KAK_SHOOTING_GALLERY_REWARD, 0x42, 0x30, "Kak Shooting Gallery Reward", KAK_SHOOTING_GALLERY_REWARD, PROGRESSIVE_BOW, {Category::cKakarikoVillage, Category::cKakariko, Category::cMinigame}, SpoilerCollectionCheck::Chest(0x42, 0x1F), SpoilerCollectionCheckGroup::GROUP_KAKARIKO);
locationTable[KAK_TRADE_ODD_MUSHROOM] = ItemLocation::Base (RC_KAK_TRADE_ODD_MUSHROOM, 0x4E, 0x20, "Kak Trade Odd Mushroom", KAK_TRADE_ODD_MUSHROOM, ODD_POTION, {Category::cKakarikoVillage, Category::cKakariko, Category::cAdultTrade}, SpoilerCollectionCheck::ItemGetInf(56), SpoilerCollectionCheckGroup::GROUP_KAKARIKO);
locationTable[KAK_GRANNYS_SHOP] = ItemLocation::Base (RC_KAK_GRANNYS_SHOP, 0x4E, 0x10, "Kak Granny's Shop", KAK_GRANNYS_SHOP, BLUE_POTION_REFILL, {Category::cKakarikoVillage, Category::cKakariko, Category::cMerchant}, SpoilerCollectionCheck::EventChkInf(0x32), SpoilerCollectionCheckGroup::GROUP_KAKARIKO);
locationTable[KAK_ANJU_AS_ADULT] = ItemLocation::Base (RC_KAK_ANJU_AS_ADULT, 0x52, 0x1D, "Kak Anju as Adult", KAK_ANJU_AS_ADULT, CLAIM_CHECK, {Category::cKakarikoVillage, Category::cKakariko,}, SpoilerCollectionCheck::ItemGetInf(36), SpoilerCollectionCheckGroup::GROUP_KAKARIKO);
locationTable[KAK_ANJU_AS_CHILD] = ItemLocation::Base (RC_KAK_ANJU_AS_CHILD, 0x52, 0x0F, "Kak Anju as Child", KAK_ANJU_AS_CHILD, EMPTY_BOTTLE, {Category::cKakarikoVillage, Category::cKakariko, Category::cMinigame}, SpoilerCollectionCheck::ItemGetInf(4), SpoilerCollectionCheckGroup::GROUP_KAKARIKO);
locationTable[KAK_TRADE_POCKET_CUCCO] = ItemLocation::Base (RC_KAK_TRADE_POCKET_CUCCO, 0x52, 0x0E, "Kak Trade Pocket Cucco", KAK_TRADE_POCKET_CUCCO, COJIRO, {Category::cKakarikoVillage, Category::cKakariko, Category::cAdultTrade}, SpoilerCollectionCheck::ItemGetInf(38), SpoilerCollectionCheckGroup::GROUP_KAKARIKO);
@ -1281,6 +1282,7 @@ std::vector<uint32_t> overworldLocations = {
KAK_MAN_ON_ROOF,
KAK_SHOOTING_GALLERY_REWARD,
KAK_TRADE_ODD_MUSHROOM,
KAK_GRANNYS_SHOP,
KAK_ANJU_AS_CHILD,
KAK_ANJU_AS_ADULT,
KAK_TRADE_POCKET_CUCCO,

View File

@ -725,6 +725,7 @@ void GenerateItemPool() {
AddItemToMainPool(BOMBCHU_10);
}
} else {
PlaceItemInLocation(KAK_GRANNYS_SHOP, BOTTLE_WITH_BLUE_POTION, false, true);
PlaceItemInLocation(GC_MEDIGORON, GIANTS_KNIFE, false, true);
PlaceItemInLocation(WASTELAND_BOMBCHU_SALESMAN, BOMBCHU_10, false, true);
}
@ -1071,7 +1072,11 @@ void GenerateItemPool() {
IceTrapModels.push_back(ItemTable(RandomElement(bottles)).GetItemID()); //Get one random bottle type for ice traps
for (uint8_t i = 0; i < bottleCount; i++) {
if (i >= rutoBottles) {
AddRandomBottle(bottles);
if ((i == bottleCount - 1) && ShuffleMerchants.IsNot(SHUFFLEMERCHANTS_OFF)) {
AddItemToMainPool(BOTTLE_WITH_BLUE_POTION);
} else {
AddRandomBottle(bottles);
}
} else {
AddItemToMainPool(RUTOS_LETTER);
}

View File

@ -388,6 +388,7 @@ typedef enum {
KAK_REDEAD_GROTTO_CHEST,
KAK_SHOOTING_GALLERY_REWARD,
KAK_TRADE_ODD_MUSHROOM,
KAK_GRANNYS_SHOP,
KAK_10_GOLD_SKULLTULA_REWARD,
KAK_20_GOLD_SKULLTULA_REWARD,
KAK_30_GOLD_SKULLTULA_REWARD,
@ -1821,6 +1822,7 @@ typedef enum {
CARPET_SALESMAN_DIALOG_SECOND,
CARPET_SALESMAN_DIALOG_THIRD,
CARPET_SALESMAN_DIALOG_FOURTH,
GRANNY_DIALOG,
KEY_ENUM_MAX,
} Key;

View File

@ -191,6 +191,7 @@ void AreaTable_Init_Kakariko() {
EventAccess(&OddPoulticeAccess, {[]{return OddPoulticeAccess || (IsAdult && (OddMushroomAccess || (OddMushroom && DisableTradeRevert)));}}),
}, {
LocationAccess(KAK_TRADE_ODD_MUSHROOM, {[]{return IsAdult && OddMushroom;}}),
LocationAccess(KAK_GRANNYS_SHOP, {[]{return IsAdult && OddMushroom && AdultsWallet;}}),
}, {
//Exits
Entrance(KAK_BACKYARD, {[]{return true;}}),

View File

@ -447,15 +447,16 @@ string_view magicBeansDesc = "Enabling this adds a pack of 10 beans t
/*------------------------------ //
| SHUFFLE MERCHANTS | //
------------------------------*/ //
string_view merchantsDesc = "Enabling this adds a Giant's Knife and a pack\n" //
"of Bombchus to the item pool and changes both\n" //
"Medigoron and the Haunted Wasteland Carpet\n" //
"Salesman to sell a random item once at the price\n"
"of 200 rupees."; //
string_view merchantsHintsDesc = "These hints will make Medigoron and the Carpet\n" //
"Salesman tell you which item they're selling.\n" //
string_view merchantsDesc = "Enabling this changes Medigoron, Granny and the\n"//
"Carpet Salesman to sell a random item once at a\n"//
"high price (100 for Granny, 200 for the others).\n\n"
"A Giant's Knife and a pack of Bombchus will be\n" //
"added to the item pool, and one of the bottles\n" //
"will contain a Blue Potion"; //
string_view merchantsHintsDesc = "These hints will make the merchants tell you\n" //
"which item they're selling.\n" //
"\n" //
"The Clearer Hints setting will affect how they\n" //
"The Hint Clarity setting will affect how they\n" //
"refer to the item."; //
/*------------------------------ //
| SHUFFLE FROG SONG RUPEES | //

View File

@ -1792,12 +1792,14 @@ namespace Settings {
IncludeAndHide({ZR_MAGIC_BEAN_SALESMAN});
}
//Force include Medigoron and Carpet salesman if Shuffle Merchants is off
//Force include Medigoron, Granny and Carpet salesman if Shuffle Merchants is off
if (ShuffleMerchants.IsNot(SHUFFLEMERCHANTS_OFF)) {
Unhide({GC_MEDIGORON});
Unhide({KAK_GRANNYS_SHOP});
Unhide({WASTELAND_BOMBCHU_SALESMAN});
} else {
IncludeAndHide({GC_MEDIGORON});
IncludeAndHide({KAK_GRANNYS_SHOP});
IncludeAndHide({WASTELAND_BOMBCHU_SALESMAN});
}

View File

@ -58,6 +58,15 @@ public:
}
}
// Convert first char to upper case
Text Capitalize(void) const {
Text cap = *this + "";
for (std::string* str : {&cap.english, &cap.french, &cap.spanish}) {
(*str)[0] = std::toupper((*str)[0]);
}
return cap;
}
//find the appropriate bars that separate singular from plural
void SetForm(int form) {
for (std::string* str : {&english, &french, &spanish}) {

View File

@ -540,7 +540,19 @@ void Randomizer::LoadMerchantMessages(const char* spoilerFileName) {
"Wie wäre es mit %r&{{item}}%w für %g200 Rubine?%w\x1B&%gJa!&Nein!%w",
"Veux-tu acheter %r&{{item}}%w pour %g200 rubis?%w\x1B&%gOui&Non&w"
});
//Granny Shopy
//RANDOTODO: Implement obscure/ambiguous hints
CustomMessageManager::Instance->CreateMessage(
Randomizer::merchantMessageTableID, TEXT_GRANNYS_SHOP,
{
TEXTBOX_TYPE_BLACK,
TEXTBOX_POS_BOTTOM,
"%r{{item}}%w!&How about %g100 rupees%w?\x1B&%gYes&No%w",
"%r{{item}}%w!&Wie wäre es mit %g100 Rubine?%w\x1B&%gJa!&Nein!%w",
"%r{{item}}%w!&Que dis-tu de %g100 rubis?%w\x1B&%gOui&Non&w"
});
//Carpet Salesman
//RANDOTODO: Implement obscure/ambiguous hints
std::vector<std::string> cgBoxTwoText;
@ -2591,7 +2603,8 @@ std::map<RandomizerCheck, RandomizerInf> rcToRandomizerInf = {
{ RC_MARKET_BOMBCHU_SHOP_ITEM_7, RAND_INF_SHOP_ITEMS_MARKET_BOMBCHU_SHOP_ITEM_7 },
{ RC_MARKET_BOMBCHU_SHOP_ITEM_8, RAND_INF_SHOP_ITEMS_MARKET_BOMBCHU_SHOP_ITEM_8 },
{ RC_GC_MEDIGORON, RAND_INF_MERCHANTS_MEDIGORON },
{ RC_WASTELAND_BOMBCHU_SALESMAN, RAND_INF_MERCHANTS_CARPET_SALESMAN },
{ RC_KAK_GRANNYS_SHOP, RAND_INF_MERCHANTS_GRANNYS_SHOP },
{ RC_WASTELAND_BOMBCHU_SALESMAN, RAND_INF_MERCHANTS_CARPET_SALESMAN },
{ RC_LW_TRADE_COJIRO, RAND_INF_ADULT_TRADES_LW_TRADE_COJIRO },
{ RC_GV_TRADE_SAW, RAND_INF_ADULT_TRADES_GV_TRADE_SAW },
{ RC_DMT_TRADE_BROKEN_SWORD, RAND_INF_ADULT_TRADES_DMT_TRADE_BROKEN_SWORD },
@ -3776,9 +3789,10 @@ void DrawRandoEditor(bool& open) {
// Shuffle Merchants
ImGui::Text(Settings::ShuffleMerchants.GetName().c_str());
UIWidgets::InsertHelpHoverText(
"Enabling this adds a Giant's Knife and a pack of Bombchus to the item pool "
"and changes both Medigoron and the Haunted Wasteland Carpet Salesman to sell "
"a random item once at the price of 200 rupees.\n\n"
"Enabling this changes Medigoron, Granny and the Carpet Salesman to sell a random item "
"once at a high price (100 for Granny, 200 for the others).\n"
"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"
"On (no hints) - Salesmen will be included but won't tell you what you'll get.\n"
"On (with hints) - Salesmen will be included and you'll know what you're buying."
);
@ -4664,6 +4678,11 @@ CustomMessageEntry Randomizer::GetMerchantMessage(RandomizerInf randomizerInf, u
if (textId == TEXT_SCRUB_RANDOM && shopItemPrice == 0) {
messageEntry = CustomMessageManager::Instance->RetrieveMessage(Randomizer::merchantMessageTableID, TEXT_SCRUB_RANDOM_FREE);
} else if (textId == TEXT_GRANNYS_SHOP) {
// Capitalize the first letter for the item in Granny's text as the item is the first word presented
for (auto &itemName : shopItemName) {
itemName[0] = std::toupper(itemName[0]);
}
}
CustomMessageManager::ReplaceStringInMessage(messageEntry, "{{item}}", shopItemName[0], shopItemName[1], shopItemName[2]);

View File

@ -158,6 +158,7 @@ typedef enum {
RC_KAK_REDEAD_GROTTO_CHEST,
RC_KAK_SHOOTING_GALLERY_REWARD,
RC_KAK_TRADE_ODD_MUSHROOM,
RC_KAK_GRANNYS_SHOP,
RC_KAK_TRADE_POCKET_CUCCO,
RC_KAK_10_GOLD_SKULLTULA_REWARD,
RC_KAK_20_GOLD_SKULLTULA_REWARD,

View File

@ -224,6 +224,7 @@ std::map<RandomizerCheck, RandomizerCheckObject> rcObjects = {
RC_OBJECT(RC_KAK_MAN_ON_ROOF, RCVORMQ_BOTH, RCTYPE_STANDARD, RCAREA_KAKARIKO_VILLAGE, ACTOR_ID_MAX, SCENE_SPOT01, 0x00, GI_NONE, "Man on Roof", "Kak Man on Roof"),
RC_OBJECT(RC_KAK_SHOOTING_GALLERY_REWARD, RCVORMQ_BOTH, RCTYPE_STANDARD, RCAREA_KAKARIKO_VILLAGE, ACTOR_ID_MAX, SCENE_SYATEKIJYOU, 0x00, GI_NONE, "Shooting Gallery Reward", "Kak Shooting Gallery Reward"),
RC_OBJECT(RC_KAK_TRADE_ODD_MUSHROOM, RCVORMQ_BOTH, RCTYPE_ADULT_TRADE, RCAREA_KAKARIKO_VILLAGE, ACTOR_ID_MAX, SCENE_MAHOUYA, 0x00, GI_NONE, "Trade Odd Mushroom", "Kak Trade Odd Mushroom"),
RC_OBJECT(RC_KAK_GRANNYS_SHOP, RCVORMQ_BOTH, RCTYPE_MERCHANT, RCAREA_KAKARIKO_VILLAGE, ACTOR_ID_MAX, SCENE_MAHOUYA, 0x00, GI_POTION_BLUE, "Granny's Shop", "Kak Granny's Shop"),
RC_OBJECT(RC_KAK_ANJU_AS_ADULT, RCVORMQ_BOTH, RCTYPE_ADULT_TRADE, RCAREA_KAKARIKO_VILLAGE, ACTOR_ID_MAX, SCENE_SPOT01, 0x00, GI_NONE, "Anju as Adult", "Kak Anju as Adult"),
RC_OBJECT(RC_KAK_ANJU_AS_CHILD, RCVORMQ_BOTH, RCTYPE_STANDARD, RCAREA_KAKARIKO_VILLAGE, ACTOR_ID_MAX, SCENE_SPOT01, 0x00, GI_NONE, "Anju as Child", "Kak Anju as Child"),
RC_OBJECT(RC_KAK_TRADE_POCKET_CUCCO, RCVORMQ_BOTH, RCTYPE_ADULT_TRADE, RCAREA_KAKARIKO_VILLAGE, ACTOR_ID_MAX, SCENE_SPOT01, 0x00, GI_NONE, "Trade Pocket Cucco", "Kak Trade Pocket Cucco"),

View File

@ -142,6 +142,7 @@ typedef enum {
RAND_INF_MERCHANTS_CARPET_SALESMAN,
RAND_INF_MERCHANTS_MEDIGORON,
RAND_INF_MERCHANTS_GRANNYS_SHOP,
RAND_INF_ADULT_TRADES_LW_TRADE_COJIRO,
RAND_INF_ADULT_TRADES_GV_TRADE_SAW,

View File

@ -1773,11 +1773,20 @@ extern "C" int CustomMessage_RetrieveIfExists(PlayState* play) {
messageEntry = CustomMessageManager::Instance->RetrieveMessage(Randomizer::NaviRandoMessageTableID, naviTextId);
} else if (Randomizer_GetSettingValue(RSK_SHUFFLE_MAGIC_BEANS) && textId == TEXT_BEAN_SALESMAN) {
messageEntry = CustomMessageManager::Instance->RetrieveMessage(Randomizer::merchantMessageTableID, TEXT_BEAN_SALESMAN);
} else if (Randomizer_GetSettingValue(RSK_SHUFFLE_MERCHANTS) != RO_SHUFFLE_MERCHANTS_OFF && (textId == TEXT_MEDIGORON ||
} else if (Randomizer_GetSettingValue(RSK_SHUFFLE_MERCHANTS) != RO_SHUFFLE_MERCHANTS_OFF && (textId == TEXT_MEDIGORON ||
(textId == TEXT_GRANNYS_SHOP && !Flags_GetRandomizerInf(RAND_INF_MERCHANTS_GRANNYS_SHOP) &&
(Randomizer_GetSettingValue(RSK_SHUFFLE_ADULT_TRADE) || INV_CONTENT(ITEM_CLAIM_CHECK) == ITEM_CLAIM_CHECK)) ||
(textId == TEXT_CARPET_SALESMAN_1 && !Flags_GetRandomizerInf(RAND_INF_MERCHANTS_CARPET_SALESMAN)) ||
(textId == TEXT_CARPET_SALESMAN_2 && !Flags_GetRandomizerInf(RAND_INF_MERCHANTS_CARPET_SALESMAN)))) {
RandomizerInf randoInf = (RandomizerInf)(textId == TEXT_MEDIGORON ? RAND_INF_MERCHANTS_MEDIGORON : RAND_INF_MERCHANTS_CARPET_SALESMAN);
messageEntry = OTRGlobals::Instance->gRandomizer->GetMerchantMessage(randoInf, textId, Randomizer_GetSettingValue(RSK_SHUFFLE_MERCHANTS) != RO_SHUFFLE_MERCHANTS_ON_HINT);
RandomizerInf randoInf;
if (textId == TEXT_MEDIGORON) {
randoInf = RAND_INF_MERCHANTS_MEDIGORON;
} else if (textId == TEXT_GRANNYS_SHOP) {
randoInf = RAND_INF_MERCHANTS_GRANNYS_SHOP;
} else {
randoInf = RAND_INF_MERCHANTS_CARPET_SALESMAN;
}
messageEntry = OTRGlobals::Instance->gRandomizer->GetMerchantMessage(randoInf, textId, Randomizer_GetSettingValue(RSK_SHUFFLE_MERCHANTS) != RO_SHUFFLE_MERCHANTS_ON_HINT);
} else if (Randomizer_GetSettingValue(RSK_BOMBCHUS_IN_LOGIC) &&
(textId == TEXT_BUY_BOMBCHU_10_DESC || textId == TEXT_BUY_BOMBCHU_10_PROMPT)) {
messageEntry = CustomMessageManager::Instance->RetrieveMessage(customMessageTableID, textId);

View File

@ -174,6 +174,9 @@ void EnDs_OfferOddPotion(EnDs* this, PlayState* play) {
s32 EnDs_CheckRupeesAndBottle() {
if (gSaveContext.rupees < 100) {
return 0;
} else if (gSaveContext.n64ddFlag && Randomizer_GetSettingValue(RSK_SHUFFLE_MERCHANTS) != RO_SHUFFLE_MERCHANTS_OFF &&
!Flags_GetRandomizerInf(RAND_INF_MERCHANTS_GRANNYS_SHOP)) {
return 2;
} else if (Inventory_HasEmptyBottle() == 0) {
return 1;
} else {
@ -183,10 +186,23 @@ s32 EnDs_CheckRupeesAndBottle() {
void EnDs_GiveBluePotion(EnDs* this, PlayState* play) {
if (Actor_HasParent(&this->actor, play)) {
if (gSaveContext.n64ddFlag && Randomizer_GetSettingValue(RSK_SHUFFLE_MERCHANTS) != RO_SHUFFLE_MERCHANTS_OFF &&
(Randomizer_GetSettingValue(RSK_SHUFFLE_ADULT_TRADE) || INV_CONTENT(ITEM_CLAIM_CHECK) == ITEM_CLAIM_CHECK) &&
!Flags_GetRandomizerInf(RAND_INF_MERCHANTS_GRANNYS_SHOP)) {
Flags_SetRandomizerInf(RAND_INF_MERCHANTS_GRANNYS_SHOP);
}
this->actor.parent = NULL;
this->actionFunc = EnDs_Talk;
} else {
func_8002F434(&this->actor, play, GI_POTION_BLUE, 10000.0f, 50.0f);
if (gSaveContext.n64ddFlag && Randomizer_GetSettingValue(RSK_SHUFFLE_MERCHANTS) != RO_SHUFFLE_MERCHANTS_OFF &&
(Randomizer_GetSettingValue(RSK_SHUFFLE_ADULT_TRADE) || INV_CONTENT(ITEM_CLAIM_CHECK) == ITEM_CLAIM_CHECK) &&
!Flags_GetRandomizerInf(RAND_INF_MERCHANTS_GRANNYS_SHOP)) {
GetItemEntry entry = Randomizer_GetItemFromKnownCheck(RC_KAK_GRANNYS_SHOP, GI_POTION_BLUE);
GiveItemEntryFromActor(&this->actor, play, entry, 10000.0f, 50.0f);
} else {
func_8002F434(&this->actor, play, GI_POTION_BLUE, 10000.0f, 50.0f);
}
}
}
@ -205,10 +221,20 @@ void EnDs_OfferBluePotion(EnDs* this, PlayState* play) {
case 2: // have 100 rupees and empty bottle
Rupees_ChangeBy(-100);
this->actor.flags &= ~ACTOR_FLAG_16;
GetItemEntry entry = ItemTable_Retrieve(GI_POTION_BLUE);
gSaveContext.pendingSale = entry.itemId;
gSaveContext.pendingSaleMod = entry.modIndex;
func_8002F434(&this->actor, play, GI_POTION_BLUE, 10000.0f, 50.0f);
GetItemEntry itemEntry;
if (gSaveContext.n64ddFlag && Randomizer_GetSettingValue(RSK_SHUFFLE_MERCHANTS) != RO_SHUFFLE_MERCHANTS_OFF &&
(Randomizer_GetSettingValue(RSK_SHUFFLE_ADULT_TRADE) || INV_CONTENT(ITEM_CLAIM_CHECK) == ITEM_CLAIM_CHECK) &&
!Flags_GetRandomizerInf(RAND_INF_MERCHANTS_GRANNYS_SHOP)) {
itemEntry = Randomizer_GetItemFromKnownCheck(RC_KAK_GRANNYS_SHOP, GI_POTION_BLUE);
GiveItemEntryFromActor(&this->actor, play, itemEntry, 10000.0f, 50.0f);
} else {
itemEntry = ItemTable_Retrieve(GI_POTION_BLUE);
func_8002F434(&this->actor, play, GI_POTION_BLUE, 10000.0f, 50.0f);
}
gSaveContext.pendingSale = itemEntry.itemId;
gSaveContext.pendingSaleMod = itemEntry.modIndex;
this->actionFunc = EnDs_GiveBluePotion;
return;
}
@ -229,7 +255,8 @@ void EnDs_Wait(EnDs* this, PlayState* play) {
Audio_PlaySoundGeneral(NA_SE_SY_TRE_BOX_APPEAR, &D_801333D4, 4, &D_801333E0, &D_801333E0, &D_801333E8);
player->actor.textId = 0x504A;
this->actionFunc = EnDs_OfferOddPotion;
} else if (gSaveContext.itemGetInf[3] & 1) {
} else if ((gSaveContext.n64ddFlag && Randomizer_GetSettingValue(RSK_SHUFFLE_ADULT_TRADE) == RO_GENERIC_OFF) ||
gSaveContext.itemGetInf[3] & 1) {
player->actor.textId = 0x500C;
this->actionFunc = EnDs_OfferBluePotion;
} else {

View File

@ -251,18 +251,21 @@ void EnGm_ProcessChoiceIndex(EnGm* this, PlayState* play) {
Message_ContinueTextbox(play, 0xC8);
this->actionFunc = func_80A3DD7C;
} else {
GetItemEntry itemEntry;
if (gSaveContext.n64ddFlag && Randomizer_GetSettingValue(RSK_SHUFFLE_MERCHANTS) != RO_SHUFFLE_MERCHANTS_OFF &&
!Flags_GetRandomizerInf(RAND_INF_MERCHANTS_MEDIGORON)) {
GetItemEntry itemEntry = Randomizer_GetItemFromKnownCheck(RC_GC_MEDIGORON, GI_SWORD_KNIFE);
gSaveContext.pendingSale = itemEntry.itemId;
itemEntry = Randomizer_GetItemFromKnownCheck(RC_GC_MEDIGORON, GI_SWORD_KNIFE);
GiveItemEntryFromActor(&this->actor, play, itemEntry, 415.0f, 10.0f);
gSaveContext.infTable[11] |= 2;
this->actionFunc = func_80A3DF00;
} else {
gSaveContext.pendingSale = ItemTable_Retrieve(GI_SWORD_KNIFE).itemId;
itemEntry = ItemTable_Retrieve(GI_SWORD_KNIFE);
func_8002F434(&this->actor, play, GI_SWORD_KNIFE, 415.0f, 10.0f);
this->actionFunc = func_80A3DF00;
}
gSaveContext.pendingSale = itemEntry.itemId;
gSaveContext.pendingSaleMod = itemEntry.modIndex;
this->actionFunc = func_80A3DF00;
}
break;
case 1: // no
@ -283,15 +286,13 @@ void func_80A3DF00(EnGm* this, PlayState* play) {
this->actor.parent = NULL;
this->actionFunc = func_80A3DF60;
} else {
if (gSaveContext.n64ddFlag && (Randomizer_GetSettingValue(RSK_SHUFFLE_MERCHANTS) != RO_SHUFFLE_MERCHANTS_OFF) &&
if (gSaveContext.n64ddFlag && Randomizer_GetSettingValue(RSK_SHUFFLE_MERCHANTS) != RO_SHUFFLE_MERCHANTS_OFF &&
!Flags_GetRandomizerInf(RAND_INF_MERCHANTS_MEDIGORON)) {
GetItemEntry itemEntry = Randomizer_GetItemFromKnownCheck(RC_GC_MEDIGORON, GI_SWORD_KNIFE);
gSaveContext.pendingSale = itemEntry.itemId;
GiveItemEntryFromActor(&this->actor, play, itemEntry, 415.0f, 10.0f);
gSaveContext.infTable[11] |= 2;
}
else {
gSaveContext.pendingSale = ItemTable_Retrieve(GI_SWORD_KNIFE).itemId;
func_8002F434(&this->actor, play, GI_SWORD_KNIFE, 415.0f, 10.0f);
}
}