Merge branch 'develop' into FlareDancer

This commit is contained in:
Pepper0ni 2025-07-03 18:06:45 +01:00
commit b89afac9ce
88 changed files with 1202 additions and 1177 deletions

1
.gitignore vendored
View file

@ -457,3 +457,4 @@ soh/properties.h
# Tools
/clang-format
/clang-format.exe
*.o2r

View file

@ -25,7 +25,7 @@ if (-not (Test-Path $clangFormatFilePath) -or ($currentVersion -ne $requiredVers
}
$wc = New-Object net.webclient
$wc.Downloadfile($url, $llvmInstallerPath)
$wc.Downloadfile($url, $PSScriptRoot + $llvmInstallerPath)
$sevenZipPath = "C:\Program Files\7-Zip\7z.exe"
$specificFileInArchive = "bin\clang-format.exe"

View file

@ -2,6 +2,7 @@
"health": "Health - $0 Hearts",
"magic": "Magic - $0",
"rupees": "Rupees - $0",
"keys": "Keys - $0",
"floor": "Floor $0",
"basement": "Basement $0",
"item_menu": "Select Item",

View file

@ -2,6 +2,7 @@
"health": "Vie - $0 Coeurs",
"magic": "Magie - $0",
"rupees": "Rubis - $0",
"keys": "Clés - $0",
"floor": "Étage $0",
"basement": "Sous-sol $0",
"item_menu": "Inventaire",

View file

@ -2,6 +2,7 @@
"health": "Energie - $0 Herzen",
"magic": "Magie - $0",
"rupees": "Rubine - $0",
"keys": "Schlüssel - $0",
"floor": "Etage $0",
"basement": "Keller $0",
"item_menu": "Gegenstände",

View file

@ -44,6 +44,9 @@
"SkipText": 1,
"TextSpeed": 5,
"TimeFlowFileSelect": 1,
"TimeSavers": {
"SkipJabuJabuFish": 1
},
"TwoHandedIdle": 1,
"VisualAgony": 1,
"WidescreenActorCulling": 1

View file

@ -116,6 +116,7 @@
"Story": 1
},
"SkipForcedDialog": 3,
"SkipJabuJabuFish": 1,
"SkipMiscInteractions": 1,
"SkipOwlInteractions": 1,
"SkipTowerEscape": 1,

View file

@ -1,9 +1,10 @@
#include <libultraship/bridge.h>
#include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h"
#include "soh/ShipInit.hpp"
#include "z64save.h"
extern "C" SaveContext gSaveContext;
extern "C" {
#include "z64save.h"
extern SaveContext gSaveContext;
}
#define CVAR_INFINITE_MAGIC_NAME CVAR_CHEAT("InfiniteMagic")
#define CVAR_INFINITE_MAGIC_DEFAULT 0

View file

@ -1,11 +1,12 @@
#include <libultraship/bridge.h>
#include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h"
#include "soh/ShipInit.hpp"
extern "C" {
#include "functions.h"
#include "macros.h"
#include "variables.h"
extern "C" PlayState* gPlayState;
extern PlayState* gPlayState;
}
static constexpr int32_t CVAR_RUPEE_DASH_DEFAULT = 0;
#define CVAR_RUPEE_DASH_NAME CVAR_ENHANCEMENT("RupeeDash")

View file

