[Rando] Shuffle Beggar (#6455)
Some checks failed
generate-builds / generate-soh-otr (push) Has been cancelled
clang-format / clang-format (pull_request) Has been cancelled
generate-builds / generate-soh-otr (pull_request) Has been cancelled
generate-builds / build-macos (push) Has been cancelled
generate-builds / build-linux (push) Has been cancelled
generate-builds / build-windows (push) Has been cancelled
generate-builds / build-macos (pull_request) Has been cancelled
generate-builds / build-linux (pull_request) Has been cancelled
generate-builds / build-windows (pull_request) Has been cancelled

This commit is contained in:
A Green Spoon
2026-04-03 15:01:07 +09:00
committed by GitHub
parent 0ccff93fae
commit 50aed798a1
21 changed files with 205 additions and 1 deletions

View File

@@ -219,6 +219,10 @@ typedef enum {
TEXT_SHEIK_HAVE_HOOK = 0x7010, TEXT_SHEIK_HAVE_HOOK = 0x7010,
TEXT_ALTAR_CHILD = 0x7040, TEXT_ALTAR_CHILD = 0x7040,
TEXT_CHEST_GAME_PROCEED = 0x704C, TEXT_CHEST_GAME_PROCEED = 0x704C,
TEXT_BEGGAR_BUY_BLUE_FIRE = 0x70F0,
TEXT_BEGGAR_BUY_FISH = 0x70F1,
TEXT_BEGGAR_BUY_BUGS = 0x70F2,
TEXT_BEGGAR_BUY_FAIRY = 0x70F3,
TEXT_GHOST_SHOP_EXPLAINATION = 0x70F4, TEXT_GHOST_SHOP_EXPLAINATION = 0x70F4,
TEXT_GHOST_SHOP_CARD_HAS_POINTS = 0x70F5, TEXT_GHOST_SHOP_CARD_HAS_POINTS = 0x70F5,
TEXT_GHOST_SHOP_BUY_NORMAL_POE = 0x70F6, TEXT_GHOST_SHOP_BUY_NORMAL_POE = 0x70F6,

View File

@@ -195,6 +195,14 @@ typedef enum {
// - `*EnTk` // - `*EnTk`
VB_BE_VALID_GRAVEDIGGING_SPOT, VB_BE_VALID_GRAVEDIGGING_SPOT,
// #### `result`
// ```c
// true
// ```
// #### `args`
// - 'EnHy*'
VB_BEGGAR_GIVE_ITEM,
// #### `result` // #### `result`
// ```c // ```c
// this->collider.base.acFlags & 2 || blueFireArrowHit // this->collider.base.acFlags & 2 || blueFireArrowHit

View File

@@ -2315,6 +2315,14 @@ void StaticData::HintTable_Init_Exclude_Overworld() {
hintTextTable[RHT_WONDER_ITEM_DESERT_COLOSSUS] = HintText(CustomMessage("They say that a #wonder item near the temple of the sand# hides #[[1]]#.", hintTextTable[RHT_WONDER_ITEM_DESERT_COLOSSUS] = HintText(CustomMessage("They say that a #wonder item near the temple of the sand# hides #[[1]]#.",
/*german*/ "Man erzählt sich, daß sich ein #Wunder-Gegenstand nahe des Tempels des Sandes# #[[1]]# verstecke.", /*german*/ "Man erzählt sich, daß sich ein #Wunder-Gegenstand nahe des Tempels des Sandes# #[[1]]# verstecke.",
/*french*/ "Selon moi, un #objet merveilleux près du temple du sable# cache #[[1]]#.", {QM_RED, QM_GREEN})); /*french*/ "Selon moi, un #objet merveilleux près du temple du sable# cache #[[1]]#.", {QM_RED, QM_GREEN}));
hintTextTable[RHT_BEGGAR_MARKET] = HintText(CustomMessage("They say that #trading with a beggar in the market# gives #[[1]]#.",
/*german*/ "Man erzählt sich, daß das #Handeln mit einem Bettler auf dem Markt# #[[1]]# gäbe.",
/*french*/ "Selon moi, #échanger avec un mendiant sur le marché# donne #[[1]]#.", {QM_RED, QM_GREEN}));
hintTextTable[RHT_BEGGAR_KAKARIKO_VILLAGE] = HintText(CustomMessage("They say that #trading with a beggar in Kakariko Village# gives #[[1]]#.",
/*german*/ "Man erzählt sich, daß das #Handeln mit einem Bettler in Kakariko# #[[1]]# gäbe.",
/*french*/ "Selon moi, #échanger avec un mendiant dans le Village de Cocorico# donne #[[1]]#.", {QM_RED, QM_GREEN}));
// clang-format on // clang-format on
} }
} // namespace Rando } // namespace Rando

View File

@@ -497,6 +497,10 @@ void GenerateItemPool() {
ctx->PlaceItemInLocation(RC_WASTELAND_BOMBCHU_SALESMAN, RG_BOMBCHU_10, false, true); ctx->PlaceItemInLocation(RC_WASTELAND_BOMBCHU_SALESMAN, RG_BOMBCHU_10, false, true);
} }
// Shuffle Beggar
bool beggarActive = (bool)ctx->GetOption(RSK_SHUFFLE_BEGGAR);
PlaceItemsForType(RCTYPE_BEGGAR, beggarActive, false);
if (ctx->GetOption(RSK_SHUFFLE_FROG_SONG_RUPEES)) { if (ctx->GetOption(RSK_SHUFFLE_FROG_SONG_RUPEES)) {
AddFixedItemToPool(RG_PURPLE_RUPEE, 5); AddFixedItemToPool(RG_PURPLE_RUPEE, 5);
} else { } else {

View File

@@ -196,6 +196,7 @@ void Context::GenerateLocationPool() {
!(location.GetRandomizerCheck() == RC_LW_DEKU_SCRUB_GROTTO_FRONT || !(location.GetRandomizerCheck() == RC_LW_DEKU_SCRUB_GROTTO_FRONT ||
location.GetRandomizerCheck() == RC_LW_DEKU_SCRUB_NEAR_BRIDGE || location.GetRandomizerCheck() == RC_LW_DEKU_SCRUB_NEAR_BRIDGE ||
location.GetRandomizerCheck() == RC_HF_DEKU_SCRUB_GROTTO)) || location.GetRandomizerCheck() == RC_HF_DEKU_SCRUB_GROTTO)) ||
(location.GetRCType() == RCTYPE_BEGGAR && mOptions[RSK_SHUFFLE_BEGGAR].Is(RO_GENERIC_OFF)) ||
(location.GetRCType() == RCTYPE_ADULT_TRADE && mOptions[RSK_SHUFFLE_ADULT_TRADE].Is(RO_GENERIC_OFF)) || (location.GetRCType() == RCTYPE_ADULT_TRADE && mOptions[RSK_SHUFFLE_ADULT_TRADE].Is(RO_GENERIC_OFF)) ||
(location.GetRCType() == RCTYPE_COW && mOptions[RSK_SHUFFLE_COWS].Is(RO_GENERIC_OFF)) || (location.GetRCType() == RCTYPE_COW && mOptions[RSK_SHUFFLE_COWS].Is(RO_GENERIC_OFF)) ||
(location.GetRandomizerCheck() == RC_LH_HYRULE_LOACH && (location.GetRandomizerCheck() == RC_LH_HYRULE_LOACH &&

View File

@@ -0,0 +1,115 @@
#include <soh/OTRGlobals.h>
extern "C" {
#include "overlays/actors/ovl_En_Hy/z_en_hy.h"
extern PlayState* gPlayState;
}
CheckIdentity ShuffleBeggar_GetBeggarIdentity(int32_t textId) {
CheckIdentity beggarIdentity;
s16 sceneNum = gPlayState->sceneNum;
beggarIdentity = OTRGlobals::Instance->gRandomizer->IdentifyBeggar(sceneNum, textId);
return beggarIdentity;
}
uint8_t EnHy_RandomizerHoldsItem(int32_t textId) {
CheckIdentity beggarIdentity = ShuffleBeggar_GetBeggarIdentity(textId);
if (beggarIdentity.randomizerCheck == RC_UNKNOWN_CHECK || !IS_RANDO ||
Flags_GetRandomizerInf(beggarIdentity.randomizerInf)) {
return false;
}
return true;
}
void BuildEnHyMessage_BlueFire(uint16_t* textId, bool* loadFromMessageTable) {
if (!EnHy_RandomizerHoldsItem(TEXT_BEGGAR_BUY_BLUE_FIRE)) {
return;
}
CustomMessage msg = CustomMessage(
"%cBlue Fire%w! I'll trade you %rsomething special%w for it. No returns! I get new "
"special inventory %bevery 7 years or so%w...",
"%cBlaues Feuer%w! Ich tausche es gegen %retwas Besonderes%w. Und nicht feilschen, okay! Ich bekomme neue "
"besondere Ware %balle 7 Jahre oder so%w...",
"%cFeu bleu%w ! Je l'échange contre %rquelque chose de spécial%w. Pas de retour ! Je reçois de nouveaux "
"articles spéciaux %btous les 7 ans environ%w...");
msg.AutoFormat();
msg.LoadIntoFont();
*loadFromMessageTable = false;
}
void BuildEnHyMessage_Fish(uint16_t* textId, bool* loadFromMessageTable) {
if (!EnHy_RandomizerHoldsItem(TEXT_BEGGAR_BUY_FISH)) {
return;
}
CustomMessage msg = CustomMessage(
"A %pfish%w! I'll trade you %rsomething special%w for it. No returns! I get new "
"special inventory %bevery 7 years or so%w...",
"Ein %pFisch%w! Ich tausche ihn gegen %retwas Besonderes%w. Und nicht feilschen, okay! Ich bekomme neue "
"besondere Ware %balle 7 Jahre oder so%w...",
"Un %ppoisson%w ! Je l'échange contre %rquelque chose de spécial%w. Pas de retour ! Je reçois de nouveaux "
"articles spéciaux %btous les 7 ans environ%w...");
msg.AutoFormat();
msg.LoadIntoFont();
*loadFromMessageTable = false;
}
void BuildEnHyMessage_Bug(uint16_t* textId, bool* loadFromMessageTable) {
if (!EnHy_RandomizerHoldsItem(TEXT_BEGGAR_BUY_BUGS)) {
return;
}
CustomMessage msg =
CustomMessage("A tiny %gbug%w! I'll trade you %rsomething special%w for it. No returns! I get new "
"special inventory %bevery 7 years or so%w...",
"Ein kleiner %gKäfer%w! Ich tausche ihn gegen %retwas Besonderes%w. Und nicht feilschen, okay! "
"Ich bekomme neue "
"besondere Ware %balle 7 Jahre oder so%w...",
"Un petit %ginsecte%w ! Je l'échange contre %rquelque chose de spécial%w. Pas de retour ! Je "
"reçois de nouveaux "
"articles spéciaux %btous les 7 ans environ%w...");
msg.AutoFormat();
msg.LoadIntoFont();
*loadFromMessageTable = false;
}
void RegisterShuffleBeggar() {
bool shouldRegister = IS_RANDO && Rando::Context::GetInstance()->GetOption(RSK_SHUFFLE_BEGGAR).Get();
COND_VB_SHOULD(VB_BEGGAR_GIVE_ITEM, shouldRegister, {
EnHy* enHy = va_arg(args, EnHy*);
int32_t beggarTextId = enHy->actor.textId;
if (beggarTextId != TEXT_BEGGAR_BUY_FAIRY) {
if (EnHy_RandomizerHoldsItem(beggarTextId)) {
CheckIdentity beggarIdentity = ShuffleBeggar_GetBeggarIdentity(beggarTextId);
Flags_SetRandomizerInf(beggarIdentity.randomizerInf);
*should = false;
}
}
});
COND_ID_HOOK(OnOpenText, TEXT_BEGGAR_BUY_BLUE_FIRE, shouldRegister, BuildEnHyMessage_BlueFire);
COND_ID_HOOK(OnOpenText, TEXT_BEGGAR_BUY_FISH, shouldRegister, BuildEnHyMessage_Fish);
COND_ID_HOOK(OnOpenText, TEXT_BEGGAR_BUY_BUGS, shouldRegister, BuildEnHyMessage_Bug);
}
void Rando::StaticData::RegisterBeggarLocations() {
static bool registered = false;
if (registered)
return;
registered = true;
// clang-format off
// Randomizer Check Randomizer Check Quest RCType Area Actor ID Scene ID Params Short Name Hint Text Key Vanilla Item Spoiler Collection Check
locationTable[RC_MK_BEGGAR_BUGS] = Location::Base(RC_MK_BEGGAR_BUGS, RCQUEST_BOTH, RCTYPE_BEGGAR, RCAREA_MARKET, ACTOR_EN_HY, SCENE_MARKET_DAY, 0x70F2, "Beggar Bugs", RHT_BEGGAR_MARKET, RG_PURPLE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_MK_BEGGAR_BUGS));
locationTable[RC_MK_BEGGAR_FISH] = Location::Base(RC_MK_BEGGAR_FISH, RCQUEST_BOTH, RCTYPE_BEGGAR, RCAREA_MARKET, ACTOR_EN_HY, SCENE_MARKET_DAY, 0x70F1, "Beggar Fish", RHT_BEGGAR_MARKET, RG_PURPLE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_MK_BEGGAR_FISH));
locationTable[RC_MK_BEGGAR_BLUE_FIRE] = Location::Base(RC_MK_BEGGAR_BLUE_FIRE, RCQUEST_BOTH, RCTYPE_BEGGAR, RCAREA_MARKET, ACTOR_EN_HY, SCENE_MARKET_DAY, 0x70F0, "Beggar Blue Fire", RHT_BEGGAR_MARKET, RG_HUGE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_MK_BEGGAR_BLUE_FIRE));
locationTable[RC_KAK_BEGGAR_BUGS] = Location::Base(RC_KAK_BEGGAR_BUGS, RCQUEST_BOTH, RCTYPE_BEGGAR, RCAREA_KAKARIKO_VILLAGE, ACTOR_EN_HY, SCENE_KAKARIKO_VILLAGE, 0x70F2, "Beggar Bugs", RHT_BEGGAR_KAKARIKO_VILLAGE, RG_PURPLE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_KAK_BEGGAR_BUGS));
locationTable[RC_KAK_BEGGAR_FISH] = Location::Base(RC_KAK_BEGGAR_FISH, RCQUEST_BOTH, RCTYPE_BEGGAR, RCAREA_KAKARIKO_VILLAGE, ACTOR_EN_HY, SCENE_KAKARIKO_VILLAGE, 0x70F1, "Beggar Fish", RHT_BEGGAR_KAKARIKO_VILLAGE, RG_PURPLE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_KAK_BEGGAR_FISH));
locationTable[RC_KAK_BEGGAR_BLUE_FIRE] = Location::Base(RC_KAK_BEGGAR_BLUE_FIRE, RCQUEST_BOTH, RCTYPE_BEGGAR, RCAREA_KAKARIKO_VILLAGE, ACTOR_EN_HY, SCENE_KAKARIKO_VILLAGE, 0x70F0, "Beggar Blue Fire", RHT_BEGGAR_KAKARIKO_VILLAGE, RG_HUGE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_KAK_BEGGAR_BLUE_FIRE));
// clang-format on
}
static RegisterShipInitFunc registerShuffleBeggar(RegisterShuffleBeggar, { "IS_RANDO" });
static RegisterShipInitFunc registerBeggarLocations(Rando::StaticData::RegisterBeggarLocations);

