mirror of
https://github.com/HarbourMasters/Shipwright
synced 2026-09-29 11:21:12 -04:00
Shuffle Scarecrow Song (#7205)
This commit is contained in:
@@ -472,6 +472,13 @@
|
||||
"When disabled, \"Start with Zelda's Letter\" skips child Zelda: you also get the item Impa would give."
|
||||
]
|
||||
},
|
||||
"shuffle_scarecrows_song": {
|
||||
"name": "Shuffle Scarecrow's Song",
|
||||
"description": [
|
||||
"Shuffles Scarecrow's Song into the item pool. Teaching Bonooru a song as child, then playing it ",
|
||||
"back to him as adult, gives a random item instead."
|
||||
]
|
||||
},
|
||||
"shuffle_gerudo_membership_card": {
|
||||
"name": "Shuffle Gerudo Membership Card",
|
||||
"description": [
|
||||
@@ -1168,14 +1175,6 @@
|
||||
"name": "Shuffle Masks",
|
||||
"description": "The Happy Mask Shop never opens, masks are shuffled with the rest of the items."
|
||||
},
|
||||
"skip_scarecrows_song": {
|
||||
"name": "Skip Scarecrow's Song",
|
||||
"description": [
|
||||
"Start with the ability to summon Pierre the Scarecrow. Pulling out an Ocarina in the usual locations will ",
|
||||
"automatically summon him.\n",
|
||||
"With \"Shuffle Ocarina Buttons\" enabled, you'll need at least two Ocarina buttons to summon him."
|
||||
]
|
||||
},
|
||||
"skip_planting_beans": {
|
||||
"name": "Skip Planting Beans",
|
||||
"description": [
|
||||
@@ -1826,6 +1825,9 @@
|
||||
"starting_zeldas_letter": {
|
||||
"name": "Start with Zelda's Letter"
|
||||
},
|
||||
"starting_scarecrows_song": {
|
||||
"name": "Start with Scarecrow's Song"
|
||||
},
|
||||
"starting_claim_check": {
|
||||
"name": "Start with Claim Check"
|
||||
},
|
||||
|
||||
@@ -56,9 +56,9 @@
|
||||
"ShuffleTokens": 3,
|
||||
"ShuffleWeirdEgg": 2,
|
||||
"SkipEponaRace": 1,
|
||||
"SkipScarecrowsSong": 1,
|
||||
"StartingAge": 2,
|
||||
"StartingMapsCompasses": 0,
|
||||
"StartingScarecrowsSong": 1,
|
||||
"StartingZeldasLetter": 1,
|
||||
"SunlightArrows": 1
|
||||
}
|
||||
|
||||
@@ -36,11 +36,11 @@
|
||||
"ShuffleOcarinas": 1,
|
||||
"ShuffleWeirdEgg": 2,
|
||||
"SkipEponaRace": 1,
|
||||
"SkipScarecrowsSong": 1,
|
||||
"StartingKokiriSword": 1,
|
||||
"StartingBunnyHood": 1,
|
||||
"StartingMapsCompasses": 0,
|
||||
"StartingOcarina": 1,
|
||||
"StartingScarecrowsSong": 1,
|
||||
"StartingZeldasLetter": 1,
|
||||
"SunlightArrows": 1,
|
||||
"ZorasFountain": 1
|
||||
|
||||
@@ -49,9 +49,9 @@
|
||||
"ShuffleTokens": 3,
|
||||
"ShuffleWeirdEgg": 2,
|
||||
"SkipEponaRace": 1,
|
||||
"SkipScarecrowsSong": 1,
|
||||
"StartingMapsCompasses": 0,
|
||||
"StartingOcarina": 1,
|
||||
"StartingScarecrowsSong": 1,
|
||||
"StartingZeldasLetter": 1,
|
||||
"SunlightArrows": 1,
|
||||
"ZorasFountain": 1
|
||||
|
||||
@@ -896,6 +896,9 @@ void TimeSaverOnVanillaBehaviorHandler(GIVanillaBehavior id, bool* should, va_li
|
||||
break;
|
||||
}
|
||||
case VB_SKIP_SCARECROWS_SONG: {
|
||||
if (IS_RANDO && RAND_GET_OPTION(RSK_SHUFFLE_SCARECROWS_SONG)) {
|
||||
break;
|
||||
}
|
||||
if (gPlayState->msgCtx.msgMode == MSGMODE_OCARINA_PLAYING &&
|
||||
CVarGetInteger(CVAR_ENHANCEMENT("InstantScarecrow"), 0) && gSaveContext.scarecrowSpawnSongSet) {
|
||||
*should = true;
|
||||
|
||||
@@ -2132,6 +2132,7 @@ void DrawEquipmentTab() {
|
||||
randomizer.GetRandoSettingValue(RSK_SHUFFLE_OPEN_CHEST) ||
|
||||
randomizer.GetRandoSettingValue(RSK_SHUFFLE_SPEAK) ||
|
||||
randomizer.GetRandoSettingValue(RSK_SHUFFLE_OCARINA_BUTTONS) ||
|
||||
randomizer.GetRandoSettingValue(RSK_SHUFFLE_SCARECROWS_SONG) ||
|
||||
randomizer.GetRandoSettingValue(RSK_ROCS_FEATHER);
|
||||
|
||||
if (bombchuProgressive || triforceHunt || anyAbilityShuffle) {
|
||||
@@ -2216,6 +2217,8 @@ void DrawEquipmentTab() {
|
||||
static_cast<RandomizerInf>(RAND_INF_HAS_OCARINA_A + i));
|
||||
}
|
||||
}
|
||||
if (randomizer.GetRandoSettingValue(RSK_SHUFFLE_SCARECROWS_SONG))
|
||||
add(RG_SCARECROWS_SONG, RAND_INF_HAS_SCARECROWS_SONG);
|
||||
if (randomizer.GetRandoSettingValue(RSK_ROCS_FEATHER))
|
||||
add(RG_ROCS_FEATHER, RAND_INF_OBTAINED_ROCS_FEATHER);
|
||||
if (randomizer.GetRandoSettingValue(RSK_SHUFFLE_FISHING_POLE))
|
||||
|
||||
@@ -1263,6 +1263,14 @@ typedef enum {
|
||||
// - `*EnGb`
|
||||
VB_GIVE_ITEM_FROM_POE_COLLECTOR,
|
||||
|
||||
// #### `result`
|
||||
// ```c
|
||||
// !Flags_GetEventChkInf(EVENTCHKINF_PLAYED_SONG_FOR_SCARECROW_AS_ADULT)
|
||||
// ```
|
||||
// #### `args`
|
||||
// - None
|
||||
VB_GIVE_ITEM_FROM_SCARECROW,
|
||||
|
||||
// #### `result`
|
||||
// ```c
|
||||
// true
|
||||
|
||||
@@ -905,6 +905,7 @@ void SetupDisplayNames() {
|
||||
strcpy(itemTimestampDisplayName[TIMESTAMP_FOUND_ZR_BEAN_SOUL], "ZR Bean Soul: ");
|
||||
strcpy(itemTimestampDisplayName[TIMESTAMP_FOUND_SKELETON_KEY], "Skeleton Key: ");
|
||||
strcpy(itemTimestampDisplayName[TIMESTAMP_FOUND_ROCS_FEATHER], "Roc's Feather: ");
|
||||
strcpy(itemTimestampDisplayName[TIMESTAMP_FOUND_SCARECROWS_SONG], "Scarecrow's Song: ");
|
||||
// clang-format on
|
||||
}
|
||||
|
||||
|
||||
@@ -121,7 +121,8 @@ typedef enum {
|
||||
/* 0xED */ TIMESTAMP_FOUND_SKELETON_KEY,
|
||||
/* 0xEE */ TIMESTAMP_FOUND_ROCS_FEATHER,
|
||||
/* 0xEF */ TIMESTAMP_TIMESPLITS_COMPLETED,
|
||||
/* 0xF0 */ TIMESTAMP_MAX
|
||||
/* 0xF0 */ TIMESTAMP_FOUND_SCARECROWS_SONG,
|
||||
/* 0xF1 */ TIMESTAMP_MAX
|
||||
} GameplayStatTimestamp;
|
||||
|
||||
typedef enum {
|
||||
|
||||
@@ -154,6 +154,11 @@ Kaleido::Kaleido() {
|
||||
if (ctx->GetOption(RSK_SHUFFLE_OCARINA_BUTTONS)) {
|
||||
mEntries.push_back(std::make_shared<KaleidoEntryOcarinaButtons>());
|
||||
}
|
||||
if (ctx->GetOption(RSK_SHUFFLE_SCARECROWS_SONG)) {
|
||||
mEntries.push_back(std::make_shared<KaleidoEntryIconFlag>(
|
||||
gSongNoteTex, G_IM_FMT_IA, G_IM_SIZ_8b, 16, 24, Color_RGBA8{ 40, 160, 40, 255 },
|
||||
FlagType::FLAG_RANDOMIZER_INF, RAND_INF_HAS_SCARECROWS_SONG, "Scarecrow's Song"));
|
||||
}
|
||||
if (ctx->GetOption(RSK_SHUFFLE_BOSS_SOULS).IsNot(RO_BOSS_SOULS_OFF)) {
|
||||
static const char* bossSoulNames[] = {
|
||||
"Gohma's Soul", "King Dodongo's Soul", "Barinade's Soul", "Phantom Ganon's Soul",
|
||||
|
||||
@@ -512,6 +512,10 @@ void StaticData::HintTable_Init_Exclude_Overworld() {
|
||||
/*french*/ "Selon moi, le #trésor au fond du lac# est #[[1]]#.", {QM_RED, QM_GREEN}));
|
||||
// /*spanish*/ Según dicen, el #tesoro hundido del lago# se trata de #[[1]]#.
|
||||
|
||||
hintTextTable[RHT_LH_SCARECROWS_SONG] = HintText(CustomMessage("They say that #teaching a scarecrow a tune# is rewarded with #[[1]]#.",
|
||||
/*german*/ TODO_TRANSLATE,
|
||||
/*french*/ TODO_TRANSLATE, {QM_RED, QM_GREEN}));
|
||||
|
||||
hintTextTable[RHT_TH_FREED_CARPENTERS] = HintText(CustomMessage("They say that #rescuing captured carpenters# is rewarded with #[[1]]#.",
|
||||
/*german*/ "Man erzählt sich, daß das #Retten gefangener Zimmerleute# #[[1]]# einbrächte.",
|
||||
/*french*/ "Selon moi, #secourir les charpentiers capturés# assure #[[1]]#.", {QM_RED, QM_GREEN}));
|
||||
|
||||
@@ -2090,6 +2090,12 @@ void StaticData::HintTable_Init_Item() {
|
||||
hintTextTable[RHT_MASK_GERUDO] = HintText(CustomMessage("a gerudo mask", /*german*/"!!!", /*french*/"le Masque de Gerudo"), {CustomMessage("a mask", /*german*/"!!!", /*french*/"un masque")});
|
||||
hintTextTable[RHT_MASK_TRUTH] = HintText(CustomMessage("a mask of truth", /*german*/"!!!", /*french*/"le Masque de Vérité"), {CustomMessage("a mask", /*german*/"!!!", /*french*/"un masque")});
|
||||
|
||||
hintTextTable[RHT_SCARECROWS_SONG] = HintText(CustomMessage("Scarecrow's Song", /*german*/"das Vogelscheuchenlied", /*french*/"le chant de l'épouvantail"),
|
||||
{
|
||||
CustomMessage("a song", /*german*/"ein Lied", /*french*/"un chant")
|
||||
}, {
|
||||
CustomMessage("a scarecrow's memory", /*german*/"eine Vogelscheuchen-Erinnerung", /*french*/"un souvenir d'épouvantail")});
|
||||
|
||||
hintTextTable[RHT_FISHING_POLE] = HintText(CustomMessage("a fishing pole", /*german*/"eine Angelrute", /*french*/"une canne à pêche"),
|
||||
// /*spanish*/caña de pescar
|
||||
{
|
||||
|
||||
@@ -387,6 +387,10 @@ void GenerateItemPool() {
|
||||
AddItemToPool(RG_ZELDAS_LETTER, 2, 1, 1, 1);
|
||||
}
|
||||
|
||||
if (ctx->GetOption(RSK_SHUFFLE_SCARECROWS_SONG) && !ctx->GetOption(RSK_STARTING_SCARECROWS_SONG)) {
|
||||
AddItemToPool(RG_SCARECROWS_SONG, 2, 1, 1, 1);
|
||||
}
|
||||
|
||||
if (ctx->GetOption(RSK_SHUFFLE_OCARINA)) {
|
||||
if (ctx->GetOption(RSK_STARTING_OCARINA).IsNot(RO_STARTING_OCARINA_TIME)) {
|
||||
int baseOcarinas = ctx->GetOption(RSK_STARTING_OCARINA).Is(RO_STARTING_OCARINA_OFF) ? 2 : 1;
|
||||
|
||||
@@ -120,6 +120,7 @@ void GenerateStartingInventory() {
|
||||
if (ctx->GetOption(RSK_SHUFFLE_ZELDAS_LETTER)) {
|
||||
AddItemToInventory(RG_ZELDAS_LETTER, ctx->GetOption(RSK_STARTING_ZELDAS_LETTER) ? 1 : 0);
|
||||
}
|
||||
AddItemToInventory(RG_SCARECROWS_SONG, ctx->GetOption(RSK_STARTING_SCARECROWS_SONG) ? 1 : 0);
|
||||
AddItemToInventory(RG_KEATON_MASK, ctx->GetOption(RSK_STARTING_KEATON_MASK) ? 1 : 0);
|
||||
AddItemToInventory(RG_SKULL_MASK, ctx->GetOption(RSK_STARTING_SKULL_MASK) ? 1 : 0);
|
||||
AddItemToInventory(RG_SPOOKY_MASK, ctx->GetOption(RSK_STARTING_SPOOKY_MASK) ? 1 : 0);
|
||||
|
||||
@@ -415,6 +415,12 @@ void PlandomizerItemImageCorrection(Rando::Item randoItem) {
|
||||
textureID = gui->GetTextureByName("ITEM_OCARINA_TIME");
|
||||
}
|
||||
|
||||
if (randoItem.GetRandomizerGet() == RG_SCARECROWS_SONG) {
|
||||
textureID = gui->GetTextureByName("RG_SCARECROWS_SONG");
|
||||
imageSize = ImVec2(24.0f, 32.0f);
|
||||
imagePadding = 6.0f;
|
||||
}
|
||||
|
||||
if (textureID == 0) {
|
||||
textureID = gui->GetTextureByName(itemMapping[randoItem.GetGIEntry()->itemId].name);
|
||||
}
|
||||
|
||||
@@ -159,6 +159,7 @@ std::map<RandomizerCheck, RandomizerInf> rcToRandomizerInf = {
|
||||
{ RC_LH_ADULT_FISHING, RAND_INF_ADULT_FISHING },
|
||||
{ RC_MARKET_10_BIG_POES, RAND_INF_10_BIG_POES },
|
||||
{ RC_KAK_100_GOLD_SKULLTULA_REWARD, RAND_INF_KAK_100_GOLD_SKULLTULA_REWARD },
|
||||
{ RC_LH_SCARECROWS_SONG, RAND_INF_LH_SCARECROWS_SONG },
|
||||
{ RC_KF_STORMS_GROTTO_BEEHIVE_LEFT, RAND_INF_BEEHIVE_KF_STORMS_GROTTO_LEFT },
|
||||
{ RC_KF_STORMS_GROTTO_BEEHIVE_RIGHT, RAND_INF_BEEHIVE_KF_STORMS_GROTTO_RIGHT },
|
||||
{ RC_LW_NEAR_SHORTCUTS_GROTTO_BEEHIVE_LEFT, RAND_INF_BEEHIVE_LW_NEAR_SHORTCUTS_GROTTO_LEFT },
|
||||
|
||||
@@ -172,6 +172,8 @@ void Context::GenerateLocationPool() {
|
||||
mOptions[RSK_SHUFFLE_MASTER_SWORD].Is(RO_GENERIC_OFF)) ||
|
||||
(location.GetRandomizerCheck() == RC_KAK_100_GOLD_SKULLTULA_REWARD &&
|
||||
mOptions[RSK_SHUFFLE_100_GS_REWARD].Is(RO_GENERIC_OFF)) ||
|
||||
(location.GetRandomizerCheck() == RC_LH_SCARECROWS_SONG &&
|
||||
mOptions[RSK_SHUFFLE_SCARECROWS_SONG].Is(RO_GENERIC_OFF)) ||
|
||||
(location.GetRCType() == RCTYPE_CHEST_GAME && mOptions[RSK_SHUFFLE_CHEST_MINIGAME].Is(RO_GENERIC_OFF)) ||
|
||||
location.GetRCType() == RCTYPE_STATIC_HINT || // can't have items
|
||||
location.GetRCType() == RCTYPE_GOSSIP_STONE || // can't have items
|
||||
|
||||
@@ -982,6 +982,11 @@ static void InitTrickNames() {
|
||||
{ Text{ "Floating Lure", "Floating Lure", "Schwimmer" }, Text{ "a ", "un ", "einen " } },
|
||||
{ Text{ "Fishing Reel", "Fishing Reel", "Angelschnur" }, Text{ "a ", "un ", "eine " } },
|
||||
};
|
||||
trickNameTable[RG_SCARECROWS_SONG] = {
|
||||
{ Text{ "Pierre's Polka", "Polka de Pierre", "Pierres Polka" }, Text{ "", "la ", "" } },
|
||||
{ Text{ "Crow's Song", "Chant du corbeau", "Krähenlied" }, Text{ "the ", "le ", "das " } },
|
||||
{ Text{ "Bonooru's Ballad", "Ballade de Bonooru", "Bonoorus Ballade" }, Text{ "", "la ", "" } },
|
||||
};
|
||||
trickNameTable[RG_SKELETON_KEY] = {
|
||||
// TODO_TRANSLATE
|
||||
{ Text{ "Stalfos Key" }, Text{ "the " } }, { Text{ "Nightmare Key" }, Text{ "the " } },
|
||||
|
||||
@@ -14,6 +14,7 @@ extern "C" {
|
||||
#include "objects/gameplay_keep/gameplay_keep.h"
|
||||
#include "objects/object_gi_compass/object_gi_compass.h"
|
||||
#include "objects/object_gi_map/object_gi_map.h"
|
||||
#include "objects/object_gi_melody/object_gi_melody.h"
|
||||
#include "objects/object_gi_hearts/object_gi_hearts.h"
|
||||
#include "objects/object_gi_rupy/object_gi_rupy.h"
|
||||
#include "objects/object_gi_scale/object_gi_scale.h"
|
||||
@@ -1221,6 +1222,25 @@ extern "C" void Randomizer_DrawFishingPoleGI(PlayState* play, GetItemEntry* getI
|
||||
CLOSE_DISPS(play->state.gfxCtx);
|
||||
}
|
||||
|
||||
extern "C" void Randomizer_DrawScarecrowsSong(PlayState* play, GetItemEntry* getItemEntry) {
|
||||
OPEN_DISPS(play->state.gfxCtx);
|
||||
|
||||
Gfx_SetupDL_25Xlu(play->state.gfxCtx);
|
||||
|
||||
gSPMatrix(POLY_XLU_DISP++, Matrix_NewMtx(play->state.gfxCtx, (char*)__FILE__, __LINE__),
|
||||
G_MTX_MODELVIEW | G_MTX_LOAD);
|
||||
|
||||
// dark green note, distinct from the lighter Saria and Minuet greens
|
||||
gDPSetGrayscaleColor(POLY_XLU_DISP++, 40, 160, 40, 255);
|
||||
gSPGrayscale(POLY_XLU_DISP++, true);
|
||||
|
||||
gSPDisplayList(POLY_XLU_DISP++, (Gfx*)gGiSongNoteDL);
|
||||
|
||||
gSPGrayscale(POLY_XLU_DISP++, false);
|
||||
|
||||
CLOSE_DISPS(play->state.gfxCtx);
|
||||
}
|
||||
|
||||
extern "C" void Randomizer_DrawSkeletonKey(PlayState* play, GetItemEntry* getItemEntry) {
|
||||
OPEN_DISPS(play->state.gfxCtx);
|
||||
|
||||
|
||||
@@ -27,6 +27,7 @@ void Randomizer_DrawJabberNut(PlayState* play, GetItemEntry* getItemEntry);
|
||||
void Randomizer_DrawOpenChest(PlayState* play, GetItemEntry* getItemEntry);
|
||||
void Randomizer_DrawSilverRupee(PlayState* play, GetItemEntry* getItemEntry);
|
||||
void Randomizer_DrawFishingPoleGI(PlayState* play, GetItemEntry* getItemEntry);
|
||||
void Randomizer_DrawScarecrowsSong(PlayState* play, GetItemEntry* getItemEntry);
|
||||
void Randomizer_DrawSkeletonKey(PlayState* play, GetItemEntry* getItemEntry);
|
||||
void Randomizer_DrawMysteryItem(PlayState* play, GetItemEntry* getItemEntry);
|
||||
void Randomizer_DrawBombchuBag(PlayState* play, GetItemEntry* getItemEntry);
|
||||
|
||||
@@ -1932,9 +1932,18 @@ void RandomizerOnVanillaBehaviorHandler(GIVanillaBehavior id, bool* should, va_l
|
||||
break;
|
||||
}
|
||||
|
||||
if (gPlayState->msgCtx.msgMode == MSGMODE_OCARINA_PLAYING && RAND_GET_OPTION(RSK_SKIP_SCARECROWS_SONG)) {
|
||||
if (Flags_GetRandomizerInf(RAND_INF_HAS_SCARECROWS_SONG) &&
|
||||
gPlayState->msgCtx.msgMode == MSGMODE_OCARINA_PLAYING) {
|
||||
*should = true;
|
||||
break;
|
||||
} else if (RAND_GET_OPTION(RSK_SHUFFLE_SCARECROWS_SONG)) {
|
||||
*should = false;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case VB_GIVE_ITEM_FROM_SCARECROW: {
|
||||
if (RAND_GET_OPTION(RSK_SHUFFLE_SCARECROWS_SONG)) {
|
||||
Flags_SetRandomizerInf(RAND_INF_LH_SCARECROWS_SONG);
|
||||
*should = false;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -402,6 +402,8 @@ void Rando::StaticData::InitItemTable() {
|
||||
itemTable[RG_GANON_SOUL].SetCustomDrawFunc(Randomizer_DrawBossSoul);
|
||||
itemTable[RG_FISHING_POLE] = Item(RG_FISHING_POLE, Text{ "Fishing Pole", "Canne à Pêche", "Angelrute" }, ITEMTYPE_ITEM, RG_FISHING_POLE, true, LOGIC_FISHING_POLE, RHT_FISHING_POLE, RG_FISHING_POLE, OBJECT_GI_FISH, GID_FISHING_POLE, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_RANDOMIZER, {"the ", "la ", "das "});
|
||||
itemTable[RG_FISHING_POLE].SetCustomDrawFunc(Randomizer_DrawFishingPoleGI);
|
||||
itemTable[RG_SCARECROWS_SONG] = Item(RG_SCARECROWS_SONG, Text{ "Scarecrow's Song", "Chant de l'Épouvantail", "Vogelscheuchenlied" }, ITEMTYPE_ITEM, RG_SCARECROWS_SONG, true, LOGIC_NONE, RHT_SCARECROWS_SONG, RG_SCARECROWS_SONG, OBJECT_GI_MELODY, GID_SONG_GENERIC, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_RANDOMIZER, {"the ", "le ", "das "});
|
||||
itemTable[RG_SCARECROWS_SONG].SetCustomDrawFunc(Randomizer_DrawScarecrowsSong);
|
||||
|
||||
itemTable[RG_OCARINA_A_BUTTON] = Item(RG_OCARINA_A_BUTTON, Text{ "Ocarina A Button", "Touche A de l'Ocarina", "Taste A der Okarina" }, ITEMTYPE_ITEM, GI_MAP, true, LOGIC_OCARINA_A_BUTTON, RHT_OCARINA_A_BUTTON, RG_OCARINA_A_BUTTON, OBJECT_GI_MAP, GID_STONE_OF_AGONY, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_RANDOMIZER, {"the ", "la ", "den "});
|
||||
itemTable[RG_OCARINA_A_BUTTON].SetCustomDrawFunc(Randomizer_DrawOcarinaButton);
|
||||
|
||||
@@ -15,6 +15,7 @@ void RegionTable_Init_LakeHylia() {
|
||||
}, {
|
||||
//Locations
|
||||
LOCATION(RC_LH_UNDERWATER_ITEM, logic->IsChild && logic->HasItem(RG_SILVER_SCALE)),
|
||||
LOCATION(RC_LH_SCARECROWS_SONG, logic->Get(LOGIC_CHILD_SCARECROW) && logic->Get(LOGIC_ADULT_SCARECROW)),
|
||||
LOCATION(RC_LH_SUN, logic->IsAdult && ((logic->Get(LOGIC_WATER_TEMPLE_CLEAR) && logic->HasItem(RG_BRONZE_SCALE)) || logic->ReachDistantScarecrow()) && logic->CanUse(RG_FAIRY_BOW)),
|
||||
LOCATION(RC_LH_FREESTANDING_POH, logic->IsAdult && (logic->ReachScarecrow() || logic->BeanPlanted(LOGIC_PLANT_LAKE_HYLIA_BEAN)) && logic->CanAvoidEnemy(RE_GUAY, ED_CLOSE, false) && logic->HasItem(RG_CLIMB)),
|
||||
LOCATION(RC_LH_GS_BEAN_PATCH, logic->CanSpawnSoilSkull(RG_LAKE_HYLIA_BEAN_SOUL) && logic->CanGetEnemyDrop(RE_GOLD_SKULLTULA)),
|
||||
|
||||
@@ -187,6 +187,7 @@ void Rando::StaticData::InitLocationTable() {
|
||||
locationTable[RC_LH_LAB_DIVE] = Location::Base(RC_LH_LAB_DIVE, RCQUEST_BOTH, RCTYPE_STANDARD, ACTOR_ID_MAX, SCENE_LAKESIDE_LABORATORY, 0x00, "Lab Dive", RHT_LH_LAB_DIVE, RG_PIECE_OF_HEART, SpoilerCollectionCheck::ItemGetInf(16), true);
|
||||
locationTable[RC_LH_TRADE_FROG] = Location::Base(RC_LH_TRADE_FROG, RCQUEST_BOTH, RCTYPE_ADULT_TRADE, ACTOR_ID_MAX, SCENE_LAKESIDE_LABORATORY, 0x00, "Lab Trade Eyeball Frog", RHT_LH_TRADE_FROG, RG_EYEDROPS, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ADULT_TRADES_LH_TRADE_FROG), 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(EVENTCHKINF_OBTAINED_RUTOS_LETTER), true);
|
||||
locationTable[RC_LH_SCARECROWS_SONG] = Location::Base(RC_LH_SCARECROWS_SONG, RCQUEST_BOTH, RCTYPE_STANDARD, ACTOR_ID_MAX, SCENE_LAKE_HYLIA, 0x00, "Scarecrow's Song", RHT_LH_SCARECROWS_SONG, RG_SCARECROWS_SONG, SpoilerCollectionCheck::RandomizerInf(RAND_INF_LH_SCARECROWS_SONG));
|
||||
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_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);
|
||||
|
||||
@@ -144,6 +144,7 @@ bool Logic::HasItem(RandomizerGet itemName) {
|
||||
case RG_POWER_BRACELET:
|
||||
case RG_CHILD_WALLET:
|
||||
case RG_FISHING_POLE:
|
||||
case RG_SCARECROWS_SONG:
|
||||
case RG_BRONZE_SCALE:
|
||||
case RG_CLIMB:
|
||||
case RG_CRAWL:
|
||||
@@ -1605,8 +1606,8 @@ bool Logic::HookshotOrBoomerang() {
|
||||
}
|
||||
|
||||
bool Logic::ScarecrowsSong() {
|
||||
return (ctx->GetOption(RSK_SKIP_SCARECROWS_SONG) && HasItem(RG_FAIRY_OCARINA) && OcarinaButtons() >= 2) ||
|
||||
(Get(LOGIC_CHILD_SCARECROW) && Get(LOGIC_ADULT_SCARECROW));
|
||||
return (HasItem(RG_SCARECROWS_SONG) && HasItem(RG_FAIRY_OCARINA) && OcarinaButtons() >= 2) ||
|
||||
(!ctx->GetOption(RSK_SHUFFLE_SCARECROWS_SONG) && Get(LOGIC_CHILD_SCARECROW) && Get(LOGIC_ADULT_SCARECROW));
|
||||
}
|
||||
|
||||
bool Logic::BlueFire() {
|
||||
@@ -2029,6 +2030,7 @@ std::map<RandomizerGet, uint32_t> StaticData::RandoGetToRandInf = {
|
||||
{ RG_SPEAK_KOKIRI, RAND_INF_CAN_SPEAK_KOKIRI },
|
||||
{ RG_SPEAK_ZORA, RAND_INF_CAN_SPEAK_ZORA },
|
||||
{ RG_FISHING_POLE, RAND_INF_FISHING_POLE_FOUND },
|
||||
{ RG_SCARECROWS_SONG, RAND_INF_HAS_SCARECROWS_SONG },
|
||||
{ RG_ROCS_FEATHER, RAND_INF_OBTAINED_ROCS_FEATHER },
|
||||
{ RG_GUARD_HOUSE_KEY, RAND_INF_GUARD_HOUSE_KEY_OBTAINED },
|
||||
{ RG_MARKET_BAZAAR_KEY, RAND_INF_MARKET_BAZAAR_KEY_OBTAINED },
|
||||
@@ -2501,6 +2503,7 @@ void Logic::ApplyItemEffect(Item& item, bool state) {
|
||||
case RG_SPEAK_KOKIRI:
|
||||
case RG_SPEAK_ZORA:
|
||||
case RG_FISHING_POLE:
|
||||
case RG_SCARECROWS_SONG:
|
||||
case RG_GUARD_HOUSE_KEY:
|
||||
case RG_MARKET_BAZAAR_KEY:
|
||||
case RG_MARKET_POTION_SHOP_KEY:
|
||||
|
||||
@@ -512,6 +512,8 @@ ItemObtainability Randomizer::GetItemObtainabilityFromRandomizerGet(RandomizerGe
|
||||
: (gSaveContext.magicLevel < 2 ? CAN_OBTAIN : CANT_OBTAIN_ALREADY_HAVE);
|
||||
case RG_FISHING_POLE:
|
||||
return !Flags_GetRandomizerInf(RAND_INF_FISHING_POLE_FOUND) ? CAN_OBTAIN : CANT_OBTAIN_ALREADY_HAVE;
|
||||
case RG_SCARECROWS_SONG:
|
||||
return !Flags_GetRandomizerInf(RAND_INF_HAS_SCARECROWS_SONG) ? CAN_OBTAIN : CANT_OBTAIN_ALREADY_HAVE;
|
||||
|
||||
// Songs
|
||||
case RG_ZELDAS_LULLABY:
|
||||
@@ -1091,6 +1093,8 @@ static std::unordered_map<RandomizerGet, GameplayStatTimestamp> randomizerGetToS
|
||||
{ RG_SKELETON_KEY, TIMESTAMP_FOUND_SKELETON_KEY },
|
||||
|
||||
{ RG_ROCS_FEATHER, TIMESTAMP_FOUND_ROCS_FEATHER },
|
||||
|
||||
{ RG_SCARECROWS_SONG, TIMESTAMP_FOUND_SCARECROWS_SONG },
|
||||
};
|
||||
|
||||
// Gameplay stat tracking: Update time the item was acquired
|
||||
|
||||
@@ -277,6 +277,7 @@ RANDO_ENUM_ITEM(RC_ZF_GS_ABOVE_THE_LOG)
|
||||
RANDO_ENUM_ITEM(RC_ZF_GS_TREE)
|
||||
RANDO_ENUM_ITEM(RC_ZF_GS_HIDDEN_CAVE)
|
||||
RANDO_ENUM_ITEM(RC_LH_UNDERWATER_ITEM)
|
||||
RANDO_ENUM_ITEM(RC_LH_SCARECROWS_SONG)
|
||||
RANDO_ENUM_ITEM(RC_LH_CHILD_FISHING)
|
||||
RANDO_ENUM_ITEM(RC_LH_CHILD_FISH_1)
|
||||
RANDO_ENUM_ITEM(RC_LH_CHILD_FISH_2)
|
||||
|
||||
@@ -255,6 +255,7 @@ RANDO_ENUM_ITEM(RG_OCARINA_C_LEFT_BUTTON)
|
||||
RANDO_ENUM_ITEM(RG_OCARINA_C_RIGHT_BUTTON)
|
||||
RANDO_ENUM_ITEM(RG_SKELETON_KEY)
|
||||
RANDO_ENUM_ITEM(RG_FISHING_POLE)
|
||||
RANDO_ENUM_ITEM(RG_SCARECROWS_SONG)
|
||||
RANDO_ENUM_ITEM(RG_DEKU_STICK_BAG)
|
||||
RANDO_ENUM_ITEM(RG_DEKU_NUT_BAG)
|
||||
RANDO_ENUM_ITEM(RG_HINT)
|
||||
|
||||
@@ -362,6 +362,7 @@ RANDO_ENUM_ITEM(RHT_ZF_GS_ABOVE_THE_LOG)
|
||||
RANDO_ENUM_ITEM(RHT_ZF_GS_TREE)
|
||||
RANDO_ENUM_ITEM(RHT_ZF_GS_HIDDEN_CAVE)
|
||||
RANDO_ENUM_ITEM(RHT_LH_UNDERWATER_ITEM)
|
||||
RANDO_ENUM_ITEM(RHT_LH_SCARECROWS_SONG)
|
||||
RANDO_ENUM_ITEM(RHT_LH_CHILD_FISHING)
|
||||
RANDO_ENUM_ITEM(RHT_LH_ADULT_FISHING)
|
||||
RANDO_ENUM_ITEM(RHT_LH_POND_FISH)
|
||||
@@ -1079,6 +1080,7 @@ RANDO_ENUM_ITEM(RHT_CRAWL)
|
||||
RANDO_ENUM_ITEM(RHT_SPEAK)
|
||||
RANDO_ENUM_ITEM(RHT_OPEN_CHEST)
|
||||
RANDO_ENUM_ITEM(RHT_FISHING_POLE)
|
||||
RANDO_ENUM_ITEM(RHT_SCARECROWS_SONG)
|
||||
RANDO_ENUM_ITEM(RHT_SKELETON_KEY)
|
||||
RANDO_ENUM_ITEM(RHT_SILVER_RUPEE_DODONGOS_CAVERN)
|
||||
RANDO_ENUM_ITEM(RHT_SILVER_RUPEE_SHADOW_TEMPLE)
|
||||
|
||||
@@ -155,6 +155,8 @@ RANDO_ENUM_ITEM(RAND_INF_ADULT_TRADES_DMT_TRADE_CLAIM_CHECK)
|
||||
|
||||
RANDO_ENUM_ITEM(RAND_INF_KAK_100_GOLD_SKULLTULA_REWARD)
|
||||
|
||||
RANDO_ENUM_ITEM(RAND_INF_LH_SCARECROWS_SONG)
|
||||
|
||||
RANDO_ENUM_ITEM(RAND_INF_GREG_FOUND)
|
||||
|
||||
RANDO_ENUM_ITEM(RAND_INF_TOT_MASTER_SWORD)
|
||||
@@ -1499,6 +1501,7 @@ RANDO_ENUM_ITEM(RAND_INF_GROTTO_FISH_LW_NEAR_SHORTCUTS_GROTTO)
|
||||
RANDO_ENUM_ITEM(RAND_INF_GROTTO_FISH_KF_STORMS_GROTTO)
|
||||
|
||||
RANDO_ENUM_ITEM(RAND_INF_FISHING_POLE_FOUND)
|
||||
RANDO_ENUM_ITEM(RAND_INF_HAS_SCARECROWS_SONG)
|
||||
|
||||
RANDO_ENUM_ITEM(RAND_INF_ZD_FISH_1)
|
||||
RANDO_ENUM_ITEM(RAND_INF_ZD_FISH_2)
|
||||
|
||||
@@ -93,6 +93,7 @@ RANDO_ENUM_ITEM(RSK_SHUFFLE_BEEHIVES)
|
||||
RANDO_ENUM_ITEM(RSK_SHUFFLE_COWS)
|
||||
RANDO_ENUM_ITEM(RSK_SHUFFLE_WEIRD_EGG)
|
||||
RANDO_ENUM_ITEM(RSK_SHUFFLE_ZELDAS_LETTER)
|
||||
RANDO_ENUM_ITEM(RSK_SHUFFLE_SCARECROWS_SONG)
|
||||
RANDO_ENUM_ITEM(RSK_SHUFFLE_GERUDO_MEMBERSHIP_CARD)
|
||||
RANDO_ENUM_ITEM(RSK_SHUFFLE_POTS)
|
||||
RANDO_ENUM_ITEM(RSK_SHUFFLE_CRATES)
|
||||
@@ -177,6 +178,7 @@ RANDO_ENUM_ITEM(RSK_STARTING_BOTTLE_3)
|
||||
RANDO_ENUM_ITEM(RSK_STARTING_BOTTLE_4)
|
||||
RANDO_ENUM_ITEM(RSK_STARTING_WEIRD_EGG)
|
||||
RANDO_ENUM_ITEM(RSK_STARTING_ZELDAS_LETTER)
|
||||
RANDO_ENUM_ITEM(RSK_STARTING_SCARECROWS_SONG)
|
||||
RANDO_ENUM_ITEM(RSK_STARTING_CLAIM_CHECK)
|
||||
RANDO_ENUM_ITEM(RSK_STARTING_GERUDO_CARD)
|
||||
RANDO_ENUM_ITEM(RSK_STARTING_BIGGORON_SWORD)
|
||||
@@ -185,7 +187,6 @@ RANDO_ENUM_ITEM(RSK_SHUFFLE_CHEST_MINIGAME)
|
||||
RANDO_ENUM_ITEM(RSK_BIG_POE_COUNT)
|
||||
RANDO_ENUM_ITEM(RSK_SKIP_EPONA_RACE)
|
||||
RANDO_ENUM_ITEM(RSK_SHUFFLE_MASKS)
|
||||
RANDO_ENUM_ITEM(RSK_SKIP_SCARECROWS_SONG)
|
||||
RANDO_ENUM_ITEM(RSK_SKIP_PLANTING_BEANS)
|
||||
RANDO_ENUM_ITEM(RSK_SKULLS_SUNS_SONG)
|
||||
RANDO_ENUM_ITEM(RSK_EARLY_GRANNYS_SHOP)
|
||||
|
||||
@@ -157,6 +157,8 @@ void RandomizerCheckObjects::UpdateImGuiVisibility() {
|
||||
CVarGetInteger(CVAR_RANDOMIZER_SETTING("ShuffleOcarinas"), RO_GENERIC_NO)) && // ocarina locations
|
||||
(location.GetRandomizerCheck() != RC_HC_ZELDAS_LETTER ||
|
||||
CVarGetInteger(CVAR_RANDOMIZER_SETTING("ShuffleZeldasLetter"), RO_GENERIC_NO)) &&
|
||||
(location.GetRandomizerCheck() != RC_LH_SCARECROWS_SONG ||
|
||||
CVarGetInteger(CVAR_RANDOMIZER_SETTING("ShuffleScarecrowsSong"), RO_GENERIC_NO)) &&
|
||||
(location.GetRCType() !=
|
||||
RCTYPE_GOSSIP_STONE) && // don't show gossip stones (maybe gossipsanity will be a thing eventually?)
|
||||
(location.GetRCType() != RCTYPE_STATIC_HINT) && // don't show static hints
|
||||
|
||||
@@ -112,6 +112,7 @@ bool showBossKeysanity;
|
||||
bool showGanonBossKey;
|
||||
bool showOcarinas;
|
||||
bool show100SkullReward;
|
||||
bool showScarecrowsSong;
|
||||
bool showLinksPocket;
|
||||
bool showChestMinigame;
|
||||
bool fortressFast;
|
||||
@@ -1653,6 +1654,8 @@ void LoadSettings() {
|
||||
IS_RANDO && OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_SHUFFLE_OCARINA) == RO_GENERIC_YES;
|
||||
show100SkullReward = IS_RANDO && OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(
|
||||
RSK_SHUFFLE_100_GS_REWARD) == RO_GENERIC_YES;
|
||||
showScarecrowsSong = IS_RANDO && OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(
|
||||
RSK_SHUFFLE_SCARECROWS_SONG) == RO_GENERIC_YES;
|
||||
// don't show Link's Pocket if not randomizer, or if rando and pocket is disabled
|
||||
showLinksPocket = IS_RANDO && OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_LINKS_POCKET) !=
|
||||
RO_LINKS_POCKET_NOTHING;
|
||||
@@ -1970,6 +1973,7 @@ bool IsCheckShuffled(RandomizerCheck rc) {
|
||||
(loc->GetRCType() != RCTYPE_BOSS_KEY || showBossKeysanity) &&
|
||||
(loc->GetRCType() != RCTYPE_GANON_BOSS_KEY || showGanonBossKey) &&
|
||||
(rc != RC_KAK_100_GOLD_SKULLTULA_REWARD || show100SkullReward) &&
|
||||
(rc != RC_LH_SCARECROWS_SONG || showScarecrowsSong) &&
|
||||
(loc->GetRCType() != RCTYPE_GF_KEY && rc != RC_TH_FREED_CARPENTERS ||
|
||||
(showGerudoCard && rc == RC_TH_FREED_CARPENTERS) ||
|
||||
(fortressNormal && showGerudoFortressKeys && loc->GetRCType() == RCTYPE_GF_KEY) ||
|
||||
|
||||
@@ -176,6 +176,10 @@ std::vector<ItemTrackerItem> openChestItems = {
|
||||
ITEM_TRACKER_RG(RG_OPEN_CHEST, "", 0, DrawItem),
|
||||
};
|
||||
|
||||
std::vector<ItemTrackerItem> scarecrowsSongItems = {
|
||||
ITEM_TRACKER_RG(RG_SCARECROWS_SONG, "", 0, DrawItem),
|
||||
};
|
||||
|
||||
std::vector<ItemTrackerItem> beanSoulItems = {
|
||||
ITEM_TRACKER_RG_CUSTOM(RG_DEATH_MOUNTAIN_CRATER_BEAN_SOUL, "DMC", ITEM_BEAN, 0, DrawItem),
|
||||
ITEM_TRACKER_RG_CUSTOM(RG_DEATH_MOUNTAIN_TRAIL_BEAN_SOUL, "DMT", ITEM_BEAN, 0, DrawItem),
|
||||
@@ -1198,6 +1202,9 @@ void DrawItem(ItemTrackerItem item) {
|
||||
case RG_OPEN_CHEST:
|
||||
itemName = "Open";
|
||||
break;
|
||||
case RG_SCARECROWS_SONG:
|
||||
itemName = "Scarecrow's Song";
|
||||
break;
|
||||
}
|
||||
} else if (item.kind == ITEM_KIND_DUMMY) {
|
||||
if (item.id == ITEMTYPE_SILVER) {
|
||||
@@ -1622,6 +1629,9 @@ void UpdateVectors() {
|
||||
if (IS_RANDO && RAND_GET_OPTION(RSK_SHUFFLE_OPEN_CHEST)) {
|
||||
mainWindowItems.insert(mainWindowItems.end(), openChestItems.begin(), openChestItems.end());
|
||||
}
|
||||
if (IS_RANDO && RAND_GET_OPTION(RSK_SHUFFLE_SCARECROWS_SONG)) {
|
||||
mainWindowItems.insert(mainWindowItems.end(), scarecrowsSongItems.begin(), scarecrowsSongItems.end());
|
||||
}
|
||||
|
||||
// if we're adding greg to the misc window,
|
||||
// and misc isn't on the main window,
|
||||
|
||||
@@ -344,6 +344,9 @@ void SetStartingItems() {
|
||||
Randomizer_GetSettingValue(RSK_SHUFFLE_ZELDAS_LETTER)) {
|
||||
Item_Give(NULL, ITEM_LETTER_ZELDA);
|
||||
}
|
||||
if (Randomizer_GetSettingValue(RSK_STARTING_SCARECROWS_SONG)) {
|
||||
Flags_SetRandomizerInf(RAND_INF_HAS_SCARECROWS_SONG);
|
||||
}
|
||||
if (Randomizer_GetSettingValue(RSK_STARTING_CLAIM_CHECK)) {
|
||||
Item_Give(NULL, ITEM_CLAIM_CHECK);
|
||||
}
|
||||
|
||||
@@ -858,6 +858,7 @@ void Settings::CreateOptions() {
|
||||
OPT_U8(RSK_SHUFFLE_OPEN_CHEST, {"Off", "On", "Progressive"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("ShuffleOpenChest"), WIDGET_CVAR_COMBOBOX, RO_OPEN_CHEST_OFF);
|
||||
OPT_U8(RSK_SHUFFLE_WEIRD_EGG, {"Vanilla", "Shuffled", "Skip Waking Talon"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("ShuffleWeirdEgg"), WIDGET_CVAR_COMBOBOX, RO_WEIRD_EGG_VANILLA);
|
||||
OPT_BOOL(RSK_SHUFFLE_ZELDAS_LETTER, CVAR_RANDOMIZER_SETTING("ShuffleZeldasLetter"));
|
||||
OPT_BOOL(RSK_SHUFFLE_SCARECROWS_SONG, CVAR_RANDOMIZER_SETTING("ShuffleScarecrowsSong"));
|
||||
OPT_BOOL(RSK_SHUFFLE_GERUDO_MEMBERSHIP_CARD, CVAR_RANDOMIZER_SETTING("ShuffleGerudoToken"));
|
||||
OPT_U8(RSK_SHUFFLE_POTS, {"Off", "Dungeons", "Overworld", "All Pots"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("ShufflePots"), WIDGET_CVAR_COMBOBOX, RO_SHUFFLE_POTS_OFF);
|
||||
OPT_U8(RSK_SHUFFLE_GRASS, {"Off", "Dungeons", "Overworld", "All Grass"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("ShuffleGrass"), WIDGET_CVAR_COMBOBOX, RO_SHUFFLE_GRASS_OFF);
|
||||
@@ -1341,7 +1342,6 @@ void Settings::CreateOptions() {
|
||||
OPT_BOOL(RSK_SKIP_CHILD_STEALTH, {"Don't Skip", "Skip"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("SkipChildStealth"), WIDGET_CVAR_CHECKBOX, RO_GENERIC_DONT_SKIP);
|
||||
OPT_BOOL(RSK_EARLY_GRANNYS_SHOP, CVAR_RANDOMIZER_SETTING("EarlyGrannysShop"));
|
||||
OPT_BOOL(RSK_SKIP_EPONA_RACE, {"Don't Skip", "Skip"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("SkipEponaRace"), WIDGET_CVAR_CHECKBOX, RO_GENERIC_DONT_SKIP);
|
||||
OPT_BOOL(RSK_SKIP_SCARECROWS_SONG, CVAR_RANDOMIZER_SETTING("SkipScarecrowsSong"));
|
||||
OPT_BOOL(RSK_SKIP_PLANTING_BEANS, CVAR_RANDOMIZER_SETTING("SkipPlantingBeans"));
|
||||
OPT_U8(RSK_BIG_POE_COUNT, {NumOpts(0, 10)}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("BigPoeTargetCount"), WIDGET_CVAR_SLIDER_INT, 10);
|
||||
OPT_CALLBACK(RSK_BIG_POE_COUNT, {
|
||||
@@ -1446,6 +1446,7 @@ void Settings::CreateOptions() {
|
||||
OPT_U8(RSK_STARTING_BOTTLE_4, {"Off", "Empty Bottle", "Bottle with Big Poe"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("StartingBottle4"), WIDGET_CVAR_COMBOBOX, 0);
|
||||
OPT_BOOL(RSK_STARTING_WEIRD_EGG, CVAR_RANDOMIZER_SETTING("StartingWeirdEgg"));
|
||||
OPT_BOOL(RSK_STARTING_ZELDAS_LETTER, CVAR_RANDOMIZER_SETTING("StartingZeldasLetter"));
|
||||
OPT_BOOL(RSK_STARTING_SCARECROWS_SONG, CVAR_RANDOMIZER_SETTING("StartingScarecrowsSong"));
|
||||
OPT_BOOL(RSK_STARTING_CLAIM_CHECK, CVAR_RANDOMIZER_SETTING("StartingClaimCheck"));
|
||||
OPT_BOOL(RSK_STARTING_GERUDO_CARD, CVAR_RANDOMIZER_SETTING("StartingGerudoCard"));
|
||||
OPT_BOOL(RSK_STARTING_KEATON_MASK, CVAR_RANDOMIZER_SETTING("StartingKeatonMask"));
|
||||
@@ -1886,7 +1887,6 @@ void Settings::CreateOptions() {
|
||||
&mOptions[RSK_EARLY_GRANNYS_SHOP],
|
||||
&mOptions[RSK_SKIP_PLANTING_BEANS],
|
||||
&mOptions[RSK_SKIP_EPONA_RACE],
|
||||
&mOptions[RSK_SKIP_SCARECROWS_SONG],
|
||||
},
|
||||
WidgetContainerType::SECTION);
|
||||
mOptionGroups[RSG_MENU_SECTION_WINCON] = OptionGroup::SubGroup("Win Condition",
|
||||
@@ -2022,24 +2022,43 @@ void Settings::CreateOptions() {
|
||||
mOptionGroups[RSG_MENU_SECTION_BASIC_SHUFFLES] =
|
||||
OptionGroup::SubGroup("Shuffle Items",
|
||||
{
|
||||
&mOptions[RSK_SHUFFLE_SONGS], &mOptions[RSK_SHUFFLE_TOKENS],
|
||||
&mOptions[RSK_SHUFFLE_KOKIRI_SWORD], &mOptions[RSK_SHUFFLE_MASTER_SWORD],
|
||||
&mOptions[RSK_SHUFFLE_OCARINA], &mOptions[RSK_SHUFFLE_WEIRD_EGG],
|
||||
&mOptions[RSK_SHUFFLE_ZELDAS_LETTER], &mOptions[RSK_SHUFFLE_GERUDO_MEMBERSHIP_CARD],
|
||||
&mOptions[RSK_SHUFFLE_MASKS], &mOptions[RSK_FISHSANITY],
|
||||
&mOptions[RSK_FISHSANITY_POND_COUNT], &mOptions[RSK_FISHSANITY_AGE_SPLIT],
|
||||
&mOptions[RSK_SHUFFLE_FREESTANDING], &mOptions[RSK_SHUFFLE_WONDER_ITEMS],
|
||||
&mOptions[RSK_SHUFFLE_SILVER], &mOptions[RSK_SHUFFLE_BEEHIVES],
|
||||
&mOptions[RSK_SHUFFLE_COWS], &mOptions[RSK_SHUFFLE_POTS],
|
||||
&mOptions[RSK_SHUFFLE_GRASS], &mOptions[RSK_SHUFFLE_CRATES],
|
||||
&mOptions[RSK_SHUFFLE_BOULDERS], &mOptions[RSK_SHUFFLE_ROCKS],
|
||||
&mOptions[RSK_SHUFFLE_TREES], &mOptions[RSK_SHUFFLE_BUSHES],
|
||||
&mOptions[RSK_SHUFFLE_ICICLES], &mOptions[RSK_SHUFFLE_RED_ICE],
|
||||
&mOptions[RSK_SHUFFLE_SIGNS], &mOptions[RSK_SHUFFLE_FROG_SONG_RUPEES],
|
||||
&mOptions[RSK_SHUFFLE_ADULT_TRADE], &mOptions[RSK_SHUFFLE_CHEST_MINIGAME],
|
||||
&mOptions[RSK_SHUFFLE_100_GS_REWARD], &mOptions[RSK_SHUFFLE_FOUNTAIN_FAIRIES],
|
||||
&mOptions[RSK_SHUFFLE_STONE_FAIRIES], &mOptions[RSK_SHUFFLE_BEAN_FAIRIES],
|
||||
&mOptions[RSK_SHUFFLE_SONG_FAIRIES], &mOptions[RSK_SHUFFLE_BUTTERFLY_FAIRIES],
|
||||
&mOptions[RSK_SHUFFLE_SONGS],
|
||||
&mOptions[RSK_SHUFFLE_TOKENS],
|
||||
&mOptions[RSK_SHUFFLE_KOKIRI_SWORD],
|
||||
&mOptions[RSK_SHUFFLE_MASTER_SWORD],
|
||||
&mOptions[RSK_SHUFFLE_OCARINA],
|
||||
&mOptions[RSK_SHUFFLE_WEIRD_EGG],
|
||||
&mOptions[RSK_SHUFFLE_ZELDAS_LETTER],
|
||||
&mOptions[RSK_SHUFFLE_SCARECROWS_SONG],
|
||||
&mOptions[RSK_SHUFFLE_GERUDO_MEMBERSHIP_CARD],
|
||||
&mOptions[RSK_SHUFFLE_MASKS],
|
||||
&mOptions[RSK_FISHSANITY],
|
||||
&mOptions[RSK_FISHSANITY_POND_COUNT],
|
||||
&mOptions[RSK_FISHSANITY_AGE_SPLIT],
|
||||
&mOptions[RSK_SHUFFLE_FREESTANDING],
|
||||
&mOptions[RSK_SHUFFLE_WONDER_ITEMS],
|
||||
&mOptions[RSK_SHUFFLE_SILVER],
|
||||
&mOptions[RSK_SHUFFLE_BEEHIVES],
|
||||
&mOptions[RSK_SHUFFLE_COWS],
|
||||
&mOptions[RSK_SHUFFLE_POTS],
|
||||
&mOptions[RSK_SHUFFLE_GRASS],
|
||||
&mOptions[RSK_SHUFFLE_CRATES],
|
||||
&mOptions[RSK_SHUFFLE_BOULDERS],
|
||||
&mOptions[RSK_SHUFFLE_ROCKS],
|
||||
&mOptions[RSK_SHUFFLE_TREES],
|
||||
&mOptions[RSK_SHUFFLE_BUSHES],
|
||||
&mOptions[RSK_SHUFFLE_ICICLES],
|
||||
&mOptions[RSK_SHUFFLE_RED_ICE],
|
||||
&mOptions[RSK_SHUFFLE_SIGNS],
|
||||
&mOptions[RSK_SHUFFLE_FROG_SONG_RUPEES],
|
||||
&mOptions[RSK_SHUFFLE_ADULT_TRADE],
|
||||
&mOptions[RSK_SHUFFLE_CHEST_MINIGAME],
|
||||
&mOptions[RSK_SHUFFLE_100_GS_REWARD],
|
||||
&mOptions[RSK_SHUFFLE_FOUNTAIN_FAIRIES],
|
||||
&mOptions[RSK_SHUFFLE_STONE_FAIRIES],
|
||||
&mOptions[RSK_SHUFFLE_BEAN_FAIRIES],
|
||||
&mOptions[RSK_SHUFFLE_SONG_FAIRIES],
|
||||
&mOptions[RSK_SHUFFLE_BUTTERFLY_FAIRIES],
|
||||
},
|
||||
WidgetContainerType::SECTION);
|
||||
mOptionGroups[RSG_MENU_COLUMN_BASIC_SHUFFLES] =
|
||||
@@ -2277,6 +2296,7 @@ void Settings::CreateOptions() {
|
||||
&mOptions[RSK_SHUFFLE_OPEN_CHEST],
|
||||
&mOptions[RSK_SHUFFLE_WEIRD_EGG],
|
||||
&mOptions[RSK_SHUFFLE_ZELDAS_LETTER],
|
||||
&mOptions[RSK_SHUFFLE_SCARECROWS_SONG],
|
||||
&mOptions[RSK_SHUFFLE_GERUDO_MEMBERSHIP_CARD],
|
||||
&mOptions[RSK_SHUFFLE_MASKS],
|
||||
&mOptions[RSK_SHUFFLE_MERCHANTS],
|
||||
@@ -2391,6 +2411,7 @@ void Settings::CreateOptions() {
|
||||
&mOptions[RSK_STARTING_REQUIEM_OF_SPIRIT],
|
||||
&mOptions[RSK_STARTING_NOCTURNE_OF_SHADOW],
|
||||
&mOptions[RSK_STARTING_PRELUDE_OF_LIGHT],
|
||||
&mOptions[RSK_STARTING_SCARECROWS_SONG],
|
||||
});
|
||||
mOptionGroups[RSG_STARTING_OTHER] = OptionGroup::SubGroup("Other", {
|
||||
&mOptions[RSK_STARTING_STICKS],
|
||||
@@ -2409,7 +2430,6 @@ void Settings::CreateOptions() {
|
||||
OptionGroupType::DEFAULT);
|
||||
mOptionGroups[RSG_TIMESAVERS] = OptionGroup("Timesaver Settings", {
|
||||
&mOptions[RSK_SKIP_EPONA_RACE],
|
||||
&mOptions[RSK_SKIP_SCARECROWS_SONG],
|
||||
&mOptions[RSK_SKIP_PLANTING_BEANS],
|
||||
&mOptions[RSK_BIG_POE_COUNT],
|
||||
});
|
||||
@@ -3159,6 +3179,7 @@ void Settings::RandomizeAllSettings() {
|
||||
case RSK_STARTING_BOTTLE_4:
|
||||
case RSK_STARTING_WEIRD_EGG:
|
||||
case RSK_STARTING_ZELDAS_LETTER:
|
||||
case RSK_STARTING_SCARECROWS_SONG:
|
||||
case RSK_STARTING_CLAIM_CHECK:
|
||||
case RSK_STARTING_GERUDO_CARD:
|
||||
case RSK_STARTING_BIGGORON_SWORD:
|
||||
|
||||
@@ -250,6 +250,12 @@ void RegisterImGuiItemIcons() {
|
||||
gui->LoadGuiTexture("ITEM_RUPEE_SILVER", gRupeeCounterIconTex, "", silver);
|
||||
gui->LoadGuiTexture("ITEM_RUPEE_SILVER_Faded", gRupeeCounterIconTex, "", silverFaded);
|
||||
|
||||
ImVec4 scarecrow = ImVec4(40.0f / 255.0f, 160.0f / 255.0f, 40.0f / 255.0f, 1.0f);
|
||||
ImVec4 scarecrowFaded = scarecrow;
|
||||
scarecrowFaded.w = 0.3f;
|
||||
gui->LoadGuiTexture("RG_SCARECROWS_SONG", gSongNoteTex, "", scarecrow);
|
||||
gui->LoadGuiTexture("RG_SCARECROWS_SONG_Faded", gSongNoteTex, "", scarecrowFaded);
|
||||
|
||||
for (const auto& entry : questMapping) {
|
||||
gui->LoadGuiTexture(entry.second.name, entry.second.texturePath, "", ImVec4(1, 1, 1, 1));
|
||||
gui->LoadGuiTexture(entry.second.nameFaded, entry.second.texturePath, "", ImVec4(1, 1, 1, 0.3f));
|
||||
|
||||
@@ -601,13 +601,15 @@ void SohMenu::AddMenuEnhancements() {
|
||||
.CVar(CVAR_ENHANCEMENT("InstantScarecrow"))
|
||||
.PreFunc([](WidgetInfo& info) {
|
||||
info.options->disabled =
|
||||
IS_RANDO && OTRGlobals::Instance->gRandoContext->GetOption(RSK_SKIP_SCARECROWS_SONG);
|
||||
info.options->disabledTooltip = "This setting is forcefully enabled because a randomized save "
|
||||
"file with the option \"Skip Scarecrow's Song\" is currently loaded.";
|
||||
IS_RANDO && (OTRGlobals::Instance->gRandoContext->GetOption(RSK_STARTING_SCARECROWS_SONG) ||
|
||||
OTRGlobals::Instance->gRandoContext->GetOption(RSK_SHUFFLE_SCARECROWS_SONG));
|
||||
info.options->disabledTooltip =
|
||||
"This setting is controlled by the randomizer because a randomized save file with the option "
|
||||
"\"Start with Scarecrow's Song\" or \"Shuffle Scarecrow's Song\" is currently loaded.";
|
||||
})
|
||||
.Options(CheckboxOptions().Tooltip(
|
||||
"Pierre appears when an Ocarina is pulled out. Requires learning the Scarecrow's Song first.\n"
|
||||
"Without the randomizer option \"Skip Scarecrow's Song\" enabled for a seed, this still requires you "
|
||||
"Without the randomizer option \"Start with Scarecrow's Song\" enabled for a seed, this still requires you "
|
||||
"to teach the scarecrow the song as both ages before summoning."));
|
||||
AddWidget(path, "Faster Rupee Accumulator", WIDGET_CVAR_CHECKBOX)
|
||||
.CVar(CVAR_ENHANCEMENT("FasterRupeeAccumulator"))
|
||||
|
||||
@@ -93,16 +93,15 @@ static void StartingItemTiered(RandomizerSettingKey rsk, const std::vector<uint3
|
||||
}
|
||||
|
||||
// Toggleable 32x48 song icon, mirroring the songMapping loop in DrawQuestStatusTab.
|
||||
static void StartingSongToggle(RandomizerSettingKey rsk, QuestItem song) {
|
||||
static void StartingSongToggle(RandomizerSettingKey rsk, const std::string& name, const std::string& nameFaded) {
|
||||
Rando::Option& option = Rando::Settings::GetInstance()->GetOption(rsk);
|
||||
const char* cvar = option.GetCVarName().c_str();
|
||||
const SongMapEntry& entry = songMapping[song];
|
||||
bool on = CVarGetInteger(cvar, 0) != 0;
|
||||
|
||||
ImGui::PushID(static_cast<int32_t>(rsk));
|
||||
PushStyleButton(Colors::DarkGray);
|
||||
if (ImGui::ImageButton(entry.name.c_str(), GetFast3dGui()->GetTextureByName(on ? entry.name : entry.nameFaded),
|
||||
kSongSize, ImVec2(0, 0), ImVec2(1, 1))) {
|
||||
if (ImGui::ImageButton(name.c_str(), GetFast3dGui()->GetTextureByName(on ? name : nameFaded), kSongSize,
|
||||
ImVec2(0, 0), ImVec2(1, 1))) {
|
||||
CVarSetInteger(cvar, on ? 0 : 1);
|
||||
SaveStartingItemCVars();
|
||||
}
|
||||
@@ -111,6 +110,11 @@ static void StartingSongToggle(RandomizerSettingKey rsk, QuestItem song) {
|
||||
ImGui::PopID();
|
||||
}
|
||||
|
||||
static void StartingSongToggle(RandomizerSettingKey rsk, QuestItem song) {
|
||||
const SongMapEntry& entry = songMapping[song];
|
||||
StartingSongToggle(rsk, entry.name, entry.nameFaded);
|
||||
}
|
||||
|
||||
// Item icon followed by a count slider, like the ammo rows in DrawInventoryTab. The slider
|
||||
// mirrors the Option's own semantics: the CVar stores the option index and the displayed
|
||||
// number comes from the option text (matching how WIDGET_CVAR_SLIDER_INT renders these).
|
||||
@@ -352,6 +356,8 @@ void DrawStartingItemsMenu(WidgetInfo& info) {
|
||||
StartingSongToggle(RSK_STARTING_NOCTURNE_OF_SHADOW, QUEST_SONG_NOCTURNE);
|
||||
ImGui::SameLine();
|
||||
StartingSongToggle(RSK_STARTING_PRELUDE_OF_LIGHT, QUEST_SONG_PRELUDE);
|
||||
ImGui::SameLine();
|
||||
StartingSongToggle(RSK_STARTING_SCARECROWS_SONG, "RG_SCARECROWS_SONG", "RG_SCARECROWS_SONG_Faded");
|
||||
|
||||
ImGui::SeparatorText("Other");
|
||||
StartingItemCombobox(RSK_LINKS_POCKET);
|
||||
|
||||
@@ -1459,6 +1459,7 @@ static const Migration version7Migrations[] = {
|
||||
{ "gRandoEnhancements.CustomKeyModels", nullptr },
|
||||
{ "gRandoSettings.LogicRules", "gRandoSettings.NoLogic" },
|
||||
{ "gRandoSettings.AllLocationsReachable", "gRandoSettings.AllChecksReachable" },
|
||||
{ "gRandoSettings.SkipScarecrowsSong", "gRandoSettings.StartingScarecrowsSong" },
|
||||
{ nullptr, nullptr },
|
||||
};
|
||||
|
||||
|
||||
@@ -2090,7 +2090,8 @@ void AudioOcarina_PlaybackSong(void) {
|
||||
}
|
||||
return;
|
||||
} else {
|
||||
sPlaybackNoteTimer -= nextNoteTimerStep;
|
||||
// SoH [Fix] several audio tasks can run between updates, don't wrap below zero
|
||||
sPlaybackNoteTimer -= MIN(nextNoteTimerStep, sPlaybackNoteTimer);
|
||||
}
|
||||
|
||||
// Update volume
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
#include "z_en_kakasi3.h"
|
||||
#include "vt.h"
|
||||
#include "objects/object_ka/object_ka.h"
|
||||
#include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h"
|
||||
|
||||
#define FLAGS (ACTOR_FLAG_ATTENTION_ENABLED | ACTOR_FLAG_FRIENDLY | ACTOR_FLAG_UPDATE_DURING_OCARINA)
|
||||
|
||||
@@ -387,7 +388,8 @@ void func_80A91A90(EnKakasi3* this, PlayState* play) {
|
||||
|
||||
if (this->dialogState == Message_GetState(&play->msgCtx) && Message_ShouldAdvance(play)) {
|
||||
if (this->unk_195) {
|
||||
if (!Flags_GetEventChkInf(EVENTCHKINF_PLAYED_SONG_FOR_SCARECROW_AS_ADULT)) {
|
||||
if (GameInteractor_Should(VB_GIVE_ITEM_FROM_SCARECROW,
|
||||
!Flags_GetEventChkInf(EVENTCHKINF_PLAYED_SONG_FOR_SCARECROW_AS_ADULT))) {
|
||||
Flags_SetEventChkInf(EVENTCHKINF_PLAYED_SONG_FOR_SCARECROW_AS_ADULT);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user