@ -82,7 +82,7 @@ static void RollRandomTrap(uint32_t seed) {
case ADD_SPEED_TRAP:
Audio_PlaySoundGeneral(NA_SE_VO_KZ_MOVE, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale,
&gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb);
GameInteractor::State::RunSpeedModifier = -2;
GameInteractor::State::MovementSpeedMultiplier = 0.5f;
statusTimer = 200;
Notification::Emit({ .message = "Speed Decreased!" });
break;
@ -112,7 +112,7 @@ static void RollRandomTrap(uint32_t seed) {
static void OnPlayerUpdate() {
Player* player = GET_PLAYER(gPlayState);
if (statusTimer == 0) {
GameInteractor::State::RunSpeedModifier = 0;
GameInteractor::State::MovementSpeedMultiplier = 1.0f;
}
if (eventTimer == 0) {
switch (roll) {

View file

@ -4,7 +4,6 @@
#include <array>
#include <string>
#include <vector>
std::array<std::string, LANGUAGE_MAX> RandomizerSettingsMenuText[RSM_MAX] = {
{

View file

@ -1,12 +1,13 @@
#include <libultraship/bridge.h>
#include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h"
#include "soh/ShipInit.hpp"
extern "C" {
#include "functions.h"
#include "macros.h"
#include "variables.h"
#include "z64save.h"
extern "C" PlayState* gPlayState;
extern PlayState* gPlayState;
}
static constexpr int32_t CVAR_BGS_FIX_DEFAULT = 0;
#define CVAR_BGS_FIX_NAME CVAR_ENHANCEMENT("FixBrokenGiantsKnife")

View file

@ -1,12 +1,13 @@
#include <libultraship/bridge.h>
#include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h"
#include "soh/ShipInit.hpp"
extern "C" {
#include "functions.h"
#include "macros.h"
#include "variables.h"
#include "z64save.h"
extern "C" PlayState* gPlayState;
extern PlayState* gPlayState;
}
static constexpr int32_t CVAR_NUT_UPGRADE_FIX_DEFAULT = 0;
#define CVAR_NUT_UPGRADE_FIX_NAME CVAR_ENHANCEMENT("DekuNutUpgradeFix")

View file

@ -1,10 +1,9 @@
#include <libultraship/bridge.h>
#include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h"
#include "soh/ShipInit.hpp"
#include "functions.h"
#include "macros.h"
extern "C" {
#include "functions.h"
#include "macros.h"
extern PlayState* gPlayState;
extern SaveContext gSaveContext;
}

View file

@ -14,7 +14,7 @@ void Ru1Init(void* actorRef) {
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);
}

View file

@ -1,15 +1,7 @@
#include "bootcommands.h"
#include "gameconsole.h"
#include <macros.h>
#include <z64.h>
#include <libultraship/libultra.h>
#include <stddef.h>
#include <stdbool.h>
#include <libultraship/bridge.h>
#include <functions.h>
#include <variables.h>
#include <string.h>
#include <stdarg.h>
#include <z64.h>
#include "soh/OTRGlobals.h"
#include "bootcommands.h"
#include "soh/cvar_prefixes.h"
void BootCommands_Init() {

View file

@ -1,7 +1,5 @@
#ifndef _BOOTCOMMANDS_H_
#define _BOOTCOMMANDS_H_
#include <libultraship/libultra.h>
#include <z64.h>
void BootCommands_Init();

View file

@ -1366,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()
@ -1432,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(

View file

@ -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);

View file

@ -1130,7 +1130,7 @@ static bool SpeedModifierHandler(std::shared_ptr<Ship::Console> Console, const s
ERROR_MESSAGE("[SOH] Unexpected arguments passed");
return 1;
}
GameInteractionEffectBase* effect = new GameInteractionEffect::ModifyRunSpeedModifier();
GameInteractionEffectBase* effect = new GameInteractionEffect::ModifyMovementSpeedMultiplier();
try {
dynamic_cast<ParameterizedGameInteractionEffect*>(effect)->parameters[0] = std::stoi(args[1], nullptr, 10);
@ -1471,10 +1471,7 @@ static bool AvailableChecksProcessUndiscoveredExitsHandler(std::shared_ptr<Ship:
INFO_MESSAGE("[SOH] Available Checks - Process Undiscovered Exits %s",
logic->ACProcessUndiscoveredExits ? "enabled" : "disabled");
if (GameInteractor::IsSaveLoaded(true)) {
CheckTracker::RecalculateAvailableChecks();
}
CheckTracker::RecalculateAvailableChecks();
return 0;
}

View file

@ -6,8 +6,6 @@
#include <vector>
#include <string>
#include <cmath>
#include <libultraship/bridge.h>
#include <libultraship/libultraship.h>
#include "soh/OTRGlobals.h"
#include "soh/Enhancements/game-interactor/GameInteractor.h"

View file

@ -1305,6 +1305,15 @@ void DrawQuestStatusTab() {
ImGui::Text("Dungeon Items");
static int32_t dungeonItemsScene = SCENE_DEKU_TREE;
static int32_t lastDungeonScene = -1;
if (gPlayState != nullptr) {
int32_t sceneNum = gPlayState->sceneNum;
if (sceneNum >= SCENE_DEKU_TREE && sceneNum <= SCENE_JABU_JABU_BOSS && lastDungeonScene != sceneNum) {
dungeonItemsScene = sceneNum;
lastDungeonScene = sceneNum;
}
}
PushStyleCombobox(THEME_COLOR);
if (ImGui::BeginCombo("##DungeonSelect", SohUtils::GetSceneName(dungeonItemsScene).c_str())) {
for (int32_t dungeonIndex = SCENE_DEKU_TREE; dungeonIndex < SCENE_JABU_JABU_BOSS + 1; dungeonIndex++) {

View file

@ -28,33 +28,66 @@ bool IsEnemyAllowedToSpawn(int16_t sceneNum, int8_t roomNum, EnemyEntry enemy);
EnemyEntry GetRandomizedEnemyEntry(uint32_t seed, PlayState* play);
const char* enemyCVarList[RANDOMIZED_ENEMY_SPAWN_TABLE_SIZE] = {
CVAR_ENHANCEMENT("RandomizedEnemyList.Anubis"), CVAR_ENHANCEMENT("RandomizedEnemyList.Armos"),
CVAR_ENHANCEMENT("RandomizedEnemyList.Arwing"), CVAR_ENHANCEMENT("RandomizedEnemyList.BabyDodongo"),
CVAR_ENHANCEMENT("RandomizedEnemyList.Bari"), CVAR_ENHANCEMENT("RandomizedEnemyList.Beamos"),
CVAR_ENHANCEMENT("RandomizedEnemyList.BigSkulltula"), CVAR_ENHANCEMENT("RandomizedEnemyList.BigStalchild"),
CVAR_ENHANCEMENT("RandomizedEnemyList.Biri"), CVAR_ENHANCEMENT("RandomizedEnemyList.BlackKnuckle"),
CVAR_ENHANCEMENT("RandomizedEnemyList.BlueTektite"), CVAR_ENHANCEMENT("RandomizedEnemyList.Bubble"),
CVAR_ENHANCEMENT("RandomizedEnemyList.ClubMoblin"), CVAR_ENHANCEMENT("RandomizedEnemyList.DarkLink"),
CVAR_ENHANCEMENT("RandomizedEnemyList.Dinolfos"), CVAR_ENHANCEMENT("RandomizedEnemyList.Dodongo"),
CVAR_ENHANCEMENT("RandomizedEnemyList.FireKeese"), CVAR_ENHANCEMENT("RandomizedEnemyList.FlareDancer"),
CVAR_ENHANCEMENT("RandomizedEnemyList.FloorTile"), CVAR_ENHANCEMENT("RandomizedEnemyList.Floormaster"),
CVAR_ENHANCEMENT("RandomizedEnemyList.FlyingPeahat"), CVAR_ENHANCEMENT("RandomizedEnemyList.FlyingPot"),
CVAR_ENHANCEMENT("RandomizedEnemyList.Freezard"), CVAR_ENHANCEMENT("RandomizedEnemyList.Gibdo"),
CVAR_ENHANCEMENT("RandomizedEnemyList.GohmaLarva"), CVAR_ENHANCEMENT("RandomizedEnemyList.Guay"),
CVAR_ENHANCEMENT("RandomizedEnemyList.IceKeese"), CVAR_ENHANCEMENT("RandomizedEnemyList.InvisSkulltula"),
CVAR_ENHANCEMENT("RandomizedEnemyList.Keese"), CVAR_ENHANCEMENT("RandomizedEnemyList.LargeBaba"),
CVAR_ENHANCEMENT("RandomizedEnemyList.LikeLike"), CVAR_ENHANCEMENT("RandomizedEnemyList.Lizalfos"),
CVAR_ENHANCEMENT("RandomizedEnemyList.MadScrub"), CVAR_ENHANCEMENT("RandomizedEnemyList.NormalWolfos"),
CVAR_ENHANCEMENT("RandomizedEnemyList.PeahatLarva"), /*CVAR_ENHANCEMENT("RandomizedEnemyList.Poe"),*/
CVAR_ENHANCEMENT("RandomizedEnemyList.Redead"), CVAR_ENHANCEMENT("RandomizedEnemyList.RedTektite"),
CVAR_ENHANCEMENT("RandomizedEnemyList.Shabom"), CVAR_ENHANCEMENT("RandomizedEnemyList.ShellBlade"),
CVAR_ENHANCEMENT("RandomizedEnemyList.Skulltula"), CVAR_ENHANCEMENT("RandomizedEnemyList.SkullKid"),
CVAR_ENHANCEMENT("RandomizedEnemyList.SmallBaba"), CVAR_ENHANCEMENT("RandomizedEnemyList.SmallStalchild"),
CVAR_ENHANCEMENT("RandomizedEnemyList.SpearMoblin"), CVAR_ENHANCEMENT("RandomizedEnemyList.Spike"),
CVAR_ENHANCEMENT("RandomizedEnemyList.Stalfos"), CVAR_ENHANCEMENT("RandomizedEnemyList.Stinger"),
CVAR_ENHANCEMENT("RandomizedEnemyList.Tailparasan"), CVAR_ENHANCEMENT("RandomizedEnemyList.TorchSlug"),
CVAR_ENHANCEMENT("RandomizedEnemyList.Wallmaster"), CVAR_ENHANCEMENT("RandomizedEnemyList.WhiteKnuckle"),
CVAR_ENHANCEMENT("RandomizedEnemyList.WhiteWolfos"), CVAR_ENHANCEMENT("RandomizedEnemyList.WitheredBaba"),
CVAR_ENHANCEMENT("RandomizedEnemyList.Anubis"),
CVAR_ENHANCEMENT("RandomizedEnemyList.Armos"),
CVAR_ENHANCEMENT("RandomizedEnemyList.Arwing"),
CVAR_ENHANCEMENT("RandomizedEnemyList.BabyDodongo"),
CVAR_ENHANCEMENT("RandomizedEnemyList.Bari"),
CVAR_ENHANCEMENT("RandomizedEnemyList.Beamos"),
CVAR_ENHANCEMENT("RandomizedEnemyList.BigSkulltula"),
CVAR_ENHANCEMENT("RandomizedEnemyList.BigStalchild"),
CVAR_ENHANCEMENT("RandomizedEnemyList.Biri"),
CVAR_ENHANCEMENT("RandomizedEnemyList.BlackKnuckle"),
CVAR_ENHANCEMENT("RandomizedEnemyList.BlueTektite"),
CVAR_ENHANCEMENT("RandomizedEnemyList.Bubble"),
CVAR_ENHANCEMENT("RandomizedEnemyList.ClubMoblin"),
CVAR_ENHANCEMENT("RandomizedEnemyList.DarkLink"),
CVAR_ENHANCEMENT("RandomizedEnemyList.Dinolfos"),
CVAR_ENHANCEMENT("RandomizedEnemyList.Dodongo"),
CVAR_ENHANCEMENT("RandomizedEnemyList.FireKeese"),
CVAR_ENHANCEMENT("RandomizedEnemyList.FlareDancer"),
CVAR_ENHANCEMENT("RandomizedEnemyList.FloorTile"),
CVAR_ENHANCEMENT("RandomizedEnemyList.Floormaster"),
CVAR_ENHANCEMENT("RandomizedEnemyList.FlyingPeahat"),
CVAR_ENHANCEMENT("RandomizedEnemyList.FlyingPot"),
CVAR_ENHANCEMENT("RandomizedEnemyList.Freezard"),
CVAR_ENHANCEMENT("RandomizedEnemyList.Gibdo"),
CVAR_ENHANCEMENT("RandomizedEnemyList.GohmaLarva"),
CVAR_ENHANCEMENT("RandomizedEnemyList.Guay"),
CVAR_ENHANCEMENT("RandomizedEnemyList.IceKeese"),
CVAR_ENHANCEMENT("RandomizedEnemyList.InvisFireKeese"),
CVAR_ENHANCEMENT("RandomizedEnemyList.InvisFloormaster"),
CVAR_ENHANCEMENT("RandomizedEnemyList.InvisIceKeese"),
CVAR_ENHANCEMENT("RandomizedEnemyList.InvisKeese"),
CVAR_ENHANCEMENT("RandomizedEnemyList.InvisRedead"),
CVAR_ENHANCEMENT("RandomizedEnemyList.InvisSkulltula"),
CVAR_ENHANCEMENT("RandomizedEnemyList.InvisStalfos"),
CVAR_ENHANCEMENT("RandomizedEnemyList.Keese"),
CVAR_ENHANCEMENT("RandomizedEnemyList.LargeBaba"),
CVAR_ENHANCEMENT("RandomizedEnemyList.LikeLike"),
CVAR_ENHANCEMENT("RandomizedEnemyList.Lizalfos"),
CVAR_ENHANCEMENT("RandomizedEnemyList.MadScrub"),
CVAR_ENHANCEMENT("RandomizedEnemyList.NormalWolfos"),
CVAR_ENHANCEMENT("RandomizedEnemyList.PeahatLarva"),
// CVAR_ENHANCEMENT("RandomizedEnemyList.Poe"),
CVAR_ENHANCEMENT("RandomizedEnemyList.Redead"),
CVAR_ENHANCEMENT("RandomizedEnemyList.RedTektite"),
CVAR_ENHANCEMENT("RandomizedEnemyList.Shabom"),
CVAR_ENHANCEMENT("RandomizedEnemyList.ShellBlade"),
CVAR_ENHANCEMENT("RandomizedEnemyList.Skulltula"),
CVAR_ENHANCEMENT("RandomizedEnemyList.SkullKid"),
CVAR_ENHANCEMENT("RandomizedEnemyList.SmallBaba"),
CVAR_ENHANCEMENT("RandomizedEnemyList.SmallStalchild"),
CVAR_ENHANCEMENT("RandomizedEnemyList.SpearMoblin"),
CVAR_ENHANCEMENT("RandomizedEnemyList.Spike"),
CVAR_ENHANCEMENT("RandomizedEnemyList.Stalfos"),
CVAR_ENHANCEMENT("RandomizedEnemyList.Stinger"),
CVAR_ENHANCEMENT("RandomizedEnemyList.Tailparasan"),
CVAR_ENHANCEMENT("RandomizedEnemyList.TorchSlug"),
CVAR_ENHANCEMENT("RandomizedEnemyList.Wallmaster"),
CVAR_ENHANCEMENT("RandomizedEnemyList.WhiteKnuckle"),
CVAR_ENHANCEMENT("RandomizedEnemyList.WhiteWolfos"),
CVAR_ENHANCEMENT("RandomizedEnemyList.WitheredBaba"),
};
const char* enemyNameList[RANDOMIZED_ENEMY_SPAWN_TABLE_SIZE] = {
@ -85,7 +118,13 @@ const char* enemyNameList[RANDOMIZED_ENEMY_SPAWN_TABLE_SIZE] = {
"Gohma Larva",
"Guay",
"Ice Keese",
"Invisible Fire Keese",
"Invisible Floormaster",
"Invisible Ice Keese",
"Invisible Keese",
"Invisible Redead",
"Invisible Skulltula",
"Invisible Stalfos",
"Keese",
"Large Deku Baba",
"Like-Like",
@ -134,20 +173,26 @@ static EnemyEntry randomizedEnemySpawnTable[RANDOMIZED_ENEMY_SPAWN_TABLE_SIZE] =
{ ACTOR_EN_FIREFLY, 1 }, // Fire Keese
{ ACTOR_EN_FD, 0 }, // Flare Dancer (possible cause of crashes because of spawning flame actors on
// sloped ground)
{ ACTOR_EN_YUKABYUN, 0 }, // Flying Floor Tile
{ ACTOR_EN_FLOORMAS, 0 }, // Floormaster
{ ACTOR_EN_PEEHAT, -1 }, // Flying Peahat (big grounded, doesn't spawn larva)
{ ACTOR_EN_TUBO_TRAP, 0 }, // Flying pot
{ ACTOR_EN_FZ, 0 }, // Freezard
{ ACTOR_EN_RD, 32766 }, // Gibdo (standing)
{ ACTOR_EN_GOMA, 7 }, // Gohma Larva (Non-Gohma rooms)
{ ACTOR_EN_CROW, 0 }, // Guay
{ ACTOR_EN_FIREFLY, 4 }, // Ice Keese
{ ACTOR_EN_ST, 2 }, // Skulltula (invisible)
{ ACTOR_EN_FIREFLY, 2 }, // Regular Keese
{ ACTOR_EN_DEKUBABA, 1 }, // Deku Baba (large)
// Doesn't work (reliant on surface and also normally used in tandem with a leever spawner, kills itself too quickly
// otherwise) { ACTOR_EN_REEBA, 0 }, // Leever
{ ACTOR_EN_YUKABYUN, 0 }, // Flying Floor Tile
{ ACTOR_EN_FLOORMAS, 0 }, // Floormaster
{ ACTOR_EN_PEEHAT, -1 }, // Flying Peahat (big grounded, doesn't spawn larva)
{ ACTOR_EN_TUBO_TRAP, 0 }, // Flying pot
{ ACTOR_EN_FZ, 0 }, // Freezard
{ ACTOR_EN_RD, 32766 }, // Gibdo (standing)
{ ACTOR_EN_GOMA, 7 }, // Gohma Larva (Non-Gohma rooms)
{ ACTOR_EN_CROW, 0 }, // Guay
{ ACTOR_EN_FIREFLY, 4 }, // Ice Keese
{ ACTOR_EN_FIREFLY, 0x8001 }, // Fire Keese (invisible)
{ ACTOR_EN_FLOORMAS, 0x8000 }, // Floormaster (invisible)
{ ACTOR_EN_FIREFLY, 0x8004 }, // Ice Keese (invisible)
{ ACTOR_EN_FIREFLY, 0x8002 }, // Keese (invisible)
{ ACTOR_EN_RD, 3 }, // Redead (invisible)
{ ACTOR_EN_ST, 2 }, // Skulltula (invisible)
{ ACTOR_EN_TEST, 0 }, // Stalfos (invisible)
{ ACTOR_EN_FIREFLY, 2 }, // Regular Keese
{ ACTOR_EN_DEKUBABA, 1 }, // Deku Baba (large)
// Doesn't work (reliant on surface, without a spawner it kills itself too quickly)
// { ACTOR_EN_REEBA, 0 }, // Leever
{ ACTOR_EN_RR, 0 }, // Like-Like
{ ACTOR_EN_ZF, -1 }, // Lizalfos
{ ACTOR_EN_DEKUNUTS, 768 }, // Mad Scrub (triple attack) (projectiles don't work)

View file

@ -3,7 +3,7 @@
#include <libultraship/libultra/types.h>
#include "item-tables/ItemTableTypes.h"
#define RANDOMIZED_ENEMY_SPAWN_TABLE_SIZE 53
#define RANDOMIZED_ENEMY_SPAWN_TABLE_SIZE 59
extern const char* enemyCVarList[];
extern const char* enemyNameList[];

View file

@ -11,6 +11,7 @@ have functions to both enable and disable said effect.
#include "GameInteractionEffect.h"
#include "GameInteractor.h"
#include <libultraship/bridge.h>
#include "soh/Enhancements/cosmetics/CosmeticsEditor.h"
extern "C" {
#include <z64.h>
@ -371,19 +372,23 @@ void ForceEquipBoots::_Remove() {
GameInteractor::RawAction::ForceEquipBoots(EQUIP_VALUE_BOOTS_KOKIRI);
}
// MARK: - ModifyRunSpeedModifier
GameInteractionEffectQueryResult ModifyRunSpeedModifier::CanBeApplied() {
// MARK: - ModifyMovementSpeedMultiplier
GameInteractionEffectQueryResult ModifyMovementSpeedMultiplier::CanBeApplied() {
if (!GameInteractor::IsSaveLoaded() || GameInteractor::IsGameplayPaused()) {
return GameInteractionEffectQueryResult::TemporarilyNotPossible;
} else {
return GameInteractionEffectQueryResult::Possible;
}
}
void ModifyRunSpeedModifier::_Apply() {
GameInteractor::State::RunSpeedModifier = parameters[0];
void ModifyMovementSpeedMultiplier::_Apply() {
if (parameters[0] == -2) {
GameInteractor::State::MovementSpeedMultiplier = 0.5f;
} else if (parameters[0] == 2) {
GameInteractor::State::MovementSpeedMultiplier = 2.0f;
}
}
void ModifyRunSpeedModifier::_Remove() {
GameInteractor::State::RunSpeedModifier = 0;
void ModifyMovementSpeedMultiplier::_Remove() {
GameInteractor::State::MovementSpeedMultiplier = 1.0f;
}
// MARK: - OneHitKO
@ -485,18 +490,6 @@ void SetCollisionViewer::_Remove() {
GameInteractor::RawAction::SetCollisionViewer(false);
}
// MARK: - SetCosmeticsColor
GameInteractionEffectQueryResult SetCosmeticsColor::CanBeApplied() {
if (!GameInteractor::IsSaveLoaded()) {
return GameInteractionEffectQueryResult::TemporarilyNotPossible;
} else {
return GameInteractionEffectQueryResult::Possible;
}
}
void SetCosmeticsColor::_Apply() {
GameInteractor::RawAction::SetCosmeticsColor(parameters[0], parameters[1]);
}
// MARK: - RandomizeCosmetics
GameInteractionEffectQueryResult RandomizeCosmetics::CanBeApplied() {
if (!GameInteractor::IsSaveLoaded()) {
@ -506,7 +499,7 @@ GameInteractionEffectQueryResult RandomizeCosmetics::CanBeApplied() {
}
}
void RandomizeCosmetics::_Apply() {
GameInteractor::RawAction::RandomizeCosmeticsColors(true);
CosmeticsEditor_RandomizeAll();
}
// MARK: - PressButton

View file

@ -156,7 +156,7 @@ class ForceEquipBoots : public RemovableGameInteractionEffect, public Parameteri
void _Remove() override;
};
class ModifyRunSpeedModifier : public RemovableGameInteractionEffect, public ParameterizedGameInteractionEffect {
class ModifyMovementSpeedMultiplier : public RemovableGameInteractionEffect, public ParameterizedGameInteractionEffect {
GameInteractionEffectQueryResult CanBeApplied() override;
void _Apply() override;
void _Remove() override;
@ -200,11 +200,6 @@ class SetCollisionViewer : public RemovableGameInteractionEffect {
void _Remove() override;
};
class SetCosmeticsColor : public GameInteractionEffectBase, public ParameterizedGameInteractionEffect {
GameInteractionEffectQueryResult CanBeApplied() override;
void _Apply() override;
};
class RandomizeCosmetics : public GameInteractionEffectBase {
GameInteractionEffectQueryResult CanBeApplied() override;
void _Apply() override;

View file

@ -76,7 +76,7 @@ uint8_t GameInteractor_PacifistModeActive();
uint8_t GameInteractor_DisableZTargetingActive();
uint8_t GameInteractor_ReverseControlsActive();
int32_t GameInteractor_DefenseModifier();
int32_t GameInteractor_RunSpeedModifier();
float GameInteractor_MovementSpeedMultiplier();
GIGravityLevel GameInteractor_GravityLevel();
uint32_t GameInteractor_GetEmulatedButtons();
void GameInteractor_SetEmulatedButtons(uint32_t buttons);
@ -204,7 +204,7 @@ class GameInteractor {
static bool DisableZTargetingActive;
static bool ReverseControlsActive;
static int32_t DefenseModifier;
static int32_t RunSpeedModifier;
static float MovementSpeedMultiplier;
static GIGravityLevel GravityLevel;
static uint32_t EmulatedButtons;
static uint8_t RandomBombFuseTimerActive;
@ -566,8 +566,6 @@ class GameInteractor {
static void ClearAssignedButtons(uint8_t buttonSet);
static void SetTimeOfDay(uint32_t time);
static void SetCollisionViewer(bool active);
static void SetCosmeticsColor(uint8_t cosmeticCategory, uint8_t colorValue);
static void RandomizeCosmeticsColors(bool excludeBiddingWarColors);
static void EmulateButtonPress(int32_t button);
static void AddOrTakeAmmo(int16_t amount, int16_t item);
static void EmulateRandomButtonPress(uint32_t chancePercentage = 100);
@ -575,8 +573,10 @@ class GameInteractor {
static void SetPlayerInvincibility(bool active);
static void ClearCutscenePointer();
static GameInteractionEffectQueryResult SpawnEnemyWithOffset(uint32_t enemyId, int32_t enemyParams);
static GameInteractionEffectQueryResult SpawnActor(uint32_t actorId, int32_t actorParams);
static GameInteractionEffectQueryResult SpawnEnemyWithOffset(uint32_t enemyId, int32_t enemyParams,
std::string nameTag = "");
static GameInteractionEffectQueryResult SpawnActor(uint32_t actorId, int32_t actorParams,
std::string nameTag = "");
};
};

View file

@ -1,9 +1,9 @@
#include "GameInteractor.h"
#include <libultraship/bridge.h>
#include "soh/Enhancements/cosmetics/CosmeticsEditor.h"
#include "soh/Enhancements/randomizer/3drando/random.hpp"
#include <math.h>
#include "soh/Enhancements/debugger/colViewer.h"
#include "soh/Enhancements/nametag.h"
extern "C" {
#include "variables.h"
@ -405,125 +405,6 @@ void GameInteractor::RawAction::SetCollisionViewer(bool active) {
}
}
void GameInteractor::RawAction::SetCosmeticsColor(uint8_t cosmeticCategory, uint8_t colorValue) {
Color_RGBA8 newColor;
newColor.r = 255;
newColor.g = 255;
newColor.b = 255;
newColor.a = 255;
switch (colorValue) {
case GI_COLOR_RED:
newColor.r = 200;
newColor.g = 30;
newColor.b = 30;
break;
case GI_COLOR_GREEN:
newColor.r = 50;
newColor.g = 200;
newColor.b = 50;
break;
case GI_COLOR_BLUE:
newColor.r = 50;
newColor.g = 50;
newColor.b = 200;
break;
case GI_COLOR_ORANGE:
newColor.r = 200;
newColor.g = 120;
newColor.b = 0;
break;
case GI_COLOR_YELLOW:
newColor.r = 234;
newColor.g = 240;
newColor.b = 33;
break;
case GI_COLOR_PURPLE:
newColor.r = 144;
newColor.g = 13;
newColor.b = 178;
break;
case GI_COLOR_PINK:
newColor.r = 215;
newColor.g = 93;
newColor.b = 246;
break;
case GI_COLOR_BROWN:
newColor.r = 108;
newColor.g = 72;
newColor.b = 15;
break;
case GI_COLOR_BLACK:
newColor.r = 0;
newColor.g = 0;
newColor.b = 0;
break;
default:
break;
}
switch (cosmeticCategory) {
case GI_COSMETICS_TUNICS:
CVarSetColor(CVAR_COSMETIC("Link.KokiriTunic.Value"), newColor);
CVarSetInteger(CVAR_COSMETIC("Link.KokiriTunic.Changed"), 1);
CVarSetColor(CVAR_COSMETIC("Link.GoronTunic.Value"), newColor);
CVarSetInteger(CVAR_COSMETIC("Link.GoronTunic.Changed"), 1);
CVarSetColor(CVAR_COSMETIC("Link.ZoraTunic.Value"), newColor);
CVarSetInteger(CVAR_COSMETIC("Link.ZoraTunic.Changed"), 1);
break;
case GI_COSMETICS_NAVI:
CVarSetColor(CVAR_COSMETIC("Navi.EnemyPrimary.Value"), newColor);
CVarSetInteger(CVAR_COSMETIC("Navi.EnemyPrimary.Changed"), 1);
CVarSetColor(CVAR_COSMETIC("Navi.EnemySecondary.Value"), newColor);
CVarSetInteger(CVAR_COSMETIC("Navi.EnemySecondary.Changed"), 1);
CVarSetColor(CVAR_COSMETIC("Navi.IdlePrimary.Value"), newColor);
CVarSetInteger(CVAR_COSMETIC("Navi.IdlePrimary.Changed"), 1);
CVarSetColor(CVAR_COSMETIC("Navi.IdleSecondary.Value"), newColor);
CVarSetInteger(CVAR_COSMETIC("Navi.IdleSecondary.Changed"), 1);
CVarSetColor(CVAR_COSMETIC("Navi.NPCPrimary.Value"), newColor);
CVarSetInteger(CVAR_COSMETIC("Navi.NPCPrimary.Changed"), 1);
CVarSetColor(CVAR_COSMETIC("Navi.NPCSecondary.Value"), newColor);
CVarSetInteger(CVAR_COSMETIC("Navi.NPCSecondary.Changed"), 1);
CVarSetColor(CVAR_COSMETIC("Navi.PropsPrimary.Value"), newColor);
CVarSetInteger(CVAR_COSMETIC("Navi.PropsPrimary.Changed"), 1);
CVarSetColor(CVAR_COSMETIC("Navi.PropsSecondary.Value"), newColor);
CVarSetInteger(CVAR_COSMETIC("Navi.PropsSecondary.Changed"), 1);
break;
case GI_COSMETICS_HAIR:
CVarSetColor(CVAR_COSMETIC("Link.Hair.Value"), newColor);
CVarSetInteger(CVAR_COSMETIC("Link.Hair.Changed"), 1);
break;
}
Ship::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesNextFrame();
ApplyOrResetCustomGfxPatches();
}
void GameInteractor::RawAction::RandomizeCosmeticsColors(bool excludeBiddingWarColors) {
const char* cvarsToLock[12] = {
CVAR_COSMETIC("Link.KokiriTunic.Locked"), CVAR_COSMETIC("Link.GoronTunic.Locked"),
CVAR_COSMETIC("Link.ZoraTunic.Locked"), CVAR_COSMETIC("Navi.EnemyPrimary.Locked"),
CVAR_COSMETIC("Navi.EnemySecondary.Locked"), CVAR_COSMETIC("Navi.IdlePrimary.Locked"),
CVAR_COSMETIC("Navi.IdleSecondary.Locked"), CVAR_COSMETIC("Navi.NPCPrimary.Locked"),
CVAR_COSMETIC("Navi.NPCSecondary.Locked"), CVAR_COSMETIC("Navi.PropsPrimary.Locked"),
CVAR_COSMETIC("Navi.PropsSecondary.Locked"), CVAR_COSMETIC("Link.Hair.Locked")
};
if (excludeBiddingWarColors) {
for (uint8_t i = 0; i < 12; i++) {
CVarSetInteger(cvarsToLock[i], 1);
}
}
CosmeticsEditor_RandomizeAll();
if (excludeBiddingWarColors) {
for (uint8_t i = 0; i < 12; i++) {
CVarSetInteger(cvarsToLock[i], 0);
}
}
}
void GameInteractor::RawAction::EmulateButtonPress(int32_t button) {
GameInteractor::State::EmulatedButtons |= button;
}
@ -580,8 +461,8 @@ void GameInteractor::RawAction::ClearCutscenePointer() {
gPlayState->csCtx.segment = &null_cs;
}
GameInteractionEffectQueryResult GameInteractor::RawAction::SpawnEnemyWithOffset(uint32_t enemyId,
int32_t enemyParams) {
GameInteractionEffectQueryResult GameInteractor::RawAction::SpawnEnemyWithOffset(uint32_t enemyId, int32_t enemyParams,
std::string nameTag) {
if (!GameInteractor::CanSpawnActor()) {
return GameInteractionEffectQueryResult::TemporarilyNotPossible;
@ -651,15 +532,29 @@ GameInteractionEffectQueryResult GameInteractor::RawAction::SpawnEnemyWithOffset
pos.x += 10;
pos.y += 10;
pos.z += 10;
if (Actor_Spawn(&gPlayState->actorCtx, gPlayState, enemyId, pos.x, pos.y, pos.z, 0, 0, 0, enemyParams, 0) ==
NULL) {
Actor* actor =
Actor_Spawn(&gPlayState->actorCtx, gPlayState, enemyId, pos.x, pos.y, pos.z, 0, 0, 0, enemyParams, 0);
if (actor == NULL) {
return GameInteractionEffectQueryResult::TemporarilyNotPossible;
}
if (nameTag != "" && CVarGetInteger(CVAR_REMOTE_CROWD_CONTROL("EnemyNameTags"), 0)) {
NameTag_RegisterForActor(actor, nameTag.c_str());
}
if (CVarGetInteger(CVAR_REMOTE_CROWD_CONTROL("SpawnedEnemiesIgnoredIngame"), 0)) {
Actor_ChangeCategory(gPlayState, &gPlayState->actorCtx, actor, ACTORCAT_NPC);
}
}
return GameInteractionEffectQueryResult::Possible;
} else {
if (Actor_Spawn(&gPlayState->actorCtx, gPlayState, enemyId, pos.x, pos.y, pos.z, 0, 0, 0, enemyParams, 0) !=
NULL) {
Actor* actor =
Actor_Spawn(&gPlayState->actorCtx, gPlayState, enemyId, pos.x, pos.y, pos.z, 0, 0, 0, enemyParams, 0);
if (actor != NULL) {
if (nameTag != "" && CVarGetInteger(CVAR_REMOTE_CROWD_CONTROL("EnemyNameTags"), 0)) {
NameTag_RegisterForActor(actor, nameTag.c_str());
}
if (CVarGetInteger(CVAR_REMOTE_CROWD_CONTROL("SpawnedEnemiesIgnoredIngame"), 0)) {
Actor_ChangeCategory(gPlayState, &gPlayState->actorCtx, actor, ACTORCAT_NPC);
}
return GameInteractionEffectQueryResult::Possible;
}
}
@ -667,7 +562,8 @@ GameInteractionEffectQueryResult GameInteractor::RawAction::SpawnEnemyWithOffset
return GameInteractionEffectQueryResult::TemporarilyNotPossible;
}
GameInteractionEffectQueryResult GameInteractor::RawAction::SpawnActor(uint32_t actorId, int32_t actorParams) {
GameInteractionEffectQueryResult GameInteractor::RawAction::SpawnActor(uint32_t actorId, int32_t actorParams,
std::string nameTag) {
if (!GameInteractor::CanSpawnActor()) {
return GameInteractionEffectQueryResult::TemporarilyNotPossible;
@ -684,6 +580,9 @@ GameInteractionEffectQueryResult GameInteractor::RawAction::SpawnActor(uint32_t
return GameInteractionEffectQueryResult::TemporarilyNotPossible;
}
if (nameTag != "" && CVarGetInteger(CVAR_REMOTE_CROWD_CONTROL("EnemyNameTags"), 0)) {
NameTag_RegisterForActor((Actor*)cucco, nameTag.c_str());
}
cucco->actionFunc = func_80AB70A0_nocutscene;
return GameInteractionEffectQueryResult::Possible;
} else if (actorId == ACTOR_EN_BOM) {
@ -703,8 +602,15 @@ GameInteractionEffectQueryResult GameInteractor::RawAction::SpawnActor(uint32_t
return GameInteractionEffectQueryResult::Possible;
} else {
// Generic spawn an actor at Link's position
if (Actor_Spawn(&gPlayState->actorCtx, gPlayState, actorId, player->actor.world.pos.x,
player->actor.world.pos.y, player->actor.world.pos.z, 0, 0, 0, actorParams, 0) != NULL) {
Actor* actor = Actor_Spawn(&gPlayState->actorCtx, gPlayState, actorId, player->actor.world.pos.x,
player->actor.world.pos.y, player->actor.world.pos.z, 0, 0, 0, actorParams, 0);
if (actor != NULL) {
if (nameTag != "" && CVarGetInteger(CVAR_REMOTE_CROWD_CONTROL("EnemyNameTags"), 0)) {
NameTag_RegisterForActor((Actor*)actor, nameTag.c_str());
}
if (CVarGetInteger(CVAR_REMOTE_CROWD_CONTROL("SpawnedEnemiesIgnoredIngame"), 0)) {
Actor_ChangeCategory(gPlayState, &gPlayState->actorCtx, actor, ACTORCAT_NPC);
}
return GameInteractionEffectQueryResult::Possible;
}
}

View file

@ -10,7 +10,7 @@ bool GameInteractor::State::PacifistModeActive = 0;
bool GameInteractor::State::DisableZTargetingActive = 0;
bool GameInteractor::State::ReverseControlsActive = 0;
int32_t GameInteractor::State::DefenseModifier = 0;
int32_t GameInteractor::State::RunSpeedModifier = 0;
float GameInteractor::State::MovementSpeedMultiplier = 1.0f;
GIGravityLevel GameInteractor::State::GravityLevel = GI_GRAVITY_LEVEL_NORMAL;
uint32_t GameInteractor::State::EmulatedButtons = 0;
uint8_t GameInteractor::State::RandomBombFuseTimerActive = 0;
@ -81,8 +81,8 @@ int32_t GameInteractor_DefenseModifier() {
}
// MARK: - GameInteractor::State::DisableCameraRotationActive
int32_t GameInteractor_RunSpeedModifier() {
return GameInteractor::State::RunSpeedModifier;
float GameInteractor_MovementSpeedMultiplier() {
return GameInteractor::State::MovementSpeedMultiplier;
}
// MARK: - GameInteractor::State::DisableCameraRotationActive

View file

@ -1972,27 +1972,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, die 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#|"
@ -2001,26 +2001,26 @@ 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#.^",
/*german*/ "$gDie Weisen werden darauf&warten, daß der Held&#Greg# findet.^",
/*french*/ "$gLes êtres de sagesse attendront le héros muni de #Greg#.^",
{QM_GREEN}));
{QM_GREEN}, {}, TEXTBOX_TYPE_BLUE));
/*--------------------------
@ -2174,22 +2174,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 er 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#.^"

View file

@ -313,11 +313,11 @@ void StaticData::HintTable_Init_Exclude_Overworld() {
/*german*/ "Man erzählt sich, daß ein #Tauchexperiment# #[[1]]# einbrächte.",
/*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ß ein #Krug 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_TH_BREAK_ROOM_FRONT_POT] = HintText(CustomMessage("They say that the #front pot watched by resting thieves# contains #[[1]]#.", {QM_RED, QM_GREEN}));//TODO_TRANSLATE
@ -1532,15 +1540,24 @@ void StaticData::HintTable_Init_Exclude_Overworld() {
/*german*/ "Man erzählt sich, daß ein #Krug 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ß ein #Krug 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 #Krug 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 #Krug 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_ALLEY_HOUSE] = HintText(CustomMessage("They say that a #bearded man's pot# contains #[[1]]#.",
/*german*/ "Man erzählt sich, daß eine #Krug 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ß ein #Krug 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ß ein #Krug auf dem Friedhof# #[[1]]# enthielte.",
/*french*/ "Selon moi, une #jarre dans le Cimetière# contient #[[1]]#.", {QM_RED, QM_GREEN}));
@ -1564,13 +1581,17 @@ void StaticData::HintTable_Init_Exclude_Overworld() {
/*german*/ "Man erzählt sich, daß ein #Krug 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ß ein #Krug 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 #Krug 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ß ein #Krug 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 #Krug 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 #Krug 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.",

View file

@ -728,20 +728,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 +754,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 +767,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));

View file

@ -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;

View file

@ -108,149 +108,149 @@ void Rando::StaticData::RegisterPotLocations() {
registered = true;
// 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_TH_BREAK_ROOM_FRONT_POT] = Location::Pot(RC_TH_BREAK_ROOM_FRONT_POT, RCQUEST_BOTH, RCAREA_GERUDO_FORTRESS, SCENE_THIEVES_HIDEOUT, TWO_ACTOR_PARAMS(1438, -3629), "Break Room Front Pot", RHT_TH_BREAK_ROOM_FRONT_POT, RG_ARROWS_10, SpoilerCollectionCheck::RandomizerInf(RAND_INF_TH_BREAK_ROOM_FRONT_POT));
locationTable[RC_TH_BREAK_ROOM_BACK_POT] = Location::Pot(RC_TH_BREAK_ROOM_BACK_POT, RCQUEST_BOTH, RCAREA_GERUDO_FORTRESS, SCENE_THIEVES_HIDEOUT, TWO_ACTOR_PARAMS(1403, -3679), "Break Room Back Pot", RHT_TH_BREAK_ROOM_BACK_POT, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_TH_BREAK_ROOM_BACK_POT));
locationTable[RC_TH_KITCHEN_POT_1] = Location::Pot(RC_TH_KITCHEN_POT_1, RCQUEST_BOTH, RCAREA_GERUDO_FORTRESS, SCENE_THIEVES_HIDEOUT, TWO_ACTOR_PARAMS(1908, -789), "Kitchen Pot 1", RHT_TH_KITCHEN_POT_1, RG_ARROWS_10, SpoilerCollectionCheck::RandomizerInf(RAND_INF_TH_KITCHEN_POT_1));
locationTable[RC_TH_KITCHEN_POT_2] = Location::Pot(RC_TH_KITCHEN_POT_2, RCQUEST_BOTH, RCAREA_GERUDO_FORTRESS, SCENE_THIEVES_HIDEOUT, TWO_ACTOR_PARAMS(1951, -850), "Kitchen Pot 2", RHT_TH_KITCHEN_POT_2, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_TH_KITCHEN_POT_2));
locationTable[RC_TH_1_TORCH_CELL_RIGHT_POT] = Location::Pot(RC_TH_1_TORCH_CELL_RIGHT_POT, RCQUEST_BOTH, RCAREA_GERUDO_FORTRESS, SCENE_THIEVES_HIDEOUT, TWO_ACTOR_PARAMS(-475, -2622), "1 Torch Cell Right Pot", RHT_TH_1_TORCH_CELL_RIGHT_POT, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_TH_1_TORCH_CELL_RIGHT_POT));
locationTable[RC_TH_1_TORCH_CELL_MID_POT] = Location::Pot(RC_TH_1_TORCH_CELL_MID_POT, RCQUEST_BOTH, RCAREA_GERUDO_FORTRESS, SCENE_THIEVES_HIDEOUT, TWO_ACTOR_PARAMS(-512, -2621), "1 Torch Cell Middle Pot", RHT_TH_1_TORCH_CELL_MID_POT, RG_RED_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_TH_1_TORCH_CELL_MID_POT));
locationTable[RC_TH_1_TORCH_CELL_LEFT_POT] = Location::Pot(RC_TH_1_TORCH_CELL_LEFT_POT, RCQUEST_BOTH, RCAREA_GERUDO_FORTRESS, SCENE_THIEVES_HIDEOUT, TWO_ACTOR_PARAMS(-511, -2582), "1 Torch Cell Left Pot", RHT_TH_1_TORCH_CELL_LEFT_POT, RG_ARROWS_10, SpoilerCollectionCheck::RandomizerInf(RAND_INF_TH_1_TORCH_CELL_LEFT_POT));
locationTable[RC_TH_STEEP_SLOPE_RIGHT_POT] = Location::Pot(RC_TH_STEEP_SLOPE_RIGHT_POT, RCQUEST_BOTH, RCAREA_GERUDO_FORTRESS, SCENE_THIEVES_HIDEOUT, TWO_ACTOR_PARAMS(67, -1975), "Steep Slope Right Pot", RHT_TH_STEEP_SLOPE_RIGHT_POT, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_TH_STEEP_SLOPE_RIGHT_POT));
locationTable[RC_TH_STEEP_SLOPE_LEFT_POT] = Location::Pot(RC_TH_STEEP_SLOPE_LEFT_POT, RCQUEST_BOTH, RCAREA_GERUDO_FORTRESS, SCENE_THIEVES_HIDEOUT, TWO_ACTOR_PARAMS(39, -1943), "Steep Slope Left Pot", RHT_TH_STEEP_SLOPE_LEFT_POT, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_TH_STEEP_SLOPE_LEFT_POT));
locationTable[RC_TH_NEAR_DOUBLE_CELL_RIGHT_POT] = Location::Pot(RC_TH_NEAR_DOUBLE_CELL_RIGHT_POT, RCQUEST_BOTH, RCAREA_GERUDO_FORTRESS, SCENE_THIEVES_HIDEOUT, TWO_ACTOR_PARAMS(691, 48), "Double Cell Right Pot", RHT_TH_NEAR_DOUBLE_CELL_RIGHT_POT, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_TH_NEAR_DOUBLE_CELL_RIGHT_POT));
locationTable[RC_TH_NEAR_DOUBLE_CELL_MID_POT] = Location::Pot(RC_TH_NEAR_DOUBLE_CELL_MID_POT, RCQUEST_BOTH, RCAREA_GERUDO_FORTRESS, SCENE_THIEVES_HIDEOUT, TWO_ACTOR_PARAMS(691, 16), "Double Cell Middle Pot", RHT_TH_NEAR_DOUBLE_CELL_MID_POT, RG_RED_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_TH_NEAR_DOUBLE_CELL_MID_POT));
locationTable[RC_TH_NEAR_DOUBLE_CELL_LEFT_POT] = Location::Pot(RC_TH_NEAR_DOUBLE_CELL_LEFT_POT, RCQUEST_BOTH, RCAREA_GERUDO_FORTRESS, SCENE_THIEVES_HIDEOUT, TWO_ACTOR_PARAMS(661, 16), "Double Cell Left Pot", RHT_TH_NEAR_DOUBLE_CELL_LEFT_POT, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_NEAR_DOUBLE_CELL_LEFT_POT));
locationTable[RC_TH_RIGHTMOST_JAILED_POT] = Location::Pot(RC_TH_RIGHTMOST_JAILED_POT, RCQUEST_BOTH, RCAREA_GERUDO_FORTRESS, SCENE_THIEVES_HIDEOUT, TWO_ACTOR_PARAMS(26, 524), "Rightmost Jailed Pot", RHT_TH_RIGHTMOST_JAILED_POT, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_TH_RIGHTMOST_JAILED_POT));
locationTable[RC_TH_RIGHT_MIDDLE_JAILED_POT] = Location::Pot(RC_TH_RIGHT_MIDDLE_JAILED_POT, RCQUEST_BOTH, RCAREA_GERUDO_FORTRESS, SCENE_THIEVES_HIDEOUT, TWO_ACTOR_PARAMS(61, 549), "Right Middle Jailed Pot", RHT_TH_LEFT_MIDDLE_JAILED_POT, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_TH_RIGHT_MIDDLE_JAILED_POT));
locationTable[RC_TH_LEFT_MIDDLE_JAILED_POT] = Location::Pot(RC_TH_LEFT_MIDDLE_JAILED_POT, RCQUEST_BOTH, RCAREA_GERUDO_FORTRESS, SCENE_THIEVES_HIDEOUT, TWO_ACTOR_PARAMS(215, 549), "Left Middle Jailed Pot", RHT_TH_RIGHT_MIDDLE_JAILED_POT, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_TH_LEFT_MIDDLE_JAILED_POT));
locationTable[RC_TH_LEFTMOST_JAILED_POT] = Location::Pot(RC_TH_LEFTMOST_JAILED_POT, RCQUEST_BOTH, RCAREA_GERUDO_FORTRESS, SCENE_THIEVES_HIDEOUT, TWO_ACTOR_PARAMS(254, 529), "Leftmost Jailed Pot", RHT_TH_LEFTMOST_JAILED_POT, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_TH_LEFTMOST_JAILED_POT));
locationTable[RC_WASTELAND_NEAR_GS_POT_1] = Location::Pot(RC_WASTELAND_NEAR_GS_POT_1, RCQUEST_BOTH, RCAREA_WASTELAND, SCENE_HAUNTED_WASTELAND, TWO_ACTOR_PARAMS(488, -2424), "Near GS Pot 1", RHT_POT_WASTELAND, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_WASTELAND_NEAR_GS_POT_1));
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_WASTELAND, 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_WASTELAND, 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_WASTELAND, 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_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));
locationTable[RC_KAK_NEAR_IMPAS_HOUSE_POT_1] = Location::Pot(RC_KAK_NEAR_IMPAS_HOUSE_POT_1, RCQUEST_BOTH, RCAREA_KAKARIKO_VILLAGE, SCENE_KAKARIKO_VILLAGE, TWO_ACTOR_PARAMS(-384, 1568), "Near Impas House Pot 1", RHT_POT_KAKARIKO, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_KAK_NEAR_IMPAS_HOUSE_POT_1));
locationTable[RC_KAK_NEAR_IMPAS_HOUSE_POT_2] = Location::Pot(RC_KAK_NEAR_IMPAS_HOUSE_POT_2, RCQUEST_BOTH, RCAREA_KAKARIKO_VILLAGE, SCENE_KAKARIKO_VILLAGE, TWO_ACTOR_PARAMS(-384, 1539), "Near Impas House Pot 2", RHT_POT_KAKARIKO, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_KAK_NEAR_IMPAS_HOUSE_POT_2));
locationTable[RC_KAK_NEAR_IMPAS_HOUSE_POT_3] = Location::Pot(RC_KAK_NEAR_IMPAS_HOUSE_POT_3, RCQUEST_BOTH, RCAREA_KAKARIKO_VILLAGE, SCENE_KAKARIKO_VILLAGE, TWO_ACTOR_PARAMS(-384, 1510), "Near Impas House Pot 3", RHT_POT_KAKARIKO, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_KAK_NEAR_IMPAS_HOUSE_POT_3));
locationTable[RC_KAK_NEAR_GUARDS_HOUSE_POT_1] = Location::Pot(RC_KAK_NEAR_GUARDS_HOUSE_POT_1, RCQUEST_BOTH, RCAREA_KAKARIKO_VILLAGE, SCENE_KAKARIKO_VILLAGE, TWO_ACTOR_PARAMS(-392, -870), "Near Guards House Pot 1", RHT_POT_KAKARIKO, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_KAK_NEAR_GUARDS_HOUSE_POT_1));
locationTable[RC_KAK_NEAR_GUARDS_HOUSE_POT_2] = Location::Pot(RC_KAK_NEAR_GUARDS_HOUSE_POT_2, RCQUEST_BOTH, RCAREA_KAKARIKO_VILLAGE, SCENE_KAKARIKO_VILLAGE, TWO_ACTOR_PARAMS(-422, -883), "Near Guards House Pot 2", RHT_POT_KAKARIKO, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_KAK_NEAR_GUARDS_HOUSE_POT_2));
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_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));
locationTable[RC_GC_UPPER_STAIRCASE_POT_2] = Location::Pot(RC_GC_UPPER_STAIRCASE_POT_2, RCQUEST_BOTH, RCAREA_GORON_CITY, SCENE_GORON_CITY, TWO_ACTOR_PARAMS(-1185, 95), "Upper Staircase Pot 2", RHT_POT_GORON_CITY, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GC_UPPER_STAIRCASE_POT_2));
locationTable[RC_GC_UPPER_STAIRCASE_POT_3] = Location::Pot(RC_GC_UPPER_STAIRCASE_POT_3, RCQUEST_BOTH, RCAREA_GORON_CITY, SCENE_GORON_CITY, TWO_ACTOR_PARAMS(-1200, 63), "Upper Staircase Pot 3", RHT_POT_GORON_CITY, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GC_UPPER_STAIRCASE_POT_3));
locationTable[RC_GC_MEDIGORON_POT_1] = Location::Pot(RC_GC_MEDIGORON_POT_1, RCQUEST_BOTH, RCAREA_GORON_CITY, SCENE_GORON_CITY, TWO_ACTOR_PARAMS(-694, 1196), "Medigoron Pot 1", RHT_POT_GORON_CITY, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GC_MEDIGORON_POT_1));
locationTable[RC_GC_DARUNIA_POT_1] = Location::Pot(RC_GC_DARUNIA_POT_1, RCQUEST_BOTH, RCAREA_GORON_CITY, SCENE_GORON_CITY, TWO_ACTOR_PARAMS(262, -1210), "Darunia Pot 1", RHT_POT_GORON_CITY, RG_ARROWS_5, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GC_DARUNIA_POT_1));
locationTable[RC_GC_DARUNIA_POT_2] = Location::Pot(RC_GC_DARUNIA_POT_2, RCQUEST_BOTH, RCAREA_GORON_CITY, SCENE_GORON_CITY, TWO_ACTOR_PARAMS(261, -1254), "Darunia Pot 2", RHT_POT_GORON_CITY, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GC_DARUNIA_POT_2));
locationTable[RC_GC_DARUNIA_POT_3] = Location::Pot(RC_GC_DARUNIA_POT_3, RCQUEST_BOTH, RCAREA_GORON_CITY, SCENE_GORON_CITY, TWO_ACTOR_PARAMS(262, -1386), "Darunia Pot 3", RHT_POT_GORON_CITY, RG_RED_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GC_DARUNIA_POT_3));
// 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_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_TH_BREAK_ROOM_FRONT_POT] = Location::Pot(RC_TH_BREAK_ROOM_FRONT_POT, RCQUEST_BOTH, RCAREA_GERUDO_FORTRESS, SCENE_THIEVES_HIDEOUT, TWO_ACTOR_PARAMS(1438, -3629), "Break Room Front Pot", RHT_TH_BREAK_ROOM_FRONT_POT, RG_ARROWS_10, SpoilerCollectionCheck::RandomizerInf(RAND_INF_TH_BREAK_ROOM_FRONT_POT));
locationTable[RC_TH_BREAK_ROOM_BACK_POT] = Location::Pot(RC_TH_BREAK_ROOM_BACK_POT, RCQUEST_BOTH, RCAREA_GERUDO_FORTRESS, SCENE_THIEVES_HIDEOUT, TWO_ACTOR_PARAMS(1403, -3679), "Break Room Back Pot", RHT_TH_BREAK_ROOM_BACK_POT, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_TH_BREAK_ROOM_BACK_POT));
locationTable[RC_TH_KITCHEN_POT_1] = Location::Pot(RC_TH_KITCHEN_POT_1, RCQUEST_BOTH, RCAREA_GERUDO_FORTRESS, SCENE_THIEVES_HIDEOUT, TWO_ACTOR_PARAMS(1908, -789), "Kitchen Pot 1", RHT_TH_KITCHEN_POT_1, RG_ARROWS_10, SpoilerCollectionCheck::RandomizerInf(RAND_INF_TH_KITCHEN_POT_1));
locationTable[RC_TH_KITCHEN_POT_2] = Location::Pot(RC_TH_KITCHEN_POT_2, RCQUEST_BOTH, RCAREA_GERUDO_FORTRESS, SCENE_THIEVES_HIDEOUT, TWO_ACTOR_PARAMS(1951, -850), "Kitchen Pot 2", RHT_TH_KITCHEN_POT_2, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_TH_KITCHEN_POT_2));
locationTable[RC_TH_1_TORCH_CELL_RIGHT_POT] = Location::Pot(RC_TH_1_TORCH_CELL_RIGHT_POT, RCQUEST_BOTH, RCAREA_GERUDO_FORTRESS, SCENE_THIEVES_HIDEOUT, TWO_ACTOR_PARAMS(-475, -2622), "1 Torch Cell Right Pot", RHT_TH_1_TORCH_CELL_RIGHT_POT, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_TH_1_TORCH_CELL_RIGHT_POT));
locationTable[RC_TH_1_TORCH_CELL_MID_POT] = Location::Pot(RC_TH_1_TORCH_CELL_MID_POT, RCQUEST_BOTH, RCAREA_GERUDO_FORTRESS, SCENE_THIEVES_HIDEOUT, TWO_ACTOR_PARAMS(-512, -2621), "1 Torch Cell Middle Pot", RHT_TH_1_TORCH_CELL_MID_POT, RG_RED_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_TH_1_TORCH_CELL_MID_POT));
locationTable[RC_TH_1_TORCH_CELL_LEFT_POT] = Location::Pot(RC_TH_1_TORCH_CELL_LEFT_POT, RCQUEST_BOTH, RCAREA_GERUDO_FORTRESS, SCENE_THIEVES_HIDEOUT, TWO_ACTOR_PARAMS(-511, -2582), "1 Torch Cell Left Pot", RHT_TH_1_TORCH_CELL_LEFT_POT, RG_ARROWS_10, SpoilerCollectionCheck::RandomizerInf(RAND_INF_TH_1_TORCH_CELL_LEFT_POT));
locationTable[RC_TH_STEEP_SLOPE_RIGHT_POT] = Location::Pot(RC_TH_STEEP_SLOPE_RIGHT_POT, RCQUEST_BOTH, RCAREA_GERUDO_FORTRESS, SCENE_THIEVES_HIDEOUT, TWO_ACTOR_PARAMS(67, -1975), "Steep Slope Right Pot", RHT_TH_STEEP_SLOPE_RIGHT_POT, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_TH_STEEP_SLOPE_RIGHT_POT));
locationTable[RC_TH_STEEP_SLOPE_LEFT_POT] = Location::Pot(RC_TH_STEEP_SLOPE_LEFT_POT, RCQUEST_BOTH, RCAREA_GERUDO_FORTRESS, SCENE_THIEVES_HIDEOUT, TWO_ACTOR_PARAMS(39, -1943), "Steep Slope Left Pot", RHT_TH_STEEP_SLOPE_LEFT_POT, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_TH_STEEP_SLOPE_LEFT_POT));
locationTable[RC_TH_NEAR_DOUBLE_CELL_RIGHT_POT] = Location::Pot(RC_TH_NEAR_DOUBLE_CELL_RIGHT_POT, RCQUEST_BOTH, RCAREA_GERUDO_FORTRESS, SCENE_THIEVES_HIDEOUT, TWO_ACTOR_PARAMS(691, 48), "Double Cell Right Pot", RHT_TH_NEAR_DOUBLE_CELL_RIGHT_POT, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_TH_NEAR_DOUBLE_CELL_RIGHT_POT));
locationTable[RC_TH_NEAR_DOUBLE_CELL_MID_POT] = Location::Pot(RC_TH_NEAR_DOUBLE_CELL_MID_POT, RCQUEST_BOTH, RCAREA_GERUDO_FORTRESS, SCENE_THIEVES_HIDEOUT, TWO_ACTOR_PARAMS(691, 16), "Double Cell Middle Pot", RHT_TH_NEAR_DOUBLE_CELL_MID_POT, RG_RED_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_TH_NEAR_DOUBLE_CELL_MID_POT));
locationTable[RC_TH_NEAR_DOUBLE_CELL_LEFT_POT] = Location::Pot(RC_TH_NEAR_DOUBLE_CELL_LEFT_POT, RCQUEST_BOTH, RCAREA_GERUDO_FORTRESS, SCENE_THIEVES_HIDEOUT, TWO_ACTOR_PARAMS(661, 16), "Double Cell Left Pot", RHT_TH_NEAR_DOUBLE_CELL_LEFT_POT, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_NEAR_DOUBLE_CELL_LEFT_POT));
locationTable[RC_TH_RIGHTMOST_JAILED_POT] = Location::Pot(RC_TH_RIGHTMOST_JAILED_POT, RCQUEST_BOTH, RCAREA_GERUDO_FORTRESS, SCENE_THIEVES_HIDEOUT, TWO_ACTOR_PARAMS(26, 524), "Rightmost Jailed Pot", RHT_TH_RIGHTMOST_JAILED_POT, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_TH_RIGHTMOST_JAILED_POT));
locationTable[RC_TH_RIGHT_MIDDLE_JAILED_POT] = Location::Pot(RC_TH_RIGHT_MIDDLE_JAILED_POT, RCQUEST_BOTH, RCAREA_GERUDO_FORTRESS, SCENE_THIEVES_HIDEOUT, TWO_ACTOR_PARAMS(61, 549), "Right Middle Jailed Pot", RHT_TH_LEFT_MIDDLE_JAILED_POT, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_TH_RIGHT_MIDDLE_JAILED_POT));
locationTable[RC_TH_LEFT_MIDDLE_JAILED_POT] = Location::Pot(RC_TH_LEFT_MIDDLE_JAILED_POT, RCQUEST_BOTH, RCAREA_GERUDO_FORTRESS, SCENE_THIEVES_HIDEOUT, TWO_ACTOR_PARAMS(215, 549), "Left Middle Jailed Pot", RHT_TH_RIGHT_MIDDLE_JAILED_POT, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_TH_LEFT_MIDDLE_JAILED_POT));
locationTable[RC_TH_LEFTMOST_JAILED_POT] = Location::Pot(RC_TH_LEFTMOST_JAILED_POT, RCQUEST_BOTH, RCAREA_GERUDO_FORTRESS, SCENE_THIEVES_HIDEOUT, TWO_ACTOR_PARAMS(254, 529), "Leftmost Jailed Pot", RHT_TH_LEFTMOST_JAILED_POT, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_TH_LEFTMOST_JAILED_POT));
locationTable[RC_WASTELAND_NEAR_GS_POT_1] = Location::Pot(RC_WASTELAND_NEAR_GS_POT_1, RCQUEST_BOTH, RCAREA_WASTELAND, SCENE_HAUNTED_WASTELAND, TWO_ACTOR_PARAMS(488, -2424), "Near GS Pot 1", RHT_POT_WASTELAND, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_WASTELAND_NEAR_GS_POT_1));
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_WASTELAND, 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_WASTELAND, 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_WASTELAND, 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_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_ALLEY_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_ALLEY_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_ALLEY_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));
locationTable[RC_KAK_NEAR_IMPAS_HOUSE_POT_1] = Location::Pot(RC_KAK_NEAR_IMPAS_HOUSE_POT_1, RCQUEST_BOTH, RCAREA_KAKARIKO_VILLAGE, SCENE_KAKARIKO_VILLAGE, TWO_ACTOR_PARAMS(-384, 1568), "Near Impas House Pot 1", RHT_POT_KAKARIKO, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_KAK_NEAR_IMPAS_HOUSE_POT_1));
locationTable[RC_KAK_NEAR_IMPAS_HOUSE_POT_2] = Location::Pot(RC_KAK_NEAR_IMPAS_HOUSE_POT_2, RCQUEST_BOTH, RCAREA_KAKARIKO_VILLAGE, SCENE_KAKARIKO_VILLAGE, TWO_ACTOR_PARAMS(-384, 1539), "Near Impas House Pot 2", RHT_POT_KAKARIKO, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_KAK_NEAR_IMPAS_HOUSE_POT_2));
locationTable[RC_KAK_NEAR_IMPAS_HOUSE_POT_3] = Location::Pot(RC_KAK_NEAR_IMPAS_HOUSE_POT_3, RCQUEST_BOTH, RCAREA_KAKARIKO_VILLAGE, SCENE_KAKARIKO_VILLAGE, TWO_ACTOR_PARAMS(-384, 1510), "Near Impas House Pot 3", RHT_POT_KAKARIKO, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_KAK_NEAR_IMPAS_HOUSE_POT_3));
locationTable[RC_KAK_NEAR_GUARDS_HOUSE_POT_1] = Location::Pot(RC_KAK_NEAR_GUARDS_HOUSE_POT_1, RCQUEST_BOTH, RCAREA_KAKARIKO_VILLAGE, SCENE_KAKARIKO_VILLAGE, TWO_ACTOR_PARAMS(-392, -870), "Near Guards House Pot 1", RHT_POT_KAKARIKO, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_KAK_NEAR_GUARDS_HOUSE_POT_1));
locationTable[RC_KAK_NEAR_GUARDS_HOUSE_POT_2] = Location::Pot(RC_KAK_NEAR_GUARDS_HOUSE_POT_2, RCQUEST_BOTH, RCAREA_KAKARIKO_VILLAGE, SCENE_KAKARIKO_VILLAGE, TWO_ACTOR_PARAMS(-422, -883), "Near Guards House Pot 2", RHT_POT_KAKARIKO, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_KAK_NEAR_GUARDS_HOUSE_POT_2));
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_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));
locationTable[RC_GC_UPPER_STAIRCASE_POT_2] = Location::Pot(RC_GC_UPPER_STAIRCASE_POT_2, RCQUEST_BOTH, RCAREA_GORON_CITY, SCENE_GORON_CITY, TWO_ACTOR_PARAMS(-1185, 95), "Upper Staircase Pot 2", RHT_POT_GORON_CITY, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GC_UPPER_STAIRCASE_POT_2));
locationTable[RC_GC_UPPER_STAIRCASE_POT_3] = Location::Pot(RC_GC_UPPER_STAIRCASE_POT_3, RCQUEST_BOTH, RCAREA_GORON_CITY, SCENE_GORON_CITY, TWO_ACTOR_PARAMS(-1200, 63), "Upper Staircase Pot 3", RHT_POT_GORON_CITY, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GC_UPPER_STAIRCASE_POT_3));
locationTable[RC_GC_MEDIGORON_POT_1] = Location::Pot(RC_GC_MEDIGORON_POT_1, RCQUEST_BOTH, RCAREA_GORON_CITY, SCENE_GORON_CITY, TWO_ACTOR_PARAMS(-694, 1196), "Medigoron Pot 1", RHT_POT_GORON_CITY, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GC_MEDIGORON_POT_1));
locationTable[RC_GC_DARUNIA_POT_1] = Location::Pot(RC_GC_DARUNIA_POT_1, RCQUEST_BOTH, RCAREA_GORON_CITY, SCENE_GORON_CITY, TWO_ACTOR_PARAMS(262, -1210), "Darunia Pot 1", RHT_POT_GORON_CITY, RG_ARROWS_5, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GC_DARUNIA_POT_1));
locationTable[RC_GC_DARUNIA_POT_2] = Location::Pot(RC_GC_DARUNIA_POT_2, RCQUEST_BOTH, RCAREA_GORON_CITY, SCENE_GORON_CITY, TWO_ACTOR_PARAMS(261, -1254), "Darunia Pot 2", RHT_POT_GORON_CITY, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GC_DARUNIA_POT_2));
locationTable[RC_GC_DARUNIA_POT_3] = Location::Pot(RC_GC_DARUNIA_POT_3, RCQUEST_BOTH, RCAREA_GORON_CITY, SCENE_GORON_CITY, TWO_ACTOR_PARAMS(262, -1386), "Darunia Pot 3", RHT_POT_GORON_CITY, RG_RED_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GC_DARUNIA_POT_3));
locationTable[RC_DMC_NEAR_GC_POT_2] = Location::Pot(RC_DMC_NEAR_GC_POT_2, RCQUEST_BOTH, RCAREA_DEATH_MOUNTAIN_CRATER, SCENE_DEATH_MOUNTAIN_CRATER, TWO_ACTOR_PARAMS(-1546, 141), "Near GC Pot 2", RHT_POT_DEATH_MOUNTAIN_CRATER, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_DMC_NEAR_GC_POT_2));
locationTable[RC_DMC_NEAR_GC_POT_3] = Location::Pot(RC_DMC_NEAR_GC_POT_3, RCQUEST_BOTH, RCAREA_DEATH_MOUNTAIN_CRATER, SCENE_DEATH_MOUNTAIN_CRATER, TWO_ACTOR_PARAMS(-1641, -127), "Near GC Pot 3", RHT_POT_DEATH_MOUNTAIN_CRATER, RG_ARROWS_5, SpoilerCollectionCheck::RandomizerInf(RAND_INF_DMC_NEAR_GC_POT_3));
locationTable[RC_DMC_NEAR_GC_POT_1] = Location::Pot(RC_DMC_NEAR_GC_POT_1, RCQUEST_BOTH, RCAREA_DEATH_MOUNTAIN_CRATER, SCENE_DEATH_MOUNTAIN_CRATER, TWO_ACTOR_PARAMS(-1590, 132), "Near GC Pot 1", RHT_POT_DEATH_MOUNTAIN_CRATER, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_DMC_NEAR_GC_POT_1));
locationTable[RC_DMC_NEAR_GC_POT_4] = Location::Pot(RC_DMC_NEAR_GC_POT_4, RCQUEST_BOTH, RCAREA_DEATH_MOUNTAIN_CRATER, SCENE_DEATH_MOUNTAIN_CRATER, TWO_ACTOR_PARAMS(-1606, -166), "Near GC Pot 4", RHT_POT_DEATH_MOUNTAIN_CRATER, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_DMC_NEAR_GC_POT_4));
locationTable[RC_ZD_NEAR_SHOP_POT_1] = Location::Pot(RC_ZD_NEAR_SHOP_POT_1, RCQUEST_BOTH, RCAREA_ZORAS_DOMAIN, SCENE_ZORAS_DOMAIN, TWO_ACTOR_PARAMS(676, 377), "Near Shop Pot 1", RHT_POT_ZORAS_DOMAIN, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ZD_NEAR_SHOP_POT_1));
locationTable[RC_ZD_NEAR_SHOP_POT_2] = Location::Pot(RC_ZD_NEAR_SHOP_POT_2, RCQUEST_BOTH, RCAREA_ZORAS_DOMAIN, SCENE_ZORAS_DOMAIN, TWO_ACTOR_PARAMS(614, 419), "Near Shop Pot 2", RHT_POT_ZORAS_DOMAIN, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ZD_NEAR_SHOP_POT_2));
locationTable[RC_ZD_NEAR_SHOP_POT_3] = Location::Pot(RC_ZD_NEAR_SHOP_POT_3, RCQUEST_BOTH, RCAREA_ZORAS_DOMAIN, SCENE_ZORAS_DOMAIN, TWO_ACTOR_PARAMS(289, 415), "Near Shop Pot 3", RHT_POT_ZORAS_DOMAIN, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ZD_NEAR_SHOP_POT_3));
locationTable[RC_ZD_NEAR_SHOP_POT_4] = Location::Pot(RC_ZD_NEAR_SHOP_POT_4, RCQUEST_BOTH, RCAREA_ZORAS_DOMAIN, SCENE_ZORAS_DOMAIN, TWO_ACTOR_PARAMS(289, 289), "Near Shop Pot 4", RHT_POT_ZORAS_DOMAIN, RG_DEKU_NUTS_5, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ZD_NEAR_SHOP_POT_4));
locationTable[RC_ZD_NEAR_SHOP_POT_5] = Location::Pot(RC_ZD_NEAR_SHOP_POT_5, RCQUEST_BOTH, RCAREA_ZORAS_DOMAIN, SCENE_ZORAS_DOMAIN, TWO_ACTOR_PARAMS(220, 384), "Near Shop Pot 5", RHT_POT_ZORAS_DOMAIN, RG_DEKU_STICK_1, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ZD_NEAR_SHOP_POT_5));
locationTable[RC_ZF_HIDDEN_CAVE_POT_1] = Location::Pot(RC_ZF_HIDDEN_CAVE_POT_1, RCQUEST_BOTH, RCAREA_ZORAS_FOUNTAIN, SCENE_ZORAS_FOUNTAIN, TWO_ACTOR_PARAMS(385, 2587), "Hidden Cave Pot 1", RHT_POT_ZORAS_FOUNTAIN, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ZF_HIDDEN_CAVE_POT_1));
locationTable[RC_ZF_HIDDEN_CAVE_POT_2] = Location::Pot(RC_ZF_HIDDEN_CAVE_POT_2, RCQUEST_BOTH, RCAREA_ZORAS_FOUNTAIN, SCENE_ZORAS_FOUNTAIN, TWO_ACTOR_PARAMS(418, 2609), "Hidden Cave Pot 2", RHT_POT_ZORAS_FOUNTAIN, RG_ARROWS_10, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ZF_HIDDEN_CAVE_POT_2));
locationTable[RC_ZF_HIDDEN_CAVE_POT_3] = Location::Pot(RC_ZF_HIDDEN_CAVE_POT_3, RCQUEST_BOTH, RCAREA_ZORAS_FOUNTAIN, SCENE_ZORAS_FOUNTAIN, TWO_ACTOR_PARAMS(430, 2568), "Hidden Cave Pot 3", RHT_POT_ZORAS_FOUNTAIN, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ZF_HIDDEN_CAVE_POT_3));
locationTable[RC_ZF_NEAR_JABU_POT_1] = Location::Pot(RC_ZF_NEAR_JABU_POT_1, RCQUEST_BOTH, RCAREA_ZORAS_FOUNTAIN, SCENE_ZORAS_FOUNTAIN, TWO_ACTOR_PARAMS(-1630, 170), "Near Jabu Pot 1", RHT_POT_ZORAS_FOUNTAIN, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ZF_NEAR_JABU_POT_1));
locationTable[RC_ZF_NEAR_JABU_POT_2] = Location::Pot(RC_ZF_NEAR_JABU_POT_2, RCQUEST_BOTH, RCAREA_ZORAS_FOUNTAIN, SCENE_ZORAS_FOUNTAIN, TWO_ACTOR_PARAMS(-1550, 170), "Near Jabu Pot 2", RHT_POT_ZORAS_FOUNTAIN, RG_DEKU_SEEDS_30, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ZF_NEAR_JABU_POT_2));
locationTable[RC_ZF_NEAR_JABU_POT_3] = Location::Pot(RC_ZF_NEAR_JABU_POT_3, RCQUEST_BOTH, RCAREA_ZORAS_FOUNTAIN, SCENE_ZORAS_FOUNTAIN, TWO_ACTOR_PARAMS(-1630, -260), "Near Jabu Pot 3", RHT_POT_ZORAS_FOUNTAIN, RG_DEKU_SEEDS_30, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ZF_NEAR_JABU_POT_3));
locationTable[RC_ZF_NEAR_JABU_POT_4] = Location::Pot(RC_ZF_NEAR_JABU_POT_4, RCQUEST_BOTH, RCAREA_ZORAS_FOUNTAIN, SCENE_ZORAS_FOUNTAIN, TWO_ACTOR_PARAMS(-1550, -260), "Near Jabu Pot 4", RHT_POT_ZORAS_FOUNTAIN, RG_DEKU_SEEDS_30, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ZF_NEAR_JABU_POT_4));
locationTable[RC_LLR_FRONT_POT_1] = Location::Pot(RC_LLR_FRONT_POT_1, RCQUEST_BOTH, RCAREA_LON_LON_RANCH, SCENE_LON_LON_RANCH, TWO_ACTOR_PARAMS(667, -3218), "Front Pot 1", RHT_POT_LON_LON_RANCH, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_LLR_FRONT_POT_1));
locationTable[RC_LLR_FRONT_POT_2] = Location::Pot(RC_LLR_FRONT_POT_2, RCQUEST_BOTH, RCAREA_LON_LON_RANCH, SCENE_LON_LON_RANCH, TWO_ACTOR_PARAMS(667, -3186), "Front Pot 2", RHT_POT_LON_LON_RANCH, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_LLR_FRONT_POT_2));
locationTable[RC_LLR_FRONT_POT_3] = Location::Pot(RC_LLR_FRONT_POT_3, RCQUEST_BOTH, RCAREA_LON_LON_RANCH, SCENE_LON_LON_RANCH, TWO_ACTOR_PARAMS(667, -3154), "Front Pot 3", RHT_POT_LON_LON_RANCH, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_LLR_FRONT_POT_3));
locationTable[RC_LLR_FRONT_POT_4] = Location::Pot(RC_LLR_FRONT_POT_4, RCQUEST_BOTH, RCAREA_LON_LON_RANCH, SCENE_LON_LON_RANCH, TWO_ACTOR_PARAMS(667, -3122), "Front Pot 4", RHT_POT_LON_LON_RANCH, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_LLR_FRONT_POT_4));
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_ZD_NEAR_SHOP_POT_1] = Location::Pot(RC_ZD_NEAR_SHOP_POT_1, RCQUEST_BOTH, RCAREA_ZORAS_DOMAIN, SCENE_ZORAS_DOMAIN, TWO_ACTOR_PARAMS(676, 377), "Near Shop Pot 1", RHT_POT_ZORAS_DOMAIN, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ZD_NEAR_SHOP_POT_1));
locationTable[RC_ZD_NEAR_SHOP_POT_2] = Location::Pot(RC_ZD_NEAR_SHOP_POT_2, RCQUEST_BOTH, RCAREA_ZORAS_DOMAIN, SCENE_ZORAS_DOMAIN, TWO_ACTOR_PARAMS(614, 419), "Near Shop Pot 2", RHT_POT_ZORAS_DOMAIN, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ZD_NEAR_SHOP_POT_2));
locationTable[RC_ZD_NEAR_SHOP_POT_3] = Location::Pot(RC_ZD_NEAR_SHOP_POT_3, RCQUEST_BOTH, RCAREA_ZORAS_DOMAIN, SCENE_ZORAS_DOMAIN, TWO_ACTOR_PARAMS(289, 415), "Near Shop Pot 3", RHT_POT_ZORAS_DOMAIN, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ZD_NEAR_SHOP_POT_3));
locationTable[RC_ZD_NEAR_SHOP_POT_4] = Location::Pot(RC_ZD_NEAR_SHOP_POT_4, RCQUEST_BOTH, RCAREA_ZORAS_DOMAIN, SCENE_ZORAS_DOMAIN, TWO_ACTOR_PARAMS(289, 289), "Near Shop Pot 4", RHT_POT_ZORAS_DOMAIN, RG_DEKU_NUTS_5, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ZD_NEAR_SHOP_POT_4));
locationTable[RC_ZD_NEAR_SHOP_POT_5] = Location::Pot(RC_ZD_NEAR_SHOP_POT_5, RCQUEST_BOTH, RCAREA_ZORAS_DOMAIN, SCENE_ZORAS_DOMAIN, TWO_ACTOR_PARAMS(220, 384), "Near Shop Pot 5", RHT_POT_ZORAS_DOMAIN, RG_DEKU_STICK_1, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ZD_NEAR_SHOP_POT_5));
locationTable[RC_ZF_HIDDEN_CAVE_POT_1] = Location::Pot(RC_ZF_HIDDEN_CAVE_POT_1, RCQUEST_BOTH, RCAREA_ZORAS_FOUNTAIN, SCENE_ZORAS_FOUNTAIN, TWO_ACTOR_PARAMS(385, 2587), "Hidden Cave Pot 1", RHT_POT_ZORAS_FOUNTAIN, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ZF_HIDDEN_CAVE_POT_1));
locationTable[RC_ZF_HIDDEN_CAVE_POT_2] = Location::Pot(RC_ZF_HIDDEN_CAVE_POT_2, RCQUEST_BOTH, RCAREA_ZORAS_FOUNTAIN, SCENE_ZORAS_FOUNTAIN, TWO_ACTOR_PARAMS(418, 2609), "Hidden Cave Pot 2", RHT_POT_ZORAS_FOUNTAIN, RG_ARROWS_10, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ZF_HIDDEN_CAVE_POT_2));
locationTable[RC_ZF_HIDDEN_CAVE_POT_3] = Location::Pot(RC_ZF_HIDDEN_CAVE_POT_3, RCQUEST_BOTH, RCAREA_ZORAS_FOUNTAIN, SCENE_ZORAS_FOUNTAIN, TWO_ACTOR_PARAMS(430, 2568), "Hidden Cave Pot 3", RHT_POT_ZORAS_FOUNTAIN, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ZF_HIDDEN_CAVE_POT_3));
locationTable[RC_ZF_NEAR_JABU_POT_1] = Location::Pot(RC_ZF_NEAR_JABU_POT_1, RCQUEST_BOTH, RCAREA_ZORAS_FOUNTAIN, SCENE_ZORAS_FOUNTAIN, TWO_ACTOR_PARAMS(-1630, 170), "Near Jabu Pot 1", RHT_POT_ZORAS_FOUNTAIN, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ZF_NEAR_JABU_POT_1));
locationTable[RC_ZF_NEAR_JABU_POT_2] = Location::Pot(RC_ZF_NEAR_JABU_POT_2, RCQUEST_BOTH, RCAREA_ZORAS_FOUNTAIN, SCENE_ZORAS_FOUNTAIN, TWO_ACTOR_PARAMS(-1550, 170), "Near Jabu Pot 2", RHT_POT_ZORAS_FOUNTAIN, RG_DEKU_SEEDS_30, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ZF_NEAR_JABU_POT_2));
locationTable[RC_ZF_NEAR_JABU_POT_3] = Location::Pot(RC_ZF_NEAR_JABU_POT_3, RCQUEST_BOTH, RCAREA_ZORAS_FOUNTAIN, SCENE_ZORAS_FOUNTAIN, TWO_ACTOR_PARAMS(-1630, -260), "Near Jabu Pot 3", RHT_POT_ZORAS_FOUNTAIN, RG_DEKU_SEEDS_30, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ZF_NEAR_JABU_POT_3));
locationTable[RC_ZF_NEAR_JABU_POT_4] = Location::Pot(RC_ZF_NEAR_JABU_POT_4, RCQUEST_BOTH, RCAREA_ZORAS_FOUNTAIN, SCENE_ZORAS_FOUNTAIN, TWO_ACTOR_PARAMS(-1550, -260), "Near Jabu Pot 4", RHT_POT_ZORAS_FOUNTAIN, RG_DEKU_SEEDS_30, SpoilerCollectionCheck::RandomizerInf(RAND_INF_ZF_NEAR_JABU_POT_4));
locationTable[RC_LLR_FRONT_POT_1] = Location::Pot(RC_LLR_FRONT_POT_1, RCQUEST_BOTH, RCAREA_LON_LON_RANCH, SCENE_LON_LON_RANCH, TWO_ACTOR_PARAMS(667, -3218), "Front Pot 1", RHT_POT_LON_LON_RANCH, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_LLR_FRONT_POT_1));
locationTable[RC_LLR_FRONT_POT_2] = Location::Pot(RC_LLR_FRONT_POT_2, RCQUEST_BOTH, RCAREA_LON_LON_RANCH, SCENE_LON_LON_RANCH, TWO_ACTOR_PARAMS(667, -3186), "Front Pot 2", RHT_POT_LON_LON_RANCH, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_LLR_FRONT_POT_2));
locationTable[RC_LLR_FRONT_POT_3] = Location::Pot(RC_LLR_FRONT_POT_3, RCQUEST_BOTH, RCAREA_LON_LON_RANCH, SCENE_LON_LON_RANCH, TWO_ACTOR_PARAMS(667, -3154), "Front Pot 3", RHT_POT_LON_LON_RANCH, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_LLR_FRONT_POT_3));
locationTable[RC_LLR_FRONT_POT_4] = Location::Pot(RC_LLR_FRONT_POT_4, RCQUEST_BOTH, RCAREA_LON_LON_RANCH, SCENE_LON_LON_RANCH, TWO_ACTOR_PARAMS(667, -3122), "Front Pot 4", RHT_POT_LON_LON_RANCH, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_LLR_FRONT_POT_4));
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_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 Hint Text Key Vanilla Spoiler Collection Check
locationTable[RC_DODONGOS_CAVERN_LIZALFOS_POT_3] = Location::Pot(RC_DODONGOS_CAVERN_LIZALFOS_POT_3, RCQUEST_VANILLA, RCAREA_DODONGOS_CAVERN, SCENE_DODONGOS_CAVERN, TWO_ACTOR_PARAMS(2673, -2060), "Lizalfos Pot 3", RHT_POT_DODONGOS_CAVERN, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_DODONGOS_CAVERN_LIZALFOS_POT_3));