View File

@@ -65,6 +65,9 @@ void RegionTable_Init_Kakariko() {
LOCATION(RC_KAK_SOUTHEAST_EXIT_ARROW_SIGN, logic->CanRead()), LOCATION(RC_KAK_SOUTHEAST_EXIT_ARROW_SIGN, logic->CanRead()),
LOCATION(RC_KAK_FRONT_GATE_ARROW_SIGN, logic->CanRead()), LOCATION(RC_KAK_FRONT_GATE_ARROW_SIGN, logic->CanRead()),
LOCATION(RC_KAK_WONDER_UNDER_CONSTRUCTION, logic->IsChild), LOCATION(RC_KAK_WONDER_UNDER_CONSTRUCTION, logic->IsChild),
LOCATION(RC_KAK_BEGGAR_BUGS, logic->IsAdult && logic->CanUse(RG_BOTTLE_WITH_BUGS)),
LOCATION(RC_KAK_BEGGAR_FISH, logic->IsAdult && logic->CanUse(RG_BOTTLE_WITH_FISH)),
LOCATION(RC_KAK_BEGGAR_BLUE_FIRE, logic->IsAdult && logic->CanUse(RG_BOTTLE_WITH_BLUE_FIRE)),
}, { }, {
//Exits //Exits
ENTRANCE(RR_HYRULE_FIELD, true), ENTRANCE(RR_HYRULE_FIELD, true),

View File

@@ -35,6 +35,9 @@ void RegionTable_Init_Market() {
LOCATION(RC_MKT_WONDER_DAY_5, logic->IsChild && logic->AtDay), LOCATION(RC_MKT_WONDER_DAY_5, logic->IsChild && logic->AtDay),
LOCATION(RC_MKT_WONDER_NIGHT_1, logic->IsChild && logic->AtNight), LOCATION(RC_MKT_WONDER_NIGHT_1, logic->IsChild && logic->AtNight),
LOCATION(RC_MKT_WONDER_NIGHT_2, logic->IsChild && logic->AtNight), LOCATION(RC_MKT_WONDER_NIGHT_2, logic->IsChild && logic->AtNight),
LOCATION(RC_MK_BEGGAR_BUGS, logic->IsChild && logic->AtDay && logic->CanUse(RG_BOTTLE_WITH_BUGS)),
LOCATION(RC_MK_BEGGAR_FISH, logic->IsChild && logic->AtDay && logic->CanUse(RG_BOTTLE_WITH_FISH)),
LOCATION(RC_MK_BEGGAR_BLUE_FIRE, logic->IsChild && logic->AtDay && logic->CanUse(RG_BOTTLE_WITH_BLUE_FIRE)),
}, { }, {
//Exits //Exits
ENTRANCE(RR_MARKET_ENTRANCE, true), ENTRANCE(RR_MARKET_ENTRANCE, true),

View File

@@ -495,6 +495,9 @@ void Settings::CreateOptionDescriptions() {
"\n" "\n"
"This setting does not effect the item earned from playing\n" "This setting does not effect the item earned from playing\n"
"the Song of Storms and the frog song minigame."; "the Song of Storms and the frog song minigame.";
mOptionDescriptions[RSK_SHUFFLE_BEGGAR] =
"Shuffle the rewards the Beggar gives for selling bugs, fish, and Blue Fire.\n"
"The Beggar will give separate rewards to child and adult.";
mOptionDescriptions[RSK_SHUFFLE_ADULT_TRADE] = mOptionDescriptions[RSK_SHUFFLE_ADULT_TRADE] =
"Adds all of the adult trade quest items into the pool, each of which " "Adds all of the adult trade quest items into the pool, each of which "
"can be traded for a unique reward.\n" "can be traded for a unique reward.\n"

View File

@@ -3272,6 +3272,13 @@ std::map<RandomizerCheck, RandomizerInf> rcToRandomizerInf = {
{ RC_GERUDO_TRAINING_GROUND_MQ_WONDER_DINOLFOS_ROOM, RAND_INF_GERUDO_TRAINING_GROUND_MQ_WONDER_DINOLFOS_ROOM }, { RC_GERUDO_TRAINING_GROUND_MQ_WONDER_DINOLFOS_ROOM, RAND_INF_GERUDO_TRAINING_GROUND_MQ_WONDER_DINOLFOS_ROOM },
{ RC_GERUDO_TRAINING_GROUND_MQ_WONDER_EYE_STATUE, RAND_INF_GERUDO_TRAINING_GROUND_MQ_WONDER_EYE_STATUE }, { RC_GERUDO_TRAINING_GROUND_MQ_WONDER_EYE_STATUE, RAND_INF_GERUDO_TRAINING_GROUND_MQ_WONDER_EYE_STATUE },
{ RC_GANONS_CASTLE_MQ_WONDER_SHADOW_TRIAL, RAND_INF_GANONS_CASTLE_MQ_WONDER_SHADOW_TRIAL }, { RC_GANONS_CASTLE_MQ_WONDER_SHADOW_TRIAL, RAND_INF_GANONS_CASTLE_MQ_WONDER_SHADOW_TRIAL },
// Beggar
{ RC_MK_BEGGAR_BUGS, RAND_INF_MK_BEGGAR_BUGS },
{ RC_MK_BEGGAR_FISH, RAND_INF_MK_BEGGAR_FISH },
{ RC_MK_BEGGAR_BLUE_FIRE, RAND_INF_MK_BEGGAR_BLUE_FIRE },
{ RC_KAK_BEGGAR_BUGS, RAND_INF_KAK_BEGGAR_BUGS },
{ RC_KAK_BEGGAR_FISH, RAND_INF_KAK_BEGGAR_FISH },
{ RC_KAK_BEGGAR_BLUE_FIRE, RAND_INF_KAK_BEGGAR_BLUE_FIRE },
}; };
CheckIdentity Randomizer::IdentifyBeehive(s32 sceneNum, s16 xPosition, s32 respawnData) { CheckIdentity Randomizer::IdentifyBeehive(s32 sceneNum, s16 xPosition, s32 respawnData) {
@@ -3817,6 +3824,22 @@ CheckIdentity Randomizer::IdentifyWonderItem(s32 sceneNum, s32 par1, s32 par2) {
return wonderIdentity; return wonderIdentity;
} }
CheckIdentity Randomizer::IdentifyBeggar(s32 sceneNum, s32 textId) {
CheckIdentity beggarIdentity;
beggarIdentity.randomizerInf = RAND_INF_MAX;
beggarIdentity.randomizerCheck = RC_UNKNOWN_CHECK;
Rando::Location* location = GetCheckObjectFromActor(ACTOR_EN_HY, sceneNum, textId);
if (location->GetRandomizerCheck() == RC_UNKNOWN_CHECK) {
LUSLOG_WARN("IdentifyBeggar did not receive a valid RC value (%d).", location->GetRandomizerCheck());
} else {
beggarIdentity.randomizerInf = rcToRandomizerInf[location->GetRandomizerCheck()];
beggarIdentity.randomizerCheck = location->GetRandomizerCheck();
}
return beggarIdentity;
}
u8 Randomizer::GetRandoSettingValue(RandomizerSettingKey randoSettingKey) { u8 Randomizer::GetRandoSettingValue(RandomizerSettingKey randoSettingKey) {
return Rando::Context::GetInstance()->GetOption(randoSettingKey).Get(); return Rando::Context::GetInstance()->GetOption(randoSettingKey).Get();
} }

View File

@@ -45,6 +45,7 @@ class Randomizer {
CheckIdentity IdentifyTree(s32 sceneNum, s32 posX, s32 posZ); CheckIdentity IdentifyTree(s32 sceneNum, s32 posX, s32 posZ);
CheckIdentity IdentifySign(s32 sceneNum, s32 posX, s32 posZ, s32 id); CheckIdentity IdentifySign(s32 sceneNum, s32 posX, s32 posZ, s32 id);
CheckIdentity IdentifyWonderItem(s32 sceneNum, s32 par1, s32 par2); CheckIdentity IdentifyWonderItem(s32 sceneNum, s32 par1, s32 par2);
CheckIdentity IdentifyBeggar(s32 sceneNum, s32 textId);
GetItemEntry GetItemFromKnownCheck(RandomizerCheck randomizerCheck, GetItemID ogItemId, GetItemEntry GetItemFromKnownCheck(RandomizerCheck randomizerCheck, GetItemID ogItemId,
bool checkObtainability = true); bool checkObtainability = true);
GetItemEntry GetItemFromActor(s16 actorId, s16 sceneNum, s16 actorParams, GetItemID ogItemId, GetItemEntry GetItemFromActor(s16 actorId, s16 sceneNum, s16 actorParams, GetItemID ogItemId,

View File

@@ -2859,6 +2859,13 @@ RANDO_ENUM_ITEM(RC_SHADOW_TEMPLE_TRUTHSPINNER_RECTANGLE_SIGN)
RANDO_ENUM_ITEM(RC_SHADOW_TEMPLE_FALLING_SPIKES_RECTANGLE_SIGN) RANDO_ENUM_ITEM(RC_SHADOW_TEMPLE_FALLING_SPIKES_RECTANGLE_SIGN)
// MQ Dungeon Signs // MQ Dungeon Signs
RANDO_ENUM_ITEM(RC_SHADOW_TEMPLE_MQ_LOWER_PIT_RECTANGLE_SIGN) RANDO_ENUM_ITEM(RC_SHADOW_TEMPLE_MQ_LOWER_PIT_RECTANGLE_SIGN)
// Beggar
RANDO_ENUM_ITEM(RC_MK_BEGGAR_BUGS)
RANDO_ENUM_ITEM(RC_MK_BEGGAR_FISH)
RANDO_ENUM_ITEM(RC_MK_BEGGAR_BLUE_FIRE)
RANDO_ENUM_ITEM(RC_KAK_BEGGAR_BUGS)
RANDO_ENUM_ITEM(RC_KAK_BEGGAR_FISH)
RANDO_ENUM_ITEM(RC_KAK_BEGGAR_BLUE_FIRE)
RANDO_ENUM_ITEM(RC_MAX) RANDO_ENUM_ITEM(RC_MAX)
RANDO_ENUM_END(RandomizerCheck) RANDO_ENUM_END(RandomizerCheck)

View File

@@ -1605,6 +1605,9 @@ RANDO_ENUM_ITEM(RHT_SIGN_GERUDO_FORTRESS)
RANDO_ENUM_ITEM(RHT_SIGN_HAUNTED_WASTELAND) RANDO_ENUM_ITEM(RHT_SIGN_HAUNTED_WASTELAND)
RANDO_ENUM_ITEM(RHT_SIGN_DODONGOS_CAVERN) RANDO_ENUM_ITEM(RHT_SIGN_DODONGOS_CAVERN)
RANDO_ENUM_ITEM(RHT_SIGN_SHADOW_TEMPLE) RANDO_ENUM_ITEM(RHT_SIGN_SHADOW_TEMPLE)
// BEGGAR
RANDO_ENUM_ITEM(RHT_BEGGAR_MARKET)
RANDO_ENUM_ITEM(RHT_BEGGAR_KAKARIKO_VILLAGE)
// MAX // MAX
RANDO_ENUM_ITEM(RHT_MAX) RANDO_ENUM_ITEM(RHT_MAX)
RANDO_ENUM_END(RandomizerHintTextKey) RANDO_ENUM_END(RandomizerHintTextKey)

View File

@@ -2426,6 +2426,13 @@ RANDO_ENUM_ITEM(RAND_INF_SHADOW_TEMPLE_TRUTHSPINNER_RECTANGLE_SIGN)
RANDO_ENUM_ITEM(RAND_INF_SHADOW_TEMPLE_FALLING_SPIKES_RECTANGLE_SIGN) RANDO_ENUM_ITEM(RAND_INF_SHADOW_TEMPLE_FALLING_SPIKES_RECTANGLE_SIGN)
// MQ Dungeon Signs // MQ Dungeon Signs
RANDO_ENUM_ITEM(RAND_INF_SHADOW_TEMPLE_MQ_LOWER_PIT_RECTANGLE_SIGN) RANDO_ENUM_ITEM(RAND_INF_SHADOW_TEMPLE_MQ_LOWER_PIT_RECTANGLE_SIGN)
// Beggar
RANDO_ENUM_ITEM(RAND_INF_MK_BEGGAR_BUGS)
RANDO_ENUM_ITEM(RAND_INF_MK_BEGGAR_FISH)
RANDO_ENUM_ITEM(RAND_INF_MK_BEGGAR_BLUE_FIRE)
RANDO_ENUM_ITEM(RAND_INF_KAK_BEGGAR_BUGS)
RANDO_ENUM_ITEM(RAND_INF_KAK_BEGGAR_FISH)
RANDO_ENUM_ITEM(RAND_INF_KAK_BEGGAR_BLUE_FIRE)
RANDO_ENUM_ITEM(RAND_INF_MAX) RANDO_ENUM_ITEM(RAND_INF_MAX)

View File

@@ -132,6 +132,7 @@ RANDO_ENUM_ITEM(RCTYPE_SONG_FAIRY) // Fairies from Songs
RANDO_ENUM_ITEM(RCTYPE_BUTTERFLY_FAIRY) // Fairies from Butterflies RANDO_ENUM_ITEM(RCTYPE_BUTTERFLY_FAIRY) // Fairies from Butterflies
RANDO_ENUM_ITEM(RCTYPE_GRASS) // Grass RANDO_ENUM_ITEM(RCTYPE_GRASS) // Grass
RANDO_ENUM_ITEM(RCTYPE_SIGN) // Signs RANDO_ENUM_ITEM(RCTYPE_SIGN) // Signs
RANDO_ENUM_ITEM(RCTYPE_BEGGAR) // Beggar
RANDO_ENUM_END(RandomizerCheckType) RANDO_ENUM_END(RandomizerCheckType)
RANDO_ENUM_BEGIN(RandomizerCheckQuest) RANDO_ENUM_BEGIN(RandomizerCheckQuest)

View File

@@ -160,6 +160,7 @@ RANDO_ENUM_ITEM(RSK_MERCHANT_PRICES_ADULT_WALLET_WEIGHT)
RANDO_ENUM_ITEM(RSK_MERCHANT_PRICES_GIANT_WALLET_WEIGHT) RANDO_ENUM_ITEM(RSK_MERCHANT_PRICES_GIANT_WALLET_WEIGHT)
RANDO_ENUM_ITEM(RSK_MERCHANT_PRICES_TYCOON_WALLET_WEIGHT) RANDO_ENUM_ITEM(RSK_MERCHANT_PRICES_TYCOON_WALLET_WEIGHT)
RANDO_ENUM_ITEM(RSK_MERCHANT_PRICES_AFFORDABLE) RANDO_ENUM_ITEM(RSK_MERCHANT_PRICES_AFFORDABLE)
RANDO_ENUM_ITEM(RSK_SHUFFLE_BEGGAR)
RANDO_ENUM_ITEM(RSK_BLUE_FIRE_ARROWS) RANDO_ENUM_ITEM(RSK_BLUE_FIRE_ARROWS)
RANDO_ENUM_ITEM(RSK_SUNLIGHT_ARROWS) RANDO_ENUM_ITEM(RSK_SUNLIGHT_ARROWS)
RANDO_ENUM_ITEM(RSK_SLINGBOW_BREAK_BEEHIVES) RANDO_ENUM_ITEM(RSK_SLINGBOW_BREAK_BEEHIVES)

View File

@@ -140,6 +140,8 @@ void RandomizerCheckObjects::UpdateImGuiVisibility() {
(location.GetRCType() != RCTYPE_MERCHANT || (location.GetRCType() != RCTYPE_MERCHANT ||
CVarGetInteger(CVAR_RANDOMIZER_SETTING("ShuffleMerchants"), RO_SHUFFLE_MERCHANTS_OFF) != CVarGetInteger(CVAR_RANDOMIZER_SETTING("ShuffleMerchants"), RO_SHUFFLE_MERCHANTS_OFF) !=
RO_SHUFFLE_MERCHANTS_OFF) && RO_SHUFFLE_MERCHANTS_OFF) &&
(location.GetRCType() != RCTYPE_BEGGAR ||
CVarGetInteger(CVAR_RANDOMIZER_SETTING("ShuffleBeggar"), RO_GENERIC_NO)) &&
(location.GetRCType() != RCTYPE_SONG_LOCATION || (location.GetRCType() != RCTYPE_SONG_LOCATION ||
(CVarGetInteger(CVAR_RANDOMIZER_SETTING("ShuffleSongs"), RO_SONG_SHUFFLE_SONG_LOCATIONS) != (CVarGetInteger(CVAR_RANDOMIZER_SETTING("ShuffleSongs"), RO_SONG_SHUFFLE_SONG_LOCATIONS) !=
RO_SONG_SHUFFLE_SONG_LOCATIONS && RO_SONG_SHUFFLE_SONG_LOCATIONS &&

View File

@@ -83,6 +83,7 @@ bool showOverworldSigns;
bool showDungeonSigns; bool showDungeonSigns;
bool showOverworldWonderItems; bool showOverworldWonderItems;
bool showDungeonWonderItems; bool showDungeonWonderItems;
bool showBeggar;
bool showFrogSongRupees; bool showFrogSongRupees;
bool showFountainFairies; bool showFountainFairies;
bool showStoneFairies; bool showStoneFairies;
@@ -1512,6 +1513,7 @@ void LoadSettings() {
showDungeonWonderItems = false; showDungeonWonderItems = false;
break; break;
} }
showBeggar = OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_SHUFFLE_BEGGAR);
} else { // Vanilla } else { // Vanilla
showOverworldTokens = true; showOverworldTokens = true;
showDungeonTokens = true; showDungeonTokens = true;
@@ -1527,6 +1529,7 @@ void LoadSettings() {
showBushes = false; showBushes = false;
showOverworldWonderItems = false; showOverworldWonderItems = false;
showDungeonWonderItems = false; showDungeonWonderItems = false;
showBeggar = false;
} }
fortressFast = false; fortressFast = false;
@@ -1617,6 +1620,7 @@ bool IsCheckShuffled(RandomizerCheck rc) {
(showMajorScrubs && (rc == RC_LW_DEKU_SCRUB_NEAR_BRIDGE || // The 3 scrubs that are always randomized (showMajorScrubs && (rc == RC_LW_DEKU_SCRUB_NEAR_BRIDGE || // The 3 scrubs that are always randomized
rc == RC_HF_DEKU_SCRUB_GROTTO || rc == RC_LW_DEKU_SCRUB_GROTTO_FRONT))) && rc == RC_HF_DEKU_SCRUB_GROTTO || rc == RC_LW_DEKU_SCRUB_GROTTO_FRONT))) &&
(loc->GetRCType() != RCTYPE_MERCHANT || showMerchants) && (loc->GetRCType() != RCTYPE_MERCHANT || showMerchants) &&
(loc->GetRCType() != RCTYPE_BEGGAR || showBeggar) &&
(loc->GetRCType() != RCTYPE_SONG_LOCATION || showSongs) && (loc->GetRCType() != RCTYPE_SONG_LOCATION || showSongs) &&
(loc->GetRCType() != RCTYPE_BEEHIVE || showBeehives) && (loc->GetRCType() != RCTYPE_BEEHIVE || showBeehives) &&
(loc->GetRCType() != RCTYPE_OCARINA || showOcarinas) && (loc->GetRCType() != RCTYPE_OCARINA || showOcarinas) &&

View File

@@ -1009,6 +1009,7 @@ void Settings::CreateOptions() {
OPT_U8(RSK_MERCHANT_PRICES_GIANT_WALLET_WEIGHT, "Merchant Giant Wallet Weight", {NumOpts(0, 100)}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("MerchantGiantWalletWeight"), mOptionDescriptions[RSK_MERCHANT_PRICES_GIANT_WALLET_WEIGHT], WIDGET_CVAR_SLIDER_INT, 10, true, nullptr, IMFLAG_NONE); OPT_U8(RSK_MERCHANT_PRICES_GIANT_WALLET_WEIGHT, "Merchant Giant Wallet Weight", {NumOpts(0, 100)}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("MerchantGiantWalletWeight"), mOptionDescriptions[RSK_MERCHANT_PRICES_GIANT_WALLET_WEIGHT], WIDGET_CVAR_SLIDER_INT, 10, true, nullptr, IMFLAG_NONE);
OPT_U8(RSK_MERCHANT_PRICES_TYCOON_WALLET_WEIGHT, "Merchant Tycoon Wallet Weight", {NumOpts(0, 100)}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("MerchantTycoonWalletWeight"), mOptionDescriptions[RSK_MERCHANT_PRICES_TYCOON_WALLET_WEIGHT], WIDGET_CVAR_SLIDER_INT, 10, true, nullptr, IMFLAG_NONE); OPT_U8(RSK_MERCHANT_PRICES_TYCOON_WALLET_WEIGHT, "Merchant Tycoon Wallet Weight", {NumOpts(0, 100)}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("MerchantTycoonWalletWeight"), mOptionDescriptions[RSK_MERCHANT_PRICES_TYCOON_WALLET_WEIGHT], WIDGET_CVAR_SLIDER_INT, 10, true, nullptr, IMFLAG_NONE);
OPT_BOOL(RSK_MERCHANT_PRICES_AFFORDABLE, "Merchant Affordable Prices", CVAR_RANDOMIZER_SETTING("MerchantPricesAffordable"), mOptionDescriptions[RSK_MERCHANT_PRICES_AFFORDABLE]); OPT_BOOL(RSK_MERCHANT_PRICES_AFFORDABLE, "Merchant Affordable Prices", CVAR_RANDOMIZER_SETTING("MerchantPricesAffordable"), mOptionDescriptions[RSK_MERCHANT_PRICES_AFFORDABLE]);
OPT_BOOL(RSK_SHUFFLE_BEGGAR, "Shuffle Beggar", CVAR_RANDOMIZER_SETTING("ShuffleBeggar"), mOptionDescriptions[RSK_SHUFFLE_BEGGAR]);
OPT_BOOL(RSK_SHUFFLE_FROG_SONG_RUPEES, "Shuffle Frog Song Rupees", CVAR_RANDOMIZER_SETTING("ShuffleFrogSongRupees"), mOptionDescriptions[RSK_SHUFFLE_FROG_SONG_RUPEES]); OPT_BOOL(RSK_SHUFFLE_FROG_SONG_RUPEES, "Shuffle Frog Song Rupees", CVAR_RANDOMIZER_SETTING("ShuffleFrogSongRupees"), mOptionDescriptions[RSK_SHUFFLE_FROG_SONG_RUPEES]);
OPT_BOOL(RSK_SHUFFLE_ADULT_TRADE, "Shuffle Adult Trade", CVAR_RANDOMIZER_SETTING("ShuffleAdultTrade"), mOptionDescriptions[RSK_SHUFFLE_ADULT_TRADE]); OPT_BOOL(RSK_SHUFFLE_ADULT_TRADE, "Shuffle Adult Trade", CVAR_RANDOMIZER_SETTING("ShuffleAdultTrade"), mOptionDescriptions[RSK_SHUFFLE_ADULT_TRADE]);
OPT_U8(RSK_SHUFFLE_CHEST_MINIGAME, "Shuffle Chest Minigame", {"Off", "On (Separate)", "On (Pack)"}); OPT_U8(RSK_SHUFFLE_CHEST_MINIGAME, "Shuffle Chest Minigame", {"Off", "On (Separate)", "On (Pack)"});
@@ -1909,6 +1910,7 @@ void Settings::CreateOptions() {
&mOptions[RSK_MERCHANT_PRICES_GIANT_WALLET_WEIGHT], &mOptions[RSK_MERCHANT_PRICES_GIANT_WALLET_WEIGHT],
&mOptions[RSK_MERCHANT_PRICES_TYCOON_WALLET_WEIGHT], &mOptions[RSK_MERCHANT_PRICES_TYCOON_WALLET_WEIGHT],
&mOptions[RSK_MERCHANT_PRICES_AFFORDABLE], &mOptions[RSK_MERCHANT_PRICES_AFFORDABLE],
&mOptions[RSK_SHUFFLE_BEGGAR],
}, },
WidgetContainerType::SECTION); WidgetContainerType::SECTION);
mOptionGroups[RSG_MENU_COLUMN_SHOP_SHUFFLES] = mOptionGroups[RSG_MENU_COLUMN_SHOP_SHUFFLES] =
@@ -2164,6 +2166,7 @@ void Settings::CreateOptions() {
&mOptions[RSK_MERCHANT_PRICES_GIANT_WALLET_WEIGHT], &mOptions[RSK_MERCHANT_PRICES_GIANT_WALLET_WEIGHT],
&mOptions[RSK_MERCHANT_PRICES_TYCOON_WALLET_WEIGHT], &mOptions[RSK_MERCHANT_PRICES_TYCOON_WALLET_WEIGHT],
&mOptions[RSK_MERCHANT_PRICES_AFFORDABLE], &mOptions[RSK_MERCHANT_PRICES_AFFORDABLE],
&mOptions[RSK_SHUFFLE_BEGGAR],
&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],

View File

@@ -64,6 +64,7 @@ class StaticData {
static void RegisterTreeLocations(); static void RegisterTreeLocations();
static void RegisterSignLocations(); static void RegisterSignLocations();
static void RegisterWonderItemLocations(); static void RegisterWonderItemLocations();
static void RegisterBeggarLocations();
static void InitHashMaps(); static void InitHashMaps();
static std::array<std::pair<RandomizerCheck, RandomizerCheck>, 17> randomizerFishingPondFish; static std::array<std::pair<RandomizerCheck, RandomizerCheck>, 17> randomizerFishingPondFish;
static std::unordered_map<int8_t, RandomizerCheck> randomizerGrottoFishMap; static std::unordered_map<int8_t, RandomizerCheck> randomizerGrottoFishMap;

View File

@@ -610,7 +610,9 @@ s16 func_80A70058(PlayState* play, Actor* thisx) {
case 0x70F1: case 0x70F1:
case 0x70F2: case 0x70F2:
case 0x70F3: case 0x70F3:
Rupees_ChangeBy(beggarRewards[this->actor.textId - 0x70F0]); if (GameInteractor_Should(VB_BEGGAR_GIVE_ITEM, true, this)) {
Rupees_ChangeBy(beggarRewards[this->actor.textId - 0x70F0]);
}
Animation_ChangeByInfo(&this->skelAnime, sAnimationInfo, ENHY_ANIM_17); Animation_ChangeByInfo(&this->skelAnime, sAnimationInfo, ENHY_ANIM_17);
Player_UpdateBottleHeld(play, GET_PLAYER(play), ITEM_BOTTLE, PLAYER_IA_BOTTLE); Player_UpdateBottleHeld(play, GET_PLAYER(play), ITEM_BOTTLE, PLAYER_IA_BOTTLE);
break; break;