Fire Temple Goron Shuffle (#7377)

This commit is contained in:
Chris
2026-10-12 19:17:09 -04:00
committed by GitHub
parent 18225f0e6e
commit 96be197fd2
20 changed files with 359 additions and 1 deletions
+8
View File
@@ -548,6 +548,14 @@
"Red Ice will have a particle effect inside it when it holds a randomized item"
]
},
"shuffle_fire_gorons": {
"name": "Shuffle Fire Temple Gorons",
"description": [
"The Gorons imprisoned in the Fire Temple will give a randomized item ",
"when talked to after being freed.\n",
"Gorons will have a particle effect above them when they hold a randomized item."
]
},
"shuffle_signs": {
"name": "Shuffle Signs",
"description": [
@@ -598,6 +598,14 @@ typedef enum {
// - None
VB_DEKU_STICK_BURN_OUT,
// #### `result`
// ```c
// Flags_GetSwitch(play, (this->actor.params & 0xFC00) >> 0xA)
// ```
// #### `args`
// - `*EnGo2`
VB_DESPAWN_FREED_FIRE_GORON,
// #### `result`
// ```c
// Flags_GetItemGetInf(ITEMGETINF_30)
@@ -1165,6 +1173,14 @@ typedef enum {
// - `*Actor` (EnDivingGame - &this->actor)
VB_GIVE_ITEM_FROM_DIVING_MINIGAME,
// #### `result`
// ```c
// true
// ```
// #### `args`
// - `*EnGo2`
VB_GIVE_ITEM_FROM_FIRE_GORON,
// #### `result`
// ```c
// true
@@ -971,6 +971,58 @@ void StaticData::HintTable_Init_Exclude_Dungeon() {
/*german*/ "Man erzählt sich, daß das #Anrufen der Sonne, hinter dem Thron eines Ritters in einem Vulkan#, #[[1]]# enthülle.",
/*french*/ "Selon moi, #appeler le soleil derrière le trône d’un chevalier dans un volcan# révèle #[[1]]#.", {QM_RED, QM_GREEN}));
hintTextTable[RHT_FIRE_TEMPLE_NEAR_BOSS_GORON] = HintText(CustomMessage("They say that #freeing a Goron near a dragon# gives #[[1]]#.",
/*german*/ "Man erzählt sich, daß das #Befreien eines Goronen nahe eines Drachens# #[[1]]# gäbe.",
/*french*/ "Selon moi, #libérer le Goron près d'un dragon# donne #[[1]]#.", {QM_RED, QM_GREEN}));
hintTextTable[RHT_FIRE_TEMPLE_BOSS_KEY_GORON] = HintText(CustomMessage("They say that #freeing a Goron beyond a totem# gives #[[1]]#.",
/*german*/ "Man erzählt sich, daß das #Befreien eines Goronen jenseits eines Totems# #[[1]]# gäbe.",
/*french*/ "Selon moi, #libérer le Goron derrière un totem# donne #[[1]]#.", {QM_RED, QM_GREEN}));
hintTextTable[RHT_FIRE_TEMPLE_BIG_LAVA_ROOM_LOWER_OPEN_DOOR_GORON] = HintText(CustomMessage("They say that #freeing a Goron trapped near lava# gives #[[1]]#.",
/*german*/ "Man erzählt sich, daß das #Befreien eines nahe der Lava gefangenen Goronen# #[[1]]# gäbe.",
/*french*/ "Selon moi, #libérer le Goron emprisonné près de la lave# donne #[[1]]#.", {QM_RED, QM_GREEN}));
hintTextTable[RHT_FIRE_TEMPLE_BIG_LAVA_ROOM_BLOCKED_DOOR_GORON] = HintText(CustomMessage("They say that #freeing a Goron walled in over a lava pit# gives #[[1]]#.",
/*german*/ "Man erzählt sich, daß das #Befreien eines eingemauerten Goronen über einem Lavastrom# #[[1]]# gäbe.",
/*french*/ "Selon moi, #libérer le Goron emmuré dans un lac de lave# donne #[[1]]#.", {QM_RED, QM_GREEN}));
hintTextTable[RHT_FIRE_TEMPLE_BOULDER_MAZE_LOWER_GORON] = HintText(CustomMessage("They say that #freeing a Goron at the end of a maze# gives #[[1]]#.",
/*german*/ "Man erzählt sich, daß das #Befreien eines Goronen am Ende eines Labyrinths# #[[1]]# gäbe.",
/*french*/ "Selon moi, #libérer le Goron dans le labyrinthe# donne #[[1]]#.", {QM_RED, QM_GREEN}));
hintTextTable[RHT_FIRE_TEMPLE_BOULDER_MAZE_SHORTCUT_GORON] = HintText(CustomMessage("They say that #freeing a Goron on a blocked path# gives #[[1]]#.",
/*german*/ "Man erzählt sich, daß das #Befreien eines Goronen auf einem blockierten Pfad# #[[1]]# gäbe.",
/*french*/ "Selon moi, #libérer le Goron sous un sol fragile# donne #[[1]]#.", {QM_RED, QM_GREEN}));
hintTextTable[RHT_FIRE_TEMPLE_BOULDER_MAZE_SIDE_ROOM_GORON] = HintText(CustomMessage("They say that #freeing a Goron hidden near a maze# gives #[[1]]#.",
/*german*/ "Man erzählt sich, daß das #Befreien eines nahe eines Labyrinths versteckten Goronen# #[[1]]# gäbe.",
/*french*/ "Selon moi, #libérer le Goron caché près du labyrinthe# donne #[[1]]#.", {QM_RED, QM_GREEN}));
hintTextTable[RHT_FIRE_TEMPLE_BOULDER_MAZE_UPPER_GORON] = HintText(CustomMessage("They say that #freeing a Goron above a maze# gives #[[1]]#.",
/*german*/ "Man erzählt sich, daß das #Befreien eines Goronen oberhalb eines Labyrinths# #[[1]]# gäbe.",
/*french*/ "Selon moi, #libérer le Goron au dessus du labyrinthe# donne #[[1]]#.", {QM_RED, QM_GREEN}));
hintTextTable[RHT_FIRE_TEMPLE_HIGHEST_GORON] = HintText(CustomMessage("They say that #freeing a Goron atop the Fire Temple# gives #[[1]]#.",
/*german*/ "Man erzählt sich, daß das #Befreien eines Goronen an der Spitze des Feuertempels# #[[1]]# gäbe.",
/*french*/ "Selon moi, #libérer le Goron au sommet du Temple du Feu# donne #[[1]]#.", {QM_RED, QM_GREEN}));
hintTextTable[RHT_FIRE_TEMPLE_MQ_MAP_GORON] = HintText(CustomMessage("They say that #freeing a Goron beside a map# gives #[[1]]#.",
/*german*/ "Man erzählt sich, daß das #Befreien eines Goronen neben einer Karte# #[[1]]# gäbe.",
/*french*/ "Selon moi, #libérer le Goron près d'une carte# donne #[[1]]#.", {QM_RED, QM_GREEN}));
hintTextTable[RHT_FIRE_TEMPLE_MQ_BIG_LAVA_ROOM_OPEN_DOOR_GORON] = HintText(CustomMessage("They say that #freeing a Goron in a cage above lava# gives #[[1]]#.",
/*german*/ "Man erzählt sich, daß das #Befreien eines Goronen in einem Käfig über der Lava# #[[1]]# gäbe.",
/*french*/ "Selon moi, #libérer le Goron en cage au dessus de la lave# donne #[[1]]#.", {QM_RED, QM_GREEN}));
hintTextTable[RHT_FIRE_TEMPLE_MQ_BIG_LAVA_ROOM_BLOCKED_DOOR_GORON] = HintText(CustomMessage("They say that #freeing a Goron behind a blocked lava door# gives #[[1]]#.",
/*german*/ "Man erzählt sich, daß das #Befreien eines Goronen hinter einer blockierten Lavatür# #[[1]]# gäbe.",
/*french*/ "Selon moi, #libérer le Goron derrière la porte bloquée du lac de lave# donne #[[1]]#.", {QM_RED, QM_GREEN}));
hintTextTable[RHT_FIRE_TEMPLE_MQ_LIZALFOS_MAZE_SIDE_ROOM_GORON] = HintText(CustomMessage("They say that #freeing a Goron hidden beside a maze# gives #[[1]]#.",
/*german*/ "Man erzählt sich, daß das #Befreien eines neben einem Labyrinth versteckten Goronen# #[[1]]# gäbe.",
/*french*/ "Selon moi, #libérer le Goron caché à côté du labyrinthe# donne #[[1]]#.", {QM_RED, QM_GREEN}));
hintTextTable[RHT_CRATE_FIRE_TEMPLE] = HintText(CustomMessage("They say that a #crate in the Fire Temple# contains #[[1]]#.",
/*german*/ "Man erzählt sich, daß eine #Kiste im Feuertempel# #[[1]]# enthielte.",
/*french*/ "Selon moi, une #caisse dans le Temple du Feu# contient #[[1]]#.", {QM_RED, QM_GREEN}));
@@ -85,6 +85,22 @@ static CustomMessage FireTempleGoronMessages[] = {
"Wat weiß'n ich, wieso ich hier&eingepfercht wurd. Ich mach&doch nur %g\"Pull&Requests\"%w.",
"Je ne sais pas comment on m'a jeté&ici. Il faut croire que je dors comme&une pierre.",
},
{
"Hey! Somebody finally stopped!^All the others ran right past me.&Something about %r\"wasting "
"time\"%w...^I'm telling everyone back home!&...They won't believe me.",
"Hey! Endlich bleibt mal&jemand stehen!^Alle anderen sind einfach an mir&vorbeigerannt. Irgendwas "
"von&%r\"Zeitverschwendung\"%w...^Das erzähle ich allen zu Hause!&...Die werden mir nie glauben.",
"Hé! Enfin quelqu'un&qui s'arrête!^Tous les autres m'ont dépassé en&courant. Ils parlaient de&%r\"perte "
"de temps\"%w...^Je vais le raconter à tout le&monde! ...Personne ne me croira.",
},
{
"You came all this way just to&talk to me?^Nobody does that unless I've got&%rsomething they "
"want%w...^...Hey, why are you looking&at my pockets?",
"Du bist den ganzen Weg gekommen,&nur um mit mir zu reden?^Das macht keiner, außer ich habe&%retwas, das er "
"haben will%w...^...Hey, warum starrst Du so&auf meine Taschen?",
"Tu es venu jusqu'ici juste pour&me parler?^Personne ne fait ça, sauf si j'ai&%rquelque chose qu'il "
"veut%w...^...Hé, pourquoi tu regardes&mes poches comme ça?",
},
};
void BuildGoronMessage(uint16_t* textId, bool* loadFromMessageTable) {
@@ -3091,6 +3091,19 @@ std::map<RandomizerCheck, RandomizerInf> rcToRandomizerInf = {
RAND_INF_GANONS_CASTLE_MQ_WATER_TRIAL_SECOND_DOOR_RED_ICE_4 },
{ RC_GANONS_CASTLE_MQ_WATER_TRIAL_SECOND_DOOR_RED_ICE_5,
RAND_INF_GANONS_CASTLE_MQ_WATER_TRIAL_SECOND_DOOR_RED_ICE_5 },
{ RC_FIRE_TEMPLE_NEAR_BOSS_GORON, RAND_INF_FIRE_TEMPLE_NEAR_BOSS_GORON },
{ RC_FIRE_TEMPLE_BOSS_KEY_GORON, RAND_INF_FIRE_TEMPLE_BOSS_KEY_GORON },
{ RC_FIRE_TEMPLE_BIG_LAVA_ROOM_LOWER_OPEN_DOOR_GORON, RAND_INF_FIRE_TEMPLE_BIG_LAVA_ROOM_LOWER_OPEN_DOOR_GORON },
{ RC_FIRE_TEMPLE_BIG_LAVA_ROOM_BLOCKED_DOOR_GORON, RAND_INF_FIRE_TEMPLE_BIG_LAVA_ROOM_BLOCKED_DOOR_GORON },
{ RC_FIRE_TEMPLE_BOULDER_MAZE_LOWER_GORON, RAND_INF_FIRE_TEMPLE_BOULDER_MAZE_LOWER_GORON },
{ RC_FIRE_TEMPLE_BOULDER_MAZE_SHORTCUT_GORON, RAND_INF_FIRE_TEMPLE_BOULDER_MAZE_SHORTCUT_GORON },
{ RC_FIRE_TEMPLE_BOULDER_MAZE_SIDE_ROOM_GORON, RAND_INF_FIRE_TEMPLE_BOULDER_MAZE_SIDE_ROOM_GORON },
{ RC_FIRE_TEMPLE_BOULDER_MAZE_UPPER_GORON, RAND_INF_FIRE_TEMPLE_BOULDER_MAZE_UPPER_GORON },
{ RC_FIRE_TEMPLE_HIGHEST_GORON, RAND_INF_FIRE_TEMPLE_HIGHEST_GORON },
{ RC_FIRE_TEMPLE_MQ_MAP_GORON, RAND_INF_FIRE_TEMPLE_MQ_MAP_GORON },
{ RC_FIRE_TEMPLE_MQ_BIG_LAVA_ROOM_OPEN_DOOR_GORON, RAND_INF_FIRE_TEMPLE_MQ_BIG_LAVA_ROOM_OPEN_DOOR_GORON },
{ RC_FIRE_TEMPLE_MQ_BIG_LAVA_ROOM_BLOCKED_DOOR_GORON, RAND_INF_FIRE_TEMPLE_MQ_BIG_LAVA_ROOM_BLOCKED_DOOR_GORON },
{ RC_FIRE_TEMPLE_MQ_LIZALFOS_MAZE_SIDE_ROOM_GORON, RAND_INF_FIRE_TEMPLE_MQ_LIZALFOS_MAZE_SIDE_ROOM_GORON },
{ RC_SHADOW_N_UNDER_BLADE_SILVER, RAND_INF_RC_SHADOW_N_UNDER_BLADE_SILVER },
{ RC_SHADOW_TALL_BLOCK_BLADE_SILVER, RAND_INF_RC_SHADOW_TALL_BLOCK_BLADE_SILVER },
{ RC_SHADOW_N_NOOK_BLADE_SILVER, RAND_INF_RC_SHADOW_N_NOOK_BLADE_SILVER },
@@ -208,6 +208,7 @@ void Context::GenerateLocationPool() {
(location.GetRCType() == RCTYPE_BUSH && !mOptions[RSK_SHUFFLE_BUSHES]) ||
(location.GetRCType() == RCTYPE_ICICLE && !mOptions[RSK_SHUFFLE_ICICLES]) ||
(location.GetRCType() == RCTYPE_RED_ICE && !mOptions[RSK_SHUFFLE_RED_ICE]) ||
(location.GetRCType() == RCTYPE_FIRE_GORON && !mOptions[RSK_SHUFFLE_FIRE_GORONS]) ||
(location.GetRCType() == RCTYPE_SIGN && mOptions[RSK_SHUFFLE_SIGNS].Is(RO_SHUFFLE_SIGNS_OFF)) ||
(location.GetRCType() == RCTYPE_WONDER_ITEM &&
mOptions[RSK_SHUFFLE_WONDER_ITEMS].Is(RO_SHUFFLE_WONDER_ITEMS_OFF)) ||
@@ -0,0 +1,173 @@
#include <spdlog/spdlog.h>
#include "soh/OTRGlobals.h"
#include "soh/ResourceManagerHelpers.h"
#include "soh/Enhancements/game-interactor/GameInteractor.h"
#include "soh/ObjectExtension/ObjectExtension.h"
#include "soh/Enhancements/randomizer/randomizer.h"
#include "soh/Enhancements/randomizer/RCToRandInf.h"
#include "soh/ShipInit.hpp"
#include "static_data.h"
#include "item_category_adj.h"
#include "particle_cmc.h"
#include <libultraship/bridge/consolevariablebridge.h>
extern "C" {
#include "macros.h"
#include "functions.h"
#include "overlays/actors/ovl_En_Go2/z_en_go2.h"
extern PlayState* gPlayState;
}
static s32 FireGoron_GetSwitchFlag(Actor* actor) {
return (actor->params & 0xFC00) >> 0xA;
}
static bool FireGoron_IsFireGoron(Actor* actor) {
return (actor->params & 0x1F) == GORON_FIRE_GENERIC;
}
static CheckIdentity IdentifyFireGoron(Actor* actor) {
CheckIdentity goronIdentity;
goronIdentity.randomizerInf = RAND_INF_MAX;
goronIdentity.randomizerCheck = RC_UNKNOWN_CHECK;
Rando::Location* location = OTRGlobals::Instance->gRandomizer->GetCheckObjectFromActor(
ACTOR_EN_GO2, gPlayState->sceneNum, FireGoron_GetSwitchFlag(actor));
IdentifyCheck(&goronIdentity, location);
return goronIdentity;
}
static bool FireGoron_IdentityHoldsItem(const CheckIdentity& goronIdentity) {
return goronIdentity.randomizerCheck != RC_UNKNOWN_CHECK && !Flags_GetRandomizerInf(goronIdentity.randomizerInf);
}
static bool FireGoron_HoldsItem(Actor* actor) {
const auto goronIdentity = ObjectExtension::GetInstance().Get<CheckIdentity>(actor);
return goronIdentity != nullptr && FireGoron_IdentityHoldsItem(*goronIdentity);
}
static void FireGoron_SpawnSparkles(Actor* actor, const CheckIdentity& goronIdentity) {
if (actor->xzDistToPlayer > 1000.0f) {
return;
}
bool cmc = CVarGetInteger(CVAR_ENHANCEMENT("ChestSizeAndTextureMatchContents"), 0);
int requiresStoneAgony = CVarGetInteger(CVAR_ENHANCEMENT("ChestSizeDependsStoneOfAgony"), 0);
int isNotCMC = !cmc || (requiresStoneAgony && !CHECK_QUEST_ITEM(QUEST_STONE_OF_AGONY));
GetItemEntry goronItem =
Rando::Context::GetInstance()->GetFinalGIEntry(goronIdentity.randomizerCheck, true, GI_NONE);
GetItemCategory getItemCategory = isNotCMC ? ITEM_CATEGORY_MAJOR : Randomizer_AdjustItemCategory(goronItem);
Color_RGBA8 primColor = Randomizer_GetParticleCMCColor(getItemCategory, COLOR_PRIMARY);
Color_RGBA8 secColor = Randomizer_GetParticleCMCColor(getItemCategory, COLOR_SECONDARY);
Color_RGBA8 envColor = Randomizer_GetParticleCMCColor(getItemCategory, COLOR_FLARE);
Vec3f pos;
Vec3f velocity = { 0.0f, -0.05f, 0.0f };
Vec3f accel = { 0.0f, -0.025f, 0.0f };
pos.x = Rand_CenteredFloat(10.0f) + actor->world.pos.x;
pos.y = (Rand_ZeroOne() * 10.0f) + actor->world.pos.y + 60.0f;
pos.z = Rand_CenteredFloat(10.0f) + actor->world.pos.z;
EffectSsKiraKira_SpawnFocused(gPlayState, &pos, &velocity, &accel, &secColor, &envColor, 2000, 100);
EffectSsKiraKira_SpawnFocused(gPlayState, &pos, &velocity, &accel, &primColor, &envColor, 2000, 100);
}
static void FireGoron_RandomizerUpdate(void* actorRef) {
Actor* actor = static_cast<Actor*>(actorRef);
if (FireGoron_HoldsItem(actor)) {
const auto& goronIdentity = *ObjectExtension::GetInstance().Get<CheckIdentity>(actor);
if (!Rando::Context::GetInstance()->GetItemLocation(goronIdentity.randomizerCheck)->IsExcluded()) {
FireGoron_SpawnSparkles(actor, goronIdentity);
}
}
}
static void FireGoron_LogUnrecognized(Actor* actor) {
SPDLOG_WARN("Unrecognized Fire Temple goron: scene=0x{:02X} room={} quest={} params=0x{:04X} type={} "
"switchFlag={} pos=({},{},{}) rotY=0x{:04X}",
gPlayState->sceneNum, actor->room,
ResourceMgr_IsSceneMasterQuest(gPlayState->sceneNum) ? "MQ" : "Vanilla",
static_cast<u16>(actor->params), actor->params & 0x1F, FireGoron_GetSwitchFlag(actor),
static_cast<s32>(actor->world.pos.x), static_cast<s32>(actor->world.pos.y),
static_cast<s32>(actor->world.pos.z), static_cast<u16>(actor->shape.rot.y));
}
static void FireGoron_RandomizerInit(void* actorRef) {
Actor* actor = static_cast<Actor*>(actorRef);
if (!FireGoron_IsFireGoron(actor)) {
return;
}
auto goronIdentity = IdentifyFireGoron(actor);
if (goronIdentity.randomizerCheck == RC_UNKNOWN_CHECK) {
return;
}
ObjectExtension::GetInstance().Set<CheckIdentity>(actor, std::move(goronIdentity));
if (FireGoron_HoldsItem(actor) && Flags_GetSwitch(gPlayState, FireGoron_GetSwitchFlag(actor))) {
EnGo2_GetItemAnimation(reinterpret_cast<EnGo2*>(actor), gPlayState);
}
}
void RegisterShuffleFireGorons() {
bool shouldRegister = IS_RANDO && RAND_GET_OPTION(RSK_SHUFFLE_FIRE_GORONS);
COND_ID_HOOK(OnActorInit, ACTOR_EN_GO2, shouldRegister, FireGoron_RandomizerInit);
COND_ID_HOOK(OnActorUpdate, ACTOR_EN_GO2, shouldRegister, FireGoron_RandomizerUpdate);
COND_VB_SHOULD(VB_DESPAWN_FREED_FIRE_GORON, shouldRegister, {
EnGo2* goron = va_arg(args, EnGo2*);
auto goronIdentity = IdentifyFireGoron(&goron->actor);
if (*should && FireGoron_IdentityHoldsItem(goronIdentity) &&
!Rando::Context::GetInstance()->GetItemLocation(goronIdentity.randomizerCheck)->IsExcluded()) {
*should = false;
}
});
COND_VB_SHOULD(VB_GIVE_ITEM_FROM_FIRE_GORON, shouldRegister, {
EnGo2* goron = va_arg(args, EnGo2*);
if (FireGoron_HoldsItem(&goron->actor)) {
Flags_SetRandomizerInf(ObjectExtension::GetInstance().Get<CheckIdentity>(&goron->actor)->randomizerInf);
} else if (ObjectExtension::GetInstance().Get<CheckIdentity>(&goron->actor) == nullptr) {
FireGoron_LogUnrecognized(&goron->actor);
}
});
}
static RegisterShipInitFunc initFunc_ShuffleFireGorons(RegisterShuffleFireGorons, { "IS_RANDO" });
void Rando::StaticData::RegisterFireGoronLocations() {
static bool registered = false;
if (registered)
return;
registered = true;
// clang-format off
// Randomizer Check Randomizer Check Quest Area Scene ID Params Short Name Hint Text Key Spoiler Collection Check
locationTable[RC_FIRE_TEMPLE_NEAR_BOSS_GORON] = Location::FireGoron(RC_FIRE_TEMPLE_NEAR_BOSS_GORON, RCQUEST_VANILLA, RCAREA_FIRE_TEMPLE, SCENE_FIRE_TEMPLE, 8, "Near Boss Goron", RHT_FIRE_TEMPLE_NEAR_BOSS_GORON, SpoilerCollectionCheck::RandomizerInf(RAND_INF_FIRE_TEMPLE_NEAR_BOSS_GORON));
locationTable[RC_FIRE_TEMPLE_BOSS_KEY_GORON] = Location::FireGoron(RC_FIRE_TEMPLE_BOSS_KEY_GORON, RCQUEST_VANILLA, RCAREA_FIRE_TEMPLE, SCENE_FIRE_TEMPLE, 9, "Boss Key Goron", RHT_FIRE_TEMPLE_BOSS_KEY_GORON, SpoilerCollectionCheck::RandomizerInf(RAND_INF_FIRE_TEMPLE_BOSS_KEY_GORON));
locationTable[RC_FIRE_TEMPLE_BIG_LAVA_ROOM_LOWER_OPEN_DOOR_GORON] = Location::FireGoron(RC_FIRE_TEMPLE_BIG_LAVA_ROOM_LOWER_OPEN_DOOR_GORON, RCQUEST_VANILLA, RCAREA_FIRE_TEMPLE, SCENE_FIRE_TEMPLE, 1, "Big Lava Room Lower Open Door Goron", RHT_FIRE_TEMPLE_BIG_LAVA_ROOM_LOWER_OPEN_DOOR_GORON, SpoilerCollectionCheck::RandomizerInf(RAND_INF_FIRE_TEMPLE_BIG_LAVA_ROOM_LOWER_OPEN_DOOR_GORON));
locationTable[RC_FIRE_TEMPLE_BIG_LAVA_ROOM_BLOCKED_DOOR_GORON] = Location::FireGoron(RC_FIRE_TEMPLE_BIG_LAVA_ROOM_BLOCKED_DOOR_GORON, RCQUEST_VANILLA, RCAREA_FIRE_TEMPLE, SCENE_FIRE_TEMPLE, 2, "Big Lava Room Blocked Door Goron", RHT_FIRE_TEMPLE_BIG_LAVA_ROOM_BLOCKED_DOOR_GORON, SpoilerCollectionCheck::RandomizerInf(RAND_INF_FIRE_TEMPLE_BIG_LAVA_ROOM_BLOCKED_DOOR_GORON));
locationTable[RC_FIRE_TEMPLE_BOULDER_MAZE_LOWER_GORON] = Location::FireGoron(RC_FIRE_TEMPLE_BOULDER_MAZE_LOWER_GORON, RCQUEST_VANILLA, RCAREA_FIRE_TEMPLE, SCENE_FIRE_TEMPLE, 3, "Boulder Maze Lower Goron", RHT_FIRE_TEMPLE_BOULDER_MAZE_LOWER_GORON, SpoilerCollectionCheck::RandomizerInf(RAND_INF_FIRE_TEMPLE_BOULDER_MAZE_LOWER_GORON));
locationTable[RC_FIRE_TEMPLE_BOULDER_MAZE_SHORTCUT_GORON] = Location::FireGoron(RC_FIRE_TEMPLE_BOULDER_MAZE_SHORTCUT_GORON, RCQUEST_VANILLA, RCAREA_FIRE_TEMPLE, SCENE_FIRE_TEMPLE, 4, "Boulder Maze Shortcut Goron", RHT_FIRE_TEMPLE_BOULDER_MAZE_SHORTCUT_GORON, SpoilerCollectionCheck::RandomizerInf(RAND_INF_FIRE_TEMPLE_BOULDER_MAZE_SHORTCUT_GORON));
locationTable[RC_FIRE_TEMPLE_BOULDER_MAZE_SIDE_ROOM_GORON] = Location::FireGoron(RC_FIRE_TEMPLE_BOULDER_MAZE_SIDE_ROOM_GORON, RCQUEST_VANILLA, RCAREA_FIRE_TEMPLE, SCENE_FIRE_TEMPLE, 5, "Boulder Maze Side Room Goron", RHT_FIRE_TEMPLE_BOULDER_MAZE_SIDE_ROOM_GORON, SpoilerCollectionCheck::RandomizerInf(RAND_INF_FIRE_TEMPLE_BOULDER_MAZE_SIDE_ROOM_GORON));
locationTable[RC_FIRE_TEMPLE_BOULDER_MAZE_UPPER_GORON] = Location::FireGoron(RC_FIRE_TEMPLE_BOULDER_MAZE_UPPER_GORON, RCQUEST_VANILLA, RCAREA_FIRE_TEMPLE, SCENE_FIRE_TEMPLE, 10, "Boulder Maze Upper Goron", RHT_FIRE_TEMPLE_BOULDER_MAZE_UPPER_GORON, SpoilerCollectionCheck::RandomizerInf(RAND_INF_FIRE_TEMPLE_BOULDER_MAZE_UPPER_GORON));
locationTable[RC_FIRE_TEMPLE_HIGHEST_GORON] = Location::FireGoron(RC_FIRE_TEMPLE_HIGHEST_GORON, RCQUEST_VANILLA, RCAREA_FIRE_TEMPLE, SCENE_FIRE_TEMPLE, 11, "Highest Goron", RHT_FIRE_TEMPLE_HIGHEST_GORON, SpoilerCollectionCheck::RandomizerInf(RAND_INF_FIRE_TEMPLE_HIGHEST_GORON));
locationTable[RC_FIRE_TEMPLE_MQ_MAP_GORON] = Location::FireGoron(RC_FIRE_TEMPLE_MQ_MAP_GORON, RCQUEST_MQ, RCAREA_FIRE_TEMPLE, SCENE_FIRE_TEMPLE, 9, "MQ Map Goron", RHT_FIRE_TEMPLE_MQ_MAP_GORON, SpoilerCollectionCheck::RandomizerInf(RAND_INF_FIRE_TEMPLE_MQ_MAP_GORON));
locationTable[RC_FIRE_TEMPLE_MQ_BIG_LAVA_ROOM_OPEN_DOOR_GORON] = Location::FireGoron(RC_FIRE_TEMPLE_MQ_BIG_LAVA_ROOM_OPEN_DOOR_GORON, RCQUEST_MQ, RCAREA_FIRE_TEMPLE, SCENE_FIRE_TEMPLE, 1, "MQ Big Lava Room Open Door Goron", RHT_FIRE_TEMPLE_MQ_BIG_LAVA_ROOM_OPEN_DOOR_GORON, SpoilerCollectionCheck::RandomizerInf(RAND_INF_FIRE_TEMPLE_MQ_BIG_LAVA_ROOM_OPEN_DOOR_GORON));
locationTable[RC_FIRE_TEMPLE_MQ_BIG_LAVA_ROOM_BLOCKED_DOOR_GORON] = Location::FireGoron(RC_FIRE_TEMPLE_MQ_BIG_LAVA_ROOM_BLOCKED_DOOR_GORON, RCQUEST_MQ, RCAREA_FIRE_TEMPLE, SCENE_FIRE_TEMPLE, 2, "MQ Big Lava Room Blocked Door Goron", RHT_FIRE_TEMPLE_MQ_BIG_LAVA_ROOM_BLOCKED_DOOR_GORON, SpoilerCollectionCheck::RandomizerInf(RAND_INF_FIRE_TEMPLE_MQ_BIG_LAVA_ROOM_BLOCKED_DOOR_GORON));
locationTable[RC_FIRE_TEMPLE_MQ_LIZALFOS_MAZE_SIDE_ROOM_GORON] = Location::FireGoron(RC_FIRE_TEMPLE_MQ_LIZALFOS_MAZE_SIDE_ROOM_GORON, RCQUEST_MQ, RCAREA_FIRE_TEMPLE, SCENE_FIRE_TEMPLE, 5, "MQ Lizalfos Maze Side Room Goron", RHT_FIRE_TEMPLE_MQ_LIZALFOS_MAZE_SIDE_ROOM_GORON, SpoilerCollectionCheck::RandomizerInf(RAND_INF_FIRE_TEMPLE_MQ_LIZALFOS_MAZE_SIDE_ROOM_GORON));
// clang-format on
}
static RegisterShipInitFunc registerFireGoronLocations(Rando::StaticData::RegisterFireGoronLocations);
@@ -695,4 +695,12 @@ Rando::Location Rando::Location::RedIce(RandomizerCheck rc, RandomizerCheckQuest
return { rc, quest_, RCTYPE_RED_ICE, area_, ACTOR_BG_ICE_SHELTER,
scene_, actorParams_, std::move(shortName_), hintKey, RG_NONE,
false, collectionCheck };
}
Rando::Location Rando::Location::FireGoron(RandomizerCheck rc, RandomizerCheckQuest quest_, RandomizerCheckArea area_,
SceneID scene_, int32_t actorParams_, std::string&& shortName_,
RandomizerHintTextKey hintKey, SpoilerCollectionCheck collectionCheck) {
return { rc, quest_, RCTYPE_FIRE_GORON, area_, ACTOR_EN_GO2,
scene_, actorParams_, std::move(shortName_), hintKey, RG_NONE,
false, collectionCheck };
}
@@ -264,6 +264,10 @@ class Location {
int32_t actorParams_, std::string&& shortName_, RandomizerHintTextKey hintKey,
SpoilerCollectionCheck collectionCheck);
static Location FireGoron(RandomizerCheck rc, RandomizerCheckQuest quest_, RandomizerCheckArea area_,
SceneID scene_, int32_t actorParams_, std::string&& shortName_,
RandomizerHintTextKey hintKey, SpoilerCollectionCheck collectionCheck);
static Location OtherHint(RandomizerCheck rc, RandomizerCheckQuest quest_, RandomizerCheckArea area_,
ActorID actorId_, SceneID scene_, std::string&& shortName_, std::string&& spoilerName_);
@@ -28,6 +28,7 @@ void RegionTable_Init_FireTemple() {
areaTable[RR_FIRE_TEMPLE_NEAR_BOSS_ROOM] = Region("Fire Temple Near Boss Room", SCENE_FIRE_TEMPLE, {}, {
//Locations
LOCATION(RC_FIRE_TEMPLE_NEAR_BOSS_CHEST, logic->FireTimer() >= 16 && logic->HasItem(RG_OPEN_CHEST)),
LOCATION(RC_FIRE_TEMPLE_NEAR_BOSS_GORON, logic->FireTimer() >= 16 && logic->HasItem(RG_SPEAK_GORON)),
//It's plausible to get the pots with rang from the larger square platform, but it's a blind shot that likely needs a setup
//and I've only been able to get the nearest 2, regardless it's a trick and probably a specific one like GY crate freestanding with rang
}, {
@@ -112,6 +113,7 @@ void RegionTable_Init_FireTemple() {
areaTable[RR_FIRE_TEMPLE_LOOP_GORON_CAGE] = Region("Fire Temple Loop Goron Cage", SCENE_FIRE_TEMPLE, {}, {
//Locations
LOCATION(RC_FIRE_TEMPLE_BOSS_KEY_CHEST, logic->CanOpenLargeChest()),
LOCATION(RC_FIRE_TEMPLE_BOSS_KEY_GORON, logic->HasItem(RG_SPEAK_GORON)),
}, {
//Exits
ENTRANCE(RR_FIRE_TEMPLE_LOOP_CAGE_SWITCH, logic->Get(LOGIC_FIRE_LOOP_SWITCH)),
@@ -148,6 +150,7 @@ void RegionTable_Init_FireTemple() {
areaTable[RR_FIRE_TEMPLE_1F_CURVED_CAGE] = Region("Fire Temple 1F Curved Cage", SCENE_FIRE_TEMPLE, {}, {
//Locations
LOCATION(RC_FIRE_TEMPLE_BIG_LAVA_ROOM_LOWER_OPEN_DOOR_CHEST, logic->HasItem(RG_OPEN_CHEST)),
LOCATION(RC_FIRE_TEMPLE_BIG_LAVA_ROOM_LOWER_OPEN_DOOR_GORON, logic->HasItem(RG_SPEAK_GORON)),
}, {
//Exits
ENTRANCE(RR_FIRE_TEMPLE_BIG_LAVA_ROOM, true),
@@ -166,6 +169,7 @@ void RegionTable_Init_FireTemple() {
areaTable[RR_FIRE_TEMPLE_STRAIGHTFORWARD_CAGE] = Region("Fire Temple Straightforward Cage", SCENE_FIRE_TEMPLE, {}, {
//Locations
LOCATION(RC_FIRE_TEMPLE_BIG_LAVA_ROOM_BLOCKED_DOOR_CHEST, logic->HasItem(RG_OPEN_CHEST)),
LOCATION(RC_FIRE_TEMPLE_BIG_LAVA_ROOM_BLOCKED_DOOR_GORON, logic->HasItem(RG_SPEAK_GORON)),
}, {
//Exits
ENTRANCE(RR_FIRE_TEMPLE_BIG_LAVA_ROOM, true),
@@ -223,6 +227,7 @@ void RegionTable_Init_FireTemple() {
}, {
//Locations
LOCATION(RC_FIRE_TEMPLE_BOULDER_MAZE_SHORTCUT_CHEST, logic->HasItem(RG_OPEN_CHEST)),
LOCATION(RC_FIRE_TEMPLE_BOULDER_MAZE_SHORTCUT_GORON, logic->HasItem(RG_SPEAK_GORON)),
}, {
//Exits
ENTRANCE(RR_FIRE_TEMPLE_SHORTCUT_ROOM, true),
@@ -232,6 +237,7 @@ void RegionTable_Init_FireTemple() {
areaTable[RR_FIRE_TEMPLE_BOULDER_MAZE_LOWER] = Region("Fire Temple Boulder Maze Lower", SCENE_FIRE_TEMPLE, {}, {
//Locations
LOCATION(RC_FIRE_TEMPLE_BOULDER_MAZE_LOWER_CHEST, logic->HasItem(RG_OPEN_CHEST)),
LOCATION(RC_FIRE_TEMPLE_BOULDER_MAZE_LOWER_GORON, logic->HasItem(RG_SPEAK_GORON)),
LOCATION(RC_FIRE_TEMPLE_GS_BOULDER_MAZE, logic->HasExplosives() && (logic->IsAdult || logic->HookshotOrBoomerang() || logic->CanGroundJumpslash())),
}, {
//Exits
@@ -244,6 +250,7 @@ void RegionTable_Init_FireTemple() {
areaTable[RR_FIRE_TEMPLE_3F_CURVED_CAGE] = Region("Fire Temple 3F Curved Cage", SCENE_FIRE_TEMPLE, {}, {
//Locations
LOCATION(RC_FIRE_TEMPLE_BOULDER_MAZE_SIDE_ROOM_CHEST, logic->HasItem(RG_OPEN_CHEST)),
LOCATION(RC_FIRE_TEMPLE_BOULDER_MAZE_SIDE_ROOM_GORON, logic->HasItem(RG_SPEAK_GORON)),
}, {
//Exits
ENTRANCE(RR_FIRE_TEMPLE_BOULDER_MAZE_LOWER, true),
@@ -305,6 +312,7 @@ void RegionTable_Init_FireTemple() {
areaTable[RR_FIRE_TEMPLE_BOULDER_MAZE_UPPER] = Region("Fire Temple Boulder Maze Upper", SCENE_FIRE_TEMPLE, {}, {
//Locations
LOCATION(RC_FIRE_TEMPLE_BOULDER_MAZE_UPPER_CHEST, logic->HasItem(RG_OPEN_CHEST)),
LOCATION(RC_FIRE_TEMPLE_BOULDER_MAZE_UPPER_GORON, logic->HasItem(RG_SPEAK_GORON)),
}, {
//Exits
ENTRANCE(RR_FIRE_TEMPLE_SHORTCUT_CLIMB, logic->HasExplosives()),
@@ -410,6 +418,7 @@ void RegionTable_Init_FireTemple() {
areaTable[RR_FIRE_TEMPLE_SOT_CAGE_SWITCH] = Region("Fire Temple Sot Cage Switch", SCENE_FIRE_TEMPLE, {}, {
//Locations
LOCATION(RC_FIRE_TEMPLE_HIGHEST_GORON_CHEST, (logic->CanUse(RG_SONG_OF_TIME) || ctx->GetTrickOption(RT_VISIBLE_COLLISION)) && logic->CanUse(RG_MEGATON_HAMMER) && logic->HasItem(RG_OPEN_CHEST)),
LOCATION(RC_FIRE_TEMPLE_HIGHEST_GORON, (logic->CanUse(RG_SONG_OF_TIME) || ctx->GetTrickOption(RT_VISIBLE_COLLISION)) && logic->CanUse(RG_MEGATON_HAMMER) && logic->HasItem(RG_SPEAK_GORON)),
}, {
//Exits
ENTRANCE(RR_FIRE_TEMPLE_BOSS_ENTRYWAY, false),
@@ -592,6 +601,7 @@ void RegionTable_Init_FireTemple() {
areaTable[RR_FIRE_TEMPLE_MQ_LOOP_GORON_CAGE] = Region("Fire Temple MQ Loop Goron Cage", SCENE_FIRE_TEMPLE, {}, {
//Locations
LOCATION(RC_FIRE_TEMPLE_MQ_MAP_CHEST, logic->CanOpenLargeChest()),
LOCATION(RC_FIRE_TEMPLE_MQ_MAP_GORON, logic->HasItem(RG_SPEAK_GORON)),
}, {
//Exits
ENTRANCE(RR_FIRE_TEMPLE_MQ_LOOP_CAGE_SWITCH, logic->Get(LOGIC_FIRE_OPENED_LOWEST_GORON_CAGE)),
@@ -708,6 +718,7 @@ void RegionTable_Init_FireTemple() {
//Locations
//implies CanGetEnemyDrop(RE_GOLD_SKULLTULA)
LOCATION(RC_FIRE_TEMPLE_MQ_GS_BIG_LAVA_ROOM_OPEN_DOOR, logic->CanUse(RG_MEGATON_HAMMER)),
LOCATION(RC_FIRE_TEMPLE_MQ_BIG_LAVA_ROOM_OPEN_DOOR_GORON, logic->CanUse(RG_MEGATON_HAMMER) && logic->HasItem(RG_SPEAK_GORON)),
}, {
//Exits
ENTRANCE(RR_FIRE_TEMPLE_MQ_BIG_LAVA_ROOM, true),
@@ -716,6 +727,7 @@ void RegionTable_Init_FireTemple() {
areaTable[RR_FIRE_TEMPLE_MQ_TORCH_LOCKED_CAGE] = Region("Fire Temple MQ Torch Locked Cage", SCENE_FIRE_TEMPLE, {}, {
//Locations
LOCATION(RC_FIRE_TEMPLE_MQ_BIG_LAVA_ROOM_BLOCKED_DOOR_CHEST, logic->HasFireSource() && logic->HasItem(RG_OPEN_CHEST)),
LOCATION(RC_FIRE_TEMPLE_MQ_BIG_LAVA_ROOM_BLOCKED_DOOR_GORON, logic->HasFireSource() && logic->HasItem(RG_SPEAK_GORON)),
}, {
//Exits
ENTRANCE(RR_FIRE_TEMPLE_MQ_BIG_LAVA_BLOCKED_DOOR, true),
@@ -829,6 +841,7 @@ void RegionTable_Init_FireTemple() {
areaTable[RR_FIRE_TEMPLE_MQ_3F_CURVED_CAGE] = Region("Fire Temple MQ 3F Curved Cage", SCENE_FIRE_TEMPLE, {}, {
//Locations
LOCATION(RC_FIRE_TEMPLE_MQ_LIZALFOS_MAZE_SIDE_ROOM_CHEST, logic->HasItem(RG_OPEN_CHEST)),
LOCATION(RC_FIRE_TEMPLE_MQ_LIZALFOS_MAZE_SIDE_ROOM_GORON, logic->HasItem(RG_SPEAK_GORON)),
}, {
//Exits
ENTRANCE(RR_FIRE_TEMPLE_MQ_MAZE_SWITCH_DOOR, true),
@@ -3533,6 +3533,19 @@ RANDO_ENUM_ITEM(RC_GANONS_CASTLE_MQ_WATER_TRIAL_SECOND_DOOR_RED_ICE_2)
RANDO_ENUM_ITEM(RC_GANONS_CASTLE_MQ_WATER_TRIAL_SECOND_DOOR_RED_ICE_3)
RANDO_ENUM_ITEM(RC_GANONS_CASTLE_MQ_WATER_TRIAL_SECOND_DOOR_RED_ICE_4)
RANDO_ENUM_ITEM(RC_GANONS_CASTLE_MQ_WATER_TRIAL_SECOND_DOOR_RED_ICE_5)
RANDO_ENUM_ITEM(RC_FIRE_TEMPLE_NEAR_BOSS_GORON)
RANDO_ENUM_ITEM(RC_FIRE_TEMPLE_BOSS_KEY_GORON)
RANDO_ENUM_ITEM(RC_FIRE_TEMPLE_BIG_LAVA_ROOM_LOWER_OPEN_DOOR_GORON)
RANDO_ENUM_ITEM(RC_FIRE_TEMPLE_BIG_LAVA_ROOM_BLOCKED_DOOR_GORON)
RANDO_ENUM_ITEM(RC_FIRE_TEMPLE_BOULDER_MAZE_LOWER_GORON)
RANDO_ENUM_ITEM(RC_FIRE_TEMPLE_BOULDER_MAZE_SHORTCUT_GORON)
RANDO_ENUM_ITEM(RC_FIRE_TEMPLE_BOULDER_MAZE_SIDE_ROOM_GORON)
RANDO_ENUM_ITEM(RC_FIRE_TEMPLE_BOULDER_MAZE_UPPER_GORON)
RANDO_ENUM_ITEM(RC_FIRE_TEMPLE_HIGHEST_GORON)
RANDO_ENUM_ITEM(RC_FIRE_TEMPLE_MQ_MAP_GORON)
RANDO_ENUM_ITEM(RC_FIRE_TEMPLE_MQ_BIG_LAVA_ROOM_OPEN_DOOR_GORON)
RANDO_ENUM_ITEM(RC_FIRE_TEMPLE_MQ_BIG_LAVA_ROOM_BLOCKED_DOOR_GORON)
RANDO_ENUM_ITEM(RC_FIRE_TEMPLE_MQ_LIZALFOS_MAZE_SIDE_ROOM_GORON)
RANDO_ENUM_ITEM(RC_MAX)
RANDO_ENUM_END(RandomizerCheck)
@@ -1701,6 +1701,20 @@ RANDO_ENUM_ITEM(RHT_RED_ICE_ZORAS_DOMAIN)
RANDO_ENUM_ITEM(RHT_GERUDO_TRAINING_GROUND_RED_ICE)
RANDO_ENUM_ITEM(RHT_ICE_CAVERN_RED_ICE)
RANDO_ENUM_ITEM(RHT_GANONS_CASTLE_RED_ICE)
// FIRE TEMPLE GORONS
RANDO_ENUM_ITEM(RHT_FIRE_TEMPLE_NEAR_BOSS_GORON)
RANDO_ENUM_ITEM(RHT_FIRE_TEMPLE_BOSS_KEY_GORON)
RANDO_ENUM_ITEM(RHT_FIRE_TEMPLE_BIG_LAVA_ROOM_LOWER_OPEN_DOOR_GORON)
RANDO_ENUM_ITEM(RHT_FIRE_TEMPLE_BIG_LAVA_ROOM_BLOCKED_DOOR_GORON)
RANDO_ENUM_ITEM(RHT_FIRE_TEMPLE_BOULDER_MAZE_LOWER_GORON)
RANDO_ENUM_ITEM(RHT_FIRE_TEMPLE_BOULDER_MAZE_SHORTCUT_GORON)
RANDO_ENUM_ITEM(RHT_FIRE_TEMPLE_BOULDER_MAZE_SIDE_ROOM_GORON)
RANDO_ENUM_ITEM(RHT_FIRE_TEMPLE_BOULDER_MAZE_UPPER_GORON)
RANDO_ENUM_ITEM(RHT_FIRE_TEMPLE_HIGHEST_GORON)
RANDO_ENUM_ITEM(RHT_FIRE_TEMPLE_MQ_MAP_GORON)
RANDO_ENUM_ITEM(RHT_FIRE_TEMPLE_MQ_BIG_LAVA_ROOM_OPEN_DOOR_GORON)
RANDO_ENUM_ITEM(RHT_FIRE_TEMPLE_MQ_BIG_LAVA_ROOM_BLOCKED_DOOR_GORON)
RANDO_ENUM_ITEM(RHT_FIRE_TEMPLE_MQ_LIZALFOS_MAZE_SIDE_ROOM_GORON)
// MAX
RANDO_ENUM_ITEM(RHT_MAX)
RANDO_ENUM_END(RandomizerHintTextKey)
@@ -3097,6 +3097,19 @@ RANDO_ENUM_ITEM(RAND_INF_HAS_FOUND_DEKU_SHIELD)
RANDO_ENUM_ITEM(RAND_INF_HAS_FOUND_HYLIAN_SHIELD)
RANDO_ENUM_ITEM(RAND_INF_HAS_FOUND_GORON_TUNIC)
RANDO_ENUM_ITEM(RAND_INF_HAS_FOUND_ZORA_TUNIC)
RANDO_ENUM_ITEM(RAND_INF_FIRE_TEMPLE_NEAR_BOSS_GORON)
RANDO_ENUM_ITEM(RAND_INF_FIRE_TEMPLE_BOSS_KEY_GORON)
RANDO_ENUM_ITEM(RAND_INF_FIRE_TEMPLE_BIG_LAVA_ROOM_LOWER_OPEN_DOOR_GORON)
RANDO_ENUM_ITEM(RAND_INF_FIRE_TEMPLE_BIG_LAVA_ROOM_BLOCKED_DOOR_GORON)
RANDO_ENUM_ITEM(RAND_INF_FIRE_TEMPLE_BOULDER_MAZE_LOWER_GORON)
RANDO_ENUM_ITEM(RAND_INF_FIRE_TEMPLE_BOULDER_MAZE_SHORTCUT_GORON)
RANDO_ENUM_ITEM(RAND_INF_FIRE_TEMPLE_BOULDER_MAZE_SIDE_ROOM_GORON)
RANDO_ENUM_ITEM(RAND_INF_FIRE_TEMPLE_BOULDER_MAZE_UPPER_GORON)
RANDO_ENUM_ITEM(RAND_INF_FIRE_TEMPLE_HIGHEST_GORON)
RANDO_ENUM_ITEM(RAND_INF_FIRE_TEMPLE_MQ_MAP_GORON)
RANDO_ENUM_ITEM(RAND_INF_FIRE_TEMPLE_MQ_BIG_LAVA_ROOM_OPEN_DOOR_GORON)
RANDO_ENUM_ITEM(RAND_INF_FIRE_TEMPLE_MQ_BIG_LAVA_ROOM_BLOCKED_DOOR_GORON)
RANDO_ENUM_ITEM(RAND_INF_FIRE_TEMPLE_MQ_LIZALFOS_MAZE_SIDE_ROOM_GORON)
RANDO_ENUM_ITEM(RAND_INF_MAX)
@@ -139,6 +139,7 @@ RANDO_ENUM_ITEM(RCTYPE_SIGN) // Signs
RANDO_ENUM_ITEM(RCTYPE_BEGGAR) // Beggar
RANDO_ENUM_ITEM(RCTYPE_ICICLE) // Icicles
RANDO_ENUM_ITEM(RCTYPE_RED_ICE) // Red Ice
RANDO_ENUM_ITEM(RCTYPE_FIRE_GORON) // Fire Temple Gorons
RANDO_ENUM_END(RandomizerCheckType)
RANDO_ENUM_BEGIN(RandomizerCheckQuest)
@@ -311,6 +311,7 @@ RANDO_ENUM_ITEM(RSK_SHUFFLE_SIGNS)
RANDO_ENUM_ITEM(RSK_ROCS_FEATHER)
RANDO_ENUM_ITEM(RSK_SHUFFLE_ICICLES)
RANDO_ENUM_ITEM(RSK_SHUFFLE_RED_ICE)
RANDO_ENUM_ITEM(RSK_SHUFFLE_FIRE_GORONS)
RANDO_ENUM_ITEM(RSK_STARTING_KEATON_MASK)
RANDO_ENUM_ITEM(RSK_STARTING_SKULL_MASK)
RANDO_ENUM_ITEM(RSK_STARTING_SPOOKY_MASK)
@@ -210,6 +210,8 @@ void RandomizerCheckObjects::UpdateImGuiVisibility() {
CVarGetInteger(CVAR_RANDOMIZER_SETTING("ShuffleIcicles"), RO_GENERIC_NO)) &&
(location.GetRCType() != RCTYPE_RED_ICE ||
CVarGetInteger(CVAR_RANDOMIZER_SETTING("ShuffleRedIce"), RO_GENERIC_NO)) &&
(location.GetRCType() != RCTYPE_FIRE_GORON ||
CVarGetInteger(CVAR_RANDOMIZER_SETTING("ShuffleFireGorons"), RO_GENERIC_NO)) &&
(location.GetRCType() != RCTYPE_FISH ||
Rando::Fishsanity::GetFishLocationIncluded(&location, FSO_SOURCE_CVARS)) &&
(location.GetRCType() != RCTYPE_ADULT_TRADE ||
@@ -99,6 +99,7 @@ bool showDungeonWonderItems;
bool showBeggar;
bool showIcicles;
bool showRedIce;
bool showFireGorons;
bool showFrogSongRupees;
bool showFountainFairies;
bool showStoneFairies;
@@ -1801,6 +1802,7 @@ void LoadSettings() {
showBeggar = OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_SHUFFLE_BEGGAR);
showIcicles = OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_SHUFFLE_ICICLES);
showRedIce = OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_SHUFFLE_RED_ICE);
showFireGorons = OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_SHUFFLE_FIRE_GORONS);
} else { // Vanilla
showOverworldTokens = true;
showDungeonTokens = true;
@@ -1822,6 +1824,7 @@ void LoadSettings() {
showBeggar = false;
showIcicles = false;
showRedIce = false;
showFireGorons = false;
}
fortressFast = false;
@@ -1950,6 +1953,7 @@ bool IsCheckShuffled(RandomizerCheck rc) {
(showDungeonWonderItems && RandomizerCheckObjects::AreaIsDungeon(loc->GetArea()))) &&
(loc->GetRCType() != RCTYPE_ICICLE || showIcicles) &&
(loc->GetRCType() != RCTYPE_RED_ICE || showRedIce) &&
(loc->GetRCType() != RCTYPE_FIRE_GORON || showFireGorons) &&
(loc->GetRCType() != RCTYPE_FISH || Rando::Fishsanity::GetFishLocationIncluded(loc)) &&
(loc->GetRCType() != RCTYPE_FREESTANDING ||
(showOverworldFreestanding && RandomizerCheckObjects::AreaIsOverworld(loc->GetArea())) ||
@@ -869,6 +869,7 @@ void Settings::CreateOptions() {
OPT_BOOL(RSK_SHUFFLE_BUSHES, CVAR_RANDOMIZER_SETTING("ShuffleBushes"));
OPT_BOOL(RSK_SHUFFLE_ICICLES, CVAR_RANDOMIZER_SETTING("ShuffleIcicles"));
OPT_BOOL(RSK_SHUFFLE_RED_ICE, CVAR_RANDOMIZER_SETTING("ShuffleRedIce"));
OPT_BOOL(RSK_SHUFFLE_FIRE_GORONS, CVAR_RANDOMIZER_SETTING("ShuffleFireGorons"));
OPT_U8(RSK_SHUFFLE_SIGNS, {"Off", "Dungeons", "Overworld", "All Signs"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("ShuffleSigns"), WIDGET_CVAR_COMBOBOX, RO_SHUFFLE_SIGNS_OFF);
OPT_BOOL(RSK_SHUFFLE_FISHING_POLE, CVAR_RANDOMIZER_SETTING("ShuffleFishingPole"));
OPT_CALLBACK(RSK_SHUFFLE_FISHING_POLE, {
@@ -2050,6 +2051,7 @@ void Settings::CreateOptions() {
&mOptions[RSK_SHUFFLE_BUSHES],
&mOptions[RSK_SHUFFLE_ICICLES],
&mOptions[RSK_SHUFFLE_RED_ICE],
&mOptions[RSK_SHUFFLE_FIRE_GORONS],
&mOptions[RSK_SHUFFLE_SIGNS],
&mOptions[RSK_SHUFFLE_FROG_SONG_RUPEES],
&mOptions[RSK_SHUFFLE_ADULT_TRADE],
@@ -2285,6 +2287,7 @@ void Settings::CreateOptions() {
&mOptions[RSK_SHUFFLE_BUSHES],
&mOptions[RSK_SHUFFLE_ICICLES],
&mOptions[RSK_SHUFFLE_RED_ICE],
&mOptions[RSK_SHUFFLE_FIRE_GORONS],
&mOptions[RSK_SHUFFLE_SIGNS],
&mOptions[RSK_SHUFFLE_KOKIRI_SWORD],
&mOptions[RSK_SHUFFLE_OCARINA],
@@ -72,6 +72,7 @@ class StaticData {
static void RegisterBeggarLocations();
static void RegisterIcicleLocations();
static void RegisterRedIceLocations();
static void RegisterFireGoronLocations();
static void InitHashMaps();
static std::array<std::pair<RandomizerCheck, RandomizerCheck>, 17> randomizerFishingPondFish;
static std::unordered_map<int8_t, RandomizerCheck> randomizerGrottoFishMap;
@@ -1608,7 +1608,8 @@ void EnGo2_Init(Actor* thisx, PlayState* play) {
EnGo2_SetupRolling(this, play);
break;
case GORON_FIRE_GENERIC:
if (Flags_GetSwitch(play, (this->actor.params & 0xFC00) >> 0xA)) {
if (GameInteractor_Should(VB_DESPAWN_FREED_FIRE_GORON,
Flags_GetSwitch(play, (this->actor.params & 0xFC00) >> 0xA), this)) {
Actor_Kill(&this->actor);
} else {
this->isAwake = true;
@@ -1930,6 +1931,7 @@ void EnGo2_GoronFireGenericAction(EnGo2* this, PlayState* play) {
switch (this->goronState) {
case 0: // Wake up
if (Message_GetState(&play->msgCtx) == TEXT_STATE_CLOSING) {
GameInteractor_Should(VB_GIVE_ITEM_FROM_FIRE_GORON, true, this);
if (GameInteractor_Should(VB_PLAY_GORON_FREE_CS, true)) {
EnGo2_GoronFireCamera(this, play);
play->msgCtx.msgMode = MSGMODE_PAUSED;