View file

@ -1,13 +1,17 @@
#include <libultraship/bridge.h>
#include "draw.h"
#include "z64.h"
#include "macros.h"
#include "functions.h"
#include "variables.h"
#include "soh/OTRGlobals.h"
#include "soh/cvar_prefixes.h"
#include "randomizerTypes.h"
#include <array>
#include "soh_assets.h"
#include "soh/Enhancements/cosmetics/cosmeticsTypes.h"
extern "C" {
#include "z64.h"
#include "macros.h"
#include "functions.h"
#include "variables.h"
#include "dungeon.h"
#include "objects/object_gi_key/object_gi_key.h"
#include "objects/object_gi_bosskey/object_gi_bosskey.h"
#include "objects/object_gi_compass/object_gi_compass.h"
@ -30,11 +34,6 @@
#include "overlays/ovl_Boss_Sst/ovl_Boss_Sst.h"
#include "objects/object_tw/object_tw.h"
#include "objects/object_ganon2/object_ganon2.h"
#include "soh_assets.h"
#include "dungeon.h"
#include "soh/Enhancements/cosmetics/cosmeticsTypes.h"
extern "C" {
extern PlayState* gPlayState;
extern SaveContext gSaveContext;
}

View file

@ -45,8 +45,6 @@ std::string Entrance::GetName() const {
}
void Entrance::printAgeTimeAccess() {
// CitraPrint("Name: ");
// CitraPrint(name);
auto message = "Child Day: " + std::to_string(CheckConditionAtAgeTime(logic->IsChild, logic->AtDay)) +
"\t"
"Child Night: " +
@ -57,7 +55,6 @@ void Entrance::printAgeTimeAccess() {
"\t"
"Adult Night: " +
std::to_string(CheckConditionAtAgeTime(logic->IsAdult, logic->AtNight));
// CitraPrint(message);
}
bool Entrance::ConditionsMet(bool allAgeTimes) const {
@ -276,8 +273,8 @@ void SetAllEntrancesData() {
{ 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_GF_OUTSIDE_GTG, RR_GERUDO_TRAINING_GROUND_ENTRYWAY, ENTR_GERUDO_TRAINING_GROUND_ENTRANCE },
{ EntranceType::Dungeon, RR_GERUDO_TRAINING_GROUND_ENTRYWAY, RR_GF_OUTSIDE_GTG, ENTR_GERUDOS_FORTRESS_OUTSIDE_GERUDO_TRAINING_GROUND } },
{ { EntranceType::Dungeon, RR_GF_TO_GTG, RR_GERUDO_TRAINING_GROUND_ENTRYWAY, ENTR_GERUDO_TRAINING_GROUND_ENTRANCE },
{ EntranceType::Dungeon, RR_GERUDO_TRAINING_GROUND_ENTRYWAY, RR_GF_EXITING_GTG, 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 } },
@ -1214,15 +1211,6 @@ int EntranceShuffler::ShuffleAllEntrances() {
if (ctx->GetOption(RSK_SHUFFLE_BOSS_ENTRANCES).Is(RO_BOSS_ROOM_ENTRANCE_SHUFFLE_FULL)) {
entrancePools[EntranceType::Boss] = GetShuffleableEntrances(EntranceType::ChildBoss);
AddElementsToPool(entrancePools[EntranceType::Boss], GetShuffleableEntrances(EntranceType::AdultBoss));
// If forest is closed, ensure Ghoma is inside the Deku tree
// Deku tree being in its vanilla location is handled below
if (ctx->GetOption(RSK_FOREST).Is(RO_CLOSED_FOREST_ON) &&
!(ctx->GetOption(RSK_SHUFFLE_OVERWORLD_ENTRANCES) || ctx->GetOption(RSK_SHUFFLE_INTERIOR_ENTRANCES))) {
FilterAndEraseFromPool(entrancePools[EntranceType::Boss], [](const Entrance* entrance) {
return entrance->GetParentRegionKey() == RR_DEKU_TREE_BOSS_ENTRYWAY &&
entrance->GetConnectedRegionKey() == RR_DEKU_TREE_BOSS_ROOM;
});
}
if (ctx->GetOption(RSK_DECOUPLED_ENTRANCES)) {
for (Entrance* entrance : entrancePools[EntranceType::Boss]) {
entrancePools[EntranceType::BossReverse].push_back(entrance->GetReverse());
@ -1231,14 +1219,6 @@ int EntranceShuffler::ShuffleAllEntrances() {
} else {
entrancePools[EntranceType::ChildBoss] = GetShuffleableEntrances(EntranceType::ChildBoss);
entrancePools[EntranceType::AdultBoss] = GetShuffleableEntrances(EntranceType::AdultBoss);
// If forest is closed, ensure Ghoma is inside the Deku tree
if (ctx->GetOption(RSK_FOREST).Is(RO_CLOSED_FOREST_ON) &&
!(ctx->GetOption(RSK_SHUFFLE_OVERWORLD_ENTRANCES) || ctx->GetOption(RSK_SHUFFLE_INTERIOR_ENTRANCES))) {
FilterAndEraseFromPool(entrancePools[EntranceType::ChildBoss], [](const Entrance* entrance) {
return entrance->GetParentRegionKey() == RR_DEKU_TREE_BOSS_ENTRYWAY &&
entrance->GetConnectedRegionKey() == RR_DEKU_TREE_BOSS_ROOM;
});
}
if (ctx->GetOption(RSK_DECOUPLED_ENTRANCES)) {
for (Entrance* entrance : entrancePools[EntranceType::ChildBoss]) {
entrancePools[EntranceType::ChildBossReverse].push_back(entrance->GetReverse());
@ -1258,14 +1238,6 @@ int EntranceShuffler::ShuffleAllEntrances() {
AddElementsToPool(entrancePools[EntranceType::Dungeon],
GetShuffleableEntrances(EntranceType::GanonDungeon));
}
// If forest is closed don't allow a forest escape via spirit temple hands
if (ctx->GetOption(RSK_FOREST).Is(RO_CLOSED_FOREST_ON) &&
!(ctx->GetOption(RSK_SHUFFLE_OVERWORLD_ENTRANCES) || ctx->GetOption(RSK_SHUFFLE_INTERIOR_ENTRANCES))) {
FilterAndEraseFromPool(entrancePools[EntranceType::Dungeon], [](const Entrance* entrance) {
return entrance->GetParentRegionKey() == RR_KF_OUTSIDE_DEKU_TREE &&
entrance->GetConnectedRegionKey() == RR_DEKU_TREE_ENTRYWAY;
});
}
if (ctx->GetOption(RSK_DECOUPLED_ENTRANCES)) {
for (Entrance* entrance : entrancePools[EntranceType::Dungeon]) {
entrancePools[EntranceType::DungeonReverse].push_back(entrance->GetReverse());

View file

@ -299,6 +299,8 @@ const CustomMessage Hint::GetHintMessage(MessageFormat format, size_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, size_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();

View file

@ -22,6 +22,7 @@ extern "C" {
#include "soh/Enhancements/randomizer/randomizer_entrance.h"
#include "soh/Enhancements/randomizer/randomizer_grotto.h"
#include "src/overlays/actors/ovl_Bg_Treemouth/z_bg_treemouth.h"
#include "src/overlays/actors/ovl_Bg_Jya_Bigmirror/z_bg_jya_bigmirror.h"
#include "src/overlays/actors/ovl_En_Si/z_en_si.h"
#include "src/overlays/actors/ovl_En_Shopnuts/z_en_shopnuts.h"
#include "src/overlays/actors/ovl_En_Dns/z_en_dns.h"
@ -263,6 +264,14 @@ void RandomizerOnSceneFlagSetHandler(int16_t sceneNum, int16_t flagType, int16_t
Flags_SetRandomizerInf(RAND_INF_GF_GTG_GATE_PERMANENTLY_OPEN);
}
if (sceneNum == SCENE_SPIRIT_TEMPLE && flagType == FLAG_SCENE_SWITCH) {
bool isVanilla =
Rando::Context::GetInstance()->GetDungeons()->GetDungeonFromScene(SCENE_SPIRIT_TEMPLE)->IsVanilla();
if (isVanilla && flag == 0x23) {
Flags_SetRandomizerInf(RAND_INF_SPIRIT_SUN_ON_FLOOR_ON);
}
}
RandomizerCheck rc = GetRandomizerCheckFromSceneFlag(sceneNum, flagType, flag);
if (rc == RC_UNKNOWN_CHECK)
return;
@ -1783,7 +1792,7 @@ void RandomizerOnSceneInitHandler(int16_t sceneNum) {
Entrance_OverrideSpawnScene(sceneNum, gPlayState->curSpawn);
}
// LACs & Prelude checks
// LACS & Prelude checks
static uint32_t updateHook = 0;
if (updateHook) {
@ -1855,6 +1864,16 @@ void EnDns_RandomizerPurchase(EnDns* enDns) {
void RandomizerOnActorInitHandler(void* actorRef) {
Actor* actor = static_cast<Actor*>(actorRef);
if (actor->id == ACTOR_PLAYER) {
if (gPlayState->sceneNum == SCENE_SPIRIT_TEMPLE) {
bool isVanilla =
Rando::Context::GetInstance()->GetDungeons()->GetDungeonFromScene(SCENE_SPIRIT_TEMPLE)->IsVanilla();
if (isVanilla && Flags_GetRandomizerInf(RAND_INF_SPIRIT_SUN_ON_FLOOR_ON)) {
Flags_SetSwitch(gPlayState, 0x23);
}
}
}
if (actor->id == ACTOR_EN_SI) {
RandomizerCheck rc =
OTRGlobals::Instance->gRandomizer->GetCheckFromActor(actor->id, gPlayState->sceneNum, actor->params);
@ -1986,6 +2005,15 @@ void RandomizerOnActorInitHandler(void* actorRef) {
}
}
if (actor->id == ACTOR_BG_JYA_BIGMIRROR && Flags_GetRandomizerInf(RAND_INF_SPIRIT_BIG_MIRROR_STATUE_TURNED)) {
Flags_SetSwitch(gPlayState, 0x29); // destroy wall
auto jyaBigMirror = static_cast<BgJyaBigmirror*>(actorRef);
jyaBigMirror->puzzleFlags |=
BIGMIR_PUZZLE_COBRA1_SOLVED | BIGMIR_PUZZLE_COBRA2_SOLVED | BIGMIR_PUZZLE_BOMBIWA_DESTROYED;
jyaBigMirror->cobraInfo[0].rotY = 0x4000;
jyaBigMirror->cobraInfo[1].rotY = 0x8000;
}
if (actor->id == ACTOR_DEMO_KEKKAI && actor->params == 0) { // 0 == KEKKAI_TOWER
if (CompletedAllTrials()) {
Actor_Kill(actor);
@ -2151,6 +2179,16 @@ void RandomizerOnActorUpdateHandler(void* refActor) {
}
}
if (actor->id == ACTOR_BG_JYA_BIGMIRROR) {
auto jyaBigMirror = reinterpret_cast<BgJyaBigmirror*>(actor);
if ((jyaBigMirror->puzzleFlags & (BIGMIR_PUZZLE_COBRA1_SOLVED | BIGMIR_PUZZLE_COBRA2_SOLVED)) ==
(BIGMIR_PUZZLE_COBRA1_SOLVED | BIGMIR_PUZZLE_COBRA2_SOLVED)) {
Flags_SetRandomizerInf(RAND_INF_SPIRIT_BIG_MIRROR_STATUE_TURNED);
} else {
Flags_UnsetRandomizerInf(RAND_INF_SPIRIT_BIG_MIRROR_STATUE_TURNED);
}
}
// In ER, override the warp song locations. Also removes the warp song cutscene
if (RAND_GET_OPTION(RSK_SHUFFLE_ENTRANCES) && actor->id == ACTOR_DEMO_KANKYO &&
actor->params == 0x000F) { // Warp Song particles

View file

@ -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,10 +37,11 @@ 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;
@ -456,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();
}

View file

@ -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;

View file

@ -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", "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.)", "Fanghaken (prog.)" }, 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.)", "Stärke (prog.)" }, 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.)", "Bombentasche (prog.)" }, 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.)", "Bogen (prog.)" }, 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.)", "Schleuder (prog.)" }, 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.)", "Geldbörse (prog.)" }, ITEMTYPE_ITEM, 0x85, true, LOGIC_PROGRESSIVE_WALLET, RHT_PROGRESSIVE_WALLET, true);
itemTable[RG_PROGRESSIVE_SCALE] = Item(RG_PROGRESSIVE_SCALE, Text{ "Progressive Scale", "Écaille (prog.)", "Zora-Schuppe (prog.)" }, 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.)", "Nuß-Kapazität (prog.)" }, 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.)", "Stab-Kapazität (prog.)" }, 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.)", "Krabbelminen (prog.)" }, 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.)", "Magische Kraft (prog.)" }, 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.)", "Okarina (prog.)" }, 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.)", "Goronen-Schwert (prog.)" }, 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.)", "Fanghaken (prog.)" }, 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.)", "Stärke (prog.)" }, 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.)", "Bombentasche (prog.)" }, 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.)", "Bogen (prog.)" }, 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.)", "Schleuder (prog.)" }, 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.)", "Geldbörse (prog.)" }, 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.)", "Zora-Schuppe (prog.)" }, 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.)", "Nuß-Kapazität (prog.)" }, 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.)", "Stab-Kapazität (prog.)" }, 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.)", "Krabbelminen (prog.)" }, 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.)", "Magische Kraft (prog.)" }, 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.)", "Okarina (prog.)" }, 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.)", "Goronen-Schwert (prog.)" }, 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 (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-Kerne 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", "Kä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", "Irrlicht 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);

