diff --git a/soh/assets/objects/object_custom_equip/object_custom_equip.h b/soh/assets/objects/object_custom_equip/object_custom_equip.h index 380116a0f99..2564a686cd6 100644 --- a/soh/assets/objects/object_custom_equip/object_custom_equip.h +++ b/soh/assets/objects/object_custom_equip/object_custom_equip.h @@ -113,6 +113,44 @@ static const ALIGN_ASSET(2) char gCustomAdultFPSHandDL[] = dgCustomAdultFPSHandD #define dgCustomChildFPSHandDL "__OTR__objects/object_custom_equip/gCustomChildFPSHandDL" static const ALIGN_ASSET(2) char gCustomChildFPSHandDL[] = dgCustomChildFPSHandDL; +// Custom Bottle Content Display Lists +#define dgCustomBottleDL "__OTR__objects/object_custom_equip/gCustomBottleDL" +static const ALIGN_ASSET(2) char gCustomBottleDL[] = dgCustomBottleDL; +#define dgCustomBottleRedPotionDL "__OTR__objects/object_custom_equip/gCustomBottleRedPotionDL" +static const ALIGN_ASSET(2) char gCustomBottleRedPotionDL[] = dgCustomBottleRedPotionDL; + +#define dgCustomBottleGreenPotionDL "__OTR__objects/object_custom_equip/gCustomBottleGreenPotionDL" +static const ALIGN_ASSET(2) char gCustomBottleGreenPotionDL[] = dgCustomBottleGreenPotionDL; + +#define dgCustomBottleBluePotionDL "__OTR__objects/object_custom_equip/gCustomBottleBluePotionDL" +static const ALIGN_ASSET(2) char gCustomBottleBluePotionDL[] = dgCustomBottleBluePotionDL; + +#define dgCustomBottleFairyDL "__OTR__objects/object_custom_equip/gCustomBottleFairyDL" +static const ALIGN_ASSET(2) char gCustomBottleFairyDL[] = dgCustomBottleFairyDL; + +#define dgCustomBottleFishDL "__OTR__objects/object_custom_equip/gCustomBottleFishDL" +static const ALIGN_ASSET(2) char gCustomBottleFishDL[] = dgCustomBottleFishDL; + +#define dgCustomBottleMilkDL "__OTR__objects/object_custom_equip/gCustomBottleMilkDL" +static const ALIGN_ASSET(2) char gCustomBottleMilkDL[] = dgCustomBottleMilkDL; + +#define dgCustomBottleMilkHalfDL "__OTR__objects/object_custom_equip/gCustomBottleMilkHalfDL" +static const ALIGN_ASSET(2) char gCustomBottleMilkHalfDL[] = dgCustomBottleMilkHalfDL; + +#define dgCustomBottleLetterDL "__OTR__objects/object_custom_equip/gCustomBottleLetterDL" +static const ALIGN_ASSET(2) char gCustomBottleLetterDL[] = dgCustomBottleLetterDL; + +#define dgCustomBottleBlueFireDL "__OTR__objects/object_custom_equip/gCustomBottleBlueFireDL" +static const ALIGN_ASSET(2) char gCustomBottleBlueFireDL[] = dgCustomBottleBlueFireDL; + +#define dgCustomBottleBugDL "__OTR__objects/object_custom_equip/gCustomBottleBugDL" +static const ALIGN_ASSET(2) char gCustomBottleBugDL[] = dgCustomBottleBugDL; + +#define dgCustomBottleBigPoeDL "__OTR__objects/object_custom_equip/gCustomBottleBigPoeDL" +static const ALIGN_ASSET(2) char gCustomBottleBigPoeDL[] = dgCustomBottleBigPoeDL; + +#define dgCustomBottlePoeDL "__OTR__objects/object_custom_equip/gCustomBottlePoeDL" +static const ALIGN_ASSET(2) char gCustomBottlePoeDL[] = dgCustomBottlePoeDL; #endif // OBJECTS_OBJECT_CUSTOM_EQUIP_H diff --git a/soh/soh/Enhancements/Cheats/NoLikeLikeItemSteal.cpp b/soh/soh/Enhancements/Cheats/NoLikeLikeItemSteal.cpp new file mode 100644 index 00000000000..825ecbe1bfb --- /dev/null +++ b/soh/soh/Enhancements/Cheats/NoLikeLikeItemSteal.cpp @@ -0,0 +1,17 @@ +#include +#include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h" +#include "soh/ShipInit.hpp" + +extern "C" { +#include "macros.h" +} + +static constexpr int32_t CVAR_NOLIKELIKEITEMSTEAL_DEFAULT = 0; +#define CVAR_NOLIKELIKEITEMSTEAL_NAME CVAR_CHEAT("NoLikeLikeItemSteal") +#define CVAR_NOLIKELIKEITEMSTEAL_VALUE CVarGetInteger(CVAR_NOLIKELIKEITEMSTEAL_NAME, CVAR_NOLIKELIKEITEMSTEAL_DEFAULT) + +void RegisterNoLikeLikeItemSteal() { + COND_VB_SHOULD(VB_LIKE_LIKE_STEAL_EQUIPMENT, CVAR_NOLIKELIKEITEMSTEAL_VALUE, { *should = false; }); +} + +static RegisterShipInitFunc initFunc(RegisterNoLikeLikeItemSteal, { CVAR_NOLIKELIKEITEMSTEAL_NAME }); \ No newline at end of file diff --git a/soh/soh/Enhancements/cosmetics/CustomSkeletons.cpp b/soh/soh/Enhancements/CustomSkeletons.cpp similarity index 100% rename from soh/soh/Enhancements/cosmetics/CustomSkeletons.cpp rename to soh/soh/Enhancements/CustomSkeletons.cpp diff --git a/soh/soh/Enhancements/DropThrowOnlyActors.cpp b/soh/soh/Enhancements/DropThrowOnlyActors.cpp new file mode 100644 index 00000000000..16d106068af --- /dev/null +++ b/soh/soh/Enhancements/DropThrowOnlyActors.cpp @@ -0,0 +1,66 @@ +#include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h" +#include "soh/ShipInit.hpp" + +extern "C" { +extern PlayState* gPlayState; +} + +static int sDropThrowOnlyLastValue = -1; + +static void AllowThrowOnlyDrop(Actor* actor, int cvarValue) { + if (actor == nullptr) { + return; + } + + switch (actor->id) { + case ACTOR_EN_ISHI: + case ACTOR_EN_KUSA: + case ACTOR_EN_NIW: + case ACTOR_OBJ_TSUBO: + break; + default: + return; + } + + if (cvarValue) { + actor->flags &= ~ACTOR_FLAG_THROW_ONLY; + } else { + actor->flags |= ACTOR_FLAG_THROW_ONLY; + } +} + +static void OnThrowOnlyActorInit(void* actorPtr) { + if (gPlayState == nullptr || actorPtr == nullptr) { + return; + } + + // Use current cvar state for newly spawned actors too + const int currentValue = CVarGetInteger(CVAR_ENHANCEMENT("DropThrowOnlyObjects"), 0); + AllowThrowOnlyDrop((Actor*)actorPtr, currentValue); +} + +static void DropThrowOnlyCVarWatcher() { + if (gPlayState == nullptr) { + return; + } + + const int currentValue = CVarGetInteger(CVAR_ENHANCEMENT("DropThrowOnlyObjects"), 0); + + sDropThrowOnlyLastValue = currentValue; + + for (int category = 0; category < ACTORCAT_MAX; category++) { + for (Actor* actor = gPlayState->actorCtx.actorLists[category].head; actor != nullptr; actor = actor->next) { + AllowThrowOnlyDrop(actor, currentValue); + } + } +} + +void RegisterAllowThrowOnlyDrop() { + // Always enabled so newly spawned actors match the current cvar state. + COND_HOOK(OnActorInit, true, OnThrowOnlyActorInit); + + COND_HOOK(OnGameFrameUpdate, CVarGetInteger(CVAR_ENHANCEMENT("DropThrowOnlyObjects"), 0) != sDropThrowOnlyLastValue, + DropThrowOnlyCVarWatcher); +} + +static RegisterShipInitFunc initFunc(RegisterAllowThrowOnlyDrop, { CVAR_ENHANCEMENT("DropThrowOnlyObjects") }); \ No newline at end of file diff --git a/soh/soh/Enhancements/ExtraTraps.cpp b/soh/soh/Enhancements/ExtraTraps.cpp index 0be9f2bd31b..1bd91aaf499 100644 --- a/soh/soh/Enhancements/ExtraTraps.cpp +++ b/soh/soh/Enhancements/ExtraTraps.cpp @@ -197,4 +197,4 @@ void RegisterExtraTraps() { }); } -static RegisterShipInitFunc initFunc(RegisterExtraTraps, { CVAR_EXTRA_TRAPS_NAME }); +static RegisterShipInitFunc initFunc(RegisterExtraTraps, { CVAR_EXTRA_TRAPS_NAME }); \ No newline at end of file diff --git a/soh/soh/Enhancements/Presets/Presets.cpp b/soh/soh/Enhancements/Presets/Presets.cpp index a6ffbcf9608..dace75e1cf1 100644 --- a/soh/soh/Enhancements/Presets/Presets.cpp +++ b/soh/soh/Enhancements/Presets/Presets.cpp @@ -250,18 +250,25 @@ void SavePreset(std::string& presetName) { } presets[presetName].presetValues["presetName"] = presetName; presets[presetName].presetValues["fileType"] = FILE_TYPE_PRESET; - std::ofstream file( - fmt::format("{}/{}.json", Ship::Context::GetInstance()->LocateFileAcrossAppDirs("presets"), presetName)); + std::ofstream file(FormatPresetPath(presetName)); file << presets[presetName].presetValues.dump(4); file.close(); LoadPresets(); } -static std::string newPresetName; +void DeletePreset(std::string& presetName) { + std::string presetPath = FormatPresetPath(presetName); + if (fs::exists(presetPath)) { + fs::remove(presetPath); + } + presets.erase(presetName); +} + +static std::string newPresetName, oldPresetName; static bool saveSection[PRESET_SECTION_MAX]; -void DrawNewPresetPopup() { - bool nameExists = presets.contains(newPresetName); +void DrawEditPresetPopup() { + bool nameExists = presets.contains(newPresetName) && newPresetName != oldPresetName; UIWidgets::InputString("Preset Name", &newPresetName, UIWidgets::InputOptions() .Color(THEME_COLOR) @@ -270,7 +277,7 @@ void DrawNewPresetPopup() { .LabelPosition(UIWidgets::LabelPositions::Near) .ErrorText("Preset name already exists") .HasError(nameExists)); - nameExists = presets.contains(newPresetName); + nameExists = presets.contains(newPresetName) && newPresetName != oldPresetName; bool noneSelected = true; for (int i = PRESET_SECTION_SETTINGS; i < PRESET_SECTION_MAX; i++) { if (saveSection[i]) { @@ -348,10 +355,15 @@ void DrawNewPresetPopup() { presets[newPresetName].fileName = newPresetName; std::fill_n(presets[newPresetName].apply, PRESET_SECTION_MAX, true); SavePreset(newPresetName); + if (newPresetName != oldPresetName) { + DeletePreset(oldPresetName); + } newPresetName = ""; + oldPresetName = ""; ImGui::CloseCurrentPopup(); } if (UIWidgets::Button("Cancel", UIWidgets::ButtonOptions().Padding({ 6.0f, 6.0f }).Color(THEME_COLOR))) { + oldPresetName = ""; ImGui::CloseCurrentPopup(); } ImGui::EndPopup(); @@ -364,25 +376,32 @@ void PresetsCustomWidget(WidgetInfo& info) { .disabledTooltip = "Disabled because of race lockout" } }) .Size(UIWidgets::Sizes::Inline) .Color(THEME_COLOR))) { - ImGui::OpenPopup("newPreset"); + oldPresetName = ""; + newPresetName = ""; + std::fill_n(saveSection, PRESET_SECTION_MAX, true); + ImGui::OpenPopup("editPreset"); + } else if (oldPresetName != "") { + ImGui::OpenPopup("editPreset"); } - if (ImGui::BeginPopup("newPreset", ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_NoResize | - ImGuiWindowFlags_NoMove | ImGuiWindowFlags_NoScrollbar | - ImGuiWindowFlags_NoSavedSettings | ImGuiWindowFlags_NoTitleBar)) { - DrawNewPresetPopup(); + if (ImGui::BeginPopup("editPreset", ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_NoResize | + ImGuiWindowFlags_NoMove | ImGuiWindowFlags_NoScrollbar | + ImGuiWindowFlags_NoSavedSettings | ImGuiWindowFlags_NoTitleBar)) { + DrawEditPresetPopup(); } ImGui::SameLine(); UIWidgets::CVarCheckbox("Hide built-in presets", CVAR_GENERAL("HideBuiltInPresets"), UIWidgets::CheckboxOptions().Color(THEME_COLOR)); bool hideBuiltIn = CVarGetInteger(CVAR_GENERAL("HideBuiltInPresets"), 0); UIWidgets::PushStyleTabs(THEME_COLOR); - if (ImGui::BeginTable("PresetWidgetTable", PRESET_SECTION_MAX + 3)) { + if (ImGui::BeginTable("PresetWidgetTable", PRESET_SECTION_MAX + 4)) { ImGui::TableSetupColumn("Name", ImGuiTableColumnFlags_WidthFixed, 400); for (int i = PRESET_SECTION_SETTINGS; i < PRESET_SECTION_MAX; i++) { ImGui::TableSetupColumn(blockInfo[i].names[0].c_str()); } ImGui::TableSetupColumn("Apply", ImGuiTableColumnFlags_WidthFixed, ImGui::CalcTextSize("Apply").x + ImGui::GetStyle().FramePadding.x * 2); + ImGui::TableSetupColumn("Edit", ImGuiTableColumnFlags_WidthFixed, + ImGui::CalcTextSize("Edit").x + ImGui::GetStyle().FramePadding.x * 2); ImGui::TableSetupColumn("Delete", ImGuiTableColumnFlags_WidthFixed, ImGui::CalcTextSize("Delete").x + ImGui::GetStyle().FramePadding.x * 2); BlankButton(); @@ -431,13 +450,17 @@ void PresetsCustomWidget(WidgetInfo& info) { ImGui::TableNextColumn(); UIWidgets::PushStyleButton(THEME_COLOR); if (!info.isBuiltIn) { + if (UIWidgets::Button(("Edit##" + name).c_str(), UIWidgets::ButtonOptions().Padding({ 6.0f, 6.0f }))) { + std::copy(info.apply, info.apply + PRESET_SECTION_MAX, saveSection); + newPresetName = name; + oldPresetName = name; + } + UIWidgets::PopStyleButton(); + ImGui::TableNextColumn(); + UIWidgets::PushStyleButton(THEME_COLOR); if (UIWidgets::Button(("Delete##" + name).c_str(), UIWidgets::ButtonOptions().Padding({ 6.0f, 6.0f }))) { - auto path = FormatPresetPath(info.fileName); - if (fs::exists(path)) { - fs::remove(path); - } - presets.erase(name); + DeletePreset(info.fileName); UIWidgets::PopStyleButton(); break; } diff --git a/soh/soh/Enhancements/QoL/ResetNaviTimer.cpp b/soh/soh/Enhancements/QoL/ResetNaviTimer.cpp index b3048be538f..6f88067757c 100644 --- a/soh/soh/Enhancements/QoL/ResetNaviTimer.cpp +++ b/soh/soh/Enhancements/QoL/ResetNaviTimer.cpp @@ -14,4 +14,4 @@ static void RegisterResetNaviTimer() { COND_HOOK(OnSceneInit, CVAR_RESET_NAVI_VALUE, [](int32_t) { gSaveContext.naviTimer = 0; }); } -static RegisterShipInitFunc initFunc(RegisterResetNaviTimer, { CVAR_RESET_NAVI_NAME }); +static RegisterShipInitFunc initFunc(RegisterResetNaviTimer, { CVAR_RESET_NAVI_NAME }); \ No newline at end of file diff --git a/soh/soh/Enhancements/audio/DisableNaviCallAudio.cpp b/soh/soh/Enhancements/audio/DisableNaviCallAudio.cpp new file mode 100644 index 00000000000..2a2cfbc5780 --- /dev/null +++ b/soh/soh/Enhancements/audio/DisableNaviCallAudio.cpp @@ -0,0 +1,13 @@ +#include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h" +#include "soh/ShipInit.hpp" + +static constexpr int32_t CVAR_DISABLENAVICALLAUDIO_DEFAULT = 0; +#define CVAR_DISABLENAVICALLAUDIO_NAME CVAR_AUDIO("DisableNaviCallAudio") +#define CVAR_DISABLENAVICALLAUDIO_VALUE \ + CVarGetInteger(CVAR_DISABLENAVICALLAUDIO_NAME, CVAR_DISABLENAVICALLAUDIO_DEFAULT) + +void RegisterDisableNaviCallAudio() { + COND_VB_SHOULD(VB_PLAY_NAVI_CALL_SOUND, CVAR_DISABLENAVICALLAUDIO_VALUE, { *should = false; }); +} + +static RegisterShipInitFunc initFunc(RegisterDisableNaviCallAudio, { CVAR_DISABLENAVICALLAUDIO_NAME }); \ No newline at end of file diff --git a/soh/soh/Enhancements/cosmetics/CosmeticsEditor.cpp b/soh/soh/Enhancements/cosmetics/CosmeticsEditor.cpp index 49e74f69cf1..f2f77a68ebd 100644 --- a/soh/soh/Enhancements/cosmetics/CosmeticsEditor.cpp +++ b/soh/soh/Enhancements/cosmetics/CosmeticsEditor.cpp @@ -1889,6 +1889,10 @@ void DrawSillyTab() { UIWidgets::Separator(true, true, 2.0f, 2.0f); + UIWidgets::CVarCheckbox( + "Invisible Navi", CVAR_COSMETIC("InvisibleNavi"), + UIWidgets::CheckboxOptions().Color(THEME_COLOR).Tooltip("Makes Navi invisible and disables her sounds.")); + UIWidgets::CVarCheckbox("Let It Snow", CVAR_GENERAL("LetItSnow"), UIWidgets::CheckboxOptions() .Color(THEME_COLOR) diff --git a/soh/soh/Enhancements/cosmetics/InvisibleNavi.cpp b/soh/soh/Enhancements/cosmetics/InvisibleNavi.cpp new file mode 100644 index 00000000000..ce1006e83e3 --- /dev/null +++ b/soh/soh/Enhancements/cosmetics/InvisibleNavi.cpp @@ -0,0 +1,63 @@ +#include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h" +#include "soh/ShipInit.hpp" + +extern "C" { +#include "src/overlays/actors/ovl_En_Elf/z_en_elf.h" +} + +static constexpr int32_t CVAR_INVISIBLENAVI_DEFAULT = 0; +#define CVAR_INVISIBLENAVI_NAME CVAR_COSMETIC("InvisibleNavi") +#define CVAR_INVISIBLENAVI_VALUE CVarGetInteger(CVAR_INVISIBLENAVI_NAME, CVAR_INVISIBLENAVI_DEFAULT) + +void RegisterInvisibleNavi() { + COND_VB_SHOULD(VB_FAIRY_DRAW, CVAR_INVISIBLENAVI_VALUE, { + EnElf* enElf = va_arg(args, EnElf*); + if (enElf->actor.params == FAIRY_NAVI) { + *should = false; + } + }); + + COND_VB_SHOULD(VB_FAIRY_SPAWN_SPARKLES, CVAR_INVISIBLENAVI_VALUE, { + EnElf* enElf = va_arg(args, EnElf*); + if (enElf->actor.params == FAIRY_NAVI) { + *should = false; + } + }); + + COND_VB_SHOULD(VB_FAIRY_PLAY_C_UP_TALK_SOUND, CVAR_INVISIBLENAVI_VALUE, { + EnElf* enElf = va_arg(args, EnElf*); + if (enElf->actor.params == FAIRY_NAVI) { + *should = false; + } + }); + + COND_VB_SHOULD(VB_FAIRY_PLAY_DASH_SOUND, CVAR_INVISIBLENAVI_VALUE, { + EnElf* enElf = va_arg(args, EnElf*); + if (enElf->actor.params == FAIRY_NAVI) { + *should = false; + } + }); + + COND_VB_SHOULD(VB_FAIRY_PLAY_VANISH_SOUND, CVAR_INVISIBLENAVI_VALUE, { + EnElf* enElf = va_arg(args, EnElf*); + if (enElf->actor.params == FAIRY_NAVI) { + *should = false; + } + }); + + COND_VB_SHOULD(VB_FAIRY_UPDATE_LIGHTS, CVAR_INVISIBLENAVI_VALUE, { + EnElf* enElf = va_arg(args, EnElf*); + if (enElf->actor.params == FAIRY_NAVI) { + // Force Navi's light radius to zero. + Lights_PointGlowSetInfo(&enElf->lightInfoGlow, enElf->actor.world.pos.x, enElf->actor.world.pos.y, + enElf->actor.world.pos.z, 255, 255, 255, 0); + *should = false; + } + }); + + COND_VB_SHOULD(VB_PLAY_NAVI_CALL_SOUND, CVAR_INVISIBLENAVI_VALUE, { *should = false; }); + + COND_VB_SHOULD(VB_PLAY_INTRO_NAVI_SOUNDS, CVAR_INVISIBLENAVI_VALUE, { *should = false; }); +} + +static RegisterShipInitFunc initFunc(RegisterInvisibleNavi, { CVAR_INVISIBLENAVI_NAME }); \ No newline at end of file diff --git a/soh/soh/Enhancements/customequipment.cpp b/soh/soh/Enhancements/customequipment.cpp index 1ce4c79048e..21dc19a2cdc 100644 --- a/soh/soh/Enhancements/customequipment.cpp +++ b/soh/soh/Enhancements/customequipment.cpp @@ -78,11 +78,16 @@ static void UpdateCustomEquipment() { RefreshCustomEquipment(); } +static void OnBottleHeldChanged(s32 item, s32 actionParam) { + RefreshCustomEquipment(); +} + static void PatchCustomEquipment() { COND_HOOK(OnPlayerSetModels, true, UpdateCustomEquipmentSetModel); COND_HOOK(OnLinkEquipmentChange, true, UpdateCustomEquipment); COND_HOOK(OnLinkSkeletonInit, true, UpdateCustomEquipment); COND_HOOK(OnAssetAltChange, true, UpdateCustomEquipment); + COND_HOOK(OnPlayerBottleHeldChanged, true, OnBottleHeldChanged); } static RegisterShipInitFunc initFunc(PatchCustomEquipment); @@ -476,6 +481,97 @@ static void ApplyCommonEquipmentPatches() { }); } +static s32 sLastBottleContentIndex = -1; + +static void ResetBottlePatch() { + const bool isChild = LINK_IS_CHILD; + const char* bottleDL = isChild ? gLinkChildBottleDL : gLinkAdultBottleDL; + + UnpatchGroup(bottleDL, { "customBottle1", "customBottle2", "customBottle3" }); + sLastBottleContentIndex = -1; +} + +static void ApplyBottleContentPatches() { + constexpr s32 BOTTLE_EMPTY = 0; + constexpr s32 BOTTLE_MILK_FULL = PLAYER_IA_BOTTLE_MILK_FULL - PLAYER_IA_BOTTLE; + constexpr s32 BOTTLE_MILK_HALF = PLAYER_IA_BOTTLE_MILK_HALF - PLAYER_IA_BOTTLE; + constexpr s32 BOTTLE_FAIRY = PLAYER_IA_BOTTLE_FAIRY - PLAYER_IA_BOTTLE; + constexpr s32 BOTTLE_ACTION_COUNT = BOTTLE_FAIRY + 1; + + const char* bottleContentDLs[] = { + nullptr, // 0: PLAYER_IA_BOTTLE (empty - no custom content needed) + gCustomBottleFishDL, // 1: PLAYER_IA_BOTTLE_FISH + gCustomBottleBlueFireDL, // 2: PLAYER_IA_BOTTLE_FIRE + gCustomBottleBugDL, // 3: PLAYER_IA_BOTTLE_BUG + gCustomBottlePoeDL, // 4: PLAYER_IA_BOTTLE_POE + gCustomBottleBigPoeDL, // 5: PLAYER_IA_BOTTLE_BIG_POE + gCustomBottleLetterDL, // 6: PLAYER_IA_BOTTLE_RUTOS_LETTER + gCustomBottleRedPotionDL, // 7: PLAYER_IA_BOTTLE_POTION_RED + gCustomBottleBluePotionDL, // 8: PLAYER_IA_BOTTLE_POTION_BLUE + gCustomBottleGreenPotionDL, // 9: PLAYER_IA_BOTTLE_POTION_GREEN + gCustomBottleMilkDL, // 10: PLAYER_IA_BOTTLE_MILK_FULL + gCustomBottleMilkHalfDL, // 11: PLAYER_IA_BOTTLE_MILK_HALF + gCustomBottleFairyDL, // 12: PLAYER_IA_BOTTLE_FAIRY + }; + + if (!ResourceMgr_IsAltAssetsEnabled()) { + ResetBottlePatch(); + ResourceMgr_UnloadResource(gCustomBottleDL); + return; + } + + bool bottleDLAvailable = ResourceGetIsCustomByName(gCustomBottleDL) || ResourceMgr_FileExists(gCustomBottleDL); + + if (!bottleDLAvailable) { + return; + } + + if (gPlayState == nullptr) { + return; + } + + Player* player = GET_PLAYER(gPlayState); + if (player == nullptr) { + return; + } + + s32 bottleIndex = player->itemAction - PLAYER_IA_BOTTLE; + + // Special case: when drinking milk, preserve the half-full visual instead of showing empty + if (sLastBottleContentIndex == BOTTLE_MILK_FULL && bottleIndex == BOTTLE_EMPTY) { + bottleIndex = BOTTLE_MILK_HALF; + } + + bool isBottleAction = (bottleIndex >= 0 && bottleIndex < BOTTLE_ACTION_COUNT); + + if (!isBottleAction) { + if (sLastBottleContentIndex != -1) { + ResetBottlePatch(); + } + return; + } + + if (sLastBottleContentIndex == bottleIndex) { + return; + } + + const bool isChild = LINK_IS_CHILD; + const char* bottleDL = isChild ? gLinkChildBottleDL : gLinkAdultBottleDL; + + const char* contentDL = bottleContentDLs[bottleIndex]; + + if (contentDL && !ResourceMgr_FileExists(contentDL) && !ResourceGetIsCustomByName(contentDL)) { + contentDL = nullptr; + } + + ApplyPatchEntries({ + { bottleDL, gCustomBottleDL, "customBottle1", "customBottle2", contentDL ? "customBottle3" : nullptr, + contentDL }, + }); + + sLastBottleContentIndex = bottleIndex; +} + void UpdatePatchCustomEquipmentDlists() { const u8 equippedSword = GetEquippedSwordItem(); @@ -510,4 +606,5 @@ void UpdatePatchCustomEquipmentDlists() { } ApplyCommonEquipmentPatches(); + ApplyBottleContentPatches(); } diff --git a/soh/soh/Enhancements/debugger/debugSaveEditor.cpp b/soh/soh/Enhancements/debugger/debugSaveEditor.cpp index 4d5b459b460..b2f30502530 100644 --- a/soh/soh/Enhancements/debugger/debugSaveEditor.cpp +++ b/soh/soh/Enhancements/debugger/debugSaveEditor.cpp @@ -1927,7 +1927,6 @@ void SaveEditorWindow::DrawElement() { DrawPlayerTab(); ImGui::EndTabItem(); } - ImGui::EndTabBar(); } diff --git a/soh/soh/Enhancements/game-interactor/GameInteractor_HookTable.h b/soh/soh/Enhancements/game-interactor/GameInteractor_HookTable.h index 93cee420ea2..cf0896ad904 100644 --- a/soh/soh/Enhancements/game-interactor/GameInteractor_HookTable.h +++ b/soh/soh/Enhancements/game-interactor/GameInteractor_HookTable.h @@ -47,6 +47,7 @@ DEFINE_HOOK(OnPlayerBonk, ()); DEFINE_HOOK(OnPlayerSetModels, (Player * player, u8 modelGroup)); DEFINE_HOOK(OnPlayerHealthChange, (int16_t amount)); DEFINE_HOOK(OnPlayerBottleUpdate, (int16_t contents)); +DEFINE_HOOK(OnPlayerBottleHeldChanged, (s32 item, s32 actionParam)); DEFINE_HOOK(OnPlayerHoldUpShield, ()); DEFINE_HOOK(OnPlayerFirstPersonControl, (Player * player)); DEFINE_HOOK(OnPlayerProcessStick, ()); diff --git a/soh/soh/Enhancements/game-interactor/GameInteractor_Hooks.cpp b/soh/soh/Enhancements/game-interactor/GameInteractor_Hooks.cpp index 480b981c45f..1fa545a8da5 100644 --- a/soh/soh/Enhancements/game-interactor/GameInteractor_Hooks.cpp +++ b/soh/soh/Enhancements/game-interactor/GameInteractor_Hooks.cpp @@ -102,6 +102,10 @@ void GameInteractor_ExecuteOnPlayerUpdate() { GameInteractor::Instance->ExecuteHooks(); } +void GameInteractor_ExecuteOnPlayerBottleHeldChanged(s32 item, s32 actionParam) { + GameInteractor::Instance->ExecuteHooks(item, actionParam); +} + void GameInteractor_ExecuteOnSetDoAction(uint16_t action) { GameInteractor::Instance->ExecuteHooks(action); } diff --git a/soh/soh/Enhancements/game-interactor/GameInteractor_Hooks.h b/soh/soh/Enhancements/game-interactor/GameInteractor_Hooks.h index 6bcd0dc9765..222a9a7169a 100644 --- a/soh/soh/Enhancements/game-interactor/GameInteractor_Hooks.h +++ b/soh/soh/Enhancements/game-interactor/GameInteractor_Hooks.h @@ -29,6 +29,7 @@ void GameInteractor_ExecuteOnSceneSpawnActors(); void GameInteractor_ExecuteOnLinkSkeletonInit(); void GameInteractor_ExecuteOnLinkEquipmentChange(); void GameInteractor_ExecuteOnPlayerUpdate(); +void GameInteractor_ExecuteOnPlayerBottleHeldChanged(s32 item, s32 actionParam); void GameInteractor_ExecuteOnSetDoAction(uint16_t action); void GameInteractor_ExecuteOnPlayerSfx(u16 sfxId); void GameInteractor_ExecuteOnOcarinaSongAction(); diff --git a/soh/soh/Enhancements/game-interactor/vanilla-behavior/GIVanillaBehavior.h b/soh/soh/Enhancements/game-interactor/vanilla-behavior/GIVanillaBehavior.h index da262f6ea2f..289a454aa94 100644 --- a/soh/soh/Enhancements/game-interactor/vanilla-behavior/GIVanillaBehavior.h +++ b/soh/soh/Enhancements/game-interactor/vanilla-behavior/GIVanillaBehavior.h @@ -236,6 +236,15 @@ typedef enum { // - `*Actor` (interactRangeActor) VB_BOTTLE_ACTOR, + // #### `result` + // Actor is ACTOR_OBJ_BOMBIWA, or ACTOR_OBJ_HAMISHI + // ```c + // Flags_GetSwitch(play, this->actor.params & 0x3F) + // ``` + // #### `args` + // - `*Actor` (interactRangeActor) + VB_BOULDER_BREAK_FLAG, + // #### `result` // ```c // true @@ -342,6 +351,14 @@ typedef enum { // - None VB_CRAWL, + // #### `result` + // ```c + // true + // ``` + // #### `args` + // - None + VB_ROLL, + // #### `result` // ```c // true @@ -570,6 +587,14 @@ typedef enum { // - `int32_t` (startMode) VB_EXECUTE_PLAYER_STARTMODE_FUNC, + // #### `result` + // ```c + // ((this->unk_2A8 != 8) && !(this->fairyFlags & 8)) + // ``` + // #### `args` + // - `*EnElf` + VB_FAIRY_DRAW, + // #### `result` // ```c // true @@ -578,6 +603,47 @@ typedef enum { // - `*EnElf` VB_FAIRY_HEAL, + // #### `result` + // ```c + // true + // ``` + // #### `args` + // - `*EnElf` + // - `int32_t` (sparkleLife) + VB_FAIRY_SPAWN_SPARKLES, + + // #### `result` + // ```c + // true + // ``` + // #### `args` + // - `*EnElf` + VB_FAIRY_PLAY_C_UP_TALK_SOUND, + + // #### `result` + // ```c + // true + // ``` + // #### `args` + // - `*EnElf` + VB_FAIRY_PLAY_DASH_SOUND, + + // #### `result` + // ```c + // true + // ``` + // #### `args` + // - `*EnElf` + VB_FAIRY_PLAY_VANISH_SOUND, + + // #### `result` + // ```c + // true + // ``` + // #### `args` + // - `*EnElf` + VB_FAIRY_UPDATE_LIGHTS, + // #### `result` // ```c // false @@ -1696,6 +1762,14 @@ typedef enum { // - None VB_PLAY_GORON_FREE_CS, + // #### `result` + // ```c + // true + // ``` + // #### `args` + // - `*ObjectKankyo` + VB_PLAY_INTRO_NAVI_SOUNDS, + // #### `result` // ```c // true @@ -1720,6 +1794,14 @@ typedef enum { // - None VB_PLAY_NABOORU_CAPTURED_CS, + // #### `result` + // ```c + // true + // ``` + // #### `args` + // - `int32_t` (naviCallState) (promoted from `uint16_t` by va_arg) + VB_PLAY_NAVI_CALL_SOUND, + // #### `result` // ```c // true @@ -1944,6 +2026,14 @@ typedef enum { // - None VB_REVERT_SPOILING_ITEMS, + // #### `result` + // ```c + // false + // ``` + // #### `args` + // - `*EnIshi` + VB_ROCK_DROP_ITEM, + // #### `result` // ```c // !Flags_GetInfTable(INFTABLE_145) @@ -2394,6 +2484,14 @@ typedef enum { // - `*Actor` VB_RECIEVE_FALL_DAMAGE, + // #### `result` + // ```c + // true + // ``` + // #### `args` + // - `*EnRr` + VB_LIKE_LIKE_DROP_COLLECTIBLE, + // #### `result` // ```c // true @@ -2402,6 +2500,14 @@ typedef enum { // - `*EnRr` VB_LIKE_LIKE_GRAB_PLAYER, + // #### `result` + // ```c + // true + // ``` + // #### `args` + // - `*EnRr` + VB_LIKE_LIKE_STEAL_EQUIPMENT, + // #### `result` // ```c // entry != NULL diff --git a/soh/soh/Enhancements/gameplaystats.cpp b/soh/soh/Enhancements/gameplaystats.cpp index 6b2e1c72140..545dfbed520 100644 --- a/soh/soh/Enhancements/gameplaystats.cpp +++ b/soh/soh/Enhancements/gameplaystats.cpp @@ -448,7 +448,7 @@ void DrawGameplayStatsHeader() { // if tag is empty (not a release build) if (gGitCommitTag[0] == 0) { GameplayStatsRow("Git Branch:", (char*)gGitBranch); - GameplayStatsRow("Git Commit Hash:", (char*)gGitCommitHash); + GameplayStatsRow("Version : 14.2 | Git Commit Hash:", (char*)gGitCommitHash); } else { GameplayStatsRow("Build Version:", (char*)gBuildVersion); } diff --git a/soh/soh/Enhancements/kaleido.cpp b/soh/soh/Enhancements/kaleido.cpp index 68e78032a2c..f37501451ea 100644 --- a/soh/soh/Enhancements/kaleido.cpp +++ b/soh/soh/Enhancements/kaleido.cpp @@ -202,6 +202,12 @@ Kaleido::Kaleido() { 32, aButtonColor, FlagType::FLAG_RANDOMIZER_INF, RAND_INF_CAN_GRAB, "Grab")); } + if (ctx->GetOption(RSK_SHUFFLE_ROLL)) { + mEntries.push_back(std::make_shared(gButtonBackgroundTex, G_IM_FMT_IA, G_IM_SIZ_8b, 32, + 32, aButtonColor, FlagType::FLAG_RANDOMIZER_INF, + RAND_INF_CAN_ROLL, "Roll")); + } + if (ctx->GetOption(RSK_SHUFFLE_SPEAK)) { int rg = RG_SPEAK_DEKU; for (int i = RAND_INF_CAN_SPEAK_DEKU; i <= RAND_INF_CAN_SPEAK_ZORA; i++, rg++) { diff --git a/soh/soh/Enhancements/randomizer/3drando/hint_list/hint_list_exclude_dungeon.cpp b/soh/soh/Enhancements/randomizer/3drando/hint_list/hint_list_exclude_dungeon.cpp index aa375716f68..87880711616 100644 --- a/soh/soh/Enhancements/randomizer/3drando/hint_list/hint_list_exclude_dungeon.cpp +++ b/soh/soh/Enhancements/randomizer/3drando/hint_list/hint_list_exclude_dungeon.cpp @@ -131,6 +131,10 @@ void StaticData::HintTable_Init_Exclude_Dungeon() { /*german*/ "Man erzählt sich, daß eine #Kiste im Deku-Baum# #[[1]]# enthielte.", /*french*/ "Selon moi, une #caisse dans l'Arbre Mojo# contient #[[1]]#.", {QM_RED, QM_GREEN})); + hintTextTable[RHT_DEKU_BOULDER] = HintText(CustomMessage("They say that a #boulder in the Deku Tree# contains #[[1]]#.", + /*german*/ "!!!", + /*french*/ "!!!", {QM_RED, QM_GREEN})); + /*-------------------------- | DODONGOS CAVERN | ---------------------------*/ @@ -313,6 +317,10 @@ void StaticData::HintTable_Init_Exclude_Dungeon() { /*german*/ "Man erzählt sich, daß eine #Kiste in Dodongos Höhle# #[[1]]# enthielte.", /*french*/ "Selon moi, une #caisse dans la Caverne Dodongo# contient #[[1]]#.", {QM_RED, QM_GREEN})); + hintTextTable[RHT_DODONGOS_BOULDER] = HintText(CustomMessage("They say that a #boulder in Dodongo's Cavern# contains #[[1]]#.", + /*german*/ "!!!", + /*french*/ "!!!", {QM_RED, QM_GREEN})); + /*-------------------------- | JABU JABUS BELLY | ---------------------------*/ @@ -480,6 +488,10 @@ void StaticData::HintTable_Init_Exclude_Dungeon() { /*german*/ "Man erzählt sich, daß eine #Kiste in Jabu-Jabus Bauch# #[[1]]# enthielte.", /*french*/ "Selon moi, une #caisse dans le Ventre de Jabu-Jabu# contient #[[1]]#.", {QM_RED, QM_GREEN})); + hintTextTable[RHT_JABU_BOULDER] = HintText(CustomMessage("They say that a #boulder in Jabu Jabu's Belly# contains #[[1]]#.", + /*german*/ "!!!", + /*french*/ "!!!", {QM_RED, QM_GREEN})); + /*-------------------------- | FOREST TEMPLE | ---------------------------*/ @@ -1322,6 +1334,10 @@ void StaticData::HintTable_Init_Exclude_Dungeon() { /*german*/ "Man erzählt sich, daß eine #Kiste im Geistertempel# #[[1]]# enthielte.", /*french*/ "Selon moi, une #caisse dans le Temple de l'Esprit# contient #[[1]]#.", {QM_RED, QM_GREEN})); + hintTextTable[RHT_SPIRIT_TEMPLE_BOULDER] = HintText(CustomMessage("They say that a #boulder in the Spirit Temple# contains #[[1]]#.", + /*german*/ "!!!", + /*french*/ "!!!", {QM_RED, QM_GREEN})); + /*-------------------------- | SHADOW TEMPLE | ---------------------------*/ @@ -1735,6 +1751,9 @@ void StaticData::HintTable_Init_Exclude_Dungeon() { /*german*/ "Man erzählt sich, daß etwas #Gras auf dem Grund des Brunnens# #[[1]]# verstecke.", /*french*/ "Selon moi, de l'#herbe dans le Puits# cache #[[1]]#.", {QM_RED, QM_GREEN})); + hintTextTable[RHT_BOTW_BOULDER] = HintText(CustomMessage("They say that a #boulder in Bottom of the Well# contains #[[1]]#.", + /*german*/ "!!!", + /*french*/ "!!!", {QM_RED, QM_GREEN})); /*-------------------------- | ICE CAVERN | diff --git a/soh/soh/Enhancements/randomizer/3drando/hint_list/hint_list_exclude_overworld.cpp b/soh/soh/Enhancements/randomizer/3drando/hint_list/hint_list_exclude_overworld.cpp index 487c761584b..d1cfdd1f866 100644 --- a/soh/soh/Enhancements/randomizer/3drando/hint_list/hint_list_exclude_overworld.cpp +++ b/soh/soh/Enhancements/randomizer/3drando/hint_list/hint_list_exclude_overworld.cpp @@ -2126,6 +2126,113 @@ void StaticData::HintTable_Init_Exclude_Overworld() { HintText(CustomMessage("They say that a #tree in Lon Lon Ranch# contains #[[1]]#.", /*german*/ "", /*french*/ "Selon moi, un #arbre au Ranch Lon Lon# cache #[[1]]#.", { QM_RED, QM_GREEN })); + hintTextTable[RHT_KF_ROCK] = HintText(CustomMessage("They say that a #rock in Kokiri Forest# contains #[[1]]#.", + /*german*/ "", + /*french*/ "Selon moi, une #roche dans la Fôret Kokiri# contient #[[1]]#.", {QM_RED, QM_GREEN})); + hintTextTable[RHT_LW_BOULDER] = HintText(CustomMessage("They say that a #boulder in the Lost Woods# contains #[[1]]#.", + /*german*/ "", + /*french*/ "", {QM_RED, QM_GREEN})); + hintTextTable[RHT_HC_ROCK] = HintText(CustomMessage("They say that a #rock at Hyrule Castle# contains #[[1]]#.", + /*german*/ "", + /*french*/ "", {QM_RED, QM_GREEN})); + hintTextTable[RHT_HC_BOULDER] = HintText(CustomMessage("They say that a #boulder at Hyrule Castle# contains #[[1]]#.", + /*german*/ "", + /*french*/ "", {QM_RED, QM_GREEN})); + hintTextTable[RHT_OGC_BRONZE_BOULDER] = HintText(CustomMessage("They say that a #bronze boulder outside Ganon's Castle# contains #[[1]]#.", + /*german*/ "", + /*french*/ "", {QM_RED, QM_GREEN})); + hintTextTable[RHT_OGC_SILVER_BOULDER] = HintText(CustomMessage("They say that a #silver boulder outside Ganon's Castle# contains #[[1]]#.", + /*german*/ "", + /*french*/ "", {QM_RED, QM_GREEN})); + hintTextTable[RHT_DMC_ROCK] = HintText(CustomMessage("They say that a #rock in Death Mountain Crater# contains #[[1]]#.", + /*german*/ "", + /*french*/ "", {QM_RED, QM_GREEN})); + hintTextTable[RHT_DMC_BOULDER] = HintText(CustomMessage("They say that a #boulder in Death Mountain Crater# contains #[[1]]#.", + /*german*/ "", + /*french*/ "", {QM_RED, QM_GREEN})); + hintTextTable[RHT_DMC_BRONZE_BOULDER] = HintText(CustomMessage("They say that a #bronze boulder in Death Mountain Crater# contains #[[1]]#.", + /*german*/ "", + /*french*/ "", {QM_RED, QM_GREEN})); + hintTextTable[RHT_GV_SILVER_BOULDER] = HintText(CustomMessage("They say that a #silver boulder in Gerudo Valley# contains #[[1]]#.", + /*german*/ "", + /*french*/ "", {QM_RED, QM_GREEN})); + hintTextTable[RHT_GV_ROCK] = HintText(CustomMessage("They say that a #rock in Gerudo Valley# contains #[[1]]#.", + /*german*/ "", + /*french*/ "", {QM_RED, QM_GREEN})); + hintTextTable[RHT_GV_BOULDER] = HintText(CustomMessage("They say that a #boulder in Gerudo Valley# contains #[[1]]#.", + /*german*/ "", + /*french*/ "", {QM_RED, QM_GREEN})); + hintTextTable[RHT_GV_BRONZE_BOULDER] = HintText(CustomMessage("They say that a #bronze boulder in Gerudo Valley# contains #[[1]]#.", + /*german*/ "", + /*french*/ "", {QM_RED, QM_GREEN})); + hintTextTable[RHT_HF_SILVER_BOULDER] = HintText(CustomMessage("They say that a #silver boulder on Hyrule Field# contains #[[1]]#.", + /*german*/ "", + /*french*/ "", {QM_RED, QM_GREEN})); + hintTextTable[RHT_HF_ROCK] = HintText(CustomMessage("They say that a #rock on Hyrule Field# contains #[[1]]#.", + /*german*/ "", + /*french*/ "", {QM_RED, QM_GREEN})); + hintTextTable[RHT_HF_BOULDER] = HintText(CustomMessage("They say that a #boulder on Hyrule Field# contains #[[1]]#.", + /*german*/ "", + /*french*/ "", {QM_RED, QM_GREEN})); + hintTextTable[RHT_HF_BRONZE_BOULDER] = HintText(CustomMessage("They say that a #bronze boulder on Hyrule Field# contains #[[1]]#.", + /*german*/ "", + /*french*/ "", {QM_RED, QM_GREEN})); + hintTextTable[RHT_KAK_SILVER_BOULDER] = HintText(CustomMessage("They say that a #silver boulder at Kakariko Village# contains #[[1]]#.", + /*german*/ "", + /*french*/ "", {QM_RED, QM_GREEN})); + hintTextTable[RHT_KAK_ROCK] = HintText(CustomMessage("They say that a #rock at Kakariko Village# contains #[[1]]#.", + /*german*/ "", + /*french*/ "", {QM_RED, QM_GREEN})); + hintTextTable[RHT_GY_ROCK] = HintText(CustomMessage("They say that a #rock in a graveyard# contains #[[1]]#.", + /*german*/ "", + /*french*/ "", {QM_RED, QM_GREEN})); + + hintTextTable[RHT_LA_ROCK] = HintText(CustomMessage("They say that a #rock at Lake Hylia# contains #[[1]]#.", + /*german*/ "", + /*french*/ "", {QM_RED, QM_GREEN})); + + hintTextTable[RHT_ZD_ROCK] = HintText(CustomMessage("They say that a #rock in Zora's Domain# contains #[[1]]#.", + /*german*/ "", + /*french*/ "", {QM_RED, QM_GREEN})); + hintTextTable[RHT_ZF_BOULDER] = HintText(CustomMessage("They say that a #boulder in Zora's Fountain# contains #[[1]]#.", + /*german*/ "", + /*french*/ "", {QM_RED, QM_GREEN})); + hintTextTable[RHT_ZF_SILVER_BOULDER] = HintText(CustomMessage("They say that a #silver boulder in Zora's Fountain# contains #[[1]]#.", + /*german*/ "", + /*french*/ "", {QM_RED, QM_GREEN})); + hintTextTable[RHT_ZR_ROCK] = HintText(CustomMessage("They say that a #rock along a river# contains #[[1]]#.", + /*german*/ "", + /*french*/ "", {QM_RED, QM_GREEN})); + hintTextTable[RHT_ZR_BOULDER] = HintText(CustomMessage("They say that a #boulder along a river# contains #[[1]]#.", + /*german*/ "", + /*french*/ "", {QM_RED, QM_GREEN})); + hintTextTable[RHT_DMT_ROCK] = HintText(CustomMessage("They say that a #rock on Death Mountain Trail# contains #[[1]]#.", + /*german*/ "", + /*french*/ "", {QM_RED, QM_GREEN})); + hintTextTable[RHT_DMT_BOULDER] = HintText(CustomMessage("They say that a #boulder on Death Mountain Trail# contains #[[1]]#.", + /*german*/ "", + /*french*/ "", {QM_RED, QM_GREEN})); + hintTextTable[RHT_DMT_BRONZE_BOULDER] = HintText(CustomMessage("They say that a #bronze boulder on Death Mountain Trail# contains #[[1]]#.", + /*german*/ "", + /*french*/ "", {QM_RED, QM_GREEN})); + hintTextTable[RHT_GC_ROCK] = HintText(CustomMessage("They say that a #rock in Goron City# contains #[[1]]#.", + /*german*/ "", + /*french*/ "", {QM_RED, QM_GREEN})); + hintTextTable[RHT_GC_BOULDER] = HintText(CustomMessage("They say that a #boulder in Goron City# contains #[[1]]#.", + /*german*/ "", + /*french*/ "", {QM_RED, QM_GREEN})); + hintTextTable[RHT_GC_BRONZE_BOULDER] = HintText(CustomMessage("They say that a #bronze boulder in Goron City# contains #[[1]]#.", + /*german*/ "", + /*french*/ "", {QM_RED, QM_GREEN})); + hintTextTable[RHT_GC_SILVER_BOULDER] = HintText(CustomMessage("They say that a #silver boulder in Goron City# contains #[[1]]#.", + /*german*/ "", + /*french*/ "", {QM_RED, QM_GREEN})); + hintTextTable[RHT_COLOSSUS_SILVER_BOULDER] = HintText(CustomMessage("They say that a #silver boulder in a desert# contains #[[1]]#.", + /*german*/ "", + /*french*/ "", {QM_RED, QM_GREEN})); + hintTextTable[RHT_COLOSSUS_ROCK] = HintText(CustomMessage("They say that a #rock in a desert# contains #[[1]]#.", + /*german*/ "", + /*french*/ "", {QM_RED, QM_GREEN})); hintTextTable[RHT_BUSH_HYRULE_FIELD] = HintText(CustomMessage("They say that a #bush in Hyrle Field# contains #[[1]]#.", diff --git a/soh/soh/Enhancements/randomizer/3drando/hint_list/hint_list_item.cpp b/soh/soh/Enhancements/randomizer/3drando/hint_list/hint_list_item.cpp index 5783be19ca3..1492a9ccace 100644 --- a/soh/soh/Enhancements/randomizer/3drando/hint_list/hint_list_item.cpp +++ b/soh/soh/Enhancements/randomizer/3drando/hint_list/hint_list_item.cpp @@ -2121,6 +2121,11 @@ void StaticData::HintTable_Init_Item() { hintTextTable[RHT_CLIMB] = HintText(CustomMessage("the ability to climb", /*german*/TODO_TRANSLATE, /*french*/"la capacité de grimper")); hintTextTable[RHT_CRAWL] = HintText(CustomMessage("the ability to crawl", /*german*/TODO_TRANSLATE, /*french*/"la capacité de ramper")); hintTextTable[RHT_OPEN_CHEST] = HintText(CustomMessage("the ability to open chests", /*german*/TODO_TRANSLATE, /*french*/TODO_TRANSLATE)); + + //RANDOTODO if these are ever used for anything other than name, they want abscure and ambiguous hints + + hintTextTable[RHT_ROLL] = HintText(CustomMessage("the ability to roll", /*german*/"die Fähigkeit zu rollen", /*french*/"la capacité de faire des roulades")); + hintTextTable[RHT_SPEAK] = HintText(CustomMessage("the ability to speak", /*german*/TODO_TRANSLATE, /*french*/"la faculté de parler")); hintTextTable[RHT_QUIVER_INF] = HintText(CustomMessage("an infinite Quiver", /*german*/"der unendliche Köcher", /*french*/"un Carquois Infini")); diff --git a/soh/soh/Enhancements/randomizer/3drando/item_pool.cpp b/soh/soh/Enhancements/randomizer/3drando/item_pool.cpp index 15ccebba77d..b92184ffdff 100644 --- a/soh/soh/Enhancements/randomizer/3drando/item_pool.cpp +++ b/soh/soh/Enhancements/randomizer/3drando/item_pool.cpp @@ -408,6 +408,9 @@ void GenerateItemPool() { if (ctx->GetOption(RSK_SHUFFLE_CLIMB)) { AddItemToPool(RG_CLIMB, 2, 1, 1, 1); } + if (ctx->GetOption(RSK_SHUFFLE_ROLL)) { + AddItemToPool(RG_ROLL, 2, 1, 1, 1); + } if (ctx->GetOption(RSK_SHUFFLE_CRAWL)) { AddItemToPool(RG_CRAWL, 2, 1, 1, 1); } @@ -456,6 +459,17 @@ void GenerateItemPool() { ctx->GetOption(RSK_LOGIC_RULES).Is(RO_LOGIC_NO_LOGIC) && dungeonCratesActive); PlaceItemsForType(RCTYPE_SMALL_CRATE, overworldCratesActive, dungeonCratesActive); + // Shuffle Rocks + bool rocksActive = ctx->GetOption(RSK_SHUFFLE_ROCKS).Get(); + PlaceItemsForType(RCTYPE_ROCK, rocksActive, rocksActive); + + // Shuffle Boulders + bool overworldBouldersActive = ctx->GetOption(RSK_SHUFFLE_BOULDERS).Is(RO_SHUFFLE_BOULDERS_OVERWORLD) || + ctx->GetOption(RSK_SHUFFLE_BOULDERS).Is(RO_SHUFFLE_BOULDERS_ALL); + bool dungeonBouldersActive = ctx->GetOption(RSK_SHUFFLE_BOULDERS).Is(RO_SHUFFLE_BOULDERS_DUNGEONS) || + ctx->GetOption(RSK_SHUFFLE_BOULDERS).Is(RO_SHUFFLE_BOULDERS_ALL); + PlaceItemsForType(RCTYPE_BOULDER, overworldBouldersActive, dungeonBouldersActive); + if (ctx->GetOption(RSK_FISHSANITY).Is(RO_FISHSANITY_HYRULE_LOACH)) { AddFixedItemToPool(RG_PURPLE_RUPEE, 1); } else { @@ -946,4 +960,4 @@ void GenerateItemPool() { } assert(itemPool.size() == locCount); -} +} \ No newline at end of file diff --git a/soh/soh/Enhancements/randomizer/3drando/shops.cpp b/soh/soh/Enhancements/randomizer/3drando/shops.cpp index 92684c9a6ab..b296541da3a 100644 --- a/soh/soh/Enhancements/randomizer/3drando/shops.cpp +++ b/soh/soh/Enhancements/randomizer/3drando/shops.cpp @@ -1005,6 +1005,10 @@ void InitTrickNames() { // TODO_TRANSLATE Text{ "Crouch" }, }; + trickNameTable[RG_ROLL] = { + // TODO_TRANSLATE + Text{ "Roll" }, + }; trickNameTable[RG_OPEN_CHEST] = { // TODO_TRANSLATE Text{ "Open Cheats" }, diff --git a/soh/soh/Enhancements/randomizer/SeedContext.cpp b/soh/soh/Enhancements/randomizer/SeedContext.cpp index 41a6cb02b3d..21658b3f709 100644 --- a/soh/soh/Enhancements/randomizer/SeedContext.cpp +++ b/soh/soh/Enhancements/randomizer/SeedContext.cpp @@ -50,6 +50,8 @@ Context::Context() { &mOptions[RSK_SHUFFLE_COWS], &mOptions[RSK_SHUFFLE_POTS], &mOptions[RSK_SHUFFLE_CRATES], + &mOptions[RSK_SHUFFLE_ROCKS], + &mOptions[RSK_SHUFFLE_BOULDERS], &mOptions[RSK_SHUFFLE_FREESTANDING], &mOptions[RSK_SHUFFLE_MERCHANTS], &mOptions[RSK_SHUFFLE_FROG_SONG_RUPEES], @@ -214,6 +216,8 @@ void Context::GenerateLocationPool() { (location.GetRCType() == RCTYPE_TREE && !mOptions[RSK_SHUFFLE_TREES]) || (location.GetRCType() == RCTYPE_NLTREE && (!mOptions[RSK_SHUFFLE_TREES] || mOptions[RSK_LOGIC_RULES].IsNot(RO_LOGIC_NO_LOGIC))) || + (location.GetRCType() == RCTYPE_ROCK && !mOptions[RSK_SHUFFLE_ROCKS]) || + (location.GetRCType() == RCTYPE_BOULDER && mOptions[RSK_SHUFFLE_BOULDERS].Is(RO_SHUFFLE_BOULDERS_OFF)) || (location.GetRCType() == RCTYPE_BUSH && !mOptions[RSK_SHUFFLE_BUSHES]) || (location.GetRCType() == RCTYPE_FREESTANDING && mOptions[RSK_SHUFFLE_FREESTANDING].Is(RO_SHUFFLE_FREESTANDING_OFF)) || @@ -232,7 +236,9 @@ void Context::GenerateLocationPool() { mOptions[RSK_SHUFFLE_CRATES].Is(RO_SHUFFLE_CRATES_DUNGEONS) && mOptions[RSK_LOGIC_RULES].Is(RO_LOGIC_NO_LOGIC)) || (location.GetRCType() == RCTYPE_SMALL_CRATE && - mOptions[RSK_SHUFFLE_CRATES].Is(RO_SHUFFLE_CRATES_DUNGEONS))) { + mOptions[RSK_SHUFFLE_CRATES].Is(RO_SHUFFLE_CRATES_DUNGEONS)) && + (location.GetRCType() == RCTYPE_BOULDER && + mOptions[RSK_SHUFFLE_BOULDERS].Is(RO_SHUFFLE_BOULDERS_DUNGEONS))) { continue; } // If we've gotten past all the conditions where an overworld location should not be @@ -253,7 +259,9 @@ void Context::GenerateLocationPool() { mOptions[RSK_SHUFFLE_CRATES].Is(RO_SHUFFLE_CRATES_OVERWORLD) && mOptions[RSK_LOGIC_RULES].Is(RO_LOGIC_NO_LOGIC)) || (location.GetRCType() == RCTYPE_SMALL_CRATE && - mOptions[RSK_SHUFFLE_CRATES].Is(RO_SHUFFLE_CRATES_OVERWORLD))) { + mOptions[RSK_SHUFFLE_CRATES].Is(RO_SHUFFLE_CRATES_OVERWORLD)) && + (location.GetRCType() == RCTYPE_BOULDER && + mOptions[RSK_SHUFFLE_BOULDERS].Is(RO_SHUFFLE_BOULDERS_OVERWORLD))) { continue; } // also add to that dungeon's location list. diff --git a/soh/soh/Enhancements/randomizer/ShuffleRocks.cpp b/soh/soh/Enhancements/randomizer/ShuffleRocks.cpp new file mode 100644 index 00000000000..64c68563205 --- /dev/null +++ b/soh/soh/Enhancements/randomizer/ShuffleRocks.cpp @@ -0,0 +1,725 @@ +#include "ShuffleRocks.h" +#include "soh/Enhancements/enhancementTypes.h" +#include "soh_assets.h" +#include "static_data.h" +#include "soh/ObjectExtension/ObjectExtension.h" + +extern "C" { +#include "variables.h" +#include "overlays/actors/ovl_En_Ishi/z_en_ishi.h" +#include "overlays/actors/ovl_Obj_Bombiwa/z_obj_bombiwa.h" +#include "overlays/actors/ovl_Obj_Hamishi/z_obj_hamishi.h" +#include "objects/gameplay_field_keep/gameplay_field_keep.h" +#include "objects/gameplay_keep/gameplay_keep.h" +#include "objects/object_bombiwa/object_bombiwa.h" +extern PlayState* gPlayState; +} + +#define RAND_GET_OPTION(option) Rando::Context::GetInstance()->GetOption(option).Get() + +extern void EnItem00_DrawRandomizedItem(EnItem00* enItem00, PlayState* play); + +extern "C" void DrawItemCircle(PlayState* play, float scale, RockIdentity rockIdentity) { + GraphicsContext* __gfxCtx = play->state.gfxCtx; + int csmc = CVarGetInteger(CVAR_ENHANCEMENT("ChestSizeAndTextureMatchContents"), 0); + int requiresStoneAgony = CVarGetInteger(CVAR_ENHANCEMENT("ChestSizeDependsStoneOfAgony"), 0); + + u8 r1 = 200, g1 = 200, b1 = 200, r2 = 100, g2 = 100, b2 = 100; + + if ((!requiresStoneAgony || (requiresStoneAgony && CHECK_QUEST_ITEM(QUEST_STONE_OF_AGONY)))) { + auto itemEntry = Rando::Context::GetInstance()->GetFinalGIEntry(rockIdentity.randomizerCheck, true, GI_NONE); + GetItemCategory getItemCategory = itemEntry.getItemCategory; + + switch (getItemCategory) { + case ITEM_CATEGORY_LESSER: + switch (itemEntry.itemId) { + case ITEM_HEART_PIECE: + case ITEM_HEART_PIECE_2: + case ITEM_HEART_CONTAINER: + r1 = 160; + g1 = 80; + b1 = 20; + r2 = 40; + g2 = 160; + b2 = 160; + break; + default: + r1 = 160; + g1 = 140; + b1 = 80; + r2 = 80; + g2 = 70; + b2 = 40; + break; + } + break; + case ITEM_CATEGORY_SMALL_KEY: + r1 = 144; + g1 = 144; + b1 = 144; + r2 = 128; + g2 = 128; + b2 = 128; + break; + case ITEM_CATEGORY_BOSS_KEY: + r1 = 240; + g1 = 220; + b1 = 0; + r2 = 128; + g2 = 128; + b2 = 128; + break; + case ITEM_CATEGORY_SKULLTULA_TOKEN: + r1 = 24; + g1 = 20; + b1 = 0; + r2 = 96; + g2 = 80; + b2 = 0; + break; + case ITEM_CATEGORY_MAJOR: + r1 = 240; + g1 = 220; + b1 = 0; + r2 = 240; + g2 = 220; + b2 = 0; + break; + default: + break; + } + } + + Matrix_Scale(scale, 1.0, scale, MTXMODE_APPLY); + gSPMatrix(POLY_XLU_DISP++, MATRIX_NEWMTX(play->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + gSPSegment(POLY_XLU_DISP++, 0x08, + (uintptr_t)Gfx_TwoTexScroll(play->state.gfxCtx, 0, 0, 0, 16, 32, 1, 0, (play->gameplayFrames * 10) % 128, + 16, 32)); + gDPSetPrimColor(POLY_XLU_DISP++, 0x80, 0x80, r1, g1, b1, 255); + gDPSetEnvColor(POLY_XLU_DISP++, r2, g2, b2, 255); + gSPDisplayList(POLY_XLU_DISP++, (Gfx*)gHoverBootsCircleDL); +} + +extern "C" void EnIshi_RandomizerDraw(Actor* thisx, PlayState* play) { + auto rockActor = ((EnIshi*)thisx); + const auto rockIdentity = ObjectExtension::GetInstance().Get(thisx); + + OPEN_DISPS(play->state.gfxCtx); + Gfx_SetupDL_25Opa(play->state.gfxCtx); + + if (rockActor->actor.params & 1) { + gSPMatrix(POLY_OPA_DISP++, MATRIX_NEWMTX(play->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + gDPSetPrimColor(POLY_OPA_DISP++, 0, 0, 255, 255, 255, 255); + gSPDisplayList(POLY_OPA_DISP++, (Gfx*)gSilverRockDL); + } else { + Gfx_DrawDListOpa(play, (Gfx*)gFieldKakeraDL); + } + + if (rockIdentity != nullptr && rockIdentity->randomizerCheck != RC_MAX && + Flags_GetRandomizerInf(rockIdentity->randomizerInf) == 0) { + + Matrix_Translate(rockActor->actor.world.pos.x, + rockActor->actor.world.pos.y + (rockActor->actor.params & 1 ? 32 : 8), + rockActor->actor.world.pos.z, MTXMODE_NEW); + DrawItemCircle(play, (rockActor->actor.params & 1 ? 8 : 2), *rockIdentity); + } + + CLOSE_DISPS(play->state.gfxCtx); +} + +extern "C" void ObjBombiwa_RandomizerDraw(Actor* thisx, PlayState* play) { + auto rockActor = ((ObjBombiwa*)thisx); + const auto rockIdentity = ObjectExtension::GetInstance().Get(thisx); + + OPEN_DISPS(play->state.gfxCtx); + Gfx_SetupDL_25Opa(play->state.gfxCtx); + + Gfx_DrawDListOpa(play, (Gfx*)object_bombiwa_DL_0009E0); + gSPMatrix(POLY_OPA_DISP++, MATRIX_NEWMTX(play->state.gfxCtx), G_MTX_MODELVIEW | G_MTX_LOAD); + gSPDisplayList(POLY_OPA_DISP++, (Gfx*)object_bombiwa_DL_0009E0); + + if (rockIdentity != nullptr && rockIdentity->randomizerCheck != RC_MAX && + Flags_GetRandomizerInf(rockIdentity->randomizerInf) == 0) { + Matrix_Translate(rockActor->actor.world.pos.x, rockActor->actor.world.pos.y + 32, rockActor->actor.world.pos.z, + MTXMODE_NEW); + DrawItemCircle(play, 8, *rockIdentity); + } + + CLOSE_DISPS(play->state.gfxCtx); +} + +extern "C" void ObjHamishi_RandomizerDraw(Actor* thisx, PlayState* play) { + auto rockActor = ((ObjHamishi*)thisx); + const auto rockIdentity = ObjectExtension::GetInstance().Get(thisx); + + OPEN_DISPS(play->state.gfxCtx); + Gfx_SetupDL_25Opa(play->state.gfxCtx); + + gSPMatrix(POLY_OPA_DISP++, MATRIX_NEWMTX(play->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + gDPSetPrimColor(POLY_OPA_DISP++, 0, 0, 255, 170, 130, 255); + gSPDisplayList(POLY_OPA_DISP++, (Gfx*)gSilverRockDL); + + if (rockIdentity != nullptr && rockIdentity->randomizerCheck != RC_MAX && + Flags_GetRandomizerInf(rockIdentity->randomizerInf) == 0) { + Matrix_Translate(rockActor->actor.world.pos.x, rockActor->actor.world.pos.y + 32, rockActor->actor.world.pos.z, + MTXMODE_NEW); + DrawItemCircle(play, 8, *rockIdentity); + } + + CLOSE_DISPS(play->state.gfxCtx); +} + +uint8_t Rock_RandomizerHoldsItem(RockIdentity rockIdentity, PlayState* play, bool isBoulder) { + RandomizerCheck rc = rockIdentity.randomizerCheck; + if (rc == RC_MAX || rc == RC_UNKNOWN_CHECK) + return false; + + uint8_t isDungeon = Rando::StaticData::GetLocation(rc)->IsDungeon(); + uint8_t setting = + Rando::Context::GetInstance()->GetOption(isBoulder ? RSK_SHUFFLE_BOULDERS : RSK_SHUFFLE_ROCKS).Get(); + + // Don't pull randomized item if rock isn't randomized or is already checked + return IS_RANDO && + ((!isBoulder && setting) || (isBoulder && (setting == RO_SHUFFLE_BOULDERS_ALL || + (isDungeon && setting == RO_SHUFFLE_BOULDERS_DUNGEONS) || + (!isDungeon && setting == RO_SHUFFLE_BOULDERS_OVERWORLD)))) && + !Flags_GetRandomizerInf(rockIdentity.randomizerInf); +} + +void Rock_RandomizerSpawnCollectible(Actor* actor, RockIdentity rockIdentity, PlayState* play) { + LUSLOG_INFO("ROCKdrop %d\t:\t%d, %d", rockIdentity.randomizerCheck, (s16)actor->world.pos.x, + (s16)actor->world.pos.z); + EnItem00* item00 = (EnItem00*)Item_DropCollectible2(play, &actor->world.pos, ITEM00_SOH_DUMMY); + item00->randoInf = rockIdentity.randomizerInf; + item00->itemEntry = Rando::Context::GetInstance()->GetFinalGIEntry(rockIdentity.randomizerCheck, true, GI_NONE); + item00->actor.draw = (ActorFunc)EnItem00_DrawRandomizedItem; + item00->actor.velocity.y = 9.0f; + item00->actor.speedXZ = 2.0f; + item00->actor.world.rot.y = Rand_CenteredFloat(65536.0f); +} + +void EnIshi_RandomizerInit(void* actorRef) { + Actor* actor = static_cast(actorRef); + + if (actor->id != ACTOR_EN_ISHI) + return; + + EnIshi* rockActor = static_cast(actorRef); + + auto rockIdentity = OTRGlobals::Instance->gRandomizer->IdentifyRock(gPlayState->sceneNum, (s16)actor->world.pos.x, + (s16)actor->world.pos.z); + if (rockIdentity.randomizerCheck == RC_MAX) { + LUSLOG_WARN("ROCK ishi %d\t:\t%d, %d", rockIdentity.randomizerCheck, actor->params & 1, + (s16)actor->world.pos.x, (s16)actor->world.pos.z); + } else { + LUSLOG_INFO("ROCK ishi%d %d\t:\t%d, %d", rockIdentity.randomizerCheck, actor->params & 1, + (s16)actor->world.pos.x, (s16)actor->world.pos.z); + } + + if (Rock_RandomizerHoldsItem(rockIdentity, gPlayState, actor->params & 1)) { + ObjectExtension::GetInstance().Set(actor, std::move(rockIdentity)); + rockActor->actor.draw = EnIshi_RandomizerDraw; + } +} + +void ObjBombiwa_RandomizerInit(void* actorRef) { + Actor* actor = static_cast(actorRef); + + if (actor->id != ACTOR_OBJ_BOMBIWA) + return; + + ObjBombiwa* rockActor = static_cast(actorRef); + + auto rockIdentity = OTRGlobals::Instance->gRandomizer->IdentifyRock(gPlayState->sceneNum, (s16)actor->world.pos.x, + (s16)actor->world.pos.z); + if (rockIdentity.randomizerCheck == RC_MAX) { + LUSLOG_INFO("ROCK bombiwa\t:\t%d, %d", rockIdentity.randomizerCheck, (s16)actor->world.pos.x, + (s16)actor->world.pos.z); + } else { + LUSLOG_INFO("ROCK bombiwa%d\t:\t%d, %d", rockIdentity.randomizerCheck, (s16)actor->world.pos.x, + (s16)actor->world.pos.z); + } + if (Rock_RandomizerHoldsItem(rockIdentity, gPlayState, true)) { + ObjectExtension::GetInstance().Set(actor, std::move(rockIdentity)); + rockActor->actor.draw = ObjBombiwa_RandomizerDraw; + } +} + +void ObjHamishi_RandomizerInit(void* actorRef) { + Actor* actor = static_cast(actorRef); + + if (actor->id != ACTOR_OBJ_HAMISHI) + return; + + ObjHamishi* rockActor = static_cast(actorRef); + + auto rockIdentity = OTRGlobals::Instance->gRandomizer->IdentifyRock(gPlayState->sceneNum, (s16)actor->world.pos.x, + (s16)actor->world.pos.z); + if (rockIdentity.randomizerCheck == RC_MAX) { + LUSLOG_WARN("ROCK hamishi\t:\t%d, %d", rockIdentity.randomizerCheck, (s16)actor->world.pos.x, + (s16)actor->world.pos.z); + } else { + LUSLOG_INFO("ROCK hamishi%d\t:\t%d, %d", rockIdentity.randomizerCheck, (s16)actor->world.pos.x, + (s16)actor->world.pos.z); + } + if (Rock_RandomizerHoldsItem(rockIdentity, gPlayState, true)) { + ObjectExtension::GetInstance().Set(actor, std::move(rockIdentity)); + rockActor->actor.draw = ObjHamishi_RandomizerDraw; + } +} + +void ObjBombiwa_RandomizerKill(void* actorRef) { + Actor* actor = static_cast(actorRef); + + if (actor->id != ACTOR_OBJ_BOMBIWA) + return; + + ObjBombiwa* rockActor = static_cast(actorRef); + const auto rockIdentity = ObjectExtension::GetInstance().Get(actorRef); + + if (rockIdentity != nullptr && Rock_RandomizerHoldsItem(*rockIdentity, gPlayState, true)) { + Rock_RandomizerSpawnCollectible(&rockActor->actor, *rockIdentity, gPlayState); + rockIdentity->randomizerCheck = RC_MAX; + rockIdentity->randomizerInf = RAND_INF_MAX; + } +} + +void ObjHamishi_RandomizerKill(void* actorRef) { + Actor* actor = static_cast(actorRef); + + if (actor->id != ACTOR_OBJ_HAMISHI) + return; + + ObjHamishi* rockActor = static_cast(actorRef); + const auto rockIdentity = ObjectExtension::GetInstance().Get(actorRef); + + if (rockIdentity != nullptr && Rock_RandomizerHoldsItem(*rockIdentity, gPlayState, true)) { + Rock_RandomizerSpawnCollectible(&rockActor->actor, *rockIdentity, gPlayState); + rockIdentity->randomizerCheck = RC_MAX; + rockIdentity->randomizerInf = RAND_INF_MAX; + } +} + +void RegisterShuffleRock() { + bool shouldRegister = IS_RANDO && (RAND_GET_OPTION(RSK_SHUFFLE_ROCKS) || RAND_GET_OPTION(RSK_SHUFFLE_BOULDERS)); + bool shouldRegisterBoulder = IS_RANDO && RAND_GET_OPTION(RSK_SHUFFLE_BOULDERS); + + COND_ID_HOOK(OnActorInit, ACTOR_EN_ISHI, shouldRegister, EnIshi_RandomizerInit); + COND_ID_HOOK(OnActorInit, ACTOR_OBJ_BOMBIWA, shouldRegisterBoulder, ObjBombiwa_RandomizerInit); + COND_ID_HOOK(OnActorInit, ACTOR_OBJ_HAMISHI, shouldRegisterBoulder, ObjHamishi_RandomizerInit); + COND_ID_HOOK(OnActorKill, ACTOR_OBJ_BOMBIWA, shouldRegisterBoulder, ObjBombiwa_RandomizerKill); + COND_ID_HOOK(OnActorKill, ACTOR_OBJ_HAMISHI, shouldRegisterBoulder, ObjHamishi_RandomizerKill); + + COND_VB_SHOULD(VB_ROCK_DROP_ITEM, shouldRegister, { + EnIshi* rockActor = va_arg(args, EnIshi*); + const auto rockIdentity = ObjectExtension::GetInstance().Get(rockActor); + if (rockIdentity != nullptr && + Rock_RandomizerHoldsItem(*rockIdentity, gPlayState, rockActor->actor.params & 1)) { + Rock_RandomizerSpawnCollectible(&rockActor->actor, *rockIdentity, gPlayState); + rockIdentity->randomizerCheck = RC_MAX; + rockIdentity->randomizerInf = RAND_INF_MAX; + *should = false; + } + }); + + COND_VB_SHOULD(VB_BOULDER_BREAK_FLAG, shouldRegisterBoulder, { + Actor* rockActor = va_arg(args, Actor*); + // hook called before OnActorInit sets up object extension + auto rockIdentity = OTRGlobals::Instance->gRandomizer->IdentifyRock( + gPlayState->sceneNum, (s16)rockActor->world.pos.x, (s16)rockActor->world.pos.z); + if (rockIdentity.randomizerCheck != RC_UNKNOWN_CHECK && + Rock_RandomizerHoldsItem(rockIdentity, gPlayState, true)) { + *should = false; + } + }); +} + +void Rando::StaticData::RegisterRockLocations() { +#define ROCKLOC(id, area, scene, hint, x, z) \ + (locationTable[RC_##id] = Location::Rock(RC_##id, RCQUEST_BOTH, area, scene, TWO_ACTOR_PARAMS(x, z), #id, hint, \ + RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_##id))) +#define BOLDLOC(id, area, scene, hint, x, z) \ + (locationTable[RC_##id] = Location::Boulder(RC_##id, RCQUEST_BOTH, area, scene, TWO_ACTOR_PARAMS(x, z), #id, hint, \ + SpoilerCollectionCheck::RandomizerInf(RAND_INF_##id))) + ROCKLOC(KF_CIRCLE_ROCK_1, RCAREA_KOKIRI_FOREST, SCENE_KOKIRI_FOREST, RHT_KF_ROCK, -292, -350); + ROCKLOC(KF_CIRCLE_ROCK_2, RCAREA_KOKIRI_FOREST, SCENE_KOKIRI_FOREST, RHT_KF_ROCK, -235, -373); + ROCKLOC(KF_CIRCLE_ROCK_3, RCAREA_KOKIRI_FOREST, SCENE_KOKIRI_FOREST, RHT_KF_ROCK, -212, -430); + ROCKLOC(KF_CIRCLE_ROCK_4, RCAREA_KOKIRI_FOREST, SCENE_KOKIRI_FOREST, RHT_KF_ROCK, -235, -486); + ROCKLOC(KF_CIRCLE_ROCK_5, RCAREA_KOKIRI_FOREST, SCENE_KOKIRI_FOREST, RHT_KF_ROCK, -292, -510); + ROCKLOC(KF_CIRCLE_ROCK_6, RCAREA_KOKIRI_FOREST, SCENE_KOKIRI_FOREST, RHT_KF_ROCK, -348, -486); + ROCKLOC(KF_CIRCLE_ROCK_7, RCAREA_KOKIRI_FOREST, SCENE_KOKIRI_FOREST, RHT_KF_ROCK, -372, -430); + ROCKLOC(KF_CIRCLE_ROCK_8, RCAREA_KOKIRI_FOREST, SCENE_KOKIRI_FOREST, RHT_KF_ROCK, -348, -373); + ROCKLOC(KF_ROCK_BY_SARIAS_HOUSE, RCAREA_KOKIRI_FOREST, SCENE_KOKIRI_FOREST, RHT_KF_ROCK, 248, 601); + ROCKLOC(KF_ROCK_BEHIND_SARIAS_HOUSE, RCAREA_KOKIRI_FOREST, SCENE_KOKIRI_FOREST, RHT_KF_ROCK, 726, 961); + ROCKLOC(KF_ROCK_BY_MIDOS_HOUSE, RCAREA_KOKIRI_FOREST, SCENE_KOKIRI_FOREST, RHT_KF_ROCK, -672, -623); + ROCKLOC(KF_ROCK_BY_KNOW_IT_ALLS_HOUSE, RCAREA_KOKIRI_FOREST, SCENE_KOKIRI_FOREST, RHT_KF_ROCK, -1361, 145); + BOLDLOC(LW_BOULDER_BY_GORON_CITY, RCAREA_LOST_WOODS, SCENE_LOST_WOODS, RHT_LW_BOULDER, 915, -925); + BOLDLOC(LW_BOULDER_BY_SACRED_FOREST_MEADOW, RCAREA_LOST_WOODS, SCENE_LOST_WOODS, RHT_LW_BOULDER, 670, -2520); + BOLDLOC(LW_RUPEE_BOULDER, RCAREA_LOST_WOODS, SCENE_LOST_WOODS, RHT_LW_BOULDER, 1720, -2510); + + locationTable[RC_HC_ROCK_1] = Location::Rock( + RC_HC_ROCK_1, RCQUEST_BOTH, RCAREA_HYRULE_CASTLE, SCENE_HYRULE_CASTLE, TWO_ACTOR_PARAMS(-216, 2977), + "HC Rock 1", RHT_HC_ROCK, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_HC_ROCK_1)); + locationTable[RC_HC_ROCK_2] = Location::Rock( + RC_HC_ROCK_2, RCQUEST_BOTH, RCAREA_HYRULE_CASTLE, SCENE_HYRULE_CASTLE, TWO_ACTOR_PARAMS(-110, 3006), + "HC Rock 2", RHT_HC_ROCK, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_HC_ROCK_2)); + locationTable[RC_HC_ROCK_3] = Location::Rock( + RC_HC_ROCK_3, RCQUEST_BOTH, RCAREA_HYRULE_CASTLE, SCENE_HYRULE_CASTLE, TWO_ACTOR_PARAMS(-129, 2897), + "HC Rock 3", RHT_HC_ROCK, RG_RECOVERY_HEART, SpoilerCollectionCheck::RandomizerInf(RAND_INF_HC_ROCK_3)); + BOLDLOC(HC_BOULDER, RCAREA_HYRULE_CASTLE, SCENE_HYRULE_CASTLE, RHT_HC_BOULDER, 2730, 2540); + BOLDLOC(OGC_BRONZE_BOULDER_1, RCAREA_HYRULE_CASTLE, SCENE_OUTSIDE_GANONS_CASTLE, RHT_OGC_BRONZE_BOULDER, 2324, 533); + BOLDLOC(OGC_BRONZE_BOULDER_2, RCAREA_HYRULE_CASTLE, SCENE_OUTSIDE_GANONS_CASTLE, RHT_OGC_BRONZE_BOULDER, 1590, 787); + BOLDLOC(OGC_BRONZE_BOULDER_3, RCAREA_HYRULE_CASTLE, SCENE_OUTSIDE_GANONS_CASTLE, RHT_OGC_BRONZE_BOULDER, 1661, 748); + BOLDLOC(OGC_SILVER_BOULDER_1, RCAREA_HYRULE_CASTLE, SCENE_OUTSIDE_GANONS_CASTLE, RHT_OGC_SILVER_BOULDER, 1606, 685); + BOLDLOC(OGC_SILVER_BOULDER_2, RCAREA_HYRULE_CASTLE, SCENE_OUTSIDE_GANONS_CASTLE, RHT_OGC_SILVER_BOULDER, 1766, 726); + BOLDLOC(OGC_SILVER_BOULDER_3, RCAREA_HYRULE_CASTLE, SCENE_OUTSIDE_GANONS_CASTLE, RHT_OGC_SILVER_BOULDER, 1701, 661); + BOLDLOC(OGC_SILVER_BOULDER_4, RCAREA_HYRULE_CASTLE, SCENE_OUTSIDE_GANONS_CASTLE, RHT_OGC_SILVER_BOULDER, 2260, 560); + + ROCKLOC(DMC_ROCK_BY_FIRE_TEMPLE_1, RCAREA_DEATH_MOUNTAIN_CRATER, SCENE_DEATH_MOUNTAIN_CRATER, RHT_DMC_ROCK, -50, + -714); + ROCKLOC(DMC_ROCK_BY_FIRE_TEMPLE_2, RCAREA_DEATH_MOUNTAIN_CRATER, SCENE_DEATH_MOUNTAIN_CRATER, RHT_DMC_ROCK, -26, + -807); + ROCKLOC(DMC_ROCK_BY_FIRE_TEMPLE_3, RCAREA_DEATH_MOUNTAIN_CRATER, SCENE_DEATH_MOUNTAIN_CRATER, RHT_DMC_ROCK, 61, + -763); + ROCKLOC(DMC_ROCK_BY_FIRE_TEMPLE_4, RCAREA_DEATH_MOUNTAIN_CRATER, SCENE_DEATH_MOUNTAIN_CRATER, RHT_DMC_ROCK, 71, + -610); + ROCKLOC(DMC_ROCK_BY_FIRE_TEMPLE_5, RCAREA_DEATH_MOUNTAIN_CRATER, SCENE_DEATH_MOUNTAIN_CRATER, RHT_DMC_ROCK, 79, + -700); + ROCKLOC(DMC_CIRCLE_ROCK_1, RCAREA_DEATH_MOUNTAIN_CRATER, SCENE_DEATH_MOUNTAIN_CRATER, RHT_DMC_ROCK, 40, 1850); + ROCKLOC(DMC_CIRCLE_ROCK_2, RCAREA_DEATH_MOUNTAIN_CRATER, SCENE_DEATH_MOUNTAIN_CRATER, RHT_DMC_ROCK, 96, 1826); + ROCKLOC(DMC_CIRCLE_ROCK_3, RCAREA_DEATH_MOUNTAIN_CRATER, SCENE_DEATH_MOUNTAIN_CRATER, RHT_DMC_ROCK, 120, 1770); + ROCKLOC(DMC_CIRCLE_ROCK_4, RCAREA_DEATH_MOUNTAIN_CRATER, SCENE_DEATH_MOUNTAIN_CRATER, RHT_DMC_ROCK, 96, 1713); + ROCKLOC(DMC_CIRCLE_ROCK_5, RCAREA_DEATH_MOUNTAIN_CRATER, SCENE_DEATH_MOUNTAIN_CRATER, RHT_DMC_ROCK, 40, 1690); + ROCKLOC(DMC_CIRCLE_ROCK_6, RCAREA_DEATH_MOUNTAIN_CRATER, SCENE_DEATH_MOUNTAIN_CRATER, RHT_DMC_ROCK, -16, 1713); + ROCKLOC(DMC_CIRCLE_ROCK_7, RCAREA_DEATH_MOUNTAIN_CRATER, SCENE_DEATH_MOUNTAIN_CRATER, RHT_DMC_ROCK, -40, 1770); + ROCKLOC(DMC_CIRCLE_ROCK_8, RCAREA_DEATH_MOUNTAIN_CRATER, SCENE_DEATH_MOUNTAIN_CRATER, RHT_DMC_ROCK, -16, 1826); + ROCKLOC(DMC_GOSSIP_ROCK_1, RCAREA_DEATH_MOUNTAIN_CRATER, SCENE_DEATH_MOUNTAIN_CRATER, RHT_DMC_ROCK, 1261, 1533); + ROCKLOC(DMC_GOSSIP_ROCK_2, RCAREA_DEATH_MOUNTAIN_CRATER, SCENE_DEATH_MOUNTAIN_CRATER, RHT_DMC_ROCK, 1356, 1541); + BOLDLOC(DMC_BOULDER_1, RCAREA_DEATH_MOUNTAIN_CRATER, SCENE_DEATH_MOUNTAIN_CRATER, RHT_DMC_BOULDER, -504, 1070); + BOLDLOC(DMC_BOULDER_2, RCAREA_DEATH_MOUNTAIN_CRATER, SCENE_DEATH_MOUNTAIN_CRATER, RHT_DMC_BOULDER, 236, 1199); + BOLDLOC(DMC_BOULDER_3, RCAREA_DEATH_MOUNTAIN_CRATER, SCENE_DEATH_MOUNTAIN_CRATER, RHT_DMC_BOULDER, 40, 1770); + BOLDLOC(DMC_BRONZE_BOULDER_1, RCAREA_DEATH_MOUNTAIN_CRATER, SCENE_DEATH_MOUNTAIN_CRATER, RHT_DMC_BRONZE_BOULDER, + -1699, -472); + BOLDLOC(DMC_BRONZE_BOULDER_2, RCAREA_DEATH_MOUNTAIN_CRATER, SCENE_DEATH_MOUNTAIN_CRATER, RHT_DMC_BRONZE_BOULDER, + -1332, 921); + BOLDLOC(DMC_BRONZE_BOULDER_3, RCAREA_DEATH_MOUNTAIN_CRATER, SCENE_DEATH_MOUNTAIN_CRATER, RHT_DMC_BRONZE_BOULDER, + -1303, 975); + BOLDLOC(DMC_BRONZE_BOULDER_4, RCAREA_DEATH_MOUNTAIN_CRATER, SCENE_DEATH_MOUNTAIN_CRATER, RHT_DMC_BRONZE_BOULDER, + -1060, 944); + + BOLDLOC(GV_SILVER_BOULDER, RCAREA_GERUDO_VALLEY, SCENE_GERUDO_VALLEY, RHT_GV_SILVER_BOULDER, 280, 1470); + ROCKLOC(GV_ROCK_1, RCAREA_GERUDO_VALLEY, SCENE_GERUDO_VALLEY, RHT_GV_ROCK, 2738, 297); + ROCKLOC(GV_ROCK_2, RCAREA_GERUDO_VALLEY, SCENE_GERUDO_VALLEY, RHT_GV_ROCK, 2715, 316); + ROCKLOC(GV_ROCK_3, RCAREA_GERUDO_VALLEY, SCENE_GERUDO_VALLEY, RHT_GV_ROCK, 2699, 275); + ROCKLOC(GV_UNDERWATER_ROCK_1, RCAREA_GERUDO_VALLEY, SCENE_GERUDO_VALLEY, RHT_GV_ROCK, 1559, -63); + ROCKLOC(GV_UNDERWATER_ROCK_2, RCAREA_GERUDO_VALLEY, SCENE_GERUDO_VALLEY, RHT_GV_ROCK, 1605, 26); + ROCKLOC(GV_UNDERWATER_ROCK_3, RCAREA_GERUDO_VALLEY, SCENE_GERUDO_VALLEY, RHT_GV_ROCK, 1686, -33); + ROCKLOC(GV_ROCK_ACROSS_BRIDGE_1, RCAREA_GERUDO_VALLEY, SCENE_GERUDO_VALLEY, RHT_GV_ROCK, -666, -899); + ROCKLOC(GV_ROCK_ACROSS_BRIDGE_2, RCAREA_GERUDO_VALLEY, SCENE_GERUDO_VALLEY, RHT_GV_ROCK, -526, -890); + ROCKLOC(GV_ROCK_ACROSS_BRIDGE_3, RCAREA_GERUDO_VALLEY, SCENE_GERUDO_VALLEY, RHT_GV_ROCK, -607, -791); + ROCKLOC(GV_ROCK_ACROSS_BRIDGE_4, RCAREA_GERUDO_VALLEY, SCENE_GERUDO_VALLEY, RHT_GV_ROCK, -458, -782); + BOLDLOC(GV_BOULDER_1, RCAREA_GERUDO_VALLEY, SCENE_GERUDO_VALLEY, RHT_GV_BOULDER, 751, 569); + BOLDLOC(GV_BOULDER_2, RCAREA_GERUDO_VALLEY, SCENE_GERUDO_VALLEY, RHT_GV_BOULDER, 545, -510); + BOLDLOC(GV_BOULDER_ACROSS_BRIDGE, RCAREA_GERUDO_VALLEY, SCENE_GERUDO_VALLEY, RHT_GV_BOULDER, -954, 577); + BOLDLOC(GV_BRONZE_BOULDER_1, RCAREA_GERUDO_VALLEY, SCENE_GERUDO_VALLEY, RHT_GV_BRONZE_BOULDER, 861, -778); + BOLDLOC(GV_BRONZE_BOULDER_2, RCAREA_GERUDO_VALLEY, SCENE_GERUDO_VALLEY, RHT_GV_BRONZE_BOULDER, 735, 375); + BOLDLOC(GV_BRONZE_BOULDER_ACROSS_BRIDGE_1, RCAREA_GERUDO_VALLEY, SCENE_GERUDO_VALLEY, RHT_GV_BRONZE_BOULDER, -1352, + 767); + BOLDLOC(GV_BRONZE_BOULDER_ACROSS_BRIDGE_2, RCAREA_GERUDO_VALLEY, SCENE_GERUDO_VALLEY, RHT_GV_BRONZE_BOULDER, -1695, + -350); + BOLDLOC(GV_BRONZE_BOULDER_ACROSS_BRIDGE_3, RCAREA_GERUDO_VALLEY, SCENE_GERUDO_VALLEY, RHT_GV_BRONZE_BOULDER, -1001, + 637); + BOLDLOC(GV_BRONZE_BOULDER_ACROSS_BRIDGE_4, RCAREA_GERUDO_VALLEY, SCENE_GERUDO_VALLEY, RHT_GV_BRONZE_BOULDER, -1291, + 787); + BOLDLOC(GV_BRONZE_BOULDER_ACROSS_BRIDGE_5, RCAREA_GERUDO_VALLEY, SCENE_GERUDO_VALLEY, RHT_GV_BRONZE_BOULDER, -1416, + 778); + BOLDLOC(GV_BRONZE_BOULDER_ACROSS_BRIDGE_6, RCAREA_GERUDO_VALLEY, SCENE_GERUDO_VALLEY, RHT_GV_BRONZE_BOULDER, -1256, + 856); + + BOLDLOC(HF_SILVER_BOULDER, RCAREA_HYRULE_FIELD, SCENE_HYRULE_FIELD, RHT_HF_SILVER_BOULDER, 674, 8256); + ROCKLOC(HF_ROCK_1, RCAREA_HYRULE_FIELD, SCENE_HYRULE_FIELD, RHT_HF_ROCK, -7875, 6995); + ROCKLOC(HF_ROCK_2, RCAREA_HYRULE_FIELD, SCENE_HYRULE_FIELD, RHT_HF_ROCK, -7818, 6971); + ROCKLOC(HF_ROCK_3, RCAREA_HYRULE_FIELD, SCENE_HYRULE_FIELD, RHT_HF_ROCK, -7795, 6915); + ROCKLOC(HF_ROCK_4, RCAREA_HYRULE_FIELD, SCENE_HYRULE_FIELD, RHT_HF_ROCK, -7818, 6858); + ROCKLOC(HF_ROCK_5, RCAREA_HYRULE_FIELD, SCENE_HYRULE_FIELD, RHT_HF_ROCK, -7875, 6835); + ROCKLOC(HF_ROCK_6, RCAREA_HYRULE_FIELD, SCENE_HYRULE_FIELD, RHT_HF_ROCK, -7931, 6858); + ROCKLOC(HF_ROCK_7, RCAREA_HYRULE_FIELD, SCENE_HYRULE_FIELD, RHT_HF_ROCK, -7955, 6915); + ROCKLOC(HF_ROCK_8, RCAREA_HYRULE_FIELD, SCENE_HYRULE_FIELD, RHT_HF_ROCK, -7931, 6971); + BOLDLOC(HF_BOULDER_NORTH, RCAREA_HYRULE_FIELD, SCENE_HYRULE_FIELD, RHT_HF_BOULDER, -4450, -425); + BOLDLOC(HF_BOULDER_BY_MARKET, RCAREA_HYRULE_FIELD, SCENE_HYRULE_FIELD, RHT_HF_BOULDER, -1425, 810); + BOLDLOC(HF_BOULDER_SOUTH, RCAREA_HYRULE_FIELD, SCENE_HYRULE_FIELD, RHT_HF_BOULDER, -270, 12350); + BOLDLOC(HF_BRONZE_BOULDER_1, RCAREA_HYRULE_FIELD, SCENE_HYRULE_FIELD, RHT_HF_BRONZE_BOULDER, -7870, 6920); + BOLDLOC(HF_BRONZE_BOULDER_2, RCAREA_HYRULE_FIELD, SCENE_HYRULE_FIELD, RHT_HF_BRONZE_BOULDER, -7804, 7983); + BOLDLOC(HF_BRONZE_BOULDER_3, RCAREA_HYRULE_FIELD, SCENE_HYRULE_FIELD, RHT_HF_BRONZE_BOULDER, -8397, 7947); + BOLDLOC(HF_BRONZE_BOULDER_4, RCAREA_HYRULE_FIELD, SCENE_HYRULE_FIELD, RHT_HF_BRONZE_BOULDER, -6461, 8220); + + BOLDLOC(KAK_SILVER_BOULDER, RCAREA_KAKARIKO_VILLAGE, SCENE_KAKARIKO_VILLAGE, RHT_KAK_SILVER_BOULDER, 1436, 1361); + ROCKLOC(KAK_ROCK_1, RCAREA_KAKARIKO_VILLAGE, SCENE_KAKARIKO_VILLAGE, RHT_KAK_ROCK, 220, -1236); + ROCKLOC(KAK_ROCK_2, RCAREA_KAKARIKO_VILLAGE, SCENE_KAKARIKO_VILLAGE, RHT_KAK_ROCK, -664, 1288); + ROCKLOC(GY_ROCK, RCAREA_GRAVEYARD, SCENE_GRAVEYARD, RHT_GY_ROCK, -1193, 693); + ROCKLOC(LA_ROCK, RCAREA_LAKE_HYLIA, SCENE_LAKE_HYLIA, RHT_LA_ROCK, 1222, 3953); + + ROCKLOC(ZD_CIRCLE_ROCK_1, RCAREA_ZORAS_DOMAIN, SCENE_ZORAS_DOMAIN, RHT_ZD_ROCK, 462, -696); + ROCKLOC(ZD_CIRCLE_ROCK_2, RCAREA_ZORAS_DOMAIN, SCENE_ZORAS_DOMAIN, RHT_ZD_ROCK, 518, -719); + ROCKLOC(ZD_CIRCLE_ROCK_3, RCAREA_ZORAS_DOMAIN, SCENE_ZORAS_DOMAIN, RHT_ZD_ROCK, 542, -776); + ROCKLOC(ZD_CIRCLE_ROCK_4, RCAREA_ZORAS_DOMAIN, SCENE_ZORAS_DOMAIN, RHT_ZD_ROCK, 518, -832); + ROCKLOC(ZD_CIRCLE_ROCK_5, RCAREA_ZORAS_DOMAIN, SCENE_ZORAS_DOMAIN, RHT_ZD_ROCK, 462, -856); + ROCKLOC(ZD_CIRCLE_ROCK_6, RCAREA_ZORAS_DOMAIN, SCENE_ZORAS_DOMAIN, RHT_ZD_ROCK, 405, -832); + ROCKLOC(ZD_CIRCLE_ROCK_7, RCAREA_ZORAS_DOMAIN, SCENE_ZORAS_DOMAIN, RHT_ZD_ROCK, 382, -776); + ROCKLOC(ZD_CIRCLE_ROCK_8, RCAREA_ZORAS_DOMAIN, SCENE_ZORAS_DOMAIN, RHT_ZD_ROCK, 405, -719); + BOLDLOC(ZF_BOULDER, RCAREA_ZORAS_FOUNTAIN, SCENE_ZORAS_FOUNTAIN, RHT_ZF_BOULDER, 189, 2586); + BOLDLOC(ZF_SILVER_BOULDER, RCAREA_ZORAS_FOUNTAIN, SCENE_ZORAS_FOUNTAIN, RHT_ZF_SILVER_BOULDER, 316, 2634); + BOLDLOC(ZF_UNDERGROUND_BOULDER, RCAREA_ZORAS_FOUNTAIN, SCENE_ZORAS_FOUNTAIN, RHT_ZF_BOULDER, 317, 2631); + BOLDLOC(ZR_BOULDER_1, RCAREA_ZORAS_RIVER, SCENE_ZORAS_RIVER, RHT_ZR_BOULDER, -1456, 434); + BOLDLOC(ZR_BOULDER_2, RCAREA_ZORAS_RIVER, SCENE_ZORAS_RIVER, RHT_ZR_BOULDER, -1518, 435); + BOLDLOC(ZR_BOULDER_3, RCAREA_ZORAS_RIVER, SCENE_ZORAS_RIVER, RHT_ZR_BOULDER, -1576, 430); + BOLDLOC(ZR_BOULDER_4, RCAREA_ZORAS_RIVER, SCENE_ZORAS_RIVER, RHT_ZR_BOULDER, -1400, 482); + ROCKLOC(ZR_CIRCLE_ROCK_1, RCAREA_ZORAS_RIVER, SCENE_ZORAS_RIVER, RHT_ZR_ROCK, -1635, -53); + ROCKLOC(ZR_CIRCLE_ROCK_2, RCAREA_ZORAS_RIVER, SCENE_ZORAS_RIVER, RHT_ZR_ROCK, -1578, -76); + ROCKLOC(ZR_CIRCLE_ROCK_3, RCAREA_ZORAS_RIVER, SCENE_ZORAS_RIVER, RHT_ZR_ROCK, -1555, -133); + ROCKLOC(ZR_CIRCLE_ROCK_4, RCAREA_ZORAS_RIVER, SCENE_ZORAS_RIVER, RHT_ZR_ROCK, -1578, -189); + ROCKLOC(ZR_CIRCLE_ROCK_5, RCAREA_ZORAS_RIVER, SCENE_ZORAS_RIVER, RHT_ZR_ROCK, -1635, -213); + ROCKLOC(ZR_CIRCLE_ROCK_6, RCAREA_ZORAS_RIVER, SCENE_ZORAS_RIVER, RHT_ZR_ROCK, -1691, -189); + ROCKLOC(ZR_CIRCLE_ROCK_7, RCAREA_ZORAS_RIVER, SCENE_ZORAS_RIVER, RHT_ZR_ROCK, -1715, -133); + ROCKLOC(ZR_CIRCLE_ROCK_8, RCAREA_ZORAS_RIVER, SCENE_ZORAS_RIVER, RHT_ZR_ROCK, -1691, -76); + ROCKLOC(ZR_UPPER_CIRCLE_BOULDER, RCAREA_ZORAS_RIVER, SCENE_ZORAS_RIVER, RHT_ZR_BOULDER, 672, -366); + ROCKLOC(ZR_UPPER_CIRCLE_ROCK_1, RCAREA_ZORAS_RIVER, SCENE_ZORAS_RIVER, RHT_ZR_ROCK, 668, -290); + ROCKLOC(ZR_UPPER_CIRCLE_ROCK_2, RCAREA_ZORAS_RIVER, SCENE_ZORAS_RIVER, RHT_ZR_ROCK, 724, -313); + ROCKLOC(ZR_UPPER_CIRCLE_ROCK_3, RCAREA_ZORAS_RIVER, SCENE_ZORAS_RIVER, RHT_ZR_ROCK, 748, -370); + ROCKLOC(ZR_UPPER_CIRCLE_ROCK_4, RCAREA_ZORAS_RIVER, SCENE_ZORAS_RIVER, RHT_ZR_ROCK, 724, -426); + ROCKLOC(ZR_UPPER_CIRCLE_ROCK_5, RCAREA_ZORAS_RIVER, SCENE_ZORAS_RIVER, RHT_ZR_ROCK, 668, -450); + ROCKLOC(ZR_UPPER_CIRCLE_ROCK_6, RCAREA_ZORAS_RIVER, SCENE_ZORAS_RIVER, RHT_ZR_ROCK, 611, -426); + ROCKLOC(ZR_UPPER_CIRCLE_ROCK_7, RCAREA_ZORAS_RIVER, SCENE_ZORAS_RIVER, RHT_ZR_ROCK, 588, -370); + ROCKLOC(ZR_UPPER_CIRCLE_ROCK_8, RCAREA_ZORAS_RIVER, SCENE_ZORAS_RIVER, RHT_ZR_ROCK, 611, -313); + ROCKLOC(ZR_ROCK, RCAREA_ZORAS_RIVER, SCENE_ZORAS_RIVER, RHT_ZR_ROCK, 2044, -786); + ROCKLOC(ZR_UNDERWATER_ROCK_1, RCAREA_ZORAS_RIVER, SCENE_ZORAS_RIVER, RHT_ZR_ROCK, 2425, -446); + ROCKLOC(ZR_UNDERWATER_ROCK_2, RCAREA_ZORAS_RIVER, SCENE_ZORAS_RIVER, RHT_ZR_ROCK, 2425, -524); + ROCKLOC(ZR_UNDERWATER_ROCK_3, RCAREA_ZORAS_RIVER, SCENE_ZORAS_RIVER, RHT_ZR_ROCK, 2503, -571); + ROCKLOC(ZR_UNDERWATER_ROCK_4, RCAREA_ZORAS_RIVER, SCENE_ZORAS_RIVER, RHT_ZR_ROCK, 2550, -415); + + // 5 rocks by dc + ROCKLOC(DMT_ROCK_1, RCAREA_DEATH_MOUNTAIN_TRAIL, SCENE_DEATH_MOUNTAIN_TRAIL, RHT_DMT_ROCK, -1816, -513); + ROCKLOC(DMT_ROCK_2, RCAREA_DEATH_MOUNTAIN_TRAIL, SCENE_DEATH_MOUNTAIN_TRAIL, RHT_DMT_ROCK, -1831, -614); + ROCKLOC(DMT_ROCK_3, RCAREA_DEATH_MOUNTAIN_TRAIL, SCENE_DEATH_MOUNTAIN_TRAIL, RHT_DMT_ROCK, -1857, -536); + ROCKLOC(DMT_ROCK_4, RCAREA_DEATH_MOUNTAIN_TRAIL, SCENE_DEATH_MOUNTAIN_TRAIL, RHT_DMT_ROCK, -1878, -465); + ROCKLOC(DMT_ROCK_5, RCAREA_DEATH_MOUNTAIN_TRAIL, SCENE_DEATH_MOUNTAIN_TRAIL, RHT_DMT_ROCK, -1787, -550); + // child only + ROCKLOC(DMT_SUMMIT_ROCK, RCAREA_DEATH_MOUNTAIN_TRAIL, SCENE_DEATH_MOUNTAIN_TRAIL, RHT_DMT_ROCK, -327, -4286); + // ring in front of gc + ROCKLOC(DMT_CIRCLE_ROCK_1, RCAREA_DEATH_MOUNTAIN_TRAIL, SCENE_DEATH_MOUNTAIN_TRAIL, RHT_DMT_ROCK, -383, -1126); + ROCKLOC(DMT_CIRCLE_ROCK_2, RCAREA_DEATH_MOUNTAIN_TRAIL, SCENE_DEATH_MOUNTAIN_TRAIL, RHT_DMT_ROCK, -326, -1149); + ROCKLOC(DMT_CIRCLE_ROCK_3, RCAREA_DEATH_MOUNTAIN_TRAIL, SCENE_DEATH_MOUNTAIN_TRAIL, RHT_DMT_ROCK, -303, -1206); + ROCKLOC(DMT_CIRCLE_ROCK_4, RCAREA_DEATH_MOUNTAIN_TRAIL, SCENE_DEATH_MOUNTAIN_TRAIL, RHT_DMT_ROCK, -326, -1262); + ROCKLOC(DMT_CIRCLE_ROCK_5, RCAREA_DEATH_MOUNTAIN_TRAIL, SCENE_DEATH_MOUNTAIN_TRAIL, RHT_DMT_ROCK, -383, -1286); + ROCKLOC(DMT_CIRCLE_ROCK_6, RCAREA_DEATH_MOUNTAIN_TRAIL, SCENE_DEATH_MOUNTAIN_TRAIL, RHT_DMT_ROCK, -439, -1262); + ROCKLOC(DMT_CIRCLE_ROCK_7, RCAREA_DEATH_MOUNTAIN_TRAIL, SCENE_DEATH_MOUNTAIN_TRAIL, RHT_DMT_ROCK, -463, -1206); + ROCKLOC(DMT_CIRCLE_ROCK_8, RCAREA_DEATH_MOUNTAIN_TRAIL, SCENE_DEATH_MOUNTAIN_TRAIL, RHT_DMT_ROCK, -439, -1149); + BOLDLOC(DMT_BOULDER_1, RCAREA_DEATH_MOUNTAIN_TRAIL, SCENE_DEATH_MOUNTAIN_TRAIL, RHT_DMT_BOULDER, -625, -55); + BOLDLOC(DMT_BOULDER_2, RCAREA_DEATH_MOUNTAIN_TRAIL, SCENE_DEATH_MOUNTAIN_TRAIL, RHT_DMT_BOULDER, -808, -59); + BOLDLOC(DMT_BOULDER_3, RCAREA_DEATH_MOUNTAIN_TRAIL, SCENE_DEATH_MOUNTAIN_TRAIL, RHT_DMT_BOULDER, -1060, -51); + BOLDLOC(DMT_COW_BOULDER, RCAREA_DEATH_MOUNTAIN_TRAIL, SCENE_DEATH_MOUNTAIN_TRAIL, RHT_DMT_BOULDER, -688, -285); + BOLDLOC(DMT_BRONZE_BOULDER_1, RCAREA_DEATH_MOUNTAIN_TRAIL, SCENE_DEATH_MOUNTAIN_TRAIL, RHT_DMT_BRONZE_BOULDER, + -1175, -803); + BOLDLOC(DMT_BRONZE_BOULDER_2, RCAREA_DEATH_MOUNTAIN_TRAIL, SCENE_DEATH_MOUNTAIN_TRAIL, RHT_DMT_BRONZE_BOULDER, + -1948, 1706); + BOLDLOC(DMT_BRONZE_BOULDER_3, RCAREA_DEATH_MOUNTAIN_TRAIL, SCENE_DEATH_MOUNTAIN_TRAIL, RHT_DMT_BRONZE_BOULDER, + -2019, 1101); + BOLDLOC(DMT_BRONZE_BOULDER_4, RCAREA_DEATH_MOUNTAIN_TRAIL, SCENE_DEATH_MOUNTAIN_TRAIL, RHT_DMT_BRONZE_BOULDER, + -1658, -88); + BOLDLOC(DMT_BRONZE_BOULDER_5, RCAREA_DEATH_MOUNTAIN_TRAIL, SCENE_DEATH_MOUNTAIN_TRAIL, RHT_DMT_BRONZE_BOULDER, + -1753, 445); + BOLDLOC(DMT_BRONZE_BOULDER_6, RCAREA_DEATH_MOUNTAIN_TRAIL, SCENE_DEATH_MOUNTAIN_TRAIL, RHT_DMT_BRONZE_BOULDER, + -1018, 1283); + BOLDLOC(DMT_BRONZE_BOULDER_7, RCAREA_DEATH_MOUNTAIN_TRAIL, SCENE_DEATH_MOUNTAIN_TRAIL, RHT_DMT_BRONZE_BOULDER, + -1986, 727); + BOLDLOC(DMT_BRONZE_BOULDER_8, RCAREA_DEATH_MOUNTAIN_TRAIL, SCENE_DEATH_MOUNTAIN_TRAIL, RHT_DMT_BRONZE_BOULDER, -23, + -3196); + BOLDLOC(DMT_BRONZE_BOULDER_9, RCAREA_DEATH_MOUNTAIN_TRAIL, SCENE_DEATH_MOUNTAIN_TRAIL, RHT_DMT_BRONZE_BOULDER, -343, + -2794); + BOLDLOC(DMT_BRONZE_BOULDER_10, RCAREA_DEATH_MOUNTAIN_TRAIL, SCENE_DEATH_MOUNTAIN_TRAIL, RHT_DMT_BRONZE_BOULDER, + -154, -2484); + BOLDLOC(DMT_BRONZE_BOULDER_11, RCAREA_DEATH_MOUNTAIN_TRAIL, SCENE_DEATH_MOUNTAIN_TRAIL, RHT_DMT_BRONZE_BOULDER, + -1590, -402); + BOLDLOC(GC_LW_BOULDER_1, RCAREA_GORON_CITY, SCENE_GORON_CITY, RHT_GC_BOULDER, 416, 1049); + BOLDLOC(GC_LW_BOULDER_2, RCAREA_GORON_CITY, SCENE_GORON_CITY, RHT_GC_BOULDER, 470, 1031); + BOLDLOC(GC_LW_BOULDER_3, RCAREA_GORON_CITY, SCENE_GORON_CITY, RHT_GC_BOULDER, 367, 1078); + BOLDLOC(GC_ENTRANCE_BOULDER_1, RCAREA_GORON_CITY, SCENE_GORON_CITY, RHT_GC_BOULDER, -670, 470); + BOLDLOC(GC_ENTRANCE_BOULDER_2, RCAREA_GORON_CITY, SCENE_GORON_CITY, RHT_GC_BOULDER, -607, 419); + BOLDLOC(GC_ENTRANCE_BOULDER_3, RCAREA_GORON_CITY, SCENE_GORON_CITY, RHT_GC_BOULDER, -756, 474); + BOLDLOC(GC_MAZE_SILVER_BOULDER_1, RCAREA_GORON_CITY, SCENE_GORON_CITY, RHT_GC_SILVER_BOULDER, -1479, -794); + BOLDLOC(GC_MAZE_SILVER_BOULDER_2, RCAREA_GORON_CITY, SCENE_GORON_CITY, RHT_GC_SILVER_BOULDER, -1478, -855); + BOLDLOC(GC_MAZE_SILVER_BOULDER_3, RCAREA_GORON_CITY, SCENE_GORON_CITY, RHT_GC_SILVER_BOULDER, -1474, -624); + BOLDLOC(GC_MAZE_SILVER_BOULDER_4, RCAREA_GORON_CITY, SCENE_GORON_CITY, RHT_GC_SILVER_BOULDER, -1471, -993); + BOLDLOC(GC_MAZE_SILVER_BOULDER_5, RCAREA_GORON_CITY, SCENE_GORON_CITY, RHT_GC_SILVER_BOULDER, -1467, -1064); + BOLDLOC(GC_MAZE_SILVER_BOULDER_6, RCAREA_GORON_CITY, SCENE_GORON_CITY, RHT_GC_SILVER_BOULDER, -1460, -1121); + BOLDLOC(GC_MAZE_SILVER_BOULDER_7, RCAREA_GORON_CITY, SCENE_GORON_CITY, RHT_GC_SILVER_BOULDER, -1451, -567); + BOLDLOC(GC_MAZE_SILVER_BOULDER_8, RCAREA_GORON_CITY, SCENE_GORON_CITY, RHT_GC_SILVER_BOULDER, -1448, -672); + BOLDLOC(GC_MAZE_SILVER_BOULDER_9, RCAREA_GORON_CITY, SCENE_GORON_CITY, RHT_GC_SILVER_BOULDER, -1440, -1174); + BOLDLOC(GC_MAZE_SILVER_BOULDER_10, RCAREA_GORON_CITY, SCENE_GORON_CITY, RHT_GC_SILVER_BOULDER, -1437, -1342); + BOLDLOC(GC_MAZE_SILVER_BOULDER_11, RCAREA_GORON_CITY, SCENE_GORON_CITY, RHT_GC_SILVER_BOULDER, -1424, -1245); + BOLDLOC(GC_MAZE_SILVER_BOULDER_12, RCAREA_GORON_CITY, SCENE_GORON_CITY, RHT_GC_SILVER_BOULDER, -1424, -609); + BOLDLOC(GC_MAZE_SILVER_BOULDER_13, RCAREA_GORON_CITY, SCENE_GORON_CITY, RHT_GC_SILVER_BOULDER, -1399, -1300); + BOLDLOC(GC_MAZE_SILVER_BOULDER_14, RCAREA_GORON_CITY, SCENE_GORON_CITY, RHT_GC_SILVER_BOULDER, -1394, -654); + BOLDLOC(GC_MAZE_SILVER_BOULDER_15, RCAREA_GORON_CITY, SCENE_GORON_CITY, RHT_GC_SILVER_BOULDER, -1343, -698); + BOLDLOC(GC_MAZE_SILVER_BOULDER_16, RCAREA_GORON_CITY, SCENE_GORON_CITY, RHT_GC_SILVER_BOULDER, -1319, -1086); + BOLDLOC(GC_MAZE_SILVER_BOULDER_17, RCAREA_GORON_CITY, SCENE_GORON_CITY, RHT_GC_SILVER_BOULDER, -1312, -1039); + BOLDLOC(GC_MAZE_SILVER_BOULDER_18, RCAREA_GORON_CITY, SCENE_GORON_CITY, RHT_GC_SILVER_BOULDER, -1306, -837); + BOLDLOC(GC_MAZE_SILVER_BOULDER_19, RCAREA_GORON_CITY, SCENE_GORON_CITY, RHT_GC_SILVER_BOULDER, -1279, -656); + BOLDLOC(GC_MAZE_SILVER_BOULDER_20, RCAREA_GORON_CITY, SCENE_GORON_CITY, RHT_GC_SILVER_BOULDER, -1255, -840); + BOLDLOC(GC_MAZE_SILVER_BOULDER_21, RCAREA_GORON_CITY, SCENE_GORON_CITY, RHT_GC_SILVER_BOULDER, -1246, -1075); + BOLDLOC(GC_MAZE_SILVER_BOULDER_22, RCAREA_GORON_CITY, SCENE_GORON_CITY, RHT_GC_SILVER_BOULDER, -1244, -589); + BOLDLOC(GC_MAZE_SILVER_BOULDER_23, RCAREA_GORON_CITY, SCENE_GORON_CITY, RHT_GC_SILVER_BOULDER, -1210, -852); + BOLDLOC(GC_MAZE_SILVER_BOULDER_24, RCAREA_GORON_CITY, SCENE_GORON_CITY, RHT_GC_SILVER_BOULDER, -1206, -627); + BOLDLOC(GC_MAZE_SILVER_BOULDER_25, RCAREA_GORON_CITY, SCENE_GORON_CITY, RHT_GC_SILVER_BOULDER, -1187, -896); + BOLDLOC(GC_MAZE_SILVER_BOULDER_26, RCAREA_GORON_CITY, SCENE_GORON_CITY, RHT_GC_SILVER_BOULDER, -1157, -954); + BOLDLOC(GC_MAZE_SILVER_BOULDER_27, RCAREA_GORON_CITY, SCENE_GORON_CITY, RHT_GC_SILVER_BOULDER, -1130, -1137); + BOLDLOC(GC_MAZE_SILVER_BOULDER_28, RCAREA_GORON_CITY, SCENE_GORON_CITY, RHT_GC_SILVER_BOULDER, -1120, -1001); + BOLDLOC(GC_MAZE_SILVER_BOULDER_29, RCAREA_GORON_CITY, SCENE_GORON_CITY, RHT_GC_SILVER_BOULDER, -1179, -1098); + BOLDLOC(GC_MAZE_BOULDER_1, RCAREA_GORON_CITY, SCENE_GORON_CITY, RHT_GC_BOULDER, -1342, -628); + BOLDLOC(GC_MAZE_BOULDER_2, RCAREA_GORON_CITY, SCENE_GORON_CITY, RHT_GC_BOULDER, -1456, -501); + BOLDLOC(GC_MAZE_BOULDER_3, RCAREA_GORON_CITY, SCENE_GORON_CITY, RHT_GC_BOULDER, -1233, -511); + BOLDLOC(GC_MAZE_BOULDER_4, RCAREA_GORON_CITY, SCENE_GORON_CITY, RHT_GC_BOULDER, -1137, -657); + BOLDLOC(GC_MAZE_BOULDER_5, RCAREA_GORON_CITY, SCENE_GORON_CITY, RHT_GC_BOULDER, -1124, -913); + BOLDLOC(GC_MAZE_BOULDER_6, RCAREA_GORON_CITY, SCENE_GORON_CITY, RHT_GC_BOULDER, -1326, -771); + BOLDLOC(GC_MAZE_BOULDER_7, RCAREA_GORON_CITY, SCENE_GORON_CITY, RHT_GC_BOULDER, -1469, -737); + BOLDLOC(GC_MAZE_BOULDER_8, RCAREA_GORON_CITY, SCENE_GORON_CITY, RHT_GC_BOULDER, -1476, -921); + BOLDLOC(GC_MAZE_BOULDER_9, RCAREA_GORON_CITY, SCENE_GORON_CITY, RHT_GC_BOULDER, -1391, -1087); + BOLDLOC(GC_MAZE_BOULDER_10, RCAREA_GORON_CITY, SCENE_GORON_CITY, RHT_GC_BOULDER, -1222, -997); + BOLDLOC(GC_MAZE_BRONZE_BOULDER_1, RCAREA_GORON_CITY, SCENE_GORON_CITY, RHT_GC_BRONZE_BOULDER, -1541, -631); + BOLDLOC(GC_MAZE_BRONZE_BOULDER_2, RCAREA_GORON_CITY, SCENE_GORON_CITY, RHT_GC_BRONZE_BOULDER, -1536, -861); + BOLDLOC(GC_MAZE_BRONZE_BOULDER_3, RCAREA_GORON_CITY, SCENE_GORON_CITY, RHT_GC_BRONZE_BOULDER, -1536, -1102); + BOLDLOC(GC_MAZE_BRONZE_BOULDER_4, RCAREA_GORON_CITY, SCENE_GORON_CITY, RHT_GC_BRONZE_BOULDER, -1534, -752); + BOLDLOC(GC_MAZE_BRONZE_BOULDER_5, RCAREA_GORON_CITY, SCENE_GORON_CITY, RHT_GC_BRONZE_BOULDER, -1536, -991); + ROCKLOC(GC_MAZE_ROCK, RCAREA_GORON_CITY, SCENE_GORON_CITY, RHT_GC_ROCK, -1197, -1329); + BOLDLOC(COLOSSUS_SILVER_BOULDER, RCAREA_DESERT_COLOSSUS, SCENE_DESERT_COLOSSUS, RHT_COLOSSUS_SILVER_BOULDER, 61, + -1301); + ROCKLOC(COLOSSUS_ROCK, RCAREA_DESERT_COLOSSUS, SCENE_DESERT_COLOSSUS, RHT_COLOSSUS_ROCK, 1537, 667); + ROCKLOC(COLOSSUS_CIRCLE_1_ROCK_1, RCAREA_DESERT_COLOSSUS, SCENE_DESERT_COLOSSUS, RHT_COLOSSUS_ROCK, -250, -1272); + ROCKLOC(COLOSSUS_CIRCLE_1_ROCK_2, RCAREA_DESERT_COLOSSUS, SCENE_DESERT_COLOSSUS, RHT_COLOSSUS_ROCK, -193, -1295); + ROCKLOC(COLOSSUS_CIRCLE_1_ROCK_3, RCAREA_DESERT_COLOSSUS, SCENE_DESERT_COLOSSUS, RHT_COLOSSUS_ROCK, -170, -1352); + ROCKLOC(COLOSSUS_CIRCLE_1_ROCK_4, RCAREA_DESERT_COLOSSUS, SCENE_DESERT_COLOSSUS, RHT_COLOSSUS_ROCK, -193, -1408); + ROCKLOC(COLOSSUS_CIRCLE_1_ROCK_5, RCAREA_DESERT_COLOSSUS, SCENE_DESERT_COLOSSUS, RHT_COLOSSUS_ROCK, -250, -1432); + ROCKLOC(COLOSSUS_CIRCLE_1_ROCK_6, RCAREA_DESERT_COLOSSUS, SCENE_DESERT_COLOSSUS, RHT_COLOSSUS_ROCK, -306, -1408); + ROCKLOC(COLOSSUS_CIRCLE_1_ROCK_7, RCAREA_DESERT_COLOSSUS, SCENE_DESERT_COLOSSUS, RHT_COLOSSUS_ROCK, -330, -1352); + ROCKLOC(COLOSSUS_CIRCLE_1_ROCK_8, RCAREA_DESERT_COLOSSUS, SCENE_DESERT_COLOSSUS, RHT_COLOSSUS_ROCK, -306, -1295); + ROCKLOC(COLOSSUS_CIRCLE_2_ROCK_1, RCAREA_DESERT_COLOSSUS, SCENE_DESERT_COLOSSUS, RHT_COLOSSUS_ROCK, -834, -766); + ROCKLOC(COLOSSUS_CIRCLE_2_ROCK_2, RCAREA_DESERT_COLOSSUS, SCENE_DESERT_COLOSSUS, RHT_COLOSSUS_ROCK, -777, -789); + ROCKLOC(COLOSSUS_CIRCLE_2_ROCK_3, RCAREA_DESERT_COLOSSUS, SCENE_DESERT_COLOSSUS, RHT_COLOSSUS_ROCK, -754, -846); + ROCKLOC(COLOSSUS_CIRCLE_2_ROCK_4, RCAREA_DESERT_COLOSSUS, SCENE_DESERT_COLOSSUS, RHT_COLOSSUS_ROCK, -777, -902); + ROCKLOC(COLOSSUS_CIRCLE_2_ROCK_5, RCAREA_DESERT_COLOSSUS, SCENE_DESERT_COLOSSUS, RHT_COLOSSUS_ROCK, -834, -926); + ROCKLOC(COLOSSUS_CIRCLE_2_ROCK_6, RCAREA_DESERT_COLOSSUS, SCENE_DESERT_COLOSSUS, RHT_COLOSSUS_ROCK, -890, -902); + ROCKLOC(COLOSSUS_CIRCLE_2_ROCK_7, RCAREA_DESERT_COLOSSUS, SCENE_DESERT_COLOSSUS, RHT_COLOSSUS_ROCK, -914, -846); + ROCKLOC(COLOSSUS_CIRCLE_2_ROCK_8, RCAREA_DESERT_COLOSSUS, SCENE_DESERT_COLOSSUS, RHT_COLOSSUS_ROCK, -890, -789); + ROCKLOC(HC_STORMS_GROTTO_ROCK_1, RCAREA_HYRULE_CASTLE, SCENE_GROTTOS, RHT_HC_STORMS_GROTTO_ROCK, 1811, 813); + ROCKLOC(HC_STORMS_GROTTO_ROCK_2, RCAREA_HYRULE_CASTLE, SCENE_GROTTOS, RHT_HC_STORMS_GROTTO_ROCK, 1867, 789); + ROCKLOC(HC_STORMS_GROTTO_ROCK_3, RCAREA_HYRULE_CASTLE, SCENE_GROTTOS, RHT_HC_STORMS_GROTTO_ROCK, 1891, 733); + ROCKLOC(HC_STORMS_GROTTO_ROCK_4, RCAREA_HYRULE_CASTLE, SCENE_GROTTOS, RHT_HC_STORMS_GROTTO_ROCK, 1867, 676); + ROCKLOC(HC_STORMS_GROTTO_ROCK_5, RCAREA_HYRULE_CASTLE, SCENE_GROTTOS, RHT_HC_STORMS_GROTTO_ROCK, 1811, 653); + ROCKLOC(HC_STORMS_GROTTO_ROCK_6, RCAREA_HYRULE_CASTLE, SCENE_GROTTOS, RHT_HC_STORMS_GROTTO_ROCK, 1754, 676); + ROCKLOC(HC_STORMS_GROTTO_ROCK_7, RCAREA_HYRULE_CASTLE, SCENE_GROTTOS, RHT_HC_STORMS_GROTTO_ROCK, 1731, 733); + ROCKLOC(HC_STORMS_GROTTO_ROCK_8, RCAREA_HYRULE_CASTLE, SCENE_GROTTOS, RHT_HC_STORMS_GROTTO_ROCK, 1754, 789); + locationTable[RC_BOTW_BOULDER_1] = + Location::Boulder(RC_BOTW_BOULDER_1, RCQUEST_VANILLA, RCAREA_BOTTOM_OF_THE_WELL, SCENE_BOTTOM_OF_THE_WELL, + TWO_ACTOR_PARAMS(-684, -734), "BOTW Boulder 1", RHT_BOTW_BOULDER, + SpoilerCollectionCheck::RandomizerInf(RAND_INF_BOTW_BOULDER_1)); + locationTable[RC_BOTW_BOULDER_2] = + Location::Boulder(RC_BOTW_BOULDER_2, RCQUEST_VANILLA, RCAREA_BOTTOM_OF_THE_WELL, SCENE_BOTTOM_OF_THE_WELL, + TWO_ACTOR_PARAMS(-632, -805), "BOTW Boulder 2", RHT_BOTW_BOULDER, + SpoilerCollectionCheck::RandomizerInf(RAND_INF_BOTW_BOULDER_2)); + locationTable[RC_BOTW_BOULDER_3] = + Location::Boulder(RC_BOTW_BOULDER_3, RCQUEST_VANILLA, RCAREA_BOTTOM_OF_THE_WELL, SCENE_BOTTOM_OF_THE_WELL, + TWO_ACTOR_PARAMS(333, -681), "BOTW Boulder 3", RHT_BOTW_BOULDER, + SpoilerCollectionCheck::RandomizerInf(RAND_INF_BOTW_BOULDER_3)); + locationTable[RC_BOTW_BOULDER_4] = + Location::Boulder(RC_BOTW_BOULDER_4, RCQUEST_VANILLA, RCAREA_BOTTOM_OF_THE_WELL, SCENE_BOTTOM_OF_THE_WELL, + TWO_ACTOR_PARAMS(409, -637), "BOTW Boulder 4", RHT_BOTW_BOULDER, + SpoilerCollectionCheck::RandomizerInf(RAND_INF_BOTW_BOULDER_4)); + locationTable[RC_BOTW_BOULDER_5] = + Location::Boulder(RC_BOTW_BOULDER_5, RCQUEST_VANILLA, RCAREA_BOTTOM_OF_THE_WELL, SCENE_BOTTOM_OF_THE_WELL, + TWO_ACTOR_PARAMS(334, -8), "BOTW Boulder 5", RHT_BOTW_BOULDER, + SpoilerCollectionCheck::RandomizerInf(RAND_INF_BOTW_BOULDER_5)); + locationTable[RC_BOTW_BOULDER_6] = + Location::Boulder(RC_BOTW_BOULDER_6, RCQUEST_VANILLA, RCAREA_BOTTOM_OF_THE_WELL, SCENE_BOTTOM_OF_THE_WELL, + TWO_ACTOR_PARAMS(312, 64), "BOTW Boulder 6", RHT_BOTW_BOULDER, + SpoilerCollectionCheck::RandomizerInf(RAND_INF_BOTW_BOULDER_6)); +#define MQBOLD(id, area, hint, x, z) \ + (locationTable[RC_##id] = \ + Location::Boulder(RC_##id, RCQUEST_MQ, RCAREA_##area, SCENE_##area, TWO_ACTOR_PARAMS(x, z), #id, hint, \ + SpoilerCollectionCheck::RandomizerInf(RAND_INF_##id))) + MQBOLD(DEKU_TREE_MQ_BOULDER_1, DEKU_TREE, RHT_DEKU_BOULDER, -1237, 1558); + MQBOLD(DEKU_TREE_MQ_BOULDER_2, DEKU_TREE, RHT_DEKU_BOULDER, -1183, 1522); + MQBOLD(DEKU_TREE_MQ_BOULDER_3, DEKU_TREE, RHT_DEKU_BOULDER, -1129, 1469); + MQBOLD(DODONGOS_CAVERN_MQ_LOBBY_BOULDER_1, DODONGOS_CAVERN, RHT_DODONGOS_BOULDER, -435, -1720); + MQBOLD(DODONGOS_CAVERN_MQ_LOBBY_BOULDER_2, DODONGOS_CAVERN, RHT_DODONGOS_BOULDER, 432, -1719); + MQBOLD(DODONGOS_CAVERN_MQ_MOUTH_SIDE_BRIDGE_BOULDER_1, DODONGOS_CAVERN, RHT_DODONGOS_BOULDER, 807, -874); + MQBOLD(DODONGOS_CAVERN_MQ_MOUTH_SIDE_BRIDGE_BOULDER_2, DODONGOS_CAVERN, RHT_DODONGOS_BOULDER, 802, -972); + MQBOLD(DODONGOS_CAVERN_MQ_MOUTH_SIDE_BRIDGE_BOULDER_3, DODONGOS_CAVERN, RHT_DODONGOS_BOULDER, 783, -923); + MQBOLD(DODONGOS_CAVERN_MQ_RIGHT_SIDE_BOULDER_1, DODONGOS_CAVERN, RHT_DODONGOS_BOULDER, 2464, -402); + MQBOLD(DODONGOS_CAVERN_MQ_RIGHT_SIDE_BOULDER_2, DODONGOS_CAVERN, RHT_DODONGOS_BOULDER, 2942, -495); + MQBOLD(DODONGOS_CAVERN_MQ_LIZALFOS_ROOM_BOULDER_1, DODONGOS_CAVERN, RHT_DODONGOS_BOULDER, 4219, -1651); + MQBOLD(DODONGOS_CAVERN_MQ_LIZALFOS_ROOM_BOULDER_2, DODONGOS_CAVERN, RHT_DODONGOS_BOULDER, 4178, -1602); + MQBOLD(DODONGOS_CAVERN_MQ_LIZALFOS_ROOM_BOULDER_3, DODONGOS_CAVERN, RHT_DODONGOS_BOULDER, 4162, -1581); + MQBOLD(DODONGOS_CAVERN_MQ_LIZALFOS_ROOM_BOULDER_4, DODONGOS_CAVERN, RHT_DODONGOS_BOULDER, 4133, -1561); + MQBOLD(DODONGOS_CAVERN_MQ_LIZALFOS_ROOM_BOULDER_5, DODONGOS_CAVERN, RHT_DODONGOS_BOULDER, 4091, -1510); + MQBOLD(DODONGOS_CAVERN_MQ_LIZALFOS_ROOM_BOULDER_6, DODONGOS_CAVERN, RHT_DODONGOS_BOULDER, 4067, -1487); + MQBOLD(DODONGOS_CAVERN_MQ_LIZALFOS_ROOM_BOULDER_7, DODONGOS_CAVERN, RHT_DODONGOS_BOULDER, 4028, -1472); + MQBOLD(DODONGOS_CAVERN_MQ_LIZALFOS_ROOM_BOULDER_8, DODONGOS_CAVERN, RHT_DODONGOS_BOULDER, 3965, -1473); + MQBOLD(DODONGOS_CAVERN_MQ_LIZALFOS_ROOM_BOULDER_9, DODONGOS_CAVERN, RHT_DODONGOS_BOULDER, 3898, -1467); + MQBOLD(DODONGOS_CAVERN_MQ_LIZALFOS_ROOM_BOULDER_10, DODONGOS_CAVERN, RHT_DODONGOS_BOULDER, 3832, -1437); + MQBOLD(DODONGOS_CAVERN_MQ_LIZALFOS_ROOM_BOULDER_11, DODONGOS_CAVERN, RHT_DODONGOS_BOULDER, 3799, -1383); + MQBOLD(DODONGOS_CAVERN_MQ_LIZALFOS_ROOM_BOULDER_12, DODONGOS_CAVERN, RHT_DODONGOS_BOULDER, 3760, -1318); + MQBOLD(DODONGOS_CAVERN_MQ_TWO_FLAMES_BOULDER, DODONGOS_CAVERN, RHT_DODONGOS_BOULDER, 2737, -1058); + locationTable[RC_JABU_JABUS_BELLY_MQ_ENTRANCE_BOULDER] = + Location::Boulder(RC_JABU_JABUS_BELLY_MQ_ENTRANCE_BOULDER, RCQUEST_MQ, RCAREA_JABU_JABUS_BELLY, SCENE_JABU_JABU, + TWO_ACTOR_PARAMS(-1, -296), "RC_JABU_JABUS_BELLY_MQ_ENTRANCE_BOULDER", RHT_JABU_BOULDER, + SpoilerCollectionCheck::RandomizerInf(RAND_INF_JABU_JABUS_BELLY_MQ_ENTRANCE_BOULDER)); + locationTable[RC_JABU_JABUS_BELLY_MQ_HOLES_ROOM_BOULDER_1] = Location::Boulder( + RC_JABU_JABUS_BELLY_MQ_HOLES_ROOM_BOULDER_1, RCQUEST_MQ, RCAREA_JABU_JABUS_BELLY, SCENE_JABU_JABU, + TWO_ACTOR_PARAMS(350, -3533), "RC_JABU_JABUS_BELLY_MQ_HOLES_ROOM_BOULDER_1", RHT_JABU_BOULDER, + SpoilerCollectionCheck::RandomizerInf(RAND_INF_JABU_JABUS_BELLY_MQ_HOLES_ROOM_BOULDER_1)); + locationTable[RC_JABU_JABUS_BELLY_MQ_HOLES_ROOM_BOULDER_2] = Location::Boulder( + RC_JABU_JABUS_BELLY_MQ_HOLES_ROOM_BOULDER_2, RCQUEST_MQ, RCAREA_JABU_JABUS_BELLY, SCENE_JABU_JABU, + TWO_ACTOR_PARAMS(-192, -3211), "RC_JABU_JABUS_BELLY_MQ_HOLES_ROOM_BOULDER_2", RHT_JABU_BOULDER, + SpoilerCollectionCheck::RandomizerInf(RAND_INF_JABU_JABUS_BELLY_MQ_HOLES_ROOM_BOULDER_2)); + locationTable[RC_JABU_JABUS_BELLY_MQ_HOLES_ROOM_WALL_BOULDER_1] = Location::Boulder( + RC_JABU_JABUS_BELLY_MQ_HOLES_ROOM_WALL_BOULDER_1, RCQUEST_MQ, RCAREA_JABU_JABUS_BELLY, SCENE_JABU_JABU, + TWO_ACTOR_PARAMS(245, -2792), "RC_JABU_JABUS_BELLY_MQ_HOLES_ROOM_WALL_BOULDER_1", RHT_JABU_BOULDER, + SpoilerCollectionCheck::RandomizerInf(RAND_INF_JABU_JABUS_BELLY_MQ_HOLES_ROOM_WALL_BOULDER_1)); + locationTable[RC_JABU_JABUS_BELLY_MQ_HOLES_ROOM_WALL_BOULDER_2] = Location::Boulder( + RC_JABU_JABUS_BELLY_MQ_HOLES_ROOM_WALL_BOULDER_2, RCQUEST_MQ, RCAREA_JABU_JABUS_BELLY, SCENE_JABU_JABU, + TWO_ACTOR_PARAMS(220, -2790), "RC_JABU_JABUS_BELLY_MQ_HOLES_ROOM_WALL_BOULDER_2", RHT_JABU_BOULDER, + SpoilerCollectionCheck::RandomizerInf(RAND_INF_JABU_JABUS_BELLY_MQ_HOLES_ROOM_WALL_BOULDER_2)); + locationTable[RC_JABU_JABUS_BELLY_MQ_HOLES_ROOM_WALL_BOULDER_3] = Location::Boulder( + RC_JABU_JABUS_BELLY_MQ_HOLES_ROOM_WALL_BOULDER_3, RCQUEST_MQ, RCAREA_JABU_JABUS_BELLY, SCENE_JABU_JABU, + TWO_ACTOR_PARAMS(274, -2790), "RC_JABU_JABUS_BELLY_MQ_HOLES_ROOM_WALL_BOULDER_3", RHT_JABU_BOULDER, + SpoilerCollectionCheck::RandomizerInf(RAND_INF_JABU_JABUS_BELLY_MQ_HOLES_ROOM_WALL_BOULDER_3)); + locationTable[RC_JABU_JABUS_BELLY_MQ_FORKED_CORRIDOR_BOULDER_1] = Location::Boulder( + RC_JABU_JABUS_BELLY_MQ_FORKED_CORRIDOR_BOULDER_1, RCQUEST_MQ, RCAREA_JABU_JABUS_BELLY, SCENE_JABU_JABU, + TWO_ACTOR_PARAMS(31, -5177), "RC_JABU_JABUS_BELLY_MQ_FORKED_CORRIDOR_BOULDER_1", RHT_JABU_BOULDER, + SpoilerCollectionCheck::RandomizerInf(RAND_INF_JABU_JABUS_BELLY_MQ_FORKED_CORRIDOR_BOULDER_1)); + locationTable[RC_JABU_JABUS_BELLY_MQ_FORKED_CORRIDOR_BOULDER_2] = Location::Boulder( + RC_JABU_JABUS_BELLY_MQ_FORKED_CORRIDOR_BOULDER_2, RCQUEST_MQ, RCAREA_JABU_JABUS_BELLY, SCENE_JABU_JABU, + TWO_ACTOR_PARAMS(-37, -5173), "RC_JABU_JABUS_BELLY_MQ_FORKED_CORRIDOR_BOULDER_2", RHT_JABU_BOULDER, + SpoilerCollectionCheck::RandomizerInf(RAND_INF_JABU_JABUS_BELLY_MQ_FORKED_CORRIDOR_BOULDER_2)); + locationTable[RC_JABU_JABUS_BELLY_MQ_TAILPASARAN_BOULDER] = Location::Boulder( + RC_JABU_JABUS_BELLY_MQ_TAILPASARAN_BOULDER, RCQUEST_MQ, RCAREA_JABU_JABUS_BELLY, SCENE_JABU_JABU, + TWO_ACTOR_PARAMS(-885, -5907), "RC_JABU_JABUS_BELLY_MQ_TAILPASARAN_BOULDER", RHT_JABU_BOULDER, + SpoilerCollectionCheck::RandomizerInf(RAND_INF_JABU_JABUS_BELLY_MQ_TAILPASARAN_BOULDER)); + locationTable[RC_JABU_JABUS_BELLY_MQ_TAILPASARAN_WALL_BOULDER] = Location::Boulder( + RC_JABU_JABUS_BELLY_MQ_TAILPASARAN_WALL_BOULDER, RCQUEST_MQ, RCAREA_JABU_JABUS_BELLY, SCENE_JABU_JABU, + TWO_ACTOR_PARAMS(-411, -5682), "RC_JABU_JABUS_BELLY_MQ_TAILPASARAN_WALL_BOULDER", RHT_JABU_BOULDER, + SpoilerCollectionCheck::RandomizerInf(RAND_INF_JABU_JABUS_BELLY_MQ_TAILPASARAN_WALL_BOULDER)); + // skip spirit temple boulder, so adult can clear without collecting check for child to pass + MQBOLD(SPIRIT_TEMPLE_MQ_ENTRANCE_BOULDER_1, SPIRIT_TEMPLE, RHT_SPIRIT_TEMPLE_BOULDER, -160, 270); + MQBOLD(SPIRIT_TEMPLE_MQ_ENTRANCE_BOULDER_2, SPIRIT_TEMPLE, RHT_SPIRIT_TEMPLE_BOULDER, 160, 270); + MQBOLD(SPIRIT_TEMPLE_MQ_ENTRANCE_BOULDER_3, SPIRIT_TEMPLE, RHT_SPIRIT_TEMPLE_BOULDER, 350, 220); + MQBOLD(SPIRIT_TEMPLE_MQ_ENTRANCE_CEILING_BOULDER, SPIRIT_TEMPLE, RHT_SPIRIT_TEMPLE_BOULDER, 0, -60); + MQBOLD(SPIRIT_TEMPLE_MQ_EARLY_ADULT_BOULDER, SPIRIT_TEMPLE, RHT_SPIRIT_TEMPLE_BOULDER, 1070, -290); + MQBOLD(BOTW_MQ_BOULDER_1, BOTTOM_OF_THE_WELL, RHT_BOTW_BOULDER, -370, -160); + MQBOLD(BOTW_MQ_BOULDER_2, BOTTOM_OF_THE_WELL, RHT_BOTW_BOULDER, -521, -353); + MQBOLD(BOTW_MQ_BOULDER_3, BOTTOM_OF_THE_WELL, RHT_BOTW_BOULDER, -541, -404); +} + +static ObjectExtension::Register RegisterRockIdentity; +static RegisterShipInitFunc initFunc(RegisterShuffleRock, { "IS_RANDO" }); +static RegisterShipInitFunc initFunc2(Rando::StaticData::RegisterRockLocations); \ No newline at end of file diff --git a/soh/soh/Enhancements/randomizer/ShuffleRocks.h b/soh/soh/Enhancements/randomizer/ShuffleRocks.h new file mode 100644 index 00000000000..ad7ea4d7a83 --- /dev/null +++ b/soh/soh/Enhancements/randomizer/ShuffleRocks.h @@ -0,0 +1,15 @@ +#ifndef SHUFFLEROCKS_H +#define SHUFFLEROCKS_H + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif +void EnIshi_RandomizerInit(void* actorRef); +#ifdef __cplusplus +}; +#endif + +#endif // SHUFFLEROCKS_H \ No newline at end of file diff --git a/soh/soh/Enhancements/randomizer/animation_capture_tool.cpp b/soh/soh/Enhancements/randomizer/animation_capture_tool.cpp new file mode 100644 index 00000000000..a91936a7e03 --- /dev/null +++ b/soh/soh/Enhancements/randomizer/animation_capture_tool.cpp @@ -0,0 +1,52 @@ +// I provide here the code which allowed me to have all the data for the roll animation for roll_animation_data.h +// I had temporarily put it in the Draw.cpp file and I called the function when Link performed a roll + +/* +#define NUM_FRAMES_TO_CAPTURE 10 +static Vec3s capturedRollFrames[NUM_FRAMES_TO_CAPTURE][LIMB_COUNT_LINK]; +static int captureFrameCount = 0; +static bool captureComplete = false; +static bool captureStarted = false; + +extern "C" void CaptureRollAnimation(PlayState* play) { + if (captureComplete) + return; + + Player* player = GET_PLAYER(play); + if (player == NULL || player->skelAnime.jointTable == NULL) + return; + + // Checks if the player is rolling | Vérifie si le joueur roule + bool isRolling = (player->actionFunc == Player_Action_Roll); + + if (isRolling) { + if (!captureStarted) { + captureStarted = true; + osSyncPrintf("\n========== DÉBUT CAPTURE ANIMATION ROLL ==========\n"); + } + + // Captures a frame every 2 game frames | Capture une frame toutes les 2 frames de jeu + if ((play->state.frames % 2) == 0 && captureFrameCount < NUM_FRAMES_TO_CAPTURE) { + osSyncPrintf("\n// Frame %d\n", captureFrameCount); + osSyncPrintf("{\n"); + + for (int i = 0; i < LIMB_COUNT_LINK; i++) { + Vec3s joint = player->skelAnime.jointTable[i]; + capturedRollFrames[captureFrameCount][i] = joint; + + osSyncPrintf(" { %d, %d, %d }, // Limb %d\n", joint.x, joint.y, joint.z, i); + } + + osSyncPrintf("},\n"); + + captureFrameCount++; + + if (captureFrameCount >= NUM_FRAMES_TO_CAPTURE) { + captureComplete = true; + osSyncPrintf("\n========== FIN CAPTURE - %d FRAMES CAPTURÉES ==========\n", NUM_FRAMES_TO_CAPTURE); + osSyncPrintf("Copie ces données et envoie-les moi !\n\n"); + } + } + } +} +*/ \ No newline at end of file diff --git a/soh/soh/Enhancements/randomizer/draw.cpp b/soh/soh/Enhancements/randomizer/draw.cpp index 32cfe801c6a..b5cbee2a371 100644 --- a/soh/soh/Enhancements/randomizer/draw.cpp +++ b/soh/soh/Enhancements/randomizer/draw.cpp @@ -36,7 +36,11 @@ extern "C" { #include "overlays/actors/ovl_Boss_Goma/z_boss_goma.h" #include "objects/object_tw/object_tw.h" #include "objects/object_ganon2/object_ganon2.h" +#include "objects/object_vase/object_vase.h" +#include "objects/object_link_child/object_link_child.h" +#include "roll_animation_data.h" #include "objects/object_gi_shield_1/object_gi_shield_1.h" + extern PlayState* gPlayState; extern SaveContext gSaveContext; } @@ -119,6 +123,17 @@ extern "C" void Randomizer_DrawSmallKey(PlayState* play, GetItemEntry* getItemEn CLOSE_DISPS(play->state.gfxCtx); } +extern "C" void Randomizer_DrawBeanSprout(PlayState* play, GetItemEntry* getItemEntry) { + OPEN_DISPS(play->state.gfxCtx); + + Gfx_SetupDL_25Opa(play->state.gfxCtx); + Matrix_Scale(0.3f, 0.3f, 0.3f, MTXMODE_APPLY); + gSPMatrix(POLY_OPA_DISP++, MATRIX_NEWMTX(play->state.gfxCtx), G_MTX_MODELVIEW | G_MTX_LOAD); + gSPDisplayList(POLY_OPA_DISP++, (Gfx*)gMagicBeanSeedlingDL); + + CLOSE_DISPS(play->state.gfxCtx); +} + extern "C" void Randomizer_DrawMap(PlayState* play, GetItemEntry* getItemEntry) { s16 color_slot = getItemEntry->drawItemId - RG_DEKU_TREE_MAP; s16 colors[12][3] = { @@ -947,17 +962,6 @@ extern "C" void DrawGanon(PlayState* play) { CLOSE_DISPS(play->state.gfxCtx); } -extern "C" void Randomizer_DrawBeanSprout(PlayState* play, GetItemEntry* getItemEntry) { - OPEN_DISPS(play->state.gfxCtx); - - Gfx_SetupDL_25Opa(play->state.gfxCtx); - Matrix_Scale(0.3f, 0.3f, 0.3f, MTXMODE_APPLY); - gSPMatrix(POLY_OPA_DISP++, MATRIX_NEWMTX(play->state.gfxCtx), G_MTX_MODELVIEW | G_MTX_LOAD); - gSPDisplayList(POLY_OPA_DISP++, (Gfx*)gMagicBeanSeedlingDL); - - CLOSE_DISPS(play->state.gfxCtx); -} - extern "C" void Randomizer_DrawBossSoul(PlayState* play, GetItemEntry* getItemEntry) { s16 slot; if (getItemEntry->getItemId != RG_ICE_TRAP) { @@ -1189,6 +1193,48 @@ extern "C" void Randomizer_DrawKneePads(PlayState* play, GetItemEntry* getItemEn CLOSE_DISPS(play->state.gfxCtx); } +extern "C" void Randomizer_DrawRollAbility(PlayState* play, GetItemEntry* getItemEntry) { + static bool initialized = false; + static SkelAnime skelAnime; + static Vec3s jointTable[ROLL_ANIMATION_LIMBS]; + static Vec3s morphTable[ROLL_ANIMATION_LIMBS]; + static u32 lastUpdate = 0; + static int currentFrame = 0; + + if (!initialized) { + initialized = true; + SkelAnime_InitFlex(play, &skelAnime, (FlexSkeletonHeader*)gLinkChildSkel, NULL, jointTable, morphTable, + ROLL_ANIMATION_LIMBS); + } + + // Manual animation with captured frames + if (lastUpdate != play->state.frames) { + lastUpdate = play->state.frames; + + // Advances one frame every 2 frames of play + if ((play->state.frames % 2) == 0) { + currentFrame = (currentFrame + 1) % ROLL_ANIMATION_FRAMES; + } + + // Copies data from current frame + for (int i = 0; i < ROLL_ANIMATION_LIMBS; i++) { + jointTable[i] = rollAnimationData[currentFrame][i]; + } + } + + OPEN_DISPS(play->state.gfxCtx); + + Gfx_SetupDL_25Opa(play->state.gfxCtx); + + Matrix_Translate(0.0f, -30.0f, 0.0f, MTXMODE_APPLY); + Matrix_RotateY(play->gameplayFrames * 0.05f, MTXMODE_APPLY); + Matrix_Scale(0.01f, 0.01f, 0.01f, MTXMODE_APPLY); + + SkelAnime_DrawFlexOpa(play, skelAnime.skeleton, jointTable, skelAnime.dListCount, NULL, NULL, NULL); + + CLOSE_DISPS(play->state.gfxCtx); +} + extern "C" void Randomizer_DrawJabberNut(PlayState* play, GetItemEntry* getItemEntry) { OPEN_DISPS(play->state.gfxCtx); @@ -1403,4 +1449,4 @@ extern "C" void Randomizer_DrawOverworldKey(PlayState* play, GetItemEntry* getIt gSPDisplayList(POLY_OPA_DISP++, (Gfx*)gHouseKeyDL); CLOSE_DISPS(play->state.gfxCtx); -} +} \ No newline at end of file diff --git a/soh/soh/Enhancements/randomizer/draw.h b/soh/soh/Enhancements/randomizer/draw.h index d674f562fac..0f9eaf7fab8 100644 --- a/soh/soh/Enhancements/randomizer/draw.h +++ b/soh/soh/Enhancements/randomizer/draw.h @@ -24,7 +24,9 @@ void Randomizer_DrawOcarinaButton(PlayState* play, GetItemEntry* getItemEntry); void Randomizer_DrawBronzeScale(PlayState* play, GetItemEntry* getItemEntry); void Randomizer_DrawPowerBracelet(PlayState* play, GetItemEntry* getItemEntry); void Randomizer_DrawLadder(PlayState* play, GetItemEntry* getItemEntry); +void Randomizer_DrawRollAbility(PlayState* play, GetItemEntry* getItemEntry); void Randomizer_DrawKneePads(PlayState* play, GetItemEntry* getItemEntry); +void Randomizer_DrawRollAbility(PlayState* play, GetItemEntry* getItemEntry); void Randomizer_DrawJabberNut(PlayState* play, GetItemEntry* getItemEntry); void Randomizer_DrawOpenChest(PlayState* play, GetItemEntry* getItemEntry); void Randomizer_DrawFishingPoleGI(PlayState* play, GetItemEntry* getItemEntry); diff --git a/soh/soh/Enhancements/randomizer/hook_handlers.cpp b/soh/soh/Enhancements/randomizer/hook_handlers.cpp index ff14d7c8f89..bc4c4f2f419 100644 --- a/soh/soh/Enhancements/randomizer/hook_handlers.cpp +++ b/soh/soh/Enhancements/randomizer/hook_handlers.cpp @@ -1,4 +1,4 @@ -#include +#include #include "soh/OTRGlobals.h" #include "soh/ResourceManagerHelpers.h" #include "soh/Enhancements/enhancementTypes.h" @@ -865,6 +865,9 @@ void RandomizerOnVanillaBehaviorHandler(GIVanillaBehavior id, bool* should, va_l case VB_CRAWL: *should = *should && Flags_GetRandomizerInf(RAND_INF_CAN_CRAWL); break; + case VB_ROLL: + *should = !RAND_GET_OPTION(RSK_SHUFFLE_ROLL) || Flags_GetRandomizerInf(RAND_INF_CAN_ROLL); + break; case VB_ALLOW_ENTRANCE_CS_FOR_EITHER_AGE: { s32 entranceIndex = va_arg(args, s32); diff --git a/soh/soh/Enhancements/randomizer/item_list.cpp b/soh/soh/Enhancements/randomizer/item_list.cpp index d2be0ce00ce..044928229c2 100644 --- a/soh/soh/Enhancements/randomizer/item_list.cpp +++ b/soh/soh/Enhancements/randomizer/item_list.cpp @@ -390,7 +390,10 @@ void Rando::StaticData::InitItemTable() { itemTable[RG_OPEN_CHEST] = Item(RG_OPEN_CHEST, Text{ "Open Chests", TODO_TRANSLATE, TODO_TRANSLATE }, ITEMTYPE_ITEM, GI_KEY_SMALL, true, LOGIC_NONE, RHT_OPEN_CHEST, RG_OPEN_CHEST, OBJECT_GI_KEY, GID_KEY_SMALL, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_RANDOMIZER); itemTable[RG_OPEN_CHEST].SetCustomDrawFunc(Randomizer_DrawOpenChest); - itemTable[RG_PROGRESSIVE_BOMBCHU_BAG] = Item(RG_PROGRESSIVE_BOMBCHU_BAG, Text{ "Bombchu Bag", "Sac de Missiles Teigneux", "Krabbelminentasche" }, ITEMTYPE_ITEM, RG_PROGRESSIVE_BOMBCHU_BAG, true, LOGIC_BOMBCHUS, RHT_BOMBCHU_BAG, RG_PROGRESSIVE_BOMBCHU_BAG, OBJECT_GI_BOMB_2, GID_BOMBCHU, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_RANDOMIZER, {"a ", "eine ", "un "}); + itemTable[RG_ROLL] = Item(RG_ROLL, Text{ "Roll", "Rouler", "Rolle" }, ITEMTYPE_ITEM, GI_SCALE_SILVER, true, LOGIC_NONE, RHT_ROLL, RG_ROLL, OBJECT_GI_SCALE, GID_SCALE_SILVER, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_RANDOMIZER); + itemTable[RG_ROLL].SetCustomDrawFunc(Randomizer_DrawRollAbility); + + itemTable[RG_PROGRESSIVE_BOMBCHU_BAG] = Item(RG_PROGRESSIVE_BOMBCHU_BAG, Text{ "Bombchu Bag", "Sac de Missiles Teigneux", "Krabbelminentasche" }, ITEMTYPE_ITEM, RG_PROGRESSIVE_BOMBCHU_BAG, true, LOGIC_BOMBCHUS, RHT_BOMBCHU_BAG, RG_PROGRESSIVE_BOMBCHU_BAG, OBJECT_GI_BOMB_2, GID_BOMBCHU, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_RANDOMIZER); itemTable[RG_PROGRESSIVE_BOMBCHU_BAG].SetCustomDrawFunc(Randomizer_DrawBombchuBag); itemTable[RG_QUIVER_INF] = Item(RG_QUIVER_INF, Text{ "Infinite Quiver", "Carquois Infini", "Unendlicher Köcher" }, ITEMTYPE_ITEM, RG_QUIVER_INF, true, LOGIC_PROGRESSIVE_BOW, RHT_QUIVER_INF, RG_QUIVER_INF, OBJECT_GI_ARROWCASE, GID_QUIVER_50, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_LESSER, MOD_RANDOMIZER, {"the ", "den ", "le "}); diff --git a/soh/soh/Enhancements/randomizer/location.cpp b/soh/soh/Enhancements/randomizer/location.cpp index e129a6b264b..25c687f2b6f 100644 --- a/soh/soh/Enhancements/randomizer/location.cpp +++ b/soh/soh/Enhancements/randomizer/location.cpp @@ -581,6 +581,23 @@ Rando::Location Rando::Location::NLTree(RandomizerCheck rc, RandomizerCheckQuest false, collectionCheck }; } +Rando::Location Rando::Location::Rock(RandomizerCheck rc, RandomizerCheckQuest quest_, RandomizerCheckArea area_, + SceneID scene_, int32_t actorParams_, std::string&& shortName_, + RandomizerHintTextKey hintKey, RandomizerGet vanillaItem, + SpoilerCollectionCheck collectionCheck) { + return { rc, quest_, RCTYPE_ROCK, area_, ACTOR_EN_ISHI, + scene_, actorParams_, std::move(shortName_), hintKey, vanillaItem, + false, collectionCheck }; +} + +Rando::Location Rando::Location::Boulder(RandomizerCheck rc, RandomizerCheckQuest quest_, RandomizerCheckArea area_, + SceneID scene_, int32_t actorParams_, std::string&& shortName_, + RandomizerHintTextKey hintKey, SpoilerCollectionCheck collectionCheck) { + return { rc, quest_, RCTYPE_BOULDER, area_, ACTOR_EN_ISHI, + scene_, actorParams_, std::move(shortName_), hintKey, RG_BOMBS_5, + false, collectionCheck }; +} + Rando::Location Rando::Location::Bush(RandomizerCheck rc, RandomizerCheckQuest quest_, RandomizerCheckArea area_, SceneID scene_, int32_t actorParams_, std::string&& shortName_, RandomizerHintTextKey hintKey, RandomizerGet vanillaItem, diff --git a/soh/soh/Enhancements/randomizer/location.h b/soh/soh/Enhancements/randomizer/location.h index 24b192cc342..e1406c56581 100644 --- a/soh/soh/Enhancements/randomizer/location.h +++ b/soh/soh/Enhancements/randomizer/location.h @@ -67,15 +67,7 @@ class Location { actorParams(actorParams_), shortName(std::move(shortName_)), spoilerName(std::move(spoilerName_)), hintKey(hintKey_), vanillaItem(vanillaItem_), isVanillaCompletion(isVanillaCompletion_), collectionCheck(collectionCheck_), vanillaPrice(vanillaPrice_) { - if (spoilerName.length() < 23) { - excludedOption = LocationOption(rc, spoilerName); - } else { - const size_t lastSpace = spoilerName.rfind(' ', 23); - std::string settingText = spoilerName; - settingText.replace(lastSpace, 1, "\n "); - - excludedOption = LocationOption(rc, spoilerName); - } + excludedOption = LocationOption(rc, spoilerName); } Location(const RandomizerCheck rc_, const RandomizerCheckQuest quest_, const RandomizerCheckType checkType_, @@ -87,15 +79,7 @@ class Location { actorParams(actorParams_), shortName(shortName_), spoilerName(SpoilerNameFromShortName(shortName_, area_)), hintKey(hintKey_), vanillaItem(vanillaItem_), isVanillaCompletion(isVanillaCompletion_), collectionCheck(collectionCheck_), vanillaPrice(vanillaPrice_) { - if (spoilerName.length() < 23) { - excludedOption = LocationOption(rc, spoilerName); - } else { - const size_t lastSpace = spoilerName.rfind(' ', 23); - std::string settingText = spoilerName; - settingText.replace(lastSpace, 1, "\n "); - - excludedOption = LocationOption(rc, spoilerName); - } + excludedOption = LocationOption(rc, spoilerName); } static std::string SpoilerNameFromShortName(std::string shortName, RandomizerCheckArea area) { @@ -253,6 +237,14 @@ class Location { int32_t actorParams_, std::string&& shortName_, RandomizerHintTextKey hintKey, RandomizerGet vanillaItem, SpoilerCollectionCheck collectionCheck); + static Location Rock(RandomizerCheck rc, RandomizerCheckQuest quest_, RandomizerCheckArea area_, SceneID scene_, + int32_t actorParams_, std::string&& shortName_, RandomizerHintTextKey hintKey, + RandomizerGet vanillaItem, SpoilerCollectionCheck collectionCheck); + + static Location Boulder(RandomizerCheck rc, RandomizerCheckQuest quest_, RandomizerCheckArea area_, SceneID scene_, + int32_t actorParams_, std::string&& shortName_, RandomizerHintTextKey hintKey, + SpoilerCollectionCheck collectionCheck); + static Location Bush(RandomizerCheck rc, RandomizerCheckQuest quest_, RandomizerCheckArea area_, SceneID scene_, int32_t actorParams_, std::string&& shortName_, RandomizerHintTextKey hintKey, RandomizerGet vanillaItem, SpoilerCollectionCheck collectionCheck); diff --git a/soh/soh/Enhancements/randomizer/location_access/dungeons/bottom_of_the_well.cpp b/soh/soh/Enhancements/randomizer/location_access/dungeons/bottom_of_the_well.cpp index a61b936a0f0..87b95ddfd81 100644 --- a/soh/soh/Enhancements/randomizer/location_access/dungeons/bottom_of_the_well.cpp +++ b/soh/soh/Enhancements/randomizer/location_access/dungeons/bottom_of_the_well.cpp @@ -231,6 +231,12 @@ void RegionTable_Init_BottomOfTheWell() { LOCATION(RC_BOTTOM_OF_THE_WELL_BASEMENT_BEHIND_ROCKS_GRASS_7, logic->CanCutShrubs()), LOCATION(RC_BOTTOM_OF_THE_WELL_BASEMENT_BEHIND_ROCKS_GRASS_8, logic->CanCutShrubs()), LOCATION(RC_BOTTOM_OF_THE_WELL_BASEMENT_BEHIND_ROCKS_GRASS_9, logic->CanCutShrubs()), + LOCATION(RC_BOTW_BOULDER_1, logic->BlastOrSmash()), + LOCATION(RC_BOTW_BOULDER_2, logic->BlastOrSmash()), + LOCATION(RC_BOTW_BOULDER_3, logic->BlastOrSmash() || logic->CanUse(RG_DINS_FIRE) || (logic->CanUse(RG_STICKS) && ctx->GetTrickOption(RT_BOTW_BASEMENT))), + LOCATION(RC_BOTW_BOULDER_4, logic->BlastOrSmash()), + LOCATION(RC_BOTW_BOULDER_5, logic->BlastOrSmash()), + LOCATION(RC_BOTW_BOULDER_6, logic->BlastOrSmash()), }, { //Exits ENTRANCE(RR_BOTW_B3_OOZE, AnyAgeTime([]{return logic->BlastOrSmash() || logic->HasItem(RG_GORONS_BRACELET);})), @@ -278,6 +284,9 @@ void RegionTable_Init_BottomOfTheWell() { LOCATION(RC_BOTTOM_OF_THE_WELL_MQ_OUTER_LOBBY_POT, AnyAgeTime([]{return logic->BlastOrSmash();}) && logic->CanHitEyeTargets()), LOCATION(RC_BOTTOM_OF_THE_WELL_MQ_BOMB_LEFT_HEART, logic->HasExplosives()), LOCATION(RC_BOTTOM_OF_THE_WELL_MQ_BOMB_RIGHT_HEART, logic->HasExplosives()), + LOCATION(RC_BOTW_MQ_BOULDER_1, logic->BlastOrSmash()), + LOCATION(RC_BOTW_MQ_BOULDER_2, logic->BlastOrSmash()), + LOCATION(RC_BOTW_MQ_BOULDER_3, logic->BlastOrSmash()), }, { //Exits ENTRANCE(RR_BOTW_ENTRYWAY, logic->CanUse(RG_CRAWL) && (logic->HasItem(RG_CLIMB) || logic->CanUse(RG_HOOKSHOT))), diff --git a/soh/soh/Enhancements/randomizer/location_access/dungeons/deku_tree.cpp b/soh/soh/Enhancements/randomizer/location_access/dungeons/deku_tree.cpp index 18d379d2dea..cb0294cb567 100644 --- a/soh/soh/Enhancements/randomizer/location_access/dungeons/deku_tree.cpp +++ b/soh/soh/Enhancements/randomizer/location_access/dungeons/deku_tree.cpp @@ -23,7 +23,6 @@ void RegionTable_Init_DekuTree() { EVENT_ACCESS(LOGIC_DEKU_TREE_1F_BROKE_WEB, logic->HasFireSource()), }, { //Locations - LOCATION(RC_DEKU_TREE_MAP_CHEST, logic->HasItem(RG_OPEN_CHEST)), LOCATION(RC_DEKU_TREE_LOBBY_LOWER_HEART, logic->CanUse(RG_BOOMERANG)), LOCATION(RC_DEKU_TREE_LOBBY_GRASS_1, logic->CanCutShrubs()), LOCATION(RC_DEKU_TREE_LOBBY_GRASS_2, logic->CanCutShrubs()), @@ -41,7 +40,7 @@ void RegionTable_Init_DekuTree() { areaTable[RR_DEKU_TREE_LOBBY_2F] = Region("Deku Tree Lobby 2F", SCENE_DEKU_TREE, {}, { //Locations - LOCATION(RC_DEKU_TREE_MAP_CHEST, true), + LOCATION(RC_DEKU_TREE_MAP_CHEST, logic->HasItem(RG_OPEN_CHEST)), LOCATION(RC_DEKU_TREE_LOBBY_LOWER_HEART, true), }, { //Exits @@ -325,6 +324,9 @@ void RegionTable_Init_DekuTree() { //Locations LOCATION(RC_DEKU_TREE_MQ_GS_PAST_BOULDER_VINES, logic->CanGetEnemyDrop(RE_GOLD_SKULLTULA, ED_BOOMERANG)), LOCATION(RC_DEKU_TREE_MQ_COMPASS_ROOM_HEART, true), + LOCATION(RC_DEKU_TREE_MQ_BOULDER_1, true), + LOCATION(RC_DEKU_TREE_MQ_BOULDER_2, true), + LOCATION(RC_DEKU_TREE_MQ_BOULDER_3, true), }, { //Exits ENTRANCE(RR_DEKU_TREE_MQ_COMPASS_ROOM, logic->BlastOrSmash()), diff --git a/soh/soh/Enhancements/randomizer/location_access/dungeons/dodongos_cavern.cpp b/soh/soh/Enhancements/randomizer/location_access/dungeons/dodongos_cavern.cpp index 6066a0f9846..6520adb4c20 100644 --- a/soh/soh/Enhancements/randomizer/location_access/dungeons/dodongos_cavern.cpp +++ b/soh/soh/Enhancements/randomizer/location_access/dungeons/dodongos_cavern.cpp @@ -291,6 +291,8 @@ void RegionTable_Init_DodongosCavern() { LOCATION(RC_DODONGOS_CAVERN_MQ_MAP_CHEST, (logic->CanBreakMudWalls() || logic->HasItem(RG_GORONS_BRACELET)) && logic->HasItem(RG_OPEN_CHEST)), LOCATION(RC_DODONGOS_CAVERN_MQ_DEKU_SCRUB_LOBBY_REAR, logic->CanStunDeku() && logic->HasItem(RG_SPEAK_DEKU) && GetCheckPrice() <= GetWalletCapacity()), LOCATION(RC_DODONGOS_CAVERN_MQ_DEKU_SCRUB_LOBBY_FRONT, logic->CanStunDeku() && logic->HasItem(RG_SPEAK_DEKU) && GetCheckPrice() <= GetWalletCapacity()), + LOCATION(RC_DODONGOS_CAVERN_MQ_LOBBY_BOULDER_1, logic->BlastOrSmash() || logic->HasItem(RG_GORONS_BRACELET)), + LOCATION(RC_DODONGOS_CAVERN_MQ_LOBBY_BOULDER_2, logic->BlastOrSmash() || logic->HasItem(RG_GORONS_BRACELET)), }, { //Exits ENTRANCE(RR_DODONGOS_CAVERN_MQ_BEGINNING, true), @@ -328,7 +330,12 @@ void RegionTable_Init_DodongosCavern() { //Events EVENT_ACCESS(LOGIC_DC_MQ_CLEAR_UPPER_LOBBY_ROCKS, logic->BlastOrSmash() || logic->CanUse(RG_DINS_FIRE)), EVENT_ACCESS(LOGIC_DC_EYES_LIT, logic->HasExplosives() || (logic->Get(LOGIC_DC_MQ_CLEAR_UPPER_LOBBY_ROCKS) && logic->HasItem(RG_GORONS_BRACELET) && ((logic->IsAdult && ctx->GetTrickOption(RT_DC_MQ_ADULT_EYES)) || (logic->IsChild && ctx->GetTrickOption(RT_DC_MQ_CHILD_EYES))))), - }, {}, { + }, { + //Locations + LOCATION(RC_DODONGOS_CAVERN_MQ_MOUTH_SIDE_BRIDGE_BOULDER_1, logic->Get(LOGIC_DC_MQ_CLEAR_UPPER_LOBBY_ROCKS)), + LOCATION(RC_DODONGOS_CAVERN_MQ_MOUTH_SIDE_BRIDGE_BOULDER_2, logic->Get(LOGIC_DC_MQ_CLEAR_UPPER_LOBBY_ROCKS)), + LOCATION(RC_DODONGOS_CAVERN_MQ_MOUTH_SIDE_BRIDGE_BOULDER_3, logic->Get(LOGIC_DC_MQ_CLEAR_UPPER_LOBBY_ROCKS)), + }, { //Exits ENTRANCE(RR_DODONGOS_CAVERN_MQ_LOBBY, true), ENTRANCE(RR_DODONGOS_CAVERN_MQ_TORCH_PUZZLE_UPPER, logic->Get(LOGIC_DC_MQ_CLEAR_UPPER_LOBBY_ROCKS)), @@ -452,6 +459,18 @@ void RegionTable_Init_DodongosCavern() { LOCATION(RC_DODONGOS_CAVERN_MQ_UPPER_LIZALFOS_POT_3, logic->CanBreakPots()), LOCATION(RC_DODONGOS_CAVERN_MQ_UPPER_LIZALFOS_POT_4, logic->CanBreakPots()), LOCATION(RC_DODONGOS_CAVERN_MQ_LIZALFOS_ROOM_HEART, logic->BlastOrSmash()), + LOCATION(RC_DODONGOS_CAVERN_MQ_LIZALFOS_ROOM_BOULDER_1, logic->BlastOrSmash() && logic->TakeDamage()), + LOCATION(RC_DODONGOS_CAVERN_MQ_LIZALFOS_ROOM_BOULDER_2, logic->BlastOrSmash() && logic->TakeDamage()), + LOCATION(RC_DODONGOS_CAVERN_MQ_LIZALFOS_ROOM_BOULDER_3, logic->BlastOrSmash() && logic->TakeDamage()), + LOCATION(RC_DODONGOS_CAVERN_MQ_LIZALFOS_ROOM_BOULDER_4, logic->BlastOrSmash() && logic->TakeDamage()), + LOCATION(RC_DODONGOS_CAVERN_MQ_LIZALFOS_ROOM_BOULDER_5, logic->BlastOrSmash()), + LOCATION(RC_DODONGOS_CAVERN_MQ_LIZALFOS_ROOM_BOULDER_6, logic->BlastOrSmash()), + LOCATION(RC_DODONGOS_CAVERN_MQ_LIZALFOS_ROOM_BOULDER_7, logic->BlastOrSmash() && logic->TakeDamage()), + LOCATION(RC_DODONGOS_CAVERN_MQ_LIZALFOS_ROOM_BOULDER_8, logic->BlastOrSmash() && logic->TakeDamage()), + LOCATION(RC_DODONGOS_CAVERN_MQ_LIZALFOS_ROOM_BOULDER_9, logic->BlastOrSmash() && logic->TakeDamage()), + LOCATION(RC_DODONGOS_CAVERN_MQ_LIZALFOS_ROOM_BOULDER_10, logic->BlastOrSmash() && logic->TakeDamage()), + LOCATION(RC_DODONGOS_CAVERN_MQ_LIZALFOS_ROOM_BOULDER_11, logic->BlastOrSmash() && logic->TakeDamage()), + LOCATION(RC_DODONGOS_CAVERN_MQ_LIZALFOS_ROOM_BOULDER_12, logic->BlastOrSmash() && logic->TakeDamage()), }, { //Exits //Falling down gets you stuck with nothing there, not a useful exit for logic @@ -465,6 +484,7 @@ void RegionTable_Init_DodongosCavern() { LOCATION(RC_DODONGOS_CAVERN_MQ_TWO_FLAMES_POT_2, logic->CanBreakPots()), LOCATION(RC_DODONGOS_CAVERN_MQ_TWO_FLAMES_CRATE_1, logic->CanBreakCrates()), LOCATION(RC_DODONGOS_CAVERN_MQ_TWO_FLAMES_CRATE_2, logic->CanBreakCrates()), + LOCATION(RC_DODONGOS_CAVERN_MQ_TWO_FLAMES_BOULDER, logic->BlastOrSmash() || logic->HasItem(RG_GORONS_BRACELET)), }, { //Exits ENTRANCE(RR_DODONGOS_CAVERN_MQ_UPPER_LIZALFOS, true), @@ -491,10 +511,12 @@ void RegionTable_Init_DodongosCavern() { areaTable[RR_DODONGOS_CAVERN_MQ_LOWER_RIGHT_SIDE] = Region("Dodongos Cavern MQ Lower Right Side", SCENE_DODONGOS_CAVERN, {}, { //Locations - LOCATION(RC_DODONGOS_CAVERN_MQ_RIGHT_SIDE_POT_1, logic->CanBreakPots()), - LOCATION(RC_DODONGOS_CAVERN_MQ_RIGHT_SIDE_POT_2, logic->CanBreakPots()), - LOCATION(RC_DODONGOS_CAVERN_MQ_RIGHT_SIDE_POT_3, logic->CanBreakPots()), - LOCATION(RC_DODONGOS_CAVERN_MQ_RIGHT_SIDE_POT_4, logic->CanBreakPots()), + LOCATION(RC_DODONGOS_CAVERN_MQ_RIGHT_SIDE_POT_1, logic->CanBreakPots()), + LOCATION(RC_DODONGOS_CAVERN_MQ_RIGHT_SIDE_POT_2, logic->CanBreakPots()), + LOCATION(RC_DODONGOS_CAVERN_MQ_RIGHT_SIDE_POT_3, logic->CanBreakPots()), + LOCATION(RC_DODONGOS_CAVERN_MQ_RIGHT_SIDE_POT_4, logic->CanBreakPots()), + LOCATION(RC_DODONGOS_CAVERN_MQ_RIGHT_SIDE_BOULDER_1, logic->BlastOrSmash() || logic->HasItem(RG_GORONS_BRACELET) || logic->CanUse(RG_DINS_FIRE)), + LOCATION(RC_DODONGOS_CAVERN_MQ_RIGHT_SIDE_BOULDER_2, logic->CanDetonateBombFlowers() || logic->HasItem(RG_GORONS_BRACELET) || (ctx->GetTrickOption(RT_BLUE_FIRE_MUD_WALLS) && logic->CanUse(RG_BOTTLE_WITH_BLUE_FIRE) && (logic->EffectiveHealth() != 1 || logic->CanUse(RG_NAYRUS_LOVE)))), }, { //Exits ENTRANCE(RR_DODONGOS_CAVERN_MQ_LOBBY, true), diff --git a/soh/soh/Enhancements/randomizer/location_access/dungeons/fire_temple.cpp b/soh/soh/Enhancements/randomizer/location_access/dungeons/fire_temple.cpp index 7d9581d73bb..942a8d7a442 100644 --- a/soh/soh/Enhancements/randomizer/location_access/dungeons/fire_temple.cpp +++ b/soh/soh/Enhancements/randomizer/location_access/dungeons/fire_temple.cpp @@ -305,7 +305,7 @@ void RegionTable_Init_FireTemple() { ENTRANCE(RR_FIRE_TEMPLE_NEAR_BOSS_ROOM, logic->Get(LOGIC_FIRE_HIT_PLATFORM) && (logic->IsAdult || logic->CanUse(RG_HOVER_BOOTS) || logic->TakeDamage())), ENTRANCE(RR_FIRE_TEMPLE_CORRIDOR, true), ENTRANCE(RR_FIRE_TEMPLE_FIRE_MAZE_PLATFORMS, logic->CanUse(RG_HOVER_BOOTS) || (logic->IsAdult && (logic->Get(LOGIC_FIRE_HIT_ABOVE_MAZE_PLATFORM) || logic->CanGroundJump()))), - ENTRANCE(RR_FIRE_TEMPLE_CAGELESS_CHEST_ROOM, true), + ENTRANCE(RR_FIRE_TEMPLE_CAGELESS_CHEST_ROOM, logic->HasItem(RG_OPEN_CHEST)), ENTRANCE(RR_FIRE_TEMPLE_SOT_CAGE_LOWER, logic->SmallKeys(SCENE_FIRE_TEMPLE, 8)), ENTRANCE(RR_FIRE_TEMPLE_FIRE_MAZE_SWITCH, (bool)ctx->GetTrickOption(RT_FIRE_SKIP_FLAME_WALLS)), }); diff --git a/soh/soh/Enhancements/randomizer/location_access/dungeons/forest_temple.cpp b/soh/soh/Enhancements/randomizer/location_access/dungeons/forest_temple.cpp index a54d6bd7747..4ff721c718a 100644 --- a/soh/soh/Enhancements/randomizer/location_access/dungeons/forest_temple.cpp +++ b/soh/soh/Enhancements/randomizer/location_access/dungeons/forest_temple.cpp @@ -197,7 +197,7 @@ void RegionTable_Init_ForestTemple() { areaTable[RR_FOREST_TEMPLE_SEWER] = Region("Forest Temple Sewer", SCENE_FOREST_TEMPLE, {}, { //Locations - LOCATION(RC_FOREST_TEMPLE_WELL_CHEST, logic->CanOpenUnderwaterChest() && logic->WaterTimer() >= 8), + LOCATION(RC_FOREST_TEMPLE_WELL_CHEST, logic->CanOpenUnderwaterChest() && logic->WaterTimer() >= 8 && logic->HasItem(RG_OPEN_CHEST)), LOCATION(RC_FOREST_TEMPLE_WELL_WEST_HEART, logic->CanUse(RG_IRON_BOOTS) && logic->WaterTimer() >= 8), LOCATION(RC_FOREST_TEMPLE_WELL_EAST_HEART, logic->CanUse(RG_IRON_BOOTS) && logic->WaterTimer() >= 8), }, { @@ -672,7 +672,6 @@ void RegionTable_Init_ForestTemple() { }); areaTable[RR_FOREST_TEMPLE_MQ_NE_COURTYARD_DOORFRAME] = Region("Forest Temple MQ NE Courtyard Doorframe", SCENE_FOREST_TEMPLE, {}, { - //Locations //Actually killing the skull from the doorframe with melee is annoying. Hammer swing hits low enough unaided, other swords need to crouch stab but the spot is precise based on range. kokiri sword doesn't reach at all for adult. LOCATION(RC_FOREST_TEMPLE_MQ_GS_RAISED_ISLAND_COURTYARD, logic->CanKillEnemy(RE_GOLD_SKULLTULA, ED_BOMB_THROW) || logic->CanUse(RG_MEGATON_HAMMER) || (logic->CanStandingShield() && (logic->CanUse(RG_STICKS) || logic->CanUse(RG_BIGGORON_SWORD) || logic->CanUse(RG_MASTER_SWORD) || (logic->IsChild && logic->CanUse(RG_KOKIRI_SWORD))))), diff --git a/soh/soh/Enhancements/randomizer/location_access/dungeons/gerudo_training_ground.cpp b/soh/soh/Enhancements/randomizer/location_access/dungeons/gerudo_training_ground.cpp index 1f89806ee83..67dc21f3aad 100644 --- a/soh/soh/Enhancements/randomizer/location_access/dungeons/gerudo_training_ground.cpp +++ b/soh/soh/Enhancements/randomizer/location_access/dungeons/gerudo_training_ground.cpp @@ -409,4 +409,4 @@ void RegionTable_Init_GerudoTrainingGround() { #pragma endregion // clang-format on -} +} \ No newline at end of file diff --git a/soh/soh/Enhancements/randomizer/location_access/dungeons/jabujabus_belly.cpp b/soh/soh/Enhancements/randomizer/location_access/dungeons/jabujabus_belly.cpp index 6286eaae5cb..4a967768e19 100644 --- a/soh/soh/Enhancements/randomizer/location_access/dungeons/jabujabus_belly.cpp +++ b/soh/soh/Enhancements/randomizer/location_access/dungeons/jabujabus_belly.cpp @@ -272,6 +272,7 @@ void RegionTable_Init_JabuJabusBelly() { LOCATION(RC_JABU_JABUS_BELLY_MQ_ENTRANCE_POT_2, logic->CanBreakPots()), LOCATION(RC_JABU_JABUS_BELLY_MQ_FIRST_GRASS_1, logic->CanCutShrubs()), LOCATION(RC_JABU_JABUS_BELLY_MQ_FIRST_GRASS_2, logic->CanCutShrubs()), + LOCATION(RC_JABU_JABUS_BELLY_MQ_ENTRANCE_BOULDER, logic->BlastOrSmash()), }, { //Exits ENTRANCE(RR_JABU_JABUS_BELLY_ENTRYWAY, true), @@ -342,6 +343,11 @@ void RegionTable_Init_JabuJabusBelly() { LOCATION(RC_JABU_JABUS_BELLY_MQ_BASEMENT_GRASS_1, logic->CanCutShrubs()), LOCATION(RC_JABU_JABUS_BELLY_MQ_BASEMENT_GRASS_2, logic->CanCutShrubs()), LOCATION(RC_JABU_JABUS_BELLY_MQ_BASEMENT_GRASS_3, logic->CanCutShrubs()), + LOCATION(RC_JABU_JABUS_BELLY_MQ_HOLES_ROOM_BOULDER_1, logic->BlastOrSmash()), + LOCATION(RC_JABU_JABUS_BELLY_MQ_HOLES_ROOM_BOULDER_2, logic->BlastOrSmash()), + LOCATION(RC_JABU_JABUS_BELLY_MQ_HOLES_ROOM_WALL_BOULDER_1, logic->HasExplosives()), + LOCATION(RC_JABU_JABUS_BELLY_MQ_HOLES_ROOM_WALL_BOULDER_2, logic->HasExplosives()), + LOCATION(RC_JABU_JABUS_BELLY_MQ_HOLES_ROOM_WALL_BOULDER_3, logic->HasExplosives()), }, { //Exits ENTRANCE(RR_JABU_JABUS_BELLY_MQ_HOLES_ROOM, logic->HasItem(RG_CLIMB)), @@ -438,6 +444,8 @@ void RegionTable_Init_JabuJabusBelly() { LOCATION(RC_JABU_JABUS_BELLY_MQ_FALLING_LIKE_LIKE_GRASS, logic->CanCutShrubs()), LOCATION(RC_JABU_JABUS_BELLY_MQ_TRIPLE_HALLWAY_SMALL_CRATE_1, logic->CanBreakSmallCrates()), LOCATION(RC_JABU_JABUS_BELLY_MQ_TRIPLE_HALLWAY_SMALL_CRATE_2, logic->CanBreakSmallCrates()), + LOCATION(RC_JABU_JABUS_BELLY_MQ_FORKED_CORRIDOR_BOULDER_1, logic->BlastOrSmash()), + LOCATION(RC_JABU_JABUS_BELLY_MQ_FORKED_CORRIDOR_BOULDER_2, logic->BlastOrSmash()), }, { //Exits ENTRANCE(RR_JABU_JABUS_BELLY_MQ_FORKED_CORRIDOR, true), diff --git a/soh/soh/Enhancements/randomizer/location_access/dungeons/spirit_temple.cpp b/soh/soh/Enhancements/randomizer/location_access/dungeons/spirit_temple.cpp index 90cd300fc63..d0529983bf7 100644 --- a/soh/soh/Enhancements/randomizer/location_access/dungeons/spirit_temple.cpp +++ b/soh/soh/Enhancements/randomizer/location_access/dungeons/spirit_temple.cpp @@ -563,6 +563,10 @@ void RegionTable_Init_SpiritTemple() { LOCATION(RC_SPIRIT_TEMPLE_MQ_ENTRANCE_POT_2, logic->CanBreakPots()), LOCATION(RC_SPIRIT_TEMPLE_MQ_ENTRANCE_POT_3, logic->CanBreakPots()), LOCATION(RC_SPIRIT_TEMPLE_MQ_ENTRANCE_POT_4, logic->CanBreakPots()), + LOCATION(RC_SPIRIT_TEMPLE_MQ_ENTRANCE_BOULDER_1, logic->BlastOrSmash()), + LOCATION(RC_SPIRIT_TEMPLE_MQ_ENTRANCE_BOULDER_2, logic->BlastOrSmash()), + LOCATION(RC_SPIRIT_TEMPLE_MQ_ENTRANCE_BOULDER_3, logic->BlastOrSmash()), + LOCATION(RC_SPIRIT_TEMPLE_MQ_ENTRANCE_CEILING_BOULDER, logic->CanUse(RG_BOMBCHU_5)), }, { //Exits ENTRANCE(RR_SPIRIT_TEMPLE_ENTRYWAY, true), @@ -581,6 +585,7 @@ void RegionTable_Init_SpiritTemple() { LOCATION(RC_SPIRIT_TEMPLE_MQ_CHILD_SLUGMA_POT, logic->CanBreakPots()), LOCATION(RC_SPIRIT_TEMPLE_MQ_CHILD_LEFT_HEART, logic->CanHitEyeTargets()), LOCATION(RC_SPIRIT_TEMPLE_MQ_CHILD_RIGHT_HEART, logic->CanHitEyeTargets()), + LOCATION(RC_SPIRIT_TEMPLE_MQ_CHILD_HAMMER_SWITCH_CHEST, logic->Get(LOGIC_SPIRIT_MQ_TIME_TRAVEL_CHEST) && logic->HasItem(RG_OPEN_CHEST)), }, { //Exits //Nabooru's legs are technically visible one way collision here, but I'm not sure if this counts @@ -910,6 +915,7 @@ void RegionTable_Init_SpiritTemple() { //Locations LOCATION(RC_SPIRIT_TEMPLE_MQ_EARLY_ADULT_POT_1, logic->CanBreakPots()), LOCATION(RC_SPIRIT_TEMPLE_MQ_EARLY_ADULT_POT_2, logic->CanBreakPots()), + LOCATION(RC_SPIRIT_TEMPLE_MQ_EARLY_ADULT_BOULDER, logic->BlastOrSmash()), }, { //Exits ENTRANCE(RR_SPIRIT_TEMPLE_MQ_FOYER, logic->CanUse(RG_MEGATON_HAMMER) || (ctx->GetTrickOption(RT_HOVER_BOOST_SIMPLE) && logic->CanUse(RG_HOVER_BOOTS) && logic->CanStandingShield() && (logic->CanUseSword() || logic->CanUse(RG_STICKS)))), diff --git a/soh/soh/Enhancements/randomizer/location_access/dungeons/water_temple.cpp b/soh/soh/Enhancements/randomizer/location_access/dungeons/water_temple.cpp index eee04dabc05..95b4aaece26 100644 --- a/soh/soh/Enhancements/randomizer/location_access/dungeons/water_temple.cpp +++ b/soh/soh/Enhancements/randomizer/location_access/dungeons/water_temple.cpp @@ -215,7 +215,7 @@ void RegionTable_Init_WaterTemple() { areaTable[RR_WATER_TEMPLE_BOULDERS_SOUTH] = Region("Water Temple Boulders South", SCENE_WATER_TEMPLE, {}, { //Locations - LOCATION(RC_WATER_TEMPLE_GS_NEAR_BOSS_KEY_CHEST, logic->CanUse(RG_LONGSHOT)), + LOCATION(RC_WATER_TEMPLE_GS_NEAR_BOSS_KEY_CHEST, logic->CanUse(RG_LONGSHOT) && logic->HasItem(RG_OPEN_CHEST)), }, { //Exits ENTRANCE(RR_WATER_TEMPLE_BEHIND_SPIKE_MOAT, logic->SmallKeys(SCENE_WATER_TEMPLE, 4)), @@ -285,11 +285,11 @@ void RegionTable_Init_WaterTemple() { areaTable[RR_WATER_TEMPLE_CANAL_ALCOVE] = Region("Water Temple Canal Alcove", SCENE_WATER_TEMPLE, {}, { //Locations - LOCATION(RC_WATER_TEMPLE_GS_NEAR_BOSS_KEY_CHEST, logic->CanGetEnemyDrop(RE_GOLD_SKULLTULA, ED_BOOMERANG) || + LOCATION(RC_WATER_TEMPLE_GS_NEAR_BOSS_KEY_CHEST, (logic->CanGetEnemyDrop(RE_GOLD_SKULLTULA, ED_BOOMERANG) || //child can also do a hovers backwalk backflip to reach the token after killing the skull ((logic->IsAdult || (ctx->GetTrickOption(RT_GROUND_JUMP_HARD) && logic->CanGroundJump())) && //killing with bombchu from here is hard due to the terrain, but adult can do it much easier from the river so it's only relevant for child - logic->CanUse(RG_HOVER_BOOTS) && logic->CanKillEnemy(RE_GOLD_SKULLTULA, logic->HasItem(RG_BRONZE_SCALE) && logic->IsAdult ? ED_SHORT_JUMPSLASH : ED_BOOMERANG))), + logic->CanUse(RG_HOVER_BOOTS) && logic->CanKillEnemy(RE_GOLD_SKULLTULA, logic->HasItem(RG_BRONZE_SCALE) && logic->IsAdult ? ED_SHORT_JUMPSLASH : ED_BOOMERANG))) && logic->HasItem(RG_OPEN_CHEST)), }, { //Exits ENTRANCE(RR_WATER_TEMPLE_3_JETS_SWITCH, true), @@ -299,7 +299,7 @@ void RegionTable_Init_WaterTemple() { areaTable[RR_WATER_TEMPLE_BOULDER_CANAL] = Region("Water Temple Boulder Canal", SCENE_WATER_TEMPLE, {}, { //Locations - LOCATION(RC_WATER_TEMPLE_GS_NEAR_BOSS_KEY_CHEST, (logic->IsAdult && logic->CanGetEnemyDrop(RE_GOLD_SKULLTULA, ED_BOOMERANG)) || (logic->CanUse(RG_IRON_BOOTS) && logic->CanUse(RG_HOOKSHOT))), + LOCATION(RC_WATER_TEMPLE_GS_NEAR_BOSS_KEY_CHEST, ((logic->IsAdult && logic->CanGetEnemyDrop(RE_GOLD_SKULLTULA, ED_BOOMERANG)) || (logic->CanUse(RG_IRON_BOOTS) && logic->CanUse(RG_HOOKSHOT))) && logic->HasItem(RG_OPEN_CHEST)), }, { //Exits //making the jump as adult without jumpslash is possible, but hard enough to be a trick @@ -311,7 +311,7 @@ void RegionTable_Init_WaterTemple() { areaTable[RR_WATER_TEMPLE_BEHIND_CANAL] = Region("Water Temple Behind Canal", SCENE_WATER_TEMPLE, {}, { //Locations - LOCATION(RC_WATER_TEMPLE_GS_NEAR_BOSS_KEY_CHEST, logic->CanUse(RG_IRON_BOOTS) && logic->CanUse(RG_HOOKSHOT) && logic->WaterTimer() >= 8), + LOCATION(RC_WATER_TEMPLE_GS_NEAR_BOSS_KEY_CHEST, logic->CanUse(RG_IRON_BOOTS) && logic->CanUse(RG_HOOKSHOT) && logic->WaterTimer() >= 8 && logic->HasItem(RG_OPEN_CHEST)), }, { //Exits ENTRANCE(RR_WATER_TEMPLE_BOULDER_CANAL, logic->HasItem(RG_BRONZE_SCALE)), @@ -377,7 +377,7 @@ void RegionTable_Init_WaterTemple() { LOCATION(RC_WATER_TEMPLE_DRAGON_CHEST, logic->HasItem(RG_BRONZE_SCALE) && logic->HasItem(RG_OPEN_CHEST) && ((logic->CanUse(RG_HOOKSHOT) && logic->CanUse(RG_IRON_BOOTS)) || (((logic->IsAdult && ctx->GetTrickOption(RT_WATER_ADULT_DRAGON)) || (logic->IsChild && ctx->GetTrickOption(RT_WATER_CHILD_DRAGON))) && - logic->CanHitSwitch(ED_BOOMERANG, true) && (logic->HasItem(RG_SILVER_SCALE) || (logic->CanUse(RG_IRON_BOOTS) && logic->WaterTimer() >= 8))))), + logic->CanHitSwitch(ED_BOOMERANG, true) && (logic->HasItem(RG_SILVER_SCALE) || (logic->CanUse(RG_IRON_BOOTS) && logic->WaterTimer() >= 8)))) && logic->HasItem(RG_OPEN_CHEST)), }, { //Exits ENTRANCE(RR_WATER_TEMPLE_OUTSIDE_DRAGON_ROOM, true), @@ -605,7 +605,7 @@ void RegionTable_Init_WaterTemple() { LOCATION(RC_WATER_TEMPLE_RIVER_CHEST, logic->HasItem(RG_OPEN_CHEST)), LOCATION(RC_WATER_TEMPLE_DRAGON_CHEST, logic->IsAdult && logic->CanHitSwitch(ED_LONGSHOT) && logic->HasItem(RG_BRONZE_SCALE) && logic->HasItem(RG_OPEN_CHEST) && ((ctx->GetTrickOption(RT_WATER_ADULT_DRAGON) && (logic->HasItem(RG_SILVER_SCALE) || (logic->CanUse(RG_IRON_BOOTS) && logic->WaterTimer() >= 8))) || - ctx->GetTrickOption(RT_WATER_DRAGON_JUMP_DIVE))), + ctx->GetTrickOption(RT_WATER_DRAGON_JUMP_DIVE)) && logic->HasItem(RG_OPEN_CHEST)), }, { //Exits ENTRANCE(RR_WATER_TEMPLE_DRAGON_ROOM, logic->HasItem(RG_BRONZE_SCALE) || logic->CanUse(RG_LONGSHOT) || (logic->IsAdult && logic->CanUse(RG_HOVER_BOOTS) && logic->CanJumpslash())), @@ -1137,11 +1137,12 @@ void RegionTable_Init_WaterTemple() { areaTable[RR_WATER_TEMPLE_MQ_DRAGON_ROOM_TUNNEL] = Region("Water Temple MQ Dragon Room Tunnel", SCENE_WATER_TEMPLE, {}, { //Locations - LOCATION(RC_WATER_TEMPLE_MQ_DRAGON_ROOM_SUBMERGED_CRATE_1, logic->CanBreakCrates()), - LOCATION(RC_WATER_TEMPLE_MQ_DRAGON_ROOM_SUBMERGED_CRATE_2, logic->CanBreakCrates()), - LOCATION(RC_WATER_TEMPLE_MQ_DRAGON_ROOM_SUBMERGED_CRATE_3, logic->CanBreakCrates()), - LOCATION(RC_WATER_TEMPLE_MQ_DRAGON_ROOM_SUBMERGED_CRATE_4, logic->CanBreakCrates()), - }, { + LOCATION(RC_WATER_TEMPLE_MQ_DRAGON_ROOM_SUBMERGED_CRATE_1, logic->HasItem(RG_ROLL)), + LOCATION(RC_WATER_TEMPLE_MQ_DRAGON_ROOM_SUBMERGED_CRATE_2, logic->HasItem(RG_ROLL)), + LOCATION(RC_WATER_TEMPLE_MQ_DRAGON_ROOM_SUBMERGED_CRATE_3, logic->HasItem(RG_ROLL)), + LOCATION(RC_WATER_TEMPLE_MQ_DRAGON_ROOM_SUBMERGED_CRATE_4, logic->HasItem(RG_ROLL)), + }, + { //Exits ENTRANCE(RR_WATER_TEMPLE_MQ_RIVER_POTS, logic->CanUse(RG_LONGSHOT)), ENTRANCE(RR_WATER_TEMPLE_MQ_DRAGON_ROOM_ALCOVE, logic->HasItem(RG_BRONZE_SCALE) || logic->CanUse(RG_HOOKSHOT)), @@ -1225,14 +1226,14 @@ void RegionTable_Init_WaterTemple() { areaTable[RR_WATER_TEMPLE_MQ_TRIANGLE_TORCH_ROOM] = Region("Water Temple MQ Triangle Torch Room", SCENE_WATER_TEMPLE, {}, { //Locations - LOCATION(RC_WATER_TEMPLE_MQ_TRIPLE_TORCH_ROOM_SUBMERGED_CRATE_1, (logic->CanUse(RG_IRON_BOOTS) && logic->WaterTimer() >= 16 && logic->CanBreakCrates()) || + LOCATION(RC_WATER_TEMPLE_MQ_TRIPLE_TORCH_ROOM_SUBMERGED_CRATE_1, (logic->CanUse(RG_IRON_BOOTS) && logic->WaterTimer() >= 16 && logic->HasItem(RG_ROLL)) || (logic->CanUse(RG_BOMBCHU_5) && logic->CanUse(RG_BOOMERANG))), - LOCATION(RC_WATER_TEMPLE_MQ_TRIPLE_TORCH_ROOM_SUBMERGED_CRATE_2, (logic->CanUse(RG_IRON_BOOTS) && logic->WaterTimer() >= 16 && logic->CanBreakCrates()) || + LOCATION(RC_WATER_TEMPLE_MQ_TRIPLE_TORCH_ROOM_SUBMERGED_CRATE_2, (logic->CanUse(RG_IRON_BOOTS) && logic->WaterTimer() >= 16 && logic->HasItem(RG_ROLL)) || (logic->CanUse(RG_BOMBCHU_5) && logic->CanUse(RG_BOOMERANG))), - LOCATION(RC_WATER_TEMPLE_MQ_TRIPLE_TORCH_ROOM_SUBMERGED_CRATE_3, logic->CanUse(RG_IRON_BOOTS) && logic->WaterTimer() >= 16 && logic->CanBreakCrates()), - LOCATION(RC_WATER_TEMPLE_MQ_TRIPLE_TORCH_ROOM_SUBMERGED_CRATE_4, logic->CanUse(RG_IRON_BOOTS) && logic->WaterTimer() >= 16 && logic->CanBreakCrates()), - LOCATION(RC_WATER_TEMPLE_MQ_TRIPLE_TORCH_ROOM_SUBMERGED_CRATE_5, logic->CanUse(RG_IRON_BOOTS) && logic->WaterTimer() >= 16 && logic->CanBreakCrates()), - LOCATION(RC_WATER_TEMPLE_MQ_TRIPLE_TORCH_ROOM_SUBMERGED_CRATE_6, logic->CanUse(RG_IRON_BOOTS) && logic->WaterTimer() >= 16 && logic->CanBreakCrates()), + LOCATION(RC_WATER_TEMPLE_MQ_TRIPLE_TORCH_ROOM_SUBMERGED_CRATE_3, logic->CanUse(RG_IRON_BOOTS) && logic->WaterTimer() >= 16 && logic->HasItem(RG_ROLL)), + LOCATION(RC_WATER_TEMPLE_MQ_TRIPLE_TORCH_ROOM_SUBMERGED_CRATE_4, logic->CanUse(RG_IRON_BOOTS) && logic->WaterTimer() >= 16 && logic->HasItem(RG_ROLL)), + LOCATION(RC_WATER_TEMPLE_MQ_TRIPLE_TORCH_ROOM_SUBMERGED_CRATE_5, logic->CanUse(RG_IRON_BOOTS) && logic->WaterTimer() >= 16 && logic->HasItem(RG_ROLL)), + LOCATION(RC_WATER_TEMPLE_MQ_TRIPLE_TORCH_ROOM_SUBMERGED_CRATE_6, logic->CanUse(RG_IRON_BOOTS) && logic->WaterTimer() >= 16 && logic->HasItem(RG_ROLL)), }, { //Exits ENTRANCE(RR_WATER_TEMPLE_MQ_MAIN, logic->Get(LOGIC_WATER_MQ_B1_SWITCH) && ((logic->WaterLevel(WL_LOW) && logic->HasItem(RG_GOLDEN_SCALE)) || (logic->CanUse(RG_IRON_BOOTS) && logic->WaterTimer() >= 40 && (logic->HasItem(RG_BRONZE_SCALE) || logic->CanUse(RG_LONGSHOT))))), @@ -1284,12 +1285,12 @@ void RegionTable_Init_WaterTemple() { //Locations LOCATION(RC_WATER_TEMPLE_MQ_WHIRLPOOL_FRONT_CRATE_1, logic->CanBreakCrates()), LOCATION(RC_WATER_TEMPLE_MQ_WHIRLPOOL_FRONT_CRATE_2, logic->CanBreakCrates()), - LOCATION(RC_WATER_TEMPLE_MQ_WHIRLPOOL_SUBMERGED_CRATE_1, logic->CanUse(RG_IRON_BOOTS) && logic->WaterTimer() >= 16 && logic->CanBreakCrates()), - LOCATION(RC_WATER_TEMPLE_MQ_WHIRLPOOL_SUBMERGED_CRATE_2, logic->CanUse(RG_IRON_BOOTS) && logic->WaterTimer() >= 16 && logic->CanBreakCrates()), - LOCATION(RC_WATER_TEMPLE_MQ_WHIRLPOOL_SUBMERGED_CRATE_3, logic->CanUse(RG_IRON_BOOTS) && logic->WaterTimer() >= 16 && logic->CanBreakCrates()), - LOCATION(RC_WATER_TEMPLE_MQ_WHIRLPOOL_SUBMERGED_CRATE_4, logic->CanUse(RG_IRON_BOOTS) && logic->WaterTimer() >= 16 && logic->CanBreakCrates()), - LOCATION(RC_WATER_TEMPLE_MQ_WHIRLPOOL_SUBMERGED_CRATE_5, logic->CanUse(RG_IRON_BOOTS) && logic->WaterTimer() >= 16 && logic->CanBreakCrates()), - LOCATION(RC_WATER_TEMPLE_MQ_WHIRLPOOL_SUBMERGED_CRATE_6, logic->CanUse(RG_IRON_BOOTS) && logic->WaterTimer() >= 16 && logic->CanBreakCrates()), + LOCATION(RC_WATER_TEMPLE_MQ_WHIRLPOOL_SUBMERGED_CRATE_1, logic->CanUse(RG_IRON_BOOTS) && logic->WaterTimer() >= 16 && logic->HasItem(RG_ROLL)), + LOCATION(RC_WATER_TEMPLE_MQ_WHIRLPOOL_SUBMERGED_CRATE_2, logic->CanUse(RG_IRON_BOOTS) && logic->WaterTimer() >= 16 && logic->HasItem(RG_ROLL)), + LOCATION(RC_WATER_TEMPLE_MQ_WHIRLPOOL_SUBMERGED_CRATE_3, logic->CanUse(RG_IRON_BOOTS) && logic->WaterTimer() >= 16 && logic->HasItem(RG_ROLL)), + LOCATION(RC_WATER_TEMPLE_MQ_WHIRLPOOL_SUBMERGED_CRATE_4, logic->CanUse(RG_IRON_BOOTS) && logic->WaterTimer() >= 16 && logic->HasItem(RG_ROLL)), + LOCATION(RC_WATER_TEMPLE_MQ_WHIRLPOOL_SUBMERGED_CRATE_5, logic->CanUse(RG_IRON_BOOTS) && logic->WaterTimer() >= 16 && logic->HasItem(RG_ROLL)), + LOCATION(RC_WATER_TEMPLE_MQ_WHIRLPOOL_SUBMERGED_CRATE_6, logic->CanUse(RG_IRON_BOOTS) && logic->WaterTimer() >= 16 && logic->HasItem(RG_ROLL)), }, { //Exits ENTRANCE(RR_WATER_TEMPLE_MQ_BEHIND_SPIKE_MOAT, true), diff --git a/soh/soh/Enhancements/randomizer/location_access/overworld/castle_grounds.cpp b/soh/soh/Enhancements/randomizer/location_access/overworld/castle_grounds.cpp index 2a33f87d7f8..bbcc1f97eb6 100644 --- a/soh/soh/Enhancements/randomizer/location_access/overworld/castle_grounds.cpp +++ b/soh/soh/Enhancements/randomizer/location_access/overworld/castle_grounds.cpp @@ -59,6 +59,10 @@ void RegionTable_Init_CastleGrounds() { LOCATION(RC_HC_NEAR_GUARDS_TREE_6, logic->CanBonkTrees()), LOCATION(RC_HC_NL_TREE_1, false), LOCATION(RC_HC_NL_TREE_2, false), + LOCATION(RC_HC_ROCK_1, logic->HasItem(RG_POWER_BRACELET) || logic->BlastOrSmash()), + LOCATION(RC_HC_ROCK_2, logic->HasItem(RG_POWER_BRACELET) || logic->BlastOrSmash()), + LOCATION(RC_HC_ROCK_3, logic->HasItem(RG_POWER_BRACELET) || logic->BlastOrSmash()), + LOCATION(RC_HC_BOULDER, logic->BlastOrSmash()), }, { //Exits ENTRANCE(RR_HC_GATE, true), @@ -141,6 +145,14 @@ void RegionTable_Init_CastleGrounds() { LOCATION(RC_HC_STORMS_GROTTO_POT_2, logic->CanBreakPots()), LOCATION(RC_HC_STORMS_GROTTO_POT_3, logic->CanBreakPots()), LOCATION(RC_HC_STORMS_GROTTO_POT_4, logic->CanBreakPots()), + LOCATION(RC_HC_STORMS_GROTTO_ROCK_1, true), + LOCATION(RC_HC_STORMS_GROTTO_ROCK_2, true), + LOCATION(RC_HC_STORMS_GROTTO_ROCK_3, true), + LOCATION(RC_HC_STORMS_GROTTO_ROCK_4, true), + LOCATION(RC_HC_STORMS_GROTTO_ROCK_5, true), + LOCATION(RC_HC_STORMS_GROTTO_ROCK_6, true), + LOCATION(RC_HC_STORMS_GROTTO_ROCK_7, true), + LOCATION(RC_HC_STORMS_GROTTO_ROCK_8, true), }, { //Exits ENTRANCE(RR_HC_STORMS_GROTTO, true), @@ -151,7 +163,14 @@ void RegionTable_Init_CastleGrounds() { EVENT_ACCESS(LOGIC_BUILD_RAINBOW_BRIDGE, logic->CanBuildRainbowBridge()), }, { //Locations - LOCATION(RC_OGC_GS, logic->CanJumpslashExceptHammer() || logic->CanUseProjectile() || (logic->CanShield() && logic->CanUse(RG_MEGATON_HAMMER)) || logic->CanUse(RG_DINS_FIRE)), + LOCATION(RC_OGC_GS, logic->CanJumpslashExceptHammer() || logic->CanUseProjectile() || (logic->CanShield() && logic->CanUse(RG_MEGATON_HAMMER)) || logic->CanUse(RG_DINS_FIRE)), + LOCATION(RC_OGC_BRONZE_BOULDER_1, logic->CanUse(RG_MEGATON_HAMMER)), + LOCATION(RC_OGC_BRONZE_BOULDER_2, logic->CanUse(RG_MEGATON_HAMMER)), + LOCATION(RC_OGC_BRONZE_BOULDER_3, logic->CanUse(RG_MEGATON_HAMMER)), + LOCATION(RC_OGC_SILVER_BOULDER_1, logic->CanUse(RG_SILVER_GAUNTLETS)), + LOCATION(RC_OGC_SILVER_BOULDER_2, logic->CanUse(RG_SILVER_GAUNTLETS)), + LOCATION(RC_OGC_SILVER_BOULDER_3, logic->CanUse(RG_SILVER_GAUNTLETS)), + LOCATION(RC_OGC_SILVER_BOULDER_4, logic->CanUse(RG_SILVER_GAUNTLETS)), }, { //Exits ENTRANCE(RR_CASTLE_GROUNDS, logic->AtNight), diff --git a/soh/soh/Enhancements/randomizer/location_access/overworld/death_mountain_crater.cpp b/soh/soh/Enhancements/randomizer/location_access/overworld/death_mountain_crater.cpp index f1281e27b2b..c1e51a8d3d1 100644 --- a/soh/soh/Enhancements/randomizer/location_access/overworld/death_mountain_crater.cpp +++ b/soh/soh/Enhancements/randomizer/location_access/overworld/death_mountain_crater.cpp @@ -5,7 +5,21 @@ using namespace Rando; void RegionTable_Init_DeathMountainCrater() { // clang-format off - areaTable[RR_DMC_UPPER_NEARBY] = Region("DMC Upper Nearby", SCENE_DEATH_MOUNTAIN_CRATER, {}, {}, { + areaTable[RR_DMC_UPPER_NEARBY] = Region("DMC Upper Nearby", SCENE_DEATH_MOUNTAIN_CRATER, {}, { + LOCATION(RC_DMC_CIRCLE_ROCK_1, logic->HasItem(RG_POWER_BRACELET) || logic->BlastOrSmash()), + LOCATION(RC_DMC_CIRCLE_ROCK_2, logic->HasItem(RG_POWER_BRACELET) || logic->BlastOrSmash()), + LOCATION(RC_DMC_CIRCLE_ROCK_3, logic->HasItem(RG_POWER_BRACELET) || logic->BlastOrSmash()), + LOCATION(RC_DMC_CIRCLE_ROCK_4, logic->HasItem(RG_POWER_BRACELET) || logic->BlastOrSmash()), + LOCATION(RC_DMC_CIRCLE_ROCK_5, logic->HasItem(RG_POWER_BRACELET) || logic->BlastOrSmash()), + LOCATION(RC_DMC_CIRCLE_ROCK_6, logic->HasItem(RG_POWER_BRACELET) || logic->BlastOrSmash()), + LOCATION(RC_DMC_CIRCLE_ROCK_7, logic->HasItem(RG_POWER_BRACELET) || logic->BlastOrSmash()), + LOCATION(RC_DMC_CIRCLE_ROCK_8, logic->HasItem(RG_POWER_BRACELET) || logic->BlastOrSmash()), + LOCATION(RC_DMC_GOSSIP_ROCK_1, logic->IsChild && (logic->HasItem(RG_POWER_BRACELET) || logic->BlastOrSmash())), + LOCATION(RC_DMC_GOSSIP_ROCK_2, logic->IsChild && (logic->HasItem(RG_POWER_BRACELET) || logic->BlastOrSmash())), + LOCATION(RC_DMC_BOULDER_1, logic->BlastOrSmash()), + LOCATION(RC_DMC_BOULDER_2, logic->BlastOrSmash()), + LOCATION(RC_DMC_BOULDER_3, logic->BlastOrSmash()), + }, { //Exits ENTRANCE(RR_DMC_UPPER_LOCAL, logic->FireTimer() >= 48), ENTRANCE(RR_DEATH_MOUNTAIN_SUMMIT, true), @@ -48,6 +62,14 @@ void RegionTable_Init_DeathMountainCrater() { LOCATION(RC_DMC_NEAR_GC_POT_2, logic->CanBreakPots()), LOCATION(RC_DMC_NEAR_GC_POT_3, logic->CanBreakPots()), LOCATION(RC_DMC_NEAR_GC_POT_4, logic->CanBreakPots()), + LOCATION(RC_DMC_NEAR_GC_POT_1, logic->CanBreakPots()), + LOCATION(RC_DMC_NEAR_GC_POT_2, logic->CanBreakPots()), + LOCATION(RC_DMC_NEAR_GC_POT_3, logic->CanBreakPots()), + LOCATION(RC_DMC_NEAR_GC_POT_4, logic->CanBreakPots()), + LOCATION(RC_DMC_BRONZE_BOULDER_1, logic->CanUse(RG_MEGATON_HAMMER)), + LOCATION(RC_DMC_BRONZE_BOULDER_2, logic->CanUse(RG_MEGATON_HAMMER)), + LOCATION(RC_DMC_BRONZE_BOULDER_3, logic->CanUse(RG_MEGATON_HAMMER)), + LOCATION(RC_DMC_BRONZE_BOULDER_4, logic->CanUse(RG_MEGATON_HAMMER)), }, { //Exits ENTRANCE(RR_DMC_LOWER_LOCAL, logic->FireTimer() >= 48), @@ -90,6 +112,11 @@ void RegionTable_Init_DeathMountainCrater() { LOCATION(RC_DMC_BEAN_SPROUT_FAIRY_1, logic->IsChild && logic->CanUse(RG_MAGIC_BEAN) && logic->HasItem(RG_DEATH_MOUNTAIN_CRATER_BEAN_SOUL) && logic->CanUse(RG_SONG_OF_STORMS) && (logic->FireTimer() >= 8 || logic->Hearts() >= 3)), LOCATION(RC_DMC_BEAN_SPROUT_FAIRY_2, logic->IsChild && logic->CanUse(RG_MAGIC_BEAN) && logic->HasItem(RG_DEATH_MOUNTAIN_CRATER_BEAN_SOUL) && logic->CanUse(RG_SONG_OF_STORMS) && (logic->FireTimer() >= 8 || logic->Hearts() >= 3)), LOCATION(RC_DMC_BEAN_SPROUT_FAIRY_3, logic->IsChild && logic->CanUse(RG_MAGIC_BEAN) && logic->HasItem(RG_DEATH_MOUNTAIN_CRATER_BEAN_SOUL) && logic->CanUse(RG_SONG_OF_STORMS) && (logic->FireTimer() >= 8 || logic->Hearts() >= 3)), + LOCATION(RC_DMC_ROCK_BY_FIRE_TEMPLE_1, logic->IsAdult && (logic->HasItem(RG_POWER_BRACELET) || logic->BlastOrSmash())), + LOCATION(RC_DMC_ROCK_BY_FIRE_TEMPLE_2, logic->IsAdult && (logic->HasItem(RG_POWER_BRACELET) || logic->BlastOrSmash())), + LOCATION(RC_DMC_ROCK_BY_FIRE_TEMPLE_3, logic->IsAdult && (logic->HasItem(RG_POWER_BRACELET) || logic->BlastOrSmash())), + LOCATION(RC_DMC_ROCK_BY_FIRE_TEMPLE_4, logic->IsAdult && (logic->HasItem(RG_POWER_BRACELET) || logic->BlastOrSmash())), + LOCATION(RC_DMC_ROCK_BY_FIRE_TEMPLE_5, logic->IsAdult && (logic->HasItem(RG_POWER_BRACELET) || logic->BlastOrSmash())), }, { //Exits ENTRANCE(RR_DMC_CENTRAL_NEARBY, true), diff --git a/soh/soh/Enhancements/randomizer/location_access/overworld/death_mountain_trail.cpp b/soh/soh/Enhancements/randomizer/location_access/overworld/death_mountain_trail.cpp index 7cb55cf831d..cf94c28fdda 100644 --- a/soh/soh/Enhancements/randomizer/location_access/overworld/death_mountain_trail.cpp +++ b/soh/soh/Enhancements/randomizer/location_access/overworld/death_mountain_trail.cpp @@ -21,6 +21,33 @@ void RegionTable_Init_DeathMountainTrail() { LOCATION(RC_DMT_BEAN_SPROUT_FAIRY_2, logic->IsChild && logic->CanUse(RG_MAGIC_BEAN) && logic->HasItem(RG_DEATH_MOUNTAIN_TRAIL_BEAN_SOUL) && logic->CanUse(RG_SONG_OF_STORMS) && (logic->HasExplosives() || logic->HasItem(RG_GORONS_BRACELET))), LOCATION(RC_DMT_BEAN_SPROUT_FAIRY_3, logic->IsChild && logic->CanUse(RG_MAGIC_BEAN) && logic->HasItem(RG_DEATH_MOUNTAIN_TRAIL_BEAN_SOUL) && logic->CanUse(RG_SONG_OF_STORMS) && (logic->HasExplosives() || logic->HasItem(RG_GORONS_BRACELET))), LOCATION(RC_DMT_FLAG_SUN_FAIRY, logic->CanUse(RG_SUNS_SONG)), + LOCATION(RC_DMT_ROCK_1, logic->HasItem(RG_POWER_BRACELET) || logic->BlastOrSmash()), + LOCATION(RC_DMT_ROCK_2, logic->HasItem(RG_POWER_BRACELET) || logic->BlastOrSmash()), + LOCATION(RC_DMT_ROCK_3, logic->HasItem(RG_POWER_BRACELET) || logic->BlastOrSmash()), + LOCATION(RC_DMT_ROCK_4, logic->HasItem(RG_POWER_BRACELET) || logic->BlastOrSmash()), + LOCATION(RC_DMT_ROCK_5, logic->HasItem(RG_POWER_BRACELET) || logic->BlastOrSmash()), + LOCATION(RC_DMT_CIRCLE_ROCK_1, logic->HasItem(RG_POWER_BRACELET) || logic->BlastOrSmash()), + LOCATION(RC_DMT_CIRCLE_ROCK_2, logic->HasItem(RG_POWER_BRACELET) || logic->BlastOrSmash()), + LOCATION(RC_DMT_CIRCLE_ROCK_3, logic->HasItem(RG_POWER_BRACELET) || logic->BlastOrSmash()), + LOCATION(RC_DMT_CIRCLE_ROCK_4, logic->HasItem(RG_POWER_BRACELET) || logic->BlastOrSmash()), + LOCATION(RC_DMT_CIRCLE_ROCK_5, logic->HasItem(RG_POWER_BRACELET) || logic->BlastOrSmash()), + LOCATION(RC_DMT_CIRCLE_ROCK_6, logic->HasItem(RG_POWER_BRACELET) || logic->BlastOrSmash()), + LOCATION(RC_DMT_CIRCLE_ROCK_7, logic->HasItem(RG_POWER_BRACELET) || logic->BlastOrSmash()), + LOCATION(RC_DMT_CIRCLE_ROCK_8, logic->HasItem(RG_POWER_BRACELET) || logic->BlastOrSmash()), + LOCATION(RC_DMT_BOULDER_1, logic->BlastOrSmash()), + LOCATION(RC_DMT_BOULDER_2, logic->BlastOrSmash()), + LOCATION(RC_DMT_BOULDER_3, logic->IsChild && logic->BlastOrSmash()), + LOCATION(RC_DMT_BRONZE_BOULDER_1, logic->IsAdult && logic->CanUse(RG_MEGATON_HAMMER)), + LOCATION(RC_DMT_BRONZE_BOULDER_2, logic->IsAdult && logic->CanUse(RG_MEGATON_HAMMER)), + LOCATION(RC_DMT_BRONZE_BOULDER_3, logic->IsAdult && logic->CanUse(RG_MEGATON_HAMMER)), + LOCATION(RC_DMT_BRONZE_BOULDER_4, logic->IsAdult && logic->CanUse(RG_MEGATON_HAMMER)), + LOCATION(RC_DMT_BRONZE_BOULDER_5, logic->IsAdult && logic->CanUse(RG_MEGATON_HAMMER)), + LOCATION(RC_DMT_BRONZE_BOULDER_6, logic->IsAdult && logic->CanUse(RG_MEGATON_HAMMER)), + LOCATION(RC_DMT_BRONZE_BOULDER_7, logic->IsAdult && logic->CanUse(RG_MEGATON_HAMMER)), + LOCATION(RC_DMT_BRONZE_BOULDER_8, logic->IsAdult && logic->CanUse(RG_MEGATON_HAMMER)), + LOCATION(RC_DMT_BRONZE_BOULDER_9, logic->IsAdult && logic->CanUse(RG_MEGATON_HAMMER)), + LOCATION(RC_DMT_BRONZE_BOULDER_10, logic->IsAdult && logic->CanUse(RG_MEGATON_HAMMER)), + LOCATION(RC_DMT_BRONZE_BOULDER_11, logic->IsAdult && logic->CanUse(RG_MEGATON_HAMMER)), }, { //Exits ENTRANCE(RR_KAK_BEHIND_GATE, true), @@ -51,6 +78,8 @@ void RegionTable_Init_DeathMountainTrail() { LOCATION(RC_DMT_TRADE_CLAIM_CHECK, logic->IsAdult && logic->CanUse(RG_CLAIM_CHECK)), LOCATION(RC_DMT_GOSSIP_STONE_FAIRY, logic->CallGossipFairy()), LOCATION(RC_DMT_GOSSIP_STONE_FAIRY_BIG, logic->CanUse(RG_SONG_OF_STORMS)), + LOCATION(RC_DMT_COW_BOULDER, logic->BlastOrSmash()), + LOCATION(RC_DMT_SUMMIT_ROCK, logic->IsChild), LOCATION(RC_DMT_GOSSIP_STONE, true), LOCATION(RC_BIGGORON_HINT, logic->IsAdult && logic->HasItem(RG_SPEAK_GORON)), }, { diff --git a/soh/soh/Enhancements/randomizer/location_access/overworld/desert_colossus.cpp b/soh/soh/Enhancements/randomizer/location_access/overworld/desert_colossus.cpp index a60194dd191..c83848d0f92 100644 --- a/soh/soh/Enhancements/randomizer/location_access/overworld/desert_colossus.cpp +++ b/soh/soh/Enhancements/randomizer/location_access/overworld/desert_colossus.cpp @@ -19,6 +19,24 @@ void RegionTable_Init_DesertColossus() { LOCATION(RC_COLOSSUS_BEAN_SPROUT_FAIRY_3, logic->IsChild && logic->CanUse(RG_MAGIC_BEAN) && logic->HasItem(RG_DESERT_COLOSSUS_BEAN_SOUL) && logic->CanUse(RG_SONG_OF_STORMS)), LOCATION(RC_COLOSSUS_GOSSIP_STONE_FAIRY, logic->CallGossipFairy()), LOCATION(RC_COLOSSUS_GOSSIP_STONE_FAIRY_BIG, logic->CanUse(RG_SONG_OF_STORMS)), + LOCATION(RC_COLOSSUS_SILVER_BOULDER, logic->CanUse(RG_SILVER_GAUNTLETS)), + LOCATION(RC_COLOSSUS_ROCK, logic->HasItem(RG_POWER_BRACELET) || logic->BlastOrSmash()), + LOCATION(RC_COLOSSUS_CIRCLE_1_ROCK_1, logic->HasItem(RG_POWER_BRACELET) || logic->BlastOrSmash()), + LOCATION(RC_COLOSSUS_CIRCLE_1_ROCK_2, logic->HasItem(RG_POWER_BRACELET) || logic->BlastOrSmash()), + LOCATION(RC_COLOSSUS_CIRCLE_1_ROCK_3, logic->HasItem(RG_POWER_BRACELET) || logic->BlastOrSmash()), + LOCATION(RC_COLOSSUS_CIRCLE_1_ROCK_4, logic->HasItem(RG_POWER_BRACELET) || logic->BlastOrSmash()), + LOCATION(RC_COLOSSUS_CIRCLE_1_ROCK_5, logic->HasItem(RG_POWER_BRACELET) || logic->BlastOrSmash()), + LOCATION(RC_COLOSSUS_CIRCLE_1_ROCK_6, logic->HasItem(RG_POWER_BRACELET) || logic->BlastOrSmash()), + LOCATION(RC_COLOSSUS_CIRCLE_1_ROCK_7, logic->HasItem(RG_POWER_BRACELET) || logic->BlastOrSmash()), + LOCATION(RC_COLOSSUS_CIRCLE_1_ROCK_8, logic->HasItem(RG_POWER_BRACELET) || logic->BlastOrSmash()), + LOCATION(RC_COLOSSUS_CIRCLE_2_ROCK_1, logic->HasItem(RG_POWER_BRACELET) || logic->BlastOrSmash()), + LOCATION(RC_COLOSSUS_CIRCLE_2_ROCK_2, logic->HasItem(RG_POWER_BRACELET) || logic->BlastOrSmash()), + LOCATION(RC_COLOSSUS_CIRCLE_2_ROCK_3, logic->HasItem(RG_POWER_BRACELET) || logic->BlastOrSmash()), + LOCATION(RC_COLOSSUS_CIRCLE_2_ROCK_4, logic->HasItem(RG_POWER_BRACELET) || logic->BlastOrSmash()), + LOCATION(RC_COLOSSUS_CIRCLE_2_ROCK_5, logic->HasItem(RG_POWER_BRACELET) || logic->BlastOrSmash()), + LOCATION(RC_COLOSSUS_CIRCLE_2_ROCK_6, logic->HasItem(RG_POWER_BRACELET) || logic->BlastOrSmash()), + LOCATION(RC_COLOSSUS_CIRCLE_2_ROCK_7, logic->HasItem(RG_POWER_BRACELET) || logic->BlastOrSmash()), + LOCATION(RC_COLOSSUS_CIRCLE_2_ROCK_8, logic->HasItem(RG_POWER_BRACELET) || logic->BlastOrSmash()), LOCATION(RC_COLOSSUS_GOSSIP_STONE, true), }, { //Exits diff --git a/soh/soh/Enhancements/randomizer/location_access/overworld/gerudo_fortress.cpp b/soh/soh/Enhancements/randomizer/location_access/overworld/gerudo_fortress.cpp index 6f2f2bf3128..f7926664be7 100644 --- a/soh/soh/Enhancements/randomizer/location_access/overworld/gerudo_fortress.cpp +++ b/soh/soh/Enhancements/randomizer/location_access/overworld/gerudo_fortress.cpp @@ -225,9 +225,8 @@ void RegionTable_Init_GerudoFortress() { LOCATION(RC_GF_HBA_CANOPY_EAST_CRATE, logic->CanBreakCrates()), LOCATION(RC_GF_HBA_CANOPY_WEST_CRATE, logic->CanBreakCrates()), LOCATION(RC_GF_NORTH_TARGET_EAST_CRATE, logic->CanBreakCrates()), - LOCATION(RC_GF_NORTH_TARGET_WEST_CRATE, logic->IsAdult || (logic->BlastOrSmash() || logic->HookshotOrBoomerang() || logic->CanUse(RG_HOVER_BOOTS))), - //implies logic->CanBreakCrates() - LOCATION(RC_GF_NORTH_TARGET_CHILD_CRATE, logic->IsChild && logic->BlastOrSmash()), + LOCATION(RC_GF_NORTH_TARGET_WEST_CRATE, (logic->IsAdult || (logic->BlastOrSmash() || logic->HookshotOrBoomerang() || logic->CanUse(RG_HOVER_BOOTS))) && logic->CanBreakCrates()), + LOCATION(RC_GF_NORTH_TARGET_CHILD_CRATE, logic->IsChild && logic->BlastOrSmash() && logic->CanBreakCrates()), LOCATION(RC_GF_SOUTH_TARGET_EAST_CRATE, logic->CanBreakCrates()), LOCATION(RC_GF_SOUTH_TARGET_WEST_CRATE, logic->CanBreakCrates()), }, { diff --git a/soh/soh/Enhancements/randomizer/location_access/overworld/gerudo_valley.cpp b/soh/soh/Enhancements/randomizer/location_access/overworld/gerudo_valley.cpp index 2c2193f9b9c..61c82540b99 100644 --- a/soh/soh/Enhancements/randomizer/location_access/overworld/gerudo_valley.cpp +++ b/soh/soh/Enhancements/randomizer/location_access/overworld/gerudo_valley.cpp @@ -11,6 +11,16 @@ void RegionTable_Init_GerudoValley() { }, { //Locations LOCATION(RC_GV_GS_SMALL_BRIDGE, logic->IsChild && logic->HookshotOrBoomerang() && logic->CanGetNightTimeGS()), + LOCATION(RC_GV_ROCK_1, logic->HasItem(RG_POWER_BRACELET) || logic->BlastOrSmash()), + LOCATION(RC_GV_ROCK_2, logic->HasItem(RG_POWER_BRACELET) || logic->BlastOrSmash()), + LOCATION(RC_GV_ROCK_3, logic->HasItem(RG_POWER_BRACELET) || logic->BlastOrSmash()), + LOCATION(RC_GV_UNDERWATER_ROCK_1, (logic->IsAdult && logic->HasItem(RG_POWER_BRACELET)) || logic->CanUse(RG_BOMBCHU_5)), + LOCATION(RC_GV_UNDERWATER_ROCK_2, (logic->IsAdult && logic->HasItem(RG_POWER_BRACELET)) || logic->CanUse(RG_BOMBCHU_5)), + LOCATION(RC_GV_UNDERWATER_ROCK_3, (logic->IsAdult && logic->HasItem(RG_POWER_BRACELET))|| logic->CanUse(RG_BOMBCHU_5)), + LOCATION(RC_GV_BOULDER_1, logic->IsAdult && logic->BlastOrSmash()), + LOCATION(RC_GV_BOULDER_2, logic->IsAdult && logic->BlastOrSmash()), + LOCATION(RC_GV_BRONZE_BOULDER_1, logic->IsAdult && logic->CanUse(RG_MEGATON_HAMMER)), + LOCATION(RC_GV_BRONZE_BOULDER_2, logic->IsAdult && logic->CanUse(RG_MEGATON_HAMMER)), }, { //Exits ENTRANCE(RR_HYRULE_FIELD, true), @@ -66,7 +76,10 @@ void RegionTable_Init_GerudoValley() { ENTRANCE(RR_GV_UPPER_STREAM_WATER, true), }); - areaTable[RR_GV_GROTTO_LEDGE] = Region("GV Grotto Ledge", SCENE_GERUDO_VALLEY, {}, {}, { + areaTable[RR_GV_GROTTO_LEDGE] = Region("GV Grotto Ledge", SCENE_GERUDO_VALLEY, {}, { + //Locations + LOCATION(RC_GV_SILVER_BOULDER, logic->CanUse(RG_SILVER_GAUNTLETS)), + }, { //Exits ENTRANCE(RR_GV_UPPER_STREAM, ctx->GetTrickOption(RT_DAMAGE_BOOST_SIMPLE) && logic->HasExplosives() && logic->TakeDamage()), ENTRANCE(RR_GV_LOWER_STREAM, logic->HasItem(RG_BRONZE_SCALE) || logic->CanUse(RG_IRON_BOOTS)), @@ -94,6 +107,17 @@ void RegionTable_Init_GerudoValley() { LOCATION(RC_GV_CRATE_BRIDGE_2, logic->IsChild && logic->CanBreakCrates()), LOCATION(RC_GV_CRATE_BRIDGE_3, logic->IsChild && logic->CanBreakCrates()), LOCATION(RC_GV_CRATE_BRIDGE_4, logic->IsChild && logic->CanBreakCrates()), + LOCATION(RC_GV_ROCK_ACROSS_BRIDGE_1, logic->IsAdult && (logic->HasItem(RG_POWER_BRACELET) || logic->BlastOrSmash())), + LOCATION(RC_GV_ROCK_ACROSS_BRIDGE_2, logic->IsAdult && (logic->HasItem(RG_POWER_BRACELET) || logic->BlastOrSmash())), + LOCATION(RC_GV_ROCK_ACROSS_BRIDGE_3, logic->IsAdult && (logic->HasItem(RG_POWER_BRACELET) || logic->BlastOrSmash())), + LOCATION(RC_GV_ROCK_ACROSS_BRIDGE_4, logic->IsAdult && (logic->HasItem(RG_POWER_BRACELET) || logic->BlastOrSmash())), + LOCATION(RC_GV_BOULDER_ACROSS_BRIDGE, logic->IsAdult && logic->BlastOrSmash()), + LOCATION(RC_GV_BRONZE_BOULDER_ACROSS_BRIDGE_1, logic->IsAdult && logic->CanUse(RG_MEGATON_HAMMER)), + LOCATION(RC_GV_BRONZE_BOULDER_ACROSS_BRIDGE_2, logic->IsAdult && logic->CanUse(RG_MEGATON_HAMMER)), + LOCATION(RC_GV_BRONZE_BOULDER_ACROSS_BRIDGE_3, logic->IsAdult && logic->CanUse(RG_MEGATON_HAMMER)), + LOCATION(RC_GV_BRONZE_BOULDER_ACROSS_BRIDGE_4, logic->IsAdult && logic->CanUse(RG_MEGATON_HAMMER)), + LOCATION(RC_GV_BRONZE_BOULDER_ACROSS_BRIDGE_5, logic->IsAdult && logic->CanUse(RG_MEGATON_HAMMER)), + LOCATION(RC_GV_BRONZE_BOULDER_ACROSS_BRIDGE_6, logic->IsAdult && logic->CanUse(RG_MEGATON_HAMMER)), }, { //Exits ENTRANCE(RR_GF_OUTSKIRTS, true), diff --git a/soh/soh/Enhancements/randomizer/location_access/overworld/goron_city.cpp b/soh/soh/Enhancements/randomizer/location_access/overworld/goron_city.cpp index e39dac9e600..02c1756740b 100644 --- a/soh/soh/Enhancements/randomizer/location_access/overworld/goron_city.cpp +++ b/soh/soh/Enhancements/randomizer/location_access/overworld/goron_city.cpp @@ -35,7 +35,57 @@ void RegionTable_Init_GoronCity() { LOCATION(RC_GC_UPPER_STAIRCASE_POT_2, logic->CanBreakPots()), LOCATION(RC_GC_UPPER_STAIRCASE_POT_3, logic->CanBreakPots()), LOCATION(RC_GC_MAZE_CRATE, logic->BlastOrSmash() || (logic->CanUse(RG_SILVER_GAUNTLETS) && logic->CanBreakCrates())), - + LOCATION(RC_GC_ENTRANCE_BOULDER_1, logic->BlastOrSmash()), + LOCATION(RC_GC_ENTRANCE_BOULDER_2, logic->BlastOrSmash()), + LOCATION(RC_GC_ENTRANCE_BOULDER_3, logic->BlastOrSmash()), + LOCATION(RC_GC_LW_BOULDER_1, logic->Get(LOGIC_GORON_CITY_WOODS_WARP_OPEN)), + LOCATION(RC_GC_LW_BOULDER_2, logic->Get(LOGIC_GORON_CITY_WOODS_WARP_OPEN)), + LOCATION(RC_GC_LW_BOULDER_3, logic->Get(LOGIC_GORON_CITY_WOODS_WARP_OPEN)), + LOCATION(RC_GC_MAZE_SILVER_BOULDER_1, logic->CanUse(RG_SILVER_GAUNTLETS)), + LOCATION(RC_GC_MAZE_SILVER_BOULDER_2, logic->CanUse(RG_SILVER_GAUNTLETS)), + LOCATION(RC_GC_MAZE_SILVER_BOULDER_3, logic->CanUse(RG_SILVER_GAUNTLETS)), + LOCATION(RC_GC_MAZE_SILVER_BOULDER_4, logic->CanUse(RG_SILVER_GAUNTLETS)), + LOCATION(RC_GC_MAZE_SILVER_BOULDER_5, logic->CanUse(RG_SILVER_GAUNTLETS)), + LOCATION(RC_GC_MAZE_SILVER_BOULDER_6, logic->CanUse(RG_SILVER_GAUNTLETS)), + LOCATION(RC_GC_MAZE_SILVER_BOULDER_7, logic->CanUse(RG_SILVER_GAUNTLETS)), + LOCATION(RC_GC_MAZE_SILVER_BOULDER_8, logic->CanUse(RG_SILVER_GAUNTLETS)), + LOCATION(RC_GC_MAZE_SILVER_BOULDER_9, logic->CanUse(RG_SILVER_GAUNTLETS)), + LOCATION(RC_GC_MAZE_SILVER_BOULDER_10, logic->CanUse(RG_SILVER_GAUNTLETS)), + LOCATION(RC_GC_MAZE_SILVER_BOULDER_11, logic->CanUse(RG_SILVER_GAUNTLETS)), + LOCATION(RC_GC_MAZE_SILVER_BOULDER_12, logic->CanUse(RG_SILVER_GAUNTLETS)), + LOCATION(RC_GC_MAZE_SILVER_BOULDER_13, logic->CanUse(RG_SILVER_GAUNTLETS)), + LOCATION(RC_GC_MAZE_SILVER_BOULDER_14, logic->CanUse(RG_SILVER_GAUNTLETS)), + LOCATION(RC_GC_MAZE_SILVER_BOULDER_15, logic->CanUse(RG_SILVER_GAUNTLETS)), + LOCATION(RC_GC_MAZE_SILVER_BOULDER_16, logic->CanUse(RG_SILVER_GAUNTLETS)), + LOCATION(RC_GC_MAZE_SILVER_BOULDER_17, logic->CanUse(RG_SILVER_GAUNTLETS)), + LOCATION(RC_GC_MAZE_SILVER_BOULDER_18, logic->CanUse(RG_SILVER_GAUNTLETS)), + LOCATION(RC_GC_MAZE_SILVER_BOULDER_19, logic->CanUse(RG_SILVER_GAUNTLETS)), + LOCATION(RC_GC_MAZE_SILVER_BOULDER_20, logic->CanUse(RG_SILVER_GAUNTLETS)), + LOCATION(RC_GC_MAZE_SILVER_BOULDER_21, logic->CanUse(RG_SILVER_GAUNTLETS)), + LOCATION(RC_GC_MAZE_SILVER_BOULDER_22, logic->CanUse(RG_SILVER_GAUNTLETS)), + LOCATION(RC_GC_MAZE_SILVER_BOULDER_23, logic->CanUse(RG_SILVER_GAUNTLETS)), + LOCATION(RC_GC_MAZE_SILVER_BOULDER_24, logic->CanUse(RG_SILVER_GAUNTLETS)), + LOCATION(RC_GC_MAZE_SILVER_BOULDER_25, logic->CanUse(RG_SILVER_GAUNTLETS)), + LOCATION(RC_GC_MAZE_SILVER_BOULDER_26, logic->CanUse(RG_SILVER_GAUNTLETS)), + LOCATION(RC_GC_MAZE_SILVER_BOULDER_27, logic->CanUse(RG_SILVER_GAUNTLETS)), + LOCATION(RC_GC_MAZE_SILVER_BOULDER_28, logic->CanUse(RG_SILVER_GAUNTLETS)), + LOCATION(RC_GC_MAZE_SILVER_BOULDER_29, logic->CanUse(RG_SILVER_GAUNTLETS)), + LOCATION(RC_GC_MAZE_BOULDER_1, logic->BlastOrSmash()), + LOCATION(RC_GC_MAZE_BOULDER_2, logic->BlastOrSmash()), + LOCATION(RC_GC_MAZE_BOULDER_3, logic->BlastOrSmash()), + LOCATION(RC_GC_MAZE_BOULDER_4, logic->BlastOrSmash()), + LOCATION(RC_GC_MAZE_BOULDER_5, logic->BlastOrSmash()), + LOCATION(RC_GC_MAZE_BOULDER_6, logic->BlastOrSmash()), + LOCATION(RC_GC_MAZE_BOULDER_7, logic->BlastOrSmash()), + LOCATION(RC_GC_MAZE_BOULDER_8, logic->BlastOrSmash()), + LOCATION(RC_GC_MAZE_BOULDER_9, logic->BlastOrSmash()), + LOCATION(RC_GC_MAZE_BOULDER_10, logic->BlastOrSmash()), + LOCATION(RC_GC_MAZE_BRONZE_BOULDER_1, logic->CanUse(RG_MEGATON_HAMMER)), + LOCATION(RC_GC_MAZE_BRONZE_BOULDER_2, logic->CanUse(RG_MEGATON_HAMMER)), + LOCATION(RC_GC_MAZE_BRONZE_BOULDER_3, logic->CanUse(RG_MEGATON_HAMMER)), + LOCATION(RC_GC_MAZE_BRONZE_BOULDER_4, logic->CanUse(RG_MEGATON_HAMMER)), + LOCATION(RC_GC_MAZE_BRONZE_BOULDER_5, logic->CanUse(RG_MEGATON_HAMMER)), + LOCATION(RC_GC_MAZE_ROCK, logic->BlastOrSmash() || logic->CanUse(RG_SILVER_GAUNTLETS)), }, { //Exits ENTRANCE(RR_DEATH_MOUNTAIN_TRAIL, true), diff --git a/soh/soh/Enhancements/randomizer/location_access/overworld/graveyard.cpp b/soh/soh/Enhancements/randomizer/location_access/overworld/graveyard.cpp index 77ac0aa44d0..8c8d5c57892 100644 --- a/soh/soh/Enhancements/randomizer/location_access/overworld/graveyard.cpp +++ b/soh/soh/Enhancements/randomizer/location_access/overworld/graveyard.cpp @@ -32,6 +32,7 @@ void RegionTable_Init_Graveyard() { LOCATION(RC_GY_GRASS_11, logic->CanCutShrubs()), LOCATION(RC_GY_GRASS_12, logic->CanCutShrubs()), LOCATION(RC_GRAVEYARD_CRATE, ((logic->IsAdult && CanPlantBean(RR_THE_GRAVEYARD, RG_GRAVEYARD_BEAN_SOUL)) || logic->CanUse(RG_LONGSHOT)) && logic->CanBreakCrates()), + LOCATION(RC_GY_ROCK, logic->HasItem(RG_POWER_BRACELET) || logic->BlastOrSmash()), }, { //Exits ENTRANCE(RR_GRAVEYARD_SHIELD_GRAVE, (logic->IsAdult || logic->AtNight) && logic->HasItem(RG_POWER_BRACELET)), diff --git a/soh/soh/Enhancements/randomizer/location_access/overworld/hyrule_field.cpp b/soh/soh/Enhancements/randomizer/location_access/overworld/hyrule_field.cpp index c3a7eeecc4f..498be950bf7 100644 --- a/soh/soh/Enhancements/randomizer/location_access/overworld/hyrule_field.cpp +++ b/soh/soh/Enhancements/randomizer/location_access/overworld/hyrule_field.cpp @@ -110,6 +110,22 @@ void RegionTable_Init_HyruleField() { LOCATION(RC_HF_CHILD_SOUTHEAST_TREE_5, logic->IsChild && logic->CanBonkTrees()), LOCATION(RC_HF_CHILD_SOUTHEAST_TREE_6, logic->IsChild && logic->CanBonkTrees()), LOCATION(RC_HF_TEKTITE_GROTTO_TREE, logic->CanBonkTrees()), + LOCATION(RC_HF_SILVER_BOULDER, logic->CanUse(RG_SILVER_GAUNTLETS)), + LOCATION(RC_HF_ROCK_1, logic->HasItem(RG_POWER_BRACELET) || logic->BlastOrSmash()), + LOCATION(RC_HF_ROCK_2, logic->HasItem(RG_POWER_BRACELET) || logic->BlastOrSmash()), + LOCATION(RC_HF_ROCK_3, logic->HasItem(RG_POWER_BRACELET) || logic->BlastOrSmash()), + LOCATION(RC_HF_ROCK_4, logic->HasItem(RG_POWER_BRACELET) || logic->BlastOrSmash()), + LOCATION(RC_HF_ROCK_5, logic->HasItem(RG_POWER_BRACELET) || logic->BlastOrSmash()), + LOCATION(RC_HF_ROCK_6, logic->HasItem(RG_POWER_BRACELET) || logic->BlastOrSmash()), + LOCATION(RC_HF_ROCK_7, logic->HasItem(RG_POWER_BRACELET) || logic->BlastOrSmash()), + LOCATION(RC_HF_ROCK_8, logic->HasItem(RG_POWER_BRACELET) || logic->BlastOrSmash()), + LOCATION(RC_HF_BOULDER_NORTH, logic->BlastOrSmash()), + LOCATION(RC_HF_BOULDER_BY_MARKET, logic->BlastOrSmash()), + LOCATION(RC_HF_BOULDER_SOUTH, logic->BlastOrSmash()), + LOCATION(RC_HF_BRONZE_BOULDER_1, logic->IsAdult && logic->CanUse(RG_MEGATON_HAMMER)), + LOCATION(RC_HF_BRONZE_BOULDER_2, logic->IsAdult && logic->CanUse(RG_MEGATON_HAMMER)), + LOCATION(RC_HF_BRONZE_BOULDER_3, logic->IsAdult && logic->CanUse(RG_MEGATON_HAMMER)), + LOCATION(RC_HF_BRONZE_BOULDER_4, logic->IsAdult && logic->CanUse(RG_MEGATON_HAMMER)), LOCATION(RC_HF_BUSH_NEAR_LAKE_1, true), LOCATION(RC_HF_BUSH_NEAR_LAKE_2, true), LOCATION(RC_HF_BUSH_NEAR_LAKE_3, true), diff --git a/soh/soh/Enhancements/randomizer/location_access/overworld/kakariko.cpp b/soh/soh/Enhancements/randomizer/location_access/overworld/kakariko.cpp index 3e4c92a1d80..2a975d1ca59 100644 --- a/soh/soh/Enhancements/randomizer/location_access/overworld/kakariko.cpp +++ b/soh/soh/Enhancements/randomizer/location_access/overworld/kakariko.cpp @@ -60,6 +60,9 @@ void RegionTable_Init_Kakariko() { LOCATION(RC_KAK_NEAR_BOARDING_HOUSE_CHILD_CRATE, logic->IsChild && logic->CanBreakCrates()), LOCATION(RC_KAK_NEAR_BAZAAR_CHILD_CRATE, logic->IsChild && logic->CanBreakCrates()), LOCATION(RC_KAK_TREE, logic->CanBonkTrees()), + LOCATION(RC_KAK_SILVER_BOULDER, logic->IsAdult && logic->CanUse(RG_SILVER_GAUNTLETS)), + LOCATION(RC_KAK_ROCK_1, logic->HasItem(RG_POWER_BRACELET) || logic->BlastOrSmash()), + LOCATION(RC_KAK_ROCK_2, logic->HasItem(RG_POWER_BRACELET) || logic->BlastOrSmash()), }, { //Exits ENTRANCE(RR_HYRULE_FIELD, true), diff --git a/soh/soh/Enhancements/randomizer/location_access/overworld/kokiri_forest.cpp b/soh/soh/Enhancements/randomizer/location_access/overworld/kokiri_forest.cpp index d6b1674b2f6..0edff4fd485 100644 --- a/soh/soh/Enhancements/randomizer/location_access/overworld/kokiri_forest.cpp +++ b/soh/soh/Enhancements/randomizer/location_access/overworld/kokiri_forest.cpp @@ -25,13 +25,13 @@ void RegionTable_Init_KokiriForest() { LOCATION(RC_KF_SOUTH_GRASS_EAST_RUPEE, logic->IsChild), LOCATION(RC_KF_NORTH_GRASS_WEST_RUPEE, logic->IsChild), LOCATION(RC_KF_NORTH_GRASS_EAST_RUPEE, logic->IsChild), - LOCATION(RC_KF_BEAN_RUPEE_1, logic->IsAdult && (CanPlantBean(RR_KOKIRI_FOREST, RG_KOKIRI_FOREST_BEAN_SOUL) || logic->CanUse(RG_HOVER_BOOTS) || logic->CanUse(RG_BOOMERANG))), - LOCATION(RC_KF_BEAN_RUPEE_2, logic->IsAdult && (CanPlantBean(RR_KOKIRI_FOREST, RG_KOKIRI_FOREST_BEAN_SOUL) || logic->CanUse(RG_HOVER_BOOTS) || logic->CanUse(RG_BOOMERANG))), - LOCATION(RC_KF_BEAN_RUPEE_3, logic->IsAdult && (CanPlantBean(RR_KOKIRI_FOREST, RG_KOKIRI_FOREST_BEAN_SOUL) || logic->CanUse(RG_HOVER_BOOTS) || logic->CanUse(RG_BOOMERANG))), - LOCATION(RC_KF_BEAN_RUPEE_4, logic->IsAdult && (CanPlantBean(RR_KOKIRI_FOREST, RG_KOKIRI_FOREST_BEAN_SOUL) || logic->CanUse(RG_HOVER_BOOTS) || logic->CanUse(RG_BOOMERANG))), - LOCATION(RC_KF_BEAN_RUPEE_5, logic->IsAdult && (CanPlantBean(RR_KOKIRI_FOREST, RG_KOKIRI_FOREST_BEAN_SOUL) || logic->CanUse(RG_HOVER_BOOTS) || logic->CanUse(RG_BOOMERANG))), - LOCATION(RC_KF_BEAN_RUPEE_6, logic->IsAdult && (CanPlantBean(RR_KOKIRI_FOREST, RG_KOKIRI_FOREST_BEAN_SOUL) || logic->CanUse(RG_HOVER_BOOTS) || logic->CanUse(RG_BOOMERANG))), - LOCATION(RC_KF_BEAN_RED_RUPEE, logic->IsAdult && (CanPlantBean(RR_KOKIRI_FOREST, RG_KOKIRI_FOREST_BEAN_SOUL) || logic->CanUse(RG_HOVER_BOOTS) || logic->CanUse(RG_BOOMERANG))), + LOCATION(RC_KF_BEAN_RUPEE_1, logic->IsAdult && (CanPlantBean(RR_KOKIRI_FOREST, RG_KOKIRI_FOREST_BEAN_SOUL) || (logic->CanUse(RG_HOVER_BOOTS) && logic->HasItem(RG_ROLL)) || logic->CanUse(RG_BOOMERANG))), + LOCATION(RC_KF_BEAN_RUPEE_2, logic->IsAdult && (CanPlantBean(RR_KOKIRI_FOREST, RG_KOKIRI_FOREST_BEAN_SOUL) || (logic->CanUse(RG_HOVER_BOOTS) && logic->HasItem(RG_ROLL)) || logic->CanUse(RG_BOOMERANG))), + LOCATION(RC_KF_BEAN_RUPEE_3, logic->IsAdult && (CanPlantBean(RR_KOKIRI_FOREST, RG_KOKIRI_FOREST_BEAN_SOUL) || (logic->CanUse(RG_HOVER_BOOTS) && logic->HasItem(RG_ROLL)) || logic->CanUse(RG_BOOMERANG))), + LOCATION(RC_KF_BEAN_RUPEE_4, logic->IsAdult && (CanPlantBean(RR_KOKIRI_FOREST, RG_KOKIRI_FOREST_BEAN_SOUL) || (logic->CanUse(RG_HOVER_BOOTS) && logic->HasItem(RG_ROLL)) || logic->CanUse(RG_BOOMERANG))), + LOCATION(RC_KF_BEAN_RUPEE_5, logic->IsAdult && (CanPlantBean(RR_KOKIRI_FOREST, RG_KOKIRI_FOREST_BEAN_SOUL) || (logic->CanUse(RG_HOVER_BOOTS) && logic->HasItem(RG_ROLL)) || logic->CanUse(RG_BOOMERANG))), + LOCATION(RC_KF_BEAN_RUPEE_6, logic->IsAdult && (CanPlantBean(RR_KOKIRI_FOREST, RG_KOKIRI_FOREST_BEAN_SOUL) || (logic->CanUse(RG_HOVER_BOOTS) && logic->HasItem(RG_ROLL)) || logic->CanUse(RG_BOOMERANG))), + LOCATION(RC_KF_BEAN_RED_RUPEE, logic->IsAdult && (CanPlantBean(RR_KOKIRI_FOREST, RG_KOKIRI_FOREST_BEAN_SOUL) || (logic->CanUse(RG_HOVER_BOOTS) && logic->HasItem(RG_ROLL)) || logic->CanUse(RG_BOOMERANG))), LOCATION(RC_KF_SARIAS_ROOF_WEST_HEART, logic->IsChild), LOCATION(RC_KF_SARIAS_ROOF_EAST_HEART, logic->IsChild), LOCATION(RC_KF_SARIAS_ROOF_NORTH_HEART, logic->IsChild), @@ -67,6 +67,18 @@ void RegionTable_Init_KokiriForest() { LOCATION(RC_KF_ADULT_GRASS_18, logic->IsAdult && logic->CanCutShrubs()), LOCATION(RC_KF_ADULT_GRASS_19, logic->IsAdult && logic->CanCutShrubs()), LOCATION(RC_KF_ADULT_GRASS_20, logic->IsAdult && logic->CanCutShrubs()), + LOCATION(RC_KF_CIRCLE_ROCK_1, logic->HasItem(RG_POWER_BRACELET) || logic->BlastOrSmash()), + LOCATION(RC_KF_CIRCLE_ROCK_2, logic->HasItem(RG_POWER_BRACELET) || logic->BlastOrSmash()), + LOCATION(RC_KF_CIRCLE_ROCK_3, logic->HasItem(RG_POWER_BRACELET) || logic->BlastOrSmash()), + LOCATION(RC_KF_CIRCLE_ROCK_4, logic->HasItem(RG_POWER_BRACELET) || logic->BlastOrSmash()), + LOCATION(RC_KF_CIRCLE_ROCK_5, logic->HasItem(RG_POWER_BRACELET) || logic->BlastOrSmash()), + LOCATION(RC_KF_CIRCLE_ROCK_6, logic->HasItem(RG_POWER_BRACELET) || logic->BlastOrSmash()), + LOCATION(RC_KF_CIRCLE_ROCK_7, logic->HasItem(RG_POWER_BRACELET) || logic->BlastOrSmash()), + LOCATION(RC_KF_CIRCLE_ROCK_8, logic->HasItem(RG_POWER_BRACELET) || logic->BlastOrSmash()), + LOCATION(RC_KF_ROCK_BY_SARIAS_HOUSE, logic->IsChild && (logic->HasItem(RG_POWER_BRACELET) || logic->BlastOrSmash())), + LOCATION(RC_KF_ROCK_BEHIND_SARIAS_HOUSE, logic->IsChild && (logic->HasItem(RG_POWER_BRACELET) || logic->BlastOrSmash())), + LOCATION(RC_KF_ROCK_BY_MIDOS_HOUSE, logic->IsChild && (logic->HasItem(RG_POWER_BRACELET) || logic->BlastOrSmash())), + LOCATION(RC_KF_ROCK_BY_KNOW_IT_ALLS_HOUSE, logic->IsChild && (logic->HasItem(RG_POWER_BRACELET) || logic->BlastOrSmash())), }, { //Exits ENTRANCE(RR_KF_BOULDER_LOOP, logic->CanUse(RG_CRAWL)), diff --git a/soh/soh/Enhancements/randomizer/location_access/overworld/lake_hylia.cpp b/soh/soh/Enhancements/randomizer/location_access/overworld/lake_hylia.cpp index cdd10605021..d1d9fd8b103 100644 --- a/soh/soh/Enhancements/randomizer/location_access/overworld/lake_hylia.cpp +++ b/soh/soh/Enhancements/randomizer/location_access/overworld/lake_hylia.cpp @@ -102,7 +102,10 @@ void RegionTable_Init_LakeHylia() { ENTRANCE(RR_WATER_TEMPLE_ENTRYWAY, logic->CanUse(RG_HOOKSHOT) && ((logic->CanUse(RG_IRON_BOOTS) || (ctx->GetTrickOption(RT_LH_WATER_HOOKSHOT) && logic->HasItem(RG_GOLDEN_SCALE))) || (logic->IsAdult && logic->CanUse(RG_LONGSHOT) && logic->HasItem(RG_GOLDEN_SCALE)))), }); - areaTable[RR_LH_FISHING_ISLAND] = Region("LH Fishing Island", SCENE_LAKE_HYLIA, {}, {}, { + areaTable[RR_LH_FISHING_ISLAND] = Region("LH Fishing Island", SCENE_LAKE_HYLIA, {}, { + //Locations + LOCATION(RC_LA_ROCK, logic->HasItem(RG_POWER_BRACELET) || logic->BlastOrSmash()), + }, { //Exits ENTRANCE(RR_LAKE_HYLIA, logic->HasItem(RG_BRONZE_SCALE)), ENTRANCE(RR_LH_FISHING_POND, logic->CanOpenOverworldDoor(RG_FISHING_HOLE_KEY)), @@ -117,11 +120,11 @@ void RegionTable_Init_LakeHylia() { //Locations LOCATION(RC_LH_LAB_DIVE, (logic->HasItem(RG_GOLDEN_SCALE) || (ctx->GetTrickOption(RT_LH_LAB_DIVING) && logic->CanUse(RG_IRON_BOOTS) && logic->CanUse(RG_HOOKSHOT) && logic->HasItem(RG_BRONZE_SCALE))) && logic->HasItem(RG_SPEAK_HYLIAN)), LOCATION(RC_LH_TRADE_FROG, logic->IsAdult && logic->CanUse(RG_EYEBALL_FROG)), - LOCATION(RC_LH_GS_LAB_CRATE, logic->CanUse(RG_IRON_BOOTS) && logic->CanUse(RG_HOOKSHOT) && logic->CanBreakCrates()), + LOCATION(RC_LH_GS_LAB_CRATE, logic->CanUse(RG_IRON_BOOTS) && logic->CanUse(RG_HOOKSHOT) && logic->HasItem(RG_ROLL)), LOCATION(RC_LH_LAB_FRONT_RUPEE, logic->CanUse(RG_IRON_BOOTS) || logic->HasItem(RG_GOLDEN_SCALE)), LOCATION(RC_LH_LAB_LEFT_RUPEE, logic->CanUse(RG_IRON_BOOTS) || logic->HasItem(RG_GOLDEN_SCALE)), LOCATION(RC_LH_LAB_RIGHT_RUPEE, logic->CanUse(RG_IRON_BOOTS) || logic->HasItem(RG_GOLDEN_SCALE)), - LOCATION(RC_LH_LAB_CRATE, logic->CanUse(RG_IRON_BOOTS) && logic->CanBreakCrates()), + LOCATION(RC_LH_LAB_CRATE, logic->CanUse(RG_IRON_BOOTS) && logic->HasItem(RG_ROLL)), }, { //Exits ENTRANCE(RR_LAKE_HYLIA, true), diff --git a/soh/soh/Enhancements/randomizer/location_access/overworld/lost_woods.cpp b/soh/soh/Enhancements/randomizer/location_access/overworld/lost_woods.cpp index 4d5b015a872..cc74f5e6c6d 100644 --- a/soh/soh/Enhancements/randomizer/location_access/overworld/lost_woods.cpp +++ b/soh/soh/Enhancements/randomizer/location_access/overworld/lost_woods.cpp @@ -48,6 +48,7 @@ void RegionTable_Init_LostWoods() { LOCATION(RC_LW_GOSSIP_STONE_FAIRY, logic->CallGossipFairyExceptSuns()), LOCATION(RC_LW_GOSSIP_STONE_FAIRY_BIG, logic->CanUse(RG_SONG_OF_STORMS)), LOCATION(RC_LW_SHORTCUT_STORMS_FAIRY, logic->CanUse(RG_SONG_OF_STORMS)), + LOCATION(RC_LW_BOULDER_BY_GORON_CITY, logic->BlastOrSmash()), LOCATION(RC_LW_GOSSIP_STONE, true), LOCATION(RC_LW_GRASS_1, logic->CanCutShrubs()), LOCATION(RC_LW_GRASS_2, logic->CanCutShrubs()), @@ -81,6 +82,8 @@ void RegionTable_Init_LostWoods() { LOCATION(RC_LW_GRASS_7, logic->CanCutShrubs()), LOCATION(RC_LW_GRASS_8, logic->CanCutShrubs()), LOCATION(RC_LW_GRASS_9, logic->CanCutShrubs()), + LOCATION(RC_LW_BOULDER_BY_SACRED_FOREST_MEADOW, logic->BlastOrSmash()), + LOCATION(RC_LW_RUPEE_BOULDER, logic->BlastOrSmash()), }, { //Exits ENTRANCE(RR_LW_FOREST_EXIT, true), diff --git a/soh/soh/Enhancements/randomizer/location_access/overworld/market.cpp b/soh/soh/Enhancements/randomizer/location_access/overworld/market.cpp index 9eabf6c290c..777ee84f414 100644 --- a/soh/soh/Enhancements/randomizer/location_access/overworld/market.cpp +++ b/soh/soh/Enhancements/randomizer/location_access/overworld/market.cpp @@ -23,10 +23,10 @@ void RegionTable_Init_Market() { LOCATION(RC_MARKET_GRASS_6, logic->IsChild && (logic->CanUseSword() || logic->HasItem(RG_GORONS_BRACELET))), LOCATION(RC_MARKET_GRASS_7, logic->IsChild && (logic->CanUseSword() || logic->HasItem(RG_GORONS_BRACELET))), LOCATION(RC_MARKET_GRASS_8, logic->IsChild && (logic->CanUseSword() || logic->HasItem(RG_GORONS_BRACELET))), - LOCATION(RC_MK_NEAR_BAZAAR_CRATE_1, logic->IsChild /*&& logic->CanRoll()*/), - LOCATION(RC_MK_NEAR_BAZAAR_CRATE_2, logic->IsChild /*&& logic->CanRoll()*/), - LOCATION(RC_MK_SHOOTING_GALLERY_CRATE_1, logic->IsChild /*&& logic->CanRoll()*/), - LOCATION(RC_MK_SHOOTING_GALLERY_CRATE_2, logic->IsChild /*&& logic->CanRoll()*/), + LOCATION(RC_MK_NEAR_BAZAAR_CRATE_1, logic->IsChild && logic->HasItem(RG_ROLL)), + LOCATION(RC_MK_NEAR_BAZAAR_CRATE_2, logic->IsChild && logic->HasItem(RG_ROLL)), + LOCATION(RC_MK_SHOOTING_GALLERY_CRATE_1, logic->IsChild && logic->HasItem(RG_ROLL)), + LOCATION(RC_MK_SHOOTING_GALLERY_CRATE_2, logic->IsChild && logic->HasItem(RG_ROLL)), LOCATION(RC_MARKET_TREE, logic->IsChild && logic->CanBonkTrees()), }, { //Exits @@ -227,7 +227,7 @@ void RegionTable_Init_Market() { areaTable[RR_MARKET_DOG_LADY_HOUSE] = Region("Market Dog Lady House", SCENE_DOG_LADY_HOUSE, {}, { //Locations LOCATION(RC_MARKET_LOST_DOG, logic->IsChild && logic->AtNight && logic->HasItem(RG_SPEAK_HYLIAN)), - LOCATION(RC_MK_LOST_DOG_HOUSE_CRATE, logic->CanBreakCrates()), + LOCATION(RC_MK_LOST_DOG_HOUSE_CRATE, logic->HasItem(RG_ROLL)), }, { //Exits ENTRANCE(RR_MARKET_BACK_ALLEY, true), diff --git a/soh/soh/Enhancements/randomizer/location_access/overworld/zoras_domain.cpp b/soh/soh/Enhancements/randomizer/location_access/overworld/zoras_domain.cpp index fe82c7d0cda..74ed9645c1e 100644 --- a/soh/soh/Enhancements/randomizer/location_access/overworld/zoras_domain.cpp +++ b/soh/soh/Enhancements/randomizer/location_access/overworld/zoras_domain.cpp @@ -35,6 +35,14 @@ void RegionTable_Init_ZorasDomain() { LOCATION(RC_ZD_NEAR_SHOP_POT_3, logic->CanBreakPots()), LOCATION(RC_ZD_NEAR_SHOP_POT_4, logic->CanBreakPots()), LOCATION(RC_ZD_NEAR_SHOP_POT_5, logic->CanBreakPots()), + LOCATION(RC_ZD_CIRCLE_ROCK_1, logic->HasItem(RG_POWER_BRACELET) || logic->BlastOrSmash()), + LOCATION(RC_ZD_CIRCLE_ROCK_2, logic->HasItem(RG_POWER_BRACELET) || logic->BlastOrSmash()), + LOCATION(RC_ZD_CIRCLE_ROCK_3, logic->HasItem(RG_POWER_BRACELET) || logic->BlastOrSmash()), + LOCATION(RC_ZD_CIRCLE_ROCK_4, logic->HasItem(RG_POWER_BRACELET) || logic->BlastOrSmash()), + LOCATION(RC_ZD_CIRCLE_ROCK_5, logic->HasItem(RG_POWER_BRACELET) || logic->BlastOrSmash()), + LOCATION(RC_ZD_CIRCLE_ROCK_6, logic->HasItem(RG_POWER_BRACELET) || logic->BlastOrSmash()), + LOCATION(RC_ZD_CIRCLE_ROCK_7, logic->HasItem(RG_POWER_BRACELET) || logic->BlastOrSmash()), + LOCATION(RC_ZD_CIRCLE_ROCK_8, logic->HasItem(RG_POWER_BRACELET) || logic->BlastOrSmash()), }, { //Exits ENTRANCE(RR_ZR_BEHIND_WATERFALL, true), diff --git a/soh/soh/Enhancements/randomizer/location_access/overworld/zoras_fountain.cpp b/soh/soh/Enhancements/randomizer/location_access/overworld/zoras_fountain.cpp index 4d861b431f3..d6dbccc1e4f 100644 --- a/soh/soh/Enhancements/randomizer/location_access/overworld/zoras_fountain.cpp +++ b/soh/soh/Enhancements/randomizer/location_access/overworld/zoras_fountain.cpp @@ -23,6 +23,9 @@ void RegionTable_Init_ZorasFountain() { LOCATION(RC_ZF_NEAR_JABU_POT_3, logic->IsChild && logic->CanBreakPots()), LOCATION(RC_ZF_NEAR_JABU_POT_4, logic->IsChild && logic->CanBreakPots()), LOCATION(RC_ZF_TREE, logic->IsChild && logic->CanBonkTrees()), + LOCATION(RC_ZF_BOULDER, logic->BlastOrSmash()), + LOCATION(RC_ZF_SILVER_BOULDER, logic->CanUse(RG_SILVER_GAUNTLETS)), + LOCATION(RC_ZF_UNDERGROUND_BOULDER, logic->CanUse(RG_SILVER_GAUNTLETS) && logic->BlastOrSmash()), LOCATION(RC_ZF_BUSH_1, logic->IsChild), LOCATION(RC_ZF_BUSH_2, logic->IsChild), LOCATION(RC_ZF_BUSH_3, logic->IsChild), diff --git a/soh/soh/Enhancements/randomizer/location_access/overworld/zoras_river.cpp b/soh/soh/Enhancements/randomizer/location_access/overworld/zoras_river.cpp index 9c897538dce..516acf890e9 100644 --- a/soh/soh/Enhancements/randomizer/location_access/overworld/zoras_river.cpp +++ b/soh/soh/Enhancements/randomizer/location_access/overworld/zoras_river.cpp @@ -7,20 +7,24 @@ void RegionTable_Init_ZoraRiver() { // clang-format off areaTable[RR_ZR_FRONT] = Region("ZR Front", SCENE_ZORAS_RIVER, {}, { //Locations - LOCATION(RC_ZR_GS_TREE, logic->IsChild && logic->CanKillEnemy(RE_GOLD_SKULLTULA, ED_CLOSE) && logic->CanBonkTrees()), - LOCATION(RC_ZR_GRASS_1, logic->CanCutShrubs()), - LOCATION(RC_ZR_GRASS_2, logic->CanCutShrubs()), - LOCATION(RC_ZR_GRASS_3, logic->CanCutShrubs()), - LOCATION(RC_ZR_GRASS_4, logic->CanCutShrubs()), - LOCATION(RC_ZR_GRASS_5, logic->CanCutShrubs()), - LOCATION(RC_ZR_GRASS_6, logic->CanCutShrubs()), - LOCATION(RC_ZR_GRASS_7, logic->CanCutShrubs()), - LOCATION(RC_ZR_GRASS_8, logic->CanCutShrubs()), - LOCATION(RC_ZR_GRASS_9, logic->CanCutShrubs()), - LOCATION(RC_ZR_GRASS_10, logic->CanCutShrubs()), - LOCATION(RC_ZR_GRASS_11, logic->CanCutShrubs()), - LOCATION(RC_ZR_GRASS_12, logic->CanCutShrubs()), - LOCATION(RC_ZR_TREE, logic->IsChild && logic->CanBonkTrees()), + LOCATION(RC_ZR_GS_TREE, logic->IsChild && logic->CanKillEnemy(RE_GOLD_SKULLTULA, ED_CLOSE) && logic->CanBonkTrees()), + LOCATION(RC_ZR_GRASS_1, logic->CanCutShrubs()), + LOCATION(RC_ZR_GRASS_2, logic->CanCutShrubs()), + LOCATION(RC_ZR_GRASS_3, logic->CanCutShrubs()), + LOCATION(RC_ZR_GRASS_4, logic->CanCutShrubs()), + LOCATION(RC_ZR_GRASS_5, logic->CanCutShrubs()), + LOCATION(RC_ZR_GRASS_6, logic->CanCutShrubs()), + LOCATION(RC_ZR_GRASS_7, logic->CanCutShrubs()), + LOCATION(RC_ZR_GRASS_8, logic->CanCutShrubs()), + LOCATION(RC_ZR_GRASS_9, logic->CanCutShrubs()), + LOCATION(RC_ZR_GRASS_10, logic->CanCutShrubs()), + LOCATION(RC_ZR_GRASS_11, logic->CanCutShrubs()), + LOCATION(RC_ZR_GRASS_12, logic->CanCutShrubs()), + LOCATION(RC_ZR_TREE, logic->IsChild && logic->CanBonkTrees()), + LOCATION(RC_ZR_BOULDER_1, logic->IsChild && logic->BlastOrSmash()), + LOCATION(RC_ZR_BOULDER_2, logic->IsChild && logic->BlastOrSmash()), + LOCATION(RC_ZR_BOULDER_3, logic->IsChild && logic->BlastOrSmash()), + LOCATION(RC_ZR_BOULDER_4, logic->IsChild && logic->BlastOrSmash()), }, { //Exits ENTRANCE(RR_ZORAS_RIVER, logic->IsAdult || logic->BlastOrSmash()), @@ -54,6 +58,28 @@ void RegionTable_Init_ZoraRiver() { LOCATION(RC_ZR_BENEATH_WATERFALL_MIDDLE_LEFT_RUPEE, logic->IsAdult && (logic->HasItem(RG_BRONZE_SCALE) || logic->CanUse(RG_IRON_BOOTS) || logic->CanUse(RG_BOOMERANG))), LOCATION(RC_ZR_BENEATH_WATERFALL_MIDDLE_RIGHT_RUPEE, logic->IsAdult && (logic->HasItem(RG_BRONZE_SCALE) || logic->CanUse(RG_IRON_BOOTS) || logic->CanUse(RG_BOOMERANG))), LOCATION(RC_ZR_BENEATH_WATERFALL_RIGHT_RUPEE, logic->IsAdult && (logic->HasItem(RG_BRONZE_SCALE) || logic->CanUse(RG_IRON_BOOTS) || logic->CanUse(RG_BOOMERANG))), + LOCATION(RC_ZR_CIRCLE_ROCK_1, logic->HasItem(RG_POWER_BRACELET) || logic->BlastOrSmash()), + LOCATION(RC_ZR_CIRCLE_ROCK_2, logic->HasItem(RG_POWER_BRACELET) || logic->BlastOrSmash()), + LOCATION(RC_ZR_CIRCLE_ROCK_3, logic->HasItem(RG_POWER_BRACELET) || logic->BlastOrSmash()), + LOCATION(RC_ZR_CIRCLE_ROCK_4, logic->HasItem(RG_POWER_BRACELET) || logic->BlastOrSmash()), + LOCATION(RC_ZR_CIRCLE_ROCK_5, logic->HasItem(RG_POWER_BRACELET) || logic->BlastOrSmash()), + LOCATION(RC_ZR_CIRCLE_ROCK_6, logic->HasItem(RG_POWER_BRACELET) || logic->BlastOrSmash()), + LOCATION(RC_ZR_CIRCLE_ROCK_7, logic->HasItem(RG_POWER_BRACELET) || logic->BlastOrSmash()), + LOCATION(RC_ZR_CIRCLE_ROCK_8, logic->HasItem(RG_POWER_BRACELET) || logic->BlastOrSmash()), + LOCATION(RC_ZR_UPPER_CIRCLE_BOULDER, logic->BlastOrSmash()), + LOCATION(RC_ZR_UPPER_CIRCLE_ROCK_1, logic->HasItem(RG_POWER_BRACELET) || logic->BlastOrSmash()), + LOCATION(RC_ZR_UPPER_CIRCLE_ROCK_2, logic->HasItem(RG_POWER_BRACELET) || logic->BlastOrSmash()), + LOCATION(RC_ZR_UPPER_CIRCLE_ROCK_3, logic->HasItem(RG_POWER_BRACELET) || logic->BlastOrSmash()), + LOCATION(RC_ZR_UPPER_CIRCLE_ROCK_4, logic->HasItem(RG_POWER_BRACELET) || logic->BlastOrSmash()), + LOCATION(RC_ZR_UPPER_CIRCLE_ROCK_5, logic->HasItem(RG_POWER_BRACELET) || logic->BlastOrSmash()), + LOCATION(RC_ZR_UPPER_CIRCLE_ROCK_6, logic->HasItem(RG_POWER_BRACELET) || logic->BlastOrSmash()), + LOCATION(RC_ZR_UPPER_CIRCLE_ROCK_7, logic->HasItem(RG_POWER_BRACELET) || logic->BlastOrSmash()), + LOCATION(RC_ZR_UPPER_CIRCLE_ROCK_8, logic->HasItem(RG_POWER_BRACELET) || logic->BlastOrSmash()), + LOCATION(RC_ZR_ROCK, logic->HasItem(RG_POWER_BRACELET) || logic->BlastOrSmash()), + LOCATION(RC_ZR_UNDERWATER_ROCK_1, (logic->IsAdult && logic->HasItem(RG_POWER_BRACELET)) || logic->CanUse(RG_BOMBCHU_5)), + LOCATION(RC_ZR_UNDERWATER_ROCK_2, (logic->IsAdult && logic->HasItem(RG_POWER_BRACELET)) || logic->CanUse(RG_BOMBCHU_5)), + LOCATION(RC_ZR_UNDERWATER_ROCK_3, (logic->IsAdult && logic->HasItem(RG_POWER_BRACELET)) || logic->CanUse(RG_BOMBCHU_5)), + LOCATION(RC_ZR_UNDERWATER_ROCK_4, (logic->IsAdult && logic->HasItem(RG_POWER_BRACELET)) || logic->CanUse(RG_BOMBCHU_5)), LOCATION(RC_ZR_NEAR_DOMAIN_GOSSIP_STONE, true), LOCATION(RC_ZR_NEAR_FREESTANDING_POH_GRASS, logic->CanUse(RG_BOOMERANG)), }, { diff --git a/soh/soh/Enhancements/randomizer/logic.cpp b/soh/soh/Enhancements/randomizer/logic.cpp index 1e90099ddea..254faffb53c 100644 --- a/soh/soh/Enhancements/randomizer/logic.cpp +++ b/soh/soh/Enhancements/randomizer/logic.cpp @@ -259,12 +259,16 @@ bool Logic::HasItem(RandomizerGet itemName) { return CurrentUpgrade(UPG_SCALE) >= 1; case RG_GOLDEN_SCALE: return CurrentUpgrade(UPG_SCALE) >= 2; + case RG_CLIMB: return CheckRandoInf(RAND_INF_CAN_CLIMB); case RG_CRAWL: return CheckRandoInf(RAND_INF_CAN_CRAWL); + case RG_ROLL: + return CheckRandoInf(RAND_INF_CAN_ROLL); case RG_OPEN_CHEST: return CheckRandoInf(RAND_INF_CAN_OPEN_CHEST); + case RG_POCKET_EGG: return CheckRandoInf(RAND_INF_ADULT_TRADES_HAS_POCKET_EGG) || CheckRandoInf(RAND_INF_ADULT_TRADES_HAS_POCKET_CUCCO); @@ -1324,7 +1328,7 @@ bool Logic::CanBreakPots(EnemyDistance distance, bool wallOrFloor, bool inWater) } bool Logic::CanBreakCrates() { - return true; + return HasItem(RG_ROLL) || CanUse(RG_MEGATON_HAMMER) || CanUse(RG_BOMB_BAG) || CanUse(RG_BOMBCHU_5); } bool Logic::CanBreakSmallCrates() { @@ -1332,7 +1336,7 @@ bool Logic::CanBreakSmallCrates() { } bool Logic::CanBonkTrees() { - return true; + return HasItem(RG_ROLL); } bool Logic::HasExplosives() { @@ -1778,6 +1782,8 @@ void Logic::ApplyItemEffect(Item& item, bool state) { case RG_CRAWL: SetRandoInf(RAND_INF_CAN_CRAWL, state); break; + case RG_ROLL: + SetRandoInf(RAND_INF_CAN_ROLL, state); case RG_OPEN_CHEST: SetRandoInf(RAND_INF_CAN_OPEN_CHEST, state); break; @@ -2689,6 +2695,12 @@ void Logic::Reset(bool resetSaveContext /*= true*/) { SetRandoInf(RAND_INF_CAN_CRAWL, true); } + // If we're not shuffling roll, we start with it + if (ctx->GetOption(RSK_SHUFFLE_ROLL).Is(false)) { + SetRandoInf(RAND_INF_CAN_ROLL, true); + } + + // If we're not shuffling open chest, we start with it if (ctx->GetOption(RSK_SHUFFLE_OPEN_CHEST).Is(false)) { SetRandoInf(RAND_INF_CAN_OPEN_CHEST, true); } diff --git a/soh/soh/Enhancements/randomizer/option_descriptions.cpp b/soh/soh/Enhancements/randomizer/option_descriptions.cpp index 3eddec7e642..45cb96f24c5 100644 --- a/soh/soh/Enhancements/randomizer/option_descriptions.cpp +++ b/soh/soh/Enhancements/randomizer/option_descriptions.cpp @@ -262,6 +262,7 @@ void Settings::CreateOptionDescriptions() { "Shuffle the ability to grab as a progressive upgrade before Goron Bracelet."; mOptionDescriptions[RSK_SHUFFLE_CLIMB] = "Shuffle the ability to climb ladders into the item pool."; mOptionDescriptions[RSK_SHUFFLE_CRAWL] = "Shuffles the ability to use crawlspaces into the item pool."; + mOptionDescriptions[RSK_SHUFFLE_ROLL] = "Shuffles the ability do a roll into the item pool."; mOptionDescriptions[RSK_SHUFFLE_SPEAK] = "Shuffle ability to speak to NPCs. 6 jabbernuts will be shuffled:\nDeku, Gerudo, Goron, Hylian, Kokiri, " "Zora\nKaepora Gaebora speaks any language."; @@ -518,6 +519,8 @@ void Settings::CreateOptionDescriptions() { "Overworld - Only shuffle grass/bushes that are outside of dungeons.\n" "\n" "All Grass/Bushes - Shuffle all grass/bushes."; + mOptionDescriptions[RSK_SHUFFLE_ROCKS] = "Shuffle rock locations."; + mOptionDescriptions[RSK_SHUFFLE_BOULDERS] = "Shuffle boulder locations."; mOptionDescriptions[RSK_SHUFFLE_DUNGEON_REWARDS] = "Shuffles the location of Spiritual Stones and medallions.\n" "Vanilla - Spiritual Stones and medallions will be given from their respective boss.\n" diff --git a/soh/soh/Enhancements/randomizer/randomizer.cpp b/soh/soh/Enhancements/randomizer/randomizer.cpp index 1162e64a2d0..b0cc44e2f2b 100644 --- a/soh/soh/Enhancements/randomizer/randomizer.cpp +++ b/soh/soh/Enhancements/randomizer/randomizer.cpp @@ -127,6 +127,7 @@ std::map randomizerGetToRandInf = { { RG_CLIMB, RAND_INF_CAN_CLIMB }, { RG_CRAWL, RAND_INF_CAN_CRAWL }, { RG_OPEN_CHEST, RAND_INF_CAN_OPEN_CHEST }, + { RG_ROLL, RAND_INF_CAN_ROLL }, { RG_SPEAK_DEKU, RAND_INF_CAN_SPEAK_DEKU }, { RG_SPEAK_GERUDO, RAND_INF_CAN_SPEAK_GERUDO }, { RG_SPEAK_GORON, RAND_INF_CAN_SPEAK_GORON }, @@ -2922,6 +2923,286 @@ std::map rcToRandomizerInf = { { RC_ZR_TREE, RAND_INF_ZR_TREE }, { RC_KAK_TREE, RAND_INF_KAK_TREE }, { RC_LLR_TREE, RAND_INF_LLR_TREE }, + { RC_KF_CIRCLE_ROCK_1, RAND_INF_KF_CIRCLE_ROCK_1 }, + { RC_KF_CIRCLE_ROCK_2, RAND_INF_KF_CIRCLE_ROCK_2 }, + { RC_KF_CIRCLE_ROCK_3, RAND_INF_KF_CIRCLE_ROCK_3 }, + { RC_KF_CIRCLE_ROCK_4, RAND_INF_KF_CIRCLE_ROCK_4 }, + { RC_KF_CIRCLE_ROCK_5, RAND_INF_KF_CIRCLE_ROCK_5 }, + { RC_KF_CIRCLE_ROCK_6, RAND_INF_KF_CIRCLE_ROCK_6 }, + { RC_KF_CIRCLE_ROCK_7, RAND_INF_KF_CIRCLE_ROCK_7 }, + { RC_KF_CIRCLE_ROCK_8, RAND_INF_KF_CIRCLE_ROCK_8 }, + { RC_KF_ROCK_BY_SARIAS_HOUSE, RAND_INF_KF_ROCK_BY_SARIAS_HOUSE }, + { RC_KF_ROCK_BEHIND_SARIAS_HOUSE, RAND_INF_KF_ROCK_BEHIND_SARIAS_HOUSE }, + { RC_KF_ROCK_BY_MIDOS_HOUSE, RAND_INF_KF_ROCK_BY_MIDOS_HOUSE }, + { RC_KF_ROCK_BY_KNOW_IT_ALLS_HOUSE, RAND_INF_KF_ROCK_BY_KNOW_IT_ALLS_HOUSE }, + { RC_LW_BOULDER_BY_GORON_CITY, RAND_INF_LW_BOULDER_BY_GORON_CITY }, + { RC_LW_BOULDER_BY_SACRED_FOREST_MEADOW, RAND_INF_LW_BOULDER_BY_SACRED_FOREST_MEADOW }, + { RC_LW_RUPEE_BOULDER, RAND_INF_LW_RUPEE_BOULDER }, + { RC_HC_ROCK_1, RAND_INF_HC_ROCK_1 }, + { RC_HC_ROCK_2, RAND_INF_HC_ROCK_2 }, + { RC_HC_ROCK_3, RAND_INF_HC_ROCK_3 }, + { RC_HC_BOULDER, RAND_INF_HC_BOULDER }, + { RC_OGC_BRONZE_BOULDER_1, RAND_INF_OGC_BRONZE_BOULDER_1 }, + { RC_OGC_BRONZE_BOULDER_2, RAND_INF_OGC_BRONZE_BOULDER_2 }, + { RC_OGC_BRONZE_BOULDER_3, RAND_INF_OGC_BRONZE_BOULDER_3 }, + { RC_OGC_SILVER_BOULDER_1, RAND_INF_OGC_SILVER_BOULDER_1 }, + { RC_OGC_SILVER_BOULDER_2, RAND_INF_OGC_SILVER_BOULDER_2 }, + { RC_OGC_SILVER_BOULDER_3, RAND_INF_OGC_SILVER_BOULDER_3 }, + { RC_OGC_SILVER_BOULDER_4, RAND_INF_OGC_SILVER_BOULDER_4 }, + { RC_DMC_CIRCLE_ROCK_1, RAND_INF_DMC_CIRCLE_ROCK_1 }, + { RC_DMC_CIRCLE_ROCK_2, RAND_INF_DMC_CIRCLE_ROCK_2 }, + { RC_DMC_CIRCLE_ROCK_3, RAND_INF_DMC_CIRCLE_ROCK_3 }, + { RC_DMC_CIRCLE_ROCK_4, RAND_INF_DMC_CIRCLE_ROCK_4 }, + { RC_DMC_CIRCLE_ROCK_5, RAND_INF_DMC_CIRCLE_ROCK_5 }, + { RC_DMC_CIRCLE_ROCK_6, RAND_INF_DMC_CIRCLE_ROCK_6 }, + { RC_DMC_CIRCLE_ROCK_7, RAND_INF_DMC_CIRCLE_ROCK_7 }, + { RC_DMC_CIRCLE_ROCK_8, RAND_INF_DMC_CIRCLE_ROCK_8 }, + { RC_DMC_ROCK_BY_FIRE_TEMPLE_1, RAND_INF_DMC_ROCK_BY_FIRE_TEMPLE_1 }, + { RC_DMC_ROCK_BY_FIRE_TEMPLE_2, RAND_INF_DMC_ROCK_BY_FIRE_TEMPLE_2 }, + { RC_DMC_ROCK_BY_FIRE_TEMPLE_3, RAND_INF_DMC_ROCK_BY_FIRE_TEMPLE_3 }, + { RC_DMC_ROCK_BY_FIRE_TEMPLE_4, RAND_INF_DMC_ROCK_BY_FIRE_TEMPLE_4 }, + { RC_DMC_ROCK_BY_FIRE_TEMPLE_5, RAND_INF_DMC_ROCK_BY_FIRE_TEMPLE_5 }, + { RC_DMC_GOSSIP_ROCK_1, RAND_INF_DMC_GOSSIP_ROCK_1 }, + { RC_DMC_GOSSIP_ROCK_2, RAND_INF_DMC_GOSSIP_ROCK_2 }, + { RC_DMC_BOULDER_1, RAND_INF_DMC_BOULDER_1 }, + { RC_DMC_BOULDER_2, RAND_INF_DMC_BOULDER_2 }, + { RC_DMC_BOULDER_3, RAND_INF_DMC_BOULDER_3 }, + { RC_DMC_BRONZE_BOULDER_1, RAND_INF_DMC_BRONZE_BOULDER_1 }, + { RC_DMC_BRONZE_BOULDER_2, RAND_INF_DMC_BRONZE_BOULDER_2 }, + { RC_DMC_BRONZE_BOULDER_3, RAND_INF_DMC_BRONZE_BOULDER_3 }, + { RC_DMC_BRONZE_BOULDER_4, RAND_INF_DMC_BRONZE_BOULDER_4 }, + { RC_GV_SILVER_BOULDER, RAND_INF_GV_SILVER_BOULDER }, + { RC_GV_ROCK_1, RAND_INF_GV_ROCK_1 }, + { RC_GV_ROCK_2, RAND_INF_GV_ROCK_2 }, + { RC_GV_ROCK_3, RAND_INF_GV_ROCK_3 }, + { RC_GV_UNDERWATER_ROCK_1, RAND_INF_GV_UNDERWATER_ROCK_1 }, + { RC_GV_UNDERWATER_ROCK_2, RAND_INF_GV_UNDERWATER_ROCK_2 }, + { RC_GV_UNDERWATER_ROCK_3, RAND_INF_GV_UNDERWATER_ROCK_3 }, + { RC_GV_ROCK_ACROSS_BRIDGE_1, RAND_INF_GV_ROCK_ACROSS_BRIDGE_1 }, + { RC_GV_ROCK_ACROSS_BRIDGE_2, RAND_INF_GV_ROCK_ACROSS_BRIDGE_2 }, + { RC_GV_ROCK_ACROSS_BRIDGE_3, RAND_INF_GV_ROCK_ACROSS_BRIDGE_3 }, + { RC_GV_ROCK_ACROSS_BRIDGE_4, RAND_INF_GV_ROCK_ACROSS_BRIDGE_4 }, + { RC_GV_BOULDER_1, RAND_INF_GV_BOULDER_1 }, + { RC_GV_BOULDER_2, RAND_INF_GV_BOULDER_2 }, + { RC_GV_BOULDER_ACROSS_BRIDGE, RAND_INF_GV_BOULDER_ACROSS_BRIDGE }, + { RC_GV_BRONZE_BOULDER_1, RAND_INF_GV_BRONZE_BOULDER_1 }, + { RC_GV_BRONZE_BOULDER_2, RAND_INF_GV_BRONZE_BOULDER_2 }, + { RC_GV_BRONZE_BOULDER_ACROSS_BRIDGE_1, RAND_INF_GV_BRONZE_BOULDER_ACROSS_BRIDGE_1 }, + { RC_GV_BRONZE_BOULDER_ACROSS_BRIDGE_2, RAND_INF_GV_BRONZE_BOULDER_ACROSS_BRIDGE_2 }, + { RC_GV_BRONZE_BOULDER_ACROSS_BRIDGE_3, RAND_INF_GV_BRONZE_BOULDER_ACROSS_BRIDGE_3 }, + { RC_GV_BRONZE_BOULDER_ACROSS_BRIDGE_4, RAND_INF_GV_BRONZE_BOULDER_ACROSS_BRIDGE_4 }, + { RC_GV_BRONZE_BOULDER_ACROSS_BRIDGE_5, RAND_INF_GV_BRONZE_BOULDER_ACROSS_BRIDGE_5 }, + { RC_GV_BRONZE_BOULDER_ACROSS_BRIDGE_6, RAND_INF_GV_BRONZE_BOULDER_ACROSS_BRIDGE_6 }, + { RC_HF_SILVER_BOULDER, RAND_INF_HF_SILVER_BOULDER }, + { RC_HF_ROCK_1, RAND_INF_HF_ROCK_1 }, + { RC_HF_ROCK_2, RAND_INF_HF_ROCK_2 }, + { RC_HF_ROCK_3, RAND_INF_HF_ROCK_3 }, + { RC_HF_ROCK_4, RAND_INF_HF_ROCK_4 }, + { RC_HF_ROCK_5, RAND_INF_HF_ROCK_5 }, + { RC_HF_ROCK_6, RAND_INF_HF_ROCK_6 }, + { RC_HF_ROCK_7, RAND_INF_HF_ROCK_7 }, + { RC_HF_ROCK_8, RAND_INF_HF_ROCK_8 }, + { RC_HF_BOULDER_NORTH, RAND_INF_HF_BOULDER_NORTH }, + { RC_HF_BOULDER_BY_MARKET, RAND_INF_HF_BOULDER_BY_MARKET }, + { RC_HF_BOULDER_SOUTH, RAND_INF_HF_BOULDER_SOUTH }, + { RC_HF_BRONZE_BOULDER_1, RAND_INF_HF_BRONZE_BOULDER_1 }, + { RC_HF_BRONZE_BOULDER_2, RAND_INF_HF_BRONZE_BOULDER_2 }, + { RC_HF_BRONZE_BOULDER_3, RAND_INF_HF_BRONZE_BOULDER_3 }, + { RC_HF_BRONZE_BOULDER_4, RAND_INF_HF_BRONZE_BOULDER_4 }, + { RC_KAK_SILVER_BOULDER, RAND_INF_KAK_SILVER_BOULDER }, + { RC_KAK_ROCK_1, RAND_INF_KAK_ROCK_1 }, + { RC_KAK_ROCK_2, RAND_INF_KAK_ROCK_2 }, + { RC_GY_ROCK, RAND_INF_GY_ROCK }, + { RC_LA_ROCK, RAND_INF_LA_ROCK }, + { RC_ZD_CIRCLE_ROCK_1, RAND_INF_ZD_CIRCLE_ROCK_1 }, + { RC_ZD_CIRCLE_ROCK_2, RAND_INF_ZD_CIRCLE_ROCK_2 }, + { RC_ZD_CIRCLE_ROCK_3, RAND_INF_ZD_CIRCLE_ROCK_3 }, + { RC_ZD_CIRCLE_ROCK_4, RAND_INF_ZD_CIRCLE_ROCK_4 }, + { RC_ZD_CIRCLE_ROCK_5, RAND_INF_ZD_CIRCLE_ROCK_5 }, + { RC_ZD_CIRCLE_ROCK_6, RAND_INF_ZD_CIRCLE_ROCK_6 }, + { RC_ZD_CIRCLE_ROCK_7, RAND_INF_ZD_CIRCLE_ROCK_7 }, + { RC_ZD_CIRCLE_ROCK_8, RAND_INF_ZD_CIRCLE_ROCK_8 }, + { RC_ZF_BOULDER, RAND_INF_ZF_BOULDER }, + { RC_ZF_SILVER_BOULDER, RAND_INF_ZF_SILVER_BOULDER }, + { RC_ZF_UNDERGROUND_BOULDER, RAND_INF_ZF_UNDERGROUND_BOULDER }, + { RC_ZR_BOULDER_1, RAND_INF_ZR_BOULDER_1 }, + { RC_ZR_BOULDER_2, RAND_INF_ZR_BOULDER_2 }, + { RC_ZR_BOULDER_3, RAND_INF_ZR_BOULDER_3 }, + { RC_ZR_BOULDER_4, RAND_INF_ZR_BOULDER_4 }, + { RC_ZR_CIRCLE_ROCK_1, RAND_INF_ZR_CIRCLE_ROCK_1 }, + { RC_ZR_CIRCLE_ROCK_2, RAND_INF_ZR_CIRCLE_ROCK_2 }, + { RC_ZR_CIRCLE_ROCK_3, RAND_INF_ZR_CIRCLE_ROCK_3 }, + { RC_ZR_CIRCLE_ROCK_4, RAND_INF_ZR_CIRCLE_ROCK_4 }, + { RC_ZR_CIRCLE_ROCK_5, RAND_INF_ZR_CIRCLE_ROCK_5 }, + { RC_ZR_CIRCLE_ROCK_6, RAND_INF_ZR_CIRCLE_ROCK_6 }, + { RC_ZR_CIRCLE_ROCK_7, RAND_INF_ZR_CIRCLE_ROCK_7 }, + { RC_ZR_CIRCLE_ROCK_8, RAND_INF_ZR_CIRCLE_ROCK_8 }, + { RC_ZR_UPPER_CIRCLE_BOULDER, RAND_INF_ZR_UPPER_CIRCLE_BOULDER }, + { RC_ZR_UPPER_CIRCLE_ROCK_1, RAND_INF_ZR_UPPER_CIRCLE_ROCK_1 }, + { RC_ZR_UPPER_CIRCLE_ROCK_2, RAND_INF_ZR_UPPER_CIRCLE_ROCK_2 }, + { RC_ZR_UPPER_CIRCLE_ROCK_3, RAND_INF_ZR_UPPER_CIRCLE_ROCK_3 }, + { RC_ZR_UPPER_CIRCLE_ROCK_4, RAND_INF_ZR_UPPER_CIRCLE_ROCK_4 }, + { RC_ZR_UPPER_CIRCLE_ROCK_5, RAND_INF_ZR_UPPER_CIRCLE_ROCK_5 }, + { RC_ZR_UPPER_CIRCLE_ROCK_6, RAND_INF_ZR_UPPER_CIRCLE_ROCK_6 }, + { RC_ZR_UPPER_CIRCLE_ROCK_7, RAND_INF_ZR_UPPER_CIRCLE_ROCK_7 }, + { RC_ZR_UPPER_CIRCLE_ROCK_8, RAND_INF_ZR_UPPER_CIRCLE_ROCK_8 }, + { RC_ZR_ROCK, RAND_INF_ZR_ROCK }, + { RC_ZR_UNDERWATER_ROCK_1, RAND_INF_ZR_UNDERWATER_ROCK_1 }, + { RC_ZR_UNDERWATER_ROCK_2, RAND_INF_ZR_UNDERWATER_ROCK_2 }, + { RC_ZR_UNDERWATER_ROCK_3, RAND_INF_ZR_UNDERWATER_ROCK_3 }, + { RC_ZR_UNDERWATER_ROCK_4, RAND_INF_ZR_UNDERWATER_ROCK_4 }, + { RC_DMT_ROCK_1, RAND_INF_DMT_ROCK_1 }, + { RC_DMT_ROCK_2, RAND_INF_DMT_ROCK_2 }, + { RC_DMT_ROCK_3, RAND_INF_DMT_ROCK_3 }, + { RC_DMT_ROCK_4, RAND_INF_DMT_ROCK_4 }, + { RC_DMT_ROCK_5, RAND_INF_DMT_ROCK_5 }, + { RC_DMT_SUMMIT_ROCK, RAND_INF_DMT_SUMMIT_ROCK }, + { RC_DMT_CIRCLE_ROCK_1, RAND_INF_DMT_CIRCLE_ROCK_1 }, + { RC_DMT_CIRCLE_ROCK_2, RAND_INF_DMT_CIRCLE_ROCK_2 }, + { RC_DMT_CIRCLE_ROCK_3, RAND_INF_DMT_CIRCLE_ROCK_3 }, + { RC_DMT_CIRCLE_ROCK_4, RAND_INF_DMT_CIRCLE_ROCK_4 }, + { RC_DMT_CIRCLE_ROCK_5, RAND_INF_DMT_CIRCLE_ROCK_5 }, + { RC_DMT_CIRCLE_ROCK_6, RAND_INF_DMT_CIRCLE_ROCK_6 }, + { RC_DMT_CIRCLE_ROCK_7, RAND_INF_DMT_CIRCLE_ROCK_7 }, + { RC_DMT_CIRCLE_ROCK_8, RAND_INF_DMT_CIRCLE_ROCK_8 }, + { RC_DMT_BOULDER_1, RAND_INF_DMT_BOULDER_1 }, + { RC_DMT_BOULDER_2, RAND_INF_DMT_BOULDER_2 }, + { RC_DMT_BOULDER_3, RAND_INF_DMT_BOULDER_3 }, + { RC_DMT_COW_BOULDER, RAND_INF_DMT_COW_BOULDER }, + { RC_DMT_BRONZE_BOULDER_1, RAND_INF_DMT_BRONZE_BOULDER_1 }, + { RC_DMT_BRONZE_BOULDER_2, RAND_INF_DMT_BRONZE_BOULDER_2 }, + { RC_DMT_BRONZE_BOULDER_3, RAND_INF_DMT_BRONZE_BOULDER_3 }, + { RC_DMT_BRONZE_BOULDER_4, RAND_INF_DMT_BRONZE_BOULDER_4 }, + { RC_DMT_BRONZE_BOULDER_5, RAND_INF_DMT_BRONZE_BOULDER_5 }, + { RC_DMT_BRONZE_BOULDER_6, RAND_INF_DMT_BRONZE_BOULDER_6 }, + { RC_DMT_BRONZE_BOULDER_7, RAND_INF_DMT_BRONZE_BOULDER_7 }, + { RC_DMT_BRONZE_BOULDER_8, RAND_INF_DMT_BRONZE_BOULDER_8 }, + { RC_DMT_BRONZE_BOULDER_9, RAND_INF_DMT_BRONZE_BOULDER_9 }, + { RC_DMT_BRONZE_BOULDER_10, RAND_INF_DMT_BRONZE_BOULDER_10 }, + { RC_DMT_BRONZE_BOULDER_11, RAND_INF_DMT_BRONZE_BOULDER_11 }, + { RC_GC_LW_BOULDER_1, RAND_INF_GC_LW_BOULDER_1 }, + { RC_GC_LW_BOULDER_2, RAND_INF_GC_LW_BOULDER_2 }, + { RC_GC_LW_BOULDER_3, RAND_INF_GC_LW_BOULDER_3 }, + { RC_GC_ENTRANCE_BOULDER_1, RAND_INF_GC_ENTRANCE_BOULDER_1 }, + { RC_GC_ENTRANCE_BOULDER_2, RAND_INF_GC_ENTRANCE_BOULDER_2 }, + { RC_GC_ENTRANCE_BOULDER_3, RAND_INF_GC_ENTRANCE_BOULDER_3 }, + { RC_GC_MAZE_SILVER_BOULDER_1, RAND_INF_GC_MAZE_SILVER_BOULDER_1 }, + { RC_GC_MAZE_SILVER_BOULDER_2, RAND_INF_GC_MAZE_SILVER_BOULDER_2 }, + { RC_GC_MAZE_SILVER_BOULDER_3, RAND_INF_GC_MAZE_SILVER_BOULDER_3 }, + { RC_GC_MAZE_SILVER_BOULDER_4, RAND_INF_GC_MAZE_SILVER_BOULDER_4 }, + { RC_GC_MAZE_SILVER_BOULDER_5, RAND_INF_GC_MAZE_SILVER_BOULDER_5 }, + { RC_GC_MAZE_SILVER_BOULDER_6, RAND_INF_GC_MAZE_SILVER_BOULDER_6 }, + { RC_GC_MAZE_SILVER_BOULDER_7, RAND_INF_GC_MAZE_SILVER_BOULDER_7 }, + { RC_GC_MAZE_SILVER_BOULDER_8, RAND_INF_GC_MAZE_SILVER_BOULDER_8 }, + { RC_GC_MAZE_SILVER_BOULDER_9, RAND_INF_GC_MAZE_SILVER_BOULDER_9 }, + { RC_GC_MAZE_SILVER_BOULDER_10, RAND_INF_GC_MAZE_SILVER_BOULDER_10 }, + { RC_GC_MAZE_SILVER_BOULDER_11, RAND_INF_GC_MAZE_SILVER_BOULDER_11 }, + { RC_GC_MAZE_SILVER_BOULDER_12, RAND_INF_GC_MAZE_SILVER_BOULDER_12 }, + { RC_GC_MAZE_SILVER_BOULDER_13, RAND_INF_GC_MAZE_SILVER_BOULDER_13 }, + { RC_GC_MAZE_SILVER_BOULDER_14, RAND_INF_GC_MAZE_SILVER_BOULDER_14 }, + { RC_GC_MAZE_SILVER_BOULDER_15, RAND_INF_GC_MAZE_SILVER_BOULDER_15 }, + { RC_GC_MAZE_SILVER_BOULDER_16, RAND_INF_GC_MAZE_SILVER_BOULDER_16 }, + { RC_GC_MAZE_SILVER_BOULDER_17, RAND_INF_GC_MAZE_SILVER_BOULDER_17 }, + { RC_GC_MAZE_SILVER_BOULDER_18, RAND_INF_GC_MAZE_SILVER_BOULDER_18 }, + { RC_GC_MAZE_SILVER_BOULDER_19, RAND_INF_GC_MAZE_SILVER_BOULDER_19 }, + { RC_GC_MAZE_SILVER_BOULDER_20, RAND_INF_GC_MAZE_SILVER_BOULDER_20 }, + { RC_GC_MAZE_SILVER_BOULDER_21, RAND_INF_GC_MAZE_SILVER_BOULDER_21 }, + { RC_GC_MAZE_SILVER_BOULDER_22, RAND_INF_GC_MAZE_SILVER_BOULDER_22 }, + { RC_GC_MAZE_SILVER_BOULDER_23, RAND_INF_GC_MAZE_SILVER_BOULDER_23 }, + { RC_GC_MAZE_SILVER_BOULDER_24, RAND_INF_GC_MAZE_SILVER_BOULDER_24 }, + { RC_GC_MAZE_SILVER_BOULDER_25, RAND_INF_GC_MAZE_SILVER_BOULDER_25 }, + { RC_GC_MAZE_SILVER_BOULDER_26, RAND_INF_GC_MAZE_SILVER_BOULDER_26 }, + { RC_GC_MAZE_SILVER_BOULDER_27, RAND_INF_GC_MAZE_SILVER_BOULDER_27 }, + { RC_GC_MAZE_SILVER_BOULDER_28, RAND_INF_GC_MAZE_SILVER_BOULDER_28 }, + { RC_GC_MAZE_SILVER_BOULDER_29, RAND_INF_GC_MAZE_SILVER_BOULDER_29 }, + { RC_GC_MAZE_BOULDER_1, RAND_INF_GC_MAZE_BOULDER_1 }, + { RC_GC_MAZE_BOULDER_2, RAND_INF_GC_MAZE_BOULDER_2 }, + { RC_GC_MAZE_BOULDER_3, RAND_INF_GC_MAZE_BOULDER_3 }, + { RC_GC_MAZE_BOULDER_4, RAND_INF_GC_MAZE_BOULDER_4 }, + { RC_GC_MAZE_BOULDER_5, RAND_INF_GC_MAZE_BOULDER_5 }, + { RC_GC_MAZE_BOULDER_6, RAND_INF_GC_MAZE_BOULDER_6 }, + { RC_GC_MAZE_BOULDER_7, RAND_INF_GC_MAZE_BOULDER_7 }, + { RC_GC_MAZE_BOULDER_8, RAND_INF_GC_MAZE_BOULDER_8 }, + { RC_GC_MAZE_BOULDER_9, RAND_INF_GC_MAZE_BOULDER_9 }, + { RC_GC_MAZE_BOULDER_10, RAND_INF_GC_MAZE_BOULDER_10 }, + { RC_GC_MAZE_BRONZE_BOULDER_1, RAND_INF_GC_MAZE_BRONZE_BOULDER_1 }, + { RC_GC_MAZE_BRONZE_BOULDER_2, RAND_INF_GC_MAZE_BRONZE_BOULDER_2 }, + { RC_GC_MAZE_BRONZE_BOULDER_3, RAND_INF_GC_MAZE_BRONZE_BOULDER_3 }, + { RC_GC_MAZE_BRONZE_BOULDER_4, RAND_INF_GC_MAZE_BRONZE_BOULDER_4 }, + { RC_GC_MAZE_BRONZE_BOULDER_5, RAND_INF_GC_MAZE_BRONZE_BOULDER_5 }, + { RC_GC_MAZE_ROCK, RAND_INF_GC_MAZE_ROCK }, + { RC_COLOSSUS_SILVER_BOULDER, RAND_INF_COLOSSUS_SILVER_BOULDER }, + { RC_COLOSSUS_ROCK, RAND_INF_COLOSSUS_ROCK }, + { RC_COLOSSUS_CIRCLE_1_ROCK_1, RAND_INF_COLOSSUS_CIRCLE_1_ROCK_1 }, + { RC_COLOSSUS_CIRCLE_1_ROCK_2, RAND_INF_COLOSSUS_CIRCLE_1_ROCK_2 }, + { RC_COLOSSUS_CIRCLE_1_ROCK_3, RAND_INF_COLOSSUS_CIRCLE_1_ROCK_3 }, + { RC_COLOSSUS_CIRCLE_1_ROCK_4, RAND_INF_COLOSSUS_CIRCLE_1_ROCK_4 }, + { RC_COLOSSUS_CIRCLE_1_ROCK_5, RAND_INF_COLOSSUS_CIRCLE_1_ROCK_5 }, + { RC_COLOSSUS_CIRCLE_1_ROCK_6, RAND_INF_COLOSSUS_CIRCLE_1_ROCK_6 }, + { RC_COLOSSUS_CIRCLE_1_ROCK_7, RAND_INF_COLOSSUS_CIRCLE_1_ROCK_7 }, + { RC_COLOSSUS_CIRCLE_1_ROCK_8, RAND_INF_COLOSSUS_CIRCLE_1_ROCK_8 }, + { RC_COLOSSUS_CIRCLE_2_ROCK_1, RAND_INF_COLOSSUS_CIRCLE_2_ROCK_1 }, + { RC_COLOSSUS_CIRCLE_2_ROCK_2, RAND_INF_COLOSSUS_CIRCLE_2_ROCK_2 }, + { RC_COLOSSUS_CIRCLE_2_ROCK_3, RAND_INF_COLOSSUS_CIRCLE_2_ROCK_3 }, + { RC_COLOSSUS_CIRCLE_2_ROCK_4, RAND_INF_COLOSSUS_CIRCLE_2_ROCK_4 }, + { RC_COLOSSUS_CIRCLE_2_ROCK_5, RAND_INF_COLOSSUS_CIRCLE_2_ROCK_5 }, + { RC_COLOSSUS_CIRCLE_2_ROCK_6, RAND_INF_COLOSSUS_CIRCLE_2_ROCK_6 }, + { RC_COLOSSUS_CIRCLE_2_ROCK_7, RAND_INF_COLOSSUS_CIRCLE_2_ROCK_7 }, + { RC_COLOSSUS_CIRCLE_2_ROCK_8, RAND_INF_COLOSSUS_CIRCLE_2_ROCK_8 }, + { RC_HC_STORMS_GROTTO_ROCK_1, RAND_INF_HC_STORMS_GROTTO_ROCK_1 }, + { RC_HC_STORMS_GROTTO_ROCK_2, RAND_INF_HC_STORMS_GROTTO_ROCK_2 }, + { RC_HC_STORMS_GROTTO_ROCK_3, RAND_INF_HC_STORMS_GROTTO_ROCK_3 }, + { RC_HC_STORMS_GROTTO_ROCK_4, RAND_INF_HC_STORMS_GROTTO_ROCK_4 }, + { RC_HC_STORMS_GROTTO_ROCK_5, RAND_INF_HC_STORMS_GROTTO_ROCK_5 }, + { RC_HC_STORMS_GROTTO_ROCK_6, RAND_INF_HC_STORMS_GROTTO_ROCK_6 }, + { RC_HC_STORMS_GROTTO_ROCK_7, RAND_INF_HC_STORMS_GROTTO_ROCK_7 }, + { RC_HC_STORMS_GROTTO_ROCK_8, RAND_INF_HC_STORMS_GROTTO_ROCK_8 }, + { RC_BOTW_BOULDER_1, RAND_INF_BOTW_BOULDER_1 }, + { RC_BOTW_BOULDER_2, RAND_INF_BOTW_BOULDER_2 }, + { RC_BOTW_BOULDER_3, RAND_INF_BOTW_BOULDER_3 }, + { RC_BOTW_BOULDER_4, RAND_INF_BOTW_BOULDER_4 }, + { RC_BOTW_BOULDER_5, RAND_INF_BOTW_BOULDER_5 }, + { RC_BOTW_BOULDER_6, RAND_INF_BOTW_BOULDER_6 }, + { RC_DEKU_TREE_MQ_BOULDER_1, RAND_INF_DEKU_TREE_MQ_BOULDER_1 }, + { RC_DEKU_TREE_MQ_BOULDER_2, RAND_INF_DEKU_TREE_MQ_BOULDER_2 }, + { RC_DEKU_TREE_MQ_BOULDER_3, RAND_INF_DEKU_TREE_MQ_BOULDER_3 }, + { RC_DODONGOS_CAVERN_MQ_LOBBY_BOULDER_1, RAND_INF_DODONGOS_CAVERN_MQ_LOBBY_BOULDER_1 }, + { RC_DODONGOS_CAVERN_MQ_LOBBY_BOULDER_2, RAND_INF_DODONGOS_CAVERN_MQ_LOBBY_BOULDER_2 }, + { RC_DODONGOS_CAVERN_MQ_MOUTH_SIDE_BRIDGE_BOULDER_1, RAND_INF_DODONGOS_CAVERN_MQ_MOUTH_SIDE_BRIDGE_BOULDER_1 }, + { RC_DODONGOS_CAVERN_MQ_MOUTH_SIDE_BRIDGE_BOULDER_2, RAND_INF_DODONGOS_CAVERN_MQ_MOUTH_SIDE_BRIDGE_BOULDER_2 }, + { RC_DODONGOS_CAVERN_MQ_MOUTH_SIDE_BRIDGE_BOULDER_3, RAND_INF_DODONGOS_CAVERN_MQ_MOUTH_SIDE_BRIDGE_BOULDER_3 }, + { RC_DODONGOS_CAVERN_MQ_RIGHT_SIDE_BOULDER_1, RAND_INF_DODONGOS_CAVERN_MQ_RIGHT_SIDE_BOULDER_1 }, + { RC_DODONGOS_CAVERN_MQ_RIGHT_SIDE_BOULDER_2, RAND_INF_DODONGOS_CAVERN_MQ_RIGHT_SIDE_BOULDER_2 }, + { RC_DODONGOS_CAVERN_MQ_LIZALFOS_ROOM_BOULDER_1, RAND_INF_DODONGOS_CAVERN_MQ_LIZALFOS_ROOM_BOULDER_1 }, + { RC_DODONGOS_CAVERN_MQ_LIZALFOS_ROOM_BOULDER_2, RAND_INF_DODONGOS_CAVERN_MQ_LIZALFOS_ROOM_BOULDER_2 }, + { RC_DODONGOS_CAVERN_MQ_LIZALFOS_ROOM_BOULDER_3, RAND_INF_DODONGOS_CAVERN_MQ_LIZALFOS_ROOM_BOULDER_3 }, + { RC_DODONGOS_CAVERN_MQ_LIZALFOS_ROOM_BOULDER_4, RAND_INF_DODONGOS_CAVERN_MQ_LIZALFOS_ROOM_BOULDER_4 }, + { RC_DODONGOS_CAVERN_MQ_LIZALFOS_ROOM_BOULDER_5, RAND_INF_DODONGOS_CAVERN_MQ_LIZALFOS_ROOM_BOULDER_5 }, + { RC_DODONGOS_CAVERN_MQ_LIZALFOS_ROOM_BOULDER_6, RAND_INF_DODONGOS_CAVERN_MQ_LIZALFOS_ROOM_BOULDER_6 }, + { RC_DODONGOS_CAVERN_MQ_LIZALFOS_ROOM_BOULDER_7, RAND_INF_DODONGOS_CAVERN_MQ_LIZALFOS_ROOM_BOULDER_7 }, + { RC_DODONGOS_CAVERN_MQ_LIZALFOS_ROOM_BOULDER_8, RAND_INF_DODONGOS_CAVERN_MQ_LIZALFOS_ROOM_BOULDER_8 }, + { RC_DODONGOS_CAVERN_MQ_LIZALFOS_ROOM_BOULDER_9, RAND_INF_DODONGOS_CAVERN_MQ_LIZALFOS_ROOM_BOULDER_9 }, + { RC_DODONGOS_CAVERN_MQ_LIZALFOS_ROOM_BOULDER_10, RAND_INF_DODONGOS_CAVERN_MQ_LIZALFOS_ROOM_BOULDER_10 }, + { RC_DODONGOS_CAVERN_MQ_LIZALFOS_ROOM_BOULDER_11, RAND_INF_DODONGOS_CAVERN_MQ_LIZALFOS_ROOM_BOULDER_11 }, + { RC_DODONGOS_CAVERN_MQ_LIZALFOS_ROOM_BOULDER_12, RAND_INF_DODONGOS_CAVERN_MQ_LIZALFOS_ROOM_BOULDER_12 }, + { RC_JABU_JABUS_BELLY_MQ_ENTRANCE_BOULDER, RAND_INF_JABU_JABUS_BELLY_MQ_ENTRANCE_BOULDER }, + { RC_JABU_JABUS_BELLY_MQ_HOLES_ROOM_BOULDER_1, RAND_INF_JABU_JABUS_BELLY_MQ_HOLES_ROOM_BOULDER_1 }, + { RC_JABU_JABUS_BELLY_MQ_HOLES_ROOM_BOULDER_2, RAND_INF_JABU_JABUS_BELLY_MQ_HOLES_ROOM_BOULDER_2 }, + { RC_JABU_JABUS_BELLY_MQ_HOLES_ROOM_WALL_BOULDER_1, RAND_INF_JABU_JABUS_BELLY_MQ_HOLES_ROOM_WALL_BOULDER_1 }, + { RC_JABU_JABUS_BELLY_MQ_HOLES_ROOM_WALL_BOULDER_2, RAND_INF_JABU_JABUS_BELLY_MQ_HOLES_ROOM_WALL_BOULDER_2 }, + { RC_JABU_JABUS_BELLY_MQ_HOLES_ROOM_WALL_BOULDER_3, RAND_INF_JABU_JABUS_BELLY_MQ_HOLES_ROOM_WALL_BOULDER_3 }, + { RC_JABU_JABUS_BELLY_MQ_FORKED_CORRIDOR_BOULDER_1, RAND_INF_JABU_JABUS_BELLY_MQ_FORKED_CORRIDOR_BOULDER_1 }, + { RC_JABU_JABUS_BELLY_MQ_FORKED_CORRIDOR_BOULDER_2, RAND_INF_JABU_JABUS_BELLY_MQ_FORKED_CORRIDOR_BOULDER_2 }, + { RC_JABU_JABUS_BELLY_MQ_TAILPASARAN_BOULDER, RAND_INF_JABU_JABUS_BELLY_MQ_TAILPASARAN_BOULDER }, + { RC_JABU_JABUS_BELLY_MQ_TAILPASARAN_WALL_BOULDER, RAND_INF_JABU_JABUS_BELLY_MQ_TAILPASARAN_WALL_BOULDER }, + { RC_SPIRIT_TEMPLE_MQ_ENTRANCE_BOULDER_1, RAND_INF_SPIRIT_TEMPLE_MQ_ENTRANCE_BOULDER_1 }, + { RC_SPIRIT_TEMPLE_MQ_ENTRANCE_BOULDER_2, RAND_INF_SPIRIT_TEMPLE_MQ_ENTRANCE_BOULDER_2 }, + { RC_SPIRIT_TEMPLE_MQ_ENTRANCE_BOULDER_3, RAND_INF_SPIRIT_TEMPLE_MQ_ENTRANCE_BOULDER_3 }, + { RC_SPIRIT_TEMPLE_MQ_ENTRANCE_CEILING_BOULDER, RAND_INF_SPIRIT_TEMPLE_MQ_ENTRANCE_CEILING_BOULDER }, + { RC_SPIRIT_TEMPLE_MQ_EARLY_ADULT_BOULDER, RAND_INF_SPIRIT_TEMPLE_MQ_EARLY_ADULT_BOULDER }, + { RC_BOTW_MQ_BOULDER_1, RAND_INF_BOTW_MQ_BOULDER_1 }, + { RC_BOTW_MQ_BOULDER_2, RAND_INF_BOTW_MQ_BOULDER_2 }, + { RC_BOTW_MQ_BOULDER_3, RAND_INF_BOTW_MQ_BOULDER_3 }, { RC_HF_BUSH_NEAR_LAKE_1, RAND_INF_HF_BUSH_NEAR_LAKE_1 }, { RC_HF_BUSH_NEAR_LAKE_2, RAND_INF_HF_BUSH_NEAR_LAKE_2 }, { RC_HF_BUSH_NEAR_LAKE_3, RAND_INF_HF_BUSH_NEAR_LAKE_3 }, @@ -3011,7 +3292,6 @@ CheckIdentity Randomizer::IdentifyBeehive(s32 sceneNum, s16 xPosition, s32 respa } Rando::Location* Randomizer::GetCheckObjectFromActor(s16 actorId, s16 sceneNum, s32 actorParams = 0x00) { - auto fs = OTRGlobals::Instance->gRandoContext->GetFishsanity(); RandomizerCheck specialRc = RC_UNKNOWN_CHECK; // TODO: Migrate these special cases into table, or at least document why they are special switch (sceneNum) { @@ -3430,6 +3710,22 @@ CheckIdentity Randomizer::IdentifyTree(s32 sceneNum, s32 posX, s32 posZ) { return treeIdentity; } +RockIdentity Randomizer::IdentifyRock(s32 sceneNum, s32 posX, s32 posZ) { + struct RockIdentity rockIdentity; + + rockIdentity.randomizerInf = RAND_INF_MAX; + rockIdentity.randomizerCheck = RC_UNKNOWN_CHECK; + + Rando::Location* location = GetCheckObjectFromActor(ACTOR_EN_ISHI, sceneNum, TWO_ACTOR_PARAMS(posX, posZ)); + + if (location->GetRandomizerCheck() != RC_UNKNOWN_CHECK) { + rockIdentity.randomizerInf = rcToRandomizerInf[location->GetRandomizerCheck()]; + rockIdentity.randomizerCheck = location->GetRandomizerCheck(); + } + + return rockIdentity; +} + u8 Randomizer::GetRandoSettingValue(RandomizerSettingKey randoSettingKey) { return Rando::Context::GetInstance()->GetOption(randoSettingKey).Get(); } diff --git a/soh/soh/Enhancements/randomizer/randomizer.h b/soh/soh/Enhancements/randomizer/randomizer.h index b64a804e4ef..3cf750bccb2 100644 --- a/soh/soh/Enhancements/randomizer/randomizer.h +++ b/soh/soh/Enhancements/randomizer/randomizer.h @@ -43,6 +43,7 @@ class Randomizer { CheckIdentity IdentifyCrate(s32 sceneNum, s32 posX, s32 posZ); CheckIdentity IdentifySmallCrate(s32 sceneNum, s32 posX, s32 posZ); CheckIdentity IdentifyTree(s32 sceneNum, s32 posX, s32 posZ); + RockIdentity IdentifyRock(s32 sceneNum, s32 posX, s32 posZ); GetItemEntry GetItemFromKnownCheck(RandomizerCheck randomizerCheck, GetItemID ogItemId, bool checkObtainability = true); GetItemEntry GetItemFromActor(s16 actorId, s16 sceneNum, s16 actorParams, GetItemID ogItemId, diff --git a/soh/soh/Enhancements/randomizer/randomizerTypes.h b/soh/soh/Enhancements/randomizer/randomizerTypes.h index a0de7c5f0e3..66157781844 100644 --- a/soh/soh/Enhancements/randomizer/randomizerTypes.h +++ b/soh/soh/Enhancements/randomizer/randomizerTypes.h @@ -469,6 +469,8 @@ typedef enum { RCTYPE_BEAN_FAIRY, // Fairies from Beans RCTYPE_SONG_FAIRY, // Fairies from Songs RCTYPE_GRASS, // Grass + RCTYPE_ROCK, // Rocks + RCTYPE_BOULDER, // Boulders } RandomizerCheckType; typedef enum { RCQUEST_VANILLA, RCQUEST_MQ, RCQUEST_BOTH } RandomizerCheckQuest; @@ -4123,6 +4125,288 @@ typedef enum { RC_DEKU_TREE_QUEEN_GOHMA_GRASS_8, // End Grass + RC_KF_CIRCLE_ROCK_1, + RC_KF_CIRCLE_ROCK_2, + RC_KF_CIRCLE_ROCK_3, + RC_KF_CIRCLE_ROCK_4, + RC_KF_CIRCLE_ROCK_5, + RC_KF_CIRCLE_ROCK_6, + RC_KF_CIRCLE_ROCK_7, + RC_KF_CIRCLE_ROCK_8, + RC_KF_ROCK_BY_SARIAS_HOUSE, + RC_KF_ROCK_BEHIND_SARIAS_HOUSE, + RC_KF_ROCK_BY_MIDOS_HOUSE, + RC_KF_ROCK_BY_KNOW_IT_ALLS_HOUSE, + RC_LW_BOULDER_BY_GORON_CITY, + RC_LW_BOULDER_BY_SACRED_FOREST_MEADOW, + RC_LW_RUPEE_BOULDER, + RC_HC_ROCK_1, + RC_HC_ROCK_2, + RC_HC_ROCK_3, + RC_HC_BOULDER, + RC_OGC_BRONZE_BOULDER_1, + RC_OGC_BRONZE_BOULDER_2, + RC_OGC_BRONZE_BOULDER_3, + RC_OGC_SILVER_BOULDER_1, + RC_OGC_SILVER_BOULDER_2, + RC_OGC_SILVER_BOULDER_3, + RC_OGC_SILVER_BOULDER_4, + RC_DMC_CIRCLE_ROCK_1, + RC_DMC_CIRCLE_ROCK_2, + RC_DMC_CIRCLE_ROCK_3, + RC_DMC_CIRCLE_ROCK_4, + RC_DMC_CIRCLE_ROCK_5, + RC_DMC_CIRCLE_ROCK_6, + RC_DMC_CIRCLE_ROCK_7, + RC_DMC_CIRCLE_ROCK_8, + RC_DMC_ROCK_BY_FIRE_TEMPLE_1, + RC_DMC_ROCK_BY_FIRE_TEMPLE_2, + RC_DMC_ROCK_BY_FIRE_TEMPLE_3, + RC_DMC_ROCK_BY_FIRE_TEMPLE_4, + RC_DMC_ROCK_BY_FIRE_TEMPLE_5, + RC_DMC_GOSSIP_ROCK_1, + RC_DMC_GOSSIP_ROCK_2, + RC_DMC_BOULDER_1, + RC_DMC_BOULDER_2, + RC_DMC_BOULDER_3, + RC_DMC_BRONZE_BOULDER_1, + RC_DMC_BRONZE_BOULDER_2, + RC_DMC_BRONZE_BOULDER_3, + RC_DMC_BRONZE_BOULDER_4, + RC_GV_SILVER_BOULDER, + RC_GV_ROCK_1, + RC_GV_ROCK_2, + RC_GV_ROCK_3, + RC_GV_UNDERWATER_ROCK_1, + RC_GV_UNDERWATER_ROCK_2, + RC_GV_UNDERWATER_ROCK_3, + RC_GV_ROCK_ACROSS_BRIDGE_1, + RC_GV_ROCK_ACROSS_BRIDGE_2, + RC_GV_ROCK_ACROSS_BRIDGE_3, + RC_GV_ROCK_ACROSS_BRIDGE_4, + RC_GV_BOULDER_1, + RC_GV_BOULDER_2, + RC_GV_BOULDER_ACROSS_BRIDGE, + RC_GV_BRONZE_BOULDER_1, + RC_GV_BRONZE_BOULDER_2, + RC_GV_BRONZE_BOULDER_ACROSS_BRIDGE_1, + RC_GV_BRONZE_BOULDER_ACROSS_BRIDGE_2, + RC_GV_BRONZE_BOULDER_ACROSS_BRIDGE_3, + RC_GV_BRONZE_BOULDER_ACROSS_BRIDGE_4, + RC_GV_BRONZE_BOULDER_ACROSS_BRIDGE_5, + RC_GV_BRONZE_BOULDER_ACROSS_BRIDGE_6, + RC_HF_SILVER_BOULDER, + RC_HF_ROCK_1, + RC_HF_ROCK_2, + RC_HF_ROCK_3, + RC_HF_ROCK_4, + RC_HF_ROCK_5, + RC_HF_ROCK_6, + RC_HF_ROCK_7, + RC_HF_ROCK_8, + RC_HF_BOULDER_NORTH, + RC_HF_BOULDER_BY_MARKET, + RC_HF_BOULDER_SOUTH, + RC_HF_BRONZE_BOULDER_1, + RC_HF_BRONZE_BOULDER_2, + RC_HF_BRONZE_BOULDER_3, + RC_HF_BRONZE_BOULDER_4, + RC_KAK_SILVER_BOULDER, + RC_KAK_ROCK_1, + RC_KAK_ROCK_2, + RC_GY_ROCK, + RC_LA_ROCK, + RC_ZD_CIRCLE_ROCK_1, + RC_ZD_CIRCLE_ROCK_2, + RC_ZD_CIRCLE_ROCK_3, + RC_ZD_CIRCLE_ROCK_4, + RC_ZD_CIRCLE_ROCK_5, + RC_ZD_CIRCLE_ROCK_6, + RC_ZD_CIRCLE_ROCK_7, + RC_ZD_CIRCLE_ROCK_8, + RC_ZF_BOULDER, + RC_ZF_SILVER_BOULDER, + RC_ZF_UNDERGROUND_BOULDER, + RC_ZR_BOULDER_1, + RC_ZR_BOULDER_2, + RC_ZR_BOULDER_3, + RC_ZR_BOULDER_4, + RC_ZR_CIRCLE_ROCK_1, + RC_ZR_CIRCLE_ROCK_2, + RC_ZR_CIRCLE_ROCK_3, + RC_ZR_CIRCLE_ROCK_4, + RC_ZR_CIRCLE_ROCK_5, + RC_ZR_CIRCLE_ROCK_6, + RC_ZR_CIRCLE_ROCK_7, + RC_ZR_CIRCLE_ROCK_8, + RC_ZR_UPPER_CIRCLE_BOULDER, + RC_ZR_UPPER_CIRCLE_ROCK_1, + RC_ZR_UPPER_CIRCLE_ROCK_2, + RC_ZR_UPPER_CIRCLE_ROCK_3, + RC_ZR_UPPER_CIRCLE_ROCK_4, + RC_ZR_UPPER_CIRCLE_ROCK_5, + RC_ZR_UPPER_CIRCLE_ROCK_6, + RC_ZR_UPPER_CIRCLE_ROCK_7, + RC_ZR_UPPER_CIRCLE_ROCK_8, + RC_ZR_ROCK, + RC_ZR_UNDERWATER_ROCK_1, + RC_ZR_UNDERWATER_ROCK_2, + RC_ZR_UNDERWATER_ROCK_3, + RC_ZR_UNDERWATER_ROCK_4, + RC_DMT_ROCK_1, + RC_DMT_ROCK_2, + RC_DMT_ROCK_3, + RC_DMT_ROCK_4, + RC_DMT_ROCK_5, + RC_DMT_SUMMIT_ROCK, + RC_DMT_CIRCLE_ROCK_1, + RC_DMT_CIRCLE_ROCK_2, + RC_DMT_CIRCLE_ROCK_3, + RC_DMT_CIRCLE_ROCK_4, + RC_DMT_CIRCLE_ROCK_5, + RC_DMT_CIRCLE_ROCK_6, + RC_DMT_CIRCLE_ROCK_7, + RC_DMT_CIRCLE_ROCK_8, + RC_DMT_BOULDER_1, + RC_DMT_BOULDER_2, + RC_DMT_BOULDER_3, + RC_DMT_COW_BOULDER, + RC_DMT_BRONZE_BOULDER_1, + RC_DMT_BRONZE_BOULDER_2, + RC_DMT_BRONZE_BOULDER_3, + RC_DMT_BRONZE_BOULDER_4, + RC_DMT_BRONZE_BOULDER_5, + RC_DMT_BRONZE_BOULDER_6, + RC_DMT_BRONZE_BOULDER_7, + RC_DMT_BRONZE_BOULDER_8, + RC_DMT_BRONZE_BOULDER_9, + RC_DMT_BRONZE_BOULDER_10, + RC_DMT_BRONZE_BOULDER_11, + RC_GC_LW_BOULDER_1, + RC_GC_LW_BOULDER_2, + RC_GC_LW_BOULDER_3, + RC_GC_ENTRANCE_BOULDER_1, + RC_GC_ENTRANCE_BOULDER_2, + RC_GC_ENTRANCE_BOULDER_3, + RC_GC_MAZE_SILVER_BOULDER_1, + RC_GC_MAZE_SILVER_BOULDER_2, + RC_GC_MAZE_SILVER_BOULDER_3, + RC_GC_MAZE_SILVER_BOULDER_4, + RC_GC_MAZE_SILVER_BOULDER_5, + RC_GC_MAZE_SILVER_BOULDER_6, + RC_GC_MAZE_SILVER_BOULDER_7, + RC_GC_MAZE_SILVER_BOULDER_8, + RC_GC_MAZE_SILVER_BOULDER_9, + RC_GC_MAZE_SILVER_BOULDER_10, + RC_GC_MAZE_SILVER_BOULDER_11, + RC_GC_MAZE_SILVER_BOULDER_12, + RC_GC_MAZE_SILVER_BOULDER_13, + RC_GC_MAZE_SILVER_BOULDER_14, + RC_GC_MAZE_SILVER_BOULDER_15, + RC_GC_MAZE_SILVER_BOULDER_16, + RC_GC_MAZE_SILVER_BOULDER_17, + RC_GC_MAZE_SILVER_BOULDER_18, + RC_GC_MAZE_SILVER_BOULDER_19, + RC_GC_MAZE_SILVER_BOULDER_20, + RC_GC_MAZE_SILVER_BOULDER_21, + RC_GC_MAZE_SILVER_BOULDER_22, + RC_GC_MAZE_SILVER_BOULDER_23, + RC_GC_MAZE_SILVER_BOULDER_24, + RC_GC_MAZE_SILVER_BOULDER_25, + RC_GC_MAZE_SILVER_BOULDER_26, + RC_GC_MAZE_SILVER_BOULDER_27, + RC_GC_MAZE_SILVER_BOULDER_28, + RC_GC_MAZE_SILVER_BOULDER_29, + RC_GC_MAZE_BOULDER_1, + RC_GC_MAZE_BOULDER_2, + RC_GC_MAZE_BOULDER_3, + RC_GC_MAZE_BOULDER_4, + RC_GC_MAZE_BOULDER_5, + RC_GC_MAZE_BOULDER_6, + RC_GC_MAZE_BOULDER_7, + RC_GC_MAZE_BOULDER_8, + RC_GC_MAZE_BOULDER_9, + RC_GC_MAZE_BOULDER_10, + RC_GC_MAZE_BRONZE_BOULDER_1, + RC_GC_MAZE_BRONZE_BOULDER_2, + RC_GC_MAZE_BRONZE_BOULDER_3, + RC_GC_MAZE_BRONZE_BOULDER_4, + RC_GC_MAZE_BRONZE_BOULDER_5, + RC_GC_MAZE_ROCK, + RC_COLOSSUS_SILVER_BOULDER, + RC_COLOSSUS_ROCK, + RC_COLOSSUS_CIRCLE_1_ROCK_1, + RC_COLOSSUS_CIRCLE_1_ROCK_2, + RC_COLOSSUS_CIRCLE_1_ROCK_3, + RC_COLOSSUS_CIRCLE_1_ROCK_4, + RC_COLOSSUS_CIRCLE_1_ROCK_5, + RC_COLOSSUS_CIRCLE_1_ROCK_6, + RC_COLOSSUS_CIRCLE_1_ROCK_7, + RC_COLOSSUS_CIRCLE_1_ROCK_8, + RC_COLOSSUS_CIRCLE_2_ROCK_1, + RC_COLOSSUS_CIRCLE_2_ROCK_2, + RC_COLOSSUS_CIRCLE_2_ROCK_3, + RC_COLOSSUS_CIRCLE_2_ROCK_4, + RC_COLOSSUS_CIRCLE_2_ROCK_5, + RC_COLOSSUS_CIRCLE_2_ROCK_6, + RC_COLOSSUS_CIRCLE_2_ROCK_7, + RC_COLOSSUS_CIRCLE_2_ROCK_8, + RC_HC_STORMS_GROTTO_ROCK_1, + RC_HC_STORMS_GROTTO_ROCK_2, + RC_HC_STORMS_GROTTO_ROCK_3, + RC_HC_STORMS_GROTTO_ROCK_4, + RC_HC_STORMS_GROTTO_ROCK_5, + RC_HC_STORMS_GROTTO_ROCK_6, + RC_HC_STORMS_GROTTO_ROCK_7, + RC_HC_STORMS_GROTTO_ROCK_8, + RC_BOTW_BOULDER_1, + RC_BOTW_BOULDER_2, + RC_BOTW_BOULDER_3, + RC_BOTW_BOULDER_4, + RC_BOTW_BOULDER_5, + RC_BOTW_BOULDER_6, + RC_DEKU_TREE_MQ_BOULDER_1, + RC_DEKU_TREE_MQ_BOULDER_2, + RC_DEKU_TREE_MQ_BOULDER_3, + RC_DODONGOS_CAVERN_MQ_LOBBY_BOULDER_1, + RC_DODONGOS_CAVERN_MQ_LOBBY_BOULDER_2, + RC_DODONGOS_CAVERN_MQ_MOUTH_SIDE_BRIDGE_BOULDER_1, + RC_DODONGOS_CAVERN_MQ_MOUTH_SIDE_BRIDGE_BOULDER_2, + RC_DODONGOS_CAVERN_MQ_MOUTH_SIDE_BRIDGE_BOULDER_3, + RC_DODONGOS_CAVERN_MQ_RIGHT_SIDE_BOULDER_1, + RC_DODONGOS_CAVERN_MQ_RIGHT_SIDE_BOULDER_2, + RC_DODONGOS_CAVERN_MQ_LIZALFOS_ROOM_BOULDER_1, + RC_DODONGOS_CAVERN_MQ_LIZALFOS_ROOM_BOULDER_2, + RC_DODONGOS_CAVERN_MQ_LIZALFOS_ROOM_BOULDER_3, + RC_DODONGOS_CAVERN_MQ_LIZALFOS_ROOM_BOULDER_4, + RC_DODONGOS_CAVERN_MQ_LIZALFOS_ROOM_BOULDER_5, + RC_DODONGOS_CAVERN_MQ_LIZALFOS_ROOM_BOULDER_6, + RC_DODONGOS_CAVERN_MQ_LIZALFOS_ROOM_BOULDER_7, + RC_DODONGOS_CAVERN_MQ_LIZALFOS_ROOM_BOULDER_8, + RC_DODONGOS_CAVERN_MQ_LIZALFOS_ROOM_BOULDER_9, + RC_DODONGOS_CAVERN_MQ_LIZALFOS_ROOM_BOULDER_10, + RC_DODONGOS_CAVERN_MQ_LIZALFOS_ROOM_BOULDER_11, + RC_DODONGOS_CAVERN_MQ_LIZALFOS_ROOM_BOULDER_12, + RC_DODONGOS_CAVERN_MQ_TWO_FLAMES_BOULDER, + RC_JABU_JABUS_BELLY_MQ_ENTRANCE_BOULDER, + RC_JABU_JABUS_BELLY_MQ_HOLES_ROOM_BOULDER_1, + RC_JABU_JABUS_BELLY_MQ_HOLES_ROOM_BOULDER_2, + RC_JABU_JABUS_BELLY_MQ_HOLES_ROOM_WALL_BOULDER_1, + RC_JABU_JABUS_BELLY_MQ_HOLES_ROOM_WALL_BOULDER_2, + RC_JABU_JABUS_BELLY_MQ_HOLES_ROOM_WALL_BOULDER_3, + RC_JABU_JABUS_BELLY_MQ_FORKED_CORRIDOR_BOULDER_1, + RC_JABU_JABUS_BELLY_MQ_FORKED_CORRIDOR_BOULDER_2, + RC_JABU_JABUS_BELLY_MQ_TAILPASARAN_BOULDER, + RC_JABU_JABUS_BELLY_MQ_TAILPASARAN_WALL_BOULDER, + RC_SPIRIT_TEMPLE_MQ_ENTRANCE_BOULDER_1, + RC_SPIRIT_TEMPLE_MQ_ENTRANCE_BOULDER_2, + RC_SPIRIT_TEMPLE_MQ_ENTRANCE_BOULDER_3, + RC_SPIRIT_TEMPLE_MQ_ENTRANCE_CEILING_BOULDER, + RC_SPIRIT_TEMPLE_MQ_EARLY_ADULT_BOULDER, + RC_BOTW_MQ_BOULDER_1, + RC_BOTW_MQ_BOULDER_2, + RC_BOTW_MQ_BOULDER_3, + RC_MAX } RandomizerCheck; @@ -4637,6 +4921,7 @@ typedef enum { RG_POWER_BRACELET, RG_CLIMB, RG_CRAWL, + RG_ROLL, RG_OPEN_CHEST, RG_SPEAK_DEKU, RG_SPEAK_GERUDO, @@ -5851,6 +6136,7 @@ typedef enum { RHT_OCARINA_C_DOWN_BUTTON, RHT_OCARINA_C_LEFT_BUTTON, RHT_OCARINA_C_RIGHT_BUTTON, + RHT_BRONZE_SCALE, RHT_MASK_KEATON, RHT_MASK_SKULL, RHT_MASK_SPOOKY, @@ -5859,9 +6145,9 @@ typedef enum { RHT_MASK_ZORA, RHT_MASK_GERUDO, RHT_MASK_TRUTH, - RHT_BRONZE_SCALE, RHT_CLIMB, RHT_CRAWL, + RHT_ROLL, RHT_SPEAK, RHT_OPEN_CHEST, RHT_FISHING_POLE, @@ -6334,6 +6620,48 @@ typedef enum { RHT_DODONGOS_CAVERN_GRASS, RHT_BOTTOM_OF_THE_WELL_GRASS, RHT_JABU_JABUS_BELLY_GRASS, + + RHT_KF_ROCK, + RHT_LW_BOULDER, + RHT_HC_ROCK, + RHT_HC_BOULDER, + RHT_OGC_BRONZE_BOULDER, + RHT_OGC_SILVER_BOULDER, + RHT_DMC_ROCK, + RHT_DMC_BOULDER, + RHT_DMC_BRONZE_BOULDER, + RHT_GV_SILVER_BOULDER, + RHT_GV_ROCK, + RHT_GV_BOULDER, + RHT_GV_BRONZE_BOULDER, + RHT_HF_SILVER_BOULDER, + RHT_HF_ROCK, + RHT_HF_BOULDER, + RHT_HF_BRONZE_BOULDER, + RHT_KAK_SILVER_BOULDER, + RHT_KAK_ROCK, + RHT_GY_ROCK, + RHT_LA_ROCK, + RHT_ZD_ROCK, + RHT_ZF_BOULDER, + RHT_ZF_SILVER_BOULDER, + RHT_ZR_BOULDER, + RHT_ZR_ROCK, + RHT_DMT_ROCK, + RHT_DMT_BOULDER, + RHT_DMT_BRONZE_BOULDER, + RHT_GC_BOULDER, + RHT_GC_SILVER_BOULDER, + RHT_GC_BRONZE_BOULDER, + RHT_GC_ROCK, + RHT_COLOSSUS_SILVER_BOULDER, + RHT_COLOSSUS_ROCK, + RHT_HC_STORMS_GROTTO_ROCK, + RHT_BOTW_BOULDER, + RHT_DEKU_BOULDER, + RHT_DODONGOS_BOULDER, + RHT_JABU_BOULDER, + RHT_SPIRIT_TEMPLE_BOULDER, // MAX RHT_MAX, } RandomizerHintTextKey; @@ -6462,6 +6790,7 @@ typedef enum { RSK_SHUFFLE_GRAB, RSK_SHUFFLE_CLIMB, RSK_SHUFFLE_CRAWL, + RSK_SHUFFLE_ROLL, RSK_SHUFFLE_OPEN_CHEST, RSK_SHUFFLE_SPEAK, RSK_STARTING_DEKU_SHIELD, @@ -6664,6 +6993,8 @@ typedef enum { RSK_SHUFFLE_SONG_FAIRIES, RSK_LOCK_OVERWORLD_DOORS, RSK_SHUFFLE_GRASS, + RSK_SHUFFLE_ROCKS, + RSK_SHUFFLE_BOULDERS, RSK_ROCS_FEATHER, RSK_MAX } RandomizerSettingKey; @@ -7037,6 +7368,14 @@ typedef enum { RO_SHUFFLE_CRATES_ALL, } RandoOptionShuffleCrates; +// Shuffle Boulder settings (off, dungeons, overworld, all) +typedef enum { + RO_SHUFFLE_BOULDERS_OFF, + RO_SHUFFLE_BOULDERS_DUNGEONS, + RO_SHUFFLE_BOULDERS_OVERWORLD, + RO_SHUFFLE_BOULDERS_ALL, +} RandoOptionShuffleBoulders; + // Link's Pocket Settings (dungeon reward, advancement, anything, nothing) typedef enum { RO_LINKS_POCKET_DUNGEON_REWARD, @@ -7120,6 +7459,11 @@ typedef struct ShopItemIdentity { int32_t itemPrice; } ShopItemIdentity; +typedef struct RockIdentity { + RandomizerInf randomizerInf; + RandomizerCheck randomizerCheck; +} RockIdentity; + typedef enum { TRACKER_WINDOW_FLOATING, TRACKER_WINDOW_WINDOW, diff --git a/soh/soh/Enhancements/randomizer/randomizer_check_tracker.cpp b/soh/soh/Enhancements/randomizer/randomizer_check_tracker.cpp index 13ac143ffbf..be2dbd6e8ca 100644 --- a/soh/soh/Enhancements/randomizer/randomizer_check_tracker.cpp +++ b/soh/soh/Enhancements/randomizer/randomizer_check_tracker.cpp @@ -79,6 +79,9 @@ bool showDungeonGrass; bool showOverworldCrates; bool showDungeonCrates; bool showTrees; +bool showRocks; +bool showOverworldBoulders; +bool showDungeonBoulders; bool showBushes; bool showFrogSongRupees; bool showFountainFairies; @@ -1244,12 +1247,12 @@ void CheckTrackerWindow::DrawElement() { ImGui::EndTable(); // Checks Lead-out ImGui::EndTable(); // Quick Options Lead-out - Trackers::EndFloatWindows(); if (doingCollapseOrExpand) { optCollapseAll = false; optExpandAll = false; } } + Trackers::EndFloatWindows(); } bool UpdateFilters() { @@ -1454,7 +1457,28 @@ void LoadSettings() { showDungeonCrates = false; break; } + showTrees = OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_SHUFFLE_TREES); + + showRocks = OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_SHUFFLE_ROCKS); + switch (OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_SHUFFLE_BOULDERS)) { + case RO_SHUFFLE_BOULDERS_ALL: + showOverworldBoulders = true; + showDungeonBoulders = true; + break; + case RO_SHUFFLE_BOULDERS_OVERWORLD: + showOverworldBoulders = true; + showDungeonBoulders = false; + break; + case RO_SHUFFLE_BOULDERS_DUNGEONS: + showOverworldBoulders = false; + showDungeonBoulders = true; + break; + default: + showOverworldBoulders = false; + showDungeonBoulders = false; + break; + } showBushes = OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_SHUFFLE_BUSHES); } else { // Vanilla showOverworldTokens = true; @@ -1466,6 +1490,9 @@ void LoadSettings() { showOverworldCrates = false; showDungeonCrates = false; showTrees = false; + showRocks = false; + showOverworldBoulders = false; + showDungeonBoulders = false; showBushes = false; } @@ -1583,6 +1610,10 @@ bool IsCheckShuffled(RandomizerCheck rc) { (loc->GetRCType() != RCTYPE_NLTREE || (showTrees && OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_LOGIC_RULES) == RO_LOGIC_NO_LOGIC)) && + (loc->GetRCType() != RCTYPE_ROCK || showRocks) && + (loc->GetRCType() != RCTYPE_BOULDER || + (showOverworldBoulders && RandomizerCheckObjects::AreaIsOverworld(loc->GetArea())) || + (showDungeonBoulders && RandomizerCheckObjects::AreaIsDungeon(loc->GetArea()))) && (loc->GetRCType() != RCTYPE_BUSH || showBushes) && (loc->GetRCType() != RCTYPE_COW || showCows) && (loc->GetRCType() != RCTYPE_FISH || OTRGlobals::Instance->gRandoContext->GetFishsanity()->GetFishLocationIncluded(loc)) && diff --git a/soh/soh/Enhancements/randomizer/randomizer_entrance_tracker.cpp b/soh/soh/Enhancements/randomizer/randomizer_entrance_tracker.cpp index 3277370bace..460b2831a1b 100644 --- a/soh/soh/Enhancements/randomizer/randomizer_entrance_tracker.cpp +++ b/soh/soh/Enhancements/randomizer/randomizer_entrance_tracker.cpp @@ -1067,8 +1067,8 @@ void EntranceTrackerWindow::DrawElement() { } } ImGui::EndChild(); - Trackers::EndFloatWindows(); } + Trackers::EndFloatWindows(); } void EntranceTrackerWindow::InitElement() { diff --git a/soh/soh/Enhancements/randomizer/randomizer_inf.h b/soh/soh/Enhancements/randomizer/randomizer_inf.h index a6489dd403d..2a88ca3acd6 100644 --- a/soh/soh/Enhancements/randomizer/randomizer_inf.h +++ b/soh/soh/Enhancements/randomizer/randomizer_inf.h @@ -1141,6 +1141,7 @@ DEFINE_RAND_INF(RAND_INF_CAUGHT_LOACH) DEFINE_RAND_INF(RAND_INF_CAN_SWIM) DEFINE_RAND_INF(RAND_INF_CAN_CLIMB) DEFINE_RAND_INF(RAND_INF_CAN_CRAWL) +DEFINE_RAND_INF(RAND_INF_CAN_ROLL) DEFINE_RAND_INF(RAND_INF_CAN_GRAB) DEFINE_RAND_INF(RAND_INF_CAN_OPEN_CHEST) DEFINE_RAND_INF(RAND_INF_CAN_SPEAK_DEKU) @@ -2109,6 +2110,288 @@ DEFINE_RAND_INF(RAND_INF_DEKU_TREE_QUEEN_GOHMA_GRASS_6) DEFINE_RAND_INF(RAND_INF_DEKU_TREE_QUEEN_GOHMA_GRASS_7) DEFINE_RAND_INF(RAND_INF_DEKU_TREE_QUEEN_GOHMA_GRASS_8) // End Grass +DEFINE_RAND_INF(RAND_INF_KF_CIRCLE_ROCK_1) +DEFINE_RAND_INF(RAND_INF_KF_CIRCLE_ROCK_2) +DEFINE_RAND_INF(RAND_INF_KF_CIRCLE_ROCK_3) +DEFINE_RAND_INF(RAND_INF_KF_CIRCLE_ROCK_4) +DEFINE_RAND_INF(RAND_INF_KF_CIRCLE_ROCK_5) +DEFINE_RAND_INF(RAND_INF_KF_CIRCLE_ROCK_6) +DEFINE_RAND_INF(RAND_INF_KF_CIRCLE_ROCK_7) +DEFINE_RAND_INF(RAND_INF_KF_CIRCLE_ROCK_8) +DEFINE_RAND_INF(RAND_INF_KF_ROCK_BY_SARIAS_HOUSE) +DEFINE_RAND_INF(RAND_INF_KF_ROCK_BEHIND_SARIAS_HOUSE) +DEFINE_RAND_INF(RAND_INF_KF_ROCK_BY_MIDOS_HOUSE) +DEFINE_RAND_INF(RAND_INF_KF_ROCK_BY_KNOW_IT_ALLS_HOUSE) +DEFINE_RAND_INF(RAND_INF_LW_BOULDER_BY_GORON_CITY) +DEFINE_RAND_INF(RAND_INF_LW_BOULDER_BY_SACRED_FOREST_MEADOW) +DEFINE_RAND_INF(RAND_INF_LW_RUPEE_BOULDER) +DEFINE_RAND_INF(RAND_INF_HC_ROCK_1) +DEFINE_RAND_INF(RAND_INF_HC_ROCK_2) +DEFINE_RAND_INF(RAND_INF_HC_ROCK_3) +DEFINE_RAND_INF(RAND_INF_HC_BOULDER) +DEFINE_RAND_INF(RAND_INF_OGC_BRONZE_BOULDER_1) +DEFINE_RAND_INF(RAND_INF_OGC_BRONZE_BOULDER_2) +DEFINE_RAND_INF(RAND_INF_OGC_BRONZE_BOULDER_3) +DEFINE_RAND_INF(RAND_INF_OGC_SILVER_BOULDER_1) +DEFINE_RAND_INF(RAND_INF_OGC_SILVER_BOULDER_2) +DEFINE_RAND_INF(RAND_INF_OGC_SILVER_BOULDER_3) +DEFINE_RAND_INF(RAND_INF_OGC_SILVER_BOULDER_4) +DEFINE_RAND_INF(RAND_INF_DMC_CIRCLE_ROCK_1) +DEFINE_RAND_INF(RAND_INF_DMC_CIRCLE_ROCK_2) +DEFINE_RAND_INF(RAND_INF_DMC_CIRCLE_ROCK_3) +DEFINE_RAND_INF(RAND_INF_DMC_CIRCLE_ROCK_4) +DEFINE_RAND_INF(RAND_INF_DMC_CIRCLE_ROCK_5) +DEFINE_RAND_INF(RAND_INF_DMC_CIRCLE_ROCK_6) +DEFINE_RAND_INF(RAND_INF_DMC_CIRCLE_ROCK_7) +DEFINE_RAND_INF(RAND_INF_DMC_CIRCLE_ROCK_8) +DEFINE_RAND_INF(RAND_INF_DMC_ROCK_BY_FIRE_TEMPLE_1) +DEFINE_RAND_INF(RAND_INF_DMC_ROCK_BY_FIRE_TEMPLE_2) +DEFINE_RAND_INF(RAND_INF_DMC_ROCK_BY_FIRE_TEMPLE_3) +DEFINE_RAND_INF(RAND_INF_DMC_ROCK_BY_FIRE_TEMPLE_4) +DEFINE_RAND_INF(RAND_INF_DMC_ROCK_BY_FIRE_TEMPLE_5) +DEFINE_RAND_INF(RAND_INF_DMC_GOSSIP_ROCK_1) +DEFINE_RAND_INF(RAND_INF_DMC_GOSSIP_ROCK_2) +DEFINE_RAND_INF(RAND_INF_DMC_BOULDER_1) +DEFINE_RAND_INF(RAND_INF_DMC_BOULDER_2) +DEFINE_RAND_INF(RAND_INF_DMC_BOULDER_3) +DEFINE_RAND_INF(RAND_INF_DMC_BRONZE_BOULDER_1) +DEFINE_RAND_INF(RAND_INF_DMC_BRONZE_BOULDER_2) +DEFINE_RAND_INF(RAND_INF_DMC_BRONZE_BOULDER_3) +DEFINE_RAND_INF(RAND_INF_DMC_BRONZE_BOULDER_4) +DEFINE_RAND_INF(RAND_INF_GV_SILVER_BOULDER) +DEFINE_RAND_INF(RAND_INF_GV_ROCK_1) +DEFINE_RAND_INF(RAND_INF_GV_ROCK_2) +DEFINE_RAND_INF(RAND_INF_GV_ROCK_3) +DEFINE_RAND_INF(RAND_INF_GV_UNDERWATER_ROCK_1) +DEFINE_RAND_INF(RAND_INF_GV_UNDERWATER_ROCK_2) +DEFINE_RAND_INF(RAND_INF_GV_UNDERWATER_ROCK_3) +DEFINE_RAND_INF(RAND_INF_GV_ROCK_ACROSS_BRIDGE_1) +DEFINE_RAND_INF(RAND_INF_GV_ROCK_ACROSS_BRIDGE_2) +DEFINE_RAND_INF(RAND_INF_GV_ROCK_ACROSS_BRIDGE_3) +DEFINE_RAND_INF(RAND_INF_GV_ROCK_ACROSS_BRIDGE_4) +DEFINE_RAND_INF(RAND_INF_GV_BOULDER_1) +DEFINE_RAND_INF(RAND_INF_GV_BOULDER_2) +DEFINE_RAND_INF(RAND_INF_GV_BOULDER_ACROSS_BRIDGE) +DEFINE_RAND_INF(RAND_INF_GV_BRONZE_BOULDER_1) +DEFINE_RAND_INF(RAND_INF_GV_BRONZE_BOULDER_2) +DEFINE_RAND_INF(RAND_INF_GV_BRONZE_BOULDER_ACROSS_BRIDGE_1) +DEFINE_RAND_INF(RAND_INF_GV_BRONZE_BOULDER_ACROSS_BRIDGE_2) +DEFINE_RAND_INF(RAND_INF_GV_BRONZE_BOULDER_ACROSS_BRIDGE_3) +DEFINE_RAND_INF(RAND_INF_GV_BRONZE_BOULDER_ACROSS_BRIDGE_4) +DEFINE_RAND_INF(RAND_INF_GV_BRONZE_BOULDER_ACROSS_BRIDGE_5) +DEFINE_RAND_INF(RAND_INF_GV_BRONZE_BOULDER_ACROSS_BRIDGE_6) +DEFINE_RAND_INF(RAND_INF_HF_SILVER_BOULDER) +DEFINE_RAND_INF(RAND_INF_HF_ROCK_1) +DEFINE_RAND_INF(RAND_INF_HF_ROCK_2) +DEFINE_RAND_INF(RAND_INF_HF_ROCK_3) +DEFINE_RAND_INF(RAND_INF_HF_ROCK_4) +DEFINE_RAND_INF(RAND_INF_HF_ROCK_5) +DEFINE_RAND_INF(RAND_INF_HF_ROCK_6) +DEFINE_RAND_INF(RAND_INF_HF_ROCK_7) +DEFINE_RAND_INF(RAND_INF_HF_ROCK_8) +DEFINE_RAND_INF(RAND_INF_HF_BOULDER_NORTH) +DEFINE_RAND_INF(RAND_INF_HF_BOULDER_BY_MARKET) +DEFINE_RAND_INF(RAND_INF_HF_BOULDER_SOUTH) +DEFINE_RAND_INF(RAND_INF_HF_BRONZE_BOULDER_1) +DEFINE_RAND_INF(RAND_INF_HF_BRONZE_BOULDER_2) +DEFINE_RAND_INF(RAND_INF_HF_BRONZE_BOULDER_3) +DEFINE_RAND_INF(RAND_INF_HF_BRONZE_BOULDER_4) +DEFINE_RAND_INF(RAND_INF_KAK_SILVER_BOULDER) +DEFINE_RAND_INF(RAND_INF_KAK_ROCK_1) +DEFINE_RAND_INF(RAND_INF_KAK_ROCK_2) +DEFINE_RAND_INF(RAND_INF_GY_ROCK) +DEFINE_RAND_INF(RAND_INF_LA_ROCK) +DEFINE_RAND_INF(RAND_INF_ZD_CIRCLE_ROCK_1) +DEFINE_RAND_INF(RAND_INF_ZD_CIRCLE_ROCK_2) +DEFINE_RAND_INF(RAND_INF_ZD_CIRCLE_ROCK_3) +DEFINE_RAND_INF(RAND_INF_ZD_CIRCLE_ROCK_4) +DEFINE_RAND_INF(RAND_INF_ZD_CIRCLE_ROCK_5) +DEFINE_RAND_INF(RAND_INF_ZD_CIRCLE_ROCK_6) +DEFINE_RAND_INF(RAND_INF_ZD_CIRCLE_ROCK_7) +DEFINE_RAND_INF(RAND_INF_ZD_CIRCLE_ROCK_8) +DEFINE_RAND_INF(RAND_INF_ZF_BOULDER) +DEFINE_RAND_INF(RAND_INF_ZF_SILVER_BOULDER) +DEFINE_RAND_INF(RAND_INF_ZF_UNDERGROUND_BOULDER) +DEFINE_RAND_INF(RAND_INF_ZR_BOULDER_1) +DEFINE_RAND_INF(RAND_INF_ZR_BOULDER_2) +DEFINE_RAND_INF(RAND_INF_ZR_BOULDER_3) +DEFINE_RAND_INF(RAND_INF_ZR_BOULDER_4) +DEFINE_RAND_INF(RAND_INF_ZR_CIRCLE_ROCK_1) +DEFINE_RAND_INF(RAND_INF_ZR_CIRCLE_ROCK_2) +DEFINE_RAND_INF(RAND_INF_ZR_CIRCLE_ROCK_3) +DEFINE_RAND_INF(RAND_INF_ZR_CIRCLE_ROCK_4) +DEFINE_RAND_INF(RAND_INF_ZR_CIRCLE_ROCK_5) +DEFINE_RAND_INF(RAND_INF_ZR_CIRCLE_ROCK_6) +DEFINE_RAND_INF(RAND_INF_ZR_CIRCLE_ROCK_7) +DEFINE_RAND_INF(RAND_INF_ZR_CIRCLE_ROCK_8) +DEFINE_RAND_INF(RAND_INF_ZR_UPPER_CIRCLE_BOULDER) +DEFINE_RAND_INF(RAND_INF_ZR_UPPER_CIRCLE_ROCK_1) +DEFINE_RAND_INF(RAND_INF_ZR_UPPER_CIRCLE_ROCK_2) +DEFINE_RAND_INF(RAND_INF_ZR_UPPER_CIRCLE_ROCK_3) +DEFINE_RAND_INF(RAND_INF_ZR_UPPER_CIRCLE_ROCK_4) +DEFINE_RAND_INF(RAND_INF_ZR_UPPER_CIRCLE_ROCK_5) +DEFINE_RAND_INF(RAND_INF_ZR_UPPER_CIRCLE_ROCK_6) +DEFINE_RAND_INF(RAND_INF_ZR_UPPER_CIRCLE_ROCK_7) +DEFINE_RAND_INF(RAND_INF_ZR_UPPER_CIRCLE_ROCK_8) +DEFINE_RAND_INF(RAND_INF_ZR_ROCK) +DEFINE_RAND_INF(RAND_INF_ZR_UNDERWATER_ROCK_1) +DEFINE_RAND_INF(RAND_INF_ZR_UNDERWATER_ROCK_2) +DEFINE_RAND_INF(RAND_INF_ZR_UNDERWATER_ROCK_3) +DEFINE_RAND_INF(RAND_INF_ZR_UNDERWATER_ROCK_4) +DEFINE_RAND_INF(RAND_INF_DMT_ROCK_1) +DEFINE_RAND_INF(RAND_INF_DMT_ROCK_2) +DEFINE_RAND_INF(RAND_INF_DMT_ROCK_3) +DEFINE_RAND_INF(RAND_INF_DMT_ROCK_4) +DEFINE_RAND_INF(RAND_INF_DMT_ROCK_5) +DEFINE_RAND_INF(RAND_INF_DMT_SUMMIT_ROCK) +DEFINE_RAND_INF(RAND_INF_DMT_CIRCLE_ROCK_1) +DEFINE_RAND_INF(RAND_INF_DMT_CIRCLE_ROCK_2) +DEFINE_RAND_INF(RAND_INF_DMT_CIRCLE_ROCK_3) +DEFINE_RAND_INF(RAND_INF_DMT_CIRCLE_ROCK_4) +DEFINE_RAND_INF(RAND_INF_DMT_CIRCLE_ROCK_5) +DEFINE_RAND_INF(RAND_INF_DMT_CIRCLE_ROCK_6) +DEFINE_RAND_INF(RAND_INF_DMT_CIRCLE_ROCK_7) +DEFINE_RAND_INF(RAND_INF_DMT_CIRCLE_ROCK_8) +DEFINE_RAND_INF(RAND_INF_DMT_BOULDER_1) +DEFINE_RAND_INF(RAND_INF_DMT_BOULDER_2) +DEFINE_RAND_INF(RAND_INF_DMT_BOULDER_3) +DEFINE_RAND_INF(RAND_INF_DMT_COW_BOULDER) +DEFINE_RAND_INF(RAND_INF_DMT_BRONZE_BOULDER_1) +DEFINE_RAND_INF(RAND_INF_DMT_BRONZE_BOULDER_2) +DEFINE_RAND_INF(RAND_INF_DMT_BRONZE_BOULDER_3) +DEFINE_RAND_INF(RAND_INF_DMT_BRONZE_BOULDER_4) +DEFINE_RAND_INF(RAND_INF_DMT_BRONZE_BOULDER_5) +DEFINE_RAND_INF(RAND_INF_DMT_BRONZE_BOULDER_6) +DEFINE_RAND_INF(RAND_INF_DMT_BRONZE_BOULDER_7) +DEFINE_RAND_INF(RAND_INF_DMT_BRONZE_BOULDER_8) +DEFINE_RAND_INF(RAND_INF_DMT_BRONZE_BOULDER_9) +DEFINE_RAND_INF(RAND_INF_DMT_BRONZE_BOULDER_10) +DEFINE_RAND_INF(RAND_INF_DMT_BRONZE_BOULDER_11) +DEFINE_RAND_INF(RAND_INF_GC_LW_BOULDER_1) +DEFINE_RAND_INF(RAND_INF_GC_LW_BOULDER_2) +DEFINE_RAND_INF(RAND_INF_GC_LW_BOULDER_3) +DEFINE_RAND_INF(RAND_INF_GC_ENTRANCE_BOULDER_1) +DEFINE_RAND_INF(RAND_INF_GC_ENTRANCE_BOULDER_2) +DEFINE_RAND_INF(RAND_INF_GC_ENTRANCE_BOULDER_3) +DEFINE_RAND_INF(RAND_INF_GC_MAZE_SILVER_BOULDER_1) +DEFINE_RAND_INF(RAND_INF_GC_MAZE_SILVER_BOULDER_2) +DEFINE_RAND_INF(RAND_INF_GC_MAZE_SILVER_BOULDER_3) +DEFINE_RAND_INF(RAND_INF_GC_MAZE_SILVER_BOULDER_4) +DEFINE_RAND_INF(RAND_INF_GC_MAZE_SILVER_BOULDER_5) +DEFINE_RAND_INF(RAND_INF_GC_MAZE_SILVER_BOULDER_6) +DEFINE_RAND_INF(RAND_INF_GC_MAZE_SILVER_BOULDER_7) +DEFINE_RAND_INF(RAND_INF_GC_MAZE_SILVER_BOULDER_8) +DEFINE_RAND_INF(RAND_INF_GC_MAZE_SILVER_BOULDER_9) +DEFINE_RAND_INF(RAND_INF_GC_MAZE_SILVER_BOULDER_10) +DEFINE_RAND_INF(RAND_INF_GC_MAZE_SILVER_BOULDER_11) +DEFINE_RAND_INF(RAND_INF_GC_MAZE_SILVER_BOULDER_12) +DEFINE_RAND_INF(RAND_INF_GC_MAZE_SILVER_BOULDER_13) +DEFINE_RAND_INF(RAND_INF_GC_MAZE_SILVER_BOULDER_14) +DEFINE_RAND_INF(RAND_INF_GC_MAZE_SILVER_BOULDER_15) +DEFINE_RAND_INF(RAND_INF_GC_MAZE_SILVER_BOULDER_16) +DEFINE_RAND_INF(RAND_INF_GC_MAZE_SILVER_BOULDER_17) +DEFINE_RAND_INF(RAND_INF_GC_MAZE_SILVER_BOULDER_18) +DEFINE_RAND_INF(RAND_INF_GC_MAZE_SILVER_BOULDER_19) +DEFINE_RAND_INF(RAND_INF_GC_MAZE_SILVER_BOULDER_20) +DEFINE_RAND_INF(RAND_INF_GC_MAZE_SILVER_BOULDER_21) +DEFINE_RAND_INF(RAND_INF_GC_MAZE_SILVER_BOULDER_22) +DEFINE_RAND_INF(RAND_INF_GC_MAZE_SILVER_BOULDER_23) +DEFINE_RAND_INF(RAND_INF_GC_MAZE_SILVER_BOULDER_24) +DEFINE_RAND_INF(RAND_INF_GC_MAZE_SILVER_BOULDER_25) +DEFINE_RAND_INF(RAND_INF_GC_MAZE_SILVER_BOULDER_26) +DEFINE_RAND_INF(RAND_INF_GC_MAZE_SILVER_BOULDER_27) +DEFINE_RAND_INF(RAND_INF_GC_MAZE_SILVER_BOULDER_28) +DEFINE_RAND_INF(RAND_INF_GC_MAZE_SILVER_BOULDER_29) +DEFINE_RAND_INF(RAND_INF_GC_MAZE_BOULDER_1) +DEFINE_RAND_INF(RAND_INF_GC_MAZE_BOULDER_2) +DEFINE_RAND_INF(RAND_INF_GC_MAZE_BOULDER_3) +DEFINE_RAND_INF(RAND_INF_GC_MAZE_BOULDER_4) +DEFINE_RAND_INF(RAND_INF_GC_MAZE_BOULDER_5) +DEFINE_RAND_INF(RAND_INF_GC_MAZE_BOULDER_6) +DEFINE_RAND_INF(RAND_INF_GC_MAZE_BOULDER_7) +DEFINE_RAND_INF(RAND_INF_GC_MAZE_BOULDER_8) +DEFINE_RAND_INF(RAND_INF_GC_MAZE_BOULDER_9) +DEFINE_RAND_INF(RAND_INF_GC_MAZE_BOULDER_10) +DEFINE_RAND_INF(RAND_INF_GC_MAZE_BRONZE_BOULDER_1) +DEFINE_RAND_INF(RAND_INF_GC_MAZE_BRONZE_BOULDER_2) +DEFINE_RAND_INF(RAND_INF_GC_MAZE_BRONZE_BOULDER_3) +DEFINE_RAND_INF(RAND_INF_GC_MAZE_BRONZE_BOULDER_4) +DEFINE_RAND_INF(RAND_INF_GC_MAZE_BRONZE_BOULDER_5) +DEFINE_RAND_INF(RAND_INF_GC_MAZE_ROCK) +DEFINE_RAND_INF(RAND_INF_COLOSSUS_SILVER_BOULDER) +DEFINE_RAND_INF(RAND_INF_COLOSSUS_ROCK) +DEFINE_RAND_INF(RAND_INF_COLOSSUS_CIRCLE_1_ROCK_1) +DEFINE_RAND_INF(RAND_INF_COLOSSUS_CIRCLE_1_ROCK_2) +DEFINE_RAND_INF(RAND_INF_COLOSSUS_CIRCLE_1_ROCK_3) +DEFINE_RAND_INF(RAND_INF_COLOSSUS_CIRCLE_1_ROCK_4) +DEFINE_RAND_INF(RAND_INF_COLOSSUS_CIRCLE_1_ROCK_5) +DEFINE_RAND_INF(RAND_INF_COLOSSUS_CIRCLE_1_ROCK_6) +DEFINE_RAND_INF(RAND_INF_COLOSSUS_CIRCLE_1_ROCK_7) +DEFINE_RAND_INF(RAND_INF_COLOSSUS_CIRCLE_1_ROCK_8) +DEFINE_RAND_INF(RAND_INF_COLOSSUS_CIRCLE_2_ROCK_1) +DEFINE_RAND_INF(RAND_INF_COLOSSUS_CIRCLE_2_ROCK_2) +DEFINE_RAND_INF(RAND_INF_COLOSSUS_CIRCLE_2_ROCK_3) +DEFINE_RAND_INF(RAND_INF_COLOSSUS_CIRCLE_2_ROCK_4) +DEFINE_RAND_INF(RAND_INF_COLOSSUS_CIRCLE_2_ROCK_5) +DEFINE_RAND_INF(RAND_INF_COLOSSUS_CIRCLE_2_ROCK_6) +DEFINE_RAND_INF(RAND_INF_COLOSSUS_CIRCLE_2_ROCK_7) +DEFINE_RAND_INF(RAND_INF_COLOSSUS_CIRCLE_2_ROCK_8) +DEFINE_RAND_INF(RAND_INF_HC_STORMS_GROTTO_ROCK_1) +DEFINE_RAND_INF(RAND_INF_HC_STORMS_GROTTO_ROCK_2) +DEFINE_RAND_INF(RAND_INF_HC_STORMS_GROTTO_ROCK_3) +DEFINE_RAND_INF(RAND_INF_HC_STORMS_GROTTO_ROCK_4) +DEFINE_RAND_INF(RAND_INF_HC_STORMS_GROTTO_ROCK_5) +DEFINE_RAND_INF(RAND_INF_HC_STORMS_GROTTO_ROCK_6) +DEFINE_RAND_INF(RAND_INF_HC_STORMS_GROTTO_ROCK_7) +DEFINE_RAND_INF(RAND_INF_HC_STORMS_GROTTO_ROCK_8) +DEFINE_RAND_INF(RAND_INF_BOTW_BOULDER_1) +DEFINE_RAND_INF(RAND_INF_BOTW_BOULDER_2) +DEFINE_RAND_INF(RAND_INF_BOTW_BOULDER_3) +DEFINE_RAND_INF(RAND_INF_BOTW_BOULDER_4) +DEFINE_RAND_INF(RAND_INF_BOTW_BOULDER_5) +DEFINE_RAND_INF(RAND_INF_BOTW_BOULDER_6) +DEFINE_RAND_INF(RAND_INF_DEKU_TREE_MQ_BOULDER_1) +DEFINE_RAND_INF(RAND_INF_DEKU_TREE_MQ_BOULDER_2) +DEFINE_RAND_INF(RAND_INF_DEKU_TREE_MQ_BOULDER_3) +DEFINE_RAND_INF(RAND_INF_DODONGOS_CAVERN_MQ_LOBBY_BOULDER_1) +DEFINE_RAND_INF(RAND_INF_DODONGOS_CAVERN_MQ_LOBBY_BOULDER_2) +DEFINE_RAND_INF(RAND_INF_DODONGOS_CAVERN_MQ_MOUTH_SIDE_BRIDGE_BOULDER_1) +DEFINE_RAND_INF(RAND_INF_DODONGOS_CAVERN_MQ_MOUTH_SIDE_BRIDGE_BOULDER_2) +DEFINE_RAND_INF(RAND_INF_DODONGOS_CAVERN_MQ_MOUTH_SIDE_BRIDGE_BOULDER_3) +DEFINE_RAND_INF(RAND_INF_DODONGOS_CAVERN_MQ_RIGHT_SIDE_BOULDER_1) +DEFINE_RAND_INF(RAND_INF_DODONGOS_CAVERN_MQ_RIGHT_SIDE_BOULDER_2) +DEFINE_RAND_INF(RAND_INF_DODONGOS_CAVERN_MQ_LIZALFOS_ROOM_BOULDER_1) +DEFINE_RAND_INF(RAND_INF_DODONGOS_CAVERN_MQ_LIZALFOS_ROOM_BOULDER_2) +DEFINE_RAND_INF(RAND_INF_DODONGOS_CAVERN_MQ_LIZALFOS_ROOM_BOULDER_3) +DEFINE_RAND_INF(RAND_INF_DODONGOS_CAVERN_MQ_LIZALFOS_ROOM_BOULDER_4) +DEFINE_RAND_INF(RAND_INF_DODONGOS_CAVERN_MQ_LIZALFOS_ROOM_BOULDER_5) +DEFINE_RAND_INF(RAND_INF_DODONGOS_CAVERN_MQ_LIZALFOS_ROOM_BOULDER_6) +DEFINE_RAND_INF(RAND_INF_DODONGOS_CAVERN_MQ_LIZALFOS_ROOM_BOULDER_7) +DEFINE_RAND_INF(RAND_INF_DODONGOS_CAVERN_MQ_LIZALFOS_ROOM_BOULDER_8) +DEFINE_RAND_INF(RAND_INF_DODONGOS_CAVERN_MQ_LIZALFOS_ROOM_BOULDER_9) +DEFINE_RAND_INF(RAND_INF_DODONGOS_CAVERN_MQ_LIZALFOS_ROOM_BOULDER_10) +DEFINE_RAND_INF(RAND_INF_DODONGOS_CAVERN_MQ_LIZALFOS_ROOM_BOULDER_11) +DEFINE_RAND_INF(RAND_INF_DODONGOS_CAVERN_MQ_LIZALFOS_ROOM_BOULDER_12) +DEFINE_RAND_INF(RAND_INF_DODONGOS_CAVERN_MQ_TWO_FLAMES_BOULDER) +DEFINE_RAND_INF(RAND_INF_JABU_JABUS_BELLY_MQ_ENTRANCE_BOULDER) +DEFINE_RAND_INF(RAND_INF_JABU_JABUS_BELLY_MQ_HOLES_ROOM_BOULDER_1) +DEFINE_RAND_INF(RAND_INF_JABU_JABUS_BELLY_MQ_HOLES_ROOM_BOULDER_2) +DEFINE_RAND_INF(RAND_INF_JABU_JABUS_BELLY_MQ_HOLES_ROOM_WALL_BOULDER_1) +DEFINE_RAND_INF(RAND_INF_JABU_JABUS_BELLY_MQ_HOLES_ROOM_WALL_BOULDER_2) +DEFINE_RAND_INF(RAND_INF_JABU_JABUS_BELLY_MQ_HOLES_ROOM_WALL_BOULDER_3) +DEFINE_RAND_INF(RAND_INF_JABU_JABUS_BELLY_MQ_FORKED_CORRIDOR_BOULDER_1) +DEFINE_RAND_INF(RAND_INF_JABU_JABUS_BELLY_MQ_FORKED_CORRIDOR_BOULDER_2) +DEFINE_RAND_INF(RAND_INF_JABU_JABUS_BELLY_MQ_TAILPASARAN_BOULDER) +DEFINE_RAND_INF(RAND_INF_JABU_JABUS_BELLY_MQ_TAILPASARAN_WALL_BOULDER) +DEFINE_RAND_INF(RAND_INF_SPIRIT_TEMPLE_MQ_ENTRANCE_BOULDER_1) +DEFINE_RAND_INF(RAND_INF_SPIRIT_TEMPLE_MQ_ENTRANCE_BOULDER_2) +DEFINE_RAND_INF(RAND_INF_SPIRIT_TEMPLE_MQ_ENTRANCE_BOULDER_3) +DEFINE_RAND_INF(RAND_INF_SPIRIT_TEMPLE_MQ_ENTRANCE_CEILING_BOULDER) +DEFINE_RAND_INF(RAND_INF_SPIRIT_TEMPLE_MQ_EARLY_ADULT_BOULDER) +DEFINE_RAND_INF(RAND_INF_BOTW_MQ_BOULDER_1) +DEFINE_RAND_INF(RAND_INF_BOTW_MQ_BOULDER_2) +DEFINE_RAND_INF(RAND_INF_BOTW_MQ_BOULDER_3) + DEFINE_RAND_INF(RAND_INF_OBTAINED_RUTOS_LETTER) DEFINE_RAND_INF(RAND_INF_OBTAINED_NAYRUS_LOVE) DEFINE_RAND_INF(RAND_INF_OBTAINED_ROCS_FEATHER) diff --git a/soh/soh/Enhancements/randomizer/randomizer_item_tracker.cpp b/soh/soh/Enhancements/randomizer/randomizer_item_tracker.cpp index 1dabde2631c..9d830d99262 100644 --- a/soh/soh/Enhancements/randomizer/randomizer_item_tracker.cpp +++ b/soh/soh/Enhancements/randomizer/randomizer_item_tracker.cpp @@ -154,6 +154,10 @@ std::vector climbItems = { ITEM_TRACKER_ITEM(RG_CLIMB, 0, DrawItem), }; +std::vector rollItems = { + ITEM_TRACKER_ITEM(RG_ROLL, 0, DrawItem), +}; + std::vector grabItems = { ITEM_TRACKER_ITEM(RG_POWER_BRACELET, 0, DrawItem), }; @@ -1185,6 +1189,11 @@ void DrawItem(ItemTrackerItem item) { hasItem = Flags_GetRandomizerInf(RAND_INF_CAN_CLIMB); itemName = "Climb"; break; + case RG_ROLL: + actualItemId = item.id; + hasItem = Flags_GetRandomizerInf(RAND_INF_CAN_ROLL); + itemName = "Roll"; + break; case RG_POWER_BRACELET: actualItemId = item.id; hasItem = Flags_GetRandomizerInf(RAND_INF_CAN_GRAB); @@ -1631,6 +1640,9 @@ void UpdateVectors() { if (IS_RANDO && RAND_GET_OPTION(RSK_SHUFFLE_CLIMB)) { mainWindowItems.insert(mainWindowItems.end(), climbItems.begin(), climbItems.end()); } + if (IS_RANDO && RAND_GET_OPTION(RSK_SHUFFLE_ROLL)) { + mainWindowItems.insert(mainWindowItems.end(), rollItems.begin(), rollItems.end()); + } if (IS_RANDO && RAND_GET_OPTION(RSK_SHUFFLE_CRAWL)) { mainWindowItems.insert(mainWindowItems.end(), crawlItems.begin(), crawlItems.end()); } @@ -2367,6 +2379,7 @@ void RegisterItemTrackerWidgets() { .ComboMap(extendedDisplayTypes)) .Callback([](WidgetInfo& info) { shouldUpdateVectors = true; }); ; + SohGui::mSohMenu->AddSearchWidget( { fishingPoleTracking, "Randomizer", "Item Tracker", "General Settings", "icon" }); diff --git a/soh/soh/Enhancements/randomizer/roll_animation_data.h b/soh/soh/Enhancements/randomizer/roll_animation_data.h new file mode 100644 index 00000000000..5d0700721c0 --- /dev/null +++ b/soh/soh/Enhancements/randomizer/roll_animation_data.h @@ -0,0 +1,348 @@ +#ifndef ROLL_ANIMATION_DATA_H +#define ROLL_ANIMATION_DATA_H + +#include "z64.h" + +#define ROLL_ANIMATION_FRAMES 20 +#define ROLL_ANIMATION_LIMBS 22 + +static const Vec3s rollAnimationData[ROLL_ANIMATION_FRAMES][ROLL_ANIMATION_LIMBS] = { + { + // Frame 0 + { 74, 3528, -37 }, + { 0, 0, 0 }, + { -16384, -626, -16384 }, + { 0, 0, 0 }, + { 135, 5446, -5887 }, + { 0, 0, 23451 }, + { 2115, 1887, -20292 }, + { 1024, -219, -1846 }, + { 0, 0, 5914 }, + { -443, -1625, -21253 }, + { 16384, 417, 16384 }, + { 476, -93, 19351 }, + { 0, 0, 23344 }, + { 0, 0, 0 }, + { -21137, -12435, -10526 }, + { 0, 0, -6675 }, + { -36, -503, -16171 }, + { 12851, 7298, -17081 }, + { 0, 0, -19713 }, + { 4373, 5305, -15750 }, + { -16384, 27240, -730 }, + { 0, 0, 0 }, + }, + { + // Frame 1 + { 54, 3227, -89 }, + { 2313, 0, 0 }, + { -16384, -685, -16384 }, + { 0, 0, 0 }, + { -152, 5099, -11115 }, + { 0, 0, 24427 }, + { 2059, 1815, -21046 }, + { -59, -710, -6843 }, + { 0, 0, 10860 }, + { -979, -1386, -22412 }, + { 16183, -133, 16490 }, + { 503, -59, 18352 }, + { 0, 0, 25530 }, + { 0, 0, 0 }, + { -20393, -12323, -12080 }, + { 0, 0, -6726 }, + { -25, -562, -16150 }, + { 14095, 8887, -16891 }, + { 0, 0, -18784 }, + { 3073, 5837, -17586 }, + { -15392, 27325, 1213 }, + { 0, 0, 0 }, + }, + { + // Frame 2 + { -25, 2218, -133 }, + { 7607, 0, 0 }, + { -16384, -781, -16384 }, + { 0, 0, 0 }, + { -654, 1069, -20519 }, + { 0, 0, 20760 }, + { 1304, 1666, -23774 }, + { -518, -3910, -15614 }, + { 0, 0, 22754 }, + { -1707, -1918, -22925 }, + { 16384, -4331, 16384 }, + { 641, 74, 13206 }, + { 0, 0, 30948 }, + { 0, 0, 0 }, + { -15708, -11590, -21423 }, + { 0, 0, -6949 }, + { 37, -880, -16032 }, + { -12778, 15014, 15677 }, + { 0, 0, -13974 }, + { -4182, 8702, -27734 }, + { -13006, 28312, 6371 }, + { 0, 0, 0 }, + }, + { + // Frame 3 + { -57, 2670, 558 }, { 13602, 0, 0 }, + { -16384, 0, -16384 }, { 0, 0, 0 }, + { 1852, 198, -7548 }, { 0, 0, 1654 }, + { 1472, 2843, -23780 }, { -2685, -3676, -6545 }, + { 0, 0, 15549 }, { 1676, -2089, -20933 }, + { -1427, -19182, -27019 }, { 698, -257, 10968 }, + { 0, 0, 18514 }, { 0, 0, 0 }, + { 23192, -22237, 548 }, { 0, 0, -6929 }, + { 86, -1131, -15938 }, { -11355, 7097, 10885 }, + { 0, 0, -11056 }, { -10661, 10872, 29098 }, + { -15580, 27296, 800 }, { 0, 0, 0 }, + }, + { + // Frame 4 + { -60, 2207, 382 }, { 20068, 0, 0 }, + { -16384, 2162, -16384 }, { 0, 0, 0 }, + { 219, 581, -17012 }, { 0, 0, 16199 }, + { 1446, 2552, -20834 }, { -1193, -3974, -12795 }, + { 0, 0, 22901 }, { 1355, -1424, -20722 }, + { -24738, -12007, -7558 }, { 462, -469, 19859 }, + { 0, 0, 17568 }, { 0, 0, 0 }, + { -1152, -8811, 22716 }, { 0, 0, -5124 }, + { 43, -913, -16019 }, { -2615, 21391, 18299 }, + { 0, 0, -20972 }, { -7167, 7353, -29571 }, + { -16740, 27249, -1447 }, { 0, 0, 0 }, + }, + { + // Frame 5 + { -60, 1477, 314 }, { 26774, 0, 0 }, + { -16384, 4992, -16384 }, { 0, 0, 0 }, + { 1331, 909, -8175 }, { 0, 0, 8190 }, + { 538, 2622, -21124 }, { -443, -603, -1212 }, + { 0, 0, 24711 }, { 491, -584, -20713 }, + { -21267, -11295, -7882 }, { 552, 479, 16219 }, + { 0, 0, 17341 }, { 0, 0, 0 }, + { 2866, -7762, 19771 }, { 0, 0, -3812 }, + { -416, 862, -16656 }, { -2940, 16895, 20702 }, + { 0, 0, -18661 }, { -5100, 10643, -25824 }, + { -15495, 27304, 1032 }, { 0, 0, 0 }, + }, + { + // Frame 6 + { -60, 771, 241 }, { -32044, 0, 0 }, { -16384, 7684, -16384 }, { 0, 0, 0 }, + { -27, 459, -14461 }, { 0, 0, 13541 }, { 63, 2434, -21507 }, { 140, -3557, -8362 }, + { 0, 0, 25043 }, { -525, 149, -20932 }, { -18194, -11230, -7652 }, { 519, 2089, 15610 }, + { 0, 0, 17631 }, { 0, 0, 0 }, { 3504, -7332, 22086 }, { 0, 0, -4207 }, + { -1489, 5198, -18222 }, { 967, 12936, 27541 }, { 0, 0, -17131 }, { -2949, 6188, -22075 }, + { -16864, 27258, -1679 }, { 0, 0, 0 }, + }, + { + // Frame 7 + { -60, 511, -4 }, { -25546, 0, 0 }, + { -16384, 8878, -16384 }, { 0, 0, 0 }, + { -799, 63, -16740 }, { 0, 0, 14954 }, + { 943, 1296, -21262 }, { 1564, -3136, -16443 }, + { 0, 0, 25526 }, { -1303, 490, -21402 }, + { -18554, -11994, -7123 }, { 464, 3612, 15275 }, + { 0, 0, 18235 }, { 0, 0, 0 }, + { 3231, -6977, 25545 }, { 0, 0, -4847 }, + { -321, 5196, -18440 }, { 2710, 9642, 31101 }, + { 0, 0, -15600 }, { -985, 4840, -20355 }, + { -16899, 27261, -1747 }, { 0, 0, 0 }, + }, + { + // Frame 8 + { -60, 771, -444 }, { -19497, 0, 0 }, + { -16384, 6684, -16384 }, { 0, 0, 0 }, + { -2556, 1051, -17674 }, { 0, 0, 27472 }, + { 1977, 423, -21477 }, { 1754, -2055, -18579 }, + { 0, 0, 25919 }, { -1681, 96, -22354 }, + { -20790, -12983, -5802 }, { 376, 4598, 14848 }, + { 0, 0, 18950 }, { 0, 0, 0 }, + { 3130, -6330, 27866 }, { 0, 0, -5576 }, + { 2725, 2012, -17715 }, { 4493, 6440, -31020 }, + { 0, 0, -14167 }, { 1055, 3881, -18845 }, + { -16739, 27250, -1432 }, { 0, 0, 0 }, + }, + { + // Frame 9 + { -59, 940, -590 }, { -16713, 0, 0 }, + { -16384, 5073, -16384 }, { 0, 0, 0 }, + { -2448, 996, -16808 }, { 0, 0, 26712 }, + { 2021, 695, -22206 }, { 1957, -1988, -18219 }, + { 0, 0, 26656 }, { -1789, -334, -23017 }, + { -22257, -13213, -4844 }, { 333, 4517, 14584 }, + { 0, 0, 19285 }, { 0, 0, 0 }, + { 2948, -5849, 28856 }, { 0, 0, -5925 }, + { 4383, 81, -17239 }, { 5329, 5036, -29493 }, + { 0, 0, -13518 }, { 1992, 3521, -18202 }, + { -16629, 27244, -1214 }, { 0, 0, 0 }, + }, + { + // Frame 10 + { -59, 1348, -649 }, { -11768, 0, 0 }, + { -16384, 1883, -16384 }, { 0, 0, 0 }, + { -2196, 778, -10577 }, { 0, 0, 28012 }, + { 1653, 2033, -24440 }, { 2855, -2524, -11436 }, + { 0, 0, 27911 }, { -1938, -1318, -24470 }, + { -25057, -12419, -3692 }, { 177, 3296, 14007 }, + { 0, 0, 19787 }, { 0, 0, 0 }, + { 2482, -4950, 30438 }, { 0, 0, -6494 }, + { 6915, -3159, -16394 }, { 6751, 2940, -27054 }, + { 0, 0, -12420 }, { 3479, 2992, -17208 }, + { -16434, 27240, -830 }, { 0, 0, 0 }, + }, + { + // Frame 11 + { -58, 1735, -542 }, { -7750, 0, 0 }, + { -16384, 184, -16384 }, { 0, 0, 0 }, + { -1205, 108, -8043 }, { 0, 0, 25981 }, + { 1346, 2790, -26757 }, { 2029, -1692, -8455 }, + { 0, 0, 25863 }, { -1961, -2047, -25988 }, + { -28048, -11954, -2090 }, { -470, 3031, 12591 }, + { 0, 0, 19948 }, { 0, 0, 0 }, + { 2309, -4596, 31084 }, { 0, 0, -6786 }, + { 7219, -4155, -16045 }, { 7656, 2711, -26079 }, + { 0, 0, -11861 }, { 4229, 2661, -16666 }, + { -16363, 27240, -688 }, { 0, 0, 0 }, + }, + { + // Frame 12 + { 74, 3528, -37 }, + { 0, 0, 0 }, + { -16384, -626, -16384 }, + { 0, 0, 0 }, + { 135, 5446, -5887 }, + { 0, 0, 23451 }, + { 2115, 1887, -20292 }, + { 1024, -219, -1846 }, + { 0, 0, 5914 }, + { -443, -1625, -21253 }, + { 16384, 417, 16384 }, + { 476, -93, 19351 }, + { 0, 0, 23344 }, + { 0, 0, 0 }, + { -21137, -12435, -10526 }, + { 0, 0, -6675 }, + { -36, -503, -16171 }, + { 12851, 7298, -17081 }, + { 0, 0, -19713 }, + { 4373, 5305, -15750 }, + { -16384, 27240, -730 }, + { 0, 0, 0 }, + }, + { + // Frame 13 + { 54, 3227, -89 }, + { 2313, 0, 0 }, + { -16384, -685, -16384 }, + { 0, 0, 0 }, + { -152, 5099, -11115 }, + { 0, 0, 24427 }, + { 2059, 1815, -21046 }, + { -59, -710, -6843 }, + { 0, 0, 10860 }, + { -979, -1386, -22412 }, + { 16183, -133, 16490 }, + { 503, -59, 18352 }, + { 0, 0, 25530 }, + { 0, 0, 0 }, + { -20393, -12323, -12080 }, + { 0, 0, -6726 }, + { -25, -562, -16150 }, + { 14095, 8887, -16891 }, + { 0, 0, -18784 }, + { 3073, 5837, -17586 }, + { -15392, 27325, 1213 }, + { 0, 0, 0 }, + }, + { + // Frame 14 + { -25, 2218, -133 }, + { 7607, 0, 0 }, + { -16384, -781, -16384 }, + { 0, 0, 0 }, + { -654, 1069, -20519 }, + { 0, 0, 20760 }, + { 1304, 1666, -23774 }, + { -518, -3910, -15614 }, + { 0, 0, 22754 }, + { -1707, -1918, -22925 }, + { 16384, -4331, 16384 }, + { 641, 74, 13206 }, + { 0, 0, 30948 }, + { 0, 0, 0 }, + { -15708, -11590, -21423 }, + { 0, 0, -6949 }, + { 37, -880, -16032 }, + { -12778, 15014, 15677 }, + { 0, 0, -13974 }, + { -4182, 8702, -27734 }, + { -13006, 28312, 6371 }, + { 0, 0, 0 }, + }, + { + // Frame 15 + { -57, 2670, 558 }, { 13602, 0, 0 }, + { -16384, 0, -16384 }, { 0, 0, 0 }, + { 1852, 198, -7548 }, { 0, 0, 1654 }, + { 1472, 2843, -23780 }, { -2685, -3676, -6545 }, + { 0, 0, 15549 }, { 1676, -2089, -20933 }, + { -1427, -19182, -27019 }, { 698, -257, 10968 }, + { 0, 0, 18514 }, { 0, 0, 0 }, + { 23192, -22237, 548 }, { 0, 0, -6929 }, + { 86, -1131, -15938 }, { -11355, 7097, 10885 }, + { 0, 0, -11056 }, { -10661, 10872, 29098 }, + { -15580, 27296, 800 }, { 0, 0, 0 }, + }, + { + // Frame 16 + { -60, 2207, 382 }, { 20068, 0, 0 }, + { -16384, 2162, -16384 }, { 0, 0, 0 }, + { 219, 581, -17012 }, { 0, 0, 16199 }, + { 1446, 2552, -20834 }, { -1193, -3974, -12795 }, + { 0, 0, 22901 }, { 1355, -1424, -20722 }, + { -24738, -12007, -7558 }, { 462, -469, 19859 }, + { 0, 0, 17568 }, { 0, 0, 0 }, + { -1152, -8811, 22716 }, { 0, 0, -5124 }, + { 43, -913, -16019 }, { -2615, 21391, 18299 }, + { 0, 0, -20972 }, { -7167, 7353, -29571 }, + { -16740, 27249, -1447 }, { 0, 0, 0 }, + }, + { + // Frame 17 + { -60, 1477, 314 }, { 26774, 0, 0 }, + { -16384, 4992, -16384 }, { 0, 0, 0 }, + { 1331, 909, -8175 }, { 0, 0, 8190 }, + { 538, 2622, -21124 }, { -443, -603, -1212 }, + { 0, 0, 24711 }, { 491, -584, -20713 }, + { -21267, -11295, -7882 }, { 552, 479, 16219 }, + { 0, 0, 17341 }, { 0, 0, 0 }, + { 2866, -7762, 19771 }, { 0, 0, -3812 }, + { -416, 862, -16656 }, { -2940, 16895, 20702 }, + { 0, 0, -18661 }, { -5100, 10643, -25824 }, + { -15495, 27304, 1032 }, { 0, 0, 0 }, + }, + { + // Frame 18 + { -60, 771, 241 }, { -32044, 0, 0 }, { -16384, 7684, -16384 }, { 0, 0, 0 }, + { -27, 459, -14461 }, { 0, 0, 13541 }, { 63, 2434, -21507 }, { 140, -3557, -8362 }, + { 0, 0, 25043 }, { -525, 149, -20932 }, { -18194, -11230, -7652 }, { 519, 2089, 15610 }, + { 0, 0, 17631 }, { 0, 0, 0 }, { 3504, -7332, 22086 }, { 0, 0, -4207 }, + { -1489, 5198, -18222 }, { 967, 12936, 27541 }, { 0, 0, -17131 }, { -2949, 6188, -22075 }, + { -16864, 27258, -1679 }, { 0, 0, 0 }, + }, + { + // Frame 19 + { -60, 511, -4 }, { -25546, 0, 0 }, + { -16384, 8878, -16384 }, { 0, 0, 0 }, + { -799, 63, -16740 }, { 0, 0, 14954 }, + { 943, 1296, -21262 }, { 1564, -3136, -16443 }, + { 0, 0, 25526 }, { -1303, 490, -21402 }, + { -18554, -11994, -7123 }, { 464, 3612, 15275 }, + { 0, 0, 18235 }, { 0, 0, 0 }, + { 3231, -6977, 25545 }, { 0, 0, -4847 }, + { -321, 5196, -18440 }, { 2710, 9642, 31101 }, + { 0, 0, -15600 }, { -985, 4840, -20355 }, + { -16899, 27261, -1747 }, { 0, 0, 0 }, + }, +}; + +#endif // ROLL_ANIMATION_DATA_H \ No newline at end of file diff --git a/soh/soh/Enhancements/randomizer/savefile.cpp b/soh/soh/Enhancements/randomizer/savefile.cpp index a2522ce5a11..18e09ef1e1e 100644 --- a/soh/soh/Enhancements/randomizer/savefile.cpp +++ b/soh/soh/Enhancements/randomizer/savefile.cpp @@ -324,6 +324,10 @@ extern "C" void Randomizer_InitSaveFile() { Flags_SetRandomizerInf(RAND_INF_CAN_CRAWL); } + if (Randomizer_GetSettingValue(RSK_SHUFFLE_ROLL) == RO_GENERIC_OFF) { + Flags_SetRandomizerInf(RAND_INF_CAN_ROLL); + } + if (Randomizer_GetSettingValue(RSK_SHUFFLE_SPEAK) == RO_GENERIC_OFF) { Flags_SetEventChkInf(EVENTCHKINF_SPOKE_TO_NABOORU_IN_SPIRIT_TEMPLE); Flags_SetRandomizerInf(RAND_INF_CAN_SPEAK_DEKU); diff --git a/soh/soh/Enhancements/randomizer/settings.cpp b/soh/soh/Enhancements/randomizer/settings.cpp index 125dcd30236..89018a65209 100644 --- a/soh/soh/Enhancements/randomizer/settings.cpp +++ b/soh/soh/Enhancements/randomizer/settings.cpp @@ -787,6 +787,7 @@ void Settings::CreateOptions() { OPT_BOOL(RSK_SHUFFLE_SWIM, "Shuffle Swim", CVAR_RANDOMIZER_SETTING("ShuffleSwim"), mOptionDescriptions[RSK_SHUFFLE_SWIM]); OPT_BOOL(RSK_SHUFFLE_CLIMB, "Shuffle Climb", CVAR_RANDOMIZER_SETTING("ShuffleClimb"), mOptionDescriptions[RSK_SHUFFLE_CLIMB]); OPT_BOOL(RSK_SHUFFLE_CRAWL, "Shuffle Crawl", CVAR_RANDOMIZER_SETTING("ShuffleCrawl"), mOptionDescriptions[RSK_SHUFFLE_CRAWL]); + OPT_BOOL(RSK_SHUFFLE_ROLL, "Shuffle Roll", CVAR_RANDOMIZER_SETTING("ShuffleRoll"), mOptionDescriptions[RSK_SHUFFLE_ROLL]); OPT_BOOL(RSK_SHUFFLE_GRAB, "Shuffle Grab", CVAR_RANDOMIZER_SETTING("ShuffleGrab"), mOptionDescriptions[RSK_SHUFFLE_GRAB]); OPT_BOOL(RSK_SHUFFLE_SPEAK, "Shuffle Jabber Nuts", CVAR_RANDOMIZER_SETTING("ShuffleSpeak"), mOptionDescriptions[RSK_SHUFFLE_SPEAK]); OPT_BOOL(RSK_SHUFFLE_OPEN_CHEST, "Shuffle Open Chest", CVAR_RANDOMIZER_SETTING("ShuffleOpenChest"), mOptionDescriptions[RSK_SHUFFLE_OPEN_CHEST]); @@ -796,6 +797,8 @@ void Settings::CreateOptions() { OPT_U8(RSK_SHUFFLE_GRASS, "Shuffle Grass", {"Off", "Dungeons", "Overworld", "All Grass/Bushes"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("ShuffleGrass"), mOptionDescriptions[RSK_SHUFFLE_GRASS], WIDGET_CVAR_COMBOBOX, RO_SHUFFLE_GRASS_OFF); OPT_U8(RSK_SHUFFLE_CRATES, "Shuffle Crates", {"Off", "Dungeons", "Overworld", "All Crates"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("ShuffleCrates"), mOptionDescriptions[RSK_SHUFFLE_CRATES], WIDGET_CVAR_COMBOBOX, RO_SHUFFLE_CRATES_OFF); OPT_BOOL(RSK_SHUFFLE_TREES, "Shuffle Trees", CVAR_RANDOMIZER_SETTING("ShuffleTrees"), mOptionDescriptions[RSK_SHUFFLE_TREES]); + OPT_BOOL(RSK_SHUFFLE_ROCKS, "Shuffle Rocks", CVAR_RANDOMIZER_SETTING("ShuffleRocks"), mOptionDescriptions[RSK_SHUFFLE_ROCKS]); + OPT_U8(RSK_SHUFFLE_BOULDERS, "Shuffle Boulders", {"Off", "Dungeons", "Overworld", "All Boulders"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("ShuffleBoulders"), mOptionDescriptions[RSK_SHUFFLE_BOULDERS], WIDGET_CVAR_COMBOBOX, RO_SHUFFLE_BOULDERS_OFF); OPT_BOOL(RSK_SHUFFLE_BUSHES, "Shuffle Bushes", CVAR_RANDOMIZER_SETTING("ShuffleBushes"), mOptionDescriptions[RSK_SHUFFLE_BUSHES]); OPT_BOOL(RSK_SHUFFLE_FISHING_POLE, "Shuffle Fishing Pole", CVAR_RANDOMIZER_SETTING("ShuffleFishingPole"), mOptionDescriptions[RSK_SHUFFLE_FISHING_POLE]); OPT_CALLBACK(RSK_SHUFFLE_FISHING_POLE, { @@ -2331,6 +2334,8 @@ void Settings::CreateOptions() { &mOptions[RSK_FISHSANITY_AGE_SPLIT], &mOptions[RSK_SHUFFLE_FREESTANDING], &mOptions[RSK_SHUFFLE_BEEHIVES], + &mOptions[RSK_SHUFFLE_ROCKS], + &mOptions[RSK_SHUFFLE_BOULDERS], &mOptions[RSK_SHUFFLE_COWS], &mOptions[RSK_SHUFFLE_POTS], &mOptions[RSK_SHUFFLE_GRASS], @@ -2374,6 +2379,7 @@ void Settings::CreateOptions() { &mOptions[RSK_SCRUBS_PRICES_GIANT_WALLET_WEIGHT], &mOptions[RSK_SCRUBS_PRICES_TYCOON_WALLET_WEIGHT], &mOptions[RSK_SCRUBS_PRICES_AFFORDABLE], + &mOptions[RSK_SHUFFLE_MERCHANTS], &mOptions[RSK_MERCHANT_PRICES], &mOptions[RSK_MERCHANT_PRICES_FIXED_PRICE], @@ -2389,28 +2395,21 @@ void Settings::CreateOptions() { WidgetContainerType::SECTION); mOptionGroups[RSG_MENU_COLUMN_SHOP_SHUFFLES] = OptionGroup::SubGroup("", { &mOptionGroups[RSG_MENU_SECTION_SHOP_SHUFFLES] }, WidgetContainerType::COLUMN); - mOptionGroups[RSG_MENU_SECTION_ADDITIONAL_ITEMS] = OptionGroup::SubGroup("Additional Items", - { - &mOptions[RSK_SHUFFLE_CHILD_WALLET], - &mOptions[RSK_INCLUDE_TYCOON_WALLET], - &mOptions[RSK_SHUFFLE_FISHING_POLE], - &mOptions[RSK_SHUFFLE_DEKU_STICK_BAG], - &mOptions[RSK_SHUFFLE_DEKU_NUT_BAG], - &mOptions[RSK_SHUFFLE_OCARINA_BUTTONS], - &mOptions[RSK_SHUFFLE_SWIM], - &mOptions[RSK_SHUFFLE_GRAB], - &mOptions[RSK_SHUFFLE_CLIMB], - &mOptions[RSK_SHUFFLE_CRAWL], - &mOptions[RSK_SHUFFLE_SPEAK], - &mOptions[RSK_SHUFFLE_OPEN_CHEST], - &mOptions[RSK_SHUFFLE_BEAN_SOULS], - &mOptions[RSK_ROCS_FEATHER], - &mOptions[RSK_BOMBCHU_BAG], - &mOptions[RSK_ENABLE_BOMBCHU_DROPS], - &mOptions[RSK_INFINITE_UPGRADES], - &mOptions[RSK_SKELETON_KEY], - }, - WidgetContainerType::SECTION); + mOptionGroups[RSG_MENU_SECTION_ADDITIONAL_ITEMS] = + OptionGroup::SubGroup("Additional Items", + { + &mOptions[RSK_SHUFFLE_CHILD_WALLET], &mOptions[RSK_INCLUDE_TYCOON_WALLET], + &mOptions[RSK_SHUFFLE_FISHING_POLE], &mOptions[RSK_SHUFFLE_DEKU_STICK_BAG], + &mOptions[RSK_SHUFFLE_DEKU_NUT_BAG], &mOptions[RSK_SHUFFLE_OCARINA_BUTTONS], + &mOptions[RSK_SHUFFLE_SWIM], &mOptions[RSK_SHUFFLE_GRAB], + &mOptions[RSK_SHUFFLE_CLIMB], &mOptions[RSK_SHUFFLE_CRAWL], + &mOptions[RSK_SHUFFLE_ROLL], &mOptions[RSK_SHUFFLE_SPEAK], + &mOptions[RSK_SHUFFLE_OPEN_CHEST], &mOptions[RSK_SHUFFLE_BEAN_SOULS], + &mOptions[RSK_ROCS_FEATHER], &mOptions[RSK_BOMBCHU_BAG], + &mOptions[RSK_ENABLE_BOMBCHU_DROPS], &mOptions[RSK_INFINITE_UPGRADES], + &mOptions[RSK_SKELETON_KEY], + }, + WidgetContainerType::SECTION); mOptionGroups[RSG_MENU_COLUMN_ADDITIONAL_ITEMS] = OptionGroup::SubGroup("", { &mOptionGroups[RSG_MENU_SECTION_ADDITIONAL_ITEMS] }, WidgetContainerType::COLUMN); mOptionGroups[RSG_MENU_SIDEBAR_SHUFFLES] = @@ -2617,6 +2616,8 @@ void Settings::CreateOptions() { &mOptions[RSK_SHUFFLE_CRATES], &mOptions[RSK_SHUFFLE_TREES], &mOptions[RSK_SHUFFLE_BUSHES], + &mOptions[RSK_SHUFFLE_ROCKS], + &mOptions[RSK_SHUFFLE_BOULDERS], &mOptions[RSK_SHUFFLE_KOKIRI_SWORD], &mOptions[RSK_SHUFFLE_OCARINA], &mOptions[RSK_SHUFFLE_OCARINA_BUTTONS], @@ -2624,6 +2625,7 @@ void Settings::CreateOptions() { &mOptions[RSK_SHUFFLE_GRAB], &mOptions[RSK_SHUFFLE_CLIMB], &mOptions[RSK_SHUFFLE_CRAWL], + &mOptions[RSK_SHUFFLE_ROLL], &mOptions[RSK_SHUFFLE_SPEAK], &mOptions[RSK_SHUFFLE_OPEN_CHEST], &mOptions[RSK_SHUFFLE_WEIRD_EGG], diff --git a/soh/soh/Enhancements/randomizer/static_data.h b/soh/soh/Enhancements/randomizer/static_data.h index 0b837179ba2..a0b084e6caf 100644 --- a/soh/soh/Enhancements/randomizer/static_data.h +++ b/soh/soh/Enhancements/randomizer/static_data.h @@ -62,6 +62,7 @@ class StaticData { static void RegisterGrassLocations(); static void RegisterCrateLocations(); static void RegisterTreeLocations(); + static void RegisterRockLocations(); static void InitHashMaps(); static std::array, 17> randomizerFishingPondFish; static std::unordered_map randomizerGrottoFishMap; diff --git a/soh/soh/SohGui/ImGuiUtils.cpp b/soh/soh/SohGui/ImGuiUtils.cpp index 3f01e6e5543..a58c4a044ed 100644 --- a/soh/soh/SohGui/ImGuiUtils.cpp +++ b/soh/soh/SohGui/ImGuiUtils.cpp @@ -154,6 +154,7 @@ std::map customItemsMapping = { std::map actionShuffleMapping = { { RG_CRAWL, { RG_CRAWL, "RG_CRAWL", "RG_CRAWL_Faded", gButtonBackgroundTex } }, { RG_CLIMB, { RG_CLIMB, "RG_CLIMB", "RG_CLIMB_Faded", gButtonBackgroundTex } }, + { RG_ROLL, { RG_ROLL, "RG_ROLL", "RG_ROLL_Faded", gButtonBackgroundTex } }, { RG_POWER_BRACELET, { RG_POWER_BRACELET, "RG_POWER_BRACELET", "RG_POWER_BRACELET_Faded", gButtonBackgroundTex } }, }; diff --git a/soh/soh/SohGui/SohMenuEnhancements.cpp b/soh/soh/SohGui/SohMenuEnhancements.cpp index 26287850c66..999a566e772 100644 --- a/soh/soh/SohGui/SohMenuEnhancements.cpp +++ b/soh/soh/SohGui/SohMenuEnhancements.cpp @@ -290,6 +290,10 @@ void SohMenu::AddMenuEnhancements() { .CVar(CVAR_ENHANCEMENT("BetterOwl")) .Options(CheckboxOptions().Tooltip( "The default response to Kaepora Gaebora is always that you understood what he said.")); + AddWidget(path, "Allow Dropping Throw-Only Objects", WIDGET_CVAR_CHECKBOX) + .CVar(CVAR_ENHANCEMENT("DropThrowOnlyObjects")) + .Options(CheckboxOptions().Tooltip("Allows normally throw-only objects (such as Cuccos, pots, grass, and small " + "rocks) to be dropped by pressing A while standing still.")); AddWidget(path, "Convenience", WIDGET_SEPARATOR_TEXT); AddWidget(path, "Quit Fishing at Door", WIDGET_CVAR_CHECKBOX) @@ -1770,6 +1774,9 @@ void SohMenu::AddMenuEnhancements() { .Options(CheckboxOptions().Tooltip( "Keese and Guay no longer target you and simply ignore you as if you were wearing the " "Skull Mask.")); + AddWidget(path, "Like Like don't Steal Items", WIDGET_CVAR_CHECKBOX) + .CVar(CVAR_CHEAT("NoLikeLikeItemSteal")) + .Options(CheckboxOptions().Tooltip("Prevents Like Likes from being able to steal your equipments.")); AddWidget(path, "Disable Haunted Wasteland Sandstorm", WIDGET_CVAR_CHECKBOX) .CVar(CVAR_CHEAT("DisableSandstorm")) .Options(CheckboxOptions().Tooltip("Disables sandstorm effect in Haunted Wasteland.")); diff --git a/soh/src/code/z_parameter.c b/soh/src/code/z_parameter.c index 049f0eaf574..3d46ae0c87d 100644 --- a/soh/src/code/z_parameter.c +++ b/soh/src/code/z_parameter.c @@ -2814,7 +2814,7 @@ void Interface_SetNaviCall(PlayState* play, u16 naviCallState) { if (((naviCallState == 0x1D) || (naviCallState == 0x1E)) && !interfaceCtx->naviCalling && (play->csCtx.state == CS_STATE_IDLE)) { - if (!CVarGetInteger(CVAR_AUDIO("DisableNaviCallAudio"), 0)) { + if (GameInteractor_Should(VB_PLAY_NAVI_CALL_SOUND, true, naviCallState)) { // clang-format off if (naviCallState == 0x1E) { Audio_PlaySoundGeneral(NA_SE_VO_NAVY_CALL, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb); } diff --git a/soh/src/code/z_player_lib.c b/soh/src/code/z_player_lib.c index aa3623b6a72..2dd49e2eb56 100644 --- a/soh/src/code/z_player_lib.c +++ b/soh/src/code/z_player_lib.c @@ -695,6 +695,7 @@ void Player_UpdateBottleHeld(PlayState* play, Player* this, s32 item, s32 action } this->itemAction = actionParam; + GameInteractor_ExecuteOnPlayerBottleHeldChanged(item, actionParam); } void Player_ReleaseLockOn(Player* this) { diff --git a/soh/src/overlays/actors/ovl_En_Elf/z_en_elf.c b/soh/src/overlays/actors/ovl_En_Elf/z_en_elf.c index 96a9297b969..94f3d75a411 100644 --- a/soh/src/overlays/actors/ovl_En_Elf/z_en_elf.c +++ b/soh/src/overlays/actors/ovl_En_Elf/z_en_elf.c @@ -817,28 +817,30 @@ void EnElf_UpdateLights(EnElf* this, PlayState* play) { s16 glowLightRadius; Player* player; - glowLightRadius = 100; + if (GameInteractor_Should(VB_FAIRY_UPDATE_LIGHTS, true, this)) { + glowLightRadius = 100; - if (this->unk_2A8 == 8) { - glowLightRadius = 0; - } + if (this->unk_2A8 == 8) { + glowLightRadius = 0; + } - if (this->fairyFlags & 0x20) { - player = GET_PLAYER(play); - Lights_PointNoGlowSetInfo(&this->lightInfoNoGlow, player->actor.world.pos.x, - (s16)(player->actor.world.pos.y) + 60.0f, player->actor.world.pos.z, 255, 255, 255, - 200); - } else { - Lights_PointNoGlowSetInfo(&this->lightInfoNoGlow, this->actor.world.pos.x, this->actor.world.pos.y, - this->actor.world.pos.z, 255, 255, 255, -1); - } + if (this->fairyFlags & 0x20) { + player = GET_PLAYER(play); + Lights_PointNoGlowSetInfo(&this->lightInfoNoGlow, player->actor.world.pos.x, + (s16)(player->actor.world.pos.y) + 60.0f, player->actor.world.pos.z, 255, 255, + 255, 200); + } else { + Lights_PointNoGlowSetInfo(&this->lightInfoNoGlow, this->actor.world.pos.x, this->actor.world.pos.y, + this->actor.world.pos.z, 255, 255, 255, -1); + } - Lights_PointGlowSetInfo(&this->lightInfoGlow, this->actor.world.pos.x, this->actor.world.pos.y, - this->actor.world.pos.z, 255, 255, 255, glowLightRadius); + Lights_PointGlowSetInfo(&this->lightInfoGlow, this->actor.world.pos.x, this->actor.world.pos.y, + this->actor.world.pos.z, 255, 255, 255, glowLightRadius); - this->unk_2BC = Math_Atan2S(this->actor.velocity.z, this->actor.velocity.x); + this->unk_2BC = Math_Atan2S(this->actor.velocity.z, this->actor.velocity.x); - Actor_SetScale(&this->actor, this->actor.scale.x); + Actor_SetScale(&this->actor, this->actor.scale.x); + } } void func_80A03CF8(EnElf* this, PlayState* play) { @@ -872,7 +874,9 @@ void func_80A03CF8(EnElf* this, PlayState* play) { if ((play->sceneNum == SCENE_LINKS_HOUSE) && (gSaveContext.sceneSetupIndex == 4)) { // play dash sound as Navi enters Links house in the intro if (play->csCtx.frames == 55) { - Audio_PlayActorSound2(&this->actor, NA_SE_EV_FAIRY_DASH); + if (GameInteractor_Should(VB_FAIRY_PLAY_DASH_SOUND, true, this)) { + Audio_PlayActorSound2(&this->actor, NA_SE_EV_FAIRY_DASH); + } } // play dash sound in intervals as Navi is waking up Link in the intro @@ -884,7 +888,9 @@ void func_80A03CF8(EnElf* this, PlayState* play) { } else { if (this->actor.world.pos.y < prevPos.y) { this->fairyFlags |= 0x40; - Audio_PlayActorSound2(&this->actor, NA_SE_EV_FAIRY_DASH); + if (GameInteractor_Should(VB_FAIRY_PLAY_DASH_SOUND, true, this)) { + Audio_PlayActorSound2(&this->actor, NA_SE_EV_FAIRY_DASH); + } } } } @@ -967,7 +973,9 @@ void func_80A03CF8(EnElf* this, PlayState* play) { this->fairyFlags |= 2; if (this->unk_2C7 == 0) { - Audio_PlayActorSound2(&this->actor, NA_SE_EV_FAIRY_DASH); + if (GameInteractor_Should(VB_FAIRY_PLAY_DASH_SOUND, true, this)) { + Audio_PlayActorSound2(&this->actor, NA_SE_EV_FAIRY_DASH); + } } this->unk_2C0 = 0x64; @@ -1015,7 +1023,9 @@ void func_80A04414(EnElf* this, PlayState* play) { this->unk_29C = 1.0f; if (this->unk_2C7 == 0) { - Audio_PlayActorSound2(&this->actor, NA_SE_EV_FAIRY_DASH); + if (GameInteractor_Should(VB_FAIRY_PLAY_DASH_SOUND, true, this)) { + Audio_PlayActorSound2(&this->actor, NA_SE_EV_FAIRY_DASH); + } } } else { @@ -1105,7 +1115,9 @@ void func_80A0461C(EnElf* this, PlayState* play) { temp = 0; } else { if (this->unk_2C7 == 0) { - Audio_PlayActorSound2(&this->actor, NA_SE_EV_NAVY_VANISH); + if (GameInteractor_Should(VB_FAIRY_PLAY_VANISH_SOUND, true, this)) { + Audio_PlayActorSound2(&this->actor, NA_SE_EV_NAVY_VANISH); + } } temp = 7; } @@ -1149,7 +1161,9 @@ void func_80A0461C(EnElf* this, PlayState* play) { if (!(player->stateFlags2 & PLAYER_STATE2_NAVI_ACTIVE)) { temp = 7; if (this->unk_2C7 == 0) { - Audio_PlayActorSound2(&this->actor, NA_SE_EV_NAVY_VANISH); + if (GameInteractor_Should(VB_FAIRY_PLAY_VANISH_SOUND, true, this)) { + Audio_PlayActorSound2(&this->actor, NA_SE_EV_NAVY_VANISH); + } } } break; @@ -1159,7 +1173,9 @@ void func_80A0461C(EnElf* this, PlayState* play) { this->unk_2C0 = 42; temp = 11; if (this->unk_2C7 == 0) { - Audio_PlayActorSound2(&this->actor, NA_SE_EV_FAIRY_DASH); + if (GameInteractor_Should(VB_FAIRY_PLAY_DASH_SOUND, true, this)) { + Audio_PlayActorSound2(&this->actor, NA_SE_EV_FAIRY_DASH); + } } } break; @@ -1190,20 +1206,22 @@ void EnElf_SpawnSparkles(EnElf* this, PlayState* play, s32 sparkleLife) { Color_RGBA8 primColor; Color_RGBA8 envColor; - sparklePos.x = Rand_CenteredFloat(6.0f) + this->actor.world.pos.x; - sparklePos.y = (Rand_ZeroOne() * 6.0f) + this->actor.world.pos.y; - sparklePos.z = Rand_CenteredFloat(6.0f) + this->actor.world.pos.z; + if (GameInteractor_Should(VB_FAIRY_SPAWN_SPARKLES, true, this, sparkleLife)) { + sparklePos.x = Rand_CenteredFloat(6.0f) + this->actor.world.pos.x; + sparklePos.y = (Rand_ZeroOne() * 6.0f) + this->actor.world.pos.y; + sparklePos.z = Rand_CenteredFloat(6.0f) + this->actor.world.pos.z; - primColor.r = this->innerColor.r; - primColor.g = this->innerColor.g; - primColor.b = this->innerColor.b; + primColor.r = this->innerColor.r; + primColor.g = this->innerColor.g; + primColor.b = this->innerColor.b; - envColor.r = this->outerColor.r; - envColor.g = this->outerColor.g; - envColor.b = this->outerColor.b; + envColor.r = this->outerColor.r; + envColor.g = this->outerColor.g; + envColor.b = this->outerColor.b; - EffectSsKiraKira_SpawnDispersed(play, &sparklePos, &sparkleVelocity, &sparkleAccel, &primColor, &envColor, 1000, - sparkleLife); + EffectSsKiraKira_SpawnDispersed(play, &sparklePos, &sparkleVelocity, &sparkleAccel, &primColor, &envColor, 1000, + sparkleLife); + } } void func_80A04D90(EnElf* this, PlayState* play) { @@ -1392,7 +1410,9 @@ void func_80A053F0(Actor* thisx, PlayState* play) { } if (Actor_ProcessTalkRequest(thisx, play)) { - func_800F4524(&gSfxDefaultPos, NA_SE_VO_SK_LAUGH, 0x20); + if (GameInteractor_Should(VB_FAIRY_PLAY_C_UP_TALK_SOUND, true, this)) { + func_800F4524(&gSfxDefaultPos, NA_SE_VO_SK_LAUGH, 0x20); + } thisx->focus.pos = thisx->world.pos; if (thisx->textId == ElfMessage_GetCUpText(play)) { @@ -1506,7 +1526,7 @@ void EnElf_Draw(Actor* thisx, PlayState* play) { Gfx* dListHead; Player* player = GET_PLAYER(play); - if ((this->unk_2A8 != 8) && !(this->fairyFlags & 8)) { + if (GameInteractor_Should(VB_FAIRY_DRAW, ((this->unk_2A8 != 8) && !(this->fairyFlags & 8)), this)) { if (!(player->stateFlags1 & PLAYER_STATE1_FIRST_PERSON) || (kREG(90) < this->actor.projectedPos.z)) { dListHead = Graph_Alloc(play->state.gfxCtx, sizeof(Gfx) * 4); diff --git a/soh/src/overlays/actors/ovl_En_Ishi/z_en_ishi.c b/soh/src/overlays/actors/ovl_En_Ishi/z_en_ishi.c index 37dc1fa9db7..fccc1a0d222 100644 --- a/soh/src/overlays/actors/ovl_En_Ishi/z_en_ishi.c +++ b/soh/src/overlays/actors/ovl_En_Ishi/z_en_ishi.c @@ -8,6 +8,7 @@ #include "overlays/effects/ovl_Effect_Ss_Kakera/z_eff_ss_kakera.h" #include "objects/gameplay_field_keep/gameplay_field_keep.h" #include "soh/OTRGlobals.h" +#include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h" #include "vt.h" @@ -251,6 +252,10 @@ void EnIshi_SpawnDustLarge(EnIshi* this, PlayState* play) { void EnIshi_DropCollectible(EnIshi* this, PlayState* play) { s16 dropParams; + if (!GameInteractor_Should(VB_ROCK_DROP_ITEM, true, this)) { + return; + } + if ((this->actor.params & 1) == ROCK_SMALL) { dropParams = (this->actor.params >> 8) & 0xF; diff --git a/soh/src/overlays/actors/ovl_En_Rr/z_en_rr.c b/soh/src/overlays/actors/ovl_En_Rr/z_en_rr.c index 831e11b8c38..d94e6dd220b 100644 --- a/soh/src/overlays/actors/ovl_En_Rr/z_en_rr.c +++ b/soh/src/overlays/actors/ovl_En_Rr/z_en_rr.c @@ -300,32 +300,35 @@ void EnRr_SetupReleasePlayer(EnRr* this, PlayState* play) { this->wobbleSizeTarget = 2048.0f; tunic = 0; shield = 0; - if (CUR_EQUIP_VALUE(EQUIP_TYPE_SHIELD) != EQUIP_VALUE_SHIELD_MIRROR) { - shield = Inventory_DeleteEquipment(play, EQUIP_TYPE_SHIELD); - if (shield != 0) { - this->eatenShield = shield; - this->retreat = true; + if (GameInteractor_Should(VB_LIKE_LIKE_STEAL_EQUIPMENT, true, this)) { + if (CUR_EQUIP_VALUE(EQUIP_TYPE_SHIELD) != EQUIP_VALUE_SHIELD_MIRROR) { + shield = Inventory_DeleteEquipment(play, EQUIP_TYPE_SHIELD); + if (shield != 0) { + this->eatenShield = shield; + this->retreat = true; + } } - } - if (CUR_EQUIP_VALUE(EQUIP_TYPE_TUNIC) != EQUIP_VALUE_TUNIC_KOKIRI && !IS_RANDO /* Randomizer Save File */) { - tunic = Inventory_DeleteEquipment(play, EQUIP_TYPE_TUNIC); - if (tunic != 0) { - this->eatenTunic = tunic; - this->retreat = true; + if (CUR_EQUIP_VALUE(EQUIP_TYPE_TUNIC) != EQUIP_VALUE_TUNIC_KOKIRI && !IS_RANDO /* Randomizer Save File */) { + tunic = Inventory_DeleteEquipment(play, EQUIP_TYPE_TUNIC); + if (tunic != 0) { + this->eatenTunic = tunic; + this->retreat = true; + } + } + + switch (EnRr_GetMessage(shield, tunic)) { + case RR_MESSAGE_SHIELD: + Message_StartTextbox(play, 0x305F, NULL); + break; + case RR_MESSAGE_TUNIC: + Message_StartTextbox(play, 0x3060, NULL); + break; + case RR_MESSAGE_TUNIC | RR_MESSAGE_SHIELD: + Message_StartTextbox(play, 0x3061, NULL); + break; } } player->actor.parent = NULL; - switch (EnRr_GetMessage(shield, tunic)) { - case RR_MESSAGE_SHIELD: - Message_StartTextbox(play, 0x305F, NULL); - break; - case RR_MESSAGE_TUNIC: - Message_StartTextbox(play, 0x3060, NULL); - break; - case RR_MESSAGE_TUNIC | RR_MESSAGE_SHIELD: - Message_StartTextbox(play, 0x3061, NULL); - break; - } osSyncPrintf(VT_FGCOL(YELLOW) "%s[%d] : Rr_Catch_Cancel" VT_RST "\n", __FILE__, __LINE__); func_8002F6D4(play, &this->actor, 4.0f, this->actor.shape.rot.y, 12.0f, 8); if (this->actor.colorFilterTimer == 0) { @@ -666,50 +669,53 @@ void EnRr_Death(EnRr* this, PlayState* play) { (SQ(4 - i) * (f32)this->frameCount * 0.003f) + 1.0f; } } else if (this->frameCount >= 95) { - Vec3f dropPos; - - dropPos.x = this->actor.world.pos.x; - dropPos.y = this->actor.world.pos.y; - dropPos.z = this->actor.world.pos.z; - switch (this->eatenShield) { - case 1: - Item_DropCollectible(play, &dropPos, ITEM00_SHIELD_DEKU); - break; - case 2: - Item_DropCollectible(play, &dropPos, ITEM00_SHIELD_HYLIAN); - break; - } - switch (this->eatenTunic) { - case 2: - Item_DropCollectible(play, &dropPos, ITEM00_TUNIC_GORON); - break; - case 3: - Item_DropCollectible(play, &dropPos, ITEM00_TUNIC_ZORA); - break; - } - // "dropped" - osSyncPrintf(VT_FGCOL(GREEN) "「%s」が出た!!" VT_RST "\n", sDropNames[this->dropType]); - switch (this->dropType) { - case RR_DROP_MAGIC: - Item_DropCollectible(play, &dropPos, ITEM00_MAGIC_SMALL); - break; - case RR_DROP_ARROW: - Item_DropCollectible(play, &dropPos, ITEM00_ARROWS_SINGLE); - break; - case RR_DROP_FLEXIBLE: - Item_DropCollectible(play, &dropPos, ITEM00_FLEXIBLE); - break; - case RR_DROP_RUPEE_PURPLE: - Item_DropCollectible(play, &dropPos, ITEM00_RUPEE_PURPLE); - break; - case RR_DROP_RUPEE_RED: - Item_DropCollectible(play, &dropPos, ITEM00_RUPEE_RED); - break; - case RR_DROP_RANDOM_RUPEE: - default: - Item_DropCollectibleRandom(play, &this->actor, &dropPos, 12 << 4); - break; + if (GameInteractor_Should(VB_LIKE_LIKE_DROP_COLLECTIBLE, true, this)) { + Vec3f dropPos; + + dropPos.x = this->actor.world.pos.x; + dropPos.y = this->actor.world.pos.y; + dropPos.z = this->actor.world.pos.z; + switch (this->eatenShield) { + case 1: + Item_DropCollectible(play, &dropPos, ITEM00_SHIELD_DEKU); + break; + case 2: + Item_DropCollectible(play, &dropPos, ITEM00_SHIELD_HYLIAN); + break; + } + switch (this->eatenTunic) { + case 2: + Item_DropCollectible(play, &dropPos, ITEM00_TUNIC_GORON); + break; + case 3: + Item_DropCollectible(play, &dropPos, ITEM00_TUNIC_ZORA); + break; + } + // "dropped" + osSyncPrintf(VT_FGCOL(GREEN) "「%s」が出た!!" VT_RST "\n", sDropNames[this->dropType]); + switch (this->dropType) { + case RR_DROP_MAGIC: + Item_DropCollectible(play, &dropPos, ITEM00_MAGIC_SMALL); + break; + case RR_DROP_ARROW: + Item_DropCollectible(play, &dropPos, ITEM00_ARROWS_SINGLE); + break; + case RR_DROP_FLEXIBLE: + Item_DropCollectible(play, &dropPos, ITEM00_FLEXIBLE); + break; + case RR_DROP_RUPEE_PURPLE: + Item_DropCollectible(play, &dropPos, ITEM00_RUPEE_PURPLE); + break; + case RR_DROP_RUPEE_RED: + Item_DropCollectible(play, &dropPos, ITEM00_RUPEE_RED); + break; + case RR_DROP_RANDOM_RUPEE: + default: + Item_DropCollectibleRandom(play, &this->actor, &dropPos, 12 << 4); + break; + } } + Actor_Kill(&this->actor); } else if (this->frameCount == 88) { Vec3f pos; diff --git a/soh/src/overlays/actors/ovl_Obj_Bombiwa/z_obj_bombiwa.c b/soh/src/overlays/actors/ovl_Obj_Bombiwa/z_obj_bombiwa.c index 602236816e0..019a09320c1 100644 --- a/soh/src/overlays/actors/ovl_Obj_Bombiwa/z_obj_bombiwa.c +++ b/soh/src/overlays/actors/ovl_Obj_Bombiwa/z_obj_bombiwa.c @@ -7,6 +7,7 @@ #include "z_obj_bombiwa.h" #include "overlays/effects/ovl_Effect_Ss_Kakera/z_eff_ss_kakera.h" #include "objects/object_bombiwa/object_bombiwa.h" +#include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h" #define FLAGS 0 @@ -75,7 +76,7 @@ void ObjBombiwa_InitCollision(Actor* thisx, PlayState* play) { void ObjBombiwa_Init(Actor* thisx, PlayState* play) { Actor_ProcessInitChain(thisx, sInitChain); ObjBombiwa_InitCollision(thisx, play); - if ((Flags_GetSwitch(play, thisx->params & 0x3F) != 0)) { + if (GameInteractor_Should(VB_BOULDER_BREAK_FLAG, Flags_GetSwitch(play, thisx->params & 0x3F), thisx)) { Actor_Kill(thisx); } else { CollisionCheck_SetInfo(&thisx->colChkInfo, NULL, &sColChkInfoInit); diff --git a/soh/src/overlays/actors/ovl_Obj_Hamishi/z_obj_hamishi.c b/soh/src/overlays/actors/ovl_Obj_Hamishi/z_obj_hamishi.c index d4d952cc0bc..c609992d72b 100644 --- a/soh/src/overlays/actors/ovl_Obj_Hamishi/z_obj_hamishi.c +++ b/soh/src/overlays/actors/ovl_Obj_Hamishi/z_obj_hamishi.c @@ -6,6 +6,7 @@ #include "z_obj_hamishi.h" #include "objects/gameplay_field_keep/gameplay_field_keep.h" +#include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h" #define FLAGS 0 @@ -150,7 +151,7 @@ void ObjHamishi_Init(Actor* thisx, PlayState* play) { ObjHamishi_InitCollision(&this->actor, play); CollisionCheck_SetInfo(&this->actor.colChkInfo, NULL, &sColChkInfoInit); - if (Flags_GetSwitch(play, this->actor.params & 0x3F)) { + if (GameInteractor_Should(VB_BOULDER_BREAK_FLAG, Flags_GetSwitch(play, this->actor.params & 0x3F), this)) { Actor_Kill(&this->actor); return; } diff --git a/soh/src/overlays/actors/ovl_Object_Kankyo/z_object_kankyo.c b/soh/src/overlays/actors/ovl_Object_Kankyo/z_object_kankyo.c index 2b8cfcb7a10..8582f2e3ea3 100644 --- a/soh/src/overlays/actors/ovl_Object_Kankyo/z_object_kankyo.c +++ b/soh/src/overlays/actors/ovl_Object_Kankyo/z_object_kankyo.c @@ -8,6 +8,7 @@ #include "objects/object_demo_kekkai/object_demo_kekkai.h" #include "objects/gameplay_keep/gameplay_keep.h" #include "objects/object_spot02_objects/object_spot02_objects.h" +#include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h" #include "soh/frame_interpolation.h" #include @@ -205,23 +206,25 @@ void ObjectKankyo_Fairies(ObjectKankyo* this, PlayState* play) { dist = 1.0f; } - func_800F436C(&sSoundPos, NA_SE_EV_NAVY_FLY - SFX_FLAG, (0.4f * dist) + 0.6f); - switch (play->csCtx.frames) { - case 473: - Sfx_PlaySfxCentered2(NA_SE_VO_NA_HELLO_3); - break; + if (GameInteractor_Should(VB_PLAY_INTRO_NAVI_SOUNDS, true, this)) { + func_800F436C(&sSoundPos, NA_SE_EV_NAVY_FLY - SFX_FLAG, (0.4f * dist) + 0.6f); + switch (play->csCtx.frames) { + case 473: + Sfx_PlaySfxCentered2(NA_SE_VO_NA_HELLO_3); + break; - case 583: - func_800F4524(&gSfxDefaultPos, NA_SE_VO_NA_HELLO_2, 32); - break; + case 583: + func_800F4524(&gSfxDefaultPos, NA_SE_VO_NA_HELLO_2, 32); + break; - case 763: - Sfx_PlaySfxCentered(NA_SE_EV_NAVY_CRASH - SFX_FLAG); - break; + case 763: + Sfx_PlaySfxCentered(NA_SE_EV_NAVY_CRASH - SFX_FLAG); + break; - case 771: - Sfx_PlaySfxCentered(NA_SE_VO_RT_THROW); - break; + case 771: + Sfx_PlaySfxCentered(NA_SE_VO_RT_THROW); + break; + } } } diff --git a/soh/src/overlays/actors/ovl_player_actor/z_player.c b/soh/src/overlays/actors/ovl_player_actor/z_player.c index 617b76fec6d..ab36e244113 100644 --- a/soh/src/overlays/actors/ovl_player_actor/z_player.c +++ b/soh/src/overlays/actors/ovl_player_actor/z_player.c @@ -6306,11 +6306,13 @@ s32 func_8083BBA0(Player* this, PlayState* play) { } void Player_SetupRoll(Player* this, PlayState* play) { - Player_SetupAction(play, this, Player_Action_Roll, 0); - LinkAnimation_PlayOnceSetSpeed(play, &this->skelAnime, - GET_PLAYER_ANIM(PLAYER_ANIMGROUP_landing_roll, this->modelAnimType), - 1.25f * sWaterSpeedFactor); - gSaveContext.ship.stats.count[COUNT_ROLLS]++; + if (GameInteractor_Should(VB_ROLL, true)) { + Player_SetupAction(play, this, Player_Action_Roll, 0); + LinkAnimation_PlayOnceSetSpeed(play, &this->skelAnime, + GET_PLAYER_ANIM(PLAYER_ANIMGROUP_landing_roll, this->modelAnimType), + 1.25f * sWaterSpeedFactor); + gSaveContext.ship.stats.count[COUNT_ROLLS]++; + } } s32 Player_TryRoll(Player* this, PlayState* play) {