mirror of
https://github.com/HarbourMasters/Shipwright
synced 2026-05-25 23:45:11 -04:00
Compare commits
92 Commits
9.0.2
...
develop-blair
| Author | SHA1 | Date | |
|---|---|---|---|
| ac93d7cc15 | |||
| 27f2292f9d | |||
| 837f497ea6 | |||
| 405fc7a31d | |||
| cbd376afa9 | |||
| 7b38093665 | |||
| 21e37d9ac2 | |||
| 820d097c84 | |||
| 224efe2946 | |||
| b6166f41c8 | |||
| 9ff9bebaa2 | |||
| 568639dfc0 | |||
| e104870e6a | |||
| 353ad944be | |||
| 89c1c97522 | |||
| b87f1432fd | |||
| be77a9be71 | |||
| 7d7072f717 | |||
| ccf3d4b6a0 | |||
| d06cf6bf10 | |||
| d51e88b972 | |||
| c588d48672 | |||
| 35ad68578e | |||
| 5066fbf82c | |||
| 47c5a7f308 | |||
| 37fb25d2b3 | |||
| 681e8dda26 | |||
| a93b484cf3 | |||
| dfa10383e4 | |||
| 32683e2a74 | |||
| a9b857469e | |||
| 1161ce3546 | |||
| 8b616c8709 | |||
| 3b82b8eeff | |||
| 4676242086 | |||
| afde504a0f | |||
| 17613d1f50 | |||
| b564148380 | |||
| a9a49ccbe6 | |||
| 2daf343755 | |||
| b932b8f6c9 | |||
| 19e9f39a9a | |||
| aa7693a103 | |||
| f2bc7cd1dc | |||
| 620d08002c | |||
| 35361c9e8d | |||
| b600836e4f | |||
| eefe7729ab | |||
| ab9af742fa | |||
| c7e3e08f8d | |||
| 69792e9717 | |||
| 0b9fe2d9b9 | |||
| ad850e50b1 | |||
| 40da9997c5 | |||
| fc10e36cdb | |||
| f0e36c2694 | |||
| de96f3cd0a | |||
| d330f22071 | |||
| d69a45674f | |||
| a9fc317a5a | |||
| 2511275b8b | |||
| 01ce1eeac8 | |||
| 5bf3761a18 | |||
| 081f82875a | |||
| 4334a132e3 | |||
| f0e40fd1dc | |||
| f16e34e8b8 | |||
| 53566c9a73 | |||
| ecad59e31f | |||
| 8e34942924 | |||
| e0d5fbec42 | |||
| b30fff5d57 | |||
| 66351fa4e4 | |||
| 9cb6530858 | |||
| 6acabae38f | |||
| 4fd0bf402e | |||
| e8c2db8151 | |||
| f72085b6ca | |||
| 804a24861b | |||
| 6cbb298f76 | |||
| 19eb4f39ab | |||
| bc3b17f4ab | |||
| baa91cbadb | |||
| 6c14311b66 | |||
| a016453042 | |||
| 17ed54dbc5 | |||
| fec676bbf8 | |||
| 3d3d9c5226 | |||
| 8a8ea676ba | |||
| 103a36e5fe | |||
| 3c4f38e2f0 | |||
| 29af294b0c |
+2
-1
@@ -2,10 +2,11 @@ cmake_minimum_required(VERSION 3.26.0 FATAL_ERROR)
|
||||
|
||||
set(CMAKE_SYSTEM_VERSION 10.0 CACHE STRING "" FORCE)
|
||||
set(CMAKE_CXX_STANDARD 20 CACHE STRING "The C++ standard to use")
|
||||
set(CMAKE_C_STANDARD 17 CACHE STRING "The C standard to use")
|
||||
|
||||
set(CMAKE_OSX_DEPLOYMENT_TARGET "10.15" CACHE STRING "Minimum OS X deployment version")
|
||||
|
||||
project(Ship VERSION 9.0.2 LANGUAGES C CXX)
|
||||
project(Ship VERSION 9.0.5 LANGUAGES C CXX)
|
||||
include(CMake/soh-cvars.cmake)
|
||||
include(CMake/lus-cvars.cmake)
|
||||
|
||||
|
||||
@@ -4,6 +4,7 @@ set(CMAKE_SYSTEM_VERSION 10.0 CACHE STRING "" FORCE)
|
||||
|
||||
project(soh LANGUAGES C CXX)
|
||||
set(CMAKE_CXX_STANDARD 20 CACHE STRING "The C++ standard to use")
|
||||
set(CMAKE_C_STANDARD 17 CACHE STRING "The C standard to use")
|
||||
|
||||
if (CMAKE_SYSTEM_NAME STREQUAL "Darwin")
|
||||
enable_language(OBJCXX)
|
||||
|
||||
@@ -15,7 +15,7 @@ extern "C"
|
||||
#include <soh/Enhancements/randomizer/randomizer_inf.h>
|
||||
|
||||
#if defined(INCLUDE_GAME_PRINTF) && defined(_DEBUG)
|
||||
#define osSyncPrintf(fmt, ...) lusprintf(__FILE__, __LINE__, 0, fmt, __VA_ARGS__)
|
||||
#define osSyncPrintf(fmt, ...) lusprintf(__FILE__, __LINE__, 0, fmt, ##__VA_ARGS__)
|
||||
#else
|
||||
#define osSyncPrintf(fmt, ...) osSyncPrintfUnused(fmt, ##__VA_ARGS__)
|
||||
#endif
|
||||
|
||||
+1
-1
@@ -544,7 +544,7 @@ typedef enum {
|
||||
LANGUAGE_MAX
|
||||
} Language;
|
||||
|
||||
#define TODO_TRANSLATE "__Translate_This__"
|
||||
#define TODO_TRANSLATE "TranslateThis"
|
||||
|
||||
// TODO get these properties from the textures themselves
|
||||
#define FONT_CHAR_TEX_WIDTH 16
|
||||
|
||||
@@ -82,6 +82,7 @@ const std::vector<PresetEntry> enhancedPresetEntries = {
|
||||
PRESET_ENTRY_S32(CVAR_ENHANCEMENT("DisableCritWiggle"), 1), PRESET_ENTRY_S32(CVAR_ENHANCEMENT("BetterOwl"), 1),
|
||||
PRESET_ENTRY_S32(CVAR_ENHANCEMENT("QuitFishingAtDoor"), 1), PRESET_ENTRY_S32(CVAR_ENHANCEMENT("InstantPutaway"), 1),
|
||||
PRESET_ENTRY_S32(CVAR_ENHANCEMENT("TimeSavers.SleepingWaterfall"), 1),
|
||||
PRESET_ENTRY_S32(CVAR_ENHANCEMENT("TimeSavers.SkipJabuJabuFish"), 1),
|
||||
|
||||
// Skips & Speed-ups
|
||||
PRESET_ENTRY_S32(CVAR_ENHANCEMENT("SkipText"), 1), PRESET_ENTRY_S32(CVAR_ENHANCEMENT("TextSpeed"), 5),
|
||||
@@ -176,6 +177,7 @@ const std::vector<PresetEntry> randomizerPresetEntries = {
|
||||
PRESET_ENTRY_S32(CVAR_ENHANCEMENT("QuitFishingAtDoor"), 1),
|
||||
PRESET_ENTRY_S32(CVAR_ENHANCEMENT("InstantPutaway"), 1),
|
||||
PRESET_ENTRY_S32(CVAR_ENHANCEMENT("TimeSavers.SleepingWaterfall"), 1),
|
||||
PRESET_ENTRY_S32(CVAR_ENHANCEMENT("TimeSavers.SkipJabuJabuFish"), 1),
|
||||
|
||||
// Skips & Speed-ups
|
||||
PRESET_ENTRY_S32(CVAR_ENHANCEMENT("TimeSavers.SkipCutscene.Intro"), 1),
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
#include "soh/Enhancements/game-interactor/GameInteractor.h"
|
||||
#include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h"
|
||||
#include "soh/OTRGlobals.h"
|
||||
#include "soh/Enhancements/timesaver_hook_handlers.h"
|
||||
|
||||
extern "C" {
|
||||
#include "macros.h"
|
||||
@@ -12,6 +13,7 @@ extern "C" {
|
||||
|
||||
#define RAND_GET_OPTION(option) Rando::Context::GetInstance()->GetOption(option).Get()
|
||||
|
||||
extern "C" PlayState* gPlayState;
|
||||
static bool sEnteredBlueWarp = false;
|
||||
|
||||
/**
|
||||
@@ -124,6 +126,13 @@ void SkipBlueWarp_ShouldPlayBlueWarpCS(GIVanillaBehavior _, bool* should, va_lis
|
||||
*/
|
||||
void SkipBlueWarp_ShouldGiveItem(GIVanillaBehavior _, bool* should, va_list originalArgs) {
|
||||
if (CVarGetInteger(CVAR_ENHANCEMENT("TimeSavers.SkipCutscene.Story"), IS_RANDO)) {
|
||||
if (IS_VANILLA) {
|
||||
if (gPlayState->sceneNum == SCENE_SHADOW_TEMPLE_BOSS) {
|
||||
TimeSaverQueueItem(RG_SHADOW_MEDALLION);
|
||||
} else if (gPlayState->sceneNum == SCENE_SPIRIT_TEMPLE_BOSS) {
|
||||
TimeSaverQueueItem(RG_SPIRIT_MEDALLION);
|
||||
}
|
||||
}
|
||||
*should = false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -93,7 +93,7 @@ void SkipChildRutoInteractions_Register() {
|
||||
if (enRu1->action == 22) {
|
||||
enRu1->action = 27;
|
||||
enRu1->drawConfig = 1;
|
||||
enRu1->actor.flags |= ACTOR_FLAG_ATTENTION_ENABLED | ACTOR_FLAG_FRIENDLY;
|
||||
enRu1->actor.flags &= ~(ACTOR_FLAG_ATTENTION_ENABLED | ACTOR_FLAG_FRIENDLY);
|
||||
Animation_Change(&enRu1->skelAnime, (AnimationHeader*)&gRutoChildSittingAnim, 1.0f, 0.0f,
|
||||
Animation_GetLastFrame((void*)&gRutoChildSittingAnim), ANIMMODE_LOOP, 0.0f);
|
||||
}
|
||||
|
||||
@@ -265,6 +265,9 @@ void Draw_SfxTab(const std::string& tabId, SeqType type, const std::string& tabN
|
||||
}
|
||||
}
|
||||
|
||||
auto playingFromMenu = CVarGetInteger(CVAR_AUDIO("Playing"), 0);
|
||||
auto currentBGM = func_800FA0B4(SEQ_PLAYER_BGM_MAIN);
|
||||
|
||||
// Longest text in Audio Editor
|
||||
ImVec2 columnSize = ImGui::CalcTextSize("Navi - Look/Hey/Watchout (Target Enemy)");
|
||||
ImGui::BeginTable(tabId.c_str(), 3, ImGuiTableFlags_SizingFixedFit);
|
||||
@@ -291,10 +294,16 @@ void Draw_SfxTab(const std::string& tabId, SeqType type, const std::string& tabN
|
||||
const std::string lockedButton = ICON_FA_LOCK + hiddenKey;
|
||||
const std::string unlockedButton = ICON_FA_UNLOCK + hiddenKey;
|
||||
const int currentValue = CVarGetInteger(cvarKey.c_str(), defaultValue);
|
||||
const bool isCurrentlyPlaying = currentValue == playingFromMenu || seqData.sequenceId == currentBGM;
|
||||
|
||||
ImGui::TableNextRow();
|
||||
ImGui::TableNextColumn();
|
||||
ImGui::Text("%s", seqData.label.c_str());
|
||||
if (isCurrentlyPlaying) {
|
||||
ImGui::TextColored(UIWidgets::ColorValues.at(UIWidgets::Colors::Yellow), "%s %s", ICON_FA_PLAY,
|
||||
seqData.label.c_str());
|
||||
} else {
|
||||
ImGui::Text("%s", seqData.label.c_str());
|
||||
}
|
||||
ImGui::TableNextColumn();
|
||||
ImGui::PushItemWidth(-FLT_MIN);
|
||||
const int initialValue = map.contains(currentValue) ? currentValue : defaultValue;
|
||||
|
||||
@@ -501,6 +501,10 @@ void BossRush_OnVanillaBehaviorHandler(GIVanillaBehavior id, bool* should, va_li
|
||||
}
|
||||
break;
|
||||
}
|
||||
case VB_PLAY_BLUE_WARP_CS: {
|
||||
*should = false;
|
||||
break;
|
||||
}
|
||||
// Spawn clean blue warps (no ruto, adult animation, etc)
|
||||
case VB_SPAWN_BLUE_WARP: {
|
||||
switch (gPlayState->sceneNum) {
|
||||
|
||||
@@ -642,10 +642,14 @@ void SohInputEditorWindow::DrawStickSection(uint8_t port, uint8_t stick, int32_t
|
||||
|
||||
ImGui::SameLine();
|
||||
ImGui::BeginGroup();
|
||||
DrawStickDirectionLine(ICON_FA_ARROW_UP, port, stick, Ship::UP, color);
|
||||
DrawStickDirectionLine(ICON_FA_ARROW_DOWN, port, stick, Ship::DOWN, color);
|
||||
DrawStickDirectionLine(ICON_FA_ARROW_LEFT, port, stick, Ship::LEFT, color);
|
||||
DrawStickDirectionLine(ICON_FA_ARROW_RIGHT, port, stick, Ship::RIGHT, color);
|
||||
DrawStickDirectionLine(StringHelper::Sprintf("%s##%d", ICON_FA_ARROW_UP, stick).c_str(), port, stick, Ship::UP,
|
||||
color);
|
||||
DrawStickDirectionLine(StringHelper::Sprintf("%s##%d", ICON_FA_ARROW_DOWN, stick).c_str(), port, stick, Ship::DOWN,
|
||||
color);
|
||||
DrawStickDirectionLine(StringHelper::Sprintf("%s##%d", ICON_FA_ARROW_LEFT, stick).c_str(), port, stick, Ship::LEFT,
|
||||
color);
|
||||
DrawStickDirectionLine(StringHelper::Sprintf("%s##%d", ICON_FA_ARROW_RIGHT, stick).c_str(), port, stick,
|
||||
Ship::RIGHT, color);
|
||||
ImGui::EndGroup();
|
||||
ImGui::SetNextItemOpen(true, ImGuiCond_Once);
|
||||
if (ImGui::TreeNode(StringHelper::Sprintf("Analog Stick Options##%d", id).c_str())) {
|
||||
@@ -1335,12 +1339,12 @@ void SohInputEditorWindow::DrawOcarinaControlPanel() {
|
||||
|
||||
ImGui::AlignTextToFramePadding();
|
||||
ImGui::BulletText("Disable song detection");
|
||||
DrawButtonLine(ICON_FA_BAN, 0, BTN_CUSTOM_OCARINA_DISABLE_SONGS);
|
||||
DrawButtonLine(ICON_FA_BAN "##DisableSongDetection", 0, BTN_CUSTOM_OCARINA_DISABLE_SONGS);
|
||||
|
||||
ImGui::AlignTextToFramePadding();
|
||||
ImGui::BulletText("Pitch");
|
||||
DrawButtonLine(ICON_FA_ARROW_UP, 0, BTN_CUSTOM_OCARINA_PITCH_UP);
|
||||
DrawButtonLine(ICON_FA_ARROW_DOWN, 0, BTN_CUSTOM_OCARINA_PITCH_DOWN);
|
||||
DrawButtonLine(ICON_FA_ARROW_UP "##Pitch", 0, BTN_CUSTOM_OCARINA_PITCH_UP);
|
||||
DrawButtonLine(ICON_FA_ARROW_DOWN "##Pitch", 0, BTN_CUSTOM_OCARINA_PITCH_DOWN);
|
||||
|
||||
if (!CVarGetInteger(CVAR_SETTING("CustomOcarina.Enabled"), 0)) {
|
||||
ImGui::EndDisabled();
|
||||
@@ -1362,10 +1366,10 @@ void SohInputEditorWindow::DrawCameraControlPanel() {
|
||||
.Color(THEME_COLOR)
|
||||
.Tooltip("Allows for aiming with the right stick in:\n-First-Person/C-Up view\n-Weapon Aiming"));
|
||||
if (CVarGetInteger(CVAR_SETTING("Controls.RightStickAim"), 0)) {
|
||||
CVarCheckbox("Allow moving while in first person mode", CVAR_SETTING("MoveInFirstPerson"),
|
||||
CVarCheckbox("Allow moving while in first-person mode", CVAR_SETTING("MoveInFirstPerson"),
|
||||
CheckboxOptions()
|
||||
.Color(THEME_COLOR)
|
||||
.Tooltip("Changes the left stick to move the player while in first person mode"));
|
||||
.Tooltip("Changes the left stick to move the player while in first-person mode"));
|
||||
}
|
||||
CVarCheckbox("Invert Aiming X Axis", CVAR_SETTING("Controls.InvertAimingXAxis"),
|
||||
CheckboxOptions()
|
||||
@@ -1428,7 +1432,9 @@ void SohInputEditorWindow::DrawCameraControlPanel() {
|
||||
CheckboxOptions()
|
||||
.Color(THEME_COLOR)
|
||||
.Tooltip("Enables free look camera control\nNote: You must remap C buttons off of the right stick in the "
|
||||
"controller config menu, and map the camera stick to the right stick."));
|
||||
"controller config menu, and map the camera stick to the right stick.\n"
|
||||
"Doesn't work in areas were the game locks the camera.\n"
|
||||
"Scene reload may be necessary to enable."));
|
||||
CVarCheckbox("Invert Camera X Axis", CVAR_SETTING("FreeLook.InvertXAxis"),
|
||||
CheckboxOptions().Color(THEME_COLOR).Tooltip("Inverts the Camera X Axis in:\n-Free look"));
|
||||
CVarCheckbox(
|
||||
|
||||
@@ -155,12 +155,12 @@ const std::string CustomMessage::GetFrench(MessageFormat format) const {
|
||||
}
|
||||
|
||||
const std::string CustomMessage::GetForCurrentLanguage(MessageFormat format) const {
|
||||
return GetForLanguage(((Language)gSaveContext.language == LANGUAGE_JPN) ? LANGUAGE_ENG : gSaveContext.language,
|
||||
format);
|
||||
return GetForLanguage(
|
||||
((Language)gSaveContext.language == LANGUAGE_JPN) ? LANGUAGE_ENG : (Language)gSaveContext.language, format);
|
||||
}
|
||||
|
||||
const std::string CustomMessage::GetForLanguage(uint8_t language, MessageFormat format) const {
|
||||
std::string output = messages[language] != TODO_TRANSLATE ? messages[language] : messages[LANGUAGE_ENG];
|
||||
std::string output = !messages[language].starts_with(TODO_TRANSLATE) ? messages[language] : messages[LANGUAGE_ENG];
|
||||
ProcessMessageFormat(output, format);
|
||||
return output;
|
||||
}
|
||||
|
||||
@@ -47,6 +47,7 @@ class CustomMessage {
|
||||
TextBoxPosition position_ = TEXTBOX_POS_BOTTOM);
|
||||
CustomMessage(std::string english_, TextBoxType type_ = TEXTBOX_TYPE_BLACK,
|
||||
TextBoxPosition position_ = TEXTBOX_POS_BOTTOM);
|
||||
// RANDOTODO trying to declare this with capital and type causes ambiguity with the first signature
|
||||
CustomMessage(std::string english_, std::vector<std::string> colors_, std::vector<bool> capital_ = {},
|
||||
TextBoxType type_ = TEXTBOX_TYPE_BLACK, TextBoxPosition position_ = TEXTBOX_POS_BOTTOM);
|
||||
CustomMessage(Text text, TextBoxType type_ = TEXTBOX_TYPE_BLACK, TextBoxPosition position_ = TEXTBOX_POS_BOTTOM);
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
#include "soh/Enhancements/game-interactor/GameInteractor.h"
|
||||
#include "soh/Enhancements/cosmetics/CosmeticsEditor.h"
|
||||
#include "soh/Enhancements/audio/AudioEditor.h"
|
||||
#include "soh/Enhancements/randomizer/logic.h"
|
||||
|
||||
#define Path _Path
|
||||
#define PATH_HACK
|
||||
@@ -1450,6 +1451,52 @@ static bool SfxHandler(std::shared_ptr<Ship::Console> Console, const std::vector
|
||||
return 0;
|
||||
}
|
||||
|
||||
static bool AvailableChecksProcessUndiscoveredExitsHandler(std::shared_ptr<Ship::Console> Console,
|
||||
const std::vector<std::string>& args, std::string* output) {
|
||||
const auto& logic = Rando::Context::GetInstance()->GetLogic();
|
||||
bool enabled = false;
|
||||
|
||||
if (args.size() == 1) {
|
||||
enabled = !logic->ACProcessUndiscoveredExits;
|
||||
} else {
|
||||
try {
|
||||
enabled = std::stoi(args[1]);
|
||||
} catch (std::invalid_argument const& ex) {
|
||||
ERROR_MESSAGE("[SOH] Enable should be 0 or 1");
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
logic->ACProcessUndiscoveredExits = enabled;
|
||||
INFO_MESSAGE("[SOH] Available Checks - Process Undiscovered Exits %s",
|
||||
logic->ACProcessUndiscoveredExits ? "enabled" : "disabled");
|
||||
|
||||
CheckTracker::RecalculateAvailableChecks();
|
||||
return 0;
|
||||
}
|
||||
|
||||
static bool AvailableChecksRecalculateHandler(std::shared_ptr<Ship::Console> Console,
|
||||
const std::vector<std::string>& args, std::string* output) {
|
||||
RandomizerRegion startingRegion = RR_ROOT;
|
||||
|
||||
if (args.size() > 1) {
|
||||
try {
|
||||
startingRegion = static_cast<RandomizerRegion>(std::stoi(args[1]));
|
||||
} catch (std::invalid_argument const& ex) {
|
||||
ERROR_MESSAGE("[SOH] Region should be a number");
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (startingRegion <= RR_NONE || startingRegion >= RR_MAX) {
|
||||
ERROR_MESSAGE("[SOH] Region should be between 1 and %d", RR_MAX - 1);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
CheckTracker::RecalculateAvailableChecks(startingRegion);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void DebugConsole_Init(void) {
|
||||
// Console
|
||||
CMD_REGISTER("file_select", { FileSelectHandler, "Returns to the file select." });
|
||||
@@ -1708,5 +1755,15 @@ void DebugConsole_Init(void) {
|
||||
{ "group_name", Ship::ArgumentType::TEXT, true },
|
||||
} });
|
||||
|
||||
CMD_REGISTER("acpue", { AvailableChecksProcessUndiscoveredExitsHandler,
|
||||
"Available Checks - Process Undiscovered Exits",
|
||||
{ { "enable", Ship::ArgumentType::NUMBER, true } } });
|
||||
|
||||
CMD_REGISTER("acr", { AvailableChecksRecalculateHandler,
|
||||
"Available Checks - Recalculate",
|
||||
{
|
||||
{ "starting_region", Ship::ArgumentType::NUMBER, true },
|
||||
} });
|
||||
|
||||
Ship::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesNextFrame();
|
||||
}
|
||||
|
||||
@@ -11,8 +11,13 @@
|
||||
|
||||
extern "C" {
|
||||
#include <z64.h>
|
||||
#include "src/overlays/actors/ovl_En_Rr/z_en_rr.h"
|
||||
}
|
||||
|
||||
#define CVAR_ENEMY_RANDOMIZER_NAME CVAR_ENHANCEMENT("RandomizedEnemies")
|
||||
#define CVAR_ENEMY_RANDOMIZER_DEFAULT ENEMY_RANDOMIZER_OFF
|
||||
#define CVAR_ENEMY_RANDOMIZER_VALUE CVarGetInteger(CVAR_ENEMY_RANDOMIZER_NAME, CVAR_ENEMY_RANDOMIZER_DEFAULT)
|
||||
|
||||
const char* enemyCVarList[] = {
|
||||
CVAR_ENHANCEMENT("RandomizedEnemyList.Armos"), CVAR_ENHANCEMENT("RandomizedEnemyList.Arwing"),
|
||||
CVAR_ENHANCEMENT("RandomizedEnemyList.BabyDodongo"), CVAR_ENHANCEMENT("RandomizedEnemyList.Bari"),
|
||||
@@ -270,15 +275,7 @@ extern "C" uint8_t GetRandomizedEnemy(PlayState* play, int16_t* actorId, f32* po
|
||||
// Get randomized enemy ID and parameter.
|
||||
uint32_t seed =
|
||||
play->sceneNum + *actorId + (int)*posX + (int)*posY + (int)*posZ + *rotX + *rotY + *rotZ + *params;
|
||||
EnemyEntry randomEnemy = GetRandomizedEnemyEntry(seed);
|
||||
|
||||
int8_t timesRandomized = 1;
|
||||
|
||||
// While randomized enemy isn't allowed in certain situations, randomize again.
|
||||
while (!IsEnemyAllowedToSpawn(play->sceneNum, play->roomCtx.curRoom.num, randomEnemy)) {
|
||||
randomEnemy = GetRandomizedEnemyEntry(seed + timesRandomized);
|
||||
timesRandomized++;
|
||||
}
|
||||
EnemyEntry randomEnemy = GetRandomizedEnemyEntry(seed, play);
|
||||
|
||||
*actorId = randomEnemy.id;
|
||||
*params = randomEnemy.params;
|
||||
@@ -334,19 +331,28 @@ void GetSelectedEnemies() {
|
||||
}
|
||||
}
|
||||
|
||||
EnemyEntry GetRandomizedEnemyEntry(uint32_t seed) {
|
||||
EnemyEntry GetRandomizedEnemyEntry(uint32_t seed, PlayState* play) {
|
||||
std::vector<EnemyEntry> filteredEnemyList = {};
|
||||
if (selectedEnemyList.size() == 0) {
|
||||
GetSelectedEnemies();
|
||||
}
|
||||
if (CVarGetInteger(CVAR_ENHANCEMENT("RandomizedEnemies"), ENEMY_RANDOMIZER_OFF) == ENEMY_RANDOMIZER_RANDOM_SEEDED) {
|
||||
for (EnemyEntry enemy : selectedEnemyList) {
|
||||
if (IsEnemyAllowedToSpawn(play->sceneNum, play->roomCtx.curRoom.num, enemy)) {
|
||||
filteredEnemyList.push_back(enemy);
|
||||
}
|
||||
}
|
||||
if (filteredEnemyList.size() == 0) {
|
||||
filteredEnemyList = selectedEnemyList;
|
||||
}
|
||||
if (CVAR_ENEMY_RANDOMIZER_VALUE == ENEMY_RANDOMIZER_RANDOM_SEEDED) {
|
||||
uint32_t finalSeed =
|
||||
seed + (IS_RANDO ? Rando::Context::GetInstance()->GetSeed() : gSaveContext.ship.stats.fileCreatedAt);
|
||||
Random_Init(finalSeed);
|
||||
uint32_t randomNumber = Random(0, selectedEnemyList.size());
|
||||
return selectedEnemyList[randomNumber];
|
||||
uint32_t randomNumber = Random(0, filteredEnemyList.size());
|
||||
return filteredEnemyList[randomNumber];
|
||||
} else {
|
||||
uint32_t randomSelectedEnemy = Random(0, selectedEnemyList.size());
|
||||
return selectedEnemyList[randomSelectedEnemy];
|
||||
uint32_t randomSelectedEnemy = Random(0, filteredEnemyList.size());
|
||||
return filteredEnemyList[randomSelectedEnemy];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -427,11 +433,9 @@ bool IsEnemyAllowedToSpawn(int16_t sceneNum, int8_t roomNum, EnemyEntry enemy) {
|
||||
// Shell Blade & Spike - Child Link can't kill these with sword or Deku Stick.
|
||||
// Arwing & Dark Link - Both go out of bounds way too easily, softlocking the player.
|
||||
// Wallmaster - Not easily visible, often makes players think they're softlocked and that there's no enemies left.
|
||||
// Club Moblin - Many issues with them falling or placing out of bounds. Maybe fixable in the future?
|
||||
bool enemiesToExcludeClearRooms = enemy.id == ACTOR_EN_FZ || enemy.id == ACTOR_EN_VM || enemy.id == ACTOR_EN_SB ||
|
||||
enemy.id == ACTOR_EN_NY || enemy.id == ACTOR_EN_CLEAR_TAG ||
|
||||
enemy.id == ACTOR_EN_WALLMAS || enemy.id == ACTOR_EN_TORCH2 ||
|
||||
enemy.id == ACTOR_EN_MB;
|
||||
enemy.id == ACTOR_EN_WALLMAS || enemy.id == ACTOR_EN_TORCH2;
|
||||
|
||||
// Bari - Spawns 3 more enemies, potentially extremely difficult in timed rooms.
|
||||
bool enemiesToExcludeTimedRooms = enemiesToExcludeClearRooms || enemy.id == ACTOR_EN_VALI;
|
||||
@@ -532,3 +536,45 @@ bool IsEnemyAllowedToSpawn(int16_t sceneNum, int8_t roomNum, EnemyEntry enemy) {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
void RegisterEnemyRandomizer() {
|
||||
// prevent dark link from triggering a voidout
|
||||
COND_VB_SHOULD(VB_TRIGGER_VOIDOUT, CVAR_ENEMY_RANDOMIZER_VALUE != CVAR_ENEMY_RANDOMIZER_DEFAULT, {
|
||||
Actor* actor = va_arg(args, Actor*);
|
||||
|
||||
if (actor->category != ACTORCAT_PLAYER) {
|
||||
*should = false;
|
||||
Actor_Kill(actor);
|
||||
}
|
||||
});
|
||||
|
||||
// prevent dark link dealing fall damage to the player
|
||||
COND_VB_SHOULD(VB_RECIEVE_FALL_DAMAGE, CVAR_ENEMY_RANDOMIZER_VALUE != CVAR_ENEMY_RANDOMIZER_DEFAULT, {
|
||||
Actor* actor = va_arg(args, Actor*);
|
||||
|
||||
if (actor->category != ACTORCAT_PLAYER) {
|
||||
*should = false;
|
||||
}
|
||||
});
|
||||
|
||||
// prevent dark link from interfering with HESS/recoil/etc when at more than 100 away from him
|
||||
COND_VB_SHOULD(VB_TORCH2_HANDLE_CLANKING, CVAR_ENEMY_RANDOMIZER_VALUE != CVAR_ENEMY_RANDOMIZER_DEFAULT, {
|
||||
Actor* darkLink = va_arg(args, Actor*);
|
||||
|
||||
if (darkLink->xzDistToPlayer > 100.0f) {
|
||||
*should = false;
|
||||
}
|
||||
});
|
||||
|
||||
// prevent dark link from being grabbed by like likes and therefore grabbing the player
|
||||
COND_VB_SHOULD(VB_LIKE_LIKE_GRAB_PLAYER, CVAR_ENEMY_RANDOMIZER_VALUE != CVAR_ENEMY_RANDOMIZER_DEFAULT, {
|
||||
EnRr* likeLike = va_arg(args, EnRr*);
|
||||
|
||||
if (!(likeLike->collider1.base.oc != NULL && likeLike->collider1.base.oc->category == ACTORCAT_PLAYER) &&
|
||||
!(likeLike->collider2.base.oc != NULL && likeLike->collider2.base.oc->category == ACTORCAT_PLAYER)) {
|
||||
*should = false;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
static RegisterShipInitFunc initFunc(RegisterEnemyRandomizer, { CVAR_ENEMY_RANDOMIZER_NAME });
|
||||
@@ -1,6 +1,7 @@
|
||||
#pragma once
|
||||
|
||||
#include <libultraship/bridge.h>
|
||||
#include "item-tables/ItemTableTypes.h"
|
||||
|
||||
typedef struct EnemyEntry {
|
||||
int16_t id;
|
||||
@@ -11,7 +12,7 @@ typedef struct EnemyEntry {
|
||||
|
||||
bool IsEnemyFoundToRandomize(int16_t sceneNum, int8_t roomNum, int16_t actorId, int16_t params, float posX);
|
||||
bool IsEnemyAllowedToSpawn(int16_t sceneNum, int8_t roomNum, EnemyEntry enemy);
|
||||
EnemyEntry GetRandomizedEnemyEntry(uint32_t seed);
|
||||
EnemyEntry GetRandomizedEnemyEntry(uint32_t seed, PlayState* play);
|
||||
|
||||
extern const char* enemyCVarList[];
|
||||
extern const char* enemyNameList[];
|
||||
|
||||
@@ -474,6 +474,14 @@ typedef enum {
|
||||
// - `*BgHeavyBlock`
|
||||
VB_FREEZE_LINK_FOR_BLOCK_THROW,
|
||||
|
||||
// #### `result`
|
||||
// ```c
|
||||
// true
|
||||
// ```
|
||||
// #### `args`
|
||||
// - None
|
||||
VB_FREEZE_LINK_FOR_FOREST_PILLARS,
|
||||
|
||||
// #### `result`
|
||||
// ```c
|
||||
// true
|
||||
@@ -1358,6 +1366,14 @@ typedef enum {
|
||||
// - `*BgTreemouth`
|
||||
VB_PLAY_DEKU_TREE_INTRO_CS,
|
||||
|
||||
// #### `result`
|
||||
// ```c
|
||||
// true
|
||||
// ```
|
||||
// #### `args`
|
||||
// - `*DemoKekkai`
|
||||
VB_PLAY_DISPEL_BARRIER_CS,
|
||||
|
||||
// #### `result`
|
||||
// ```c
|
||||
// true
|
||||
@@ -1422,6 +1438,15 @@ typedef enum {
|
||||
// - None
|
||||
VB_PLAY_FIRE_ARROW_CS,
|
||||
|
||||
// #### `result`
|
||||
// ```c
|
||||
// true
|
||||
// ```
|
||||
// #### `args`
|
||||
// - `*EnHeishi2`
|
||||
// - `bool` (clearCamera - true if the code clears a sub-camera, false otherwise)
|
||||
VB_PLAY_GATE_OPENING_OR_CLOSING_CS,
|
||||
|
||||
// #### `result`
|
||||
// ```c
|
||||
// true
|
||||
@@ -1986,6 +2011,38 @@ typedef enum {
|
||||
// #### `args`
|
||||
// - `*EnWonderTalk2`
|
||||
VB_WONDER_TALK,
|
||||
|
||||
// #### `result`
|
||||
// ```c
|
||||
// true
|
||||
// ```
|
||||
// #### `args`
|
||||
// - `*Actor`
|
||||
VB_TRIGGER_VOIDOUT,
|
||||
|
||||
// #### `result`
|
||||
// ```c
|
||||
// true
|
||||
// ```
|
||||
// #### `args`
|
||||
// - `*Actor`
|
||||
VB_TORCH2_HANDLE_CLANKING,
|
||||
|
||||
// #### `result`
|
||||
// ```c
|
||||
// true
|
||||
// ```
|
||||
// #### `args`
|
||||
// - `*Actor`
|
||||
VB_RECIEVE_FALL_DAMAGE,
|
||||
|
||||
// #### `result`
|
||||
// ```c
|
||||
// true
|
||||
// ```
|
||||
// #### `args`
|
||||
// - `*EnRr`
|
||||
VB_LIKE_LIKE_GRAB_PLAYER,
|
||||
} GIVanillaBehavior;
|
||||
|
||||
#endif
|
||||
|
||||
@@ -99,6 +99,13 @@ void SwitchAge() {
|
||||
gSaveContext.nextTransitionType = TRANS_TYPE_FADE_BLACK_FAST;
|
||||
gPlayState->linkAgeOnLoad ^= 1;
|
||||
|
||||
// Discover adult/child spawns
|
||||
if (gPlayState->linkAgeOnLoad == LINK_AGE_ADULT) {
|
||||
Entrance_SetEntranceDiscovered(ENTR_HYRULE_FIELD_10, false);
|
||||
} else {
|
||||
Entrance_SetEntranceDiscovered(ENTR_LINKS_HOUSE_CHILD_SPAWN, false);
|
||||
}
|
||||
|
||||
static HOOK_ID hookId = 0;
|
||||
hookId = REGISTER_VB_SHOULD(VB_INFLICT_VOID_DAMAGE, {
|
||||
*should = false;
|
||||
|
||||
@@ -209,6 +209,13 @@ void ProcessExits(Region* region, GetAccessibleLocationsStruct& gals, Randomizer
|
||||
bool stopOnBeatable = false, bool addToPlaythrough = false) {
|
||||
auto ctx = Rando::Context::GetInstance();
|
||||
for (auto& exit : region->exits) {
|
||||
int16_t entranceIndex = exit.GetIndex();
|
||||
if (!logic->ACProcessUndiscoveredExits && logic->CalculatingAvailableChecks &&
|
||||
ctx->GetOption(RSK_SHUFFLE_ENTRANCES).Get() && exit.IsShuffled() && entranceIndex != -1 &&
|
||||
!Entrance_GetIsEntranceDiscovered(entranceIndex)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
Region* exitRegion = exit.GetConnectedRegion();
|
||||
// Update Time of Day Access for the exit
|
||||
if (UpdateToDAccess(&exit, exitRegion)) {
|
||||
@@ -421,18 +428,13 @@ bool AddCheckToLogic(LocationAccess& locPair, GetAccessibleLocationsStruct& gals
|
||||
Rando::ItemLocation* location = ctx->GetItemLocation(loc);
|
||||
RandomizerGet locItem = location->GetPlacedRandomizerGet();
|
||||
|
||||
if (!location->IsAddedToPool() && locPair.ConditionsMet(parentRegion, gals.calculatingAvailableChecks)) {
|
||||
if (gals.calculatingAvailableChecks) {
|
||||
gals.accessibleLocations.push_back(loc);
|
||||
StopPerformanceTimer(PT_LOCATION_LOGIC);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!location->IsAddedToPool() && locPair.ConditionsMet(parentRegion, logic->CalculatingAvailableChecks)) {
|
||||
location->AddToPool();
|
||||
|
||||
if (locItem == RG_NONE) {
|
||||
if (locItem == RG_NONE || logic->CalculatingAvailableChecks) {
|
||||
gals.accessibleLocations.push_back(loc); // Empty location, consider for placement
|
||||
} else {
|
||||
}
|
||||
if (locItem != RG_NONE) {
|
||||
// If ignore has a value, we want to check if the item location should be considered or not
|
||||
// This is necessary due to the below preprocessing for playthrough generation
|
||||
if (ignore != RG_NONE) {
|
||||
@@ -528,11 +530,32 @@ void ProcessRegion(Region* region, GetAccessibleLocationsStruct& gals, Randomize
|
||||
// Return any of the targetLocations that are accessible in logic
|
||||
std::vector<RandomizerCheck> ReachabilitySearch(const std::vector<RandomizerCheck>& targetLocations,
|
||||
RandomizerGet ignore /* = RG_NONE*/,
|
||||
bool calculatingAvailableChecks /* = false */) {
|
||||
bool calculatingAvailableChecks /* = false */,
|
||||
RandomizerRegion startingRegion /* = RR_ROOT */) {
|
||||
auto ctx = Rando::Context::GetInstance();
|
||||
GetAccessibleLocationsStruct gals(0);
|
||||
gals.calculatingAvailableChecks = calculatingAvailableChecks;
|
||||
ResetLogic(ctx, gals, !calculatingAvailableChecks);
|
||||
if (startingRegion != RR_ROOT) {
|
||||
gals.regionPool.insert(gals.regionPool.begin(), startingRegion);
|
||||
|
||||
const auto& region = RegionTable(startingRegion);
|
||||
if (ctx->GetOption(RSK_SELECTED_STARTING_AGE).Is(RO_AGE_CHILD)) {
|
||||
region->childDay = true;
|
||||
} else {
|
||||
region->adultDay = true;
|
||||
}
|
||||
if (region->timePass) {
|
||||
if (ctx->GetOption(RSK_SELECTED_STARTING_AGE).Is(RO_AGE_CHILD)) {
|
||||
region->childNight = true;
|
||||
} else {
|
||||
region->adultNight = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (calculatingAvailableChecks) {
|
||||
logic->Reset(false);
|
||||
logic->CalculatingAvailableChecks = true;
|
||||
}
|
||||
do {
|
||||
gals.InitLoop();
|
||||
for (size_t i = 0; i < gals.regionPool.size(); i++) {
|
||||
@@ -625,6 +648,8 @@ void ValidateEntrances(bool checkPoeCollectorAccess, bool checkOtherEntranceAcce
|
||||
if (ctx->GetOption(RSK_SHUFFLE_INTERIOR_ENTRANCES).Is(RO_INTERIOR_ENTRANCE_SHUFFLE_OFF)) {
|
||||
Rando::StaticData::RetrieveItem(RG_GUARD_HOUSE_KEY).ApplyEffect();
|
||||
}
|
||||
RegionTable(RR_ROOT)->adultNight = true;
|
||||
RegionTable(RR_ROOT)->adultDay = true;
|
||||
} else {
|
||||
ApplyAllAdvancmentItems();
|
||||
}
|
||||
|
||||
@@ -34,8 +34,6 @@ struct GetAccessibleLocationsStruct {
|
||||
std::vector<RandomizerCheck> itemSphere;
|
||||
std::list<Rando::Entrance*> entranceSphere;
|
||||
|
||||
bool calculatingAvailableChecks = false;
|
||||
|
||||
GetAccessibleLocationsStruct(int _maxGsCount){
|
||||
regionPool = {RR_ROOT};
|
||||
gsCount = 0;
|
||||
@@ -58,16 +56,17 @@ struct GetAccessibleLocationsStruct {
|
||||
void ClearProgress();
|
||||
void VanillaFill();
|
||||
int Fill();
|
||||
void SetAreas();
|
||||
|
||||
std::vector<RandomizerCheck> GetEmptyLocations(std::vector<RandomizerCheck> allowedLocations);
|
||||
|
||||
void ProcessRegion(Region* region, GetAccessibleLocationsStruct& gals, RandomizerGet ignore = RG_NONE,
|
||||
bool stopOnBeatable = false, bool addToPlaythrough = false);
|
||||
|
||||
std::vector<RandomizerCheck> ReachabilitySearch(const std::vector<RandomizerCheck>& allowedLocations, RandomizerGet ignore=RG_NONE, bool calculatingAvailableChecks=false);
|
||||
std::vector<RandomizerCheck> ReachabilitySearch(const std::vector<RandomizerCheck>& allowedLocations, RandomizerGet ignore=RG_NONE, bool calculatingAvailableChecks=false, RandomizerRegion startingRegion=RR_ROOT);
|
||||
|
||||
void GeneratePlaythrough();
|
||||
|
||||
bool CheckBeatable(RandomizerGet ignore=RG_NONE);
|
||||
|
||||
void ValidateEntrances(bool checkPoeCollectorAccess, bool checkOtherEntranceAccess);
|
||||
void ValidateEntrances(bool checkPoeCollectorAccess, bool checkOtherEntranceAccess);
|
||||
|
||||
@@ -1976,27 +1976,27 @@ void StaticData::HintTable_Init() {
|
||||
hintTextTable[RHT_BRIDGE_OPEN_HINT] = HintText(CustomMessage("$lThe awakened ones have #already created a bridge# to the castle where the evil dwells.^",
|
||||
/*german*/ "$lDie Weisen haben #bereits&eine Brücke zum Portal von&Ganons Schloß gelegt#...^",
|
||||
/*french*/ "$lLes êtres de sagesse ont#déjà créé un pont# vers le repaire du mal.^",
|
||||
{QM_LBLUE}));
|
||||
{QM_LBLUE}, {}, TEXTBOX_TYPE_BLUE));
|
||||
// /*spanish*/$lLos sabios #ya habrán creado un puente#&al castillo, de donde emana el mal.^
|
||||
|
||||
|
||||
hintTextTable[RHT_BRIDGE_VANILLA_HINT] = HintText(CustomMessage("$6The awakened ones require the #Shadow and Spirit Medallions# as well as the #Light Arrows#.^",
|
||||
/*german*/ "$6Die Weisen werden darauf warten, daß der Held das #Amulett des Schattens, Amulett der Geister# und die #Licht-Pfeile# sammelt.^",
|
||||
/*french*/ "$6Les êtres de sagesse attendront le héros muni des #Médaillons de l'Ombre et l'Esprit# et des #Flèches de Lumière#.^",
|
||||
{QM_RED, QM_YELLOW}));
|
||||
{QM_RED, QM_YELLOW}, {}, TEXTBOX_TYPE_BLUE));
|
||||
// /*spanish*/$6Los sabios aguardarán a que el héroe obtenga tanto el #Medallón de las Sombras y el del Espíritu# junto
|
||||
// a la #flecha de luz#.^
|
||||
|
||||
hintTextTable[RHT_BRIDGE_STONES_HINT] = HintText(CustomMessage("$0The awakened ones will await for the Hero to collect #[[d]] Spiritual Stone||s|#.^",
|
||||
/*german*/ "$0Die Weisen werden darauf warten, daß der Held #[[d]] |Heiligen Stein|Heilige Steine|# sammelt.^",
|
||||
/*french*/ "$0Les êtres de sagesse attendront le héros muni de #[[d]] |Pierre Ancestrale|Pierres Ancestrales|#.^",
|
||||
{QM_BLUE}));
|
||||
{QM_BLUE}, {}, TEXTBOX_TYPE_BLUE));
|
||||
// /*spanish*/$0Los sabios aguardarán a que el héroe&obtenga #[[d]] |piedra espiritual|piedras espirituales|#.^
|
||||
|
||||
hintTextTable[RHT_BRIDGE_MEDALLIONS_HINT] = HintText(CustomMessage("$8The awakened ones will await for the Hero to collect #[[d]] Medallion||s|#.^",
|
||||
/*german*/ "$8Die Weisen werden darauf warten, daß der Held #[[d]] Amulett||e|# sammelt.^",
|
||||
/*french*/ "$8Les êtres de sagesse attendront le héros muni de #[[d]] Médaillon||s|#.^",
|
||||
{QM_RED}));
|
||||
{QM_RED}, {}, TEXTBOX_TYPE_BLUE));
|
||||
// /*spanish*/$8Los sabios aguardarán a que el héroe&obtenga #[[d]] |medallón|medallones|#.^
|
||||
|
||||
hintTextTable[RHT_BRIDGE_REWARDS_HINT] = HintText(CustomMessage("$CThe awakened ones will await for the Hero to collect #[[d]]# |#Spiritual Stone# or #Medallion#|"
|
||||
@@ -2005,24 +2005,24 @@ void StaticData::HintTable_Init() {
|
||||
"#Heilige Steine# oder #Amulette#| sammelt.^",
|
||||
/*french*/ "$CLes êtres de sagesse attendront le héros muni de #[[d]]# |#Pierre Ancestrale# ou #Médaillon#"
|
||||
"|#Pierres Ancestrales# ou #Médaillons#|.^",
|
||||
{QM_YELLOW, QM_BLUE, QM_RED}));
|
||||
{QM_YELLOW, QM_BLUE, QM_RED}, {}, TEXTBOX_TYPE_BLUE));
|
||||
// /*spanish*/$CLos sabios aguardarán a que el héroe obtenga #[[d]]# |#piedra espiritual# o #medallón#|
|
||||
//#piedras espirtuales# y #medallones#|.^
|
||||
|
||||
hintTextTable[RHT_BRIDGE_DUNGEONS_HINT] = HintText(CustomMessage("$mThe awakened ones will await for the Hero to conquer #[[d]] Dungeon||s|#.^",
|
||||
/*german*/ "$mDie Weisen werden darauf warten, daß der Held #[[d]] Labyrinth||e|# abschließt.^",
|
||||
/*french*/ "$mLes êtres de sagesse attendront la conquête de #[[d]] Donjon||s|#.^",
|
||||
{QM_PINK}));
|
||||
{QM_PINK}, {}, TEXTBOX_TYPE_BLUE));
|
||||
// /*spanish*/$mLos sabios aguardarán a que el héroe complete #[[d]] mazmorra||s|#.^
|
||||
|
||||
hintTextTable[RHT_BRIDGE_TOKENS_HINT] = HintText(CustomMessage("$sThe awakened ones will await for the Hero to collect #[[d]] Gold Skulltula Token||s|#.^",
|
||||
/*german*/ "$sDie Weisen werden darauf warten, daß der Held #[[d]] Skulltula-Symbol||e|# sammelt.^",
|
||||
/*french*/ "$sLes êtres de sagesse attendront le héros muni de #[[d]] Symbole||s| de Skulltula d'or#.^",
|
||||
{QM_YELLOW}));
|
||||
{QM_YELLOW}, {}, TEXTBOX_TYPE_BLUE));
|
||||
// /*spanish*/$sLos sabios aguardarán a que el héroe obtenga #[[d]] símbolo||s| de skulltula dorada#.^
|
||||
|
||||
hintTextTable[RHT_BRIDGE_GREG_HINT] = HintText(CustomMessage("$gThe awakened ones will await for the Hero to find #Greg#.^",
|
||||
{QM_GREEN}));
|
||||
hintTextTable[RHT_BRIDGE_GREG_HINT] = HintText(CustomMessage("$gThe awakened ones will await for the Hero to find #Greg#.^", TODO_TRANSLATE, TODO_TRANSLATE,
|
||||
{QM_GREEN}, {}, TEXTBOX_TYPE_BLUE));
|
||||
|
||||
|
||||
/*--------------------------
|
||||
@@ -2176,22 +2176,22 @@ void StaticData::HintTable_Init() {
|
||||
hintTextTable[RHT_CHILD_ALTAR_STONES] = HintText(CustomMessage("3 Spiritual Stones found in Hyrule...^$0#[[1]]#...^$1#[[2]]#...^$2#[[3]]#...^",
|
||||
/*german*/ "Drei Heilige Steine, zu finden in Hyrule...$0#[[1]]#...^$1#[[2]]#...^$2#[[3]]#...^",
|
||||
/*french*/ "Les trois Pierres Ancestrales cachées&dans Hyrule...$0#[[1]]#...^$1#[[2]]#...^$2#[[3]]#...^",
|
||||
{QM_GREEN, QM_RED, QM_BLUE}, {true, true, true}));
|
||||
{QM_GREEN, QM_RED, QM_BLUE}, {true, true, true}, TEXTBOX_TYPE_BLUE));
|
||||
// /*spanish*/ Tres piedras espirituales halladas por Hyrule...$0#[[1]]#...^$1#[[2]]#...^$2#[[3]]#...^
|
||||
|
||||
hintTextTable[RHT_CHILD_ALTAR_TEXT_END_DOTOPEN] = HintText(CustomMessage("$oYe who may become a Hero...&The path to the future is open...",
|
||||
/*german*/ "$oJener auf dem Weg des Helden...&Der Pfad zur Zukunft sei geöffnet...",
|
||||
/*french*/ "$oÀ celui qui a quête de devenir&héros...&Le futur vous accueille béant..."));
|
||||
/*french*/ "$oÀ celui qui a quête de devenir&héros...&Le futur vous accueille béant...", TEXTBOX_TYPE_BLUE));
|
||||
// /*spanish*/$oPara aquel que se convierta en el héroe...&La puerta al futuro está a su disposición...
|
||||
|
||||
hintTextTable[RHT_CHILD_ALTAR_TEXT_END_DOTSONGONLY] = HintText(CustomMessage("$cYe who may become a Hero...&Stand with the Ocarina and&play the Song of Time.",
|
||||
/*german*/ "$cJener auf dem Weg des Helden...&Nehme er seine Okarina zur Hand und&spiele hier die Hymne der Zeit.",
|
||||
/*french*/ "$cÀ celui qui a quête de devenir&héros...&Portez l'Ocarina et jouez&le chant du temps."));
|
||||
/*french*/ "$cÀ celui qui a quête de devenir&héros...&Portez l'Ocarina et jouez&le chant du temps.", TEXTBOX_TYPE_BLUE));
|
||||
// /*spanish*/$cPara aquel que se convierta en el héroe...&Tome la ocarina y&entone la Canción del Tiempo.
|
||||
|
||||
hintTextTable[RHT_CHILD_ALTAR_TEXT_END_DOTCLOSED] = HintText(CustomMessage("$iYe who may become a Hero...&Offer the spiritual stones and&play the Song of Time.",
|
||||
/*german*/ "$iJener mit den drei Heiligen Steinen&nehme seine Okarina zur Hand und&spiele hier die Hymne der Zeit.",
|
||||
/*french*/ "$iÀ celui qui a quête de devenir&héros... Présentez les Pierres&Ancestrales et jouez&le chant du temps."));
|
||||
/*french*/ "$iÀ celui qui a quête de devenir&héros... Présentez les Pierres&Ancestrales et jouez&le chant du temps.", TEXTBOX_TYPE_BLUE));
|
||||
// /*spanish*/$iPara aquel que se convierta en el héroe...&Tome las piedras espirituales y&entone la Canción del Tiempo.
|
||||
|
||||
hintTextTable[RHT_ADULT_ALTAR_MEDALLIONS] = HintText(CustomMessage("An awakening voice from the Sacred Realm will call those destined to be Sages, who dwell in the #five temples#.^"
|
||||
@@ -2412,13 +2412,13 @@ void StaticData::HintTable_Init() {
|
||||
|
||||
hintTextTable[RHT_ISOLATED_PLACE] = HintText(CustomMessage("an Isolated Place"));
|
||||
|
||||
hintTextTable[RHT_DUNGEON_ORDINARY] = HintText(CustomMessage(" It's ordinary.",
|
||||
/*german*/ "&Sieht aus wie immer.",
|
||||
/*french*/ "&Elle vous semble %rordinaire%w."));
|
||||
hintTextTable[RHT_DUNGEON_ORDINARY] = HintText(CustomMessage("&It's %gordinary%w.",
|
||||
/*german*/ "&Sieht aus %gwie immer%w.",
|
||||
/*french*/ "&Elle vous semble %gordinaire%w."));
|
||||
|
||||
hintTextTable[RHT_DUNGEON_MASTERFUL] = HintText(CustomMessage(" It's masterful!",
|
||||
/*german*/ "&Man kann darauf die Worte&%r\"Master Quest\"%w entziffern...",
|
||||
/*french*/ "&Étrange... les mots %r\"Master&Quest\"%w sont gravés dessus."));
|
||||
hintTextTable[RHT_DUNGEON_MASTERFUL] = HintText(CustomMessage("&It's %rmasterful%w!",
|
||||
/*german*/ "&Man kann darauf die Worte %r\"Master_Quest\"%w entziffern...",
|
||||
/*french*/ "&Étrange... les mots %r\"Master_Quest\"%w sont gravés dessus."));
|
||||
|
||||
// clang-format on
|
||||
}
|
||||
|
||||
@@ -313,11 +313,11 @@ void StaticData::HintTable_Init_Exclude_Overworld() {
|
||||
/*german*/ "Man erzählt sich, daß ein #Tauchexperiment# mit #[[1]]# belohnt würde.",
|
||||
/*french*/ "Selon moi, l'#expérience de plongée# donne #[[1]]#.", {QM_RED, QM_GREEN}));
|
||||
// /*spanish*/ Según dicen, #bucear para un experimento# se premia con #[[1]]#.
|
||||
// RANDOTODO: needs translation
|
||||
|
||||
hintTextTable[RHT_ZD_FISH] = HintText(CustomMessage("They say that a #fish by a waterfall# hoards #[[1]]#.",
|
||||
/*german*/ "Man erzählt sich, daß ein #Fisch nahe eines Wasserfalls# #[[1]]# horte.",
|
||||
/*french*/ "Selon moi, #[[1]]#.", {QM_RED, QM_GREEN}));
|
||||
// /*spanish*/ Según dicen, #[[1]]#.
|
||||
/*french*/ "Selon moi, un #poisson près d'une cascade# a #[[1]]#.", {QM_RED, QM_GREEN}));
|
||||
// /*spanish*/ Según dicen, un #pez junto a una cascada# otorga #[[1]]#.
|
||||
|
||||
|
||||
hintTextTable[RHT_GC_ROLLING_GORON_AS_ADULT] = HintText(CustomMessage("They say that #reassuring a young Goron# is rewarded with #[[1]]#.",
|
||||
@@ -1492,9 +1492,17 @@ void StaticData::HintTable_Init_Exclude_Overworld() {
|
||||
/*french*/ "Selon moi, une #rucheau derrière le Roi des Zoras# cache #[[1]]#.", {QM_RED, QM_GREEN}));
|
||||
// /*spanish*/ Según dicen, una #colmena detrás del rey de los zoras# esconde #[[1]]#.
|
||||
|
||||
hintTextTable[RHT_POT_KOKIRI_FOREST] = HintText(CustomMessage("They say that a #pot in Kokiri Forest# contains #[[1]]#.",
|
||||
/*german*/ "Man erzählt sich, daß eine #Vase im Kokiri-Wald# #[[1]]# enthielte.",
|
||||
/*french*/ "Selon moi, une #jarre dans la Fôret Kokiri# contient #[[1]]#.", {QM_RED, QM_GREEN}));
|
||||
hintTextTable[RHT_POT_LINKS_HOUSE] = HintText(CustomMessage("They say that the #pot in the hero's house# contains #[[1]]#.",
|
||||
/*german*/ "Man erzählt sich, daß eine #Vase im Kokiri-Wald# #[[1]]# enthielte.", //TODO_TRANSLATE update to match
|
||||
/*french*/ "Selon moi, une #jarre dans la Fôret Kokiri# contient #[[1]]#.", {QM_RED, QM_GREEN})); //TODO_TRANSLATE update to match
|
||||
|
||||
hintTextTable[RHT_POT_TWINS_HOUSE] = HintText(CustomMessage("They say that a #pot shared by twins# contains #[[1]]#.",
|
||||
/*german*/ "Man erzählt sich, daß eine #Vase im Kokiri-Wald# #[[1]]# enthielte.", //TODO_TRANSLATE update to match
|
||||
/*french*/ "Selon moi, une #jarre dans la Fôret Kokiri# contient #[[1]]#.", {QM_RED, QM_GREEN})); //TODO_TRANSLATE update to match
|
||||
|
||||
hintTextTable[RHT_POT_KNOW_IT_ALL] = HintText(CustomMessage("They say that a #know-it-all bother's pot# contains #[[1]]#.",
|
||||
/*german*/ "Man erzählt sich, daß eine #Vase im Kokiri-Wald# #[[1]]# enthielte.", //TODO_TRANSLATE update to match
|
||||
/*french*/ "Selon moi, une #jarre dans la Fôret Kokiri# contient #[[1]]#.", {QM_RED, QM_GREEN})); //TODO_TRANSLATE update to match
|
||||
|
||||
hintTextTable[RHT_POT_GERUDO_FORTRESS] = HintText(CustomMessage("They say that a #pot in Gerudo Fortress# contains #[[1]]#.",
|
||||
/*german*/ "Man erzählt sich, daß eine #Vase in der Gerudo-Festung# #[[1]]# enthielte.",
|
||||
@@ -1504,15 +1512,24 @@ void StaticData::HintTable_Init_Exclude_Overworld() {
|
||||
/*german*/ "Man erzählt sich, daß eine #Vase in der Gespensterwüste# #[[1]]# enthielte.",
|
||||
/*french*/ "Selon moi, une #jarre dans le Désert Hanté# contient #[[1]]#.", {QM_RED, QM_GREEN}));
|
||||
|
||||
hintTextTable[RHT_POT_MARKET] = HintText(CustomMessage("They say that a #pot in Market# contains #[[1]]#.",
|
||||
/*german*/ "Man erzählt sich, daß eine #Vase auf dem Markt# #[[1]]# enthielte.",
|
||||
/*french*/ "Selon moi, une #jarre dans la Place du Marché# contient #[[1]]#.", {QM_RED, QM_GREEN}));
|
||||
hintTextTable[RHT_POT_GUARD_HOUSE] = HintText(CustomMessage("They say that a #pot in the Guard House# contains #[[1]]#.",
|
||||
/*german*/ "Man erzählt sich, daß eine #Vase auf dem Markt# #[[1]]# enthielte.",//TODO_TRANSLATE update to match
|
||||
/*french*/ "Selon moi, une #jarre dans la Place du Marché# contient #[[1]]#.", {QM_RED, QM_GREEN}));//TODO_TRANSLATE update to match
|
||||
|
||||
hintTextTable[RHT_POT_POE_SHOP] = HintText(CustomMessage("They say that a #pot in the Poe Shop# contains #[[1]]#.",
|
||||
/*german*/ "Man erzählt sich, daß eine #Vase auf dem Markt# #[[1]]# enthielte.",//TODO_TRANSLATE update to match
|
||||
/*french*/ "Selon moi, une #jarre dans la Place du Marché# contient #[[1]]#.", {QM_RED, QM_GREEN}));//TODO_TRANSLATE update to match
|
||||
|
||||
hintTextTable[RHT_POT_ALLY_HOUSE] = HintText(CustomMessage("They say that a #bearded man's pot# contains #[[1]]#.",
|
||||
/*german*/ "Man erzählt sich, daß eine #Vase auf dem Markt# #[[1]]# enthielte.",//TODO_TRANSLATE update to match
|
||||
/*french*/ "Selon moi, une #jarre dans la Place du Marché# contient #[[1]]#.", {QM_RED, QM_GREEN}));//TODO_TRANSLATE update to match
|
||||
|
||||
hintTextTable[RHT_POT_KAKARIKO] = HintText(CustomMessage("They say that a #pot in Kakariko Village# contains #[[1]]#.",
|
||||
/*german*/ "Man erzählt sich, daß eine #Vase in Kakariko# #[[1]]# enthielte.",
|
||||
/*french*/ "Selon moi, une #jarre dans le Village de Cocorico# contient #[[1]]#.", {QM_RED, QM_GREEN}));
|
||||
|
||||
hintTextTable[RHT_POT_GRAVEYARD] = HintText(CustomMessage("They say that a #pot in Graveyard# contains #[[1]]#.",
|
||||
hintTextTable[RHT_POT_DAMPE] = HintText(CustomMessage("They say that a #pot in gravekeeper's tomb# contains #[[1]]#.",
|
||||
//TODO_TRANSLATE check these to make sure they refernce dampe's tomb not the graveyard area
|
||||
/*german*/ "Man erzählt sich, daß eine #Vase auf dem Friedhof# #[[1]]# enthielte.",
|
||||
/*french*/ "Selon moi, une #jarre dans le Cimetière# contient #[[1]]#.", {QM_RED, QM_GREEN}));
|
||||
|
||||
@@ -1536,13 +1553,17 @@ void StaticData::HintTable_Init_Exclude_Overworld() {
|
||||
/*german*/ "Man erzählt sich, daß eine #Vase auf der Lon Lon-Farm# #[[1]]# enthielte.",
|
||||
/*french*/ "Selon moi, une #jarre dans le Ranch Lon Lon# contient #[[1]]#.", {QM_RED, QM_GREEN}));
|
||||
|
||||
hintTextTable[RHT_POT_HYRULE_FIELD] = HintText(CustomMessage("They say that a #pot in Hyrule Field# contains #[[1]]#.",
|
||||
/*german*/ "Man erzählt sich, daß eine #Vase in der Hylianischen Steppe# #[[1]]# enthielte.",
|
||||
/*french*/ "Selon moi, une #jarre dans la Plaine d'Hyrule# contient #[[1]]#.", {QM_RED, QM_GREEN}));
|
||||
hintTextTable[RHT_POT_TALONS_HOUSE] = HintText(CustomMessage("They say that a #pot in Talon's Bedroom# contains #[[1]]#.",
|
||||
/*german*/ "Man erzählt sich, daß eine #Vase auf der Lon Lon-Farm# #[[1]]# enthielte.",//TODO_TRANSLATE update to match
|
||||
/*french*/ "Selon moi, une #jarre dans le Ranch Lon Lon# contient #[[1]]#.", {QM_RED, QM_GREEN}));//TODO_TRANSLATE update to match
|
||||
|
||||
hintTextTable[RHT_POT_HYRULE_CASTLE] = HintText(CustomMessage("They say that a #pot in Hyrule Castle# contains #[[1]]#.",
|
||||
/*german*/ "Man erzählt sich, daß eine #Vase in Schloß Hyrule# #[[1]]# enthielte.",
|
||||
/*french*/ "Selon moi, une #jarre dans le Château d'Hyrule# contient #[[1]]#.", {QM_RED, QM_GREEN}));
|
||||
hintTextTable[RHT_POT_WEB_GROTTO] = HintText(CustomMessage("They say that a #pot behind a grotto's webbing# contains #[[1]]#.",
|
||||
/*german*/ "Man erzählt sich, daß eine #Vase in der Hylianischen Steppe# #[[1]]# enthielte.",//TODO_TRANSLATE update to match
|
||||
/*french*/ "Selon moi, une #jarre dans la Plaine d'Hyrule# contient #[[1]]#.", {QM_RED, QM_GREEN}));//TODO_TRANSLATE update to match
|
||||
|
||||
hintTextTable[RHT_POT_MUD_WALL_GROTTO] = HintText(CustomMessage("They say that a #pot walled off in a grotto# contains #[[1]]#.",
|
||||
/*german*/ "Man erzählt sich, daß eine #Vase in Schloß Hyrule# #[[1]]# enthielte.",//TODO_TRANSLATE update to match
|
||||
/*french*/ "Selon moi, une #jarre dans le Château d'Hyrule# contient #[[1]]#.", {QM_RED, QM_GREEN}));//TODO_TRANSLATE update to match
|
||||
|
||||
hintTextTable[RHT_KOKIRI_FOREST_RUPEE] = HintText(CustomMessage("They say that a rupee in a #tranquil forest# hides #[[1]]#.",
|
||||
/*german*/ "Man erzählt sich, daß ein Rubin in einem #ruhigen Wald# #[[1]]# verstecke.",
|
||||
|
||||
@@ -648,6 +648,9 @@ void CreateStoneHints() {
|
||||
if (ctx->GetOption(RSK_SKIP_CHILD_ZELDA)) {
|
||||
ctx->GetItemLocation(RC_SONG_FROM_IMPA)->SetHintAccesible();
|
||||
}
|
||||
if (ctx->GetOption(RSK_SELECTED_STARTING_AGE).Is(RO_AGE_ADULT)) {
|
||||
ctx->GetItemLocation(RC_TOT_MASTER_SWORD)->SetHintAccesible();
|
||||
}
|
||||
|
||||
// Add 'always' location hints
|
||||
std::vector<RandomizerCheck> alwaysHintLocations = {};
|
||||
@@ -728,20 +731,22 @@ std::vector<RandomizerCheck> FindItemsAndMarkHinted(std::vector<RandomizerGet> i
|
||||
|
||||
void CreateChildAltarHint() {
|
||||
auto ctx = Rando::Context::GetInstance();
|
||||
if (!ctx->GetHint(RH_ALTAR_CHILD)->IsEnabled() && ctx->GetOption(RSK_TOT_ALTAR_HINT)) {
|
||||
if (!ctx->GetHint(RH_ALTAR_CHILD)->IsEnabled()) {
|
||||
std::vector<RandomizerCheck> stoneLocs = {};
|
||||
// force marking the rewards as hinted if they are at the end of dungeons as they can be inferred
|
||||
if (ctx->GetOption(RSK_SHUFFLE_DUNGEON_REWARDS).Is(RO_DUNGEON_REWARDS_END_OF_DUNGEON) ||
|
||||
ctx->GetOption(RSK_SHUFFLE_DUNGEON_REWARDS).Is(RO_DUNGEON_REWARDS_VANILLA)) {
|
||||
stoneLocs = FindItemsAndMarkHinted({ RG_KOKIRI_EMERALD, RG_GORON_RUBY, RG_ZORA_SAPPHIRE }, {});
|
||||
} else {
|
||||
stoneLocs =
|
||||
FindItemsAndMarkHinted({ RG_KOKIRI_EMERALD, RG_GORON_RUBY, RG_ZORA_SAPPHIRE }, { RC_ALTAR_HINT_CHILD });
|
||||
}
|
||||
std::vector<RandomizerArea> stoneAreas = {};
|
||||
for (auto loc : stoneLocs) {
|
||||
if (loc != RC_UNKNOWN_CHECK) {
|
||||
stoneAreas.push_back(ctx->GetItemLocation(loc)->GetRandomArea());
|
||||
if (ctx->GetOption(RSK_TOT_ALTAR_HINT)) {
|
||||
// force marking the rewards as hinted if they are at the end of dungeons as they can be inferred
|
||||
if (ctx->GetOption(RSK_SHUFFLE_DUNGEON_REWARDS).Is(RO_DUNGEON_REWARDS_END_OF_DUNGEON) ||
|
||||
ctx->GetOption(RSK_SHUFFLE_DUNGEON_REWARDS).Is(RO_DUNGEON_REWARDS_VANILLA)) {
|
||||
stoneLocs = FindItemsAndMarkHinted({ RG_KOKIRI_EMERALD, RG_GORON_RUBY, RG_ZORA_SAPPHIRE }, {});
|
||||
} else {
|
||||
stoneLocs = FindItemsAndMarkHinted({ RG_KOKIRI_EMERALD, RG_GORON_RUBY, RG_ZORA_SAPPHIRE },
|
||||
{ RC_ALTAR_HINT_CHILD });
|
||||
}
|
||||
for (auto loc : stoneLocs) {
|
||||
if (loc != RC_UNKNOWN_CHECK) {
|
||||
stoneAreas.push_back(ctx->GetItemLocation(loc)->GetRandomArea());
|
||||
}
|
||||
}
|
||||
}
|
||||
ctx->AddHint(RH_ALTAR_CHILD, Hint(RH_ALTAR_CHILD, HINT_TYPE_ALTAR_CHILD, {}, stoneLocs, stoneAreas));
|
||||
@@ -752,6 +757,7 @@ void CreateAdultAltarHint() {
|
||||
auto ctx = Rando::Context::GetInstance();
|
||||
if (!ctx->GetHint(RH_ALTAR_ADULT)->IsEnabled()) {
|
||||
std::vector<RandomizerCheck> medallionLocs = {};
|
||||
std::vector<RandomizerArea> medallionAreas = {};
|
||||
if (ctx->GetOption(RSK_TOT_ALTAR_HINT)) {
|
||||
// force marking the rewards as hinted if they are at the end of dungeons as they can be inferred
|
||||
if (ctx->GetOption(RSK_SHUFFLE_DUNGEON_REWARDS).Is(RO_DUNGEON_REWARDS_END_OF_DUNGEON) ||
|
||||
@@ -764,11 +770,10 @@ void CreateAdultAltarHint() {
|
||||
RG_WATER_MEDALLION, RG_SPIRIT_MEDALLION, RG_SHADOW_MEDALLION },
|
||||
{ RC_ALTAR_HINT_ADULT });
|
||||
}
|
||||
}
|
||||
std::vector<RandomizerArea> medallionAreas = {};
|
||||
for (auto loc : medallionLocs) {
|
||||
if (loc != RC_UNKNOWN_CHECK) {
|
||||
medallionAreas.push_back(ctx->GetItemLocation(loc)->GetRandomArea());
|
||||
for (auto loc : medallionLocs) {
|
||||
if (loc != RC_UNKNOWN_CHECK) {
|
||||
medallionAreas.push_back(ctx->GetItemLocation(loc)->GetRandomArea());
|
||||
}
|
||||
}
|
||||
}
|
||||
ctx->AddHint(RH_ALTAR_ADULT, Hint(RH_ALTAR_ADULT, HINT_TYPE_ALTAR_ADULT, {}, medallionLocs, medallionAreas));
|
||||
|
||||
@@ -354,7 +354,7 @@ void PlaceJunkInExcludedLocation(const RandomizerCheck il) {
|
||||
// place a non-advancement item in this location
|
||||
auto ctx = Rando::Context::GetInstance();
|
||||
for (size_t i = 0; i < ItemPool.size(); i++) {
|
||||
if (!Rando::StaticData::RetrieveItem(ItemPool[i]).IsAdvancement()) {
|
||||
if (Rando::StaticData::RetrieveItem(ItemPool[i]).GetCategory() == ITEM_CATEGORY_JUNK) {
|
||||
ctx->PlaceItemInLocation(il, ItemPool[i]);
|
||||
ItemPool.erase(ItemPool.begin() + i);
|
||||
return;
|
||||
@@ -861,7 +861,7 @@ void GenerateItemPool() {
|
||||
AddItemToMainPool(RG_GERUDO_MEMBERSHIP_CARD);
|
||||
ctx->possibleIceTrapModels.push_back(RG_GERUDO_MEMBERSHIP_CARD);
|
||||
} else if (ctx->GetOption(RSK_SHUFFLE_GERUDO_MEMBERSHIP_CARD)) {
|
||||
AddItemToPool(PendingJunkPool, RG_GERUDO_MEMBERSHIP_CARD);
|
||||
AddItemToPool(ItemPool, RG_GERUDO_MEMBERSHIP_CARD);
|
||||
ctx->PlaceItemInLocation(RC_GF_GERUDO_MEMBERSHIP_CARD, RG_ICE_TRAP, false, true);
|
||||
} else {
|
||||
ctx->PlaceItemInLocation(RC_GF_GERUDO_MEMBERSHIP_CARD, RG_GERUDO_MEMBERSHIP_CARD, false, true);
|
||||
|
||||
@@ -362,7 +362,7 @@ void Rando::StaticData::RegisterCrateLocations() {
|
||||
locationTable[RC_KAK_NEAR_IMPAS_HOUSE_ADULT_CRATE_1] = Location::Crate(RC_KAK_NEAR_IMPAS_HOUSE_ADULT_CRATE_1, RCQUEST_BOTH, RCAREA_KAKARIKO_VILLAGE, SCENE_KAKARIKO_VILLAGE, TWO_ACTOR_PARAMS(-389, 1518), "Near Impas House Adult Crate 1", RHT_CRATE_KAKARIKO_VILLAGE, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_KAK_NEAR_IMPAS_HOUSE_ADULT_CRATE_1));
|
||||
locationTable[RC_KAK_NEAR_IMPAS_HOUSE_ADULT_CRATE_2] = Location::Crate(RC_KAK_NEAR_IMPAS_HOUSE_ADULT_CRATE_2, RCQUEST_BOTH, RCAREA_KAKARIKO_VILLAGE, SCENE_KAKARIKO_VILLAGE, TWO_ACTOR_PARAMS(-389, 1470), "Near Impas House Adult Crate 2", RHT_CRATE_KAKARIKO_VILLAGE, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_KAK_NEAR_IMPAS_HOUSE_ADULT_CRATE_2));
|
||||
locationTable[RC_KAK_NEAR_BAZAAR_ADULT_CRATE_1] = Location::Crate(RC_KAK_NEAR_BAZAAR_ADULT_CRATE_1, RCQUEST_BOTH, RCAREA_KAKARIKO_VILLAGE, SCENE_KAKARIKO_VILLAGE, TWO_ACTOR_PARAMS(-433, -401), "Near Bazaar Adult Crate 1", RHT_CRATE_KAKARIKO_VILLAGE, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_KAK_NEAR_BAZAAR_ADULT_CRATE_1));
|
||||
locationTable[RC_KAK_NEAR_BAZAAR_ADULT_CRATE_2] = Location::Crate(RC_KAK_NEAR_BAZAAR_ADULT_CRATE_2, RCQUEST_BOTH, RCAREA_KAKARIKO_VILLAGE, SCENE_KAKARIKO_VILLAGE, TWO_ACTOR_PARAMS(-489, -424), "Near Bazaar Adult Crate 2`", RHT_CRATE_KAKARIKO_VILLAGE, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_KAK_NEAR_BAZAAR_ADULT_CRATE_2));
|
||||
locationTable[RC_KAK_NEAR_BAZAAR_ADULT_CRATE_2] = Location::Crate(RC_KAK_NEAR_BAZAAR_ADULT_CRATE_2, RCQUEST_BOTH, RCAREA_KAKARIKO_VILLAGE, SCENE_KAKARIKO_VILLAGE, TWO_ACTOR_PARAMS(-489, -424), "Near Bazaar Adult Crate 2", RHT_CRATE_KAKARIKO_VILLAGE, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_KAK_NEAR_BAZAAR_ADULT_CRATE_2));
|
||||
locationTable[RC_KAK_BEHIND_GS_HOUSE_ADULT_CRATE] = Location::Crate(RC_KAK_BEHIND_GS_HOUSE_ADULT_CRATE, RCQUEST_BOTH, RCAREA_KAKARIKO_VILLAGE, SCENE_KAKARIKO_VILLAGE, TWO_ACTOR_PARAMS(-724, 871), "Behind GS House Adult Crate", RHT_CRATE_KAKARIKO_VILLAGE, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_KAK_BEHIND_GS_HOUSE_ADULT_CRATE));
|
||||
locationTable[RC_KAK_NEAR_GY_CHILD_CRATE] = Location::Crate(RC_KAK_NEAR_GY_CHILD_CRATE, RCQUEST_BOTH, RCAREA_KAKARIKO_VILLAGE, SCENE_KAKARIKO_VILLAGE, TWO_ACTOR_PARAMS(1732, 1366), "Near Graveyard Child Crate", RHT_CRATE_KAKARIKO_VILLAGE, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_KAK_NEAR_GY_CHILD_CRATE));
|
||||
locationTable[RC_KAK_NEAR_WINDMILL_CHILD_CRATE] = Location::Crate(RC_KAK_NEAR_WINDMILL_CHILD_CRATE, RCQUEST_BOTH, RCAREA_KAKARIKO_VILLAGE, SCENE_KAKARIKO_VILLAGE, TWO_ACTOR_PARAMS(1170, 601), "Near Windmill Child Crate", RHT_CRATE_KAKARIKO_VILLAGE, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_KAK_NEAR_WINDMILL_CHILD_CRATE));
|
||||
|
||||
@@ -103,11 +103,11 @@ void Rando::StaticData::RegisterPotLocations() {
|
||||
// clang-format off
|
||||
// Overworld Pots
|
||||
// Randomizer Check Randomizer Check Quest Area Scene ID Params Short Name Hint Text Key Vanilla Spoiler Collection Check
|
||||
locationTable[RC_KF_LINKS_HOUSE_POT] = Location::Pot(RC_KF_LINKS_HOUSE_POT, RCQUEST_BOTH, RCAREA_KOKIRI_FOREST, SCENE_LINKS_HOUSE, TWO_ACTOR_PARAMS(-118, 51), "Links House Pot", RHT_POT_KOKIRI_FOREST, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_KF_LINKS_HOUSE_POT));
|
||||
locationTable[RC_KF_TWINS_HOUSE_POT_2] = Location::Pot(RC_KF_TWINS_HOUSE_POT_2, RCQUEST_BOTH, RCAREA_KOKIRI_FOREST, SCENE_TWINS_HOUSE, TWO_ACTOR_PARAMS(35, 57), "Twins House Pot 2", RHT_POT_KOKIRI_FOREST, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_KF_TWINS_HOUSE_POT_2));
|
||||
locationTable[RC_KF_TWINS_HOUSE_POT_1] = Location::Pot(RC_KF_TWINS_HOUSE_POT_1, RCQUEST_BOTH, RCAREA_KOKIRI_FOREST, SCENE_TWINS_HOUSE, TWO_ACTOR_PARAMS(33, -55), "Twins House Pot 1", RHT_POT_KOKIRI_FOREST, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_KF_TWINS_HOUSE_POT_1));
|
||||
locationTable[RC_KF_BROTHERS_HOUSE_POT_1] = Location::Pot(RC_KF_BROTHERS_HOUSE_POT_1, RCQUEST_BOTH, RCAREA_KOKIRI_FOREST, SCENE_KNOW_IT_ALL_BROS_HOUSE, TWO_ACTOR_PARAMS(-134, -29), "Brothers House Pot 1", RHT_POT_KOKIRI_FOREST, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_KF_BROTHERS_HOUSE_POT_1));
|
||||
locationTable[RC_KF_BROTHERS_HOUSE_POT_2] = Location::Pot(RC_KF_BROTHERS_HOUSE_POT_2, RCQUEST_BOTH, RCAREA_KOKIRI_FOREST, SCENE_KNOW_IT_ALL_BROS_HOUSE, TWO_ACTOR_PARAMS(-68, 114), "Brothers House Pot 2", RHT_POT_KOKIRI_FOREST, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_KF_BROTHERS_HOUSE_POT_2));
|
||||
locationTable[RC_KF_LINKS_HOUSE_POT] = Location::Pot(RC_KF_LINKS_HOUSE_POT, RCQUEST_BOTH, RCAREA_KOKIRI_FOREST, SCENE_LINKS_HOUSE, TWO_ACTOR_PARAMS(-118, 51), "Links House Pot", RHT_POT_LINKS_HOUSE, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_KF_LINKS_HOUSE_POT));
|
||||
locationTable[RC_KF_TWINS_HOUSE_POT_2] = Location::Pot(RC_KF_TWINS_HOUSE_POT_2, RCQUEST_BOTH, RCAREA_KOKIRI_FOREST, SCENE_TWINS_HOUSE, TWO_ACTOR_PARAMS(35, 57), "Twins House Pot 2", RHT_POT_TWINS_HOUSE, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_KF_TWINS_HOUSE_POT_2));
|
||||
locationTable[RC_KF_TWINS_HOUSE_POT_1] = Location::Pot(RC_KF_TWINS_HOUSE_POT_1, RCQUEST_BOTH, RCAREA_KOKIRI_FOREST, SCENE_TWINS_HOUSE, TWO_ACTOR_PARAMS(33, -55), "Twins House Pot 1", RHT_POT_TWINS_HOUSE, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_KF_TWINS_HOUSE_POT_1));
|
||||
locationTable[RC_KF_BROTHERS_HOUSE_POT_1] = Location::Pot(RC_KF_BROTHERS_HOUSE_POT_1, RCQUEST_BOTH, RCAREA_KOKIRI_FOREST, SCENE_KNOW_IT_ALL_BROS_HOUSE, TWO_ACTOR_PARAMS(-134, -29), "Brothers House Pot 1", RHT_POT_KNOW_IT_ALL, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_KF_BROTHERS_HOUSE_POT_1));
|
||||
locationTable[RC_KF_BROTHERS_HOUSE_POT_2] = Location::Pot(RC_KF_BROTHERS_HOUSE_POT_2, RCQUEST_BOTH, RCAREA_KOKIRI_FOREST, SCENE_KNOW_IT_ALL_BROS_HOUSE, TWO_ACTOR_PARAMS(-68, 114), "Brothers House Pot 2", RHT_POT_KNOW_IT_ALL, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_KF_BROTHERS_HOUSE_POT_2));
|
||||
locationTable[RC_GF_BREAK_ROOM_POT_1] = Location::Pot(RC_GF_BREAK_ROOM_POT_1, RCQUEST_BOTH, RCAREA_GERUDO_FORTRESS, SCENE_THIEVES_HIDEOUT, TWO_ACTOR_PARAMS(1438, -3629), "Break Room Pot 1", RHT_POT_GERUDO_FORTRESS, RG_ARROWS_10, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GF_BREAK_ROOM_POT_1));
|
||||
locationTable[RC_GF_BREAK_ROOM_POT_2] = Location::Pot(RC_GF_BREAK_ROOM_POT_2, RCQUEST_BOTH, RCAREA_GERUDO_FORTRESS, SCENE_THIEVES_HIDEOUT, TWO_ACTOR_PARAMS(1403, -3679), "Break Room Pot 2", RHT_POT_GERUDO_FORTRESS, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GF_BREAK_ROOM_POT_2));
|
||||
locationTable[RC_GF_KITCHEN_POT_1] = Location::Pot(RC_GF_KITCHEN_POT_1, RCQUEST_BOTH, RCAREA_GERUDO_FORTRESS, SCENE_THIEVES_HIDEOUT, TWO_ACTOR_PARAMS(1908, -789), "Kitchen Pot 1", RHT_POT_GERUDO_FORTRESS, RG_ARROWS_10, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GF_KITCHEN_POT_1));
|
||||
@@ -128,64 +128,64 @@ void Rando::StaticData::RegisterPotLocations() {
|
||||
locationTable[RC_WASTELAND_NEAR_GS_POT_2] = Location::Pot(RC_WASTELAND_NEAR_GS_POT_2, RCQUEST_BOTH, RCAREA_WASTELAND, SCENE_HAUNTED_WASTELAND, TWO_ACTOR_PARAMS(485, -2463), "Near GS Pot 2", RHT_POT_GERUDO_FORTRESS, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_WASTELAND_NEAR_GS_POT_2));
|
||||
locationTable[RC_WASTELAND_NEAR_GS_POT_3] = Location::Pot(RC_WASTELAND_NEAR_GS_POT_3, RCQUEST_BOTH, RCAREA_WASTELAND, SCENE_HAUNTED_WASTELAND, TWO_ACTOR_PARAMS(806, -2426), "Near GS Pot 3", RHT_POT_GERUDO_FORTRESS, RG_DEKU_NUTS_5, SpoilerCollectionCheck::RandomizerInf(RAND_INF_WASTELAND_NEAR_GS_POT_3));
|
||||
locationTable[RC_WASTELAND_NEAR_GS_POT_4] = Location::Pot(RC_WASTELAND_NEAR_GS_POT_4, RCQUEST_BOTH, RCAREA_WASTELAND, SCENE_HAUNTED_WASTELAND, TWO_ACTOR_PARAMS(801, -2460), "Near GS Pot 4", RHT_POT_GERUDO_FORTRESS, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_WASTELAND_NEAR_GS_POT_4));
|
||||
locationTable[RC_MK_GUARD_HOUSE_CHILD_POT_1] = Location::Pot(RC_MK_GUARD_HOUSE_CHILD_POT_1, RCQUEST_BOTH, RCAREA_MARKET, SCENE_MARKET_GUARD_HOUSE, TWO_ACTOR_PARAMS(-60, 27), "Guard House Child Pot 1", RHT_POT_MARKET, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_MK_GUARD_HOUSE_CHILD_POT_1));
|
||||
locationTable[RC_MK_GUARD_HOUSE_CHILD_POT_2] = Location::Pot(RC_MK_GUARD_HOUSE_CHILD_POT_2, RCQUEST_BOTH, RCAREA_MARKET, SCENE_MARKET_GUARD_HOUSE, TWO_ACTOR_PARAMS(-89, 28), "Guard House Child Pot 2", RHT_POT_MARKET, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_MK_GUARD_HOUSE_CHILD_POT_2));
|
||||
locationTable[RC_MK_GUARD_HOUSE_CHILD_POT_3] = Location::Pot(RC_MK_GUARD_HOUSE_CHILD_POT_3, RCQUEST_BOTH, RCAREA_MARKET, SCENE_MARKET_GUARD_HOUSE, TWO_ACTOR_PARAMS(-110, 6), "Guard House Child Pot 3", RHT_POT_MARKET, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_MK_GUARD_HOUSE_CHILD_POT_3));
|
||||
locationTable[RC_MK_GUARD_HOUSE_CHILD_POT_4] = Location::Pot(RC_MK_GUARD_HOUSE_CHILD_POT_4, RCQUEST_BOTH, RCAREA_MARKET, SCENE_MARKET_GUARD_HOUSE, TWO_ACTOR_PARAMS(-58, -7), "Guard House Child Pot 4", RHT_POT_MARKET, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_MK_GUARD_HOUSE_CHILD_POT_4));
|
||||
locationTable[RC_MK_GUARD_HOUSE_CHILD_POT_5] = Location::Pot(RC_MK_GUARD_HOUSE_CHILD_POT_5, RCQUEST_BOTH, RCAREA_MARKET, SCENE_MARKET_GUARD_HOUSE, TWO_ACTOR_PARAMS(-80, -7), "Guard House Child Pot 5", RHT_POT_MARKET, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_MK_GUARD_HOUSE_CHILD_POT_5));
|
||||
locationTable[RC_MK_GUARD_HOUSE_CHILD_POT_6] = Location::Pot(RC_MK_GUARD_HOUSE_CHILD_POT_6, RCQUEST_BOTH, RCAREA_MARKET, SCENE_MARKET_GUARD_HOUSE, TWO_ACTOR_PARAMS(-65, -45), "Guard House Child Pot 6", RHT_POT_MARKET, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_MK_GUARD_HOUSE_CHILD_POT_6));
|
||||
locationTable[RC_MK_GUARD_HOUSE_CHILD_POT_7] = Location::Pot(RC_MK_GUARD_HOUSE_CHILD_POT_7, RCQUEST_BOTH, RCAREA_MARKET, SCENE_MARKET_GUARD_HOUSE, TWO_ACTOR_PARAMS(-85, -41), "Guard House Child Pot 7", RHT_POT_MARKET, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_MK_GUARD_HOUSE_CHILD_POT_7));
|
||||
locationTable[RC_MK_GUARD_HOUSE_CHILD_POT_8] = Location::Pot(RC_MK_GUARD_HOUSE_CHILD_POT_8, RCQUEST_BOTH, RCAREA_MARKET, SCENE_MARKET_GUARD_HOUSE, TWO_ACTOR_PARAMS(-107, -45), "Guard House Child Pot 8", RHT_POT_MARKET, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_MK_GUARD_HOUSE_CHILD_POT_8));
|
||||
locationTable[RC_MK_GUARD_HOUSE_CHILD_POT_9] = Location::Pot(RC_MK_GUARD_HOUSE_CHILD_POT_9, RCQUEST_BOTH, RCAREA_MARKET, SCENE_MARKET_GUARD_HOUSE, TWO_ACTOR_PARAMS(-66, -79), "Guard House Child Pot 9", RHT_POT_MARKET, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_MK_GUARD_HOUSE_CHILD_POT_9));
|
||||
locationTable[RC_MK_GUARD_HOUSE_CHILD_POT_10] = Location::Pot(RC_MK_GUARD_HOUSE_CHILD_POT_10, RCQUEST_BOTH, RCAREA_MARKET, SCENE_MARKET_GUARD_HOUSE, TWO_ACTOR_PARAMS(-88, -84), "Guard House Child Pot 10", RHT_POT_MARKET, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_MK_GUARD_HOUSE_CHILD_POT_10));
|
||||
locationTable[RC_MK_GUARD_HOUSE_CHILD_POT_11] = Location::Pot(RC_MK_GUARD_HOUSE_CHILD_POT_11, RCQUEST_BOTH, RCAREA_MARKET, SCENE_MARKET_GUARD_HOUSE, TWO_ACTOR_PARAMS(70, 215), "Guard House Child Pot 11", RHT_POT_MARKET, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_MK_GUARD_HOUSE_CHILD_POT_11));
|
||||
locationTable[RC_MK_GUARD_HOUSE_CHILD_POT_12] = Location::Pot(RC_MK_GUARD_HOUSE_CHILD_POT_12, RCQUEST_BOTH, RCAREA_MARKET, SCENE_MARKET_GUARD_HOUSE, TWO_ACTOR_PARAMS(68, 148), "Guard House Child Pot 12", RHT_POT_MARKET, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_MK_GUARD_HOUSE_CHILD_POT_12));
|
||||
locationTable[RC_MK_GUARD_HOUSE_CHILD_POT_13] = Location::Pot(RC_MK_GUARD_HOUSE_CHILD_POT_13, RCQUEST_BOTH, RCAREA_MARKET, SCENE_MARKET_GUARD_HOUSE, TWO_ACTOR_PARAMS(73, 117), "Guard House Child Pot 13", RHT_POT_MARKET, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_MK_GUARD_HOUSE_CHILD_POT_13));
|
||||
locationTable[RC_MK_GUARD_HOUSE_CHILD_POT_14] = Location::Pot(RC_MK_GUARD_HOUSE_CHILD_POT_14, RCQUEST_BOTH, RCAREA_MARKET, SCENE_MARKET_GUARD_HOUSE, TWO_ACTOR_PARAMS(40, 123), "Guard House Child Pot 14", RHT_POT_MARKET, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_MK_GUARD_HOUSE_CHILD_POT_14));
|
||||
locationTable[RC_MK_GUARD_HOUSE_CHILD_POT_15] = Location::Pot(RC_MK_GUARD_HOUSE_CHILD_POT_15, RCQUEST_BOTH, RCAREA_MARKET, SCENE_MARKET_GUARD_HOUSE, TWO_ACTOR_PARAMS(43, 89), "Guard House Child Pot 15", RHT_POT_MARKET, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_MK_GUARD_HOUSE_CHILD_POT_15));
|
||||
locationTable[RC_MK_GUARD_HOUSE_CHILD_POT_16] = Location::Pot(RC_MK_GUARD_HOUSE_CHILD_POT_16, RCQUEST_BOTH, RCAREA_MARKET, SCENE_MARKET_GUARD_HOUSE, TWO_ACTOR_PARAMS(68, 81), "Guard House Child Pot 16", RHT_POT_MARKET, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_MK_GUARD_HOUSE_CHILD_POT_16));
|
||||
locationTable[RC_MK_GUARD_HOUSE_CHILD_POT_17] = Location::Pot(RC_MK_GUARD_HOUSE_CHILD_POT_17, RCQUEST_BOTH, RCAREA_MARKET, SCENE_MARKET_GUARD_HOUSE, TWO_ACTOR_PARAMS(21, 73), "Guard House Child Pot 17", RHT_POT_MARKET, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_MK_GUARD_HOUSE_CHILD_POT_17));
|
||||
locationTable[RC_MK_GUARD_HOUSE_CHILD_POT_18] = Location::Pot(RC_MK_GUARD_HOUSE_CHILD_POT_18, RCQUEST_BOTH, RCAREA_MARKET, SCENE_MARKET_GUARD_HOUSE, TWO_ACTOR_PARAMS(64, 45), "Guard House Child Pot 18", RHT_POT_MARKET, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_MK_GUARD_HOUSE_CHILD_POT_18));
|
||||
locationTable[RC_MK_GUARD_HOUSE_CHILD_POT_19] = Location::Pot(RC_MK_GUARD_HOUSE_CHILD_POT_19, RCQUEST_BOTH, RCAREA_MARKET, SCENE_MARKET_GUARD_HOUSE, TWO_ACTOR_PARAMS(84, 31), "Guard House Child Pot 19", RHT_POT_MARKET, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_MK_GUARD_HOUSE_CHILD_POT_19));
|
||||
locationTable[RC_MK_GUARD_HOUSE_CHILD_POT_20] = Location::Pot(RC_MK_GUARD_HOUSE_CHILD_POT_20, RCQUEST_BOTH, RCAREA_MARKET, SCENE_MARKET_GUARD_HOUSE, TWO_ACTOR_PARAMS(42, 26), "Guard House Child Pot 20", RHT_POT_MARKET, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_MK_GUARD_HOUSE_CHILD_POT_20));
|
||||
locationTable[RC_MK_GUARD_HOUSE_CHILD_POT_21] = Location::Pot(RC_MK_GUARD_HOUSE_CHILD_POT_21, RCQUEST_BOTH, RCAREA_MARKET, SCENE_MARKET_GUARD_HOUSE, TWO_ACTOR_PARAMS(20, 34), "Guard House Child Pot 21", RHT_POT_MARKET, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_MK_GUARD_HOUSE_CHILD_POT_21));
|
||||
locationTable[RC_MK_GUARD_HOUSE_CHILD_POT_22] = Location::Pot(RC_MK_GUARD_HOUSE_CHILD_POT_22, RCQUEST_BOTH, RCAREA_MARKET, SCENE_MARKET_GUARD_HOUSE, TWO_ACTOR_PARAMS(89, -2), "Guard House Child Pot 22", RHT_POT_MARKET, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_MK_GUARD_HOUSE_CHILD_POT_22));
|
||||
locationTable[RC_MK_GUARD_HOUSE_CHILD_POT_23] = Location::Pot(RC_MK_GUARD_HOUSE_CHILD_POT_23, RCQUEST_BOTH, RCAREA_MARKET, SCENE_MARKET_GUARD_HOUSE, TWO_ACTOR_PARAMS(70, -12), "Guard House Child Pot 23", RHT_POT_MARKET, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_MK_GUARD_HOUSE_CHILD_POT_23));
|
||||
locationTable[RC_MK_GUARD_HOUSE_CHILD_POT_24] = Location::Pot(RC_MK_GUARD_HOUSE_CHILD_POT_24, RCQUEST_BOTH, RCAREA_MARKET, SCENE_MARKET_GUARD_HOUSE, TWO_ACTOR_PARAMS(42, -5), "Guard House Child Pot 24", RHT_POT_MARKET, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_MK_GUARD_HOUSE_CHILD_POT_24));
|
||||
locationTable[RC_MK_GUARD_HOUSE_CHILD_POT_25] = Location::Pot(RC_MK_GUARD_HOUSE_CHILD_POT_25, RCQUEST_BOTH, RCAREA_MARKET, SCENE_MARKET_GUARD_HOUSE, TWO_ACTOR_PARAMS(16, -6), "Guard House Child Pot 25", RHT_POT_MARKET, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_MK_GUARD_HOUSE_CHILD_POT_25));
|
||||
locationTable[RC_MK_GUARD_HOUSE_CHILD_POT_26] = Location::Pot(RC_MK_GUARD_HOUSE_CHILD_POT_26, RCQUEST_BOTH, RCAREA_MARKET, SCENE_MARKET_GUARD_HOUSE, TWO_ACTOR_PARAMS(68, -44), "Guard House Child Pot 26", RHT_POT_MARKET, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_MK_GUARD_HOUSE_CHILD_POT_26));
|
||||
locationTable[RC_MK_GUARD_HOUSE_CHILD_POT_27] = Location::Pot(RC_MK_GUARD_HOUSE_CHILD_POT_27, RCQUEST_BOTH, RCAREA_MARKET, SCENE_MARKET_GUARD_HOUSE, TWO_ACTOR_PARAMS(37, -40), "Guard House Child Pot 27", RHT_POT_MARKET, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_MK_GUARD_HOUSE_CHILD_POT_27));
|
||||
locationTable[RC_MK_GUARD_HOUSE_CHILD_POT_28] = Location::Pot(RC_MK_GUARD_HOUSE_CHILD_POT_28, RCQUEST_BOTH, RCAREA_MARKET, SCENE_MARKET_GUARD_HOUSE, TWO_ACTOR_PARAMS(70, -80), "Guard House Child Pot 28", RHT_POT_MARKET, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_MK_GUARD_HOUSE_CHILD_POT_28));
|
||||
locationTable[RC_MK_GUARD_HOUSE_CHILD_POT_29] = Location::Pot(RC_MK_GUARD_HOUSE_CHILD_POT_29, RCQUEST_BOTH, RCAREA_MARKET, SCENE_MARKET_GUARD_HOUSE, TWO_ACTOR_PARAMS(50, -74), "Guard House Child Pot 29", RHT_POT_MARKET, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_MK_GUARD_HOUSE_CHILD_POT_29));
|
||||
locationTable[RC_MK_GUARD_HOUSE_CHILD_POT_30] = Location::Pot(RC_MK_GUARD_HOUSE_CHILD_POT_30, RCQUEST_BOTH, RCAREA_MARKET, SCENE_MARKET_GUARD_HOUSE, TWO_ACTOR_PARAMS(28, -79), "Guard House Child Pot 30", RHT_POT_MARKET, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_MK_GUARD_HOUSE_CHILD_POT_30));
|
||||
locationTable[RC_MK_GUARD_HOUSE_CHILD_POT_31] = Location::Pot(RC_MK_GUARD_HOUSE_CHILD_POT_31, RCQUEST_BOTH, RCAREA_MARKET, SCENE_MARKET_GUARD_HOUSE, TWO_ACTOR_PARAMS(39, -111), "Guard House Child Pot 31", RHT_POT_MARKET, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_MK_GUARD_HOUSE_CHILD_POT_31));
|
||||
locationTable[RC_MK_GUARD_HOUSE_CHILD_POT_32] = Location::Pot(RC_MK_GUARD_HOUSE_CHILD_POT_32, RCQUEST_BOTH, RCAREA_MARKET, SCENE_MARKET_GUARD_HOUSE, TWO_ACTOR_PARAMS(169, 216), "Guard House Child Pot 32", RHT_POT_MARKET, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_MK_GUARD_HOUSE_CHILD_POT_32));
|
||||
locationTable[RC_MK_GUARD_HOUSE_CHILD_POT_33] = Location::Pot(RC_MK_GUARD_HOUSE_CHILD_POT_33, RCQUEST_BOTH, RCAREA_MARKET, SCENE_MARKET_GUARD_HOUSE, TWO_ACTOR_PARAMS(168, 166), "Guard House Child Pot 33", RHT_POT_MARKET, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_MK_GUARD_HOUSE_CHILD_POT_33));
|
||||
locationTable[RC_MK_GUARD_HOUSE_CHILD_POT_34] = Location::Pot(RC_MK_GUARD_HOUSE_CHILD_POT_34, RCQUEST_BOTH, RCAREA_MARKET, SCENE_MARKET_GUARD_HOUSE, TWO_ACTOR_PARAMS(170, 120), "Guard House Child Pot 34", RHT_POT_MARKET, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_MK_GUARD_HOUSE_CHILD_POT_34));
|
||||
locationTable[RC_MK_GUARD_HOUSE_CHILD_POT_35] = Location::Pot(RC_MK_GUARD_HOUSE_CHILD_POT_35, RCQUEST_BOTH, RCAREA_MARKET, SCENE_MARKET_GUARD_HOUSE, TWO_ACTOR_PARAMS(177, 85), "Guard House Child Pot 35", RHT_POT_MARKET, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_MK_GUARD_HOUSE_CHILD_POT_35));
|
||||
locationTable[RC_MK_GUARD_HOUSE_CHILD_POT_36] = Location::Pot(RC_MK_GUARD_HOUSE_CHILD_POT_36, RCQUEST_BOTH, RCAREA_MARKET, SCENE_MARKET_GUARD_HOUSE, TWO_ACTOR_PARAMS(155, 39), "Guard House Child Pot 36", RHT_POT_MARKET, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_MK_GUARD_HOUSE_CHILD_POT_36));
|
||||
locationTable[RC_MK_GUARD_HOUSE_CHILD_POT_37] = Location::Pot(RC_MK_GUARD_HOUSE_CHILD_POT_37, RCQUEST_BOTH, RCAREA_MARKET, SCENE_MARKET_GUARD_HOUSE, TWO_ACTOR_PARAMS(184, 13), "Guard House Child Pot 37", RHT_POT_MARKET, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_MK_GUARD_HOUSE_CHILD_POT_37));
|
||||
locationTable[RC_MK_GUARD_HOUSE_CHILD_POT_38] = Location::Pot(RC_MK_GUARD_HOUSE_CHILD_POT_38, RCQUEST_BOTH, RCAREA_MARKET, SCENE_MARKET_GUARD_HOUSE, TWO_ACTOR_PARAMS(156, -1), "Guard House Child Pot 38", RHT_POT_MARKET, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_MK_GUARD_HOUSE_CHILD_POT_38));
|
||||
locationTable[RC_MK_GUARD_HOUSE_CHILD_POT_39] = Location::Pot(RC_MK_GUARD_HOUSE_CHILD_POT_39, RCQUEST_BOTH, RCAREA_MARKET, SCENE_MARKET_GUARD_HOUSE, TWO_ACTOR_PARAMS(181, -33), "Guard House Child Pot 39", RHT_POT_MARKET, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_MK_GUARD_HOUSE_CHILD_POT_39));
|
||||
locationTable[RC_MK_GUARD_HOUSE_CHILD_POT_40] = Location::Pot(RC_MK_GUARD_HOUSE_CHILD_POT_40, RCQUEST_BOTH, RCAREA_MARKET, SCENE_MARKET_GUARD_HOUSE, TWO_ACTOR_PARAMS(156, -45), "Guard House Child Pot 40", RHT_POT_MARKET, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_MK_GUARD_HOUSE_CHILD_POT_40));
|
||||
locationTable[RC_MK_GUARD_HOUSE_CHILD_POT_41] = Location::Pot(RC_MK_GUARD_HOUSE_CHILD_POT_41, RCQUEST_BOTH, RCAREA_MARKET, SCENE_MARKET_GUARD_HOUSE, TWO_ACTOR_PARAMS(172, -82), "Guard House Child Pot 41", RHT_POT_MARKET, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_MK_GUARD_HOUSE_CHILD_POT_41));
|
||||
locationTable[RC_MK_GUARD_HOUSE_CHILD_POT_42] = Location::Pot(RC_MK_GUARD_HOUSE_CHILD_POT_42, RCQUEST_BOTH, RCAREA_MARKET, SCENE_MARKET_GUARD_HOUSE, TWO_ACTOR_PARAMS(170, -120), "Guard House Child Pot 42", RHT_POT_MARKET, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_MK_GUARD_HOUSE_CHILD_POT_42));
|
||||
locationTable[RC_MK_GUARD_HOUSE_CHILD_POT_43] = Location::Pot(RC_MK_GUARD_HOUSE_CHILD_POT_43, RCQUEST_BOTH, RCAREA_MARKET, SCENE_MARKET_GUARD_HOUSE, TWO_ACTOR_PARAMS(170, -166), "Guard House Child Pot 43", RHT_POT_MARKET, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_MK_GUARD_HOUSE_CHILD_POT_43));
|
||||
locationTable[RC_MK_GUARD_HOUSE_CHILD_POT_44] = Location::Pot(RC_MK_GUARD_HOUSE_CHILD_POT_44, RCQUEST_BOTH, RCAREA_MARKET, SCENE_MARKET_GUARD_HOUSE, TWO_ACTOR_PARAMS(170, -216), "Guard House Child Pot 44", RHT_POT_MARKET, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_MK_GUARD_HOUSE_CHILD_POT_44));
|
||||
locationTable[RC_MK_GUARD_HOUSE_ADULT_POT_1] = Location::Pot(RC_MK_GUARD_HOUSE_ADULT_POT_1, RCQUEST_BOTH, RCAREA_MARKET, SCENE_MARKET_GUARD_HOUSE, TWO_ACTOR_PARAMS(61, 204), "Guard House Adult Pot 1", RHT_POT_MARKET, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_MK_GUARD_HOUSE_ADULT_POT_1));
|
||||
locationTable[RC_MK_GUARD_HOUSE_ADULT_POT_2] = Location::Pot(RC_MK_GUARD_HOUSE_ADULT_POT_2, RCQUEST_BOTH, RCAREA_MARKET, SCENE_MARKET_GUARD_HOUSE, TWO_ACTOR_PARAMS(71, 132), "Guard House Adult Pot 2", RHT_POT_MARKET, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_MK_GUARD_HOUSE_ADULT_POT_2));
|
||||
locationTable[RC_MK_GUARD_HOUSE_ADULT_POT_3] = Location::Pot(RC_MK_GUARD_HOUSE_ADULT_POT_3, RCQUEST_BOTH, RCAREA_MARKET, SCENE_MARKET_GUARD_HOUSE, TWO_ACTOR_PARAMS(74, 23), "Guard House Adult Pot 3", RHT_POT_MARKET, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_MK_GUARD_HOUSE_ADULT_POT_3));
|
||||
locationTable[RC_MK_GUARD_HOUSE_ADULT_POT_4] = Location::Pot(RC_MK_GUARD_HOUSE_ADULT_POT_4, RCQUEST_BOTH, RCAREA_MARKET, SCENE_MARKET_GUARD_HOUSE, TWO_ACTOR_PARAMS(40, 4), "Guard House Adult Pot 4", RHT_POT_MARKET, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_MK_GUARD_HOUSE_ADULT_POT_4));
|
||||
locationTable[RC_MK_GUARD_HOUSE_ADULT_POT_5] = Location::Pot(RC_MK_GUARD_HOUSE_ADULT_POT_5, RCQUEST_BOTH, RCAREA_MARKET, SCENE_MARKET_GUARD_HOUSE, TWO_ACTOR_PARAMS(71, -22), "Guard House Adult Pot 5", RHT_POT_MARKET, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_MK_GUARD_HOUSE_ADULT_POT_5));
|
||||
locationTable[RC_MK_GUARD_HOUSE_ADULT_POT_6] = Location::Pot(RC_MK_GUARD_HOUSE_ADULT_POT_6, RCQUEST_BOTH, RCAREA_MARKET, SCENE_MARKET_GUARD_HOUSE, TWO_ACTOR_PARAMS(44, -151), "Guard House Adult Pot 6", RHT_POT_MARKET, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_MK_GUARD_HOUSE_ADULT_POT_6));
|
||||
locationTable[RC_MK_GUARD_HOUSE_ADULT_POT_7] = Location::Pot(RC_MK_GUARD_HOUSE_ADULT_POT_7, RCQUEST_BOTH, RCAREA_MARKET, SCENE_MARKET_GUARD_HOUSE, TWO_ACTOR_PARAMS(79, -182), "Guard House Adult Pot 7", RHT_POT_MARKET, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_MK_GUARD_HOUSE_ADULT_POT_7));
|
||||
locationTable[RC_MK_GUARD_HOUSE_ADULT_POT_8] = Location::Pot(RC_MK_GUARD_HOUSE_ADULT_POT_8, RCQUEST_BOTH, RCAREA_MARKET, SCENE_MARKET_GUARD_HOUSE, TWO_ACTOR_PARAMS(44, -198), "Guard House Adult Pot 8", RHT_POT_MARKET, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_MK_GUARD_HOUSE_ADULT_POT_8));
|
||||
locationTable[RC_MK_GUARD_HOUSE_ADULT_POT_9] = Location::Pot(RC_MK_GUARD_HOUSE_ADULT_POT_9, RCQUEST_BOTH, RCAREA_MARKET, SCENE_MARKET_GUARD_HOUSE, TWO_ACTOR_PARAMS(168, 210), "Guard House Adult Pot 9", RHT_POT_MARKET, RG_RED_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_MK_GUARD_HOUSE_ADULT_POT_9));
|
||||
locationTable[RC_MK_GUARD_HOUSE_ADULT_POT_10] = Location::Pot(RC_MK_GUARD_HOUSE_ADULT_POT_10, RCQUEST_BOTH, RCAREA_MARKET, SCENE_MARKET_GUARD_HOUSE, TWO_ACTOR_PARAMS(167, -122), "Guard House Adult Pot 10", RHT_POT_MARKET, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_MK_GUARD_HOUSE_ADULT_POT_10));
|
||||
locationTable[RC_MK_GUARD_HOUSE_ADULT_POT_11] = Location::Pot(RC_MK_GUARD_HOUSE_ADULT_POT_11, RCQUEST_BOTH, RCAREA_MARKET, SCENE_MARKET_GUARD_HOUSE, TWO_ACTOR_PARAMS(167, -210), "Guard House Adult Pot 11", RHT_POT_MARKET, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_MK_GUARD_HOUSE_ADULT_POT_11));
|
||||
locationTable[RC_MK_BACK_ALLEY_HOUSE_POT_1] = Location::Pot(RC_MK_BACK_ALLEY_HOUSE_POT_1, RCQUEST_BOTH, RCAREA_MARKET, SCENE_BACK_ALLEY_HOUSE, TWO_ACTOR_PARAMS(100, 45), "Back Alley House Pot 1", RHT_POT_MARKET, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_MK_BACK_ALLEY_HOUSE_POT_1));
|
||||
locationTable[RC_MK_BACK_ALLEY_HOUSE_POT_2] = Location::Pot(RC_MK_BACK_ALLEY_HOUSE_POT_2, RCQUEST_BOTH, RCAREA_MARKET, SCENE_BACK_ALLEY_HOUSE, TWO_ACTOR_PARAMS(12, -180), "Back Alley House Pot 2", RHT_POT_MARKET, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_MK_BACK_ALLEY_HOUSE_POT_2));
|
||||
locationTable[RC_MK_BACK_ALLEY_HOUSE_POT_3] = Location::Pot(RC_MK_BACK_ALLEY_HOUSE_POT_3, RCQUEST_BOTH, RCAREA_MARKET, SCENE_BACK_ALLEY_HOUSE, TWO_ACTOR_PARAMS(-54, -180), "Back Alley House Pot 3", RHT_POT_MARKET, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_MK_BACK_ALLEY_HOUSE_POT_3));
|
||||
locationTable[RC_MK_GUARD_HOUSE_CHILD_POT_1] = Location::Pot(RC_MK_GUARD_HOUSE_CHILD_POT_1, RCQUEST_BOTH, RCAREA_MARKET, SCENE_MARKET_GUARD_HOUSE, TWO_ACTOR_PARAMS(-60, 27), "Guard House Child Pot 1", RHT_POT_GUARD_HOUSE, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_MK_GUARD_HOUSE_CHILD_POT_1));
|
||||
locationTable[RC_MK_GUARD_HOUSE_CHILD_POT_2] = Location::Pot(RC_MK_GUARD_HOUSE_CHILD_POT_2, RCQUEST_BOTH, RCAREA_MARKET, SCENE_MARKET_GUARD_HOUSE, TWO_ACTOR_PARAMS(-89, 28), "Guard House Child Pot 2", RHT_POT_GUARD_HOUSE, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_MK_GUARD_HOUSE_CHILD_POT_2));
|
||||
locationTable[RC_MK_GUARD_HOUSE_CHILD_POT_3] = Location::Pot(RC_MK_GUARD_HOUSE_CHILD_POT_3, RCQUEST_BOTH, RCAREA_MARKET, SCENE_MARKET_GUARD_HOUSE, TWO_ACTOR_PARAMS(-110, 6), "Guard House Child Pot 3", RHT_POT_GUARD_HOUSE, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_MK_GUARD_HOUSE_CHILD_POT_3));
|
||||
locationTable[RC_MK_GUARD_HOUSE_CHILD_POT_4] = Location::Pot(RC_MK_GUARD_HOUSE_CHILD_POT_4, RCQUEST_BOTH, RCAREA_MARKET, SCENE_MARKET_GUARD_HOUSE, TWO_ACTOR_PARAMS(-58, -7), "Guard House Child Pot 4", RHT_POT_GUARD_HOUSE, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_MK_GUARD_HOUSE_CHILD_POT_4));
|
||||
locationTable[RC_MK_GUARD_HOUSE_CHILD_POT_5] = Location::Pot(RC_MK_GUARD_HOUSE_CHILD_POT_5, RCQUEST_BOTH, RCAREA_MARKET, SCENE_MARKET_GUARD_HOUSE, TWO_ACTOR_PARAMS(-80, -7), "Guard House Child Pot 5", RHT_POT_GUARD_HOUSE, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_MK_GUARD_HOUSE_CHILD_POT_5));
|
||||
locationTable[RC_MK_GUARD_HOUSE_CHILD_POT_6] = Location::Pot(RC_MK_GUARD_HOUSE_CHILD_POT_6, RCQUEST_BOTH, RCAREA_MARKET, SCENE_MARKET_GUARD_HOUSE, TWO_ACTOR_PARAMS(-65, -45), "Guard House Child Pot 6", RHT_POT_GUARD_HOUSE, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_MK_GUARD_HOUSE_CHILD_POT_6));
|
||||
locationTable[RC_MK_GUARD_HOUSE_CHILD_POT_7] = Location::Pot(RC_MK_GUARD_HOUSE_CHILD_POT_7, RCQUEST_BOTH, RCAREA_MARKET, SCENE_MARKET_GUARD_HOUSE, TWO_ACTOR_PARAMS(-85, -41), "Guard House Child Pot 7", RHT_POT_GUARD_HOUSE, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_MK_GUARD_HOUSE_CHILD_POT_7));
|
||||
locationTable[RC_MK_GUARD_HOUSE_CHILD_POT_8] = Location::Pot(RC_MK_GUARD_HOUSE_CHILD_POT_8, RCQUEST_BOTH, RCAREA_MARKET, SCENE_MARKET_GUARD_HOUSE, TWO_ACTOR_PARAMS(-107, -45), "Guard House Child Pot 8", RHT_POT_GUARD_HOUSE, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_MK_GUARD_HOUSE_CHILD_POT_8));
|
||||
locationTable[RC_MK_GUARD_HOUSE_CHILD_POT_9] = Location::Pot(RC_MK_GUARD_HOUSE_CHILD_POT_9, RCQUEST_BOTH, RCAREA_MARKET, SCENE_MARKET_GUARD_HOUSE, TWO_ACTOR_PARAMS(-66, -79), "Guard House Child Pot 9", RHT_POT_GUARD_HOUSE, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_MK_GUARD_HOUSE_CHILD_POT_9));
|
||||
locationTable[RC_MK_GUARD_HOUSE_CHILD_POT_10] = Location::Pot(RC_MK_GUARD_HOUSE_CHILD_POT_10, RCQUEST_BOTH, RCAREA_MARKET, SCENE_MARKET_GUARD_HOUSE, TWO_ACTOR_PARAMS(-88, -84), "Guard House Child Pot 10", RHT_POT_GUARD_HOUSE, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_MK_GUARD_HOUSE_CHILD_POT_10));
|
||||
locationTable[RC_MK_GUARD_HOUSE_CHILD_POT_11] = Location::Pot(RC_MK_GUARD_HOUSE_CHILD_POT_11, RCQUEST_BOTH, RCAREA_MARKET, SCENE_MARKET_GUARD_HOUSE, TWO_ACTOR_PARAMS(70, 215), "Guard House Child Pot 11", RHT_POT_GUARD_HOUSE, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_MK_GUARD_HOUSE_CHILD_POT_11));
|
||||
locationTable[RC_MK_GUARD_HOUSE_CHILD_POT_12] = Location::Pot(RC_MK_GUARD_HOUSE_CHILD_POT_12, RCQUEST_BOTH, RCAREA_MARKET, SCENE_MARKET_GUARD_HOUSE, TWO_ACTOR_PARAMS(68, 148), "Guard House Child Pot 12", RHT_POT_GUARD_HOUSE, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_MK_GUARD_HOUSE_CHILD_POT_12));
|
||||
locationTable[RC_MK_GUARD_HOUSE_CHILD_POT_13] = Location::Pot(RC_MK_GUARD_HOUSE_CHILD_POT_13, RCQUEST_BOTH, RCAREA_MARKET, SCENE_MARKET_GUARD_HOUSE, TWO_ACTOR_PARAMS(73, 117), "Guard House Child Pot 13", RHT_POT_GUARD_HOUSE, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_MK_GUARD_HOUSE_CHILD_POT_13));
|
||||
locationTable[RC_MK_GUARD_HOUSE_CHILD_POT_14] = Location::Pot(RC_MK_GUARD_HOUSE_CHILD_POT_14, RCQUEST_BOTH, RCAREA_MARKET, SCENE_MARKET_GUARD_HOUSE, TWO_ACTOR_PARAMS(40, 123), "Guard House Child Pot 14", RHT_POT_GUARD_HOUSE, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_MK_GUARD_HOUSE_CHILD_POT_14));
|
||||
locationTable[RC_MK_GUARD_HOUSE_CHILD_POT_15] = Location::Pot(RC_MK_GUARD_HOUSE_CHILD_POT_15, RCQUEST_BOTH, RCAREA_MARKET, SCENE_MARKET_GUARD_HOUSE, TWO_ACTOR_PARAMS(43, 89), "Guard House Child Pot 15", RHT_POT_GUARD_HOUSE, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_MK_GUARD_HOUSE_CHILD_POT_15));
|
||||
locationTable[RC_MK_GUARD_HOUSE_CHILD_POT_16] = Location::Pot(RC_MK_GUARD_HOUSE_CHILD_POT_16, RCQUEST_BOTH, RCAREA_MARKET, SCENE_MARKET_GUARD_HOUSE, TWO_ACTOR_PARAMS(68, 81), "Guard House Child Pot 16", RHT_POT_GUARD_HOUSE, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_MK_GUARD_HOUSE_CHILD_POT_16));
|
||||
locationTable[RC_MK_GUARD_HOUSE_CHILD_POT_17] = Location::Pot(RC_MK_GUARD_HOUSE_CHILD_POT_17, RCQUEST_BOTH, RCAREA_MARKET, SCENE_MARKET_GUARD_HOUSE, TWO_ACTOR_PARAMS(21, 73), "Guard House Child Pot 17", RHT_POT_GUARD_HOUSE, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_MK_GUARD_HOUSE_CHILD_POT_17));
|
||||
locationTable[RC_MK_GUARD_HOUSE_CHILD_POT_18] = Location::Pot(RC_MK_GUARD_HOUSE_CHILD_POT_18, RCQUEST_BOTH, RCAREA_MARKET, SCENE_MARKET_GUARD_HOUSE, TWO_ACTOR_PARAMS(64, 45), "Guard House Child Pot 18", RHT_POT_GUARD_HOUSE, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_MK_GUARD_HOUSE_CHILD_POT_18));
|
||||
locationTable[RC_MK_GUARD_HOUSE_CHILD_POT_19] = Location::Pot(RC_MK_GUARD_HOUSE_CHILD_POT_19, RCQUEST_BOTH, RCAREA_MARKET, SCENE_MARKET_GUARD_HOUSE, TWO_ACTOR_PARAMS(84, 31), "Guard House Child Pot 19", RHT_POT_GUARD_HOUSE, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_MK_GUARD_HOUSE_CHILD_POT_19));
|
||||
locationTable[RC_MK_GUARD_HOUSE_CHILD_POT_20] = Location::Pot(RC_MK_GUARD_HOUSE_CHILD_POT_20, RCQUEST_BOTH, RCAREA_MARKET, SCENE_MARKET_GUARD_HOUSE, TWO_ACTOR_PARAMS(42, 26), "Guard House Child Pot 20", RHT_POT_GUARD_HOUSE, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_MK_GUARD_HOUSE_CHILD_POT_20));
|
||||
locationTable[RC_MK_GUARD_HOUSE_CHILD_POT_21] = Location::Pot(RC_MK_GUARD_HOUSE_CHILD_POT_21, RCQUEST_BOTH, RCAREA_MARKET, SCENE_MARKET_GUARD_HOUSE, TWO_ACTOR_PARAMS(20, 34), "Guard House Child Pot 21", RHT_POT_GUARD_HOUSE, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_MK_GUARD_HOUSE_CHILD_POT_21));
|
||||
locationTable[RC_MK_GUARD_HOUSE_CHILD_POT_22] = Location::Pot(RC_MK_GUARD_HOUSE_CHILD_POT_22, RCQUEST_BOTH, RCAREA_MARKET, SCENE_MARKET_GUARD_HOUSE, TWO_ACTOR_PARAMS(89, -2), "Guard House Child Pot 22", RHT_POT_GUARD_HOUSE, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_MK_GUARD_HOUSE_CHILD_POT_22));
|
||||
locationTable[RC_MK_GUARD_HOUSE_CHILD_POT_23] = Location::Pot(RC_MK_GUARD_HOUSE_CHILD_POT_23, RCQUEST_BOTH, RCAREA_MARKET, SCENE_MARKET_GUARD_HOUSE, TWO_ACTOR_PARAMS(70, -12), "Guard House Child Pot 23", RHT_POT_GUARD_HOUSE, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_MK_GUARD_HOUSE_CHILD_POT_23));
|
||||
locationTable[RC_MK_GUARD_HOUSE_CHILD_POT_24] = Location::Pot(RC_MK_GUARD_HOUSE_CHILD_POT_24, RCQUEST_BOTH, RCAREA_MARKET, SCENE_MARKET_GUARD_HOUSE, TWO_ACTOR_PARAMS(42, -5), "Guard House Child Pot 24", RHT_POT_GUARD_HOUSE, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_MK_GUARD_HOUSE_CHILD_POT_24));
|
||||
locationTable[RC_MK_GUARD_HOUSE_CHILD_POT_25] = Location::Pot(RC_MK_GUARD_HOUSE_CHILD_POT_25, RCQUEST_BOTH, RCAREA_MARKET, SCENE_MARKET_GUARD_HOUSE, TWO_ACTOR_PARAMS(16, -6), "Guard House Child Pot 25", RHT_POT_GUARD_HOUSE, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_MK_GUARD_HOUSE_CHILD_POT_25));
|
||||
locationTable[RC_MK_GUARD_HOUSE_CHILD_POT_26] = Location::Pot(RC_MK_GUARD_HOUSE_CHILD_POT_26, RCQUEST_BOTH, RCAREA_MARKET, SCENE_MARKET_GUARD_HOUSE, TWO_ACTOR_PARAMS(68, -44), "Guard House Child Pot 26", RHT_POT_GUARD_HOUSE, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_MK_GUARD_HOUSE_CHILD_POT_26));
|
||||
locationTable[RC_MK_GUARD_HOUSE_CHILD_POT_27] = Location::Pot(RC_MK_GUARD_HOUSE_CHILD_POT_27, RCQUEST_BOTH, RCAREA_MARKET, SCENE_MARKET_GUARD_HOUSE, TWO_ACTOR_PARAMS(37, -40), "Guard House Child Pot 27", RHT_POT_GUARD_HOUSE, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_MK_GUARD_HOUSE_CHILD_POT_27));
|
||||
locationTable[RC_MK_GUARD_HOUSE_CHILD_POT_28] = Location::Pot(RC_MK_GUARD_HOUSE_CHILD_POT_28, RCQUEST_BOTH, RCAREA_MARKET, SCENE_MARKET_GUARD_HOUSE, TWO_ACTOR_PARAMS(70, -80), "Guard House Child Pot 28", RHT_POT_GUARD_HOUSE, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_MK_GUARD_HOUSE_CHILD_POT_28));
|
||||
locationTable[RC_MK_GUARD_HOUSE_CHILD_POT_29] = Location::Pot(RC_MK_GUARD_HOUSE_CHILD_POT_29, RCQUEST_BOTH, RCAREA_MARKET, SCENE_MARKET_GUARD_HOUSE, TWO_ACTOR_PARAMS(50, -74), "Guard House Child Pot 29", RHT_POT_GUARD_HOUSE, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_MK_GUARD_HOUSE_CHILD_POT_29));
|
||||
locationTable[RC_MK_GUARD_HOUSE_CHILD_POT_30] = Location::Pot(RC_MK_GUARD_HOUSE_CHILD_POT_30, RCQUEST_BOTH, RCAREA_MARKET, SCENE_MARKET_GUARD_HOUSE, TWO_ACTOR_PARAMS(28, -79), "Guard House Child Pot 30", RHT_POT_GUARD_HOUSE, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_MK_GUARD_HOUSE_CHILD_POT_30));
|
||||
locationTable[RC_MK_GUARD_HOUSE_CHILD_POT_31] = Location::Pot(RC_MK_GUARD_HOUSE_CHILD_POT_31, RCQUEST_BOTH, RCAREA_MARKET, SCENE_MARKET_GUARD_HOUSE, TWO_ACTOR_PARAMS(39, -111), "Guard House Child Pot 31", RHT_POT_GUARD_HOUSE, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_MK_GUARD_HOUSE_CHILD_POT_31));
|
||||
locationTable[RC_MK_GUARD_HOUSE_CHILD_POT_32] = Location::Pot(RC_MK_GUARD_HOUSE_CHILD_POT_32, RCQUEST_BOTH, RCAREA_MARKET, SCENE_MARKET_GUARD_HOUSE, TWO_ACTOR_PARAMS(169, 216), "Guard House Child Pot 32", RHT_POT_GUARD_HOUSE, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_MK_GUARD_HOUSE_CHILD_POT_32));
|
||||
locationTable[RC_MK_GUARD_HOUSE_CHILD_POT_33] = Location::Pot(RC_MK_GUARD_HOUSE_CHILD_POT_33, RCQUEST_BOTH, RCAREA_MARKET, SCENE_MARKET_GUARD_HOUSE, TWO_ACTOR_PARAMS(168, 166), "Guard House Child Pot 33", RHT_POT_GUARD_HOUSE, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_MK_GUARD_HOUSE_CHILD_POT_33));
|
||||
locationTable[RC_MK_GUARD_HOUSE_CHILD_POT_34] = Location::Pot(RC_MK_GUARD_HOUSE_CHILD_POT_34, RCQUEST_BOTH, RCAREA_MARKET, SCENE_MARKET_GUARD_HOUSE, TWO_ACTOR_PARAMS(170, 120), "Guard House Child Pot 34", RHT_POT_GUARD_HOUSE, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_MK_GUARD_HOUSE_CHILD_POT_34));
|
||||
locationTable[RC_MK_GUARD_HOUSE_CHILD_POT_35] = Location::Pot(RC_MK_GUARD_HOUSE_CHILD_POT_35, RCQUEST_BOTH, RCAREA_MARKET, SCENE_MARKET_GUARD_HOUSE, TWO_ACTOR_PARAMS(177, 85), "Guard House Child Pot 35", RHT_POT_GUARD_HOUSE, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_MK_GUARD_HOUSE_CHILD_POT_35));
|
||||
locationTable[RC_MK_GUARD_HOUSE_CHILD_POT_36] = Location::Pot(RC_MK_GUARD_HOUSE_CHILD_POT_36, RCQUEST_BOTH, RCAREA_MARKET, SCENE_MARKET_GUARD_HOUSE, TWO_ACTOR_PARAMS(155, 39), "Guard House Child Pot 36", RHT_POT_GUARD_HOUSE, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_MK_GUARD_HOUSE_CHILD_POT_36));
|
||||
locationTable[RC_MK_GUARD_HOUSE_CHILD_POT_37] = Location::Pot(RC_MK_GUARD_HOUSE_CHILD_POT_37, RCQUEST_BOTH, RCAREA_MARKET, SCENE_MARKET_GUARD_HOUSE, TWO_ACTOR_PARAMS(184, 13), "Guard House Child Pot 37", RHT_POT_GUARD_HOUSE, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_MK_GUARD_HOUSE_CHILD_POT_37));
|
||||
locationTable[RC_MK_GUARD_HOUSE_CHILD_POT_38] = Location::Pot(RC_MK_GUARD_HOUSE_CHILD_POT_38, RCQUEST_BOTH, RCAREA_MARKET, SCENE_MARKET_GUARD_HOUSE, TWO_ACTOR_PARAMS(156, -1), "Guard House Child Pot 38", RHT_POT_GUARD_HOUSE, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_MK_GUARD_HOUSE_CHILD_POT_38));
|
||||
locationTable[RC_MK_GUARD_HOUSE_CHILD_POT_39] = Location::Pot(RC_MK_GUARD_HOUSE_CHILD_POT_39, RCQUEST_BOTH, RCAREA_MARKET, SCENE_MARKET_GUARD_HOUSE, TWO_ACTOR_PARAMS(181, -33), "Guard House Child Pot 39", RHT_POT_GUARD_HOUSE, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_MK_GUARD_HOUSE_CHILD_POT_39));
|
||||
locationTable[RC_MK_GUARD_HOUSE_CHILD_POT_40] = Location::Pot(RC_MK_GUARD_HOUSE_CHILD_POT_40, RCQUEST_BOTH, RCAREA_MARKET, SCENE_MARKET_GUARD_HOUSE, TWO_ACTOR_PARAMS(156, -45), "Guard House Child Pot 40", RHT_POT_GUARD_HOUSE, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_MK_GUARD_HOUSE_CHILD_POT_40));
|
||||
locationTable[RC_MK_GUARD_HOUSE_CHILD_POT_41] = Location::Pot(RC_MK_GUARD_HOUSE_CHILD_POT_41, RCQUEST_BOTH, RCAREA_MARKET, SCENE_MARKET_GUARD_HOUSE, TWO_ACTOR_PARAMS(172, -82), "Guard House Child Pot 41", RHT_POT_GUARD_HOUSE, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_MK_GUARD_HOUSE_CHILD_POT_41));
|
||||
locationTable[RC_MK_GUARD_HOUSE_CHILD_POT_42] = Location::Pot(RC_MK_GUARD_HOUSE_CHILD_POT_42, RCQUEST_BOTH, RCAREA_MARKET, SCENE_MARKET_GUARD_HOUSE, TWO_ACTOR_PARAMS(170, -120), "Guard House Child Pot 42", RHT_POT_GUARD_HOUSE, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_MK_GUARD_HOUSE_CHILD_POT_42));
|
||||
locationTable[RC_MK_GUARD_HOUSE_CHILD_POT_43] = Location::Pot(RC_MK_GUARD_HOUSE_CHILD_POT_43, RCQUEST_BOTH, RCAREA_MARKET, SCENE_MARKET_GUARD_HOUSE, TWO_ACTOR_PARAMS(170, -166), "Guard House Child Pot 43", RHT_POT_GUARD_HOUSE, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_MK_GUARD_HOUSE_CHILD_POT_43));
|
||||
locationTable[RC_MK_GUARD_HOUSE_CHILD_POT_44] = Location::Pot(RC_MK_GUARD_HOUSE_CHILD_POT_44, RCQUEST_BOTH, RCAREA_MARKET, SCENE_MARKET_GUARD_HOUSE, TWO_ACTOR_PARAMS(170, -216), "Guard House Child Pot 44", RHT_POT_GUARD_HOUSE, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_MK_GUARD_HOUSE_CHILD_POT_44));
|
||||
locationTable[RC_MK_GUARD_HOUSE_ADULT_POT_1] = Location::Pot(RC_MK_GUARD_HOUSE_ADULT_POT_1, RCQUEST_BOTH, RCAREA_MARKET, SCENE_MARKET_GUARD_HOUSE, TWO_ACTOR_PARAMS(61, 204), "Guard House Adult Pot 1", RHT_POT_POE_SHOP, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_MK_GUARD_HOUSE_ADULT_POT_1));
|
||||
locationTable[RC_MK_GUARD_HOUSE_ADULT_POT_2] = Location::Pot(RC_MK_GUARD_HOUSE_ADULT_POT_2, RCQUEST_BOTH, RCAREA_MARKET, SCENE_MARKET_GUARD_HOUSE, TWO_ACTOR_PARAMS(71, 132), "Guard House Adult Pot 2", RHT_POT_POE_SHOP, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_MK_GUARD_HOUSE_ADULT_POT_2));
|
||||
locationTable[RC_MK_GUARD_HOUSE_ADULT_POT_3] = Location::Pot(RC_MK_GUARD_HOUSE_ADULT_POT_3, RCQUEST_BOTH, RCAREA_MARKET, SCENE_MARKET_GUARD_HOUSE, TWO_ACTOR_PARAMS(74, 23), "Guard House Adult Pot 3", RHT_POT_POE_SHOP, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_MK_GUARD_HOUSE_ADULT_POT_3));
|
||||
locationTable[RC_MK_GUARD_HOUSE_ADULT_POT_4] = Location::Pot(RC_MK_GUARD_HOUSE_ADULT_POT_4, RCQUEST_BOTH, RCAREA_MARKET, SCENE_MARKET_GUARD_HOUSE, TWO_ACTOR_PARAMS(40, 4), "Guard House Adult Pot 4", RHT_POT_POE_SHOP, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_MK_GUARD_HOUSE_ADULT_POT_4));
|
||||
locationTable[RC_MK_GUARD_HOUSE_ADULT_POT_5] = Location::Pot(RC_MK_GUARD_HOUSE_ADULT_POT_5, RCQUEST_BOTH, RCAREA_MARKET, SCENE_MARKET_GUARD_HOUSE, TWO_ACTOR_PARAMS(71, -22), "Guard House Adult Pot 5", RHT_POT_POE_SHOP, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_MK_GUARD_HOUSE_ADULT_POT_5));
|
||||
locationTable[RC_MK_GUARD_HOUSE_ADULT_POT_6] = Location::Pot(RC_MK_GUARD_HOUSE_ADULT_POT_6, RCQUEST_BOTH, RCAREA_MARKET, SCENE_MARKET_GUARD_HOUSE, TWO_ACTOR_PARAMS(44, -151), "Guard House Adult Pot 6", RHT_POT_POE_SHOP, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_MK_GUARD_HOUSE_ADULT_POT_6));
|
||||
locationTable[RC_MK_GUARD_HOUSE_ADULT_POT_7] = Location::Pot(RC_MK_GUARD_HOUSE_ADULT_POT_7, RCQUEST_BOTH, RCAREA_MARKET, SCENE_MARKET_GUARD_HOUSE, TWO_ACTOR_PARAMS(79, -182), "Guard House Adult Pot 7", RHT_POT_POE_SHOP, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_MK_GUARD_HOUSE_ADULT_POT_7));
|
||||
locationTable[RC_MK_GUARD_HOUSE_ADULT_POT_8] = Location::Pot(RC_MK_GUARD_HOUSE_ADULT_POT_8, RCQUEST_BOTH, RCAREA_MARKET, SCENE_MARKET_GUARD_HOUSE, TWO_ACTOR_PARAMS(44, -198), "Guard House Adult Pot 8", RHT_POT_POE_SHOP, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_MK_GUARD_HOUSE_ADULT_POT_8));
|
||||
locationTable[RC_MK_GUARD_HOUSE_ADULT_POT_9] = Location::Pot(RC_MK_GUARD_HOUSE_ADULT_POT_9, RCQUEST_BOTH, RCAREA_MARKET, SCENE_MARKET_GUARD_HOUSE, TWO_ACTOR_PARAMS(168, 210), "Guard House Adult Pot 9", RHT_POT_POE_SHOP, RG_RED_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_MK_GUARD_HOUSE_ADULT_POT_9));
|
||||
locationTable[RC_MK_GUARD_HOUSE_ADULT_POT_10] = Location::Pot(RC_MK_GUARD_HOUSE_ADULT_POT_10, RCQUEST_BOTH, RCAREA_MARKET, SCENE_MARKET_GUARD_HOUSE, TWO_ACTOR_PARAMS(167, -122), "Guard House Adult Pot 10", RHT_POT_POE_SHOP, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_MK_GUARD_HOUSE_ADULT_POT_10));
|
||||
locationTable[RC_MK_GUARD_HOUSE_ADULT_POT_11] = Location::Pot(RC_MK_GUARD_HOUSE_ADULT_POT_11, RCQUEST_BOTH, RCAREA_MARKET, SCENE_MARKET_GUARD_HOUSE, TWO_ACTOR_PARAMS(167, -210), "Guard House Adult Pot 11", RHT_POT_POE_SHOP, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_MK_GUARD_HOUSE_ADULT_POT_11));
|
||||
locationTable[RC_MK_BACK_ALLEY_HOUSE_POT_1] = Location::Pot(RC_MK_BACK_ALLEY_HOUSE_POT_1, RCQUEST_BOTH, RCAREA_MARKET, SCENE_BACK_ALLEY_HOUSE, TWO_ACTOR_PARAMS(100, 45), "Back Alley House Pot 1", RHT_POT_ALLY_HOUSE, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_MK_BACK_ALLEY_HOUSE_POT_1));
|
||||
locationTable[RC_MK_BACK_ALLEY_HOUSE_POT_2] = Location::Pot(RC_MK_BACK_ALLEY_HOUSE_POT_2, RCQUEST_BOTH, RCAREA_MARKET, SCENE_BACK_ALLEY_HOUSE, TWO_ACTOR_PARAMS(12, -180), "Back Alley House Pot 2", RHT_POT_ALLY_HOUSE, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_MK_BACK_ALLEY_HOUSE_POT_2));
|
||||
locationTable[RC_MK_BACK_ALLEY_HOUSE_POT_3] = Location::Pot(RC_MK_BACK_ALLEY_HOUSE_POT_3, RCQUEST_BOTH, RCAREA_MARKET, SCENE_BACK_ALLEY_HOUSE, TWO_ACTOR_PARAMS(-54, -180), "Back Alley House Pot 3", RHT_POT_ALLY_HOUSE, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_MK_BACK_ALLEY_HOUSE_POT_3));
|
||||
locationTable[RC_KAK_NEAR_POTION_SHOP_POT_1] = Location::Pot(RC_KAK_NEAR_POTION_SHOP_POT_1, RCQUEST_BOTH, RCAREA_KAKARIKO_VILLAGE, SCENE_KAKARIKO_VILLAGE, TWO_ACTOR_PARAMS(222, -377), "Near Potion Shop Pot 1", RHT_POT_KAKARIKO, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_KAK_NEAR_POTION_SHOP_POT_1));
|
||||
locationTable[RC_KAK_NEAR_POTION_SHOP_POT_2] = Location::Pot(RC_KAK_NEAR_POTION_SHOP_POT_2, RCQUEST_BOTH, RCAREA_KAKARIKO_VILLAGE, SCENE_KAKARIKO_VILLAGE, TWO_ACTOR_PARAMS(255, -366), "Near Potion Shop Pot 2", RHT_POT_KAKARIKO, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_KAK_NEAR_POTION_SHOP_POT_2));
|
||||
locationTable[RC_KAK_NEAR_POTION_SHOP_POT_3] = Location::Pot(RC_KAK_NEAR_POTION_SHOP_POT_3, RCQUEST_BOTH, RCAREA_KAKARIKO_VILLAGE, SCENE_KAKARIKO_VILLAGE, TWO_ACTOR_PARAMS(284, -356), "Near Potion Shop Pot 3", RHT_POT_KAKARIKO, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_KAK_NEAR_POTION_SHOP_POT_3));
|
||||
@@ -197,12 +197,12 @@ void Rando::StaticData::RegisterPotLocations() {
|
||||
locationTable[RC_KAK_NEAR_GUARDS_HOUSE_POT_3] = Location::Pot(RC_KAK_NEAR_GUARDS_HOUSE_POT_3, RCQUEST_BOTH, RCAREA_KAKARIKO_VILLAGE, SCENE_KAKARIKO_VILLAGE, TWO_ACTOR_PARAMS(-450, -895), "Near Guards House Pot 3", RHT_POT_KAKARIKO, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_KAK_NEAR_GUARDS_HOUSE_POT_3));
|
||||
locationTable[RC_KAK_NEAR_MEDICINE_SHOP_POT_1] = Location::Pot(RC_KAK_NEAR_MEDICINE_SHOP_POT_1, RCQUEST_BOTH, RCAREA_KAKARIKO_VILLAGE, SCENE_KAKARIKO_VILLAGE, TWO_ACTOR_PARAMS(781, 89), "Near Medicine Shop Pot 1", RHT_POT_KAKARIKO, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_KAK_NEAR_MEDICINE_SHOP_POT_1));
|
||||
locationTable[RC_KAK_NEAR_MEDICINE_SHOP_POT_2] = Location::Pot(RC_KAK_NEAR_MEDICINE_SHOP_POT_2, RCQUEST_BOTH, RCAREA_KAKARIKO_VILLAGE, SCENE_KAKARIKO_VILLAGE, TWO_ACTOR_PARAMS(815, 89), "Near Medicine Shop Pot 2", RHT_POT_KAKARIKO, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_KAK_NEAR_MEDICINE_SHOP_POT_2));
|
||||
locationTable[RC_GY_DAMPES_GRAVE_POT_1] = Location::Pot(RC_GY_DAMPES_GRAVE_POT_1, RCQUEST_BOTH, RCAREA_GRAVEYARD, SCENE_WINDMILL_AND_DAMPES_GRAVE, TWO_ACTOR_PARAMS(-319, -1542), "Dampes Grave Pot 1", RHT_POT_GRAVEYARD, RG_ARROWS_5, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GY_DAMPES_GRAVE_POT_1));
|
||||
locationTable[RC_GY_DAMPES_GRAVE_POT_2] = Location::Pot(RC_GY_DAMPES_GRAVE_POT_2, RCQUEST_BOTH, RCAREA_GRAVEYARD, SCENE_WINDMILL_AND_DAMPES_GRAVE, TWO_ACTOR_PARAMS(-319, -1600), "Dampes Grave Pot 2", RHT_POT_GRAVEYARD, RG_BOMBS_5, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GY_DAMPES_GRAVE_POT_2));
|
||||
locationTable[RC_GY_DAMPES_GRAVE_POT_3] = Location::Pot(RC_GY_DAMPES_GRAVE_POT_3, RCQUEST_BOTH, RCAREA_GRAVEYARD, SCENE_WINDMILL_AND_DAMPES_GRAVE, TWO_ACTOR_PARAMS(-364, -1571), "Dampes Grave Pot 3", RHT_POT_GRAVEYARD, RG_RED_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GY_DAMPES_GRAVE_POT_3));
|
||||
locationTable[RC_GY_DAMPES_GRAVE_POT_4] = Location::Pot(RC_GY_DAMPES_GRAVE_POT_4, RCQUEST_BOTH, RCAREA_GRAVEYARD, SCENE_WINDMILL_AND_DAMPES_GRAVE, TWO_ACTOR_PARAMS(198, -1540), "Dampes Grave Pot 4", RHT_POT_GRAVEYARD, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GY_DAMPES_GRAVE_POT_4));
|
||||
locationTable[RC_GY_DAMPES_GRAVE_POT_5] = Location::Pot(RC_GY_DAMPES_GRAVE_POT_5, RCQUEST_BOTH, RCAREA_GRAVEYARD, SCENE_WINDMILL_AND_DAMPES_GRAVE, TWO_ACTOR_PARAMS(198, -1608), "Dampes Grave Pot 5", RHT_POT_GRAVEYARD, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GY_DAMPES_GRAVE_POT_5));
|
||||
locationTable[RC_GY_DAMPES_GRAVE_POT_6] = Location::Pot(RC_GY_DAMPES_GRAVE_POT_6, RCQUEST_BOTH, RCAREA_GRAVEYARD, SCENE_WINDMILL_AND_DAMPES_GRAVE, TWO_ACTOR_PARAMS(239, -1577), "Dampes Grave Pot 6", RHT_POT_GRAVEYARD, RG_DEKU_NUTS_5, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GY_DAMPES_GRAVE_POT_6));
|
||||
locationTable[RC_GY_DAMPES_GRAVE_POT_1] = Location::Pot(RC_GY_DAMPES_GRAVE_POT_1, RCQUEST_BOTH, RCAREA_GRAVEYARD, SCENE_WINDMILL_AND_DAMPES_GRAVE, TWO_ACTOR_PARAMS(-319, -1542), "Dampes Grave Pot 1", RHT_POT_DAMPE, RG_ARROWS_5, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GY_DAMPES_GRAVE_POT_1));
|
||||
locationTable[RC_GY_DAMPES_GRAVE_POT_2] = Location::Pot(RC_GY_DAMPES_GRAVE_POT_2, RCQUEST_BOTH, RCAREA_GRAVEYARD, SCENE_WINDMILL_AND_DAMPES_GRAVE, TWO_ACTOR_PARAMS(-319, -1600), "Dampes Grave Pot 2", RHT_POT_DAMPE, RG_BOMBS_5, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GY_DAMPES_GRAVE_POT_2));
|
||||
locationTable[RC_GY_DAMPES_GRAVE_POT_3] = Location::Pot(RC_GY_DAMPES_GRAVE_POT_3, RCQUEST_BOTH, RCAREA_GRAVEYARD, SCENE_WINDMILL_AND_DAMPES_GRAVE, TWO_ACTOR_PARAMS(-364, -1571), "Dampes Grave Pot 3", RHT_POT_DAMPE, RG_RED_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GY_DAMPES_GRAVE_POT_3));
|
||||
locationTable[RC_GY_DAMPES_GRAVE_POT_4] = Location::Pot(RC_GY_DAMPES_GRAVE_POT_4, RCQUEST_BOTH, RCAREA_GRAVEYARD, SCENE_WINDMILL_AND_DAMPES_GRAVE, TWO_ACTOR_PARAMS(198, -1540), "Dampes Grave Pot 4", RHT_POT_DAMPE, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GY_DAMPES_GRAVE_POT_4));
|
||||
locationTable[RC_GY_DAMPES_GRAVE_POT_5] = Location::Pot(RC_GY_DAMPES_GRAVE_POT_5, RCQUEST_BOTH, RCAREA_GRAVEYARD, SCENE_WINDMILL_AND_DAMPES_GRAVE, TWO_ACTOR_PARAMS(198, -1608), "Dampes Grave Pot 5", RHT_POT_DAMPE, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GY_DAMPES_GRAVE_POT_5));
|
||||
locationTable[RC_GY_DAMPES_GRAVE_POT_6] = Location::Pot(RC_GY_DAMPES_GRAVE_POT_6, RCQUEST_BOTH, RCAREA_GRAVEYARD, SCENE_WINDMILL_AND_DAMPES_GRAVE, TWO_ACTOR_PARAMS(239, -1577), "Dampes Grave Pot 6", RHT_POT_DAMPE, RG_DEKU_NUTS_5, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GY_DAMPES_GRAVE_POT_6));
|
||||
locationTable[RC_GC_LOWER_STAIRCASE_POT_1] = Location::Pot(RC_GC_LOWER_STAIRCASE_POT_1, RCQUEST_BOTH, RCAREA_GORON_CITY, SCENE_GORON_CITY, TWO_ACTOR_PARAMS(-189, 866), "Lower Staircase Pot 1", RHT_POT_GORON_CITY, RG_DEKU_STICK_1, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GC_LOWER_STAIRCASE_POT_1));
|
||||
locationTable[RC_GC_LOWER_STAIRCASE_POT_2] = Location::Pot(RC_GC_LOWER_STAIRCASE_POT_2, RCQUEST_BOTH, RCAREA_GORON_CITY, SCENE_GORON_CITY, TWO_ACTOR_PARAMS(-271, 825), "Lower Staircase Pot 2", RHT_POT_GORON_CITY, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GC_LOWER_STAIRCASE_POT_2));
|
||||
locationTable[RC_GC_UPPER_STAIRCASE_POT_1] = Location::Pot(RC_GC_UPPER_STAIRCASE_POT_1, RCQUEST_BOTH, RCAREA_GORON_CITY, SCENE_GORON_CITY, TWO_ACTOR_PARAMS(-1170, 60), "Upper Staircase Pot 1", RHT_POT_GORON_CITY, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GC_UPPER_STAIRCASE_POT_1));
|
||||
@@ -235,15 +235,15 @@ void Rando::StaticData::RegisterPotLocations() {
|
||||
locationTable[RC_LLR_RAIN_SHED_POT_1] = Location::Pot(RC_LLR_RAIN_SHED_POT_1, RCQUEST_BOTH, RCAREA_LON_LON_RANCH, SCENE_LON_LON_RANCH, TWO_ACTOR_PARAMS(852, 172), "Rain Shed Pot 1", RHT_POT_LON_LON_RANCH, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_LLR_RAIN_SHED_POT_1));
|
||||
locationTable[RC_LLR_RAIN_SHED_POT_2] = Location::Pot(RC_LLR_RAIN_SHED_POT_2, RCQUEST_BOTH, RCAREA_LON_LON_RANCH, SCENE_LON_LON_RANCH, TWO_ACTOR_PARAMS(840, 212), "Rain Shed Pot 2", RHT_POT_LON_LON_RANCH, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_LLR_RAIN_SHED_POT_2));
|
||||
locationTable[RC_LLR_RAIN_SHED_POT_3] = Location::Pot(RC_LLR_RAIN_SHED_POT_3, RCQUEST_BOTH, RCAREA_LON_LON_RANCH, SCENE_LON_LON_RANCH, TWO_ACTOR_PARAMS(872, 219), "Rain Shed Pot 3", RHT_POT_LON_LON_RANCH, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_LLR_RAIN_SHED_POT_3));
|
||||
locationTable[RC_LLR_TALONS_HOUSE_POT_1] = Location::Pot(RC_LLR_TALONS_HOUSE_POT_1, RCQUEST_BOTH, RCAREA_LON_LON_RANCH, SCENE_LON_LON_BUILDINGS, TWO_ACTOR_PARAMS(1255, 47), "Talons House Pot 1", RHT_POT_LON_LON_RANCH, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_LLR_TALONS_HOUSE_POT_1));
|
||||
locationTable[RC_LLR_TALONS_HOUSE_POT_2] = Location::Pot(RC_LLR_TALONS_HOUSE_POT_2, RCQUEST_BOTH, RCAREA_LON_LON_RANCH, SCENE_LON_LON_BUILDINGS, TWO_ACTOR_PARAMS(1256, -51), "Talons House Pot 2", RHT_POT_LON_LON_RANCH, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_LLR_TALONS_HOUSE_POT_2));
|
||||
locationTable[RC_LLR_TALONS_HOUSE_POT_3] = Location::Pot(RC_LLR_TALONS_HOUSE_POT_3, RCQUEST_BOTH, RCAREA_LON_LON_RANCH, SCENE_LON_LON_BUILDINGS, TWO_ACTOR_PARAMS(1256, -78), "Talons House Pot 3", RHT_POT_LON_LON_RANCH, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_LLR_TALONS_HOUSE_POT_3));
|
||||
locationTable[RC_HF_COW_GROTTO_POT_1] = Location::Pot(RC_HF_COW_GROTTO_POT_1, RCQUEST_BOTH, RCAREA_HYRULE_FIELD, SCENE_GROTTOS, TWO_ACTOR_PARAMS(3410, -223), "Cow Grotto Pot 1", RHT_POT_HYRULE_FIELD, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_HF_COW_GROTTO_POT_1));
|
||||
locationTable[RC_HF_COW_GROTTO_POT_2] = Location::Pot(RC_HF_COW_GROTTO_POT_2, RCQUEST_BOTH, RCAREA_HYRULE_FIELD, SCENE_GROTTOS, TWO_ACTOR_PARAMS(3390, -258), "Cow Grotto Pot 2", RHT_POT_HYRULE_FIELD, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_HF_COW_GROTTO_POT_2));
|
||||
locationTable[RC_HC_STORMS_GROTTO_POT_1] = Location::Pot(RC_HC_STORMS_GROTTO_POT_1, RCQUEST_BOTH, RCAREA_HYRULE_CASTLE, SCENE_GROTTOS, TWO_ACTOR_PARAMS(1843, 1014), "Storms Grotto Pot 1", RHT_POT_HYRULE_CASTLE, RG_RED_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_HC_STORMS_GROTTO_POT_1));
|
||||
locationTable[RC_HC_STORMS_GROTTO_POT_2] = Location::Pot(RC_HC_STORMS_GROTTO_POT_2, RCQUEST_BOTH, RCAREA_HYRULE_CASTLE, SCENE_GROTTOS, TWO_ACTOR_PARAMS(1769, 954), "Storms Grotto Pot 2", RHT_POT_HYRULE_CASTLE, RG_ARROWS_5, SpoilerCollectionCheck::RandomizerInf(RAND_INF_HC_STORMS_GROTTO_POT_2));
|
||||
locationTable[RC_HC_STORMS_GROTTO_POT_3] = Location::Pot(RC_HC_STORMS_GROTTO_POT_3, RCQUEST_BOTH, RCAREA_HYRULE_CASTLE, SCENE_GROTTOS, TWO_ACTOR_PARAMS(1857, 897), "Storms Grotto Pot 3", RHT_POT_HYRULE_CASTLE, RG_BOMBS_5, SpoilerCollectionCheck::RandomizerInf(RAND_INF_HC_STORMS_GROTTO_POT_3));
|
||||
locationTable[RC_HC_STORMS_GROTTO_POT_4] = Location::Pot(RC_HC_STORMS_GROTTO_POT_4, RCQUEST_BOTH, RCAREA_HYRULE_CASTLE, SCENE_GROTTOS, TWO_ACTOR_PARAMS(1764, 847), "Storms Grotto Pot 4", RHT_POT_HYRULE_CASTLE, RG_DEKU_NUTS_5, SpoilerCollectionCheck::RandomizerInf(RAND_INF_HC_STORMS_GROTTO_POT_4));
|
||||
locationTable[RC_LLR_TALONS_HOUSE_POT_1] = Location::Pot(RC_LLR_TALONS_HOUSE_POT_1, RCQUEST_BOTH, RCAREA_LON_LON_RANCH, SCENE_LON_LON_BUILDINGS, TWO_ACTOR_PARAMS(1255, 47), "Talons House Pot 1", RHT_POT_TALONS_HOUSE, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_LLR_TALONS_HOUSE_POT_1));
|
||||
locationTable[RC_LLR_TALONS_HOUSE_POT_2] = Location::Pot(RC_LLR_TALONS_HOUSE_POT_2, RCQUEST_BOTH, RCAREA_LON_LON_RANCH, SCENE_LON_LON_BUILDINGS, TWO_ACTOR_PARAMS(1256, -51), "Talons House Pot 2", RHT_POT_TALONS_HOUSE, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_LLR_TALONS_HOUSE_POT_2));
|
||||
locationTable[RC_LLR_TALONS_HOUSE_POT_3] = Location::Pot(RC_LLR_TALONS_HOUSE_POT_3, RCQUEST_BOTH, RCAREA_LON_LON_RANCH, SCENE_LON_LON_BUILDINGS, TWO_ACTOR_PARAMS(1256, -78), "Talons House Pot 3", RHT_POT_TALONS_HOUSE, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_LLR_TALONS_HOUSE_POT_3));
|
||||
locationTable[RC_HF_COW_GROTTO_POT_1] = Location::Pot(RC_HF_COW_GROTTO_POT_1, RCQUEST_BOTH, RCAREA_HYRULE_FIELD, SCENE_GROTTOS, TWO_ACTOR_PARAMS(3410, -223), "Cow Grotto Pot 1", RHT_POT_WEB_GROTTO, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_HF_COW_GROTTO_POT_1));
|
||||
locationTable[RC_HF_COW_GROTTO_POT_2] = Location::Pot(RC_HF_COW_GROTTO_POT_2, RCQUEST_BOTH, RCAREA_HYRULE_FIELD, SCENE_GROTTOS, TWO_ACTOR_PARAMS(3390, -258), "Cow Grotto Pot 2", RHT_POT_WEB_GROTTO, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_HF_COW_GROTTO_POT_2));
|
||||
locationTable[RC_HC_STORMS_GROTTO_POT_1] = Location::Pot(RC_HC_STORMS_GROTTO_POT_1, RCQUEST_BOTH, RCAREA_HYRULE_CASTLE, SCENE_GROTTOS, TWO_ACTOR_PARAMS(1843, 1014), "Storms Grotto Pot 1", RHT_POT_MUD_WALL_GROTTO, RG_RED_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_HC_STORMS_GROTTO_POT_1));
|
||||
locationTable[RC_HC_STORMS_GROTTO_POT_2] = Location::Pot(RC_HC_STORMS_GROTTO_POT_2, RCQUEST_BOTH, RCAREA_HYRULE_CASTLE, SCENE_GROTTOS, TWO_ACTOR_PARAMS(1769, 954), "Storms Grotto Pot 2", RHT_POT_MUD_WALL_GROTTO, RG_ARROWS_5, SpoilerCollectionCheck::RandomizerInf(RAND_INF_HC_STORMS_GROTTO_POT_2));
|
||||
locationTable[RC_HC_STORMS_GROTTO_POT_3] = Location::Pot(RC_HC_STORMS_GROTTO_POT_3, RCQUEST_BOTH, RCAREA_HYRULE_CASTLE, SCENE_GROTTOS, TWO_ACTOR_PARAMS(1857, 897), "Storms Grotto Pot 3", RHT_POT_MUD_WALL_GROTTO, RG_BOMBS_5, SpoilerCollectionCheck::RandomizerInf(RAND_INF_HC_STORMS_GROTTO_POT_3));
|
||||
locationTable[RC_HC_STORMS_GROTTO_POT_4] = Location::Pot(RC_HC_STORMS_GROTTO_POT_4, RCQUEST_BOTH, RCAREA_HYRULE_CASTLE, SCENE_GROTTOS, TWO_ACTOR_PARAMS(1764, 847), "Storms Grotto Pot 4", RHT_POT_MUD_WALL_GROTTO, RG_DEKU_NUTS_5, SpoilerCollectionCheck::RandomizerInf(RAND_INF_HC_STORMS_GROTTO_POT_4));
|
||||
|
||||
// Dungeon Pots
|
||||
// Randomizer Check Randomizer Check Quest Area Scene ID Params Short Name Spoiler Name Hint Text Key Vanilla Spoiler Collection Check
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
#include "fishsanity.h"
|
||||
#include "macros.h"
|
||||
#include "3drando/hints.hpp"
|
||||
#include "soh/util.h"
|
||||
#include "../kaleido.h"
|
||||
|
||||
#include <fstream>
|
||||
@@ -160,12 +161,16 @@ bool Context::IsQuestOfLocationActive(RandomizerCheck rc) {
|
||||
|
||||
void Context::GenerateLocationPool() {
|
||||
allLocations.clear();
|
||||
overworldLocations.clear();
|
||||
for (auto dungeon : ctx->GetDungeons()->GetDungeonList()) {
|
||||
dungeon->locations.clear();
|
||||
}
|
||||
for (Location& location : StaticData::GetLocationTable()) {
|
||||
// skip RCs that shouldn't be in the pool for any reason (i.e. settings, unsupported check type, etc.)
|
||||
// TODO: Exclude checks for some of the older shuffles from the pool too i.e. Frog Songs, Scrubs, etc.)
|
||||
if (location.GetRandomizerCheck() == RC_UNKNOWN_CHECK ||
|
||||
location.GetRandomizerCheck() == RC_TRIFORCE_COMPLETED || // already in pool
|
||||
(location.GetRandomizerCheck() == RC_MASTER_SWORD_PEDESTAL &&
|
||||
(location.GetRandomizerCheck() == RC_TOT_MASTER_SWORD &&
|
||||
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)) ||
|
||||
@@ -370,25 +375,8 @@ GetItemEntry Context::GetFinalGIEntry(const RandomizerCheck rc, const bool check
|
||||
return giEntry;
|
||||
}
|
||||
|
||||
std::string sanitize(std::string stringValue) {
|
||||
// Add backslashes.
|
||||
for (auto i = stringValue.begin();;) {
|
||||
auto const pos =
|
||||
std::find_if(i, stringValue.end(), [](char const c) { return '\\' == c || '\'' == c || '"' == c; });
|
||||
if (pos == stringValue.end()) {
|
||||
break;
|
||||
}
|
||||
i = std::next(stringValue.insert(pos, '\\'), 2);
|
||||
}
|
||||
|
||||
// Removes others.
|
||||
std::erase_if(stringValue, [](char const c) { return '\n' == c || '\r' == c || '\0' == c || '\x1A' == c; });
|
||||
|
||||
return stringValue;
|
||||
}
|
||||
|
||||
void Context::ParseSpoiler(const char* spoilerFileName) {
|
||||
std::ifstream spoilerFileStream(sanitize(spoilerFileName));
|
||||
std::ifstream spoilerFileStream(SohUtils::Sanitize(spoilerFileName));
|
||||
if (!spoilerFileStream) {
|
||||
return;
|
||||
}
|
||||
@@ -397,11 +385,13 @@ void Context::ParseSpoiler(const char* spoilerFileName) {
|
||||
try {
|
||||
nlohmann::json spoilerFileJson;
|
||||
spoilerFileStream >> spoilerFileJson;
|
||||
spoilerFileStream.close();
|
||||
ParseHashIconIndexesJson(spoilerFileJson);
|
||||
Rando::Settings::GetInstance()->ParseJson(spoilerFileJson);
|
||||
ParseItemLocationsJson(spoilerFileJson);
|
||||
ParseHintJson(spoilerFileJson);
|
||||
ParseTricksJson(spoilerFileJson);
|
||||
mEntranceShuffler->ParseJson(spoilerFileJson);
|
||||
ParseHintJson(spoilerFileJson);
|
||||
mDungeons->ParseJson(spoilerFileJson);
|
||||
mTrials->ParseJson(spoilerFileJson);
|
||||
mSpoilerLoaded = true;
|
||||
@@ -469,6 +459,17 @@ void Context::ParseHintJson(nlohmann::json spoilerFileJson) {
|
||||
CreateStaticHints();
|
||||
}
|
||||
|
||||
void Context::ParseTricksJson(nlohmann::json spoilerFileJson) {
|
||||
nlohmann::json enabledTricksJson = spoilerFileJson["enabledTricks"];
|
||||
const auto& settings = Rando::Settings::GetInstance();
|
||||
for (auto it : enabledTricksJson) {
|
||||
int rt = settings->GetRandomizerTrickByName(it);
|
||||
if (rt != -1) {
|
||||
mTrickOptions[rt].Set(RO_GENERIC_ON);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
std::shared_ptr<EntranceShuffler> Context::GetEntranceShuffler() {
|
||||
return mEntranceShuffler;
|
||||
}
|
||||
@@ -524,6 +525,10 @@ RandoOptionLACSCondition Context::LACSCondition() const {
|
||||
return mLACSCondition;
|
||||
}
|
||||
|
||||
void Context::LACSCondition(RandoOptionLACSCondition lacsCondition) {
|
||||
mLACSCondition = lacsCondition;
|
||||
}
|
||||
|
||||
std::shared_ptr<Kaleido> Context::GetKaleido() {
|
||||
if (mKaleido == nullptr) {
|
||||
mKaleido = std::make_shared<Kaleido>();
|
||||
|
||||
@@ -104,12 +104,22 @@ class Context {
|
||||
* @return RandoOptionLACSCondition
|
||||
*/
|
||||
RandoOptionLACSCondition LACSCondition() const;
|
||||
|
||||
/**
|
||||
* @brief Sets the resolved Light Arrow CutScene check condition.
|
||||
* There is no direct option for this, it is inferred based on the value of a few other options.
|
||||
*
|
||||
* @param lacsCondition
|
||||
*/
|
||||
void LACSCondition(RandoOptionLACSCondition lacsCondition);
|
||||
|
||||
GetItemEntry GetFinalGIEntry(RandomizerCheck rc, bool checkObtainability = true, GetItemID ogItemId = GI_NONE);
|
||||
void ParseSpoiler(const char* spoilerFileName);
|
||||
void ParseHashIconIndexesJson(nlohmann::json spoilerFileJson);
|
||||
void ParseItemLocationsJson(nlohmann::json spoilerFileJson);
|
||||
void WriteHintJson(nlohmann::ordered_json& spoilerFileJson);
|
||||
void ParseHintJson(nlohmann::json spoilerFileJson);
|
||||
void ParseTricksJson(nlohmann::json spoilerFileJson);
|
||||
std::map<RandomizerCheck, ItemOverride> overrides = {};
|
||||
std::vector<std::vector<RandomizerCheck>> playthroughLocations = {};
|
||||
std::vector<RandomizerCheck> everyPossibleLocation = {};
|
||||
|
||||
@@ -250,7 +250,319 @@ std::string EntranceNameByRegions(RandomizerRegion parentRegion, RandomizerRegio
|
||||
return RegionTable(parentRegion)->regionName + " -> " + RegionTable(connectedRegion)->regionName;
|
||||
}
|
||||
|
||||
void SetAllEntrancesData(std::vector<EntranceInfoPair>& entranceShuffleTable) {
|
||||
std::unordered_map<int16_t, Entrance*> entranceMap;
|
||||
|
||||
void SetAllEntrancesData() {
|
||||
std::vector<EntranceInfoPair> entranceShuffleTable = {
|
||||
// clang-format off
|
||||
// Type Parent Region Connected Region Index
|
||||
{ { EntranceType::Dungeon, RR_KF_OUTSIDE_DEKU_TREE, RR_DEKU_TREE_ENTRYWAY, ENTR_DEKU_TREE_ENTRANCE },
|
||||
{ EntranceType::Dungeon, RR_DEKU_TREE_ENTRYWAY, RR_KF_OUTSIDE_DEKU_TREE, ENTR_KOKIRI_FOREST_OUTSIDE_DEKU_TREE } },
|
||||
{ { EntranceType::Dungeon, RR_DEATH_MOUNTAIN_TRAIL, RR_DODONGOS_CAVERN_ENTRYWAY, ENTR_DODONGOS_CAVERN_ENTRANCE },
|
||||
{ EntranceType::Dungeon, RR_DODONGOS_CAVERN_ENTRYWAY, RR_DEATH_MOUNTAIN_TRAIL, ENTR_DEATH_MOUNTAIN_TRAIL_OUTSIDE_DODONGOS_CAVERN } },
|
||||
{ { EntranceType::Dungeon, RR_ZORAS_FOUNTAIN, RR_JABU_JABUS_BELLY_ENTRYWAY, ENTR_JABU_JABU_ENTRANCE },
|
||||
{ EntranceType::Dungeon, RR_JABU_JABUS_BELLY_ENTRYWAY, RR_ZORAS_FOUNTAIN, ENTR_ZORAS_FOUNTAIN_OUTSIDE_JABU_JABU } },
|
||||
{ { EntranceType::Dungeon, RR_SACRED_FOREST_MEADOW, RR_FOREST_TEMPLE_ENTRYWAY, ENTR_FOREST_TEMPLE_ENTRANCE },
|
||||
{ EntranceType::Dungeon, RR_FOREST_TEMPLE_ENTRYWAY, RR_SACRED_FOREST_MEADOW, ENTR_SACRED_FOREST_MEADOW_OUTSIDE_TEMPLE } },
|
||||
{ { EntranceType::Dungeon, RR_DMC_CENTRAL_LOCAL, RR_FIRE_TEMPLE_ENTRYWAY, ENTR_FIRE_TEMPLE_ENTRANCE },
|
||||
{ EntranceType::Dungeon, RR_FIRE_TEMPLE_ENTRYWAY, RR_DMC_CENTRAL_LOCAL, ENTR_DEATH_MOUNTAIN_CRATER_OUTSIDE_TEMPLE } },
|
||||
{ { EntranceType::Dungeon, RR_LAKE_HYLIA, RR_WATER_TEMPLE_ENTRYWAY, ENTR_WATER_TEMPLE_ENTRANCE },
|
||||
{ EntranceType::Dungeon, RR_WATER_TEMPLE_ENTRYWAY, RR_LAKE_HYLIA, ENTR_LAKE_HYLIA_OUTSIDE_TEMPLE } },
|
||||
{ { EntranceType::Dungeon, RR_DESERT_COLOSSUS, RR_SPIRIT_TEMPLE_ENTRYWAY, ENTR_SPIRIT_TEMPLE_ENTRANCE },
|
||||
{ EntranceType::Dungeon, RR_SPIRIT_TEMPLE_ENTRYWAY, RR_DESERT_COLOSSUS_OUTSIDE_TEMPLE, ENTR_DESERT_COLOSSUS_OUTSIDE_TEMPLE } },
|
||||
{ { EntranceType::Dungeon, RR_GRAVEYARD_WARP_PAD_REGION, RR_SHADOW_TEMPLE_ENTRYWAY, ENTR_SHADOW_TEMPLE_ENTRANCE },
|
||||
{ EntranceType::Dungeon, RR_SHADOW_TEMPLE_ENTRYWAY, RR_GRAVEYARD_WARP_PAD_REGION, ENTR_GRAVEYARD_OUTSIDE_TEMPLE } },
|
||||
{ { EntranceType::Dungeon, RR_KAK_WELL, RR_BOTTOM_OF_THE_WELL_ENTRYWAY, ENTR_BOTTOM_OF_THE_WELL_ENTRANCE },
|
||||
{ EntranceType::Dungeon, RR_BOTTOM_OF_THE_WELL_ENTRYWAY, RR_KAK_WELL, ENTR_KAKARIKO_VILLAGE_OUTSIDE_BOTTOM_OF_THE_WELL } },
|
||||
{ { EntranceType::Dungeon, RR_ZF_LEDGE, RR_ICE_CAVERN_ENTRYWAY, ENTR_ICE_CAVERN_ENTRANCE },
|
||||
{ EntranceType::Dungeon, RR_ICE_CAVERN_ENTRYWAY, RR_ZF_LEDGE, ENTR_ZORAS_FOUNTAIN_OUTSIDE_ICE_CAVERN } },
|
||||
{ { EntranceType::Dungeon, RR_GERUDO_FORTRESS, RR_GERUDO_TRAINING_GROUND_ENTRYWAY, ENTR_GERUDO_TRAINING_GROUND_ENTRANCE },
|
||||
{ EntranceType::Dungeon, RR_GERUDO_TRAINING_GROUND_ENTRYWAY, RR_GERUDO_FORTRESS, ENTR_GERUDOS_FORTRESS_OUTSIDE_GERUDO_TRAINING_GROUND } },
|
||||
{ { EntranceType::GanonDungeon, RR_GANONS_CASTLE_LEDGE, RR_GANONS_CASTLE_ENTRYWAY, ENTR_INSIDE_GANONS_CASTLE_ENTRANCE },
|
||||
{ EntranceType::GanonDungeon, RR_GANONS_CASTLE_ENTRYWAY, RR_CASTLE_GROUNDS_FROM_GANONS_CASTLE, ENTR_CASTLE_GROUNDS_RAINBOW_BRIDGE_EXIT } },
|
||||
|
||||
{ { EntranceType::Interior, RR_KOKIRI_FOREST, RR_KF_MIDOS_HOUSE, ENTR_MIDOS_HOUSE_0 },
|
||||
{ EntranceType::Interior, RR_KF_MIDOS_HOUSE, RR_KOKIRI_FOREST, ENTR_KOKIRI_FOREST_OUTSIDE_MIDOS_HOUSE } },
|
||||
{ { EntranceType::Interior, RR_KOKIRI_FOREST, RR_KF_SARIAS_HOUSE, ENTR_SARIAS_HOUSE_0 },
|
||||
{ EntranceType::Interior, RR_KF_SARIAS_HOUSE, RR_KOKIRI_FOREST, ENTR_KOKIRI_FOREST_OUTSIDE_SARIAS_HOUSE } },
|
||||
{ { EntranceType::Interior, RR_KOKIRI_FOREST, RR_KF_HOUSE_OF_TWINS, ENTR_TWINS_HOUSE_0 },
|
||||
{ EntranceType::Interior, RR_KF_HOUSE_OF_TWINS, RR_KOKIRI_FOREST, ENTR_KOKIRI_FOREST_OUTSIDE_TWINS_HOUSE } },
|
||||
{ { EntranceType::Interior, RR_KOKIRI_FOREST, RR_KF_KNOW_IT_ALL_HOUSE, ENTR_KNOW_IT_ALL_BROS_HOUSE_0 },
|
||||
{ EntranceType::Interior, RR_KF_KNOW_IT_ALL_HOUSE, RR_KOKIRI_FOREST, ENTR_KOKIRI_FOREST_OUTSIDE_KNOW_IT_ALL_HOUSE } },
|
||||
{ { EntranceType::Interior, RR_KOKIRI_FOREST, RR_KF_KOKIRI_SHOP, ENTR_KOKIRI_SHOP_0 },
|
||||
{ EntranceType::Interior, RR_KF_KOKIRI_SHOP, RR_KOKIRI_FOREST, ENTR_KOKIRI_FOREST_OUTSIDE_SHOP } },
|
||||
{ { EntranceType::Interior, RR_LAKE_HYLIA, RR_LH_LAB, ENTR_LAKESIDE_LABORATORY_0 },
|
||||
{ EntranceType::Interior, RR_LH_LAB, RR_LAKE_HYLIA, ENTR_LAKE_HYLIA_OUTSIDE_LAB } },
|
||||
{ { EntranceType::Interior, RR_LH_FISHING_ISLAND, RR_LH_FISHING_POND, ENTR_FISHING_POND_0 },
|
||||
{ EntranceType::Interior, RR_LH_FISHING_POND, RR_LH_FISHING_ISLAND, ENTR_LAKE_HYLIA_OUTSIDE_FISHING_POND } },
|
||||
{ { EntranceType::Interior, RR_GV_FORTRESS_SIDE, RR_GV_CARPENTER_TENT, ENTR_CARPENTERS_TENT_0 },
|
||||
{ EntranceType::Interior, RR_GV_CARPENTER_TENT, RR_GV_FORTRESS_SIDE, ENTR_GERUDO_VALLEY_OUTSIDE_TENT } },
|
||||
{ { EntranceType::Interior, RR_MARKET_ENTRANCE, RR_MARKET_GUARD_HOUSE, ENTR_MARKET_GUARD_HOUSE_0 },
|
||||
{ EntranceType::Interior, RR_MARKET_GUARD_HOUSE, RR_MARKET_ENTRANCE, ENTR_MARKET_ENTRANCE_OUTSIDE_GUARD_HOUSE } },
|
||||
{ { EntranceType::Interior, RR_THE_MARKET, RR_MARKET_MASK_SHOP, ENTR_HAPPY_MASK_SHOP_0 },
|
||||
{ EntranceType::Interior, RR_MARKET_MASK_SHOP, RR_THE_MARKET, ENTR_MARKET_DAY_OUTSIDE_HAPPY_MASK_SHOP } },
|
||||
{ { EntranceType::Interior, RR_THE_MARKET, RR_MARKET_BOMBCHU_BOWLING, ENTR_BOMBCHU_BOWLING_ALLEY_0 },
|
||||
{ EntranceType::Interior, RR_MARKET_BOMBCHU_BOWLING, RR_THE_MARKET, ENTR_MARKET_DAY_OUTSIDE_BOMBCHU_BOWLING } },
|
||||
{ { EntranceType::Interior, RR_THE_MARKET, RR_MARKET_POTION_SHOP, ENTR_POTION_SHOP_MARKET_0 },
|
||||
{ EntranceType::Interior, RR_MARKET_POTION_SHOP, RR_THE_MARKET, ENTR_MARKET_DAY_OUTSIDE_POTION_SHOP } },
|
||||
{ { EntranceType::Interior, RR_THE_MARKET, RR_MARKET_TREASURE_CHEST_GAME, ENTR_TREASURE_BOX_SHOP_0 },
|
||||
{ EntranceType::Interior, RR_MARKET_TREASURE_CHEST_GAME, RR_THE_MARKET, ENTR_MARKET_DAY_OUTSIDE_TREASURE_BOX_SHOP } },
|
||||
{ { EntranceType::Interior, RR_MARKET_BACK_ALLEY, RR_MARKET_BOMBCHU_SHOP, ENTR_BOMBCHU_SHOP_1 },
|
||||
{ EntranceType::Interior, RR_MARKET_BOMBCHU_SHOP, RR_MARKET_BACK_ALLEY, ENTR_BACK_ALLEY_DAY_OUTSIDE_BOMBCHU_SHOP } },
|
||||
{ { EntranceType::Interior, RR_MARKET_BACK_ALLEY, RR_MARKET_MAN_IN_GREEN_HOUSE, ENTR_BACK_ALLEY_MAN_IN_GREEN_HOUSE },
|
||||
{ EntranceType::Interior, RR_MARKET_MAN_IN_GREEN_HOUSE, RR_MARKET_BACK_ALLEY, ENTR_BACK_ALLEY_DAY_OUTSIDE_MAN_IN_GREEN_HOUSE } },
|
||||
{ { EntranceType::Interior, RR_KAKARIKO_VILLAGE, RR_KAK_CARPENTER_BOSS_HOUSE, ENTR_KAKARIKO_CENTER_GUEST_HOUSE_0 },
|
||||
{ EntranceType::Interior, RR_KAK_CARPENTER_BOSS_HOUSE, RR_KAKARIKO_VILLAGE, ENTR_KAKARIKO_VILLAGE_OUTSIDE_CENTER_GUEST_HOUSE } },
|
||||
{ { EntranceType::Interior, RR_KAKARIKO_VILLAGE, RR_KAK_HOUSE_OF_SKULLTULA, ENTR_HOUSE_OF_SKULLTULA_0 },
|
||||
{ EntranceType::Interior, RR_KAK_HOUSE_OF_SKULLTULA, RR_KAKARIKO_VILLAGE, ENTR_KAKARIKO_VILLAGE_OUTSIDE_SKULKLTULA_HOUSE } },
|
||||
{ { EntranceType::Interior, RR_KAKARIKO_VILLAGE, RR_KAK_IMPAS_HOUSE, ENTR_IMPAS_HOUSE_FRONT },
|
||||
{ EntranceType::Interior, RR_KAK_IMPAS_HOUSE, RR_KAKARIKO_VILLAGE, ENTR_KAKARIKO_VILLAGE_OUTSIDE_IMPAS_HOUSE_FRONT } },
|
||||
{ { EntranceType::Interior, RR_KAK_IMPAS_LEDGE, RR_KAK_IMPAS_HOUSE_BACK, ENTR_IMPAS_HOUSE_BACK },
|
||||
{ EntranceType::Interior, RR_KAK_IMPAS_HOUSE_BACK, RR_KAK_IMPAS_LEDGE, ENTR_KAKARIKO_VILLAGE_OUTSIDE_IMPAS_HOUSE_BACK } },
|
||||
{ { EntranceType::Interior, RR_KAK_BACKYARD, RR_KAK_ODD_POTION_BUILDING, ENTR_POTION_SHOP_GRANNY_0 },
|
||||
{ EntranceType::Interior, RR_KAK_ODD_POTION_BUILDING, RR_KAK_BACKYARD, ENTR_KAKARIKO_VILLAGE_OUTSIDE_SHOP_GRANNY } },
|
||||
{ { EntranceType::Interior, RR_THE_GRAVEYARD, RR_GRAVEYARD_DAMPES_HOUSE, ENTR_GRAVEKEEPERS_HUT_0 },
|
||||
{ EntranceType::Interior, RR_GRAVEYARD_DAMPES_HOUSE, RR_THE_GRAVEYARD, ENTR_GRAVEYARD_OUTSIDE_DAMPES_HUT } },
|
||||
{ { EntranceType::Interior, RR_GORON_CITY, RR_GC_SHOP, ENTR_GORON_SHOP_0 },
|
||||
{ EntranceType::Interior, RR_GC_SHOP, RR_GORON_CITY, ENTR_GORON_CITY_OUTSIDE_SHOP } },
|
||||
{ { EntranceType::Interior, RR_ZORAS_DOMAIN, RR_ZD_SHOP, ENTR_ZORA_SHOP_0 },
|
||||
{ EntranceType::Interior, RR_ZD_SHOP, RR_ZORAS_DOMAIN, ENTR_ZORAS_DOMAIN_OUTSIDE_SHOP } },
|
||||
{ { EntranceType::Interior, RR_LON_LON_RANCH, RR_LLR_TALONS_HOUSE, ENTR_LON_LON_BUILDINGS_TALONS_HOUSE },
|
||||
{ EntranceType::Interior, RR_LLR_TALONS_HOUSE, RR_LON_LON_RANCH, ENTR_LON_LON_RANCH_OUTSIDE_TALONS_HOUSE } },
|
||||
{ { EntranceType::Interior, RR_LON_LON_RANCH, RR_LLR_STABLES, ENTR_STABLE_0 },
|
||||
{ EntranceType::Interior, RR_LLR_STABLES, RR_LON_LON_RANCH, ENTR_LON_LON_RANCH_OUTSIDE_STABLES } },
|
||||
{ { EntranceType::Interior, RR_LON_LON_RANCH, RR_LLR_TOWER, ENTR_LON_LON_BUILDINGS_TOWER },
|
||||
{ EntranceType::Interior, RR_LLR_TOWER, RR_LON_LON_RANCH, ENTR_LON_LON_RANCH_OUTSIDE_TOWER } },
|
||||
{ { EntranceType::Interior, RR_THE_MARKET, RR_MARKET_BAZAAR, ENTR_BAZAAR_1 },
|
||||
{ EntranceType::Interior, RR_MARKET_BAZAAR, RR_THE_MARKET, ENTR_MARKET_DAY_OUTSIDE_BAZAAR } },
|
||||
{ { EntranceType::Interior, RR_THE_MARKET, RR_MARKET_SHOOTING_GALLERY, ENTR_SHOOTING_GALLERY_1 },
|
||||
{ EntranceType::Interior, RR_MARKET_SHOOTING_GALLERY, RR_THE_MARKET, ENTR_MARKET_DAY_OUTSIDE_SHOOTING_GALLERY } },
|
||||
{ { EntranceType::Interior, RR_KAKARIKO_VILLAGE, RR_KAK_BAZAAR, ENTR_BAZAAR_0 },
|
||||
{ EntranceType::Interior, RR_KAK_BAZAAR, RR_KAKARIKO_VILLAGE, ENTR_KAKARIKO_VILLAGE_OUTSIDE_BAZAAR } },
|
||||
{ { EntranceType::Interior, RR_KAKARIKO_VILLAGE, RR_KAK_SHOOTING_GALLERY, ENTR_SHOOTING_GALLERY_0 },
|
||||
{ EntranceType::Interior, RR_KAK_SHOOTING_GALLERY, RR_KAKARIKO_VILLAGE, ENTR_KAKARIKO_VILLAGE_OUTSIDE_SHOOTING_GALLERY } },
|
||||
{ { EntranceType::Interior, RR_DESERT_COLOSSUS, RR_COLOSSUS_GREAT_FAIRY_FOUNTAIN, ENTR_GREAT_FAIRYS_FOUNTAIN_SPELLS_NAYRUS_COLOSSUS },
|
||||
{ EntranceType::Interior, RR_COLOSSUS_GREAT_FAIRY_FOUNTAIN, RR_DESERT_COLOSSUS, ENTR_DESERT_COLOSSUS_GREAT_FAIRY_EXIT } },
|
||||
{ { EntranceType::Interior, RR_HYRULE_CASTLE_GROUNDS, RR_HC_GREAT_FAIRY_FOUNTAIN, ENTR_GREAT_FAIRYS_FOUNTAIN_SPELLS_DINS_HC },
|
||||
{ EntranceType::Interior, RR_HC_GREAT_FAIRY_FOUNTAIN, RR_CASTLE_GROUNDS, ENTR_CASTLE_GROUNDS_GREAT_FAIRY_EXIT } },
|
||||
{ { EntranceType::Interior, RR_GANONS_CASTLE_GROUNDS, RR_OGC_GREAT_FAIRY_FOUNTAIN, ENTR_GREAT_FAIRYS_FOUNTAIN_MAGIC_OGC_DD },
|
||||
// 0x3E8 is an unused entrance index repruposed to differentiate between the HC and OGC fairy
|
||||
// fountain exits (normally they both use 0x340)
|
||||
{ EntranceType::Interior, RR_OGC_GREAT_FAIRY_FOUNTAIN, RR_CASTLE_GROUNDS, ENTR_POTION_SHOP_KAKARIKO_1 } },
|
||||
{ { EntranceType::Interior, RR_DMC_LOWER_NEARBY, RR_DMC_GREAT_FAIRY_FOUNTAIN, ENTR_GREAT_FAIRYS_FOUNTAIN_MAGIC_DMC },
|
||||
{ EntranceType::Interior, RR_DMC_GREAT_FAIRY_FOUNTAIN, RR_DMC_LOWER_LOCAL, ENTR_DEATH_MOUNTAIN_CRATER_GREAT_FAIRY_EXIT } },
|
||||
{ { EntranceType::Interior, RR_DEATH_MOUNTAIN_SUMMIT, RR_DMT_GREAT_FAIRY_FOUNTAIN, ENTR_GREAT_FAIRYS_FOUNTAIN_MAGIC_DMT },
|
||||
{ EntranceType::Interior, RR_DMT_GREAT_FAIRY_FOUNTAIN, RR_DEATH_MOUNTAIN_SUMMIT, ENTR_DEATH_MOUNTAIN_TRAIL_GREAT_FAIRY_EXIT } },
|
||||
{ { EntranceType::Interior, RR_ZORAS_FOUNTAIN, RR_ZF_GREAT_FAIRY_FOUNTAIN, ENTR_GREAT_FAIRYS_FOUNTAIN_SPELLS_FARORES_ZF },
|
||||
{ EntranceType::Interior, RR_ZF_GREAT_FAIRY_FOUNTAIN, RR_ZORAS_FOUNTAIN, ENTR_ZORAS_FOUNTAIN_OUTSIDE_GREAT_FAIRY } },
|
||||
|
||||
{ { EntranceType::SpecialInterior, RR_KOKIRI_FOREST, RR_KF_LINKS_HOUSE, ENTR_LINKS_HOUSE_1 },
|
||||
{ EntranceType::SpecialInterior, RR_KF_LINKS_HOUSE, RR_KOKIRI_FOREST, ENTR_KOKIRI_FOREST_OUTSIDE_LINKS_HOUSE } },
|
||||
{ { EntranceType::SpecialInterior, RR_TOT_ENTRANCE, RR_TEMPLE_OF_TIME, ENTR_TEMPLE_OF_TIME_ENTRANCE },
|
||||
{ EntranceType::SpecialInterior, RR_TEMPLE_OF_TIME, RR_TOT_ENTRANCE, ENTR_TEMPLE_OF_TIME_EXTERIOR_DAY_OUTSIDE_TEMPLE } },
|
||||
{ { EntranceType::SpecialInterior, RR_KAKARIKO_VILLAGE, RR_KAK_WINDMILL, ENTR_WINDMILL_AND_DAMPES_GRAVE_WINDMILL },
|
||||
{ EntranceType::SpecialInterior, RR_KAK_WINDMILL, RR_KAKARIKO_VILLAGE, ENTR_KAKARIKO_VILLAGE_OUTSIDE_WINDMILL } },
|
||||
{ { EntranceType::SpecialInterior, RR_KAKARIKO_VILLAGE, RR_KAK_POTION_SHOP_FRONT, ENTR_POTION_SHOP_KAKARIKO_FRONT },
|
||||
{ EntranceType::SpecialInterior, RR_KAK_POTION_SHOP_FRONT, RR_KAKARIKO_VILLAGE, ENTR_KAKARIKO_VILLAGE_OUTSIDE_POTION_SHOP_FRONT } },
|
||||
{ { EntranceType::SpecialInterior, RR_KAK_BACKYARD, RR_KAK_POTION_SHOP_BACK, ENTR_POTION_SHOP_KAKARIKO_BACK },
|
||||
{ EntranceType::SpecialInterior, RR_KAK_POTION_SHOP_BACK, RR_KAK_BACKYARD, ENTR_KAKARIKO_VILLAGE_OUTSIDE_POTION_SHOP_BACK } },
|
||||
|
||||
// Grotto Loads use an entrance index of 0x0700 + their grotto id. The id is used as index for the
|
||||
// grottoLoadTable in soh/soh/Enhancements/randomizer/randomizer_grotto.c
|
||||
// Grotto Returns use an entrance index of 0x0800 + their grotto id. The id is used as index for the
|
||||
// grottoReturnTable in soh/soh/Enhancements/randomizer/randomizer_grotto.c
|
||||
{ { EntranceType::GrottoGrave, RR_DESERT_COLOSSUS, RR_COLOSSUS_GROTTO, ENTRANCE_GROTTO_LOAD(GROTTO_COLOSSUS_OFFSET) },
|
||||
{ EntranceType::GrottoGrave, RR_COLOSSUS_GROTTO, RR_DESERT_COLOSSUS, ENTRANCE_GROTTO_EXIT(GROTTO_COLOSSUS_OFFSET) } },
|
||||
{ { EntranceType::GrottoGrave, RR_LAKE_HYLIA, RR_LH_GROTTO, ENTRANCE_GROTTO_LOAD(GROTTO_LH_OFFSET) },
|
||||
{ EntranceType::GrottoGrave, RR_LH_GROTTO, RR_LAKE_HYLIA, ENTRANCE_GROTTO_EXIT(GROTTO_LH_OFFSET) } },
|
||||
{ { EntranceType::GrottoGrave, RR_ZORAS_RIVER, RR_ZR_STORMS_GROTTO, ENTRANCE_GROTTO_LOAD(GROTTO_ZR_STORMS_OFFSET) },
|
||||
{ EntranceType::GrottoGrave, RR_ZR_STORMS_GROTTO, RR_ZORAS_RIVER, ENTRANCE_GROTTO_EXIT(GROTTO_ZR_STORMS_OFFSET) } },
|
||||
{ { EntranceType::GrottoGrave, RR_ZORAS_RIVER, RR_ZR_FAIRY_GROTTO, ENTRANCE_GROTTO_LOAD(GROTTO_ZR_FAIRY_OFFSET) },
|
||||
{ EntranceType::GrottoGrave, RR_ZR_FAIRY_GROTTO, RR_ZORAS_RIVER, ENTRANCE_GROTTO_EXIT(GROTTO_ZR_FAIRY_OFFSET) } },
|
||||
{ { EntranceType::GrottoGrave, RR_ZORAS_RIVER, RR_ZR_OPEN_GROTTO, ENTRANCE_GROTTO_LOAD(GROTTO_ZR_OPEN_OFFSET) },
|
||||
{ EntranceType::GrottoGrave, RR_ZR_OPEN_GROTTO, RR_ZORAS_RIVER, ENTRANCE_GROTTO_EXIT(GROTTO_ZR_OPEN_OFFSET) } },
|
||||
{ { EntranceType::GrottoGrave, RR_DMC_LOWER_NEARBY, RR_DMC_HAMMER_GROTTO, ENTRANCE_GROTTO_LOAD(GROTTO_DMC_HAMMER_OFFSET) },
|
||||
{ EntranceType::GrottoGrave, RR_DMC_HAMMER_GROTTO, RR_DMC_LOWER_LOCAL, ENTRANCE_GROTTO_EXIT(GROTTO_DMC_HAMMER_OFFSET) } },
|
||||
{ { EntranceType::GrottoGrave, RR_DMC_UPPER_NEARBY, RR_DMC_UPPER_GROTTO, ENTRANCE_GROTTO_LOAD(GROTTO_DMC_UPPER_OFFSET) },
|
||||
{ EntranceType::GrottoGrave, RR_DMC_UPPER_GROTTO, RR_DMC_UPPER_LOCAL, ENTRANCE_GROTTO_EXIT(GROTTO_DMC_UPPER_OFFSET) } },
|
||||
{ { EntranceType::GrottoGrave, RR_GC_GROTTO_PLATFORM, RR_GC_GROTTO, ENTRANCE_GROTTO_LOAD(GROTTO_GORON_CITY_OFFSET) },
|
||||
{ EntranceType::GrottoGrave, RR_GC_GROTTO, RR_GC_GROTTO_PLATFORM, ENTRANCE_GROTTO_EXIT(GROTTO_GORON_CITY_OFFSET) } },
|
||||
{ { EntranceType::GrottoGrave, RR_DEATH_MOUNTAIN_TRAIL, RR_DMT_STORMS_GROTTO, ENTRANCE_GROTTO_LOAD(GROTTO_DMT_STORMS_OFFSET) },
|
||||
{ EntranceType::GrottoGrave, RR_DMT_STORMS_GROTTO, RR_DEATH_MOUNTAIN_TRAIL, ENTRANCE_GROTTO_EXIT(GROTTO_DMT_STORMS_OFFSET) } },
|
||||
{ { EntranceType::GrottoGrave, RR_DEATH_MOUNTAIN_SUMMIT, RR_DMT_COW_GROTTO, ENTRANCE_GROTTO_LOAD(GROTTO_DMT_COW_OFFSET) },
|
||||
{ EntranceType::GrottoGrave, RR_DMT_COW_GROTTO, RR_DEATH_MOUNTAIN_SUMMIT, ENTRANCE_GROTTO_EXIT(GROTTO_DMT_COW_OFFSET) } },
|
||||
{ { EntranceType::GrottoGrave, RR_KAK_BACKYARD, RR_KAK_OPEN_GROTTO, ENTRANCE_GROTTO_LOAD(GROTTO_KAK_OPEN_OFFSET) },
|
||||
{ EntranceType::GrottoGrave, RR_KAK_OPEN_GROTTO, RR_KAK_BACKYARD, ENTRANCE_GROTTO_EXIT(GROTTO_KAK_OPEN_OFFSET) } },
|
||||
{ { EntranceType::GrottoGrave, RR_KAKARIKO_VILLAGE, RR_KAK_REDEAD_GROTTO, ENTRANCE_GROTTO_LOAD(GROTTO_KAK_REDEAD_OFFSET) },
|
||||
{ EntranceType::GrottoGrave, RR_KAK_REDEAD_GROTTO, RR_KAKARIKO_VILLAGE, ENTRANCE_GROTTO_EXIT(GROTTO_KAK_REDEAD_OFFSET) } },
|
||||
{ { EntranceType::GrottoGrave, RR_HYRULE_CASTLE_GROUNDS, RR_HC_STORMS_GROTTO, ENTRANCE_GROTTO_LOAD(GROTTO_HC_STORMS_OFFSET) },
|
||||
{ EntranceType::GrottoGrave, RR_HC_STORMS_GROTTO, RR_CASTLE_GROUNDS, ENTRANCE_GROTTO_EXIT(GROTTO_HC_STORMS_OFFSET) } },
|
||||
{ { EntranceType::GrottoGrave, RR_HYRULE_FIELD, RR_HF_TEKTITE_GROTTO, ENTRANCE_GROTTO_LOAD(GROTTO_HF_TEKTITE_OFFSET) },
|
||||
{ EntranceType::GrottoGrave, RR_HF_TEKTITE_GROTTO, RR_HYRULE_FIELD, ENTRANCE_GROTTO_EXIT(GROTTO_HF_TEKTITE_OFFSET) } },
|
||||
{ { EntranceType::GrottoGrave, RR_HYRULE_FIELD, RR_HF_NEAR_KAK_GROTTO, ENTRANCE_GROTTO_LOAD(GROTTO_HF_NEAR_KAK_OFFSET) },
|
||||
{ EntranceType::GrottoGrave, RR_HF_NEAR_KAK_GROTTO, RR_HYRULE_FIELD, ENTRANCE_GROTTO_EXIT(GROTTO_HF_NEAR_KAK_OFFSET) } },
|
||||
{ { EntranceType::GrottoGrave, RR_HYRULE_FIELD, RR_HF_FAIRY_GROTTO, ENTRANCE_GROTTO_LOAD(GROTTO_HF_FAIRY_OFFSET) },
|
||||
{ EntranceType::GrottoGrave, RR_HF_FAIRY_GROTTO, RR_HYRULE_FIELD, ENTRANCE_GROTTO_EXIT(GROTTO_HF_FAIRY_OFFSET) } },
|
||||
{ { EntranceType::GrottoGrave, RR_HYRULE_FIELD, RR_HF_NEAR_MARKET_GROTTO, ENTRANCE_GROTTO_LOAD(GROTTO_HF_NEAR_MARKET_OFFSET) },
|
||||
{ EntranceType::GrottoGrave, RR_HF_NEAR_MARKET_GROTTO, RR_HYRULE_FIELD, ENTRANCE_GROTTO_EXIT(GROTTO_HF_NEAR_MARKET_OFFSET) } },
|
||||
{ { EntranceType::GrottoGrave, RR_HYRULE_FIELD, RR_HF_COW_GROTTO, ENTRANCE_GROTTO_LOAD(GROTTO_HF_COW_OFFSET) },
|
||||
{ EntranceType::GrottoGrave, RR_HF_COW_GROTTO, RR_HYRULE_FIELD, ENTRANCE_GROTTO_EXIT(GROTTO_HF_COW_OFFSET) } },
|
||||
{ { EntranceType::GrottoGrave, RR_HYRULE_FIELD, RR_HF_INSIDE_FENCE_GROTTO, ENTRANCE_GROTTO_LOAD(GROTTO_HF_INSIDE_FENCE_OFFSET) },
|
||||
{ EntranceType::GrottoGrave, RR_HF_INSIDE_FENCE_GROTTO, RR_HYRULE_FIELD, ENTRANCE_GROTTO_EXIT(GROTTO_HF_INSIDE_FENCE_OFFSET) } },
|
||||
{ { EntranceType::GrottoGrave, RR_HYRULE_FIELD, RR_HF_OPEN_GROTTO, ENTRANCE_GROTTO_LOAD(GROTTO_HF_OPEN_OFFSET) },
|
||||
{ EntranceType::GrottoGrave, RR_HF_OPEN_GROTTO, RR_HYRULE_FIELD, ENTRANCE_GROTTO_EXIT(GROTTO_HF_OPEN_OFFSET) } },
|
||||
{ { EntranceType::GrottoGrave, RR_HYRULE_FIELD, RR_HF_SOUTHEAST_GROTTO, ENTRANCE_GROTTO_LOAD(GROTTO_HF_SOUTHEAST_OFFSET) },
|
||||
{ EntranceType::GrottoGrave, RR_HF_SOUTHEAST_GROTTO, RR_HYRULE_FIELD, ENTRANCE_GROTTO_EXIT(GROTTO_HF_SOUTHEAST_OFFSET) } },
|
||||
{ { EntranceType::GrottoGrave, RR_LON_LON_RANCH, RR_LLR_GROTTO, ENTRANCE_GROTTO_LOAD(GROTTO_LLR_OFFSET) },
|
||||
{ EntranceType::GrottoGrave, RR_LLR_GROTTO, RR_LON_LON_RANCH, ENTRANCE_GROTTO_EXIT(GROTTO_LLR_OFFSET) } },
|
||||
{ { EntranceType::GrottoGrave, RR_SFM_ENTRYWAY, RR_SFM_WOLFOS_GROTTO, ENTRANCE_GROTTO_LOAD(GROTTO_SFM_WOLFOS_OFFSET) },
|
||||
{ EntranceType::GrottoGrave, RR_SFM_WOLFOS_GROTTO, RR_SFM_ENTRYWAY, ENTRANCE_GROTTO_EXIT(GROTTO_SFM_WOLFOS_OFFSET) } },
|
||||
{ { EntranceType::GrottoGrave, RR_SACRED_FOREST_MEADOW, RR_SFM_STORMS_GROTTO, ENTRANCE_GROTTO_LOAD(GROTTO_SFM_STORMS_OFFSET) },
|
||||
{ EntranceType::GrottoGrave, RR_SFM_STORMS_GROTTO, RR_SACRED_FOREST_MEADOW, ENTRANCE_GROTTO_EXIT(GROTTO_SFM_STORMS_OFFSET) } },
|
||||
{ { EntranceType::GrottoGrave, RR_SACRED_FOREST_MEADOW, RR_SFM_FAIRY_GROTTO, ENTRANCE_GROTTO_LOAD(GROTTO_SFM_FAIRY_OFFSET) },
|
||||
{ EntranceType::GrottoGrave, RR_SFM_FAIRY_GROTTO, RR_SACRED_FOREST_MEADOW, ENTRANCE_GROTTO_EXIT(GROTTO_SFM_FAIRY_OFFSET) } },
|
||||
{ { EntranceType::GrottoGrave, RR_LW_BEYOND_MIDO, RR_LW_SCRUBS_GROTTO, ENTRANCE_GROTTO_LOAD(GROTTO_LW_SCRUBS_OFFSET) },
|
||||
{ EntranceType::GrottoGrave, RR_LW_SCRUBS_GROTTO, RR_LW_BEYOND_MIDO, ENTRANCE_GROTTO_EXIT(GROTTO_LW_SCRUBS_OFFSET) } },
|
||||
{ { EntranceType::GrottoGrave, RR_THE_LOST_WOODS, RR_LW_NEAR_SHORTCUTS_GROTTO, ENTRANCE_GROTTO_LOAD(GROTTO_LW_NEAR_SHORTCUTS_OFFSET) },
|
||||
{ EntranceType::GrottoGrave, RR_LW_NEAR_SHORTCUTS_GROTTO, RR_THE_LOST_WOODS, ENTRANCE_GROTTO_EXIT(GROTTO_LW_NEAR_SHORTCUTS_OFFSET) } },
|
||||
{ { EntranceType::GrottoGrave, RR_KOKIRI_FOREST, RR_KF_STORMS_GROTTO, ENTRANCE_GROTTO_LOAD(GROTTO_KF_STORMS_OFFSET) },
|
||||
{ EntranceType::GrottoGrave, RR_KF_STORMS_GROTTO, RR_KOKIRI_FOREST, ENTRANCE_GROTTO_EXIT(GROTTO_KF_STORMS_OFFSET) } },
|
||||
{ { EntranceType::GrottoGrave, RR_ZORAS_DOMAIN_ISLAND, RR_ZD_STORMS_GROTTO, ENTRANCE_GROTTO_LOAD(GROTTO_ZD_STORMS_OFFSET) },
|
||||
{ EntranceType::GrottoGrave, RR_ZD_STORMS_GROTTO, RR_ZORAS_DOMAIN_ISLAND, ENTRANCE_GROTTO_EXIT(GROTTO_ZD_STORMS_OFFSET) } },
|
||||
{ { EntranceType::GrottoGrave, RR_GERUDO_FORTRESS, RR_GF_STORMS_GROTTO, ENTRANCE_GROTTO_LOAD(GROTTO_GF_STORMS_OFFSET) },
|
||||
{ EntranceType::GrottoGrave, RR_GF_STORMS_GROTTO, RR_GERUDO_FORTRESS, ENTRANCE_GROTTO_EXIT(GROTTO_GF_STORMS_OFFSET) } },
|
||||
{ { EntranceType::GrottoGrave, RR_GV_FORTRESS_SIDE, RR_GV_STORMS_GROTTO, ENTRANCE_GROTTO_LOAD(GROTTO_GV_STORMS_OFFSET) },
|
||||
{ EntranceType::GrottoGrave, RR_GV_STORMS_GROTTO, RR_GV_FORTRESS_SIDE, ENTRANCE_GROTTO_EXIT(GROTTO_GV_STORMS_OFFSET) } },
|
||||
{ { EntranceType::GrottoGrave, RR_GV_GROTTO_LEDGE, RR_GV_OCTOROK_GROTTO, ENTRANCE_GROTTO_LOAD(GROTTO_GV_OCTOROK_OFFSET) },
|
||||
{ EntranceType::GrottoGrave, RR_GV_OCTOROK_GROTTO, RR_GV_GROTTO_LEDGE, ENTRANCE_GROTTO_EXIT(GROTTO_GV_OCTOROK_OFFSET) } },
|
||||
{ { EntranceType::GrottoGrave, RR_LW_BEYOND_MIDO, RR_DEKU_THEATER, ENTRANCE_GROTTO_LOAD(GROTTO_LW_DEKU_THEATRE_OFFSET) },
|
||||
{ EntranceType::GrottoGrave, RR_DEKU_THEATER, RR_LW_BEYOND_MIDO, ENTRANCE_GROTTO_EXIT(GROTTO_LW_DEKU_THEATRE_OFFSET) } },
|
||||
|
||||
// Graves have their own specified entrance indices
|
||||
{ { EntranceType::GrottoGrave, RR_THE_GRAVEYARD, RR_GRAVEYARD_SHIELD_GRAVE, ENTR_GRAVE_WITH_FAIRYS_FOUNTAIN_0 },
|
||||
{ EntranceType::GrottoGrave, RR_GRAVEYARD_SHIELD_GRAVE, RR_THE_GRAVEYARD, ENTR_GRAVEYARD_SHIELD_GRAVE_EXIT } },
|
||||
{ { EntranceType::GrottoGrave, RR_THE_GRAVEYARD, RR_GRAVEYARD_HEART_PIECE_GRAVE, ENTR_REDEAD_GRAVE_0 },
|
||||
{ EntranceType::GrottoGrave, RR_GRAVEYARD_HEART_PIECE_GRAVE, RR_THE_GRAVEYARD, ENTR_GRAVEYARD_HEART_PIECE_GRAVE_EXIT } },
|
||||
{ { EntranceType::GrottoGrave, RR_THE_GRAVEYARD, RR_GRAVEYARD_COMPOSERS_GRAVE, ENTR_ROYAL_FAMILYS_TOMB_0 },
|
||||
{ EntranceType::GrottoGrave, RR_GRAVEYARD_COMPOSERS_GRAVE, RR_THE_GRAVEYARD, ENTR_GRAVEYARD_ROYAL_TOMB_EXIT } },
|
||||
{ { EntranceType::GrottoGrave, RR_THE_GRAVEYARD, RR_GRAVEYARD_DAMPES_GRAVE, ENTR_WINDMILL_AND_DAMPES_GRAVE_GRAVE },
|
||||
{ EntranceType::GrottoGrave, RR_GRAVEYARD_DAMPES_GRAVE, RR_THE_GRAVEYARD, ENTR_GRAVEYARD_DAMPES_GRAVE_EXIT } },
|
||||
|
||||
{ { EntranceType::Overworld, RR_KOKIRI_FOREST, RR_LW_BRIDGE_FROM_FOREST, ENTR_LOST_WOODS_BRIDGE_EAST_EXIT },
|
||||
{ EntranceType::Overworld, RR_LW_BRIDGE, RR_KOKIRI_FOREST, ENTR_KOKIRI_FOREST_LOWER_EXIT } },
|
||||
{ { EntranceType::Overworld, RR_KOKIRI_FOREST, RR_THE_LOST_WOODS, ENTR_LOST_WOODS_SOUTH_EXIT },
|
||||
{ EntranceType::Overworld, RR_LW_FOREST_EXIT, RR_KOKIRI_FOREST, ENTR_KOKIRI_FOREST_UPPER_EXIT } },
|
||||
{ { EntranceType::Overworld, RR_THE_LOST_WOODS, RR_GC_WOODS_WARP, ENTR_GORON_CITY_TUNNEL_SHORTCUT },
|
||||
{ EntranceType::Overworld, RR_GC_WOODS_WARP, RR_THE_LOST_WOODS, ENTR_LOST_WOODS_TUNNEL_SHORTCUT } },
|
||||
{ { EntranceType::Overworld, RR_THE_LOST_WOODS, RR_ZORAS_RIVER, ENTR_ZORAS_RIVER_UNDERWATER_SHORTCUT },
|
||||
{ EntranceType::Overworld, RR_ZORAS_RIVER, RR_THE_LOST_WOODS, ENTR_LOST_WOODS_UNDERWATER_SHORTCUT } },
|
||||
{ { EntranceType::Overworld, RR_LW_BEYOND_MIDO, RR_SFM_ENTRYWAY, ENTR_SACRED_FOREST_MEADOW_SOUTH_EXIT },
|
||||
{ EntranceType::Overworld, RR_SFM_ENTRYWAY, RR_LW_BEYOND_MIDO, ENTR_LOST_WOODS_NORTH_EXIT } },
|
||||
{ { EntranceType::Overworld, RR_LW_BRIDGE, RR_HYRULE_FIELD, ENTR_HYRULE_FIELD_WOODED_EXIT },
|
||||
{ EntranceType::Overworld, RR_HYRULE_FIELD, RR_LW_BRIDGE, ENTR_LOST_WOODS_BRIDGE_WEST_EXIT } },
|
||||
{ { EntranceType::Overworld, RR_HYRULE_FIELD, RR_LAKE_HYLIA, ENTR_LAKE_HYLIA_NORTH_EXIT },
|
||||
{ EntranceType::Overworld, RR_LAKE_HYLIA, RR_HYRULE_FIELD, ENTR_HYRULE_FIELD_FENCE_EXIT } },
|
||||
{ { EntranceType::Overworld, RR_HYRULE_FIELD, RR_GERUDO_VALLEY, ENTR_GERUDO_VALLEY_EAST_EXIT },
|
||||
{ EntranceType::Overworld, RR_GERUDO_VALLEY, RR_HYRULE_FIELD, ENTR_HYRULE_FIELD_ROCKY_PATH } },
|
||||
{ { EntranceType::Overworld, RR_HYRULE_FIELD, RR_MARKET_ENTRANCE, ENTR_MARKET_ENTRANCE_NEAR_GUARD_EXIT },
|
||||
{ EntranceType::Overworld, RR_MARKET_ENTRANCE, RR_HYRULE_FIELD, ENTR_HYRULE_FIELD_ON_BRIDGE_SPAWN } },
|
||||
{ { EntranceType::Overworld, RR_HYRULE_FIELD, RR_KAKARIKO_VILLAGE, ENTR_KAKARIKO_VILLAGE_FRONT_GATE },
|
||||
{ EntranceType::Overworld, RR_KAKARIKO_VILLAGE, RR_HYRULE_FIELD, ENTR_HYRULE_FIELD_STAIRS_EXIT } },
|
||||
{ { EntranceType::Overworld, RR_HYRULE_FIELD, RR_ZR_FRONT, ENTR_ZORAS_RIVER_WEST_EXIT },
|
||||
{ EntranceType::Overworld, RR_ZR_FRONT, RR_HYRULE_FIELD, ENTR_HYRULE_FIELD_RIVER_EXIT } },
|
||||
{ { EntranceType::Overworld, RR_HYRULE_FIELD, RR_LON_LON_RANCH, ENTR_LON_LON_RANCH_ENTRANCE },
|
||||
{ EntranceType::Overworld, RR_LON_LON_RANCH, RR_HYRULE_FIELD, ENTR_HYRULE_FIELD_CENTER_EXIT } },
|
||||
{ { EntranceType::Overworld, RR_LAKE_HYLIA, RR_ZORAS_DOMAIN, ENTR_ZORAS_DOMAIN_UNDERWATER_SHORTCUT },
|
||||
{ EntranceType::Overworld, RR_ZORAS_DOMAIN, RR_LAKE_HYLIA, ENTR_LAKE_HYLIA_UNDERWATER_SHORTCUT } },
|
||||
{ { EntranceType::Overworld, RR_GV_FORTRESS_SIDE, RR_GERUDO_FORTRESS, ENTR_GERUDOS_FORTRESS_EAST_EXIT },
|
||||
{ EntranceType::Overworld, RR_GERUDO_FORTRESS, RR_GV_FORTRESS_SIDE, ENTR_GERUDO_VALLEY_WEST_EXIT } },
|
||||
{ { EntranceType::Overworld, RR_GF_OUTSIDE_GATE, RR_WASTELAND_NEAR_FORTRESS, ENTR_HAUNTED_WASTELAND_EAST_EXIT },
|
||||
{ EntranceType::Overworld, RR_WASTELAND_NEAR_FORTRESS, RR_GF_OUTSIDE_GATE, ENTR_GERUDOS_FORTRESS_GATE_EXIT } },
|
||||
{ { EntranceType::Overworld, RR_WASTELAND_NEAR_COLOSSUS, RR_DESERT_COLOSSUS, ENTR_DESERT_COLOSSUS_EAST_EXIT },
|
||||
{ EntranceType::Overworld, RR_DESERT_COLOSSUS, RR_WASTELAND_NEAR_COLOSSUS, ENTR_HAUNTED_WASTELAND_WEST_EXIT } },
|
||||
{ { EntranceType::Overworld, RR_MARKET_ENTRANCE, RR_THE_MARKET, ENTR_MARKET_SOUTH_EXIT },
|
||||
{ EntranceType::Overworld, RR_THE_MARKET, RR_MARKET_ENTRANCE, ENTR_MARKET_ENTRANCE_NORTH_EXIT } },
|
||||
{ { EntranceType::Overworld, RR_THE_MARKET, RR_CASTLE_GROUNDS, ENTR_CASTLE_GROUNDS_SOUTH_EXIT },
|
||||
{ EntranceType::Overworld, RR_CASTLE_GROUNDS, RR_THE_MARKET, ENTR_MARKET_DAY_CASTLE_EXIT } },
|
||||
{ { EntranceType::Overworld, RR_THE_MARKET, RR_TOT_ENTRANCE, ENTR_TEMPLE_OF_TIME_EXTERIOR_DAY_GOSSIP_STONE_EXIT },
|
||||
{ EntranceType::Overworld, RR_TOT_ENTRANCE, RR_THE_MARKET, ENTR_MARKET_DAY_TEMPLE_EXIT } },
|
||||
{ { EntranceType::Overworld, RR_KAKARIKO_VILLAGE, RR_THE_GRAVEYARD, ENTR_GRAVEYARD_ENTRANCE },
|
||||
{ EntranceType::Overworld, RR_THE_GRAVEYARD, RR_KAKARIKO_VILLAGE, ENTR_KAKARIKO_VILLAGE_SOUTHEAST_EXIT } },
|
||||
{ { EntranceType::Overworld, RR_KAK_BEHIND_GATE, RR_DEATH_MOUNTAIN_TRAIL, ENTR_DEATH_MOUNTAIN_TRAIL_BOTTOM_EXIT },
|
||||
{ EntranceType::Overworld, RR_DEATH_MOUNTAIN_TRAIL, RR_KAK_BEHIND_GATE, ENTR_KAKARIKO_VILLAGE_GUARD_GATE } },
|
||||
{ { EntranceType::Overworld, RR_DEATH_MOUNTAIN_TRAIL, RR_GORON_CITY, ENTR_GORON_CITY_UPPER_EXIT },
|
||||
{ EntranceType::Overworld, RR_GORON_CITY, RR_DEATH_MOUNTAIN_TRAIL, ENTR_DEATH_MOUNTAIN_TRAIL_GC_EXIT } },
|
||||
{ { EntranceType::Overworld, RR_GC_DARUNIAS_CHAMBER, RR_DMC_LOWER_LOCAL, ENTR_DEATH_MOUNTAIN_CRATER_GC_EXIT },
|
||||
{ EntranceType::Overworld, RR_DMC_LOWER_NEARBY, RR_GC_DARUNIAS_CHAMBER, ENTR_GORON_CITY_DARUNIA_ROOM_EXIT } },
|
||||
{ { EntranceType::Overworld, RR_DEATH_MOUNTAIN_SUMMIT, RR_DMC_UPPER_LOCAL, ENTR_DEATH_MOUNTAIN_CRATER_UPPER_EXIT },
|
||||
{ EntranceType::Overworld, RR_DMC_UPPER_NEARBY, RR_DEATH_MOUNTAIN_SUMMIT, ENTR_DEATH_MOUNTAIN_TRAIL_SUMMIT_EXIT } },
|
||||
{ { EntranceType::Overworld, RR_ZR_BEHIND_WATERFALL, RR_ZORAS_DOMAIN, ENTR_ZORAS_DOMAIN_ENTRANCE },
|
||||
{ EntranceType::Overworld, RR_ZORAS_DOMAIN, RR_ZR_BEHIND_WATERFALL, ENTR_ZORAS_RIVER_WATERFALL_EXIT } },
|
||||
{ { EntranceType::Overworld, RR_ZD_BEHIND_KING_ZORA, RR_ZORAS_FOUNTAIN, ENTR_ZORAS_FOUNTAIN_TUNNEL_EXIT },
|
||||
{ EntranceType::Overworld, RR_ZORAS_FOUNTAIN, RR_ZD_BEHIND_KING_ZORA, ENTR_ZORAS_DOMAIN_KING_ZORA_EXIT } },
|
||||
|
||||
{ { EntranceType::Overworld, RR_GV_LOWER_STREAM, RR_LAKE_HYLIA, ENTR_LAKE_HYLIA_RIVER_EXIT },
|
||||
NO_RETURN_ENTRANCE },
|
||||
|
||||
{ { EntranceType::OwlDrop, RR_LH_OWL_FLIGHT, RR_HYRULE_FIELD, ENTR_HYRULE_FIELD_OWL_DROP },
|
||||
NO_RETURN_ENTRANCE },
|
||||
{ { EntranceType::OwlDrop, RR_DMT_OWL_FLIGHT, RR_KAK_IMPAS_ROOFTOP, ENTR_KAKARIKO_VILLAGE_OWL_DROP },
|
||||
NO_RETURN_ENTRANCE },
|
||||
|
||||
{ { EntranceType::Spawn, RR_CHILD_SPAWN, RR_KF_LINKS_HOUSE, ENTR_LINKS_HOUSE_CHILD_SPAWN },
|
||||
NO_RETURN_ENTRANCE },
|
||||
{ { EntranceType::Spawn, RR_ADULT_SPAWN, RR_TEMPLE_OF_TIME, ENTR_HYRULE_FIELD_10 },
|
||||
NO_RETURN_ENTRANCE }, // 0x282 is an unused entrance index repurposed to differentiate between
|
||||
// Adult Spawn and prelude of light (normally they both use 0x5F4)
|
||||
{ { EntranceType::WarpSong, RR_MINUET_OF_FOREST_WARP, RR_SACRED_FOREST_MEADOW, ENTR_SACRED_FOREST_MEADOW_WARP_PAD },
|
||||
NO_RETURN_ENTRANCE },
|
||||
{ { EntranceType::WarpSong, RR_BOLERO_OF_FIRE_WARP, RR_DMC_CENTRAL_LOCAL, ENTR_DEATH_MOUNTAIN_CRATER_WARP_PAD },
|
||||
NO_RETURN_ENTRANCE },
|
||||
{ { EntranceType::WarpSong, RR_SERENADE_OF_WATER_WARP, RR_LAKE_HYLIA, ENTR_LAKE_HYLIA_WARP_PAD },
|
||||
NO_RETURN_ENTRANCE },
|
||||
{ { EntranceType::WarpSong, RR_REQUIEM_OF_SPIRIT_WARP, RR_DESERT_COLOSSUS, ENTR_DESERT_COLOSSUS_WARP_PAD },
|
||||
NO_RETURN_ENTRANCE },
|
||||
{ { EntranceType::WarpSong, RR_NOCTURNE_OF_SHADOW_WARP, RR_GRAVEYARD_WARP_PAD_REGION, ENTR_GRAVEYARD_WARP_PAD },
|
||||
NO_RETURN_ENTRANCE },
|
||||
{ { EntranceType::WarpSong, RR_PRELUDE_OF_LIGHT_WARP, RR_TEMPLE_OF_TIME, ENTR_TEMPLE_OF_TIME_WARP_PAD },
|
||||
NO_RETURN_ENTRANCE },
|
||||
|
||||
{ { EntranceType::ChildBoss, RR_DEKU_TREE_BOSS_ENTRYWAY, RR_DEKU_TREE_BOSS_ROOM, ENTR_DEKU_TREE_BOSS_ENTRANCE },
|
||||
{ EntranceType::ChildBoss, RR_DEKU_TREE_BOSS_ROOM, RR_DEKU_TREE_BOSS_EXIT, ENTR_DEKU_TREE_BOSS_DOOR } },
|
||||
{ { EntranceType::ChildBoss, RR_DODONGOS_CAVERN_BOSS_ENTRYWAY, RR_DODONGOS_CAVERN_BOSS_ROOM, ENTR_DODONGOS_CAVERN_BOSS_ENTRANCE },
|
||||
{ EntranceType::ChildBoss, RR_DODONGOS_CAVERN_BOSS_ROOM, RR_DODONGOS_CAVERN_BOSS_EXIT, ENTR_DODONGOS_CAVERN_BOSS_DOOR } },
|
||||
{ { EntranceType::ChildBoss, RR_JABU_JABUS_BELLY_BOSS_ENTRYWAY, RR_JABU_JABUS_BELLY_BOSS_ROOM, ENTR_JABU_JABU_BOSS_ENTRANCE },
|
||||
{ EntranceType::ChildBoss, RR_JABU_JABUS_BELLY_BOSS_ROOM, RR_JABU_JABUS_BELLY_BOSS_EXIT, ENTR_JABU_JABU_BOSS_DOOR } },
|
||||
{ { EntranceType::AdultBoss, RR_FOREST_TEMPLE_BOSS_ENTRYWAY, RR_FOREST_TEMPLE_BOSS_ROOM, ENTR_FOREST_TEMPLE_BOSS_ENTRANCE },
|
||||
{ EntranceType::AdultBoss, RR_FOREST_TEMPLE_BOSS_ROOM, RR_FOREST_TEMPLE_BOSS_ENTRYWAY, ENTR_FOREST_TEMPLE_BOSS_DOOR } },
|
||||
{ { EntranceType::AdultBoss, RR_FIRE_TEMPLE_BOSS_ENTRYWAY, RR_FIRE_TEMPLE_BOSS_ROOM, ENTR_FIRE_TEMPLE_BOSS_ENTRANCE },
|
||||
{ EntranceType::AdultBoss, RR_FIRE_TEMPLE_BOSS_ROOM, RR_FIRE_TEMPLE_BOSS_ENTRYWAY, ENTR_FIRE_TEMPLE_BOSS_DOOR } },
|
||||
{ { EntranceType::AdultBoss, RR_WATER_TEMPLE_BOSS_ENTRYWAY, RR_WATER_TEMPLE_BOSS_ROOM, ENTR_WATER_TEMPLE_BOSS_ENTRANCE },
|
||||
{ EntranceType::AdultBoss, RR_WATER_TEMPLE_BOSS_ROOM, RR_WATER_TEMPLE_BOSS_ENTRYWAY, ENTR_WATER_TEMPLE_BOSS_DOOR } },
|
||||
{ { EntranceType::AdultBoss, RR_SPIRIT_TEMPLE_BOSS_ENTRYWAY, RR_SPIRIT_TEMPLE_BOSS_ROOM, ENTR_SPIRIT_TEMPLE_BOSS_ENTRANCE },
|
||||
{ EntranceType::AdultBoss, RR_SPIRIT_TEMPLE_BOSS_ROOM, RR_SPIRIT_TEMPLE_BOSS_ENTRYWAY, ENTR_SPIRIT_TEMPLE_BOSS_DOOR } },
|
||||
{ { EntranceType::AdultBoss, RR_SHADOW_TEMPLE_BOSS_ENTRYWAY, RR_SHADOW_TEMPLE_BOSS_ROOM, ENTR_SHADOW_TEMPLE_BOSS_ENTRANCE },
|
||||
{ EntranceType::AdultBoss, RR_SHADOW_TEMPLE_BOSS_ROOM, RR_SHADOW_TEMPLE_BOSS_ENTRYWAY, ENTR_SHADOW_TEMPLE_BOSS_DOOR } },
|
||||
|
||||
{ { EntranceType::BlueWarp, RR_DEKU_TREE_BOSS_ROOM, RR_KF_OUTSIDE_DEKU_TREE, ENTR_KOKIRI_FOREST_DEKU_TREE_BLUE_WARP },
|
||||
NO_RETURN_ENTRANCE },
|
||||
{ { EntranceType::BlueWarp, RR_DODONGOS_CAVERN_BOSS_ROOM, RR_DEATH_MOUNTAIN_TRAIL, ENTR_DEATH_MOUNTAIN_TRAIL_DODONGO_BLUE_WARP },
|
||||
NO_RETURN_ENTRANCE },
|
||||
{ { EntranceType::BlueWarp, RR_JABU_JABUS_BELLY_BOSS_ROOM, RR_ZORAS_FOUNTAIN, ENTR_ZORAS_FOUNTAIN_JABU_JABU_BLUE_WARP },
|
||||
NO_RETURN_ENTRANCE },
|
||||
{ { EntranceType::BlueWarp, RR_FOREST_TEMPLE_BOSS_ROOM, RR_SACRED_FOREST_MEADOW, ENTR_SACRED_FOREST_MEADOW_FOREST_TEMPLE_BLUE_WARP },
|
||||
NO_RETURN_ENTRANCE },
|
||||
{ { EntranceType::BlueWarp, RR_FIRE_TEMPLE_BOSS_ROOM, RR_DMC_CENTRAL_LOCAL, ENTR_DEATH_MOUNTAIN_CRATER_FIRE_TEMPLE_BLUE_WARP },
|
||||
NO_RETURN_ENTRANCE },
|
||||
{ { EntranceType::BlueWarp, RR_WATER_TEMPLE_BOSS_ROOM, RR_LAKE_HYLIA, ENTR_LAKE_HYLIA_WATER_TEMPLE_BLUE_WARP },
|
||||
NO_RETURN_ENTRANCE },
|
||||
{ { EntranceType::BlueWarp, RR_SPIRIT_TEMPLE_BOSS_ROOM, RR_DESERT_COLOSSUS, ENTR_DESERT_COLOSSUS_SPIRIT_TEMPLE_BLUE_WARP },
|
||||
NO_RETURN_ENTRANCE },
|
||||
{ { EntranceType::BlueWarp, RR_SHADOW_TEMPLE_BOSS_ROOM, RR_GRAVEYARD_WARP_PAD_REGION, ENTR_GRAVEYARD_SHADOW_TEMPLE_BLUE_WARP },
|
||||
NO_RETURN_ENTRANCE },
|
||||
// clang-format on
|
||||
};
|
||||
|
||||
auto ctx = Rando::Context::GetInstance();
|
||||
for (auto& entrancePair : entranceShuffleTable) {
|
||||
|
||||
@@ -262,6 +574,7 @@ void SetAllEntrancesData(std::vector<EntranceInfoPair>& entranceShuffleTable) {
|
||||
forwardEntrance->SetIndex(forwardEntry.index);
|
||||
forwardEntrance->SetType(forwardEntry.type);
|
||||
forwardEntrance->SetAsPrimary();
|
||||
entranceMap[forwardEntry.index] = forwardEntrance;
|
||||
|
||||
// When decouple entrances is on, mark the forward entrance
|
||||
if (ctx->GetOption(RSK_DECOUPLED_ENTRANCES)) {
|
||||
@@ -273,6 +586,7 @@ void SetAllEntrancesData(std::vector<EntranceInfoPair>& entranceShuffleTable) {
|
||||
returnEntrance->SetIndex(returnEntry.index);
|
||||
returnEntrance->SetType(returnEntry.type);
|
||||
forwardEntrance->BindTwoWay(returnEntrance);
|
||||
entranceMap[returnEntry.index] = returnEntrance;
|
||||
|
||||
// Mark reverse entrance as decoupled
|
||||
if (ctx->GetOption(RSK_DECOUPLED_ENTRANCES)) {
|
||||
@@ -857,316 +1171,6 @@ int EntranceShuffler::ShuffleAllEntrances() {
|
||||
mTotalRandomizableEntrances = 0;
|
||||
mCurNumRandomizedEntrances = 0;
|
||||
|
||||
std::vector<EntranceInfoPair> entranceShuffleTable = {
|
||||
// clang-format off
|
||||
// Type Parent Region Connected Region Index
|
||||
{ { EntranceType::Dungeon, RR_KF_OUTSIDE_DEKU_TREE, RR_DEKU_TREE_ENTRYWAY, ENTR_DEKU_TREE_ENTRANCE },
|
||||
{ EntranceType::Dungeon, RR_DEKU_TREE_ENTRYWAY, RR_KF_OUTSIDE_DEKU_TREE, ENTR_KOKIRI_FOREST_OUTSIDE_DEKU_TREE } },
|
||||
{ { EntranceType::Dungeon, RR_DEATH_MOUNTAIN_TRAIL, RR_DODONGOS_CAVERN_ENTRYWAY, ENTR_DODONGOS_CAVERN_ENTRANCE },
|
||||
{ EntranceType::Dungeon, RR_DODONGOS_CAVERN_ENTRYWAY, RR_DEATH_MOUNTAIN_TRAIL, ENTR_DEATH_MOUNTAIN_TRAIL_OUTSIDE_DODONGOS_CAVERN } },
|
||||
{ { EntranceType::Dungeon, RR_ZORAS_FOUNTAIN, RR_JABU_JABUS_BELLY_ENTRYWAY, ENTR_JABU_JABU_ENTRANCE },
|
||||
{ EntranceType::Dungeon, RR_JABU_JABUS_BELLY_ENTRYWAY, RR_ZORAS_FOUNTAIN, ENTR_ZORAS_FOUNTAIN_OUTSIDE_JABU_JABU } },
|
||||
{ { EntranceType::Dungeon, RR_SACRED_FOREST_MEADOW, RR_FOREST_TEMPLE_ENTRYWAY, ENTR_FOREST_TEMPLE_ENTRANCE },
|
||||
{ EntranceType::Dungeon, RR_FOREST_TEMPLE_ENTRYWAY, RR_SACRED_FOREST_MEADOW, ENTR_SACRED_FOREST_MEADOW_OUTSIDE_TEMPLE } },
|
||||
{ { EntranceType::Dungeon, RR_DMC_CENTRAL_LOCAL, RR_FIRE_TEMPLE_ENTRYWAY, ENTR_FIRE_TEMPLE_ENTRANCE },
|
||||
{ EntranceType::Dungeon, RR_FIRE_TEMPLE_ENTRYWAY, RR_DMC_CENTRAL_LOCAL, ENTR_DEATH_MOUNTAIN_CRATER_OUTSIDE_TEMPLE } },
|
||||
{ { EntranceType::Dungeon, RR_LAKE_HYLIA, RR_WATER_TEMPLE_ENTRYWAY, ENTR_WATER_TEMPLE_ENTRANCE },
|
||||
{ EntranceType::Dungeon, RR_WATER_TEMPLE_ENTRYWAY, RR_LAKE_HYLIA, ENTR_LAKE_HYLIA_OUTSIDE_TEMPLE } },
|
||||
{ { EntranceType::Dungeon, RR_DESERT_COLOSSUS, RR_SPIRIT_TEMPLE_ENTRYWAY, ENTR_SPIRIT_TEMPLE_ENTRANCE },
|
||||
{ EntranceType::Dungeon, RR_SPIRIT_TEMPLE_ENTRYWAY, RR_DESERT_COLOSSUS_OUTSIDE_TEMPLE, ENTR_DESERT_COLOSSUS_OUTSIDE_TEMPLE } },
|
||||
{ { EntranceType::Dungeon, RR_GRAVEYARD_WARP_PAD_REGION, RR_SHADOW_TEMPLE_ENTRYWAY, ENTR_SHADOW_TEMPLE_ENTRANCE },
|
||||
{ EntranceType::Dungeon, RR_SHADOW_TEMPLE_ENTRYWAY, RR_GRAVEYARD_WARP_PAD_REGION, ENTR_GRAVEYARD_OUTSIDE_TEMPLE } },
|
||||
{ { EntranceType::Dungeon, RR_KAK_WELL, RR_BOTTOM_OF_THE_WELL_ENTRYWAY, ENTR_BOTTOM_OF_THE_WELL_ENTRANCE },
|
||||
{ EntranceType::Dungeon, RR_BOTTOM_OF_THE_WELL_ENTRYWAY, RR_KAK_WELL, ENTR_KAKARIKO_VILLAGE_OUTSIDE_BOTTOM_OF_THE_WELL } },
|
||||
{ { EntranceType::Dungeon, RR_ZF_LEDGE, RR_ICE_CAVERN_ENTRYWAY, ENTR_ICE_CAVERN_ENTRANCE },
|
||||
{ EntranceType::Dungeon, RR_ICE_CAVERN_ENTRYWAY, RR_ZF_LEDGE, ENTR_ZORAS_FOUNTAIN_OUTSIDE_ICE_CAVERN } },
|
||||
{ { EntranceType::Dungeon, RR_GERUDO_FORTRESS, RR_GERUDO_TRAINING_GROUND_ENTRYWAY, ENTR_GERUDO_TRAINING_GROUND_ENTRANCE },
|
||||
{ EntranceType::Dungeon, RR_GERUDO_TRAINING_GROUND_ENTRYWAY, RR_GERUDO_FORTRESS, ENTR_GERUDOS_FORTRESS_OUTSIDE_GERUDO_TRAINING_GROUND } },
|
||||
{ { EntranceType::GanonDungeon, RR_GANONS_CASTLE_LEDGE, RR_GANONS_CASTLE_ENTRYWAY, ENTR_INSIDE_GANONS_CASTLE_ENTRANCE },
|
||||
{ EntranceType::GanonDungeon, RR_GANONS_CASTLE_ENTRYWAY, RR_CASTLE_GROUNDS_FROM_GANONS_CASTLE, ENTR_CASTLE_GROUNDS_RAINBOW_BRIDGE_EXIT } },
|
||||
|
||||
{ { EntranceType::Interior, RR_KOKIRI_FOREST, RR_KF_MIDOS_HOUSE, ENTR_MIDOS_HOUSE_0 },
|
||||
{ EntranceType::Interior, RR_KF_MIDOS_HOUSE, RR_KOKIRI_FOREST, ENTR_KOKIRI_FOREST_OUTSIDE_MIDOS_HOUSE } },
|
||||
{ { EntranceType::Interior, RR_KOKIRI_FOREST, RR_KF_SARIAS_HOUSE, ENTR_SARIAS_HOUSE_0 },
|
||||
{ EntranceType::Interior, RR_KF_SARIAS_HOUSE, RR_KOKIRI_FOREST, ENTR_KOKIRI_FOREST_OUTSIDE_SARIAS_HOUSE } },
|
||||
{ { EntranceType::Interior, RR_KOKIRI_FOREST, RR_KF_HOUSE_OF_TWINS, ENTR_TWINS_HOUSE_0 },
|
||||
{ EntranceType::Interior, RR_KF_HOUSE_OF_TWINS, RR_KOKIRI_FOREST, ENTR_KOKIRI_FOREST_OUTSIDE_TWINS_HOUSE } },
|
||||
{ { EntranceType::Interior, RR_KOKIRI_FOREST, RR_KF_KNOW_IT_ALL_HOUSE, ENTR_KNOW_IT_ALL_BROS_HOUSE_0 },
|
||||
{ EntranceType::Interior, RR_KF_KNOW_IT_ALL_HOUSE, RR_KOKIRI_FOREST, ENTR_KOKIRI_FOREST_OUTSIDE_KNOW_IT_ALL_HOUSE } },
|
||||
{ { EntranceType::Interior, RR_KOKIRI_FOREST, RR_KF_KOKIRI_SHOP, ENTR_KOKIRI_SHOP_0 },
|
||||
{ EntranceType::Interior, RR_KF_KOKIRI_SHOP, RR_KOKIRI_FOREST, ENTR_KOKIRI_FOREST_OUTSIDE_SHOP } },
|
||||
{ { EntranceType::Interior, RR_LAKE_HYLIA, RR_LH_LAB, ENTR_LAKESIDE_LABORATORY_0 },
|
||||
{ EntranceType::Interior, RR_LH_LAB, RR_LAKE_HYLIA, ENTR_LAKE_HYLIA_OUTSIDE_LAB } },
|
||||
{ { EntranceType::Interior, RR_LH_FISHING_ISLAND, RR_LH_FISHING_POND, ENTR_FISHING_POND_0 },
|
||||
{ EntranceType::Interior, RR_LH_FISHING_POND, RR_LH_FISHING_ISLAND, ENTR_LAKE_HYLIA_OUTSIDE_FISHING_POND } },
|
||||
{ { EntranceType::Interior, RR_GV_FORTRESS_SIDE, RR_GV_CARPENTER_TENT, ENTR_CARPENTERS_TENT_0 },
|
||||
{ EntranceType::Interior, RR_GV_CARPENTER_TENT, RR_GV_FORTRESS_SIDE, ENTR_GERUDO_VALLEY_OUTSIDE_TENT } },
|
||||
{ { EntranceType::Interior, RR_MARKET_ENTRANCE, RR_MARKET_GUARD_HOUSE, ENTR_MARKET_GUARD_HOUSE_0 },
|
||||
{ EntranceType::Interior, RR_MARKET_GUARD_HOUSE, RR_MARKET_ENTRANCE, ENTR_MARKET_ENTRANCE_OUTSIDE_GUARD_HOUSE } },
|
||||
{ { EntranceType::Interior, RR_THE_MARKET, RR_MARKET_MASK_SHOP, ENTR_HAPPY_MASK_SHOP_0 },
|
||||
{ EntranceType::Interior, RR_MARKET_MASK_SHOP, RR_THE_MARKET, ENTR_MARKET_DAY_OUTSIDE_HAPPY_MASK_SHOP } },
|
||||
{ { EntranceType::Interior, RR_THE_MARKET, RR_MARKET_BOMBCHU_BOWLING, ENTR_BOMBCHU_BOWLING_ALLEY_0 },
|
||||
{ EntranceType::Interior, RR_MARKET_BOMBCHU_BOWLING, RR_THE_MARKET, ENTR_MARKET_DAY_OUTSIDE_BOMBCHU_BOWLING } },
|
||||
{ { EntranceType::Interior, RR_THE_MARKET, RR_MARKET_POTION_SHOP, ENTR_POTION_SHOP_MARKET_0 },
|
||||
{ EntranceType::Interior, RR_MARKET_POTION_SHOP, RR_THE_MARKET, ENTR_MARKET_DAY_OUTSIDE_POTION_SHOP } },
|
||||
{ { EntranceType::Interior, RR_THE_MARKET, RR_MARKET_TREASURE_CHEST_GAME, ENTR_TREASURE_BOX_SHOP_0 },
|
||||
{ EntranceType::Interior, RR_MARKET_TREASURE_CHEST_GAME, RR_THE_MARKET, ENTR_MARKET_DAY_OUTSIDE_TREASURE_BOX_SHOP } },
|
||||
{ { EntranceType::Interior, RR_MARKET_BACK_ALLEY, RR_MARKET_BOMBCHU_SHOP, ENTR_BOMBCHU_SHOP_1 },
|
||||
{ EntranceType::Interior, RR_MARKET_BOMBCHU_SHOP, RR_MARKET_BACK_ALLEY, ENTR_BACK_ALLEY_DAY_OUTSIDE_BOMBCHU_SHOP } },
|
||||
{ { EntranceType::Interior, RR_MARKET_BACK_ALLEY, RR_MARKET_MAN_IN_GREEN_HOUSE, ENTR_BACK_ALLEY_MAN_IN_GREEN_HOUSE },
|
||||
{ EntranceType::Interior, RR_MARKET_MAN_IN_GREEN_HOUSE, RR_MARKET_BACK_ALLEY, ENTR_BACK_ALLEY_DAY_OUTSIDE_MAN_IN_GREEN_HOUSE } },
|
||||
{ { EntranceType::Interior, RR_KAKARIKO_VILLAGE, RR_KAK_CARPENTER_BOSS_HOUSE, ENTR_KAKARIKO_CENTER_GUEST_HOUSE_0 },
|
||||
{ EntranceType::Interior, RR_KAK_CARPENTER_BOSS_HOUSE, RR_KAKARIKO_VILLAGE, ENTR_KAKARIKO_VILLAGE_OUTSIDE_CENTER_GUEST_HOUSE } },
|
||||
{ { EntranceType::Interior, RR_KAKARIKO_VILLAGE, RR_KAK_HOUSE_OF_SKULLTULA, ENTR_HOUSE_OF_SKULLTULA_0 },
|
||||
{ EntranceType::Interior, RR_KAK_HOUSE_OF_SKULLTULA, RR_KAKARIKO_VILLAGE, ENTR_KAKARIKO_VILLAGE_OUTSIDE_SKULKLTULA_HOUSE } },
|
||||
{ { EntranceType::Interior, RR_KAKARIKO_VILLAGE, RR_KAK_IMPAS_HOUSE, ENTR_IMPAS_HOUSE_FRONT },
|
||||
{ EntranceType::Interior, RR_KAK_IMPAS_HOUSE, RR_KAKARIKO_VILLAGE, ENTR_KAKARIKO_VILLAGE_OUTSIDE_IMPAS_HOUSE_FRONT } },
|
||||
{ { EntranceType::Interior, RR_KAK_IMPAS_LEDGE, RR_KAK_IMPAS_HOUSE_BACK, ENTR_IMPAS_HOUSE_BACK },
|
||||
{ EntranceType::Interior, RR_KAK_IMPAS_HOUSE_BACK, RR_KAK_IMPAS_LEDGE, ENTR_KAKARIKO_VILLAGE_OUTSIDE_IMPAS_HOUSE_BACK } },
|
||||
{ { EntranceType::Interior, RR_KAK_BACKYARD, RR_KAK_ODD_POTION_BUILDING, ENTR_POTION_SHOP_GRANNY_0 },
|
||||
{ EntranceType::Interior, RR_KAK_ODD_POTION_BUILDING, RR_KAK_BACKYARD, ENTR_KAKARIKO_VILLAGE_OUTSIDE_SHOP_GRANNY } },
|
||||
{ { EntranceType::Interior, RR_THE_GRAVEYARD, RR_GRAVEYARD_DAMPES_HOUSE, ENTR_GRAVEKEEPERS_HUT_0 },
|
||||
{ EntranceType::Interior, RR_GRAVEYARD_DAMPES_HOUSE, RR_THE_GRAVEYARD, ENTR_GRAVEYARD_OUTSIDE_DAMPES_HUT } },
|
||||
{ { EntranceType::Interior, RR_GORON_CITY, RR_GC_SHOP, ENTR_GORON_SHOP_0 },
|
||||
{ EntranceType::Interior, RR_GC_SHOP, RR_GORON_CITY, ENTR_GORON_CITY_OUTSIDE_SHOP } },
|
||||
{ { EntranceType::Interior, RR_ZORAS_DOMAIN, RR_ZD_SHOP, ENTR_ZORA_SHOP_0 },
|
||||
{ EntranceType::Interior, RR_ZD_SHOP, RR_ZORAS_DOMAIN, ENTR_ZORAS_DOMAIN_OUTSIDE_SHOP } },
|
||||
{ { EntranceType::Interior, RR_LON_LON_RANCH, RR_LLR_TALONS_HOUSE, ENTR_LON_LON_BUILDINGS_TALONS_HOUSE },
|
||||
{ EntranceType::Interior, RR_LLR_TALONS_HOUSE, RR_LON_LON_RANCH, ENTR_LON_LON_RANCH_OUTSIDE_TALONS_HOUSE } },
|
||||
{ { EntranceType::Interior, RR_LON_LON_RANCH, RR_LLR_STABLES, ENTR_STABLE_0 },
|
||||
{ EntranceType::Interior, RR_LLR_STABLES, RR_LON_LON_RANCH, ENTR_LON_LON_RANCH_OUTSIDE_STABLES } },
|
||||
{ { EntranceType::Interior, RR_LON_LON_RANCH, RR_LLR_TOWER, ENTR_LON_LON_BUILDINGS_TOWER },
|
||||
{ EntranceType::Interior, RR_LLR_TOWER, RR_LON_LON_RANCH, ENTR_LON_LON_RANCH_OUTSIDE_TOWER } },
|
||||
{ { EntranceType::Interior, RR_THE_MARKET, RR_MARKET_BAZAAR, ENTR_BAZAAR_1 },
|
||||
{ EntranceType::Interior, RR_MARKET_BAZAAR, RR_THE_MARKET, ENTR_MARKET_DAY_OUTSIDE_BAZAAR } },
|
||||
{ { EntranceType::Interior, RR_THE_MARKET, RR_MARKET_SHOOTING_GALLERY, ENTR_SHOOTING_GALLERY_1 },
|
||||
{ EntranceType::Interior, RR_MARKET_SHOOTING_GALLERY, RR_THE_MARKET, ENTR_MARKET_DAY_OUTSIDE_SHOOTING_GALLERY } },
|
||||
{ { EntranceType::Interior, RR_KAKARIKO_VILLAGE, RR_KAK_BAZAAR, ENTR_BAZAAR_0 },
|
||||
{ EntranceType::Interior, RR_KAK_BAZAAR, RR_KAKARIKO_VILLAGE, ENTR_KAKARIKO_VILLAGE_OUTSIDE_BAZAAR } },
|
||||
{ { EntranceType::Interior, RR_KAKARIKO_VILLAGE, RR_KAK_SHOOTING_GALLERY, ENTR_SHOOTING_GALLERY_0 },
|
||||
{ EntranceType::Interior, RR_KAK_SHOOTING_GALLERY, RR_KAKARIKO_VILLAGE, ENTR_KAKARIKO_VILLAGE_OUTSIDE_SHOOTING_GALLERY } },
|
||||
{ { EntranceType::Interior, RR_DESERT_COLOSSUS, RR_COLOSSUS_GREAT_FAIRY_FOUNTAIN, ENTR_GREAT_FAIRYS_FOUNTAIN_SPELLS_NAYRUS_COLOSSUS },
|
||||
{ EntranceType::Interior, RR_COLOSSUS_GREAT_FAIRY_FOUNTAIN, RR_DESERT_COLOSSUS, ENTR_DESERT_COLOSSUS_GREAT_FAIRY_EXIT } },
|
||||
{ { EntranceType::Interior, RR_HYRULE_CASTLE_GROUNDS, RR_HC_GREAT_FAIRY_FOUNTAIN, ENTR_GREAT_FAIRYS_FOUNTAIN_SPELLS_DINS_HC },
|
||||
{ EntranceType::Interior, RR_HC_GREAT_FAIRY_FOUNTAIN, RR_CASTLE_GROUNDS, ENTR_CASTLE_GROUNDS_GREAT_FAIRY_EXIT } },
|
||||
{ { EntranceType::Interior, RR_GANONS_CASTLE_GROUNDS, RR_OGC_GREAT_FAIRY_FOUNTAIN, ENTR_GREAT_FAIRYS_FOUNTAIN_MAGIC_OGC_DD },
|
||||
// 0x3E8 is an unused entrance index repruposed to differentiate between the HC and OGC fairy
|
||||
// fountain exits (normally they both use 0x340)
|
||||
{ EntranceType::Interior, RR_OGC_GREAT_FAIRY_FOUNTAIN, RR_CASTLE_GROUNDS, ENTR_POTION_SHOP_KAKARIKO_1 } },
|
||||
{ { EntranceType::Interior, RR_DMC_LOWER_NEARBY, RR_DMC_GREAT_FAIRY_FOUNTAIN, ENTR_GREAT_FAIRYS_FOUNTAIN_MAGIC_DMC },
|
||||
{ EntranceType::Interior, RR_DMC_GREAT_FAIRY_FOUNTAIN, RR_DMC_LOWER_LOCAL, ENTR_DEATH_MOUNTAIN_CRATER_GREAT_FAIRY_EXIT } },
|
||||
{ { EntranceType::Interior, RR_DEATH_MOUNTAIN_SUMMIT, RR_DMT_GREAT_FAIRY_FOUNTAIN, ENTR_GREAT_FAIRYS_FOUNTAIN_MAGIC_DMT },
|
||||
{ EntranceType::Interior, RR_DMT_GREAT_FAIRY_FOUNTAIN, RR_DEATH_MOUNTAIN_SUMMIT, ENTR_DEATH_MOUNTAIN_TRAIL_GREAT_FAIRY_EXIT } },
|
||||
{ { EntranceType::Interior, RR_ZORAS_FOUNTAIN, RR_ZF_GREAT_FAIRY_FOUNTAIN, ENTR_GREAT_FAIRYS_FOUNTAIN_SPELLS_FARORES_ZF },
|
||||
{ EntranceType::Interior, RR_ZF_GREAT_FAIRY_FOUNTAIN, RR_ZORAS_FOUNTAIN, ENTR_ZORAS_FOUNTAIN_OUTSIDE_GREAT_FAIRY } },
|
||||
|
||||
{ { EntranceType::SpecialInterior, RR_KOKIRI_FOREST, RR_KF_LINKS_HOUSE, ENTR_LINKS_HOUSE_1 },
|
||||
{ EntranceType::SpecialInterior, RR_KF_LINKS_HOUSE, RR_KOKIRI_FOREST, ENTR_KOKIRI_FOREST_OUTSIDE_LINKS_HOUSE } },
|
||||
{ { EntranceType::SpecialInterior, RR_TOT_ENTRANCE, RR_TEMPLE_OF_TIME, ENTR_TEMPLE_OF_TIME_ENTRANCE },
|
||||
{ EntranceType::SpecialInterior, RR_TEMPLE_OF_TIME, RR_TOT_ENTRANCE, ENTR_TEMPLE_OF_TIME_EXTERIOR_DAY_OUTSIDE_TEMPLE } },
|
||||
{ { EntranceType::SpecialInterior, RR_KAKARIKO_VILLAGE, RR_KAK_WINDMILL, ENTR_WINDMILL_AND_DAMPES_GRAVE_WINDMILL },
|
||||
{ EntranceType::SpecialInterior, RR_KAK_WINDMILL, RR_KAKARIKO_VILLAGE, ENTR_KAKARIKO_VILLAGE_OUTSIDE_WINDMILL } },
|
||||
{ { EntranceType::SpecialInterior, RR_KAKARIKO_VILLAGE, RR_KAK_POTION_SHOP_FRONT, ENTR_POTION_SHOP_KAKARIKO_FRONT },
|
||||
{ EntranceType::SpecialInterior, RR_KAK_POTION_SHOP_FRONT, RR_KAKARIKO_VILLAGE, ENTR_KAKARIKO_VILLAGE_OUTSIDE_POTION_SHOP_FRONT } },
|
||||
{ { EntranceType::SpecialInterior, RR_KAK_BACKYARD, RR_KAK_POTION_SHOP_BACK, ENTR_POTION_SHOP_KAKARIKO_BACK },
|
||||
{ EntranceType::SpecialInterior, RR_KAK_POTION_SHOP_BACK, RR_KAK_BACKYARD, ENTR_KAKARIKO_VILLAGE_OUTSIDE_POTION_SHOP_BACK } },
|
||||
|
||||
// Grotto Loads use an entrance index of 0x0700 + their grotto id. The id is used as index for the
|
||||
// grottoLoadTable in soh/soh/Enhancements/randomizer/randomizer_grotto.c
|
||||
// Grotto Returns use an entrance index of 0x0800 + their grotto id. The id is used as index for the
|
||||
// grottoReturnTable in soh/soh/Enhancements/randomizer/randomizer_grotto.c
|
||||
{ { EntranceType::GrottoGrave, RR_DESERT_COLOSSUS, RR_COLOSSUS_GROTTO, ENTRANCE_GROTTO_LOAD(GROTTO_COLOSSUS_OFFSET) },
|
||||
{ EntranceType::GrottoGrave, RR_COLOSSUS_GROTTO, RR_DESERT_COLOSSUS, ENTRANCE_GROTTO_EXIT(GROTTO_COLOSSUS_OFFSET) } },
|
||||
{ { EntranceType::GrottoGrave, RR_LAKE_HYLIA, RR_LH_GROTTO, ENTRANCE_GROTTO_LOAD(GROTTO_LH_OFFSET) },
|
||||
{ EntranceType::GrottoGrave, RR_LH_GROTTO, RR_LAKE_HYLIA, ENTRANCE_GROTTO_EXIT(GROTTO_LH_OFFSET) } },
|
||||
{ { EntranceType::GrottoGrave, RR_ZORAS_RIVER, RR_ZR_STORMS_GROTTO, ENTRANCE_GROTTO_LOAD(GROTTO_ZR_STORMS_OFFSET) },
|
||||
{ EntranceType::GrottoGrave, RR_ZR_STORMS_GROTTO, RR_ZORAS_RIVER, ENTRANCE_GROTTO_EXIT(GROTTO_ZR_STORMS_OFFSET) } },
|
||||
{ { EntranceType::GrottoGrave, RR_ZORAS_RIVER, RR_ZR_FAIRY_GROTTO, ENTRANCE_GROTTO_LOAD(GROTTO_ZR_FAIRY_OFFSET) },
|
||||
{ EntranceType::GrottoGrave, RR_ZR_FAIRY_GROTTO, RR_ZORAS_RIVER, ENTRANCE_GROTTO_EXIT(GROTTO_ZR_FAIRY_OFFSET) } },
|
||||
{ { EntranceType::GrottoGrave, RR_ZORAS_RIVER, RR_ZR_OPEN_GROTTO, ENTRANCE_GROTTO_LOAD(GROTTO_ZR_OPEN_OFFSET) },
|
||||
{ EntranceType::GrottoGrave, RR_ZR_OPEN_GROTTO, RR_ZORAS_RIVER, ENTRANCE_GROTTO_EXIT(GROTTO_ZR_OPEN_OFFSET) } },
|
||||
{ { EntranceType::GrottoGrave, RR_DMC_LOWER_NEARBY, RR_DMC_HAMMER_GROTTO, ENTRANCE_GROTTO_LOAD(GROTTO_DMC_HAMMER_OFFSET) },
|
||||
{ EntranceType::GrottoGrave, RR_DMC_HAMMER_GROTTO, RR_DMC_LOWER_LOCAL, ENTRANCE_GROTTO_EXIT(GROTTO_DMC_HAMMER_OFFSET) } },
|
||||
{ { EntranceType::GrottoGrave, RR_DMC_UPPER_NEARBY, RR_DMC_UPPER_GROTTO, ENTRANCE_GROTTO_LOAD(GROTTO_DMC_UPPER_OFFSET) },
|
||||
{ EntranceType::GrottoGrave, RR_DMC_UPPER_GROTTO, RR_DMC_UPPER_LOCAL, ENTRANCE_GROTTO_EXIT(GROTTO_DMC_UPPER_OFFSET) } },
|
||||
{ { EntranceType::GrottoGrave, RR_GC_GROTTO_PLATFORM, RR_GC_GROTTO, ENTRANCE_GROTTO_LOAD(GROTTO_GORON_CITY_OFFSET) },
|
||||
{ EntranceType::GrottoGrave, RR_GC_GROTTO, RR_GC_GROTTO_PLATFORM, ENTRANCE_GROTTO_EXIT(GROTTO_GORON_CITY_OFFSET) } },
|
||||
{ { EntranceType::GrottoGrave, RR_DEATH_MOUNTAIN_TRAIL, RR_DMT_STORMS_GROTTO, ENTRANCE_GROTTO_LOAD(GROTTO_DMT_STORMS_OFFSET) },
|
||||
{ EntranceType::GrottoGrave, RR_DMT_STORMS_GROTTO, RR_DEATH_MOUNTAIN_TRAIL, ENTRANCE_GROTTO_EXIT(GROTTO_DMT_STORMS_OFFSET) } },
|
||||
{ { EntranceType::GrottoGrave, RR_DEATH_MOUNTAIN_SUMMIT, RR_DMT_COW_GROTTO, ENTRANCE_GROTTO_LOAD(GROTTO_DMT_COW_OFFSET) },
|
||||
{ EntranceType::GrottoGrave, RR_DMT_COW_GROTTO, RR_DEATH_MOUNTAIN_SUMMIT, ENTRANCE_GROTTO_EXIT(GROTTO_DMT_COW_OFFSET) } },
|
||||
{ { EntranceType::GrottoGrave, RR_KAK_BACKYARD, RR_KAK_OPEN_GROTTO, ENTRANCE_GROTTO_LOAD(GROTTO_KAK_OPEN_OFFSET) },
|
||||
{ EntranceType::GrottoGrave, RR_KAK_OPEN_GROTTO, RR_KAK_BACKYARD, ENTRANCE_GROTTO_EXIT(GROTTO_KAK_OPEN_OFFSET) } },
|
||||
{ { EntranceType::GrottoGrave, RR_KAKARIKO_VILLAGE, RR_KAK_REDEAD_GROTTO, ENTRANCE_GROTTO_LOAD(GROTTO_KAK_REDEAD_OFFSET) },
|
||||
{ EntranceType::GrottoGrave, RR_KAK_REDEAD_GROTTO, RR_KAKARIKO_VILLAGE, ENTRANCE_GROTTO_EXIT(GROTTO_KAK_REDEAD_OFFSET) } },
|
||||
{ { EntranceType::GrottoGrave, RR_HYRULE_CASTLE_GROUNDS, RR_HC_STORMS_GROTTO, ENTRANCE_GROTTO_LOAD(GROTTO_HC_STORMS_OFFSET) },
|
||||
{ EntranceType::GrottoGrave, RR_HC_STORMS_GROTTO, RR_CASTLE_GROUNDS, ENTRANCE_GROTTO_EXIT(GROTTO_HC_STORMS_OFFSET) } },
|
||||
{ { EntranceType::GrottoGrave, RR_HYRULE_FIELD, RR_HF_TEKTITE_GROTTO, ENTRANCE_GROTTO_LOAD(GROTTO_HF_TEKTITE_OFFSET) },
|
||||
{ EntranceType::GrottoGrave, RR_HF_TEKTITE_GROTTO, RR_HYRULE_FIELD, ENTRANCE_GROTTO_EXIT(GROTTO_HF_TEKTITE_OFFSET) } },
|
||||
{ { EntranceType::GrottoGrave, RR_HYRULE_FIELD, RR_HF_NEAR_KAK_GROTTO, ENTRANCE_GROTTO_LOAD(GROTTO_HF_NEAR_KAK_OFFSET) },
|
||||
{ EntranceType::GrottoGrave, RR_HF_NEAR_KAK_GROTTO, RR_HYRULE_FIELD, ENTRANCE_GROTTO_EXIT(GROTTO_HF_NEAR_KAK_OFFSET) } },
|
||||
{ { EntranceType::GrottoGrave, RR_HYRULE_FIELD, RR_HF_FAIRY_GROTTO, ENTRANCE_GROTTO_LOAD(GROTTO_HF_FAIRY_OFFSET) },
|
||||
{ EntranceType::GrottoGrave, RR_HF_FAIRY_GROTTO, RR_HYRULE_FIELD, ENTRANCE_GROTTO_EXIT(GROTTO_HF_FAIRY_OFFSET) } },
|
||||
{ { EntranceType::GrottoGrave, RR_HYRULE_FIELD, RR_HF_NEAR_MARKET_GROTTO, ENTRANCE_GROTTO_LOAD(GROTTO_HF_NEAR_MARKET_OFFSET) },
|
||||
{ EntranceType::GrottoGrave, RR_HF_NEAR_MARKET_GROTTO, RR_HYRULE_FIELD, ENTRANCE_GROTTO_EXIT(GROTTO_HF_NEAR_MARKET_OFFSET) } },
|
||||
{ { EntranceType::GrottoGrave, RR_HYRULE_FIELD, RR_HF_COW_GROTTO, ENTRANCE_GROTTO_LOAD(GROTTO_HF_COW_OFFSET) },
|
||||
{ EntranceType::GrottoGrave, RR_HF_COW_GROTTO, RR_HYRULE_FIELD, ENTRANCE_GROTTO_EXIT(GROTTO_HF_COW_OFFSET) } },
|
||||
{ { EntranceType::GrottoGrave, RR_HYRULE_FIELD, RR_HF_INSIDE_FENCE_GROTTO, ENTRANCE_GROTTO_LOAD(GROTTO_HF_INSIDE_FENCE_OFFSET) },
|
||||
{ EntranceType::GrottoGrave, RR_HF_INSIDE_FENCE_GROTTO, RR_HYRULE_FIELD, ENTRANCE_GROTTO_EXIT(GROTTO_HF_INSIDE_FENCE_OFFSET) } },
|
||||
{ { EntranceType::GrottoGrave, RR_HYRULE_FIELD, RR_HF_OPEN_GROTTO, ENTRANCE_GROTTO_LOAD(GROTTO_HF_OPEN_OFFSET) },
|
||||
{ EntranceType::GrottoGrave, RR_HF_OPEN_GROTTO, RR_HYRULE_FIELD, ENTRANCE_GROTTO_EXIT(GROTTO_HF_OPEN_OFFSET) } },
|
||||
{ { EntranceType::GrottoGrave, RR_HYRULE_FIELD, RR_HF_SOUTHEAST_GROTTO, ENTRANCE_GROTTO_LOAD(GROTTO_HF_SOUTHEAST_OFFSET) },
|
||||
{ EntranceType::GrottoGrave, RR_HF_SOUTHEAST_GROTTO, RR_HYRULE_FIELD, ENTRANCE_GROTTO_EXIT(GROTTO_HF_SOUTHEAST_OFFSET) } },
|
||||
{ { EntranceType::GrottoGrave, RR_LON_LON_RANCH, RR_LLR_GROTTO, ENTRANCE_GROTTO_LOAD(GROTTO_LLR_OFFSET) },
|
||||
{ EntranceType::GrottoGrave, RR_LLR_GROTTO, RR_LON_LON_RANCH, ENTRANCE_GROTTO_EXIT(GROTTO_LLR_OFFSET) } },
|
||||
{ { EntranceType::GrottoGrave, RR_SFM_ENTRYWAY, RR_SFM_WOLFOS_GROTTO, ENTRANCE_GROTTO_LOAD(GROTTO_SFM_WOLFOS_OFFSET) },
|
||||
{ EntranceType::GrottoGrave, RR_SFM_WOLFOS_GROTTO, RR_SFM_ENTRYWAY, ENTRANCE_GROTTO_EXIT(GROTTO_SFM_WOLFOS_OFFSET) } },
|
||||
{ { EntranceType::GrottoGrave, RR_SACRED_FOREST_MEADOW, RR_SFM_STORMS_GROTTO, ENTRANCE_GROTTO_LOAD(GROTTO_SFM_STORMS_OFFSET) },
|
||||
{ EntranceType::GrottoGrave, RR_SFM_STORMS_GROTTO, RR_SACRED_FOREST_MEADOW, ENTRANCE_GROTTO_EXIT(GROTTO_SFM_STORMS_OFFSET) } },
|
||||
{ { EntranceType::GrottoGrave, RR_SACRED_FOREST_MEADOW, RR_SFM_FAIRY_GROTTO, ENTRANCE_GROTTO_LOAD(GROTTO_SFM_FAIRY_OFFSET) },
|
||||
{ EntranceType::GrottoGrave, RR_SFM_FAIRY_GROTTO, RR_SACRED_FOREST_MEADOW, ENTRANCE_GROTTO_EXIT(GROTTO_SFM_FAIRY_OFFSET) } },
|
||||
{ { EntranceType::GrottoGrave, RR_LW_BEYOND_MIDO, RR_LW_SCRUBS_GROTTO, ENTRANCE_GROTTO_LOAD(GROTTO_LW_SCRUBS_OFFSET) },
|
||||
{ EntranceType::GrottoGrave, RR_LW_SCRUBS_GROTTO, RR_LW_BEYOND_MIDO, ENTRANCE_GROTTO_EXIT(GROTTO_LW_SCRUBS_OFFSET) } },
|
||||
{ { EntranceType::GrottoGrave, RR_THE_LOST_WOODS, RR_LW_NEAR_SHORTCUTS_GROTTO, ENTRANCE_GROTTO_LOAD(GROTTO_LW_NEAR_SHORTCUTS_OFFSET) },
|
||||
{ EntranceType::GrottoGrave, RR_LW_NEAR_SHORTCUTS_GROTTO, RR_THE_LOST_WOODS, ENTRANCE_GROTTO_EXIT(GROTTO_LW_NEAR_SHORTCUTS_OFFSET) } },
|
||||
{ { EntranceType::GrottoGrave, RR_KOKIRI_FOREST, RR_KF_STORMS_GROTTO, ENTRANCE_GROTTO_LOAD(GROTTO_KF_STORMS_OFFSET) },
|
||||
{ EntranceType::GrottoGrave, RR_KF_STORMS_GROTTO, RR_KOKIRI_FOREST, ENTRANCE_GROTTO_EXIT(GROTTO_KF_STORMS_OFFSET) } },
|
||||
{ { EntranceType::GrottoGrave, RR_ZORAS_DOMAIN_ISLAND, RR_ZD_STORMS_GROTTO, ENTRANCE_GROTTO_LOAD(GROTTO_ZD_STORMS_OFFSET) },
|
||||
{ EntranceType::GrottoGrave, RR_ZD_STORMS_GROTTO, RR_ZORAS_DOMAIN_ISLAND, ENTRANCE_GROTTO_EXIT(GROTTO_ZD_STORMS_OFFSET) } },
|
||||
{ { EntranceType::GrottoGrave, RR_GERUDO_FORTRESS, RR_GF_STORMS_GROTTO, ENTRANCE_GROTTO_LOAD(GROTTO_GF_STORMS_OFFSET) },
|
||||
{ EntranceType::GrottoGrave, RR_GF_STORMS_GROTTO, RR_GERUDO_FORTRESS, ENTRANCE_GROTTO_EXIT(GROTTO_GF_STORMS_OFFSET) } },
|
||||
{ { EntranceType::GrottoGrave, RR_GV_FORTRESS_SIDE, RR_GV_STORMS_GROTTO, ENTRANCE_GROTTO_LOAD(GROTTO_GV_STORMS_OFFSET) },
|
||||
{ EntranceType::GrottoGrave, RR_GV_STORMS_GROTTO, RR_GV_FORTRESS_SIDE, ENTRANCE_GROTTO_EXIT(GROTTO_GV_STORMS_OFFSET) } },
|
||||
{ { EntranceType::GrottoGrave, RR_GV_GROTTO_LEDGE, RR_GV_OCTOROK_GROTTO, ENTRANCE_GROTTO_LOAD(GROTTO_GV_OCTOROK_OFFSET) },
|
||||
{ EntranceType::GrottoGrave, RR_GV_OCTOROK_GROTTO, RR_GV_GROTTO_LEDGE, ENTRANCE_GROTTO_EXIT(GROTTO_GV_OCTOROK_OFFSET) } },
|
||||
{ { EntranceType::GrottoGrave, RR_LW_BEYOND_MIDO, RR_DEKU_THEATER, ENTRANCE_GROTTO_LOAD(GROTTO_LW_DEKU_THEATRE_OFFSET) },
|
||||
{ EntranceType::GrottoGrave, RR_DEKU_THEATER, RR_LW_BEYOND_MIDO, ENTRANCE_GROTTO_EXIT(GROTTO_LW_DEKU_THEATRE_OFFSET) } },
|
||||
|
||||
// Graves have their own specified entrance indices
|
||||
{ { EntranceType::GrottoGrave, RR_THE_GRAVEYARD, RR_GRAVEYARD_SHIELD_GRAVE, ENTR_GRAVE_WITH_FAIRYS_FOUNTAIN_0 },
|
||||
{ EntranceType::GrottoGrave, RR_GRAVEYARD_SHIELD_GRAVE, RR_THE_GRAVEYARD, ENTR_GRAVEYARD_SHIELD_GRAVE_EXIT } },
|
||||
{ { EntranceType::GrottoGrave, RR_THE_GRAVEYARD, RR_GRAVEYARD_HEART_PIECE_GRAVE, ENTR_REDEAD_GRAVE_0 },
|
||||
{ EntranceType::GrottoGrave, RR_GRAVEYARD_HEART_PIECE_GRAVE, RR_THE_GRAVEYARD, ENTR_GRAVEYARD_HEART_PIECE_GRAVE_EXIT } },
|
||||
{ { EntranceType::GrottoGrave, RR_THE_GRAVEYARD, RR_GRAVEYARD_COMPOSERS_GRAVE, ENTR_ROYAL_FAMILYS_TOMB_0 },
|
||||
{ EntranceType::GrottoGrave, RR_GRAVEYARD_COMPOSERS_GRAVE, RR_THE_GRAVEYARD, ENTR_GRAVEYARD_ROYAL_TOMB_EXIT } },
|
||||
{ { EntranceType::GrottoGrave, RR_THE_GRAVEYARD, RR_GRAVEYARD_DAMPES_GRAVE, ENTR_WINDMILL_AND_DAMPES_GRAVE_GRAVE },
|
||||
{ EntranceType::GrottoGrave, RR_GRAVEYARD_DAMPES_GRAVE, RR_THE_GRAVEYARD, ENTR_GRAVEYARD_DAMPES_GRAVE_EXIT } },
|
||||
|
||||
{ { EntranceType::Overworld, RR_KOKIRI_FOREST, RR_LW_BRIDGE_FROM_FOREST, ENTR_LOST_WOODS_BRIDGE_EAST_EXIT },
|
||||
{ EntranceType::Overworld, RR_LW_BRIDGE, RR_KOKIRI_FOREST, ENTR_KOKIRI_FOREST_LOWER_EXIT } },
|
||||
{ { EntranceType::Overworld, RR_KOKIRI_FOREST, RR_THE_LOST_WOODS, ENTR_LOST_WOODS_SOUTH_EXIT },
|
||||
{ EntranceType::Overworld, RR_LW_FOREST_EXIT, RR_KOKIRI_FOREST, ENTR_KOKIRI_FOREST_UPPER_EXIT } },
|
||||
{ { EntranceType::Overworld, RR_THE_LOST_WOODS, RR_GC_WOODS_WARP, ENTR_GORON_CITY_TUNNEL_SHORTCUT },
|
||||
{ EntranceType::Overworld, RR_GC_WOODS_WARP, RR_THE_LOST_WOODS, ENTR_LOST_WOODS_TUNNEL_SHORTCUT } },
|
||||
{ { EntranceType::Overworld, RR_THE_LOST_WOODS, RR_ZORAS_RIVER, ENTR_ZORAS_RIVER_UNDERWATER_SHORTCUT },
|
||||
{ EntranceType::Overworld, RR_ZORAS_RIVER, RR_THE_LOST_WOODS, ENTR_LOST_WOODS_UNDERWATER_SHORTCUT } },
|
||||
{ { EntranceType::Overworld, RR_LW_BEYOND_MIDO, RR_SFM_ENTRYWAY, ENTR_SACRED_FOREST_MEADOW_SOUTH_EXIT },
|
||||
{ EntranceType::Overworld, RR_SFM_ENTRYWAY, RR_LW_BEYOND_MIDO, ENTR_LOST_WOODS_NORTH_EXIT } },
|
||||
{ { EntranceType::Overworld, RR_LW_BRIDGE, RR_HYRULE_FIELD, ENTR_HYRULE_FIELD_WOODED_EXIT },
|
||||
{ EntranceType::Overworld, RR_HYRULE_FIELD, RR_LW_BRIDGE, ENTR_LOST_WOODS_BRIDGE_WEST_EXIT } },
|
||||
{ { EntranceType::Overworld, RR_HYRULE_FIELD, RR_LAKE_HYLIA, ENTR_LAKE_HYLIA_NORTH_EXIT },
|
||||
{ EntranceType::Overworld, RR_LAKE_HYLIA, RR_HYRULE_FIELD, ENTR_HYRULE_FIELD_FENCE_EXIT } },
|
||||
{ { EntranceType::Overworld, RR_HYRULE_FIELD, RR_GERUDO_VALLEY, ENTR_GERUDO_VALLEY_EAST_EXIT },
|
||||
{ EntranceType::Overworld, RR_GERUDO_VALLEY, RR_HYRULE_FIELD, ENTR_HYRULE_FIELD_ROCKY_PATH } },
|
||||
{ { EntranceType::Overworld, RR_HYRULE_FIELD, RR_MARKET_ENTRANCE, ENTR_MARKET_ENTRANCE_NEAR_GUARD_EXIT },
|
||||
{ EntranceType::Overworld, RR_MARKET_ENTRANCE, RR_HYRULE_FIELD, ENTR_HYRULE_FIELD_ON_BRIDGE_SPAWN } },
|
||||
{ { EntranceType::Overworld, RR_HYRULE_FIELD, RR_KAKARIKO_VILLAGE, ENTR_KAKARIKO_VILLAGE_FRONT_GATE },
|
||||
{ EntranceType::Overworld, RR_KAKARIKO_VILLAGE, RR_HYRULE_FIELD, ENTR_HYRULE_FIELD_STAIRS_EXIT } },
|
||||
{ { EntranceType::Overworld, RR_HYRULE_FIELD, RR_ZR_FRONT, ENTR_ZORAS_RIVER_WEST_EXIT },
|
||||
{ EntranceType::Overworld, RR_ZR_FRONT, RR_HYRULE_FIELD, ENTR_HYRULE_FIELD_RIVER_EXIT } },
|
||||
{ { EntranceType::Overworld, RR_HYRULE_FIELD, RR_LON_LON_RANCH, ENTR_LON_LON_RANCH_ENTRANCE },
|
||||
{ EntranceType::Overworld, RR_LON_LON_RANCH, RR_HYRULE_FIELD, ENTR_HYRULE_FIELD_CENTER_EXIT } },
|
||||
{ { EntranceType::Overworld, RR_LAKE_HYLIA, RR_ZORAS_DOMAIN, ENTR_ZORAS_DOMAIN_UNDERWATER_SHORTCUT },
|
||||
{ EntranceType::Overworld, RR_ZORAS_DOMAIN, RR_LAKE_HYLIA, ENTR_LAKE_HYLIA_UNDERWATER_SHORTCUT } },
|
||||
{ { EntranceType::Overworld, RR_GV_FORTRESS_SIDE, RR_GERUDO_FORTRESS, ENTR_GERUDOS_FORTRESS_EAST_EXIT },
|
||||
{ EntranceType::Overworld, RR_GERUDO_FORTRESS, RR_GV_FORTRESS_SIDE, ENTR_GERUDO_VALLEY_WEST_EXIT } },
|
||||
{ { EntranceType::Overworld, RR_GF_OUTSIDE_GATE, RR_WASTELAND_NEAR_FORTRESS, ENTR_HAUNTED_WASTELAND_EAST_EXIT },
|
||||
{ EntranceType::Overworld, RR_WASTELAND_NEAR_FORTRESS, RR_GF_OUTSIDE_GATE, ENTR_GERUDOS_FORTRESS_GATE_EXIT } },
|
||||
{ { EntranceType::Overworld, RR_WASTELAND_NEAR_COLOSSUS, RR_DESERT_COLOSSUS, ENTR_DESERT_COLOSSUS_EAST_EXIT },
|
||||
{ EntranceType::Overworld, RR_DESERT_COLOSSUS, RR_WASTELAND_NEAR_COLOSSUS, ENTR_HAUNTED_WASTELAND_WEST_EXIT } },
|
||||
{ { EntranceType::Overworld, RR_MARKET_ENTRANCE, RR_THE_MARKET, ENTR_MARKET_SOUTH_EXIT },
|
||||
{ EntranceType::Overworld, RR_THE_MARKET, RR_MARKET_ENTRANCE, ENTR_MARKET_ENTRANCE_NORTH_EXIT } },
|
||||
{ { EntranceType::Overworld, RR_THE_MARKET, RR_CASTLE_GROUNDS, ENTR_CASTLE_GROUNDS_SOUTH_EXIT },
|
||||
{ EntranceType::Overworld, RR_CASTLE_GROUNDS, RR_THE_MARKET, ENTR_MARKET_DAY_CASTLE_EXIT } },
|
||||
{ { EntranceType::Overworld, RR_THE_MARKET, RR_TOT_ENTRANCE, ENTR_TEMPLE_OF_TIME_EXTERIOR_DAY_GOSSIP_STONE_EXIT },
|
||||
{ EntranceType::Overworld, RR_TOT_ENTRANCE, RR_THE_MARKET, ENTR_MARKET_DAY_TEMPLE_EXIT } },
|
||||
{ { EntranceType::Overworld, RR_KAKARIKO_VILLAGE, RR_THE_GRAVEYARD, ENTR_GRAVEYARD_ENTRANCE },
|
||||
{ EntranceType::Overworld, RR_THE_GRAVEYARD, RR_KAKARIKO_VILLAGE, ENTR_KAKARIKO_VILLAGE_SOUTHEAST_EXIT } },
|
||||
{ { EntranceType::Overworld, RR_KAK_BEHIND_GATE, RR_DEATH_MOUNTAIN_TRAIL, ENTR_DEATH_MOUNTAIN_TRAIL_BOTTOM_EXIT },
|
||||
{ EntranceType::Overworld, RR_DEATH_MOUNTAIN_TRAIL, RR_KAK_BEHIND_GATE, ENTR_KAKARIKO_VILLAGE_GUARD_GATE } },
|
||||
{ { EntranceType::Overworld, RR_DEATH_MOUNTAIN_TRAIL, RR_GORON_CITY, ENTR_GORON_CITY_UPPER_EXIT },
|
||||
{ EntranceType::Overworld, RR_GORON_CITY, RR_DEATH_MOUNTAIN_TRAIL, ENTR_DEATH_MOUNTAIN_TRAIL_GC_EXIT } },
|
||||
{ { EntranceType::Overworld, RR_GC_DARUNIAS_CHAMBER, RR_DMC_LOWER_LOCAL, ENTR_DEATH_MOUNTAIN_CRATER_GC_EXIT },
|
||||
{ EntranceType::Overworld, RR_DMC_LOWER_NEARBY, RR_GC_DARUNIAS_CHAMBER, ENTR_GORON_CITY_DARUNIA_ROOM_EXIT } },
|
||||
{ { EntranceType::Overworld, RR_DEATH_MOUNTAIN_SUMMIT, RR_DMC_UPPER_LOCAL, ENTR_DEATH_MOUNTAIN_CRATER_UPPER_EXIT },
|
||||
{ EntranceType::Overworld, RR_DMC_UPPER_NEARBY, RR_DEATH_MOUNTAIN_SUMMIT, ENTR_DEATH_MOUNTAIN_TRAIL_SUMMIT_EXIT } },
|
||||
{ { EntranceType::Overworld, RR_ZR_BEHIND_WATERFALL, RR_ZORAS_DOMAIN, ENTR_ZORAS_DOMAIN_ENTRANCE },
|
||||
{ EntranceType::Overworld, RR_ZORAS_DOMAIN, RR_ZR_BEHIND_WATERFALL, ENTR_ZORAS_RIVER_WATERFALL_EXIT } },
|
||||
{ { EntranceType::Overworld, RR_ZD_BEHIND_KING_ZORA, RR_ZORAS_FOUNTAIN, ENTR_ZORAS_FOUNTAIN_TUNNEL_EXIT },
|
||||
{ EntranceType::Overworld, RR_ZORAS_FOUNTAIN, RR_ZD_BEHIND_KING_ZORA, ENTR_ZORAS_DOMAIN_KING_ZORA_EXIT } },
|
||||
|
||||
{ { EntranceType::Overworld, RR_GV_LOWER_STREAM, RR_LAKE_HYLIA, ENTR_LAKE_HYLIA_RIVER_EXIT },
|
||||
NO_RETURN_ENTRANCE },
|
||||
|
||||
{ { EntranceType::OwlDrop, RR_LH_OWL_FLIGHT, RR_HYRULE_FIELD, ENTR_HYRULE_FIELD_OWL_DROP },
|
||||
NO_RETURN_ENTRANCE },
|
||||
{ { EntranceType::OwlDrop, RR_DMT_OWL_FLIGHT, RR_KAK_IMPAS_ROOFTOP, ENTR_KAKARIKO_VILLAGE_OWL_DROP },
|
||||
NO_RETURN_ENTRANCE },
|
||||
|
||||
{ { EntranceType::Spawn, RR_CHILD_SPAWN, RR_KF_LINKS_HOUSE, ENTR_LINKS_HOUSE_CHILD_SPAWN },
|
||||
NO_RETURN_ENTRANCE },
|
||||
{ { EntranceType::Spawn, RR_ADULT_SPAWN, RR_TEMPLE_OF_TIME, ENTR_HYRULE_FIELD_10 },
|
||||
NO_RETURN_ENTRANCE }, // 0x282 is an unused entrance index repurposed to differentiate between
|
||||
// Adult Spawn and prelude of light (normally they both use 0x5F4)
|
||||
{ { EntranceType::WarpSong, RR_MINUET_OF_FOREST_WARP, RR_SACRED_FOREST_MEADOW, ENTR_SACRED_FOREST_MEADOW_WARP_PAD },
|
||||
NO_RETURN_ENTRANCE },
|
||||
{ { EntranceType::WarpSong, RR_BOLERO_OF_FIRE_WARP, RR_DMC_CENTRAL_LOCAL, ENTR_DEATH_MOUNTAIN_CRATER_WARP_PAD },
|
||||
NO_RETURN_ENTRANCE },
|
||||
{ { EntranceType::WarpSong, RR_SERENADE_OF_WATER_WARP, RR_LAKE_HYLIA, ENTR_LAKE_HYLIA_WARP_PAD },
|
||||
NO_RETURN_ENTRANCE },
|
||||
{ { EntranceType::WarpSong, RR_REQUIEM_OF_SPIRIT_WARP, RR_DESERT_COLOSSUS, ENTR_DESERT_COLOSSUS_WARP_PAD },
|
||||
NO_RETURN_ENTRANCE },
|
||||
{ { EntranceType::WarpSong, RR_NOCTURNE_OF_SHADOW_WARP, RR_GRAVEYARD_WARP_PAD_REGION, ENTR_GRAVEYARD_WARP_PAD },
|
||||
NO_RETURN_ENTRANCE },
|
||||
{ { EntranceType::WarpSong, RR_PRELUDE_OF_LIGHT_WARP, RR_TEMPLE_OF_TIME, ENTR_TEMPLE_OF_TIME_WARP_PAD },
|
||||
NO_RETURN_ENTRANCE },
|
||||
|
||||
{ { EntranceType::ChildBoss, RR_DEKU_TREE_BOSS_ENTRYWAY, RR_DEKU_TREE_BOSS_ROOM, ENTR_DEKU_TREE_BOSS_ENTRANCE },
|
||||
{ EntranceType::ChildBoss, RR_DEKU_TREE_BOSS_ROOM, RR_DEKU_TREE_BOSS_ENTRYWAY, ENTR_DEKU_TREE_BOSS_DOOR } },
|
||||
{ { EntranceType::ChildBoss, RR_DODONGOS_CAVERN_BOSS_ENTRYWAY, RR_DODONGOS_CAVERN_BOSS_ROOM, ENTR_DODONGOS_CAVERN_BOSS_ENTRANCE },
|
||||
{ EntranceType::ChildBoss, RR_DODONGOS_CAVERN_BOSS_ROOM, RR_DODONGOS_CAVERN_BOSS_ENTRYWAY, ENTR_DODONGOS_CAVERN_BOSS_DOOR } },
|
||||
{ { EntranceType::ChildBoss, RR_JABU_JABUS_BELLY_BOSS_ENTRYWAY, RR_JABU_JABUS_BELLY_BOSS_ROOM, ENTR_JABU_JABU_BOSS_ENTRANCE },
|
||||
{ EntranceType::ChildBoss, RR_JABU_JABUS_BELLY_BOSS_ROOM, RR_JABU_JABUS_BELLY_BOSS_ENTRYWAY, ENTR_JABU_JABU_BOSS_DOOR } },
|
||||
{ { EntranceType::AdultBoss, RR_FOREST_TEMPLE_BOSS_ENTRYWAY, RR_FOREST_TEMPLE_BOSS_ROOM, ENTR_FOREST_TEMPLE_BOSS_ENTRANCE },
|
||||
{ EntranceType::AdultBoss, RR_FOREST_TEMPLE_BOSS_ROOM, RR_FOREST_TEMPLE_BOSS_ENTRYWAY, ENTR_FOREST_TEMPLE_BOSS_DOOR } },
|
||||
{ { EntranceType::AdultBoss, RR_FIRE_TEMPLE_BOSS_ENTRYWAY, RR_FIRE_TEMPLE_BOSS_ROOM, ENTR_FIRE_TEMPLE_BOSS_ENTRANCE },
|
||||
{ EntranceType::AdultBoss, RR_FIRE_TEMPLE_BOSS_ROOM, RR_FIRE_TEMPLE_BOSS_ENTRYWAY, ENTR_FIRE_TEMPLE_BOSS_DOOR } },
|
||||
{ { EntranceType::AdultBoss, RR_WATER_TEMPLE_BOSS_ENTRYWAY, RR_WATER_TEMPLE_BOSS_ROOM, ENTR_WATER_TEMPLE_BOSS_ENTRANCE },
|
||||
{ EntranceType::AdultBoss, RR_WATER_TEMPLE_BOSS_ROOM, RR_WATER_TEMPLE_BOSS_ENTRYWAY, ENTR_WATER_TEMPLE_BOSS_DOOR } },
|
||||
{ { EntranceType::AdultBoss, RR_SPIRIT_TEMPLE_BOSS_ENTRYWAY, RR_SPIRIT_TEMPLE_BOSS_ROOM, ENTR_SPIRIT_TEMPLE_BOSS_ENTRANCE },
|
||||
{ EntranceType::AdultBoss, RR_SPIRIT_TEMPLE_BOSS_ROOM, RR_SPIRIT_TEMPLE_BOSS_ENTRYWAY, ENTR_SPIRIT_TEMPLE_BOSS_DOOR } },
|
||||
{ { EntranceType::AdultBoss, RR_SHADOW_TEMPLE_BOSS_ENTRYWAY, RR_SHADOW_TEMPLE_BOSS_ROOM, ENTR_SHADOW_TEMPLE_BOSS_ENTRANCE },
|
||||
{ EntranceType::AdultBoss, RR_SHADOW_TEMPLE_BOSS_ROOM, RR_SHADOW_TEMPLE_BOSS_ENTRYWAY, ENTR_SHADOW_TEMPLE_BOSS_DOOR } },
|
||||
|
||||
{ { EntranceType::BlueWarp, RR_DEKU_TREE_BOSS_ROOM, RR_KF_OUTSIDE_DEKU_TREE, ENTR_KOKIRI_FOREST_DEKU_TREE_BLUE_WARP },
|
||||
NO_RETURN_ENTRANCE },
|
||||
{ { EntranceType::BlueWarp, RR_DODONGOS_CAVERN_BOSS_ROOM, RR_DEATH_MOUNTAIN_TRAIL, ENTR_DEATH_MOUNTAIN_TRAIL_DODONGO_BLUE_WARP },
|
||||
NO_RETURN_ENTRANCE },
|
||||
{ { EntranceType::BlueWarp, RR_JABU_JABUS_BELLY_BOSS_ROOM, RR_ZORAS_FOUNTAIN, ENTR_ZORAS_FOUNTAIN_JABU_JABU_BLUE_WARP },
|
||||
NO_RETURN_ENTRANCE },
|
||||
{ { EntranceType::BlueWarp, RR_FOREST_TEMPLE_BOSS_ROOM, RR_SACRED_FOREST_MEADOW, ENTR_SACRED_FOREST_MEADOW_FOREST_TEMPLE_BLUE_WARP },
|
||||
NO_RETURN_ENTRANCE },
|
||||
{ { EntranceType::BlueWarp, RR_FIRE_TEMPLE_BOSS_ROOM, RR_DMC_CENTRAL_LOCAL, ENTR_DEATH_MOUNTAIN_CRATER_FIRE_TEMPLE_BLUE_WARP },
|
||||
NO_RETURN_ENTRANCE },
|
||||
{ { EntranceType::BlueWarp, RR_WATER_TEMPLE_BOSS_ROOM, RR_LAKE_HYLIA, ENTR_LAKE_HYLIA_WATER_TEMPLE_BLUE_WARP },
|
||||
NO_RETURN_ENTRANCE },
|
||||
{ { EntranceType::BlueWarp, RR_SPIRIT_TEMPLE_BOSS_ROOM, RR_DESERT_COLOSSUS, ENTR_DESERT_COLOSSUS_SPIRIT_TEMPLE_BLUE_WARP },
|
||||
NO_RETURN_ENTRANCE },
|
||||
{ { EntranceType::BlueWarp, RR_SHADOW_TEMPLE_BOSS_ROOM, RR_GRAVEYARD_WARP_PAD_REGION, ENTR_GRAVEYARD_SHADOW_TEMPLE_BLUE_WARP },
|
||||
NO_RETURN_ENTRANCE },
|
||||
// clang-format on
|
||||
};
|
||||
|
||||
std::map<std::string, PriorityEntrance> priorityEntranceTable = {
|
||||
{ "Bolero", { { RR_DMC_CENTRAL_LOCAL }, { EntranceType::OwlDrop, EntranceType::WarpSong } } },
|
||||
{ "Nocturne",
|
||||
@@ -1178,7 +1182,7 @@ int EntranceShuffler::ShuffleAllEntrances() {
|
||||
};
|
||||
|
||||
mEntranceShuffleFailure = false;
|
||||
SetAllEntrancesData(entranceShuffleTable);
|
||||
SetAllEntrancesData();
|
||||
|
||||
EntrancePools oneWayEntrancePools = {};
|
||||
EntrancePools entrancePools = {};
|
||||
@@ -1488,11 +1492,11 @@ int EntranceShuffler::ShuffleAllEntrances() {
|
||||
if (true /* ctx->GetOption(RSK_SHUFFLE_BLUEWARP_ENTRANCES).Is(RO_BLUEWARP_ENTRANCE_SHUFFLE_DUNGEON) */) {
|
||||
// If a boss room is inside a boss door, make the blue warp go outside the dungeon's entrance
|
||||
std::map<std::string, Entrance*> bossExits = {
|
||||
{ EntranceNameByRegions(RR_DEKU_TREE_BOSS_ROOM, RR_DEKU_TREE_BOSS_ENTRYWAY),
|
||||
{ EntranceNameByRegions(RR_DEKU_TREE_BOSS_ROOM, RR_DEKU_TREE_BOSS_EXIT),
|
||||
GetEntrance(EntranceNameByRegions(RR_DEKU_TREE_ENTRYWAY, RR_KF_OUTSIDE_DEKU_TREE)) },
|
||||
{ EntranceNameByRegions(RR_DODONGOS_CAVERN_BOSS_ROOM, RR_DODONGOS_CAVERN_BOSS_ENTRYWAY),
|
||||
{ EntranceNameByRegions(RR_DODONGOS_CAVERN_BOSS_ROOM, RR_DODONGOS_CAVERN_BOSS_EXIT),
|
||||
GetEntrance(EntranceNameByRegions(RR_DODONGOS_CAVERN_ENTRYWAY, RR_DEATH_MOUNTAIN_TRAIL)) },
|
||||
{ EntranceNameByRegions(RR_JABU_JABUS_BELLY_BOSS_ROOM, RR_JABU_JABUS_BELLY_BOSS_ENTRYWAY),
|
||||
{ EntranceNameByRegions(RR_JABU_JABUS_BELLY_BOSS_ROOM, RR_JABU_JABUS_BELLY_BOSS_EXIT),
|
||||
GetEntrance(EntranceNameByRegions(RR_JABU_JABUS_BELLY_ENTRYWAY, RR_ZORAS_FOUNTAIN)) },
|
||||
{ EntranceNameByRegions(RR_FOREST_TEMPLE_BOSS_ROOM, RR_FOREST_TEMPLE_BOSS_ENTRYWAY),
|
||||
GetEntrance(EntranceNameByRegions(RR_FOREST_TEMPLE_ENTRYWAY, RR_SACRED_FOREST_MEADOW)) },
|
||||
@@ -1530,11 +1534,11 @@ int EntranceShuffler::ShuffleAllEntrances() {
|
||||
// Pair <BlueWarp exit, BossRoom reverse exit>
|
||||
std::vector<EntrancePair> bossRoomExitPairs = {
|
||||
{ GetEntrance(EntranceNameByRegions(RR_DEKU_TREE_BOSS_ROOM, RR_KF_OUTSIDE_DEKU_TREE)),
|
||||
GetEntrance(EntranceNameByRegions(RR_DEKU_TREE_BOSS_ROOM, RR_DEKU_TREE_BOSS_ENTRYWAY)) },
|
||||
GetEntrance(EntranceNameByRegions(RR_DEKU_TREE_BOSS_ROOM, RR_DEKU_TREE_BOSS_EXIT)) },
|
||||
{ GetEntrance(EntranceNameByRegions(RR_DODONGOS_CAVERN_BOSS_ROOM, RR_DEATH_MOUNTAIN_TRAIL)),
|
||||
GetEntrance(EntranceNameByRegions(RR_DODONGOS_CAVERN_BOSS_ROOM, RR_DODONGOS_CAVERN_BOSS_ENTRYWAY)) },
|
||||
GetEntrance(EntranceNameByRegions(RR_DODONGOS_CAVERN_BOSS_ROOM, RR_DODONGOS_CAVERN_BOSS_EXIT)) },
|
||||
{ GetEntrance(EntranceNameByRegions(RR_JABU_JABUS_BELLY_BOSS_ROOM, RR_ZORAS_FOUNTAIN)),
|
||||
GetEntrance(EntranceNameByRegions(RR_JABU_JABUS_BELLY_BOSS_ROOM, RR_JABU_JABUS_BELLY_BOSS_ENTRYWAY)) },
|
||||
GetEntrance(EntranceNameByRegions(RR_JABU_JABUS_BELLY_BOSS_ROOM, RR_JABU_JABUS_BELLY_BOSS_EXIT)) },
|
||||
{ GetEntrance(EntranceNameByRegions(RR_FOREST_TEMPLE_BOSS_ROOM, RR_SACRED_FOREST_MEADOW)),
|
||||
GetEntrance(EntranceNameByRegions(RR_FOREST_TEMPLE_BOSS_ROOM, RR_FOREST_TEMPLE_BOSS_ENTRYWAY)) },
|
||||
{ GetEntrance(EntranceNameByRegions(RR_FIRE_TEMPLE_BOSS_ROOM, RR_DMC_CENTRAL_LOCAL)),
|
||||
@@ -1662,6 +1666,30 @@ void EntranceShuffler::ParseJson(nlohmann::json spoilerFileJson) {
|
||||
}
|
||||
}
|
||||
} catch (const std::exception& e) { throw e; }
|
||||
// We may need to reset more things here or elsewhere in spoiler loading
|
||||
RegionTable_Init();
|
||||
ApplyEntranceOverrides();
|
||||
SetAreas();
|
||||
}
|
||||
|
||||
void EntranceShuffler::ApplyEntranceOverrides() {
|
||||
SetAllEntrancesData();
|
||||
|
||||
for (size_t i = 0; i < entranceOverrides.size(); i++) {
|
||||
EntranceOverride entranceOverride = entranceOverrides[i];
|
||||
|
||||
if (entranceOverride.index == 0 && entranceOverride.destination == 0 && entranceOverride.override == 0 &&
|
||||
entranceOverride.overrideDestination == 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
Entrance* entrance = entranceMap[entranceOverride.index];
|
||||
Entrance* overrideEntrance = entranceMap[entranceOverride.override];
|
||||
|
||||
entrance->Disconnect();
|
||||
entrance->Connect(overrideEntrance->GetOriginalConnectedRegionKey());
|
||||
entrance->SetAsShuffled();
|
||||
}
|
||||
}
|
||||
} // namespace Rando
|
||||
|
||||
|
||||
@@ -128,6 +128,7 @@ class EntranceShuffler {
|
||||
void CreateEntranceOverrides();
|
||||
void UnshuffleAllEntrances();
|
||||
void ParseJson(nlohmann::json spoilerFileJson);
|
||||
void ApplyEntranceOverrides();
|
||||
|
||||
private:
|
||||
std::vector<Entrance*> AssumeEntrancePool(std::vector<Entrance*>& entrancePool);
|
||||
|
||||
@@ -299,6 +299,8 @@ const CustomMessage Hint::GetHintMessage(MessageFormat format, uint8_t id) const
|
||||
} else if (hintType == HINT_TYPE_ALTAR_CHILD) {
|
||||
if (ctx->GetOption(RSK_TOT_ALTAR_HINT)) {
|
||||
hintText = StaticData::hintTextTable[RHT_CHILD_ALTAR_STONES].GetHintMessage();
|
||||
} else {
|
||||
hintText.SetTextBoxType(TEXTBOX_TYPE_BLUE);
|
||||
}
|
||||
if (ctx->GetOption(RSK_DOOR_OF_TIME).Is(RO_DOOROFTIME_OPEN)) {
|
||||
hintText += CustomMessage(StaticData::hintTextTable[RHT_CHILD_ALTAR_TEXT_END_DOTOPEN].GetHintMessage());
|
||||
@@ -310,6 +312,8 @@ const CustomMessage Hint::GetHintMessage(MessageFormat format, uint8_t id) const
|
||||
} else if (hintType == HINT_TYPE_ALTAR_ADULT) {
|
||||
if (ctx->GetOption(RSK_TOT_ALTAR_HINT)) {
|
||||
hintText = StaticData::hintTextTable[RHT_ADULT_ALTAR_MEDALLIONS].GetHintMessage();
|
||||
} else {
|
||||
hintText.SetTextBoxType(TEXTBOX_TYPE_BLUE);
|
||||
}
|
||||
hintText += GetBridgeReqsText() + GetGanonBossKeyText() +
|
||||
StaticData::hintTextTable[RHT_ADULT_ALTAR_TEXT_END].GetHintMessage();
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
#include <libultraship/bridge.h>
|
||||
#include <libultraship/bridge.h>
|
||||
#include "soh/OTRGlobals.h"
|
||||
#include "soh/ResourceManagerHelpers.h"
|
||||
#include "soh/Enhancements/enhancementTypes.h"
|
||||
@@ -327,7 +327,10 @@ void RandomizerOnPlayerUpdateForRCQueueHandler() {
|
||||
getItemEntry.modIndex == MOD_RANDOMIZER) &&
|
||||
(getItemEntry.getItemCategory == ITEM_CATEGORY_JUNK ||
|
||||
getItemEntry.getItemCategory == ITEM_CATEGORY_SKULLTULA_TOKEN ||
|
||||
getItemEntry.getItemCategory == ITEM_CATEGORY_LESSER))))) {
|
||||
getItemEntry.getItemCategory == ITEM_CATEGORY_LESSER ||
|
||||
// Treat small keys as junk if Skeleton Key is obtained.
|
||||
(getItemEntry.getItemCategory == ITEM_CATEGORY_SMALL_KEY &&
|
||||
Flags_GetRandomizerInf(RAND_INF_HAS_SKELETON_KEY))))))) {
|
||||
Item_DropCollectible(gPlayState, &spawnPos, ITEM00_SOH_GIVE_ITEM_ENTRY | 0x8000);
|
||||
}
|
||||
}
|
||||
@@ -865,7 +868,7 @@ void RandomizerOnVanillaBehaviorHandler(GIVanillaBehavior id, bool* should, va_l
|
||||
*should = !Flags_GetEventChkInf(EVENTCHKINF_BONGO_BONGO_ESCAPED_FROM_WELL) && LINK_IS_ADULT &&
|
||||
gEntranceTable[((void)0, gSaveContext.entranceIndex)].scene == SCENE_KAKARIKO_VILLAGE &&
|
||||
CHECK_QUEST_ITEM(QUEST_MEDALLION_FOREST) && CHECK_QUEST_ITEM(QUEST_MEDALLION_FIRE) &&
|
||||
CHECK_QUEST_ITEM(QUEST_MEDALLION_WATER);
|
||||
CHECK_QUEST_ITEM(QUEST_MEDALLION_WATER) && gSaveContext.cutsceneIndex < 0xFFF0;
|
||||
break;
|
||||
case VB_BE_ELIGIBLE_FOR_CHILD_ROLLING_GORON_REWARD: {
|
||||
// Don't require a bomb bag to get prize in rando
|
||||
@@ -881,7 +884,7 @@ void RandomizerOnVanillaBehaviorHandler(GIVanillaBehavior id, bool* should, va_l
|
||||
break;
|
||||
}
|
||||
case VB_GIVE_ITEM_MASTER_SWORD:
|
||||
if (RAND_GET_OPTION(RSK_SHUFFLE_MASTER_SWORD)) {
|
||||
if (RAND_GET_OPTION(RSK_SHUFFLE_MASTER_SWORD) || RAND_GET_OPTION(RSK_STARTING_MASTER_SWORD)) {
|
||||
*should = false;
|
||||
} else {
|
||||
*should = true;
|
||||
@@ -1023,17 +1026,55 @@ void RandomizerOnVanillaBehaviorHandler(GIVanillaBehavior id, bool* should, va_l
|
||||
}
|
||||
|
||||
if (item00->itemEntry.modIndex == MOD_NONE) {
|
||||
std::string message;
|
||||
|
||||
switch (gSaveContext.language) {
|
||||
case LANGUAGE_FRA:
|
||||
message = "Vous obtenez: ";
|
||||
break;
|
||||
case LANGUAGE_GER:
|
||||
message = "Du erhältst: ";
|
||||
break;
|
||||
case LANGUAGE_ENG:
|
||||
default:
|
||||
message = "You found ";
|
||||
break;
|
||||
}
|
||||
|
||||
Notification::Emit({
|
||||
.itemIcon = GetTextureForItemId(item00->itemEntry.itemId),
|
||||
.message = "You found ",
|
||||
.message = message,
|
||||
.suffix = SohUtils::GetItemName(item00->itemEntry.itemId),
|
||||
});
|
||||
} else if (item00->itemEntry.modIndex == MOD_RANDOMIZER) {
|
||||
std::string message;
|
||||
std::string itemName;
|
||||
|
||||
switch (gSaveContext.language) {
|
||||
case LANGUAGE_FRA:
|
||||
message = "Vous obtenez: ";
|
||||
itemName = Rando::StaticData::RetrieveItem((RandomizerGet)item00->itemEntry.getItemId)
|
||||
.GetName()
|
||||
.french;
|
||||
break;
|
||||
case LANGUAGE_GER:
|
||||
message = "Du erhältst: ";
|
||||
itemName = Rando::StaticData::RetrieveItem((RandomizerGet)item00->itemEntry.getItemId)
|
||||
.GetName()
|
||||
.german;
|
||||
break;
|
||||
case LANGUAGE_ENG:
|
||||
default:
|
||||
message = "You found ";
|
||||
itemName = Rando::StaticData::RetrieveItem((RandomizerGet)item00->itemEntry.getItemId)
|
||||
.GetName()
|
||||
.english;
|
||||
break;
|
||||
}
|
||||
|
||||
Notification::Emit({
|
||||
.message = "You found ",
|
||||
.suffix = Rando::StaticData::RetrieveItem((RandomizerGet)item00->itemEntry.getItemId)
|
||||
.GetName()
|
||||
.english,
|
||||
.message = message,
|
||||
.suffix = itemName,
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -21,7 +21,8 @@ Item::Item(const RandomizerGet randomizerGet_, Text name_, const ItemType type_,
|
||||
const int16_t chestAnimation_, const GetItemCategory category_, const uint16_t modIndex_,
|
||||
const bool progressive_, const uint16_t price_)
|
||||
: randomizerGet(randomizerGet_), name(std::move(name_)), type(type_), getItemId(getItemId_),
|
||||
advancement(advancement_), logicVal(logicVal_), hintKey(hintKey_), progressive(progressive_), price(price_) {
|
||||
advancement(advancement_), logicVal(logicVal_), hintKey(hintKey_), category(category_), progressive(progressive_),
|
||||
price(price_) {
|
||||
if (modIndex_ == MOD_RANDOMIZER || getItemId > 0x7D) {
|
||||
giEntry = std::make_shared<GetItemEntry>(GetItemEntry{
|
||||
itemId_, field_, static_cast<int16_t>((chestAnimation_ != CHEST_ANIM_SHORT ? 1 : -1) * (gid_ + 1)), textId_,
|
||||
@@ -36,24 +37,31 @@ Item::Item(const RandomizerGet randomizerGet_, Text name_, const ItemType type_,
|
||||
}
|
||||
|
||||
Item::Item(const RandomizerGet randomizerGet_, Text name_, const ItemType type_, const int16_t getItemId_,
|
||||
const bool advancement_, LogicVal logicVal_, const RandomizerHintTextKey hintKey_, const bool progressive_,
|
||||
const uint16_t price_)
|
||||
const bool advancement_, LogicVal logicVal_, const RandomizerHintTextKey hintKey_,
|
||||
const GetItemCategory category_, const bool progressive_, const uint16_t price_)
|
||||
: randomizerGet(randomizerGet_), name(std::move(name_)), type(type_), getItemId(getItemId_),
|
||||
advancement(advancement_), logicVal(logicVal_), hintKey(hintKey_), progressive(progressive_), price(price_) {
|
||||
advancement(advancement_), logicVal(logicVal_), hintKey(hintKey_), category(category_), progressive(progressive_),
|
||||
price(price_) {
|
||||
}
|
||||
|
||||
Item::~Item() = default;
|
||||
|
||||
void Item::ApplyEffect() const {
|
||||
auto ctx = Rando::Context::GetInstance();
|
||||
ctx->GetLogic()->ApplyItemEffect(StaticData::RetrieveItem(randomizerGet), true);
|
||||
ctx->GetLogic()->SetInLogic(logicVal, true);
|
||||
auto logic = ctx->GetLogic();
|
||||
if (!logic->CalculatingAvailableChecks) {
|
||||
logic->ApplyItemEffect(StaticData::RetrieveItem(randomizerGet), true);
|
||||
}
|
||||
logic->SetInLogic(logicVal, true);
|
||||
}
|
||||
|
||||
void Item::UndoEffect() const {
|
||||
auto ctx = Rando::Context::GetInstance();
|
||||
ctx->GetLogic()->ApplyItemEffect(StaticData::RetrieveItem(randomizerGet), false);
|
||||
ctx->GetLogic()->SetInLogic(logicVal, false);
|
||||
auto logic = ctx->GetLogic();
|
||||
if (!logic->CalculatingAvailableChecks) {
|
||||
logic->ApplyItemEffect(StaticData::RetrieveItem(randomizerGet), false);
|
||||
}
|
||||
logic->SetInLogic(logicVal, false);
|
||||
}
|
||||
|
||||
const Text& Item::GetName() const {
|
||||
@@ -450,6 +458,10 @@ const HintText& Item::GetHint() const {
|
||||
return StaticData::hintTextTable[hintKey];
|
||||
}
|
||||
|
||||
GetItemCategory Item::GetCategory() {
|
||||
return category;
|
||||
}
|
||||
|
||||
bool Item::operator==(const Item& right) const {
|
||||
return type == right.GetItemType() && getItemId == right.GetItemID();
|
||||
}
|
||||
|
||||
@@ -35,7 +35,8 @@ class Item {
|
||||
uint16_t textId_, uint16_t field_, int16_t chestAnimation_, GetItemCategory category_, uint16_t modIndex_,
|
||||
bool progressive_ = false, uint16_t price_ = 0);
|
||||
Item(RandomizerGet randomizerGet_, Text name_, ItemType type_, int16_t getItemId_, bool advancement_,
|
||||
LogicVal logicVal_, RandomizerHintTextKey hintKey_, bool progressive_ = false, uint16_t price_ = 0);
|
||||
LogicVal logicVal_, RandomizerHintTextKey hintKey_, GetItemCategory category_, bool progressive_ = false,
|
||||
uint16_t price_ = 0);
|
||||
~Item();
|
||||
|
||||
void ApplyEffect() const;
|
||||
@@ -58,6 +59,7 @@ class Item {
|
||||
bool IsMajorItem() const;
|
||||
RandomizerHintTextKey GetHintKey() const;
|
||||
const HintText& GetHint() const;
|
||||
GetItemCategory GetCategory();
|
||||
bool operator==(const Item& right) const;
|
||||
bool operator!=(const Item& right) const;
|
||||
|
||||
@@ -69,6 +71,7 @@ class Item {
|
||||
bool advancement;
|
||||
LogicVal logicVal;
|
||||
RandomizerHintTextKey hintKey;
|
||||
GetItemCategory category;
|
||||
bool progressive;
|
||||
uint16_t price;
|
||||
bool playthrough = false;
|
||||
|
||||
@@ -59,19 +59,19 @@ void Rando::StaticData::InitItemTable() {
|
||||
// Skulltula Token
|
||||
itemTable[RG_GOLD_SKULLTULA_TOKEN] = Item(RG_GOLD_SKULLTULA_TOKEN, Text{ "Gold Skulltula Token", "Symbole de Skulltula d'Or", "Goldenes Skulltula-Symbol" }, ITEMTYPE_TOKEN, GI_SKULL_TOKEN, true, LOGIC_GOLD_SKULLTULA_TOKENS, RHT_GOLD_SKULLTULA_TOKEN, ITEM_SKULL_TOKEN, OBJECT_GI_SUTARU, GID_SKULL_TOKEN, 0xB4, 0x80, CHEST_ANIM_SHORT, ITEM_CATEGORY_SKULLTULA_TOKEN, MOD_NONE);
|
||||
// Progressive Items
|
||||
itemTable[RG_PROGRESSIVE_HOOKSHOT] = Item(RG_PROGRESSIVE_HOOKSHOT, Text{ "Progressive Hookshot", "Grappin (prog.)", "Progressiver Fanghaken" }, ITEMTYPE_ITEM, 0x80, true, LOGIC_PROGRESSIVE_HOOKSHOT, RHT_PROGRESSIVE_HOOKSHOT, true);
|
||||
itemTable[RG_PROGRESSIVE_STRENGTH] = Item(RG_PROGRESSIVE_STRENGTH, Text{ "Strength Upgrade", "Amélioration de Force (prog.)", "Progressives Kraft-Upgrade" }, ITEMTYPE_ITEM, 0x81, true, LOGIC_PROGRESSIVE_STRENGTH, RHT_PROGRESSIVE_STRENGTH, true);
|
||||
itemTable[RG_PROGRESSIVE_BOMB_BAG] = Item(RG_PROGRESSIVE_BOMB_BAG, Text{ "Progressive Bomb Bag", "Sac de Bombes (prog.)", "Progressive Bombentasche" }, ITEMTYPE_ITEM, 0x82, true, LOGIC_PROGRESSIVE_BOMB_BAG, RHT_PROGRESSIVE_BOMB_BAG, true);
|
||||
itemTable[RG_PROGRESSIVE_BOW] = Item(RG_PROGRESSIVE_BOW, Text{ "Progressive Bow", "Arc (prog.)", "Progressiver Bogen" }, ITEMTYPE_ITEM, 0x83, true, LOGIC_PROGRESSIVE_BOW, RHT_PROGRESSIVE_BOW, true);
|
||||
itemTable[RG_PROGRESSIVE_SLINGSHOT] = Item(RG_PROGRESSIVE_SLINGSHOT, Text{ "Progressive Slingshot", "Lance-Pierre (prog.)", "Progressive Steinschleuder" }, ITEMTYPE_ITEM, 0x84, true, LOGIC_PROGRESSIVE_BULLET_BAG, RHT_PROGRESSIVE_SLINGSHOT, true);
|
||||
itemTable[RG_PROGRESSIVE_WALLET] = Item(RG_PROGRESSIVE_WALLET, Text{ "Progressive Wallet", "Bourse (prog.)", "Progressive Geldbörse" }, ITEMTYPE_ITEM, 0x85, true, LOGIC_PROGRESSIVE_WALLET, RHT_PROGRESSIVE_WALLET, true);
|
||||
itemTable[RG_PROGRESSIVE_SCALE] = Item(RG_PROGRESSIVE_SCALE, Text{ "Progressive Scale", "Écaille (prog.)", "Progressive Schuppe" }, ITEMTYPE_ITEM, 0x86, true, LOGIC_PROGRESSIVE_SCALE, RHT_PROGRESSIVE_SCALE, true);
|
||||
itemTable[RG_PROGRESSIVE_NUT_UPGRADE] = Item(RG_PROGRESSIVE_NUT_UPGRADE, Text{ "Progressive Nut Capacity", "Capacité de Noix (prog.)", "Progressive Nuß-Kapazität" }, ITEMTYPE_ITEM, 0x87, true, LOGIC_PROGRESSIVE_NUT_BAG, RHT_PROGRESSIVE_NUT_UPGRADE, true);
|
||||
itemTable[RG_PROGRESSIVE_STICK_UPGRADE] = Item(RG_PROGRESSIVE_STICK_UPGRADE, Text{ "Progressive Stick Capacity", "Capacité de Bâtons (prog.)", "Progressive Stab-Kapazität" }, ITEMTYPE_ITEM, 0x88, true, LOGIC_PROGRESSIVE_STICK_BAG, RHT_PROGRESSIVE_STICK_UPGRADE, true);
|
||||
itemTable[RG_PROGRESSIVE_BOMBCHUS] = Item(RG_PROGRESSIVE_BOMBCHUS, Text{ "Progressive Bombchu", "Missiles (prog.)", "Progressive Krabbelminen" }, ITEMTYPE_ITEM, 0x89, true, LOGIC_BOMBCHUS, RHT_PROGRESSIVE_BOMBCHUS, true);
|
||||
itemTable[RG_PROGRESSIVE_MAGIC_METER] = Item(RG_PROGRESSIVE_MAGIC_METER, Text{ "Progressive Magic Meter", "Jauge de Magie (prog.)", "Progressives Magisches Maß" }, ITEMTYPE_ITEM, 0x8A, true, LOGIC_PROGRESSIVE_MAGIC, RHT_PROGRESSIVE_MAGIC_METER, true);
|
||||
itemTable[RG_PROGRESSIVE_OCARINA] = Item(RG_PROGRESSIVE_OCARINA, Text{ "Progressive Ocarina", "Ocarina (prog.)", "Progressive Okarina" }, ITEMTYPE_ITEM, 0x8B, true, LOGIC_PROGRESSIVE_OCARINA, RHT_PROGRESSIVE_OCARINA, true);
|
||||
itemTable[RG_PROGRESSIVE_GORONSWORD] = Item(RG_PROGRESSIVE_GORONSWORD, Text{ "Progressive Goron Sword", "Épée Goron (prog.)", "Progressives Goronen-Schwert" }, ITEMTYPE_ITEM, 0xD4, true, LOGIC_PROGRESSIVE_GIANT_KNIFE, RHT_PROGRESSIVE_GORONSWORD, true);
|
||||
itemTable[RG_PROGRESSIVE_HOOKSHOT] = Item(RG_PROGRESSIVE_HOOKSHOT, Text{ "Progressive Hookshot", "Grappin (prog.)", "Progressiver Fanghaken" }, ITEMTYPE_ITEM, 0x80, true, LOGIC_PROGRESSIVE_HOOKSHOT, RHT_PROGRESSIVE_HOOKSHOT, ITEM_CATEGORY_MAJOR, true);
|
||||
itemTable[RG_PROGRESSIVE_STRENGTH] = Item(RG_PROGRESSIVE_STRENGTH, Text{ "Strength Upgrade", "Amélioration de Force (prog.)", "Progressives Kraft-Upgrade" }, ITEMTYPE_ITEM, 0x81, true, LOGIC_PROGRESSIVE_STRENGTH, RHT_PROGRESSIVE_STRENGTH, ITEM_CATEGORY_MAJOR, true);
|
||||
itemTable[RG_PROGRESSIVE_BOMB_BAG] = Item(RG_PROGRESSIVE_BOMB_BAG, Text{ "Progressive Bomb Bag", "Sac de Bombes (prog.)", "Progressive Bombentasche" }, ITEMTYPE_ITEM, 0x82, true, LOGIC_PROGRESSIVE_BOMB_BAG, RHT_PROGRESSIVE_BOMB_BAG, ITEM_CATEGORY_MAJOR, true);
|
||||
itemTable[RG_PROGRESSIVE_BOW] = Item(RG_PROGRESSIVE_BOW, Text{ "Progressive Bow", "Arc (prog.)", "Progressiver Bogen" }, ITEMTYPE_ITEM, 0x83, true, LOGIC_PROGRESSIVE_BOW, RHT_PROGRESSIVE_BOW, ITEM_CATEGORY_MAJOR, true);
|
||||
itemTable[RG_PROGRESSIVE_SLINGSHOT] = Item(RG_PROGRESSIVE_SLINGSHOT, Text{ "Progressive Slingshot", "Lance-Pierre (prog.)", "Progressive Steinschleuder" }, ITEMTYPE_ITEM, 0x84, true, LOGIC_PROGRESSIVE_BULLET_BAG, RHT_PROGRESSIVE_SLINGSHOT, ITEM_CATEGORY_MAJOR, true);
|
||||
itemTable[RG_PROGRESSIVE_WALLET] = Item(RG_PROGRESSIVE_WALLET, Text{ "Progressive Wallet", "Bourse (prog.)", "Progressive Geldbörse" }, ITEMTYPE_ITEM, 0x85, true, LOGIC_PROGRESSIVE_WALLET, RHT_PROGRESSIVE_WALLET, ITEM_CATEGORY_MAJOR, true);
|
||||
itemTable[RG_PROGRESSIVE_SCALE] = Item(RG_PROGRESSIVE_SCALE, Text{ "Progressive Scale", "Écaille (prog.)", "Progressive Schuppe" }, ITEMTYPE_ITEM, 0x86, true, LOGIC_PROGRESSIVE_SCALE, RHT_PROGRESSIVE_SCALE, ITEM_CATEGORY_MAJOR, true);
|
||||
itemTable[RG_PROGRESSIVE_NUT_UPGRADE] = Item(RG_PROGRESSIVE_NUT_UPGRADE, Text{ "Progressive Nut Capacity", "Capacité de Noix (prog.)", "Progressive Nuß-Kapazität" }, ITEMTYPE_ITEM, 0x87, true, LOGIC_PROGRESSIVE_NUT_BAG, RHT_PROGRESSIVE_NUT_UPGRADE, ITEM_CATEGORY_MAJOR, true);
|
||||
itemTable[RG_PROGRESSIVE_STICK_UPGRADE] = Item(RG_PROGRESSIVE_STICK_UPGRADE, Text{ "Progressive Stick Capacity", "Capacité de Bâtons (prog.)", "Progressive Stab-Kapazität" }, ITEMTYPE_ITEM, 0x88, true, LOGIC_PROGRESSIVE_STICK_BAG, RHT_PROGRESSIVE_STICK_UPGRADE, ITEM_CATEGORY_MAJOR, true);
|
||||
itemTable[RG_PROGRESSIVE_BOMBCHUS] = Item(RG_PROGRESSIVE_BOMBCHUS, Text{ "Progressive Bombchu", "Missiles (prog.)", "Progressive Krabbelminen" }, ITEMTYPE_ITEM, 0x89, true, LOGIC_BOMBCHUS, RHT_PROGRESSIVE_BOMBCHUS, ITEM_CATEGORY_MAJOR, true);
|
||||
itemTable[RG_PROGRESSIVE_MAGIC_METER] = Item(RG_PROGRESSIVE_MAGIC_METER, Text{ "Progressive Magic Meter", "Jauge de Magie (prog.)", "Progressives Magisches Maß" }, ITEMTYPE_ITEM, 0x8A, true, LOGIC_PROGRESSIVE_MAGIC, RHT_PROGRESSIVE_MAGIC_METER, ITEM_CATEGORY_MAJOR, true);
|
||||
itemTable[RG_PROGRESSIVE_OCARINA] = Item(RG_PROGRESSIVE_OCARINA, Text{ "Progressive Ocarina", "Ocarina (prog.)", "Progressive Okarina" }, ITEMTYPE_ITEM, 0x8B, true, LOGIC_PROGRESSIVE_OCARINA, RHT_PROGRESSIVE_OCARINA, ITEM_CATEGORY_MAJOR, true);
|
||||
itemTable[RG_PROGRESSIVE_GORONSWORD] = Item(RG_PROGRESSIVE_GORONSWORD, Text{ "Progressive Goron Sword", "Épée Goron (prog.)", "Progressives Goronen-Schwert" }, ITEMTYPE_ITEM, 0xD4, true, LOGIC_PROGRESSIVE_GIANT_KNIFE, RHT_PROGRESSIVE_GORONSWORD, ITEM_CATEGORY_MAJOR, true);
|
||||
// Bottles
|
||||
itemTable[RG_EMPTY_BOTTLE] = Item(RG_EMPTY_BOTTLE, Text{ "Empty Bottle", "Bouteille Vide", "Leere Flasche" }, ITEMTYPE_ITEM, GI_BOTTLE, true, LOGIC_BOTTLES, RHT_BOTTLE_WITH_MILK, ITEM_BOTTLE, OBJECT_GI_BOTTLE, GID_BOTTLE, 0x42, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_NONE);
|
||||
itemTable[RG_BOTTLE_WITH_MILK] = Item(RG_BOTTLE_WITH_MILK, Text{ "Bottle with Milk", "Bouteille avec du Lait", "Flasche mit Milch" }, ITEMTYPE_ITEM, GI_MILK_BOTTLE, true, LOGIC_BOTTLES, RHT_BOTTLE_WITH_MILK, ITEM_MILK_BOTTLE, OBJECT_GI_MILK, GID_MILK, 0x98, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_NONE);
|
||||
@@ -305,7 +305,7 @@ void Rando::StaticData::InitItemTable() {
|
||||
itemTable[RG_BUY_BOMBCHUS_10] = Item(RG_BUY_BOMBCHUS_10, Text{ "Buy Bombchu (10)", "Acheter: Missiles (10)", "Krabbelminen kaufen (10)" }, ITEMTYPE_SHOP, GI_BOMBCHUS_10, true, LOGIC_BUY_BOMBCHUS, RHT_BOMBCHUS_10, ITEM_BOMBCHU, OBJECT_GI_BOMB_2, GID_BOMBCHU, 0x33, 0x80, CHEST_ANIM_SHORT, ITEM_CATEGORY_JUNK, MOD_NONE, false, 99);
|
||||
itemTable[RG_BUY_BOMBCHUS_20] = Item(RG_BUY_BOMBCHUS_20, Text{ "Buy Bombchu (20)", "Acheter: Missiles (20)", "Krabbelminen kaufen (20)" }, ITEMTYPE_SHOP, GI_BOMBCHUS_20, true, LOGIC_BUY_BOMBCHUS, RHT_BOMBCHUS_20, ITEM_BOMBCHUS_20, OBJECT_GI_BOMB_2, GID_BOMBCHU, 0x33, 0x80, CHEST_ANIM_SHORT, ITEM_CATEGORY_JUNK, MOD_NONE, false, 180);
|
||||
itemTable[RG_BUY_DEKU_SEEDS_30] = Item(RG_BUY_DEKU_SEEDS_30, Text{ "Buy Deku Seeds (30)", "Acheter: Graines Mojo (30)", "Deku-Samen kaufen (30)" }, ITEMTYPE_SHOP, GI_SEEDS_30, true, LOGIC_BUY_SEED, RHT_DEKU_SEEDS_30, ITEM_SEEDS_30, OBJECT_GI_SEED, GID_SEEDS, 0xDC, 0x50, CHEST_ANIM_SHORT, ITEM_CATEGORY_JUNK, MOD_NONE, false, 30);
|
||||
itemTable[RG_SOLD_OUT] = Item(RG_SOLD_OUT, Text{ "Sold Out", "Rupture de stock", "Ausverkauft" }, ITEMTYPE_SHOP, RG_SOLD_OUT, false, LOGIC_NONE, RHT_NONE, false, 0);
|
||||
itemTable[RG_SOLD_OUT] = Item(RG_SOLD_OUT, Text{ "Sold Out", "Rupture de stock", "Ausverkauft" }, ITEMTYPE_SHOP, RG_SOLD_OUT, false, LOGIC_NONE, RHT_NONE, ITEM_CATEGORY_JUNK, false, 0);
|
||||
itemTable[RG_BUY_BLUE_FIRE] = Item(RG_BUY_BLUE_FIRE, Text{ "Buy Blue Fire", "Acheter: Flamme Bleue", "Blaues Feuer kaufen" }, ITEMTYPE_SHOP, GI_BLUE_FIRE, true, LOGIC_BLUE_FIRE_ACCESS, RHT_BOTTLE_WITH_BLUE_FIRE, ITEM_BLUE_FIRE, OBJECT_GI_FIRE, GID_BLUE_FIRE, 0x5D, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_JUNK, MOD_NONE, false, 300);
|
||||
itemTable[RG_BUY_BOTTLE_BUG] = Item(RG_BUY_BOTTLE_BUG, Text{ "Buy Bottle Bug", "Acheter: Insecte en bouteille", "Flaschenkäfer kaufen" }, ITEMTYPE_SHOP, GI_BUGS, true, LOGIC_BUGS_ACCESS, RHT_BOTTLE_WITH_BUGS, ITEM_BUG, OBJECT_GI_INSECT, GID_BUG, 0x7A, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_JUNK, MOD_NONE, false, 50);
|
||||
itemTable[RG_BUY_POE] = Item(RG_BUY_POE, Text{ "Buy Poe", "Acheter: Esprit", "Geist kaufen" }, ITEMTYPE_SHOP, RG_BUY_POE, false, LOGIC_NONE, RHT_BOTTLE_WITH_BIG_POE, ITEM_POE, OBJECT_GI_GHOST, GID_POE, 0x97, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_JUNK, MOD_NONE, false, 30);
|
||||
@@ -372,8 +372,8 @@ void Rando::StaticData::InitItemTable() {
|
||||
|
||||
itemTable[RG_DEKU_NUT_BAG] = Item(RG_DEKU_NUT_BAG, Text{ "Deku Nut Bag", "Sac de Noix Mojo", "Deku-Nuß-Tasche" }, ITEMTYPE_ITEM, GI_NUT_UPGRADE_30, true, LOGIC_PROGRESSIVE_NUT_BAG, RHT_NONE, RG_DEKU_NUT_BAG, OBJECT_GI_NUTS, GID_NUTS, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_RANDOMIZER);
|
||||
|
||||
itemTable[RG_TRIFORCE] = Item(RG_TRIFORCE, Text{ "Triforce", "Triforce", "Triforce" }, ITEMTYPE_EVENT, RG_TRIFORCE, false, LOGIC_NONE, RHT_NONE);
|
||||
itemTable[RG_HINT] = Item(RG_HINT, Text{ "Hint", "Indice", "Hinweis" }, ITEMTYPE_EVENT, RG_HINT, false, LOGIC_NONE, RHT_NONE);
|
||||
itemTable[RG_TRIFORCE] = Item(RG_TRIFORCE, Text{ "Triforce", "Triforce", "Triforce" }, ITEMTYPE_EVENT, RG_TRIFORCE, false, LOGIC_NONE, RHT_NONE, ITEM_CATEGORY_MAJOR);
|
||||
itemTable[RG_HINT] = Item(RG_HINT, Text{ "Hint", "Indice", "Hinweis" }, ITEMTYPE_EVENT, RG_HINT, false, LOGIC_NONE, RHT_NONE, ITEM_CATEGORY_LESSER);
|
||||
// Individual stages of progressive items (only here for GetItemEntry purposes, not for use in seed gen)
|
||||
itemTable[RG_HOOKSHOT] = Item(RG_HOOKSHOT, Text{ "Hookshot", "Grappin", "Fanghaken" }, ITEMTYPE_ITEM, GI_HOOKSHOT, true, LOGIC_PROGRESSIVE_HOOKSHOT, RHT_HOOKSHOT, ITEM_HOOKSHOT, OBJECT_GI_HOOKSHOT, GID_HOOKSHOT, 0x36, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_NONE);
|
||||
itemTable[RG_LONGSHOT] = Item(RG_LONGSHOT, Text{ "Longshot", "Super-Grappin", "Enterhaken" }, ITEMTYPE_ITEM, GI_LONGSHOT, true, LOGIC_PROGRESSIVE_HOOKSHOT, RHT_LONGSHOT, ITEM_LONGSHOT, OBJECT_GI_HOOKSHOT, GID_LONGSHOT, 0x4F, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_NONE);
|
||||
|
||||
@@ -54,8 +54,9 @@ const std::string& Rando::Location::GetShortName() const {
|
||||
|
||||
bool Rando::Location::IsDungeon() const {
|
||||
return (checkType != RCTYPE_SKULL_TOKEN &&
|
||||
(scene <= SCENE_GERUDO_TRAINING_GROUND || scene == SCENE_INSIDE_GANONS_CASTLE ||
|
||||
(scene >= SCENE_DEKU_TREE_BOSS && scene <= SCENE_GANONDORF_BOSS))) ||
|
||||
(scene <= SCENE_GERUDO_TRAINING_GROUND || scene == SCENE_INSIDE_GANONS_CASTLE ||
|
||||
(scene >= SCENE_DEKU_TREE_BOSS && scene <= SCENE_GANONDORF_BOSS)) ||
|
||||
(rc == RC_SPIRIT_TEMPLE_SILVER_GAUNTLETS_CHEST || rc == RC_SPIRIT_TEMPLE_MIRROR_SHIELD_CHEST)) ||
|
||||
(checkType == RCTYPE_SKULL_TOKEN && scene <= SCENE_ICE_CAVERN);
|
||||
}
|
||||
|
||||
|
||||
@@ -10,9 +10,10 @@
|
||||
#include "soh/Enhancements/debugger/performanceTimer.h"
|
||||
|
||||
#include <fstream>
|
||||
#include <soh/OTRGlobals.h>
|
||||
|
||||
#include "3drando/shops.hpp"
|
||||
extern "C" {
|
||||
extern SaveContext gSaveContext;
|
||||
extern PlayState* gPlayState;
|
||||
}
|
||||
|
||||
@@ -45,17 +46,71 @@ bool LocationAccess::ConditionsMet(Region* parentRegion, bool calculatingAvailab
|
||||
conditionsMet = true;
|
||||
}
|
||||
|
||||
return conditionsMet &&
|
||||
(calculatingAvailableChecks || CanBuy()); // TODO: run CanBuy when price is known due to settings
|
||||
return conditionsMet && CanBuy(calculatingAvailableChecks);
|
||||
}
|
||||
|
||||
bool LocationAccess::CanBuy() const {
|
||||
return CanBuyAnother(location);
|
||||
static uint16_t GetMinimumPrice(const Rando::Location* loc) {
|
||||
extern PriceSettingsStruct shopsanityPrices;
|
||||
extern PriceSettingsStruct scrubPrices;
|
||||
extern PriceSettingsStruct merchantPrices;
|
||||
PriceSettingsStruct priceSettings = loc->GetRCType() == RCTYPE_SHOP ? shopsanityPrices
|
||||
: loc->GetRCType() == RCTYPE_SCRUB ? scrubPrices
|
||||
: merchantPrices;
|
||||
|
||||
auto ctx = Rando::Context::GetInstance();
|
||||
switch (ctx->GetOption(priceSettings.main).Get()) {
|
||||
case RO_PRICE_VANILLA:
|
||||
return loc->GetVanillaPrice();
|
||||
case RO_PRICE_CHEAP_BALANCED:
|
||||
return 0;
|
||||
case RO_PRICE_BALANCED:
|
||||
return 0;
|
||||
case RO_PRICE_FIXED:
|
||||
return ctx->GetOption(priceSettings.fixedPrice).Get() * 5;
|
||||
case RO_PRICE_RANGE: {
|
||||
uint16_t range1 = ctx->GetOption(priceSettings.range1).Get() * 5;
|
||||
uint16_t range2 = ctx->GetOption(priceSettings.range1).Get() * 5;
|
||||
return range1 < range2 ? range1 : range2;
|
||||
}
|
||||
case RO_PRICE_SET_BY_WALLET: {
|
||||
if (ctx->GetOption(priceSettings.noWallet).Get()) {
|
||||
return 0;
|
||||
} else if (ctx->GetOption(priceSettings.childWallet).Get()) {
|
||||
return 1;
|
||||
} else if (ctx->GetOption(priceSettings.adultWallet).Get()) {
|
||||
return 100;
|
||||
} else if (ctx->GetOption(priceSettings.giantWallet).Get()) {
|
||||
return 201;
|
||||
} else {
|
||||
return 501;
|
||||
}
|
||||
}
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
bool LocationAccess::CanBuy(bool calculatingAvailableChecks) const {
|
||||
const auto& loc = Rando::StaticData::GetLocation(location);
|
||||
const auto& itemLoc = OTRGlobals::Instance->gRandoContext->GetItemLocation(location);
|
||||
|
||||
if (loc->GetRCType() == RCTYPE_SHOP || loc->GetRCType() == RCTYPE_SCRUB || loc->GetRCType() == RCTYPE_MERCHANT) {
|
||||
// Checks should only be identified while playing
|
||||
if (calculatingAvailableChecks && itemLoc->GetCheckStatus() != RCSHOW_IDENTIFIED) {
|
||||
return CanBuyAnother(GetMinimumPrice(loc));
|
||||
} else {
|
||||
return CanBuyAnother(itemLoc->GetPrice());
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CanBuyAnother(RandomizerCheck rc) {
|
||||
uint16_t price = ctx->GetItemLocation(rc)->GetPrice();
|
||||
return CanBuyAnother(ctx->GetItemLocation(rc)->GetPrice());
|
||||
}
|
||||
|
||||
bool CanBuyAnother(uint16_t price) {
|
||||
if (price > 500) {
|
||||
return logic->HasItem(RG_TYCOON_WALLET);
|
||||
} else if (price > 200) {
|
||||
@@ -275,7 +330,7 @@ bool BeanPlanted(const RandomizerRegion region) {
|
||||
if (gPlayState != nullptr && gPlayState->sceneNum == sceneID) {
|
||||
swch = gPlayState->actorCtx.flags.swch;
|
||||
} else if (sceneID != SCENE_ID_MAX) {
|
||||
swch = gSaveContext.sceneFlags[sceneID].swch;
|
||||
swch = Rando::Context::GetInstance()->GetLogic()->GetSaveContext()->sceneFlags[sceneID].swch;
|
||||
} else {
|
||||
swch = 0;
|
||||
}
|
||||
@@ -327,11 +382,14 @@ void RegionTable_Init() {
|
||||
//The big poes bottle softlock safety check does not account for the guard house lock if the guard house is not shuffled, so the key is needed before we can safely allow bottle use in logic
|
||||
//RANDOTODO a setting that lets you drink/dump big poes so we don't need this logic
|
||||
EventAccess(&logic->CouldEmptyBigPoes, []{return !ctx->GetOption(RSK_SHUFFLE_INTERIOR_ENTRANCES).Is(RO_INTERIOR_ENTRANCE_SHUFFLE_OFF) || logic->CanOpenOverworldDoor(RG_GUARD_HOUSE_KEY);}),
|
||||
EventAccess(&logic->FreedEpona, []{return (bool)ctx->GetOption(RSK_SKIP_EPONA_RACE);}),
|
||||
}, {
|
||||
//Locations
|
||||
LOCATION(RC_LINKS_POCKET, true),
|
||||
LOCATION(RC_TRIFORCE_COMPLETED, logic->GetSaveContext()->ship.quest.data.randomizer.triforcePiecesCollected >= ctx->GetOption(RSK_TRIFORCE_HUNT_PIECES_REQUIRED).Get() + 1;),
|
||||
LOCATION(RC_SARIA_SONG_HINT, logic->CanUse(RG_SARIAS_SONG)),
|
||||
LOCATION(RC_SONG_FROM_IMPA, (bool)ctx->GetOption(RSK_SKIP_CHILD_ZELDA)),
|
||||
LOCATION(RC_TOT_MASTER_SWORD, (bool)ctx->GetOption(RSK_SELECTED_STARTING_AGE).Is(RO_AGE_ADULT)),
|
||||
}, {
|
||||
//Exits
|
||||
Entrance(RR_ROOT_EXITS, []{return true;}),
|
||||
|
||||
@@ -100,9 +100,10 @@ class LocationAccess {
|
||||
std::string condition_str;
|
||||
|
||||
// Makes sure shop locations are buyable
|
||||
bool CanBuy() const;
|
||||
bool CanBuy(bool calculatingAvailableChecks) const;
|
||||
};
|
||||
|
||||
bool CanBuyAnother(uint16_t price);
|
||||
bool CanBuyAnother(RandomizerCheck rc);
|
||||
|
||||
namespace Rando {
|
||||
@@ -136,7 +137,6 @@ class Region {
|
||||
bool adultDay = false;
|
||||
bool adultNight = false;
|
||||
bool addedToPool = false;
|
||||
;
|
||||
|
||||
void ApplyTimePass();
|
||||
|
||||
|
||||
@@ -25,7 +25,6 @@ void RegionTable_Init_BottomOfTheWell() {
|
||||
}, {
|
||||
//Locations
|
||||
LOCATION(RC_BOTTOM_OF_THE_WELL_FRONT_CENTER_BOMBABLE_CHEST, logic->HasExplosives()),
|
||||
LOCATION(RC_BOTTOM_OF_THE_WELL_FREESTANDING_KEY, (logic->HasItem(RG_BRONZE_SCALE) || logic->LoweredWaterInsideBotw) && logic->CanUse(RG_STICKS) || logic->CanUse(RG_DINS_FIRE)),
|
||||
LOCATION(RC_BOTTOM_OF_THE_WELL_UNDERWATER_FRONT_CHEST, logic->LoweredWaterInsideBotw),
|
||||
LOCATION(RC_BOTTOM_OF_THE_WELL_UNDERWATER_LEFT_CHEST, logic->LoweredWaterInsideBotw),
|
||||
LOCATION(RC_BOTTOM_OF_THE_WELL_NEAR_ENTRANCE_POT_1, logic->CanBreakPots()),
|
||||
|
||||
@@ -436,11 +436,16 @@ void RegionTable_Init_DekuTree() {
|
||||
#pragma endregion
|
||||
|
||||
// Boss Room
|
||||
// RANDOTODO make it so entrance randomiser can properly handle more than 1 access to that entrance
|
||||
areaTable[RR_DEKU_TREE_BOSS_ENTRYWAY] = Region("Deku Tree Boss Entryway", "Deku Tree", {RA_DEKU_TREE}, NO_DAY_NIGHT_CYCLE, {}, {}, {
|
||||
// Exits
|
||||
Entrance(RR_DEKU_TREE_BOSS_ROOM, []{return true;}),
|
||||
});
|
||||
|
||||
areaTable[RR_DEKU_TREE_BOSS_EXIT] = Region("Deku Tree Boss Exit", "Deku Tree", {RA_DEKU_TREE}, NO_DAY_NIGHT_CYCLE, {}, {}, {
|
||||
// Exits
|
||||
Entrance(RR_DEKU_TREE_OUTSIDE_BOSS_ROOM, []{return ctx->GetDungeon(DEKU_TREE)->IsVanilla();}),
|
||||
Entrance(RR_DEKU_TREE_MQ_OUTSIDE_BOSS_ROOM, []{return ctx->GetDungeon(DEKU_TREE)->IsMQ();}),
|
||||
Entrance(RR_DEKU_TREE_BOSS_ROOM, []{return true;}),
|
||||
});
|
||||
|
||||
areaTable[RR_DEKU_TREE_BOSS_ROOM] = Region("Deku Tree Boss Room", "Deku Tree", {}, NO_DAY_NIGHT_CYCLE, {
|
||||
@@ -460,8 +465,8 @@ void RegionTable_Init_DekuTree() {
|
||||
LOCATION(RC_DEKU_TREE_QUEEN_GOHMA_GRASS_8, logic->CanCutShrubs()),
|
||||
}, {
|
||||
// Exits
|
||||
Entrance(RR_DEKU_TREE_BOSS_ENTRYWAY, []{return true;}),
|
||||
Entrance(RR_KF_OUTSIDE_DEKU_TREE, []{return logic->DekuTreeClear;}, false),
|
||||
Entrance(RR_DEKU_TREE_BOSS_EXIT, []{return true;}),
|
||||
Entrance(RR_KF_OUTSIDE_DEKU_TREE, []{return logic->DekuTreeClear;}, false),
|
||||
});
|
||||
|
||||
// clang-format on
|
||||
|
||||
@@ -268,6 +268,7 @@ void RegionTable_Init_DodongosCavern() {
|
||||
LOCATION(RC_DODONGOS_CAVERN_MQ_DEKU_SCRUB_LOBBY_FRONT, logic->CanStunDeku()),
|
||||
}, {
|
||||
//Exits
|
||||
Entrance(RR_DODONGOS_CAVERN_MQ_BEGINNING, []{return true;}),
|
||||
Entrance(RR_DODONGOS_CAVERN_MQ_GOSSIP_STONE, []{return Here(RR_DODONGOS_CAVERN_MQ_LOBBY, []{return logic->CanBreakMudWalls() || logic->HasItem(RG_GORONS_BRACELET);});}),
|
||||
Entrance(RR_DODONGOS_CAVERN_MQ_MOUTH_SIDE_BRIDGE, []{return Here(RR_DODONGOS_CAVERN_MQ_LOBBY, []{return logic->BlastOrSmash() || logic->HasItem(RG_GORONS_BRACELET);});}),
|
||||
Entrance(RR_DODONGOS_CAVERN_MQ_STAIRS_LOWER, []{return Here(RR_DODONGOS_CAVERN_MQ_LOBBY, []{return logic->BlastOrSmash() || logic->HasItem(RG_GORONS_BRACELET);});}),
|
||||
@@ -386,7 +387,7 @@ void RegionTable_Init_DodongosCavern() {
|
||||
Entrance(RR_DODONGOS_CAVERN_MQ_UPPER_LIZALFOS, []{return logic->CanUse(RG_STICKS) && logic->HasItem(RG_GORONS_BRACELET);}), //Implies access to RR_DODONGOS_CAVERN_MQ_BIG_BLOCK_ROOM from here
|
||||
});
|
||||
|
||||
areaTable[RR_DODONGOS_CAVERN_MQ_BIG_BLOCK_ROOM] = Region("Dodongos Cavern MQ Torch Puzzle Lower", "Dodongos Cavern", {RA_DODONGOS_CAVERN}, NO_DAY_NIGHT_CYCLE, {}, {
|
||||
areaTable[RR_DODONGOS_CAVERN_MQ_BIG_BLOCK_ROOM] = Region("Dodongos Cavern MQ Big Block Room", "Dodongos Cavern", {RA_DODONGOS_CAVERN}, NO_DAY_NIGHT_CYCLE, {}, {
|
||||
//Locations
|
||||
LOCATION(RC_DODONGOS_CAVERN_MQ_BIG_BLOCK_POT_1, logic->CanBreakPots()),
|
||||
LOCATION(RC_DODONGOS_CAVERN_MQ_BIG_BLOCK_POT_2, logic->CanBreakPots()),
|
||||
@@ -426,7 +427,7 @@ void RegionTable_Init_DodongosCavern() {
|
||||
Entrance(RR_DODONGOS_CAVERN_MQ_TWO_FIRES_ROOM, []{return Here(RR_DODONGOS_CAVERN_MQ_UPPER_LIZALFOS, []{return logic->CanKillEnemy(RE_LIZALFOS);});}),
|
||||
});
|
||||
|
||||
areaTable[RR_DODONGOS_CAVERN_MQ_TWO_FIRES_ROOM] = Region("Dodongos Cavern MQ Before Upper Lizalfos", "Dodongos Cavern", {RA_DODONGOS_CAVERN}, NO_DAY_NIGHT_CYCLE, {}, {
|
||||
areaTable[RR_DODONGOS_CAVERN_MQ_TWO_FIRES_ROOM] = Region("Dodongos Cavern MQ Two Fires Room", "Dodongos Cavern", {RA_DODONGOS_CAVERN}, NO_DAY_NIGHT_CYCLE, {}, {
|
||||
//Locations
|
||||
LOCATION(RC_DODONGOS_CAVERN_MQ_TWO_FLAMES_POT_1, logic->CanBreakPots()),
|
||||
LOCATION(RC_DODONGOS_CAVERN_MQ_TWO_FLAMES_POT_2, logic->CanBreakPots()),
|
||||
@@ -558,11 +559,16 @@ void RegionTable_Init_DodongosCavern() {
|
||||
#pragma endregion
|
||||
|
||||
// Boss Room
|
||||
// RANDOTODO make it so entrance randomiser can properly handle more than 1 access to that entrance
|
||||
areaTable[RR_DODONGOS_CAVERN_BOSS_ENTRYWAY] = Region("Dodongos Cavern Boss Entryway", "Dodongos Cavern", {RA_DODONGOS_CAVERN}, NO_DAY_NIGHT_CYCLE, {}, {}, {
|
||||
// Exits
|
||||
Entrance(RR_DODONGOS_CAVERN_BOSS_ROOM, []{return true;}),
|
||||
});
|
||||
|
||||
areaTable[RR_DODONGOS_CAVERN_BOSS_EXIT] = Region("Dodongos Cavern Boss Exit", "Dodongos Cavern", {RA_DODONGOS_CAVERN}, NO_DAY_NIGHT_CYCLE, {}, {}, {
|
||||
// Exits
|
||||
Entrance(RR_DODONGOS_CAVERN_BOSS_AREA, []{return ctx->GetDungeon(DODONGOS_CAVERN)->IsVanilla();}),
|
||||
Entrance(RR_DODONGOS_CAVERN_MQ_BEHIND_MOUTH, []{return ctx->GetDungeon(DODONGOS_CAVERN)->IsMQ();}),
|
||||
Entrance(RR_DODONGOS_CAVERN_BOSS_ROOM, []{return true;}),
|
||||
});
|
||||
|
||||
areaTable[RR_DODONGOS_CAVERN_BOSS_ROOM] = Region("Dodongos Cavern Boss Room", "Dodongos Cavern", {}, NO_DAY_NIGHT_CYCLE, {
|
||||
@@ -575,8 +581,8 @@ void RegionTable_Init_DodongosCavern() {
|
||||
LOCATION(RC_KING_DODONGO, logic->DodongosCavernClear),
|
||||
}, {
|
||||
// Exits
|
||||
Entrance(RR_DODONGOS_CAVERN_BOSS_ENTRYWAY, []{return true;}),
|
||||
Entrance(RR_DEATH_MOUNTAIN_TRAIL, []{return logic->DodongosCavernClear;}, false),
|
||||
Entrance(RR_DODONGOS_CAVERN_BOSS_EXIT, []{return true;}),
|
||||
Entrance(RR_DEATH_MOUNTAIN_TRAIL, []{return logic->DodongosCavernClear;}, false),
|
||||
});
|
||||
|
||||
// clang-format on
|
||||
|
||||
@@ -20,7 +20,7 @@ void RegionTable_Init_FireTemple() {
|
||||
//Exits
|
||||
Entrance(RR_FIRE_TEMPLE_ENTRYWAY, []{return true;}),
|
||||
Entrance(RR_FIRE_TEMPLE_NEAR_BOSS_ROOM, []{return logic->FireTimer() >= 24;}),
|
||||
Entrance(RR_FIRE_TEMPLE_LOOP_ENEMIES, []{return Here(RR_FIRE_TEMPLE_FIRST_ROOM, []{return logic->CanUse(RG_MEGATON_HAMMER);}) && (logic->SmallKeys(RR_FIRE_TEMPLE, 8) || !logic->IsKeysanity);}),
|
||||
Entrance(RR_FIRE_TEMPLE_LOOP_ENEMIES, []{return Here(RR_FIRE_TEMPLE_FIRST_ROOM, []{return logic->CanUse(RG_MEGATON_HAMMER);}) && (logic->SmallKeys(RR_FIRE_TEMPLE, 8) || !logic->IsFireLoopLocked);}),
|
||||
Entrance(RR_FIRE_TEMPLE_LOOP_EXIT, []{return true;}),
|
||||
Entrance(RR_FIRE_TEMPLE_BIG_LAVA_ROOM, []{return logic->SmallKeys(RR_FIRE_TEMPLE, 2) && logic->FireTimer() >= 24;}),
|
||||
});
|
||||
@@ -38,12 +38,12 @@ void RegionTable_Init_FireTemple() {
|
||||
}, {
|
||||
//Exits
|
||||
Entrance(RR_FIRE_TEMPLE_FIRST_ROOM, []{return true;}),
|
||||
Entrance(RR_FIRE_TEMPLE_BOSS_ENTRYWAY, []{return logic->HasItem(RG_FIRE_TEMPLE_BOSS_KEY) && ((logic->IsAdult && (ctx->GetTrickOption(RT_FIRE_BOSS_DOOR_JUMP) || Here(RR_FIRE_TEMPLE_FIRE_MAZE_UPPER, []{return logic->CanUse(RG_MEGATON_HAMMER);}))) || logic->CanUse(RG_HOVER_BOOTS));}),
|
||||
Entrance(RR_FIRE_TEMPLE_BOSS_ENTRYWAY, []{return logic->IsAdult && (ctx->GetTrickOption(RT_FIRE_BOSS_DOOR_JUMP) || Here(RR_FIRE_TEMPLE_FIRE_MAZE_UPPER, []{return logic->CanUse(RG_MEGATON_HAMMER);}) || logic->CanUse(RG_HOVER_BOOTS));}),
|
||||
});
|
||||
|
||||
areaTable[RR_FIRE_TEMPLE_LOOP_ENEMIES] = Region("Fire Temple Loop Enemies", "Fire Temple", {RA_FIRE_TEMPLE}, NO_DAY_NIGHT_CYCLE, {}, {}, {
|
||||
//Exits
|
||||
Entrance(RR_FIRE_TEMPLE_FIRST_ROOM, []{return logic->SmallKeys(RR_FIRE_TEMPLE, 8) || !logic->IsKeysanity;}),
|
||||
Entrance(RR_FIRE_TEMPLE_FIRST_ROOM, []{return logic->SmallKeys(RR_FIRE_TEMPLE, 8) || !logic->IsFireLoopLocked;}),
|
||||
Entrance(RR_FIRE_TEMPLE_LOOP_TILES, []{return Here(RR_FIRE_TEMPLE_LOOP_ENEMIES, []{return logic->CanKillEnemy(RE_TORCH_SLUG) && logic->CanKillEnemy(RE_FIRE_KEESE);});}),
|
||||
});
|
||||
|
||||
@@ -445,7 +445,7 @@ void RegionTable_Init_FireTemple() {
|
||||
Entrance(RR_FIRE_TEMPLE_MQ_FIRST_ROOM_UPPER, []{return true;}),
|
||||
//Child cannot make it to the north side torches without a hook without specifically bunny hood speed + hover boots
|
||||
Entrance(RR_FIRE_TEMPLE_MQ_NEAR_BOSS_ROOM_NORTH, []{return logic->FireTimer() > 32 && (logic->CanUse(RG_HOOKSHOT) || (logic->IsAdult && logic->CanUse(RG_HOVER_BOOTS)));}),
|
||||
Entrance(RR_FIRE_TEMPLE_BOSS_ENTRYWAY, []{return logic->HasItem(RG_FIRE_TEMPLE_BOSS_KEY) && logic->FireTimer() >= 15 && ((logic->IsAdult && (ctx->GetTrickOption(RT_FIRE_BOSS_DOOR_JUMP) || logic->CanUse(RG_HOVER_BOOTS))) || (logic->IsAdult && logic->HitFireTemplePlatform) || (logic->HitFireTemplePlatform && logic->CanUse(RG_HOVER_BOOTS)));}),
|
||||
Entrance(RR_FIRE_TEMPLE_BOSS_ENTRYWAY, []{return logic->FireTimer() >= 15 && ((logic->IsAdult && (ctx->GetTrickOption(RT_FIRE_BOSS_DOOR_JUMP) || logic->CanUse(RG_HOVER_BOOTS))) || (logic->IsAdult && logic->HitFireTemplePlatform) || (logic->HitFireTemplePlatform && logic->CanUse(RG_HOVER_BOOTS)));}),
|
||||
});
|
||||
|
||||
//This room assumes tunic logic is handled on entry.
|
||||
@@ -701,7 +701,7 @@ void RegionTable_Init_FireTemple() {
|
||||
Entrance(RR_FIRE_TEMPLE_MQ_UPPER_FLARE_DANCER, []{return true;}),
|
||||
});
|
||||
|
||||
areaTable[RR_FIRE_TEMPLE_MQ_UPPER_FLARE_DANCER] = Region("Fire Temple MQ North Fire Maze", "Fire Temple", {RA_FIRE_TEMPLE}, NO_DAY_NIGHT_CYCLE, {}, {
|
||||
areaTable[RR_FIRE_TEMPLE_MQ_UPPER_FLARE_DANCER] = Region("Fire Temple MQ Upper Flare Dancer", "Fire Temple", {RA_FIRE_TEMPLE}, NO_DAY_NIGHT_CYCLE, {}, {
|
||||
//Locations
|
||||
LOCATION(RC_FIRE_TEMPLE_MQ_FREESTANDING_KEY, logic->CanKillEnemy(RE_FLARE_DANCER)),
|
||||
}, {
|
||||
@@ -740,7 +740,7 @@ void RegionTable_Init_FireTemple() {
|
||||
// Exits
|
||||
Entrance(RR_FIRE_TEMPLE_NEAR_BOSS_ROOM, []{return ctx->GetDungeon(FIRE_TEMPLE)->IsVanilla() && false;}),
|
||||
Entrance(RR_FIRE_TEMPLE_MQ_NEAR_BOSS_ROOM, []{return ctx->GetDungeon(FIRE_TEMPLE)->IsMQ() && false;}),
|
||||
Entrance(RR_FIRE_TEMPLE_BOSS_ROOM, []{return true;}),
|
||||
Entrance(RR_FIRE_TEMPLE_BOSS_ROOM, []{return logic->HasItem(RG_FIRE_TEMPLE_BOSS_KEY);}),
|
||||
});
|
||||
|
||||
areaTable[RR_FIRE_TEMPLE_BOSS_ROOM] = Region("Fire Temple Boss Room", "Fire Temple", {}, NO_DAY_NIGHT_CYCLE, {
|
||||
|
||||
@@ -298,7 +298,7 @@ void RegionTable_Init_ForestTemple() {
|
||||
}, {
|
||||
//Exits
|
||||
Entrance(RR_FOREST_TEMPLE_LOBBY, []{return true;}),
|
||||
Entrance(RR_FOREST_TEMPLE_BOSS_ENTRYWAY, []{return logic->HasItem(RG_FOREST_TEMPLE_BOSS_KEY);}),
|
||||
Entrance(RR_FOREST_TEMPLE_BOSS_ENTRYWAY, []{return true;}),
|
||||
});
|
||||
|
||||
#pragma endregion
|
||||
@@ -481,7 +481,7 @@ void RegionTable_Init_ForestTemple() {
|
||||
Entrance(RR_FOREST_TEMPLE_MQ_FALLING_ROOM, []{return logic->CanUse(RG_SONG_OF_TIME);}),
|
||||
});
|
||||
|
||||
areaTable[RR_FOREST_TEMPLE_MQ_JOELLE_ROOM] = Region("Forest Temple MQ Joelle room", "Forest Temple", {RA_FOREST_TEMPLE}, NO_DAY_NIGHT_CYCLE, {
|
||||
areaTable[RR_FOREST_TEMPLE_MQ_JOELLE_ROOM] = Region("Forest Temple MQ Joelle Room", "Forest Temple", {RA_FOREST_TEMPLE}, NO_DAY_NIGHT_CYCLE, {
|
||||
//Events
|
||||
EventAccess(&logic->ForestTempleJoelle, []{return logic->CanUse(RG_FAIRY_BOW);}),
|
||||
}, {
|
||||
@@ -593,7 +593,7 @@ void RegionTable_Init_ForestTemple() {
|
||||
areaTable[RR_FOREST_TEMPLE_MQ_BOSS_REGION] = Region("Forest Temple MQ Boss Region", "Forest Temple", {RA_FOREST_TEMPLE}, NO_DAY_NIGHT_CYCLE, {}, {}, {
|
||||
//Exits
|
||||
Entrance(RR_FOREST_TEMPLE_MQ_BASEMENT, []{return logic->ForestOpenBossCorridor;}),
|
||||
Entrance(RR_FOREST_TEMPLE_BOSS_ENTRYWAY, []{return logic->HasItem(RG_FOREST_TEMPLE_BOSS_KEY);}),
|
||||
Entrance(RR_FOREST_TEMPLE_BOSS_ENTRYWAY, []{return true;}),
|
||||
});
|
||||
|
||||
#pragma endregion
|
||||
@@ -603,7 +603,7 @@ void RegionTable_Init_ForestTemple() {
|
||||
// Exits
|
||||
Entrance(RR_FOREST_TEMPLE_BOSS_REGION, []{return ctx->GetDungeon(FOREST_TEMPLE)->IsVanilla() && false;}),
|
||||
Entrance(RR_FOREST_TEMPLE_MQ_BOSS_REGION, []{return ctx->GetDungeon(FOREST_TEMPLE)->IsMQ() && false;}),
|
||||
Entrance(RR_FOREST_TEMPLE_BOSS_ROOM, []{return true;}),
|
||||
Entrance(RR_FOREST_TEMPLE_BOSS_ROOM, []{return logic->HasItem(RG_FOREST_TEMPLE_BOSS_KEY);}),
|
||||
});
|
||||
|
||||
areaTable[RR_FOREST_TEMPLE_BOSS_ROOM] = Region("Forest Temple Boss Room", "Forest Temple", {}, NO_DAY_NIGHT_CYCLE, {
|
||||
|
||||
@@ -29,12 +29,7 @@ void RegionTable_Init_GanonsCastle() {
|
||||
Entrance(RR_GANONS_CASTLE_SHADOW_TRIAL, []{return true;}),
|
||||
Entrance(RR_GANONS_CASTLE_SPIRIT_TRIAL, []{return true;}),
|
||||
Entrance(RR_GANONS_CASTLE_LIGHT_TRIAL, []{return logic->CanUse(RG_GOLDEN_GAUNTLETS);}),
|
||||
Entrance(RR_GANONS_TOWER_ENTRYWAY, []{return (logic->ForestTrialClear || ctx->GetTrial(TK_FOREST_TRIAL)->IsSkipped()) &&
|
||||
(logic->FireTrialClear || ctx->GetTrial(TK_FIRE_TRIAL)->IsSkipped()) &&
|
||||
(logic->WaterTrialClear || ctx->GetTrial(TK_WATER_TRIAL)->IsSkipped()) &&
|
||||
(logic->ShadowTrialClear || ctx->GetTrial(TK_SHADOW_TRIAL)->IsSkipped()) &&
|
||||
(logic->SpiritTrialClear || ctx->GetTrial(TK_SPIRIT_TRIAL)->IsSkipped()) &&
|
||||
(logic->LightTrialClear || ctx->GetTrial(TK_LIGHT_TRIAL)->IsSkipped());}),
|
||||
Entrance(RR_GANONS_TOWER_ENTRYWAY, []{return true;}),
|
||||
Entrance(RR_GANONS_CASTLE_DEKU_SCRUBS, []{return ctx->GetTrickOption(RT_LENS_GANON) || logic->CanUse(RG_LENS_OF_TRUTH);}),
|
||||
});
|
||||
|
||||
@@ -162,13 +157,7 @@ void RegionTable_Init_GanonsCastle() {
|
||||
Entrance(RR_GANONS_CASTLE_MQ_SHADOW_TRIAL_STARTING_LEDGE, []{return true;}),
|
||||
Entrance(RR_GANONS_CASTLE_MQ_SPIRIT_TRIAL_CHAIRS_ROOM, []{return true;}),
|
||||
Entrance(RR_GANONS_CASTLE_MQ_LIGHT_TRIAL_DINOLFOS_ROOM, []{return Here(RR_GANONS_CASTLE_MQ_MAIN, []{return logic->CanUse(RG_GOLDEN_GAUNTLETS);});}),
|
||||
//RANDOTODO could we just set these events automatically based on the setting?
|
||||
Entrance(RR_GANONS_TOWER_ENTRYWAY, []{return (logic->ForestTrialClear || ctx->GetTrial(TK_FOREST_TRIAL)->IsSkipped()) &&
|
||||
(logic->FireTrialClear || ctx->GetTrial(TK_FIRE_TRIAL)->IsSkipped()) &&
|
||||
(logic->WaterTrialClear || ctx->GetTrial(TK_WATER_TRIAL)->IsSkipped()) &&
|
||||
(logic->ShadowTrialClear || ctx->GetTrial(TK_SHADOW_TRIAL)->IsSkipped()) &&
|
||||
(logic->SpiritTrialClear || ctx->GetTrial(TK_SPIRIT_TRIAL)->IsSkipped()) &&
|
||||
(logic->LightTrialClear || ctx->GetTrial(TK_LIGHT_TRIAL)->IsSkipped());}),
|
||||
Entrance(RR_GANONS_TOWER_ENTRYWAY, []{return true;}),
|
||||
Entrance(RR_GANONS_CASTLE_MQ_DEKU_SCRUBS, []{return ctx->GetTrickOption(RT_LENS_GANON_MQ) || logic->CanUse(RG_LENS_OF_TRUTH);}),
|
||||
});
|
||||
|
||||
@@ -436,7 +425,13 @@ void RegionTable_Init_GanonsCastle() {
|
||||
//Exits
|
||||
Entrance(RR_GANONS_CASTLE_LOBBY, []{return ctx->GetDungeon(GANONS_CASTLE)->IsVanilla();}),
|
||||
Entrance(RR_GANONS_CASTLE_MQ_MAIN, []{return ctx->GetDungeon(GANONS_CASTLE)->IsMQ();}),
|
||||
Entrance(RR_GANONS_TOWER_FLOOR_1, []{return true;}),
|
||||
//RANDOTODO could we just set these events automatically based on the setting?
|
||||
Entrance(RR_GANONS_TOWER_FLOOR_1, []{return (logic->ForestTrialClear || ctx->GetTrial(TK_FOREST_TRIAL)->IsSkipped()) &&
|
||||
(logic->FireTrialClear || ctx->GetTrial(TK_FIRE_TRIAL)->IsSkipped()) &&
|
||||
(logic->WaterTrialClear || ctx->GetTrial(TK_WATER_TRIAL)->IsSkipped()) &&
|
||||
(logic->ShadowTrialClear || ctx->GetTrial(TK_SHADOW_TRIAL)->IsSkipped()) &&
|
||||
(logic->SpiritTrialClear || ctx->GetTrial(TK_SPIRIT_TRIAL)->IsSkipped()) &&
|
||||
(logic->LightTrialClear || ctx->GetTrial(TK_LIGHT_TRIAL)->IsSkipped());}),
|
||||
});
|
||||
|
||||
areaTable[RR_GANONS_TOWER_FLOOR_1] = Region("Ganon's Tower Floor 1", "Ganons Castle", {RA_GANONS_CASTLE}, NO_DAY_NIGHT_CYCLE, {}, {}, {
|
||||
|
||||
@@ -149,7 +149,7 @@ void RegionTable_Init_GerudoTrainingGround() {
|
||||
Entrance(RR_GERUDO_TRAINING_GROUND_MQ_MAZE_CENTER, []{return logic->SmallKeys(RR_GERUDO_TRAINING_GROUND, 3);}),
|
||||
});
|
||||
|
||||
areaTable[RR_GERUDO_TRAINING_GROUND_MQ_MAZE_CENTER] = Region("Gerudo Training Ground MQ Center", "Gerudo Training Ground", {RA_GERUDO_TRAINING_GROUND}, NO_DAY_NIGHT_CYCLE, {
|
||||
areaTable[RR_GERUDO_TRAINING_GROUND_MQ_MAZE_CENTER] = Region("Gerudo Training Ground MQ Maze Center", "Gerudo Training Ground", {RA_GERUDO_TRAINING_GROUND}, NO_DAY_NIGHT_CYCLE, {
|
||||
//Events
|
||||
EventAccess(&logic->MQGTGMazeSwitch, []{return logic->CanUse(RG_MEGATON_HAMMER);}),
|
||||
},
|
||||
|
||||
@@ -84,7 +84,7 @@ void RegionTable_Init_IceCavern() {
|
||||
//Exits
|
||||
//the switch for the glass blocking the entrance is linked to the switch that controls the glass around the skulltulla in RR_ICE_CAVERN_MQ_SCARECROW_ROOM
|
||||
//if you clear the ice, you can hit it with a pot from here.
|
||||
Entrance(RR_ICE_CAVERN_BEGINNING, []{return logic->BlueFire();}),
|
||||
Entrance(RR_ICE_CAVERN_MQ_BEGINNING, []{return logic->BlueFire();}),
|
||||
Entrance(RR_ICE_CAVERN_MQ_MAP_ROOM, []{return Here(RR_ICE_CAVERN_MQ_BEGINNING, []{return logic->CanKillEnemy(RE_WHITE_WOLFOS) && logic->CanKillEnemy(RE_FREEZARD);});}),
|
||||
Entrance(RR_ICE_CAVERN_MQ_COMPASS_ROOM, []{return logic->IsAdult && logic->BlueFire();}),
|
||||
Entrance(RR_ICE_CAVERN_MQ_SCARECROW_ROOM, []{return logic->BlueFire();}),
|
||||
|
||||
@@ -64,7 +64,7 @@ void RegionTable_Init_JabuJabusBelly() {
|
||||
//Exits
|
||||
Entrance(RR_JABU_JABUS_BELLY_MAIN, []{return true;}),
|
||||
//there's tricks for getting here with bunny-jumps or just side-hops
|
||||
Entrance(RR_JABU_JABUS_BELLY_WATER_SWITCH_ROOM_LEDGE, []{return logic->HasItem(RG_BRONZE_SCALE) || logic->HasItem(RG_HOVER_BOOTS);}),
|
||||
Entrance(RR_JABU_JABUS_BELLY_WATER_SWITCH_ROOM_LEDGE, []{return logic->HasItem(RG_BRONZE_SCALE) || logic->CanUse(RG_HOVER_BOOTS);}),
|
||||
Entrance(RR_JABU_JABUS_BELLY_WATER_SWITCH_ROOM_SOUTH, []{return logic->IsAdult || logic->HasItem(RG_BRONZE_SCALE);}),
|
||||
});
|
||||
|
||||
@@ -90,7 +90,7 @@ void RegionTable_Init_JabuJabusBelly() {
|
||||
}, {
|
||||
//Exits
|
||||
Entrance(RR_JABU_JABUS_BELLY_B1_NORTH, []{return logic->IsAdult || logic->HasItem(RG_BRONZE_SCALE);}),
|
||||
Entrance(RR_JABU_JABUS_BELLY_WATER_SWITCH_ROOM_LEDGE, []{return logic->HasItem(RG_BRONZE_SCALE) || logic->HasItem(RG_HOVER_BOOTS);}),
|
||||
Entrance(RR_JABU_JABUS_BELLY_WATER_SWITCH_ROOM_LEDGE, []{return logic->HasItem(RG_BRONZE_SCALE) || logic->CanUse(RG_HOVER_BOOTS);}),
|
||||
Entrance(RR_JABU_JABUS_BELLY_MAIN, []{return logic->CanUseProjectile();}),
|
||||
});
|
||||
|
||||
@@ -351,10 +351,14 @@ void RegionTable_Init_JabuJabusBelly() {
|
||||
|
||||
// Boss Room
|
||||
areaTable[RR_JABU_JABUS_BELLY_BOSS_ENTRYWAY] = Region("Jabu Jabus Belly Boss Entryway", "Jabu Jabus Belly", {RA_JABU_JABUS_BELLY}, NO_DAY_NIGHT_CYCLE, {}, {}, {
|
||||
// Exits
|
||||
Entrance(RR_JABU_JABUS_BELLY_BOSS_ROOM, []{return true;}),
|
||||
});
|
||||
|
||||
areaTable[RR_JABU_JABUS_BELLY_BOSS_EXIT] = Region("Jabu Jabus Belly Boss Exit", "Jabu Jabus Belly", {RA_JABU_JABUS_BELLY}, NO_DAY_NIGHT_CYCLE, {}, {}, {
|
||||
// Exits
|
||||
Entrance(RR_JABU_JABUS_BELLY_NEAR_BOSS_ROOM, []{return ctx->GetDungeon(JABU_JABUS_BELLY)->IsVanilla();}),
|
||||
Entrance(RR_JABU_JABUS_BELLY_MQ_EAST_ROOM, []{return ctx->GetDungeon(JABU_JABUS_BELLY)->IsMQ();}),
|
||||
Entrance(RR_JABU_JABUS_BELLY_BOSS_ROOM, []{return true;}),
|
||||
});
|
||||
|
||||
areaTable[RR_JABU_JABUS_BELLY_BOSS_ROOM] = Region("Jabu Jabus Belly Boss Room", "Jabu Jabus Belly", {}, NO_DAY_NIGHT_CYCLE, {
|
||||
@@ -372,8 +376,8 @@ void RegionTable_Init_JabuJabusBelly() {
|
||||
LOCATION(RC_BARINADE, logic->JabuJabusBellyClear),
|
||||
}, {
|
||||
// Exits
|
||||
Entrance(RR_JABU_JABUS_BELLY_BOSS_ENTRYWAY, []{return false;}),
|
||||
Entrance(RR_ZORAS_FOUNTAIN, []{return logic->JabuJabusBellyClear;}, false),
|
||||
Entrance(RR_JABU_JABUS_BELLY_BOSS_EXIT, []{return false;}),
|
||||
Entrance(RR_ZORAS_FOUNTAIN, []{return logic->JabuJabusBellyClear;}, false),
|
||||
});
|
||||
|
||||
// clang-format on
|
||||
|
||||
@@ -112,7 +112,7 @@ void RegionTable_Init_ShadowTemple() {
|
||||
LOCATION(RC_SHADOW_TEMPLE_AFTER_SHIP_LOWER_HEART, (logic->CanUse(RG_FAIRY_BOW) || logic->CanUse(RG_DISTANT_SCARECROW) || (ctx->GetTrickOption(RT_SHADOW_STATUE) && logic->CanUse(RG_BOMBCHU_5))) && logic->CanUse(RG_SONG_OF_TIME) || (logic->CanUse(RG_DISTANT_SCARECROW) && logic->CanUse(RG_HOVER_BOOTS))),
|
||||
}, {
|
||||
//Exits
|
||||
Entrance(RR_SHADOW_TEMPLE_BOSS_ENTRYWAY, []{return (logic->CanUse(RG_FAIRY_BOW) || logic->CanUse(RG_DISTANT_SCARECROW) || (ctx->GetTrickOption(RT_SHADOW_STATUE) && logic->CanUse(RG_BOMBCHU_5))) && logic->SmallKeys(RR_SHADOW_TEMPLE, 5) && logic->CanUse(RG_HOVER_BOOTS) && logic->HasItem(RG_SHADOW_TEMPLE_BOSS_KEY);})
|
||||
Entrance(RR_SHADOW_TEMPLE_BOSS_ENTRYWAY, []{return (logic->CanUse(RG_FAIRY_BOW) || logic->CanUse(RG_DISTANT_SCARECROW) || (ctx->GetTrickOption(RT_SHADOW_STATUE) && logic->CanUse(RG_BOMBCHU_5))) && logic->SmallKeys(RR_SHADOW_TEMPLE, 5) && logic->CanUse(RG_HOVER_BOOTS);})
|
||||
});
|
||||
|
||||
#pragma endregion
|
||||
@@ -370,7 +370,7 @@ void RegionTable_Init_ShadowTemple() {
|
||||
}, {
|
||||
//Exits
|
||||
Entrance(RR_SHADOW_TEMPLE_MQ_ACROSS_CHASM, []{return logic->CanUse(RG_HOVER_BOOTS) && (ctx->GetTrickOption(RT_LENS_SHADOW_MQ) || logic->CanUse(RG_LENS_OF_TRUTH));}),
|
||||
Entrance(RR_SHADOW_TEMPLE_BOSS_ENTRYWAY, []{return logic->HasItem(RG_SHADOW_TEMPLE_BOSS_KEY);}),
|
||||
Entrance(RR_SHADOW_TEMPLE_BOSS_ENTRYWAY, []{return true;}),
|
||||
});
|
||||
|
||||
//Assumes lens is checked on entry
|
||||
@@ -403,7 +403,7 @@ void RegionTable_Init_ShadowTemple() {
|
||||
// Exits
|
||||
Entrance(RR_SHADOW_TEMPLE_BEYOND_BOAT, []{return ctx->GetDungeon(SHADOW_TEMPLE)->IsVanilla() && false;}),
|
||||
Entrance(RR_SHADOW_TEMPLE_MQ_BEYOND_BOAT, []{return ctx->GetDungeon(SHADOW_TEMPLE)->IsMQ() && false;}),
|
||||
Entrance(RR_SHADOW_TEMPLE_BOSS_ROOM, []{return true;}),
|
||||
Entrance(RR_SHADOW_TEMPLE_BOSS_ROOM, []{return logic->HasItem(RG_SHADOW_TEMPLE_BOSS_KEY);}),
|
||||
});
|
||||
|
||||
areaTable[RR_SHADOW_TEMPLE_BOSS_ROOM] = Region("Shadow Temple Boss Room", "Shadow Temple", {}, NO_DAY_NIGHT_CYCLE, {
|
||||
|
||||
@@ -145,7 +145,7 @@ void RegionTable_Init_SpiritTemple() {
|
||||
areaTable[RR_SPIRIT_TEMPLE_INSIDE_STATUE_HEAD] = Region("Spirit Temple Inside Statue Head", "Spirit Temple", {RA_SPIRIT_TEMPLE}, NO_DAY_NIGHT_CYCLE, {}, {}, {
|
||||
// Exits
|
||||
Entrance(RR_SPIRIT_TEMPLE_CENTRAL_CHAMBER, []{return true;}),
|
||||
Entrance(RR_SPIRIT_TEMPLE_BOSS_ENTRYWAY, []{return logic->HasItem(RG_SPIRIT_TEMPLE_BOSS_KEY);}),
|
||||
Entrance(RR_SPIRIT_TEMPLE_BOSS_ENTRYWAY, []{return true;}),
|
||||
});
|
||||
|
||||
#pragma endregion
|
||||
@@ -194,13 +194,13 @@ void RegionTable_Init_SpiritTemple() {
|
||||
});
|
||||
|
||||
// Room to store the 2 pots in to handle glitch logic going backwards around the loop later
|
||||
areaTable[RR_SPIRIT_TEMPLE_MQ_1F_GIBDO_ROOM_NORTH] = Region("Spirit Temple MQ Gibdo Room North", "Spirit Temple", {RA_SPIRIT_TEMPLE}, NO_DAY_NIGHT_CYCLE, {}, {
|
||||
areaTable[RR_SPIRIT_TEMPLE_MQ_1F_GIBDO_ROOM_NORTH] = Region("Spirit Temple MQ 1F Gibdo Room North", "Spirit Temple", {RA_SPIRIT_TEMPLE}, NO_DAY_NIGHT_CYCLE, {}, {
|
||||
//Locations
|
||||
LOCATION(RC_SPIRIT_TEMPLE_MQ_CHILD_GIBDO_POT_1, logic->CanBreakPots()),
|
||||
LOCATION(RC_SPIRIT_TEMPLE_MQ_CHILD_GIBDO_POT_2, logic->CanBreakPots()),
|
||||
}, {});
|
||||
|
||||
areaTable[RR_SPIRIT_TEMPLE_MQ_TURNTABLE_ROOM] = Region("Spirit Temple Turntable Room", "Spirit Temple", {RA_SPIRIT_TEMPLE}, NO_DAY_NIGHT_CYCLE, {
|
||||
areaTable[RR_SPIRIT_TEMPLE_MQ_TURNTABLE_ROOM] = Region("Spirit Temple MQ Turntable Room", "Spirit Temple", {RA_SPIRIT_TEMPLE}, NO_DAY_NIGHT_CYCLE, {
|
||||
//Events
|
||||
//For non-fairy pot items, you can also get them with rang without killing the stalfos
|
||||
EventAccess(&logic->FairyPot, []{return Here(RR_SPIRIT_TEMPLE_MQ_TURNTABLE_ROOM, []{return logic->CanKillEnemy(RE_STALFOS);});}),
|
||||
@@ -315,7 +315,7 @@ void RegionTable_Init_SpiritTemple() {
|
||||
Entrance(RR_SPIRIT_TEMPLE_MQ_WEST_IRON_KNUCKLE, []{return logic->SmallKeys(RR_SPIRIT_TEMPLE, 7);}),
|
||||
});
|
||||
|
||||
areaTable[RR_SPIRIT_TEMPLE_MQ_WEST_IRON_KNUCKLE] = Region("Spirit Temple MQ East Iron Knuckle", "Spirit Temple", {RA_SPIRIT_TEMPLE}, NO_DAY_NIGHT_CYCLE, {}, {}, {
|
||||
areaTable[RR_SPIRIT_TEMPLE_MQ_WEST_IRON_KNUCKLE] = Region("Spirit Temple MQ West Iron Knuckle", "Spirit Temple", {RA_SPIRIT_TEMPLE}, NO_DAY_NIGHT_CYCLE, {}, {}, {
|
||||
//Exits
|
||||
Entrance(RR_SPIRIT_TEMPLE_MQ_SUN_BLOCK_ROOM, []{return logic->SmallKeys(RR_SPIRIT_TEMPLE, 7);}),
|
||||
Entrance(RR_SPIRIT_TEMPLE_MQ_SILVER_GAUNTLETS_HAND, []{return logic->CanKillEnemy(RE_IRON_KNUCKLE);}),
|
||||
@@ -541,7 +541,7 @@ void RegionTable_Init_SpiritTemple() {
|
||||
areaTable[RR_SPIRIT_TEMPLE_MQ_INSIDE_STATUE_HEAD] = Region("Spirit Temple MQ Inside Statue Head", "Spirit Temple", {RA_SPIRIT_TEMPLE}, NO_DAY_NIGHT_CYCLE, {}, {}, {
|
||||
// Exits
|
||||
Entrance(RR_SPIRIT_TEMPLE_MQ_LOBBY, []{return true;}),
|
||||
Entrance(RR_SPIRIT_TEMPLE_BOSS_ENTRYWAY, []{return logic->HasItem(RG_SPIRIT_TEMPLE_BOSS_KEY);}),
|
||||
Entrance(RR_SPIRIT_TEMPLE_BOSS_ENTRYWAY, []{return true;}),
|
||||
});
|
||||
|
||||
#pragma endregion
|
||||
@@ -551,7 +551,7 @@ void RegionTable_Init_SpiritTemple() {
|
||||
// Exits
|
||||
Entrance(RR_SPIRIT_TEMPLE_INSIDE_STATUE_HEAD, []{return ctx->GetDungeon(SPIRIT_TEMPLE)->IsVanilla() && false;}),
|
||||
Entrance(RR_SPIRIT_TEMPLE_MQ_INSIDE_STATUE_HEAD, []{return ctx->GetDungeon(SPIRIT_TEMPLE)->IsMQ() && false;}),
|
||||
Entrance(RR_SPIRIT_TEMPLE_BOSS_ROOM, []{return true;}),
|
||||
Entrance(RR_SPIRIT_TEMPLE_BOSS_ROOM, []{return logic->HasItem(RG_SPIRIT_TEMPLE_BOSS_KEY);}),
|
||||
});
|
||||
|
||||
areaTable[RR_SPIRIT_TEMPLE_BOSS_ROOM] = Region("Spirit Temple Boss Room", "Spirit Temple", {}, NO_DAY_NIGHT_CYCLE, {
|
||||
|
||||
@@ -277,7 +277,7 @@ void RegionTable_Init_WaterTemple() {
|
||||
}, {
|
||||
//Exits
|
||||
Entrance(RR_WATER_TEMPLE_LOBBY, []{return true;}),
|
||||
Entrance(RR_WATER_TEMPLE_BOSS_ENTRYWAY, []{return logic->HasItem(RG_WATER_TEMPLE_BOSS_KEY);}),
|
||||
Entrance(RR_WATER_TEMPLE_BOSS_ENTRYWAY, []{return true;}),
|
||||
});
|
||||
|
||||
#pragma endregion
|
||||
@@ -362,10 +362,10 @@ void RegionTable_Init_WaterTemple() {
|
||||
Entrance(RR_WATER_TEMPLE_MQ_BOSS_DOOR, []{return logic->CanUse(RG_LONGSHOT) || logic->CanUse(RG_ICE_ARROWS) || logic->CanUse(RG_NAYRUS_LOVE);}),
|
||||
});
|
||||
|
||||
areaTable[RR_WATER_TEMPLE_MQ_BOSS_DOOR] = Region("Water Temple MQ Main", "Water Temple", {RA_WATER_TEMPLE}, NO_DAY_NIGHT_CYCLE, {}, {}, {
|
||||
areaTable[RR_WATER_TEMPLE_MQ_BOSS_DOOR] = Region("Water Temple MQ Boss Door", "Water Temple", {RA_WATER_TEMPLE}, NO_DAY_NIGHT_CYCLE, {}, {}, {
|
||||
//Exits
|
||||
Entrance(RR_WATER_TEMPLE_MQ_3F_NORTH_LEDGE, []{return logic->CanUse(RG_ICE_ARROWS) || logic->TakeDamage();}),
|
||||
Entrance(RR_WATER_TEMPLE_BOSS_ENTRYWAY, []{return logic->HasItem(RG_WATER_TEMPLE_BOSS_KEY);}),
|
||||
Entrance(RR_WATER_TEMPLE_BOSS_ENTRYWAY, []{return true;}),
|
||||
});
|
||||
|
||||
areaTable[RR_WATER_TEMPLE_MQ_EAST_TOWER] = Region("Water Temple MQ East Tower", "Water Temple", {RA_WATER_TEMPLE}, NO_DAY_NIGHT_CYCLE, {
|
||||
@@ -507,7 +507,7 @@ void RegionTable_Init_WaterTemple() {
|
||||
Entrance(RR_WATER_TEMPLE_MQ_BEHIND_BLUE_SWITCH_3F, []{return logic->CanUse(RG_LONGSHOT);}),
|
||||
});
|
||||
|
||||
areaTable[RR_WATER_TEMPLE_MQ_BEHIND_BLUE_SWITCH_3F] = Region("Water Temple MQ Behind Blue Switch 2F", "Water Temple", {RA_WATER_TEMPLE}, NO_DAY_NIGHT_CYCLE, {}, {
|
||||
areaTable[RR_WATER_TEMPLE_MQ_BEHIND_BLUE_SWITCH_3F] = Region("Water Temple MQ Behind Blue Switch 3F", "Water Temple", {RA_WATER_TEMPLE}, NO_DAY_NIGHT_CYCLE, {}, {
|
||||
//Locations
|
||||
LOCATION(RC_WATER_TEMPLE_MQ_GS_BEFORE_UPPER_WATER_SWITCH, logic->CanGetEnemyDrop(RE_GOLD_SKULLTULA)),
|
||||
}, {
|
||||
@@ -552,7 +552,7 @@ void RegionTable_Init_WaterTemple() {
|
||||
}, {});
|
||||
|
||||
//This room exists to hold the wonderitems that drop from the emblems here. Specifically this assumes you are standing on the final ledge
|
||||
areaTable[RR_WATER_TEMPLE_MQ_WATERFALL] = Region("Water Temple Waterfall", "Water Temple", {RA_WATER_TEMPLE}, NO_DAY_NIGHT_CYCLE, {}, {}, {
|
||||
areaTable[RR_WATER_TEMPLE_MQ_WATERFALL] = Region("Water Temple MQ Waterfall", "Water Temple", {RA_WATER_TEMPLE}, NO_DAY_NIGHT_CYCLE, {}, {}, {
|
||||
//Exits
|
||||
Entrance(RR_WATER_TEMPLE_MQ_3F_CENTRAL, []{return logic->SmallKeys(RR_WATER_TEMPLE, 1) && logic->CanUse(RG_LONGSHOT);}),
|
||||
Entrance(RR_WATER_TEMPLE_MQ_STALFOS_PIT, []{return true;}),
|
||||
@@ -658,7 +658,7 @@ void RegionTable_Init_WaterTemple() {
|
||||
|
||||
areaTable[RR_WATER_TEMPLE_MQ_DRAGON_ROOM_ALCOVE] = Region("Water Temple MQ Dragon Room Alcove", "Water Temple", {RA_WATER_TEMPLE}, NO_DAY_NIGHT_CYCLE, {
|
||||
//Events
|
||||
EventAccess(&logic->MQWaterDragonTorches, []{return true;}),
|
||||
EventAccess(&logic->MQWaterDragonTorches, []{return logic->HasFireSource();}),
|
||||
},
|
||||
{
|
||||
//Locations
|
||||
@@ -843,7 +843,7 @@ void RegionTable_Init_WaterTemple() {
|
||||
// Exits
|
||||
Entrance(RR_WATER_TEMPLE_PRE_BOSS_ROOM, []{return ctx->GetDungeon(WATER_TEMPLE)->IsVanilla() && false;}),
|
||||
Entrance(RR_WATER_TEMPLE_MQ_BOSS_DOOR, []{return ctx->GetDungeon(WATER_TEMPLE)->IsMQ() && false;}),
|
||||
Entrance(RR_WATER_TEMPLE_BOSS_ROOM, []{return true;}),
|
||||
Entrance(RR_WATER_TEMPLE_BOSS_ROOM, []{return logic->HasItem(RG_WATER_TEMPLE_BOSS_KEY);}),
|
||||
});
|
||||
|
||||
areaTable[RR_WATER_TEMPLE_BOSS_ROOM] = Region("Water Temple Boss Room", "Water Temple", {}, NO_DAY_NIGHT_CYCLE, {
|
||||
|
||||
@@ -7,9 +7,10 @@ void RegionTable_Init_Graveyard() {
|
||||
// clang-format off
|
||||
areaTable[RR_THE_GRAVEYARD] = Region("The Graveyard", "The Graveyard", {RA_THE_GRAVEYARD}, NO_DAY_NIGHT_CYCLE, {
|
||||
//Events
|
||||
EventAccess(&logic->ButterflyFairy, []{return logic->ButterflyFairy || (logic->CanUse(RG_STICKS) && logic->AtDay);}),
|
||||
EventAccess(&logic->BeanPlantFairy, []{return logic->IsChild && logic->CanUse(RG_MAGIC_BEAN) && logic->CanUse(RG_SONG_OF_STORMS);}),
|
||||
EventAccess(&logic->BugRock, []{return true;}),
|
||||
EventAccess(&logic->ButterflyFairy, []{return logic->ButterflyFairy || (logic->CanUse(RG_STICKS) && logic->AtDay);}),
|
||||
EventAccess(&logic->BeanPlantFairy, []{return logic->IsChild && logic->CanUse(RG_MAGIC_BEAN) && logic->CanUse(RG_SONG_OF_STORMS);}),
|
||||
EventAccess(&logic->BugRock, []{return true;}),
|
||||
EventAccess(&logic->BorrowBunnyHood, []{return logic->IsChild && logic->AtDay && logic->BorrowSpookyMask && logic->HasItem(RG_CHILD_WALLET);}),
|
||||
}, {
|
||||
//Locations
|
||||
LOCATION(RC_GRAVEYARD_FREESTANDING_POH, (((logic->IsAdult && CanPlantBean(RR_THE_GRAVEYARD)) || logic->CanUse(RG_LONGSHOT)) && logic->CanBreakCrates()) || (ctx->GetTrickOption(RT_GY_POH) && logic->CanUse(RG_BOOMERANG))),
|
||||
|
||||
@@ -7,7 +7,8 @@ void RegionTable_Init_HyruleField() {
|
||||
// clang-format off
|
||||
areaTable[RR_HYRULE_FIELD] = Region("Hyrule Field", "Hyrule Field", {RA_HYRULE_FIELD}, DAY_NIGHT_CYCLE, {
|
||||
//Events
|
||||
EventAccess(&logic->BigPoeKill, []{return logic->CanUse(RG_FAIRY_BOW) && logic->CanUse(RG_EPONA) && logic->HasBottle();}),
|
||||
EventAccess(&logic->BigPoeKill, []{return logic->CanUse(RG_FAIRY_BOW) && logic->CanUse(RG_EPONA) && logic->HasBottle();}),
|
||||
EventAccess(&logic->BorrowRightMasks, []{return logic->IsChild && logic->BorrowBunnyHood && logic->HasItem(RG_KOKIRI_EMERALD) && logic->HasItem(RG_GORON_RUBY) && logic->HasItem(RG_ZORA_SAPPHIRE) && logic->HasItem(RG_CHILD_WALLET);}),
|
||||
}, {
|
||||
//Locations
|
||||
LOCATION(RC_HF_OCARINA_OF_TIME_ITEM, logic->IsChild && logic->StoneCount() == 3 && logic->HasItem(RG_BRONZE_SCALE)),
|
||||
|
||||
@@ -10,6 +10,8 @@ void RegionTable_Init_Kakariko() {
|
||||
EventAccess(&logic->BugRock, []{return true;}),
|
||||
//Open Gate setting is applied in RR_ROOT
|
||||
EventAccess(&logic->KakarikoVillageGateOpen, []{return logic->IsChild && logic->HasItem(RG_ZELDAS_LETTER);}),
|
||||
//Needs wallet to be able to get another mask after selling Keaton
|
||||
EventAccess(&logic->BorrowSkullMask, []{return logic->IsChild && logic->CanBorrowMasks && logic->HasItem(RG_CHILD_WALLET);}),
|
||||
}, {
|
||||
//Locations
|
||||
LOCATION(RC_SHEIK_IN_KAKARIKO, logic->IsAdult && logic->HasItem(RG_FOREST_MEDALLION) && logic->HasItem(RG_FIRE_MEDALLION) && logic->HasItem(RG_WATER_MEDALLION)),
|
||||
@@ -265,7 +267,7 @@ void RegionTable_Init_Kakariko() {
|
||||
Entrance(RR_DEATH_MOUNTAIN_TRAIL, []{return true;}),
|
||||
});
|
||||
|
||||
areaTable[RR_KAK_WELL] = Region("Kak Behind Gate", "Kakariko Village", {RA_KAKARIKO_VILLAGE}, NO_DAY_NIGHT_CYCLE, {}, {}, {
|
||||
areaTable[RR_KAK_WELL] = Region("Kak Well", "Kakariko Village", {RA_KAKARIKO_VILLAGE}, NO_DAY_NIGHT_CYCLE, {}, {}, {
|
||||
//Exits
|
||||
Entrance(RR_KAKARIKO_VILLAGE, []{return logic->IsAdult || logic->HasItem(RG_BRONZE_SCALE) || logic->DrainWell;}),
|
||||
Entrance(RR_BOTTOM_OF_THE_WELL_ENTRYWAY, []{return logic->IsChild || (logic->DrainWell && ctx->GetOption(RSK_SHUFFLE_DUNGEON_ENTRANCES).IsNot(RO_DUNGEON_ENTRANCE_SHUFFLE_OFF));}),
|
||||
|
||||
@@ -105,7 +105,7 @@ void RegionTable_Init_LakeHylia() {
|
||||
|
||||
areaTable[RR_LH_LAB] = Region("LH Lab", "LH Lab", {}, NO_DAY_NIGHT_CYCLE, {}, {
|
||||
//Locations
|
||||
LOCATION(RC_LH_LAB_DIVE, logic->HasItem(RG_GOLDEN_SCALE) || (ctx->GetTrickOption(RT_LH_LAB_DIVING) && logic->CanUse(RG_IRON_BOOTS) && logic->CanUse(RG_HOOKSHOT))),
|
||||
LOCATION(RC_LH_LAB_DIVE, logic->HasItem(RG_GOLDEN_SCALE) || (ctx->GetTrickOption(RT_LH_LAB_DIVING) && logic->CanUse(RG_IRON_BOOTS) && logic->CanUse(RG_HOOKSHOT) && logic->HasItem(RG_BRONZE_SCALE))),
|
||||
LOCATION(RC_LH_TRADE_FROG, logic->IsAdult && logic->CanUse(RG_EYEBALL_FROG)),
|
||||
LOCATION(RC_LH_GS_LAB_CRATE, logic->CanUse(RG_IRON_BOOTS) && logic->CanUse(RG_HOOKSHOT) && logic->CanBreakCrates()),
|
||||
LOCATION(RC_LH_LAB_FRONT_RUPEE, logic->CanUse(RG_IRON_BOOTS) || logic->HasItem(RG_GOLDEN_SCALE)),
|
||||
|
||||
@@ -7,8 +7,8 @@ void RegionTable_Init_LonLonRanch() {
|
||||
// clang-format off
|
||||
areaTable[RR_LON_LON_RANCH] = Region("Lon Lon Ranch", "Lon Lon Ranch", {RA_LON_LON_RANCH}, NO_DAY_NIGHT_CYCLE, {
|
||||
//Events
|
||||
EventAccess(&logic->FreedEpona, []{return logic->FreedEpona || ((logic->HasItem(RG_CHILD_WALLET) || ctx->GetOption(RSK_SKIP_EPONA_RACE)) && logic->CanUse(RG_EPONAS_SONG) && logic->IsAdult && logic->AtDay);}),
|
||||
EventAccess(&logic->LinksCow, []{return logic->LinksCow || (logic->HasItem(RG_CHILD_WALLET) && logic->CanUse(RG_EPONAS_SONG) && logic->IsAdult && logic->AtDay);}),
|
||||
EventAccess(&logic->FreedEpona, []{return logic->HasItem(RG_CHILD_WALLET) && logic->CanUse(RG_EPONAS_SONG) && logic->IsAdult && logic->AtDay;}),
|
||||
EventAccess(&logic->LinksCow, []{return logic->HasItem(RG_CHILD_WALLET) && logic->CanUse(RG_EPONA) && logic->IsAdult && logic->AtDay;}),
|
||||
}, {
|
||||
//Locations
|
||||
LOCATION(RC_SONG_FROM_MALON, logic->IsChild && logic->HasItem(RG_ZELDAS_LETTER) && logic->HasItem(RG_FAIRY_OCARINA) && logic->AtDay),
|
||||
|
||||
@@ -12,9 +12,10 @@ void RegionTable_Init_LostWoods() {
|
||||
|
||||
areaTable[RR_THE_LOST_WOODS] = Region("Lost Woods", "Lost Woods", {RA_THE_LOST_WOODS}, NO_DAY_NIGHT_CYCLE, {
|
||||
//Events
|
||||
EventAccess(&logic->GossipStoneFairy, []{return logic->CallGossipFairyExceptSuns();}),
|
||||
EventAccess(&logic->BeanPlantFairy, []{return logic->IsChild && logic->CanUse(RG_MAGIC_BEAN) && logic->CanUse(RG_SONG_OF_STORMS);}),
|
||||
EventAccess(&logic->BugShrub, []{return logic->IsChild && logic->CanCutShrubs();}),
|
||||
EventAccess(&logic->GossipStoneFairy, []{return logic->CallGossipFairyExceptSuns();}),
|
||||
EventAccess(&logic->BeanPlantFairy, []{return logic->IsChild && logic->CanUse(RG_MAGIC_BEAN) && logic->CanUse(RG_SONG_OF_STORMS);}),
|
||||
EventAccess(&logic->BugShrub, []{return logic->IsChild && logic->CanCutShrubs();}),
|
||||
EventAccess(&logic->BorrowSpookyMask, []{return logic->IsChild && logic->BorrowSkullMask && logic->CanUse(RG_SARIAS_SONG) && logic->HasItem(RG_CHILD_WALLET);}),
|
||||
}, {
|
||||
//Locations
|
||||
LOCATION(RC_LW_SKULL_KID, logic->IsChild && logic->CanUse(RG_SARIAS_SONG)),
|
||||
@@ -110,8 +111,8 @@ void RegionTable_Init_LostWoods() {
|
||||
|
||||
areaTable[RR_DEKU_THEATER] = Region("Deku Theater", "Deku Theater", {}, NO_DAY_NIGHT_CYCLE, {}, {
|
||||
//Locations
|
||||
LOCATION(RC_DEKU_THEATER_SKULL_MASK, logic->IsChild && logic->SkullMask),
|
||||
LOCATION(RC_DEKU_THEATER_MASK_OF_TRUTH, logic->IsChild && logic->MaskOfTruth),
|
||||
LOCATION(RC_DEKU_THEATER_SKULL_MASK, logic->IsChild && logic->BorrowSkullMask),
|
||||
LOCATION(RC_DEKU_THEATER_MASK_OF_TRUTH, logic->IsChild && logic->BorrowRightMasks),
|
||||
}, {
|
||||
//Exits
|
||||
Entrance(RR_LW_BEYOND_MIDO, []{return true;}),
|
||||
|
||||
@@ -138,8 +138,14 @@ void RegionTable_Init_Market() {
|
||||
|
||||
areaTable[RR_MARKET_MASK_SHOP] = Region("Market Mask Shop", "Market Mask Shop", {}, NO_DAY_NIGHT_CYCLE, {
|
||||
//Events
|
||||
EventAccess(&logic->SkullMask, []{return logic->SkullMask || (logic->HasItem(RG_ZELDAS_LETTER) && (ctx->GetOption(RSK_COMPLETE_MASK_QUEST) || ChildCanAccess(RR_KAKARIKO_VILLAGE)));}), //RANDOTODO Complete mask quest does not need this location, so should be tied to link's pocket
|
||||
EventAccess(&logic->MaskOfTruth, []{return logic->MaskOfTruth || (logic->SkullMask && (ctx->GetOption(RSK_COMPLETE_MASK_QUEST) || (ChildCanAccess(RR_THE_LOST_WOODS) && logic->CanUse(RG_SARIAS_SONG) && RegionTable(RR_THE_GRAVEYARD)->childDay && ChildCanAccess(RR_HYRULE_FIELD) && logic->StoneCount() == 3)));}),
|
||||
//Currently, mask swap in menu doesn't need access to the mask shop
|
||||
//If it is forced on/a setting, a copy of these events should be added to root
|
||||
//it also doesn't need you to open kak gate, but that might be best treated as a bug
|
||||
EventAccess(&logic->CanBorrowMasks, []{return logic->HasItem(RG_ZELDAS_LETTER) && logic->KakarikoVillageGateOpen;}),
|
||||
EventAccess(&logic->BorrowSkullMask, []{return ctx->GetOption(RSK_COMPLETE_MASK_QUEST) && logic->CanBorrowMasks;}),
|
||||
EventAccess(&logic->BorrowSpookyMask, []{return ctx->GetOption(RSK_COMPLETE_MASK_QUEST) && logic->CanBorrowMasks;}),
|
||||
EventAccess(&logic->BorrowBunnyHood, []{return ctx->GetOption(RSK_COMPLETE_MASK_QUEST) && logic->CanBorrowMasks;}),
|
||||
EventAccess(&logic->BorrowRightMasks, []{return ctx->GetOption(RSK_COMPLETE_MASK_QUEST) && logic->CanBorrowMasks;}),
|
||||
}, {
|
||||
//Locations
|
||||
LOCATION(RC_MASK_SHOP_HINT, true),
|
||||
|
||||
@@ -31,7 +31,7 @@ void RegionTable_Init_ZorasFountain() {
|
||||
//child can break the brown rock without lifting the silver rock and it stays gone for adult, but it's not intuitive and there's no reasonable case where it matters.
|
||||
Entrance(RR_ZF_HIDDEN_CAVE, []{return logic->CanUse(RG_SILVER_GAUNTLETS) && logic->BlastOrSmash();}),
|
||||
Entrance(RR_ZF_ROCK, []{return logic->IsAdult && logic->CanUse(RG_SCARECROW);}),
|
||||
Entrance(RR_JABU_JABUS_BELLY_ENTRYWAY, []{return (logic->IsChild && logic->CanUse(RG_BOTTLE_WITH_FISH));}),
|
||||
Entrance(RR_JABU_JABUS_BELLY_ENTRYWAY, []{return logic->IsChild && (ctx->GetOption(RSK_JABU_OPEN).Is(RO_JABU_OPEN) || logic->CanUse(RG_BOTTLE_WITH_FISH));}),
|
||||
Entrance(RR_ZF_GREAT_FAIRY_FOUNTAIN, []{return logic->HasExplosives() || (ctx->GetTrickOption(RT_ZF_GREAT_FAIRY_WITHOUT_EXPLOSIVES) && logic->CanUse(RG_MEGATON_HAMMER) && logic->CanUse(RG_SILVER_GAUNTLETS));}),
|
||||
});
|
||||
|
||||
@@ -41,7 +41,7 @@ void RegionTable_Init_ZorasFountain() {
|
||||
}, {
|
||||
//Exits
|
||||
//This hover is pretty tight, come at it with momentum and aim for the small corner polygon of the big iceburg while spamming roll
|
||||
Entrance(RR_ZORAS_FOUNTAIN, []{return logic->HasItem(RG_BRONZE_SCALE) || logic->HasItem(RG_HOVER_BOOTS);}),
|
||||
Entrance(RR_ZORAS_FOUNTAIN, []{return logic->HasItem(RG_BRONZE_SCALE) || logic->CanUse(RG_HOVER_BOOTS);}),
|
||||
Entrance(RR_ZF_LAKEBED, []{return logic->CanUse(RG_IRON_BOOTS);}),
|
||||
Entrance(RR_ZF_LEDGE, []{return true;}),
|
||||
});
|
||||
|
||||
@@ -1389,6 +1389,7 @@ bool Logic::SmallKeys(RandomizerRegion dungeon, uint8_t requiredAmountGlitchless
|
||||
static_cast<uint8_t>(GlitchDifficulty::INTERMEDIATE) || GetDifficultyValueFromString(GlitchHover) >=
|
||||
static_cast<uint8_t>(GlitchDifficulty::INTERMEDIATE))) { return FireTempleKeys >= requiredAmountGlitched;
|
||||
}*/
|
||||
// If the Fire Temple loop lock is removed, Small key Count is set to 1 before starting
|
||||
return GetSmallKeyCount(SCENE_FIRE_TEMPLE) >= requiredAmountGlitchless;
|
||||
|
||||
case RR_WATER_TEMPLE:
|
||||
@@ -2227,7 +2228,7 @@ const std::vector<uint8_t>& GetDungeonSmallKeyDoors(SceneID sceneId) {
|
||||
}
|
||||
} else if (transitionActor.id == ACTOR_DOOR_SHUTTER) {
|
||||
uint8_t doorType = (transitionActor.params >> 7) & 15;
|
||||
if (doorType == SHUTTER_BACK_LOCKED || doorType == SHUTTER_BOSS || doorType == SHUTTER_KEY_LOCKED) {
|
||||
if (doorType == SHUTTER_KEY_LOCKED) {
|
||||
dungeonSmallKeyDoors[key].emplace_back(transitionActor.params & 0x3F);
|
||||
}
|
||||
}
|
||||
@@ -2331,20 +2332,25 @@ void Logic::SetInLogic(LogicVal logicVal, bool value) {
|
||||
inLogic[logicVal] = value;
|
||||
}
|
||||
|
||||
void Logic::Reset() {
|
||||
NewSaveContext();
|
||||
void Logic::Reset(bool resetSaveContext /*= true*/) {
|
||||
if (resetSaveContext) {
|
||||
NewSaveContext();
|
||||
}
|
||||
StartPerformanceTimer(PT_LOGIC_RESET);
|
||||
memset(inLogic, false, sizeof(inLogic));
|
||||
// Settings-dependent variables
|
||||
IsKeysanity = ctx->GetOption(RSK_KEYSANITY).Is(RO_DUNGEON_ITEM_LOC_ANYWHERE) ||
|
||||
ctx->GetOption(RSK_KEYSANITY).Is(RO_DUNGEON_ITEM_LOC_ANYWHERE) ||
|
||||
ctx->GetOption(RSK_KEYSANITY).Is(RO_DUNGEON_ITEM_LOC_ANYWHERE);
|
||||
IsFireLoopLocked = ctx->GetOption(RSK_KEYSANITY).Is(RO_DUNGEON_ITEM_LOC_ANYWHERE) ||
|
||||
ctx->GetOption(RSK_KEYSANITY).Is(RO_DUNGEON_ITEM_LOC_OVERWORLD) ||
|
||||
ctx->GetOption(RSK_KEYSANITY).Is(RO_DUNGEON_ITEM_LOC_ANY_DUNGEON);
|
||||
|
||||
// AmmoCanDrop = /*AmmoDrops.IsNot(AMMODROPS_NONE)*/ false; TODO: AmmoDrop setting
|
||||
|
||||
// Child item logic
|
||||
SkullMask = false;
|
||||
MaskOfTruth = false;
|
||||
// Mask quest
|
||||
CanBorrowMasks = false;
|
||||
BorrowSkullMask = false;
|
||||
BorrowSpookyMask = false;
|
||||
BorrowBunnyHood = false;
|
||||
BorrowRightMasks = false;
|
||||
|
||||
// Adult logic
|
||||
FreedEpona = false;
|
||||
@@ -2371,37 +2377,39 @@ void Logic::Reset() {
|
||||
ShadowTrialClear = false;
|
||||
LightTrialClear = false;
|
||||
|
||||
// Ocarina C Buttons
|
||||
bool ocBtnShuffle = ctx->GetOption(RSK_SHUFFLE_OCARINA_BUTTONS).Is(true);
|
||||
SetRandoInf(RAND_INF_HAS_OCARINA_A, !ocBtnShuffle);
|
||||
SetRandoInf(RAND_INF_HAS_OCARINA_C_UP, !ocBtnShuffle);
|
||||
SetRandoInf(RAND_INF_HAS_OCARINA_C_DOWN, !ocBtnShuffle);
|
||||
SetRandoInf(RAND_INF_HAS_OCARINA_C_LEFT, !ocBtnShuffle);
|
||||
SetRandoInf(RAND_INF_HAS_OCARINA_C_RIGHT, !ocBtnShuffle);
|
||||
if (resetSaveContext) {
|
||||
// Ocarina C Buttons
|
||||
bool ocBtnShuffle = ctx->GetOption(RSK_SHUFFLE_OCARINA_BUTTONS).Is(true);
|
||||
SetRandoInf(RAND_INF_HAS_OCARINA_A, !ocBtnShuffle);
|
||||
SetRandoInf(RAND_INF_HAS_OCARINA_C_UP, !ocBtnShuffle);
|
||||
SetRandoInf(RAND_INF_HAS_OCARINA_C_DOWN, !ocBtnShuffle);
|
||||
SetRandoInf(RAND_INF_HAS_OCARINA_C_LEFT, !ocBtnShuffle);
|
||||
SetRandoInf(RAND_INF_HAS_OCARINA_C_RIGHT, !ocBtnShuffle);
|
||||
|
||||
// Progressive Items
|
||||
SetUpgrade(UPG_STICKS, ctx->GetOption(RSK_SHUFFLE_DEKU_STICK_BAG).Is(true) ? 0 : 1);
|
||||
SetUpgrade(UPG_NUTS, ctx->GetOption(RSK_SHUFFLE_DEKU_NUT_BAG).Is(true) ? 0 : 1);
|
||||
// Progressive Items
|
||||
SetUpgrade(UPG_STICKS, ctx->GetOption(RSK_SHUFFLE_DEKU_STICK_BAG).Is(true) ? 0 : 1);
|
||||
SetUpgrade(UPG_NUTS, ctx->GetOption(RSK_SHUFFLE_DEKU_NUT_BAG).Is(true) ? 0 : 1);
|
||||
|
||||
// If we're not shuffling swim, we start with it
|
||||
if (ctx->GetOption(RSK_SHUFFLE_SWIM).Is(false)) {
|
||||
SetRandoInf(RAND_INF_CAN_SWIM, true);
|
||||
}
|
||||
// If we're not shuffling swim, we start with it
|
||||
if (ctx->GetOption(RSK_SHUFFLE_SWIM).Is(false)) {
|
||||
SetRandoInf(RAND_INF_CAN_SWIM, true);
|
||||
}
|
||||
|
||||
// If we're not shuffling child's wallet, we start with it
|
||||
if (ctx->GetOption(RSK_SHUFFLE_CHILD_WALLET).Is(false)) {
|
||||
SetRandoInf(RAND_INF_HAS_WALLET, true);
|
||||
}
|
||||
// If we're not shuffling child's wallet, we start with it
|
||||
if (ctx->GetOption(RSK_SHUFFLE_CHILD_WALLET).Is(false)) {
|
||||
SetRandoInf(RAND_INF_HAS_WALLET, true);
|
||||
}
|
||||
|
||||
// If we're not shuffling fishing pole, we start with it
|
||||
if (ctx->GetOption(RSK_SHUFFLE_FISHING_POLE).Is(false)) {
|
||||
SetRandoInf(RAND_INF_FISHING_POLE_FOUND, true);
|
||||
}
|
||||
// If we're not shuffling fishing pole, we start with it
|
||||
if (ctx->GetOption(RSK_SHUFFLE_FISHING_POLE).Is(false)) {
|
||||
SetRandoInf(RAND_INF_FISHING_POLE_FOUND, true);
|
||||
}
|
||||
|
||||
// If not keysanity, start with 1 logical key to account for automatically unlocking the basement door in vanilla
|
||||
// FiT
|
||||
if (!IsKeysanity && ctx->GetDungeon(Rando::FIRE_TEMPLE)->IsVanilla()) {
|
||||
SetSmallKeyCount(SCENE_FIRE_TEMPLE, 1);
|
||||
// If not keysanity, start with 1 logical key to account for automatically unlocking the basement door in
|
||||
// vanilla FiT
|
||||
if (!IsFireLoopLocked && ctx->GetDungeon(Rando::FIRE_TEMPLE)->IsVanilla()) {
|
||||
SetSmallKeyCount(SCENE_FIRE_TEMPLE, 1);
|
||||
}
|
||||
}
|
||||
|
||||
// Bottle Count
|
||||
@@ -2454,7 +2462,9 @@ void Logic::Reset() {
|
||||
// Other
|
||||
AtDay = false;
|
||||
AtNight = false;
|
||||
GetSaveContext()->linkAge = !ctx->GetOption(RSK_SELECTED_STARTING_AGE).Get();
|
||||
if (resetSaveContext) {
|
||||
GetSaveContext()->linkAge = !ctx->GetOption(RSK_SELECTED_STARTING_AGE).Get();
|
||||
}
|
||||
|
||||
// Events
|
||||
ShowedMidoSwordAndShield = false;
|
||||
@@ -2498,6 +2508,7 @@ void Logic::Reset() {
|
||||
ForestOpenBossCorridor = false;
|
||||
ShadowTrialFirstChest = false;
|
||||
MQGTGMazeSwitch = false;
|
||||
MQGTGRightSideSwitch = false;
|
||||
GTGPlatformSilverRupees = false;
|
||||
MQJabuHolesRoomDoor = false;
|
||||
JabuWestTentacle = false;
|
||||
@@ -2518,6 +2529,8 @@ void Logic::Reset() {
|
||||
Spirit1FSilverRupees = false;
|
||||
JabuRutoIn1F = false;
|
||||
|
||||
CalculatingAvailableChecks = false;
|
||||
|
||||
StopPerformanceTimer(PT_LOGIC_RESET);
|
||||
}
|
||||
} // namespace Rando
|
||||
|
||||
@@ -30,9 +30,12 @@ class Logic {
|
||||
public:
|
||||
bool noVariable = false;
|
||||
|
||||
// Child item logic
|
||||
bool SkullMask = false;
|
||||
bool MaskOfTruth = false;
|
||||
// Mask Quest
|
||||
bool CanBorrowMasks = false;
|
||||
bool BorrowSkullMask = false;
|
||||
bool BorrowSpookyMask = false;
|
||||
bool BorrowBunnyHood = false;
|
||||
bool BorrowRightMasks = false;
|
||||
|
||||
// Adult logic
|
||||
bool FreedEpona = false;
|
||||
@@ -59,7 +62,7 @@ class Logic {
|
||||
bool LightTrialClear = false;
|
||||
|
||||
// Logical keysanity
|
||||
bool IsKeysanity = false;
|
||||
bool IsFireLoopLocked = false;
|
||||
|
||||
// Bottle Count
|
||||
uint8_t Bottles = 0;
|
||||
@@ -183,6 +186,9 @@ class Logic {
|
||||
|
||||
/* --- END OF HELPERS AND LOCATION ACCESS --- */
|
||||
|
||||
bool CalculatingAvailableChecks = false;
|
||||
bool ACProcessUndiscoveredExits = false;
|
||||
|
||||
SaveContext* mSaveContext = nullptr;
|
||||
Logic();
|
||||
bool CanUse(RandomizerGet itemName);
|
||||
@@ -254,7 +260,7 @@ class Logic {
|
||||
bool CanUseProjectile();
|
||||
bool CanBuildRainbowBridge();
|
||||
bool CanTriggerLACS();
|
||||
void Reset();
|
||||
void Reset(bool resetSaveContext = true);
|
||||
void SetContext(std::shared_ptr<Context> _ctx);
|
||||
bool GetInLogic(LogicVal logicVal);
|
||||
void SetInLogic(LogicVal logicVal, bool remove);
|
||||
|
||||
@@ -42,6 +42,8 @@ void Settings::CreateOptionDescriptions() {
|
||||
"\n"
|
||||
"Open - Sleeping Waterfall is always open. "
|
||||
"Link may always enter Zora's Domain.";
|
||||
mOptionDescriptions[RSK_JABU_OPEN] = "Closed - A fish is required to open Jabu-Jabu's mouth.\n\n"
|
||||
"Open - Jabu-Jabu's mouth opens without the need for a fish.";
|
||||
mOptionDescriptions[RSK_LOCK_OVERWORLD_DOORS] =
|
||||
"Add locks to all wooden overworld doors, requiring specific small keys to open them";
|
||||
mOptionDescriptions[RSK_STARTING_AGE] =
|
||||
|
||||
@@ -65,7 +65,7 @@ const std::string Randomizer::NaviRandoMessageTableID = "RandomizerNavi";
|
||||
const std::string Randomizer::IceTrapRandoMessageTableID = "RandomizerIceTrap";
|
||||
const std::string Randomizer::randoMiscHintsTableID = "RandomizerMiscHints";
|
||||
|
||||
static const char* englishRupeeNames[190] = {
|
||||
static const char* englishRupeeNames[188] = {
|
||||
"[P]",
|
||||
"Bad RNG Rolls",
|
||||
"Baht",
|
||||
@@ -111,8 +111,6 @@ static const char* englishRupeeNames[190] = {
|
||||
"Dimes",
|
||||
"Dinars",
|
||||
"DNA",
|
||||
"Doge",
|
||||
"Dogecoin",
|
||||
"Doll Hairs",
|
||||
"Dollars",
|
||||
"Dollarydoos",
|
||||
@@ -258,25 +256,25 @@ static const char* englishRupeeNames[190] = {
|
||||
"Zorkmids",
|
||||
};
|
||||
|
||||
static const char* germanRupeeNames[80] = {
|
||||
"Baht", "Bananen", "Bitcoin", "Bonbons", "Bratwürste", "Brause UFOs", "Brötchen", "Cent",
|
||||
"Diamanten", "Dinar", "Diridari", "Dogecoin", "Dollar", "Draken", "ECU", "Elexit",
|
||||
"Erz", "Erzbrocken", "Euro", "EXP", "Forint", "Franken", "Freunde", "Gil",
|
||||
"Gold", "Groschen", "Gulden", "Gummibären", "Heller", "Juwelen", "Karolin", "Kartoffeln",
|
||||
"Kies", "Knete", "Knochen", "Kohle", "Kraniche", "Kreuzer", "Kronen", "Kronkorken",
|
||||
"Kröten", "Lira", "Mark", "Mäuse", "Monde", "Moorhühner", "Moos", "Münzen",
|
||||
"Naira", "Penunze", "Pesa", "Pfandflaschen", "Pfennig", "Pfund", "Pilze", "Plastiks",
|
||||
"Pokédollar", "Radieschen", "Rand", "Rappen", "Real", "Rial", "Riyal", "Rubine",
|
||||
"Rupien", "Saphire", "Schilling", "Seelen", "Septime", "Smaragde", "Steine", "Sterne",
|
||||
"Sternis", "Tael", "Taler", "Wagenchips", "Won", "Yen", "Yuan", "Zenny",
|
||||
static const char* germanRupeeNames[79] = {
|
||||
"Baht", "Bananen", "Bitcoin", "Bonbons", "Bratwürste", "Brause UFOs", "Brötchen", "Cent",
|
||||
"Diamanten", "Dinar", "Diridari", "Dollar", "Draken", "ECU", "Elexit", "Erz",
|
||||
"Erzbrocken", "Euro", "EXP", "Forint", "Franken", "Freunde", "Gil", "Gold",
|
||||
"Groschen", "Gulden", "Gummibären", "Heller", "Juwelen", "Karolin", "Kartoffeln", "Kies",
|
||||
"Knete", "Knochen", "Kohle", "Kraniche", "Kreuzer", "Kronen", "Kronkorken", "Kröten",
|
||||
"Lira", "Mark", "Mäuse", "Monde", "Moorhühner", "Moos", "Münzen", "Naira",
|
||||
"Penunze", "Pesa", "Pfandflaschen", "Pfennig", "Pfund", "Pilze", "Plastiks", "Pokédollar",
|
||||
"Radieschen", "Rand", "Rappen", "Real", "Rial", "Riyal", "Rubine", "Rupien",
|
||||
"Saphire", "Schilling", "Seelen", "Septime", "Smaragde", "Steine", "Sterne", "Sternis",
|
||||
"Tael", "Taler", "Wagenchips", "Won", "Yen", "Yuan", "Zenny",
|
||||
};
|
||||
|
||||
static const char* frenchRupeeNames[40] = {
|
||||
"Anneaux", "Baguettes", "Balles", "Bananes", "Bitcoin", "Blés", "Bling", "Capsules",
|
||||
"Centimes", "Champignons", "Clochettes", "Crédits", "Croissants", "Diamants", "Dogecoin", "Dollars",
|
||||
"Émeraudes", "Éthers", "Étoiles", "Euros", "Florens", "Francs", "Galds", "Gils",
|
||||
"Grouses", "Halos", "Joyaux", "Lunes", "Mailles", "Munnies", "Orbes", "Orens",
|
||||
"Pépètes", "Pièces", "Plastyks", "Pokédollars", "Pokémon", "Radis", "Rubis", "Zennies",
|
||||
static const char* frenchRupeeNames[39] = {
|
||||
"Anneaux", "Baguettes", "Balles", "Bananes", "Bitcoin", "Blés", "Bling", "Capsules",
|
||||
"Centimes", "Champignons", "Clochettes", "Crédits", "Croissants", "Diamants", "Dollars", "Émeraudes",
|
||||
"Éthers", "Étoiles", "Euros", "Florens", "Francs", "Galds", "Gils", "Grouses",
|
||||
"Halos", "Joyaux", "Lunes", "Mailles", "Munnies", "Orbes", "Orens", "Pépètes",
|
||||
"Pièces", "Plastyks", "Pokédollars", "Pokémon", "Radis", "Rubis", "Zennies",
|
||||
};
|
||||
|
||||
Randomizer::Randomizer() {
|
||||
@@ -361,16 +359,74 @@ std::unordered_map<s16, s16> getItemIdToItemId = {
|
||||
#pragma GCC push_options
|
||||
#pragma GCC optimize("O0")
|
||||
bool Randomizer::SpoilerFileExists(const char* spoilerFileName) {
|
||||
if (strcmp(spoilerFileName, "") != 0) {
|
||||
std::ifstream spoilerFileStream(SohUtils::Sanitize(spoilerFileName));
|
||||
if (!spoilerFileStream) {
|
||||
return false;
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
static std::unordered_map<std::string, bool> existsCache;
|
||||
static std::unordered_map<std::string, std::filesystem::file_time_type> lastModifiedCache;
|
||||
|
||||
if (strcmp(spoilerFileName, "") == 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return false;
|
||||
std::string sanitizedFileName = SohUtils::Sanitize(spoilerFileName);
|
||||
|
||||
try {
|
||||
// Check if file exists and get last modified time
|
||||
std::filesystem::path filePath(sanitizedFileName);
|
||||
if (!std::filesystem::exists(filePath)) {
|
||||
// Cache and return false if file doesn't exist
|
||||
existsCache[sanitizedFileName] = false;
|
||||
lastModifiedCache.erase(sanitizedFileName);
|
||||
return false;
|
||||
}
|
||||
|
||||
auto currentLastModified = std::filesystem::last_write_time(filePath);
|
||||
|
||||
// Check cache first
|
||||
auto existsCacheIt = existsCache.find(sanitizedFileName);
|
||||
auto lastModifiedCacheIt = lastModifiedCache.find(sanitizedFileName);
|
||||
|
||||
// If we have a valid cache entry and the file hasn't been modified
|
||||
if (existsCacheIt != existsCache.end() && lastModifiedCacheIt != lastModifiedCache.end() &&
|
||||
lastModifiedCacheIt->second == currentLastModified) {
|
||||
return existsCacheIt->second;
|
||||
}
|
||||
|
||||
// Cache miss or file modified - need to check contents
|
||||
std::ifstream spoilerFileStream(sanitizedFileName);
|
||||
if (spoilerFileStream) {
|
||||
nlohmann::json contents;
|
||||
spoilerFileStream >> contents;
|
||||
spoilerFileStream.close();
|
||||
|
||||
bool isValid = contents.contains("version") &&
|
||||
strcmp(std::string(contents["version"]).c_str(), (char*)gBuildVersion) == 0;
|
||||
|
||||
if (!isValid) {
|
||||
SohGui::RegisterPopup(
|
||||
"Old Spoiler Version",
|
||||
"The spoiler file located at\n" + std::string(spoilerFileName) +
|
||||
"\nwas made by a version that doesn't match the currently running version.\n" +
|
||||
"Loading for this file has been cancelled.");
|
||||
CVarClear(CVAR_GENERAL("SpoilerLog"));
|
||||
Ship::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesNextFrame();
|
||||
}
|
||||
|
||||
// Update cache
|
||||
existsCache[sanitizedFileName] = isValid;
|
||||
lastModifiedCache[sanitizedFileName] = currentLastModified;
|
||||
return isValid;
|
||||
}
|
||||
|
||||
// File couldn't be opened
|
||||
existsCache[sanitizedFileName] = false;
|
||||
lastModifiedCache.erase(sanitizedFileName);
|
||||
return false;
|
||||
|
||||
} catch (const std::filesystem::filesystem_error&) {
|
||||
// Handle filesystem errors by invalidating cache
|
||||
existsCache[sanitizedFileName] = false;
|
||||
lastModifiedCache.erase(sanitizedFileName);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
#pragma GCC pop_options
|
||||
#pragma optimize("", on)
|
||||
@@ -3578,7 +3634,7 @@ std::thread randoThread;
|
||||
|
||||
void GenerateRandomizerImgui(std::string seed = "") {
|
||||
CVarSetInteger(CVAR_GENERAL("RandoGenerating"), 1);
|
||||
CVarSave();
|
||||
Ship::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesNextFrame();
|
||||
auto ctx = Rando::Context::GetInstance();
|
||||
// RANDOTODO proper UI for selecting if a spoiler loaded should be used for settings
|
||||
Rando::Settings::GetInstance()->SetAllToContext();
|
||||
@@ -3726,13 +3782,15 @@ void RandomizerSettingsWindow::DrawElement() {
|
||||
}
|
||||
|
||||
UIWidgets::Spacer(0);
|
||||
ImGui::BeginDisabled((gSaveContext.gameMode != GAMEMODE_FILE_SELECT) || GameInteractor::IsSaveLoaded());
|
||||
if (UIWidgets::Button("Generate Randomizer",
|
||||
UIWidgets::ButtonOptions().Size(ImVec2(250.f, 0.f)).Color(THEME_COLOR))) {
|
||||
UIWidgets::ButtonOptions options = UIWidgets::ButtonOptions().Size(ImVec2(250.f, 0.f)).Color(THEME_COLOR);
|
||||
options.Disabled((gSaveContext.gameMode != GAMEMODE_FILE_SELECT) || GameInteractor::IsSaveLoaded());
|
||||
if (options.disabled) {
|
||||
options.DisabledTooltip("Must be on File Select to generate a randomizer seed.");
|
||||
}
|
||||
if (UIWidgets::Button("Generate Randomizer", options)) {
|
||||
ctx->SetSpoilerLoaded(false);
|
||||
GenerateRandomizer(CVarGetInteger(CVAR_RANDOMIZER_SETTING("ManualSeedEntry"), 0) ? seedString : "");
|
||||
}
|
||||
ImGui::EndDisabled();
|
||||
|
||||
ImGui::SameLine();
|
||||
if (!CVarGetInteger(CVAR_RANDOMIZER_SETTING("DontGenerateSpoiler"), 0)) {
|
||||
@@ -4515,6 +4573,9 @@ CustomMessage Randomizer::GetMapGetItemMessageWithHint(GetItemEntry itemEntry) {
|
||||
messageEntry.Replace("[[typeHint]]", Rando::StaticData::hintTextTable[RHT_DUNGEON_ORDINARY].GetHintMessage());
|
||||
}
|
||||
|
||||
// BUG: the icon is not in the message yet so are not accounted for, so overflows are possible
|
||||
messageEntry.AutoFormat();
|
||||
|
||||
return messageEntry;
|
||||
}
|
||||
|
||||
|
||||
@@ -566,6 +566,7 @@ typedef enum {
|
||||
RR_DEKU_TREE_MQ_OUTSIDE_BOSS_ROOM,
|
||||
|
||||
RR_DEKU_TREE_BOSS_ENTRYWAY,
|
||||
RR_DEKU_TREE_BOSS_EXIT,
|
||||
RR_DEKU_TREE_BOSS_ROOM,
|
||||
|
||||
RR_DODONGOS_CAVERN_BEGINNING,
|
||||
@@ -613,7 +614,9 @@ typedef enum {
|
||||
RR_DODONGOS_CAVERN_MQ_BEHIND_MOUTH,
|
||||
RR_DODONGOS_CAVERN_MQ_BACK_BEHIND_FIRE,
|
||||
RR_DODONGOS_CAVERN_MQ_BACK_SWITCH_GRAVE,
|
||||
|
||||
RR_DODONGOS_CAVERN_BOSS_ENTRYWAY,
|
||||
RR_DODONGOS_CAVERN_BOSS_EXIT,
|
||||
RR_DODONGOS_CAVERN_BOSS_ROOM,
|
||||
|
||||
RR_JABU_JABUS_BELLY_BEGINNING,
|
||||
@@ -642,6 +645,7 @@ typedef enum {
|
||||
RR_JABU_JABUS_BELLY_MQ_EAST_ROOM,
|
||||
|
||||
RR_JABU_JABUS_BELLY_BOSS_ENTRYWAY,
|
||||
RR_JABU_JABUS_BELLY_BOSS_EXIT,
|
||||
RR_JABU_JABUS_BELLY_BOSS_ROOM,
|
||||
|
||||
RR_FOREST_TEMPLE_FIRST_ROOM,
|
||||
@@ -2605,7 +2609,6 @@ typedef enum {
|
||||
|
||||
RC_PIERRE,
|
||||
RC_DELIVER_RUTOS_LETTER,
|
||||
RC_MASTER_SWORD_PEDESTAL,
|
||||
RC_KF_DEKU_TREE_LEFT_GOSSIP_STONE,
|
||||
RC_KF_DEKU_TREE_RIGHT_GOSSIP_STONE,
|
||||
RC_KF_GOSSIP_STONE,
|
||||
@@ -4898,7 +4901,6 @@ typedef enum {
|
||||
RHT_GANONS_CASTLE_MQ_DEKU_SCRUB_RIGHT,
|
||||
RHT_GANONS_TOWER_BOSS_KEY_CHEST,
|
||||
RHT_DELIVER_RUTOS_LETTER,
|
||||
RHT_MASTER_SWORD_PEDESTAL,
|
||||
// Beehives
|
||||
RHT_BEEHIVE_CHEST_GROTTO,
|
||||
RHT_BEEHIVE_COW_GROTTO,
|
||||
@@ -5366,19 +5368,24 @@ typedef enum {
|
||||
RHT_SKULLS_HINT,
|
||||
RHT_MASK_SHOP_HINT,
|
||||
// Shuffle Pots
|
||||
RHT_POT_KOKIRI_FOREST,
|
||||
RHT_POT_LINKS_HOUSE,
|
||||
RHT_POT_TWINS_HOUSE,
|
||||
RHT_POT_KNOW_IT_ALL,
|
||||
RHT_POT_GERUDO_FORTRESS,
|
||||
RHT_POT_WASTELAND,
|
||||
RHT_POT_MARKET,
|
||||
RHT_POT_GUARD_HOUSE,
|
||||
RHT_POT_POE_SHOP,
|
||||
RHT_POT_ALLY_HOUSE,
|
||||
RHT_POT_KAKARIKO,
|
||||
RHT_POT_GRAVEYARD,
|
||||
RHT_POT_DAMPE,
|
||||
RHT_POT_GORON_CITY,
|
||||
RHT_POT_DEATH_MOUNTAIN_CRATER,
|
||||
RHT_POT_ZORAS_DOMAIN,
|
||||
RHT_POT_ZORAS_FOUNTAIN,
|
||||
RHT_POT_LON_LON_RANCH,
|
||||
RHT_POT_HYRULE_FIELD,
|
||||
RHT_POT_HYRULE_CASTLE,
|
||||
RHT_POT_TALONS_HOUSE,
|
||||
RHT_POT_WEB_GROTTO,
|
||||
RHT_POT_MUD_WALL_GROTTO,
|
||||
RHT_POT_DODONGOS_CAVERN,
|
||||
RHT_POT_JABU_JABUS_BELLY,
|
||||
RHT_POT_FOREST_TEMPLE,
|
||||
@@ -5684,6 +5691,7 @@ typedef enum {
|
||||
RSK_DOOR_OF_TIME,
|
||||
RSK_ZORAS_FOUNTAIN,
|
||||
RSK_SLEEPING_WATERFALL,
|
||||
RSK_JABU_OPEN,
|
||||
RSK_STARTING_AGE,
|
||||
RSK_SELECTED_STARTING_AGE,
|
||||
RSK_GERUDO_FORTRESS,
|
||||
@@ -5934,6 +5942,12 @@ typedef enum {
|
||||
RO_WATERFALL_OPEN,
|
||||
} RandoOptionSleepingWaterfall;
|
||||
|
||||
// Jabu-Jabu settings (closed, open)
|
||||
typedef enum {
|
||||
RO_JABU_CLOSED,
|
||||
RO_JABU_OPEN,
|
||||
} RandoOptionJabu;
|
||||
|
||||
// Starting Age settings (child, adult, random)
|
||||
typedef enum {
|
||||
RO_AGE_CHILD,
|
||||
|
||||
@@ -495,6 +495,9 @@ void SetShopSeen(uint32_t sceneNum, bool prices) {
|
||||
}
|
||||
|
||||
void CheckTrackerLoadGame(int32_t fileNum) {
|
||||
if (IS_BOSS_RUSH) {
|
||||
return;
|
||||
}
|
||||
LoadSettings();
|
||||
TrySetAreas();
|
||||
for (auto& entry : Rando::StaticData::GetLocationTable()) {
|
||||
@@ -580,7 +583,14 @@ void CheckTrackerLoadGame(int32_t fileNum) {
|
||||
UpdateAllOrdering();
|
||||
UpdateInventoryChecks();
|
||||
UpdateFilters();
|
||||
RecalculateAvailableChecks();
|
||||
|
||||
RegionTable_Init();
|
||||
|
||||
if (Rando::Context::GetInstance()->GetOption(RSK_SHUFFLE_ENTRANCES).Get()) {
|
||||
Rando::Context::GetInstance()->GetEntranceShuffler()->ApplyEntranceOverrides();
|
||||
}
|
||||
|
||||
recalculateAvailable = true;
|
||||
}
|
||||
|
||||
void CheckTrackerShopSlotChange(uint8_t cursorSlot, int16_t basePrice) {
|
||||
@@ -898,7 +908,6 @@ void LoadFile() {
|
||||
SaveManager::Instance->LoadData("areasSpoiled", areasSpoiled, (uint32_t)0);
|
||||
UpdateAllOrdering();
|
||||
UpdateAllAreas();
|
||||
RegionTable_Init();
|
||||
}
|
||||
|
||||
void Teardown() {
|
||||
@@ -988,6 +997,11 @@ void CheckTrackerWindow::DrawElement() {
|
||||
return;
|
||||
}
|
||||
|
||||
if (recalculateAvailable) {
|
||||
recalculateAvailable = false;
|
||||
RecalculateAvailableChecks();
|
||||
}
|
||||
|
||||
SceneID sceneId = SCENE_ID_MAX;
|
||||
if (gPlayState != nullptr) {
|
||||
sceneId = (SceneID)gPlayState->sceneNum;
|
||||
@@ -1481,6 +1495,27 @@ void LoadSettings() {
|
||||
showOverworldFreestanding = false;
|
||||
showDungeonFreestanding = true;
|
||||
}
|
||||
|
||||
switch (OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_GANONS_BOSS_KEY)) {
|
||||
case RO_GANON_BOSS_KEY_LACS_STONES:
|
||||
Rando::Context::GetInstance()->LACSCondition(RO_LACS_STONES);
|
||||
break;
|
||||
case RO_GANON_BOSS_KEY_LACS_MEDALLIONS:
|
||||
Rando::Context::GetInstance()->LACSCondition(RO_LACS_MEDALLIONS);
|
||||
break;
|
||||
case RO_GANON_BOSS_KEY_LACS_REWARDS:
|
||||
Rando::Context::GetInstance()->LACSCondition(RO_LACS_REWARDS);
|
||||
break;
|
||||
case RO_GANON_BOSS_KEY_LACS_DUNGEONS:
|
||||
Rando::Context::GetInstance()->LACSCondition(RO_LACS_DUNGEONS);
|
||||
break;
|
||||
case RO_GANON_BOSS_KEY_LACS_TOKENS:
|
||||
Rando::Context::GetInstance()->LACSCondition(RO_LACS_TOKENS);
|
||||
break;
|
||||
default:
|
||||
Rando::Context::GetInstance()->LACSCondition(RO_LACS_VANILLA);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
bool IsCheckShuffled(RandomizerCheck rc) {
|
||||
@@ -1561,10 +1596,11 @@ bool IsCheckShuffled(RandomizerCheck rc) {
|
||||
bool IsVisibleInCheckTracker(RandomizerCheck rc) {
|
||||
auto loc = Rando::StaticData::GetLocation(rc);
|
||||
if (IS_RANDO) {
|
||||
return IsCheckShuffled(rc) ||
|
||||
(alwaysShowGS && loc->GetRCType() == RCTYPE_SKULL_TOKEN &&
|
||||
OTRGlobals::Instance->gRandoContext->IsQuestOfLocationActive(rc)) ||
|
||||
(loc->GetRCType() == RCTYPE_SHOP && showShops && !hideShopUnshuffledChecks);
|
||||
return !Rando::Context::GetInstance()->GetItemLocation(rc)->IsExcluded() &&
|
||||
(IsCheckShuffled(rc) ||
|
||||
(alwaysShowGS && loc->GetRCType() == RCTYPE_SKULL_TOKEN &&
|
||||
OTRGlobals::Instance->gRandoContext->IsQuestOfLocationActive(rc)) ||
|
||||
(loc->GetRCType() == RCTYPE_SHOP && showShops && !hideShopUnshuffledChecks));
|
||||
} else {
|
||||
return loc->IsVanillaCompletion() &&
|
||||
(!loc->IsDungeon() || (loc->IsDungeon() && loc->GetQuest() == gSaveContext.ship.quest.id));
|
||||
@@ -1820,7 +1856,7 @@ void DrawLocation(RandomizerCheck rc) {
|
||||
case RCSHOW_IDENTIFIED:
|
||||
case RCSHOW_SEEN:
|
||||
if (IS_RANDO) {
|
||||
if (itemLoc->GetPlacedRandomizerGet() == RG_ICE_TRAP && !mystery && !itemLoc->IsAddedToPool()) {
|
||||
if (itemLoc->GetPlacedRandomizerGet() == RG_ICE_TRAP && !mystery) {
|
||||
if (status == RCSHOW_IDENTIFIED) {
|
||||
txt = OTRGlobals::Instance->gRandoContext->overrides[rc].GetTrickName().GetForLanguage(
|
||||
gSaveContext.language);
|
||||
@@ -1830,11 +1866,10 @@ void DrawLocation(RandomizerCheck rc) {
|
||||
.GetName()
|
||||
.GetForLanguage(gSaveContext.language);
|
||||
}
|
||||
} else if (!mystery && !itemLoc->IsAddedToPool()) {
|
||||
} else if (!mystery) {
|
||||
txt = itemLoc->GetPlacedItem().GetName().GetForLanguage(gSaveContext.language);
|
||||
}
|
||||
if (IsVisibleInCheckTracker(rc) && status == RCSHOW_IDENTIFIED && !mystery &&
|
||||
!itemLoc->IsAddedToPool()) {
|
||||
if (IsVisibleInCheckTracker(rc) && status == RCSHOW_IDENTIFIED && !mystery) {
|
||||
auto price = OTRGlobals::Instance->gRandoContext->GetItemLocation(rc)->GetPrice();
|
||||
if (price) {
|
||||
txt += fmt::format(" - {}", price);
|
||||
@@ -1958,43 +1993,38 @@ void ImGuiDrawTwoColorPickerSection(const char* text, const char* cvarMainName,
|
||||
UIWidgets::PopStyleCombobox();
|
||||
}
|
||||
|
||||
void RecalculateAvailableChecks() {
|
||||
if (!enableAvailableChecks) {
|
||||
void RecalculateAvailableChecks(RandomizerRegion startingRegion /* = RR_ROOT */) {
|
||||
if (!enableAvailableChecks || !GameInteractor::IsSaveLoaded()) {
|
||||
return;
|
||||
}
|
||||
|
||||
ResetPerformanceTimer(PT_RECALCULATE_AVAILABLE_CHECKS);
|
||||
StartPerformanceTimer(PT_RECALCULATE_AVAILABLE_CHECKS);
|
||||
|
||||
const auto& ctx = Rando::Context::GetInstance();
|
||||
|
||||
std::vector<RandomizerCheck> targetLocations;
|
||||
targetLocations.reserve(RR_MAX);
|
||||
targetLocations.reserve(RC_MAX);
|
||||
for (auto& location : Rando::StaticData::GetLocationTable()) {
|
||||
RandomizerCheck rc = location.GetRandomizerCheck();
|
||||
Rando::ItemLocation* itemLocation = OTRGlobals::Instance->gRandoContext->GetItemLocation(rc);
|
||||
Rando::ItemLocation* itemLocation = ctx->GetItemLocation(rc);
|
||||
itemLocation->SetAvailable(false);
|
||||
if (!itemLocation->HasObtained()) {
|
||||
targetLocations.emplace_back(rc);
|
||||
}
|
||||
}
|
||||
|
||||
std::vector<RandomizerCheck> availableChecks = ReachabilitySearch(targetLocations, RG_NONE, true);
|
||||
std::vector<RandomizerCheck> availableChecks = ReachabilitySearch(targetLocations, RG_NONE, true, startingRegion);
|
||||
for (auto& rc : availableChecks) {
|
||||
const auto& location = Rando::StaticData::GetLocation(rc);
|
||||
const auto& itemLocation = OTRGlobals::Instance->gRandoContext->GetItemLocation(rc);
|
||||
if (location->GetRCType() == RCTYPE_SHOP && itemLocation->GetCheckStatus() == RCSHOW_IDENTIFIED) {
|
||||
if (CanBuyAnother(rc)) {
|
||||
itemLocation->SetAvailable(true);
|
||||
}
|
||||
} else {
|
||||
itemLocation->SetAvailable(true);
|
||||
}
|
||||
const auto& itemLocation = ctx->GetItemLocation(rc);
|
||||
itemLocation->SetAvailable(true);
|
||||
}
|
||||
|
||||
totalChecksAvailable = 0;
|
||||
for (auto& [rcArea, vec] : checksByArea) {
|
||||
areaChecksAvailable[rcArea] = 0;
|
||||
for (auto& rc : vec) {
|
||||
Rando::ItemLocation* itemLocation = OTRGlobals::Instance->gRandoContext->GetItemLocation(rc);
|
||||
Rando::ItemLocation* itemLocation = ctx->GetItemLocation(rc);
|
||||
if (itemLocation->IsAvailable() && IsVisibleInCheckTracker(rc) && !IsCheckHidden(rc)) {
|
||||
areaChecksAvailable[rcArea]++;
|
||||
}
|
||||
@@ -2030,10 +2060,6 @@ static std::unordered_map<int32_t, const char*> buttonStrings = {
|
||||
};
|
||||
|
||||
void CheckTrackerSettingsWindow::DrawElement() {
|
||||
if (recalculateAvailable) {
|
||||
recalculateAvailable = false;
|
||||
RecalculateAvailableChecks();
|
||||
}
|
||||
ImGui::PushStyleVar(ImGuiStyleVar_CellPadding, { 8.0f, 8.0f });
|
||||
if (ImGui::BeginTable("CheckTrackerSettingsTable", 2, ImGuiTableFlags_BordersH | ImGuiTableFlags_BordersV)) {
|
||||
ImGui::TableSetupColumn("General settings", ImGuiTableColumnFlags_WidthStretch, 200.0f);
|
||||
@@ -2173,8 +2199,8 @@ void CheckTrackerSettingsWindow::DrawElement() {
|
||||
"Checks that you saved the game while having collected.", THEME_COLOR);
|
||||
|
||||
ImGui::PopStyleVar(1);
|
||||
ImGui::EndTable();
|
||||
}
|
||||
ImGui::EndTable();
|
||||
}
|
||||
|
||||
void CheckTrackerWindow::InitElement() {
|
||||
|
||||
@@ -61,5 +61,5 @@ void UpdateAllOrdering();
|
||||
void UpdateAllAreas();
|
||||
void RecalculateAllAreaTotals();
|
||||
void SpoilAreaFromCheck(RandomizerCheck rc);
|
||||
void RecalculateAvailableChecks();
|
||||
void RecalculateAvailableChecks(RandomizerRegion startingRegion = RR_ROOT);
|
||||
} // namespace CheckTracker
|
||||
|
||||
@@ -253,7 +253,9 @@ void Entrance_Init(void) {
|
||||
for (s16 i = 0; i < 4; i++) {
|
||||
// Zero out the bit in the field which tells the game to keep playing
|
||||
// background music for all four scene setups at each index
|
||||
gEntranceTable[override + i].field &= ~ENTRANCE_INFO_CONTINUE_BGM_FLAG;
|
||||
if (override + i < ENTRANCE_TABLE_SIZE) {
|
||||
gEntranceTable[override + i].field &= ~ENTRANCE_INFO_CONTINUE_BGM_FLAG;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -809,6 +811,7 @@ void Entrance_SetEntranceDiscovered(u16 entranceIndex, u8 isReversedEntrance) {
|
||||
if (idx < SAVEFILE_ENTRANCES_DISCOVERED_IDX_COUNT) {
|
||||
u32 entranceBit = 1 << (entranceIndex - (idx * bitsPerIndex));
|
||||
gSaveContext.ship.stats.entrancesDiscovered[idx] |= entranceBit;
|
||||
CheckTracker_RecalculateAvailableChecks();
|
||||
|
||||
// Set reverse entrance when not decoupled
|
||||
if (!Randomizer_GetSettingValue(RSK_DECOUPLED_ENTRANCES) && !isReversedEntrance) {
|
||||
|
||||
@@ -1532,8 +1532,9 @@ void ItemTrackerWindow::DrawElement() {
|
||||
|
||||
if (CVarGetInteger(CVAR_TRACKER_ITEM("DisplayType.Notes"), SECTION_DISPLAY_HIDDEN) ==
|
||||
SECTION_DISPLAY_MAIN_WINDOW &&
|
||||
CVarGetInteger(CVAR_TRACKER_ITEM("DisplayType.Main"), TRACKER_DISPLAY_ALWAYS) ==
|
||||
TRACKER_DISPLAY_ALWAYS) {
|
||||
(CVarGetInteger(CVAR_TRACKER_ITEM("WindowType"), TRACKER_WINDOW_FLOATING) == TRACKER_WINDOW_FLOATING &&
|
||||
CVarGetInteger(CVAR_TRACKER_ITEM("DisplayType.Main"), TRACKER_DISPLAY_ALWAYS) ==
|
||||
TRACKER_DISPLAY_ALWAYS)) {
|
||||
DrawNotes();
|
||||
}
|
||||
EndFloatingWindows();
|
||||
@@ -1642,7 +1643,10 @@ void ItemTrackerWindow::DrawElement() {
|
||||
|
||||
if (CVarGetInteger(CVAR_TRACKER_ITEM("DisplayType.Notes"), SECTION_DISPLAY_HIDDEN) ==
|
||||
SECTION_DISPLAY_SEPARATE &&
|
||||
CVarGetInteger(CVAR_TRACKER_ITEM("DisplayType.Main"), TRACKER_DISPLAY_ALWAYS) == TRACKER_DISPLAY_ALWAYS) {
|
||||
(CVarGetInteger(CVAR_TRACKER_ITEM("WindowType"), TRACKER_WINDOW_FLOATING) == TRACKER_WINDOW_WINDOW ||
|
||||
(CVarGetInteger(CVAR_TRACKER_ITEM("WindowType"), TRACKER_WINDOW_FLOATING) == TRACKER_WINDOW_FLOATING &&
|
||||
CVarGetInteger(CVAR_TRACKER_ITEM("DisplayType.Main"), TRACKER_DISPLAY_ALWAYS) !=
|
||||
TRACKER_DISPLAY_COMBO_BUTTON))) {
|
||||
ImGui::SetNextWindowSize(ImVec2(400, 300), ImGuiCond_FirstUseEver);
|
||||
BeginFloatingWindows("Personal Notes", ImGuiWindowFlags_NoFocusOnAppearing);
|
||||
DrawNotes(true);
|
||||
@@ -1709,242 +1713,156 @@ static std::unordered_map<int32_t, const char*> minimalDisplayTypes = {
|
||||
|
||||
void ItemTrackerSettingsWindow::DrawElement() {
|
||||
ImGui::PushStyleVar(ImGuiStyleVar_CellPadding, { 8.0f, 8.0f });
|
||||
ImGui::BeginTable("itemTrackerSettingsTable", 2, ImGuiTableFlags_BordersH | ImGuiTableFlags_BordersV);
|
||||
ImGui::TableSetupColumn("General settings", ImGuiTableColumnFlags_WidthStretch, 200.0f);
|
||||
ImGui::TableSetupColumn("Section settings", ImGuiTableColumnFlags_WidthStretch, 200.0f);
|
||||
ImGui::TableHeadersRow();
|
||||
ImGui::TableNextRow();
|
||||
ImGui::TableNextColumn();
|
||||
ImGui::PushItemWidth(ImGui::GetContentRegionAvail().x);
|
||||
CVarColorPicker("Background Color##gItemTrackerBgColor", CVAR_TRACKER_ITEM("BgColor"), { 0, 0, 0, 0 }, true,
|
||||
ColorPickerRandomButton | ColorPickerResetButton, THEME_COLOR);
|
||||
if (ImGui::BeginTable("itemTrackerSettingsTable", 2, ImGuiTableFlags_BordersH | ImGuiTableFlags_BordersV)) {
|
||||
ImGui::TableSetupColumn("General settings", ImGuiTableColumnFlags_WidthStretch, 200.0f);
|
||||
ImGui::TableSetupColumn("Section settings", ImGuiTableColumnFlags_WidthStretch, 200.0f);
|
||||
ImGui::TableHeadersRow();
|
||||
ImGui::TableNextRow();
|
||||
ImGui::TableNextColumn();
|
||||
ImGui::PushItemWidth(ImGui::GetContentRegionAvail().x);
|
||||
CVarColorPicker("Background Color##gItemTrackerBgColor", CVAR_TRACKER_ITEM("BgColor"), { 0, 0, 0, 0 }, true,
|
||||
ColorPickerRandomButton | ColorPickerResetButton, THEME_COLOR);
|
||||
|
||||
ImGui::PopItemWidth();
|
||||
if (CVarCombobox("Window Type", CVAR_TRACKER_ITEM("WindowType"), windowTypes,
|
||||
ComboboxOptions()
|
||||
.DefaultIndex(TRACKER_WINDOW_FLOATING)
|
||||
.ComponentAlignment(ComponentAlignments::Right)
|
||||
.LabelPosition(LabelPositions::Far)
|
||||
.Color(THEME_COLOR))) {
|
||||
shouldUpdateVectors = true;
|
||||
}
|
||||
|
||||
if (CVarGetInteger(CVAR_TRACKER_ITEM("WindowType"), TRACKER_WINDOW_FLOATING) == TRACKER_WINDOW_FLOATING) {
|
||||
if (CVarCheckbox("Enable Dragging", CVAR_TRACKER_ITEM("Draggable"), CheckboxOptions().Color(THEME_COLOR))) {
|
||||
shouldUpdateVectors = true;
|
||||
}
|
||||
if (CVarCheckbox("Only enable while paused", CVAR_TRACKER_ITEM("ShowOnlyPaused"),
|
||||
CheckboxOptions().Color(THEME_COLOR))) {
|
||||
shouldUpdateVectors = true;
|
||||
}
|
||||
if (CVarCombobox("Display Mode", CVAR_TRACKER_ITEM("DisplayType.Main"), displayModes,
|
||||
ImGui::PopItemWidth();
|
||||
if (CVarCombobox("Window Type", CVAR_TRACKER_ITEM("WindowType"), windowTypes,
|
||||
ComboboxOptions()
|
||||
.DefaultIndex(TRACKER_DISPLAY_ALWAYS)
|
||||
.DefaultIndex(TRACKER_WINDOW_FLOATING)
|
||||
.ComponentAlignment(ComponentAlignments::Right)
|
||||
.LabelPosition(LabelPositions::Far)
|
||||
.Color(THEME_COLOR))) {
|
||||
shouldUpdateVectors = true;
|
||||
}
|
||||
if (CVarGetInteger(CVAR_TRACKER_ITEM("DisplayType.Main"), TRACKER_DISPLAY_ALWAYS) ==
|
||||
TRACKER_DISPLAY_COMBO_BUTTON) {
|
||||
if (CVarCombobox("Combo Button 1", CVAR_TRACKER_ITEM("ComboButton1"), buttons,
|
||||
|
||||
if (CVarGetInteger(CVAR_TRACKER_ITEM("WindowType"), TRACKER_WINDOW_FLOATING) == TRACKER_WINDOW_FLOATING) {
|
||||
if (CVarCheckbox("Enable Dragging", CVAR_TRACKER_ITEM("Draggable"), CheckboxOptions().Color(THEME_COLOR))) {
|
||||
shouldUpdateVectors = true;
|
||||
}
|
||||
if (CVarCheckbox("Only enable while paused", CVAR_TRACKER_ITEM("ShowOnlyPaused"),
|
||||
CheckboxOptions().Color(THEME_COLOR))) {
|
||||
shouldUpdateVectors = true;
|
||||
}
|
||||
if (CVarCombobox("Display Mode", CVAR_TRACKER_ITEM("DisplayType.Main"), displayModes,
|
||||
ComboboxOptions()
|
||||
.DefaultIndex(TRACKER_COMBO_BUTTON_L)
|
||||
.DefaultIndex(TRACKER_DISPLAY_ALWAYS)
|
||||
.ComponentAlignment(ComponentAlignments::Right)
|
||||
.LabelPosition(LabelPositions::Far)
|
||||
.Color(THEME_COLOR))) {
|
||||
shouldUpdateVectors = true;
|
||||
}
|
||||
if (CVarCombobox("Combo Button 2", CVAR_TRACKER_ITEM("ComboButton2"), buttons,
|
||||
ComboboxOptions()
|
||||
.DefaultIndex(TRACKER_COMBO_BUTTON_R)
|
||||
.ComponentAlignment(ComponentAlignments::Right)
|
||||
.LabelPosition(LabelPositions::Far)
|
||||
.Color(THEME_COLOR))) {
|
||||
if (CVarGetInteger(CVAR_TRACKER_ITEM("DisplayType.Main"), TRACKER_DISPLAY_ALWAYS) ==
|
||||
TRACKER_DISPLAY_COMBO_BUTTON) {
|
||||
if (CVarCombobox("Combo Button 1", CVAR_TRACKER_ITEM("ComboButton1"), buttons,
|
||||
ComboboxOptions()
|
||||
.DefaultIndex(TRACKER_COMBO_BUTTON_L)
|
||||
.ComponentAlignment(ComponentAlignments::Right)
|
||||
.LabelPosition(LabelPositions::Far)
|
||||
.Color(THEME_COLOR))) {
|
||||
shouldUpdateVectors = true;
|
||||
}
|
||||
if (CVarCombobox("Combo Button 2", CVAR_TRACKER_ITEM("ComboButton2"), buttons,
|
||||
ComboboxOptions()
|
||||
.DefaultIndex(TRACKER_COMBO_BUTTON_R)
|
||||
.ComponentAlignment(ComponentAlignments::Right)
|
||||
.LabelPosition(LabelPositions::Far)
|
||||
.Color(THEME_COLOR))) {
|
||||
shouldUpdateVectors = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
ImGui::Separator();
|
||||
CVarSliderInt("Icon size : %dpx", CVAR_TRACKER_ITEM("IconSize"),
|
||||
IntSliderOptions().Min(25).Max(128).DefaultValue(36).Color(THEME_COLOR));
|
||||
CVarSliderInt("Icon margins : %dpx", CVAR_TRACKER_ITEM("IconSpacing"),
|
||||
IntSliderOptions().Min(-5).Max(50).DefaultValue(12).Color(THEME_COLOR));
|
||||
CVarSliderInt("Text size : %dpx", CVAR_TRACKER_ITEM("TextSize"),
|
||||
IntSliderOptions().Min(1).Max(30).DefaultValue(13).Color(THEME_COLOR));
|
||||
|
||||
ImGui::NewLine();
|
||||
CVarCombobox("Ammo/Capacity Tracking", CVAR_TRACKER_ITEM("ItemCountType"), itemTrackerCapacityTrackOptions,
|
||||
ComboboxOptions()
|
||||
.DefaultIndex(ITEM_TRACKER_NUMBER_CURRENT_CAPACITY_ONLY)
|
||||
.ComponentAlignment(ComponentAlignments::Left)
|
||||
.LabelPosition(LabelPositions::Above)
|
||||
.Color(THEME_COLOR)
|
||||
.Tooltip("Customize what the numbers under each item are tracking."
|
||||
"\n\nNote: items without capacity upgrades will track ammo even in capacity mode"));
|
||||
if (CVarGetInteger(CVAR_TRACKER_ITEM("ItemCountType"), ITEM_TRACKER_NUMBER_CURRENT_CAPACITY_ONLY) ==
|
||||
ITEM_TRACKER_NUMBER_CURRENT_CAPACITY_ONLY ||
|
||||
CVarGetInteger(CVAR_TRACKER_ITEM("ItemCountType"), ITEM_TRACKER_NUMBER_CURRENT_CAPACITY_ONLY) ==
|
||||
ITEM_TRACKER_NUMBER_CURRENT_AMMO_ONLY) {
|
||||
if (CVarCheckbox("Align count to left side", CVAR_TRACKER_ITEM("ItemCountAlignLeft"),
|
||||
CheckboxOptions().Color(THEME_COLOR))) {
|
||||
shouldUpdateVectors = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
ImGui::Separator();
|
||||
CVarSliderInt("Icon size : %dpx", CVAR_TRACKER_ITEM("IconSize"),
|
||||
IntSliderOptions().Min(25).Max(128).DefaultValue(36).Color(THEME_COLOR));
|
||||
CVarSliderInt("Icon margins : %dpx", CVAR_TRACKER_ITEM("IconSpacing"),
|
||||
IntSliderOptions().Min(-5).Max(50).DefaultValue(12).Color(THEME_COLOR));
|
||||
CVarSliderInt("Text size : %dpx", CVAR_TRACKER_ITEM("TextSize"),
|
||||
IntSliderOptions().Min(1).Max(30).DefaultValue(13).Color(THEME_COLOR));
|
||||
|
||||
ImGui::NewLine();
|
||||
CVarCombobox("Ammo/Capacity Tracking", CVAR_TRACKER_ITEM("ItemCountType"), itemTrackerCapacityTrackOptions,
|
||||
ComboboxOptions()
|
||||
.DefaultIndex(ITEM_TRACKER_NUMBER_CURRENT_CAPACITY_ONLY)
|
||||
.ComponentAlignment(ComponentAlignments::Left)
|
||||
.LabelPosition(LabelPositions::Above)
|
||||
.Color(THEME_COLOR)
|
||||
.Tooltip("Customize what the numbers under each item are tracking."
|
||||
"\n\nNote: items without capacity upgrades will track ammo even in capacity mode"));
|
||||
if (CVarGetInteger(CVAR_TRACKER_ITEM("ItemCountType"), ITEM_TRACKER_NUMBER_CURRENT_CAPACITY_ONLY) ==
|
||||
ITEM_TRACKER_NUMBER_CURRENT_CAPACITY_ONLY ||
|
||||
CVarGetInteger(CVAR_TRACKER_ITEM("ItemCountType"), ITEM_TRACKER_NUMBER_CURRENT_CAPACITY_ONLY) ==
|
||||
ITEM_TRACKER_NUMBER_CURRENT_AMMO_ONLY) {
|
||||
if (CVarCheckbox("Align count to left side", CVAR_TRACKER_ITEM("ItemCountAlignLeft"),
|
||||
CheckboxOptions().Color(THEME_COLOR))) {
|
||||
CVarCombobox("Key Count Tracking", CVAR_TRACKER_ITEM("KeyCounts"), itemTrackerKeyTrackOptions,
|
||||
ComboboxOptions()
|
||||
.DefaultIndex(KEYS_COLLECTED_MAX)
|
||||
.ComponentAlignment(ComponentAlignments::Left)
|
||||
.LabelPosition(LabelPositions::Above)
|
||||
.Color(THEME_COLOR)
|
||||
.Tooltip("Customize what numbers are shown for key tracking."));
|
||||
|
||||
CVarCombobox("Triforce Piece Count Tracking", CVAR_TRACKER_ITEM("TriforcePieceCounts"),
|
||||
itemTrackerTriforcePieceTrackOptions,
|
||||
ComboboxOptions()
|
||||
.DefaultIndex(TRIFORCE_PIECE_COLLECTED_REQUIRED_MAX)
|
||||
.ComponentAlignment(ComponentAlignments::Left)
|
||||
.LabelPosition(LabelPositions::Above)
|
||||
.Color(THEME_COLOR)
|
||||
.Tooltip("Customize what numbers are shown for triforce piece tracking."));
|
||||
|
||||
ImGui::TableNextColumn();
|
||||
|
||||
if (CVarCombobox("Inventory", CVAR_TRACKER_ITEM("DisplayType.Inventory"), displayTypes,
|
||||
ComboboxOptions()
|
||||
.DefaultIndex(SECTION_DISPLAY_MAIN_WINDOW)
|
||||
.ComponentAlignment(ComponentAlignments::Right)
|
||||
.LabelPosition(LabelPositions::Far)
|
||||
.Color(THEME_COLOR))) {
|
||||
shouldUpdateVectors = true;
|
||||
}
|
||||
}
|
||||
|
||||
CVarCombobox("Key Count Tracking", CVAR_TRACKER_ITEM("KeyCounts"), itemTrackerKeyTrackOptions,
|
||||
ComboboxOptions()
|
||||
.DefaultIndex(KEYS_COLLECTED_MAX)
|
||||
.ComponentAlignment(ComponentAlignments::Left)
|
||||
.LabelPosition(LabelPositions::Above)
|
||||
.Color(THEME_COLOR)
|
||||
.Tooltip("Customize what numbers are shown for key tracking."));
|
||||
|
||||
CVarCombobox("Triforce Piece Count Tracking", CVAR_TRACKER_ITEM("TriforcePieceCounts"),
|
||||
itemTrackerTriforcePieceTrackOptions,
|
||||
ComboboxOptions()
|
||||
.DefaultIndex(TRIFORCE_PIECE_COLLECTED_REQUIRED_MAX)
|
||||
.ComponentAlignment(ComponentAlignments::Left)
|
||||
.LabelPosition(LabelPositions::Above)
|
||||
.Color(THEME_COLOR)
|
||||
.Tooltip("Customize what numbers are shown for triforce piece tracking."));
|
||||
|
||||
ImGui::TableNextColumn();
|
||||
|
||||
if (CVarCombobox("Inventory", CVAR_TRACKER_ITEM("DisplayType.Inventory"), displayTypes,
|
||||
ComboboxOptions()
|
||||
.DefaultIndex(SECTION_DISPLAY_MAIN_WINDOW)
|
||||
.ComponentAlignment(ComponentAlignments::Right)
|
||||
.LabelPosition(LabelPositions::Far)
|
||||
.Color(THEME_COLOR))) {
|
||||
shouldUpdateVectors = true;
|
||||
}
|
||||
if (CVarCombobox("Equipment", CVAR_TRACKER_ITEM("DisplayType.Equipment"), displayTypes,
|
||||
ComboboxOptions()
|
||||
.DefaultIndex(SECTION_DISPLAY_MAIN_WINDOW)
|
||||
.ComponentAlignment(ComponentAlignments::Right)
|
||||
.LabelPosition(LabelPositions::Far)
|
||||
.Color(THEME_COLOR))) {
|
||||
shouldUpdateVectors = true;
|
||||
}
|
||||
if (CVarCombobox("Misc", CVAR_TRACKER_ITEM("DisplayType.Misc"), displayTypes,
|
||||
ComboboxOptions()
|
||||
.DefaultIndex(SECTION_DISPLAY_MAIN_WINDOW)
|
||||
.ComponentAlignment(ComponentAlignments::Right)
|
||||
.LabelPosition(LabelPositions::Far)
|
||||
.Color(THEME_COLOR))) {
|
||||
shouldUpdateVectors = true;
|
||||
}
|
||||
if (CVarCombobox("Dungeon Rewards", CVAR_TRACKER_ITEM("DisplayType.DungeonRewards"), displayTypes,
|
||||
ComboboxOptions()
|
||||
.DefaultIndex(SECTION_DISPLAY_MAIN_WINDOW)
|
||||
.ComponentAlignment(ComponentAlignments::Right)
|
||||
.LabelPosition(LabelPositions::Far)
|
||||
.Color(THEME_COLOR))) {
|
||||
shouldUpdateVectors = true;
|
||||
}
|
||||
if (CVarGetInteger(CVAR_TRACKER_ITEM("DisplayType.DungeonRewards"), SECTION_DISPLAY_MAIN_WINDOW) ==
|
||||
SECTION_DISPLAY_SEPARATE) {
|
||||
if (CVarCheckbox("Circle display", CVAR_TRACKER_ITEM("DungeonRewardsLayout"),
|
||||
CheckboxOptions().DefaultValue(false).Color(THEME_COLOR))) {
|
||||
if (CVarCombobox("Equipment", CVAR_TRACKER_ITEM("DisplayType.Equipment"), displayTypes,
|
||||
ComboboxOptions()
|
||||
.DefaultIndex(SECTION_DISPLAY_MAIN_WINDOW)
|
||||
.ComponentAlignment(ComponentAlignments::Right)
|
||||
.LabelPosition(LabelPositions::Far)
|
||||
.Color(THEME_COLOR))) {
|
||||
shouldUpdateVectors = true;
|
||||
}
|
||||
}
|
||||
if (CVarCombobox("Songs", CVAR_TRACKER_ITEM("DisplayType.Songs"), displayTypes,
|
||||
ComboboxOptions()
|
||||
.DefaultIndex(SECTION_DISPLAY_MAIN_WINDOW)
|
||||
.ComponentAlignment(ComponentAlignments::Right)
|
||||
.LabelPosition(LabelPositions::Far)
|
||||
.Color(THEME_COLOR))) {
|
||||
shouldUpdateVectors = true;
|
||||
}
|
||||
if (CVarCombobox("Dungeon Items", CVAR_TRACKER_ITEM("DisplayType.DungeonItems"), displayTypes,
|
||||
ComboboxOptions()
|
||||
.DefaultIndex(SECTION_DISPLAY_HIDDEN)
|
||||
.ComponentAlignment(ComponentAlignments::Right)
|
||||
.LabelPosition(LabelPositions::Far)
|
||||
.Color(THEME_COLOR))) {
|
||||
shouldUpdateVectors = true;
|
||||
}
|
||||
if (CVarGetInteger(CVAR_TRACKER_ITEM("DisplayType.DungeonItems"), SECTION_DISPLAY_HIDDEN) !=
|
||||
SECTION_DISPLAY_HIDDEN) {
|
||||
if (CVarGetInteger(CVAR_TRACKER_ITEM("DisplayType.DungeonItems"), SECTION_DISPLAY_HIDDEN) ==
|
||||
if (CVarCombobox("Misc", CVAR_TRACKER_ITEM("DisplayType.Misc"), displayTypes,
|
||||
ComboboxOptions()
|
||||
.DefaultIndex(SECTION_DISPLAY_MAIN_WINDOW)
|
||||
.ComponentAlignment(ComponentAlignments::Right)
|
||||
.LabelPosition(LabelPositions::Far)
|
||||
.Color(THEME_COLOR))) {
|
||||
shouldUpdateVectors = true;
|
||||
}
|
||||
if (CVarCombobox("Dungeon Rewards", CVAR_TRACKER_ITEM("DisplayType.DungeonRewards"), displayTypes,
|
||||
ComboboxOptions()
|
||||
.DefaultIndex(SECTION_DISPLAY_MAIN_WINDOW)
|
||||
.ComponentAlignment(ComponentAlignments::Right)
|
||||
.LabelPosition(LabelPositions::Far)
|
||||
.Color(THEME_COLOR))) {
|
||||
shouldUpdateVectors = true;
|
||||
}
|
||||
if (CVarGetInteger(CVAR_TRACKER_ITEM("DisplayType.DungeonRewards"), SECTION_DISPLAY_MAIN_WINDOW) ==
|
||||
SECTION_DISPLAY_SEPARATE) {
|
||||
if (CVarCheckbox("Horizontal display", CVAR_TRACKER_ITEM("DungeonItems.Layout"),
|
||||
CheckboxOptions().DefaultValue(true).Color(THEME_COLOR))) {
|
||||
if (CVarCheckbox("Circle display", CVAR_TRACKER_ITEM("DungeonRewardsLayout"),
|
||||
CheckboxOptions().DefaultValue(false).Color(THEME_COLOR))) {
|
||||
shouldUpdateVectors = true;
|
||||
}
|
||||
}
|
||||
if (CVarCheckbox("Maps and compasses", CVAR_TRACKER_ITEM("DungeonItems.DisplayMaps"),
|
||||
CheckboxOptions().DefaultValue(true).Color(THEME_COLOR))) {
|
||||
if (CVarCombobox("Songs", CVAR_TRACKER_ITEM("DisplayType.Songs"), displayTypes,
|
||||
ComboboxOptions()
|
||||
.DefaultIndex(SECTION_DISPLAY_MAIN_WINDOW)
|
||||
.ComponentAlignment(ComponentAlignments::Right)
|
||||
.LabelPosition(LabelPositions::Far)
|
||||
.Color(THEME_COLOR))) {
|
||||
shouldUpdateVectors = true;
|
||||
}
|
||||
}
|
||||
if (CVarCombobox("Greg", CVAR_TRACKER_ITEM("DisplayType.Greg"), extendedDisplayTypes,
|
||||
ComboboxOptions()
|
||||
.DefaultIndex(SECTION_DISPLAY_EXTENDED_HIDDEN)
|
||||
.ComponentAlignment(ComponentAlignments::Right)
|
||||
.LabelPosition(LabelPositions::Far)
|
||||
.Color(THEME_COLOR))) {
|
||||
shouldUpdateVectors = true;
|
||||
}
|
||||
|
||||
if (CVarCombobox("Triforce Pieces", CVAR_TRACKER_ITEM("DisplayType.TriforcePieces"), displayTypes,
|
||||
ComboboxOptions()
|
||||
.DefaultIndex(SECTION_DISPLAY_HIDDEN)
|
||||
.ComponentAlignment(ComponentAlignments::Right)
|
||||
.LabelPosition(LabelPositions::Far)
|
||||
.Color(THEME_COLOR))) {
|
||||
shouldUpdateVectors = true;
|
||||
}
|
||||
|
||||
if (CVarCombobox("Boss Souls", CVAR_TRACKER_ITEM("DisplayType.BossSouls"), displayTypes,
|
||||
ComboboxOptions()
|
||||
.DefaultIndex(SECTION_DISPLAY_HIDDEN)
|
||||
.ComponentAlignment(ComponentAlignments::Right)
|
||||
.LabelPosition(LabelPositions::Far)
|
||||
.Color(THEME_COLOR))) {
|
||||
shouldUpdateVectors = true;
|
||||
}
|
||||
|
||||
if (CVarCombobox("Ocarina Buttons", CVAR_TRACKER_ITEM("DisplayType.OcarinaButtons"), displayTypes,
|
||||
ComboboxOptions()
|
||||
.DefaultIndex(SECTION_DISPLAY_HIDDEN)
|
||||
.ComponentAlignment(ComponentAlignments::Right)
|
||||
.LabelPosition(LabelPositions::Far)
|
||||
.Color(THEME_COLOR))) {
|
||||
shouldUpdateVectors = true;
|
||||
}
|
||||
|
||||
if (CVarCombobox("Overworld Keys", CVAR_TRACKER_ITEM("DisplayType.OverworldKeys"), displayTypes,
|
||||
ComboboxOptions()
|
||||
.DefaultIndex(SECTION_DISPLAY_HIDDEN)
|
||||
.ComponentAlignment(ComponentAlignments::Right)
|
||||
.LabelPosition(LabelPositions::Far)
|
||||
.Color(THEME_COLOR))) {
|
||||
shouldUpdateVectors = true;
|
||||
}
|
||||
|
||||
if (CVarCombobox("Fishing Pole", CVAR_TRACKER_ITEM("DisplayType.FishingPole"), extendedDisplayTypes,
|
||||
ComboboxOptions()
|
||||
.DefaultIndex(SECTION_DISPLAY_EXTENDED_HIDDEN)
|
||||
.ComponentAlignment(ComponentAlignments::Right)
|
||||
.LabelPosition(LabelPositions::Far)
|
||||
.Color(THEME_COLOR))) {
|
||||
shouldUpdateVectors = true;
|
||||
}
|
||||
|
||||
if (CVarCombobox("Total Checks", "gTrackers.ItemTracker.TotalChecks.DisplayType", minimalDisplayTypes,
|
||||
ComboboxOptions()
|
||||
.DefaultIndex(SECTION_DISPLAY_MINIMAL_HIDDEN)
|
||||
.ComponentAlignment(ComponentAlignments::Right)
|
||||
.LabelPosition(LabelPositions::Far)
|
||||
.Color(THEME_COLOR))) {
|
||||
shouldUpdateVectors = true;
|
||||
}
|
||||
|
||||
if (CVarGetInteger(CVAR_TRACKER_ITEM("DisplayType.Main"), TRACKER_DISPLAY_ALWAYS) == TRACKER_DISPLAY_ALWAYS) {
|
||||
if (CVarCombobox("Personal notes", CVAR_TRACKER_ITEM("DisplayType.Notes"), displayTypes,
|
||||
if (CVarCombobox("Dungeon Items", CVAR_TRACKER_ITEM("DisplayType.DungeonItems"), displayTypes,
|
||||
ComboboxOptions()
|
||||
.DefaultIndex(SECTION_DISPLAY_HIDDEN)
|
||||
.ComponentAlignment(ComponentAlignments::Right)
|
||||
@@ -1952,14 +1870,104 @@ void ItemTrackerSettingsWindow::DrawElement() {
|
||||
.Color(THEME_COLOR))) {
|
||||
shouldUpdateVectors = true;
|
||||
}
|
||||
}
|
||||
CVarCheckbox("Show Hookshot Identifiers", CVAR_TRACKER_ITEM("HookshotIdentifier"),
|
||||
CheckboxOptions()
|
||||
.Tooltip("Shows an 'H' or an 'L' to more easiely distinguish between Hookshot and Longshot.")
|
||||
.Color(THEME_COLOR));
|
||||
if (CVarGetInteger(CVAR_TRACKER_ITEM("DisplayType.DungeonItems"), SECTION_DISPLAY_HIDDEN) !=
|
||||
SECTION_DISPLAY_HIDDEN) {
|
||||
if (CVarGetInteger(CVAR_TRACKER_ITEM("DisplayType.DungeonItems"), SECTION_DISPLAY_HIDDEN) ==
|
||||
SECTION_DISPLAY_SEPARATE) {
|
||||
if (CVarCheckbox("Horizontal display", CVAR_TRACKER_ITEM("DungeonItems.Layout"),
|
||||
CheckboxOptions().DefaultValue(true).Color(THEME_COLOR))) {
|
||||
shouldUpdateVectors = true;
|
||||
}
|
||||
}
|
||||
if (CVarCheckbox("Maps and compasses", CVAR_TRACKER_ITEM("DungeonItems.DisplayMaps"),
|
||||
CheckboxOptions().DefaultValue(true).Color(THEME_COLOR))) {
|
||||
shouldUpdateVectors = true;
|
||||
}
|
||||
}
|
||||
if (CVarCombobox("Greg", CVAR_TRACKER_ITEM("DisplayType.Greg"), extendedDisplayTypes,
|
||||
ComboboxOptions()
|
||||
.DefaultIndex(SECTION_DISPLAY_EXTENDED_HIDDEN)
|
||||
.ComponentAlignment(ComponentAlignments::Right)
|
||||
.LabelPosition(LabelPositions::Far)
|
||||
.Color(THEME_COLOR))) {
|
||||
shouldUpdateVectors = true;
|
||||
}
|
||||
|
||||
ImGui::PopStyleVar(1);
|
||||
ImGui::EndTable();
|
||||
if (CVarCombobox("Triforce Pieces", CVAR_TRACKER_ITEM("DisplayType.TriforcePieces"), displayTypes,
|
||||
ComboboxOptions()
|
||||
.DefaultIndex(SECTION_DISPLAY_HIDDEN)
|
||||
.ComponentAlignment(ComponentAlignments::Right)
|
||||
.LabelPosition(LabelPositions::Far)
|
||||
.Color(THEME_COLOR))) {
|
||||
shouldUpdateVectors = true;
|
||||
}
|
||||
|
||||
if (CVarCombobox("Boss Souls", CVAR_TRACKER_ITEM("DisplayType.BossSouls"), displayTypes,
|
||||
ComboboxOptions()
|
||||
.DefaultIndex(SECTION_DISPLAY_HIDDEN)
|
||||
.ComponentAlignment(ComponentAlignments::Right)
|
||||
.LabelPosition(LabelPositions::Far)
|
||||
.Color(THEME_COLOR))) {
|
||||
shouldUpdateVectors = true;
|
||||
}
|
||||
|
||||
if (CVarCombobox("Ocarina Buttons", CVAR_TRACKER_ITEM("DisplayType.OcarinaButtons"), displayTypes,
|
||||
ComboboxOptions()
|
||||
.DefaultIndex(SECTION_DISPLAY_HIDDEN)
|
||||
.ComponentAlignment(ComponentAlignments::Right)
|
||||
.LabelPosition(LabelPositions::Far)
|
||||
.Color(THEME_COLOR))) {
|
||||
shouldUpdateVectors = true;
|
||||
}
|
||||
|
||||
if (CVarCombobox("Overworld Keys", CVAR_TRACKER_ITEM("DisplayType.OverworldKeys"), displayTypes,
|
||||
ComboboxOptions()
|
||||
.DefaultIndex(SECTION_DISPLAY_HIDDEN)
|
||||
.ComponentAlignment(ComponentAlignments::Right)
|
||||
.LabelPosition(LabelPositions::Far)
|
||||
.Color(THEME_COLOR))) {
|
||||
shouldUpdateVectors = true;
|
||||
}
|
||||
|
||||
if (CVarCombobox("Fishing Pole", CVAR_TRACKER_ITEM("DisplayType.FishingPole"), extendedDisplayTypes,
|
||||
ComboboxOptions()
|
||||
.DefaultIndex(SECTION_DISPLAY_EXTENDED_HIDDEN)
|
||||
.ComponentAlignment(ComponentAlignments::Right)
|
||||
.LabelPosition(LabelPositions::Far)
|
||||
.Color(THEME_COLOR))) {
|
||||
shouldUpdateVectors = true;
|
||||
}
|
||||
|
||||
if (CVarCombobox("Total Checks", "gTrackers.ItemTracker.TotalChecks.DisplayType", minimalDisplayTypes,
|
||||
ComboboxOptions()
|
||||
.DefaultIndex(SECTION_DISPLAY_MINIMAL_HIDDEN)
|
||||
.ComponentAlignment(ComponentAlignments::Right)
|
||||
.LabelPosition(LabelPositions::Far)
|
||||
.Color(THEME_COLOR))) {
|
||||
shouldUpdateVectors = true;
|
||||
}
|
||||
|
||||
if (CVarGetInteger(CVAR_TRACKER_ITEM("WindowType"), TRACKER_WINDOW_FLOATING) == TRACKER_WINDOW_WINDOW ||
|
||||
(CVarGetInteger(CVAR_TRACKER_ITEM("WindowType"), TRACKER_WINDOW_FLOATING) == TRACKER_WINDOW_FLOATING &&
|
||||
CVarGetInteger(CVAR_TRACKER_ITEM("DisplayType.Main"), TRACKER_DISPLAY_ALWAYS) !=
|
||||
TRACKER_DISPLAY_COMBO_BUTTON)) {
|
||||
if (CVarCombobox("Personal notes", CVAR_TRACKER_ITEM("DisplayType.Notes"), displayTypes,
|
||||
ComboboxOptions()
|
||||
.DefaultIndex(SECTION_DISPLAY_HIDDEN)
|
||||
.ComponentAlignment(ComponentAlignments::Right)
|
||||
.LabelPosition(LabelPositions::Far)
|
||||
.Color(THEME_COLOR))) {
|
||||
shouldUpdateVectors = true;
|
||||
}
|
||||
}
|
||||
CVarCheckbox("Show Hookshot Identifiers", CVAR_TRACKER_ITEM("HookshotIdentifier"),
|
||||
CheckboxOptions()
|
||||
.Tooltip("Shows an 'H' or an 'L' to more easiely distinguish between Hookshot and Longshot.")
|
||||
.Color(THEME_COLOR));
|
||||
|
||||
ImGui::PopStyleVar(1);
|
||||
ImGui::EndTable();
|
||||
}
|
||||
}
|
||||
|
||||
void ItemTrackerWindow::InitElement() {
|
||||
|
||||
@@ -232,6 +232,8 @@ extern "C" void Randomizer_InitSaveFile() {
|
||||
// Reset triforce pieces collected.
|
||||
gSaveContext.ship.quest.data.randomizer.triforcePiecesCollected = 0;
|
||||
|
||||
SetStartingItems();
|
||||
|
||||
// Set Cutscene flags and texts to skip them.
|
||||
Flags_SetEventChkInf(EVENTCHKINF_FIRST_SPOKE_TO_MIDO);
|
||||
Flags_SetInfTable(INFTABLE_SPOKE_TO_KAEPORA_IN_LAKE_HYLIA);
|
||||
@@ -269,9 +271,9 @@ extern "C" void Randomizer_InitSaveFile() {
|
||||
|
||||
// Remove One Time Scrubs with Scrubsanity off
|
||||
if (Randomizer_GetSettingValue(RSK_SHUFFLE_SCRUBS) == RO_SCRUBS_OFF) {
|
||||
Flags_SetRandomizerInf(RAND_INF_SCRUBS_PURCHASED_LW_DEKU_SCRUB_NEAR_BRIDGE);
|
||||
Flags_SetRandomizerInf(RAND_INF_SCRUBS_PURCHASED_LW_DEKU_SCRUB_GROTTO_FRONT);
|
||||
Flags_SetRandomizerInf(RAND_INF_SCRUBS_PURCHASED_HF_DEKU_SCRUB_GROTTO);
|
||||
Flags_SetItemGetInf(ITEMGETINF_DEKU_SCRUB_HEART_PIECE);
|
||||
Flags_SetInfTable(INFTABLE_BOUGHT_STICK_UPGRADE);
|
||||
Flags_SetInfTable(INFTABLE_BOUGHT_NUT_UPGRADE);
|
||||
}
|
||||
|
||||
int startingAge = OTRGlobals::Instance->gRandoContext->GetOption(RSK_SELECTED_STARTING_AGE).Get();
|
||||
@@ -430,6 +432,4 @@ extern "C" void Randomizer_InitSaveFile() {
|
||||
gSaveContext.itemGetInf[3] |= 0x800; // Bunny Hood related
|
||||
gSaveContext.itemGetInf[3] |= 0x8000; // Obtained Mask of Truth
|
||||
}
|
||||
|
||||
SetStartingItems();
|
||||
}
|
||||
|
||||
@@ -120,6 +120,7 @@ void Settings::CreateOptions() {
|
||||
OPT_U8(RSK_DOOR_OF_TIME, "Door of Time", {"Closed", "Song only", "Open"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("DoorOfTime"), mOptionDescriptions[RSK_DOOR_OF_TIME], WidgetType::Combobox);
|
||||
OPT_U8(RSK_ZORAS_FOUNTAIN, "Zora's Fountain", {"Closed", "Closed as child", "Open"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("ZorasFountain"), mOptionDescriptions[RSK_ZORAS_FOUNTAIN]);
|
||||
OPT_U8(RSK_SLEEPING_WATERFALL, "Sleeping Waterfall", {"Closed", "Open"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("SleepingWaterfall"), mOptionDescriptions[RSK_SLEEPING_WATERFALL]);
|
||||
OPT_U8(RSK_JABU_OPEN, "Jabu-Jabu", {"Closed", "Open"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("JabuJabu"), mOptionDescriptions[RSK_JABU_OPEN]);
|
||||
OPT_BOOL(RSK_LOCK_OVERWORLD_DOORS, "Lock Overworld Doors", CVAR_RANDOMIZER_SETTING("LockOverworldDoors"), mOptionDescriptions[RSK_LOCK_OVERWORLD_DOORS]);
|
||||
OPT_U8(RSK_GERUDO_FORTRESS, "Fortress Carpenters", {"Normal", "Fast", "Free"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("FortressCarpenters"), mOptionDescriptions[RSK_GERUDO_FORTRESS]);
|
||||
OPT_U8(RSK_RAINBOW_BRIDGE, "Rainbow Bridge", {"Vanilla", "Always open", "Stones", "Medallions", "Dungeon rewards", "Dungeons", "Tokens", "Greg"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("RainbowBridge"), mOptionDescriptions[RSK_RAINBOW_BRIDGE], WidgetType::Combobox, RO_BRIDGE_VANILLA, false, IMFLAG_NONE);
|
||||
@@ -250,7 +251,7 @@ void Settings::CreateOptions() {
|
||||
OPT_U8(RSK_LACS_REWARD_COUNT, "GCBK Reward Count", {NumOpts(0, 10)}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("LacsRewardCount"), "", WidgetType::Slider, 9, true);
|
||||
OPT_U8(RSK_LACS_DUNGEON_COUNT, "GCBK Dungeon Count", {NumOpts(0, 9)}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("LacsDungeonCount"), "", WidgetType::Slider, 8, true);
|
||||
OPT_U8(RSK_LACS_TOKEN_COUNT, "GCBK Token Count", {NumOpts(0, 100)}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("LacsTokenCount"), "", WidgetType::Slider, 100, true);
|
||||
OPT_U8(RSK_LACS_OPTIONS, "GCBK LACS Reward Options", {"Standard Reward", "Greg as Reward", "Greg as Wildcard"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("LacsRewardOptions"), "", WidgetType::Combobox, RO_LACS_STANDARD_REWARD);
|
||||
OPT_U8(RSK_LACS_OPTIONS, "GCBK LACS Reward Options", {"Standard Reward", "Greg as Reward", "Greg as Wildcard"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("LacsRewardOptions"), mOptionDescriptions[RSK_LACS_OPTIONS], WidgetType::Combobox, RO_LACS_STANDARD_REWARD);
|
||||
OPT_U8(RSK_KEYRINGS, "Key Rings", {"Off", "Random", "Count", "Selection"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("ShuffleKeyRings"), mOptionDescriptions[RSK_KEYRINGS], WidgetType::Combobox, RO_KEYRINGS_OFF);
|
||||
OPT_U8(RSK_KEYRINGS_RANDOM_COUNT, "Keyring Dungeon Count", {NumOpts(0, 9)}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("ShuffleKeyRingsRandomCount"), "", WidgetType::Slider, 8);
|
||||
OPT_U8(RSK_KEYRINGS_GERUDO_FORTRESS, "Gerudo Fortress Keyring", {"No", "Random", "Yes"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("ShuffleKeyRingsGerudoFortress"), "", WidgetType::Combobox, 0);
|
||||
@@ -1151,6 +1152,7 @@ void Settings::CreateOptions() {
|
||||
&mOptions[RSK_DOOR_OF_TIME],
|
||||
&mOptions[RSK_ZORAS_FOUNTAIN],
|
||||
&mOptions[RSK_SLEEPING_WATERFALL],
|
||||
&mOptions[RSK_JABU_OPEN],
|
||||
&mOptions[RSK_LOCK_OVERWORLD_DOORS],
|
||||
},
|
||||
WidgetContainerType::COLUMN);
|
||||
@@ -1405,6 +1407,7 @@ void Settings::CreateOptions() {
|
||||
&mOptions[RSK_DOOR_OF_TIME],
|
||||
&mOptions[RSK_ZORAS_FOUNTAIN],
|
||||
&mOptions[RSK_SLEEPING_WATERFALL],
|
||||
&mOptions[RSK_JABU_OPEN],
|
||||
&mOptions[RSK_LOCK_OVERWORLD_DOORS],
|
||||
&mOptions[RSK_GERUDO_FORTRESS],
|
||||
&mOptions[RSK_RAINBOW_BRIDGE],
|
||||
@@ -1739,6 +1742,14 @@ TrickOption& Settings::GetTrickOption(const RandomizerTrick key) {
|
||||
return mTrickOptions[key];
|
||||
}
|
||||
|
||||
int Settings::GetRandomizerTrickByName(const std::string& name) {
|
||||
const auto& it = mTrickNameToEnum.find(name);
|
||||
if (it == mTrickNameToEnum.end()) {
|
||||
return -1;
|
||||
}
|
||||
return it->second;
|
||||
}
|
||||
|
||||
void Context::ResetTrickOptions() {
|
||||
for (int count = 0; count < RT_MAX; count++) {
|
||||
mTrickOptions[count].Set(0); // RANDOTODO this can probably be done better
|
||||
@@ -2560,7 +2571,7 @@ void Context::FinalizeSettings(const std::set<RandomizerCheck>& excludedLocation
|
||||
}
|
||||
if (!mOptions[RSK_SHUFFLE_MASTER_SWORD]) {
|
||||
if (mOptions[RSK_STARTING_MASTER_SWORD]) {
|
||||
this->GetItemLocation(RC_MASTER_SWORD_PEDESTAL)->SetExcludedOption(1);
|
||||
this->GetItemLocation(RC_TOT_MASTER_SWORD)->SetExcludedOption(1);
|
||||
}
|
||||
}
|
||||
if (!mOptions[RSK_SHUFFLE_OCARINA]) {
|
||||
|
||||
@@ -50,6 +50,14 @@ class Settings {
|
||||
*/
|
||||
TrickOption& GetTrickOption(RandomizerTrick key);
|
||||
|
||||
/**
|
||||
* @brief Get the RandomizerTrick corresponding to the provided name.
|
||||
*
|
||||
* @param name
|
||||
* @return int RandomizerTrick index or -1 if not found
|
||||
*/
|
||||
int GetRandomizerTrickByName(const std::string& name);
|
||||
|
||||
/**
|
||||
* @brief Returns a reference to the entire array of options.
|
||||
*
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
#include <libultraship/bridge.h>
|
||||
#include "soh/OTRGlobals.h"
|
||||
#include "soh/Enhancements/randomizer/randomizerTypes.h"
|
||||
#include "soh/Enhancements/game-interactor/GameInteractor.h"
|
||||
#include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h"
|
||||
#include "soh/Enhancements/enhancementTypes.h"
|
||||
@@ -13,16 +12,19 @@ extern "C" {
|
||||
#include "src/overlays/actors/ovl_Bg_Treemouth/z_bg_treemouth.h"
|
||||
#include "src/overlays/actors/ovl_En_Owl/z_en_owl.h"
|
||||
#include "src/overlays/actors/ovl_En_Go2/z_en_go2.h"
|
||||
#include "src/overlays/actors/ovl_En_Heishi2/z_en_heishi2.h"
|
||||
#include "src/overlays/actors/ovl_En_Ko/z_en_ko.h"
|
||||
#include "src/overlays/actors/ovl_En_Ma1/z_en_ma1.h"
|
||||
#include "src/overlays/actors/ovl_En_Ru2/z_en_ru2.h"
|
||||
#include "src/overlays/actors/ovl_En_Zl4/z_en_zl4.h"
|
||||
#include "src/overlays/actors/ovl_En_Box/z_en_box.h"
|
||||
#include "src/overlays/actors/ovl_Demo_Im/z_demo_im.h"
|
||||
#include "src/overlays/actors/ovl_Demo_Kekkai/z_demo_kekkai.h"
|
||||
#include "src/overlays/actors/ovl_En_Sa/z_en_sa.h"
|
||||
#include "src/overlays/actors/ovl_Bg_Ddan_Kd/z_bg_ddan_kd.h"
|
||||
#include "src/overlays/actors/ovl_En_Tk/z_en_tk.h"
|
||||
#include "src/overlays/actors/ovl_En_Fu/z_en_fu.h"
|
||||
#include "src/overlays/actors/ovl_En_Jj/z_en_jj.h"
|
||||
#include "src/overlays/actors/ovl_En_Daiku/z_en_daiku.h"
|
||||
#include "src/overlays/actors/ovl_Bg_Spot02_Objects/z_bg_spot02_objects.h"
|
||||
#include "src/overlays/actors/ovl_Bg_Spot03_Taki/z_bg_spot03_taki.h"
|
||||
@@ -45,6 +47,10 @@ extern void EnGo2_CurledUp(EnGo2* enGo2, PlayState* play);
|
||||
extern void EnRu2_SetEncounterSwitchFlag(EnRu2* enRu2, PlayState* play);
|
||||
|
||||
extern void EnDaiku_EscapeSuccess(EnDaiku* enDaiku, PlayState* play);
|
||||
|
||||
extern void EnJj_WaitToOpenMouth(EnJj* enJj, PlayState* play);
|
||||
extern void EnJj_WaitForFish(EnJj* enJj, PlayState* play);
|
||||
extern void EnJj_SetupAction(EnJj* enJj, EnJjActionFunc actionFunc);
|
||||
}
|
||||
|
||||
#define RAND_GET_OPTION(option) Rando::Context::GetInstance()->GetOption(option).Get()
|
||||
@@ -158,7 +164,7 @@ void TimeSaverOnVanillaBehaviorHandler(GIVanillaBehavior id, bool* should, va_li
|
||||
*should = false;
|
||||
}
|
||||
|
||||
u8 meetsBurningKakRequirements = LINK_IS_ADULT &&
|
||||
u8 meetsBurningKakRequirements = LINK_IS_ADULT && gSaveContext.cutsceneIndex < 0xFFF0 &&
|
||||
gSaveContext.entranceIndex == ENTR_KAKARIKO_VILLAGE_FRONT_GATE &&
|
||||
Flags_GetEventChkInf(EVENTCHKINF_USED_FOREST_TEMPLE_BLUE_WARP) &&
|
||||
Flags_GetEventChkInf(EVENTCHKINF_USED_FIRE_TEMPLE_BLUE_WARP) &&
|
||||
@@ -217,6 +223,25 @@ void TimeSaverOnVanillaBehaviorHandler(GIVanillaBehavior id, bool* should, va_li
|
||||
if (CVarGetInteger(CVAR_ENHANCEMENT("TimeSavers.SkipCutscene.Entrances"), IS_RANDO) &&
|
||||
(entranceFlag != EVENTCHKINF_EPONA_OBTAINED) && entranceIndex != ENTR_SPIRIT_TEMPLE_BOSS_ENTRANCE) {
|
||||
*should = false;
|
||||
|
||||
// Check for dispulsion of Ganon's Tower barrier
|
||||
switch (entranceIndex) {
|
||||
case ENTR_INSIDE_GANONS_CASTLE_2:
|
||||
case ENTR_INSIDE_GANONS_CASTLE_3:
|
||||
case ENTR_INSIDE_GANONS_CASTLE_4:
|
||||
case ENTR_INSIDE_GANONS_CASTLE_5:
|
||||
case ENTR_INSIDE_GANONS_CASTLE_6:
|
||||
case ENTR_INSIDE_GANONS_CASTLE_7:
|
||||
if (Flags_GetEventChkInf(EVENTCHKINF_COMPLETED_FOREST_TRIAL) &&
|
||||
Flags_GetEventChkInf(EVENTCHKINF_COMPLETED_WATER_TRIAL) &&
|
||||
Flags_GetEventChkInf(EVENTCHKINF_COMPLETED_SHADOW_TRIAL) &&
|
||||
Flags_GetEventChkInf(EVENTCHKINF_COMPLETED_FIRE_TRIAL) &&
|
||||
Flags_GetEventChkInf(EVENTCHKINF_COMPLETED_LIGHT_TRIAL) &&
|
||||
Flags_GetEventChkInf(EVENTCHKINF_COMPLETED_SPIRIT_TRIAL)) {
|
||||
Flags_SetEventChkInf(EVENTCHKINF_DISPELLED_GANONS_TOWER_BARRIER);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
@@ -275,6 +300,12 @@ void TimeSaverOnVanillaBehaviorHandler(GIVanillaBehavior id, bool* should, va_li
|
||||
}
|
||||
switch (actor->id) {
|
||||
case ACTOR_OBJ_SWITCH: {
|
||||
if (((actor->params == 8224 && gPlayState->sceneNum == SCENE_DODONGOS_CAVERN) ||
|
||||
(actor->params == 6979 && gPlayState->sceneNum == SCENE_WATER_TEMPLE) ||
|
||||
(actor->params == 8961 && gPlayState->sceneNum == SCENE_SPIRIT_TEMPLE)) &&
|
||||
CVarGetInteger(CVAR_ENHANCEMENT("TimeSavers.SkipCutscene.GlitchAiding"), 0)) {
|
||||
break;
|
||||
}
|
||||
ObjSwitch* switchActor = (ObjSwitch*)actor;
|
||||
switchActor->cooldownTimer = 0;
|
||||
*should = false;
|
||||
@@ -310,6 +341,16 @@ void TimeSaverOnVanillaBehaviorHandler(GIVanillaBehavior id, bool* should, va_li
|
||||
*should = false;
|
||||
break;
|
||||
}
|
||||
case ACTOR_EN_BOX: {
|
||||
if (actor->params == -30457 && gPlayState->sceneNum == SCENE_JABU_JABU &&
|
||||
CVarGetInteger(CVAR_ENHANCEMENT("TimeSavers.SkipCutscene.GlitchAiding"), 0)) {
|
||||
break;
|
||||
}
|
||||
EnBox* boxActor = (EnBox*)actor;
|
||||
*should = false;
|
||||
RateLimitedSuccessChime();
|
||||
break;
|
||||
}
|
||||
case ACTOR_BG_HIDAN_FWBIG:
|
||||
case ACTOR_EN_EX_ITEM:
|
||||
case ACTOR_EN_DNT_NOMAL:
|
||||
@@ -322,7 +363,6 @@ void TimeSaverOnVanillaBehaviorHandler(GIVanillaBehavior id, bool* should, va_li
|
||||
case ACTOR_DOOR_SHUTTER:
|
||||
case ACTOR_BG_ICE_SHUTTER:
|
||||
case ACTOR_OBJ_LIGHTSWITCH:
|
||||
case ACTOR_EN_BOX:
|
||||
case ACTOR_OBJ_SYOKUDAI:
|
||||
case ACTOR_OBJ_TIMEBLOCK:
|
||||
case ACTOR_EN_PO_SISTERS:
|
||||
@@ -349,6 +389,11 @@ void TimeSaverOnVanillaBehaviorHandler(GIVanillaBehavior id, bool* should, va_li
|
||||
}
|
||||
break;
|
||||
}
|
||||
case VB_FREEZE_LINK_FOR_FOREST_PILLARS:
|
||||
if (CVarGetInteger(CVAR_ENHANCEMENT("TimeSavers.SkipCutscene.OnePoint"), IS_RANDO)) {
|
||||
*should = false;
|
||||
}
|
||||
break;
|
||||
case VB_SHOW_TITLE_CARD:
|
||||
if (CVarGetInteger(CVAR_ENHANCEMENT("TimeSavers.DisableTitleCard"), IS_RANDO)) {
|
||||
*should = false;
|
||||
@@ -441,6 +486,26 @@ void TimeSaverOnVanillaBehaviorHandler(GIVanillaBehavior id, bool* should, va_li
|
||||
*should = false;
|
||||
}
|
||||
break;
|
||||
case VB_PLAY_DISPEL_BARRIER_CS: {
|
||||
if (CVarGetInteger(CVAR_ENHANCEMENT("TimeSavers.SkipCutscene.OnePoint"), IS_RANDO)) {
|
||||
static s16 trialEntrances[] = {
|
||||
0,
|
||||
ENTR_INSIDE_GANONS_CASTLE_3,
|
||||
ENTR_INSIDE_GANONS_CASTLE_6,
|
||||
ENTR_INSIDE_GANONS_CASTLE_5,
|
||||
ENTR_INSIDE_GANONS_CASTLE_4,
|
||||
ENTR_INSIDE_GANONS_CASTLE_7,
|
||||
ENTR_INSIDE_GANONS_CASTLE_2,
|
||||
};
|
||||
RateLimitedSuccessChime();
|
||||
DemoKekkai* kekkai = va_arg(args, DemoKekkai*);
|
||||
gPlayState->nextEntranceIndex = trialEntrances[kekkai->actor.params];
|
||||
gPlayState->transitionTrigger = TRANS_TRIGGER_START;
|
||||
gPlayState->transitionType = TRANS_TYPE_FADE_BLACK;
|
||||
*should = false;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case VB_OWL_INTERACTION: {
|
||||
if (CVarGetInteger(CVAR_ENHANCEMENT("TimeSavers.SkipOwlInteractions"), IS_RANDO) && *should) {
|
||||
EnOwl* enOwl = va_arg(args, EnOwl*);
|
||||
@@ -720,6 +785,18 @@ void TimeSaverOnVanillaBehaviorHandler(GIVanillaBehavior id, bool* should, va_li
|
||||
|
||||
break;
|
||||
}
|
||||
case VB_PLAY_GATE_OPENING_OR_CLOSING_CS: {
|
||||
if (CVarGetInteger(CVAR_ENHANCEMENT("TimeSavers.SkipMiscInteractions"), IS_RANDO)) {
|
||||
EnHeishi2* enHeishi2 = va_arg(args, EnHeishi2*);
|
||||
enHeishi2->unk_2F2[0] = 0;
|
||||
|
||||
// The second argument determines whether the vanilla code should be run anyway. It
|
||||
// should be set to `true` ONLY IF said code calls `Play_ClearCamera`, false otherwise.
|
||||
bool clearCamera = (bool)va_arg(args, int);
|
||||
*should = clearCamera && enHeishi2->cameraId != MAIN_CAM;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case VB_PLAY_RAINBOW_BRIDGE_CS: {
|
||||
if (CVarGetInteger(CVAR_ENHANCEMENT("TimeSavers.SkipCutscene.Story"), IS_RANDO)) {
|
||||
*should = false;
|
||||
@@ -806,6 +883,8 @@ static uint32_t enMa1UpdateHook = 0;
|
||||
static uint32_t enMa1KillHook = 0;
|
||||
static uint32_t enFuUpdateHook = 0;
|
||||
static uint32_t enFuKillHook = 0;
|
||||
static uint32_t enJjUpdateHook = 0;
|
||||
static uint32_t enJjKillHook = 0;
|
||||
static uint32_t bgSpot02UpdateHook = 0;
|
||||
static uint32_t bgSpot02KillHook = 0;
|
||||
static uint32_t bgSpot03UpdateHook = 0;
|
||||
@@ -871,6 +950,39 @@ void TimeSaverOnActorInitHandler(void* actorRef) {
|
||||
});
|
||||
}
|
||||
|
||||
if (actor->id == ACTOR_EN_JJ) {
|
||||
enJjUpdateHook =
|
||||
GameInteractor::Instance->RegisterGameHook<GameInteractor::OnActorUpdate>([](void* innerActorRef) mutable {
|
||||
Actor* innerActor = static_cast<Actor*>(innerActorRef);
|
||||
|
||||
if (innerActor->id != ACTOR_EN_JJ || Flags_GetEventChkInf(EVENTCHKINF_OFFERED_FISH_TO_JABU_JABU)) {
|
||||
return;
|
||||
}
|
||||
|
||||
bool shouldOpen = IS_RANDO ? RAND_GET_OPTION(RSK_JABU_OPEN)
|
||||
: CVarGetInteger(CVAR_ENHANCEMENT("TimeSavers.SkipJabuJabuFish"), 0);
|
||||
if (!shouldOpen) {
|
||||
return;
|
||||
}
|
||||
|
||||
EnJj* enJj = static_cast<EnJj*>(innerActorRef);
|
||||
if (enJj->actionFunc == EnJj_WaitForFish) {
|
||||
EnJj_SetupAction(enJj, EnJj_WaitToOpenMouth);
|
||||
GameInteractor::Instance->UnregisterGameHook<GameInteractor::OnActorUpdate>(enJjUpdateHook);
|
||||
GameInteractor::Instance->UnregisterGameHook<GameInteractor::OnSceneInit>(enJjKillHook);
|
||||
enJjUpdateHook = 0;
|
||||
enJjKillHook = 0;
|
||||
}
|
||||
});
|
||||
enJjKillHook =
|
||||
GameInteractor::Instance->RegisterGameHook<GameInteractor::OnSceneInit>([](int16_t sceneNum) mutable {
|
||||
GameInteractor::Instance->UnregisterGameHook<GameInteractor::OnActorUpdate>(enJjUpdateHook);
|
||||
GameInteractor::Instance->UnregisterGameHook<GameInteractor::OnSceneInit>(enJjKillHook);
|
||||
enJjUpdateHook = 0;
|
||||
enJjKillHook = 0;
|
||||
});
|
||||
}
|
||||
|
||||
if (actor->id == ACTOR_EN_OWL && gPlayState->sceneNum == SCENE_ZORAS_RIVER &&
|
||||
CVarGetInteger(CVAR_ENHANCEMENT("TimeSavers.SleepingWaterfall"), 0) == 2) {
|
||||
Actor_Kill(actor);
|
||||
@@ -1096,6 +1208,10 @@ void TimeSaverOnSceneInitHandler(int16_t sceneNum) {
|
||||
|
||||
static GetItemEntry vanillaQueuedItemEntry = GET_ITEM_NONE;
|
||||
|
||||
void TimeSaverQueueItem(RandomizerGet randoGet) {
|
||||
vanillaQueuedItemEntry = Rando::StaticData::RetrieveItem(randoGet).GetGIEntry_Copy();
|
||||
}
|
||||
|
||||
void TimeSaverOnFlagSetHandler(int16_t flagType, int16_t flag) {
|
||||
// Do nothing when in a boss rush
|
||||
if (IS_BOSS_RUSH) {
|
||||
|
||||
@@ -1,6 +1,9 @@
|
||||
#ifndef TIMESAVER_HOOK_HANDLERS_H
|
||||
#define TIMESAVER_HOOK_HANDLERS_H
|
||||
|
||||
#include "soh/Enhancements/randomizer/randomizerTypes.h"
|
||||
|
||||
void TimeSaverRegisterHooks();
|
||||
void TimeSaverQueueItem(RandomizerGet randoGet);
|
||||
|
||||
#endif // TIMESAVER_HOOK_HANDLERS_H
|
||||
@@ -4,6 +4,7 @@
|
||||
#include "soh/util.h"
|
||||
#include <vector>
|
||||
#include "include/z64item.h"
|
||||
#include "Context.h"
|
||||
|
||||
#include <fstream>
|
||||
#include <filesystem>
|
||||
@@ -363,7 +364,7 @@ void TimeSplitsSkipSplit(uint32_t index) {
|
||||
}
|
||||
|
||||
void TimeSplitsFileManagement(uint32_t action, const char* listEntry, std::vector<SplitObject> listData) {
|
||||
std::string filename = "timesplitdata.json";
|
||||
std::string filename = Ship::Context::GetPathRelativeToAppDirectory("timesplitdata.json");
|
||||
json saveFile;
|
||||
json listArray = nlohmann::json::array();
|
||||
|
||||
@@ -948,9 +949,10 @@ void TimeSplitsDrawManageList() {
|
||||
}
|
||||
|
||||
void InitializeSplitDataFile() {
|
||||
if (!std::filesystem::exists("timesplitdata.json")) {
|
||||
std::string filename = Ship::Context::GetPathRelativeToAppDirectory("timesplitdata.json");
|
||||
if (!std::filesystem::exists(filename)) {
|
||||
json j;
|
||||
std::ofstream file("timesplitdata.json");
|
||||
std::ofstream file(filename);
|
||||
file << j.dump(4);
|
||||
file.close();
|
||||
}
|
||||
|
||||
+18
-6
@@ -1145,6 +1145,13 @@ extern "C" void InitOTR() {
|
||||
"Error", "SoH does not have proper file permissions. Please move it to a folder that does and run again.");
|
||||
exit(1);
|
||||
}
|
||||
if (ownPath.string().find("OneDrive") != std::string::npos) {
|
||||
Extractor::ShowErrorBox(
|
||||
"Error",
|
||||
"SoH appears to be in a OneDrive folder, which will cause issues. "
|
||||
"Please move it to a folder outside of OneDrive, like the root of a drive (e.g. \"C:\\Games\\SoH\").");
|
||||
exit(1);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if not defined(__SWITCH__) && not defined(__WIIU__)
|
||||
@@ -1428,7 +1435,9 @@ extern "C" void Graph_StartFrame() {
|
||||
}
|
||||
#endif
|
||||
case KbScancode::LUS_KB_TAB: {
|
||||
CVarSetInteger(CVAR_SETTING("AltAssets"), !CVarGetInteger(CVAR_SETTING("AltAssets"), 0));
|
||||
if (CVarGetInteger(CVAR_SETTING("Mods.AlternateAssetsHotkey"), 1)) {
|
||||
CVarSetInteger(CVAR_SETTING("AltAssets"), !CVarGetInteger(CVAR_SETTING("AltAssets"), 0));
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -2251,7 +2260,7 @@ extern "C" int CustomMessage_RetrieveIfExists(PlayState* play) {
|
||||
}
|
||||
} else if ((textId == TEXT_ALTAR_CHILD || textId == TEXT_ALTAR_ADULT)) {
|
||||
// rando hints at altar
|
||||
messageEntry = (LINK_IS_ADULT) ? ctx->GetHint(RH_ALTAR_ADULT)->GetHintMessage()
|
||||
messageEntry = (LINK_IS_ADULT) ? ctx->GetHint(RH_ALTAR_ADULT)->GetHintMessage(MF_AUTO_FORMAT)
|
||||
: ctx->GetHint(RH_ALTAR_CHILD)->GetHintMessage(MF_AUTO_FORMAT);
|
||||
} else if (textId == TEXT_GANONDORF) {
|
||||
if (ctx->GetOption(RSK_GANONDORF_HINT)) {
|
||||
@@ -2437,15 +2446,15 @@ extern "C" int CustomMessage_RetrieveIfExists(PlayState* play) {
|
||||
// animation until the text box auto-dismisses.
|
||||
// RANDOTODO: Implement a way to determine if an item came from a skulltula and
|
||||
// inject the auto-dismiss control code if it did.
|
||||
if (CVarGetInteger(CVAR_ENHANCEMENT("SkulltulaFreeze"), 0) != 0 &&
|
||||
!(IS_RANDO && Randomizer_GetSettingValue(RSK_SHUFFLE_TOKENS) != RO_TOKENSANITY_OFF)) {
|
||||
bool gsTokensShuffled = Randomizer_GetSettingValue(RSK_SHUFFLE_TOKENS) != RO_TOKENSANITY_OFF;
|
||||
if (CVarGetInteger(CVAR_ENHANCEMENT("SkulltulaFreeze"), 0) != 0 && !(IS_RANDO && gsTokensShuffled)) {
|
||||
textId = TEXT_GS_NO_FREEZE;
|
||||
} else {
|
||||
textId = TEXT_GS_FREEZE;
|
||||
}
|
||||
// In vanilla, GS token count is incremented prior to the text box displaying
|
||||
// In rando we need to bump the token count by one to show the correct count
|
||||
s16 gsCount = gSaveContext.inventory.gsTokens + (IS_RANDO ? 1 : 0);
|
||||
s16 gsCount = gSaveContext.inventory.gsTokens + ((IS_RANDO && gsTokensShuffled) ? 1 : 0);
|
||||
messageEntry = CustomMessageManager::Instance->RetrieveMessage(customMessageTableID, textId, MF_FORMATTED);
|
||||
messageEntry.Replace("[[gsCount]]", std::to_string(gsCount));
|
||||
} else if (CVarGetInteger(CVAR_ENHANCEMENT("SkulltulaFreeze"), 0) != 0 &&
|
||||
@@ -2608,4 +2617,7 @@ void SoH_ProcessDroppedFiles(std::string filePath) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
// #endregion
|
||||
|
||||
extern "C" void CheckTracker_RecalculateAvailableChecks() {
|
||||
CheckTracker::RecalculateAvailableChecks();
|
||||
}
|
||||
|
||||
@@ -163,6 +163,7 @@ void Gfx_UnregisterBlendedTexture(const char* name);
|
||||
void Gfx_TextureCacheDelete(const uint8_t* addr);
|
||||
void SaveManager_ThreadPoolWait();
|
||||
void CheckTracker_OnMessageClose();
|
||||
void CheckTracker_RecalculateAvailableChecks();
|
||||
|
||||
GetItemID RetrieveGetItemIDFromItemID(ItemID itemID);
|
||||
RandomizerGet RetrieveRandomizerGetFromItemID(ItemID itemID);
|
||||
|
||||
+68
-233
@@ -119,10 +119,8 @@ SaveManager::SaveManager() {
|
||||
AddLoadFunction("base", 4, LoadBaseVersion4);
|
||||
AddSaveFunction("base", 4, SaveBase, true, SECTION_PARENT_NONE);
|
||||
|
||||
AddLoadFunction("randomizer", 1, LoadRandomizerVersion1);
|
||||
AddLoadFunction("randomizer", 2, LoadRandomizerVersion2);
|
||||
AddLoadFunction("randomizer", 3, LoadRandomizerVersion3);
|
||||
AddSaveFunction("randomizer", 3, SaveRandomizer, true, SECTION_PARENT_NONE);
|
||||
AddLoadFunction("randomizer", 1, LoadRandomizer);
|
||||
AddSaveFunction("randomizer", 1, SaveRandomizer, true, SECTION_PARENT_NONE);
|
||||
|
||||
AddInitFunction(InitFileImpl);
|
||||
|
||||
@@ -157,234 +155,7 @@ SaveManager::SaveManager() {
|
||||
}
|
||||
}
|
||||
|
||||
// RANDOTODO should we just have dummy functions that raise warnings instead if these aren't supported?
|
||||
void SaveManager::LoadRandomizerVersion1() {
|
||||
auto randoContext = Rando::Context::GetInstance();
|
||||
RandomizerCheck location = RC_UNKNOWN_CHECK;
|
||||
for (int i = 0; i < RC_MAX; i++) {
|
||||
SaveManager::Instance->LoadData("check" + std::to_string(i), location);
|
||||
SaveManager::Instance->LoadStruct("get" + std::to_string(i), [&]() {
|
||||
SaveManager::Instance->LoadData("rgID", randoContext->GetItemLocation(location)->RefPlacedItem());
|
||||
if (randoContext->GetItemLocation(location)->GetPlacedRandomizerGet() == RG_ICE_TRAP) {
|
||||
randoContext->overrides[location].SetLocation(location);
|
||||
SaveManager::Instance->LoadData("fakeRgID", randoContext->overrides[location].RefLooksLike());
|
||||
SaveManager::Instance->LoadData("trickName", randoContext->overrides[location].GetTrickName().english);
|
||||
SaveManager::Instance->LoadData("trickName", randoContext->overrides[location].GetTrickName().french);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
for (uint32_t i = 0; i < randoContext->hashIconIndexes.size(); i++) {
|
||||
SaveManager::Instance->LoadData("seed" + std::to_string(i), randoContext->hashIconIndexes[i]);
|
||||
}
|
||||
|
||||
for (int i = 0; i < RSK_MAX; i++) {
|
||||
int key, value;
|
||||
SaveManager::Instance->LoadData("sk" + std::to_string(i), key);
|
||||
SaveManager::Instance->LoadData("sv" + std::to_string(i), value);
|
||||
randoContext->GetOption(RandomizerSettingKey(key)).Set(value);
|
||||
}
|
||||
|
||||
for (int i = 0; i < 50; i++) {
|
||||
RandomizerCheck check;
|
||||
char hintText[200];
|
||||
SaveManager::Instance->LoadData("hc" + std::to_string(i), check);
|
||||
for (int j = 0; j < ARRAY_COUNT(hintText); j++) {
|
||||
SaveManager::Instance->LoadData("ht" + std::to_string(i) + "-" + std::to_string(j), hintText[j]);
|
||||
}
|
||||
RandomizerHint stoneHint = Rando::StaticData::oldVerHintOrder[i - Rando::StaticData::oldVerGossipStoneStart];
|
||||
randoContext->AddHint(stoneHint, Rando::Hint(stoneHint, { CustomMessage(hintText) }));
|
||||
}
|
||||
|
||||
char childAltarText[250];
|
||||
for (int i = 0; i < ARRAY_COUNT(childAltarText); i++) {
|
||||
SaveManager::Instance->LoadData("cat" + std::to_string(i), childAltarText[i]);
|
||||
}
|
||||
randoContext->AddHint(RH_ALTAR_CHILD, Rando::Hint(RH_ALTAR_CHILD, { CustomMessage(childAltarText) }));
|
||||
|
||||
char adultAltarText[750];
|
||||
for (int i = 0; i < ARRAY_COUNT(adultAltarText); i++) {
|
||||
SaveManager::Instance->LoadData("aat" + std::to_string(i), adultAltarText[i]);
|
||||
}
|
||||
randoContext->AddHint(RH_ALTAR_ADULT, Rando::Hint(RH_ALTAR_ADULT, { CustomMessage(adultAltarText) }));
|
||||
|
||||
char ganonHintText[150];
|
||||
for (int i = 0; i < ARRAY_COUNT(ganonHintText); i++) {
|
||||
SaveManager::Instance->LoadData("ght" + std::to_string(i), ganonHintText[i]);
|
||||
}
|
||||
randoContext->AddHint(RH_GANONDORF_HINT, Rando::Hint(RH_GANONDORF_HINT, { CustomMessage(ganonHintText) }));
|
||||
|
||||
char ganonText[250];
|
||||
for (int i = 0; i < ARRAY_COUNT(ganonText); i++) {
|
||||
SaveManager::Instance->LoadData("gt" + std::to_string(i), ganonText[i]);
|
||||
}
|
||||
randoContext->AddHint(RH_GANONDORF_JOKE, Rando::Hint(RH_GANONDORF_JOKE, { CustomMessage(ganonText) }));
|
||||
|
||||
SaveManager::Instance->LoadData("triforcePiecesCollected",
|
||||
gSaveContext.ship.quest.data.randomizer.triforcePiecesCollected);
|
||||
|
||||
SaveManager::Instance->LoadData("pendingIceTrapCount", gSaveContext.ship.pendingIceTrapCount);
|
||||
|
||||
size_t merchantPricesSize = 0;
|
||||
if (randoContext->GetOption(RSK_SHUFFLE_SCRUBS).Is(RO_SCRUBS_OFF)) {
|
||||
merchantPricesSize += NUM_SCRUBS;
|
||||
}
|
||||
if (randoContext->GetOption(RSK_SHOPSANITY).Is(RO_SHOPSANITY_OFF)) {
|
||||
merchantPricesSize += NUM_SHOP_ITEMS;
|
||||
}
|
||||
|
||||
SaveManager::Instance->LoadArray("merchantPrices", merchantPricesSize, [&](size_t i) {
|
||||
SaveManager::Instance->LoadStruct("", [&]() {
|
||||
RandomizerCheck rc;
|
||||
SaveManager::Instance->LoadData("check", rc);
|
||||
uint32_t price;
|
||||
SaveManager::Instance->LoadData("price", price);
|
||||
randoContext->GetItemLocation(rc)->SetCustomPrice(price);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
// RANDOTODO if we actually support this, be less lazy
|
||||
void SaveManager::LoadRandomizerVersion2() {
|
||||
auto randoContext = Rando::Context::GetInstance();
|
||||
SaveManager::Instance->LoadArray("itemLocations", RC_MAX, [&](size_t i) {
|
||||
SaveManager::Instance->LoadStruct("", [&]() {
|
||||
SaveManager::Instance->LoadData("rgID", randoContext->GetItemLocation(i)->RefPlacedItem());
|
||||
RandomizerGet rg = RG_NONE;
|
||||
SaveManager::Instance->LoadData("fakeRgID", rg, RG_NONE);
|
||||
if (rg != RG_NONE) {
|
||||
randoContext->overrides[static_cast<RandomizerCheck>(i)] =
|
||||
Rando::ItemOverride(static_cast<RandomizerCheck>(i), rg);
|
||||
SaveManager::Instance->LoadData(
|
||||
"trickName", randoContext->overrides[static_cast<RandomizerCheck>(i)].GetTrickName().english);
|
||||
SaveManager::Instance->LoadData(
|
||||
"trickName", randoContext->overrides[static_cast<RandomizerCheck>(i)].GetTrickName().french);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
auto entranceCtx = randoContext->GetEntranceShuffler();
|
||||
SaveManager::Instance->LoadArray("entrances", ARRAY_COUNT(entranceCtx->entranceOverrides), [&](size_t i) {
|
||||
SaveManager::Instance->LoadStruct("", [&]() {
|
||||
SaveManager::Instance->LoadData("type", entranceCtx->entranceOverrides[i].type);
|
||||
SaveManager::Instance->LoadData("index", entranceCtx->entranceOverrides[i].index);
|
||||
SaveManager::Instance->LoadData("destination", entranceCtx->entranceOverrides[i].destination);
|
||||
SaveManager::Instance->LoadData("override", entranceCtx->entranceOverrides[i].override);
|
||||
SaveManager::Instance->LoadData("overrideDestination",
|
||||
entranceCtx->entranceOverrides[i].overrideDestination);
|
||||
});
|
||||
});
|
||||
|
||||
SaveManager::Instance->LoadArray("seed", randoContext->hashIconIndexes.size(), [&](size_t i) {
|
||||
SaveManager::Instance->LoadData("", randoContext->hashIconIndexes[i]);
|
||||
});
|
||||
|
||||
std::string inputSeed;
|
||||
SaveManager::Instance->LoadData("inputSeed", inputSeed);
|
||||
randoContext->SetSeedString(inputSeed);
|
||||
|
||||
uint32_t finalSeed;
|
||||
SaveManager::Instance->LoadData("finalSeed", finalSeed);
|
||||
randoContext->SetSeed(finalSeed);
|
||||
|
||||
SaveManager::Instance->LoadArray("randoSettings", RSK_MAX, [&](size_t i) {
|
||||
int value = 0;
|
||||
SaveManager::Instance->LoadData("", value);
|
||||
randoContext->GetOption(RandomizerSettingKey(i)).Set(value);
|
||||
});
|
||||
|
||||
SaveManager::Instance->LoadArray("hintLocations", RH_ZR_OPEN_GROTTO_GOSSIP_STONE + 1, [&](size_t i) {
|
||||
SaveManager::Instance->LoadStruct("", [&]() {
|
||||
RandomizerCheck rc = RC_UNKNOWN_CHECK;
|
||||
SaveManager::Instance->LoadData("check", rc);
|
||||
if (rc != RC_UNKNOWN_CHECK) {
|
||||
std::string hintText;
|
||||
SaveManager::Instance->LoadData("hintText", hintText);
|
||||
RandomizerHint stoneHint =
|
||||
Rando::StaticData::oldVerHintOrder[rc - Rando::StaticData::oldVerGossipStoneStart];
|
||||
randoContext->AddHint(stoneHint, Rando::Hint(stoneHint, { CustomMessage(hintText) }));
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
std::string childAltarText;
|
||||
SaveManager::Instance->LoadData("childAltarText", childAltarText);
|
||||
randoContext->AddHint(RH_ALTAR_CHILD, Rando::Hint(RH_ALTAR_CHILD, { CustomMessage(childAltarText) }));
|
||||
std::string adultAltarText;
|
||||
SaveManager::Instance->LoadData("adultAltarText", adultAltarText);
|
||||
randoContext->AddHint(RH_ALTAR_ADULT, Rando::Hint(RH_ALTAR_ADULT, { CustomMessage(adultAltarText) }));
|
||||
std::string ganonHintText;
|
||||
SaveManager::Instance->LoadData("ganonHintText", ganonHintText);
|
||||
randoContext->AddHint(RH_GANONDORF_HINT, Rando::Hint(RH_GANONDORF_HINT, { CustomMessage(ganonHintText) }));
|
||||
std::string ganonText;
|
||||
SaveManager::Instance->LoadData("ganonText", ganonText);
|
||||
randoContext->AddHint(RH_GANONDORF_JOKE, Rando::Hint(RH_GANONDORF_JOKE, { CustomMessage(ganonText) }));
|
||||
std::string dampeText;
|
||||
SaveManager::Instance->LoadData("dampeText", dampeText);
|
||||
randoContext->AddHint(RH_DAMPES_DIARY, Rando::Hint(RH_DAMPES_DIARY, { CustomMessage(dampeText) }));
|
||||
std::string gregHintText;
|
||||
SaveManager::Instance->LoadData("gregHintText", gregHintText);
|
||||
randoContext->AddHint(RH_GREG_RUPEE, Rando::Hint(RH_GREG_RUPEE, { CustomMessage(gregHintText) }));
|
||||
std::string sheikText;
|
||||
SaveManager::Instance->LoadData("sheikText", sheikText);
|
||||
randoContext->AddHint(RH_SHEIK_HINT, Rando::Hint(RH_SHEIK_HINT, { CustomMessage(sheikText) }));
|
||||
std::string sariaText;
|
||||
SaveManager::Instance->LoadData("sariaText", sariaText);
|
||||
randoContext->AddHint(RH_SARIA_HINT, Rando::Hint(RH_SARIA_HINT, { CustomMessage(sariaText) }));
|
||||
std::string fishingPoleText;
|
||||
SaveManager::Instance->LoadData("fishingPoleText", fishingPoleText);
|
||||
randoContext->AddHint(RH_FISHING_POLE, Rando::Hint(RH_FISHING_POLE, { CustomMessage(fishingPoleText) }));
|
||||
std::string warpMinuetText;
|
||||
SaveManager::Instance->LoadData("warpMinuetText", warpMinuetText);
|
||||
randoContext->AddHint(RH_MINUET_WARP_LOC, Rando::Hint(RH_MINUET_WARP_LOC, { CustomMessage(warpMinuetText) }));
|
||||
std::string warpBoleroText;
|
||||
SaveManager::Instance->LoadData("warpBoleroText", warpBoleroText);
|
||||
randoContext->AddHint(RH_BOLERO_WARP_LOC, Rando::Hint(RH_BOLERO_WARP_LOC, { CustomMessage(warpBoleroText) }));
|
||||
std::string warpSerenadeText;
|
||||
SaveManager::Instance->LoadData("warpSerenadeText", warpSerenadeText);
|
||||
randoContext->AddHint(RH_SERENADE_WARP_LOC, Rando::Hint(RH_SERENADE_WARP_LOC, { CustomMessage(warpSerenadeText) }));
|
||||
std::string warpRequiemText;
|
||||
SaveManager::Instance->LoadData("warpRequiemText", warpRequiemText);
|
||||
randoContext->AddHint(RH_REQUIEM_WARP_LOC, Rando::Hint(RH_REQUIEM_WARP_LOC, { CustomMessage(warpRequiemText) }));
|
||||
std::string warpNocturneText;
|
||||
SaveManager::Instance->LoadData("warpNocturneText", warpNocturneText);
|
||||
randoContext->AddHint(RH_NOCTURNE_WARP_LOC, Rando::Hint(RH_NOCTURNE_WARP_LOC, { CustomMessage(warpNocturneText) }));
|
||||
std::string warpPreludeText;
|
||||
SaveManager::Instance->LoadData("warpPreludeText", warpPreludeText);
|
||||
randoContext->AddHint(RH_PRELUDE_WARP_LOC, Rando::Hint(RH_PRELUDE_WARP_LOC, { CustomMessage(warpPreludeText) }));
|
||||
|
||||
SaveManager::Instance->LoadData("triforcePiecesCollected",
|
||||
gSaveContext.ship.quest.data.randomizer.triforcePiecesCollected);
|
||||
|
||||
SaveManager::Instance->LoadData("pendingIceTrapCount", gSaveContext.ship.pendingIceTrapCount);
|
||||
|
||||
std::shared_ptr<Randomizer> randomizer = OTRGlobals::Instance->gRandomizer;
|
||||
|
||||
size_t merchantPricesSize = 0;
|
||||
SaveManager::Instance->LoadData("merchantPricesSize", merchantPricesSize);
|
||||
|
||||
SaveManager::Instance->LoadArray("merchantPrices", merchantPricesSize, [&](size_t i) {
|
||||
SaveManager::Instance->LoadStruct("", [&]() {
|
||||
RandomizerCheck rc;
|
||||
SaveManager::Instance->LoadData("check", rc);
|
||||
uint32_t price;
|
||||
SaveManager::Instance->LoadData("price", price);
|
||||
randoContext->GetItemLocation(rc)->SetCustomPrice(price);
|
||||
});
|
||||
});
|
||||
|
||||
size_t mqDungeonCount;
|
||||
SaveManager::Instance->LoadData("masterQuestDungeonCount", mqDungeonCount, (size_t)0);
|
||||
|
||||
randoContext->GetDungeons()->ClearAllMQ();
|
||||
SaveManager::Instance->LoadArray("masterQuestDungeons", mqDungeonCount, [&](size_t i) {
|
||||
uint16_t scene;
|
||||
SaveManager::Instance->LoadData("", scene);
|
||||
randoContext->GetDungeons()->GetDungeonFromScene(SceneID(scene))->SetMQ();
|
||||
});
|
||||
}
|
||||
|
||||
void SaveManager::LoadRandomizerVersion3() {
|
||||
void SaveManager::LoadRandomizer() {
|
||||
auto randoContext = Rando::Context::GetInstance();
|
||||
SaveManager::Instance->LoadArray("itemLocations", RC_MAX, [&](size_t i) {
|
||||
SaveManager::Instance->LoadStruct("", [&]() {
|
||||
@@ -408,6 +179,9 @@ void SaveManager::LoadRandomizerVersion3() {
|
||||
// all ItemLocations is 0 anyway.
|
||||
randoContext->GetItemLocation(i)->SetCustomPrice(price);
|
||||
}
|
||||
bool excluded = false;
|
||||
SaveManager::Instance->LoadData("excluded", excluded, false);
|
||||
randoContext->GetItemLocation(i)->SetExcludedOption(excluded);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -498,6 +272,9 @@ void SaveManager::SaveRandomizer(SaveContext* saveContext, int sectionID, bool f
|
||||
// TODO: German (trick names don't have german translations yet)
|
||||
});
|
||||
}
|
||||
if (randoContext->GetItemLocation(i)->IsExcluded()) {
|
||||
SaveManager::Instance->SaveData("excluded", true);
|
||||
}
|
||||
if (randoContext->GetItemLocation(i)->HasCustomPrice()) {
|
||||
SaveManager::Instance->SaveData("price", randoContext->GetItemLocation(i)->GetPrice());
|
||||
}
|
||||
@@ -1334,6 +1111,7 @@ void SaveManager::LoadFile(int fileNum) {
|
||||
std::ifstream input(fileName);
|
||||
|
||||
try {
|
||||
bool deleteRando = false;
|
||||
saveBlock = nlohmann::json::object();
|
||||
input >> saveBlock;
|
||||
if (!saveBlock.contains("version")) {
|
||||
@@ -1343,8 +1121,59 @@ void SaveManager::LoadFile(int fileNum) {
|
||||
switch (saveBlock["version"].get<int>()) {
|
||||
case 1:
|
||||
for (auto& block : saveBlock["sections"].items()) {
|
||||
int sectionVersion = block.value()["version"];
|
||||
bool oldVanilla =
|
||||
block.value()["data"].empty() || block.value()["data"].contains("aat0") ||
|
||||
block.value()["data"]["entrances"].empty() ||
|
||||
SohUtils::IsStringEmpty(saveBlock["sections"]["sohStats"]["data"]["buildVersion"]);
|
||||
std::string sectionName = block.key();
|
||||
if (sectionName == "randomizer") {
|
||||
bool hasStats = saveBlock["sections"].contains("sohStats");
|
||||
if (oldVanilla || !hasStats) { // Vanilla "rando" data
|
||||
SohGui::RegisterPopup(
|
||||
"Loading old file",
|
||||
"The file in slot " + std::to_string(fileNum + 1) +
|
||||
" appears to contain randomizer data, but is a very old format or is empty.\n" +
|
||||
"The randomizer data has been removed, and this file will be treated as a vanilla "
|
||||
"file.\nIf this was a vanilla file, it still is, and you shouldn't see this "
|
||||
"message again.\n" +
|
||||
"If this was a randomizer file, the file will not work, and should be deleted.");
|
||||
deleteRando = true;
|
||||
continue;
|
||||
}
|
||||
s16 major = saveBlock["sections"]["sohStats"]["data"]["buildVersionMajor"];
|
||||
s16 minor = saveBlock["sections"]["sohStats"]["data"]["buildVersionMinor"];
|
||||
s16 patch = saveBlock["sections"]["sohStats"]["data"]["buildVersionPatch"];
|
||||
// block loading outdated rando save
|
||||
if (!(major == gBuildVersionMajor && minor == gBuildVersionMinor &&
|
||||
patch == gBuildVersionPatch)) {
|
||||
input.close();
|
||||
std::string newFileName = Ship::Context::GetPathRelativeToAppDirectory("Save") +
|
||||
("/file" + std::to_string(fileNum + 1) + "-" +
|
||||
std::to_string(GetUnixTimestamp()) + ".bak");
|
||||
std::filesystem::path newFile(newFileName);
|
||||
|
||||
#if defined(__SWITCH__) || defined(__WIIU__)
|
||||
copy_file(fileName.c_str(), newFile.c_str());
|
||||
#else
|
||||
std::filesystem::copy_file(fileName, newFile);
|
||||
#endif
|
||||
|
||||
std::filesystem::remove(fileName);
|
||||
SohGui::RegisterPopup(
|
||||
"Outdated Randomizer Save",
|
||||
"The SoH version in the file in slot " + std::to_string(fileNum + 1) +
|
||||
" does not match the currently running version.\n" +
|
||||
"Non-matching rando saves are unsupported, and the file has been renamed to\n" +
|
||||
" " + newFileName + "\n" +
|
||||
"If this was not in error, the file should be deleted.");
|
||||
saveMtx.unlock();
|
||||
return;
|
||||
}
|
||||
}
|
||||
int sectionVersion = block.value()["version"];
|
||||
if (sectionName == "randomizer" && sectionVersion != 1) {
|
||||
sectionVersion = 1;
|
||||
}
|
||||
if (!sectionLoadHandlers.contains(sectionName)) {
|
||||
// Unloadable sections aren't necessarily errors, they are probably mods that were unloaded
|
||||
// TODO report in a more noticeable manner
|
||||
@@ -1376,6 +1205,12 @@ void SaveManager::LoadFile(int fileNum) {
|
||||
assert(false);
|
||||
break;
|
||||
}
|
||||
input.close();
|
||||
if (deleteRando) {
|
||||
saveBlock["sections"].erase(saveBlock["sections"].find("randomizer"));
|
||||
SaveFile(fileNum);
|
||||
deleteRando = false;
|
||||
}
|
||||
InitMeta(fileNum);
|
||||
GameInteractor::Instance->ExecuteHooks<GameInteractor::OnLoadFile>(fileNum);
|
||||
} catch (const std::exception& e) {
|
||||
|
||||
@@ -166,11 +166,7 @@ class SaveManager {
|
||||
static void InitFileDebug();
|
||||
static void InitFileMaxed();
|
||||
|
||||
static void LoadRandomizerVersion1();
|
||||
static void LoadRandomizerVersion2();
|
||||
static void LoadRandomizerVersion3();
|
||||
static void LoadTrackerData();
|
||||
static void SaveTrackerData(SaveContext* saveContext, int sectionID, bool fullSave);
|
||||
static void LoadRandomizer();
|
||||
static void SaveRandomizer(SaveContext* saveContext, int sectionID, bool fullSave);
|
||||
|
||||
static void LoadBaseVersion1();
|
||||
|
||||
+38
-30
@@ -185,33 +185,35 @@ bool ModernMenuHeaderEntry(std::string label) {
|
||||
}
|
||||
|
||||
uint32_t Menu::DrawSearchResults(std::string& menuSearchText) {
|
||||
ImGui::BeginChild("Search Results");
|
||||
int searchCount = 0;
|
||||
for (auto& menuLabel : menuOrder) {
|
||||
auto& menuEntry = menuEntries.at(menuLabel);
|
||||
for (auto& sidebarLabel : menuEntry.sidebarOrder) {
|
||||
auto& sidebar = menuEntry.sidebars[sidebarLabel];
|
||||
for (int i = 0; i < sidebar.columnWidgets.size(); i++) {
|
||||
auto& column = sidebar.columnWidgets.at(i);
|
||||
for (auto& info : column) {
|
||||
if (info.type == WIDGET_SEARCH || info.type == WIDGET_SEPARATOR ||
|
||||
info.type == WIDGET_SEPARATOR_TEXT || info.isHidden) {
|
||||
continue;
|
||||
}
|
||||
const char* tooltip = info.options->tooltip;
|
||||
std::string widgetStr = std::string(info.name) + std::string(tooltip != NULL ? tooltip : "");
|
||||
std::transform(menuSearchText.begin(), menuSearchText.end(), menuSearchText.begin(), ::tolower);
|
||||
menuSearchText.erase(std::remove(menuSearchText.begin(), menuSearchText.end(), ' '),
|
||||
menuSearchText.end());
|
||||
std::transform(widgetStr.begin(), widgetStr.end(), widgetStr.begin(), ::tolower);
|
||||
widgetStr.erase(std::remove(widgetStr.begin(), widgetStr.end(), ' '), widgetStr.end());
|
||||
if (widgetStr.find(menuSearchText) != std::string::npos) {
|
||||
MenuDrawItem(info, 90 / sidebar.columnCount, menuThemeIndex);
|
||||
ImGui::PushStyleColor(ImGuiCol_Text, UIWidgets::ColorValues.at(UIWidgets::Colors::Gray));
|
||||
std::string origin = fmt::format(" ({} -> {}, Col {})", menuEntry.label, sidebarLabel, i + 1);
|
||||
ImGui::Text("%s", origin.c_str());
|
||||
ImGui::PopStyleColor();
|
||||
searchCount++;
|
||||
if (ImGui::BeginChild("Search Results")) {
|
||||
for (auto& menuLabel : menuOrder) {
|
||||
auto& menuEntry = menuEntries.at(menuLabel);
|
||||
for (auto& sidebarLabel : menuEntry.sidebarOrder) {
|
||||
auto& sidebar = menuEntry.sidebars[sidebarLabel];
|
||||
for (int i = 0; i < sidebar.columnWidgets.size(); i++) {
|
||||
auto& column = sidebar.columnWidgets.at(i);
|
||||
for (auto& info : column) {
|
||||
if (info.type == WIDGET_SEARCH || info.type == WIDGET_SEPARATOR ||
|
||||
info.type == WIDGET_SEPARATOR_TEXT || info.isHidden) {
|
||||
continue;
|
||||
}
|
||||
const char* tooltip = info.options->tooltip;
|
||||
std::string widgetStr = std::string(info.name) + std::string(tooltip != NULL ? tooltip : "");
|
||||
std::transform(menuSearchText.begin(), menuSearchText.end(), menuSearchText.begin(), ::tolower);
|
||||
menuSearchText.erase(std::remove(menuSearchText.begin(), menuSearchText.end(), ' '),
|
||||
menuSearchText.end());
|
||||
std::transform(widgetStr.begin(), widgetStr.end(), widgetStr.begin(), ::tolower);
|
||||
widgetStr.erase(std::remove(widgetStr.begin(), widgetStr.end(), ' '), widgetStr.end());
|
||||
if (widgetStr.find(menuSearchText) != std::string::npos) {
|
||||
MenuDrawItem(info, 90 / sidebar.columnCount, menuThemeIndex);
|
||||
ImGui::PushStyleColor(ImGuiCol_Text, UIWidgets::ColorValues.at(UIWidgets::Colors::Gray));
|
||||
std::string origin =
|
||||
fmt::format(" ({} -> {}, Col {})", menuEntry.label, sidebarLabel, i + 1);
|
||||
ImGui::Text("%s", origin.c_str());
|
||||
ImGui::PopStyleColor();
|
||||
searchCount++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -494,6 +496,7 @@ void Menu::Draw() {
|
||||
SyncVisibilityConsoleVariable();
|
||||
}
|
||||
|
||||
static bool freshOpen = true;
|
||||
void Menu::DrawElement() {
|
||||
for (auto& [reason, info] : disabledMap) {
|
||||
info.active = info.evaluation(info);
|
||||
@@ -536,6 +539,7 @@ void Menu::DrawElement() {
|
||||
if (!popout) {
|
||||
ImGui::PopStyleVar();
|
||||
}
|
||||
freshOpen = true;
|
||||
ImGui::PopStyleColor();
|
||||
ImGui::End();
|
||||
return;
|
||||
@@ -652,13 +656,13 @@ void Menu::DrawElement() {
|
||||
std::string menuSearchText = "";
|
||||
if (headerSearch) {
|
||||
ImGui::SameLine();
|
||||
if (autoFocus && ImGui::IsWindowFocused(ImGuiFocusedFlags_RootAndChildWindows) && !ImGui::IsAnyItemActive() &&
|
||||
!ImGui::IsMouseClicked(0)) {
|
||||
ImGui::SetKeyboardFocusHere(0);
|
||||
if (autoFocus && freshOpen) {
|
||||
ImGui::SetKeyboardFocusHere();
|
||||
}
|
||||
auto color = UIWidgets::ColorValues.at(menuThemeIndex);
|
||||
color.w = 0.2f;
|
||||
color.w = 0.6f;
|
||||
ImGui::PushStyleColor(ImGuiCol_FrameBg, color);
|
||||
ImGui::PushStyleVar(ImGuiStyleVar_FrameRounding, 3.0f);
|
||||
menuSearch.Draw("##search", 200.0f);
|
||||
menuSearchText = menuSearch.InputBuf;
|
||||
menuSearchText.erase(std::remove(menuSearchText.begin(), menuSearchText.end(), ' '), menuSearchText.end());
|
||||
@@ -666,6 +670,7 @@ void Menu::DrawElement() {
|
||||
ImGui::SameLine(headerWidth - 200.0f + style.ItemSpacing.x);
|
||||
ImGui::TextColored(ImVec4(1.0f, 1.0f, 1.0f, 0.4f), "Search...");
|
||||
}
|
||||
ImGui::PopStyleVar();
|
||||
ImGui::PopStyleColor();
|
||||
}
|
||||
ImGui::EndChild();
|
||||
@@ -851,6 +856,9 @@ void Menu::DrawElement() {
|
||||
poppedSize = ImGui::GetWindowSize();
|
||||
poppedPos = ImGui::GetWindowPos();
|
||||
}
|
||||
if (freshOpen) {
|
||||
freshOpen = false;
|
||||
}
|
||||
ImGui::End();
|
||||
}
|
||||
} // namespace Ship
|
||||
|
||||
@@ -563,7 +563,6 @@ void UpdateResolutionVars() {
|
||||
verticalPixelCount =
|
||||
CVarGetInteger(CVAR_PREFIX_ADVANCED_RESOLUTION ".VerticalPixelCount", pixelCountPresets[item_pixelCount]);
|
||||
// Additional settings
|
||||
showHorizontalResField = false;
|
||||
horizontalPixelCount = (verticalPixelCount / aspectRatioY) * aspectRatioX;
|
||||
// Disabling flags
|
||||
disabled_everything = !CVarGetInteger(CVAR_PREFIX_ADVANCED_RESOLUTION ".Enabled", 0);
|
||||
|
||||
@@ -71,7 +71,6 @@ std::shared_ptr<SohMenuBar> mSohMenuBar;
|
||||
std::shared_ptr<Ship::GuiWindow> mConsoleWindow;
|
||||
std::shared_ptr<SohStatsWindow> mStatsWindow;
|
||||
std::shared_ptr<Ship::GuiWindow> mGfxDebuggerWindow;
|
||||
std::shared_ptr<Ship::GuiWindow> mInputEditorWindow;
|
||||
|
||||
std::shared_ptr<SohMenu> mSohMenu;
|
||||
std::shared_ptr<AudioEditor> mAudioEditorWindow;
|
||||
@@ -131,10 +130,10 @@ void SetupGuiElements() {
|
||||
mStatsWindow = std::make_shared<SohStatsWindow>(CVAR_WINDOW("SohStats"), "Stats##Soh", ImVec2(400, 100));
|
||||
gui->AddGuiWindow(mStatsWindow);
|
||||
|
||||
mInputEditorWindow = gui->GetGuiWindow("Controller Configuration");
|
||||
/*mInputEditorWindow = gui->GetGuiWindow("Controller Configuration");
|
||||
if (mInputEditorWindow == nullptr) {
|
||||
SPDLOG_ERROR("Could not find input editor window");
|
||||
}
|
||||
}*/
|
||||
|
||||
mAudioEditorWindow = std::make_shared<AudioEditor>(CVAR_WINDOW("AudioEditor"), "Audio Editor", ImVec2(820, 630));
|
||||
gui->AddGuiWindow(mAudioEditorWindow);
|
||||
@@ -228,7 +227,6 @@ void Destroy() {
|
||||
mActorViewerWindow = nullptr;
|
||||
mCosmeticsEditorWindow = nullptr;
|
||||
mAudioEditorWindow = nullptr;
|
||||
mInputEditorWindow = nullptr;
|
||||
mStatsWindow = nullptr;
|
||||
mConsoleWindow = nullptr;
|
||||
mGfxDebuggerWindow = nullptr;
|
||||
|
||||
@@ -7,6 +7,10 @@
|
||||
#include <soh/Enhancements/Presets/Presets.h>
|
||||
#include <soh/Enhancements/TimeDisplay/TimeDisplay.h>
|
||||
|
||||
#define CVAR_INT_SHIP_INIT(cvar, val) \
|
||||
CVarSetInteger(cvar, val); \
|
||||
ShipInit::Init(cvar);
|
||||
|
||||
static std::string comboboxTooltip = "";
|
||||
static int32_t enhancementPresetSelected = ENHANCEMENT_PRESET_DEFAULT;
|
||||
bool isBetaQuestEnabled = false;
|
||||
@@ -262,6 +266,15 @@ void SohMenu::AddMenuEnhancements() {
|
||||
"open permanently.\n"
|
||||
"Never: Link never needs to play Zelda's Lullaby to open the waterfall. He only needs to have "
|
||||
"learned it and have an Ocarina."));
|
||||
AddWidget(path, "Skip Feeding Jabu-Jabu", WIDGET_CVAR_CHECKBOX)
|
||||
.CVar(CVAR_ENHANCEMENT("TimeSavers.SkipJabuJabuFish"))
|
||||
.PreFunc([](WidgetInfo& info) {
|
||||
info.options->disabled =
|
||||
IS_RANDO && OTRGlobals::Instance->gRandoContext->GetOption(RSK_JABU_OPEN).Is(RO_JABU_OPEN);
|
||||
info.options->disabledTooltip =
|
||||
"This setting is disabled because a randomizer savefile with \"Jabu-Jabu: Open\" is loaded.";
|
||||
})
|
||||
.Options(CheckboxOptions().Tooltip("Allow Link to enter Jabu-Jabu without feeding him a fish."));
|
||||
|
||||
// Skips & Speed-ups
|
||||
path.sidebarName = "Skips & Speed-ups";
|
||||
@@ -272,16 +285,16 @@ void SohMenu::AddMenuEnhancements() {
|
||||
AddWidget(path, "All##Skips", WIDGET_BUTTON)
|
||||
.Options(ButtonOptions().Size(Sizes::Inline))
|
||||
.Callback([](WidgetInfo& info) {
|
||||
CVarSetInteger(CVAR_ENHANCEMENT("TimeSavers.SkipCutscene.Intro"), true);
|
||||
CVarSetInteger(CVAR_ENHANCEMENT("TimeSavers.SkipCutscene.Entrances"), true);
|
||||
CVarSetInteger(CVAR_ENHANCEMENT("TimeSavers.SkipCutscene.Story"), true);
|
||||
CVarSetInteger(CVAR_ENHANCEMENT("TimeSavers.SkipCutscene.LearnSong"), true);
|
||||
CVarSetInteger(CVAR_ENHANCEMENT("TimeSavers.SkipCutscene.BossIntro"), true);
|
||||
CVarSetInteger(CVAR_ENHANCEMENT("TimeSavers.SkipCutscene.QuickBossDeaths"), true);
|
||||
CVarSetInteger(CVAR_ENHANCEMENT("TimeSavers.SkipCutscene.OnePoint"), true);
|
||||
CVarSetInteger(CVAR_ENHANCEMENT("TimeSavers.SkipOwlInteractions"), true);
|
||||
CVarSetInteger(CVAR_ENHANCEMENT("TimeSavers.SkipMiscInteractions"), true);
|
||||
CVarSetInteger(CVAR_ENHANCEMENT("TimeSavers.DisableTitleCard"), true);
|
||||
CVAR_INT_SHIP_INIT(CVAR_ENHANCEMENT("TimeSavers.SkipCutscene.Intro"), true);
|
||||
CVAR_INT_SHIP_INIT(CVAR_ENHANCEMENT("TimeSavers.SkipCutscene.Entrances"), true);
|
||||
CVAR_INT_SHIP_INIT(CVAR_ENHANCEMENT("TimeSavers.SkipCutscene.Story"), true);
|
||||
CVAR_INT_SHIP_INIT(CVAR_ENHANCEMENT("TimeSavers.SkipCutscene.LearnSong"), true);
|
||||
CVAR_INT_SHIP_INIT(CVAR_ENHANCEMENT("TimeSavers.SkipCutscene.BossIntro"), true);
|
||||
CVAR_INT_SHIP_INIT(CVAR_ENHANCEMENT("TimeSavers.SkipCutscene.QuickBossDeaths"), true);
|
||||
CVAR_INT_SHIP_INIT(CVAR_ENHANCEMENT("TimeSavers.SkipCutscene.OnePoint"), true);
|
||||
CVAR_INT_SHIP_INIT(CVAR_ENHANCEMENT("TimeSavers.SkipOwlInteractions"), true);
|
||||
CVAR_INT_SHIP_INIT(CVAR_ENHANCEMENT("TimeSavers.SkipMiscInteractions"), true);
|
||||
CVAR_INT_SHIP_INIT(CVAR_ENHANCEMENT("TimeSavers.DisableTitleCard"), true);
|
||||
|
||||
Ship::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesNextFrame();
|
||||
});
|
||||
@@ -289,16 +302,16 @@ void SohMenu::AddMenuEnhancements() {
|
||||
.SameLine(true)
|
||||
.Options(ButtonOptions().Size(Sizes::Inline))
|
||||
.Callback([](WidgetInfo& info) {
|
||||
CVarSetInteger(CVAR_ENHANCEMENT("TimeSavers.SkipCutscene.Intro"), false);
|
||||
CVarSetInteger(CVAR_ENHANCEMENT("TimeSavers.SkipCutscene.Entrances"), false);
|
||||
CVarSetInteger(CVAR_ENHANCEMENT("TimeSavers.SkipCutscene.Story"), false);
|
||||
CVarSetInteger(CVAR_ENHANCEMENT("TimeSavers.SkipCutscene.LearnSong"), false);
|
||||
CVarSetInteger(CVAR_ENHANCEMENT("TimeSavers.SkipCutscene.BossIntro"), false);
|
||||
CVarSetInteger(CVAR_ENHANCEMENT("TimeSavers.SkipCutscene.QuickBossDeaths"), false);
|
||||
CVarSetInteger(CVAR_ENHANCEMENT("TimeSavers.SkipCutscene.OnePoint"), false);
|
||||
CVarSetInteger(CVAR_ENHANCEMENT("TimeSavers.SkipOwlInteractions"), false);
|
||||
CVarSetInteger(CVAR_ENHANCEMENT("TimeSavers.SkipMiscInteractions"), false);
|
||||
CVarSetInteger(CVAR_ENHANCEMENT("TimeSavers.DisableTitleCard"), false);
|
||||
CVAR_INT_SHIP_INIT(CVAR_ENHANCEMENT("TimeSavers.SkipCutscene.Intro"), false);
|
||||
CVAR_INT_SHIP_INIT(CVAR_ENHANCEMENT("TimeSavers.SkipCutscene.Entrances"), false);
|
||||
CVAR_INT_SHIP_INIT(CVAR_ENHANCEMENT("TimeSavers.SkipCutscene.Story"), false);
|
||||
CVAR_INT_SHIP_INIT(CVAR_ENHANCEMENT("TimeSavers.SkipCutscene.LearnSong"), false);
|
||||
CVAR_INT_SHIP_INIT(CVAR_ENHANCEMENT("TimeSavers.SkipCutscene.BossIntro"), false);
|
||||
CVAR_INT_SHIP_INIT(CVAR_ENHANCEMENT("TimeSavers.SkipCutscene.QuickBossDeaths"), false);
|
||||
CVAR_INT_SHIP_INIT(CVAR_ENHANCEMENT("TimeSavers.SkipCutscene.OnePoint"), false);
|
||||
CVAR_INT_SHIP_INIT(CVAR_ENHANCEMENT("TimeSavers.SkipOwlInteractions"), false);
|
||||
CVAR_INT_SHIP_INIT(CVAR_ENHANCEMENT("TimeSavers.SkipMiscInteractions"), false);
|
||||
CVAR_INT_SHIP_INIT(CVAR_ENHANCEMENT("TimeSavers.DisableTitleCard"), false);
|
||||
|
||||
Ship::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesNextFrame();
|
||||
});
|
||||
@@ -334,15 +347,19 @@ void SohMenu::AddMenuEnhancements() {
|
||||
.Options(CheckboxOptions().DefaultValue(IS_RANDO));
|
||||
AddWidget(path, "Exclude Glitch-Aiding Cutscenes", WIDGET_CVAR_CHECKBOX)
|
||||
.CVar(CVAR_ENHANCEMENT("TimeSavers.SkipCutscene.GlitchAiding"))
|
||||
.Options(CheckboxOptions().Tooltip(
|
||||
"Don't skip cutscenes that are associated with useful glitches. Currently, it is "
|
||||
"only the Fire Temple Darunia CS, Forest Temple Poe Sisters CS, and the Box Skip One "
|
||||
"Point in Jabu."));
|
||||
.Options(
|
||||
CheckboxOptions().Tooltip("Don't skip cutscenes that are associated with useful glitches. Currently, it is "
|
||||
"only the Fire Temple Darunia CS, Forest Temple Poe Sisters CS, Dodongo Boss "
|
||||
"Door Switch CS, Water Temple Dragon Switch CS, the Box Skip One Point in Jabu, "
|
||||
"Early Hammer Switch CS in MQ Spirit, and Cow Switch Chest CS in MQ Jabu."));
|
||||
|
||||
AddWidget(path, "Text", WIDGET_SEPARATOR_TEXT);
|
||||
AddWidget(path, "Skip Pickup Messages", WIDGET_CVAR_CHECKBOX)
|
||||
AddWidget(path, "Skip Bottle Pickup Messages", WIDGET_CVAR_CHECKBOX)
|
||||
.CVar(CVAR_ENHANCEMENT("FastBottles"))
|
||||
.Options(CheckboxOptions().Tooltip("Skip Pickup Messages for Bottle Swipes."));
|
||||
AddWidget(path, "Skip Consumable Item Pickup Messages", WIDGET_CVAR_CHECKBOX)
|
||||
.CVar(CVAR_ENHANCEMENT("FastDrops"))
|
||||
.Options(CheckboxOptions().Tooltip("Skip Pickup Messages for new Consumable Items and Bottle Swipes."));
|
||||
.Options(CheckboxOptions().Tooltip("Skip Pickup Messages for new Consumable Items."));
|
||||
AddWidget(path, "Skip Forced Dialog", WIDGET_CVAR_COMBOBOX)
|
||||
.CVar(CVAR_ENHANCEMENT("TimeSavers.SkipForcedDialog"))
|
||||
.Options(ComboboxOptions()
|
||||
@@ -494,7 +511,7 @@ void SohMenu::AddMenuEnhancements() {
|
||||
.Options(CheckboxOptions().Tooltip(
|
||||
"Scales all of the Adult Equipment, as well as moving some a bit, to fit on Child Link better. May "
|
||||
"not work properly with some mods."));
|
||||
AddWidget(path, "Show Gauntlets in First Person", WIDGET_CVAR_CHECKBOX)
|
||||
AddWidget(path, "Show Gauntlets in First-Person", WIDGET_CVAR_CHECKBOX)
|
||||
.CVar(CVAR_ENHANCEMENT("FirstPersonGauntlets"))
|
||||
.RaceDisable(false)
|
||||
.Options(CheckboxOptions().Tooltip("Renders Gauntlets when using the Bow and Hookshot like in OoT3D."));
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
#include "SohMenu.h"
|
||||
#include "soh/Notification/Notification.h"
|
||||
#include "soh/Enhancements/controls/SohInputEditorWindow.h"
|
||||
#include "SohModals.h"
|
||||
#include <soh/GameVersions.h>
|
||||
#include "soh/ResourceManagerHelpers.h"
|
||||
#include "UIWidgets.hpp"
|
||||
@@ -13,6 +15,7 @@ extern "C" {
|
||||
namespace SohGui {
|
||||
|
||||
extern std::shared_ptr<SohMenu> mSohMenu;
|
||||
extern std::shared_ptr<SohModalWindow> mModalWindow;
|
||||
using namespace UIWidgets;
|
||||
|
||||
static std::unordered_map<int32_t, const char*> imguiScaleOptions = {
|
||||
@@ -373,6 +376,20 @@ void SohMenu::AddMenuSettings() {
|
||||
path.sidebarName = "Controls";
|
||||
path.column = SECTION_COLUMN_1;
|
||||
AddSidebarEntry("Settings", "Controls", 2);
|
||||
AddWidget(path, "Clear Devices", WIDGET_BUTTON)
|
||||
.Callback([](WidgetInfo& info) {
|
||||
SohGui::mModalWindow->RegisterPopup(
|
||||
"Clear Config",
|
||||
"This will completely erase the controls config, including registered devices.\nContinue?", "Clear",
|
||||
"Cancel",
|
||||
[]() {
|
||||
Ship::Context::GetInstance()->GetConsoleVariables()->ClearBlock(CVAR_PREFIX_SETTING ".Controllers");
|
||||
uint8_t bits = 0;
|
||||
Ship::Context::GetInstance()->GetControlDeck()->Init(&bits);
|
||||
},
|
||||
nullptr);
|
||||
})
|
||||
.Options(ButtonOptions().Size(Sizes::Inline));
|
||||
AddWidget(path, "Controller Bindings", WIDGET_SEPARATOR_TEXT);
|
||||
AddWidget(path, "Popout Bindings Window", WIDGET_WINDOW_BUTTON)
|
||||
.CVar(CVAR_WINDOW("ControllerConfiguration"))
|
||||
|
||||
+41
-1
@@ -145,7 +145,47 @@ void Audio_osWritebackDCache(void* mem, s32 size) {
|
||||
}
|
||||
|
||||
s32 osAiSetFrequency(u32 freq) {
|
||||
return 1;
|
||||
// this is based off the math from the original method
|
||||
/*
|
||||
|
||||
s32 osAiSetFrequency(u32 frequency) {
|
||||
u8 bitrate;
|
||||
f32 dacRateF = ((f32)osViClock / frequency) + 0.5f;
|
||||
u32 dacRate = dacRateF;
|
||||
|
||||
if (dacRate < 132) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
bitrate = (dacRate / 66);
|
||||
if (bitrate > 16) {
|
||||
bitrate = 16;
|
||||
}
|
||||
|
||||
HW_REG(AI_DACRATE_REG, u32) = dacRate - 1;
|
||||
HW_REG(AI_BITRATE_REG, u32) = bitrate - 1;
|
||||
return osViClock / (s32)dacRate;
|
||||
}
|
||||
|
||||
*/
|
||||
|
||||
// bitrate is unused
|
||||
|
||||
// osViClock comes from
|
||||
// #define VI_NTSC_CLOCK 48681812 /* Hz = 48.681812 MHz */
|
||||
// s32 osViClock = VI_NTSC_CLOCK;
|
||||
|
||||
// frequency was originally 32000
|
||||
|
||||
// given all of that, dacRate is
|
||||
// (u32)(((f32)48681812 / 32000) + 0.5f)
|
||||
// which evaluates to 1521 (which is > 132)
|
||||
|
||||
// this leaves us with a final calculation of
|
||||
// 48681812 / 1521
|
||||
// which evaluates to 32006
|
||||
|
||||
return 32006;
|
||||
}
|
||||
|
||||
void osInvalDCache(void* vaddr, s32 nbytes) {
|
||||
|
||||
+390
-17
@@ -7,6 +7,7 @@
|
||||
#include <assert.h>
|
||||
#include <spdlog/spdlog.h>
|
||||
#include "Enhancements/randomizer/randomizerTypes.h"
|
||||
#include <variables.h>
|
||||
|
||||
std::vector<std::string> sceneNames = {
|
||||
"Inside the Deku Tree",
|
||||
@@ -121,7 +122,7 @@ std::vector<std::string> sceneNames = {
|
||||
"Treasure Chest Room",
|
||||
};
|
||||
|
||||
std::vector<std::string> itemNames = {
|
||||
std::vector<std::string> itemNamesEng = {
|
||||
"Deku Stick",
|
||||
"Deku Nut",
|
||||
"Bomb",
|
||||
@@ -280,7 +281,325 @@ std::vector<std::string> itemNames = {
|
||||
"Deku Nut Upgrade (40)",
|
||||
};
|
||||
|
||||
std::vector<std::string> questItemNames = {
|
||||
std::vector<std::string> itemNamesFra = {
|
||||
"Bâton Mojo",
|
||||
"Noix Mojo",
|
||||
"Bombe",
|
||||
"Arc des Fées",
|
||||
"Flèche de Feu",
|
||||
"Feu de Din",
|
||||
"Lance-Pierre des Fées",
|
||||
"Ocarina des Fées",
|
||||
"Ocarina du Temps",
|
||||
"Missile Teigneux",
|
||||
"Grappin",
|
||||
"Super Grappin",
|
||||
"Flèche de Glace",
|
||||
"Vent de Farore",
|
||||
"Boomerang",
|
||||
"Monocle de Vérité",
|
||||
"Haricot Magique",
|
||||
"Masse des Titans",
|
||||
"Flèche de Lumière",
|
||||
"Amour de Nayru",
|
||||
"Bouteille Vide",
|
||||
"Potion Rouge",
|
||||
"Potion Verte",
|
||||
"Potion Bleue",
|
||||
"Fée en Bouteille",
|
||||
"Poisson",
|
||||
"Lait Lon Lon et Bouteille",
|
||||
"Lettre de Ruto",
|
||||
"Flamme Bleue",
|
||||
"Insectes",
|
||||
"Grand Spectre",
|
||||
"Lait Lon Lon (Demi)",
|
||||
"Spectre",
|
||||
"Oeuf Suspect",
|
||||
"Poule",
|
||||
"Lettre de Zelda",
|
||||
"Masque Renard",
|
||||
"Masque de Mort",
|
||||
"Masque du Fantôme",
|
||||
"Capuche de Lapin",
|
||||
"Masque Goron",
|
||||
"Masque Zora",
|
||||
"Masque Gerudo",
|
||||
"Masque de Vérité",
|
||||
"ÉPUISÉ",
|
||||
"Oeuf de Poche",
|
||||
"Cocotte de Poche",
|
||||
"Cojiro",
|
||||
"Champignon Suspect",
|
||||
"Potion Suspecte",
|
||||
"Scie du Chasseur",
|
||||
"Épée Goron (Cassée)",
|
||||
"Ordonnance",
|
||||
"Crapaud-qui-louche",
|
||||
"Super Gouttes",
|
||||
"Certificat",
|
||||
"Arc des Fées & Flèche de Feu",
|
||||
"Arc des Fées & Flèche de Glace",
|
||||
"Arc des Fées & Flèche de Lumière",
|
||||
"Épée Kokiri",
|
||||
"Épée de Légende",
|
||||
"Lame des Géants & Épée Biggoron",
|
||||
"Bouclier Mojo",
|
||||
"Bouclier Hylien",
|
||||
"Bouclier Miroir",
|
||||
"Tunique Kokiri",
|
||||
"Tunique Goron",
|
||||
"Tunique Zora",
|
||||
"Bottes Kokiri",
|
||||
"Bottes de Plomb",
|
||||
"Bottes des Airs",
|
||||
"Sac de Graines (30)",
|
||||
"Sac de Graines (40)",
|
||||
"Sac de Graines (50)",
|
||||
"Carquois (30)",
|
||||
"Grand Carquois (40)",
|
||||
"Énorme Grand Carquois (50)",
|
||||
"Sac de Bombes (20)",
|
||||
"Gros Sac de Bombes (30)",
|
||||
"Énorme Sac de Bombes (40)",
|
||||
"Bracelet Goron",
|
||||
"Gantelets d'Argent",
|
||||
"Gantelets d'Or",
|
||||
"Écaille d'Argent",
|
||||
"Écaille d'Or",
|
||||
"Lame des Géants (Cassée)",
|
||||
"Grande Bourse",
|
||||
"Bourse de Géant",
|
||||
"Graines Mojo (5)",
|
||||
"Canne à Pêche",
|
||||
"Menuet des Bois",
|
||||
"Boléro du Feu",
|
||||
"Sérénade de l'Eau",
|
||||
"Requiem de l'Esprit",
|
||||
"Nocturne de l'Ombre",
|
||||
"Prélude de la Lumière",
|
||||
"Berceuse de Zelda",
|
||||
"Chant d'Epona",
|
||||
"Chant de Saria",
|
||||
"Chant du Soleil",
|
||||
"Chant du Temps",
|
||||
"Chant des Tempêtes",
|
||||
"Médaillon de la Forêt",
|
||||
"Médaillon du Feu",
|
||||
"Médaillon de l'Eau",
|
||||
"Médaillon de l'Esprit",
|
||||
"Médaillon de l'Ombre",
|
||||
"Médaillon de la Lumière",
|
||||
"Émeraude Kokiri",
|
||||
"Rubis Goron",
|
||||
"Saphir Zora",
|
||||
"Pierre de Souffrance",
|
||||
"Carte Gerudo",
|
||||
"Symbole de Skulltula d'Or",
|
||||
"Réceptacle de Coeur",
|
||||
"Quart de Coeur",
|
||||
"Clé du Boss",
|
||||
"Boussole",
|
||||
"Carte du Donjon",
|
||||
"Petite Clé",
|
||||
"Petite Magie",
|
||||
"Grande Magie",
|
||||
"Quart de Coeur",
|
||||
"[Retiré]",
|
||||
"[Retiré]",
|
||||
"[Retiré]",
|
||||
"[Retiré]",
|
||||
"[Retiré]",
|
||||
"[Retiré]",
|
||||
"[Retiré]",
|
||||
"Lait Lon Lon",
|
||||
"Coeur",
|
||||
"Rubis Vert",
|
||||
"Rubis Bleu",
|
||||
"Rubis Rouge",
|
||||
"Rubis Pourpre",
|
||||
"Énorme Rubis",
|
||||
"[Retiré]",
|
||||
"Bâtons Mojo (5)",
|
||||
"Bâtons Mojo (10)",
|
||||
"Noix Mojo (5)",
|
||||
"Noix Mojo (10)",
|
||||
"Bombes (5)",
|
||||
"Bombes (10)",
|
||||
"Bombes (20)",
|
||||
"Bombes (30)",
|
||||
"Flèches (Petites)",
|
||||
"Flèches (Moyennes)",
|
||||
"Flèches (Grandes)",
|
||||
"Graines Mojo (30)",
|
||||
"Missile Teigneux (5)",
|
||||
"Missile Teigneux (20)",
|
||||
"Amélioration des Bâtons Mojo (20)",
|
||||
"Amélioration des Bâtons Mojo (30)",
|
||||
"Amélioration des Noix Mojo (30)",
|
||||
"Amélioration des Noix Mojo (40)",
|
||||
};
|
||||
|
||||
std::vector<std::string> itemNamesGer = {
|
||||
"Deku-Stab",
|
||||
"Deku-Nuß",
|
||||
"Bombe",
|
||||
"Feen-Bogen",
|
||||
"Feuer-Pfeil",
|
||||
"Dins Feuerinferno",
|
||||
"Feen-Schleuder",
|
||||
"Feen-Okarina",
|
||||
"Okarina der Zeit",
|
||||
"Krabbelmine",
|
||||
"Fanghaken",
|
||||
"Enterhaken",
|
||||
"Eis-Pfeil",
|
||||
"Farores Donnersturm",
|
||||
"Bumerang",
|
||||
"Auge der Wahrheit",
|
||||
"Wundererbse",
|
||||
"Stahlhammer",
|
||||
"Licht-Pfeil",
|
||||
"Nayrus Umarmung",
|
||||
"Leere Flasche",
|
||||
"Rotes Elixier",
|
||||
"Grünes Elixier",
|
||||
"Blaues Elixier",
|
||||
"Flasche (Fee)",
|
||||
"Fisch",
|
||||
"Flasche (Milch)",
|
||||
"Rutos Brief",
|
||||
"Blaues Feuer",
|
||||
"Käfer",
|
||||
"Nachtschwärmer",
|
||||
"Lon Lon-Milch (Halbe Füllung)",
|
||||
"Irrlicht",
|
||||
"Seltsames Ei",
|
||||
"Huhn",
|
||||
"Zeldas Brief",
|
||||
"Fuchs-Maske",
|
||||
"Geister-Maske",
|
||||
"Schädel-Maske",
|
||||
"Hasenohren",
|
||||
"Goronen-Maske",
|
||||
"Zora-Maske",
|
||||
"Gerudo-Maske",
|
||||
"Maske des Wissens",
|
||||
"AUSVERKAUFT",
|
||||
"Ei",
|
||||
"Kiki",
|
||||
"Henni",
|
||||
"Schimmelpilz",
|
||||
"Modertrank",
|
||||
"Säge",
|
||||
"Zerbr. Goronen-Schwert",
|
||||
"Rezept",
|
||||
"Glotzfrosch",
|
||||
"Augentropfen",
|
||||
"Zertifikat",
|
||||
"Feen-Bogen & Feuer-Pfeil",
|
||||
"Feen-Bogen & Eis-Pfeil",
|
||||
"Feen-Bogen & Licht-Pfeil",
|
||||
"Kokiri-Schwert",
|
||||
"Master-Schwert",
|
||||
"Langschwert & Biggoron-Schwert",
|
||||
"Deku-Schild",
|
||||
"Hylia-Schild",
|
||||
"Spiegel-Schild",
|
||||
"Kokiri-Rüstung",
|
||||
"Goronen-Rüstung",
|
||||
"Zora-Rüstung",
|
||||
"Lederstiefel",
|
||||
"Eisenstiefel",
|
||||
"Gleitstiefel",
|
||||
"Munitionstasche (30)",
|
||||
"Große Munitionstasche (40)",
|
||||
"Riesen-Munitionstasche (50)",
|
||||
"Köcher (30)",
|
||||
"Großer Köcher (40)",
|
||||
"Riesenköcher (50)",
|
||||
"Bombentasche (20)",
|
||||
"Große Bombentasche (30)",
|
||||
"Riesen-Bombentasche (40)",
|
||||
"Goronen-Armband",
|
||||
"Krafthandschuhe",
|
||||
"Titanhandschuhe",
|
||||
"Silberne Schuppe",
|
||||
"Goldene Schuppe",
|
||||
"Zerbr. Langschwert",
|
||||
"Große Börse",
|
||||
"Riesenbörse",
|
||||
"Deku-Kerne (5)",
|
||||
"Angelrute",
|
||||
"Menuett des Waldes",
|
||||
"Bolero des Feuers",
|
||||
"Serenade des Wassers",
|
||||
"Requiem der Geister",
|
||||
"Nocturne des Schattens",
|
||||
"Kantate des Lichts",
|
||||
"Zeldas Wiegenlied",
|
||||
"Eponas Lied",
|
||||
"Salias Lied",
|
||||
"Hymne der Sonne",
|
||||
"Hymne der Zeit",
|
||||
"Hymne des Sturms",
|
||||
"Amulett des Waldes",
|
||||
"Amulett des Feuers",
|
||||
"Amulett des Wassers",
|
||||
"Amulett der Geister",
|
||||
"Amulett des Schattens",
|
||||
"Amulett des Lichts",
|
||||
"Kokiri-Smaragd",
|
||||
"Goronen-Rubin",
|
||||
"Zora-Saphir",
|
||||
"Stein des Wissens",
|
||||
"Gerudo-Paß",
|
||||
"Skulltula-Symbol",
|
||||
"Herzcontainer",
|
||||
"Herzteil",
|
||||
"Master-Schlüssel",
|
||||
"Kompaß",
|
||||
"Labyrinth-Karte",
|
||||
"Kleiner Schlüssel",
|
||||
"Kleine Magieflasche",
|
||||
"Große Magieflasche",
|
||||
"Herzteil",
|
||||
"[Entfernt]",
|
||||
"[Entfernt]",
|
||||
"[Entfernt]",
|
||||
"[Entfernt]",
|
||||
"[Entfernt]",
|
||||
"[Entfernt]",
|
||||
"[Entfernt]",
|
||||
"Lon Lon-Milch",
|
||||
"Herz",
|
||||
"Grüner Rubin",
|
||||
"Blauer Rubin",
|
||||
"Roter Rubin",
|
||||
"Violetter Rubin",
|
||||
"Silberner Rubin",
|
||||
"[Entfernt]",
|
||||
"Deku-Stäbe (5)",
|
||||
"Deku-Stäbe (10)",
|
||||
"Deku-Nüsse (5)",
|
||||
"Deku-Nüsse (10)",
|
||||
"Bomben (5)",
|
||||
"Bomben (10)",
|
||||
"Bomben (20)",
|
||||
"Bomben (30)",
|
||||
"Pfeile (5)",
|
||||
"Pfeile (10)",
|
||||
"Pfeile (30)",
|
||||
"Deku-Kerne (30)",
|
||||
"Krabbelminen (5)",
|
||||
"Krabbelminen (20)",
|
||||
"Deku-Stab-Kapazität (20)",
|
||||
"Deku-Stab-Kapazität (30)",
|
||||
"Deku-Nuß-Kapazität (30)",
|
||||
"Deku-Nuß-Kapazität (40)",
|
||||
};
|
||||
|
||||
std::vector<std::string> questItemNamesEng = {
|
||||
"Forest Medallion", "Fire Medallion", "Water Medallion", "Spirit Medallion", "Shadow Medallion",
|
||||
"Light Medallion", "Minuet of Forest", "Bolero of Fire", "Serenade of Water", "Requiem of Spirit",
|
||||
"Nocturne of Shadow", "Prelude of Light", "Zelda's Lullaby", "Epona's Song", "Saria's Song",
|
||||
@@ -288,6 +607,42 @@ std::vector<std::string> questItemNames = {
|
||||
"Zora's Sapphire", "Stone of Agony", "Gerudo's Card", "Gold Skulltula Token",
|
||||
};
|
||||
|
||||
std::vector<std::string> questItemNamesFra = {
|
||||
"Médaillon de la Forêt", "Médaillon du Feu", "Médaillon de l'Eau", "Médaillon de l'Esprit",
|
||||
"Médaillon de l'Ombre", "Médaillon de la Lumière", "Menuet des Bois", "Boléro du Feu",
|
||||
"Sérénade de l'Eau", "Requiem de l'Esprit", "Nocturne de l'Ombre", "Prélude de la Lumière",
|
||||
"Berceuse de Zelda", "Chant d'Epona", "Chant de Saria", "Chant du Soleil",
|
||||
"Chant du Temps", "Chant des Tempêtes", "Émeraude Kokiri", "Rubis Goron",
|
||||
"Saphir Zora", "Pierre de Souffrance", "Carte Gerudo", "Symbole de Skulltula d'Or",
|
||||
};
|
||||
|
||||
std::vector<std::string> questItemNamesGer = {
|
||||
"Amulett des Waldes",
|
||||
"Amulett des Feuers",
|
||||
"Amulett des Wassers",
|
||||
"Amulett der Geister",
|
||||
"Amulett des Schattens",
|
||||
"Amulett des Lichts",
|
||||
"Menuett des Waldes",
|
||||
"Bolero des Feuers",
|
||||
"Serenade des Wassers",
|
||||
"Requiem der Geister",
|
||||
"Nocturne des Schattens",
|
||||
"Kantate des Lichts",
|
||||
"Zeldas Wiegenlied",
|
||||
"Eponas Lied",
|
||||
"Salias Lied",
|
||||
"Hymne der Sonne",
|
||||
"Hymne der Zeit",
|
||||
"Hymne des Sturms",
|
||||
"Kokiri-Smaragd",
|
||||
"Goronen-Rubin",
|
||||
"Zora-Saphir",
|
||||
"Stein des Wissens",
|
||||
"Gerudo-Paß",
|
||||
"Goldenes Skulltula-Symbol",
|
||||
};
|
||||
|
||||
std::array<std::string, RA_MAX> rcareaPrefixes = {
|
||||
"KF",
|
||||
"LW",
|
||||
@@ -334,23 +689,52 @@ const std::string& SohUtils::GetSceneName(int32_t scene) {
|
||||
}
|
||||
|
||||
const std::string& SohUtils::GetItemName(int32_t item) {
|
||||
if (item > itemNames.size()) {
|
||||
const std::vector<std::string>* currentItemNames = nullptr;
|
||||
|
||||
switch (gSaveContext.language) {
|
||||
case LANGUAGE_FRA:
|
||||
currentItemNames = &itemNamesFra;
|
||||
break;
|
||||
case LANGUAGE_GER:
|
||||
currentItemNames = &itemNamesGer;
|
||||
break;
|
||||
case LANGUAGE_ENG:
|
||||
default:
|
||||
currentItemNames = &itemNamesEng;
|
||||
break;
|
||||
}
|
||||
|
||||
if (item >= currentItemNames->size()) {
|
||||
SPDLOG_WARN("Passed invalid item id to SohUtils::GetItemName: ({})", item);
|
||||
assert(false);
|
||||
return "";
|
||||
}
|
||||
|
||||
return itemNames[item];
|
||||
return (*currentItemNames)[item];
|
||||
}
|
||||
|
||||
const std::string& SohUtils::GetQuestItemName(int32_t item) {
|
||||
if (item > questItemNames.size()) {
|
||||
const std::vector<std::string>* currentQuestItemNames = nullptr;
|
||||
|
||||
switch (gSaveContext.language) {
|
||||
case LANGUAGE_FRA:
|
||||
currentQuestItemNames = &questItemNamesFra;
|
||||
break;
|
||||
case LANGUAGE_GER:
|
||||
currentQuestItemNames = &questItemNamesGer;
|
||||
break;
|
||||
case LANGUAGE_ENG:
|
||||
default:
|
||||
currentQuestItemNames = &questItemNamesEng;
|
||||
break;
|
||||
}
|
||||
if (item > questItemNamesEng.size()) {
|
||||
SPDLOG_WARN("Passed invalid quest item id to SohUtils::GetQuestItemName: ({})", item);
|
||||
assert(false);
|
||||
return "";
|
||||
}
|
||||
|
||||
return questItemNames[item];
|
||||
return (*currentQuestItemNames)[item];
|
||||
}
|
||||
|
||||
const std::string& SohUtils::GetRandomizerCheckAreaPrefix(int32_t rcarea) {
|
||||
@@ -369,17 +753,6 @@ void SohUtils::CopyStringToCharArray(char* destination, std::string source, size
|
||||
}
|
||||
|
||||
std::string SohUtils::Sanitize(std::string stringValue) {
|
||||
// Add backslashes.
|
||||
for (auto i = stringValue.begin();;) {
|
||||
auto const pos =
|
||||
std::find_if(i, stringValue.end(), [](char const c) { return '\\' == c || '\'' == c || '"' == c; });
|
||||
if (pos == stringValue.end()) {
|
||||
break;
|
||||
}
|
||||
i = std::next(stringValue.insert(pos, '\\'), 2);
|
||||
}
|
||||
|
||||
// Removes others.
|
||||
stringValue.erase(std::remove_if(stringValue.begin(), stringValue.end(),
|
||||
[](char const c) { return '\n' == c || '\r' == c || '\0' == c || '\x1A' == c; }),
|
||||
stringValue.end());
|
||||
|
||||
@@ -4112,7 +4112,8 @@ void Interface_DrawItemButtons(PlayState* play) {
|
||||
if (CVarGetInteger(CVAR_COSMETIC("HUD.CDownButton.UseMargins"), 0) != 0) {
|
||||
X_Margins_CD = Left_HUD_Margin;
|
||||
};
|
||||
C_Down_BTN_Pos[0] = (CVarGetInteger(CVAR_COSMETIC("HUD.CDownButton.PosX"), 0) + X_Margins_CD);
|
||||
C_Down_BTN_Pos[0] =
|
||||
OTRGetDimensionFromLeftEdge(CVarGetInteger(CVAR_COSMETIC("HUD.CDownButton.PosX"), 0) + X_Margins_CD);
|
||||
} else if (CVarGetInteger(CVAR_COSMETIC("HUD.CDownButton.PosType"), 0) == ANCHOR_RIGHT) {
|
||||
if (CVarGetInteger(CVAR_COSMETIC("HUD.CDownButton.UseMargins"), 0) != 0) {
|
||||
X_Margins_CD = Right_HUD_Margin;
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
|
||||
#include "z_bg_mori_kaitenkabe.h"
|
||||
#include "objects/object_mori_objects/object_mori_objects.h"
|
||||
#include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h"
|
||||
|
||||
#define FLAGS 0
|
||||
|
||||
@@ -97,7 +98,9 @@ void BgMoriKaitenkabe_Wait(BgMoriKaitenkabe* this, PlayState* play) {
|
||||
if ((this->timer > (28 - CVarGetInteger(CVAR_ENHANCEMENT("FasterBlockPush"), 0) * 4)) &&
|
||||
!Player_InCsMode(play)) {
|
||||
BgMoriKaitenkabe_SetupRotate(this);
|
||||
Player_SetCsActionWithHaltedActors(play, &this->dyna.actor, 8);
|
||||
if (GameInteractor_Should(VB_FREEZE_LINK_FOR_FOREST_PILLARS, true)) {
|
||||
Player_SetCsActionWithHaltedActors(play, &this->dyna.actor, 8);
|
||||
}
|
||||
Math_Vec3f_Copy(&this->lockedPlayerPos, &player->actor.world.pos);
|
||||
push.x = Math_SinS(this->dyna.unk_158);
|
||||
push.y = 0.0f;
|
||||
@@ -131,7 +134,9 @@ void BgMoriKaitenkabe_Rotate(BgMoriKaitenkabe* this, PlayState* play) {
|
||||
Math_StepToF(&this->rotSpeed, 0.6f, 0.02f);
|
||||
if (Math_StepToF(&this->rotYdeg, this->rotDirection * 45.0f, this->rotSpeed)) {
|
||||
BgMoriKaitenkabe_SetupWait(this);
|
||||
Player_SetCsActionWithHaltedActors(play, thisx, 7);
|
||||
if (GameInteractor_Should(VB_FREEZE_LINK_FOR_FOREST_PILLARS, true)) {
|
||||
Player_SetCsActionWithHaltedActors(play, thisx, 7);
|
||||
}
|
||||
if (this->rotDirection > 0.0f) {
|
||||
thisx->home.rot.y += 0x2000;
|
||||
} else {
|
||||
@@ -148,7 +153,9 @@ void BgMoriKaitenkabe_Rotate(BgMoriKaitenkabe* this, PlayState* play) {
|
||||
this->dyna.unk_150 = 0.0f;
|
||||
player->stateFlags2 &= ~PLAYER_STATE2_MOVING_DYNAPOLY;
|
||||
}
|
||||
Math_Vec3f_Copy(&player->actor.world.pos, &this->lockedPlayerPos);
|
||||
if (GameInteractor_Should(VB_FREEZE_LINK_FOR_FOREST_PILLARS, true)) {
|
||||
Math_Vec3f_Copy(&player->actor.world.pos, &this->lockedPlayerPos);
|
||||
}
|
||||
}
|
||||
|
||||
void BgMoriKaitenkabe_Update(Actor* thisx, PlayState* play) {
|
||||
|
||||
@@ -131,8 +131,14 @@ void func_808BAF40(BgTokiSwd* this, PlayState* play) {
|
||||
Item_Give(play, ITEM_SWORD_MASTER);
|
||||
}
|
||||
play->csCtx.segment = D_808BB2F0;
|
||||
|
||||
// Discover adult spawn
|
||||
Entrance_SetEntranceDiscovered(ENTR_HYRULE_FIELD_10, false);
|
||||
} else {
|
||||
play->csCtx.segment = D_808BB7A0;
|
||||
|
||||
// Discover child spawn
|
||||
Entrance_SetEntranceDiscovered(ENTR_LINKS_HOUSE_CHILD_SPAWN, false);
|
||||
}
|
||||
Audio_QueueSeqCmd(SEQ_PLAYER_BGM_MAIN << 24 | NA_BGM_STOP);
|
||||
Audio_QueueSeqCmd(SEQ_PLAYER_BGM_MAIN << 24 | NA_BGM_MASTER_SWORD);
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
#include "z_demo_kekkai.h"
|
||||
#include "objects/object_demo_kekkai/object_demo_kekkai.h"
|
||||
#include "scenes/dungeons/ganontika/ganontika_scene.h"
|
||||
#include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h"
|
||||
#include "soh/ResourceManagerHelpers.h"
|
||||
|
||||
#define FLAGS (ACTOR_FLAG_UPDATE_CULLING_DISABLED | ACTOR_FLAG_DRAW_CULLING_DISABLED)
|
||||
@@ -257,13 +258,15 @@ void DemoKekkai_TrialBarrierIdle(Actor* thisx, PlayState* play) {
|
||||
CollisionCheck_SetAT(play, &play->colChkCtx, &this->collider1.base);
|
||||
CollisionCheck_SetOC(play, &play->colChkCtx, &this->collider1.base);
|
||||
if (this->collider2.base.acFlags & AC_HIT) {
|
||||
Sfx_PlaySfxCentered(NA_SE_SY_CORRECT_CHIME);
|
||||
// "I got it"
|
||||
LOG_STRING("当ったよ");
|
||||
this->actor.update = DemoKekkai_TrialBarrierDispel;
|
||||
this->timer = 0;
|
||||
play->csCtx.segment = SEGMENTED_TO_VIRTUAL(sSageCutscenes[this->actor.params]);
|
||||
gSaveContext.cutsceneTrigger = 1;
|
||||
if (GameInteractor_Should(VB_PLAY_DISPEL_BARRIER_CS, true, this)) {
|
||||
Sfx_PlaySfxCentered(NA_SE_SY_CORRECT_CHIME);
|
||||
// "I got it"
|
||||
LOG_STRING("当ったよ");
|
||||
this->actor.update = DemoKekkai_TrialBarrierDispel;
|
||||
this->timer = 0;
|
||||
play->csCtx.segment = SEGMENTED_TO_VIRTUAL(sSageCutscenes[this->actor.params]);
|
||||
gSaveContext.cutsceneTrigger = 1;
|
||||
}
|
||||
}
|
||||
CollisionCheck_SetAC(play, &play->colChkCtx, &this->collider2.base);
|
||||
func_8002F974(&this->actor, NA_SE_EV_TOWER_ENERGY - SFX_FLAG);
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
|
||||
struct DemoKekkai;
|
||||
|
||||
typedef void (*DemoKekkaiUpdateFunc)(struct DemoKekkai* this, PlayState* play);
|
||||
typedef void (*DemoKekkaiUpdateFunc)(struct DemoKekkai* thisx, PlayState* play);
|
||||
|
||||
typedef struct DemoKekkai {
|
||||
/* 0x0000 */ Actor actor;
|
||||
|
||||
@@ -314,19 +314,21 @@ void func_80A5372C(EnHeishi2* this, PlayState* play) {
|
||||
f32 frameCount = Animation_GetLastFrame(&gEnHeishiIdleAnim);
|
||||
|
||||
Animation_Change(&this->skelAnime, &gEnHeishiIdleAnim, 1.0f, 0.0f, (s16)frameCount, ANIMMODE_LOOP, -10.0f);
|
||||
this->unk_2F2[0] = 200;
|
||||
this->cameraId = Play_CreateSubCamera(play);
|
||||
Play_ChangeCameraStatus(play, MAIN_CAM, CAM_STAT_WAIT);
|
||||
Play_ChangeCameraStatus(play, this->cameraId, CAM_STAT_ACTIVE);
|
||||
this->unk_280.x = 947.0f;
|
||||
this->unk_280.y = 1195.0f;
|
||||
this->unk_280.z = 2682.0f;
|
||||
if (GameInteractor_Should(VB_PLAY_GATE_OPENING_OR_CLOSING_CS, true, this, false)) {
|
||||
this->unk_2F2[0] = 200;
|
||||
this->cameraId = Play_CreateSubCamera(play);
|
||||
Play_ChangeCameraStatus(play, MAIN_CAM, CAM_STAT_WAIT);
|
||||
Play_ChangeCameraStatus(play, this->cameraId, CAM_STAT_ACTIVE);
|
||||
this->unk_280.x = 947.0f;
|
||||
this->unk_280.y = 1195.0f;
|
||||
this->unk_280.z = 2682.0f;
|
||||
|
||||
this->unk_28C.x = 1164.0f;
|
||||
this->unk_28C.y = 1145.0f;
|
||||
this->unk_28C.z = 3014.0f;
|
||||
this->unk_28C.x = 1164.0f;
|
||||
this->unk_28C.y = 1145.0f;
|
||||
this->unk_28C.z = 3014.0f;
|
||||
|
||||
Play_CameraSetAtEye(play, this->cameraId, &this->unk_280, &this->unk_28C);
|
||||
Play_CameraSetAtEye(play, this->cameraId, &this->unk_280, &this->unk_28C);
|
||||
}
|
||||
this->actionFunc = func_80A53850;
|
||||
}
|
||||
|
||||
@@ -334,11 +336,15 @@ void func_80A53850(EnHeishi2* this, PlayState* play) {
|
||||
BgSpot15Saku* gate;
|
||||
|
||||
SkelAnime_Update(&this->skelAnime);
|
||||
Play_CameraSetAtEye(play, this->cameraId, &this->unk_280, &this->unk_28C);
|
||||
if (GameInteractor_Should(VB_PLAY_GATE_OPENING_OR_CLOSING_CS, true, this, false)) {
|
||||
Play_CameraSetAtEye(play, this->cameraId, &this->unk_280, &this->unk_28C);
|
||||
}
|
||||
gate = (BgSpot15Saku*)this->gate;
|
||||
if ((this->unk_2F2[0] == 0) || (gate->unk_168 == 0)) {
|
||||
Play_ClearCamera(play, this->cameraId);
|
||||
Play_ChangeCameraStatus(play, MAIN_CAM, CAM_STAT_ACTIVE);
|
||||
if (GameInteractor_Should(VB_PLAY_GATE_OPENING_OR_CLOSING_CS, true, this, true)) {
|
||||
Play_ClearCamera(play, this->cameraId);
|
||||
Play_ChangeCameraStatus(play, MAIN_CAM, CAM_STAT_ACTIVE);
|
||||
}
|
||||
Message_CloseTextbox(play);
|
||||
this->unk_30C = 1;
|
||||
Player_SetCsActionWithHaltedActors(play, NULL, 7);
|
||||
@@ -479,23 +485,25 @@ void func_80A53DF8(EnHeishi2* this, PlayState* play) {
|
||||
f32 frameCount = Animation_GetLastFrame(&gEnHeishiIdleAnim);
|
||||
|
||||
Animation_Change(&this->skelAnime, &gEnHeishiIdleAnim, 1.0f, 0.0f, (s16)frameCount, ANIMMODE_LOOP, -10.0f);
|
||||
this->unk_2F2[0] = 200;
|
||||
this->cameraId = Play_CreateSubCamera(play);
|
||||
Play_ChangeCameraStatus(play, MAIN_CAM, CAM_STAT_WAIT);
|
||||
Play_ChangeCameraStatus(play, this->cameraId, CAM_STAT_ACTIVE);
|
||||
this->unk_2BC.x = -71.0f;
|
||||
this->unk_280.x = -71.0f;
|
||||
this->unk_2BC.y = 571.0f;
|
||||
this->unk_280.y = 571.0f;
|
||||
this->unk_2BC.z = -1487.0f;
|
||||
this->unk_280.z = -1487.0f;
|
||||
this->unk_298.x = 181.0f;
|
||||
this->unk_28C.x = 181.0f;
|
||||
this->unk_298.y = 417.0f;
|
||||
this->unk_28C.y = 417.0f;
|
||||
this->unk_298.z = -1079.0f;
|
||||
this->unk_28C.z = -1079.0f;
|
||||
Play_CameraSetAtEye(play, this->cameraId, &this->unk_280, &this->unk_28C);
|
||||
if (GameInteractor_Should(VB_PLAY_GATE_OPENING_OR_CLOSING_CS, true, this, false)) {
|
||||
this->unk_2F2[0] = 200;
|
||||
this->cameraId = Play_CreateSubCamera(play);
|
||||
Play_ChangeCameraStatus(play, MAIN_CAM, CAM_STAT_WAIT);
|
||||
Play_ChangeCameraStatus(play, this->cameraId, CAM_STAT_ACTIVE);
|
||||
this->unk_2BC.x = -71.0f;
|
||||
this->unk_280.x = -71.0f;
|
||||
this->unk_2BC.y = 571.0f;
|
||||
this->unk_280.y = 571.0f;
|
||||
this->unk_2BC.z = -1487.0f;
|
||||
this->unk_280.z = -1487.0f;
|
||||
this->unk_298.x = 181.0f;
|
||||
this->unk_28C.x = 181.0f;
|
||||
this->unk_298.y = 417.0f;
|
||||
this->unk_28C.y = 417.0f;
|
||||
this->unk_298.z = -1079.0f;
|
||||
this->unk_28C.z = -1079.0f;
|
||||
Play_CameraSetAtEye(play, this->cameraId, &this->unk_280, &this->unk_28C);
|
||||
}
|
||||
this->actionFunc = func_80A53F30;
|
||||
}
|
||||
|
||||
@@ -503,11 +511,15 @@ void func_80A53F30(EnHeishi2* this, PlayState* play) {
|
||||
BgGateShutter* gate;
|
||||
|
||||
SkelAnime_Update(&this->skelAnime);
|
||||
Play_CameraSetAtEye(play, this->cameraId, &this->unk_280, &this->unk_28C);
|
||||
if (GameInteractor_Should(VB_PLAY_GATE_OPENING_OR_CLOSING_CS, true, this, false)) {
|
||||
Play_CameraSetAtEye(play, this->cameraId, &this->unk_280, &this->unk_28C);
|
||||
}
|
||||
gate = (BgGateShutter*)this->gate;
|
||||
if ((this->unk_2F2[0] == 0) || (gate->openingState == 0)) {
|
||||
Play_ClearCamera(play, this->cameraId);
|
||||
Play_ChangeCameraStatus(play, MAIN_CAM, CAM_STAT_ACTIVE);
|
||||
if (GameInteractor_Should(VB_PLAY_GATE_OPENING_OR_CLOSING_CS, true, this, true)) {
|
||||
Play_ClearCamera(play, this->cameraId);
|
||||
Play_ChangeCameraStatus(play, MAIN_CAM, CAM_STAT_ACTIVE);
|
||||
}
|
||||
if ((this->unk_30A != 2)) {
|
||||
if (this->unk_30A == 0) {
|
||||
this->actor.textId = 0x2015;
|
||||
|
||||
@@ -303,7 +303,7 @@ void EnMb_Init(Actor* thisx, PlayState* play) {
|
||||
|
||||
relYawFromPlayer =
|
||||
this->actor.world.rot.y - Math_Vec3f_Yaw(&this->actor.world.pos, &player->actor.world.pos);
|
||||
if (ABS(relYawFromPlayer) > 0x4000) {
|
||||
if (ABS(relYawFromPlayer) > 0x4000 && !CVarGetInteger(CVAR_ENHANCEMENT("RandomizedEnemies"), 0)) {
|
||||
this->actor.world.rot.y = thisx->world.rot.y + 0x8000;
|
||||
this->actor.shape.rot.y = thisx->world.rot.y;
|
||||
this->actor.world.pos.z = thisx->world.pos.z + 600.0f;
|
||||
|
||||
@@ -654,7 +654,7 @@ void EnPartner_Update(Actor* thisx, PlayState* play) {
|
||||
itemActor->params == ITEM00_ARROWS_MEDIUM || itemActor->params == ITEM00_ARROWS_LARGE ||
|
||||
itemActor->params == ITEM00_BOMBCHU || itemActor->params == ITEM00_MAGIC_SMALL ||
|
||||
itemActor->params == ITEM00_MAGIC_LARGE || itemActor->params == ITEM00_NUTS ||
|
||||
itemActor->params == ITEM00_STICK) {
|
||||
itemActor->params == ITEM00_STICK || itemActor->params == ITEM00_SEEDS) {
|
||||
f32 distanceToObject = Actor_WorldDistXYZToActor(&this->actor, itemActor);
|
||||
if (distanceToObject <= 20.0f) {
|
||||
itemActor->world.pos = GET_PLAYER(play)->actor.world.pos;
|
||||
|
||||
@@ -507,7 +507,7 @@ void EnRr_CollisionCheck(EnRr* this, PlayState* play) {
|
||||
this->collider2.base.ocFlags1 &= ~OC1_HIT;
|
||||
// "catch"
|
||||
osSyncPrintf(VT_FGCOL(GREEN) "キャッチ(%d)!!" VT_RST "\n", this->frameCount);
|
||||
if (play->grabPlayer(play, player)) {
|
||||
if (GameInteractor_Should(VB_LIKE_LIKE_GRAB_PLAYER, true, this) && play->grabPlayer(play, player)) {
|
||||
player->actor.parent = &this->actor;
|
||||
this->stopScroll = false;
|
||||
EnRr_SetupGrabPlayer(this, player);
|
||||
|
||||
@@ -706,7 +706,7 @@ void EnTorch2_Update(Actor* thisx, PlayState* play2) {
|
||||
sStaggerCount = 0;
|
||||
}
|
||||
}
|
||||
if (player->linearVelocity == -18.0f) {
|
||||
if (GameInteractor_Should(VB_TORCH2_HANDLE_CLANKING, player->linearVelocity == -18.0f, this)) {
|
||||
if (this->actor.xzDistToPlayer > 80.0f) {
|
||||
player->linearVelocity = 1.2f;
|
||||
} else if (this->actor.xzDistToPlayer < 70.0f) {
|
||||
|
||||
@@ -4764,7 +4764,9 @@ s32 func_808382DC(Player* this, PlayState* play) {
|
||||
gSaveContext.respawn[RESPAWN_MODE_DOWN].yaw = respawnInfo->yaw;
|
||||
}
|
||||
|
||||
Play_TriggerVoidOut(play);
|
||||
if (GameInteractor_Should(VB_TRIGGER_VOIDOUT, true, this)) {
|
||||
Play_TriggerVoidOut(play);
|
||||
}
|
||||
}
|
||||
|
||||
Player_PlayVoiceSfx(this, NA_SE_VO_LI_TAKEN_AWAY);
|
||||
@@ -5129,7 +5131,9 @@ s32 Player_HandleExitsAndVoids(PlayState* play, Player* this, CollisionPoly* pol
|
||||
}
|
||||
|
||||
if (exitIndex == 0) {
|
||||
Play_TriggerVoidOut(play);
|
||||
if (GameInteractor_Should(VB_TRIGGER_VOIDOUT, true, this)) {
|
||||
Play_TriggerVoidOut(play);
|
||||
}
|
||||
Scene_SetTransitionForNextEntrance(play);
|
||||
} else {
|
||||
play->nextEntranceIndex = play->setupExitList[exitIndex - 1];
|
||||
@@ -5163,7 +5167,9 @@ s32 Player_HandleExitsAndVoids(PlayState* play, Player* this, CollisionPoly* pol
|
||||
SurfaceType_GetSlope(&play->colCtx, poly, bgId) == 2,
|
||||
play->setupExitList[exitIndex - 1])) {
|
||||
gSaveContext.respawn[RESPAWN_MODE_DOWN].entranceIndex = play->nextEntranceIndex;
|
||||
Play_TriggerVoidOut(play);
|
||||
if (GameInteractor_Should(VB_TRIGGER_VOIDOUT, true, this)) {
|
||||
Play_TriggerVoidOut(play);
|
||||
}
|
||||
gSaveContext.respawnFlag = -2;
|
||||
}
|
||||
gSaveContext.retainWeatherMode = 1;
|
||||
@@ -5226,7 +5232,7 @@ s32 Player_HandleExitsAndVoids(PlayState* play, Player* this, CollisionPoly* pol
|
||||
if (this->actor.bgCheckFlags & 1) {
|
||||
if (this->floorProperty == 5) {
|
||||
Play_TriggerRespawn(play);
|
||||
} else {
|
||||
} else if (GameInteractor_Should(VB_TRIGGER_VOIDOUT, true, this)) {
|
||||
Play_TriggerVoidOut(play);
|
||||
}
|
||||
play->transitionType = TRANS_TYPE_FADE_BLACK_FAST;
|
||||
@@ -9613,6 +9619,10 @@ static FallImpactInfo D_80854600[] = {
|
||||
s32 func_80843E64(PlayState* play, Player* this) {
|
||||
s32 sp34;
|
||||
|
||||
if (!GameInteractor_Should(VB_RECIEVE_FALL_DAMAGE, true, this)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if ((sFloorType == 6) || (sFloorType == 9)) {
|
||||
sp34 = 0;
|
||||
} else {
|
||||
@@ -14687,7 +14697,7 @@ void Player_Action_SwingBottle(Player* this, PlayState* play) {
|
||||
if (LinkAnimation_Update(play, &this->skelAnime)) {
|
||||
if (this->av1.bottleCatchType != BOTTLE_CATCH_NONE) {
|
||||
if (!this->av2.startedTextbox) {
|
||||
if (CVarGetInteger(CVAR_ENHANCEMENT("FastDrops"), 0)) {
|
||||
if (CVarGetInteger(CVAR_ENHANCEMENT("FastBottles"), 0)) {
|
||||
this->av1.bottleCatchType = BOTTLE_CATCH_NONE;
|
||||
} else {
|
||||
// 1 is subtracted because `sBottleCatchInfo` does not have an entry for `BOTTLE_CATCH_NONE`
|
||||
@@ -14730,13 +14740,13 @@ void Player_Action_SwingBottle(Player* this, PlayState* play) {
|
||||
this->av1.bottleCatchType = i + 1;
|
||||
|
||||
this->av2.startedTextbox = false;
|
||||
if (!CVarGetInteger(CVAR_ENHANCEMENT("FastDrops"), 0)) {
|
||||
if (!CVarGetInteger(CVAR_ENHANCEMENT("FastBottles"), 0)) {
|
||||
this->stateFlags1 |= PLAYER_STATE1_IN_ITEM_CS | PLAYER_STATE1_IN_CUTSCENE;
|
||||
}
|
||||
this->interactRangeActor->parent = &this->actor;
|
||||
|
||||
Player_UpdateBottleHeld(play, this, catchInfo->itemId, ABS(catchInfo->itemAction));
|
||||
if (!CVarGetInteger(CVAR_ENHANCEMENT("FastDrops"), 0)) {
|
||||
if (!CVarGetInteger(CVAR_ENHANCEMENT("FastBottles"), 0)) {
|
||||
Player_AnimPlayOnceAdjusted(play, this, swingEntry->catchAnimation);
|
||||
func_80835EA4(play, 4);
|
||||
}
|
||||
@@ -15009,7 +15019,7 @@ void Player_Action_8084F88C(Player* this, PlayState* play) {
|
||||
if (IS_RANDO && Randomizer_GetSettingValue(RSK_SHUFFLE_ENTRANCES)) {
|
||||
Grotto_ForceRegularVoidOut();
|
||||
}
|
||||
} else {
|
||||
} else if (GameInteractor_Should(VB_TRIGGER_VOIDOUT, true, this)) {
|
||||
Play_TriggerVoidOut(play);
|
||||
}
|
||||
|
||||
|
||||
@@ -26,6 +26,7 @@
|
||||
#include "soh/SaveManager.h"
|
||||
#include "soh/OTRGlobals.h"
|
||||
#include "soh/ResourceManagerHelpers.h"
|
||||
#include "soh/ShipUtils.h"
|
||||
|
||||
typedef struct {
|
||||
s16 left;
|
||||
@@ -1053,20 +1054,27 @@ void FileChoose_UpdateRandomizer() {
|
||||
if (!SpoilerFileExists(CVarGetString(CVAR_GENERAL("SpoilerLog"), "")) &&
|
||||
!CVarGetInteger(CVAR_RANDOMIZER_SETTING("DontGenerateSpoiler"), 0)) {
|
||||
CVarSetString(CVAR_GENERAL("SpoilerLog"), "");
|
||||
Randomizer_SetSpoilerLoaded(false);
|
||||
}
|
||||
|
||||
if (CVarGetInteger(CVAR_GENERAL("RandomizerNewFileDropped"), 0) != 0 ||
|
||||
!(Randomizer_IsSeedGenerated() || Randomizer_IsSpoilerLoaded()) &&
|
||||
SpoilerFileExists(CVarGetString(CVAR_GENERAL("SpoilerLog"), "")) && !fileSelectSpoilerFileLoaded) {
|
||||
if (CVarGetInteger(CVAR_GENERAL("RandomizerNewFileDropped"), 0) != 0) {
|
||||
CVarSetString(CVAR_GENERAL("SpoilerLog"), CVarGetString(CVAR_GENERAL("RandomizerDroppedFile"), ""));
|
||||
Audio_PlayFanfare(NA_BGM_HORSE_GOAL);
|
||||
if (SpoilerFileExists(CVarGetString(CVAR_GENERAL("RandomizerDroppedFile"), ""))) {
|
||||
CVarSetString(CVAR_GENERAL("SpoilerLog"), CVarGetString(CVAR_GENERAL("RandomizerDroppedFile"), ""));
|
||||
Sfx_PlaySfxCentered(NA_SE_SY_CORRECT_CHIME);
|
||||
} else {
|
||||
Sfx_PlaySfxCentered(NA_SE_SY_ERROR);
|
||||
}
|
||||
}
|
||||
const char* fileLoc = CVarGetString(CVAR_GENERAL("SpoilerLog"), "");
|
||||
CVarSetInteger(CVAR_GENERAL("RandomizerNewFileDropped"), 0);
|
||||
CVarSetString(CVAR_GENERAL("RandomizerDroppedFile"), "");
|
||||
Randomizer_ParseSpoiler(fileLoc);
|
||||
fileSelectSpoilerFileLoaded = true;
|
||||
if (!Ship_IsCStringEmpty(fileLoc)) {
|
||||
Randomizer_ParseSpoiler(fileLoc);
|
||||
fileSelectSpoilerFileLoaded = true;
|
||||
}
|
||||
|
||||
if (SpoilerFileExists(CVarGetString(CVAR_GENERAL("SpoilerLog"), "")) &&
|
||||
CVarGetInteger(CVAR_RANDOMIZER_SETTING("DontGenerateSpoiler"), 0)) {
|
||||
|
||||
@@ -8,51 +8,6 @@
|
||||
extern const char* digitTextures[];
|
||||
|
||||
void KaleidoScope_DrawQuestStatus(PlayState* play, GraphicsContext* gfxCtx) {
|
||||
Color_RGB8 aButtonColor = { 80, 150, 255 };
|
||||
if (CVarGetInteger(CVAR_COSMETIC("HUD.AButton.Changed"), 0)) {
|
||||
aButtonColor = CVarGetColor24(CVAR_COSMETIC("HUD.AButton.Value"), aButtonColor);
|
||||
} else if (CVarGetInteger(CVAR_COSMETIC("DefaultColorScheme"), COLORSCHEME_N64) == COLORSCHEME_GAMECUBE) {
|
||||
aButtonColor = (Color_RGB8){ 80, 255, 150 };
|
||||
}
|
||||
if (!GameInteractor_Should(VB_HAVE_OCARINA_NOTE_D4, true)) {
|
||||
aButtonColor = (Color_RGB8){ 191, 191, 191 };
|
||||
}
|
||||
|
||||
Color_RGB8 cButtonsColor = { 255, 255, 50 };
|
||||
if (CVarGetInteger(CVAR_COSMETIC("HUD.CButtons.Changed"), 0)) {
|
||||
cButtonsColor = CVarGetColor24(CVAR_COSMETIC("HUD.CButtons.Value"), cButtonsColor);
|
||||
}
|
||||
Color_RGB8 cUpButtonColor = cButtonsColor;
|
||||
if (CVarGetInteger(CVAR_COSMETIC("HUD.CUpButton.Changed"), 0)) {
|
||||
cUpButtonColor = CVarGetColor24(CVAR_COSMETIC("HUD.CUpButton.Value"), cUpButtonColor);
|
||||
}
|
||||
if (!GameInteractor_Should(VB_HAVE_OCARINA_NOTE_D5, true)) {
|
||||
cUpButtonColor = (Color_RGB8){ 191, 191, 191 };
|
||||
}
|
||||
|
||||
Color_RGB8 cDownButtonColor = cButtonsColor;
|
||||
if (CVarGetInteger(CVAR_COSMETIC("HUD.CDownButton.Changed"), 0)) {
|
||||
cDownButtonColor = CVarGetColor24(CVAR_COSMETIC("HUD.CDownButton.Value"), cDownButtonColor);
|
||||
}
|
||||
if (!GameInteractor_Should(VB_HAVE_OCARINA_NOTE_F4, true)) {
|
||||
cDownButtonColor = (Color_RGB8){ 191, 191, 191 };
|
||||
}
|
||||
|
||||
Color_RGB8 cLeftButtonColor = cButtonsColor;
|
||||
if (CVarGetInteger(CVAR_COSMETIC("HUD.CLeftButton.Changed"), 0)) {
|
||||
cLeftButtonColor = CVarGetColor24(CVAR_COSMETIC("HUD.CLeftButton.Value"), cLeftButtonColor);
|
||||
}
|
||||
if (!GameInteractor_Should(VB_HAVE_OCARINA_NOTE_B4, true)) {
|
||||
cLeftButtonColor = (Color_RGB8){ 191, 191, 191 };
|
||||
}
|
||||
|
||||
Color_RGB8 cRightButtonColor = cButtonsColor;
|
||||
if (CVarGetInteger(CVAR_COSMETIC("HUD.CRightButton.Changed"), 0)) {
|
||||
cRightButtonColor = CVarGetColor24(CVAR_COSMETIC("HUD.CRightButton.Value"), cRightButtonColor);
|
||||
}
|
||||
if (!GameInteractor_Should(VB_HAVE_OCARINA_NOTE_A4, true)) {
|
||||
cRightButtonColor = (Color_RGB8){ 191, 191, 191 };
|
||||
}
|
||||
|
||||
static s16 D_8082A070[][4] = {
|
||||
{ 255, 0, 0, 255 },
|
||||
@@ -124,12 +79,22 @@ void KaleidoScope_DrawQuestStatus(PlayState* play, GraphicsContext* gfxCtx) {
|
||||
s16 pad2;
|
||||
s16 phi_s0_2;
|
||||
s16 sp208[3];
|
||||
bool dpad = CVarGetInteger(CVAR_SETTING("DPadOnPause"), 0);
|
||||
|
||||
OPEN_DISPS(gfxCtx);
|
||||
|
||||
if (((pauseCtx->unk_1E4 == 0) || (pauseCtx->unk_1E4 == 5) || (pauseCtx->unk_1E4 == 8)) &&
|
||||
(pauseCtx->pageIndex == PAUSE_QUEST)) {
|
||||
if (CVarGetInteger(CVAR_SETTING("DPadOnPause"), 0)) {
|
||||
if (CHECK_BTN_ALL(input->press.button, BTN_DLEFT)) {
|
||||
pauseCtx->stickRelX = -35;
|
||||
} else if (CHECK_BTN_ALL(input->press.button, BTN_DRIGHT)) {
|
||||
pauseCtx->stickRelX = 35;
|
||||
} else if (CHECK_BTN_ALL(input->press.button, BTN_DDOWN)) {
|
||||
pauseCtx->stickRelY = -35;
|
||||
} else if (CHECK_BTN_ALL(input->press.button, BTN_DUP)) {
|
||||
pauseCtx->stickRelY = 35;
|
||||
}
|
||||
}
|
||||
pauseCtx->cursorColorSet = 0;
|
||||
|
||||
if (pauseCtx->cursorSpecialPos == 0) {
|
||||
@@ -140,7 +105,7 @@ void KaleidoScope_DrawQuestStatus(PlayState* play, GraphicsContext* gfxCtx) {
|
||||
} else {
|
||||
phi_s3 = pauseCtx->cursorPoint[PAUSE_QUEST];
|
||||
|
||||
if ((pauseCtx->stickRelX < -30) || (dpad && CHECK_BTN_ALL(input->press.button, BTN_DLEFT))) {
|
||||
if ((pauseCtx->stickRelX < -30)) {
|
||||
phi_s0 = D_8082A1AC[phi_s3][2];
|
||||
if (phi_s0 == -3) {
|
||||
KaleidoScope_MoveCursorToSpecialPos(play, PAUSE_CURSOR_PAGE_LEFT);
|
||||
@@ -153,7 +118,7 @@ void KaleidoScope_DrawQuestStatus(PlayState* play, GraphicsContext* gfxCtx) {
|
||||
phi_s0 = D_8082A1AC[phi_s0][2];
|
||||
}
|
||||
}
|
||||
} else if ((pauseCtx->stickRelX > 30) || (dpad && CHECK_BTN_ALL(input->press.button, BTN_DRIGHT))) {
|
||||
} else if ((pauseCtx->stickRelX > 30)) {
|
||||
phi_s0 = D_8082A1AC[phi_s3][3];
|
||||
if (phi_s0 == -2) {
|
||||
KaleidoScope_MoveCursorToSpecialPos(play, PAUSE_CURSOR_PAGE_RIGHT);
|
||||
@@ -168,7 +133,7 @@ void KaleidoScope_DrawQuestStatus(PlayState* play, GraphicsContext* gfxCtx) {
|
||||
}
|
||||
}
|
||||
|
||||
if ((pauseCtx->stickRelY < -30) || (dpad && CHECK_BTN_ALL(input->press.button, BTN_DDOWN))) {
|
||||
if ((pauseCtx->stickRelY < -30)) {
|
||||
phi_s0 = D_8082A1AC[phi_s3][1];
|
||||
while (phi_s0 >= 0) {
|
||||
if ((s16)KaleidoScope_UpdateQuestStatusPoint(pauseCtx, phi_s0) != 0) {
|
||||
@@ -176,7 +141,7 @@ void KaleidoScope_DrawQuestStatus(PlayState* play, GraphicsContext* gfxCtx) {
|
||||
}
|
||||
phi_s0 = D_8082A1AC[phi_s0][1];
|
||||
}
|
||||
} else if ((pauseCtx->stickRelY > 30) || (dpad && CHECK_BTN_ALL(input->press.button, BTN_DUP))) {
|
||||
} else if ((pauseCtx->stickRelY > 30)) {
|
||||
phi_s0 = D_8082A1AC[phi_s3][0];
|
||||
while (phi_s0 >= 0) {
|
||||
if ((s16)KaleidoScope_UpdateQuestStatusPoint(pauseCtx, phi_s0) != 0) {
|
||||
@@ -267,7 +232,7 @@ void KaleidoScope_DrawQuestStatus(PlayState* play, GraphicsContext* gfxCtx) {
|
||||
}
|
||||
}
|
||||
} else if (pauseCtx->cursorSpecialPos == PAUSE_CURSOR_PAGE_LEFT) {
|
||||
if ((pauseCtx->stickRelX > 30) || (dpad && CHECK_BTN_ALL(input->press.button, BTN_DRIGHT))) {
|
||||
if ((pauseCtx->stickRelX > 30)) {
|
||||
pauseCtx->cursorPoint[PAUSE_QUEST] = 0x15;
|
||||
pauseCtx->nameDisplayTimer = 0;
|
||||
pauseCtx->cursorSpecialPos = 0;
|
||||
@@ -285,7 +250,7 @@ void KaleidoScope_DrawQuestStatus(PlayState* play, GraphicsContext* gfxCtx) {
|
||||
pauseCtx->cursorSlot[pauseCtx->pageIndex] = sp216;
|
||||
}
|
||||
} else {
|
||||
if ((pauseCtx->stickRelX < -30) || (dpad && CHECK_BTN_ALL(input->press.button, BTN_DLEFT))) {
|
||||
if ((pauseCtx->stickRelX < -30)) {
|
||||
pauseCtx->cursorPoint[PAUSE_QUEST] = 0;
|
||||
pauseCtx->nameDisplayTimer = 0;
|
||||
pauseCtx->cursorSpecialPos = 0;
|
||||
@@ -506,6 +471,52 @@ void KaleidoScope_DrawQuestStatus(PlayState* play, GraphicsContext* gfxCtx) {
|
||||
}
|
||||
|
||||
if (pauseCtx->state == 6) {
|
||||
Color_RGB8 aButtonColor = { 80, 150, 255 };
|
||||
if (CVarGetInteger(CVAR_COSMETIC("HUD.AButton.Changed"), 0)) {
|
||||
aButtonColor = CVarGetColor24(CVAR_COSMETIC("HUD.AButton.Value"), aButtonColor);
|
||||
} else if (CVarGetInteger(CVAR_COSMETIC("DefaultColorScheme"), COLORSCHEME_N64) == COLORSCHEME_GAMECUBE) {
|
||||
aButtonColor = (Color_RGB8){ 80, 255, 150 };
|
||||
}
|
||||
if (!GameInteractor_Should(VB_HAVE_OCARINA_NOTE_D4, true)) {
|
||||
aButtonColor = (Color_RGB8){ 191, 191, 191 };
|
||||
}
|
||||
|
||||
Color_RGB8 cButtonsColor = { 255, 255, 50 };
|
||||
if (CVarGetInteger(CVAR_COSMETIC("HUD.CButtons.Changed"), 0)) {
|
||||
cButtonsColor = CVarGetColor24(CVAR_COSMETIC("HUD.CButtons.Value"), cButtonsColor);
|
||||
}
|
||||
Color_RGB8 cUpButtonColor = cButtonsColor;
|
||||
if (CVarGetInteger(CVAR_COSMETIC("HUD.CUpButton.Changed"), 0)) {
|
||||
cUpButtonColor = CVarGetColor24(CVAR_COSMETIC("HUD.CUpButton.Value"), cUpButtonColor);
|
||||
}
|
||||
if (!GameInteractor_Should(VB_HAVE_OCARINA_NOTE_D5, true)) {
|
||||
cUpButtonColor = (Color_RGB8){ 191, 191, 191 };
|
||||
}
|
||||
|
||||
Color_RGB8 cDownButtonColor = cButtonsColor;
|
||||
if (CVarGetInteger(CVAR_COSMETIC("HUD.CDownButton.Changed"), 0)) {
|
||||
cDownButtonColor = CVarGetColor24(CVAR_COSMETIC("HUD.CDownButton.Value"), cDownButtonColor);
|
||||
}
|
||||
if (!GameInteractor_Should(VB_HAVE_OCARINA_NOTE_F4, true)) {
|
||||
cDownButtonColor = (Color_RGB8){ 191, 191, 191 };
|
||||
}
|
||||
|
||||
Color_RGB8 cLeftButtonColor = cButtonsColor;
|
||||
if (CVarGetInteger(CVAR_COSMETIC("HUD.CLeftButton.Changed"), 0)) {
|
||||
cLeftButtonColor = CVarGetColor24(CVAR_COSMETIC("HUD.CLeftButton.Value"), cLeftButtonColor);
|
||||
}
|
||||
if (!GameInteractor_Should(VB_HAVE_OCARINA_NOTE_B4, true)) {
|
||||
cLeftButtonColor = (Color_RGB8){ 191, 191, 191 };
|
||||
}
|
||||
|
||||
Color_RGB8 cRightButtonColor = cButtonsColor;
|
||||
if (CVarGetInteger(CVAR_COSMETIC("HUD.CRightButton.Changed"), 0)) {
|
||||
cRightButtonColor = CVarGetColor24(CVAR_COSMETIC("HUD.CRightButton.Value"), cRightButtonColor);
|
||||
}
|
||||
if (!GameInteractor_Should(VB_HAVE_OCARINA_NOTE_A4, true)) {
|
||||
cRightButtonColor = (Color_RGB8){ 191, 191, 191 };
|
||||
}
|
||||
|
||||
gDPPipeSync(POLY_OPA_DISP++);
|
||||
gDPSetCombineMode(POLY_OPA_DISP++, G_CC_MODULATEIA_PRIM, G_CC_MODULATEIA_PRIM);
|
||||
|
||||
|
||||
@@ -183,10 +183,6 @@ void KaleidoScope_DrawEquipment(PlayState* play) {
|
||||
s16 cursorX;
|
||||
s16 cursorY;
|
||||
s16 oldCursorPoint;
|
||||
bool dpad = (CVarGetInteger(CVAR_SETTING("DPadOnPause"), 0) && !CHECK_BTN_ALL(input->cur.button, BTN_CUP));
|
||||
bool pauseAnyCursor =
|
||||
(CVarGetInteger(CVAR_ENHANCEMENT("PauseAnyCursor"), 0) == PAUSE_ANY_CURSOR_RANDO_ONLY && IS_RANDO) ||
|
||||
(CVarGetInteger(CVAR_ENHANCEMENT("PauseAnyCursor"), 0) == PAUSE_ANY_CURSOR_ALWAYS_ON);
|
||||
|
||||
OPEN_DISPS(play->state.gfxCtx);
|
||||
|
||||
@@ -204,6 +200,11 @@ void KaleidoScope_DrawEquipment(PlayState* play) {
|
||||
}
|
||||
|
||||
if ((pauseCtx->state == 6) && (pauseCtx->unk_1E4 == 0) && (pauseCtx->pageIndex == PAUSE_EQUIP)) {
|
||||
bool dpad = (CVarGetInteger(CVAR_SETTING("DPadOnPause"), 0) && !CHECK_BTN_ALL(input->cur.button, BTN_CUP));
|
||||
bool pauseAnyCursor =
|
||||
(CVarGetInteger(CVAR_ENHANCEMENT("PauseAnyCursor"), 0) == PAUSE_ANY_CURSOR_RANDO_ONLY && IS_RANDO) ||
|
||||
(CVarGetInteger(CVAR_ENHANCEMENT("PauseAnyCursor"), 0) == PAUSE_ANY_CURSOR_ALWAYS_ON);
|
||||
|
||||
oldCursorPoint = pauseCtx->cursorPoint[PAUSE_EQUIP];
|
||||
pauseCtx->cursorColorSet = 0;
|
||||
|
||||
|
||||
@@ -421,11 +421,6 @@ void KaleidoScope_DrawItemSelect(PlayState* play) {
|
||||
s16 cursorY;
|
||||
s16 oldCursorPoint;
|
||||
s16 moveCursorResult;
|
||||
bool dpad = (CVarGetInteger(CVAR_SETTING("DPadOnPause"), 0) && !CHECK_BTN_ALL(input->cur.button, BTN_CUP));
|
||||
bool pauseAnyCursor =
|
||||
pauseCtx->cursorSpecialPos == 0 &&
|
||||
((CVarGetInteger(CVAR_ENHANCEMENT("PauseAnyCursor"), 0) == PAUSE_ANY_CURSOR_RANDO_ONLY && IS_RANDO) ||
|
||||
(CVarGetInteger(CVAR_ENHANCEMENT("PauseAnyCursor"), 0) == PAUSE_ANY_CURSOR_ALWAYS_ON));
|
||||
|
||||
OPEN_DISPS(play->state.gfxCtx);
|
||||
|
||||
@@ -437,6 +432,12 @@ void KaleidoScope_DrawItemSelect(PlayState* play) {
|
||||
pauseCtx->nameColorSet = 0;
|
||||
|
||||
if ((pauseCtx->state == 6) && (pauseCtx->unk_1E4 == 0) && (pauseCtx->pageIndex == PAUSE_ITEM)) {
|
||||
bool dpad = (CVarGetInteger(CVAR_SETTING("DPadOnPause"), 0) && !CHECK_BTN_ALL(input->cur.button, BTN_CUP));
|
||||
bool pauseAnyCursor =
|
||||
pauseCtx->cursorSpecialPos == 0 &&
|
||||
((CVarGetInteger(CVAR_ENHANCEMENT("PauseAnyCursor"), 0) == PAUSE_ANY_CURSOR_RANDO_ONLY && IS_RANDO) ||
|
||||
(CVarGetInteger(CVAR_ENHANCEMENT("PauseAnyCursor"), 0) == PAUSE_ANY_CURSOR_ALWAYS_ON));
|
||||
|
||||
moveCursorResult = 0 || IsItemCycling();
|
||||
oldCursorPoint = pauseCtx->cursorPoint[PAUSE_ITEM];
|
||||
|
||||
|
||||
@@ -59,11 +59,11 @@ void KaleidoScope_DrawDungeonMap(PlayState* play, GraphicsContext* gfxCtx) {
|
||||
s16 stepG;
|
||||
s16 stepB;
|
||||
u16 rgba16;
|
||||
bool dpad = CVarGetInteger(CVAR_SETTING("DPadOnPause"), 0);
|
||||
|
||||
OPEN_DISPS(gfxCtx);
|
||||
|
||||
if ((pauseCtx->state == 6) && (pauseCtx->unk_1E4 == 0) && (pauseCtx->pageIndex == PAUSE_MAP)) {
|
||||
bool dpad = CVarGetInteger(CVAR_SETTING("DPadOnPause"), 0);
|
||||
pauseCtx->cursorColorSet = 0;
|
||||
oldCursorPoint = pauseCtx->cursorPoint[PAUSE_MAP];
|
||||
|
||||
|
||||
Reference in New Issue
Block a user