View file

@ -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);
}

View file

@ -20,6 +20,18 @@ extern PlayState* gPlayState;
// generic grotto event list
std::vector<EventAccess> grottoEvents;
bool EventAccess::CheckConditionAtAgeTime(bool& age, bool& time) {
logic->IsChild = false;
logic->IsAdult = false;
logic->AtDay = false;
logic->AtNight = false;
time = true;
age = true;
return ConditionsMet();
}
// set the logic to be a specific age and time of day and see if the condition still holds
bool LocationAccess::CheckConditionAtAgeTime(bool& age, bool& time) const {
logic->IsChild = false;
@ -466,7 +478,7 @@ bool Region::UpdateEvents() {
}
void Region::AddExit(RandomizerRegion parentKey, RandomizerRegion newExitKey, ConditionFn condition) {
Rando::Entrance newExit = Rando::Entrance(newExitKey, { condition });
Rando::Entrance newExit = Rando::Entrance(newExitKey, condition);
newExit.SetParentRegion(parentKey);
exits.push_front(newExit);
}
@ -551,6 +563,110 @@ void Region::ResetVariables() {
}
}
/*
* This logic covers checks that exist in the shared areas of MQ spirit from a glitchless standpoint.
* This room has Quantum logic that I am currently handling with this function, however this is NOT suitable for
glitch logic as it relies on specific ages
* In this chunk there are 3 possibilities for passing a check, but first I have to talk about parallel universes.
* In MQ Spirit key logic, we mostly care about 2 possibilities for how the player can spend keys, creating 2
Parralel universes
* In the first universe, the player did not enter spirit as adult until after climbing as child, thus child spends
keys linearly, only needing 2 to reach statue room.
* In the second universe, the player went in as adult, possibly out of logic, and started wasting the keys to lock
child out.
* These Universes converge when the player has 7 keys (meaning adult can no longer lock child out) and adult is
known to be able to reach Statue room. This creates "Certain Access", which is tracked seperatly for each age.
* Child Certain Access is simple, if we have 7 keys and child access, it's Certain Access.
* Adult Certain Access is also simple, adult is not key locked, so if they make it to a location, it's Certain
Access.
* Things get complicated when we handle the overlap of the 2 universes,
* though an important detail is that if we have Certain Access as either age, we don't need to checked the overlap
because overlap logic is strictly stricter than either Certain Access.
* In order to track the first universe, the logic allows technical child access with the minimum number of keys,
and then checks in this function for if we have 7 keys to determine if that is Certain or not.
* This is for technical reasons, as areas with no access at all will simply not be checked.
* Normally we would need to do similar shenanigans to track the second universe, however adult must have go through
statue room to waste keys,
* so can go back there and get new keys for Child to use if they do, and the navigation logic for shared MQ spirit
from Statue Room is very simple for Adult.
* Additionally, we don't need to know if adult can actually reach spirit temple or climb to statue room, because if
the player can't do that, then universe 2 can't happen anyway,
* and if the player does so out of logic, they can do it again, as the only consumable used sets a permanent flag.
* The Adult Navigation logic is as such:
* - Broken Wall room is 6 key locked, because if the player tries to spend 6 keys in a way that would block adults
access, they would have to give child access instead.
* - The child side hammer switch for the time travelling chest is 7 key locked for adult
* - Reaching gauntlets hand is 7 key locked
* - Going back into big block room is complex, but the only check there is child only so not a concern
* - Everything else is possible with basic adult movement, or is impossible for child to reach glitchlessly
* Anything 7 key locked does not need to be checked as shared, as all child access is Certain and because of this
workaround we don't need to fake Adult access, meaning that is also Certain.
* All of this combined means that when checking if adult can reach a location in universe 2, we only have to ask if
it is a 6 key locked location or not.
* Knowing all of this this, we can confirm things are logical in 3 different ways:
* - If we have Adult Access, we know it is Certain Access, so they can get checks alone.
* - If we have 7 keys, child has Certain Access as we know they cannot be locked out, so can get checks alone,
otherwise we check the logical overlap
* - If Child and Adult can get the check (ignoring actual adult access to the location), and the location is either
not 6 key locked or we have 6 keys, we can get the check with the overlap
*/
bool Region::MQSpiritShared(ConditionFn condition, bool IsBrokenWall, bool anyAge) {
// if we have Certain Access as child, we can check anyAge and if true, resolve a condition with Here as if
// adult is here it's also Certain Access
if (logic->SmallKeys(RR_SPIRIT_TEMPLE, 7)) {
if (anyAge) {
return Here(condition);
}
return condition();
// else, if we are here as adult, we have Certain Access from that and don't need special handling for
// checking adult
} else if (Adult() && logic->IsAdult) {
return condition();
// if we do not have Certain Access, we need to check the overlap by seeing if we are both here as child and
// meet the adult universe's access condition We only need to do it as child, as only child access matters
// for this check, as adult access is assumed based on keys
} else if (Child() && logic->IsChild && (!IsBrokenWall || logic->SmallKeys(RR_SPIRIT_TEMPLE, 6))) {
bool result = false;
// store current age variables
bool pastAdult = logic->IsAdult;
bool pastChild = logic->IsChild;
// First check if the check is possible as child
logic->IsChild = true;
logic->IsAdult = false;
result = condition();
// If so, check again as adult. both have to be true for result to be true
if (result) {
logic->IsChild = false;
logic->IsAdult = true;
result = condition();
}
// set back age variables
logic->IsChild = pastChild;
logic->IsAdult = pastAdult;
return result;
}
return false;
}
void Region::printAgeTimeAccess() {
auto message = "Child Day: " + std::to_string(childDay) +
"\t"
"Child Night: " +
std::to_string(childNight) +
"\t"
"Adult Day: " +
std::to_string(adultDay) +
"\t"
"Adult Night: " +
std::to_string(adultNight);
}
std::array<Region, RR_MAX> areaTable;
bool Here(const RandomizerRegion region, ConditionFn condition) {
@ -692,11 +808,11 @@ void RegionTable_Init() {
Entrance(RR_CHILD_SPAWN, []{return logic->IsChild;}),
Entrance(RR_ADULT_SPAWN, []{return logic->IsAdult;}),
Entrance(RR_MINUET_OF_FOREST_WARP, []{return logic->CanUse(RG_MINUET_OF_FOREST);}),
Entrance(RR_BOLERO_OF_FIRE_WARP, []{return logic->CanUse(RG_BOLERO_OF_FIRE) && logic->CanLeaveForest();}),
Entrance(RR_SERENADE_OF_WATER_WARP, []{return logic->CanUse(RG_SERENADE_OF_WATER) && logic->CanLeaveForest();}),
Entrance(RR_NOCTURNE_OF_SHADOW_WARP, []{return logic->CanUse(RG_NOCTURNE_OF_SHADOW) && logic->CanLeaveForest();}),
Entrance(RR_REQUIEM_OF_SPIRIT_WARP, []{return logic->CanUse(RG_REQUIEM_OF_SPIRIT) && logic->CanLeaveForest();}),
Entrance(RR_PRELUDE_OF_LIGHT_WARP, []{return logic->CanUse(RG_PRELUDE_OF_LIGHT) && logic->CanLeaveForest();}),
Entrance(RR_BOLERO_OF_FIRE_WARP, []{return logic->CanUse(RG_BOLERO_OF_FIRE);}),
Entrance(RR_SERENADE_OF_WATER_WARP, []{return logic->CanUse(RG_SERENADE_OF_WATER);}),
Entrance(RR_NOCTURNE_OF_SHADOW_WARP, []{return logic->CanUse(RG_NOCTURNE_OF_SHADOW);}),
Entrance(RR_REQUIEM_OF_SPIRIT_WARP, []{return logic->CanUse(RG_REQUIEM_OF_SPIRIT);}),
Entrance(RR_PRELUDE_OF_LIGHT_WARP, []{return logic->CanUse(RG_PRELUDE_OF_LIGHT);}),
});
areaTable[RR_CHILD_SPAWN] = Region("Child Spawn", SCENE_ID_MAX, TIME_DOESNT_PASS, {RA_LINKS_POCKET}, {}, {}, {

View file

@ -34,17 +34,7 @@ class EventAccess {
return true;
}
bool CheckConditionAtAgeTime(bool& age, bool& time) {
logic->IsChild = false;
logic->IsAdult = false;
logic->AtDay = false;
logic->AtNight = false;
time = true;
age = true;
return ConditionsMet();
}
bool CheckConditionAtAgeTime(bool& age, bool& time);
void EventOccurred() {
*event = true;
@ -210,7 +200,7 @@ class Region {
logic->IsChild = Child();
logic->IsAdult = Adult();
// heck condition as well as having at least child or adult access
// check condition as well as having at least child or adult access
bool hereVal = condition() && (logic->IsAdult || logic->IsChild);
// set back age variables
@ -222,112 +212,11 @@ class Region {
bool CanPlantBeanCheck() const;
bool AllAccountedFor() const;
bool MQSpiritShared(ConditionFn condition, bool IsBrokenWall, bool anyAge = false);
void ResetVariables();
void printAgeTimeAccess() const {
auto message = "Child Day: " + std::to_string(childDay) +
"\t"
"Child Night: " +
std::to_string(childNight) +
"\t"
"Adult Day: " +
std::to_string(adultDay) +
"\t"
"Adult Night: " +
std::to_string(adultNight);
}
/*
* This logic covers checks that exist in the shared areas of MQ spirit from a glitchless standpoint.
* This room has Quantum logic that I am currently handling with this function, however this is NOT suitable for
glitch logic as it relies on specific ages
* In this chunk there are 3 possibilities for passing a check, but first I have to talk about parallel universes.
* In MQ Spirit key logic, we mostly care about 2 possibilities for how the player can spend keys, creating 2
Parralel universes
* In the first universe, the player did not enter spirit as adult until after climbing as child, thus child spends
keys linearly, only needing 2 to reach statue room.
* In the second universe, the player went in as adult, possibly out of logic, and started wasting the keys to lock
child out.
* These Universes converge when the player has 7 keys (meaning adult can no longer lock child out) and adult is
known to be able to reach Statue room. This creates "Certain Access", which is tracked seperatly for each age.
* Child Certain Access is simple, if we have 7 keys and child access, it's Certain Access.
* Adult Certain Access is also simple, adult is not key locked, so if they make it to a location, it's Certain
Access.
* Things get complicated when we handle the overlap of the 2 universes,
* though an important detail is that if we have Certain Access as either age, we don't need to checked the overlap
because overlap logic is strictly stricter than either Certain Access.
* In order to track the first universe, the logic allows technical child access with the minimum number of keys,
and then checks in this function for if we have 7 keys to determine if that is Certain or not.
* This is for technical reasons, as areas with no access at all will simply not be checked.
* Normally we would need to do similar shenanigans to track the second universe, however adult must have go through
statue room to waste keys,
* so can go back there and get new keys for Child to use if they do, and the navigation logic for shared MQ spirit
from Statue Room is very simple for Adult.
* Additionally, we don't need to know if adult can actually reach spirit temple or climb to statue room, because if
the player can't do that, then universe 2 can't happen anyway,
* and if the player does so out of logic, they can do it again, as the only consumable used sets a permanent flag.
* The Adult Navigation logic is as such:
* - Broken Wall room is 6 key locked, because if the player tries to spend 6 keys in a way that would block adults
access, they would have to give child access instead.
* - The child side hammer switch for the time travelling chest is 7 key locked for adult
* - Reaching gauntlets hand is 7 key locked
* - Going back into big block room is complex, but the only check there is child only so not a concern
* - Everything else is possible with basic adult movement, or is impossible for child to reach glitchlessly
* Anything 7 key locked does not need to be checked as shared, as all child access is Certain and because of this
workaround we don't need to fake Adult access, meaning that is also Certain.
* All of this combined means that when checking if adult can reach a location in universe 2, we only have to ask if
it is a 6 key locked location or not.
* Knowing all of this this, we can confirm things are logical in 3 different ways:
* - If we have Adult Access, we know it is Certain Access, so they can get checks alone.
* - If we have 7 keys, child has Certain Access as we know they cannot be locked out, so can get checks alone,
otherwise we check the logical overlap
* - If Child and Adult can get the check (ignoring actual adult access to the location), and the location is either
not 6 key locked or we have 6 keys, we can get the check with the overlap
*/
bool MQSpiritShared(ConditionFn condition, bool IsBrokenWall, bool anyAge = false) {
// if we have Certain Access as child, we can check anyAge and if true, resolve a condition with Here as if
// adult is here it's also Certain Access
if (logic->SmallKeys(RR_SPIRIT_TEMPLE, 7)) {
if (anyAge) {
return Here(condition);
}
return condition();
// else, if we are here as adult, we have Certain Access from that and don't need special handling for
// checking adult
} else if (Adult() && logic->IsAdult) {
return condition();
// if we do not have Certain Access, we need to check the overlap by seeing if we are both here as child and
// meet the adult universe's access condition We only need to do it as child, as only child access matters
// for this check, as adult access is assumed based on keys
} else if (Child() && logic->IsChild && (!IsBrokenWall || logic->SmallKeys(RR_SPIRIT_TEMPLE, 6))) {
bool result = false;
// store current age variables
bool pastAdult = logic->IsAdult;
bool pastChild = logic->IsChild;
// First check if the check is possible as child
logic->IsChild = true;
logic->IsAdult = false;
result = condition();
// If so, check again as adult. both have to be true for result to be true
if (result) {
logic->IsChild = false;
logic->IsAdult = true;
result = condition();
}
// set back age variables
logic->IsChild = pastChild;
logic->IsAdult = pastAdult;
return result;
}
return false;
}
void printAgeTimeAccess();
};
extern std::array<Region, RR_MAX> areaTable;

View file

@ -11,7 +11,7 @@ void RegionTable_Init_GerudoTrainingGround() {
//Exits
Entrance(RR_GERUDO_TRAINING_GROUND_LOBBY, []{return ctx->GetDungeon(GERUDO_TRAINING_GROUND)->IsVanilla();}),
Entrance(RR_GERUDO_TRAINING_GROUND_MQ_LOBBY, []{return ctx->GetDungeon(GERUDO_TRAINING_GROUND)->IsMQ();}),
Entrance(RR_GF_OUTSIDE_GTG, []{return true;}),
Entrance(RR_GF_EXITING_GTG, []{return true;}),
});
#pragma region Vanilla

View file

@ -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();}),
});

View file

@ -48,12 +48,12 @@ void RegionTable_Init_SpiritTemple() {
areaTable[RR_SPIRIT_TEMPLE_CHILD_CLIMB] = Region("Child Spirit Temple Climb", SCENE_SPIRIT_TEMPLE, {}, {
//Locations
LOCATION(RC_SPIRIT_TEMPLE_CHILD_CLIMB_NORTH_CHEST, logic->HasProjectile(HasProjectileAge::Both) || ((logic->SmallKeys(RR_SPIRIT_TEMPLE, 3) || (logic->SmallKeys(RR_SPIRIT_TEMPLE, 2) && ctx->GetOption(RSK_BOMBCHU_BAG) && logic->BombchuRefill() && ctx->GetOption(RSK_SHUFFLE_DUNGEON_ENTRANCES).Is(RO_DUNGEON_ENTRANCE_SHUFFLE_OFF))) && logic->CanUse(RG_SILVER_GAUNTLETS) && logic->HasProjectile(HasProjectileAge::Adult)) || (logic->SmallKeys(RR_SPIRIT_TEMPLE, 5) && logic->IsChild && logic->HasProjectile(HasProjectileAge::Child))),
LOCATION(RC_SPIRIT_TEMPLE_CHILD_CLIMB_EAST_CHEST, logic->HasProjectile(HasProjectileAge::Both) || ((logic->SmallKeys(RR_SPIRIT_TEMPLE, 3) || (logic->SmallKeys(RR_SPIRIT_TEMPLE, 2) && ctx->GetOption(RSK_BOMBCHU_BAG) && logic->BombchuRefill() && ctx->GetOption(RSK_SHUFFLE_DUNGEON_ENTRANCES).Is(RO_DUNGEON_ENTRANCE_SHUFFLE_OFF))) && logic->CanUse(RG_SILVER_GAUNTLETS) && logic->HasProjectile(HasProjectileAge::Adult)) || (logic->SmallKeys(RR_SPIRIT_TEMPLE, 5) && logic->IsChild && logic->HasProjectile(HasProjectileAge::Child))),
LOCATION(RC_SPIRIT_TEMPLE_CHILD_CLIMB_NORTH_CHEST, logic->HasProjectile(HasProjectileAge::Both) || (logic->SmallKeys(RR_SPIRIT_TEMPLE, 2) && logic->CanUse(RG_SILVER_GAUNTLETS) && logic->HasProjectile(HasProjectileAge::Adult)) || (logic->SmallKeys(RR_SPIRIT_TEMPLE, 5) && logic->IsChild && logic->HasProjectile(HasProjectileAge::Child))),
LOCATION(RC_SPIRIT_TEMPLE_CHILD_CLIMB_EAST_CHEST, logic->HasProjectile(HasProjectileAge::Both) || (logic->SmallKeys(RR_SPIRIT_TEMPLE, 2) && logic->CanUse(RG_SILVER_GAUNTLETS) && logic->HasProjectile(HasProjectileAge::Adult)) || (logic->SmallKeys(RR_SPIRIT_TEMPLE, 5) && logic->IsChild && logic->HasProjectile(HasProjectileAge::Child))),
LOCATION(RC_SPIRIT_TEMPLE_GS_SUN_ON_FLOOR_ROOM, logic->HasProjectile(HasProjectileAge::Both) || logic->CanUse(RG_DINS_FIRE) ||
(logic->TakeDamage() && (logic->CanJumpslashExceptHammer() || logic->HasProjectile(HasProjectileAge::Child))) ||
(logic->IsChild && logic->SmallKeys(RR_SPIRIT_TEMPLE, 5) && logic->HasProjectile(HasProjectileAge::Child)) ||
((logic->SmallKeys(RR_SPIRIT_TEMPLE, 3) || (logic->SmallKeys(RR_SPIRIT_TEMPLE, 2) && ctx->GetOption(RSK_BOMBCHU_BAG) && logic->BombchuRefill() && ctx->GetOption(RSK_SHUFFLE_DUNGEON_ENTRANCES).Is(RO_DUNGEON_ENTRANCE_SHUFFLE_OFF))) && logic->CanUse(RG_SILVER_GAUNTLETS) && (logic->HasProjectile(HasProjectileAge::Adult) || (logic->TakeDamage() && logic->CanJumpslashExceptHammer())))),
(logic->SmallKeys(RR_SPIRIT_TEMPLE, 2) && logic->CanUse(RG_SILVER_GAUNTLETS) && (logic->HasProjectile(HasProjectileAge::Adult) || (logic->TakeDamage() && logic->CanJumpslashExceptHammer())))),
LOCATION(RC_SPIRIT_TEMPLE_CHILD_CLIMB_POT_1, logic->CanBreakPots()),
}, {
//Exits
@ -75,11 +75,11 @@ void RegionTable_Init_SpiritTemple() {
areaTable[RR_SPIRIT_TEMPLE_CENTRAL_CHAMBER] = Region("Spirit Temple Central Chamber", SCENE_SPIRIT_TEMPLE, {}, {
//Locations
LOCATION(RC_SPIRIT_TEMPLE_MAP_CHEST, ((logic->HasExplosives() || logic->SmallKeys(RR_SPIRIT_TEMPLE, 3) || (logic->SmallKeys(RR_SPIRIT_TEMPLE, 2) && ctx->GetOption(RSK_BOMBCHU_BAG) && logic->BombchuRefill() && ctx->GetOption(RSK_SHUFFLE_DUNGEON_ENTRANCES).Is(RO_DUNGEON_ENTRANCE_SHUFFLE_OFF))) &&
LOCATION(RC_SPIRIT_TEMPLE_MAP_CHEST, ((logic->HasExplosives() || logic->SmallKeys(RR_SPIRIT_TEMPLE, 2)) &&
(logic->CanUse(RG_DINS_FIRE) || ((logic->CanUse(RG_FIRE_ARROWS) || ctx->GetTrickOption(RT_SPIRIT_MAP_CHEST)) && logic->CanUse(RG_FAIRY_BOW) && logic->CanUse(RG_STICKS) ))) ||
(logic->SmallKeys(RR_SPIRIT_TEMPLE, 5) && logic->HasExplosives() && logic->CanUse(RG_STICKS)) ||
(logic->SmallKeys(RR_SPIRIT_TEMPLE, 3) && (logic->CanUse(RG_FIRE_ARROWS) || (ctx->GetTrickOption(RT_SPIRIT_MAP_CHEST) && logic->CanUse(RG_FAIRY_BOW))) && logic->CanUse(RG_SILVER_GAUNTLETS))),
LOCATION(RC_SPIRIT_TEMPLE_SUN_BLOCK_ROOM_CHEST, ((logic->HasExplosives() || logic->SmallKeys(RR_SPIRIT_TEMPLE, 3) || (logic->SmallKeys(RR_SPIRIT_TEMPLE, 2) && ctx->GetOption(RSK_BOMBCHU_BAG) && logic->BombchuRefill() && ctx->GetOption(RSK_SHUFFLE_DUNGEON_ENTRANCES).Is(RO_DUNGEON_ENTRANCE_SHUFFLE_OFF))) &&
LOCATION(RC_SPIRIT_TEMPLE_SUN_BLOCK_ROOM_CHEST, ((logic->HasExplosives() || logic->SmallKeys(RR_SPIRIT_TEMPLE, 2)) &&
(logic->CanUse(RG_DINS_FIRE) || ((logic->CanUse(RG_FIRE_ARROWS) || ctx->GetTrickOption(RT_SPIRIT_SUN_CHEST)) && logic->CanUse(RG_FAIRY_BOW) && logic->CanUse(RG_STICKS) ))) ||
(logic->SmallKeys(RR_SPIRIT_TEMPLE, 5) && logic->HasExplosives() && logic->CanUse(RG_STICKS)) ||
(logic->SmallKeys(RR_SPIRIT_TEMPLE, 3) && (logic->CanUse(RG_FIRE_ARROWS) || (ctx->GetTrickOption(RT_SPIRIT_SUN_CHEST) && logic->CanUse(RG_FAIRY_BOW))) && logic->CanUse(RG_SILVER_GAUNTLETS))),
@ -87,20 +87,19 @@ void RegionTable_Init_SpiritTemple() {
LOCATION(RC_SPIRIT_TEMPLE_STATUE_ROOM_NORTHEAST_CHEST, logic->SmallKeys(RR_SPIRIT_TEMPLE, 3) && logic->CanUse(RG_SILVER_GAUNTLETS) && logic->CanUse(RG_ZELDAS_LULLABY) && (logic->CanUse(RG_HOOKSHOT) || logic->CanUse(RG_HOVER_BOOTS) || ctx->GetTrickOption(RT_SPIRIT_LOBBY_JUMP))),
LOCATION(RC_SPIRIT_TEMPLE_GS_HALL_AFTER_SUN_BLOCK_ROOM, (logic->HasExplosives() && logic->CanUse(RG_BOOMERANG) && logic->CanUse(RG_HOOKSHOT)) ||
(logic->CanUse(RG_BOOMERANG) && logic->SmallKeys(RR_SPIRIT_TEMPLE, 5) && logic->HasExplosives()) ||
(logic->CanUse(RG_HOOKSHOT) && logic->CanUse(RG_SILVER_GAUNTLETS) && (logic->SmallKeys(RR_SPIRIT_TEMPLE, 3) || (logic->SmallKeys(RR_SPIRIT_TEMPLE, 2) &&
logic->CanUse(RG_BOOMERANG) && ctx->GetOption(RSK_BOMBCHU_BAG) && logic->BombchuRefill() && ctx->GetOption(RSK_SHUFFLE_DUNGEON_ENTRANCES).Is(RO_DUNGEON_ENTRANCE_SHUFFLE_OFF))))),
LOCATION(RC_SPIRIT_TEMPLE_GS_LOBBY, ((logic->HasExplosives() || logic->SmallKeys(RR_SPIRIT_TEMPLE, 3) || (logic->SmallKeys(RR_SPIRIT_TEMPLE, 2) && ctx->GetOption(RSK_BOMBCHU_BAG) && logic->BombchuRefill() && ctx->GetOption(RSK_SHUFFLE_DUNGEON_ENTRANCES).Is(RO_DUNGEON_ENTRANCE_SHUFFLE_OFF))) &&
(logic->CanUse(RG_HOOKSHOT) && logic->CanUse(RG_SILVER_GAUNTLETS) && logic->SmallKeys(RR_SPIRIT_TEMPLE, 2))),
LOCATION(RC_SPIRIT_TEMPLE_GS_LOBBY, ((logic->HasExplosives() || logic->SmallKeys(RR_SPIRIT_TEMPLE, 2)) &&
ctx->GetTrickOption(RT_SPIRIT_LOBBY_GS) && logic->CanUse(RG_BOOMERANG) && (logic->CanUse(RG_HOOKSHOT) || logic->CanUse(RG_HOVER_BOOTS) || ctx->GetTrickOption(RT_SPIRIT_LOBBY_JUMP))) ||
(ctx->GetTrickOption(RT_SPIRIT_LOBBY_GS) && logic->SmallKeys(RR_SPIRIT_TEMPLE, 5) && logic->HasExplosives() && logic->CanUse(RG_BOOMERANG)) ||
(logic->SmallKeys(RR_SPIRIT_TEMPLE, 3) && logic->CanUse(RG_SILVER_GAUNTLETS) && (logic->CanUse(RG_HOOKSHOT) || logic->CanUse(RG_HOVER_BOOTS) || ctx->GetTrickOption(RT_SPIRIT_LOBBY_JUMP)))),
LOCATION(RC_SPIRIT_TEMPLE_AFTER_SUN_BLOCK_POT_1, logic->CanBreakPots() && (logic->SmallKeys(RR_SPIRIT_TEMPLE, 3) || (logic->SmallKeys(RR_SPIRIT_TEMPLE, 2) && ctx->GetOption(RSK_BOMBCHU_BAG) && logic->BombchuRefill() && ctx->GetOption(RSK_SHUFFLE_DUNGEON_ENTRANCES).Is(RO_DUNGEON_ENTRANCE_SHUFFLE_OFF)))),
LOCATION(RC_SPIRIT_TEMPLE_AFTER_SUN_BLOCK_POT_2, logic->CanBreakPots() && (logic->SmallKeys(RR_SPIRIT_TEMPLE, 3) || (logic->SmallKeys(RR_SPIRIT_TEMPLE, 2) && ctx->GetOption(RSK_BOMBCHU_BAG) && logic->BombchuRefill() && ctx->GetOption(RSK_SHUFFLE_DUNGEON_ENTRANCES).Is(RO_DUNGEON_ENTRANCE_SHUFFLE_OFF)))),
LOCATION(RC_SPIRIT_TEMPLE_CENTRAL_CHAMBER_POT_1, logic->CanBreakPots() && (logic->SmallKeys(RR_SPIRIT_TEMPLE, 3) || (logic->SmallKeys(RR_SPIRIT_TEMPLE, 2) && ctx->GetOption(RSK_BOMBCHU_BAG) && logic->BombchuRefill() && ctx->GetOption(RSK_SHUFFLE_DUNGEON_ENTRANCES).Is(RO_DUNGEON_ENTRANCE_SHUFFLE_OFF)))),
LOCATION(RC_SPIRIT_TEMPLE_CENTRAL_CHAMBER_POT_2, logic->CanBreakPots() && (logic->SmallKeys(RR_SPIRIT_TEMPLE, 3) || (logic->SmallKeys(RR_SPIRIT_TEMPLE, 2) && ctx->GetOption(RSK_BOMBCHU_BAG) && logic->BombchuRefill() && ctx->GetOption(RSK_SHUFFLE_DUNGEON_ENTRANCES).Is(RO_DUNGEON_ENTRANCE_SHUFFLE_OFF)))),
LOCATION(RC_SPIRIT_TEMPLE_CENTRAL_CHAMBER_POT_3, logic->CanBreakPots() && (logic->SmallKeys(RR_SPIRIT_TEMPLE, 3) || (logic->SmallKeys(RR_SPIRIT_TEMPLE, 2) && ctx->GetOption(RSK_BOMBCHU_BAG) && logic->BombchuRefill() && ctx->GetOption(RSK_SHUFFLE_DUNGEON_ENTRANCES).Is(RO_DUNGEON_ENTRANCE_SHUFFLE_OFF)))),
LOCATION(RC_SPIRIT_TEMPLE_CENTRAL_CHAMBER_POT_4, logic->CanBreakPots() && (logic->SmallKeys(RR_SPIRIT_TEMPLE, 3) || (logic->SmallKeys(RR_SPIRIT_TEMPLE, 2) && ctx->GetOption(RSK_BOMBCHU_BAG) && logic->BombchuRefill() && ctx->GetOption(RSK_SHUFFLE_DUNGEON_ENTRANCES).Is(RO_DUNGEON_ENTRANCE_SHUFFLE_OFF)))),
LOCATION(RC_SPIRIT_TEMPLE_CENTRAL_CHAMBER_POT_5, logic->CanBreakPots() && (logic->SmallKeys(RR_SPIRIT_TEMPLE, 3) || (logic->SmallKeys(RR_SPIRIT_TEMPLE, 2) && ctx->GetOption(RSK_BOMBCHU_BAG) && logic->BombchuRefill() && ctx->GetOption(RSK_SHUFFLE_DUNGEON_ENTRANCES).Is(RO_DUNGEON_ENTRANCE_SHUFFLE_OFF)))),
LOCATION(RC_SPIRIT_TEMPLE_CENTRAL_CHAMBER_POT_6, logic->CanBreakPots() && (logic->SmallKeys(RR_SPIRIT_TEMPLE, 3) || (logic->SmallKeys(RR_SPIRIT_TEMPLE, 2) && ctx->GetOption(RSK_BOMBCHU_BAG) && logic->BombchuRefill() && ctx->GetOption(RSK_SHUFFLE_DUNGEON_ENTRANCES).Is(RO_DUNGEON_ENTRANCE_SHUFFLE_OFF)))),
LOCATION(RC_SPIRIT_TEMPLE_AFTER_SUN_BLOCK_POT_1, logic->CanBreakPots() && logic->SmallKeys(RR_SPIRIT_TEMPLE, 2)),
LOCATION(RC_SPIRIT_TEMPLE_AFTER_SUN_BLOCK_POT_2, logic->CanBreakPots() && logic->SmallKeys(RR_SPIRIT_TEMPLE, 2)),
LOCATION(RC_SPIRIT_TEMPLE_CENTRAL_CHAMBER_POT_1, logic->CanBreakPots() && logic->SmallKeys(RR_SPIRIT_TEMPLE, 2)),
LOCATION(RC_SPIRIT_TEMPLE_CENTRAL_CHAMBER_POT_2, logic->CanBreakPots() && logic->SmallKeys(RR_SPIRIT_TEMPLE, 2)),
LOCATION(RC_SPIRIT_TEMPLE_CENTRAL_CHAMBER_POT_3, logic->CanBreakPots() && logic->SmallKeys(RR_SPIRIT_TEMPLE, 2)),
LOCATION(RC_SPIRIT_TEMPLE_CENTRAL_CHAMBER_POT_4, logic->CanBreakPots() && logic->SmallKeys(RR_SPIRIT_TEMPLE, 2)),
LOCATION(RC_SPIRIT_TEMPLE_CENTRAL_CHAMBER_POT_5, logic->CanBreakPots() && logic->SmallKeys(RR_SPIRIT_TEMPLE, 2)),
LOCATION(RC_SPIRIT_TEMPLE_CENTRAL_CHAMBER_POT_6, logic->CanBreakPots() && logic->SmallKeys(RR_SPIRIT_TEMPLE, 2)),
}, {
//Exits
Entrance(RR_SPIRIT_TEMPLE_OUTDOOR_HANDS, []{return logic->CanJumpslashExceptHammer() || logic->HasExplosives();}),

View file

@ -49,15 +49,26 @@ void RegionTable_Init_GerudoFortress() {
EventAccess(&logic->GtG_GateOpen, []{return (logic->IsAdult && logic->HasItem(RG_GERUDO_MEMBERSHIP_CARD) && logic->HasItem(RG_CHILD_WALLET));}),
}, {}, {
//Exits
Entrance(RR_GERUDO_TRAINING_GROUND_ENTRYWAY, []{return logic->GtG_GateOpen && (logic->IsAdult || ctx->GetOption(RSK_SHUFFLE_DUNGEON_ENTRANCES));}),
Entrance(RR_GF_TO_GTG, []{return logic->GtG_GateOpen && (logic->IsAdult || ctx->GetOption(RSK_SHUFFLE_DUNGEON_ENTRANCES));}),
//Jail
Entrance(RR_GF_JAIL_WINDOW, []{return logic->CanUse(RG_HOOKSHOT);}),
Entrance(RR_GF_OUTSKIRTS, []{return true;}),
Entrance(RR_GF_NEAR_GROTTO, []{return logic->IsChild || logic->CanPassEnemy(RE_GERUDO_GUARD);}),
// RANDTODO: Add tricks for getting past the gerudo guarding the hba range
Entrance(RR_GF_ABOVE_GTG, []{return logic->IsChild || logic->CanPassEnemy(RE_GERUDO_GUARD);}),
Entrance(RR_GF_TOP_OF_UPPER_VINES, []{return logic->HasItem(RG_GERUDO_MEMBERSHIP_CARD) && logic->CanUse(RG_LONGSHOT);}),
Entrance(RR_GF_HBA_RANGE, []{return logic->IsChild || logic->HasItem(RG_GERUDO_MEMBERSHIP_CARD);}),
});
areaTable[RR_GF_TO_GTG] = Region("GF to GTG", SCENE_GERUDOS_FORTRESS, {}, {}, {
Entrance(RR_GERUDO_TRAINING_GROUND_ENTRYWAY, []{return true;}),
});
// Split out to handle adult being immediately captured without card
areaTable[RR_GF_EXITING_GTG] = Region("GF Exiting GTG", SCENE_GERUDOS_FORTRESS, {}, {}, {
Entrance(RR_GF_OUTSIDE_GTG, []{return logic->IsChild || logic->HasItem(RG_GERUDO_MEMBERSHIP_CARD);}),
Entrance(RR_GF_JAIL_WINDOW, []{return logic->CanUse(RG_HOOKSHOT);}),
Entrance(RR_GF_OUTSKIRTS, []{return true;}),
Entrance(RR_GF_NEAR_GROTTO, []{return logic->IsChild || logic->CanPassEnemy(RE_GERUDO_GUARD);}),
// RANDTODO: Add tricks for getting past the gerudo guarding the hba range
Entrance(RR_GF_ABOVE_GTG, []{return logic->IsChild || logic->CanPassEnemy(RE_GERUDO_GUARD);}),
Entrance(RR_GF_TOP_OF_UPPER_VINES, []{return logic->HasItem(RG_GERUDO_MEMBERSHIP_CARD) && logic->CanUse(RG_LONGSHOT);}),
Entrance(RR_GF_HBA_RANGE, []{return logic->IsChild || logic->HasItem(RG_GERUDO_MEMBERSHIP_CARD);}),
});
#pragma endregion
@ -123,6 +134,7 @@ void RegionTable_Init_GerudoFortress() {
Entrance(RR_GF_TOP_OF_LOWER_VINES, []{return true;}),
Entrance(RR_GF_SLOPED_ROOF, []{return logic->IsAdult && logic->CanUse(RG_HOVER_BOOTS);}),
Entrance(RR_GF_TOP_OF_UPPER_VINES, []{return true /* logic->CanClimb() */;}),
Entrance(RR_GF_TO_GTG, []{return logic->IsAdult && ctx->GetTrickOption(RT_GF_LEDGE_CLIP_INTO_GTG).Get();}),
});
areaTable[RR_GF_TOP_OF_UPPER_VINES] = Region("GF Top of Upper Vines", SCENE_GERUDOS_FORTRESS, {}, {

View file

@ -63,7 +63,7 @@ void RegionTable_Init_GoronCity() {
EventAccess(&logic->GCWoodsWarpOpen, []{return logic->BlastOrSmash() || logic->CanUse(RG_DINS_FIRE);}),
}, {}, {
//Exits
Entrance(RR_GORON_CITY, []{return logic->CanLeaveForest() && logic->GCWoodsWarpOpen;}),
Entrance(RR_GORON_CITY, []{return logic->GCWoodsWarpOpen;}),
Entrance(RR_THE_LOST_WOODS, []{return true;}),
});

View file

@ -10,6 +10,7 @@ void RegionTable_Init_Graveyard() {
EventAccess(&logic->ButterflyFairy, []{return 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))),

View file

@ -8,6 +8,7 @@ void RegionTable_Init_HyruleField() {
areaTable[RR_HYRULE_FIELD] = Region("Hyrule Field", SCENE_HYRULE_FIELD, {
//Events
EventAccess(&logic->BigPoeKill, []{return logic->HasBottle() && logic->CanUse(RG_FAIRY_BOW) && (logic->CanUse(RG_EPONA) || ctx->GetTrickOption(RT_HF_BIG_POE_WITHOUT_EPONA));}),
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)),

View file

@ -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)),

View file

@ -13,7 +13,7 @@ void RegionTable_Init_KokiriForest() {
}, {
//Locations
LOCATION(RC_KF_KOKIRI_SWORD_CHEST, logic->IsChild),
LOCATION(RC_KF_GS_KNOW_IT_ALL_HOUSE, logic->IsChild && logic->CanAttack() && (/*TODO: HasNightStart ||*/ logic->CanLeaveForest() || logic->CanUse(RG_SUNS_SONG)) && logic->CanGetNightTimeGS()),
LOCATION(RC_KF_GS_KNOW_IT_ALL_HOUSE, logic->IsChild && logic->CanAttack() && logic->CanGetNightTimeGS()),
LOCATION(RC_KF_GS_BEAN_PATCH, logic->CanSpawnSoilSkull() && logic->CanAttack()),
LOCATION(RC_KF_GS_HOUSE_OF_TWINS, logic->IsAdult && (logic->HookshotOrBoomerang() || (ctx->GetTrickOption(RT_KF_ADULT_GS) && logic->CanUse(RG_HOVER_BOOTS))) && logic->CanGetNightTimeGS()),
LOCATION(RC_KF_BEAN_SPROUT_FAIRY_1, logic->IsChild && logic->CanUse(RG_MAGIC_BEAN) && logic->CanUse(RG_SONG_OF_STORMS)),

View file

@ -12,9 +12,10 @@ void RegionTable_Init_LostWoods() {
areaTable[RR_THE_LOST_WOODS] = Region("Lost Woods", SCENE_LOST_WOODS, {
//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)),
@ -56,8 +57,8 @@ void RegionTable_Init_LostWoods() {
//Exits
Entrance(RR_LW_FOREST_EXIT, []{return true;}),
Entrance(RR_GC_WOODS_WARP, []{return true;}),
Entrance(RR_LW_BRIDGE, []{return logic->CanLeaveForest() && ((logic->IsAdult && (CanPlantBean(RR_THE_LOST_WOODS) || ctx->GetTrickOption(RT_LW_BRIDGE))) || logic->CanUse(RG_HOVER_BOOTS) || logic->CanUse(RG_LONGSHOT));}),
Entrance(RR_ZR_FROM_SHORTCUT, []{return logic->CanLeaveForest() && (logic->HasItem(RG_SILVER_SCALE) || logic->CanUse(RG_IRON_BOOTS) || (ctx->GetTrickOption(RT_LOST_WOOD_NAVI_DIVE) && logic->IsChild && logic->HasItem(RG_BRONZE_SCALE) && logic->CanJumpslash()));}),
Entrance(RR_LW_BRIDGE, []{return (logic->IsAdult && (CanPlantBean(RR_THE_LOST_WOODS) || ctx->GetTrickOption(RT_LW_BRIDGE))) || logic->CanUse(RG_HOVER_BOOTS) || logic->CanUse(RG_LONGSHOT);}),
Entrance(RR_ZR_FROM_SHORTCUT, []{return logic->HasItem(RG_SILVER_SCALE) || logic->CanUse(RG_IRON_BOOTS) || (ctx->GetTrickOption(RT_LOST_WOOD_NAVI_DIVE) && logic->IsChild && logic->HasItem(RG_BRONZE_SCALE) && logic->CanJumpslash());}),
Entrance(RR_LW_BEYOND_MIDO, []{return logic->IsChild || logic->CanUse(RG_SARIAS_SONG) || ctx->GetTrickOption(RT_LW_MIDO_BACKFLIP);}),
Entrance(RR_LW_NEAR_SHORTCUTS_GROTTO, []{return Here(RR_THE_LOST_WOODS, []{return logic->BlastOrSmash();});}),
});
@ -110,8 +111,8 @@ void RegionTable_Init_LostWoods() {
areaTable[RR_DEKU_THEATER] = Region("Deku Theater", SCENE_GROTTOS, {}, {
//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;}),

View file

@ -138,8 +138,14 @@ void RegionTable_Init_Market() {
areaTable[RR_MARKET_MASK_SHOP] = Region("Market Mask Shop", SCENE_HAPPY_MASK_SHOP, {
//Events
EventAccess(&logic->SkullMask, []{return 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->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),

View file

@ -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;}),
});

View file

@ -1177,11 +1177,6 @@ bool Logic::CanStunDeku() {
return CanAttack() || CanUse(RG_NUTS) || CanReflectNuts();
}
bool Logic::CanLeaveForest() {
return ctx->GetOption(RSK_FOREST).IsNot(RO_CLOSED_FOREST_ON) || IsAdult || DekuTreeClear ||
ctx->GetOption(RSK_SHUFFLE_INTERIOR_ENTRANCES) || ctx->GetOption(RSK_SHUFFLE_OVERWORLD_ENTRANCES);
}
bool Logic::CallGossipFairyExceptSuns() {
return CanUse(RG_ZELDAS_LULLABY) || CanUse(RG_EPONAS_SONG) || CanUse(RG_SONG_OF_TIME);
}
@ -2350,9 +2345,12 @@ void Logic::Reset(bool resetSaveContext /*= true*/) {
// 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;

View file

@ -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;
@ -228,7 +231,6 @@ class Logic {
bool CanReflectNuts();
bool CanCutShrubs();
bool CanStunDeku();
bool CanLeaveForest();
bool CallGossipFairy();
bool CallGossipFairyExceptSuns();
uint8_t EffectiveHealth();

View file

@ -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] =

View file

@ -472,26 +472,72 @@ std::unordered_map<s16, s16> getItemIdToItemId = {
#pragma GCC optimize("O0")
#endif
bool Randomizer::SpoilerFileExists(const char* spoilerFileName) {
if (strcmp(spoilerFileName, "") != 0) {
std::ifstream spoilerFileStream(SohUtils::Sanitize(spoilerFileName));
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;
}
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();
if (contents.contains("version") &&
strcmp(std::string(contents["version"]).c_str(), (char*)gBuildVersion) == 0) {
return true;
} else {
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.");
}
}
}
return false;
// 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;
}
}
#ifdef _MSC_VER
#pragma optimize("", on)
@ -3713,7 +3759,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();

View file

@ -421,6 +421,8 @@ typedef enum {
RR_GF_OUTSKIRTS,
RR_GF_NEAR_GROTTO,
RR_GF_OUTSIDE_GTG,
RR_GF_TO_GTG,
RR_GF_EXITING_GTG,
RR_GF_ABOVE_GTG,
RR_GF_BOTTOM_OF_LOWER_VINES,
RR_GF_TOP_OF_LOWER_VINES,
@ -3579,6 +3581,7 @@ typedef enum {
RT_PASS_GUARDS_WITH_NOTHING,
RT_GF_JUMP,
RT_GF_WARRIOR_WITH_DIFFICULT_WEAPON,
RT_GF_LEDGE_CLIP_INTO_GTG,
RT_HW_BUNNY_CROSSING,
RT_HW_CROSSING,
RT_LENS_HW,
@ -5415,7 +5418,9 @@ 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_TH_BREAK_ROOM_FRONT_POT,
RHT_TH_BREAK_ROOM_BACK_POT,
RHT_TH_KITCHEN_POT_1,
@ -5433,16 +5438,19 @@ typedef enum {
RHT_TH_LEFT_MIDDLE_JAILED_POT,
RHT_TH_LEFTMOST_JAILED_POT,
RHT_POT_WASTELAND,
RHT_POT_MARKET,
RHT_POT_GUARD_HOUSE,
RHT_POT_POE_SHOP,
RHT_POT_ALLEY_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,
@ -5748,6 +5756,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,
@ -5997,6 +6006,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,

View file

@ -500,6 +500,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()) {
@ -592,7 +595,7 @@ void CheckTrackerLoadGame(int32_t fileNum) {
Rando::Context::GetInstance()->GetEntranceShuffler()->ApplyEntranceOverrides();
}
RecalculateAvailableChecks();
recalculateAvailable = true;
}
void CheckTrackerShopSlotChange(uint8_t cursorSlot, int16_t basePrice) {
@ -1005,6 +1008,11 @@ void CheckTrackerWindow::DrawElement() {
return;
}
if (recalculateAvailable) {
recalculateAvailable = false;
RecalculateAvailableChecks();
}
SceneID sceneId = SCENE_ID_MAX;
if (gPlayState != nullptr) {
sceneId = (SceneID)gPlayState->sceneNum;
@ -1603,10 +1611,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));
@ -2000,7 +2009,7 @@ void ImGuiDrawTwoColorPickerSection(const char* text, const char* cvarMainName,
}
void RecalculateAvailableChecks(RandomizerRegion startingRegion /* = RR_ROOT */) {
if (!enableAvailableChecks) {
if (!enableAvailableChecks || !GameInteractor::IsSaveLoaded()) {
return;
}
@ -2072,10 +2081,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);
@ -2156,10 +2161,7 @@ void CheckTrackerSettingsWindow::DrawElement() {
"with your current progress.")
.Color(THEME_COLOR))) {
enableAvailableChecks = CVarGetInteger(CVAR_TRACKER_CHECK("EnableAvailableChecks"), 0);
if (GameInteractor::IsSaveLoaded(true)) {
RecalculateAvailableChecks();
}
RecalculateAvailableChecks();
}
ImGui::EndDisabled();

View file

@ -1091,6 +1091,8 @@ DEFINE_RAND_INF(RAND_INF_MARKET_TREASURE_CHEST_GAME_KEY_5)
DEFINE_RAND_INF(RAND_INF_TH_ITEM_FROM_LEADER_OF_FORTRESS)
DEFINE_RAND_INF(RAND_INF_GF_GTG_GATE_PERMANENTLY_OPEN)
DEFINE_RAND_INF(RAND_INF_SPIRIT_SUN_ON_FLOOR_ON)
DEFINE_RAND_INF(RAND_INF_SPIRIT_BIG_MIRROR_STATUE_TURNED)
DEFINE_RAND_INF(RAND_INF_ZELDAS_LETTER)
DEFINE_RAND_INF(RAND_INF_WEIRD_EGG)

View file

@ -696,9 +696,9 @@ void DrawQuest(ItemTrackerItem item) {
bool hasQuestItem = HasQuestItem(item);
float iconSize = static_cast<float>(CVarGetInteger(CVAR_TRACKER_ITEM("IconSize"), 36));
ImGui::BeginGroup();
ImGui::Image(Ship::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName(
hasQuestItem && IsValidSaveFile() ? item.name : item.nameFaded),
ImVec2(iconSize, iconSize), ImVec2(0, 0), ImVec2(1, 1));
ImGui::ImageWithBg(Ship::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName(
hasQuestItem && IsValidSaveFile() ? item.name : item.nameFaded),
ImVec2(iconSize, iconSize), ImVec2(0, 0), ImVec2(1, 1));
if (item.id == QUEST_SKULL_TOKEN) {
DrawItemCount(item, false);
@ -1231,7 +1231,7 @@ void DrawItemsInACircle(std::vector<ItemTrackerItem> items) {
float radius = (iconSize + iconSpacing) * 2.0f;
for (int i = 0; i < items.size(); i++) {
float angle = static_cast<float>(i / items.size() * 2.0f * M_PI);
float angle = static_cast<float>(i) / items.size() * 2.0f * M_PIf;
float x = (radius / 2.0f) * cos(angle) + max.x / 2.0f;
float y = (radius / 2.0f) * sin(angle) + max.y / 2.0f;
ImGui::SetCursorPos(ImVec2(x - (CVarGetInteger(CVAR_TRACKER_ITEM("IconSize"), 36) - 8) / 2.0f, y + 4));

View file

@ -358,17 +358,6 @@ extern "C" void Randomizer_InitSaveFile() {
gSaveContext.sceneFlags[SCENE_WATER_TEMPLE].swch |= (1 << 0x15);
}
// Now handled on the fly.
// int openForest = Randomizer_GetSettingValue(RSK_FOREST);
// switch (openForest) {
// case RO_CLOSED_FOREST_OFF:
// Flags_SetEventChkInf(EVENTCHKINF_SHOWED_MIDO_SWORD_SHIELD);
// // Fallthrough
// case RO_CLOSED_FOREST_DEKU_ONLY:
// Flags_SetEventChkInf(EVENTCHKINF_OBTAINED_KOKIRI_EMERALD_DEKU_TREE_DEAD);
// break;
// }
int doorOfTime = Randomizer_GetSettingValue(RSK_DOOR_OF_TIME);
switch (doorOfTime) {
case RO_DOOROFTIME_OPEN:

View file

@ -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);
@ -590,6 +591,9 @@ void Settings::CreateOptions() {
OPT_TRICK(RT_GF_WARRIOR_WITH_DIFFICULT_WEAPON, RCQUEST_BOTH, RA_GERUDO_FORTRESS, { Tricks::Tag::NOVICE },
"Gerudo\'s Fortress Warriors with Difficult Weapons",
"Warriors can be defeated with Slingshot or Bombchus.");
OPT_TRICK(RT_GF_LEDGE_CLIP_INTO_GTG, RCQUEST_BOTH, RA_GERUDO_FORTRESS, { Tricks::Tag::NOVICE, Tricks::Tag::GLITCH },
"Ledge Clip into Training Ground",
"Adult Link can use a ledge clip to enter Gerudo Training Ground without Gerudo Card.");
// disabled for now, can't check for being able to use bunny hood & bunny hood speedup is currently completely
// decoupled from rando OPT_TRICK(RT_HW_BUNNY_CROSSING, RCQUEST_BOTH, RA_HAUNTED_WASTELAND, {Tricks::Tag::NOVICE},
// "Wasteland Crossing with Bunny Hood", "You can beat the quicksand by using the increased speed of the Bunny Hood.
@ -1173,6 +1177,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);
@ -1427,6 +1432,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],
@ -1826,10 +1832,9 @@ void Settings::UpdateOptionProperties() {
} else {
mOptionGroups[RSG_AREA_ACCESS_IMGUI].Enable();
// Starting Age - Disabled when Forest is set to Closed or under very specific conditions
if (CVarGetInteger(CVAR_RANDOMIZER_SETTING("ClosedForest"), RO_CLOSED_FOREST_ON) == RO_CLOSED_FOREST_ON ||
(CVarGetInteger(CVAR_RANDOMIZER_SETTING("DoorOfTime"), RO_DOOROFTIME_CLOSED) == RO_DOOROFTIME_CLOSED &&
CVarGetInteger(CVAR_RANDOMIZER_SETTING("ShuffleOcarinas"), RO_GENERIC_OFF) ==
RO_GENERIC_OFF)) /* closed door of time with ocarina shuffle off */ {
if (CVarGetInteger(CVAR_RANDOMIZER_SETTING("DoorOfTime"), RO_DOOROFTIME_CLOSED) == RO_DOOROFTIME_CLOSED &&
CVarGetInteger(CVAR_RANDOMIZER_SETTING("ShuffleOcarinas"), RO_GENERIC_OFF) ==
RO_GENERIC_OFF) /* closed door of time with ocarina shuffle off */ {
mOptions[RSK_STARTING_AGE].Disable(
"This option is disabled due to other options making the game unbeatable.");
} else {
@ -2526,8 +2531,7 @@ void Context::FinalizeSettings(const std::set<RandomizerCheck>& excludedLocation
}
// With certain access settings, the seed is only beatable if Starting Age is set to Child.
if (mOptions[RSK_FOREST].Is(RO_CLOSED_FOREST_ON) ||
(mOptions[RSK_DOOR_OF_TIME].Is(RO_DOOROFTIME_CLOSED) && !mOptions[RSK_SHUFFLE_OCARINA])) {
if (mOptions[RSK_DOOR_OF_TIME].Is(RO_DOOROFTIME_CLOSED) && !mOptions[RSK_SHUFFLE_OCARINA]) {
mOptions[RSK_STARTING_AGE].Set(RO_AGE_CHILD);
}
@ -2841,13 +2845,6 @@ void Context::FinalizeSettings(const std::set<RandomizerCheck>& excludedLocation
mOptions[RSK_MIX_GROTTO_ENTRANCES].Set(RO_GENERIC_OFF);
}
if (mOptions[RSK_FOREST].Is(RO_CLOSED_FOREST_ON) &&
(mOptions[RSK_SHUFFLE_INTERIOR_ENTRANCES].Is(RO_INTERIOR_ENTRANCE_SHUFFLE_ALL) ||
mOptions[RSK_SHUFFLE_OVERWORLD_ENTRANCES] || mOptions[RSK_SHUFFLE_OVERWORLD_SPAWNS] ||
mOptions[RSK_DECOUPLED_ENTRANCES] || mOptions[RSK_MIXED_ENTRANCE_POOLS])) {
mOptions[RSK_FOREST].Set(RO_CLOSED_FOREST_DEKU_ONLY);
}
if (mOptions[RSK_STARTING_AGE].Is(RO_AGE_RANDOM)) {
if (const uint32_t choice = Random(0, 2); choice == 0) {
mOptions[RSK_SELECTED_STARTING_AGE].Set(RO_AGE_CHILD);

View file

@ -9,6 +9,7 @@ extern "C" {
#include "src/overlays/actors/ovl_En_Wonder_Talk2/z_en_wonder_talk2.h"
#include "src/overlays/actors/ovl_Elf_Msg/z_elf_msg.h"
#include "src/overlays/actors/ovl_Obj_Switch/z_obj_switch.h"
#include "src/overlays/actors/ovl_Obj_Lightswitch/z_obj_lightswitch.h"
#include "src/overlays/actors/ovl_Bg_Bdan_Switch/z_bg_bdan_switch.h"
#include "src/overlays/actors/ovl_Bg_Treemouth/z_bg_treemouth.h"
#include "src/overlays/actors/ovl_En_Owl/z_en_owl.h"
@ -25,11 +26,13 @@ extern "C" {
#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"
#include "src/overlays/actors/ovl_Bg_Spot06_Objects/z_bg_spot06_objects.h"
#include "src/overlays/actors/ovl_Bg_Hidan_Kousi/z_bg_hidan_kousi.h"
#include "src/overlays/actors/ovl_Bg_Jya_Bombchuiwa/z_bg_jya_bombchuiwa.h"
#include "src/overlays/actors/ovl_Bg_Dy_Yoseizo/z_bg_dy_yoseizo.h"
#include "src/overlays/actors/ovl_En_Dnt_Demo/z_en_dnt_demo.h"
#include "src/overlays/actors/ovl_En_Po_Sisters/z_en_po_sisters.h"
@ -48,6 +51,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);
}
void EnMa1_EndTeachSong(EnMa1* enMa1, PlayState* play) {
@ -868,6 +875,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;
@ -933,6 +942,39 @@ void TimeSaverOnActorInitHandler(void* actorRef) {
});
}
if (actor->id == ACTOR_EN_JJ && !IS_RANDO) {
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);
@ -1386,14 +1428,35 @@ void TimeSaverRegisterHooks() {
});
}
void RegisterSkipWaterTempleGateDelay() {
void RegisterSkipTimerDelay() {
// Skip Water Temple gate delay
COND_ID_HOOK(OnActorUpdate, ACTOR_BG_SPOT06_OBJECTS,
CVarGetInteger(CVAR_ENHANCEMENT("TimeSavers.SkipMiscInteractions"), IS_RANDO), [](void* actor) {
BgSpot06Objects* spot06 = static_cast<BgSpot06Objects*>(actor);
auto spot06 = static_cast<BgSpot06Objects*>(actor);
if (spot06->dyna.actor.params == 0) {
spot06->timer = 0;
}
})
});
// Skip Spirit Sun on Floor activation delay
COND_ID_HOOK(OnActorUpdate, ACTOR_BG_JYA_BOMBCHUIWA,
CVarGetInteger(CVAR_ENHANCEMENT("TimeSavers.SkipMiscInteractions"), IS_RANDO), [](void* actor) {
auto jya = static_cast<BgJyaBombchuiwa*>(actor);
if (!(jya->drawFlags & 4) && jya->timer > 0 && jya->timer < 9) {
jya->timer = 9;
}
});
// Skip Spirit Sun on Floor & Sun on Block activation delay
COND_ID_HOOK(OnActorUpdate, ACTOR_OBJ_LIGHTSWITCH,
CVarGetInteger(CVAR_ENHANCEMENT("TimeSavers.SkipMiscInteractions"), IS_RANDO), [](void* actor) {
if (gPlayState->sceneNum == SCENE_SPIRIT_TEMPLE &&
(gPlayState->roomCtx.curRoom.num == 4 || gPlayState->roomCtx.curRoom.num == 8)) {
auto sun = static_cast<ObjLightswitch*>(actor);
sun->toggleDelay = 0;
}
});
}
static RegisterShipInitFunc skipWaterTempleGateDelay(RegisterSkipWaterTempleGateDelay);
static RegisterShipInitFunc skipTimerDelay(RegisterSkipTimerDelay,
{ CVAR_ENHANCEMENT("TimeSavers.SkipMiscInteractions"), "IS_RANDO" });

View file

@ -1,12 +1,11 @@
#include <vector>
#include <fstream>
#include <filesystem>
#include "TimeSplits.h"
#include "soh/Enhancements/gameplaystats.h"
#include "soh/SaveManager.h"
#include "soh/util.h"
#include <vector>
#include "include/z64item.h"
#include <fstream>
#include <filesystem>
#include "soh/OTRGlobals.h"
#include "soh/Enhancements/game-interactor/GameInteractor.h"
@ -17,6 +16,7 @@
#include "soh/SohGui/UIWidgets.hpp"
extern "C" {
#include "z64item.h"
extern SaveContext gSaveContext;
extern PlayState* gPlayState;
}

View file

@ -3,17 +3,6 @@
#define TIMESPLITS_H
#include <stdint.h>
#ifdef __cplusplus
extern "C" {
#endif
#ifdef __cplusplus
}
#endif
#endif // TIMESPLITS_H
#include <libultraship/libultraship.h>
#ifdef __cplusplus
@ -66,3 +55,5 @@ typedef struct {
} SplitObject;
#endif
#endif // TIMESPLITS_H

View file

@ -370,9 +370,16 @@ void RegisterOnKaleidoscopeUpdateHook() {
auto translation = GetParameritizedText("magic", TEXT_BANK_KALEIDO, arg);
SpeechSynthesizer::Instance->Speak(translation.c_str(), GetLanguageCode());
} else if (CHECK_BTN_ALL(input->press.button, BTN_DDOWN)) {
snprintf(arg, sizeof(arg), "%d", gSaveContext.rupees);
auto translation = GetParameritizedText("rupees", TEXT_BANK_KALEIDO, arg);
SpeechSynthesizer::Instance->Speak(translation.c_str(), GetLanguageCode());
if (gPlayState->sceneNum >= SCENE_FOREST_TEMPLE && gPlayState->sceneNum <= SCENE_INSIDE_GANONS_CASTLE) {
snprintf(arg, sizeof(arg), "%d",
std::max(gSaveContext.inventory.dungeonKeys[gPlayState->sceneNum], (s8)0));
auto translation = GetParameritizedText("keys", TEXT_BANK_KALEIDO, arg);
SpeechSynthesizer::Instance->Speak(translation.c_str(), GetLanguageCode());
} else {
snprintf(arg, sizeof(arg), "%d", gSaveContext.rupees);
auto translation = GetParameritizedText("rupees", TEXT_BANK_KALEIDO, arg);
SpeechSynthesizer::Instance->Speak(translation.c_str(), GetLanguageCode());
}
} else if (CHECK_BTN_ALL(input->press.button, BTN_DRIGHT)) {
// TODO: announce timer?
}

View file

@ -136,9 +136,11 @@ void CrowdControl::EmitMessage(uint32_t eventId, long timeRemaining, EffectResul
CrowdControl::EffectResult CrowdControl::ExecuteEffect(Effect* effect) {
GameInteractionEffectQueryResult giResult;
if (effect->category == kEffectCatSpawnEnemy) {
giResult = GameInteractor::RawAction::SpawnEnemyWithOffset(effect->spawnParams[0], effect->spawnParams[1]);
giResult = GameInteractor::RawAction::SpawnEnemyWithOffset(effect->spawnParams[0], effect->spawnParams[1],
effect->viewerName);
} else if (effect->category == kEffectCatSpawnActor) {
giResult = GameInteractor::RawAction::SpawnActor(effect->spawnParams[0], effect->spawnParams[1]);
giResult =
GameInteractor::RawAction::SpawnActor(effect->spawnParams[0], effect->spawnParams[1], effect->viewerName);
} else {
giResult = GameInteractor::ApplyEffect(effect->giEffect);
}
@ -185,6 +187,7 @@ CrowdControl::Effect* CrowdControl::ParseMessage(nlohmann::json dataReceived) {
Effect* effect = new Effect();
effect->lastExecutionResult = EffectResult::Initiate;
effect->id = dataReceived["id"];
effect->viewerName = dataReceived["viewer"];
auto parameters = dataReceived["parameters"];
uint32_t receivedParameter = 0;
auto effectName = dataReceived["code"].get<std::string>();
@ -301,13 +304,13 @@ CrowdControl::Effect* CrowdControl::ParseMessage(nlohmann::json dataReceived) {
case kEffectIncreaseSpeed:
effect->category = kEffectCatSpeed;
effect->timeRemaining = 30000;
effect->giEffect = new GameInteractionEffect::ModifyRunSpeedModifier();
effect->giEffect = new GameInteractionEffect::ModifyMovementSpeedMultiplier();
dynamic_cast<ParameterizedGameInteractionEffect*>(effect->giEffect)->parameters[0] = 2;
break;
case kEffectDecreaseSpeed:
effect->category = kEffectCatSpeed;
effect->timeRemaining = 30000;
effect->giEffect = new GameInteractionEffect::ModifyRunSpeedModifier();
effect->giEffect = new GameInteractionEffect::ModifyMovementSpeedMultiplier();
dynamic_cast<ParameterizedGameInteractionEffect*>(effect->giEffect)->parameters[0] = -2;
break;
case kEffectLowGravity:
@ -620,147 +623,6 @@ CrowdControl::Effect* CrowdControl::ParseMessage(nlohmann::json dataReceived) {
dynamic_cast<ParameterizedGameInteractionEffect*>(effect->giEffect)->parameters[0] = GI_TP_DEST_PRELUDE;
break;
// Tunic Color (Bidding War)
case kEffectTunicRed:
effect->giEffect = new GameInteractionEffect::SetCosmeticsColor();
dynamic_cast<ParameterizedGameInteractionEffect*>(effect->giEffect)->parameters[0] = GI_COSMETICS_TUNICS;
dynamic_cast<ParameterizedGameInteractionEffect*>(effect->giEffect)->parameters[1] = GI_COLOR_RED;
break;
case kEffectTunicGreen:
effect->giEffect = new GameInteractionEffect::SetCosmeticsColor();
dynamic_cast<ParameterizedGameInteractionEffect*>(effect->giEffect)->parameters[0] = GI_COSMETICS_TUNICS;
dynamic_cast<ParameterizedGameInteractionEffect*>(effect->giEffect)->parameters[1] = GI_COLOR_GREEN;
break;
case kEffectTunicBlue:
effect->giEffect = new GameInteractionEffect::SetCosmeticsColor();
dynamic_cast<ParameterizedGameInteractionEffect*>(effect->giEffect)->parameters[0] = GI_COSMETICS_TUNICS;
dynamic_cast<ParameterizedGameInteractionEffect*>(effect->giEffect)->parameters[1] = GI_COLOR_BLUE;
break;
case kEffectTunicOrange:
effect->giEffect = new GameInteractionEffect::SetCosmeticsColor();
dynamic_cast<ParameterizedGameInteractionEffect*>(effect->giEffect)->parameters[0] = GI_COSMETICS_TUNICS;
dynamic_cast<ParameterizedGameInteractionEffect*>(effect->giEffect)->parameters[1] = GI_COLOR_ORANGE;
break;
case kEffectTunicYellow:
effect->giEffect = new GameInteractionEffect::SetCosmeticsColor();
dynamic_cast<ParameterizedGameInteractionEffect*>(effect->giEffect)->parameters[0] = GI_COSMETICS_TUNICS;
dynamic_cast<ParameterizedGameInteractionEffect*>(effect->giEffect)->parameters[1] = GI_COLOR_YELLOW;
break;
case kEffectTunicPurple:
effect->giEffect = new GameInteractionEffect::SetCosmeticsColor();
dynamic_cast<ParameterizedGameInteractionEffect*>(effect->giEffect)->parameters[0] = GI_COSMETICS_TUNICS;
dynamic_cast<ParameterizedGameInteractionEffect*>(effect->giEffect)->parameters[1] = GI_COLOR_PURPLE;
break;
case kEffectTunicPink:
effect->giEffect = new GameInteractionEffect::SetCosmeticsColor();
dynamic_cast<ParameterizedGameInteractionEffect*>(effect->giEffect)->parameters[0] = GI_COSMETICS_TUNICS;
dynamic_cast<ParameterizedGameInteractionEffect*>(effect->giEffect)->parameters[1] = GI_COLOR_PINK;
break;
case kEffectTunicBrown:
effect->giEffect = new GameInteractionEffect::SetCosmeticsColor();
dynamic_cast<ParameterizedGameInteractionEffect*>(effect->giEffect)->parameters[0] = GI_COSMETICS_TUNICS;
dynamic_cast<ParameterizedGameInteractionEffect*>(effect->giEffect)->parameters[1] = GI_COLOR_BROWN;
break;
case kEffectTunicBlack:
effect->giEffect = new GameInteractionEffect::SetCosmeticsColor();
dynamic_cast<ParameterizedGameInteractionEffect*>(effect->giEffect)->parameters[0] = GI_COSMETICS_TUNICS;
dynamic_cast<ParameterizedGameInteractionEffect*>(effect->giEffect)->parameters[1] = GI_COLOR_BLACK;
break;
// Navi Color (Bidding War)
case kEffectNaviRed:
effect->giEffect = new GameInteractionEffect::SetCosmeticsColor();
dynamic_cast<ParameterizedGameInteractionEffect*>(effect->giEffect)->parameters[0] = GI_COSMETICS_NAVI;
dynamic_cast<ParameterizedGameInteractionEffect*>(effect->giEffect)->parameters[1] = GI_COLOR_RED;
break;
case kEffectNaviGreen:
effect->giEffect = new GameInteractionEffect::SetCosmeticsColor();
dynamic_cast<ParameterizedGameInteractionEffect*>(effect->giEffect)->parameters[0] = GI_COSMETICS_NAVI;
dynamic_cast<ParameterizedGameInteractionEffect*>(effect->giEffect)->parameters[1] = GI_COLOR_GREEN;
break;
case kEffectNaviBlue:
effect->giEffect = new GameInteractionEffect::SetCosmeticsColor();
dynamic_cast<ParameterizedGameInteractionEffect*>(effect->giEffect)->parameters[0] = GI_COSMETICS_NAVI;
dynamic_cast<ParameterizedGameInteractionEffect*>(effect->giEffect)->parameters[1] = GI_COLOR_BLUE;
break;
case kEffectNaviOrange:
effect->giEffect = new GameInteractionEffect::SetCosmeticsColor();
dynamic_cast<ParameterizedGameInteractionEffect*>(effect->giEffect)->parameters[0] = GI_COSMETICS_NAVI;
dynamic_cast<ParameterizedGameInteractionEffect*>(effect->giEffect)->parameters[1] = GI_COLOR_ORANGE;
break;
case kEffectNaviYellow:
effect->giEffect = new GameInteractionEffect::SetCosmeticsColor();
dynamic_cast<ParameterizedGameInteractionEffect*>(effect->giEffect)->parameters[0] = GI_COSMETICS_NAVI;
dynamic_cast<ParameterizedGameInteractionEffect*>(effect->giEffect)->parameters[1] = GI_COLOR_YELLOW;
break;
case kEffectNaviPurple:
effect->giEffect = new GameInteractionEffect::SetCosmeticsColor();
dynamic_cast<ParameterizedGameInteractionEffect*>(effect->giEffect)->parameters[0] = GI_COSMETICS_NAVI;
dynamic_cast<ParameterizedGameInteractionEffect*>(effect->giEffect)->parameters[1] = GI_COLOR_PURPLE;
break;
case kEffectNaviPink:
effect->giEffect = new GameInteractionEffect::SetCosmeticsColor();
dynamic_cast<ParameterizedGameInteractionEffect*>(effect->giEffect)->parameters[0] = GI_COSMETICS_NAVI;
dynamic_cast<ParameterizedGameInteractionEffect*>(effect->giEffect)->parameters[1] = GI_COLOR_PINK;
break;
case kEffectNaviBrown:
effect->giEffect = new GameInteractionEffect::SetCosmeticsColor();
dynamic_cast<ParameterizedGameInteractionEffect*>(effect->giEffect)->parameters[0] = GI_COSMETICS_NAVI;
dynamic_cast<ParameterizedGameInteractionEffect*>(effect->giEffect)->parameters[1] = GI_COLOR_BROWN;
break;
case kEffectNaviBlack:
effect->giEffect = new GameInteractionEffect::SetCosmeticsColor();
dynamic_cast<ParameterizedGameInteractionEffect*>(effect->giEffect)->parameters[0] = GI_COSMETICS_NAVI;
dynamic_cast<ParameterizedGameInteractionEffect*>(effect->giEffect)->parameters[1] = GI_COLOR_BLACK;
break;
// Link's Hair Color (Bidding War)
case kEffectHairRed:
effect->giEffect = new GameInteractionEffect::SetCosmeticsColor();
dynamic_cast<ParameterizedGameInteractionEffect*>(effect->giEffect)->parameters[0] = GI_COSMETICS_HAIR;
dynamic_cast<ParameterizedGameInteractionEffect*>(effect->giEffect)->parameters[1] = GI_COLOR_RED;
break;
case kEffectHairGreen:
effect->giEffect = new GameInteractionEffect::SetCosmeticsColor();
dynamic_cast<ParameterizedGameInteractionEffect*>(effect->giEffect)->parameters[0] = GI_COSMETICS_HAIR;
dynamic_cast<ParameterizedGameInteractionEffect*>(effect->giEffect)->parameters[1] = GI_COLOR_GREEN;
break;
case kEffectHairBlue:
effect->giEffect = new GameInteractionEffect::SetCosmeticsColor();
dynamic_cast<ParameterizedGameInteractionEffect*>(effect->giEffect)->parameters[0] = GI_COSMETICS_HAIR;
dynamic_cast<ParameterizedGameInteractionEffect*>(effect->giEffect)->parameters[1] = GI_COLOR_BLUE;
break;
case kEffectHairOrange:
effect->giEffect = new GameInteractionEffect::SetCosmeticsColor();
dynamic_cast<ParameterizedGameInteractionEffect*>(effect->giEffect)->parameters[0] = GI_COSMETICS_HAIR;
dynamic_cast<ParameterizedGameInteractionEffect*>(effect->giEffect)->parameters[1] = GI_COLOR_ORANGE;
break;
case kEffectHairYellow:
effect->giEffect = new GameInteractionEffect::SetCosmeticsColor();
dynamic_cast<ParameterizedGameInteractionEffect*>(effect->giEffect)->parameters[0] = GI_COSMETICS_HAIR;
dynamic_cast<ParameterizedGameInteractionEffect*>(effect->giEffect)->parameters[1] = GI_COLOR_YELLOW;
break;
case kEffectHairPurple:
effect->giEffect = new GameInteractionEffect::SetCosmeticsColor();
dynamic_cast<ParameterizedGameInteractionEffect*>(effect->giEffect)->parameters[0] = GI_COSMETICS_HAIR;
dynamic_cast<ParameterizedGameInteractionEffect*>(effect->giEffect)->parameters[1] = GI_COLOR_PURPLE;
break;
case kEffectHairPink:
effect->giEffect = new GameInteractionEffect::SetCosmeticsColor();
dynamic_cast<ParameterizedGameInteractionEffect*>(effect->giEffect)->parameters[0] = GI_COSMETICS_HAIR;
dynamic_cast<ParameterizedGameInteractionEffect*>(effect->giEffect)->parameters[1] = GI_COLOR_PINK;
break;
case kEffectHairBrown:
effect->giEffect = new GameInteractionEffect::SetCosmeticsColor();
dynamic_cast<ParameterizedGameInteractionEffect*>(effect->giEffect)->parameters[0] = GI_COSMETICS_HAIR;
dynamic_cast<ParameterizedGameInteractionEffect*>(effect->giEffect)->parameters[1] = GI_COLOR_BROWN;
break;
case kEffectHairBlack:
effect->giEffect = new GameInteractionEffect::SetCosmeticsColor();
dynamic_cast<ParameterizedGameInteractionEffect*>(effect->giEffect)->parameters[0] = GI_COSMETICS_HAIR;
dynamic_cast<ParameterizedGameInteractionEffect*>(effect->giEffect)->parameters[1] = GI_COLOR_BLACK;
break;
default:
break;
}

View file

@ -56,6 +56,7 @@ class CrowdControl : public Network {
uint32_t category = 0;
long timeRemaining;
GameInteractionEffectBase* giEffect;
std::string viewerName;
// Metadata used while executing (only for timed effects)
bool isPaused;

View file

@ -124,50 +124,5 @@ public class ShipOfHarkinian : SimpleTCPPack<SimpleTCPServerConnector>
new("Requiem Destination", "tp_requiem") { Category = "Teleport Player", Price = 100, Description = "Teleport the player to Desert Colossus." },
new("Nocturne Destination", "tp_nocturne") { Category = "Teleport Player", Price = 100, Description = "Teleport the player to the Raveyard." },
new("Prelude Destination", "tp_prelude") { Category = "Teleport Player", Price = 100, Description = "Teleport the player to the Temple of Time." },
// Tunic Color (Bidding War)
new("Tunic Color", "tunic", ItemKind.BidWar)
{
Parameters = new ParameterDef("Color", "color_tunic_param",
new Parameter("Red", "red"),
new Parameter("Green", "green"),
new Parameter("Blue", "blue"),
new Parameter("Orange", "orange"),
new Parameter("Yellow", "yellow"),
new Parameter("Purple", "purple"),
new Parameter("Pink", "pink"),
new Parameter("Brown", "brown"),
new Parameter("Black", "black"))
},
// Navi Color (Bidding War)
new("Navi Color", "navi", ItemKind.BidWar)
{
Parameters = new ParameterDef("Color", "color_navi_param",
new Parameter("Red", "red"),
new Parameter("Green", "green"),
new Parameter("Blue", "blue"),
new Parameter("Orange", "orange"),
new Parameter("Yellow", "yellow"),
new Parameter("Purple", "purple"),
new Parameter("Pink", "pink"),
new Parameter("Brown", "brown"),
new Parameter("Black", "black"))
},
// Link's Hair Color (Bidding War)
new("Link's Hair Color", "hair", ItemKind.BidWar)
{
Parameters = new ParameterDef("Color", "color_hair_param",
new Parameter("Red", "red"),
new Parameter("Green", "green"),
new Parameter("Blue", "blue"),
new Parameter("Orange", "orange"),
new Parameter("Yellow", "yellow"),
new Parameter("Purple", "purple"),
new Parameter("Pink", "pink"),
new Parameter("Brown", "brown"),
new Parameter("Black", "black"))
}
};
}

View file

@ -242,8 +242,8 @@ GameInteractionEffectBase* Sail::EffectFromJson(nlohmann::json payload) {
effect->parameters[0] = payload["parameters"][0].get<int32_t>();
}
return effect;
} else if (name == "ModifyRunSpeedModifier") {
auto effect = new GameInteractionEffect::ModifyRunSpeedModifier();
} else if (name == "ModifyMovementSpeedMultiplier") {
auto effect = new GameInteractionEffect::ModifyMovementSpeedMultiplier();
if (payload.contains("parameters")) {
effect->parameters[0] = payload["parameters"][0].get<int32_t>();
}
@ -282,13 +282,6 @@ GameInteractionEffectBase* Sail::EffectFromJson(nlohmann::json payload) {
return effect;
} else if (name == "SetCollisionViewer") {
return new GameInteractionEffect::SetCollisionViewer();
} else if (name == "SetCosmeticsColor") {
auto effect = new GameInteractionEffect::SetCosmeticsColor();
if (payload.contains("parameters")) {
effect->parameters[0] = payload["parameters"][0].get<int32_t>();
effect->parameters[1] = payload["parameters"][1].get<int32_t>();
}
return effect;
} else if (name == "RandomizeCosmetics") {
return new GameInteractionEffect::RandomizeCosmetics();
} else if (name == "PressButton") {

View file

@ -2331,7 +2331,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)) {

View file

@ -180,6 +180,9 @@ void SaveManager::LoadRandomizer() {
// all ItemLocations is 0 anyway.
randoContext->GetItemLocation(i)->SetCustomPrice(price);
}
bool excluded = false;
SaveManager::Instance->LoadData("excluded", excluded, false);
randoContext->GetItemLocation(i)->SetExcludedOption(excluded);
});
});
@ -271,6 +274,9 @@ void SaveManager::SaveRandomizer(SaveContext* saveContext, int sectionID, bool f
randoContext->GetItemOverride(i).GetTrickName().GetFrench());
});
}
if (randoContext->GetItemLocation(i)->IsExcluded()) {
SaveManager::Instance->SaveData("excluded", true);
}
if (randoContext->GetItemLocation(i)->HasCustomPrice()) {
SaveManager::Instance->SaveData("price", randoContext->GetItemLocation(i)->GetPrice());
}

View file

@ -27,7 +27,6 @@ void disableBetaQuest();
#endif
namespace SohGui {
static std::unordered_map<int32_t, const char*> languages = {
{ LANGUAGE_ENG, "English" },
{ LANGUAGE_GER, "German" },
@ -35,164 +34,6 @@ static std::unordered_map<int32_t, const char*> languages = {
{ LANGUAGE_JPN, "Japanese" },
};
static const std::unordered_map<int32_t, const char*> menuThemeOptions = {
{ UIWidgets::Colors::Red, "Red" },
{ UIWidgets::Colors::DarkRed, "Dark Red" },
{ UIWidgets::Colors::Orange, "Orange" },
{ UIWidgets::Colors::Green, "Green" },
{ UIWidgets::Colors::DarkGreen, "Dark Green" },
{ UIWidgets::Colors::LightBlue, "Light Blue" },
{ UIWidgets::Colors::Blue, "Blue" },
{ UIWidgets::Colors::DarkBlue, "Dark Blue" },
{ UIWidgets::Colors::Indigo, "Indigo" },
{ UIWidgets::Colors::Violet, "Violet" },
{ UIWidgets::Colors::Purple, "Purple" },
{ UIWidgets::Colors::Brown, "Brown" },
{ UIWidgets::Colors::Gray, "Gray" },
{ UIWidgets::Colors::DarkGray, "Dark Gray" },
};
static const std::unordered_map<int32_t, const char*> textureFilteringMap = {
{ Fast::FILTER_THREE_POINT, "Three-Point" },
{ Fast::FILTER_LINEAR, "Linear" },
{ Fast::FILTER_NONE, "None" },
};
static const std::unordered_map<int32_t, const char*> logLevels = {
{ DEBUG_LOG_TRACE, "Trace" }, { DEBUG_LOG_DEBUG, "Debug" }, { DEBUG_LOG_INFO, "Info" },
{ DEBUG_LOG_WARN, "Warn" }, { DEBUG_LOG_ERROR, "Error" }, { DEBUG_LOG_CRITICAL, "Critical" },
{ DEBUG_LOG_OFF, "Off" },
};
static const std::unordered_map<int32_t, const char*> notificationPosition = {
{ 0, "Top Left" }, { 1, "Top Right" }, { 2, "Bottom Left" }, { 3, "Bottom Right" }, { 4, "Hidden" },
};
static const std::unordered_map<int32_t, const char*> dekuStickCheat = {
{ DEKU_STICK_NORMAL, "Normal" },
{ DEKU_STICK_UNBREAKABLE, "Unbreakable" },
{ DEKU_STICK_UNBREAKABLE_AND_ALWAYS_ON_FIRE, "Unbreakable + Always on Fire" },
};
static const std::unordered_map<int32_t, const char*> skipForcedDialogOptions = {
{ FORCED_DIALOG_SKIP_NONE, "None" },
{ FORCED_DIALOG_SKIP_NAVI, "Navi" },
{ FORCED_DIALOG_SKIP_NPC, "NPCs" },
{ FORCED_DIALOG_SKIP_ALL, "All" },
};
static const std::unordered_map<int32_t, const char*> skipGetItemAnimationOptions = {
{ SGIA_DISABLED, "Disabled" },
{ SGIA_JUNK, "Junk Items" },
{ SGIA_ALL, "All Items" },
};
static const std::unordered_map<int32_t, const char*> chestStyleMatchesContentsOptions = {
{ CSMC_DISABLED, "Disabled" },
{ CSMC_BOTH, "Both" },
{ CSMC_TEXTURE, "Texture Only" },
{ CSMC_SIZE, "Size Only" },
};
static const std::unordered_map<int32_t, const char*> timeTravelOptions = {
{ TIME_TRAVEL_DISABLED, "Disabled" },
{ TIME_TRAVEL_OOT, "Ocarina of Time" },
{ TIME_TRAVEL_ANY, "Any Ocarina" },
};
static const std::unordered_map<int32_t, const char*> sleepingWaterfallOptions = {
{ WATERFALL_ALWAYS, "Always" },
{ WATERFALL_ONCE, "Once" },
{ WATERFALL_NEVER, "Never" },
};
static const std::unordered_map<int32_t, const char*> allPowers = {
{ DAMAGE_VANILLA, "Vanilla (1x)" }, { DAMAGE_DOUBLE, "Double (2x)" },
{ DAMAGE_QUADRUPLE, "Quadruple (4x)" }, { DAMAGE_OCTUPLE, "Octuple (8x)" },
{ DAMAGE_FOOLISH, "Foolish (16x)" }, { DAMAGE_RIDICULOUS, "Ridiculous (32x)" },
{ DAMAGE_MERCILESS, "Merciless (64x)" }, { DAMAGE_TORTURE, "Pure Torture (128x)" },
{ DAMAGE_OHKO, "OHKO (256x)" },
};
static const std::unordered_map<int32_t, const char*> subPowers = {
{ DAMAGE_VANILLA, "Vanilla (1x)" }, { DAMAGE_DOUBLE, "Double (2x)" },
{ DAMAGE_QUADRUPLE, "Quadruple (4x)" }, { DAMAGE_OCTUPLE, "Octuple (8x)" },
{ DAMAGE_FOOLISH, "Foolish (16x)" }, { DAMAGE_RIDICULOUS, "Ridiculous (32x)" },
{ DAMAGE_MERCILESS, "Merciless (64x)" }, { DAMAGE_TORTURE, "Pure Torture (128x)" },
};
static const std::unordered_map<int32_t, const char*> subSubPowers = {
{ DAMAGE_VANILLA, "Vanilla (1x)" }, { DAMAGE_DOUBLE, "Double (2x)" },
{ DAMAGE_QUADRUPLE, "Quadruple (4x)" }, { DAMAGE_OCTUPLE, "Octuple (8x)" },
{ DAMAGE_FOOLISH, "Foolish (16x)" }, { DAMAGE_RIDICULOUS, "Ridiculous (32x)" },
{ DAMAGE_MERCILESS, "Merciless (64x)" },
};
static const std::unordered_map<int32_t, const char*> bonkDamageValues = {
{ BONK_DAMAGE_NONE, "No Damage" }, { BONK_DAMAGE_QUARTER_HEART, "0.25 Hearts" },
{ BONK_DAMAGE_HALF_HEART, "0.5 Hearts" }, { BONK_DAMAGE_1_HEART, "1 Heart" },
{ BONK_DAMAGE_2_HEARTS, "2 Hearts" }, { BONK_DAMAGE_4_HEARTS, "4 Hearts" },
{ BONK_DAMAGE_8_HEARTS, "8 Hearts" }, { BONK_DAMAGE_OHKO, "OHKO" },
};
static const std::unordered_map<int32_t, const char*> dampeDropRates = {
{ DAMPE_NONE, "None" },
{ DAMPE_NORMAL, "Vanilla" },
{ DAMPE_JALAPENO, "Jalapeño" },
{ DAMPE_CHIPOTLE, "Serrano" },
{ DAMPE_SCOTCH_BONNET, "Habanero" },
{ DAMPE_GHOST_PEPPER, "Ghost Pepper" },
{ DAMPE_INFERNO, "Dampe's Inferno" },
};
static const std::unordered_map<int32_t, const char*> cursorAnywhereValues = {
{ PAUSE_ANY_CURSOR_RANDO_ONLY, "Only in Rando" },
{ PAUSE_ANY_CURSOR_ALWAYS_ON, "Always" },
{ PAUSE_ANY_CURSOR_ALWAYS_OFF, "Never" },
};
static const std::unordered_map<int32_t, const char*> swordToggleModes = {
{ SWORD_TOGGLE_NONE, "None" },
{ SWORD_TOGGLE_CHILD, "Child Toggle" },
{ SWORD_TOGGLE_BOTH_AGES, "Both Ages" },
};
static const std::unordered_map<int32_t, const char*> zFightingOptions = {
{ ZFIGHT_FIX_DISABLED, "Disabled" },
{ ZFIGHT_FIX_CONSISTENT_VANISH, "Consistent Vanish" },
{ ZFIGHT_FIX_NO_VANISH, "No Vanish" },
};
static const std::unordered_map<int32_t, const char*> mirroredWorldModes = {
{ MIRRORED_WORLD_OFF, "Disabled" },
{ MIRRORED_WORLD_ALWAYS, "Always" },
{ MIRRORED_WORLD_RANDOM, "Random" },
{ MIRRORED_WORLD_RANDOM_SEEDED, "Random (Seeded)" },
{ MIRRORED_WORLD_DUNGEONS_ALL, "Dungeons" },
{ MIRRORED_WORLD_DUNGEONS_VANILLA, "Dungeons (Vanilla)" },
{ MIRRORED_WORLD_DUNGEONS_MQ, "Dungeons (MQ)" },
{ MIRRORED_WORLD_DUNGEONS_RANDOM, "Dungeons Random" },
{ MIRRORED_WORLD_DUNGEONS_RANDOM_SEEDED, "Dungeons Random (Seeded)" },
};
static const std::unordered_map<int32_t, const char*> enemyRandomizerModes = {
{ ENEMY_RANDOMIZER_OFF, "Disabled" },
{ ENEMY_RANDOMIZER_RANDOM, "Random" },
{ ENEMY_RANDOMIZER_RANDOM_SEEDED, "Random (Seeded)" },
};
static const std::unordered_map<int32_t, const char*> debugSaveFileModes = {
{ 0, "Off" },
{ 1, "Vanilla" },
{ 2, "Maxed" },
};
static const std::unordered_map<int32_t, const char*> bootSequenceLabels = {
{ BOOTSEQUENCE_DEFAULT, "Default" },
{ BOOTSEQUENCE_AUTHENTIC, "Authentic" },
{ BOOTSEQUENCE_FILESELECT, "File Select" },
};
class SohMenu : public Ship::Menu {
public:
SohMenu(const std::string& consoleVariable, const std::string& name);

View file

@ -5,6 +5,18 @@ namespace SohGui {
extern std::shared_ptr<SohMenu> mSohMenu;
using namespace UIWidgets;
static const std::unordered_map<int32_t, const char*> logLevels = {
{ DEBUG_LOG_TRACE, "Trace" }, { DEBUG_LOG_DEBUG, "Debug" }, { DEBUG_LOG_INFO, "Info" },
{ DEBUG_LOG_WARN, "Warn" }, { DEBUG_LOG_ERROR, "Error" }, { DEBUG_LOG_CRITICAL, "Critical" },
{ DEBUG_LOG_OFF, "Off" },
};
static const std::unordered_map<int32_t, const char*> debugSaveFileModes = {
{ 0, "Off" },
{ 1, "Vanilla" },
{ 2, "Maxed" },
};
void SohMenu::AddMenuDevTools() {
// Add Dev Tools Menu
AddMenuEntry("Dev Tools", CVAR_SETTING("Menu.DevToolsSidebarSection"));

View file

@ -1,4 +1,4 @@
#include "SohMenu.h"
#include "SohMenu.h"
#include <soh/Enhancements/mods.h>
#include <soh/Enhancements/game-interactor/GameInteractor.h>
#include <soh/OTRGlobals.h>
@ -6,13 +6,12 @@
#include <soh/Enhancements/enemyrandomizer.h>
#include <soh/Enhancements/TimeDisplay/TimeDisplay.h>
#define CVAR_INT_SHIP_INIT(cvar, val) \
CVarSetInteger(cvar, val); \
ShipInit::Init(cvar);
static std::string comboboxTooltip = "";
bool isBetaQuestEnabled = false;
static std::unordered_map<int32_t, const char*> bunnyHoodEffectMap = {
{ BUNNY_HOOD_VANILLA, "Vanilla" },
{ BUNNY_HOOD_FAST, "Faster Run" },
{ BUNNY_HOOD_FAST_AND_JUMP, "Faster + Longer Jump" },
};
extern "C" {
void enableBetaQuest() {
@ -28,6 +27,119 @@ namespace SohGui {
extern std::shared_ptr<SohMenu> mSohMenu;
using namespace UIWidgets;
static std::unordered_map<int32_t, const char*> bunnyHoodEffectMap = {
{ BUNNY_HOOD_VANILLA, "Vanilla" },
{ BUNNY_HOOD_FAST, "Faster Run" },
{ BUNNY_HOOD_FAST_AND_JUMP, "Faster + Longer Jump" },
};
static const std::unordered_map<int32_t, const char*> dekuStickCheat = {
{ DEKU_STICK_NORMAL, "Normal" },
{ DEKU_STICK_UNBREAKABLE, "Unbreakable" },
{ DEKU_STICK_UNBREAKABLE_AND_ALWAYS_ON_FIRE, "Unbreakable + Always on Fire" },
};
static const std::unordered_map<int32_t, const char*> skipForcedDialogOptions = {
{ FORCED_DIALOG_SKIP_NONE, "None" },
{ FORCED_DIALOG_SKIP_NAVI, "Navi" },
{ FORCED_DIALOG_SKIP_NPC, "NPCs" },
{ FORCED_DIALOG_SKIP_ALL, "All" },
};
static const std::unordered_map<int32_t, const char*> chestStyleMatchesContentsOptions = {
{ CSMC_DISABLED, "Disabled" },
{ CSMC_BOTH, "Both" },
{ CSMC_TEXTURE, "Texture Only" },
{ CSMC_SIZE, "Size Only" },
};
static const std::unordered_map<int32_t, const char*> timeTravelOptions = {
{ TIME_TRAVEL_DISABLED, "Disabled" },
{ TIME_TRAVEL_OOT, "Ocarina of Time" },
{ TIME_TRAVEL_ANY, "Any Ocarina" },
};
static const std::unordered_map<int32_t, const char*> sleepingWaterfallOptions = {
{ WATERFALL_ALWAYS, "Always" },
{ WATERFALL_ONCE, "Once" },
{ WATERFALL_NEVER, "Never" },
};
static const std::unordered_map<int32_t, const char*> allPowers = {
{ DAMAGE_VANILLA, "Vanilla (1x)" }, { DAMAGE_DOUBLE, "Double (2x)" },
{ DAMAGE_QUADRUPLE, "Quadruple (4x)" }, { DAMAGE_OCTUPLE, "Octuple (8x)" },
{ DAMAGE_FOOLISH, "Foolish (16x)" }, { DAMAGE_RIDICULOUS, "Ridiculous (32x)" },
{ DAMAGE_MERCILESS, "Merciless (64x)" }, { DAMAGE_TORTURE, "Pure Torture (128x)" },
{ DAMAGE_OHKO, "OHKO (256x)" },
};
static const std::unordered_map<int32_t, const char*> subPowers = {
{ DAMAGE_VANILLA, "Vanilla (1x)" }, { DAMAGE_DOUBLE, "Double (2x)" },
{ DAMAGE_QUADRUPLE, "Quadruple (4x)" }, { DAMAGE_OCTUPLE, "Octuple (8x)" },
{ DAMAGE_FOOLISH, "Foolish (16x)" }, { DAMAGE_RIDICULOUS, "Ridiculous (32x)" },
{ DAMAGE_MERCILESS, "Merciless (64x)" }, { DAMAGE_TORTURE, "Pure Torture (128x)" },
};
static const std::unordered_map<int32_t, const char*> subSubPowers = {
{ DAMAGE_VANILLA, "Vanilla (1x)" }, { DAMAGE_DOUBLE, "Double (2x)" },
{ DAMAGE_QUADRUPLE, "Quadruple (4x)" }, { DAMAGE_OCTUPLE, "Octuple (8x)" },
{ DAMAGE_FOOLISH, "Foolish (16x)" }, { DAMAGE_RIDICULOUS, "Ridiculous (32x)" },
{ DAMAGE_MERCILESS, "Merciless (64x)" },
};
static const std::unordered_map<int32_t, const char*> bonkDamageValues = {
{ BONK_DAMAGE_NONE, "No Damage" }, { BONK_DAMAGE_QUARTER_HEART, "0.25 Hearts" },
{ BONK_DAMAGE_HALF_HEART, "0.5 Hearts" }, { BONK_DAMAGE_1_HEART, "1 Heart" },
{ BONK_DAMAGE_2_HEARTS, "2 Hearts" }, { BONK_DAMAGE_4_HEARTS, "4 Hearts" },
{ BONK_DAMAGE_8_HEARTS, "8 Hearts" }, { BONK_DAMAGE_OHKO, "OHKO" },
};
static const std::unordered_map<int32_t, const char*> dampeDropRates = {
{ DAMPE_NONE, "None" },
{ DAMPE_NORMAL, "Vanilla" },
{ DAMPE_JALAPENO, "Jalapeño" },
{ DAMPE_CHIPOTLE, "Serrano" },
{ DAMPE_SCOTCH_BONNET, "Habanero" },
{ DAMPE_GHOST_PEPPER, "Ghost Pepper" },
{ DAMPE_INFERNO, "Dampe's Inferno" },
};
static const std::unordered_map<int32_t, const char*> cursorAnywhereValues = {
{ PAUSE_ANY_CURSOR_RANDO_ONLY, "Only in Rando" },
{ PAUSE_ANY_CURSOR_ALWAYS_ON, "Always" },
{ PAUSE_ANY_CURSOR_ALWAYS_OFF, "Never" },
};
static const std::unordered_map<int32_t, const char*> zFightingOptions = {
{ ZFIGHT_FIX_DISABLED, "Disabled" },
{ ZFIGHT_FIX_CONSISTENT_VANISH, "Consistent Vanish" },
{ ZFIGHT_FIX_NO_VANISH, "No Vanish" },
};
static const std::unordered_map<int32_t, const char*> swordToggleModes = {
{ SWORD_TOGGLE_NONE, "None" },
{ SWORD_TOGGLE_CHILD, "Child Toggle" },
{ SWORD_TOGGLE_BOTH_AGES, "Both Ages" },
};
static const std::unordered_map<int32_t, const char*> mirroredWorldModes = {
{ MIRRORED_WORLD_OFF, "Disabled" },
{ MIRRORED_WORLD_ALWAYS, "Always" },
{ MIRRORED_WORLD_RANDOM, "Random" },
{ MIRRORED_WORLD_RANDOM_SEEDED, "Random (Seeded)" },
{ MIRRORED_WORLD_DUNGEONS_ALL, "Dungeons" },
{ MIRRORED_WORLD_DUNGEONS_VANILLA, "Dungeons (Vanilla)" },
{ MIRRORED_WORLD_DUNGEONS_MQ, "Dungeons (MQ)" },
{ MIRRORED_WORLD_DUNGEONS_RANDOM, "Dungeons Random" },
{ MIRRORED_WORLD_DUNGEONS_RANDOM_SEEDED, "Dungeons Random (Seeded)" },
};
static const std::unordered_map<int32_t, const char*> enemyRandomizerModes = {
{ ENEMY_RANDOMIZER_OFF, "Disabled" },
{ ENEMY_RANDOMIZER_RANDOM, "Random" },
{ ENEMY_RANDOMIZER_RANDOM_SEEDED, "Random (Seeded)" },
};
void SohMenu::AddMenuEnhancements() {
// Add Enhancements Menu
AddMenuEntry("Enhancements", CVAR_SETTING("Menu.EnhancementsSidebarSection"));
@ -217,6 +329,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-Jaby: 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";
@ -227,16 +348,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();
});
@ -244,16 +365,16 @@ void SohMenu::AddMenuEnhancements() {
.SameLine(true)
.Options(ButtonOptions().Size(Sizes::Inline))
.Callback([](WidgetInfo& info) {
CVarClear(CVAR_ENHANCEMENT("TimeSavers.SkipCutscene.Intro"));
CVarClear(CVAR_ENHANCEMENT("TimeSavers.SkipCutscene.Entrances"));
CVarClear(CVAR_ENHANCEMENT("TimeSavers.SkipCutscene.Story"));
CVarClear(CVAR_ENHANCEMENT("TimeSavers.SkipCutscene.LearnSong"));
CVarClear(CVAR_ENHANCEMENT("TimeSavers.SkipCutscene.BossIntro"));
CVarClear(CVAR_ENHANCEMENT("TimeSavers.SkipCutscene.QuickBossDeaths"));
CVarClear(CVAR_ENHANCEMENT("TimeSavers.SkipCutscene.OnePoint"));
CVarClear(CVAR_ENHANCEMENT("TimeSavers.SkipOwlInteractions"));
CVarClear(CVAR_ENHANCEMENT("TimeSavers.SkipMiscInteractions"));
CVarClear(CVAR_ENHANCEMENT("TimeSavers.DisableTitleCard"));
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();
});
@ -467,7 +588,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."));

View file

@ -96,21 +96,15 @@ void SohMenu::AddMenuNetwork() {
AddSidebarEntry("Network", path.sidebarName, 3);
path.column = SECTION_COLUMN_1;
AddWidget(path, "About Crowd Control", WIDGET_SEPARATOR_TEXT);
AddWidget(path,
"Crowd Control is a platform that allows viewers to interact "
"with a streamer's game in real time.\n"
"\n"
"Click the question mark to copy the link to the Crowd Control "
"website to your clipboard.",
"Please head over to www.crowdcontrol.live for more information!",
WIDGET_TEXT);
AddWidget(path, ICON_FA_CLIPBOARD "##CrowdControl", WIDGET_BUTTON)
.Callback([](WidgetInfo& info) {
ImGui::SetClipboardText("https://crowdcontrol.live");
Notification::Emit({
.message = "Copied to clipboard",
});
})
.Options(ButtonOptions().Tooltip("https://crowdcontrol.live"));
AddWidget(path, "Connect to Crowd Control", WIDGET_SEPARATOR_TEXT);
AddWidget(path, "Host & Port", WIDGET_CUSTOM).CustomFunction([](WidgetInfo& info) {
ImGui::BeginDisabled(CrowdControl::Instance->isEnabled || CVarGetInteger(CVAR_SETTING("DisableChanges"), 0));
ImGui::Text("%s", info.name.c_str());
@ -155,14 +149,25 @@ void SohMenu::AddMenuNetwork() {
CrowdControl::Instance->Enable();
}
});
AddWidget(path, "Connecting...##CrowdControl", WIDGET_TEXT).PreFunc([](WidgetInfo& info) {
AddWidget(path, "Connecting...", WIDGET_TEXT).PreFunc([](WidgetInfo& info) {
info.isHidden = !CrowdControl::Instance->isEnabled;
if (CrowdControl::Instance->isConnected) {
info.name = "Connected##CrowdControl";
info.name = "Connected";
} else {
info.name = "Connecting...##CrowdControl";
info.name = "Connecting...";
}
});
AddWidget(path, "Additional Settings", WIDGET_SEPARATOR_TEXT);
AddWidget(path, "Enemy Name Tags", WIDGET_CVAR_CHECKBOX)
.CVar(CVAR_REMOTE_CROWD_CONTROL("EnemyNameTags"))
.RaceDisable(true)
.Options(CheckboxOptions().Tooltip(
"When viewers spawn enemies, the enemy will have a name tag above them with the viewer's name."));
AddWidget(path, "Spawned Enemies Ignored Ingame", WIDGET_CVAR_CHECKBOX)
.CVar(CVAR_REMOTE_CROWD_CONTROL("SpawnedEnemiesIgnoredIngame"))
.RaceDisable(true)
.Options(CheckboxOptions().Tooltip("Enemies spawned by CrowdControl won't be considered for \"clear enemy "
"rooms\", so they don't need to be killed to complete these rooms."));
}
} // namespace SohGui

View file

@ -6,6 +6,12 @@ namespace SohGui {
extern std::shared_ptr<SohMenu> mSohMenu;
using namespace UIWidgets;
static const std::unordered_map<int32_t, const char*> skipGetItemAnimationOptions = {
{ SGIA_DISABLED, "Disabled" },
{ SGIA_JUNK, "Junk Items" },
{ SGIA_ALL, "All Items" },
};
void SohMenu::AddMenuRandomizer() {
// Add Randomizer Menu
AddMenuEntry("Randomizer", CVAR_SETTING("Menu.RandomizerSidebarSection"));

View file

@ -23,6 +23,39 @@ static std::unordered_map<int32_t, const char*> imguiScaleOptions = {
{ 3, "X-Large" },
};
static const std::unordered_map<int32_t, const char*> menuThemeOptions = {
{ UIWidgets::Colors::Red, "Red" },
{ UIWidgets::Colors::DarkRed, "Dark Red" },
{ UIWidgets::Colors::Orange, "Orange" },
{ UIWidgets::Colors::Green, "Green" },
{ UIWidgets::Colors::DarkGreen, "Dark Green" },
{ UIWidgets::Colors::LightBlue, "Light Blue" },
{ UIWidgets::Colors::Blue, "Blue" },
{ UIWidgets::Colors::DarkBlue, "Dark Blue" },
{ UIWidgets::Colors::Indigo, "Indigo" },
{ UIWidgets::Colors::Violet, "Violet" },
{ UIWidgets::Colors::Purple, "Purple" },
{ UIWidgets::Colors::Brown, "Brown" },
{ UIWidgets::Colors::Gray, "Gray" },
{ UIWidgets::Colors::DarkGray, "Dark Gray" },
};
static const std::unordered_map<int32_t, const char*> textureFilteringMap = {
{ Fast::FILTER_THREE_POINT, "Three-Point" },
{ Fast::FILTER_LINEAR, "Linear" },
{ Fast::FILTER_NONE, "None" },
};
static const std::unordered_map<int32_t, const char*> notificationPosition = {
{ 0, "Top Left" }, { 1, "Top Right" }, { 2, "Bottom Left" }, { 3, "Bottom Right" }, { 4, "Hidden" },
};
static const std::unordered_map<int32_t, const char*> bootSequenceLabels = {
{ BOOTSEQUENCE_DEFAULT, "Default" },
{ BOOTSEQUENCE_AUTHENTIC, "Authentic" },
{ BOOTSEQUENCE_FILESELECT, "File Select" },
};
const char* GetGameVersionString(uint32_t index) {
uint32_t gameVersion = ResourceMgr_GetGameVersion(index);
switch (gameVersion) {

View file

@ -115,10 +115,12 @@ struct WidgetOptions {
tooltip = tooltip_;
return *this;
}
WidgetOptions& Disabled(bool disabled_) {
disabled = disabled_;
return *this;
}
WidgetOptions& DisabledTooltip(const char* disabledTooltip_) {
disabledTooltip = disabledTooltip_;
return *this;
@ -143,14 +145,17 @@ struct ButtonOptions : WidgetOptions {
size = size_;
return *this;
}
ButtonOptions& Padding(ImVec2 padding_) {
padding = padding_;
return *this;
}
ButtonOptions& Tooltip(const char* tooltip_) {
WidgetOptions::tooltip = tooltip_;
return *this;
}
ButtonOptions& Color(Colors color_) {
color = color_;
return *this;
@ -168,22 +173,27 @@ struct WindowButtonOptions : WidgetOptions {
size = size_;
return *this;
}
WindowButtonOptions& Padding(ImVec2 padding_) {
padding = padding_;
return *this;
}
WindowButtonOptions& Tooltip(const char* tooltip_) {
WidgetOptions::tooltip = tooltip_;
return *this;
}
WindowButtonOptions& Color(Colors color_) {
color = color_;
return *this;
}
WindowButtonOptions& ShowButton(bool showButton_) {
showButton = showButton_;
return *this;
}
WindowButtonOptions& EmbedWindow(bool embedWindow_) {
embedWindow = embedWindow_;
return *this;
@ -201,26 +211,32 @@ struct CheckboxOptions : WidgetOptions {
defaultValue = defaultValue_;
return *this;
}
CheckboxOptions& ComponentAlignment(ComponentAlignments alignment_) {
alignment = alignment_;
return *this;
}
CheckboxOptions& LabelPosition(LabelPositions labelPosition_) {
labelPosition = labelPosition_;
return *this;
}
CheckboxOptions& Tooltip(const char* tooltip_) {
WidgetOptions::tooltip = tooltip_;
return *this;
}
CheckboxOptions& Color(Colors color_) {
color = color_;
return *this;
}
CheckboxOptions& DisabledTooltip(const char* disabledTooltip_) {
WidgetOptions::disabledTooltip = disabledTooltip_;
return *this;
}
CheckboxOptions& Padding(ImVec2 padding_) {
padding = padding_;
return *this;
@ -239,22 +255,27 @@ struct ComboboxOptions : WidgetOptions {
comboMap = comboMap_;
return *this;
}
ComboboxOptions& DefaultIndex(uint32_t defaultIndex_) {
defaultIndex = defaultIndex_;
return *this;
}
ComboboxOptions& ComponentAlignment(ComponentAlignments alignment_) {
alignment = alignment_;
return *this;
}
ComboboxOptions& LabelPosition(LabelPositions labelPosition_) {
labelPosition = labelPosition_;
return *this;
}
ComboboxOptions& Tooltip(const char* tooltip_) {
WidgetOptions::tooltip = tooltip_;
return *this;
}
ComboboxOptions& Color(Colors color_) {
color = color_;
return *this;
@ -279,46 +300,57 @@ struct IntSliderOptions : WidgetOptions {
showButtons = showButtons_;
return *this;
}
IntSliderOptions& Format(const char* format_) {
format = format_;
return *this;
}
IntSliderOptions& Step(int32_t step_) {
step = step_;
return *this;
}
IntSliderOptions& Min(int32_t min_) {
min = min_;
return *this;
}
IntSliderOptions& Max(int32_t max_) {
max = max_;
return *this;
}
IntSliderOptions& DefaultValue(int32_t defaultValue_) {
defaultValue = defaultValue_;
return *this;
}
IntSliderOptions& ComponentAlignment(ComponentAlignments alignment_) {
alignment = alignment_;
return *this;
}
IntSliderOptions& LabelPosition(LabelPositions labelPosition_) {
labelPosition = labelPosition_;
return *this;
}
IntSliderOptions& Tooltip(const char* tooltip_) {
WidgetOptions::tooltip = tooltip_;
return *this;
}
IntSliderOptions& Color(Colors color_) {
color = color_;
return *this;
}
IntSliderOptions& Size(ImVec2 size_) {
size = size_;
return *this;
}
IntSliderOptions& Clamp(bool clamp_) {
clamp = clamp_;
return *this;
@ -344,34 +376,42 @@ struct FloatSliderOptions : WidgetOptions {
showButtons = showButtons_;
return *this;
}
FloatSliderOptions& Format(const char* format_) {
format = format_;
return *this;
}
FloatSliderOptions& Step(float step_) {
step = step_;
return *this;
}
FloatSliderOptions& Min(float min_) {
min = min_;
return *this;
}
FloatSliderOptions& Max(float max_) {
max = max_;
return *this;
}
FloatSliderOptions& DefaultValue(float defaultValue_) {
defaultValue = defaultValue_;
return *this;
}
FloatSliderOptions& ComponentAlignment(ComponentAlignments alignment_) {
alignment = alignment_;
return *this;
}
FloatSliderOptions& LabelPosition(LabelPositions labelPosition_) {
labelPosition = labelPosition_;
return *this;
}
FloatSliderOptions& IsPercentage(bool isPercentage_ = true) {
isPercentage = isPercentage_;
format = "%.0f%%";
@ -379,18 +419,22 @@ struct FloatSliderOptions : WidgetOptions {
max = 1.0f;
return *this;
}
FloatSliderOptions& Tooltip(const char* tooltip_) {
WidgetOptions::tooltip = tooltip_;
return *this;
}
FloatSliderOptions& Color(Colors color_) {
color = color_;
return *this;
}
FloatSliderOptions& Size(ImVec2 size_) {
size = size_;
return *this;
}
FloatSliderOptions& Clamp(bool clamp_) {
clamp = clamp_;
return *this;
@ -406,14 +450,17 @@ struct RadioButtonsOptions : WidgetOptions {
buttonMap = buttonMap_;
return *this;
}
RadioButtonsOptions& Tooltip(const char* tooltip_) {
WidgetOptions::tooltip = tooltip_;
return *this;
}
RadioButtonsOptions& Color(Colors color_) {
color = color_;
return *this;
}
RadioButtonsOptions& DefaultIndex(int32_t defaultIndex_) {
defaultIndex = defaultIndex_;
return *this;
@ -437,10 +484,12 @@ struct InputOptions : WidgetOptions {
WidgetOptions::tooltip = tooltip_;
return *this;
}
InputOptions& Color(Colors color_) {
color = color_;
return *this;
}
InputOptions& Size(ImVec2 size_) {
size = size_;
return *this;

View file

@ -1284,8 +1284,16 @@ void Actor_UpdatePos(Actor* actor) {
}
void Actor_UpdateVelocityXZGravity(Actor* actor) {
actor->velocity.x = Math_SinS(actor->world.rot.y) * actor->speedXZ;
actor->velocity.z = Math_CosS(actor->world.rot.y) * actor->speedXZ;
Player* player = GET_PLAYER(gPlayState);
uint8_t inCutscene = player->stateFlags1 & PLAYER_STATE1_CLIMBING_LADDER ||
player->stateFlags1 & PLAYER_STATE1_IN_CUTSCENE ||
player->stateFlags2 & PLAYER_STATE2_CRAWLING;
f32 speedModifier = 1.0f;
if (actor->id == ACTOR_PLAYER && !inCutscene) {
speedModifier = GameInteractor_MovementSpeedMultiplier();
}
actor->velocity.x = Math_SinS(actor->world.rot.y) * actor->speedXZ * speedModifier;
actor->velocity.z = Math_CosS(actor->world.rot.y) * actor->speedXZ * speedModifier;
actor->velocity.y += actor->gravity;
if (actor->velocity.y < actor->minVelocityY) {
@ -5047,8 +5055,8 @@ void Flags_SetRandomizerInf(RandomizerInf flag) {
*/
s32 previouslyOff = !Flags_GetRandomizerInf(flag);
gSaveContext.ship.randomizerInf[flag >> 4] |= (1 << (flag & 0xF));
if (previouslyOff) {
gSaveContext.ship.randomizerInf[flag >> 4] |= (1 << (flag & 0xF));
LUSLOG_INFO("RandomizerInf Flag Set - %#x", flag);
GameInteractor_ExecuteOnFlagSet(FLAG_RANDOMIZER_INF, flag);
}
@ -5068,8 +5076,8 @@ void Flags_UnsetRandomizerInf(RandomizerInf flag) {
*/
s32 previouslyOn = Flags_GetRandomizerInf(flag);
gSaveContext.ship.randomizerInf[flag >> 4] &= ~(1 << (flag & 0xF));
if (previouslyOn) {
gSaveContext.ship.randomizerInf[flag >> 4] &= ~(1 << (flag & 0xF));
LUSLOG_INFO("RandomizerInf Flag Unset - %#x", flag);
GameInteractor_ExecuteOnFlagUnset(FLAG_RANDOMIZER_INF, flag);
}

View file

@ -813,7 +813,8 @@ void DoorWarp1_AdultWarpOut(DoorWarp1* this, PlayState* play) {
gSaveContext.nextCutsceneIndex = 0;
}
} else if (play->sceneNum == SCENE_SPIRIT_TEMPLE_BOSS) {
if (GameInteractor_Should(VB_PLAY_BLUE_WARP_CS, !CHECK_QUEST_ITEM(QUEST_MEDALLION_SPIRIT),
if (GameInteractor_Should(VB_PLAY_BLUE_WARP_CS,
!Flags_GetRandomizerInf(RAND_INF_DUNGEONS_DONE_SPIRIT_TEMPLE),
RAND_INF_DUNGEONS_DONE_SPIRIT_TEMPLE)) {
Flags_SetRandomizerInf(RAND_INF_DUNGEONS_DONE_SPIRIT_TEMPLE);
if (GameInteractor_Should(VB_GIVE_ITEM_FROM_BLUE_WARP, true, ITEM_MEDALLION_SPIRIT)) {
@ -831,7 +832,8 @@ void DoorWarp1_AdultWarpOut(DoorWarp1* this, PlayState* play) {
gSaveContext.nextCutsceneIndex = 0;
}
} else if (play->sceneNum == SCENE_SHADOW_TEMPLE_BOSS) {
if (GameInteractor_Should(VB_PLAY_BLUE_WARP_CS, !CHECK_QUEST_ITEM(QUEST_MEDALLION_SHADOW),
if (GameInteractor_Should(VB_PLAY_BLUE_WARP_CS,
!Flags_GetRandomizerInf(RAND_INF_DUNGEONS_DONE_SHADOW_TEMPLE),
RAND_INF_DUNGEONS_DONE_SHADOW_TEMPLE)) {
Flags_SetRandomizerInf(RAND_INF_DUNGEONS_DONE_SHADOW_TEMPLE);
if (GameInteractor_Should(VB_GIVE_ITEM_FROM_BLUE_WARP, true, ITEM_MEDALLION_SHADOW)) {

View file

@ -58,6 +58,11 @@ void EnAttackNiw_Init(Actor* thisx, PlayState* play) {
this->actor.flags &= ~ACTOR_FLAG_ATTENTION_ENABLED;
this->actor.shape.rot.y = this->actor.world.rot.y = (Rand_ZeroOne() - 0.5f) * 60000.0f;
this->actionFunc = func_809B5670;
if (CVarGetInteger("gCrowdControl", 0) &&
CVarGetInteger(CVAR_REMOTE_CROWD_CONTROL("SpawnedEnemiesIgnoredIngame"), 0)) {
Actor_ChangeCategory(gPlayState, &gPlayState->actorCtx, this, ACTORCAT_NPC);
}
}
void EnAttackNiw_Destroy(Actor* thisx, PlayState* play) {

View file

@ -7124,15 +7124,6 @@ void func_8083DFE0(Player* this, f32* arg1, s16* arg2) {
if (this->meleeWeaponState == 0) {
float maxSpeed = R_RUN_SPEED_LIMIT / 100.0f;
int32_t giSpeedModifier = GameInteractor_RunSpeedModifier();
if (giSpeedModifier != 0) {
if (giSpeedModifier > 0) {
maxSpeed *= giSpeedModifier;
} else {
maxSpeed /= abs(giSpeedModifier);
}
}
if (CVarGetInteger(CVAR_ENHANCEMENT("MMBunnyHood"), BUNNY_HOOD_VANILLA) == BUNNY_HOOD_FAST_AND_JUMP &&
this->currentMask == PLAYER_MASK_BUNNY) {
maxSpeed *= 1.5f;
@ -8873,14 +8864,6 @@ void Player_Action_80842180(Player* this, PlayState* play) {
Player_GetMovementSpeedAndYaw(this, &sp2C, &sp2A, SPEED_MODE_CURVED, play);
if (!func_8083C484(this, &sp2C, &sp2A)) {
int32_t giSpeedModifier = GameInteractor_RunSpeedModifier();
if (giSpeedModifier != 0) {
if (giSpeedModifier > 0) {
sp2C *= giSpeedModifier;
} else {
sp2C /= abs(giSpeedModifier);
}
}
if (CVarGetInteger(CVAR_ENHANCEMENT("MMBunnyHood"), BUNNY_HOOD_VANILLA) != BUNNY_HOOD_VANILLA &&
this->currentMask == PLAYER_MASK_BUNNY) {

View file

@ -124,7 +124,17 @@ void KaleidoScope_DrawQuestStatus(PlayState* play, GraphicsContext* gfxCtx) {
s16 pad2;
s16 phi_s0_2;
s16 sp208[3];
bool dpad = CVarGetInteger(CVAR_SETTING("DPadOnPause"), 0);
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;
}
}
OPEN_DISPS(gfxCtx);
@ -140,7 +150,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 +163,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 +178,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 +186,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 +277,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 +295,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;