From 8f126344a4ef22765cfa550146f89bf428e86053 Mon Sep 17 00:00:00 2001 From: Archez Date: Tue, 1 Apr 2025 22:33:38 -0400 Subject: [PATCH] Apply clang-format to files (#5273) --- soh/platform/pathconf.c | 2 +- soh/resource.h | 12 +- soh/soh/ActorDB.cpp | 13 +- soh/soh/ActorDB.h | 5 +- soh/soh/CrashHandlerExp.h | 3 +- soh/soh/CrashHandlerExt.cpp | 6 +- .../Enhancements/AssignableTunicsAndBoots.cpp | 14 +- soh/soh/Enhancements/Cheats/DekuStick.cpp | 8 +- soh/soh/Enhancements/Cheats/FreezeTime.cpp | 3 +- .../Enhancements/Cheats/Infinite/Money.cpp | 5 +- .../Cheats/Infinite/NayrusLove.cpp | 3 +- soh/soh/Enhancements/ExtraTraps.cpp | 34 +- .../Enhancements/FileSelectEnhancements.cpp | 45 +- .../Enhancements/Presets/PresetEntries.cpp | 111 +- soh/soh/Enhancements/Presets/Presets.cpp | 15 +- .../Enhancements/RemoveSpinAttackDarkness.cpp | 7 +- .../Restorations/BottleAdventure.cpp | 375 +- .../Restorations/PauseBufferInputs.cpp | 12 +- .../Enhancements/TimeDisplay/TimeDisplay.cpp | 42 +- .../Enhancements/TimeDisplay/TimeDisplay.h | 4 +- .../TimeSavers/FasterHeavyBlockLift.cpp | 27 +- .../TimeSavers/FasterRupeeAccumulator.cpp | 19 +- .../SkipCutscene/Story/SkipBlueWarp.cpp | 70 +- .../SkipCutscene/Story/SkipDekuTreeIntro.cpp | 7 +- .../Story/SkipLostWoodsBridge.cpp | 19 +- .../Story/SkipToGivingZeldasLetter.cpp | 11 +- .../Story/SkipZeldaFleeingCastle.cpp | 22 +- .../MoveJabuJabuElevator.cpp | 25 +- .../MoveMidoInKokiriForest.cpp | 21 +- .../SkipChildRutoInteractions.cpp | 17 +- .../Enhancements/TimeSavers/TimeSavers.cpp | 20 +- soh/soh/Enhancements/TimeSavers/TimeSavers.h | 20 +- .../Enhancements/audio/AudioCollection.cpp | 30 +- soh/soh/Enhancements/audio/AudioCollection.h | 86 +- soh/soh/Enhancements/audio/AudioEditor.cpp | 158 +- soh/soh/Enhancements/audio/AudioEditor.h | 13 +- soh/soh/Enhancements/bootcommands.c | 3 +- soh/soh/Enhancements/boss-rush/BossRush.cpp | 267 +- soh/soh/Enhancements/boss-rush/BossRush.h | 12 +- soh/soh/Enhancements/controls/InputViewer.cpp | 520 +- soh/soh/Enhancements/controls/InputViewer.h | 18 +- soh/soh/Enhancements/controls/Mouse.cpp | 19 +- soh/soh/Enhancements/controls/Mouse.h | 4 +- .../controls/SohInputEditorWindow.cpp | 338 +- .../controls/SohInputEditorWindow.h | 5 +- .../cosmetics/CosmeticsEditor.cpp | 1723 ++--- .../Enhancements/cosmetics/CosmeticsEditor.h | 12 +- .../cosmetics/CustomLogoTitle.cpp | 37 +- .../Enhancements/cosmetics/NoMasterSword.cpp | 28 +- .../cosmetics/authenticGfxPatches.cpp | 12 +- .../Enhancements/cosmetics/cosmeticsTypes.h | 12 +- .../custom-message/CustomMessageManager.cpp | 234 +- .../custom-message/CustomMessageManager.h | 39 +- .../custom-message/CustomMessageTypes.h | 6 +- soh/soh/Enhancements/debugconsole.cpp | 705 ++- .../Enhancements/debugger/MessageViewer.cpp | 18 +- soh/soh/Enhancements/debugger/MessageViewer.h | 10 +- .../Enhancements/debugger/SohStatsWindow.h | 6 +- soh/soh/Enhancements/debugger/actorViewer.cpp | 386 +- soh/soh/Enhancements/debugger/actorViewer.h | 2 +- soh/soh/Enhancements/debugger/colViewer.cpp | 112 +- soh/soh/Enhancements/debugger/colViewer.h | 8 +- .../Enhancements/debugger/debugSaveEditor.cpp | 1104 ++-- .../Enhancements/debugger/debugSaveEditor.h | 3213 +++++----- soh/soh/Enhancements/debugger/dlViewer.cpp | 36 +- soh/soh/Enhancements/debugger/dlViewer.h | 2 +- soh/soh/Enhancements/debugger/hookDebugger.h | 2 +- .../debugger/performanceTimer.cpp | 8 +- .../Enhancements/debugger/performanceTimer.h | 45 +- soh/soh/Enhancements/debugger/valueViewer.cpp | 46 +- soh/soh/Enhancements/debugger/valueViewer.h | 2 +- soh/soh/Enhancements/enemyrandomizer.cpp | 197 +- soh/soh/Enhancements/enemyrandomizer.h | 3 +- .../game-interactor/GameInteractionEffect.cpp | 1224 ++-- .../game-interactor/GameInteractionEffect.h | 414 +- .../game-interactor/GameInteractor.cpp | 7 +- .../GameInteractor_HookTable.h | 4 +- .../game-interactor/GameInteractor_Hooks.cpp | 7 +- .../game-interactor/GameInteractor_Hooks.h | 4 +- .../GameInteractor_RawAction.cpp | 77 +- .../vanilla-behavior/GIVanillaBehavior.h | 20 +- soh/soh/Enhancements/gameconsole.c | 3 +- soh/soh/Enhancements/gameconsole.h | 11 +- soh/soh/Enhancements/gameplaystats.cpp | 219 +- soh/soh/Enhancements/gameplaystats.h | 62 +- soh/soh/Enhancements/gameplaystatswindow.h | 2 +- .../item-tables/ItemTableManager.h | 18 +- .../Enhancements/item-tables/ItemTableTypes.h | 26 +- soh/soh/Enhancements/kaleido.cpp | 750 ++- soh/soh/Enhancements/kaleido.h | 42 +- soh/soh/Enhancements/mods.cpp | 439 +- soh/soh/Enhancements/nametag.cpp | 37 +- soh/soh/Enhancements/nametag.h | 4 +- soh/soh/Enhancements/pausewarp.c | 75 +- .../randomizer/3drando/custom_messages.cpp | 108 +- .../Enhancements/randomizer/3drando/fill.cpp | 2208 +++---- .../randomizer/3drando/hint_list.cpp | 2 +- .../hint_list/hint_list_exclude_dungeon.cpp | 2 +- .../hint_list/hint_list_exclude_overworld.cpp | 2 +- .../3drando/hint_list/hint_list_item.cpp | 2 +- .../Enhancements/randomizer/3drando/hints.cpp | 1025 +-- .../randomizer/3drando/item_pool.cpp | 2512 ++++---- .../Enhancements/randomizer/3drando/menu.cpp | 6 +- .../randomizer/3drando/playthrough.cpp | 12 +- .../randomizer/3drando/rando_main.cpp | 2 +- .../randomizer/3drando/random.cpp | 12 +- .../Enhancements/randomizer/3drando/shops.cpp | 1187 ++-- .../randomizer/3drando/spoiler_log.cpp | 260 +- .../randomizer/3drando/starting_inventory.cpp | 332 +- .../randomizer/ColoredMapsAndCompasses.cpp | 16 +- .../randomizer/LockOverworldDoors.cpp | 23 +- .../Enhancements/randomizer/Plandomizer.cpp | 732 +-- .../Enhancements/randomizer/ShuffleCows.cpp | 6 +- .../Enhancements/randomizer/ShuffleCrates.cpp | 201 +- .../Enhancements/randomizer/ShuffleCrates.h | 2 +- .../randomizer/ShuffleFairies.cpp | 40 +- .../randomizer/ShuffleFreestanding.cpp | 15 +- .../Enhancements/randomizer/ShuffleGrass.cpp | 18 +- .../Enhancements/randomizer/ShuffleGrass.h | 2 +- .../Enhancements/randomizer/ShufflePots.cpp | 12 +- soh/soh/Enhancements/randomizer/ShufflePots.h | 2 +- .../randomizer/ShuffleTradeItems.c | 8 +- soh/soh/Enhancements/randomizer/context.cpp | 107 +- soh/soh/Enhancements/randomizer/context.h | 3 +- soh/soh/Enhancements/randomizer/draw.cpp | 226 +- soh/soh/Enhancements/randomizer/draw.h | 7 +- soh/soh/Enhancements/randomizer/dungeon.cpp | 68 +- soh/soh/Enhancements/randomizer/dungeon.h | 7 +- soh/soh/Enhancements/randomizer/entrance.cpp | 56 +- soh/soh/Enhancements/randomizer/entrance.h | 7 +- .../Enhancements/randomizer/fishsanity.cpp | 862 +-- soh/soh/Enhancements/randomizer/fishsanity.h | 90 +- soh/soh/Enhancements/randomizer/hint.cpp | 1153 ++-- soh/soh/Enhancements/randomizer/hint.h | 127 +- .../Enhancements/randomizer/hook_handlers.cpp | 783 +-- soh/soh/Enhancements/randomizer/item.cpp | 59 +- soh/soh/Enhancements/randomizer/item.h | 11 +- .../Enhancements/randomizer/item_location.cpp | 28 +- .../Enhancements/randomizer/item_location.h | 4 +- .../Enhancements/randomizer/item_override.cpp | 6 +- .../Enhancements/randomizer/item_override.h | 3 +- soh/soh/Enhancements/randomizer/location.cpp | 382 +- soh/soh/Enhancements/randomizer/location.h | 263 +- .../randomizer/location_access.cpp | 309 +- .../Enhancements/randomizer/location_access.h | 484 +- .../Enhancements/randomizer/location_list.cpp | 9 +- soh/soh/Enhancements/randomizer/logic.cpp | 4676 +++++++------- soh/soh/Enhancements/randomizer/logic.h | 16 +- soh/soh/Enhancements/randomizer/option.cpp | 77 +- soh/soh/Enhancements/randomizer/option.h | 88 +- .../randomizer/option_descriptions.cpp | 313 +- .../Enhancements/randomizer/randomizer.cpp | 5514 ++++++++++------- soh/soh/Enhancements/randomizer/randomizer.h | 10 +- .../Enhancements/randomizer/randomizerTypes.h | 138 +- .../randomizer/randomizer_check_objects.cpp | 88 +- .../randomizer/randomizer_check_objects.h | 16 +- .../randomizer/randomizer_check_tracker.cpp | 975 +-- .../randomizer/randomizer_check_tracker.h | 28 +- .../randomizer/randomizer_entrance.c | 206 +- .../randomizer/randomizer_entrance.h | 14 +- .../randomizer_entrance_tracker.cpp | 164 +- .../randomizer/randomizer_entrance_tracker.h | 14 +- .../randomizer/randomizer_grotto.c | 55 +- .../Enhancements/randomizer/randomizer_inf.h | 7 +- .../randomizer/randomizer_item_tracker.cpp | 997 +-- .../randomizer/randomizer_item_tracker.h | 20 +- soh/soh/Enhancements/randomizer/savefile.cpp | 47 +- soh/soh/Enhancements/randomizer/settings.cpp | 2427 +++++--- soh/soh/Enhancements/randomizer/settings.h | 8 +- .../Enhancements/randomizer/static_data.cpp | 481 +- soh/soh/Enhancements/randomizer/static_data.h | 125 +- soh/soh/Enhancements/randomizer/trial.cpp | 8 +- soh/soh/Enhancements/randomizer/trial.h | 4 +- soh/soh/Enhancements/randomizer/tricks.cpp | 193 +- soh/soh/Enhancements/randomizer/tricks.h | 40 +- soh/soh/Enhancements/savestates.cpp | 113 +- soh/soh/Enhancements/savestates.h | 11 +- .../Enhancements/timesaver_hook_handlers.cpp | 439 +- .../Enhancements/timesplits/TimeSplits.cpp | 150 +- soh/soh/Enhancements/tts/tts.cpp | 508 +- soh/soh/Extractor/Extract.cpp | 66 +- soh/soh/Extractor/Extract.h | 8 +- soh/soh/Extractor/FastCrc32C.c | 11 +- soh/soh/Extractor/portable-file-dialogs.h | 997 ++- soh/soh/GbiWrap.cpp | 19 +- soh/soh/Network/CrowdControl/CrowdControl.cpp | 19 +- soh/soh/Network/CrowdControl/CrowdControl.h | 128 +- soh/soh/Network/Sail/Sail.cpp | 164 +- soh/soh/Notification/Notification.cpp | 39 +- soh/soh/Notification/Notification.h | 4 +- soh/soh/OTRGlobals.cpp | 676 +- soh/soh/OTRGlobals.h | 53 +- soh/soh/ResourceManagerHelpers.cpp | 85 +- soh/soh/ResourceManagerHelpers.h | 92 +- soh/soh/SaveManager.cpp | 588 +- soh/soh/ShipUtils.cpp | 22 +- soh/soh/SohGui/ImGuiUtils.cpp | 92 +- soh/soh/SohGui/ImGuiUtils.h | 22 +- soh/soh/SohGui/Menu.cpp | 28 +- soh/soh/SohGui/MenuTypes.h | 10 +- soh/soh/SohGui/ResolutionEditor.cpp | 537 +- soh/soh/SohGui/ResolutionEditor.h | 2 +- soh/soh/SohGui/SohGui.cpp | 384 +- soh/soh/SohGui/SohMenu.cpp | 4 +- soh/soh/SohGui/SohMenu.h | 59 +- soh/soh/SohGui/SohMenuBar.cpp | 16 +- soh/soh/SohGui/SohMenuBar.h | 3 +- soh/soh/SohGui/SohMenuDevTools.cpp | 14 +- soh/soh/SohGui/SohMenuEnhancements.cpp | 501 +- soh/soh/SohGui/SohMenuNetwork.cpp | 170 +- soh/soh/SohGui/SohMenuRandomizer.cpp | 71 +- soh/soh/SohGui/SohMenuSettings.cpp | 115 +- soh/soh/SohGui/SohModals.cpp | 8 +- soh/soh/SohGui/SohModals.h | 8 +- soh/soh/SohGui/UIWidgets.cpp | 73 +- soh/soh/config/ConfigMigrators.h | 2940 ++++----- soh/soh/config/ConfigUpdaters.cpp | 199 +- soh/soh/config/ConfigUpdaters.h | 32 +- soh/soh/frame_interpolation.cpp | 642 +- soh/soh/mixer.c | 294 +- .../resource/importer/AnimationFactory.cpp | 4 +- soh/soh/resource/importer/AnimationFactory.h | 3 +- soh/soh/resource/importer/ArrayFactory.cpp | 6 +- soh/soh/resource/importer/ArrayFactory.h | 5 +- .../resource/importer/AudioSampleFactory.cpp | 10 +- .../resource/importer/AudioSampleFactory.h | 3 +- .../importer/AudioSequenceFactory.cpp | 6 +- .../resource/importer/AudioSequenceFactory.h | 3 +- .../importer/AudioSoundFontFactory.cpp | 19 +- .../resource/importer/AudioSoundFontFactory.h | 3 +- .../resource/importer/BackgroundFactory.cpp | 4 +- soh/soh/resource/importer/BackgroundFactory.h | 3 +- .../importer/CollisionHeaderFactory.cpp | 23 +- .../importer/CollisionHeaderFactory.h | 6 +- soh/soh/resource/importer/CutsceneFactory.cpp | 4 +- soh/soh/resource/importer/CutsceneFactory.h | 3 +- soh/soh/resource/importer/PathFactory.cpp | 20 +- soh/soh/resource/importer/PathFactory.h | 6 +- .../importer/PlayerAnimationFactory.cpp | 4 +- .../importer/PlayerAnimationFactory.h | 3 +- soh/soh/resource/importer/SceneFactory.cpp | 31 +- soh/soh/resource/importer/SceneFactory.h | 21 +- soh/soh/resource/importer/SkeletonFactory.cpp | 21 +- soh/soh/resource/importer/SkeletonFactory.h | 6 +- .../resource/importer/SkeletonLimbFactory.cpp | 28 +- .../resource/importer/SkeletonLimbFactory.h | 6 +- soh/soh/resource/importer/TextFactory.cpp | 11 +- soh/soh/resource/importer/TextFactory.h | 6 +- .../scenecommand/EndMarkerFactory.cpp | 4 +- .../importer/scenecommand/EndMarkerFactory.h | 7 +- .../scenecommand/SceneCommandFactory.cpp | 3 +- .../scenecommand/SceneCommandFactory.h | 18 +- .../scenecommand/SetActorListFactory.cpp | 8 +- .../scenecommand/SetActorListFactory.h | 8 +- .../SetAlternateHeadersFactory.cpp | 28 +- .../scenecommand/SetAlternateHeadersFactory.h | 8 +- .../scenecommand/SetCameraSettingsFactory.cpp | 12 +- .../scenecommand/SetCameraSettingsFactory.h | 8 +- .../SetCollisionHeaderFactory.cpp | 18 +- .../scenecommand/SetCollisionHeaderFactory.h | 8 +- .../scenecommand/SetCsCameraFactory.cpp | 8 +- .../scenecommand/SetCsCameraFactory.h | 8 +- .../scenecommand/SetCutscenesFactory.cpp | 14 +- .../scenecommand/SetCutscenesFactory.h | 8 +- .../scenecommand/SetEchoSettingsFactory.cpp | 11 +- .../scenecommand/SetEchoSettingsFactory.h | 8 +- .../scenecommand/SetEntranceListFactory.cpp | 19 +- .../scenecommand/SetEntranceListFactory.h | 8 +- .../scenecommand/SetExitListFactory.cpp | 10 +- .../scenecommand/SetExitListFactory.h | 8 +- .../scenecommand/SetLightListFactory.cpp | 16 +- .../scenecommand/SetLightListFactory.h | 8 +- .../SetLightingSettingsFactory.cpp | 10 +- .../scenecommand/SetLightingSettingsFactory.h | 8 +- .../importer/scenecommand/SetMeshFactory.cpp | 44 +- .../importer/scenecommand/SetMeshFactory.h | 8 +- .../scenecommand/SetObjectListFactory.cpp | 8 +- .../scenecommand/SetObjectListFactory.h | 8 +- .../scenecommand/SetPathwaysFactory.cpp | 14 +- .../scenecommand/SetPathwaysFactory.h | 8 +- .../scenecommand/SetRoomBehaviorFactory.cpp | 11 +- .../scenecommand/SetRoomBehaviorFactory.h | 8 +- .../scenecommand/SetRoomListFactory.cpp | 18 +- .../scenecommand/SetRoomListFactory.h | 8 +- .../scenecommand/SetSkyboxModifierFactory.cpp | 14 +- .../scenecommand/SetSkyboxModifierFactory.h | 8 +- .../scenecommand/SetSkyboxSettingsFactory.cpp | 12 +- .../scenecommand/SetSkyboxSettingsFactory.h | 8 +- .../scenecommand/SetSoundSettingsFactory.cpp | 9 +- .../scenecommand/SetSoundSettingsFactory.h | 8 +- .../scenecommand/SetSpecialObjectsFactory.cpp | 12 +- .../scenecommand/SetSpecialObjectsFactory.h | 8 +- .../SetStartPositionListFactory.cpp | 12 +- .../SetStartPositionListFactory.h | 8 +- .../scenecommand/SetTimeSettingsFactory.cpp | 11 +- .../scenecommand/SetTimeSettingsFactory.h | 8 +- .../SetTransitionActorListFactory.cpp | 14 +- .../SetTransitionActorListFactory.h | 8 +- .../scenecommand/SetWindSettingsFactory.cpp | 11 +- .../scenecommand/SetWindSettingsFactory.h | 8 +- soh/soh/resource/logging/PathLogger.cpp | 42 +- soh/soh/resource/logging/PathLogger.h | 2 +- .../resource/logging/SceneCommandLoggers.cpp | 10 +- .../resource/logging/SceneCommandLoggers.h | 2 +- soh/soh/resource/type/Animation.cpp | 4 +- soh/soh/resource/type/Animation.h | 17 +- soh/soh/resource/type/Array.cpp | 2 +- soh/soh/resource/type/Array.h | 2 +- soh/soh/resource/type/AudioSample.h | 99 +- soh/soh/resource/type/AudioSequence.h | 7 +- soh/soh/resource/type/AudioSoundFont.h | 9 +- soh/soh/resource/type/Background.h | 5 +- soh/soh/resource/type/CollisionHeader.h | 12 +- soh/soh/resource/type/Cutscene.cpp | 2 +- soh/soh/resource/type/Cutscene.h | 4 +- soh/soh/resource/type/Path.h | 13 +- soh/soh/resource/type/PlayerAnimation.cpp | 2 +- soh/soh/resource/type/PlayerAnimation.h | 3 +- soh/soh/resource/type/Scene.cpp | 2 +- soh/soh/resource/type/Scene.h | 13 +- soh/soh/resource/type/Skeleton.cpp | 31 +- soh/soh/resource/type/Skeleton.h | 12 +- soh/soh/resource/type/SkeletonLimb.cpp | 2 +- soh/soh/resource/type/SkeletonLimb.h | 33 +- soh/soh/resource/type/Text.cpp | 2 +- soh/soh/resource/type/Text.h | 22 +- .../resource/type/scenecommand/EndMarker.cpp | 2 +- .../resource/type/scenecommand/EndMarker.h | 2 +- soh/soh/resource/type/scenecommand/RomFile.h | 12 +- .../resource/type/scenecommand/SceneCommand.h | 7 +- .../type/scenecommand/SetActorList.cpp | 2 +- .../resource/type/scenecommand/SetActorList.h | 6 +- .../type/scenecommand/SetAlternateHeaders.h | 3 +- .../type/scenecommand/SetCameraSettings.cpp | 2 +- .../type/scenecommand/SetCameraSettings.h | 6 +- .../type/scenecommand/SetCollisionHeader.cpp | 2 +- .../type/scenecommand/SetCollisionHeader.h | 2 +- .../type/scenecommand/SetCsCamera.cpp | 2 +- .../resource/type/scenecommand/SetCsCamera.h | 2 +- .../type/scenecommand/SetCutscenes.cpp | 2 +- .../resource/type/scenecommand/SetCutscenes.h | 2 +- .../type/scenecommand/SetEchoSettings.cpp | 2 +- .../type/scenecommand/SetEchoSettings.h | 4 +- .../type/scenecommand/SetEntranceList.cpp | 2 +- .../type/scenecommand/SetEntranceList.h | 2 +- .../type/scenecommand/SetExitList.cpp | 2 +- .../resource/type/scenecommand/SetExitList.h | 2 +- .../type/scenecommand/SetLightList.cpp | 2 +- .../resource/type/scenecommand/SetLightList.h | 2 +- .../type/scenecommand/SetLightingSettings.cpp | 2 +- .../type/scenecommand/SetLightingSettings.h | 2 +- .../resource/type/scenecommand/SetMesh.cpp | 2 +- soh/soh/resource/type/scenecommand/SetMesh.h | 56 +- .../type/scenecommand/SetObjectList.cpp | 2 +- .../type/scenecommand/SetObjectList.h | 2 +- .../resource/type/scenecommand/SetPathways.h | 2 +- .../type/scenecommand/SetRoomBehavior.cpp | 2 +- .../type/scenecommand/SetRoomBehavior.h | 6 +- .../type/scenecommand/SetRoomList.cpp | 2 +- .../resource/type/scenecommand/SetRoomList.h | 3 +- .../type/scenecommand/SetSkyboxModifier.cpp | 2 +- .../type/scenecommand/SetSkyboxModifier.h | 6 +- .../type/scenecommand/SetSkyboxSettings.cpp | 2 +- .../type/scenecommand/SetSkyboxSettings.h | 10 +- .../type/scenecommand/SetSoundSettings.cpp | 2 +- .../type/scenecommand/SetSoundSettings.h | 8 +- .../type/scenecommand/SetSpecialObjects.cpp | 2 +- .../type/scenecommand/SetSpecialObjects.h | 6 +- .../scenecommand/SetStartPositionList.cpp | 2 +- .../type/scenecommand/SetStartPositionList.h | 2 +- .../type/scenecommand/SetTimeSettings.cpp | 2 +- .../type/scenecommand/SetTimeSettings.h | 8 +- .../scenecommand/SetTransitionActorList.cpp | 2 +- .../scenecommand/SetTransitionActorList.h | 12 +- .../type/scenecommand/SetWindSettings.cpp | 2 +- .../type/scenecommand/SetWindSettings.h | 10 +- soh/soh/stubs.c | 238 +- soh/soh/util.cpp | 40 +- soh/soh/util.h | 24 +- soh/soh/z_message_OTR.cpp | 37 +- soh/soh/z_play_otr.cpp | 19 +- soh/soh/z_scene_otr.cpp | 13 +- soh/src/boot/boot_main.c | 2 +- soh/src/boot/idle.c | 9 +- soh/src/boot/is_debug.c | 2 +- soh/src/boot/z_std_dma.c | 14 +- soh/src/buffers/heaps.c | 6 +- soh/src/code/PreRender.c | 4 +- soh/src/code/TwoHeadArena.c | 2 +- soh/src/code/__osMalloc.c | 11 +- soh/src/code/audioMgr.c | 55 +- soh/src/code/audio_data.c | 6 +- soh/src/code/audio_effects.c | 2 +- soh/src/code/audio_heap.c | 3 +- soh/src/code/audio_load.c | 144 +- soh/src/code/audio_playback.c | 4 +- soh/src/code/audio_seqplayer.c | 25 +- soh/src/code/audio_synthesis.c | 24 +- soh/src/code/code_800A9F30.c | 1 - soh/src/code/code_800D2E30.c | 2 +- soh/src/code/code_800E4FE0.c | 8 +- soh/src/code/code_800EC960.c | 112 +- soh/src/code/code_800F7260.c | 24 +- soh/src/code/code_800F9280.c | 18 +- soh/src/code/code_800FC620.c | 3 +- soh/src/code/db_camera.c | 179 +- soh/src/code/fault.c | 49 +- soh/src/code/game.c | 10 +- soh/src/code/graph.c | 46 +- soh/src/code/loadfragment2.c | 3 +- soh/src/code/main.c | 6 +- soh/src/code/padmgr.c | 21 +- soh/src/code/padutils.c | 2 +- soh/src/code/relocation.c | 4 +- soh/src/code/sched.c | 2 +- soh/src/code/sys_cfb.c | 10 +- soh/src/code/sys_matrix.c | 13 +- soh/src/code/z_DLF.c | 31 +- soh/src/code/z_actor.c | 310 +- soh/src/code/z_bgcheck.c | 42 +- soh/src/code/z_camera.c | 67 +- soh/src/code/z_cheap_proc.c | 16 +- soh/src/code/z_collision_check.c | 171 +- soh/src/code/z_construct.c | 4 +- soh/src/code/z_debug.c | 58 +- soh/src/code/z_debug_display.c | 6 +- soh/src/code/z_demo.c | 111 +- soh/src/code/z_draw.c | 225 +- soh/src/code/z_eff_blure.c | 4 +- soh/src/code/z_eff_shield_particle.c | 2 +- soh/src/code/z_effect_soft_sprite.c | 15 +- soh/src/code/z_effect_soft_sprite_dlftbls.c | 12 +- soh/src/code/z_effect_soft_sprite_old_init.c | 92 +- soh/src/code/z_elf_message.c | 2 +- soh/src/code/z_en_a_keep.c | 8 +- soh/src/code/z_en_item00.c | 95 +- soh/src/code/z_face_reaction.c | 4 +- soh/src/code/z_fbdemo_circle.c | 6 +- soh/src/code/z_fbdemo_triforce.c | 2 +- soh/src/code/z_fcurve_data_skelanime.c | 11 +- soh/src/code/z_frame_advance.c | 4 +- soh/src/code/z_game_over.c | 5 +- soh/src/code/z_horse.c | 62 +- soh/src/code/z_inventory.c | 3 +- soh/src/code/z_jpeg.c | 3 +- soh/src/code/z_kaleido_manager.c | 14 +- soh/src/code/z_kaleido_scope_call.c | 12 +- soh/src/code/z_kaleido_setup.c | 8 +- soh/src/code/z_kanfont.c | 21 +- soh/src/code/z_kankyo.c | 186 +- soh/src/code/z_lifemeter.c | 59 +- soh/src/code/z_lights.c | 5 +- soh/src/code/z_malloc.c | 2 +- soh/src/code/z_map_data.c | 35 +- soh/src/code/z_map_exp.c | 286 +- soh/src/code/z_map_mark.c | 98 +- soh/src/code/z_message_PAL.c | 476 +- soh/src/code/z_moji.c | 8 +- soh/src/code/z_olib.c | 1 - soh/src/code/z_onepointdemo.c | 11 +- soh/src/code/z_parameter.c | 1682 ++--- soh/src/code/z_play.c | 130 +- soh/src/code/z_player_call.c | 4 +- soh/src/code/z_player_lib.c | 494 +- soh/src/code/z_rcp.c | 12 +- soh/src/code/z_room.c | 55 +- soh/src/code/z_scene.c | 23 +- soh/src/code/z_scene_table.c | 292 +- soh/src/code/z_skelanime.c | 127 +- soh/src/code/z_skin_awb.c | 6 +- soh/src/code/z_sound_source.c | 3 +- soh/src/code/z_sram.c | 34 +- soh/src/code/z_ss_sram.c | 8 +- soh/src/code/z_view.c | 26 +- soh/src/code/z_vismono.c | 2 +- soh/src/code/z_vr_box.c | 739 +-- soh/src/code/z_vr_box_draw.c | 4 +- soh/src/libultra/gu/guLookAt.c | 4 +- soh/src/libultra/gu/guPerspectiveF.c | 2 +- soh/src/libultra/gu/ortho.c | 2 +- soh/src/libultra/libc/sprintf.c | 6 +- .../actors/ovl_Arms_Hook/z_arms_hook.c | 24 +- .../actors/ovl_Arrow_Fire/z_arrow_fire.c | 18 +- .../actors/ovl_Arrow_Ice/z_arrow_ice.c | 18 +- .../actors/ovl_Arrow_Light/z_arrow_light.c | 18 +- .../ovl_Bg_Bdan_Objects/z_bg_bdan_objects.c | 12 +- .../ovl_Bg_Bdan_Switch/z_bg_bdan_switch.c | 3 +- .../actors/ovl_Bg_Bowl_Wall/z_bg_bowl_wall.c | 6 +- .../actors/ovl_Bg_Breakwall/z_bg_breakwall.c | 26 +- .../actors/ovl_Bg_Ddan_Kd/z_bg_ddan_kd.c | 4 +- .../actors/ovl_Bg_Dodoago/z_bg_dodoago.c | 22 +- .../ovl_Bg_Dy_Yoseizo/z_bg_dy_yoseizo.c | 36 +- .../ovl_Bg_Ganon_Otyuka/z_bg_ganon_otyuka.c | 14 +- .../ovl_Bg_Gate_Shutter/z_bg_gate_shutter.c | 3 +- .../ovl_Bg_Gjyo_Bridge/z_bg_gjyo_bridge.c | 20 +- .../ovl_Bg_Gnd_Darkmeiro/z_bg_gnd_darkmeiro.c | 6 +- .../ovl_Bg_Gnd_Firemeiro/z_bg_gnd_firemeiro.c | 6 +- .../ovl_Bg_Gnd_Soulmeiro/z_bg_gnd_soulmeiro.c | 18 +- .../overlays/actors/ovl_Bg_Haka/z_bg_haka.c | 18 +- .../actors/ovl_Bg_Haka_Gate/z_bg_haka_gate.c | 13 +- .../ovl_Bg_Haka_Sgami/z_bg_haka_sgami.c | 4 +- .../actors/ovl_Bg_Haka_Ship/z_bg_haka_ship.c | 15 +- .../actors/ovl_Bg_Haka_Trap/z_bg_haka_trap.c | 9 +- .../actors/ovl_Bg_Haka_Tubo/z_bg_haka_tubo.c | 11 +- .../ovl_Bg_Haka_Water/z_bg_haka_water.c | 11 +- .../actors/ovl_Bg_Haka_Zou/z_bg_haka_zou.c | 4 +- .../ovl_Bg_Heavy_Block/z_bg_heavy_block.c | 17 +- .../ovl_Bg_Hidan_Curtain/z_bg_hidan_curtain.c | 11 +- .../z_bg_hidan_firewall.c | 3 +- .../ovl_Bg_Hidan_Fslift/z_bg_hidan_fslift.c | 6 +- .../ovl_Bg_Hidan_Fwbig/z_bg_hidan_fwbig.c | 3 +- .../ovl_Bg_Hidan_Hamstep/z_bg_hidan_hamstep.c | 11 +- .../ovl_Bg_Hidan_Kousi/z_bg_hidan_kousi.c | 3 +- .../z_bg_hidan_kowarerukabe.c | 7 +- .../ovl_Bg_Hidan_Rock/z_bg_hidan_rock.c | 8 +- .../z_bg_hidan_rsekizou.c | 7 +- .../ovl_Bg_Hidan_Sekizou/z_bg_hidan_sekizou.c | 23 +- .../ovl_Bg_Hidan_Sima/z_bg_hidan_sima.c | 14 +- .../ovl_Bg_Ice_Shelter/z_bg_ice_shelter.c | 25 +- .../ovl_Bg_Ice_Turara/z_bg_ice_turara.c | 3 +- .../actors/ovl_Bg_Ingate/z_bg_ingate.c | 3 +- .../z_bg_jya_amishutter.c | 3 +- .../ovl_Bg_Jya_Bigmirror/z_bg_jya_bigmirror.c | 15 +- .../actors/ovl_Bg_Jya_Block/z_bg_jya_block.c | 3 +- .../z_bg_jya_bombchuiwa.c | 9 +- .../actors/ovl_Bg_Jya_Cobra/z_bg_jya_cobra.c | 9 +- .../ovl_Bg_Jya_Goroiwa/z_bg_jya_goroiwa.c | 3 +- .../ovl_Bg_Jya_Ironobj/z_bg_jya_ironobj.c | 7 +- .../actors/ovl_Bg_Jya_Lift/z_bg_jya_lift.c | 9 +- .../ovl_Bg_Jya_Megami/z_bg_jya_megami.c | 8 +- .../z_bg_jya_zurerukabe.c | 3 +- .../ovl_Bg_Menkuri_Eye/z_bg_menkuri_eye.c | 3 +- .../ovl_Bg_Mizu_Bwall/z_bg_mizu_bwall.c | 48 +- .../ovl_Bg_Mizu_Movebg/z_bg_mizu_movebg.c | 13 +- .../ovl_Bg_Mizu_Shutter/z_bg_mizu_shutter.c | 3 +- .../ovl_Bg_Mizu_Water/z_bg_mizu_water.c | 3 +- .../overlays/actors/ovl_Bg_Mjin/z_bg_mjin.c | 3 +- .../ovl_Bg_Mori_Bigst/z_bg_mori_bigst.c | 26 +- .../ovl_Bg_Mori_Elevator/z_bg_mori_elevator.c | 3 +- .../ovl_Bg_Mori_Hashigo/z_bg_mori_hashigo.c | 18 +- .../ovl_Bg_Mori_Hashira4/z_bg_mori_hashira4.c | 9 +- .../ovl_Bg_Mori_Hineri/z_bg_mori_hineri.c | 27 +- .../ovl_Bg_Mori_Idomizu/z_bg_mori_idomizu.c | 6 +- .../z_bg_mori_kaitenkabe.c | 6 +- .../z_bg_mori_rakkatenjo.c | 3 +- .../actors/ovl_Bg_Po_Event/z_bg_po_event.c | 24 +- .../ovl_Bg_Po_Syokudai/z_bg_po_syokudai.c | 18 +- .../actors/ovl_Bg_Pushbox/z_bg_pushbox.c | 3 +- .../z_bg_spot00_hanebasi.c | 12 +- .../ovl_Bg_Spot01_Fusya/z_bg_spot01_fusya.c | 3 +- .../z_bg_spot01_idohashira.c | 6 +- .../z_bg_spot01_idomizu.c | 7 +- .../z_bg_spot01_idosoko.c | 9 +- .../z_bg_spot01_objects2.c | 6 +- .../z_bg_spot02_objects.c | 48 +- .../ovl_Bg_Spot03_Taki/z_bg_spot03_taki.c | 5 +- .../z_bg_spot06_objects.c | 28 +- .../ovl_Bg_Spot07_Taki/z_bg_spot07_taki.c | 10 +- .../z_bg_spot08_bakudankabe.c | 4 +- .../z_bg_spot08_iceblock.c | 3 +- .../ovl_Bg_Spot09_Obj/z_bg_spot09_obj.c | 7 +- .../z_bg_spot11_bakudankabe.c | 4 +- .../ovl_Bg_Spot11_Oasis/z_bg_spot11_oasis.c | 11 +- .../ovl_Bg_Spot15_Rrbox/z_bg_spot15_rrbox.c | 7 +- .../ovl_Bg_Spot15_Saku/z_bg_spot15_saku.c | 3 +- .../z_bg_spot16_bombstone.c | 44 +- .../z_bg_spot16_doughnut.c | 11 +- .../z_bg_spot17_bakudankabe.c | 10 +- .../ovl_Bg_Spot17_Funen/z_bg_spot17_funen.c | 6 +- .../ovl_Bg_Spot18_Basket/z_bg_spot18_basket.c | 7 +- .../ovl_Bg_Spot18_Obj/z_bg_spot18_obj.c | 3 +- .../actors/ovl_Bg_Sst_Floor/z_bg_sst_floor.c | 6 +- .../ovl_Bg_Toki_Hikari/z_bg_toki_hikari.c | 21 +- .../actors/ovl_Bg_Toki_Swd/z_bg_toki_swd.c | 13 +- .../actors/ovl_Bg_Treemouth/z_bg_treemouth.c | 12 +- .../actors/ovl_Bg_Vb_Sima/z_bg_vb_sima.c | 7 +- .../actors/ovl_Bg_Ydan_Hasi/z_bg_ydan_hasi.c | 8 +- .../actors/ovl_Bg_Ydan_Sp/z_bg_ydan_sp.c | 22 +- soh/src/overlays/actors/ovl_Bg_Zg/z_bg_zg.c | 7 +- .../actors/ovl_Boss_Dodongo/z_boss_dodongo.c | 45 +- .../overlays/actors/ovl_Boss_Fd/z_boss_fd.c | 109 +- .../overlays/actors/ovl_Boss_Fd2/z_boss_fd2.c | 33 +- .../actors/ovl_Boss_Ganon/z_boss_ganon.c | 205 +- .../actors/ovl_Boss_Ganon2/z_boss_ganon2.c | 108 +- .../ovl_Boss_Ganon2/z_boss_ganon2_data.c | 2 +- .../ovl_Boss_Ganondrof/z_boss_ganondrof.c | 42 +- .../actors/ovl_Boss_Goma/z_boss_goma.c | 59 +- .../overlays/actors/ovl_Boss_Mo/z_boss_mo.c | 92 +- .../overlays/actors/ovl_Boss_Sst/z_boss_sst.c | 82 +- .../overlays/actors/ovl_Boss_Tw/z_boss_tw.c | 287 +- .../overlays/actors/ovl_Boss_Va/z_boss_va.c | 232 +- .../overlays/actors/ovl_Demo_6K/z_demo_6k.c | 35 +- .../overlays/actors/ovl_Demo_Du/z_demo_du.c | 25 +- .../overlays/actors/ovl_Demo_Ec/z_demo_ec.c | 24 +- .../actors/ovl_Demo_Effect/z_demo_effect.c | 140 +- .../overlays/actors/ovl_Demo_Ext/z_demo_ext.c | 4 +- .../actors/ovl_Demo_Geff/z_demo_geff.c | 3 +- .../overlays/actors/ovl_Demo_Gj/z_demo_gj.c | 14 +- .../overlays/actors/ovl_Demo_Gt/z_demo_gt.c | 22 +- .../overlays/actors/ovl_Demo_Ik/z_demo_ik.c | 37 +- .../overlays/actors/ovl_Demo_Im/z_demo_im.c | 16 +- .../actors/ovl_Demo_Kankyo/z_demo_kankyo.c | 44 +- .../actors/ovl_Demo_Kekkai/z_demo_kekkai.c | 22 +- .../overlays/actors/ovl_Demo_Sa/z_demo_sa.c | 14 +- .../overlays/actors/ovl_Demo_Shd/z_demo_shd.c | 11 +- .../actors/ovl_Demo_Tre_Lgt/z_demo_tre_lgt.c | 4 +- .../overlays/actors/ovl_Door_Ana/z_door_ana.c | 10 +- .../actors/ovl_Door_Gerudo/z_door_gerudo.c | 3 +- .../actors/ovl_Door_Killer/z_door_killer.c | 18 +- .../actors/ovl_Door_Shutter/z_door_shutter.c | 50 +- .../actors/ovl_Door_Warp1/z_door_warp1.c | 76 +- .../actors/ovl_Efc_Erupc/z_efc_erupc.c | 9 +- .../overlays/actors/ovl_Eff_Dust/z_eff_dust.c | 6 +- .../overlays/actors/ovl_Elf_Msg/z_elf_msg.c | 8 +- .../overlays/actors/ovl_Elf_Msg2/z_elf_msg2.c | 11 +- soh/src/overlays/actors/ovl_En_Am/z_en_am.c | 45 +- soh/src/overlays/actors/ovl_En_Ani/z_en_ani.c | 4 +- .../actors/ovl_En_Anubice/z_en_anubice.c | 13 +- .../ovl_En_Anubice_Fire/z_en_anubice_fire.c | 3 +- .../actors/ovl_En_Arow_Trap/z_en_arow_trap.c | 6 +- .../overlays/actors/ovl_En_Arrow/z_en_arrow.c | 45 +- soh/src/overlays/actors/ovl_En_Ba/z_en_ba.c | 21 +- soh/src/overlays/actors/ovl_En_Bb/z_en_bb.c | 18 +- .../actors/ovl_En_Bdfire/z_en_bdfire.c | 7 +- .../actors/ovl_En_Bigokuta/z_en_bigokuta.c | 11 +- .../overlays/actors/ovl_En_Bili/z_en_bili.c | 14 +- .../actors/ovl_En_Blkobj/z_en_blkobj.c | 20 +- soh/src/overlays/actors/ovl_En_Bom/z_en_bom.c | 15 +- .../ovl_En_Bom_Bowl_Man/z_en_bom_bowl_man.c | 34 +- .../actors/ovl_En_Bom_Chu/z_en_bom_chu.c | 20 +- .../overlays/actors/ovl_En_Bombf/z_en_bombf.c | 29 +- .../overlays/actors/ovl_En_Boom/z_en_boom.c | 10 +- soh/src/overlays/actors/ovl_En_Box/z_en_box.c | 90 +- .../overlays/actors/ovl_En_Brob/z_en_brob.c | 4 +- .../actors/ovl_En_Bubble/z_en_bubble.c | 3 +- .../overlays/actors/ovl_En_Butte/z_en_butte.c | 6 +- soh/src/overlays/actors/ovl_En_Bw/z_en_bw.c | 38 +- soh/src/overlays/actors/ovl_En_Bx/z_en_bx.c | 6 +- .../actors/ovl_En_Changer/z_en_changer.c | 26 +- .../actors/ovl_En_Clear_Tag/z_en_clear_tag.c | 79 +- soh/src/overlays/actors/ovl_En_Cow/z_en_cow.c | 9 +- .../overlays/actors/ovl_En_Crow/z_en_crow.c | 16 +- .../overlays/actors/ovl_En_Daiku/z_en_daiku.c | 15 +- .../z_en_daiku_kakariko.c | 9 +- .../actors/ovl_En_Dekubaba/z_en_dekubaba.c | 40 +- .../actors/ovl_En_Dekunuts/z_en_dekunuts.c | 21 +- soh/src/overlays/actors/ovl_En_Dh/z_en_dh.c | 17 +- .../ovl_En_Diving_Game/z_en_diving_game.c | 11 +- soh/src/overlays/actors/ovl_En_Dns/z_en_dns.c | 20 +- .../actors/ovl_En_Dnt_Demo/z_en_dnt_demo.c | 10 +- .../actors/ovl_En_Dnt_Jiji/z_en_dnt_jiji.c | 6 +- .../actors/ovl_En_Dnt_Nomal/z_en_dnt_nomal.c | 23 +- .../actors/ovl_En_Dodojr/z_en_dodojr.c | 14 +- .../actors/ovl_En_Dodongo/z_en_dodongo.c | 13 +- soh/src/overlays/actors/ovl_En_Dog/z_en_dog.c | 9 +- .../overlays/actors/ovl_En_Door/z_en_door.c | 24 +- soh/src/overlays/actors/ovl_En_Ds/z_en_ds.c | 10 +- soh/src/overlays/actors/ovl_En_Du/z_en_du.c | 21 +- .../actors/ovl_En_Dy_Extra/z_en_dy_extra.c | 7 +- .../overlays/actors/ovl_En_Eiyer/z_en_eiyer.c | 11 +- soh/src/overlays/actors/ovl_En_Elf/z_en_elf.c | 19 +- .../actors/ovl_En_Encount1/z_en_encount1.c | 26 +- .../actors/ovl_En_Encount2/z_en_encount2.c | 17 +- .../actors/ovl_En_Ex_Item/z_en_ex_item.c | 9 +- .../actors/ovl_En_Ex_Ruppy/z_en_ex_ruppy.c | 18 +- soh/src/overlays/actors/ovl_En_Fd/z_en_fd.c | 34 +- .../actors/ovl_En_Fd_Fire/z_en_fd_fire.c | 9 +- .../actors/ovl_En_Fhg_Fire/z_en_fhg_fire.c | 59 +- .../actors/ovl_En_Fire_Rock/z_en_fire_rock.c | 11 +- .../actors/ovl_En_Firefly/z_en_firefly.c | 19 +- .../overlays/actors/ovl_En_Fish/z_en_fish.c | 11 +- .../actors/ovl_En_Floormas/z_en_floormas.c | 18 +- soh/src/overlays/actors/ovl_En_Fr/z_en_fr.c | 51 +- soh/src/overlays/actors/ovl_En_Fu/z_en_fu.c | 4 +- soh/src/overlays/actors/ovl_En_Fw/z_en_fw.c | 17 +- soh/src/overlays/actors/ovl_En_Fz/z_en_fz.c | 19 +- .../actors/ovl_En_G_Switch/z_en_g_switch.c | 60 +- .../ovl_En_Ganon_Mant/z_en_ganon_mant.c | 9 +- .../ovl_En_Ganon_Organ/z_en_ganon_organ.c | 5 +- soh/src/overlays/actors/ovl_En_Gb/z_en_gb.c | 10 +- soh/src/overlays/actors/ovl_En_Ge1/z_en_ge1.c | 11 +- soh/src/overlays/actors/ovl_En_Ge2/z_en_ge2.c | 6 +- soh/src/overlays/actors/ovl_En_Ge3/z_en_ge3.c | 2 +- .../overlays/actors/ovl_En_GeldB/z_en_geldb.c | 19 +- .../overlays/actors/ovl_En_GirlA/z_en_girla.c | 69 +- soh/src/overlays/actors/ovl_En_Gm/z_en_gm.c | 8 +- soh/src/overlays/actors/ovl_En_Go/z_en_go.c | 44 +- soh/src/overlays/actors/ovl_En_Go2/z_en_go2.c | 103 +- .../overlays/actors/ovl_En_Goma/z_en_goma.c | 38 +- .../actors/ovl_En_Goroiwa/z_en_goroiwa.c | 16 +- soh/src/overlays/actors/ovl_En_Gs/z_en_gs.c | 46 +- .../overlays/actors/ovl_En_Guest/z_en_guest.c | 6 +- .../overlays/actors/ovl_En_Hata/z_en_hata.c | 4 +- .../actors/ovl_En_Heishi1/z_en_heishi1.c | 19 +- .../actors/ovl_En_Heishi2/z_en_heishi2.c | 19 +- .../actors/ovl_En_Heishi3/z_en_heishi3.c | 10 +- .../actors/ovl_En_Heishi4/z_en_heishi4.c | 21 +- .../actors/ovl_En_Hintnuts/z_en_hintnuts.c | 22 +- .../overlays/actors/ovl_En_Holl/z_en_holl.c | 3 +- .../actors/ovl_En_Honotrap/z_en_honotrap.c | 6 +- .../overlays/actors/ovl_En_Horse/z_en_horse.c | 187 +- .../z_en_horse_game_check.c | 15 +- .../ovl_En_Horse_Ganon/z_en_horse_ganon.c | 10 +- .../z_en_horse_link_child.c | 27 +- .../ovl_En_Horse_Normal/z_en_horse_normal.c | 54 +- .../ovl_En_Horse_Zelda/z_en_horse_zelda.c | 3 +- soh/src/overlays/actors/ovl_En_Hy/z_en_hy.c | 51 +- .../actors/ovl_En_Ice_Hono/z_en_ice_hono.c | 16 +- soh/src/overlays/actors/ovl_En_Ik/z_en_ik.c | 101 +- soh/src/overlays/actors/ovl_En_In/z_en_in.c | 20 +- .../actors/ovl_En_Insect/z_en_insect.c | 6 +- .../overlays/actors/ovl_En_Ishi/z_en_ishi.c | 12 +- soh/src/overlays/actors/ovl_En_Jj/z_en_jj.c | 7 +- soh/src/overlays/actors/ovl_En_Js/z_en_js.c | 9 +- .../actors/ovl_En_Jsjutan/z_en_jsjutan.c | 6 +- .../actors/ovl_En_Kakasi2/z_en_kakasi2.c | 12 +- .../actors/ovl_En_Kakasi3/z_en_kakasi3.c | 3 +- .../actors/ovl_En_Kanban/z_en_kanban.c | 16 +- .../actors/ovl_En_Karebaba/z_en_karebaba.c | 22 +- soh/src/overlays/actors/ovl_En_Ko/z_en_ko.c | 32 +- soh/src/overlays/actors/ovl_En_Kz/z_en_kz.c | 23 +- .../overlays/actors/ovl_En_Light/z_en_light.c | 8 +- .../actors/ovl_En_Lightbox/z_en_lightbox.c | 8 +- .../actors/ovl_En_M_Thunder/z_en_m_thunder.c | 70 +- soh/src/overlays/actors/ovl_En_Ma1/z_en_ma1.c | 32 +- soh/src/overlays/actors/ovl_En_Ma2/z_en_ma2.c | 7 +- soh/src/overlays/actors/ovl_En_Ma3/z_en_ma3.c | 4 +- soh/src/overlays/actors/ovl_En_Mag/z_en_mag.c | 46 +- soh/src/overlays/actors/ovl_En_Mb/z_en_mb.c | 32 +- soh/src/overlays/actors/ovl_En_Md/z_en_md.c | 45 +- soh/src/overlays/actors/ovl_En_Mk/z_en_mk.c | 5 +- soh/src/overlays/actors/ovl_En_Ms/z_en_ms.c | 8 +- soh/src/overlays/actors/ovl_En_Nb/z_en_nb.c | 19 +- soh/src/overlays/actors/ovl_En_Niw/z_en_niw.c | 7 +- .../actors/ovl_En_Niw_Girl/z_en_niw_girl.c | 6 +- .../actors/ovl_En_Niw_Lady/z_en_niw_lady.c | 13 +- .../actors/ovl_En_Nutsball/z_en_nutsball.c | 19 +- soh/src/overlays/actors/ovl_En_Nwc/z_en_nwc.c | 3 +- soh/src/overlays/actors/ovl_En_Ny/z_en_ny.c | 13 +- .../z_en_okarina_effect.c | 4 +- .../ovl_En_Okarina_Tag/z_en_okarina_tag.c | 18 +- .../overlays/actors/ovl_En_Okuta/z_en_okuta.c | 30 +- .../overlays/actors/ovl_En_Ossan/z_en_ossan.c | 63 +- soh/src/overlays/actors/ovl_En_Owl/z_en_owl.c | 20 +- .../overlays/actors/ovl_En_Part/z_en_part.c | 15 +- .../actors/ovl_En_Partner/z_en_partner.c | 33 +- .../actors/ovl_En_Peehat/z_en_peehat.c | 28 +- .../actors/ovl_En_Po_Desert/z_en_po_desert.c | 17 +- .../actors/ovl_En_Po_Field/z_en_po_field.c | 69 +- .../actors/ovl_En_Po_Relay/z_en_po_relay.c | 46 +- .../ovl_En_Po_Sisters/z_en_po_sisters.c | 38 +- soh/src/overlays/actors/ovl_En_Poh/z_en_poh.c | 67 +- .../actors/ovl_En_Pu_box/z_en_pu_box.c | 4 +- soh/src/overlays/actors/ovl_En_Rd/z_en_rd.c | 60 +- .../overlays/actors/ovl_En_Reeba/z_en_reeba.c | 12 +- .../ovl_En_River_Sound/z_en_river_sound.c | 9 +- soh/src/overlays/actors/ovl_En_Rl/z_en_rl.c | 10 +- soh/src/overlays/actors/ovl_En_Rr/z_en_rr.c | 15 +- soh/src/overlays/actors/ovl_En_Ru1/z_en_ru1.c | 52 +- soh/src/overlays/actors/ovl_En_Ru2/z_en_ru2.c | 7 +- soh/src/overlays/actors/ovl_En_Sa/z_en_sa.c | 25 +- soh/src/overlays/actors/ovl_En_Sda/z_en_sda.c | 9 +- .../actors/ovl_En_Shopnuts/z_en_shopnuts.c | 19 +- soh/src/overlays/actors/ovl_En_Si/z_en_si.c | 3 +- .../actors/ovl_En_Siofuki/z_en_siofuki.c | 3 +- soh/src/overlays/actors/ovl_En_Skb/z_en_skb.c | 9 +- soh/src/overlays/actors/ovl_En_Skj/z_en_skj.c | 51 +- .../actors/ovl_En_Skjneedle/z_en_skjneedle.c | 3 +- soh/src/overlays/actors/ovl_En_Ssh/z_en_ssh.c | 18 +- soh/src/overlays/actors/ovl_En_St/z_en_st.c | 7 +- soh/src/overlays/actors/ovl_En_Sth/z_en_sth.c | 15 +- .../actors/ovl_En_Stream/z_en_stream.c | 7 +- soh/src/overlays/actors/ovl_En_Sw/z_en_sw.c | 39 +- .../ovl_En_Syateki_Itm/z_en_syateki_itm.c | 22 +- .../ovl_En_Syateki_Man/z_en_syateki_man.c | 27 +- .../ovl_En_Syateki_Niw/z_en_syateki_niw.c | 10 +- soh/src/overlays/actors/ovl_En_Ta/z_en_ta.c | 6 +- .../ovl_En_Takara_Man/z_en_takara_man.c | 13 +- .../overlays/actors/ovl_En_Tana/z_en_tana.c | 6 +- .../overlays/actors/ovl_En_Test/z_en_test.c | 17 +- .../overlays/actors/ovl_En_Tite/z_en_tite.c | 23 +- soh/src/overlays/actors/ovl_En_Tk/z_en_tk.c | 19 +- .../actors/ovl_En_Torch2/z_en_torch2.c | 48 +- .../overlays/actors/ovl_En_Toryo/z_en_toryo.c | 6 +- soh/src/overlays/actors/ovl_En_Tp/z_en_tp.c | 43 +- soh/src/overlays/actors/ovl_En_Tr/z_en_tr.c | 13 +- .../actors/ovl_En_Tubo_Trap/z_en_tubo_trap.c | 10 +- .../overlays/actors/ovl_En_Vali/z_en_vali.c | 26 +- .../actors/ovl_En_Vb_Ball/z_en_vb_ball.c | 33 +- .../actors/ovl_En_Viewer/z_en_viewer.c | 75 +- soh/src/overlays/actors/ovl_En_Vm/z_en_vm.c | 25 +- .../actors/ovl_En_Wallmas/z_en_wallmas.c | 27 +- .../ovl_En_Weather_Tag/z_en_weather_tag.c | 9 +- .../actors/ovl_En_Weiyer/z_en_weiyer.c | 11 +- soh/src/overlays/actors/ovl_En_Wf/z_en_wf.c | 7 +- .../ovl_En_Wonder_Item/z_en_wonder_item.c | 5 +- .../ovl_En_Wonder_Talk/z_en_wonder_talk.c | 10 +- .../actors/ovl_En_Wood02/z_en_wood02.c | 29 +- soh/src/overlays/actors/ovl_En_Xc/z_en_xc.c | 38 +- .../actors/ovl_En_Yukabyun/z_en_yukabyun.c | 3 +- soh/src/overlays/actors/ovl_En_Zf/z_en_zf.c | 48 +- soh/src/overlays/actors/ovl_En_Zl1/z_en_zl1.c | 10 +- soh/src/overlays/actors/ovl_En_Zl2/z_en_zl2.c | 13 +- soh/src/overlays/actors/ovl_En_Zl3/z_en_zl3.c | 29 +- soh/src/overlays/actors/ovl_En_Zl4/z_en_zl4.c | 4 +- soh/src/overlays/actors/ovl_En_Zo/z_en_zo.c | 15 +- soh/src/overlays/actors/ovl_En_fHG/z_en_fhg.c | 17 +- .../actors/ovl_End_Title/z_end_title.c | 7 +- .../overlays/actors/ovl_Fishing/z_fishing.c | 215 +- .../actors/ovl_Item_B_Heart/z_item_b_heart.c | 6 +- .../ovl_Item_Etcetera/z_item_etcetera.c | 2 +- .../actors/ovl_Item_Ocarina/z_item_ocarina.c | 19 +- .../actors/ovl_Item_Shield/z_item_shield.c | 6 +- .../actors/ovl_Magic_Dark/z_magic_dark.c | 17 +- .../actors/ovl_Magic_Fire/z_magic_fire.c | 12 +- .../actors/ovl_Magic_Wind/z_magic_wind.c | 11 +- .../overlays/actors/ovl_Mir_Ray/z_mir_ray.c | 3 +- .../overlays/actors/ovl_Obj_Bean/z_obj_bean.c | 6 +- .../overlays/actors/ovl_Obj_Comb/z_obj_comb.c | 7 +- .../actors/ovl_Obj_Dekujr/z_obj_dekujr.c | 14 +- .../actors/ovl_Obj_Elevator/z_obj_elevator.c | 4 +- .../actors/ovl_Obj_Hamishi/z_obj_hamishi.c | 7 +- .../actors/ovl_Obj_Hsblock/z_obj_hsblock.c | 9 +- .../actors/ovl_Obj_Ice_Poly/z_obj_ice_poly.c | 3 +- .../actors/ovl_Obj_Kibako/z_obj_kibako.c | 15 +- .../actors/ovl_Obj_Kibako2/z_obj_kibako2.c | 11 +- .../ovl_Obj_Lightswitch/z_obj_lightswitch.c | 35 +- .../ovl_Obj_Makeoshihiki/z_obj_makeoshihiki.c | 5 +- .../overlays/actors/ovl_Obj_Mure/z_obj_mure.c | 3 +- .../actors/ovl_Obj_Mure2/z_obj_mure2.c | 3 +- .../actors/ovl_Obj_Oshihiki/z_obj_oshihiki.c | 18 +- .../ovl_Obj_Roomtimer/z_obj_roomtimer.c | 3 +- .../actors/ovl_Obj_Switch/z_obj_switch.c | 15 +- .../actors/ovl_Obj_Syokudai/z_obj_syokudai.c | 23 +- .../ovl_Obj_Timeblock/z_obj_timeblock.c | 11 +- .../actors/ovl_Obj_Tsubo/z_obj_tsubo.c | 6 +- .../ovl_Obj_Warp2block/z_obj_warp2block.c | 12 +- .../ovl_Object_Kankyo/z_object_kankyo.c | 25 +- .../actors/ovl_Oceff_Spot/z_oceff_spot.c | 7 +- .../actors/ovl_Oceff_Storm/z_oceff_storm.c | 7 +- .../actors/ovl_Oceff_Wipe/z_oceff_wipe.c | 3 +- .../actors/ovl_Oceff_Wipe2/z_oceff_wipe2.c | 3 +- .../actors/ovl_Oceff_Wipe3/z_oceff_wipe3.c | 3 +- .../actors/ovl_Oceff_Wipe4/z_oceff_wipe4.c | 5 +- .../actors/ovl_player_actor/z_player.c | 971 +-- .../ovl_Effect_Ss_Blast/z_eff_ss_blast.c | 3 +- .../ovl_Effect_Ss_Bubble/z_eff_ss_bubble.c | 3 +- .../ovl_Effect_Ss_Dead_Db/z_eff_ss_dead_db.c | 3 +- .../ovl_Effect_Ss_Dead_Ds/z_eff_ss_dead_ds.c | 3 +- .../z_eff_ss_dead_sound.c | 3 +- .../z_eff_ss_dt_bubble.c | 3 +- .../ovl_Effect_Ss_En_Fire/z_eff_ss_en_fire.c | 9 +- .../ovl_Effect_Ss_En_Ice/z_eff_ss_en_ice.c | 3 +- .../ovl_Effect_Ss_Extra/z_eff_ss_extra.c | 3 +- .../ovl_Effect_Ss_Fcircle/z_eff_ss_fcircle.c | 3 +- .../z_eff_ss_fhg_flash.c | 6 +- .../z_eff_ss_fire_tail.c | 9 +- .../z_eff_ss_g_magma2.c | 3 +- .../ovl_Effect_Ss_Hahen/z_eff_ss_hahen.c | 6 +- .../z_eff_ss_ice_piece.c | 3 +- .../z_eff_ss_ice_smoke.c | 5 +- .../ovl_Effect_Ss_K_Fire/z_eff_ss_k_fire.c | 7 +- .../ovl_Effect_Ss_Kakera/z_eff_ss_kakera.c | 6 +- .../ovl_Effect_Ss_Sibuki/z_eff_ss_sibuki.c | 3 +- .../ovl_Effect_Ss_Sibuki2/z_eff_ss_sibuki2.c | 3 +- .../z_eff_ss_solder_srch_ball.c | 6 +- .../ovl_Effect_Ss_Stick/z_eff_ss_stick.c | 3 +- .../ovl_Effect_Ss_Stone1/z_eff_ss_stone1.c | 3 +- .../ovl_file_choose/z_file_choose.c | 970 +-- .../ovl_file_choose/z_file_copy_erase.c | 66 +- .../ovl_file_choose/z_file_nameset_NES.c | 495 +- .../ovl_file_choose/z_file_nameset_PAL.c | 187 +- .../ovl_file_choose/z_file_nameset_data.c | 4 +- .../overlays/gamestates/ovl_select/z_select.c | 553 +- .../overlays/gamestates/ovl_title/z_title.c | 15 +- .../ovl_kaleido_scope/z_kaleido_collect.c | 80 +- .../misc/ovl_kaleido_scope/z_kaleido_debug.c | 3 +- .../ovl_kaleido_scope/z_kaleido_equipment.c | 185 +- .../misc/ovl_kaleido_scope/z_kaleido_item.c | 395 +- .../ovl_kaleido_scope/z_kaleido_map_PAL.c | 55 +- .../misc/ovl_kaleido_scope/z_kaleido_prompt.c | 12 +- .../ovl_kaleido_scope/z_kaleido_scope_PAL.c | 735 ++- .../misc/ovl_kaleido_scope/z_lmap_mark.c | 6 +- .../misc/ovl_kaleido_scope/z_lmap_mark_data.c | 199 +- .../misc/ovl_map_mark_data/z_map_mark_data.c | 10 +- 885 files changed, 40384 insertions(+), 36263 deletions(-) diff --git a/soh/platform/pathconf.c b/soh/platform/pathconf.c index 9e4111db3..a52d313a5 100644 --- a/soh/platform/pathconf.c +++ b/soh/platform/pathconf.c @@ -1,5 +1,5 @@ #include -long pathconf(const char *path, int name) { +long pathconf(const char* path, int name) { return -1; } \ No newline at end of file diff --git a/soh/resource.h b/soh/resource.h index 8a193b3e8..771a9af38 100644 --- a/soh/resource.h +++ b/soh/resource.h @@ -2,15 +2,15 @@ // Microsoft Visual C++ generated include file. // Used by Resource.rc // -#define IDI_ICON1 111 +#define IDI_ICON1 111 // Next default values for new objects -// +// #ifdef APSTUDIO_INVOKED #ifndef APSTUDIO_READONLY_SYMBOLS -#define _APS_NEXT_RESOURCE_VALUE 113 -#define _APS_NEXT_COMMAND_VALUE 40001 -#define _APS_NEXT_CONTROL_VALUE 1001 -#define _APS_NEXT_SYMED_VALUE 101 +#define _APS_NEXT_RESOURCE_VALUE 113 +#define _APS_NEXT_COMMAND_VALUE 40001 +#define _APS_NEXT_CONTROL_VALUE 1001 +#define _APS_NEXT_SYMED_VALUE 101 #endif #endif diff --git a/soh/soh/ActorDB.cpp b/soh/soh/ActorDB.cpp index 8b7c43ee6..70ea29675 100644 --- a/soh/soh/ActorDB.cpp +++ b/soh/soh/ActorDB.cpp @@ -4,7 +4,6 @@ ActorDB* ActorDB::Instance; - #define DEFINE_ACTOR(name, _1, _2) extern "C" ActorInit name##_InitVars; #define DEFINE_ACTOR_INTERNAL(name, _1, _2) extern "C" ActorInit name##_InitVars; #define DEFINE_ACTOR_UNSET(_0) @@ -464,7 +463,8 @@ static constexpr std::pair actorDescriptionData[] = { { ACTOR_BG_JYA_BLOCK, "Silver Block (Child Era)" }, { ACTOR_OBJ_WARP2BLOCK, "Navi Infospot (Green, Time Block)" }, }; -static std::unordered_map actorDescriptions = std::unordered_map(std::begin(actorDescriptionData), std::end(actorDescriptionData)); +static std::unordered_map actorDescriptions = + std::unordered_map(std::begin(actorDescriptionData), std::end(actorDescriptionData)); ActorDB::ActorDB() { db.reserve(ACTOR_NUMBER_MAX); // reserve size for all initial entries so we don't do it for each @@ -475,7 +475,8 @@ ActorDB::ActorDB() { // Adds an actor at the given index. The name must be unique. ActorDB::Entry& ActorDB::AddEntry(const std::string& name, const std::string& desc, size_t index) { - assert(!nameTable.contains(name)); // TODO this should maybe throw instead. We'll need to think about error handling for mods that try to declare the same actor. + assert(!nameTable.contains(name)); // TODO this should maybe throw instead. We'll need to think about error handling + // for mods that try to declare the same actor. if (db.size() < (index + 1)) { db.resize(index + 1); @@ -513,7 +514,8 @@ ActorDB::Entry& ActorDB::AddEntry(const std::string& name, const std::string& de return entry; } -// Adds an actor with the new ActorDBInit struct. The id assigned to the actor is dynamic. Use the return Entry or RetrieveId to get it. +// Adds an actor with the new ActorDBInit struct. The id assigned to the actor is dynamic. Use the return Entry or +// RetrieveId to get it. ActorDB::Entry& ActorDB::AddEntry(const ActorDBInit& init) { Entry& entry = AddEntry(init.name, init.desc, nextFreeId); @@ -598,7 +600,8 @@ static ActorDBInit EnPartnerInit = { "En_Partner", "Ivan", ACTORCAT_ITEMACTION, - (ACTOR_FLAG_UPDATE_CULLING_DISABLED | ACTOR_FLAG_DRAW_CULLING_DISABLED | ACTOR_FLAG_HOOKSHOT_PULLS_PLAYER | ACTOR_FLAG_CAN_PRESS_SWITCHES), + (ACTOR_FLAG_UPDATE_CULLING_DISABLED | ACTOR_FLAG_DRAW_CULLING_DISABLED | ACTOR_FLAG_HOOKSHOT_PULLS_PLAYER | + ACTOR_FLAG_CAN_PRESS_SWITCHES), OBJECT_GAMEPLAY_KEEP, sizeof(EnPartner), (ActorFunc)EnPartner_Init, diff --git a/soh/soh/ActorDB.h b/soh/soh/ActorDB.h index 8bcbb3f6a..dd8ecf901 100644 --- a/soh/soh/ActorDB.h +++ b/soh/soh/ActorDB.h @@ -39,7 +39,7 @@ struct ActorDBInit { }; class ActorDB { -public: + public: static ActorDB* Instance; ActorDB(); @@ -65,7 +65,8 @@ public: static void AddBuiltInCustomActors(); int GetEntryCount(); -private: + + private: Entry& AddEntry(const std::string& name, const std::string& desc, size_t index); Entry& AddEntry(const std::string& name, const std::string& desc, const ActorInit& init); diff --git a/soh/soh/CrashHandlerExp.h b/soh/soh/CrashHandlerExp.h index fd57bba42..8cda6e61e 100644 --- a/soh/soh/CrashHandlerExp.h +++ b/soh/soh/CrashHandlerExp.h @@ -1,11 +1,10 @@ #include - #ifdef __cplusplus extern "C" { #endif -void CrashHandler_PrintSohData(char* buffer, size_t* pos); +void CrashHandler_PrintSohData(char* buffer, size_t* pos); #ifdef __cplusplus } diff --git a/soh/soh/CrashHandlerExt.cpp b/soh/soh/CrashHandlerExt.cpp index c4a535f12..cc9c7b1ee 100644 --- a/soh/soh/CrashHandlerExt.cpp +++ b/soh/soh/CrashHandlerExt.cpp @@ -22,7 +22,7 @@ static std::array sCatToStrArray{ #define DEFINE_SCENE(_1, _2, enumName, _4, _5, _6) #enumName static std::array sSceneIdToStrArray{ - #include "tables/scene_table.h" +#include "tables/scene_table.h" }; #undef DEFINE_SCENE @@ -46,7 +46,7 @@ static void CrashHandler_WriteActorData(char* buffer, size_t* pos) { ActorListEntry* entry = &gPlayState->actorCtx.actorLists[i]; Actor* cur; - if(entry->length == 0) { + if (entry->length == 0) { continue; } WRITE_VAR_LINE(buffer, pos, "Actor Cat: ", sCatToStrArray[i]); @@ -76,7 +76,7 @@ extern "C" void CrashHandler_PrintSohData(char* buffer, size_t* pos) { if (gPlayState != nullptr) { append_line(buffer, pos, "Actors:"); CrashHandler_WriteActorData(buffer, pos); - + WRITE_VAR_LINE(buffer, pos, "Scene: ", sSceneIdToStrArray[gPlayState->sceneNum]); snprintf(intCharBuffer, sizeof(intCharBuffer), "%i", gPlayState->roomCtx.curRoom.num); diff --git a/soh/soh/Enhancements/AssignableTunicsAndBoots.cpp b/soh/soh/Enhancements/AssignableTunicsAndBoots.cpp index 3b4b11686..1ca5a7c19 100644 --- a/soh/soh/Enhancements/AssignableTunicsAndBoots.cpp +++ b/soh/soh/Enhancements/AssignableTunicsAndBoots.cpp @@ -16,10 +16,9 @@ static u16 sItemButtons[] = { BTN_B, BTN_CLEFT, BTN_CDOWN, BTN_CRIGHT, BTN_DUP, void UseTunicBoots(Player* player, PlayState* play, Input* input) { // Boots and tunics equip despite state - if ( - player->stateFlags1 & (PLAYER_STATE1_INPUT_DISABLED | PLAYER_STATE1_IN_ITEM_CS | PLAYER_STATE1_IN_CUTSCENE | PLAYER_STATE1_TALKING | PLAYER_STATE1_DEAD) || - player->stateFlags2 & PLAYER_STATE2_OCARINA_PLAYING - ) { + if (player->stateFlags1 & (PLAYER_STATE1_INPUT_DISABLED | PLAYER_STATE1_IN_ITEM_CS | PLAYER_STATE1_IN_CUTSCENE | + PLAYER_STATE1_TALKING | PLAYER_STATE1_DEAD) || + player->stateFlags2 & PLAYER_STATE2_OCARINA_PLAYING) { return; } @@ -40,7 +39,8 @@ void UseTunicBoots(Player* player, PlayState* play, Input* input) { Inventory_ChangeEquipment(EQUIP_TYPE_BOOTS, bootsValue); } Player_SetEquipmentData(play, player); - func_808328EC(player, CUR_EQUIP_VALUE(EQUIP_TYPE_BOOTS) == EQUIP_VALUE_BOOTS_IRON ? NA_SE_PL_WALK_HEAVYBOOTS : NA_SE_PL_CHANGE_ARMS); + func_808328EC(player, CUR_EQUIP_VALUE(EQUIP_TYPE_BOOTS) == EQUIP_VALUE_BOOTS_IRON ? NA_SE_PL_WALK_HEAVYBOOTS + : NA_SE_PL_CHANGE_ARMS); } else { u16 tunicValue = item - ITEM_TUNIC_KOKIRI + 1; if (CUR_EQUIP_VALUE(EQUIP_TYPE_TUNIC) == tunicValue) { @@ -87,7 +87,7 @@ void RegisterAssignableTunicsBoots() { } }); - // don't throw items when the pressed button is a tunic or boots + // don't throw items when the pressed button is a tunic or boots COND_VB_SHOULD(VB_THROW_OR_PUT_DOWN_HELD_ITEM, CVAR_TUNICBOOTS_VALUE != CVAR_TUNICBOOTS_DEFAULT, { // if the vanilla condition doesn't want us to throw/put down the item, early return if (!*should) { @@ -103,7 +103,7 @@ void RegisterAssignableTunicsBoots() { break; } } - + if (item >= ITEM_TUNIC_KOKIRI && item <= ITEM_BOOTS_HOVER) { *should = false; } diff --git a/soh/soh/Enhancements/Cheats/DekuStick.cpp b/soh/soh/Enhancements/Cheats/DekuStick.cpp index 8afa0e330..679878071 100644 --- a/soh/soh/Enhancements/Cheats/DekuStick.cpp +++ b/soh/soh/Enhancements/Cheats/DekuStick.cpp @@ -13,13 +13,13 @@ extern PlayState* gPlayState; #define CVAR_DEKU_STICK_VALUE CVarGetInteger(CVAR_DEKU_STICK_NAME, CVAR_DEKU_STICK_DEFAULT) void RegisterDekuStickCheats() { - COND_VB_SHOULD(VB_DEKU_STICK_BREAK, CVAR_DEKU_STICK_VALUE != DEKU_STICK_NORMAL, { *should = false; }); - COND_VB_SHOULD(VB_DEKU_STICK_BURN_OUT, CVAR_DEKU_STICK_VALUE != DEKU_STICK_NORMAL, { *should = false; }); + COND_VB_SHOULD(VB_DEKU_STICK_BREAK, CVAR_DEKU_STICK_VALUE != DEKU_STICK_NORMAL, { *should = false; }); + COND_VB_SHOULD(VB_DEKU_STICK_BURN_OUT, CVAR_DEKU_STICK_VALUE != DEKU_STICK_NORMAL, { *should = false; }); COND_VB_SHOULD(VB_DEKU_STICK_BURN_DOWN, CVAR_DEKU_STICK_VALUE != DEKU_STICK_NORMAL, { *should = false; }); COND_VB_SHOULD(VB_DEKU_STICK_BE_ON_FIRE, CVAR_DEKU_STICK_VALUE == DEKU_STICK_UNBREAKABLE_AND_ALWAYS_ON_FIRE, { Player* player = GET_PLAYER(gPlayState); - player->unk_860 = 200; // Keeps the stick's flame lit - player->unk_85C = 1.0f; // Ensures the stick is the proper length + player->unk_860 = 200; // Keeps the stick's flame lit + player->unk_85C = 1.0f; // Ensures the stick is the proper length *should = true; }); } diff --git a/soh/soh/Enhancements/Cheats/FreezeTime.cpp b/soh/soh/Enhancements/Cheats/FreezeTime.cpp index 2296c4fc9..a3028d7da 100644 --- a/soh/soh/Enhancements/Cheats/FreezeTime.cpp +++ b/soh/soh/Enhancements/Cheats/FreezeTime.cpp @@ -30,7 +30,8 @@ void RegisterFreezeTime() { GameInteractor::Instance->UnregisterGameHook(hookId); hookId = 0; if (CVAR_FREEZE_TIME_VALUE) { - hookId = GameInteractor::Instance->RegisterGameHook(OnGameFrameUpdateFreezeTime); + hookId = + GameInteractor::Instance->RegisterGameHook(OnGameFrameUpdateFreezeTime); } else { CVarClear(CVAR_PREV_TIME_NAME); } diff --git a/soh/soh/Enhancements/Cheats/Infinite/Money.cpp b/soh/soh/Enhancements/Cheats/Infinite/Money.cpp index 292f65065..38b402d6d 100644 --- a/soh/soh/Enhancements/Cheats/Infinite/Money.cpp +++ b/soh/soh/Enhancements/Cheats/Infinite/Money.cpp @@ -15,10 +15,7 @@ extern s32 Flags_GetRandomizerInf(RandomizerInf flag); #define CVAR_INFINITE_MONEY_VALUE CVarGetInteger(CVAR_INFINITE_MONEY_NAME, CVAR_INFINITE_MONEY_DEFAULT) void OnGameFrameUpdateInfiniteMoney() { - if ( - !GameInteractor::IsSaveLoaded(true) || - (IS_RANDO && !Flags_GetRandomizerInf(RAND_INF_HAS_WALLET)) - ) { + if (!GameInteractor::IsSaveLoaded(true) || (IS_RANDO && !Flags_GetRandomizerInf(RAND_INF_HAS_WALLET))) { return; } diff --git a/soh/soh/Enhancements/Cheats/Infinite/NayrusLove.cpp b/soh/soh/Enhancements/Cheats/Infinite/NayrusLove.cpp index 0bea9afc9..f3ff5fe04 100644 --- a/soh/soh/Enhancements/Cheats/Infinite/NayrusLove.cpp +++ b/soh/soh/Enhancements/Cheats/Infinite/NayrusLove.cpp @@ -7,7 +7,8 @@ extern "C" SaveContext gSaveContext; #define CVAR_INFINITE_NAYRUS_LOVE_NAME CVAR_CHEAT("InfiniteNayru") #define CVAR_INFINITE_NAYRUS_LOVE_DEFAULT 0 -#define CVAR_INFINITE_NAYRUS_LOVE_VALUE CVarGetInteger(CVAR_INFINITE_NAYRUS_LOVE_NAME, CVAR_INFINITE_NAYRUS_LOVE_DEFAULT) +#define CVAR_INFINITE_NAYRUS_LOVE_VALUE \ + CVarGetInteger(CVAR_INFINITE_NAYRUS_LOVE_NAME, CVAR_INFINITE_NAYRUS_LOVE_DEFAULT) void OnGameFrameUpdateInfiniteNayrusLove() { if (!GameInteractor::IsSaveLoaded(true)) { diff --git a/soh/soh/Enhancements/ExtraTraps.cpp b/soh/soh/Enhancements/ExtraTraps.cpp index 3391903ab..92806bacc 100644 --- a/soh/soh/Enhancements/ExtraTraps.cpp +++ b/soh/soh/Enhancements/ExtraTraps.cpp @@ -36,23 +36,19 @@ static int statusTimer = -1; static int eventTimer = -1; const char* altTrapTypeCvars[] = { - CVAR_ENHANCEMENT("ExtraTraps.Ice"), - CVAR_ENHANCEMENT("ExtraTraps.Burn"), - CVAR_ENHANCEMENT("ExtraTraps.Shock"), - CVAR_ENHANCEMENT("ExtraTraps.Knockback"), - CVAR_ENHANCEMENT("ExtraTraps.Speed"), - CVAR_ENHANCEMENT("ExtraTraps.Bomb"), - CVAR_ENHANCEMENT("ExtraTraps.Void"), - CVAR_ENHANCEMENT("ExtraTraps.Ammo"), - CVAR_ENHANCEMENT("ExtraTraps.Kill"), - CVAR_ENHANCEMENT("ExtraTraps.Teleport"), + CVAR_ENHANCEMENT("ExtraTraps.Ice"), CVAR_ENHANCEMENT("ExtraTraps.Burn"), + CVAR_ENHANCEMENT("ExtraTraps.Shock"), CVAR_ENHANCEMENT("ExtraTraps.Knockback"), + CVAR_ENHANCEMENT("ExtraTraps.Speed"), CVAR_ENHANCEMENT("ExtraTraps.Bomb"), + CVAR_ENHANCEMENT("ExtraTraps.Void"), CVAR_ENHANCEMENT("ExtraTraps.Ammo"), + CVAR_ENHANCEMENT("ExtraTraps.Kill"), CVAR_ENHANCEMENT("ExtraTraps.Teleport"), }; -std::vector getEnabledAddTraps () { +std::vector getEnabledAddTraps() { std::vector enabledAddTraps; for (int i = 0; i < ADD_TRAP_MAX; i++) { if (CVarGetInteger(altTrapTypeCvars[i], 0)) { - if (gSaveContext.equips.buttonItems[0] == ITEM_FISHING_POLE && (i == ADD_VOID_TRAP || i == ADD_TELEPORT_TRAP)) { + if (gSaveContext.equips.buttonItems[0] == ITEM_FISHING_POLE && + (i == ADD_VOID_TRAP || i == ADD_TELEPORT_TRAP)) { continue; // don't add void or teleport if you're holding the fishing pole, as this causes issues } enabledAddTraps.push_back(static_cast(i)); @@ -65,7 +61,8 @@ std::vector getEnabledAddTraps () { }; static void RollRandomTrap(uint32_t seed) { - uint32_t finalSeed = seed + (IS_RANDO ? Rando::Context::GetInstance()->GetSeed() : gSaveContext.ship.stats.fileCreatedAt); + uint32_t finalSeed = + seed + (IS_RANDO ? Rando::Context::GetInstance()->GetSeed() : gSaveContext.ship.stats.fileCreatedAt); Random_Init(finalSeed); roll = RandomElement(getEnabledAddTraps()); @@ -83,7 +80,8 @@ static void RollRandomTrap(uint32_t seed) { eventTimer = 3; break; case ADD_SPEED_TRAP: - Audio_PlaySoundGeneral(NA_SE_VO_KZ_MOVE, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb); + Audio_PlaySoundGeneral(NA_SE_VO_KZ_MOVE, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, + &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb); GameInteractor::State::RunSpeedModifier = -2; statusTimer = 200; Notification::Emit({ .message = "Speed Decreased!" }); @@ -92,7 +90,8 @@ static void RollRandomTrap(uint32_t seed) { eventTimer = 3; break; case ADD_VOID_TRAP: - Audio_PlaySoundGeneral(NA_SE_EN_GANON_LAUGH, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb); + Audio_PlaySoundGeneral(NA_SE_EN_GANON_LAUGH, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, + &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb); eventTimer = 3; break; case ADD_AMMO_TRAP: @@ -133,7 +132,8 @@ static void OnPlayerUpdate() { AMMO(ITEM_BOW) = AMMO(ITEM_BOW) * 0.5; AMMO(ITEM_BOMB) = AMMO(ITEM_BOMB) * 0.5; AMMO(ITEM_BOMBCHU) = AMMO(ITEM_BOMBCHU) * 0.5; - Audio_PlaySoundGeneral(NA_SE_VO_FR_SMILE_0, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb); + Audio_PlaySoundGeneral(NA_SE_VO_FR_SMILE_0, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, + &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb); break; case ADD_TELEPORT_TRAP: { int entrance; @@ -199,5 +199,3 @@ void RegisterExtraTraps() { } static RegisterShipInitFunc initFunc(RegisterExtraTraps, { CVAR_EXTRA_TRAPS_NAME }); - - diff --git a/soh/soh/Enhancements/FileSelectEnhancements.cpp b/soh/soh/Enhancements/FileSelectEnhancements.cpp index 84cff9d12..f9e993b6a 100644 --- a/soh/soh/Enhancements/FileSelectEnhancements.cpp +++ b/soh/soh/Enhancements/FileSelectEnhancements.cpp @@ -6,7 +6,7 @@ #include #include -std::array RandomizerSettingsMenuText[RSM_MAX] = { +std::array RandomizerSettingsMenuText[RSM_MAX] = { { // English "Start Randomizer", @@ -39,28 +39,27 @@ std::array RandomizerSettingsMenuText[RSM_MAX] = { // French "Génération en cours...", }, - { - // English - "No randomizer seed loaded.\nPlease generate one first" - #if defined(__WIIU__) || defined(__SWITCH__) - ".", - #else - ",\nor drop a spoiler log on the game window.", - #endif - // German - "No randomizer seed loaded.\nPlease generate one first" - #if defined(__WIIU__) || defined(__SWITCH__) - ".", - #else - ",\nor drop a spoiler log on the game window.", - #endif - // French - "Aucune Seed de Randomizer actuellement disponible.\nGénérez-en une dans les \"Randomizer Settings\"" - #if (defined(__WIIU__) || defined(__SWITCH__)) - "." - #else - "\nou glissez un spoilerlog sur la fenêtre du jeu." - #endif + { // English + "No randomizer seed loaded.\nPlease generate one first" +#if defined(__WIIU__) || defined(__SWITCH__) + ".", +#else + ",\nor drop a spoiler log on the game window.", +#endif + // German + "No randomizer seed loaded.\nPlease generate one first" +#if defined(__WIIU__) || defined(__SWITCH__) + ".", +#else + ",\nor drop a spoiler log on the game window.", +#endif + // French + "Aucune Seed de Randomizer actuellement disponible.\nGénérez-en une dans les \"Randomizer Settings\"" +#if (defined(__WIIU__) || defined(__SWITCH__)) + "." +#else + "\nou glissez un spoilerlog sur la fenêtre du jeu." +#endif }, }; diff --git a/soh/soh/Enhancements/Presets/PresetEntries.cpp b/soh/soh/Enhancements/Presets/PresetEntries.cpp index bfa3197ea..ebf6d4a19 100644 --- a/soh/soh/Enhancements/Presets/PresetEntries.cpp +++ b/soh/soh/Enhancements/Presets/PresetEntries.cpp @@ -3,10 +3,14 @@ #include "soh/cvar_prefixes.h" #include "soh/Enhancements/enhancementTypes.h" -#define PRESET_ENTRY_S32(cvar, value) { cvar, PRESET_ENTRY_TYPE_S32, value } -#define PRESET_ENTRY_FLOAT(cvar, value) { cvar, PRESET_ENTRY_TYPE_FLOAT, value } -#define PRESET_ENTRY_STRING(cvar, value) { cvar, PRESET_ENTRY_TYPE_STRING, value } -#define PRESET_ENTRY_CPP_STRING(cvar, value) { cvar, PRESET_ENTRY_TYPE_CPP_STRING, value } +#define PRESET_ENTRY_S32(cvar, value) \ + { cvar, PRESET_ENTRY_TYPE_S32, value } +#define PRESET_ENTRY_FLOAT(cvar, value) \ + { cvar, PRESET_ENTRY_TYPE_FLOAT, value } +#define PRESET_ENTRY_STRING(cvar, value) \ + { cvar, PRESET_ENTRY_TYPE_STRING, value } +#define PRESET_ENTRY_CPP_STRING(cvar, value) \ + { cvar, PRESET_ENTRY_TYPE_CPP_STRING, value } // TODO: Ideally everything in this file will come from one/many JSON files @@ -20,16 +24,14 @@ const std::vector vanillaPlusPresetEntries = { PRESET_ENTRY_S32(CVAR_ENHANCEMENT("BetterOwl"), 1), // Skips & Speed-ups - PRESET_ENTRY_S32(CVAR_ENHANCEMENT("SkipText"), 1), - PRESET_ENTRY_S32(CVAR_ENHANCEMENT("TextSpeed"), 5), + PRESET_ENTRY_S32(CVAR_ENHANCEMENT("SkipText"), 1), PRESET_ENTRY_S32(CVAR_ENHANCEMENT("TextSpeed"), 5), PRESET_ENTRY_S32(CVAR_ENHANCEMENT("FasterRupeeAccumulator"), 1), PRESET_ENTRY_S32(CVAR_ENHANCEMENT("SkipSaveConfirmation"), 1), // Graphics PRESET_ENTRY_S32(CVAR_ENHANCEMENT("DisableLOD"), 1), PRESET_ENTRY_S32(CVAR_ENHANCEMENT("RememberMapToggleState"), 1), - PRESET_ENTRY_S32(CVAR_ENHANCEMENT("VisualAgony"), 1), - PRESET_ENTRY_S32(CVAR_ENHANCEMENT("DynamicWalletIcon"), 1), + PRESET_ENTRY_S32(CVAR_ENHANCEMENT("VisualAgony"), 1), PRESET_ENTRY_S32(CVAR_ENHANCEMENT("DynamicWalletIcon"), 1), PRESET_ENTRY_S32(CVAR_ENHANCEMENT("TimeFlowFileSelect"), 1), PRESET_ENTRY_S32(CVAR_ENHANCEMENT("WidescreenActorCulling"), 1), @@ -41,26 +43,20 @@ const std::vector vanillaPlusPresetEntries = { // Fixes PRESET_ENTRY_S32(CVAR_ENHANCEMENT("GravediggingTourFix"), 1), PRESET_ENTRY_S32(CVAR_ENHANCEMENT("FixFloorSwitches"), 1), - PRESET_ENTRY_S32(CVAR_ENHANCEMENT("FixZoraHintDialogue"), 1), - PRESET_ENTRY_S32(CVAR_ENHANCEMENT("FixVineFall"), 1), + PRESET_ENTRY_S32(CVAR_ENHANCEMENT("FixZoraHintDialogue"), 1), PRESET_ENTRY_S32(CVAR_ENHANCEMENT("FixVineFall"), 1), PRESET_ENTRY_S32(CVAR_ENHANCEMENT("EnemySpawnsOverWaterboxes"), 1), - PRESET_ENTRY_S32(CVAR_ENHANCEMENT("FixSawSoftlock"), 1), - PRESET_ENTRY_S32(CVAR_ENHANCEMENT("DekuNutUpgradeFix"), 1), - PRESET_ENTRY_S32(CVAR_ENHANCEMENT("FixGrokenGiantsKnife"), 1), - PRESET_ENTRY_S32(CVAR_ENHANCEMENT("FixMenuLR"), 1), + PRESET_ENTRY_S32(CVAR_ENHANCEMENT("FixSawSoftlock"), 1), PRESET_ENTRY_S32(CVAR_ENHANCEMENT("DekuNutUpgradeFix"), 1), + PRESET_ENTRY_S32(CVAR_ENHANCEMENT("FixGrokenGiantsKnife"), 1), PRESET_ENTRY_S32(CVAR_ENHANCEMENT("FixMenuLR"), 1), PRESET_ENTRY_S32(CVAR_ENHANCEMENT("FixDungeonMinimapIcon"), 1), - PRESET_ENTRY_S32(CVAR_ENHANCEMENT("TwoHandedIdle"), 1), - PRESET_ENTRY_S32(CVAR_ENHANCEMENT("NaviTextFix"), 1), + PRESET_ENTRY_S32(CVAR_ENHANCEMENT("TwoHandedIdle"), 1), PRESET_ENTRY_S32(CVAR_ENHANCEMENT("NaviTextFix"), 1), PRESET_ENTRY_S32(CVAR_ENHANCEMENT("GerudoWarriorClothingFix"), 1), PRESET_ENTRY_S32(CVAR_ENHANCEMENT("FixTexturesOOB"), 1), PRESET_ENTRY_S32(CVAR_ENHANCEMENT("FixEyesOpenWhileSleeping"), 1), PRESET_ENTRY_S32(CVAR_ENHANCEMENT("FixHammerHand"), 1), PRESET_ENTRY_S32(CVAR_ENHANCEMENT("SceneSpecificDirtPathFix"), ZFIGHT_FIX_CONSISTENT_VANISH), PRESET_ENTRY_S32(CVAR_ENHANCEMENT("SilverRupeeJingleExtend"), 1), - PRESET_ENTRY_S32(CVAR_ENHANCEMENT("FixDaruniaDanceSpeed"), 1), - PRESET_ENTRY_S32(CVAR_ENHANCEMENT("CreditsFix"), 1), - PRESET_ENTRY_S32(CVAR_ENHANCEMENT("RedGanonBlood"), 1), - PRESET_ENTRY_S32(CVAR_ENHANCEMENT("PulsateBossIcon"), 1), + PRESET_ENTRY_S32(CVAR_ENHANCEMENT("FixDaruniaDanceSpeed"), 1), PRESET_ENTRY_S32(CVAR_ENHANCEMENT("CreditsFix"), 1), + PRESET_ENTRY_S32(CVAR_ENHANCEMENT("RedGanonBlood"), 1), PRESET_ENTRY_S32(CVAR_ENHANCEMENT("PulsateBossIcon"), 1), // Difficulty // NONE @@ -78,42 +74,33 @@ const std::vector vanillaPlusPresetEntries = { const std::vector enhancedPresetEntries = { // Quality of Life - PRESET_ENTRY_S32(CVAR_ENHANCEMENT("Autosave"), 1), - PRESET_ENTRY_S32(CVAR_ENHANCEMENT("PauseWarp"), 1), + PRESET_ENTRY_S32(CVAR_ENHANCEMENT("Autosave"), 1), PRESET_ENTRY_S32(CVAR_ENHANCEMENT("PauseWarp"), 1), PRESET_ENTRY_S32(CVAR_ENHANCEMENT("NoInputForCredits"), 1), PRESET_ENTRY_S32(CVAR_ENHANCEMENT("InjectItemCounts.GoldSkulltula"), 1), PRESET_ENTRY_S32(CVAR_ENHANCEMENT("InjectItemCounts.HeartPiece"), 1), PRESET_ENTRY_S32(CVAR_ENHANCEMENT("InjectItemCounts.HeartContainer"), 1), - PRESET_ENTRY_S32(CVAR_ENHANCEMENT("DisableCritWiggle"), 1), - PRESET_ENTRY_S32(CVAR_ENHANCEMENT("BetterOwl"), 1), - PRESET_ENTRY_S32(CVAR_ENHANCEMENT("QuitFishingAtDoor"), 1), - PRESET_ENTRY_S32(CVAR_ENHANCEMENT("InstantPutaway"), 1), + PRESET_ENTRY_S32(CVAR_ENHANCEMENT("DisableCritWiggle"), 1), PRESET_ENTRY_S32(CVAR_ENHANCEMENT("BetterOwl"), 1), + PRESET_ENTRY_S32(CVAR_ENHANCEMENT("QuitFishingAtDoor"), 1), PRESET_ENTRY_S32(CVAR_ENHANCEMENT("InstantPutaway"), 1), PRESET_ENTRY_S32(CVAR_ENHANCEMENT("TimeSavers.SleepingWaterfall"), 1), // Skips & Speed-ups - PRESET_ENTRY_S32(CVAR_ENHANCEMENT("SkipText"), 1), - PRESET_ENTRY_S32(CVAR_ENHANCEMENT("TextSpeed"), 5), + PRESET_ENTRY_S32(CVAR_ENHANCEMENT("SkipText"), 1), PRESET_ENTRY_S32(CVAR_ENHANCEMENT("TextSpeed"), 5), PRESET_ENTRY_S32(CVAR_ENHANCEMENT("SlowTextSpeed"), 5), PRESET_ENTRY_S32(CVAR_ENHANCEMENT("FasterHeavyBlockLift"), 1), - PRESET_ENTRY_S32(CVAR_ENHANCEMENT("SkipSwimDeepEndAnim"), 1), - PRESET_ENTRY_S32(CVAR_ENHANCEMENT("ClimbSpeed"), 3), - PRESET_ENTRY_S32(CVAR_ENHANCEMENT("FasterBlockPush"), 5), - PRESET_ENTRY_S32(CVAR_ENHANCEMENT("CrawlSpeed"), 2), - PRESET_ENTRY_FLOAT(CVAR_ENHANCEMENT("MweepSpeed"), 5.0f), - PRESET_ENTRY_S32(CVAR_ENHANCEMENT("InstantScarecrow"), 1), + PRESET_ENTRY_S32(CVAR_ENHANCEMENT("SkipSwimDeepEndAnim"), 1), PRESET_ENTRY_S32(CVAR_ENHANCEMENT("ClimbSpeed"), 3), + PRESET_ENTRY_S32(CVAR_ENHANCEMENT("FasterBlockPush"), 5), PRESET_ENTRY_S32(CVAR_ENHANCEMENT("CrawlSpeed"), 2), + PRESET_ENTRY_FLOAT(CVAR_ENHANCEMENT("MweepSpeed"), 5.0f), PRESET_ENTRY_S32(CVAR_ENHANCEMENT("InstantScarecrow"), 1), PRESET_ENTRY_S32(CVAR_ENHANCEMENT("FasterRupeeAccumulator"), 1), PRESET_ENTRY_S32(CVAR_ENHANCEMENT("SkulltulaFreeze"), 1), PRESET_ENTRY_S32(CVAR_ENHANCEMENT("SkipSaveConfirmation"), 1), // Graphics - PRESET_ENTRY_S32(CVAR_ENHANCEMENT("DisableLOD"), 1), - PRESET_ENTRY_S32(CVAR_ENHANCEMENT("NewDrops"), 1), + PRESET_ENTRY_S32(CVAR_ENHANCEMENT("DisableLOD"), 1), PRESET_ENTRY_S32(CVAR_ENHANCEMENT("NewDrops"), 1), PRESET_ENTRY_S32(CVAR_ENHANCEMENT("PauseMenuAnimatedLink"), 1), PRESET_ENTRY_S32(CVAR_ENHANCEMENT("ShowDoorLocksOnBothSides"), 1), PRESET_ENTRY_S32(CVAR_ENHANCEMENT("ToTMedallionsColors"), 1), PRESET_ENTRY_S32(CVAR_ENHANCEMENT("RememberMapToggleState"), 1), - PRESET_ENTRY_S32(CVAR_ENHANCEMENT("VisualAgony"), 1), - PRESET_ENTRY_S32(CVAR_ENHANCEMENT("DynamicWalletIcon"), 1), + PRESET_ENTRY_S32(CVAR_ENHANCEMENT("VisualAgony"), 1), PRESET_ENTRY_S32(CVAR_ENHANCEMENT("DynamicWalletIcon"), 1), PRESET_ENTRY_S32(CVAR_ENHANCEMENT("BetterAmmoRendering"), 1), PRESET_ENTRY_S32(CVAR_ENHANCEMENT("TimeFlowFileSelect"), 1), PRESET_ENTRY_S32(CVAR_ENHANCEMENT("WidescreenActorCulling"), 1), @@ -125,49 +112,36 @@ const std::vector enhancedPresetEntries = { PRESET_ENTRY_S32(CVAR_ENHANCEMENT("DpadNoDropOcarinaInput"), 1), PRESET_ENTRY_S32(CVAR_ENHANCEMENT("FastOcarinaPlayback"), 1), PRESET_ENTRY_S32(CVAR_ENHANCEMENT("MMBunnyHood"), BUNNY_HOOD_FAST), - PRESET_ENTRY_S32(CVAR_ENHANCEMENT("PersistentMasks"), 1), - PRESET_ENTRY_S32(CVAR_ENHANCEMENT("NutsExplodeBombs"), 1), + PRESET_ENTRY_S32(CVAR_ENHANCEMENT("PersistentMasks"), 1), PRESET_ENTRY_S32(CVAR_ENHANCEMENT("NutsExplodeBombs"), 1), PRESET_ENTRY_S32(CVAR_ENHANCEMENT("DisableFirstPersonChus"), 1), PRESET_ENTRY_S32(CVAR_ENHANCEMENT("BetterBombchuShopping"), 1), PRESET_ENTRY_S32(CVAR_ENHANCEMENT("SeparateArrows"), 1), - PRESET_ENTRY_S32(CVAR_ENHANCEMENT("SkipArrowAnimation"), 1), - PRESET_ENTRY_S32(CVAR_ENHANCEMENT("FastBoomerang"), 1), - PRESET_ENTRY_S32(CVAR_ENHANCEMENT("BetterFarore"), 1), - PRESET_ENTRY_S32(CVAR_ENHANCEMENT("FastFarores"), 1), + PRESET_ENTRY_S32(CVAR_ENHANCEMENT("SkipArrowAnimation"), 1), PRESET_ENTRY_S32(CVAR_ENHANCEMENT("FastBoomerang"), 1), + PRESET_ENTRY_S32(CVAR_ENHANCEMENT("BetterFarore"), 1), PRESET_ENTRY_S32(CVAR_ENHANCEMENT("FastFarores"), 1), // Fixes PRESET_ENTRY_S32(CVAR_ENHANCEMENT("GravediggingTourFix"), 1), PRESET_ENTRY_S32(CVAR_ENHANCEMENT("FixFloorSwitches"), 1), - PRESET_ENTRY_S32(CVAR_ENHANCEMENT("FixZoraHintDialogue"), 1), - PRESET_ENTRY_S32(CVAR_ENHANCEMENT("FixVineFall"), 1), + PRESET_ENTRY_S32(CVAR_ENHANCEMENT("FixZoraHintDialogue"), 1), PRESET_ENTRY_S32(CVAR_ENHANCEMENT("FixVineFall"), 1), PRESET_ENTRY_S32(CVAR_ENHANCEMENT("EnemySpawnsOverWaterboxes"), 1), - PRESET_ENTRY_S32(CVAR_ENHANCEMENT("FixSawSoftlock"), 1), - PRESET_ENTRY_S32(CVAR_ENHANCEMENT("DekuNutUpgradeFix"), 1), - PRESET_ENTRY_S32(CVAR_ENHANCEMENT("FixGrokenGiantsKnife"), 1), - PRESET_ENTRY_S32(CVAR_ENHANCEMENT("FixMenuLR"), 1), + PRESET_ENTRY_S32(CVAR_ENHANCEMENT("FixSawSoftlock"), 1), PRESET_ENTRY_S32(CVAR_ENHANCEMENT("DekuNutUpgradeFix"), 1), + PRESET_ENTRY_S32(CVAR_ENHANCEMENT("FixGrokenGiantsKnife"), 1), PRESET_ENTRY_S32(CVAR_ENHANCEMENT("FixMenuLR"), 1), PRESET_ENTRY_S32(CVAR_ENHANCEMENT("FixDungeonMinimapIcon"), 1), - PRESET_ENTRY_S32(CVAR_ENHANCEMENT("TwoHandedIdle"), 1), - PRESET_ENTRY_S32(CVAR_ENHANCEMENT("NaviTextFix"), 1), + PRESET_ENTRY_S32(CVAR_ENHANCEMENT("TwoHandedIdle"), 1), PRESET_ENTRY_S32(CVAR_ENHANCEMENT("NaviTextFix"), 1), PRESET_ENTRY_S32(CVAR_ENHANCEMENT("GerudoWarriorClothingFix"), 1), PRESET_ENTRY_S32(CVAR_ENHANCEMENT("FixTexturesOOB"), 1), PRESET_ENTRY_S32(CVAR_ENHANCEMENT("FixEyesOpenWhileSleeping"), 1), PRESET_ENTRY_S32(CVAR_ENHANCEMENT("FixHammerHand"), 1), PRESET_ENTRY_S32(CVAR_ENHANCEMENT("SceneSpecificDirtPathFix"), ZFIGHT_FIX_CONSISTENT_VANISH), PRESET_ENTRY_S32(CVAR_ENHANCEMENT("SilverRupeeJingleExtend"), 1), - PRESET_ENTRY_S32(CVAR_ENHANCEMENT("FixDaruniaDanceSpeed"), 1), - PRESET_ENTRY_S32(CVAR_ENHANCEMENT("CreditsFix"), 1), - PRESET_ENTRY_S32(CVAR_ENHANCEMENT("RedGanonBlood"), 1), - PRESET_ENTRY_S32(CVAR_ENHANCEMENT("PulsateBossIcon"), 1), - PRESET_ENTRY_S32(CVAR_ENHANCEMENT("HoverFishing"), 1), - PRESET_ENTRY_S32(CVAR_ENHANCEMENT("N64WeirdFrames"), 1), - PRESET_ENTRY_S32(CVAR_ENHANCEMENT("BombchusOOB"), 1), - PRESET_ENTRY_S32(CVAR_ENHANCEMENT("QuickPutaway"), 1), - PRESET_ENTRY_S32(CVAR_ENHANCEMENT("QuickBongoKill"), 1), - PRESET_ENTRY_S32(CVAR_ENHANCEMENT("EarlyEyeballFrog"), 1), + PRESET_ENTRY_S32(CVAR_ENHANCEMENT("FixDaruniaDanceSpeed"), 1), PRESET_ENTRY_S32(CVAR_ENHANCEMENT("CreditsFix"), 1), + PRESET_ENTRY_S32(CVAR_ENHANCEMENT("RedGanonBlood"), 1), PRESET_ENTRY_S32(CVAR_ENHANCEMENT("PulsateBossIcon"), 1), + PRESET_ENTRY_S32(CVAR_ENHANCEMENT("HoverFishing"), 1), PRESET_ENTRY_S32(CVAR_ENHANCEMENT("N64WeirdFrames"), 1), + PRESET_ENTRY_S32(CVAR_ENHANCEMENT("BombchusOOB"), 1), PRESET_ENTRY_S32(CVAR_ENHANCEMENT("QuickPutaway"), 1), + PRESET_ENTRY_S32(CVAR_ENHANCEMENT("QuickBongoKill"), 1), PRESET_ENTRY_S32(CVAR_ENHANCEMENT("EarlyEyeballFrog"), 1), // Difficulty - PRESET_ENTRY_S32(CVAR_ENHANCEMENT("EnableBombchuDrops"), 1), - PRESET_ENTRY_S32(CVAR_ENHANCEMENT("DampeWin"), 1), + PRESET_ENTRY_S32(CVAR_ENHANCEMENT("EnableBombchuDrops"), 1), PRESET_ENTRY_S32(CVAR_ENHANCEMENT("DampeWin"), 1), // Minigames PRESET_ENTRY_S32(CVAR_ENHANCEMENT("CustomizeFrogsOcarinaGame"), 1), @@ -502,15 +476,12 @@ const std::vector randomizerAdvancedPresetEntries = { PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("SkipScarecrowsSong"), 1), PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("SheikLAHint"), 0), - PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("DampeHint"), 1), - PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("GregHint"), 1), + PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("DampeHint"), 1), PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("GregHint"), 1), PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("SariaHint"), 1), PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("FrogsHint"), 1), - PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("MalonHint"), 1), - PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("HBAHint"), 1), + PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("MalonHint"), 1), PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("HBAHint"), 1), PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("MerchantText"), 1), - PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("40GSHint"), 1), - PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("50GSHint"), 1), + PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("40GSHint"), 1), PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("50GSHint"), 1), PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("FullWallets"), 1), PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("BombchuBag"), 1), diff --git a/soh/soh/Enhancements/Presets/Presets.cpp b/soh/soh/Enhancements/Presets/Presets.cpp index 79552ef5d..cef3f8362 100644 --- a/soh/soh/Enhancements/Presets/Presets.cpp +++ b/soh/soh/Enhancements/Presets/Presets.cpp @@ -10,14 +10,14 @@ std::string FormatLocations(std::vector locs) { std::string locString = ""; - for (auto loc: locs) { + for (auto loc : locs) { locString += std::to_string(loc) + ","; } return locString; } void applyPreset(std::vector entries) { - for(auto& [cvar, type, value] : entries) { + for (auto& [cvar, type, value] : entries) { switch (type) { case PRESET_ENTRY_TYPE_S32: CVarSetInteger(cvar, std::get(value)); @@ -41,20 +41,21 @@ void DrawPresetSelector(PresetType presetTypeId) { const std::string presetTypeCvar = CVAR_GENERAL("SelectedPresets.") + std::to_string(presetTypeId); const PresetTypeDefinition presetTypeDef = presetTypes.at(presetTypeId); uint16_t selectedPresetId = CVarGetInteger(presetTypeCvar.c_str(), 0); - if(selectedPresetId >= presetTypeDef.presets.size()){ + if (selectedPresetId >= presetTypeDef.presets.size()) { selectedPresetId = 0; } const PresetDefinition selectedPresetDef = presetTypeDef.presets.at(selectedPresetId); std::string comboboxTooltip = ""; - for ( auto iter = presetTypeDef.presets.begin(); iter != presetTypeDef.presets.end(); ++iter ) { - if (iter->first != 0) comboboxTooltip += "\n\n"; + for (auto iter = presetTypeDef.presets.begin(); iter != presetTypeDef.presets.end(); ++iter) { + if (iter->first != 0) + comboboxTooltip += "\n\n"; comboboxTooltip += std::string(iter->second.label) + " - " + std::string(iter->second.description); } ImGui::Text("Presets"); UIWidgets::PushStyleCombobox(THEME_COLOR); if (ImGui::BeginCombo("##PresetsComboBox", selectedPresetDef.label)) { - for ( auto iter = presetTypeDef.presets.begin(); iter != presetTypeDef.presets.end(); ++iter ) { + for (auto iter = presetTypeDef.presets.begin(); iter != presetTypeDef.presets.end(); ++iter) { if (ImGui::Selectable(iter->second.label, iter->first == selectedPresetId)) { CVarSetInteger(presetTypeCvar.c_str(), iter->first); Ship::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesNextFrame(); @@ -68,7 +69,7 @@ void DrawPresetSelector(PresetType presetTypeId) { UIWidgets::PushStyleButton(THEME_COLOR); if (ImGui::Button(("Apply Preset##" + presetTypeCvar).c_str())) { - for(const char* block : presetTypeDef.blocksToClear) { + for (const char* block : presetTypeDef.blocksToClear) { CVarClearBlock(block); } if (selectedPresetId != 0) { diff --git a/soh/soh/Enhancements/RemoveSpinAttackDarkness.cpp b/soh/soh/Enhancements/RemoveSpinAttackDarkness.cpp index 37fed1b7d..965817030 100644 --- a/soh/soh/Enhancements/RemoveSpinAttackDarkness.cpp +++ b/soh/soh/Enhancements/RemoveSpinAttackDarkness.cpp @@ -33,10 +33,13 @@ void OnEnMThunderInitReplaceUpdateWithCustom(void* thunder) { #define CVAR_REMOVESPINATTACKDARKNESS_NAME CVAR_ENHANCEMENT("RemoveSpinAttackDarkness") #define CVAR_REMOVESPINATTACKDARKNESS_DEFAULT 0 -#define CVAR_REMOVESPINATTACKDARKNESS_VALUE CVarGetInteger(CVAR_REMOVESPINATTACKDARKNESS_NAME, CVAR_REMOVESPINATTACKDARKNESS_DEFAULT) +#define CVAR_REMOVESPINATTACKDARKNESS_VALUE \ + CVarGetInteger(CVAR_REMOVESPINATTACKDARKNESS_NAME, CVAR_REMOVESPINATTACKDARKNESS_DEFAULT) void RegisterCustomEnMThunderUpdate() { - COND_ID_HOOK(OnActorInit, ACTOR_EN_M_THUNDER, CVAR_REMOVESPINATTACKDARKNESS_VALUE != CVAR_REMOVESPINATTACKDARKNESS_DEFAULT, OnEnMThunderInitReplaceUpdateWithCustom); + COND_ID_HOOK(OnActorInit, ACTOR_EN_M_THUNDER, + CVAR_REMOVESPINATTACKDARKNESS_VALUE != CVAR_REMOVESPINATTACKDARKNESS_DEFAULT, + OnEnMThunderInitReplaceUpdateWithCustom); } static RegisterShipInitFunc initFunc(RegisterCustomEnMThunderUpdate, { CVAR_REMOVESPINATTACKDARKNESS_NAME }); diff --git a/soh/soh/Enhancements/Restorations/BottleAdventure.cpp b/soh/soh/Enhancements/Restorations/BottleAdventure.cpp index c581a325d..22cc74e67 100644 --- a/soh/soh/Enhancements/Restorations/BottleAdventure.cpp +++ b/soh/soh/Enhancements/Restorations/BottleAdventure.cpp @@ -98,11 +98,13 @@ void HandleBAInventoryQuestItems() { void HandleRBAInventoryQuestItems(uint8_t itemToPutInBottle) { auto itemOnCRight = gSaveContext.equips.buttonItems[3]; - + if (itemOnCRight == ITEM_ODD_MUSHROOM) { - gSaveContext.inventory.questItems = (itemToPutInBottle << 24) | (gSaveContext.inventory.questItems & 0x00FFFFFF); + gSaveContext.inventory.questItems = + (itemToPutInBottle << 24) | (gSaveContext.inventory.questItems & 0x00FFFFFF); } else if (itemOnCRight == ITEM_ODD_POTION) { - gSaveContext.inventory.questItems = (itemToPutInBottle << 16) | (gSaveContext.inventory.questItems & 0xFF00FFFF); + gSaveContext.inventory.questItems = + (itemToPutInBottle << 16) | (gSaveContext.inventory.questItems & 0xFF00FFFF); } else if (itemOnCRight == ITEM_SAW) { gSaveContext.inventory.questItems = (itemToPutInBottle << 8) | (gSaveContext.inventory.questItems & 0xFFFF00FF); } else if (itemOnCRight == ITEM_SWORD_BROKEN) { @@ -119,7 +121,7 @@ void HandleBAInventoryDungeonItems() { void HandleRBAInventoryDungeonItems(uint8_t itemToPutInBottle) { auto itemOnCRight = gSaveContext.equips.buttonItems[3]; - + gSaveContext.inventory.dungeonItems[itemOnCRight - ITEM_PRESCRIPTION] = itemToPutInBottle; } @@ -132,7 +134,7 @@ void HandleBAInventoryDungeonKeys() { void HandleRBAInventoryDungeonKeys(uint8_t itemToPutInBottle) { auto itemOnCRight = gSaveContext.equips.buttonItems[3]; - + gSaveContext.inventory.dungeonKeys[itemOnCRight - ITEM_BULLET_BAG_40] = itemToPutInBottle; } @@ -172,90 +174,90 @@ void HandleBASceneFlags() { u32 offset = gSaveContext.equips.buttonItems[3] - ITEM_SONG_LULLABY; u32 scene = offset / sizeof(SavedSceneFlags); switch (offset % sizeof(SavedSceneFlags)) { - case 0: - gSaveContext.equips.buttonItems[0] = (gSaveContext.sceneFlags[scene].chest >> 24) & 0xFF; - break; - case 1: - gSaveContext.equips.buttonItems[0] = (gSaveContext.sceneFlags[scene].chest >> 16) & 0xFF; - break; - case 2: - gSaveContext.equips.buttonItems[0] = (gSaveContext.sceneFlags[scene].chest >> 8) & 0xFF; - break; - case 3: - gSaveContext.equips.buttonItems[0] = gSaveContext.sceneFlags[scene].chest & 0xFF; - break; - case 4: - gSaveContext.equips.buttonItems[0] = (gSaveContext.sceneFlags[scene].swch >> 24) & 0xFF; - break; - case 5: - gSaveContext.equips.buttonItems[0] = (gSaveContext.sceneFlags[scene].swch >> 16) & 0xFF; - break; - case 6: - gSaveContext.equips.buttonItems[0] = (gSaveContext.sceneFlags[scene].swch >> 8) & 0xFF; - break; - case 7: - gSaveContext.equips.buttonItems[0] = gSaveContext.sceneFlags[scene].swch & 0xFF; - break; - case 8: - gSaveContext.equips.buttonItems[0] = (gSaveContext.sceneFlags[scene].clear >> 24) & 0xFF; - break; - case 9: - gSaveContext.equips.buttonItems[0] = (gSaveContext.sceneFlags[scene].clear >> 16) & 0xFF; - break; - case 10: - gSaveContext.equips.buttonItems[0] = (gSaveContext.sceneFlags[scene].clear >> 8) & 0xFF; - break; - case 11: - gSaveContext.equips.buttonItems[0] = gSaveContext.sceneFlags[scene].clear & 0xFF; - break; - case 12: - gSaveContext.equips.buttonItems[0] = (gSaveContext.sceneFlags[scene].collect >> 24) & 0xFF; - break; - case 13: - gSaveContext.equips.buttonItems[0] = (gSaveContext.sceneFlags[scene].collect >> 16) & 0xFF; - break; - case 14: - gSaveContext.equips.buttonItems[0] = (gSaveContext.sceneFlags[scene].collect >> 8) & 0xFF; - break; - case 15: - gSaveContext.equips.buttonItems[0] = gSaveContext.sceneFlags[scene].collect & 0xFF; - break; - case 16: - gSaveContext.equips.buttonItems[0] = (gSaveContext.sceneFlags[scene].unk >> 24) & 0xFF; - break; - case 17: - gSaveContext.equips.buttonItems[0] = (gSaveContext.sceneFlags[scene].unk >> 16) & 0xFF; - break; - case 18: - gSaveContext.equips.buttonItems[0] = (gSaveContext.sceneFlags[scene].unk >> 8) & 0xFF; - break; - case 19: - gSaveContext.equips.buttonItems[0] = gSaveContext.sceneFlags[scene].unk & 0xFF; - break; - case 20: - gSaveContext.equips.buttonItems[0] = (gSaveContext.sceneFlags[scene].rooms >> 24) & 0xFF; - break; - case 21: - gSaveContext.equips.buttonItems[0] = (gSaveContext.sceneFlags[scene].rooms >> 16) & 0xFF; - break; - case 22: - gSaveContext.equips.buttonItems[0] = (gSaveContext.sceneFlags[scene].rooms >> 8) & 0xFF; - break; - case 23: - gSaveContext.equips.buttonItems[0] = gSaveContext.sceneFlags[scene].rooms & 0xFF; - break; - case 24: - gSaveContext.equips.buttonItems[0] = (gSaveContext.sceneFlags[scene].floors >> 24) & 0xFF; - break; - case 25: - gSaveContext.equips.buttonItems[0] = (gSaveContext.sceneFlags[scene].floors >> 16) & 0xFF; - break; - case 26: - gSaveContext.equips.buttonItems[0] = (gSaveContext.sceneFlags[scene].floors >> 8) & 0xFF; - break; - case 27: - gSaveContext.equips.buttonItems[0] = gSaveContext.sceneFlags[scene].floors & 0xFF; - break; + case 0: + gSaveContext.equips.buttonItems[0] = (gSaveContext.sceneFlags[scene].chest >> 24) & 0xFF; + break; + case 1: + gSaveContext.equips.buttonItems[0] = (gSaveContext.sceneFlags[scene].chest >> 16) & 0xFF; + break; + case 2: + gSaveContext.equips.buttonItems[0] = (gSaveContext.sceneFlags[scene].chest >> 8) & 0xFF; + break; + case 3: + gSaveContext.equips.buttonItems[0] = gSaveContext.sceneFlags[scene].chest & 0xFF; + break; + case 4: + gSaveContext.equips.buttonItems[0] = (gSaveContext.sceneFlags[scene].swch >> 24) & 0xFF; + break; + case 5: + gSaveContext.equips.buttonItems[0] = (gSaveContext.sceneFlags[scene].swch >> 16) & 0xFF; + break; + case 6: + gSaveContext.equips.buttonItems[0] = (gSaveContext.sceneFlags[scene].swch >> 8) & 0xFF; + break; + case 7: + gSaveContext.equips.buttonItems[0] = gSaveContext.sceneFlags[scene].swch & 0xFF; + break; + case 8: + gSaveContext.equips.buttonItems[0] = (gSaveContext.sceneFlags[scene].clear >> 24) & 0xFF; + break; + case 9: + gSaveContext.equips.buttonItems[0] = (gSaveContext.sceneFlags[scene].clear >> 16) & 0xFF; + break; + case 10: + gSaveContext.equips.buttonItems[0] = (gSaveContext.sceneFlags[scene].clear >> 8) & 0xFF; + break; + case 11: + gSaveContext.equips.buttonItems[0] = gSaveContext.sceneFlags[scene].clear & 0xFF; + break; + case 12: + gSaveContext.equips.buttonItems[0] = (gSaveContext.sceneFlags[scene].collect >> 24) & 0xFF; + break; + case 13: + gSaveContext.equips.buttonItems[0] = (gSaveContext.sceneFlags[scene].collect >> 16) & 0xFF; + break; + case 14: + gSaveContext.equips.buttonItems[0] = (gSaveContext.sceneFlags[scene].collect >> 8) & 0xFF; + break; + case 15: + gSaveContext.equips.buttonItems[0] = gSaveContext.sceneFlags[scene].collect & 0xFF; + break; + case 16: + gSaveContext.equips.buttonItems[0] = (gSaveContext.sceneFlags[scene].unk >> 24) & 0xFF; + break; + case 17: + gSaveContext.equips.buttonItems[0] = (gSaveContext.sceneFlags[scene].unk >> 16) & 0xFF; + break; + case 18: + gSaveContext.equips.buttonItems[0] = (gSaveContext.sceneFlags[scene].unk >> 8) & 0xFF; + break; + case 19: + gSaveContext.equips.buttonItems[0] = gSaveContext.sceneFlags[scene].unk & 0xFF; + break; + case 20: + gSaveContext.equips.buttonItems[0] = (gSaveContext.sceneFlags[scene].rooms >> 24) & 0xFF; + break; + case 21: + gSaveContext.equips.buttonItems[0] = (gSaveContext.sceneFlags[scene].rooms >> 16) & 0xFF; + break; + case 22: + gSaveContext.equips.buttonItems[0] = (gSaveContext.sceneFlags[scene].rooms >> 8) & 0xFF; + break; + case 23: + gSaveContext.equips.buttonItems[0] = gSaveContext.sceneFlags[scene].rooms & 0xFF; + break; + case 24: + gSaveContext.equips.buttonItems[0] = (gSaveContext.sceneFlags[scene].floors >> 24) & 0xFF; + break; + case 25: + gSaveContext.equips.buttonItems[0] = (gSaveContext.sceneFlags[scene].floors >> 16) & 0xFF; + break; + case 26: + gSaveContext.equips.buttonItems[0] = (gSaveContext.sceneFlags[scene].floors >> 8) & 0xFF; + break; + case 27: + gSaveContext.equips.buttonItems[0] = gSaveContext.sceneFlags[scene].floors & 0xFF; + break; } } @@ -264,90 +266,117 @@ void HandleRBASceneFlags(uint8_t itemToPutInBottle) { u32 offset = gSaveContext.equips.buttonItems[3] - ITEM_SONG_LULLABY; u32 scene = offset / sizeof(SavedSceneFlags); switch (offset % sizeof(SavedSceneFlags)) { - case 0: - gSaveContext.sceneFlags[scene].chest = (itemToPutInBottle << 24) | (gSaveContext.sceneFlags[scene].chest & 0x00FFFFFF); - break; - case 1: - gSaveContext.sceneFlags[scene].chest = (itemToPutInBottle << 16) | (gSaveContext.sceneFlags[scene].chest & 0xFF00FFFF); - break; - case 2: - gSaveContext.sceneFlags[scene].chest = (itemToPutInBottle << 8) | (gSaveContext.sceneFlags[scene].chest & 0xFFFF00FF); - break; - case 3: - gSaveContext.sceneFlags[scene].chest = itemToPutInBottle | (gSaveContext.sceneFlags[scene].chest & 0xFFFFFF00); - break; - case 4: - gSaveContext.sceneFlags[scene].swch = (itemToPutInBottle << 24) | (gSaveContext.sceneFlags[scene].swch & 0x00FFFFFF); - break; - case 5: - gSaveContext.sceneFlags[scene].swch = (itemToPutInBottle << 16) | (gSaveContext.sceneFlags[scene].swch & 0xFF00FFFF); - break; - case 6: - gSaveContext.sceneFlags[scene].swch = (itemToPutInBottle << 8) | (gSaveContext.sceneFlags[scene].swch & 0xFFFF00FF); - break; - case 7: - gSaveContext.sceneFlags[scene].swch = itemToPutInBottle | (gSaveContext.sceneFlags[scene].swch & 0xFFFFFF00); - break; - case 8: - gSaveContext.sceneFlags[scene].clear = (itemToPutInBottle << 24) | (gSaveContext.sceneFlags[scene].clear & 0x00FFFFFF); - break; - case 9: - gSaveContext.sceneFlags[scene].clear = (itemToPutInBottle << 16) | (gSaveContext.sceneFlags[scene].clear & 0xFF00FFFF); - break; - case 10: - gSaveContext.sceneFlags[scene].clear = (itemToPutInBottle << 8) | (gSaveContext.sceneFlags[scene].clear & 0xFFFF00FF); - break; - case 11: - gSaveContext.sceneFlags[scene].clear = itemToPutInBottle | (gSaveContext.sceneFlags[scene].clear & 0xFFFFFF00); - break; - case 12: - gSaveContext.sceneFlags[scene].collect = (itemToPutInBottle << 24) | (gSaveContext.sceneFlags[scene].collect & 0x00FFFFFF); - break; - case 13: - gSaveContext.sceneFlags[scene].collect = (itemToPutInBottle << 16) | (gSaveContext.sceneFlags[scene].collect & 0xFF00FFFF); - break; - case 14: - gSaveContext.sceneFlags[scene].collect = (itemToPutInBottle << 8) | (gSaveContext.sceneFlags[scene].collect & 0xFFFF00FF); - break; - case 15: - gSaveContext.sceneFlags[scene].collect = itemToPutInBottle | (gSaveContext.sceneFlags[scene].collect & 0xFFFFFF00); - break; - case 16: - gSaveContext.sceneFlags[scene].unk = (itemToPutInBottle << 24) | (gSaveContext.sceneFlags[scene].unk & 0x00FFFFFF); - break; - case 17: - gSaveContext.sceneFlags[scene].unk = (itemToPutInBottle << 16) | (gSaveContext.sceneFlags[scene].unk & 0xFF00FFFF); - break; - case 18: - gSaveContext.sceneFlags[scene].unk = (itemToPutInBottle << 8) | (gSaveContext.sceneFlags[scene].unk & 0xFFFF00FF); - break; - case 19: - gSaveContext.sceneFlags[scene].unk = itemToPutInBottle | (gSaveContext.sceneFlags[scene].unk & 0xFFFFFF00); - break; - case 20: - gSaveContext.sceneFlags[scene].rooms = (itemToPutInBottle << 24) | (gSaveContext.sceneFlags[scene].rooms & 0x00FFFFFF); - break; - case 21: - gSaveContext.sceneFlags[scene].rooms = (itemToPutInBottle << 16) | (gSaveContext.sceneFlags[scene].rooms & 0xFF00FFFF); - break; - case 22: - gSaveContext.sceneFlags[scene].rooms = (itemToPutInBottle << 8) | (gSaveContext.sceneFlags[scene].rooms & 0xFFFF00FF); - break; - case 23: - gSaveContext.sceneFlags[scene].rooms = itemToPutInBottle | (gSaveContext.sceneFlags[scene].rooms & 0xFFFFFF00); - break; - case 24: - gSaveContext.sceneFlags[scene].floors = (itemToPutInBottle << 24) | (gSaveContext.sceneFlags[scene].floors & 0x00FFFFFF); - break; - case 25: - gSaveContext.sceneFlags[scene].floors = (itemToPutInBottle << 16) | (gSaveContext.sceneFlags[scene].floors & 0xFF00FFFF); - break; - case 26: - gSaveContext.sceneFlags[scene].floors = (itemToPutInBottle << 8) | (gSaveContext.sceneFlags[scene].floors & 0xFFFF00FF); - break; - case 27: - gSaveContext.sceneFlags[scene].floors = itemToPutInBottle | (gSaveContext.sceneFlags[scene].floors & 0xFFFFFF00); - break; + case 0: + gSaveContext.sceneFlags[scene].chest = + (itemToPutInBottle << 24) | (gSaveContext.sceneFlags[scene].chest & 0x00FFFFFF); + break; + case 1: + gSaveContext.sceneFlags[scene].chest = + (itemToPutInBottle << 16) | (gSaveContext.sceneFlags[scene].chest & 0xFF00FFFF); + break; + case 2: + gSaveContext.sceneFlags[scene].chest = + (itemToPutInBottle << 8) | (gSaveContext.sceneFlags[scene].chest & 0xFFFF00FF); + break; + case 3: + gSaveContext.sceneFlags[scene].chest = + itemToPutInBottle | (gSaveContext.sceneFlags[scene].chest & 0xFFFFFF00); + break; + case 4: + gSaveContext.sceneFlags[scene].swch = + (itemToPutInBottle << 24) | (gSaveContext.sceneFlags[scene].swch & 0x00FFFFFF); + break; + case 5: + gSaveContext.sceneFlags[scene].swch = + (itemToPutInBottle << 16) | (gSaveContext.sceneFlags[scene].swch & 0xFF00FFFF); + break; + case 6: + gSaveContext.sceneFlags[scene].swch = + (itemToPutInBottle << 8) | (gSaveContext.sceneFlags[scene].swch & 0xFFFF00FF); + break; + case 7: + gSaveContext.sceneFlags[scene].swch = + itemToPutInBottle | (gSaveContext.sceneFlags[scene].swch & 0xFFFFFF00); + break; + case 8: + gSaveContext.sceneFlags[scene].clear = + (itemToPutInBottle << 24) | (gSaveContext.sceneFlags[scene].clear & 0x00FFFFFF); + break; + case 9: + gSaveContext.sceneFlags[scene].clear = + (itemToPutInBottle << 16) | (gSaveContext.sceneFlags[scene].clear & 0xFF00FFFF); + break; + case 10: + gSaveContext.sceneFlags[scene].clear = + (itemToPutInBottle << 8) | (gSaveContext.sceneFlags[scene].clear & 0xFFFF00FF); + break; + case 11: + gSaveContext.sceneFlags[scene].clear = + itemToPutInBottle | (gSaveContext.sceneFlags[scene].clear & 0xFFFFFF00); + break; + case 12: + gSaveContext.sceneFlags[scene].collect = + (itemToPutInBottle << 24) | (gSaveContext.sceneFlags[scene].collect & 0x00FFFFFF); + break; + case 13: + gSaveContext.sceneFlags[scene].collect = + (itemToPutInBottle << 16) | (gSaveContext.sceneFlags[scene].collect & 0xFF00FFFF); + break; + case 14: + gSaveContext.sceneFlags[scene].collect = + (itemToPutInBottle << 8) | (gSaveContext.sceneFlags[scene].collect & 0xFFFF00FF); + break; + case 15: + gSaveContext.sceneFlags[scene].collect = + itemToPutInBottle | (gSaveContext.sceneFlags[scene].collect & 0xFFFFFF00); + break; + case 16: + gSaveContext.sceneFlags[scene].unk = + (itemToPutInBottle << 24) | (gSaveContext.sceneFlags[scene].unk & 0x00FFFFFF); + break; + case 17: + gSaveContext.sceneFlags[scene].unk = + (itemToPutInBottle << 16) | (gSaveContext.sceneFlags[scene].unk & 0xFF00FFFF); + break; + case 18: + gSaveContext.sceneFlags[scene].unk = + (itemToPutInBottle << 8) | (gSaveContext.sceneFlags[scene].unk & 0xFFFF00FF); + break; + case 19: + gSaveContext.sceneFlags[scene].unk = itemToPutInBottle | (gSaveContext.sceneFlags[scene].unk & 0xFFFFFF00); + break; + case 20: + gSaveContext.sceneFlags[scene].rooms = + (itemToPutInBottle << 24) | (gSaveContext.sceneFlags[scene].rooms & 0x00FFFFFF); + break; + case 21: + gSaveContext.sceneFlags[scene].rooms = + (itemToPutInBottle << 16) | (gSaveContext.sceneFlags[scene].rooms & 0xFF00FFFF); + break; + case 22: + gSaveContext.sceneFlags[scene].rooms = + (itemToPutInBottle << 8) | (gSaveContext.sceneFlags[scene].rooms & 0xFFFF00FF); + break; + case 23: + gSaveContext.sceneFlags[scene].rooms = + itemToPutInBottle | (gSaveContext.sceneFlags[scene].rooms & 0xFFFFFF00); + break; + case 24: + gSaveContext.sceneFlags[scene].floors = + (itemToPutInBottle << 24) | (gSaveContext.sceneFlags[scene].floors & 0x00FFFFFF); + break; + case 25: + gSaveContext.sceneFlags[scene].floors = + (itemToPutInBottle << 16) | (gSaveContext.sceneFlags[scene].floors & 0xFF00FFFF); + break; + case 26: + gSaveContext.sceneFlags[scene].floors = + (itemToPutInBottle << 8) | (gSaveContext.sceneFlags[scene].floors & 0xFFFF00FF); + break; + case 27: + gSaveContext.sceneFlags[scene].floors = + itemToPutInBottle | (gSaveContext.sceneFlags[scene].floors & 0xFFFFFF00); + break; } } diff --git a/soh/soh/Enhancements/Restorations/PauseBufferInputs.cpp b/soh/soh/Enhancements/Restorations/PauseBufferInputs.cpp index 373d481ef..090c46a60 100644 --- a/soh/soh/Enhancements/Restorations/PauseBufferInputs.cpp +++ b/soh/soh/Enhancements/Restorations/PauseBufferInputs.cpp @@ -31,8 +31,9 @@ void RegisterPauseBufferInputs() { COND_VB_SHOULD(VB_KALEIDO_UNPAUSE_CLOSE, CVAR_BUFFER_VALUE || CVAR_INCLUDE_VALUE, { Input* input = &gPlayState->state.input[0]; - // STEP #3: If the user opts to include held inputs in the buffer window, store the currnently held inputs, minus - // the held inputs when the pause menu was opened. This only applies to the first frame of the buffer window + // STEP #3: If the user opts to include held inputs in the buffer window, store the currnently held inputs, + // minus the held inputs when the pause menu was opened. This only applies to the first frame of the buffer + // window if (CVAR_INCLUDE_VALUE && inputBufferTimer == 0) { pauseInputs |= input->cur.button & ~prePauseInputs; prePauseInputs = 0; @@ -56,16 +57,15 @@ void RegisterPauseBufferInputs() { Input* input = &gPlayState->state.input[0]; PauseContext* pauseCtx = &gPlayState->pauseCtx; - // STEP #1: If the user opts to include held inputs in the buffer window, store the held inputs at the beginning + // STEP #1: If the user opts to include held inputs in the buffer window, store the held inputs at the beginning // of the pause process, minus the START input if (pauseCtx->state == PAUSE_STATE_OPENING_1 && CVAR_INCLUDE_VALUE) { prePauseInputs = input->cur.button & ~BTN_START; } // STEP #2: The unpause process has begun, so let's reset the input buffer timer - if (pauseCtx->state == PAUSE_STATE_UNPAUSE_SETUP || ( - pauseCtx->state == PAUSE_STATE_SAVEPROMPT && (pauseCtx->unk_1EC == 2 || pauseCtx->unk_1EC == 5) - )) { + if (pauseCtx->state == PAUSE_STATE_UNPAUSE_SETUP || + (pauseCtx->state == PAUSE_STATE_SAVEPROMPT && (pauseCtx->unk_1EC == 2 || pauseCtx->unk_1EC == 5))) { inputBufferTimer = 0; } diff --git a/soh/soh/Enhancements/TimeDisplay/TimeDisplay.cpp b/soh/soh/Enhancements/TimeDisplay/TimeDisplay.cpp index 4b374ed8e..8f1f0ac40 100644 --- a/soh/soh/Enhancements/TimeDisplay/TimeDisplay.cpp +++ b/soh/soh/Enhancements/TimeDisplay/TimeDisplay.cpp @@ -147,18 +147,18 @@ void TimeDisplayUpdateDisplayOptions() { } } - //if (pushBack) { - // activeTimers.push_back(timeDisplayList[timeID]); - //} else { - // uint32_t index = 0; - // for (auto& check : activeTimers) { - // if (check.timeID == timeID) { - // activeTimers.erase(activeTimers.begin() + index); - // return; - // } - // index++; - // } - //} + // if (pushBack) { + // activeTimers.push_back(timeDisplayList[timeID]); + // } else { + // uint32_t index = 0; + // for (auto& check : activeTimers) { + // if (check.timeID == timeID) { + // activeTimers.erase(activeTimers.begin() + index); + // return; + // } + // index++; + // } + // } } void TimeDisplayWindow::Draw() { @@ -174,9 +174,9 @@ void TimeDisplayWindow::Draw() { ImGui::PushStyleVar(ImGuiStyleVar_WindowRounding, 4.0f); ImGui::Begin("TimerDisplay", nullptr, - ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_NoNav | ImGuiWindowFlags_NoFocusOnAppearing | - ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoDocking | ImGuiWindowFlags_NoTitleBar | - ImGuiWindowFlags_NoScrollWithMouse | ImGuiWindowFlags_NoScrollbar); + ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_NoNav | ImGuiWindowFlags_NoFocusOnAppearing | + ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoDocking | ImGuiWindowFlags_NoTitleBar | + ImGuiWindowFlags_NoScrollWithMouse | ImGuiWindowFlags_NoScrollbar); ImGui::SetWindowFontScale(fontScale); if (activeTimers.size() == 0) { ImGui::Text("No Enabled Timers..."); @@ -247,13 +247,17 @@ static void TimeDisplayInitTimers() { } void TimeDisplayWindow::InitElement() { - Ship::Context::GetInstance()->GetWindow()->GetGui()->LoadGuiTexture("GAMEPLAY_TIMER", gClockIconTex, ImVec4(1, 1, 1, 1)); - Ship::Context::GetInstance()->GetWindow()->GetGui()->LoadGuiTexture("DAY_TIME_TIMER", gSunIconTex, ImVec4(1, 1, 1, 1)); - Ship::Context::GetInstance()->GetWindow()->GetGui()->LoadGuiTexture("NIGHT_TIME_TIMER", gMoonIconTex, ImVec4(1, 1, 1, 1)); + Ship::Context::GetInstance()->GetWindow()->GetGui()->LoadGuiTexture("GAMEPLAY_TIMER", gClockIconTex, + ImVec4(1, 1, 1, 1)); + Ship::Context::GetInstance()->GetWindow()->GetGui()->LoadGuiTexture("DAY_TIME_TIMER", gSunIconTex, + ImVec4(1, 1, 1, 1)); + Ship::Context::GetInstance()->GetWindow()->GetGui()->LoadGuiTexture("NIGHT_TIME_TIMER", gMoonIconTex, + ImVec4(1, 1, 1, 1)); Ship::Context::GetInstance()->GetWindow()->GetGui()->LoadGuiTexture("NAVI_TIMER", gNaviIconTex, ImVec4(1, 1, 1, 1)); for (auto& load : digitList) { - Ship::Context::GetInstance()->GetWindow()->GetGui()->LoadGuiTexture(load.first.c_str(), load.second, ImVec4(1, 1, 1, 1)); + Ship::Context::GetInstance()->GetWindow()->GetGui()->LoadGuiTexture(load.first.c_str(), load.second, + ImVec4(1, 1, 1, 1)); } TimeDisplayInitSettings(); diff --git a/soh/soh/Enhancements/TimeDisplay/TimeDisplay.h b/soh/soh/Enhancements/TimeDisplay/TimeDisplay.h index 41cda077f..eb213640e 100644 --- a/soh/soh/Enhancements/TimeDisplay/TimeDisplay.h +++ b/soh/soh/Enhancements/TimeDisplay/TimeDisplay.h @@ -5,9 +5,9 @@ class TimeDisplayWindow : public Ship::GuiWindow { using GuiWindow::GuiWindow; void InitElement() override; - void DrawElement() override {}; + void DrawElement() override{}; void Draw() override; - void UpdateElement() override {}; + void UpdateElement() override{}; }; void TimeDisplayUpdateDisplayOptions(); diff --git a/soh/soh/Enhancements/TimeSavers/FasterHeavyBlockLift.cpp b/soh/soh/Enhancements/TimeSavers/FasterHeavyBlockLift.cpp index 73909cbda..10a22d903 100644 --- a/soh/soh/Enhancements/TimeSavers/FasterHeavyBlockLift.cpp +++ b/soh/soh/Enhancements/TimeSavers/FasterHeavyBlockLift.cpp @@ -4,12 +4,12 @@ #include "spdlog/spdlog.h" extern "C" { - #include "z64save.h" - #include "macros.h" - #include "variables.h" - #include "functions.h" - extern PlayState* gPlayState; - extern SaveContext gSaveContext; +#include "z64save.h" +#include "macros.h" +#include "variables.h" +#include "functions.h" +extern PlayState* gPlayState; +extern SaveContext gSaveContext; } /** @@ -20,29 +20,30 @@ void FasterHeavyBlockLift_Register() { REGISTER_VB_SHOULD(VB_PLAY_ONEPOINT_ACTOR_CS, { Actor* actor = va_arg(args, Actor*); - if ( - actor->id == ACTOR_BG_HEAVY_BLOCK && - (CVarGetInteger(CVAR_ENHANCEMENT("FasterHeavyBlockLift"), 0) || CVarGetInteger(CVAR_ENHANCEMENT("TimeSavers.SkipCutscene.OnePoint"), IS_RANDO)) - ) { + if (actor->id == ACTOR_BG_HEAVY_BLOCK && + (CVarGetInteger(CVAR_ENHANCEMENT("FasterHeavyBlockLift"), 0) || + CVarGetInteger(CVAR_ENHANCEMENT("TimeSavers.SkipCutscene.OnePoint"), IS_RANDO))) { *should = false; } }); REGISTER_VB_SHOULD(VB_FREEZE_LINK_FOR_BLOCK_THROW, { - if (CVarGetInteger(CVAR_ENHANCEMENT("FasterHeavyBlockLift"), 0) || CVarGetInteger(CVAR_ENHANCEMENT("TimeSavers.SkipCutscene.OnePoint"), IS_RANDO)) { + if (CVarGetInteger(CVAR_ENHANCEMENT("FasterHeavyBlockLift"), 0) || + CVarGetInteger(CVAR_ENHANCEMENT("TimeSavers.SkipCutscene.OnePoint"), IS_RANDO)) { *should = false; } }); REGISTER_VB_SHOULD(VB_PLAY_THROW_ANIMATION, { - Player *player = GET_PLAYER(gPlayState); + Player* player = GET_PLAYER(gPlayState); Actor* interactRangeActor = player->interactRangeActor; s32 interactActorId = interactRangeActor->id; LinkAnimationHeader* anim = va_arg(args, LinkAnimationHeader*); // Same actor is used for small and large silver rocks, use actor params to identify large ones bool isLargeSilverRock = interactActorId == ACTOR_EN_ISHI && interactRangeActor->params & 1 == 1; - if (CVarGetInteger(CVAR_ENHANCEMENT("FasterHeavyBlockLift"), 0) && (isLargeSilverRock || interactActorId == ACTOR_BG_HEAVY_BLOCK)) { + if (CVarGetInteger(CVAR_ENHANCEMENT("FasterHeavyBlockLift"), 0) && + (isLargeSilverRock || interactActorId == ACTOR_BG_HEAVY_BLOCK)) { *should = false; LinkAnimation_PlayOnceSetSpeed(gPlayState, &player->skelAnime, anim, 5.0f); } diff --git a/soh/soh/Enhancements/TimeSavers/FasterRupeeAccumulator.cpp b/soh/soh/Enhancements/TimeSavers/FasterRupeeAccumulator.cpp index 347787c27..36a780b6a 100644 --- a/soh/soh/Enhancements/TimeSavers/FasterRupeeAccumulator.cpp +++ b/soh/soh/Enhancements/TimeSavers/FasterRupeeAccumulator.cpp @@ -4,17 +4,18 @@ #include "spdlog/spdlog.h" extern "C" { - #include "z64save.h" - #include "macros.h" - #include "variables.h" - #include "functions.h" - extern PlayState* gPlayState; - extern SaveContext gSaveContext; +#include "z64save.h" +#include "macros.h" +#include "variables.h" +#include "functions.h" +extern PlayState* gPlayState; +extern SaveContext gSaveContext; } void FasterRupeeAccumulator_Register() { GameInteractor::Instance->RegisterGameHook([]() { - if (!CVarGetInteger(CVAR_ENHANCEMENT("FasterRupeeAccumulator"), 0)) return; + if (!CVarGetInteger(CVAR_ENHANCEMENT("FasterRupeeAccumulator"), 0)) + return; if (gSaveContext.rupeeAccumulator == 0) { return; @@ -28,10 +29,10 @@ void FasterRupeeAccumulator_Register() { } if (gSaveContext.rupeeAccumulator >= 10 && gSaveContext.rupees + 10 < CUR_CAPACITY(UPG_WALLET)) { - gSaveContext.rupeeAccumulator-= 10; + gSaveContext.rupeeAccumulator -= 10; gSaveContext.rupees += 10; } - // Losing rupees + // Losing rupees } else if (gSaveContext.rupeeAccumulator < 0) { // No rupees to lose if (gSaveContext.rupees == 0) { diff --git a/soh/soh/Enhancements/TimeSavers/SkipCutscene/Story/SkipBlueWarp.cpp b/soh/soh/Enhancements/TimeSavers/SkipCutscene/Story/SkipBlueWarp.cpp index ae4236218..674adcdfb 100644 --- a/soh/soh/Enhancements/TimeSavers/SkipCutscene/Story/SkipBlueWarp.cpp +++ b/soh/soh/Enhancements/TimeSavers/SkipCutscene/Story/SkipBlueWarp.cpp @@ -24,7 +24,7 @@ void SkipBlueWarp_ShouldPlayTransitionCS(GIVanillaBehavior _, bool* should, va_l if (IS_BOSS_RUSH) { return; } - + bool overrideBlueWarpDestinations = IS_RANDO && (RAND_GET_OPTION(RSK_SHUFFLE_DUNGEON_ENTRANCES) != RO_DUNGEON_ENTRANCE_SHUFFLE_OFF || RAND_GET_OPTION(RSK_SHUFFLE_BOSS_ENTRANCES) != RO_BOSS_ROOM_ENTRANCE_SHUFFLE_OFF); @@ -37,16 +37,19 @@ void SkipBlueWarp_ShouldPlayTransitionCS(GIVanillaBehavior _, bool* should, va_l if (gSaveContext.entranceIndex == ENTR_KOKIRI_FOREST_0 && gSaveContext.cutsceneIndex == 0xFFF1) { gSaveContext.entranceIndex = ENTR_KOKIRI_FOREST_DEKU_TREE_BLUE_WARP; isBlueWarpCutscene = true; - // Dodongo's Cavern Blue warp - } else if (gSaveContext.entranceIndex == ENTR_DEATH_MOUNTAIN_TRAIL_BOTTOM_EXIT && gSaveContext.cutsceneIndex == 0xFFF1) { + // Dodongo's Cavern Blue warp + } else if (gSaveContext.entranceIndex == ENTR_DEATH_MOUNTAIN_TRAIL_BOTTOM_EXIT && + gSaveContext.cutsceneIndex == 0xFFF1) { gSaveContext.entranceIndex = ENTR_DEATH_MOUNTAIN_TRAIL_DODONGO_BLUE_WARP; isBlueWarpCutscene = true; - // Jabu Jabu's Blue warp - } else if (gSaveContext.entranceIndex == ENTR_ZORAS_FOUNTAIN_JABU_JABU_BLUE_WARP && gSaveContext.cutsceneIndex == 0xFFF0) { + // Jabu Jabu's Blue warp + } else if (gSaveContext.entranceIndex == ENTR_ZORAS_FOUNTAIN_JABU_JABU_BLUE_WARP && + gSaveContext.cutsceneIndex == 0xFFF0) { gSaveContext.entranceIndex = ENTR_ZORAS_FOUNTAIN_JABU_JABU_BLUE_WARP; isBlueWarpCutscene = true; - // Forest Temple Blue warp - } else if (gSaveContext.entranceIndex == ENTR_CHAMBER_OF_THE_SAGES_0 && gSaveContext.cutsceneIndex == 0x0 && gSaveContext.chamberCutsceneNum == CHAMBER_CS_FOREST) { + // Forest Temple Blue warp + } else if (gSaveContext.entranceIndex == ENTR_CHAMBER_OF_THE_SAGES_0 && gSaveContext.cutsceneIndex == 0x0 && + gSaveContext.chamberCutsceneNum == CHAMBER_CS_FOREST) { // Normally set in the blue warp cutscene Flags_SetEventChkInf(EVENTCHKINF_SPOKE_TO_DEKU_TREE_SPROUT); @@ -57,27 +60,31 @@ void SkipBlueWarp_ShouldPlayTransitionCS(GIVanillaBehavior _, bool* should, va_l } isBlueWarpCutscene = true; - // Fire Temple Blue warp - } else if (gSaveContext.entranceIndex == ENTR_KAKARIKO_VILLAGE_FRONT_GATE && gSaveContext.cutsceneIndex == 0xFFF3) { + // Fire Temple Blue warp + } else if (gSaveContext.entranceIndex == ENTR_KAKARIKO_VILLAGE_FRONT_GATE && + gSaveContext.cutsceneIndex == 0xFFF3) { // Normally set in the blue warp cutscene Flags_SetEventChkInf(EVENTCHKINF_DEATH_MOUNTAIN_ERUPTED); gSaveContext.entranceIndex = ENTR_DEATH_MOUNTAIN_CRATER_FIRE_TEMPLE_BLUE_WARP; isBlueWarpCutscene = true; - // Water Temple Blue warp - } else if (gSaveContext.entranceIndex == ENTR_CHAMBER_OF_THE_SAGES_0 && gSaveContext.cutsceneIndex == 0x0 && gSaveContext.chamberCutsceneNum == CHAMBER_CS_WATER) { + // Water Temple Blue warp + } else if (gSaveContext.entranceIndex == ENTR_CHAMBER_OF_THE_SAGES_0 && gSaveContext.cutsceneIndex == 0x0 && + gSaveContext.chamberCutsceneNum == CHAMBER_CS_WATER) { // Normally set in the blue warp cutscene gSaveContext.dayTime = gSaveContext.skyboxTime = 0x4800; Flags_SetEventChkInf(EVENTCHKINF_RAISED_LAKE_HYLIA_WATER); gSaveContext.entranceIndex = ENTR_LAKE_HYLIA_WATER_TEMPLE_BLUE_WARP; isBlueWarpCutscene = true; - // Spirit Temple Blue warp - } else if (gSaveContext.entranceIndex == ENTR_CHAMBER_OF_THE_SAGES_0 && gSaveContext.cutsceneIndex == 0x0 && gSaveContext.chamberCutsceneNum == CHAMBER_CS_SPIRIT) { + // Spirit Temple Blue warp + } else if (gSaveContext.entranceIndex == ENTR_CHAMBER_OF_THE_SAGES_0 && gSaveContext.cutsceneIndex == 0x0 && + gSaveContext.chamberCutsceneNum == CHAMBER_CS_SPIRIT) { gSaveContext.entranceIndex = ENTR_DESERT_COLOSSUS_SPIRIT_TEMPLE_BLUE_WARP; isBlueWarpCutscene = true; - // Shadow Temple Blue warp - } else if (gSaveContext.entranceIndex == ENTR_CHAMBER_OF_THE_SAGES_0 && gSaveContext.cutsceneIndex == 0x0 && gSaveContext.chamberCutsceneNum == CHAMBER_CS_SHADOW) { + // Shadow Temple Blue warp + } else if (gSaveContext.entranceIndex == ENTR_CHAMBER_OF_THE_SAGES_0 && gSaveContext.cutsceneIndex == 0x0 && + gSaveContext.chamberCutsceneNum == CHAMBER_CS_SHADOW) { gSaveContext.entranceIndex = ENTR_GRAVEYARD_SHADOW_TEMPLE_BLUE_WARP; isBlueWarpCutscene = true; } @@ -92,7 +99,8 @@ void SkipBlueWarp_ShouldPlayTransitionCS(GIVanillaBehavior _, bool* should, va_l gSaveContext.cutsceneIndex = 0; } - // This is outside the above condition because we want to handle both first and following visits to the blue warp + // This is outside the above condition because we want to handle both first and following visits to the blue + // warp if (sEnteredBlueWarp && overrideBlueWarpDestinations) { Entrance_OverrideBlueWarp(); } @@ -111,7 +119,7 @@ void SkipBlueWarp_ShouldPlayBlueWarpCS(GIVanillaBehavior _, bool* should, va_lis /** * While we could rely on the Item_Give that's normally called, it's not very clear to the player that they - * received the item when skipping the blue warp cutscene, so we'll prevent that and queue it up to be given + * received the item when skipping the blue warp cutscene, so we'll prevent that and queue it up to be given * to the player instead. */ void SkipBlueWarp_ShouldGiveItem(GIVanillaBehavior _, bool* should, va_list originalArgs) { @@ -142,31 +150,35 @@ void EnKo_MoveWhenReady(EnKo* enKo, PlayState* play) { void SkipBlueWarp_OnActorUpdate(void* actorPtr) { EnKo* enKo = static_cast(actorPtr); - if ( - (enKo->actor.params & 0xFF) == ENKO_TYPE_CHILD_3 && - enKo->actionFunc == func_80A995CC && - CVarGetInteger(CVAR_ENHANCEMENT("TimeSavers.SkipCutscene.Story"), IS_RANDO) - ) { + if ((enKo->actor.params & 0xFF) == ENKO_TYPE_CHILD_3 && enKo->actionFunc == func_80A995CC && + CVarGetInteger(CVAR_ENHANCEMENT("TimeSavers.SkipCutscene.Story"), IS_RANDO)) { enKo->actionFunc = EnKo_MoveWhenReady; } } /** * This will ensure that the Deku Tree Sprout considers the Forest Temple finished when you skip the blue warp cutscene. - * Typically this checks for if you have the medallion, and when skipping the cutscene at this point you don't have it yet. + * Typically this checks for if you have the medallion, and when skipping the cutscene at this point you don't have it + * yet. */ void SkipBlueWarp_ShouldDekuJrConsiderForestTempleFinished(GIVanillaBehavior _, bool* should, va_list originalArgs) { if (CVarGetInteger(CVAR_ENHANCEMENT("TimeSavers.SkipCutscene.Story"), IS_RANDO)) { - if (gSaveContext.entranceIndex == ENTR_KOKIRI_FOREST_DEKU_TREE_BLUE_WARP && gSaveContext.cutsceneIndex == 0xFFF1) { + if (gSaveContext.entranceIndex == ENTR_KOKIRI_FOREST_DEKU_TREE_BLUE_WARP && + gSaveContext.cutsceneIndex == 0xFFF1) { *should = Flags_GetEventChkInf(EVENTCHKINF_USED_FOREST_TEMPLE_BLUE_WARP); } } } void SkipBlueWarp_Register() { - GameInteractor::Instance->RegisterGameHookForID(ACTOR_EN_KO, SkipBlueWarp_OnActorUpdate); - GameInteractor::Instance->RegisterGameHookForID(VB_PLAY_TRANSITION_CS, SkipBlueWarp_ShouldPlayTransitionCS); - GameInteractor::Instance->RegisterGameHookForID(VB_PLAY_BLUE_WARP_CS, SkipBlueWarp_ShouldPlayBlueWarpCS); - GameInteractor::Instance->RegisterGameHookForID(VB_DEKU_JR_CONSIDER_FOREST_TEMPLE_FINISHED, SkipBlueWarp_ShouldDekuJrConsiderForestTempleFinished); - GameInteractor::Instance->RegisterGameHookForID(VB_GIVE_ITEM_FROM_BLUE_WARP, SkipBlueWarp_ShouldGiveItem); + GameInteractor::Instance->RegisterGameHookForID(ACTOR_EN_KO, + SkipBlueWarp_OnActorUpdate); + GameInteractor::Instance->RegisterGameHookForID( + VB_PLAY_TRANSITION_CS, SkipBlueWarp_ShouldPlayTransitionCS); + GameInteractor::Instance->RegisterGameHookForID( + VB_PLAY_BLUE_WARP_CS, SkipBlueWarp_ShouldPlayBlueWarpCS); + GameInteractor::Instance->RegisterGameHookForID( + VB_DEKU_JR_CONSIDER_FOREST_TEMPLE_FINISHED, SkipBlueWarp_ShouldDekuJrConsiderForestTempleFinished); + GameInteractor::Instance->RegisterGameHookForID(VB_GIVE_ITEM_FROM_BLUE_WARP, + SkipBlueWarp_ShouldGiveItem); } diff --git a/soh/soh/Enhancements/TimeSavers/SkipCutscene/Story/SkipDekuTreeIntro.cpp b/soh/soh/Enhancements/TimeSavers/SkipCutscene/Story/SkipDekuTreeIntro.cpp index e1cc1db21..361f69d68 100644 --- a/soh/soh/Enhancements/TimeSavers/SkipCutscene/Story/SkipDekuTreeIntro.cpp +++ b/soh/soh/Enhancements/TimeSavers/SkipCutscene/Story/SkipDekuTreeIntro.cpp @@ -3,18 +3,19 @@ #include "soh/OTRGlobals.h" extern "C" { - #include "src/overlays/actors/ovl_Bg_Treemouth/z_bg_treemouth.h" +#include "src/overlays/actors/ovl_Bg_Treemouth/z_bg_treemouth.h" } /** * This will skip the Deku Tree intro, and simply open the mouth as you approach it. -*/ + */ void SkipDekuTreeIntro_Register() { REGISTER_VB_SHOULD(VB_PLAY_DEKU_TREE_INTRO_CS, { if (CVarGetInteger(CVAR_ENHANCEMENT("TimeSavers.SkipCutscene.Story"), IS_RANDO)) { BgTreemouth* treeMouth = va_arg(args, BgTreemouth*); Flags_SetEventChkInf(EVENTCHKINF_DEKU_TREE_OPENED_MOUTH); - Audio_PlaySoundGeneral(NA_SE_EV_WOODDOOR_OPEN, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb); + Audio_PlaySoundGeneral(NA_SE_EV_WOODDOOR_OPEN, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, + &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb); BgTreemouth_SetupAction(treeMouth, func_808BC6F8); *should = false; } diff --git a/soh/soh/Enhancements/TimeSavers/SkipCutscene/Story/SkipLostWoodsBridge.cpp b/soh/soh/Enhancements/TimeSavers/SkipCutscene/Story/SkipLostWoodsBridge.cpp index d487c1f47..9485bdb0f 100644 --- a/soh/soh/Enhancements/TimeSavers/SkipCutscene/Story/SkipLostWoodsBridge.cpp +++ b/soh/soh/Enhancements/TimeSavers/SkipCutscene/Story/SkipLostWoodsBridge.cpp @@ -3,19 +3,21 @@ #include "soh/OTRGlobals.h" extern "C" { - #include "z64save.h" - #include "functions.h" - extern PlayState* gPlayState; - extern SaveContext gSaveContext; +#include "z64save.h" +#include "functions.h" +extern PlayState* gPlayState; +extern SaveContext gSaveContext; } void SkipLostWoodsBridge_Register() { /** - * This skips the cutscene where you speak to Saria on the bridge in Lost Woods, where she gives you the Fairy Ocarina. + * This skips the cutscene where you speak to Saria on the bridge in Lost Woods, where she gives you the Fairy + * Ocarina. */ REGISTER_VB_SHOULD(VB_PLAY_TRANSITION_CS, { if (CVarGetInteger(CVAR_ENHANCEMENT("TimeSavers.SkipCutscene.Story"), IS_RANDO)) { - if ((gSaveContext.entranceIndex == ENTR_LOST_WOODS_BRIDGE_EAST_EXIT) && !Flags_GetEventChkInf(EVENTCHKINF_SPOKE_TO_SARIA_ON_BRIDGE)) { + if ((gSaveContext.entranceIndex == ENTR_LOST_WOODS_BRIDGE_EAST_EXIT) && + !Flags_GetEventChkInf(EVENTCHKINF_SPOKE_TO_SARIA_ON_BRIDGE)) { Flags_SetEventChkInf(EVENTCHKINF_SPOKE_TO_SARIA_ON_BRIDGE); if (GameInteractor_Should(VB_GIVE_ITEM_FAIRY_OCARINA, true)) { Item_Give(gPlayState, ITEM_OCARINA_FAIRY); @@ -26,8 +28,9 @@ void SkipLostWoodsBridge_Register() { }); /** - * While we could rely on the Item_Give that's normally called (and that we have above), it's not very clear to the player - * that they received the item when skipping the cutscene, so we'll prevent it, and queue it up to be given instead. + * While we could rely on the Item_Give that's normally called (and that we have above), it's not very clear to the + * player that they received the item when skipping the cutscene, so we'll prevent it, and queue it up to be given + * instead. */ REGISTER_VB_SHOULD(VB_GIVE_ITEM_FAIRY_OCARINA, { if (CVarGetInteger(CVAR_ENHANCEMENT("TimeSavers.SkipCutscene.Story"), IS_RANDO)) { diff --git a/soh/soh/Enhancements/TimeSavers/SkipCutscene/Story/SkipToGivingZeldasLetter.cpp b/soh/soh/Enhancements/TimeSavers/SkipCutscene/Story/SkipToGivingZeldasLetter.cpp index 357125db8..c623d46d2 100644 --- a/soh/soh/Enhancements/TimeSavers/SkipCutscene/Story/SkipToGivingZeldasLetter.cpp +++ b/soh/soh/Enhancements/TimeSavers/SkipCutscene/Story/SkipToGivingZeldasLetter.cpp @@ -3,7 +3,7 @@ #include "soh/OTRGlobals.h" extern "C" { - #include "src/overlays/actors/ovl_En_Zl4/z_en_zl4.h" +#include "src/overlays/actors/ovl_En_Zl4/z_en_zl4.h" } /** @@ -21,7 +21,8 @@ void EnZl4_SkipToGivingZeldasLetter(EnZl4* enZl4, PlayState* play) { Audio_PlayFanfare(NA_BGM_APPEAR); enZl4->csState = 8; // ZL4_CS_PLAN } else { - Npc_UpdateTalking(play, &enZl4->actor, &enZl4->interactInfo.talkState, enZl4->collider.dim.radius + 60.0f, EnZl4_GiveItemTextId, func_80B5B9B0); + Npc_UpdateTalking(play, &enZl4->actor, &enZl4->interactInfo.talkState, enZl4->collider.dim.radius + 60.0f, + EnZl4_GiveItemTextId, func_80B5B9B0); func_80B5BB78(enZl4, play); if (enZl4->interactInfo.talkState != NPC_TALK_STATE_IDLE) { @@ -34,12 +35,14 @@ void EnZl4_SkipToGivingZeldasLetter(EnZl4* enZl4, PlayState* play) { void SkipToGivingZeldasLetter_OnActorInit(void* actorPtr) { if (CVarGetInteger(CVAR_ENHANCEMENT("TimeSavers.SkipCutscene.Story"), IS_RANDO)) { EnZl4* enZl4 = static_cast(actorPtr); - if (enZl4->actionFunc != EnZl4_Cutscene || enZl4->csState != 0) return; + if (enZl4->actionFunc != EnZl4_Cutscene || enZl4->csState != 0) + return; enZl4->actionFunc = EnZl4_SkipToGivingZeldasLetter; } } void SkipToGivingZeldasLetter_Register() { - GameInteractor::Instance->RegisterGameHookForID(ACTOR_EN_ZL4, SkipToGivingZeldasLetter_OnActorInit); + GameInteractor::Instance->RegisterGameHookForID(ACTOR_EN_ZL4, + SkipToGivingZeldasLetter_OnActorInit); } diff --git a/soh/soh/Enhancements/TimeSavers/SkipCutscene/Story/SkipZeldaFleeingCastle.cpp b/soh/soh/Enhancements/TimeSavers/SkipCutscene/Story/SkipZeldaFleeingCastle.cpp index 1cb331539..56d26f01d 100644 --- a/soh/soh/Enhancements/TimeSavers/SkipCutscene/Story/SkipZeldaFleeingCastle.cpp +++ b/soh/soh/Enhancements/TimeSavers/SkipCutscene/Story/SkipZeldaFleeingCastle.cpp @@ -3,9 +3,9 @@ #include "soh/OTRGlobals.h" extern "C" { - #include "z64save.h" - #include "functions.h" - extern SaveContext gSaveContext; +#include "z64save.h" +#include "functions.h" +extern SaveContext gSaveContext; } void SkipZeldaFleeingCastle_ShouldPlayTransitionCS(GIVanillaBehavior _, bool* should, va_list originalArgs) { @@ -46,13 +46,11 @@ void SkipZeldaFleeingCastle_OnActorUpdate(void* actorPtr) { void SkipZeldaFleeingCastle_OnActorInit(void* actorPtr) { Actor* actor = static_cast(actorPtr); - if ( - actor->params == 3 && - CVarGetInteger(CVAR_ENHANCEMENT("TimeSavers.SkipCutscene.Story"), IS_RANDO) - ) { + if (actor->params == 3 && CVarGetInteger(CVAR_ENHANCEMENT("TimeSavers.SkipCutscene.Story"), IS_RANDO)) { framesSinceSpawn = 0; - itemOcarinaUpdateHook = GameInteractor::Instance->RegisterGameHookForPtr((uintptr_t)actorPtr, SkipZeldaFleeingCastle_OnActorUpdate); - sceneInitHook = GameInteractor::Instance->RegisterGameHook([] (int16_t sceneNum) { + itemOcarinaUpdateHook = GameInteractor::Instance->RegisterGameHookForPtr( + (uintptr_t)actorPtr, SkipZeldaFleeingCastle_OnActorUpdate); + sceneInitHook = GameInteractor::Instance->RegisterGameHook([](int16_t sceneNum) { GameInteractor::Instance->UnregisterGameHookForPtr(itemOcarinaUpdateHook); GameInteractor::Instance->UnregisterGameHook(sceneInitHook); itemOcarinaUpdateHook = 0; @@ -62,6 +60,8 @@ void SkipZeldaFleeingCastle_OnActorInit(void* actorPtr) { } void SkipZeldaFleeingCastle_Register() { - GameInteractor::Instance->RegisterGameHookForID(ACTOR_ITEM_OCARINA, SkipZeldaFleeingCastle_OnActorInit); - GameInteractor::Instance->RegisterGameHookForID(VB_PLAY_TRANSITION_CS, SkipZeldaFleeingCastle_ShouldPlayTransitionCS); + GameInteractor::Instance->RegisterGameHookForID(ACTOR_ITEM_OCARINA, + SkipZeldaFleeingCastle_OnActorInit); + GameInteractor::Instance->RegisterGameHookForID( + VB_PLAY_TRANSITION_CS, SkipZeldaFleeingCastle_ShouldPlayTransitionCS); } diff --git a/soh/soh/Enhancements/TimeSavers/SkipMiscInteractions/MoveJabuJabuElevator.cpp b/soh/soh/Enhancements/TimeSavers/SkipMiscInteractions/MoveJabuJabuElevator.cpp index 1e1c6ceb5..704339424 100644 --- a/soh/soh/Enhancements/TimeSavers/SkipMiscInteractions/MoveJabuJabuElevator.cpp +++ b/soh/soh/Enhancements/TimeSavers/SkipMiscInteractions/MoveJabuJabuElevator.cpp @@ -10,18 +10,19 @@ extern "C" { * Adjusts the behavior of the elevator to start near the bottom if you are entering the room from the bottom */ void MoveJabuJabuElevator_Register() { - GameInteractor::Instance->RegisterGameHookForID(ACTOR_BG_BDAN_OBJECTS, [](void* actorRef) { - Player* player = GET_PLAYER(gPlayState); - BgBdanObjects* bgBdanObjects = static_cast(actorRef); + GameInteractor::Instance->RegisterGameHookForID( + ACTOR_BG_BDAN_OBJECTS, [](void* actorRef) { + Player* player = GET_PLAYER(gPlayState); + BgBdanObjects* bgBdanObjects = static_cast(actorRef); - if (!CVarGetInteger(CVAR_ENHANCEMENT("TimeSavers.SkipMiscInteractions"), IS_RANDO)) { - return; - } - - if (bgBdanObjects->dyna.actor.params == 1) { - if (player->actor.world.pos.y < -500.0f) { - bgBdanObjects->timer = 220; + if (!CVarGetInteger(CVAR_ENHANCEMENT("TimeSavers.SkipMiscInteractions"), IS_RANDO)) { + return; } - } - }); + + if (bgBdanObjects->dyna.actor.params == 1) { + if (player->actor.world.pos.y < -500.0f) { + bgBdanObjects->timer = 220; + } + } + }); } diff --git a/soh/soh/Enhancements/TimeSavers/SkipMiscInteractions/MoveMidoInKokiriForest.cpp b/soh/soh/Enhancements/TimeSavers/SkipMiscInteractions/MoveMidoInKokiriForest.cpp index 59381968a..6e9b94b4a 100644 --- a/soh/soh/Enhancements/TimeSavers/SkipMiscInteractions/MoveMidoInKokiriForest.cpp +++ b/soh/soh/Enhancements/TimeSavers/SkipMiscInteractions/MoveMidoInKokiriForest.cpp @@ -3,12 +3,12 @@ #include "soh/OTRGlobals.h" extern "C" { - #include "z64save.h" - #include "macros.h" - #include "variables.h" - #include "functions.h" - extern PlayState* gPlayState; - extern SaveContext gSaveContext; +#include "z64save.h" +#include "macros.h" +#include "variables.h" +#include "functions.h" +extern PlayState* gPlayState; +extern SaveContext gSaveContext; } /** @@ -17,13 +17,10 @@ extern "C" { */ void MoveMidoInKokiriForest_Register() { REGISTER_VB_SHOULD(VB_MOVE_MIDO_IN_KOKIRI_FOREST, { - if ( - CVarGetInteger(CVAR_ENHANCEMENT("TimeSavers.SkipMiscInteractions"), IS_RANDO) && + if (CVarGetInteger(CVAR_ENHANCEMENT("TimeSavers.SkipMiscInteractions"), IS_RANDO) && !Flags_GetEventChkInf(EVENTCHKINF_SHOWED_MIDO_SWORD_SHIELD) && - (CUR_EQUIP_VALUE(EQUIP_TYPE_SHIELD) == EQUIP_VALUE_SHIELD_DEKU) && - (CUR_EQUIP_VALUE(EQUIP_TYPE_SWORD) == EQUIP_VALUE_SWORD_KOKIRI) && - gSaveContext.cutsceneIndex == 0 - ) { + (CUR_EQUIP_VALUE(EQUIP_TYPE_SHIELD) == EQUIP_VALUE_SHIELD_DEKU) && + (CUR_EQUIP_VALUE(EQUIP_TYPE_SWORD) == EQUIP_VALUE_SWORD_KOKIRI) && gSaveContext.cutsceneIndex == 0) { Flags_SetEventChkInf(EVENTCHKINF_SHOWED_MIDO_SWORD_SHIELD); *should = true; } diff --git a/soh/soh/Enhancements/TimeSavers/SkipMiscInteractions/SkipChildRutoInteractions.cpp b/soh/soh/Enhancements/TimeSavers/SkipMiscInteractions/SkipChildRutoInteractions.cpp index 2894cb914..97b65a543 100644 --- a/soh/soh/Enhancements/TimeSavers/SkipMiscInteractions/SkipChildRutoInteractions.cpp +++ b/soh/soh/Enhancements/TimeSavers/SkipMiscInteractions/SkipChildRutoInteractions.cpp @@ -29,7 +29,7 @@ void SkipChildRutoInteractions_Register() { if (*should) { Animation_Change(&enRu1->skelAnime, (AnimationHeader*)&gRutoChildTurnAroundAnim, 1.0f, 0, - Animation_GetLastFrame((void*)&gRutoChildTurnAroundAnim), ANIMMODE_ONCE, -8.0f); + Animation_GetLastFrame((void*)&gRutoChildTurnAroundAnim), ANIMMODE_ONCE, -8.0f); enRu1->action = 10; } @@ -48,7 +48,8 @@ void SkipChildRutoInteractions_Register() { } }); - // Prevents Ruto from running to the Sapphire when she wants to be tossed to it, instead she just stands up and waits for link to get closer + // Prevents Ruto from running to the Sapphire when she wants to be tossed to it, instead she just stands up and + // waits for link to get closer REGISTER_VB_SHOULD(VB_RUTO_RUN_TO_SAPPHIRE, { EnRu1* enRu1 = va_arg(args, EnRu1*); DynaPolyActor* dynaPolyActor = va_arg(args, DynaPolyActor*); @@ -63,12 +64,13 @@ void SkipChildRutoInteractions_Register() { Flags_SetSwitch(gPlayState, 0x02); Flags_SetSwitch(gPlayState, 0x1F); enRu1->action = 42; - Animation_Change(&enRu1->skelAnime, (AnimationHeader*)&gRutoChildWait2Anim, 1.0f, 0, - Animation_GetLastFrame((void*)&gRutoChildWait2Anim), ANIMMODE_LOOP, -8.0f); + Animation_Change(&enRu1->skelAnime, (AnimationHeader*)&gRutoChildWait2Anim, 1.0f, 0, + Animation_GetLastFrame((void*)&gRutoChildWait2Anim), ANIMMODE_LOOP, -8.0f); // If we aren't skipping one point cutscenes and BgBdan objects has set the camera setting // to CAM_SET_NORMAL1 (2), don't reset the camera setting to 1. This prevents the One Point // Cutscene of Ruto getting lifted up from getting queued up twice. - if (CVarGetInteger(CVAR_ENHANCEMENT("TimeSavers.SkipCutscene.OnePoint"), IS_RANDO) || enRu1->unk_28C->cameraSetting != 2) { + if (CVarGetInteger(CVAR_ENHANCEMENT("TimeSavers.SkipCutscene.OnePoint"), IS_RANDO) || + enRu1->unk_28C->cameraSetting != 2) { enRu1->unk_28C->cameraSetting = 1; } Actor* sapphire = func_80AEB124(gPlayState); @@ -80,7 +82,8 @@ void SkipChildRutoInteractions_Register() { } }); - // This overrides the behavior that causes Ruto to get upset at you before sitting back down again when INFTABLE_RUTO_IN_JJ_TALK_FIRST_TIME is set + // This overrides the behavior that causes Ruto to get upset at you before sitting back down again when + // INFTABLE_RUTO_IN_JJ_TALK_FIRST_TIME is set GameInteractor::Instance->RegisterGameHookForID(ACTOR_EN_RU1, [](void* actorRef) { EnRu1* enRu1 = static_cast(actorRef); if (!CVarGetInteger(CVAR_ENHANCEMENT("TimeSavers.SkipMiscInteractions"), IS_RANDO)) { @@ -92,7 +95,7 @@ void SkipChildRutoInteractions_Register() { enRu1->drawConfig = 1; enRu1->actor.flags |= ACTOR_FLAG_ATTENTION_ENABLED | ACTOR_FLAG_FRIENDLY; Animation_Change(&enRu1->skelAnime, (AnimationHeader*)&gRutoChildSittingAnim, 1.0f, 0.0f, - Animation_GetLastFrame((void*)&gRutoChildSittingAnim), ANIMMODE_LOOP, 0.0f); + Animation_GetLastFrame((void*)&gRutoChildSittingAnim), ANIMMODE_LOOP, 0.0f); } }); } diff --git a/soh/soh/Enhancements/TimeSavers/TimeSavers.cpp b/soh/soh/Enhancements/TimeSavers/TimeSavers.cpp index a198f8289..a881675d6 100644 --- a/soh/soh/Enhancements/TimeSavers/TimeSavers.cpp +++ b/soh/soh/Enhancements/TimeSavers/TimeSavers.cpp @@ -2,17 +2,17 @@ void TimeSavers_Register() { // SkipCutscene - // Story - SkipBlueWarp_Register(); - SkipDekuTreeIntro_Register(); - SkipLostWoodsBridge_Register(); - SkipToGivingZeldasLetter_Register(); - SkipZeldaFleeingCastle_Register(); - SkipIntro_Register(); + // Story + SkipBlueWarp_Register(); + SkipDekuTreeIntro_Register(); + SkipLostWoodsBridge_Register(); + SkipToGivingZeldasLetter_Register(); + SkipZeldaFleeingCastle_Register(); + SkipIntro_Register(); // SkipMiscInteractions - MoveJabuJabuElevator_Register(); - MoveMidoInKokiriForest_Register(); - SkipChildRutoInteractions_Register(); + MoveJabuJabuElevator_Register(); + MoveMidoInKokiriForest_Register(); + SkipChildRutoInteractions_Register(); FasterHeavyBlockLift_Register(); FasterRupeeAccumulator_Register(); } diff --git a/soh/soh/Enhancements/TimeSavers/TimeSavers.h b/soh/soh/Enhancements/TimeSavers/TimeSavers.h index ad521c6c2..9448260d6 100644 --- a/soh/soh/Enhancements/TimeSavers/TimeSavers.h +++ b/soh/soh/Enhancements/TimeSavers/TimeSavers.h @@ -4,17 +4,17 @@ void TimeSavers_Register(); // SkipCutscene - // Story - void SkipBlueWarp_Register(); - void SkipDekuTreeIntro_Register(); - void SkipLostWoodsBridge_Register(); - void SkipToGivingZeldasLetter_Register(); - void SkipZeldaFleeingCastle_Register(); - void SkipIntro_Register(); +// Story +void SkipBlueWarp_Register(); +void SkipDekuTreeIntro_Register(); +void SkipLostWoodsBridge_Register(); +void SkipToGivingZeldasLetter_Register(); +void SkipZeldaFleeingCastle_Register(); +void SkipIntro_Register(); // SkipMiscInteractions - void MoveJabuJabuElevator_Register(); - void MoveMidoInKokiriForest_Register(); - void SkipChildRutoInteractions_Register(); +void MoveJabuJabuElevator_Register(); +void MoveMidoInKokiriForest_Register(); +void SkipChildRutoInteractions_Register(); void FasterHeavyBlockLift_Register(); void FasterRupeeAccumulator_Register(); diff --git a/soh/soh/Enhancements/audio/AudioCollection.cpp b/soh/soh/Enhancements/audio/AudioCollection.cpp index 13b793b90..69b3723b4 100644 --- a/soh/soh/Enhancements/audio/AudioCollection.cpp +++ b/soh/soh/Enhancements/audio/AudioCollection.cpp @@ -11,7 +11,11 @@ #include #define SEQUENCE_MAP_ENTRY(sequenceId, label, sfxKey, category, canBeReplaced, canBeUsedAsReplacement) \ - { sequenceId, { sequenceId, label, sfxKey, category, canBeReplaced, canBeUsedAsReplacement } } + { \ + sequenceId, { \ + sequenceId, label, sfxKey, category, canBeReplaced, canBeUsedAsReplacement \ + } \ + } AudioCollection::AudioCollection() { // clang-format off @@ -355,10 +359,13 @@ void AudioCollection::AddToCollection(char* otrPath, uint16_t seqNum) { if (typeString == "fanfare") { type = SEQ_FANFARE; } - SequenceInfo info = {seqNum, - sequenceName, - StringHelper::Replace(StringHelper::Replace(StringHelper::Replace(sequenceName, " ", "_"), "~", "-"),".", ""), - type, false, true}; + SequenceInfo info = { seqNum, + sequenceName, + StringHelper::Replace( + StringHelper::Replace(StringHelper::Replace(sequenceName, " ", "_"), "~", "-"), ".", ""), + type, + false, + true }; sequenceMap.emplace(seqNum, info); } @@ -367,7 +374,8 @@ uint16_t AudioCollection::GetReplacementSequence(uint16_t seqId) { // for Hyrule Field instead. Otherwise, leave it alone, so that without any sfx editor modifications we will // play the normal track as usual. if (seqId == NA_BGM_FIELD_MORNING) { - if (CVarGetInteger(CVAR_AUDIO("ReplacedSequences.NA_BGM_FIELD_LOGIC.value"), NA_BGM_FIELD_LOGIC) != NA_BGM_FIELD_LOGIC) { + if (CVarGetInteger(CVAR_AUDIO("ReplacedSequences.NA_BGM_FIELD_LOGIC.value"), NA_BGM_FIELD_LOGIC) != + NA_BGM_FIELD_LOGIC) { seqId = NA_BGM_FIELD_LOGIC; } } @@ -402,10 +410,12 @@ void AudioCollection::AddToShufflePool(SequenceInfo* seqInfo) { } void AudioCollection::InitializeShufflePool() { - if (shufflePoolInitialized) return; - + if (shufflePoolInitialized) + return; + for (auto& [seqId, seqInfo] : sequenceMap) { - if (!seqInfo.canBeUsedAsReplacement) continue; + if (!seqInfo.canBeUsedAsReplacement) + continue; const std::string cvarKey = std::string(CVAR_AUDIO("Excluded.")) + seqInfo.sfxKey; if (CVarGetInteger(cvarKey.c_str(), 0)) { excludedSequences.insert(&seqInfo); @@ -417,7 +427,7 @@ void AudioCollection::InitializeShufflePool() { shufflePoolInitialized = true; }; -extern "C" void AudioCollection_AddToCollection(char *otrPath, uint16_t seqNum) { +extern "C" void AudioCollection_AddToCollection(char* otrPath, uint16_t seqNum) { AudioCollection::Instance->AddToCollection(otrPath, seqNum); } diff --git a/soh/soh/Enhancements/audio/AudioCollection.h b/soh/soh/Enhancements/audio/AudioCollection.h index f3fd964bc..2cdb02e21 100644 --- a/soh/soh/Enhancements/audio/AudioCollection.h +++ b/soh/soh/Enhancements/audio/AudioCollection.h @@ -6,16 +6,16 @@ #include enum SeqType { - SEQ_NOSHUFFLE = 0, - SEQ_BGM_WORLD = 1 << 0, - SEQ_BGM_EVENT = 1 << 1, + SEQ_NOSHUFFLE = 0, + SEQ_BGM_WORLD = 1 << 0, + SEQ_BGM_EVENT = 1 << 1, SEQ_BGM_BATTLE = 1 << 2, - SEQ_OCARINA = 1 << 3, - SEQ_FANFARE = 1 << 4, - SEQ_BGM_ERROR = 1 << 5, - SEQ_SFX = 1 << 6, + SEQ_OCARINA = 1 << 3, + SEQ_FANFARE = 1 << 4, + SEQ_BGM_ERROR = 1 << 5, + SEQ_SFX = 1 << 6, SEQ_INSTRUMENT = 1 << 7, - SEQ_VOICE = 1 << 8, + SEQ_VOICE = 1 << 8, SEQ_BGM_CUSTOM = SEQ_BGM_WORLD | SEQ_BGM_EVENT | SEQ_BGM_BATTLE, }; @@ -31,45 +31,45 @@ struct SequenceInfo { }; class AudioCollection { - private: - // All Loaded Audio - std::map sequenceMap; - - // Sequences/SFX to include in/exclude from shuffle pool - struct compareSequenceLabel { - bool operator() (SequenceInfo* a, SequenceInfo* b) const { - return a->label < b->label; - }; - }; - std::set includedSequences; - std::set excludedSequences; - bool shufflePoolInitialized = false; + private: + // All Loaded Audio + std::map sequenceMap; - public: - static AudioCollection* Instance; - AudioCollection(); - std::map GetAllSequences() const { - return sequenceMap; - } - std::set GetIncludedSequences() const { - return includedSequences; + // Sequences/SFX to include in/exclude from shuffle pool + struct compareSequenceLabel { + bool operator()(SequenceInfo* a, SequenceInfo* b) const { + return a->label < b->label; }; - std::set GetExcludedSequences() const { - return excludedSequences; - }; - void AddToShufflePool(SequenceInfo*); - void RemoveFromShufflePool(SequenceInfo*); - void AddToCollection(char* otrPath, uint16_t seqNum); - uint16_t GetReplacementSequence(uint16_t seqId); - void InitializeShufflePool(); - const char* GetSequenceName(uint16_t seqId); - bool HasSequenceNum(uint16_t seqId); - size_t SequenceMapSize(); - std::string GetCvarKey(std::string sfxKey); - std::string GetCvarLockKey(std::string sfxKey); + }; + std::set includedSequences; + std::set excludedSequences; + bool shufflePoolInitialized = false; + + public: + static AudioCollection* Instance; + AudioCollection(); + std::map GetAllSequences() const { + return sequenceMap; + } + std::set GetIncludedSequences() const { + return includedSequences; + }; + std::set GetExcludedSequences() const { + return excludedSequences; + }; + void AddToShufflePool(SequenceInfo*); + void RemoveFromShufflePool(SequenceInfo*); + void AddToCollection(char* otrPath, uint16_t seqNum); + uint16_t GetReplacementSequence(uint16_t seqId); + void InitializeShufflePool(); + const char* GetSequenceName(uint16_t seqId); + bool HasSequenceNum(uint16_t seqId); + size_t SequenceMapSize(); + std::string GetCvarKey(std::string sfxKey); + std::string GetCvarLockKey(std::string sfxKey); }; #else -void AudioCollection_AddToCollection(char *otrPath, uint16_t seqNum); +void AudioCollection_AddToCollection(char* otrPath, uint16_t seqNum); const char* AudioCollection_GetSequenceName(uint16_t seqId); bool AudioCollection_HasSequenceNum(uint16_t seqId); size_t AudioCollection_SequenceMapSize(); diff --git a/soh/soh/Enhancements/audio/AudioEditor.cpp b/soh/soh/Enhancements/audio/AudioEditor.cpp index 2e94e924a..9865615bd 100644 --- a/soh/soh/Enhancements/audio/AudioEditor.cpp +++ b/soh/soh/Enhancements/audio/AudioEditor.cpp @@ -17,8 +17,8 @@ #include "soh/Enhancements/game-interactor/GameInteractor.h" extern "C" { - #include "z64save.h" - extern SaveContext gSaveContext; +#include "z64save.h" +extern SaveContext gSaveContext; } Vec3f pos = { 0.0f, 0.0f, 0.0f }; @@ -58,7 +58,7 @@ size_t AuthenticCountBySequenceType(SeqType type) { case SEQ_VOICE: return SEQ_COUNT_VOICE; default: - return 0; + return 0; } } @@ -101,7 +101,8 @@ void RandomizeGroup(SeqType type) { } // if we didn't find any, return early without shuffling to prevent an infinite loop - if (!values.size()) return; + if (!values.size()) + return; } Shuffle(values); for (const auto& [seqId, seqData] : AudioCollection::Instance->GetAllSequences()) { @@ -110,7 +111,9 @@ void RandomizeGroup(SeqType type) { // don't randomize locked entries if ((seqData.category & type) && CVarGetInteger(cvarLockKey.c_str(), 0) == 0) { // Only save authentic sequence CVars - if ((((seqData.category & SEQ_BGM_CUSTOM) || seqData.category == SEQ_FANFARE) && seqData.sequenceId >= MAX_AUTHENTIC_SEQID) || seqData.canBeReplaced == false) { + if ((((seqData.category & SEQ_BGM_CUSTOM) || seqData.category == SEQ_FANFARE) && + seqData.sequenceId >= MAX_AUTHENTIC_SEQID) || + seqData.canBeReplaced == false) { continue; } const int randomValue = values.back(); @@ -172,20 +175,20 @@ void DrawPreviewButton(uint16_t sequenceId, std::string sfxKey, SeqType sequence if (CVarGetInteger(CVAR_AUDIO("Playing"), 0) == sequenceId) { if (UIWidgets::Button(stopButton.c_str(), UIWidgets::ButtonOptions() - .Size(UIWidgets::Sizes::Inline) - .Padding(ImVec2(10.0f, 6.0f)) - .Tooltip("Stop Preview") - .Color(THEME_COLOR))) { + .Size(UIWidgets::Sizes::Inline) + .Padding(ImVec2(10.0f, 6.0f)) + .Tooltip("Stop Preview") + .Color(THEME_COLOR))) { func_800F5C2C(); CVarSetInteger(CVAR_AUDIO("Playing"), 0); } } else { if (UIWidgets::Button(previewButton.c_str(), UIWidgets::ButtonOptions() - .Size(UIWidgets::Sizes::Inline) - .Padding(ImVec2(10.0f, 6.0f)) - .Tooltip("Play Preview") - .Color(THEME_COLOR))) { - if (CVarGetInteger(CVAR_AUDIO("Playing"), 0) != 0) { + .Size(UIWidgets::Sizes::Inline) + .Padding(ImVec2(10.0f, 6.0f)) + .Tooltip("Play Preview") + .Color(THEME_COLOR))) { + if (CVarGetInteger(CVAR_AUDIO("Playing"), 0) != 0) { func_800F5C2C(); CVarSetInteger(CVAR_AUDIO("Playing"), 0); } else { @@ -215,7 +218,7 @@ void Draw_SfxTab(const std::string& tabId, SeqType type, const std::string& tabN ImGui::SeparatorText(tabName.c_str()); if (UIWidgets::Button(resetAllButton.c_str(), - UIWidgets::ButtonOptions().Size(UIWidgets::Sizes::Inline).Color(THEME_COLOR))) { + UIWidgets::ButtonOptions().Size(UIWidgets::Sizes::Inline).Color(THEME_COLOR))) { auto currentBGM = func_800FA0B4(SEQ_PLAYER_BGM_MAIN); auto prevReplacement = AudioCollection::Instance->GetReplacementSequence(currentBGM); ResetGroup(map, type); @@ -227,7 +230,7 @@ void Draw_SfxTab(const std::string& tabId, SeqType type, const std::string& tabN } ImGui::SameLine(); if (UIWidgets::Button(randomizeAllButton.c_str(), - UIWidgets::ButtonOptions().Size(UIWidgets::Sizes::Inline).Color(THEME_COLOR))) { + UIWidgets::ButtonOptions().Size(UIWidgets::Sizes::Inline).Color(THEME_COLOR))) { auto currentBGM = func_800FA0B4(SEQ_PLAYER_BGM_MAIN); auto prevReplacement = AudioCollection::Instance->GetReplacementSequence(currentBGM); RandomizeGroup(type); @@ -239,7 +242,7 @@ void Draw_SfxTab(const std::string& tabId, SeqType type, const std::string& tabN } ImGui::SameLine(); if (UIWidgets::Button(lockAllButton.c_str(), - UIWidgets::ButtonOptions().Size(UIWidgets::Sizes::Inline).Color(THEME_COLOR))) { + UIWidgets::ButtonOptions().Size(UIWidgets::Sizes::Inline).Color(THEME_COLOR))) { auto currentBGM = func_800FA0B4(SEQ_PLAYER_BGM_MAIN); auto prevReplacement = AudioCollection::Instance->GetReplacementSequence(currentBGM); LockGroup(map, type); @@ -251,7 +254,7 @@ void Draw_SfxTab(const std::string& tabId, SeqType type, const std::string& tabN } ImGui::SameLine(); if (UIWidgets::Button(unlockAllButton.c_str(), - UIWidgets::ButtonOptions().Size(UIWidgets::Sizes::Inline).Color(THEME_COLOR))) { + UIWidgets::ButtonOptions().Size(UIWidgets::Sizes::Inline).Color(THEME_COLOR))) { auto currentBGM = func_800FA0B4(SEQ_PLAYER_BGM_MAIN); auto prevReplacement = AudioCollection::Instance->GetReplacementSequence(currentBGM); UnlockGroup(map, type); @@ -273,7 +276,9 @@ void Draw_SfxTab(const std::string& tabId, SeqType type, const std::string& tabN continue; } // Do not display custom sequences in the list - if ((((seqData.category & SEQ_BGM_CUSTOM) || seqData.category == SEQ_FANFARE) && defaultValue >= MAX_AUTHENTIC_SEQID) || seqData.canBeReplaced == false) { + if ((((seqData.category & SEQ_BGM_CUSTOM) || seqData.category == SEQ_FANFARE) && + defaultValue >= MAX_AUTHENTIC_SEQID) || + seqData.canBeReplaced == false) { continue; } @@ -296,8 +301,10 @@ void Draw_SfxTab(const std::string& tabId, SeqType type, const std::string& tabN UIWidgets::PushStyleCombobox(THEME_COLOR); if (ImGui::BeginCombo(hiddenKey.c_str(), map.at(initialValue).label.c_str())) { for (const auto& [value, seqData] : map) { - // If excluded as a replacement sequence, don't show in other dropdowns except the effect's own dropdown. - if (~(seqData.category) & type || (!seqData.canBeUsedAsReplacement && initialSfxKey != seqData.sfxKey)) { + // If excluded as a replacement sequence, don't show in other dropdowns except the effect's own + // dropdown. + if (~(seqData.category) & type || + (!seqData.canBeUsedAsReplacement && initialSfxKey != seqData.sfxKey)) { continue; } @@ -317,15 +324,17 @@ void Draw_SfxTab(const std::string& tabId, SeqType type, const std::string& tabN UIWidgets::PopStyleCombobox(); ImGui::TableNextColumn(); ImGui::PushItemWidth(-FLT_MIN); - DrawPreviewButton((type == SEQ_SFX || type == SEQ_VOICE || type == SEQ_INSTRUMENT) ? defaultValue : currentValue, seqData.sfxKey, type); - auto locked = CVarGetInteger(cvarLockKey.c_str(), 0) == 1; + DrawPreviewButton((type == SEQ_SFX || type == SEQ_VOICE || type == SEQ_INSTRUMENT) ? defaultValue + : currentValue, + seqData.sfxKey, type); + auto locked = CVarGetInteger(cvarLockKey.c_str(), 0) == 1; ImGui::SameLine(); ImGui::PushItemWidth(-FLT_MIN); if (UIWidgets::Button(resetButton.c_str(), UIWidgets::ButtonOptions() - .Size(UIWidgets::Sizes::Inline) - .Padding(ImVec2(10.0f, 6.0f)) - .Tooltip("Reset to default") - .Color(THEME_COLOR))) { + .Size(UIWidgets::Sizes::Inline) + .Padding(ImVec2(10.0f, 6.0f)) + .Tooltip("Reset to default") + .Color(THEME_COLOR))) { CVarClear(cvarKey.c_str()); CVarClear(cvarLockKey.c_str()); Ship::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesNextFrame(); @@ -334,10 +343,10 @@ void Draw_SfxTab(const std::string& tabId, SeqType type, const std::string& tabN ImGui::SameLine(); ImGui::PushItemWidth(-FLT_MIN); if (UIWidgets::Button(randomizeButton.c_str(), UIWidgets::ButtonOptions() - .Size(UIWidgets::Sizes::Inline) - .Padding(ImVec2(10.0f, 6.0f)) - .Tooltip("Randomize this sound") - .Color(THEME_COLOR))) { + .Size(UIWidgets::Sizes::Inline) + .Padding(ImVec2(10.0f, 6.0f)) + .Tooltip("Randomize this sound") + .Color(THEME_COLOR))) { std::vector validSequences = {}; for (const auto seqInfo : AudioCollection::Instance->GetIncludedSequences()) { if (seqInfo->category & type) { @@ -354,16 +363,16 @@ void Draw_SfxTab(const std::string& tabId, SeqType type, const std::string& tabN } Ship::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesNextFrame(); UpdateCurrentBGM(defaultValue, type); - } + } } ImGui::SameLine(); ImGui::PushItemWidth(-FLT_MIN); if (UIWidgets::Button(locked ? lockedButton.c_str() : unlockedButton.c_str(), - UIWidgets::ButtonOptions() - .Size(UIWidgets::Sizes::Inline) - .Padding(ImVec2(10.0f, 6.0f)) - .Tooltip(locked ? "Sound locked" : "Sound unlocked") - .Color(THEME_COLOR))) { + UIWidgets::ButtonOptions() + .Size(UIWidgets::Sizes::Inline) + .Padding(ImVec2(10.0f, 6.0f)) + .Tooltip(locked ? "Sound locked" : "Sound unlocked") + .Color(THEME_COLOR))) { if (locked) { CVarClear(cvarLockKey.c_str()); } else { @@ -442,7 +451,6 @@ void DrawTypeChip(SeqType type, std::string sequenceName) { ImGui::EndDisabled(); } - void AudioEditorRegisterOnSceneInitHook() { GameInteractor::Instance->RegisterGameHook([](int16_t sceneNum) { if (gSaveContext.gameMode != GAMEMODE_END_CREDITS && CVarGetInteger(CVAR_AUDIO("RandomizeAllOnNewScene"), 0)) { @@ -460,40 +468,39 @@ void AudioEditor::DrawElement() { UIWidgets::Separator(); if (UIWidgets::Button("Randomize All Groups", - UIWidgets::ButtonOptions() - .Size(ImVec2(230.0f, 0.0f)) - .Color(THEME_COLOR) - .Tooltip("Randomizes all unlocked music and sound effects across tab groups"))) { + UIWidgets::ButtonOptions() + .Size(ImVec2(230.0f, 0.0f)) + .Color(THEME_COLOR) + .Tooltip("Randomizes all unlocked music and sound effects across tab groups"))) { AudioEditor_RandomizeAll(); } ImGui::SameLine(); if (UIWidgets::Button("Reset All Groups", - UIWidgets::ButtonOptions() - .Size(ImVec2(230.0f, 0.0f)) - .Color(THEME_COLOR) - .Tooltip("Resets all unlocked music and sound effects across tab groups"))) { + UIWidgets::ButtonOptions() + .Size(ImVec2(230.0f, 0.0f)) + .Color(THEME_COLOR) + .Tooltip("Resets all unlocked music and sound effects across tab groups"))) { AudioEditor_ResetAll(); } ImGui::SameLine(); if (UIWidgets::Button("Lock All Groups", UIWidgets::ButtonOptions() - .Size(ImVec2(230.0f, 0.0f)) - .Color(THEME_COLOR) - .Tooltip("Locks all music and sound effects across tab groups"))) { + .Size(ImVec2(230.0f, 0.0f)) + .Color(THEME_COLOR) + .Tooltip("Locks all music and sound effects across tab groups"))) { AudioEditor_LockAll(); } ImGui::SameLine(); - if (UIWidgets::Button("Unlock All Groups", - UIWidgets::ButtonOptions() - .Size(ImVec2(230.0f, 0.0f)) - .Color(THEME_COLOR) - .Tooltip("Unlocks all music and sound effects across tab groups"))) { + if (UIWidgets::Button("Unlock All Groups", UIWidgets::ButtonOptions() + .Size(ImVec2(230.0f, 0.0f)) + .Color(THEME_COLOR) + .Tooltip("Unlocks all music and sound effects across tab groups"))) { AudioEditor_UnlockAll(); } UIWidgets::Separator(); UIWidgets::PushStyleTabs(THEME_COLOR); if (ImGui::BeginTabBar("SfxContextTabBar", ImGuiTabBarFlags_NoCloseWithMiddleMouseButton)) { - + static ImVec2 cellPadding(8.0f, 8.0f); if (ImGui::BeginTabItem("Audio Options")) { ImGui::PushStyleVar(ImGuiStyleVar_CellPadding, cellPadding); @@ -609,16 +616,10 @@ void AudioEditor::DrawElement() { excludeTabOpen = true; } - static std::map showType { - {SEQ_BGM_WORLD, true}, - {SEQ_BGM_EVENT, true}, - {SEQ_BGM_BATTLE, true}, - {SEQ_OCARINA, true}, - {SEQ_FANFARE, true}, - {SEQ_SFX, true }, - {SEQ_VOICE, true }, - {SEQ_INSTRUMENT, true}, - {SEQ_BGM_CUSTOM, true}, + static std::map showType{ + { SEQ_BGM_WORLD, true }, { SEQ_BGM_EVENT, true }, { SEQ_BGM_BATTLE, true }, + { SEQ_OCARINA, true }, { SEQ_FANFARE, true }, { SEQ_SFX, true }, + { SEQ_VOICE, true }, { SEQ_INSTRUMENT, true }, { SEQ_BGM_CUSTOM, true }, }; // make temporary sets because removing from the set we're iterating through crashes ImGui @@ -631,7 +632,7 @@ void AudioEditor::DrawElement() { UIWidgets::PopStyleInput(); ImGui::SameLine(); if (UIWidgets::Button("Exclude All", - UIWidgets::ButtonOptions().Size(UIWidgets::Sizes::Inline).Color(THEME_COLOR))) { + UIWidgets::ButtonOptions().Size(UIWidgets::Sizes::Inline).Color(THEME_COLOR))) { for (auto seqInfo : AudioCollection::Instance->GetIncludedSequences()) { if (sequenceSearch.PassFilter(seqInfo->label.c_str()) && showType[seqInfo->category]) { seqsToExclude.insert(seqInfo); @@ -640,7 +641,7 @@ void AudioEditor::DrawElement() { } ImGui::SameLine(); if (UIWidgets::Button("Include All", - UIWidgets::ButtonOptions().Size(UIWidgets::Sizes::Inline).Color(THEME_COLOR))) { + UIWidgets::ButtonOptions().Size(UIWidgets::Sizes::Inline).Color(THEME_COLOR))) { for (auto seqInfo : AudioCollection::Instance->GetExcludedSequences()) { if (sequenceSearch.PassFilter(seqInfo->label.c_str()) && showType[seqInfo->category]) { seqsToInclude.insert(seqInfo); @@ -648,7 +649,8 @@ void AudioEditor::DrawElement() { } } - ImGui::BeginTable("sequenceTypes", 9, ImGuiTableFlags_Resizable | ImGuiTableFlags_NoSavedSettings | ImGuiTableFlags_Borders); + ImGui::BeginTable("sequenceTypes", 9, + ImGuiTableFlags_Resizable | ImGuiTableFlags_NoSavedSettings | ImGuiTableFlags_Borders); ImGui::TableNextColumn(); ImGui::PushStyleColor(ImGuiCol_Header, GetSequenceTypeColor(SEQ_BGM_WORLD)); @@ -710,10 +712,10 @@ void AudioEditor::DrawElement() { for (auto seqInfo : AudioCollection::Instance->GetIncludedSequences()) { if (sequenceSearch.PassFilter(seqInfo->label.c_str()) && showType[seqInfo->category]) { if (UIWidgets::Button(std::string(ICON_FA_TIMES "##" + seqInfo->sfxKey).c_str(), - UIWidgets::ButtonOptions() - .Size(UIWidgets::Sizes::Inline) - .Padding(ImVec2(9.0f, 6.0f)) - .Color(THEME_COLOR))) { + UIWidgets::ButtonOptions() + .Size(UIWidgets::Sizes::Inline) + .Padding(ImVec2(9.0f, 6.0f)) + .Color(THEME_COLOR))) { seqsToExclude.insert(seqInfo); } ImGui::SameLine(); @@ -738,10 +740,10 @@ void AudioEditor::DrawElement() { for (auto seqInfo : AudioCollection::Instance->GetExcludedSequences()) { if (sequenceSearch.PassFilter(seqInfo->label.c_str()) && showType[seqInfo->category]) { if (UIWidgets::Button(std::string(ICON_FA_PLUS "##" + seqInfo->sfxKey).c_str(), - UIWidgets::ButtonOptions() - .Size(UIWidgets::Sizes::Inline) - .Padding(ImVec2(9.0f, 6.0f)) - .Color(THEME_COLOR))) { + UIWidgets::ButtonOptions() + .Size(UIWidgets::Sizes::Inline) + .Padding(ImVec2(9.0f, 6.0f)) + .Color(THEME_COLOR))) { seqsToInclude.insert(seqInfo); } ImGui::SameLine(); @@ -772,7 +774,9 @@ void AudioEditor::DrawElement() { UIWidgets::PopStyleTabs(); } -std::vector allTypes = { SEQ_BGM_WORLD, SEQ_BGM_EVENT, SEQ_BGM_BATTLE, SEQ_OCARINA, SEQ_FANFARE, SEQ_INSTRUMENT, SEQ_SFX, SEQ_VOICE, }; +std::vector allTypes = { + SEQ_BGM_WORLD, SEQ_BGM_EVENT, SEQ_BGM_BATTLE, SEQ_OCARINA, SEQ_FANFARE, SEQ_INSTRUMENT, SEQ_SFX, SEQ_VOICE, +}; void AudioEditor_RandomizeAll() { for (auto type : allTypes) { diff --git a/soh/soh/Enhancements/audio/AudioEditor.h b/soh/soh/Enhancements/audio/AudioEditor.h index b1b034f24..a5b0b385a 100644 --- a/soh/soh/Enhancements/audio/AudioEditor.h +++ b/soh/soh/Enhancements/audio/AudioEditor.h @@ -8,13 +8,13 @@ #include "AudioCollection.h" class AudioEditor : public Ship::GuiWindow { - public: - using GuiWindow::GuiWindow; + public: + using GuiWindow::GuiWindow; - void DrawElement() override; - void InitElement() override; - void UpdateElement() override {}; - ~AudioEditor() {}; + void DrawElement() override; + void InitElement() override; + void UpdateElement() override{}; + ~AudioEditor(){}; }; void AudioEditor_RandomizeAll(); @@ -29,7 +29,6 @@ extern "C" { u16 AudioEditor_GetReplacementSeq(u16 seqId); - #ifdef __cplusplus } #endif diff --git a/soh/soh/Enhancements/bootcommands.c b/soh/soh/Enhancements/bootcommands.c index ac2ae2bc5..dde827ec5 100644 --- a/soh/soh/Enhancements/bootcommands.c +++ b/soh/soh/Enhancements/bootcommands.c @@ -12,8 +12,7 @@ #include "soh/OTRGlobals.h" #include "soh/cvar_prefixes.h" -void BootCommands_Init() -{ +void BootCommands_Init() { // Clears vars to prevent randomizer menu from being disabled CVarClear(CVAR_GENERAL("RandoGenerating")); // Clear when a crash happened during rando seed generation CVarClear(CVAR_GENERAL("NewSeedGenerated")); diff --git a/soh/soh/Enhancements/boss-rush/BossRush.cpp b/soh/soh/Enhancements/boss-rush/BossRush.cpp index 6f218fcb3..76cf5637e 100644 --- a/soh/soh/Enhancements/boss-rush/BossRush.cpp +++ b/soh/soh/Enhancements/boss-rush/BossRush.cpp @@ -8,18 +8,18 @@ #include extern "C" { - #include "functions.h" - #include "macros.h" - #include "variables.h" - #include "src/overlays/actors/ovl_Boss_Goma/z_boss_goma.h" - #include "src/overlays/actors/ovl_Boss_Mo/z_boss_mo.h" - #include "src/overlays/actors/ovl_Door_Warp1/z_door_warp1.h" - extern PlayState* gPlayState; +#include "functions.h" +#include "macros.h" +#include "variables.h" +#include "src/overlays/actors/ovl_Boss_Goma/z_boss_goma.h" +#include "src/overlays/actors/ovl_Boss_Mo/z_boss_mo.h" +#include "src/overlays/actors/ovl_Door_Warp1/z_door_warp1.h" +extern PlayState* gPlayState; - Gfx* KaleidoScope_QuadTextureIA8(Gfx* gfx, void* texture, s16 width, s16 height, u16 point); - #include "textures/icon_item_nes_static/icon_item_nes_static.h" - #include "textures/icon_item_ger_static/icon_item_ger_static.h" - #include "textures/icon_item_fra_static/icon_item_fra_static.h" +Gfx* KaleidoScope_QuadTextureIA8(Gfx* gfx, void* texture, s16 width, s16 height, u16 point); +#include "textures/icon_item_nes_static/icon_item_nes_static.h" +#include "textures/icon_item_ger_static/icon_item_ger_static.h" +#include "textures/icon_item_fra_static/icon_item_fra_static.h" } typedef struct BossRushSetting { @@ -27,103 +27,79 @@ typedef struct BossRushSetting { std::vector> choices; } BossRushSetting; -BossRushSetting BossRushOptions[BR_OPTIONS_MAX] = { - { - { "BOSSES:", "BOSSE:", "BOSS:" }, - { - { "All", "Alle", "Tous" }, - { "Child", "Kind", "Enfant" }, - { "Adult", "Erwachsener", "Adulte" }, - { "Ganondorf & Ganon", "Ganondorf & Ganon", "Ganondorf & Ganon" }, - } - }, - { - { "HEARTS:", "HERZEN:", "COEURS:" }, - { - { "10", "10", "10" }, - { "15", "15", "15" }, - { "20", "20", "20" }, - { "3", "3", "3" }, - { "5", "5", "5" }, - { "7", "7", "7" }, - } - }, - { - { "AMMO:", "MUNITION:", "MUNITIONS:" }, - { - { "Limited", "Limitiert", "Limitées" }, - { "Full", "Voll", "Pleines" }, - { "Maxed", "Maximum", "Maximum" }, - } - }, - { - { "HEAL:", "REGENERATION:", "SOIN:" }, - { - { "Before Ganondorf", "Vor Ganondorf", "Avant Ganondorf" }, - { "Every Boss", "Bei jedem Boss", "Tous les Boss" }, - { "Never", "Niemals", "Jamais" }, - } - }, - { - { "HYPER BOSSES:", "HYPER-BOSSE:", "HYPER BOSS:" }, - { - { "No", "Nein", "Non" }, - { "Yes", "Ja", "Oui" }, - } - }, - { - { "MAGIC:", "MAGIE:", "MAGIE:" }, - { - { "Single", "Einzel", "Simple" }, - { "Double", "Doppel", "Double" }, - } - }, - { - { "BIG. SWORD:", "BIG.-SCHWERT:", "EPÉE DE BIG.:" }, - { - { "No", "Nein", "Non" }, - { "Yes", "Ja", "Oui" }, - } - }, - { - { "BOTTLE:", "FLASCHEN:", "BOUTEILLE:" }, - { - { "No", "Nein", "Non" }, - { "Empty", "Leer", "Vide" }, - { "Fairy", "Fee", "Fée" }, - { "Red Potion", "Rotes Elixier", "Potion Rouge" }, - { "Green Potion", "Grünes Elixier", "Potion Verte" }, - { "Blue Potion", "Blaues Elixier", "Potion Bleue" }, - } - }, - { - { "LONGSHOT:", "ENTERHAKEN:", "SUPER GRAPPIN:" }, - { - { "No", "Nein", "Non" }, - { "Yes", "Ja", "Oui" }, - } - }, - { - { "HOVER BOOTS:", "GLEITSTIEFEL:", "BOTTES DES AIRS:" }, - { - { "No", "Nein", "Non" }, - { "Yes", "Ja", "Oui" }, - } - }, - { - { "BUNNY HOOD:", "HASENOHREN:", "MASQUE DU LAPIN:" }, - { - { "No", "Nein", "Non" }, - { "Yes", "Ja", "Oui" }, - } - }, - { - { "TIMER:", "TIMER:", "TIMER:" }, - { - { "Yes", "Ja", "Oui" }, - { "No", "Nein", "Non" }, - } - } +BossRushSetting BossRushOptions[BR_OPTIONS_MAX] = { + { { "BOSSES:", "BOSSE:", "BOSS:" }, + { + { "All", "Alle", "Tous" }, + { "Child", "Kind", "Enfant" }, + { "Adult", "Erwachsener", "Adulte" }, + { "Ganondorf & Ganon", "Ganondorf & Ganon", "Ganondorf & Ganon" }, + } }, + { { "HEARTS:", "HERZEN:", "COEURS:" }, + { + { "10", "10", "10" }, + { "15", "15", "15" }, + { "20", "20", "20" }, + { "3", "3", "3" }, + { "5", "5", "5" }, + { "7", "7", "7" }, + } }, + { { "AMMO:", "MUNITION:", "MUNITIONS:" }, + { + { "Limited", "Limitiert", "Limitées" }, + { "Full", "Voll", "Pleines" }, + { "Maxed", "Maximum", "Maximum" }, + } }, + { { "HEAL:", "REGENERATION:", "SOIN:" }, + { + { "Before Ganondorf", "Vor Ganondorf", "Avant Ganondorf" }, + { "Every Boss", "Bei jedem Boss", "Tous les Boss" }, + { "Never", "Niemals", "Jamais" }, + } }, + { { "HYPER BOSSES:", "HYPER-BOSSE:", "HYPER BOSS:" }, + { + { "No", "Nein", "Non" }, + { "Yes", "Ja", "Oui" }, + } }, + { { "MAGIC:", "MAGIE:", "MAGIE:" }, + { + { "Single", "Einzel", "Simple" }, + { "Double", "Doppel", "Double" }, + } }, + { { "BIG. SWORD:", "BIG.-SCHWERT:", "EPÉE DE BIG.:" }, + { + { "No", "Nein", "Non" }, + { "Yes", "Ja", "Oui" }, + } }, + { { "BOTTLE:", "FLASCHEN:", "BOUTEILLE:" }, + { + { "No", "Nein", "Non" }, + { "Empty", "Leer", "Vide" }, + { "Fairy", "Fee", "Fée" }, + { "Red Potion", "Rotes Elixier", "Potion Rouge" }, + { "Green Potion", "Grünes Elixier", "Potion Verte" }, + { "Blue Potion", "Blaues Elixier", "Potion Bleue" }, + } }, + { { "LONGSHOT:", "ENTERHAKEN:", "SUPER GRAPPIN:" }, + { + { "No", "Nein", "Non" }, + { "Yes", "Ja", "Oui" }, + } }, + { { "HOVER BOOTS:", "GLEITSTIEFEL:", "BOTTES DES AIRS:" }, + { + { "No", "Nein", "Non" }, + { "Yes", "Ja", "Oui" }, + } }, + { { "BUNNY HOOD:", "HASENOHREN:", "MASQUE DU LAPIN:" }, + { + { "No", "Nein", "Non" }, + { "Yes", "Ja", "Oui" }, + } }, + { { "TIMER:", "TIMER:", "TIMER:" }, + { + { "Yes", "Ja", "Oui" }, + { "No", "Nein", "Non" }, + } } }; const char* BossRush_GetSettingName(u8 optionIndex, u8 language) { @@ -196,7 +172,7 @@ void BossRush_SetEquipment(u8 linkAge) { Inventory_ChangeEquipment(EQUIP_TYPE_SWORD, EQUIP_VALUE_SWORD_KOKIRI); Inventory_ChangeEquipment(EQUIP_TYPE_SHIELD, EQUIP_VALUE_SHIELD_DEKU); - // Set Adult equipment. + // Set Adult equipment. } else { brButtonItems = { ITEM_SWORD_MASTER, ITEM_BOW, ITEM_HAMMER, ITEM_BOMB, ITEM_NONE, ITEM_NONE, ITEM_NONE, ITEM_NONE }; @@ -229,34 +205,36 @@ void BossRush_HandleBlueWarp(PlayState* play, f32 warpPosX, f32 warpPosZ) { } else { play->nextEntranceIndex = ENTR_FOREST_TEMPLE_BOSS_ENTRANCE; } - // King Dodongo & Volvagia + // King Dodongo & Volvagia } else if (warpPosX == 100 && warpPosZ == -170) { if (gSaveContext.linkAge == LINK_AGE_CHILD) { play->nextEntranceIndex = ENTR_DODONGOS_CAVERN_BOSS_ENTRANCE; } else { play->nextEntranceIndex = ENTR_FIRE_TEMPLE_BOSS_ENTRANCE; } - // Barinade & Morb + // Barinade & Morb } else if (warpPosX == 199 && warpPosZ == 0) { if (gSaveContext.linkAge == LINK_AGE_CHILD) { play->nextEntranceIndex = ENTR_JABU_JABU_BOSS_ENTRANCE; } else { play->nextEntranceIndex = ENTR_WATER_TEMPLE_BOSS_ENTRANCE; } - // Twinrova + // Twinrova } else if (warpPosX == 100 && warpPosZ == 170) { play->nextEntranceIndex = ENTR_SPIRIT_TEMPLE_BOSS_2; - // Bongo Bongo + // Bongo Bongo } else if (warpPosX == -100 && warpPosZ == 170) { play->nextEntranceIndex = ENTR_SHADOW_TEMPLE_BOSS_ENTRANCE; - // Ganondork + // Ganondork } else if (warpPosX == -199 && warpPosZ == 0) { play->nextEntranceIndex = ENTR_GANONDORF_BOSS_0; } else { - SPDLOG_ERROR("[BossRush]: Unknown blue warp in chamber of sages at position ({}, {}). Warping back to chamber of sages.", warpPosX, warpPosZ); + SPDLOG_ERROR("[BossRush]: Unknown blue warp in chamber of sages at position ({}, {}). Warping back to " + "chamber of sages.", + warpPosX, warpPosZ); play->nextEntranceIndex = ENTR_CHAMBER_OF_THE_SAGES_0; } - // If coming from a boss room, teleport back to Chamber of Sages and set flag. + // If coming from a boss room, teleport back to Chamber of Sages and set flag. } else { play->nextEntranceIndex = ENTR_CHAMBER_OF_THE_SAGES_0; @@ -267,7 +245,7 @@ void BossRush_HandleBlueWarp(PlayState* play, f32 warpPosX, f32 warpPosZ) { // Change to Adult Link. if (gSaveContext.ship.quest.data.bossRush.options[BR_OPTIONS_BOSSES] == BR_CHOICE_BOSSES_ALL) { BossRush_SetEquipment(LINK_AGE_ADULT); - // Warp to credits. + // Warp to credits. } else if (gSaveContext.ship.quest.data.bossRush.options[BR_OPTIONS_BOSSES] == BR_CHOICE_BOSSES_CHILD) { play->nextEntranceIndex = ENTR_CHAMBER_OF_THE_SAGES_0; gSaveContext.nextCutsceneIndex = 0xFFF2; @@ -328,7 +306,8 @@ void BossRush_HandleCompleteBoss(PlayState* play) { Health_ChangeBy(play, 320); } - if ((CheckDungeonCount() == 3 && gSaveContext.ship.quest.data.bossRush.options[BR_OPTIONS_BOSSES] == BR_CHOICE_BOSSES_CHILD) || + if ((CheckDungeonCount() == 3 && + gSaveContext.ship.quest.data.bossRush.options[BR_OPTIONS_BOSSES] == BR_CHOICE_BOSSES_CHILD) || play->sceneNum == SCENE_GANON_BOSS) { gSaveContext.ship.stats.playTimer += 2; gSaveContext.ship.stats.gameComplete = 1; @@ -399,17 +378,17 @@ void BossRush_InitSave() { gSaveContext.eventChkInf[7] |= 0x80; // bongo bongo // Sets all rando flags to false - // Boss Rush currently uses 2 randomizer flags (RAND_INF_DUNGEONS_DONE_SPIRIT_TEMPLE & RAND_INF_DUNGEONS_DONE_SHADOW_TEMPLE) + // Boss Rush currently uses 2 randomizer flags (RAND_INF_DUNGEONS_DONE_SPIRIT_TEMPLE & + // RAND_INF_DUNGEONS_DONE_SHADOW_TEMPLE) for (s32 i = 0; i < ARRAY_COUNT(gSaveContext.ship.randomizerInf); i++) { gSaveContext.ship.randomizerInf[i] = 0; } // Set items std::array brItems = { - ITEM_STICK, ITEM_NUT, ITEM_BOMB, ITEM_BOW, ITEM_NONE, ITEM_NONE, - ITEM_SLINGSHOT, ITEM_NONE, ITEM_NONE, ITEM_HOOKSHOT, ITEM_NONE, ITEM_NONE, - ITEM_BOOMERANG, ITEM_LENS, ITEM_NONE, ITEM_HAMMER, ITEM_ARROW_LIGHT, ITEM_NONE, - ITEM_NONE, ITEM_NONE, ITEM_NONE, ITEM_NONE, ITEM_NONE, ITEM_NONE, + ITEM_STICK, ITEM_NUT, ITEM_BOMB, ITEM_BOW, ITEM_NONE, ITEM_NONE, ITEM_SLINGSHOT, ITEM_NONE, + ITEM_NONE, ITEM_HOOKSHOT, ITEM_NONE, ITEM_NONE, ITEM_BOOMERANG, ITEM_LENS, ITEM_NONE, ITEM_HAMMER, + ITEM_ARROW_LIGHT, ITEM_NONE, ITEM_NONE, ITEM_NONE, ITEM_NONE, ITEM_NONE, ITEM_NONE, ITEM_NONE, }; if (gSaveContext.ship.quest.data.bossRush.options[BR_OPTIONS_LONGSHOT] == BR_CHOICE_LONGSHOT_YES) { @@ -541,11 +520,13 @@ void BossRush_OnVanillaBehaviorHandler(GIVanillaBehavior id, bool* should, va_li break; } } - Actor_Spawn(&gPlayState->actorCtx, gPlayState, ACTOR_DOOR_WARP1, childPos.x, bossGoma->actor.world.pos.y, childPos.z, 0, 0, 0, WARP_DUNGEON_ADULT, false); + Actor_Spawn(&gPlayState->actorCtx, gPlayState, ACTOR_DOOR_WARP1, childPos.x, + bossGoma->actor.world.pos.y, childPos.z, 0, 0, 0, WARP_DUNGEON_ADULT, false); break; } case SCENE_DODONGOS_CAVERN_BOSS: { - Actor_Spawn(&gPlayState->actorCtx, gPlayState, ACTOR_DOOR_WARP1, -890.0f, -1523.76f, -3304.0f, 0, 0, 0, WARP_DUNGEON_ADULT, false); + Actor_Spawn(&gPlayState->actorCtx, gPlayState, ACTOR_DOOR_WARP1, -890.0f, -1523.76f, -3304.0f, 0, 0, + 0, WARP_DUNGEON_ADULT, false); break; } case SCENE_JABU_JABU_BOSS: { @@ -563,28 +544,34 @@ void BossRush_OnVanillaBehaviorHandler(GIVanillaBehavior id, bool* should, va_li } } - Actor_Spawn(&gPlayState->actorCtx, gPlayState, ACTOR_DOOR_WARP1, sWarpPos[sp7C].x, sWarpPos[sp7C].y, sWarpPos[sp7C].z, 0, 0, 0, WARP_DUNGEON_ADULT, false); + Actor_Spawn(&gPlayState->actorCtx, gPlayState, ACTOR_DOOR_WARP1, sWarpPos[sp7C].x, sWarpPos[sp7C].y, + sWarpPos[sp7C].z, 0, 0, 0, WARP_DUNGEON_ADULT, false); break; } case SCENE_FOREST_TEMPLE_BOSS: { - Actor_Spawn(&gPlayState->actorCtx, gPlayState, ACTOR_DOOR_WARP1, 14.0f, -33.0f, -3315.0f, 0, 0, 0, WARP_DUNGEON_ADULT, true); + Actor_Spawn(&gPlayState->actorCtx, gPlayState, ACTOR_DOOR_WARP1, 14.0f, -33.0f, -3315.0f, 0, 0, 0, + WARP_DUNGEON_ADULT, true); break; } case SCENE_FIRE_TEMPLE_BOSS: { - Actor_Spawn(&gPlayState->actorCtx, gPlayState, ACTOR_DOOR_WARP1, 0.0f, 100.0f, 0.0f, 0, 0, 0, WARP_DUNGEON_ADULT, true); + Actor_Spawn(&gPlayState->actorCtx, gPlayState, ACTOR_DOOR_WARP1, 0.0f, 100.0f, 0.0f, 0, 0, 0, + WARP_DUNGEON_ADULT, true); break; } case SCENE_WATER_TEMPLE_BOSS: { BossMo* bossMo = va_arg(args, BossMo*); - Actor_Spawn(&gPlayState->actorCtx, gPlayState, ACTOR_DOOR_WARP1, bossMo->actor.world.pos.x, -280.0f, bossMo->actor.world.pos.z, 0, 0, 0, WARP_DUNGEON_ADULT, true); + Actor_Spawn(&gPlayState->actorCtx, gPlayState, ACTOR_DOOR_WARP1, bossMo->actor.world.pos.x, -280.0f, + bossMo->actor.world.pos.z, 0, 0, 0, WARP_DUNGEON_ADULT, true); break; } case SCENE_SPIRIT_TEMPLE_BOSS: { - Actor_Spawn(&gPlayState->actorCtx, gPlayState, ACTOR_DOOR_WARP1, 600.0f, 230.0f, 0.0f, 0, 0, 0, WARP_DUNGEON_ADULT, true); + Actor_Spawn(&gPlayState->actorCtx, gPlayState, ACTOR_DOOR_WARP1, 600.0f, 230.0f, 0.0f, 0, 0, 0, + WARP_DUNGEON_ADULT, true); break; } case SCENE_SHADOW_TEMPLE_BOSS: { - Actor_Spawn(&gPlayState->actorCtx, gPlayState, ACTOR_DOOR_WARP1, -50.0f, 0.0f, 400.0f, 0, 0, 0, WARP_DUNGEON_ADULT, true); + Actor_Spawn(&gPlayState->actorCtx, gPlayState, ACTOR_DOOR_WARP1, -50.0f, 0.0f, 400.0f, 0, 0, 0, + WARP_DUNGEON_ADULT, true); break; } default: { @@ -699,12 +686,18 @@ void BossRush_RegisterHooks() { onBossDefeatHook = 0; onActorUpdate = 0; - if (!IS_BOSS_RUSH) return; + if (!IS_BOSS_RUSH) + return; - onVanillaBehaviorHook = GameInteractor::Instance->RegisterGameHook(BossRush_OnVanillaBehaviorHandler); - onSceneInitHook = GameInteractor::Instance->RegisterGameHook(BossRush_OnSceneInitHandler); - onActorInitHook = GameInteractor::Instance->RegisterGameHook(BossRush_OnActorInitHandler); - onBossDefeatHook = GameInteractor::Instance->RegisterGameHook(BossRush_OnBossDefeatHandler); - onActorUpdate = GameInteractor::Instance->RegisterGameHookForID(ACTOR_DOOR_WARP1, BossRush_OnBlueWarpUpdate); + onVanillaBehaviorHook = GameInteractor::Instance->RegisterGameHook( + BossRush_OnVanillaBehaviorHandler); + onSceneInitHook = + GameInteractor::Instance->RegisterGameHook(BossRush_OnSceneInitHandler); + onActorInitHook = + GameInteractor::Instance->RegisterGameHook(BossRush_OnActorInitHandler); + onBossDefeatHook = + GameInteractor::Instance->RegisterGameHook(BossRush_OnBossDefeatHandler); + onActorUpdate = GameInteractor::Instance->RegisterGameHookForID( + ACTOR_DOOR_WARP1, BossRush_OnBlueWarpUpdate); }); } diff --git a/soh/soh/Enhancements/boss-rush/BossRush.h b/soh/soh/Enhancements/boss-rush/BossRush.h index 292cbaf26..881d8d53f 100644 --- a/soh/soh/Enhancements/boss-rush/BossRush.h +++ b/soh/soh/Enhancements/boss-rush/BossRush.h @@ -5,12 +5,12 @@ #ifdef __cplusplus extern "C" { #endif - void BossRush_HandleBlueWarpHeal(PlayState* play); - void BossRush_InitSave(); - const char* BossRush_GetSettingName(u8 optionIndex, u8 language); - const char* BossRush_GetSettingChoiceName(u8 optionIndex, u8 choiceIndex, u8 language); - u8 BossRush_GetSettingOptionsAmount(u8 optionIndex); - void BossRush_RegisterHooks(); +void BossRush_HandleBlueWarpHeal(PlayState* play); +void BossRush_InitSave(); +const char* BossRush_GetSettingName(u8 optionIndex, u8 language); +const char* BossRush_GetSettingChoiceName(u8 optionIndex, u8 choiceIndex, u8 language); +u8 BossRush_GetSettingOptionsAmount(u8 optionIndex); +void BossRush_RegisterHooks(); #ifdef __cplusplus }; #endif diff --git a/soh/soh/Enhancements/controls/InputViewer.cpp b/soh/soh/Enhancements/controls/InputViewer.cpp index d26de6719..a48b1811f 100644 --- a/soh/soh/Enhancements/controls/InputViewer.cpp +++ b/soh/soh/Enhancements/controls/InputViewer.cpp @@ -20,15 +20,22 @@ static Color_RGBA8 textColorDefault = { 255, 255, 255, 255 }; static Color_RGBA8 range1ColorDefault = { 255, 178, 0, 255 }; static Color_RGBA8 range2ColorDefault = { 0, 255, 0, 255 }; -static std::unordered_map buttonOutlineOptions = - {{ BUTTON_OUTLINE_ALWAYS_SHOWN, "Always Shown" }, { BUTTON_OUTLINE_NOT_PRESSED, "Shown Only While Not Pressed" }, - { BUTTON_OUTLINE_PRESSED, "Shown Only While Pressed" }, { BUTTON_OUTLINE_ALWAYS_HIDDEN, "Always Hidden" }}; -static std::unordered_map buttonOutlineOptionsVerbose = - {{ BUTTON_OUTLINE_ALWAYS_SHOWN, "Outline Always Shown" }, { BUTTON_OUTLINE_NOT_PRESSED, "Outline Shown Only While Not Pressed" }, - { BUTTON_OUTLINE_PRESSED, "Outline Shown Only While Pressed" }, { BUTTON_OUTLINE_ALWAYS_HIDDEN, "Outline Always Hidden" }}; +static std::unordered_map buttonOutlineOptions = { + { BUTTON_OUTLINE_ALWAYS_SHOWN, "Always Shown" }, + { BUTTON_OUTLINE_NOT_PRESSED, "Shown Only While Not Pressed" }, + { BUTTON_OUTLINE_PRESSED, "Shown Only While Pressed" }, + { BUTTON_OUTLINE_ALWAYS_HIDDEN, "Always Hidden" } +}; +static std::unordered_map buttonOutlineOptionsVerbose = { + { BUTTON_OUTLINE_ALWAYS_SHOWN, "Outline Always Shown" }, + { BUTTON_OUTLINE_NOT_PRESSED, "Outline Shown Only While Not Pressed" }, + { BUTTON_OUTLINE_PRESSED, "Outline Shown Only While Pressed" }, + { BUTTON_OUTLINE_ALWAYS_HIDDEN, "Outline Always Hidden" } +}; -static std::unordered_map stickModeOptions = - {{ STICK_MODE_ALWAYS_SHOWN, "Always" }, { STICK_MODE_HIDDEN_IN_DEADZONE, "While In Use" }, { STICK_MODE_ALWAYS_HIDDEN, "Never" }}; +static std::unordered_map stickModeOptions = { { STICK_MODE_ALWAYS_SHOWN, "Always" }, + { STICK_MODE_HIDDEN_IN_DEADZONE, "While In Use" }, + { STICK_MODE_ALWAYS_HIDDEN, "Never" } }; InputViewer::~InputViewer() { SPDLOG_TRACE("destruct input viewer"); @@ -68,66 +75,78 @@ void InputViewer::DrawElement() { if (!sButtonTexturesLoaded) { Ship::Context::GetInstance()->GetWindow()->GetGui()->LoadTextureFromRawImage( "Input-Viewer-Background", "textures/buttons/InputViewerBackground.png"); - Ship::Context::GetInstance()->GetWindow()->GetGui()->LoadTextureFromRawImage("A-Btn", "textures/buttons/ABtn.png"); - Ship::Context::GetInstance()->GetWindow()->GetGui()->LoadTextureFromRawImage("B-Btn", "textures/buttons/BBtn.png"); - Ship::Context::GetInstance()->GetWindow()->GetGui()->LoadTextureFromRawImage("L-Btn", "textures/buttons/LBtn.png"); - Ship::Context::GetInstance()->GetWindow()->GetGui()->LoadTextureFromRawImage("R-Btn", "textures/buttons/RBtn.png"); - Ship::Context::GetInstance()->GetWindow()->GetGui()->LoadTextureFromRawImage("Z-Btn", "textures/buttons/ZBtn.png"); - Ship::Context::GetInstance()->GetWindow()->GetGui()->LoadTextureFromRawImage("Start-Btn", - "textures/buttons/StartBtn.png"); - Ship::Context::GetInstance()->GetWindow()->GetGui()->LoadTextureFromRawImage("C-Left", "textures/buttons/CLeft.png"); - Ship::Context::GetInstance()->GetWindow()->GetGui()->LoadTextureFromRawImage("C-Right", "textures/buttons/CRight.png"); - Ship::Context::GetInstance()->GetWindow()->GetGui()->LoadTextureFromRawImage("C-Up", "textures/buttons/CUp.png"); - Ship::Context::GetInstance()->GetWindow()->GetGui()->LoadTextureFromRawImage("C-Down", "textures/buttons/CDown.png"); - Ship::Context::GetInstance()->GetWindow()->GetGui()->LoadTextureFromRawImage("Analog-Stick", - "textures/buttons/AnalogStick.png"); - Ship::Context::GetInstance()->GetWindow()->GetGui()->LoadTextureFromRawImage("Dpad-Left", - "textures/buttons/DPadLeft.png"); - Ship::Context::GetInstance()->GetWindow()->GetGui()->LoadTextureFromRawImage("Dpad-Right", - "textures/buttons/DPadRight.png"); - Ship::Context::GetInstance()->GetWindow()->GetGui()->LoadTextureFromRawImage("Dpad-Up", "textures/buttons/DPadUp.png"); - Ship::Context::GetInstance()->GetWindow()->GetGui()->LoadTextureFromRawImage("Dpad-Down", - "textures/buttons/DPadDown.png"); - Ship::Context::GetInstance()->GetWindow()->GetGui()->LoadTextureFromRawImage("Modifier-1", "textures/buttons/Mod1.png"); - Ship::Context::GetInstance()->GetWindow()->GetGui()->LoadTextureFromRawImage("Modifier-2", "textures/buttons/Mod2.png"); - Ship::Context::GetInstance()->GetWindow()->GetGui()->LoadTextureFromRawImage("Right-Stick", - "textures/buttons/RightStick.png"); - Ship::Context::GetInstance()->GetWindow()->GetGui()->LoadTextureFromRawImage("A-Btn Outline", - "textures/buttons/ABtnOutline.png"); - Ship::Context::GetInstance()->GetWindow()->GetGui()->LoadTextureFromRawImage("B-Btn Outline", - "textures/buttons/BBtnOutline.png"); - Ship::Context::GetInstance()->GetWindow()->GetGui()->LoadTextureFromRawImage("L-Btn Outline", - "textures/buttons/LBtnOutline.png"); - Ship::Context::GetInstance()->GetWindow()->GetGui()->LoadTextureFromRawImage("R-Btn Outline", - "textures/buttons/RBtnOutline.png"); - Ship::Context::GetInstance()->GetWindow()->GetGui()->LoadTextureFromRawImage("Z-Btn Outline", - "textures/buttons/ZBtnOutline.png"); - Ship::Context::GetInstance()->GetWindow()->GetGui()->LoadTextureFromRawImage("Start-Btn Outline", - "textures/buttons/StartBtnOutline.png"); - Ship::Context::GetInstance()->GetWindow()->GetGui()->LoadTextureFromRawImage("C-Left Outline", - "textures/buttons/CLeftOutline.png"); - Ship::Context::GetInstance()->GetWindow()->GetGui()->LoadTextureFromRawImage("C-Right Outline", - "textures/buttons/CRightOutline.png"); - Ship::Context::GetInstance()->GetWindow()->GetGui()->LoadTextureFromRawImage("C-Up Outline", - "textures/buttons/CUpOutline.png"); - Ship::Context::GetInstance()->GetWindow()->GetGui()->LoadTextureFromRawImage("C-Down Outline", - "textures/buttons/CDownOutline.png"); - Ship::Context::GetInstance()->GetWindow()->GetGui()->LoadTextureFromRawImage("Analog-Stick Outline", - "textures/buttons/AnalogStickOutline.png"); - Ship::Context::GetInstance()->GetWindow()->GetGui()->LoadTextureFromRawImage("Dpad-Left Outline", - "textures/buttons/DPadLeftOutline.png"); - Ship::Context::GetInstance()->GetWindow()->GetGui()->LoadTextureFromRawImage("Dpad-Right Outline", - "textures/buttons/DPadRightOutline.png"); - Ship::Context::GetInstance()->GetWindow()->GetGui()->LoadTextureFromRawImage("Dpad-Up Outline", - "textures/buttons/DPadUpOutline.png"); - Ship::Context::GetInstance()->GetWindow()->GetGui()->LoadTextureFromRawImage("Dpad-Down Outline", - "textures/buttons/DPadDownOutline.png"); - Ship::Context::GetInstance()->GetWindow()->GetGui()->LoadTextureFromRawImage("Modifier-1 Outline", - "textures/buttons/Mod1Outline.png"); - Ship::Context::GetInstance()->GetWindow()->GetGui()->LoadTextureFromRawImage("Modifier-2 Outline", - "textures/buttons/Mod2Outline.png"); - Ship::Context::GetInstance()->GetWindow()->GetGui()->LoadTextureFromRawImage("Right-Stick Outline", - "textures/buttons/RightStickOutline.png"); + Ship::Context::GetInstance()->GetWindow()->GetGui()->LoadTextureFromRawImage("A-Btn", + "textures/buttons/ABtn.png"); + Ship::Context::GetInstance()->GetWindow()->GetGui()->LoadTextureFromRawImage("B-Btn", + "textures/buttons/BBtn.png"); + Ship::Context::GetInstance()->GetWindow()->GetGui()->LoadTextureFromRawImage("L-Btn", + "textures/buttons/LBtn.png"); + Ship::Context::GetInstance()->GetWindow()->GetGui()->LoadTextureFromRawImage("R-Btn", + "textures/buttons/RBtn.png"); + Ship::Context::GetInstance()->GetWindow()->GetGui()->LoadTextureFromRawImage("Z-Btn", + "textures/buttons/ZBtn.png"); + Ship::Context::GetInstance()->GetWindow()->GetGui()->LoadTextureFromRawImage( + "Start-Btn", "textures/buttons/StartBtn.png"); + Ship::Context::GetInstance()->GetWindow()->GetGui()->LoadTextureFromRawImage("C-Left", + "textures/buttons/CLeft.png"); + Ship::Context::GetInstance()->GetWindow()->GetGui()->LoadTextureFromRawImage("C-Right", + "textures/buttons/CRight.png"); + Ship::Context::GetInstance()->GetWindow()->GetGui()->LoadTextureFromRawImage("C-Up", + "textures/buttons/CUp.png"); + Ship::Context::GetInstance()->GetWindow()->GetGui()->LoadTextureFromRawImage("C-Down", + "textures/buttons/CDown.png"); + Ship::Context::GetInstance()->GetWindow()->GetGui()->LoadTextureFromRawImage( + "Analog-Stick", "textures/buttons/AnalogStick.png"); + Ship::Context::GetInstance()->GetWindow()->GetGui()->LoadTextureFromRawImage( + "Dpad-Left", "textures/buttons/DPadLeft.png"); + Ship::Context::GetInstance()->GetWindow()->GetGui()->LoadTextureFromRawImage( + "Dpad-Right", "textures/buttons/DPadRight.png"); + Ship::Context::GetInstance()->GetWindow()->GetGui()->LoadTextureFromRawImage("Dpad-Up", + "textures/buttons/DPadUp.png"); + Ship::Context::GetInstance()->GetWindow()->GetGui()->LoadTextureFromRawImage( + "Dpad-Down", "textures/buttons/DPadDown.png"); + Ship::Context::GetInstance()->GetWindow()->GetGui()->LoadTextureFromRawImage("Modifier-1", + "textures/buttons/Mod1.png"); + Ship::Context::GetInstance()->GetWindow()->GetGui()->LoadTextureFromRawImage("Modifier-2", + "textures/buttons/Mod2.png"); + Ship::Context::GetInstance()->GetWindow()->GetGui()->LoadTextureFromRawImage( + "Right-Stick", "textures/buttons/RightStick.png"); + Ship::Context::GetInstance()->GetWindow()->GetGui()->LoadTextureFromRawImage( + "A-Btn Outline", "textures/buttons/ABtnOutline.png"); + Ship::Context::GetInstance()->GetWindow()->GetGui()->LoadTextureFromRawImage( + "B-Btn Outline", "textures/buttons/BBtnOutline.png"); + Ship::Context::GetInstance()->GetWindow()->GetGui()->LoadTextureFromRawImage( + "L-Btn Outline", "textures/buttons/LBtnOutline.png"); + Ship::Context::GetInstance()->GetWindow()->GetGui()->LoadTextureFromRawImage( + "R-Btn Outline", "textures/buttons/RBtnOutline.png"); + Ship::Context::GetInstance()->GetWindow()->GetGui()->LoadTextureFromRawImage( + "Z-Btn Outline", "textures/buttons/ZBtnOutline.png"); + Ship::Context::GetInstance()->GetWindow()->GetGui()->LoadTextureFromRawImage( + "Start-Btn Outline", "textures/buttons/StartBtnOutline.png"); + Ship::Context::GetInstance()->GetWindow()->GetGui()->LoadTextureFromRawImage( + "C-Left Outline", "textures/buttons/CLeftOutline.png"); + Ship::Context::GetInstance()->GetWindow()->GetGui()->LoadTextureFromRawImage( + "C-Right Outline", "textures/buttons/CRightOutline.png"); + Ship::Context::GetInstance()->GetWindow()->GetGui()->LoadTextureFromRawImage( + "C-Up Outline", "textures/buttons/CUpOutline.png"); + Ship::Context::GetInstance()->GetWindow()->GetGui()->LoadTextureFromRawImage( + "C-Down Outline", "textures/buttons/CDownOutline.png"); + Ship::Context::GetInstance()->GetWindow()->GetGui()->LoadTextureFromRawImage( + "Analog-Stick Outline", "textures/buttons/AnalogStickOutline.png"); + Ship::Context::GetInstance()->GetWindow()->GetGui()->LoadTextureFromRawImage( + "Dpad-Left Outline", "textures/buttons/DPadLeftOutline.png"); + Ship::Context::GetInstance()->GetWindow()->GetGui()->LoadTextureFromRawImage( + "Dpad-Right Outline", "textures/buttons/DPadRightOutline.png"); + Ship::Context::GetInstance()->GetWindow()->GetGui()->LoadTextureFromRawImage( + "Dpad-Up Outline", "textures/buttons/DPadUpOutline.png"); + Ship::Context::GetInstance()->GetWindow()->GetGui()->LoadTextureFromRawImage( + "Dpad-Down Outline", "textures/buttons/DPadDownOutline.png"); + Ship::Context::GetInstance()->GetWindow()->GetGui()->LoadTextureFromRawImage( + "Modifier-1 Outline", "textures/buttons/Mod1Outline.png"); + Ship::Context::GetInstance()->GetWindow()->GetGui()->LoadTextureFromRawImage( + "Modifier-2 Outline", "textures/buttons/Mod2Outline.png"); + Ship::Context::GetInstance()->GetWindow()->GetGui()->LoadTextureFromRawImage( + "Right-Stick Outline", "textures/buttons/RightStickOutline.png"); sButtonTexturesLoaded = true; } @@ -140,7 +159,8 @@ void InputViewer::DrawElement() { const float scale = CVarGetFloat(CVAR_INPUT_VIEWER("Scale"), 1.0f); #endif const int showAnalogAngles = CVarGetInteger(CVAR_INPUT_VIEWER("AnalogAngles.Enabled"), 0); - const int buttonOutlineMode = CVarGetInteger(CVAR_INPUT_VIEWER("ButtonOutlineMode"), BUTTON_OUTLINE_NOT_PRESSED); + const int buttonOutlineMode = + CVarGetInteger(CVAR_INPUT_VIEWER("ButtonOutlineMode"), BUTTON_OUTLINE_NOT_PRESSED); const bool useGlobalOutlineMode = CVarGetInteger(CVAR_INPUT_VIEWER("UseGlobalButtonOutlineMode"), 1); ImVec2 bgSize = Ship::Context::GetInstance()->GetWindow()->GetGui()->GetTextureSize("Input-Viewer-Background"); @@ -148,12 +168,12 @@ void InputViewer::DrawElement() { ImGui::SetNextWindowSize( ImVec2(scaledBGSize.x + 20, scaledBGSize.y + - (showAnalogAngles ? ImGui::CalcTextSize("X").y : 0) * scale * - CVarGetFloat(CVAR_INPUT_VIEWER("AnalogAngles.Scale"), 1.0f) + - 20)); + (showAnalogAngles ? ImGui::CalcTextSize("X").y : 0) * scale * + CVarGetFloat(CVAR_INPUT_VIEWER("AnalogAngles.Scale"), 1.0f) + + 20)); ImGui::SetNextWindowContentSize( ImVec2(scaledBGSize.x, scaledBGSize.y + (showAnalogAngles ? 15 : 0) * scale * - CVarGetFloat(CVAR_INPUT_VIEWER("AnalogAngles.Scale"), 1.0f))); + CVarGetFloat(CVAR_INPUT_VIEWER("AnalogAngles.Scale"), 1.0f))); ImGui::SetNextWindowPos( ImVec2(mainPos.x + size.x - scaledBGSize.x - 30, mainPos.y + size.y - scaledBGSize.y - 30), ImGuiCond_FirstUseEver); @@ -161,11 +181,12 @@ void InputViewer::DrawElement() { ImGui::PushStyleColor(ImGuiCol_WindowBg, ImVec4(0, 0, 0, 0)); ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, ImVec2(0.0f, 0.0f)); - OSContPad* pads = std::dynamic_pointer_cast(Ship::Context::GetInstance()->GetControlDeck())->GetPads(); + OSContPad* pads = + std::dynamic_pointer_cast(Ship::Context::GetInstance()->GetControlDeck())->GetPads(); ImGuiWindowFlags windowFlags = ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_NoScrollbar | - ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoBackground | - ImGuiWindowFlags_NoFocusOnAppearing; + ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoBackground | + ImGuiWindowFlags_NoFocusOnAppearing; if (!CVarGetInteger(CVAR_INPUT_VIEWER("EnableDragging"), 1)) { windowFlags |= ImGuiWindowFlags_NoInputs | ImGuiWindowFlags_NoMove; @@ -188,17 +209,17 @@ void InputViewer::DrawElement() { ImGui::SetNextItemAllowOverlap(); ImGui::SetCursorPos(aPos); RenderButton("B-Btn", "B-Btn Outline", pads[0].button & BTN_B, scaledBGSize, - useGlobalOutlineMode - ? buttonOutlineMode - : CVarGetInteger(CVAR_INPUT_VIEWER("BBtnOutlineMode"), BUTTON_OUTLINE_NOT_PRESSED)); + useGlobalOutlineMode + ? buttonOutlineMode + : CVarGetInteger(CVAR_INPUT_VIEWER("BBtnOutlineMode"), BUTTON_OUTLINE_NOT_PRESSED)); } if (CVarGetInteger(CVAR_INPUT_VIEWER("ABtn"), 1)) { ImGui::SetNextItemAllowOverlap(); ImGui::SetCursorPos(aPos); RenderButton("A-Btn", "A-Btn Outline", pads[0].button & BTN_A, scaledBGSize, - useGlobalOutlineMode - ? buttonOutlineMode - : CVarGetInteger(CVAR_INPUT_VIEWER("ABtnOutlineMode"), BUTTON_OUTLINE_NOT_PRESSED)); + useGlobalOutlineMode + ? buttonOutlineMode + : CVarGetInteger(CVAR_INPUT_VIEWER("ABtnOutlineMode"), BUTTON_OUTLINE_NOT_PRESSED)); } // C buttons @@ -206,33 +227,33 @@ void InputViewer::DrawElement() { ImGui::SetNextItemAllowOverlap(); ImGui::SetCursorPos(aPos); RenderButton("C-Up", "C-Up Outline", pads[0].button & BTN_CUP, scaledBGSize, - useGlobalOutlineMode - ? buttonOutlineMode - : CVarGetInteger(CVAR_INPUT_VIEWER("CUpOutlineMode"), BUTTON_OUTLINE_NOT_PRESSED)); + useGlobalOutlineMode + ? buttonOutlineMode + : CVarGetInteger(CVAR_INPUT_VIEWER("CUpOutlineMode"), BUTTON_OUTLINE_NOT_PRESSED)); } if (CVarGetInteger(CVAR_INPUT_VIEWER("CLeft"), 1)) { ImGui::SetNextItemAllowOverlap(); ImGui::SetCursorPos(aPos); RenderButton("C-Left", "C-Left Outline", pads[0].button & BTN_CLEFT, scaledBGSize, - useGlobalOutlineMode - ? buttonOutlineMode - : CVarGetInteger(CVAR_INPUT_VIEWER("CLeftOutlineMode"), BUTTON_OUTLINE_NOT_PRESSED)); + useGlobalOutlineMode + ? buttonOutlineMode + : CVarGetInteger(CVAR_INPUT_VIEWER("CLeftOutlineMode"), BUTTON_OUTLINE_NOT_PRESSED)); } if (CVarGetInteger(CVAR_INPUT_VIEWER("CRight"), 1)) { ImGui::SetNextItemAllowOverlap(); ImGui::SetCursorPos(aPos); RenderButton("C-Right", "C-Right Outline", pads[0].button & BTN_CRIGHT, scaledBGSize, - useGlobalOutlineMode - ? buttonOutlineMode - : CVarGetInteger(CVAR_INPUT_VIEWER("CRightOutlineMode"), BUTTON_OUTLINE_NOT_PRESSED)); + useGlobalOutlineMode + ? buttonOutlineMode + : CVarGetInteger(CVAR_INPUT_VIEWER("CRightOutlineMode"), BUTTON_OUTLINE_NOT_PRESSED)); } if (CVarGetInteger(CVAR_INPUT_VIEWER("CDown"), 1)) { ImGui::SetNextItemAllowOverlap(); ImGui::SetCursorPos(aPos); RenderButton("C-Down", "C-Down Outline", pads[0].button & BTN_CDOWN, scaledBGSize, - useGlobalOutlineMode - ? buttonOutlineMode - : CVarGetInteger(CVAR_INPUT_VIEWER("CDownOutlineMode"), BUTTON_OUTLINE_NOT_PRESSED)); + useGlobalOutlineMode + ? buttonOutlineMode + : CVarGetInteger(CVAR_INPUT_VIEWER("CDownOutlineMode"), BUTTON_OUTLINE_NOT_PRESSED)); } // L/R/Z @@ -240,25 +261,25 @@ void InputViewer::DrawElement() { ImGui::SetNextItemAllowOverlap(); ImGui::SetCursorPos(aPos); RenderButton("L-Btn", "L-Btn Outline", pads[0].button & BTN_L, scaledBGSize, - useGlobalOutlineMode - ? buttonOutlineMode - : CVarGetInteger(CVAR_INPUT_VIEWER("LBtnOutlineMode"), BUTTON_OUTLINE_NOT_PRESSED)); + useGlobalOutlineMode + ? buttonOutlineMode + : CVarGetInteger(CVAR_INPUT_VIEWER("LBtnOutlineMode"), BUTTON_OUTLINE_NOT_PRESSED)); } if (CVarGetInteger(CVAR_INPUT_VIEWER("RBtn"), 1)) { ImGui::SetNextItemAllowOverlap(); ImGui::SetCursorPos(aPos); RenderButton("R-Btn", "R-Btn Outline", pads[0].button & BTN_R, scaledBGSize, - useGlobalOutlineMode - ? buttonOutlineMode - : CVarGetInteger(CVAR_INPUT_VIEWER("RBtnOutlineMode"), BUTTON_OUTLINE_NOT_PRESSED)); + useGlobalOutlineMode + ? buttonOutlineMode + : CVarGetInteger(CVAR_INPUT_VIEWER("RBtnOutlineMode"), BUTTON_OUTLINE_NOT_PRESSED)); } if (CVarGetInteger(CVAR_INPUT_VIEWER("ZBtn"), 1)) { ImGui::SetNextItemAllowOverlap(); ImGui::SetCursorPos(aPos); RenderButton("Z-Btn", "Z-Btn Outline", pads[0].button & BTN_Z, scaledBGSize, - useGlobalOutlineMode - ? buttonOutlineMode - : CVarGetInteger(CVAR_INPUT_VIEWER("ZBtnOutlineMode"), BUTTON_OUTLINE_NOT_PRESSED)); + useGlobalOutlineMode + ? buttonOutlineMode + : CVarGetInteger(CVAR_INPUT_VIEWER("ZBtnOutlineMode"), BUTTON_OUTLINE_NOT_PRESSED)); } // Start @@ -266,9 +287,9 @@ void InputViewer::DrawElement() { ImGui::SetNextItemAllowOverlap(); ImGui::SetCursorPos(aPos); RenderButton("Start-Btn", "Start-Btn Outline", pads[0].button & BTN_START, scaledBGSize, - useGlobalOutlineMode - ? buttonOutlineMode - : CVarGetInteger(CVAR_INPUT_VIEWER("StartBtnOutlineMode"), BUTTON_OUTLINE_NOT_PRESSED)); + useGlobalOutlineMode ? buttonOutlineMode + : CVarGetInteger(CVAR_INPUT_VIEWER("StartBtnOutlineMode"), + BUTTON_OUTLINE_NOT_PRESSED)); } // Dpad @@ -276,27 +297,27 @@ void InputViewer::DrawElement() { ImGui::SetNextItemAllowOverlap(); ImGui::SetCursorPos(aPos); RenderButton("Dpad-Left", "Dpad-Left Outline", pads[0].button & BTN_DLEFT, scaledBGSize, - useGlobalOutlineMode - ? buttonOutlineMode - : CVarGetInteger(CVAR_INPUT_VIEWER("DpadOutlineMode"), BUTTON_OUTLINE_NOT_PRESSED)); + useGlobalOutlineMode + ? buttonOutlineMode + : CVarGetInteger(CVAR_INPUT_VIEWER("DpadOutlineMode"), BUTTON_OUTLINE_NOT_PRESSED)); ImGui::SetNextItemAllowOverlap(); ImGui::SetCursorPos(aPos); RenderButton("Dpad-Right", "Dpad-Right Outline", pads[0].button & BTN_DRIGHT, scaledBGSize, - useGlobalOutlineMode - ? buttonOutlineMode - : CVarGetInteger(CVAR_INPUT_VIEWER("DpadOutlineMode"), BUTTON_OUTLINE_NOT_PRESSED)); + useGlobalOutlineMode + ? buttonOutlineMode + : CVarGetInteger(CVAR_INPUT_VIEWER("DpadOutlineMode"), BUTTON_OUTLINE_NOT_PRESSED)); ImGui::SetNextItemAllowOverlap(); ImGui::SetCursorPos(aPos); RenderButton("Dpad-Up", "Dpad-Up Outline", pads[0].button & BTN_DUP, scaledBGSize, - useGlobalOutlineMode - ? buttonOutlineMode - : CVarGetInteger(CVAR_INPUT_VIEWER("DpadOutlineMode"), BUTTON_OUTLINE_NOT_PRESSED)); + useGlobalOutlineMode + ? buttonOutlineMode + : CVarGetInteger(CVAR_INPUT_VIEWER("DpadOutlineMode"), BUTTON_OUTLINE_NOT_PRESSED)); ImGui::SetNextItemAllowOverlap(); ImGui::SetCursorPos(aPos); RenderButton("Dpad-Down", "Dpad-Down Outline", pads[0].button & BTN_DDOWN, scaledBGSize, - useGlobalOutlineMode - ? buttonOutlineMode - : CVarGetInteger(CVAR_INPUT_VIEWER("DpadOutlineMode"), BUTTON_OUTLINE_NOT_PRESSED)); + useGlobalOutlineMode + ? buttonOutlineMode + : CVarGetInteger(CVAR_INPUT_VIEWER("DpadOutlineMode"), BUTTON_OUTLINE_NOT_PRESSED)); } // Modifier 1 @@ -304,18 +325,18 @@ void InputViewer::DrawElement() { ImGui::SetNextItemAllowOverlap(); ImGui::SetCursorPos(aPos); RenderButton("Modifier-1", "Modifier-1 Outline", pads[0].button & BTN_CUSTOM_MODIFIER1, scaledBGSize, - useGlobalOutlineMode - ? buttonOutlineMode - : CVarGetInteger(CVAR_INPUT_VIEWER("Mod1OutlineMode"), BUTTON_OUTLINE_NOT_PRESSED)); + useGlobalOutlineMode + ? buttonOutlineMode + : CVarGetInteger(CVAR_INPUT_VIEWER("Mod1OutlineMode"), BUTTON_OUTLINE_NOT_PRESSED)); } // Modifier 2 if (CVarGetInteger(CVAR_INPUT_VIEWER("Mod2"), 0)) { ImGui::SetNextItemAllowOverlap(); ImGui::SetCursorPos(aPos); RenderButton("Modifier-2", "Modifier-2 Outline", pads[0].button & BTN_CUSTOM_MODIFIER2, scaledBGSize, - useGlobalOutlineMode - ? buttonOutlineMode - : CVarGetInteger(CVAR_INPUT_VIEWER("Mod2OutlineMode"), BUTTON_OUTLINE_NOT_PRESSED)); + useGlobalOutlineMode + ? buttonOutlineMode + : CVarGetInteger(CVAR_INPUT_VIEWER("Mod2OutlineMode"), BUTTON_OUTLINE_NOT_PRESSED)); } const bool analogStickIsInDeadzone = !pads[0].stick_x && !pads[0].stick_y; @@ -340,9 +361,9 @@ void InputViewer::DrawElement() { ImGui::SetNextItemAllowOverlap(); ImGui::SetCursorPos( ImVec2(aPos.x + maxStickDistance * ((float)(pads[0].stick_x) / MAX_AXIS_RANGE) * scale, - aPos.y - maxStickDistance * ((float)(pads[0].stick_y) / MAX_AXIS_RANGE) * scale)); + aPos.y - maxStickDistance * ((float)(pads[0].stick_y) / MAX_AXIS_RANGE) * scale)); ImGui::Image(Ship::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName("Analog-Stick"), - scaledBGSize, ImVec2(0, 0), ImVec2(1.0f, 1.0f), ImVec4(255, 255, 255, 255)); + scaledBGSize, ImVec2(0, 0), ImVec2(1.0f, 1.0f), ImVec4(255, 255, 255, 255)); } // Right Stick @@ -364,15 +385,16 @@ void InputViewer::DrawElement() { ImGui::SetNextItemAllowOverlap(); ImGui::SetCursorPos( ImVec2(aPos.x + maxRightStickDistance * ((float)(pads[0].right_stick_x) / MAX_AXIS_RANGE) * scale, - aPos.y - maxRightStickDistance * ((float)(pads[0].right_stick_y) / MAX_AXIS_RANGE) * scale)); + aPos.y - maxRightStickDistance * ((float)(pads[0].right_stick_y) / MAX_AXIS_RANGE) * scale)); ImGui::Image(Ship::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName("Right-Stick"), - scaledBGSize, ImVec2(0, 0), ImVec2(1.0f, 1.0f), ImVec4(255, 255, 255, 255)); + scaledBGSize, ImVec2(0, 0), ImVec2(1.0f, 1.0f), ImVec4(255, 255, 255, 255)); } // Analog stick angle text if (showAnalogAngles) { - ImGui::SetCursorPos(ImVec2(aPos.x + 10 + CVarGetInteger(CVAR_INPUT_VIEWER("AnalogAngles.Offset"), 0) * scale, - scaledBGSize.y + aPos.y + 10)); + ImGui::SetCursorPos( + ImVec2(aPos.x + 10 + CVarGetInteger(CVAR_INPUT_VIEWER("AnalogAngles.Offset"), 0) * scale, + scaledBGSize.y + aPos.y + 10)); // Scale font with input viewer scale float oldFontScale = ImGui::GetFont()->Scale; ImGui::GetFont()->Scale *= scale * CVarGetFloat(CVAR_INPUT_VIEWER("AnalogAngles.Scale"), 1.0f); @@ -392,18 +414,17 @@ void InputViewer::DrawElement() { if (CVarGetInteger(CVAR_INPUT_VIEWER("AnalogAngles.Range1.Enabled"), 0) && (rSquared >= (range1Min * range1Min)) && (rSquared < (range1Max * range1Max))) { ImGui::PushStyleColor( - ImGuiCol_Text, - VecFromRGBA8(CVarGetColor(CVAR_INPUT_VIEWER("AnalogAngles.Range1.Color.Value"), range1ColorDefault))); - } - else if (CVarGetInteger(CVAR_INPUT_VIEWER("AnalogAngles.Range2.Enabled"), 0) && - (rSquared >= (range2Min * range2Min)) && (rSquared < (range2Max * range2Max))) { + ImGuiCol_Text, VecFromRGBA8(CVarGetColor(CVAR_INPUT_VIEWER("AnalogAngles.Range1.Color.Value"), + range1ColorDefault))); + } else if (CVarGetInteger(CVAR_INPUT_VIEWER("AnalogAngles.Range2.Enabled"), 0) && + (rSquared >= (range2Min * range2Min)) && (rSquared < (range2Max * range2Max))) { ImGui::PushStyleColor( - ImGuiCol_Text, - VecFromRGBA8(CVarGetColor(CVAR_INPUT_VIEWER("AnalogAngles.Range2.Color.Value"), range2ColorDefault))); - } - else { - ImGui::PushStyleColor(ImGuiCol_Text, VecFromRGBA8(CVarGetColor(CVAR_INPUT_VIEWER("AnalogAngles.TextColor.Value"), - textColorDefault))); + ImGuiCol_Text, VecFromRGBA8(CVarGetColor(CVAR_INPUT_VIEWER("AnalogAngles.Range2.Color.Value"), + range2ColorDefault))); + } else { + ImGui::PushStyleColor(ImGuiCol_Text, + VecFromRGBA8(CVarGetColor(CVAR_INPUT_VIEWER("AnalogAngles.TextColor.Value"), + textColorDefault))); } // Render text @@ -430,15 +451,23 @@ InputViewerSettingsWindow::~InputViewerSettingsWindow() { void InputViewerSettingsWindow::DrawElement() { // gInputViewer.Scale CVarSliderFloat("Input Viewer Scale: %.2f", CVAR_INPUT_VIEWER("Scale"), - FloatSliderOptions().Color(THEME_COLOR).DefaultValue(1.0f).Min(0.1f).Max(5.0f).ShowButtons(true).Tooltip("Sets the on screen size of the input viewer")); + FloatSliderOptions() + .Color(THEME_COLOR) + .DefaultValue(1.0f) + .Min(0.1f) + .Max(5.0f) + .ShowButtons(true) + .Tooltip("Sets the on screen size of the input viewer")); // gInputViewer.EnableDragging - CVarCheckbox("Enable Dragging", CVAR_INPUT_VIEWER("EnableDragging"), CheckboxOptions().Color(THEME_COLOR).DefaultValue(true)); + CVarCheckbox("Enable Dragging", CVAR_INPUT_VIEWER("EnableDragging"), + CheckboxOptions().Color(THEME_COLOR).DefaultValue(true)); UIWidgets::PaddedSeparator(true, true); // gInputViewer.ShowBackground - CVarCheckbox("Show Background Layer", CVAR_INPUT_VIEWER("ShowBackground"), CheckboxOptions().Color(THEME_COLOR).DefaultValue(true)); + CVarCheckbox("Show Background Layer", CVAR_INPUT_VIEWER("ShowBackground"), + CheckboxOptions().Color(THEME_COLOR).DefaultValue(true)); UIWidgets::PaddedSeparator(true, true); @@ -446,121 +475,138 @@ void InputViewerSettingsWindow::DrawElement() { if (ImGui::CollapsingHeader("Buttons")) { // gInputViewer.ButtonOutlineMode - CVarCombobox("Button Outlines/Backgrounds", CVAR_INPUT_VIEWER("ButtonOutlineMode"), buttonOutlineOptions, - ComboboxOptions({{ .disabled = !CVarGetInteger(CVAR_INPUT_VIEWER("UseGlobalButtonOutlineMode"), 1), .disabledTooltip = "Disabled because Global Button Outline is off" }}) - .Color(THEME_COLOR).DefaultIndex(BUTTON_OUTLINE_NOT_PRESSED) - .Tooltip("Sets the desired visibility behavior for the button outline/background layers. Useful for " - "custom input viewers.")); + CVarCombobox( + "Button Outlines/Backgrounds", CVAR_INPUT_VIEWER("ButtonOutlineMode"), buttonOutlineOptions, + ComboboxOptions({ { .disabled = !CVarGetInteger(CVAR_INPUT_VIEWER("UseGlobalButtonOutlineMode"), 1), + .disabledTooltip = "Disabled because Global Button Outline is off" } }) + .Color(THEME_COLOR) + .DefaultIndex(BUTTON_OUTLINE_NOT_PRESSED) + .Tooltip("Sets the desired visibility behavior for the button outline/background layers. Useful for " + "custom input viewers.")); // gInputViewer.UseGlobalButtonOutlineMode - CVarCheckbox("Use for all buttons", CVAR_INPUT_VIEWER("UseGlobalButtonOutlineMode"), CheckboxOptions().Color(THEME_COLOR).DefaultValue(true)); + CVarCheckbox("Use for all buttons", CVAR_INPUT_VIEWER("UseGlobalButtonOutlineMode"), + CheckboxOptions().Color(THEME_COLOR).DefaultValue(true)); UIWidgets::PaddedSeparator(); bool useIndividualOutlines = !CVarGetInteger(CVAR_INPUT_VIEWER("UseGlobalButtonOutlineMode"), 1); // gInputViewer.ABtn - CVarCheckbox("Show A-Button Layers", CVAR_INPUT_VIEWER("ABtn"), CheckboxOptions().Color(THEME_COLOR).DefaultValue(true)); + CVarCheckbox("Show A-Button Layers", CVAR_INPUT_VIEWER("ABtn"), + CheckboxOptions().Color(THEME_COLOR).DefaultValue(true)); if (useIndividualOutlines && CVarGetInteger(CVAR_INPUT_VIEWER("ABtn"), 1)) { ImGui::Indent(); - CVarCombobox("##ABtnOutline", CVAR_INPUT_VIEWER("ABtnOutlineMode"), buttonOutlineOptionsVerbose, - ComboboxOptions().Color(THEME_COLOR).DefaultIndex(BUTTON_OUTLINE_NOT_PRESSED)); + CVarCombobox("##ABtnOutline", CVAR_INPUT_VIEWER("ABtnOutlineMode"), buttonOutlineOptionsVerbose, + ComboboxOptions().Color(THEME_COLOR).DefaultIndex(BUTTON_OUTLINE_NOT_PRESSED)); ImGui::Unindent(); } // gInputViewer.BBtn - CVarCheckbox("Show B-Button Layers", CVAR_INPUT_VIEWER("BBtn"), CheckboxOptions().Color(THEME_COLOR).DefaultValue(true)); + CVarCheckbox("Show B-Button Layers", CVAR_INPUT_VIEWER("BBtn"), + CheckboxOptions().Color(THEME_COLOR).DefaultValue(true)); if (useIndividualOutlines && CVarGetInteger(CVAR_INPUT_VIEWER("BBtn"), 1)) { ImGui::Indent(); CVarCombobox("##BBtnOutline", CVAR_INPUT_VIEWER("BBtnOutlineMode"), buttonOutlineOptionsVerbose, - ComboboxOptions().Color(THEME_COLOR).DefaultIndex(BUTTON_OUTLINE_NOT_PRESSED)); + ComboboxOptions().Color(THEME_COLOR).DefaultIndex(BUTTON_OUTLINE_NOT_PRESSED)); ImGui::Unindent(); } // gInputViewer.CUp - CVarCheckbox("Show C-Up Layers", CVAR_INPUT_VIEWER("CUp"), CheckboxOptions().Color(THEME_COLOR).DefaultValue(true)); + CVarCheckbox("Show C-Up Layers", CVAR_INPUT_VIEWER("CUp"), + CheckboxOptions().Color(THEME_COLOR).DefaultValue(true)); if (useIndividualOutlines && CVarGetInteger(CVAR_INPUT_VIEWER("CUp"), 1)) { ImGui::Indent(); CVarCombobox("##CUpOutline", CVAR_INPUT_VIEWER("CUpOutlineMode"), buttonOutlineOptionsVerbose, - ComboboxOptions().Color(THEME_COLOR).DefaultIndex(BUTTON_OUTLINE_NOT_PRESSED)); + ComboboxOptions().Color(THEME_COLOR).DefaultIndex(BUTTON_OUTLINE_NOT_PRESSED)); ImGui::Unindent(); } // gInputViewer.CRight - CVarCheckbox("Show C-Right Layers", CVAR_INPUT_VIEWER("CRight"), CheckboxOptions().Color(THEME_COLOR).DefaultValue(true)); + CVarCheckbox("Show C-Right Layers", CVAR_INPUT_VIEWER("CRight"), + CheckboxOptions().Color(THEME_COLOR).DefaultValue(true)); if (useIndividualOutlines && CVarGetInteger(CVAR_INPUT_VIEWER("CRight"), 1)) { ImGui::Indent(); CVarCombobox("##CRightOutline", CVAR_INPUT_VIEWER("CRightOutlineMode"), buttonOutlineOptionsVerbose, - ComboboxOptions().Color(THEME_COLOR).DefaultIndex(BUTTON_OUTLINE_NOT_PRESSED)); + ComboboxOptions().Color(THEME_COLOR).DefaultIndex(BUTTON_OUTLINE_NOT_PRESSED)); ImGui::Unindent(); } // gInputViewer.CDown - CVarCheckbox("Show C-Down Layers", CVAR_INPUT_VIEWER("CDown"), CheckboxOptions().Color(THEME_COLOR).DefaultValue(true)); + CVarCheckbox("Show C-Down Layers", CVAR_INPUT_VIEWER("CDown"), + CheckboxOptions().Color(THEME_COLOR).DefaultValue(true)); if (useIndividualOutlines && CVarGetInteger(CVAR_INPUT_VIEWER("CDown"), 1)) { ImGui::Indent(); CVarCombobox("##CDownOutline", CVAR_INPUT_VIEWER("CDownOutlineMode"), buttonOutlineOptionsVerbose, - ComboboxOptions().Color(THEME_COLOR).DefaultIndex(BUTTON_OUTLINE_NOT_PRESSED)); + ComboboxOptions().Color(THEME_COLOR).DefaultIndex(BUTTON_OUTLINE_NOT_PRESSED)); ImGui::Unindent(); } // gInputViewer.CLeft - CVarCheckbox("Show C-Left Layers", CVAR_INPUT_VIEWER("CLeft"), CheckboxOptions().Color(THEME_COLOR).DefaultValue(true)); + CVarCheckbox("Show C-Left Layers", CVAR_INPUT_VIEWER("CLeft"), + CheckboxOptions().Color(THEME_COLOR).DefaultValue(true)); if (useIndividualOutlines && CVarGetInteger(CVAR_INPUT_VIEWER("CLeft"), 1)) { ImGui::Indent(); CVarCombobox("##CLeftOutline", CVAR_INPUT_VIEWER("CLeftOutlineMode"), buttonOutlineOptionsVerbose, - ComboboxOptions().Color(THEME_COLOR).DefaultIndex(BUTTON_OUTLINE_NOT_PRESSED)); + ComboboxOptions().Color(THEME_COLOR).DefaultIndex(BUTTON_OUTLINE_NOT_PRESSED)); ImGui::Unindent(); } // gInputViewer.LBtn - CVarCheckbox("Show L-Button Layers", CVAR_INPUT_VIEWER("LBtn"), CheckboxOptions().Color(THEME_COLOR).DefaultValue(true)); + CVarCheckbox("Show L-Button Layers", CVAR_INPUT_VIEWER("LBtn"), + CheckboxOptions().Color(THEME_COLOR).DefaultValue(true)); if (useIndividualOutlines && CVarGetInteger(CVAR_INPUT_VIEWER("LBtn"), 1)) { ImGui::Indent(); CVarCombobox("##LBtnOutline", CVAR_INPUT_VIEWER("LBtnOutlineMode"), buttonOutlineOptionsVerbose, - ComboboxOptions().Color(THEME_COLOR).DefaultIndex(BUTTON_OUTLINE_NOT_PRESSED)); + ComboboxOptions().Color(THEME_COLOR).DefaultIndex(BUTTON_OUTLINE_NOT_PRESSED)); ImGui::Unindent(); } // gInputViewer.RBtn - CVarCheckbox("Show R-Button Layers", CVAR_INPUT_VIEWER("RBtn"), CheckboxOptions().Color(THEME_COLOR).DefaultValue(true)); + CVarCheckbox("Show R-Button Layers", CVAR_INPUT_VIEWER("RBtn"), + CheckboxOptions().Color(THEME_COLOR).DefaultValue(true)); if (useIndividualOutlines && CVarGetInteger(CVAR_INPUT_VIEWER("RBtn"), 1)) { ImGui::Indent(); CVarCombobox("##RBtnOutline", CVAR_INPUT_VIEWER("RBtnOutlineMode"), buttonOutlineOptionsVerbose, - ComboboxOptions().Color(THEME_COLOR).DefaultIndex(BUTTON_OUTLINE_NOT_PRESSED)); + ComboboxOptions().Color(THEME_COLOR).DefaultIndex(BUTTON_OUTLINE_NOT_PRESSED)); ImGui::Unindent(); } // gInputViewer.ZBtn - CVarCheckbox("Show Z-Button Layers", CVAR_INPUT_VIEWER("ZBtn"), CheckboxOptions().Color(THEME_COLOR).DefaultValue(true)); + CVarCheckbox("Show Z-Button Layers", CVAR_INPUT_VIEWER("ZBtn"), + CheckboxOptions().Color(THEME_COLOR).DefaultValue(true)); if (useIndividualOutlines && CVarGetInteger(CVAR_INPUT_VIEWER("ZBtn"), 1)) { ImGui::Indent(); CVarCombobox("##ZBtnOutline", CVAR_INPUT_VIEWER("ZBtnOutlineMode"), buttonOutlineOptionsVerbose, - ComboboxOptions().Color(THEME_COLOR).DefaultIndex(BUTTON_OUTLINE_NOT_PRESSED)); + ComboboxOptions().Color(THEME_COLOR).DefaultIndex(BUTTON_OUTLINE_NOT_PRESSED)); ImGui::Unindent(); } // gInputViewer.StartBtn - CVarCheckbox("Show Start Button Layers", CVAR_INPUT_VIEWER("StartBtn"), CheckboxOptions().Color(THEME_COLOR).DefaultValue(true)); + CVarCheckbox("Show Start Button Layers", CVAR_INPUT_VIEWER("StartBtn"), + CheckboxOptions().Color(THEME_COLOR).DefaultValue(true)); if (useIndividualOutlines && CVarGetInteger(CVAR_INPUT_VIEWER("StartBtn"), 1)) { ImGui::Indent(); CVarCombobox("##StartBtnOutline", CVAR_INPUT_VIEWER("StartBtnOutlineMode"), buttonOutlineOptionsVerbose, - ComboboxOptions().Color(THEME_COLOR).DefaultIndex(BUTTON_OUTLINE_NOT_PRESSED)); + ComboboxOptions().Color(THEME_COLOR).DefaultIndex(BUTTON_OUTLINE_NOT_PRESSED)); ImGui::Unindent(); } // gInputViewer.Dpad - CVarCheckbox("Show D-Pad Layers", CVAR_INPUT_VIEWER("Dpad"), CheckboxOptions().Color(THEME_COLOR).DefaultValue(true)); + CVarCheckbox("Show D-Pad Layers", CVAR_INPUT_VIEWER("Dpad"), + CheckboxOptions().Color(THEME_COLOR).DefaultValue(true)); if (useIndividualOutlines && CVarGetInteger(CVAR_INPUT_VIEWER("Dpad"), 0)) { ImGui::Indent(); CVarCombobox("##DpadOutline", CVAR_INPUT_VIEWER("DpadOutlineMode"), buttonOutlineOptionsVerbose, - ComboboxOptions().Color(THEME_COLOR).DefaultIndex(BUTTON_OUTLINE_NOT_PRESSED)); + ComboboxOptions().Color(THEME_COLOR).DefaultIndex(BUTTON_OUTLINE_NOT_PRESSED)); ImGui::Unindent(); } // gInputViewer.Mod1 - CVarCheckbox("Show Modifier Button 1 Layers", CVAR_INPUT_VIEWER("Mod1"), CheckboxOptions().Color(THEME_COLOR).DefaultValue(true)); + CVarCheckbox("Show Modifier Button 1 Layers", CVAR_INPUT_VIEWER("Mod1"), + CheckboxOptions().Color(THEME_COLOR).DefaultValue(true)); if (useIndividualOutlines && CVarGetInteger(CVAR_INPUT_VIEWER("Mod1"), 0)) { ImGui::Indent(); CVarCombobox("##Mmod1Outline", CVAR_INPUT_VIEWER("Mod1OutlineMode"), buttonOutlineOptionsVerbose, - ComboboxOptions().Color(THEME_COLOR).DefaultIndex(BUTTON_OUTLINE_NOT_PRESSED)); + ComboboxOptions().Color(THEME_COLOR).DefaultIndex(BUTTON_OUTLINE_NOT_PRESSED)); ImGui::Unindent(); } // gInputViewer.Mod2 - CVarCheckbox("Show Modifier Button 2 Layers", CVAR_INPUT_VIEWER("Mod2"), CheckboxOptions().Color(THEME_COLOR).DefaultValue(true)); + CVarCheckbox("Show Modifier Button 2 Layers", CVAR_INPUT_VIEWER("Mod2"), + CheckboxOptions().Color(THEME_COLOR).DefaultValue(true)); if (useIndividualOutlines && CVarGetInteger(CVAR_INPUT_VIEWER("Mod2"), 0)) { ImGui::Indent(); CVarCombobox("##Mod2Outline", CVAR_INPUT_VIEWER("Mod2OutlineMode"), buttonOutlineOptionsVerbose, - ComboboxOptions().Color(THEME_COLOR).DefaultIndex(BUTTON_OUTLINE_NOT_PRESSED)); + ComboboxOptions().Color(THEME_COLOR).DefaultIndex(BUTTON_OUTLINE_NOT_PRESSED)); ImGui::Unindent(); } @@ -569,72 +615,124 @@ void InputViewerSettingsWindow::DrawElement() { if (ImGui::CollapsingHeader("Analog Stick")) { // gInputViewer.AnalogStick.VisibilityMode - CVarCombobox("Analog Stick Visibility", CVAR_INPUT_VIEWER("AnalogStick.VisibilityMode"), stickModeOptions, - ComboboxOptions().Color(THEME_COLOR).DefaultIndex(STICK_MODE_ALWAYS_SHOWN) - .Tooltip("Determines the conditions under which the moving layer of the analog stick texture is visible.")); + CVarCombobox( + "Analog Stick Visibility", CVAR_INPUT_VIEWER("AnalogStick.VisibilityMode"), stickModeOptions, + ComboboxOptions() + .Color(THEME_COLOR) + .DefaultIndex(STICK_MODE_ALWAYS_SHOWN) + .Tooltip( + "Determines the conditions under which the moving layer of the analog stick texture is visible.")); // gInputViewer.AnalogStick.OutlineMode - CVarCombobox("Analog Stick Outline/Background Visibility", CVAR_INPUT_VIEWER("AnalogStick.OutlineMode"), stickModeOptions, - ComboboxOptions().Color(THEME_COLOR).DefaultIndex(STICK_MODE_ALWAYS_SHOWN) - .Tooltip("Determines the conditions under which the analog stick outline/background texture is visible.")); + CVarCombobox( + "Analog Stick Outline/Background Visibility", CVAR_INPUT_VIEWER("AnalogStick.OutlineMode"), + stickModeOptions, + ComboboxOptions() + .Color(THEME_COLOR) + .DefaultIndex(STICK_MODE_ALWAYS_SHOWN) + .Tooltip( + "Determines the conditions under which the analog stick outline/background texture is visible.")); // gInputViewer.AnalogStick.Movement - CVarSliderInt("Analog Stick Movement: %dpx", CVAR_INPUT_VIEWER("AnalogStick.Movement"), IntSliderOptions().Color(THEME_COLOR).Min(0).Max(200).DefaultValue(12).ShowButtons(true) - .Tooltip("Sets the distance to move the analog stick in the input viewer. Useful for custom input viewers.")); + CVarSliderInt("Analog Stick Movement: %dpx", CVAR_INPUT_VIEWER("AnalogStick.Movement"), + IntSliderOptions() + .Color(THEME_COLOR) + .Min(0) + .Max(200) + .DefaultValue(12) + .ShowButtons(true) + .Tooltip("Sets the distance to move the analog stick in the input viewer. Useful for custom " + "input viewers.")); UIWidgets::PaddedSeparator(true, true); } if (ImGui::CollapsingHeader("Additional (\"Right\") Stick")) { // gInputViewer.RightStick.VisibilityMode - CVarCombobox("Right Stick Visibility", CVAR_INPUT_VIEWER("RightStick.VisibilityMode"), stickModeOptions, - ComboboxOptions().Color(THEME_COLOR).DefaultIndex(STICK_MODE_ALWAYS_SHOWN) - .Tooltip("Determines the conditions under which the moving layer of the right stick texture is visible.")); + CVarCombobox( + "Right Stick Visibility", CVAR_INPUT_VIEWER("RightStick.VisibilityMode"), stickModeOptions, + ComboboxOptions() + .Color(THEME_COLOR) + .DefaultIndex(STICK_MODE_ALWAYS_SHOWN) + .Tooltip( + "Determines the conditions under which the moving layer of the right stick texture is visible.")); // gInputViewer.RightStick.OutlineMode - CVarCombobox("Right Stick Outline/Background Visibility", CVAR_INPUT_VIEWER("RightStick.OutlineMode"), stickModeOptions, - ComboboxOptions().Color(THEME_COLOR).DefaultIndex(STICK_MODE_ALWAYS_SHOWN) - .Tooltip("Determines the conditions under which the right stick outline/background texture is visible.")); + CVarCombobox( + "Right Stick Outline/Background Visibility", CVAR_INPUT_VIEWER("RightStick.OutlineMode"), stickModeOptions, + ComboboxOptions() + .Color(THEME_COLOR) + .DefaultIndex(STICK_MODE_ALWAYS_SHOWN) + .Tooltip( + "Determines the conditions under which the right stick outline/background texture is visible.")); // gInputViewer.RightStick.Movement - CVarSliderInt("Right Stick Movement: %dpx", CVAR_INPUT_VIEWER("RightStick.Movement"), IntSliderOptions().Color(THEME_COLOR).Min(0).Max(200).DefaultValue(7).ShowButtons(true) - .Tooltip("Sets the distance to move the right stick in the input viewer. Useful for custom input viewers.")); + CVarSliderInt( + "Right Stick Movement: %dpx", CVAR_INPUT_VIEWER("RightStick.Movement"), + IntSliderOptions() + .Color(THEME_COLOR) + .Min(0) + .Max(200) + .DefaultValue(7) + .ShowButtons(true) + .Tooltip( + "Sets the distance to move the right stick in the input viewer. Useful for custom input viewers.")); UIWidgets::PaddedSeparator(true, true); } if (ImGui::CollapsingHeader("Analog Angle Values")) { // gAnalogAngles - CVarCheckbox("Show Analog Stick Angle Values", CVAR_INPUT_VIEWER("AnalogAngles.Enabled"), CheckboxOptions().Color(THEME_COLOR) - .Tooltip("Displays analog stick angle values in the input viewer")); + CVarCheckbox( + "Show Analog Stick Angle Values", CVAR_INPUT_VIEWER("AnalogAngles.Enabled"), + CheckboxOptions().Color(THEME_COLOR).Tooltip("Displays analog stick angle values in the input viewer")); if (CVarGetInteger(CVAR_INPUT_VIEWER("AnalogAngles.Enabled"), 0)) { // gInputViewer.AnalogAngles.TextColor - CVarColorPicker("Text Color", CVAR_INPUT_VIEWER("AnalogAngles.TextColor"), textColorDefault, - true, ColorPickerRandomButton | ColorPickerResetButton); + CVarColorPicker("Text Color", CVAR_INPUT_VIEWER("AnalogAngles.TextColor"), textColorDefault, true, + ColorPickerRandomButton | ColorPickerResetButton); // gAnalogAngleScale - CVarSliderFloat("Angle Text Scale: %.2f%%", CVAR_INPUT_VIEWER("AnalogAngles.Scale"), - FloatSliderOptions().Color(THEME_COLOR).IsPercentage().Min(0.1f).Max(5.0f).DefaultValue(1.0f).ShowButtons(true)); + CVarSliderFloat("Angle Text Scale: %.2f%%", CVAR_INPUT_VIEWER("AnalogAngles.Scale"), + FloatSliderOptions() + .Color(THEME_COLOR) + .IsPercentage() + .Min(0.1f) + .Max(5.0f) + .DefaultValue(1.0f) + .ShowButtons(true)); // gInputViewer.AnalogAngles.Offset - CVarSliderInt("Angle Text Offset: %dpx", CVAR_INPUT_VIEWER("AnalogAngles.Offset"), IntSliderOptions().Color(THEME_COLOR).Min(0).Max(400).DefaultValue(0).ShowButtons(true) - .Tooltip("Sets the distance to move the right stick in the input viewer. Useful for custom input viewers.")); + CVarSliderInt("Angle Text Offset: %dpx", CVAR_INPUT_VIEWER("AnalogAngles.Offset"), + IntSliderOptions() + .Color(THEME_COLOR) + .Min(0) + .Max(400) + .DefaultValue(0) + .ShowButtons(true) + .Tooltip("Sets the distance to move the right stick in the input viewer. Useful for " + "custom input viewers.")); UIWidgets::PaddedSeparator(true, true); // gInputViewer.AnalogAngles.Range1.Enabled - CVarCheckbox("Highlight ESS Position", CVAR_INPUT_VIEWER("AnalogAngles.Range1.Enabled"), CheckboxOptions().Color(THEME_COLOR) - .Tooltip("Highlights the angle value text when the analog stick is in ESS position (on flat ground)")); + CVarCheckbox( + "Highlight ESS Position", CVAR_INPUT_VIEWER("AnalogAngles.Range1.Enabled"), + CheckboxOptions() + .Color(THEME_COLOR) + .Tooltip( + "Highlights the angle value text when the analog stick is in ESS position (on flat ground)")); if (CVarGetInteger(CVAR_INPUT_VIEWER("AnalogAngles.Range1.Enabled"), 0)) { // gInputViewer.AnalogAngles.Range1.Color - CVarColorPicker("ESS Color", CVAR_INPUT_VIEWER("AnalogAngles.Range1.Color"), range1ColorDefault, - true, ColorPickerRandomButton | ColorPickerResetButton); + CVarColorPicker("ESS Color", CVAR_INPUT_VIEWER("AnalogAngles.Range1.Color"), range1ColorDefault, true, + ColorPickerRandomButton | ColorPickerResetButton); } UIWidgets::PaddedSeparator(true, true); // gInputViewer.AnalogAngles.Range2.Enabled - CVarCheckbox("Highlight Walking Speed Angles", CVAR_INPUT_VIEWER("AnalogAngles.Range2.Enabled"), CheckboxOptions().Color(THEME_COLOR) - .Tooltip("Highlights the angle value text when the analog stick is at an angle that would " - "produce a walking speed (on flat ground)\n\n" - "Useful for 1.0 Empty Jumpslash Quick Put Away")); + CVarCheckbox("Highlight Walking Speed Angles", CVAR_INPUT_VIEWER("AnalogAngles.Range2.Enabled"), + CheckboxOptions() + .Color(THEME_COLOR) + .Tooltip("Highlights the angle value text when the analog stick is at an angle that would " + "produce a walking speed (on flat ground)\n\n" + "Useful for 1.0 Empty Jumpslash Quick Put Away")); if (CVarGetInteger(CVAR_INPUT_VIEWER("AnalogAngles.Range2.Enabled"), 0)) { // gInputViewer.AnalogAngles.Range2.Color - CVarColorPicker("Walking Speed Color", CVAR_INPUT_VIEWER("AnalogAngles.Range2.Color"), range2ColorDefault, - true, ColorPickerRandomButton | ColorPickerResetButton); + CVarColorPicker("Walking Speed Color", CVAR_INPUT_VIEWER("AnalogAngles.Range2.Color"), + range2ColorDefault, true, ColorPickerRandomButton | ColorPickerResetButton); } } } diff --git a/soh/soh/Enhancements/controls/InputViewer.h b/soh/soh/Enhancements/controls/InputViewer.h index a4b1cc44f..c370a4225 100644 --- a/soh/soh/Enhancements/controls/InputViewer.h +++ b/soh/soh/Enhancements/controls/InputViewer.h @@ -18,28 +18,28 @@ typedef enum { } StickMode; class InputViewer : public Ship::GuiWindow { -public: + public: using GuiWindow::GuiWindow; void Draw() override; - void InitElement() override {}; + void InitElement() override{}; void DrawElement() override; - void UpdateElement() override {}; + void UpdateElement() override{}; InputViewer(); ~InputViewer(); - - private: - void RenderButton(std::string btn, std::string btnOutline, int state, ImVec2 size, int outlineMode); + + private: + void RenderButton(std::string btn, std::string btnOutline, int state, ImVec2 size, int outlineMode); }; class InputViewerSettingsWindow : public Ship::GuiWindow { -public: + public: using GuiWindow::GuiWindow; - void InitElement() override {}; + void InitElement() override{}; void DrawElement() override; - void UpdateElement() override {}; + void UpdateElement() override{}; InputViewerSettingsWindow(); ~InputViewerSettingsWindow(); diff --git a/soh/soh/Enhancements/controls/Mouse.cpp b/soh/soh/Enhancements/controls/Mouse.cpp index ae3842a1a..4282c3718 100644 --- a/soh/soh/Enhancements/controls/Mouse.cpp +++ b/soh/soh/Enhancements/controls/Mouse.cpp @@ -42,10 +42,12 @@ void Mouse_HandleThirdPerson(f32* newCamX, f32* newCamY) { void Mouse_HandleFirstPerson(Player* player) { f32 xAxisMulti = CVarGetFloat(CVAR_SETTING("FirstPersonCameraSensitivity.X"), 1.0f); f32 yAxisMulti = CVarGetFloat(CVAR_SETTING("FirstPersonCameraSensitivity.Y"), 1.0f); - s8 invertXAxisMulti = ((CVarGetInteger(CVAR_SETTING("Controls.InvertAimingXAxis"), 0) - && !CVarGetInteger(CVAR_ENHANCEMENT("MirroredWorld"), 0)) - || (!CVarGetInteger(CVAR_SETTING("Controls.InvertAimingXAxis"), 0) - && CVarGetInteger(CVAR_ENHANCEMENT("MirroredWorld"), 0))) ? -1 : 1; + s8 invertXAxisMulti = ((CVarGetInteger(CVAR_SETTING("Controls.InvertAimingXAxis"), 0) && + !CVarGetInteger(CVAR_ENHANCEMENT("MirroredWorld"), 0)) || + (!CVarGetInteger(CVAR_SETTING("Controls.InvertAimingXAxis"), 0) && + CVarGetInteger(CVAR_ENHANCEMENT("MirroredWorld"), 0))) + ? -1 + : 1; s8 invertYAxisMulti = CVarGetInteger(CVAR_SETTING("Controls.InvertAimingYAxis"), 1) ? 1 : -1; if (MOUSE_ENABLED) { player->actor.focus.rot.y -= mouseCoordRel.x * 6.0f * xAxisMulti * invertXAxisMulti; @@ -57,7 +59,7 @@ void Mouse_RecenterCursor() { u32 width = GetWindow()->GetWidth(); u32 height = GetWindow()->GetHeight(); if (MOUSE_ENABLED) { - GetWindow()->SetMousePos({(s32) (width/2), (s32) (height/2)}); + GetWindow()->SetMousePos({ (s32)(width / 2), (s32)(height / 2) }); } } @@ -67,7 +69,8 @@ void Mouse_HandleShield(f32* sp50, f32* sp54) { s32 height = GetWindow()->GetHeight(); f32 xBound = 7200 / ((f32)width / 2); f32 yBound = 6000 / ((f32)height / 2); - *sp50 += (mouseCoord.x - (width / 2)) * xBound * (CVarGetInteger(CVAR_ENHANCEMENT("MirroredWorld"), 0) ? 1 : -1); + *sp50 += + (mouseCoord.x - (width / 2)) * xBound * (CVarGetInteger(CVAR_ENHANCEMENT("MirroredWorld"), 0) ? 1 : -1); *sp54 += (mouseCoord.y - (height / 2)) * yBound; *sp50 = CLAMP(*sp50, -7200, 7200); *sp54 = CLAMP(*sp54, -6000, 6000); @@ -142,7 +145,7 @@ void Mouse_RegisterUpdateQuickspinCount() { } void Mouse_RegisterHandleQuickspin() { - REGISTER_VB_SHOULD(VB_SHOULD_QUICKSPIN, { Mouse_HandleQuickspin(should, va_arg(args, s8*), va_arg(args, s8*)); } ); + REGISTER_VB_SHOULD(VB_SHOULD_QUICKSPIN, { Mouse_HandleQuickspin(should, va_arg(args, s8*), va_arg(args, s8*)); }); } static RegisterShipInitFunc initFunc_shieldRecenter(Mouse_RegisterRecenterCursorOnShield, { CVAR_ENABLE_MOUSE_NAME }); @@ -150,4 +153,4 @@ static RegisterShipInitFunc initFunc_firstPerson(Mouse_RegisterHandleFirstPerson static RegisterShipInitFunc initFunc_quickspinCount(Mouse_RegisterUpdateQuickspinCount, { CVAR_ENABLE_MOUSE_NAME }); static RegisterShipInitFunc initFunc_quickspin(Mouse_RegisterHandleQuickspin, { CVAR_ENABLE_MOUSE_NAME }); static RegisterShipInitFunc initFunc_shieldMove(Mouse_RegisterHandleShield, { CVAR_ENABLE_MOUSE_NAME }); -} //extern "C" +} // extern "C" diff --git a/soh/soh/Enhancements/controls/Mouse.h b/soh/soh/Enhancements/controls/Mouse.h index 38d84e078..2ab954e47 100644 --- a/soh/soh/Enhancements/controls/Mouse.h +++ b/soh/soh/Enhancements/controls/Mouse.h @@ -18,8 +18,8 @@ void Mouse_HandleShield(f32* sp50, f32* sp54); bool Mouse_HandleQuickspin(bool* should, s8* iter2, s8* sp3C); void Mouse_UpdateQuickspinCount(); #ifdef __cplusplus -}; //extern "C" +}; // extern "C" #endif -//MOUSE_H +// MOUSE_H #endif diff --git a/soh/soh/Enhancements/controls/SohInputEditorWindow.cpp b/soh/soh/Enhancements/controls/SohInputEditorWindow.cpp index dcef762cf..3f77d1ed4 100644 --- a/soh/soh/Enhancements/controls/SohInputEditorWindow.cpp +++ b/soh/soh/Enhancements/controls/SohInputEditorWindow.cpp @@ -26,29 +26,25 @@ void SohInputEditorWindow::InitElement() { mButtonsBitmasks = { BTN_A, BTN_B, BTN_START, BTN_L, BTN_R, BTN_Z, BTN_CUP, BTN_CDOWN, BTN_CLEFT, BTN_CRIGHT }; mDpadBitmasks = { BTN_DUP, BTN_DDOWN, BTN_DLEFT, BTN_DRIGHT }; mModifierButtonsBitmasks = { BTN_CUSTOM_MODIFIER1, BTN_CUSTOM_MODIFIER2 }; - mCustomOcarinaButtonsBitmasks = { - BTN_CUSTOM_OCARINA_NOTE_D4, - BTN_CUSTOM_OCARINA_NOTE_F4, - BTN_CUSTOM_OCARINA_NOTE_A4, - BTN_CUSTOM_OCARINA_NOTE_B4, - BTN_CUSTOM_OCARINA_NOTE_D5 - }; + mCustomOcarinaButtonsBitmasks = { BTN_CUSTOM_OCARINA_NOTE_D4, BTN_CUSTOM_OCARINA_NOTE_F4, + BTN_CUSTOM_OCARINA_NOTE_A4, BTN_CUSTOM_OCARINA_NOTE_B4, + BTN_CUSTOM_OCARINA_NOTE_D5 }; - addButtonName(BTN_A, "A"); - addButtonName(BTN_B, "B"); - addButtonName(BTN_CUP, "C Up"); - addButtonName(BTN_CDOWN, "C Down"); - addButtonName(BTN_CLEFT, "C Left"); - addButtonName(BTN_CRIGHT, "C Right"); - addButtonName(BTN_L, "L"); - addButtonName(BTN_Z, "Z"); - addButtonName(BTN_R, "R"); - addButtonName(BTN_START, "Start"); - addButtonName(BTN_DUP, "D-pad up"); - addButtonName(BTN_DDOWN, "D-pad down"); - addButtonName(BTN_DLEFT, "D-pad left"); - addButtonName(BTN_DRIGHT, "D-pad right"); - addButtonName(0, "None"); + addButtonName(BTN_A, "A"); + addButtonName(BTN_B, "B"); + addButtonName(BTN_CUP, "C Up"); + addButtonName(BTN_CDOWN, "C Down"); + addButtonName(BTN_CLEFT, "C Left"); + addButtonName(BTN_CRIGHT, "C Right"); + addButtonName(BTN_L, "L"); + addButtonName(BTN_Z, "Z"); + addButtonName(BTN_R, "R"); + addButtonName(BTN_START, "Start"); + addButtonName(BTN_DUP, "D-pad up"); + addButtonName(BTN_DDOWN, "D-pad down"); + addButtonName(BTN_DLEFT, "D-pad left"); + addButtonName(BTN_DRIGHT, "D-pad right"); + addButtonName(0, "None"); } #define INPUT_EDITOR_WINDOW_GAME_INPUT_BLOCK_ID 95237929 @@ -191,7 +187,7 @@ void SohInputEditorWindow::DrawAnalogPreview(const char* label, ImVec2 stick, fl #define BUTTON_COLOR_GAMEPAD_PURPLE_HOVERED ImVec4(0.431f, 0.369f, 0.706f, 1.0f) void SohInputEditorWindow::GetButtonColorsForDeviceType(Ship::PhysicalDeviceType lusIndex, ImVec4& buttonColor, - ImVec4& buttonHoveredColor) { + ImVec4& buttonHoveredColor) { switch (lusIndex) { case Ship::PhysicalDeviceType::Keyboard: buttonColor = BUTTON_COLOR_KEYBOARD_BEIGE; @@ -669,8 +665,8 @@ void SohInputEditorWindow::DrawStickSection(uint8_t port, uint8_t stick, int32_t } ImGui::SameLine(0.0f, 0.0f); ImGui::SetNextItemWidth(SCALE_IMGUI_SIZE(160.0f)); - if (ImGui::SliderInt(StringHelper::Sprintf("##Sensitivity%d", id).c_str(), &sensitivityPercentage, 0, 200, "%d%%", - ImGuiSliderFlags_AlwaysClamp)) { + if (ImGui::SliderInt(StringHelper::Sprintf("##Sensitivity%d", id).c_str(), &sensitivityPercentage, 0, 200, + "%d%%", ImGuiSliderFlags_AlwaysClamp)) { controllerStick->SetSensitivity(sensitivityPercentage); } ImGui::SameLine(0.0f, 0.0f); @@ -1070,12 +1066,16 @@ void SohInputEditorWindow::DrawLEDSection(uint8_t port) { "Original Tunic Colors", "Cosmetics Tunic Colors", "Health Colors", "Original Navi Targeting Colors", "Cosmetics Navi Targeting Colors", "Custom" }; - CVarCombobox("Source", CVAR_SETTING("LEDColorSource"), ledSources, UIWidgets::ComboboxOptions().Color(THEME_COLOR).DefaultIndex(LED_SOURCE_TUNIC_ORIGINAL) - .Tooltip("Health\n- Red when health critical (13-20% depending on max health)\n- Yellow when " - "health < 40%. Green otherwise.\n\n" - "Tunics: colors will mirror currently equipped tunic, whether original or the current " - "values in Cosmetics Editor.\n\n" - "Custom: single, solid color")); + CVarCombobox( + "Source", CVAR_SETTING("LEDColorSource"), ledSources, + UIWidgets::ComboboxOptions() + .Color(THEME_COLOR) + .DefaultIndex(LED_SOURCE_TUNIC_ORIGINAL) + .Tooltip("Health\n- Red when health critical (13-20% depending on max health)\n- Yellow when " + "health < 40%. Green otherwise.\n\n" + "Tunics: colors will mirror currently equipped tunic, whether original or the current " + "values in Cosmetics Editor.\n\n" + "Custom: single, solid color")); if (CVarGetInteger(CVAR_SETTING("LEDColorSource"), 1) == LED_SOURCE_CUSTOM) { UIWidgets::Spacer(3); auto port1Color = CVarGetColor24(CVAR_SETTING("LEDPort1Color"), { 255, 255, 255 }); @@ -1094,12 +1094,21 @@ void SohInputEditorWindow::DrawLEDSection(uint8_t port) { ImGui::Text("Custom Color"); } CVarSliderFloat("Brightness: %.1f %%", CVAR_SETTING("LEDBrightness"), - FloatSliderOptions().IsPercentage().Min(0.0f).Max(1.0f).DefaultValue(1.0f).ShowButtons(true) - .Tooltip("Sets the brightness of controller LEDs. 0% brightness = LEDs off.")); - CVarCheckbox("Critical Health Override", CVAR_SETTING("LEDCriticalOverride"), - CheckboxOptions({{ .disabled = CVarGetInteger(CVAR_SETTING("LEDColorSource"), LED_SOURCE_TUNIC_ORIGINAL) == LED_SOURCE_HEALTH, - .disabledTooltip = "Override redundant for health source."}}).DefaultValue(true) - .Tooltip("Shows red color when health is critical, otherwise displays according to color source.")); + FloatSliderOptions() + .IsPercentage() + .Min(0.0f) + .Max(1.0f) + .DefaultValue(1.0f) + .ShowButtons(true) + .Tooltip("Sets the brightness of controller LEDs. 0% brightness = LEDs off.")); + CVarCheckbox( + "Critical Health Override", CVAR_SETTING("LEDCriticalOverride"), + CheckboxOptions({ { .disabled = CVarGetInteger(CVAR_SETTING("LEDColorSource"), + LED_SOURCE_TUNIC_ORIGINAL) == LED_SOURCE_HEALTH, + .disabledTooltip = "Override redundant for health source." } }) + .DefaultValue(true) + .Tooltip( + "Shows red color when health is critical, otherwise displays according to color source.")); } ImGui::TreePop(); } @@ -1234,38 +1243,35 @@ void SohInputEditorWindow::DrawGyroSection(uint8_t port) { } } -const ImGuiTableFlags PANEL_TABLE_FLAGS = - ImGuiTableFlags_BordersH | - ImGuiTableFlags_BordersV; +const ImGuiTableFlags PANEL_TABLE_FLAGS = ImGuiTableFlags_BordersH | ImGuiTableFlags_BordersV; const ImGuiTableColumnFlags PANEL_TABLE_COLUMN_FLAGS = - ImGuiTableColumnFlags_IndentEnable | - ImGuiTableColumnFlags_NoSort; + ImGuiTableColumnFlags_IndentEnable | ImGuiTableColumnFlags_NoSort; namespace TableHelper { - void InitHeader(bool has_header = true) { - if (has_header) { - ImGui::TableHeadersRow(); - } - ImGui::TableNextRow(); - ImGui::TableNextColumn(); - ImGui::AlignTextToFramePadding(); //This is to adjust Vertical pos of item in a cell to be normlized. - ImGui::PushItemWidth(ImGui::GetContentRegionAvail().x); - } - - void NextCol() { - ImGui::TableNextColumn(); - ImGui::AlignTextToFramePadding(); - ImGui::PushItemWidth(ImGui::GetContentRegionAvail().x); - } - - void NextLine() { - ImGui::TableNextRow(); - ImGui::TableNextColumn(); - ImGui::AlignTextToFramePadding(); - ImGui::PushItemWidth(ImGui::GetContentRegionAvail().x); +void InitHeader(bool has_header = true) { + if (has_header) { + ImGui::TableHeadersRow(); } + ImGui::TableNextRow(); + ImGui::TableNextColumn(); + ImGui::AlignTextToFramePadding(); // This is to adjust Vertical pos of item in a cell to be normlized. + ImGui::PushItemWidth(ImGui::GetContentRegionAvail().x); } +void NextCol() { + ImGui::TableNextColumn(); + ImGui::AlignTextToFramePadding(); + ImGui::PushItemWidth(ImGui::GetContentRegionAvail().x); +} + +void NextLine() { + ImGui::TableNextRow(); + ImGui::TableNextColumn(); + ImGui::AlignTextToFramePadding(); + ImGui::PushItemWidth(ImGui::GetContentRegionAvail().x); +} +} // namespace TableHelper + void SohInputEditorWindow::addButtonName(N64ButtonMask mask, const char* name) { buttons.push_back(std::make_pair(mask, name)); buttonNames[mask] = std::prev(buttons.end()); @@ -1292,7 +1298,7 @@ void SohInputEditorWindow::DrawMapping(CustomButtonMap& mapping, float labelWidt ImGui::SetCursorPosY(cursorPos.y); ImGui::SetNextItemWidth(ImGui::GetFontSize() * 8); - if (ImGui::BeginCombo(StringHelper::Sprintf("##%s", mapping.cVarName).c_str(), preview)) { + if (ImGui::BeginCombo(StringHelper::Sprintf("##%s", mapping.cVarName).c_str(), preview)) { for (auto i = buttons.begin(); i != buttons.end(); i++) { if ((i->first & excludedButtons) != 0) { continue; @@ -1309,7 +1315,7 @@ void SohInputEditorWindow::DrawMapping(CustomButtonMap& mapping, float labelWidt void SohInputEditorWindow::DrawOcarinaControlPanel() { ImVec2 cursor = ImGui::GetCursorPos(); ImGui::SetCursorPos(ImVec2(cursor.x, cursor.y + 5)); - + CheckboxOptions checkOpt = CheckboxOptions().Color(THEME_COLOR); CVarCheckbox("Dpad Ocarina Playback", CVAR_SETTING("CustomOcarina.Dpad"), checkOpt); CVarCheckbox("Right Stick Ocarina Playback", CVAR_SETTING("CustomOcarina.RightStick"), checkOpt); @@ -1344,29 +1350,47 @@ void SohInputEditorWindow::DrawOcarinaControlPanel() { void SohInputEditorWindow::DrawCameraControlPanel() { ImVec2 cursor = ImGui::GetCursorPos(); ImGui::SetCursorPos(ImVec2(cursor.x + 5, cursor.y + 5)); - CVarCheckbox("Enable Mouse Controls", CVAR_SETTING("EnableMouse"), CheckboxOptions().Color(THEME_COLOR) - .Tooltip("Allows for using the mouse to control the camera (must enable Free Look), " - "aim with the shield, and perform quickspin attacks (quickly rotate the mouse then press B)")); + CVarCheckbox( + "Enable Mouse Controls", CVAR_SETTING("EnableMouse"), + CheckboxOptions() + .Color(THEME_COLOR) + .Tooltip("Allows for using the mouse to control the camera (must enable Free Look), " + "aim with the shield, and perform quickspin attacks (quickly rotate the mouse then press B)")); Ship::GuiWindow::BeginGroupPanel("Aiming/First-Person Camera", ImGui::GetContentRegionAvail()); - CVarCheckbox("Right Stick Aiming", CVAR_SETTING("Controls.RightStickAim"), CheckboxOptions().Color(THEME_COLOR) - .Tooltip("Allows for aiming with the right stick in:\n-First-Person/C-Up view\n-Weapon Aiming")); + CVarCheckbox("Right Stick Aiming", CVAR_SETTING("Controls.RightStickAim"), + CheckboxOptions() + .Color(THEME_COLOR) + .Tooltip("Allows for aiming with the right stick in:\n-First-Person/C-Up view\n-Weapon Aiming")); if (CVarGetInteger(CVAR_SETTING("Controls.RightStickAim"), 0)) { - CVarCheckbox("Allow moving while in first person mode", CVAR_SETTING("MoveInFirstPerson"), CheckboxOptions().Color(THEME_COLOR) - .Tooltip("Changes the left stick to move the player while in first person mode")); + CVarCheckbox("Allow moving while in first person mode", CVAR_SETTING("MoveInFirstPerson"), + CheckboxOptions() + .Color(THEME_COLOR) + .Tooltip("Changes the left stick to move the player while in first person mode")); } - CVarCheckbox("Invert Aiming X Axis", CVAR_SETTING("Controls.InvertAimingXAxis"), CheckboxOptions().Color(THEME_COLOR) - .Tooltip("Inverts the Camera X Axis in:\n-First-Person/C-Up view\n-Weapon Aiming")); - CVarCheckbox("Invert Aiming Y Axis", CVAR_SETTING("Controls.InvertAimingYAxis"), CheckboxOptions().Color(THEME_COLOR).DefaultValue(true) - .Tooltip("Inverts the Camera Y Axis in:\n-First-Person/C-Up view\n-Weapon Aiming")); - CVarCheckbox("Invert Shield Aiming X Axis", CVAR_SETTING("Controls.InvertShieldAimingXAxis"), CheckboxOptions().Color(THEME_COLOR).DefaultValue(true) - .Tooltip("Inverts the Shield Aiming X Axis")); - CVarCheckbox("Invert Shield Aiming Y Axis", CVAR_SETTING("Controls.InvertShieldAimingYAxis"), CheckboxOptions().Color(THEME_COLOR) - .Tooltip("Inverts the Shield Aiming Y Axis")); - CVarCheckbox("Invert Z-Weapon Aiming Y Axis", CVAR_SETTING("Controls.InvertZAimingYAxis"), CheckboxOptions().Color(THEME_COLOR).DefaultValue(true) - .Tooltip("Inverts the Camera Y Axis in:\n-Z-Weapon Aiming")); - CVarCheckbox("Disable Auto-Centering in First-Person View", CVAR_SETTING("DisableFirstPersonAutoCenterView"), CheckboxOptions().Color(THEME_COLOR) - .Tooltip("Prevents the C-Up view from auto-centering, allowing for Gyro Aiming")); - if (CVarCheckbox("Enable Custom Aiming/First-Person sensitivity", CVAR_SETTING("FirstPersonCameraSensitivity.Enabled"), CheckboxOptions().Color(THEME_COLOR))) { + CVarCheckbox("Invert Aiming X Axis", CVAR_SETTING("Controls.InvertAimingXAxis"), + CheckboxOptions() + .Color(THEME_COLOR) + .Tooltip("Inverts the Camera X Axis in:\n-First-Person/C-Up view\n-Weapon Aiming")); + CVarCheckbox("Invert Aiming Y Axis", CVAR_SETTING("Controls.InvertAimingYAxis"), + CheckboxOptions() + .Color(THEME_COLOR) + .DefaultValue(true) + .Tooltip("Inverts the Camera Y Axis in:\n-First-Person/C-Up view\n-Weapon Aiming")); + CVarCheckbox("Invert Shield Aiming X Axis", CVAR_SETTING("Controls.InvertShieldAimingXAxis"), + CheckboxOptions().Color(THEME_COLOR).DefaultValue(true).Tooltip("Inverts the Shield Aiming X Axis")); + CVarCheckbox("Invert Shield Aiming Y Axis", CVAR_SETTING("Controls.InvertShieldAimingYAxis"), + CheckboxOptions().Color(THEME_COLOR).Tooltip("Inverts the Shield Aiming Y Axis")); + CVarCheckbox("Invert Z-Weapon Aiming Y Axis", CVAR_SETTING("Controls.InvertZAimingYAxis"), + CheckboxOptions() + .Color(THEME_COLOR) + .DefaultValue(true) + .Tooltip("Inverts the Camera Y Axis in:\n-Z-Weapon Aiming")); + CVarCheckbox("Disable Auto-Centering in First-Person View", CVAR_SETTING("DisableFirstPersonAutoCenterView"), + CheckboxOptions() + .Color(THEME_COLOR) + .Tooltip("Prevents the C-Up view from auto-centering, allowing for Gyro Aiming")); + if (CVarCheckbox("Enable Custom Aiming/First-Person sensitivity", + CVAR_SETTING("FirstPersonCameraSensitivity.Enabled"), CheckboxOptions().Color(THEME_COLOR))) { if (!CVarGetInteger(CVAR_SETTING("FirstPersonCameraSensitivity.Enabled"), 0)) { CVarClear(CVAR_SETTING("FirstPersonCameraSensitivity.X")); CVarClear(CVAR_SETTING("FirstPersonCameraSensitivity.Y")); @@ -1374,10 +1398,24 @@ void SohInputEditorWindow::DrawCameraControlPanel() { } } if (CVarGetInteger(CVAR_SETTING("FirstPersonCameraSensitivity.Enabled"), 0)) { - CVarSliderFloat("Aiming/First-Person Horizontal Sensitivity: %.0f %%", CVAR_SETTING("FirstPersonCameraSensitivity.X"), - FloatSliderOptions().Color(THEME_COLOR).IsPercentage().Min(0.01f).Max(5.0f).DefaultValue(1.0f).ShowButtons(true)); - CVarSliderFloat("Aiming/First-Person Vertical Sensitivity: %.0f %%", CVAR_SETTING("FirstPersonCameraSensitivity.Y"), - FloatSliderOptions().Color(THEME_COLOR).IsPercentage().Min(0.01f).Max(5.0f).DefaultValue(1.0f).ShowButtons(true)); + CVarSliderFloat("Aiming/First-Person Horizontal Sensitivity: %.0f %%", + CVAR_SETTING("FirstPersonCameraSensitivity.X"), + FloatSliderOptions() + .Color(THEME_COLOR) + .IsPercentage() + .Min(0.01f) + .Max(5.0f) + .DefaultValue(1.0f) + .ShowButtons(true)); + CVarSliderFloat("Aiming/First-Person Vertical Sensitivity: %.0f %%", + CVAR_SETTING("FirstPersonCameraSensitivity.Y"), + FloatSliderOptions() + .Color(THEME_COLOR) + .IsPercentage() + .Min(0.01f) + .Max(5.0f) + .DefaultValue(1.0f) + .ShowButtons(true)); } Ship::GuiWindow::EndGroupPanel(0); @@ -1385,19 +1423,37 @@ void SohInputEditorWindow::DrawCameraControlPanel() { ImGui::SetCursorPos(ImVec2(cursor.x + 5, cursor.y + 5)); Ship::GuiWindow::BeginGroupPanel("Third-Person Camera", ImGui::GetContentRegionAvail()); - CVarCheckbox("Free Look", CVAR_SETTING("FreeLook.Enabled"), CheckboxOptions().Color(THEME_COLOR) - .Tooltip("Enables free look camera control\nNote: You must remap C buttons off of the right stick in the " - "controller config menu, and map the camera stick to the right stick.")); - CVarCheckbox("Invert Camera X Axis", CVAR_SETTING("FreeLook.InvertXAxis"), CheckboxOptions().Color(THEME_COLOR) - .Tooltip("Inverts the Camera X Axis in:\n-Free look")); - CVarCheckbox("Invert Camera Y Axis", CVAR_SETTING("FreeLook.InvertYAxis"), CheckboxOptions().Color(THEME_COLOR).DefaultValue(true) - .Tooltip("Inverts the Camera Y Axis in:\n-Free look")); - CVarSliderFloat("Third-Person Horizontal Sensitivity: %.0f %%", CVAR_SETTING("FreeLook.CameraSensitivity.X"), - FloatSliderOptions().Color(THEME_COLOR).IsPercentage().Min(0.01f).Max(5.0f).DefaultValue(1.0f).ShowButtons(true)); - CVarSliderFloat("Third-Person Vertical Sensitivity: %.0f %%", CVAR_SETTING("FreeLook.CameraSensitivity.Y"), - FloatSliderOptions().Color(THEME_COLOR).IsPercentage().Min(0.01f).Max(5.0f).DefaultValue(1.0f).ShowButtons(true)); - CVarSliderInt("Camera Distance: %d", CVAR_SETTING("FreeLook.MaxCameraDistance"), IntSliderOptions().Color(THEME_COLOR).Min(100).Max(900).DefaultValue(185).ShowButtons(true)); - CVarSliderInt("Camera Transition Speed: %d", CVAR_SETTING("FreeLook.TransitionSpeed"), IntSliderOptions().Color(THEME_COLOR).Min(0).Max(900).DefaultValue(25).ShowButtons(true)); + CVarCheckbox( + "Free Look", CVAR_SETTING("FreeLook.Enabled"), + CheckboxOptions() + .Color(THEME_COLOR) + .Tooltip("Enables free look camera control\nNote: You must remap C buttons off of the right stick in the " + "controller config menu, and map the camera stick to the right stick.")); + CVarCheckbox("Invert Camera X Axis", CVAR_SETTING("FreeLook.InvertXAxis"), + CheckboxOptions().Color(THEME_COLOR).Tooltip("Inverts the Camera X Axis in:\n-Free look")); + CVarCheckbox( + "Invert Camera Y Axis", CVAR_SETTING("FreeLook.InvertYAxis"), + CheckboxOptions().Color(THEME_COLOR).DefaultValue(true).Tooltip("Inverts the Camera Y Axis in:\n-Free look")); + CVarSliderFloat("Third-Person Horizontal Sensitivity: %.0f %%", CVAR_SETTING("FreeLook.CameraSensitivity.X"), + FloatSliderOptions() + .Color(THEME_COLOR) + .IsPercentage() + .Min(0.01f) + .Max(5.0f) + .DefaultValue(1.0f) + .ShowButtons(true)); + CVarSliderFloat("Third-Person Vertical Sensitivity: %.0f %%", CVAR_SETTING("FreeLook.CameraSensitivity.Y"), + FloatSliderOptions() + .Color(THEME_COLOR) + .IsPercentage() + .Min(0.01f) + .Max(5.0f) + .DefaultValue(1.0f) + .ShowButtons(true)); + CVarSliderInt("Camera Distance: %d", CVAR_SETTING("FreeLook.MaxCameraDistance"), + IntSliderOptions().Color(THEME_COLOR).Min(100).Max(900).DefaultValue(185).ShowButtons(true)); + CVarSliderInt("Camera Transition Speed: %d", CVAR_SETTING("FreeLook.TransitionSpeed"), + IntSliderOptions().Color(THEME_COLOR).Min(0).Max(900).DefaultValue(25).ShowButtons(true)); Ship::GuiWindow::EndGroupPanel(0); } @@ -1405,17 +1461,26 @@ void SohInputEditorWindow::DrawDpadControlPanel() { ImVec2 cursor = ImGui::GetCursorPos(); ImGui::SetCursorPos(ImVec2(cursor.x + 5, cursor.y + 5)); Ship::GuiWindow::BeginGroupPanel("D-Pad Options", ImGui::GetContentRegionAvail()); - CVarCheckbox("D-pad Support on Pause Screen", CVAR_SETTING("DPadOnPause"), CheckboxOptions().Color(THEME_COLOR) - .Tooltip("Navigate Pause with the D-pad\nIf used with \"D-pad as Equip Items\", you must hold C-Up to equip instead of navigate")); - CVarCheckbox("D-pad Support in Text Boxes", CVAR_SETTING("DpadInText"), CheckboxOptions().Color(THEME_COLOR) - .Tooltip("Navigate choices in text boxes, shop item selection, and the file select / name entry screens with the D-pad")); + CVarCheckbox("D-pad Support on Pause Screen", CVAR_SETTING("DPadOnPause"), + CheckboxOptions() + .Color(THEME_COLOR) + .Tooltip("Navigate Pause with the D-pad\nIf used with \"D-pad as Equip Items\", you must hold " + "C-Up to equip instead of navigate")); + CVarCheckbox("D-pad Support in Text Boxes", CVAR_SETTING("DpadInText"), + CheckboxOptions() + .Color(THEME_COLOR) + .Tooltip("Navigate choices in text boxes, shop item selection, and the file select / name entry " + "screens with the D-pad")); if (!CVarGetInteger(CVAR_SETTING("DPadOnPause"), 0) && !CVarGetInteger(CVAR_SETTING("DpadInText"), 0)) { ImGui::BeginDisabled(); } - CVarCheckbox("D-pad hold change", CVAR_SETTING("DpadHoldChange"), CheckboxOptions().Color(THEME_COLOR).DefaultValue(true) - .Tooltip("The cursor will only move a single space no matter how long a D-pad direction is held")); + CVarCheckbox("D-pad hold change", CVAR_SETTING("DpadHoldChange"), + CheckboxOptions() + .Color(THEME_COLOR) + .DefaultValue(true) + .Tooltip("The cursor will only move a single space no matter how long a D-pad direction is held")); if (!CVarGetInteger(CVAR_SETTING("DPadOnPause"), 0) && !CVarGetInteger(CVAR_SETTING("DpadInText"), 0)) { ImGui::EndDisabled(); @@ -1457,7 +1522,7 @@ void SohInputEditorWindow::DrawDeviceToggles(uint8_t portIndex) { ImGui::PushStyleColor(ImGuiCol_ButtonHovered, buttonHoveredColor); auto notIgnored = !connectedDeviceManager->PortIsIgnoringInstanceId(portIndex, instanceId); ImGui::PopItemFlag(); - if(ImGui::Checkbox(StringHelper::Sprintf("###instanceId_%d", instanceId).c_str(), ¬Ignored)) { + if (ImGui::Checkbox(StringHelper::Sprintf("###instanceId_%d", instanceId).c_str(), ¬Ignored)) { if (notIgnored) { connectedDeviceManager->UnignoreInstanceIdForPort(portIndex, instanceId); } else { @@ -1536,24 +1601,52 @@ void SohInputEditorWindow::DrawLinkTab() { DrawButtonLine("M2", portIndex, BTN_CUSTOM_MODIFIER2); ImGui::BeginDisabled(CVarGetInteger(CVAR_SETTING("DisableChanges"), 0)); - CVarCheckbox("Enable speed modifiers", CVAR_SETTING("WalkModifier.Enabled"), CheckboxOptions().Color(THEME_COLOR) - .Tooltip("Hold the assigned button to change the maximum walking or swimming speed")); + CVarCheckbox("Enable speed modifiers", CVAR_SETTING("WalkModifier.Enabled"), + CheckboxOptions() + .Color(THEME_COLOR) + .Tooltip("Hold the assigned button to change the maximum walking or swimming speed")); if (CVarGetInteger(CVAR_SETTING("WalkModifier.Enabled"), 0)) { UIWidgets::Spacer(5); Ship::GuiWindow::BeginGroupPanel("Speed Modifier", ImGui::GetContentRegionAvail()); - CVarCheckbox("Toggle modifier instead of holding", CVAR_SETTING("WalkModifier.SpeedToggle"), CheckboxOptions().Color(THEME_COLOR)); + CVarCheckbox("Toggle modifier instead of holding", CVAR_SETTING("WalkModifier.SpeedToggle"), + CheckboxOptions().Color(THEME_COLOR)); Ship::GuiWindow::BeginGroupPanel("Walk Modifier", ImGui::GetContentRegionAvail()); - CVarCheckbox("Don't affect jump distance/velocity", CVAR_SETTING("WalkModifier.DoesntChangeJump"), CheckboxOptions().Color(THEME_COLOR)); - CVarSliderFloat("Walk Modifier 1: %.0f %%", CVAR_SETTING("WalkModifier.Mapping1"), - FloatSliderOptions().Color(THEME_COLOR).IsPercentage().Min(0.0f).Max(5.0f).DefaultValue(1.0f).ShowButtons(true)); - CVarSliderFloat("Walk Modifier 2: %.0f %%", CVAR_SETTING("WalkModifier.Mapping2"), - FloatSliderOptions().Color(THEME_COLOR).IsPercentage().Min(0.0f).Max(5.0f).DefaultValue(1.0f).ShowButtons(true)); + CVarCheckbox("Don't affect jump distance/velocity", CVAR_SETTING("WalkModifier.DoesntChangeJump"), + CheckboxOptions().Color(THEME_COLOR)); + CVarSliderFloat("Walk Modifier 1: %.0f %%", CVAR_SETTING("WalkModifier.Mapping1"), + FloatSliderOptions() + .Color(THEME_COLOR) + .IsPercentage() + .Min(0.0f) + .Max(5.0f) + .DefaultValue(1.0f) + .ShowButtons(true)); + CVarSliderFloat("Walk Modifier 2: %.0f %%", CVAR_SETTING("WalkModifier.Mapping2"), + FloatSliderOptions() + .Color(THEME_COLOR) + .IsPercentage() + .Min(0.0f) + .Max(5.0f) + .DefaultValue(1.0f) + .ShowButtons(true)); Ship::GuiWindow::EndGroupPanel(0); Ship::GuiWindow::BeginGroupPanel("Swim Modifier", ImGui::GetContentRegionAvail()); - CVarSliderFloat("Swim Modifier 1: %.0f %%", CVAR_SETTING("WalkModifier.SwimMapping1"), - FloatSliderOptions().Color(THEME_COLOR).IsPercentage().Min(0.0f).Max(5.0f).DefaultValue(1.0f).ShowButtons(true)); - CVarSliderFloat("Swim Modifier 2: %.0f %%", CVAR_SETTING("WalkModifier.SwimMapping2"), - FloatSliderOptions().Color(THEME_COLOR).IsPercentage().Min(0.0f).Max(5.0f).DefaultValue(1.0f).ShowButtons(true)); + CVarSliderFloat("Swim Modifier 1: %.0f %%", CVAR_SETTING("WalkModifier.SwimMapping1"), + FloatSliderOptions() + .Color(THEME_COLOR) + .IsPercentage() + .Min(0.0f) + .Max(5.0f) + .DefaultValue(1.0f) + .ShowButtons(true)); + CVarSliderFloat("Swim Modifier 2: %.0f %%", CVAR_SETTING("WalkModifier.SwimMapping2"), + FloatSliderOptions() + .Color(THEME_COLOR) + .IsPercentage() + .Min(0.0f) + .Max(5.0f) + .DefaultValue(1.0f) + .ShowButtons(true)); Ship::GuiWindow::EndGroupPanel(0); Ship::GuiWindow::EndGroupPanel(0); } @@ -1755,7 +1848,8 @@ void SohInputEditorWindow::DrawSetDefaultsButton(uint8_t portIndex) { } PopStyleButton(); if (ImGui::BeginPopupModal("Set Defaults for Gamepad (SDL)", NULL, ImGuiWindowFlags_AlwaysAutoResize)) { - ImGui::Text("This will clear all existing mappings for\nGamepad (SDL) on port %d.\n\nContinue?", portIndex + 1); + ImGui::Text("This will clear all existing mappings for\nGamepad (SDL) on port %d.\n\nContinue?", + portIndex + 1); PushStyleButton(THEME_COLOR); if (ImGui::Button("Cancel")) { shouldClose = true; diff --git a/soh/soh/Enhancements/controls/SohInputEditorWindow.h b/soh/soh/Enhancements/controls/SohInputEditorWindow.h index 4545f771d..76d33975e 100644 --- a/soh/soh/Enhancements/controls/SohInputEditorWindow.h +++ b/soh/soh/Enhancements/controls/SohInputEditorWindow.h @@ -41,7 +41,8 @@ class SohInputEditorWindow : public Ship::GuiWindow { void DrawButtonLineEditMappingButton(uint8_t port, N64ButtonMask bitmask, std::string id); void DrawButtonLineAddMappingButton(uint8_t port, N64ButtonMask bitmask); - void DrawStickDirectionLineEditMappingButton(uint8_t port, uint8_t stick, Ship::Direction direction, std::string id); + void DrawStickDirectionLineEditMappingButton(uint8_t port, uint8_t stick, Ship::Direction direction, + std::string id); void DrawStickDirectionLineAddMappingButton(uint8_t port, uint8_t stick, Ship::Direction direction); void DrawStickSection(uint8_t port, uint8_t stick, int32_t id, ImVec4 color); @@ -84,7 +85,7 @@ class SohInputEditorWindow : public Ship::GuiWindow { void UpdateStickDirectionToMappingIds(uint8_t port); void GetButtonColorsForDeviceType(Ship::PhysicalDeviceType lusIndex, ImVec4& buttonColor, - ImVec4& buttonHoveredColor); + ImVec4& buttonHoveredColor); void DrawLinkTab(); void DrawIvanTab(); void DrawDebugPortTab(uint8_t portIndex, std::string customName = ""); diff --git a/soh/soh/Enhancements/cosmetics/CosmeticsEditor.cpp b/soh/soh/Enhancements/cosmetics/CosmeticsEditor.cpp index f4a41f587..e0f530bc2 100644 --- a/soh/soh/Enhancements/cosmetics/CosmeticsEditor.cpp +++ b/soh/soh/Enhancements/cosmetics/CosmeticsEditor.cpp @@ -51,7 +51,8 @@ extern "C" { extern PlayState* gPlayState; void ResourceMgr_PatchGfxByName(const char* path, const char* patchName, int index, Gfx instruction); -void ResourceMgr_PatchGfxCopyCommandByName(const char* path, const char* patchName, int destinationIndex, int sourceIndex); +void ResourceMgr_PatchGfxCopyCommandByName(const char* path, const char* patchName, int destinationIndex, + int sourceIndex); void ResourceMgr_UnpatchGfxByName(const char* path, const char* patchName); u8 Randomizer_GetSettingValue(RandomizerSettingKey randoSettingKey); } @@ -68,27 +69,27 @@ u8 Randomizer_GetSettingValue(RandomizerSettingKey randoSettingKey); static const ALIGN_ASSET(2) char gEndGrayscaleAndEndDlistDL[] = dgEndGrayscaleAndEndDlistDL; std::map groupLabels = { - { COSMETICS_GROUP_LINK, "Link" }, + { COSMETICS_GROUP_LINK, "Link" }, { COSMETICS_GROUP_MIRRORSHIELD, "Mirror Shield" }, - { COSMETICS_GROUP_SWORDS, "Swords" }, - { COSMETICS_GROUP_GLOVES, "Gloves" }, - { COSMETICS_GROUP_EQUIPMENT, "Equipment" }, - { COSMETICS_GROUP_KEYRING, "Keyring" }, - { COSMETICS_GROUP_SMALL_KEYS, "Small Keys" }, - { COSMETICS_GROUP_BOSS_KEYS, "Boss Keys" }, - { COSMETICS_GROUP_CONSUMABLE, "Consumables" }, - { COSMETICS_GROUP_HUD, "HUD" }, - { COSMETICS_GROUP_KALEIDO, "Pause Menu" }, - { COSMETICS_GROUP_TITLE, "Title Screen" }, - { COSMETICS_GROUP_NPC, "NPCs" }, - { COSMETICS_GROUP_WORLD, "World" }, - { COSMETICS_GROUP_MAGIC, "Magic Effects" }, - { COSMETICS_GROUP_ARROWS, "Arrow Effects" }, - { COSMETICS_GROUP_SPIN_ATTACK, "Spin Attack" }, - { COSMETICS_GROUP_TRAILS, "Trails" }, - { COSMETICS_GROUP_NAVI, "Navi" }, - { COSMETICS_GROUP_IVAN, "Ivan" }, - { COSMETICS_GROUP_MESSAGE, "Message" }, + { COSMETICS_GROUP_SWORDS, "Swords" }, + { COSMETICS_GROUP_GLOVES, "Gloves" }, + { COSMETICS_GROUP_EQUIPMENT, "Equipment" }, + { COSMETICS_GROUP_KEYRING, "Keyring" }, + { COSMETICS_GROUP_SMALL_KEYS, "Small Keys" }, + { COSMETICS_GROUP_BOSS_KEYS, "Boss Keys" }, + { COSMETICS_GROUP_CONSUMABLE, "Consumables" }, + { COSMETICS_GROUP_HUD, "HUD" }, + { COSMETICS_GROUP_KALEIDO, "Pause Menu" }, + { COSMETICS_GROUP_TITLE, "Title Screen" }, + { COSMETICS_GROUP_NPC, "NPCs" }, + { COSMETICS_GROUP_WORLD, "World" }, + { COSMETICS_GROUP_MAGIC, "Magic Effects" }, + { COSMETICS_GROUP_ARROWS, "Arrow Effects" }, + { COSMETICS_GROUP_SPIN_ATTACK, "Spin Attack" }, + { COSMETICS_GROUP_TRAILS, "Trails" }, + { COSMETICS_GROUP_NAVI, "Navi" }, + { COSMETICS_GROUP_IVAN, "Ivan" }, + { COSMETICS_GROUP_MESSAGE, "Message" }, }; typedef struct { @@ -111,13 +112,16 @@ Color_RGBA8 ColorRGBA8(uint8_t r, uint8_t g, uint8_t b, uint8_t a) { return color; } -#define COSMETIC_OPTION(id, label, group, defaultColor, supportsAlpha, supportsRainbow, advancedOption) \ - { id, { \ - CVAR_COSMETIC(id), CVAR_COSMETIC(id ".Value"), CVAR_COSMETIC(id ".Rainbow"), CVAR_COSMETIC(id ".Locked"), \ - CVAR_COSMETIC(id ".Changed"), label, group, \ - ImVec4(defaultColor.r / 255.0f, defaultColor.g / 255.0f, defaultColor.b / 255.0f, defaultColor.a / 255.0f), defaultColor, \ - supportsAlpha, supportsRainbow, advancedOption \ - } } +#define COSMETIC_OPTION(id, label, group, defaultColor, supportsAlpha, supportsRainbow, advancedOption) \ + { \ + id, { \ + CVAR_COSMETIC(id), CVAR_COSMETIC(id ".Value"), CVAR_COSMETIC(id ".Rainbow"), CVAR_COSMETIC(id ".Locked"), \ + CVAR_COSMETIC(id ".Changed"), label, group, \ + ImVec4(defaultColor.r / 255.0f, defaultColor.g / 255.0f, defaultColor.b / 255.0f, \ + defaultColor.a / 255.0f), \ + defaultColor, supportsAlpha, supportsRainbow, advancedOption \ + } \ + } // clang-format off /* @@ -442,43 +446,24 @@ static std::map cosmeticOptions = { }; // clang-format on -static const char* MarginCvarList[] { - CVAR_COSMETIC("HUD.Hearts"), - CVAR_COSMETIC("HUD.HeartsCount"), - CVAR_COSMETIC("HUD.MagicBar"), - CVAR_COSMETIC("HUD.VisualSoA"), - CVAR_COSMETIC("HUD.BButton"), - CVAR_COSMETIC("HUD.AButton"), - CVAR_COSMETIC("HUD.StartButton"), - CVAR_COSMETIC("HUD.CUpButton"), - CVAR_COSMETIC("HUD.CDownButton"), - CVAR_COSMETIC("HUD.CLeftButton"), - CVAR_COSMETIC("HUD.CRightButton"), - CVAR_COSMETIC("HUD.Dpad"), - CVAR_COSMETIC("HUD.Minimap"), - CVAR_COSMETIC("HUD.SmallKey"), - CVAR_COSMETIC("HUD.Rupees"), - CVAR_COSMETIC("HUD.Carrots"), - CVAR_COSMETIC("HUD.Timers"), - CVAR_COSMETIC("HUD.ArcheryScore"), - CVAR_COSMETIC("HUD.TitleCard.Map"), - CVAR_COSMETIC("HUD.TitleCard.Boss"), - CVAR_COSMETIC("HUD.IGT"), +static const char* MarginCvarList[]{ + CVAR_COSMETIC("HUD.Hearts"), CVAR_COSMETIC("HUD.HeartsCount"), CVAR_COSMETIC("HUD.MagicBar"), + CVAR_COSMETIC("HUD.VisualSoA"), CVAR_COSMETIC("HUD.BButton"), CVAR_COSMETIC("HUD.AButton"), + CVAR_COSMETIC("HUD.StartButton"), CVAR_COSMETIC("HUD.CUpButton"), CVAR_COSMETIC("HUD.CDownButton"), + CVAR_COSMETIC("HUD.CLeftButton"), CVAR_COSMETIC("HUD.CRightButton"), CVAR_COSMETIC("HUD.Dpad"), + CVAR_COSMETIC("HUD.Minimap"), CVAR_COSMETIC("HUD.SmallKey"), CVAR_COSMETIC("HUD.Rupees"), + CVAR_COSMETIC("HUD.Carrots"), CVAR_COSMETIC("HUD.Timers"), CVAR_COSMETIC("HUD.ArcheryScore"), + CVAR_COSMETIC("HUD.TitleCard.Map"), CVAR_COSMETIC("HUD.TitleCard.Boss"), CVAR_COSMETIC("HUD.IGT"), }; -static const char* MarginCvarNonAnchor[] { - CVAR_COSMETIC("HUD.Carrots"), - CVAR_COSMETIC("HUD.Timers"), - CVAR_COSMETIC("HUD.ArcheryScore"), - CVAR_COSMETIC("HUD.TitleCard.Map"), - CVAR_COSMETIC("HUD.TitleCard.Boss"), +static const char* MarginCvarNonAnchor[]{ + CVAR_COSMETIC("HUD.Carrots"), CVAR_COSMETIC("HUD.Timers"), CVAR_COSMETIC("HUD.ArcheryScore"), + CVAR_COSMETIC("HUD.TitleCard.Map"), CVAR_COSMETIC("HUD.TitleCard.Boss"), }; void SetMarginAll(const char* ButtonName, bool SetActivated, const char* tooltip) { - if (UIWidgets::Button(ButtonName, UIWidgets::ButtonOptions() - .Size(ImVec2(200.0f, 0.0f)) - .Color(THEME_COLOR) - .Tooltip(tooltip))) { + if (UIWidgets::Button(ButtonName, + UIWidgets::ButtonOptions().Size(ImVec2(200.0f, 0.0f)).Color(THEME_COLOR).Tooltip(tooltip))) { // MarginCvarNonAnchor is an array that list every element that has No anchor by default, because if that the // case this function will not touch it with pose type 0. u8 arrayLengthNonMargin = sizeof(MarginCvarNonAnchor) / sizeof(*MarginCvarNonAnchor); @@ -514,10 +499,10 @@ void SetMarginAll(const char* ButtonName, bool SetActivated, const char* tooltip void ResetPositionAll() { if (UIWidgets::Button("Reset all positions", - UIWidgets::ButtonOptions() - .Size(ImVec2(200.0f, 0.0f)) - .Color(THEME_COLOR) - .Tooltip("Revert every element to use their original position and no margins"))) { + UIWidgets::ButtonOptions() + .Size(ImVec2(200.0f, 0.0f)) + .Color(THEME_COLOR) + .Tooltip("Revert every element to use their original position and no margins"))) { for (auto cvarName : MarginCvarList) { std::string cvarPosType = std::string(cvarName).append(".PosType"); std::string cvarNameMargins = std::string(cvarName).append(".UseMargins"); @@ -529,7 +514,8 @@ void ResetPositionAll() { int hue = 0; -// Runs every frame to update rainbow hue, a potential future optimization is to only run this a once or twice a second and increase the speed of the rainbow hue rotation. +// Runs every frame to update rainbow hue, a potential future optimization is to only run this a once or twice a second +// and increase the speed of the rainbow hue rotation. void CosmeticsUpdateTick() { int index = 0; float rainbowSpeed = CVarGetFloat(CVAR_COSMETIC("RainbowSpeed"), 0.6f); @@ -568,501 +554,725 @@ void CosmeticsUpdateTick() { } /* - This is called every time a color is changed in the UI, and every frame to update colors that have rainbow mode enabled - The columns/arguments for PATCH_GFX are as follows: - 1. Display List: This should be a valid display list pointer, if you have errors listing one here make sure to include the appropriate header file up top - 2. Patch Name: Each of these MUST be unique, used for restoring the original DList command, if these are not unique bugs WILL happen + This is called every time a color is changed in the UI, and every frame to update colors that have rainbow mode + enabled The columns/arguments for PATCH_GFX are as follows: + 1. Display List: This should be a valid display list pointer, if you have errors listing one here make sure to + include the appropriate header file up top + 2. Patch Name: Each of these MUST be unique, used for restoring the original DList command, if these are not unique + bugs WILL happen 3. Changed Cvar: What determines if a patch should be applied or reset. - 4. GFX Command Index: Index of the GFX command you want to replace, the instructions on finding this are in the giant comment block above the cosmeticOptions map + 4. GFX Command Index: Index of the GFX command you want to replace, the instructions on finding this are in the + giant comment block above the cosmeticOptions map 5. GFX Command: The GFX command you want to insert */ void ApplyOrResetCustomGfxPatches(bool manualChange) { static CosmeticOption& magicFaroresPrimary = cosmeticOptions.at("Magic.FaroresPrimary"); if (manualChange || CVarGetInteger(magicFaroresPrimary.rainbowCvar, 0)) { Color_RGBA8 color = CVarGetColor(magicFaroresPrimary.valuesCvar, magicFaroresPrimary.defaultColor); - PATCH_GFX(sInnerCylinderDL, "Magic_FaroresPrimary1", magicFaroresPrimary.changedCvar, 24, gsDPSetPrimColor(0, 0, color.r, color.g, color.b, 255)); - PATCH_GFX(sOuterCylinderDL, "Magic_FaroresPrimary2", magicFaroresPrimary.changedCvar, 24, gsDPSetPrimColor(0, 0, color.r, color.g, color.b, 255)); + PATCH_GFX(sInnerCylinderDL, "Magic_FaroresPrimary1", magicFaroresPrimary.changedCvar, 24, + gsDPSetPrimColor(0, 0, color.r, color.g, color.b, 255)); + PATCH_GFX(sOuterCylinderDL, "Magic_FaroresPrimary2", magicFaroresPrimary.changedCvar, 24, + gsDPSetPrimColor(0, 0, color.r, color.g, color.b, 255)); } static CosmeticOption& magicFaroresSecondary = cosmeticOptions.at("Magic.FaroresSecondary"); if (manualChange || CVarGetInteger(magicFaroresSecondary.rainbowCvar, 0)) { Color_RGBA8 color = CVarGetColor(magicFaroresSecondary.valuesCvar, magicFaroresSecondary.defaultColor); - PATCH_GFX(sInnerCylinderDL, "Magic_FaroresSecondary1", magicFaroresSecondary.changedCvar, 25, gsDPSetEnvColor(color.r, color.g, color.b, 255)); - PATCH_GFX(sOuterCylinderDL, "Magic_FaroresSecondary2", magicFaroresSecondary.changedCvar, 25, gsDPSetEnvColor(color.r, color.g, color.b, 255)); + PATCH_GFX(sInnerCylinderDL, "Magic_FaroresSecondary1", magicFaroresSecondary.changedCvar, 25, + gsDPSetEnvColor(color.r, color.g, color.b, 255)); + PATCH_GFX(sOuterCylinderDL, "Magic_FaroresSecondary2", magicFaroresSecondary.changedCvar, 25, + gsDPSetEnvColor(color.r, color.g, color.b, 255)); } static CosmeticOption& linkGoronTunic = cosmeticOptions.at("Link.GoronTunic"); if (manualChange || CVarGetInteger(linkGoronTunic.rainbowCvar, 0)) { Color_RGBA8 color = CVarGetColor(linkGoronTunic.valuesCvar, linkGoronTunic.defaultColor); - PATCH_GFX(gGiGoronTunicColorDL, "Link_GoronTunic1", linkGoronTunic.changedCvar, 3, gsDPSetPrimColor(0, 0, color.r, color.g, color.b, 255)); - PATCH_GFX(gGiGoronCollarColorDL, "Link_GoronTunic2", linkGoronTunic.changedCvar, 3, gsDPSetPrimColor(0, 0, color.r / 2, color.g / 2, color.b / 2, 255)); - PATCH_GFX(gGiGoronTunicColorDL, "Link_GoronTunic3", linkGoronTunic.changedCvar, 4, gsDPSetEnvColor(color.r / 2, color.g / 2, color.b / 2, 255)); - PATCH_GFX(gGiGoronCollarColorDL, "Link_GoronTunic4", linkGoronTunic.changedCvar, 4, gsDPSetEnvColor(color.r / 2, color.g / 2, color.b / 2, 255)); + PATCH_GFX(gGiGoronTunicColorDL, "Link_GoronTunic1", linkGoronTunic.changedCvar, 3, + gsDPSetPrimColor(0, 0, color.r, color.g, color.b, 255)); + PATCH_GFX(gGiGoronCollarColorDL, "Link_GoronTunic2", linkGoronTunic.changedCvar, 3, + gsDPSetPrimColor(0, 0, color.r / 2, color.g / 2, color.b / 2, 255)); + PATCH_GFX(gGiGoronTunicColorDL, "Link_GoronTunic3", linkGoronTunic.changedCvar, 4, + gsDPSetEnvColor(color.r / 2, color.g / 2, color.b / 2, 255)); + PATCH_GFX(gGiGoronCollarColorDL, "Link_GoronTunic4", linkGoronTunic.changedCvar, 4, + gsDPSetEnvColor(color.r / 2, color.g / 2, color.b / 2, 255)); } static CosmeticOption& linkZoraTunic = cosmeticOptions.at("Link.ZoraTunic"); if (manualChange || CVarGetInteger(linkZoraTunic.rainbowCvar, 0)) { Color_RGBA8 color = CVarGetColor(linkZoraTunic.valuesCvar, linkZoraTunic.defaultColor); - PATCH_GFX(gGiZoraTunicColorDL, "Link_ZoraTunic1", linkZoraTunic.changedCvar, 3, gsDPSetPrimColor(0, 0, color.r, color.g, color.b, 255)); - PATCH_GFX(gGiZoraCollarColorDL, "Link_ZoraTunic2", linkZoraTunic.changedCvar, 3, gsDPSetPrimColor(0, 0, color.r / 2, color.g / 2, color.b / 2, 255)); - PATCH_GFX(gGiZoraTunicColorDL, "Link_ZoraTunic3", linkZoraTunic.changedCvar, 4, gsDPSetEnvColor(color.r / 2, color.g / 2, color.b / 2, 255)); - PATCH_GFX(gGiZoraCollarColorDL, "Link_ZoraTunic4", linkZoraTunic.changedCvar, 4, gsDPSetEnvColor(color.r / 2, color.g / 2, color.b / 2, 255)); + PATCH_GFX(gGiZoraTunicColorDL, "Link_ZoraTunic1", linkZoraTunic.changedCvar, 3, + gsDPSetPrimColor(0, 0, color.r, color.g, color.b, 255)); + PATCH_GFX(gGiZoraCollarColorDL, "Link_ZoraTunic2", linkZoraTunic.changedCvar, 3, + gsDPSetPrimColor(0, 0, color.r / 2, color.g / 2, color.b / 2, 255)); + PATCH_GFX(gGiZoraTunicColorDL, "Link_ZoraTunic3", linkZoraTunic.changedCvar, 4, + gsDPSetEnvColor(color.r / 2, color.g / 2, color.b / 2, 255)); + PATCH_GFX(gGiZoraCollarColorDL, "Link_ZoraTunic4", linkZoraTunic.changedCvar, 4, + gsDPSetEnvColor(color.r / 2, color.g / 2, color.b / 2, 255)); } static CosmeticOption& linkHair = cosmeticOptions.at("Link.Hair"); if (manualChange || CVarGetInteger(linkHair.rainbowCvar, 0)) { Color_RGBA8 color = CVarGetColor(linkHair.valuesCvar, linkHair.defaultColor); - PATCH_GFX(gLinkChildHeadNearDL, "Link_Hair1", linkHair.changedCvar, 10, gsDPSetGrayscaleColor(color.r, color.g, color.b, 255)); - PATCH_GFX(gLinkChildHeadFarDL, "Link_Hair2", linkHair.changedCvar, 10, gsDPSetGrayscaleColor(color.r, color.g, color.b, 255)); - PATCH_GFX(gLinkAdultHeadNearDL, "Link_Hair3", linkHair.changedCvar, 10, gsDPSetGrayscaleColor(color.r, color.g, color.b, 255)); - PATCH_GFX(gLinkAdultHeadFarDL, "Link_Hair4", linkHair.changedCvar, 10, gsDPSetGrayscaleColor(color.r, color.g, color.b, 255)); + PATCH_GFX(gLinkChildHeadNearDL, "Link_Hair1", linkHair.changedCvar, 10, + gsDPSetGrayscaleColor(color.r, color.g, color.b, 255)); + PATCH_GFX(gLinkChildHeadFarDL, "Link_Hair2", linkHair.changedCvar, 10, + gsDPSetGrayscaleColor(color.r, color.g, color.b, 255)); + PATCH_GFX(gLinkAdultHeadNearDL, "Link_Hair3", linkHair.changedCvar, 10, + gsDPSetGrayscaleColor(color.r, color.g, color.b, 255)); + PATCH_GFX(gLinkAdultHeadFarDL, "Link_Hair4", linkHair.changedCvar, 10, + gsDPSetGrayscaleColor(color.r, color.g, color.b, 255)); if (manualChange) { - PATCH_GFX(gLinkChildHeadNearDL, "Link_Hair5", linkHair.changedCvar, 46, gsSPGrayscale(true)); - PATCH_GFX(gLinkChildHeadNearDL, "Link_Hair6", linkHair.changedCvar, 54, gsSPGrayscale(false)); - PATCH_GFX(gLinkChildHeadNearDL, "Link_Hair7", linkHair.changedCvar, 136, gsSPGrayscale(true)); - PATCH_GFX(gLinkChildHeadNearDL, "Link_Hair8", linkHair.changedCvar, 162, gsSPGrayscale(false)); - PATCH_GFX(gLinkChildHeadFarDL, "Link_Hair9", linkHair.changedCvar, 101, gsSPGrayscale(true)); - PATCH_GFX(gLinkChildHeadFarDL, "Link_Hair10", linkHair.changedCvar, 118, gsSPGrayscale(false)); - PATCH_GFX(gLinkAdultHeadNearDL, "Link_Hair11", linkHair.changedCvar, 125, gsSPGrayscale(true)); - PATCH_GFX(gLinkAdultHeadNearDL, "Link_Hair12", linkHair.changedCvar, 159, gsSPGrayscale(false)); - PATCH_GFX(gLinkAdultHeadFarDL, "Link_Hair13", linkHair.changedCvar, 102, gsSPGrayscale(true)); - PATCH_GFX(gLinkAdultHeadFarDL, "Link_Hair14", linkHair.changedCvar, 122, gsSPGrayscale(false)); + PATCH_GFX(gLinkChildHeadNearDL, "Link_Hair5", linkHair.changedCvar, 46, gsSPGrayscale(true)); + PATCH_GFX(gLinkChildHeadNearDL, "Link_Hair6", linkHair.changedCvar, 54, gsSPGrayscale(false)); + PATCH_GFX(gLinkChildHeadNearDL, "Link_Hair7", linkHair.changedCvar, 136, gsSPGrayscale(true)); + PATCH_GFX(gLinkChildHeadNearDL, "Link_Hair8", linkHair.changedCvar, 162, gsSPGrayscale(false)); + PATCH_GFX(gLinkChildHeadFarDL, "Link_Hair9", linkHair.changedCvar, 101, gsSPGrayscale(true)); + PATCH_GFX(gLinkChildHeadFarDL, "Link_Hair10", linkHair.changedCvar, 118, gsSPGrayscale(false)); + PATCH_GFX(gLinkAdultHeadNearDL, "Link_Hair11", linkHair.changedCvar, 125, gsSPGrayscale(true)); + PATCH_GFX(gLinkAdultHeadNearDL, "Link_Hair12", linkHair.changedCvar, 159, gsSPGrayscale(false)); + PATCH_GFX(gLinkAdultHeadFarDL, "Link_Hair13", linkHair.changedCvar, 102, gsSPGrayscale(true)); + PATCH_GFX(gLinkAdultHeadFarDL, "Link_Hair14", linkHair.changedCvar, 122, gsSPGrayscale(false)); } } static CosmeticOption& linkLinen = cosmeticOptions.at("Link.Linen"); if (manualChange || CVarGetInteger(linkLinen.rainbowCvar, 0)) { Color_RGBA8 color = CVarGetColor(linkLinen.valuesCvar, linkLinen.defaultColor); - PATCH_GFX(gLinkAdultLeftArmNearDL, "Link_Linen1", linkLinen.changedCvar, 30, gsDPSetPrimColor(0, 0, color.r, color.g, color.b, 255)); - PATCH_GFX(gLinkAdultLeftArmNearDL, "Link_Linen2", linkLinen.changedCvar, 83, gsDPSetPrimColor(0, 0, color.r, color.g, color.b, 255)); - PATCH_GFX(gLinkAdultLeftArmOutNearDL, "Link_Linen3", linkLinen.changedCvar, 25, gsDPSetPrimColor(0, 0, color.r, color.g, color.b, 255)); - PATCH_GFX(gLinkAdultLeftArmFarDL, "Link_Linen4", linkLinen.changedCvar, 30, gsDPSetPrimColor(0, 0, color.r, color.g, color.b, 255)); - PATCH_GFX(gLinkAdultLeftArmFarDL, "Link_Linen5", linkLinen.changedCvar, 70, gsDPSetPrimColor(0, 0, color.r, color.g, color.b, 255)); - PATCH_GFX(gLinkAdultRightArmFarDL, "Link_Linen6", linkLinen.changedCvar, 30, gsDPSetPrimColor(0, 0, color.r, color.g, color.b, 255)); - PATCH_GFX(gLinkAdultRightArmFarDL, "Link_Linen7", linkLinen.changedCvar, 70, gsDPSetPrimColor(0, 0, color.r, color.g, color.b, 255)); - PATCH_GFX(gLinkAdultRightArmNearDL, "Link_Linen8", linkLinen.changedCvar, 30, gsDPSetPrimColor(0, 0, color.r, color.g, color.b, 255)); - PATCH_GFX(gLinkAdultLeftShoulderFarDL, "Link_Linen9", linkLinen.changedCvar, 55, gsDPSetPrimColor(0, 0, color.r, color.g, color.b, 255)); - PATCH_GFX(gLinkAdultLeftShoulderNearDL, "Link_Linen10", linkLinen.changedCvar, 57, gsDPSetPrimColor(0, 0, color.r, color.g, color.b, 255)); - PATCH_GFX(gLinkAdultRightShoulderNearDL, "Link_Linen11", linkLinen.changedCvar, 57, gsDPSetPrimColor(0, 0, color.r, color.g, color.b, 255)); - PATCH_GFX(gLinkAdultRightShoulderFarDL, "Link_Linen12", linkLinen.changedCvar, 55, gsDPSetPrimColor(0, 0, color.r, color.g, color.b, 255)); - PATCH_GFX(gLinkAdultTorsoNearDL, "Link_Linen13", linkLinen.changedCvar, 66, gsDPSetPrimColor(0, 0, color.r, color.g, color.b, 255)); - PATCH_GFX(gLinkAdultTorsoFarDL, "Link_Linen14", linkLinen.changedCvar, 57, gsDPSetPrimColor(0, 0, color.r, color.g, color.b, 255)); - PATCH_GFX(gLinkAdultRightThighNearDL, "Link_Linen15", linkLinen.changedCvar, 53, gsDPSetPrimColor(0, 0, color.r, color.g, color.b, 255)); - PATCH_GFX(gLinkAdultLeftThighNearDL, "Link_Linen16", linkLinen.changedCvar, 53, gsDPSetPrimColor(0, 0, color.r, color.g, color.b, 255)); - PATCH_GFX(gLinkAdultRightThighFarDL, "Link_Linen17", linkLinen.changedCvar, 54, gsDPSetPrimColor(0, 0, color.r, color.g, color.b, 255)); - PATCH_GFX(gLinkAdultLeftThighFarDL, "Link_Linen18", linkLinen.changedCvar, 54, gsDPSetPrimColor(0, 0, color.r, color.g, color.b, 255)); - PATCH_GFX(gLinkAdultRightLegNearDL, "Link_Linen19", linkLinen.changedCvar, 30, gsDPSetPrimColor(0, 0, color.r, color.g, color.b, 255)); - PATCH_GFX(gLinkAdultLeftLegNearDL, "Link_Linen20", linkLinen.changedCvar, 30, gsDPSetPrimColor(0, 0, color.r, color.g, color.b, 255)); - PATCH_GFX(gLinkAdultRightLegFarDL, "Link_Linen21", linkLinen.changedCvar, 30, gsDPSetPrimColor(0, 0, color.r, color.g, color.b, 255)); - PATCH_GFX(gLinkAdultLeftLegFarDL, "Link_Linen22", linkLinen.changedCvar, 30, gsDPSetPrimColor(0, 0, color.r, color.g, color.b, 255)); + PATCH_GFX(gLinkAdultLeftArmNearDL, "Link_Linen1", linkLinen.changedCvar, 30, + gsDPSetPrimColor(0, 0, color.r, color.g, color.b, 255)); + PATCH_GFX(gLinkAdultLeftArmNearDL, "Link_Linen2", linkLinen.changedCvar, 83, + gsDPSetPrimColor(0, 0, color.r, color.g, color.b, 255)); + PATCH_GFX(gLinkAdultLeftArmOutNearDL, "Link_Linen3", linkLinen.changedCvar, 25, + gsDPSetPrimColor(0, 0, color.r, color.g, color.b, 255)); + PATCH_GFX(gLinkAdultLeftArmFarDL, "Link_Linen4", linkLinen.changedCvar, 30, + gsDPSetPrimColor(0, 0, color.r, color.g, color.b, 255)); + PATCH_GFX(gLinkAdultLeftArmFarDL, "Link_Linen5", linkLinen.changedCvar, 70, + gsDPSetPrimColor(0, 0, color.r, color.g, color.b, 255)); + PATCH_GFX(gLinkAdultRightArmFarDL, "Link_Linen6", linkLinen.changedCvar, 30, + gsDPSetPrimColor(0, 0, color.r, color.g, color.b, 255)); + PATCH_GFX(gLinkAdultRightArmFarDL, "Link_Linen7", linkLinen.changedCvar, 70, + gsDPSetPrimColor(0, 0, color.r, color.g, color.b, 255)); + PATCH_GFX(gLinkAdultRightArmNearDL, "Link_Linen8", linkLinen.changedCvar, 30, + gsDPSetPrimColor(0, 0, color.r, color.g, color.b, 255)); + PATCH_GFX(gLinkAdultLeftShoulderFarDL, "Link_Linen9", linkLinen.changedCvar, 55, + gsDPSetPrimColor(0, 0, color.r, color.g, color.b, 255)); + PATCH_GFX(gLinkAdultLeftShoulderNearDL, "Link_Linen10", linkLinen.changedCvar, 57, + gsDPSetPrimColor(0, 0, color.r, color.g, color.b, 255)); + PATCH_GFX(gLinkAdultRightShoulderNearDL, "Link_Linen11", linkLinen.changedCvar, 57, + gsDPSetPrimColor(0, 0, color.r, color.g, color.b, 255)); + PATCH_GFX(gLinkAdultRightShoulderFarDL, "Link_Linen12", linkLinen.changedCvar, 55, + gsDPSetPrimColor(0, 0, color.r, color.g, color.b, 255)); + PATCH_GFX(gLinkAdultTorsoNearDL, "Link_Linen13", linkLinen.changedCvar, 66, + gsDPSetPrimColor(0, 0, color.r, color.g, color.b, 255)); + PATCH_GFX(gLinkAdultTorsoFarDL, "Link_Linen14", linkLinen.changedCvar, 57, + gsDPSetPrimColor(0, 0, color.r, color.g, color.b, 255)); + PATCH_GFX(gLinkAdultRightThighNearDL, "Link_Linen15", linkLinen.changedCvar, 53, + gsDPSetPrimColor(0, 0, color.r, color.g, color.b, 255)); + PATCH_GFX(gLinkAdultLeftThighNearDL, "Link_Linen16", linkLinen.changedCvar, 53, + gsDPSetPrimColor(0, 0, color.r, color.g, color.b, 255)); + PATCH_GFX(gLinkAdultRightThighFarDL, "Link_Linen17", linkLinen.changedCvar, 54, + gsDPSetPrimColor(0, 0, color.r, color.g, color.b, 255)); + PATCH_GFX(gLinkAdultLeftThighFarDL, "Link_Linen18", linkLinen.changedCvar, 54, + gsDPSetPrimColor(0, 0, color.r, color.g, color.b, 255)); + PATCH_GFX(gLinkAdultRightLegNearDL, "Link_Linen19", linkLinen.changedCvar, 30, + gsDPSetPrimColor(0, 0, color.r, color.g, color.b, 255)); + PATCH_GFX(gLinkAdultLeftLegNearDL, "Link_Linen20", linkLinen.changedCvar, 30, + gsDPSetPrimColor(0, 0, color.r, color.g, color.b, 255)); + PATCH_GFX(gLinkAdultRightLegFarDL, "Link_Linen21", linkLinen.changedCvar, 30, + gsDPSetPrimColor(0, 0, color.r, color.g, color.b, 255)); + PATCH_GFX(gLinkAdultLeftLegFarDL, "Link_Linen22", linkLinen.changedCvar, 30, + gsDPSetPrimColor(0, 0, color.r, color.g, color.b, 255)); if (manualChange) { - PATCH_GFX(gLinkAdultLeftArmFarDL, "Link_Linen23", linkLinen.changedCvar, 35, gsDPSetPrimColor(0, 0, 255, 255, 255, 255)); - PATCH_GFX(gLinkAdultLeftArmOutNearDL, "Link_Linen24", linkLinen.changedCvar, 45, gsDPSetPrimColor(0, 0, 255, 255, 255, 255)); - PATCH_GFX(gLinkAdultLeftArmNearDL, "Link_Linen25", linkLinen.changedCvar, 40, gsDPSetPrimColor(0, 0, 255, 255, 255, 255)); - PATCH_GFX(gLinkAdultLeftArmFarDL, "Link_Linen26", linkLinen.changedCvar, 77, gsDPSetPrimColor(0, 0, 255, 255, 255, 255)); - PATCH_GFX(gLinkAdultRightArmFarDL, "Link_Linen27", linkLinen.changedCvar, 35, gsDPSetPrimColor(0, 0, 255, 255, 255, 255)); - PATCH_GFX(gLinkAdultRightArmFarDL, "Link_Linen28", linkLinen.changedCvar, 77, gsDPSetPrimColor(0, 0, 255, 255, 255, 255)); - PATCH_GFX(gLinkAdultRightArmNearDL, "Link_Linen29", linkLinen.changedCvar, 42, gsDPSetPrimColor(0, 0, 255, 255, 255, 255)); - PATCH_GFX(gLinkAdultRightLegNearDL, "Link_Linen30", linkLinen.changedCvar, 43, gsDPSetPrimColor(0, 0, 255, 255, 255, 255)); - PATCH_GFX(gLinkAdultLeftLegNearDL, "Link_Linen31", linkLinen.changedCvar, 43, gsDPSetPrimColor(0, 0, 255, 255, 255, 255)); - PATCH_GFX(gLinkAdultRightLegFarDL, "Link_Linen32", linkLinen.changedCvar, 38, gsDPSetPrimColor(0, 0, 255, 255, 255, 255)); - PATCH_GFX(gLinkAdultLeftLegFarDL, "Link_Linen33", linkLinen.changedCvar, 38, gsDPSetPrimColor(0, 0, 255, 255, 255, 255)); + PATCH_GFX(gLinkAdultLeftArmFarDL, "Link_Linen23", linkLinen.changedCvar, 35, + gsDPSetPrimColor(0, 0, 255, 255, 255, 255)); + PATCH_GFX(gLinkAdultLeftArmOutNearDL, "Link_Linen24", linkLinen.changedCvar, 45, + gsDPSetPrimColor(0, 0, 255, 255, 255, 255)); + PATCH_GFX(gLinkAdultLeftArmNearDL, "Link_Linen25", linkLinen.changedCvar, 40, + gsDPSetPrimColor(0, 0, 255, 255, 255, 255)); + PATCH_GFX(gLinkAdultLeftArmFarDL, "Link_Linen26", linkLinen.changedCvar, 77, + gsDPSetPrimColor(0, 0, 255, 255, 255, 255)); + PATCH_GFX(gLinkAdultRightArmFarDL, "Link_Linen27", linkLinen.changedCvar, 35, + gsDPSetPrimColor(0, 0, 255, 255, 255, 255)); + PATCH_GFX(gLinkAdultRightArmFarDL, "Link_Linen28", linkLinen.changedCvar, 77, + gsDPSetPrimColor(0, 0, 255, 255, 255, 255)); + PATCH_GFX(gLinkAdultRightArmNearDL, "Link_Linen29", linkLinen.changedCvar, 42, + gsDPSetPrimColor(0, 0, 255, 255, 255, 255)); + PATCH_GFX(gLinkAdultRightLegNearDL, "Link_Linen30", linkLinen.changedCvar, 43, + gsDPSetPrimColor(0, 0, 255, 255, 255, 255)); + PATCH_GFX(gLinkAdultLeftLegNearDL, "Link_Linen31", linkLinen.changedCvar, 43, + gsDPSetPrimColor(0, 0, 255, 255, 255, 255)); + PATCH_GFX(gLinkAdultRightLegFarDL, "Link_Linen32", linkLinen.changedCvar, 38, + gsDPSetPrimColor(0, 0, 255, 255, 255, 255)); + PATCH_GFX(gLinkAdultLeftLegFarDL, "Link_Linen33", linkLinen.changedCvar, 38, + gsDPSetPrimColor(0, 0, 255, 255, 255, 255)); } } static CosmeticOption& linkBoots = cosmeticOptions.at("Link.Boots"); if (manualChange || CVarGetInteger(linkBoots.rainbowCvar, 0)) { Color_RGBA8 color = CVarGetColor(linkBoots.valuesCvar, linkBoots.defaultColor); - PATCH_GFX(gLinkChildRightShinNearDL, "Link_Boots1", linkBoots.changedCvar, 10, gsDPSetGrayscaleColor(color.r, color.g, color.b, 255)); - PATCH_GFX(gLinkChildRightShinFarDL, "Link_Boots2", linkBoots.changedCvar, 10, gsDPSetGrayscaleColor(color.r, color.g, color.b, 255)); - PATCH_GFX(gLinkAdultRightLegNearDL, "Link_Boots3", linkBoots.changedCvar, 10, gsDPSetGrayscaleColor(color.r, color.g, color.b, 255)); - PATCH_GFX(gLinkAdultRightLegFarDL, "Link_Boots4", linkBoots.changedCvar, 10, gsDPSetGrayscaleColor(color.r, color.g, color.b, 255)); + PATCH_GFX(gLinkChildRightShinNearDL, "Link_Boots1", linkBoots.changedCvar, 10, + gsDPSetGrayscaleColor(color.r, color.g, color.b, 255)); + PATCH_GFX(gLinkChildRightShinFarDL, "Link_Boots2", linkBoots.changedCvar, 10, + gsDPSetGrayscaleColor(color.r, color.g, color.b, 255)); + PATCH_GFX(gLinkAdultRightLegNearDL, "Link_Boots3", linkBoots.changedCvar, 10, + gsDPSetGrayscaleColor(color.r, color.g, color.b, 255)); + PATCH_GFX(gLinkAdultRightLegFarDL, "Link_Boots4", linkBoots.changedCvar, 10, + gsDPSetGrayscaleColor(color.r, color.g, color.b, 255)); if (manualChange) { - PATCH_GFX(gLinkChildRightShinNearDL, "Link_Boots5", linkBoots.changedCvar, 53, gsSPGrayscale(true)); - PATCH_GFX(gLinkChildRightShinNearDL, "Link_Boots6", linkBoots.changedCvar, 69, gsSPGrayscale(false)); - PATCH_GFX(gLinkChildRightShinFarDL, "Link_Boots7", linkBoots.changedCvar, 52, gsSPGrayscale(true)); - PATCH_GFX(gLinkChildRightShinFarDL, "Link_Boots8", linkBoots.changedCvar, 61, gsSPGrayscale(false)); - PATCH_GFX(gLinkChildLeftShinNearDL, "Link_Boots9", linkBoots.changedCvar, 53, gsSPGrayscale(true)); - PATCH_GFX(gLinkChildLeftShinNearDL, "Link_Boots10", linkBoots.changedCvar, 69, gsSPGrayscale(false)); - PATCH_GFX(gLinkChildLeftShinFarDL, "Link_Boots11", linkBoots.changedCvar, 52, gsSPGrayscale(true)); - PATCH_GFX(gLinkChildLeftShinFarDL, "Link_Boots12", linkBoots.changedCvar, 61, gsSPGrayscale(false)); - PATCH_GFX(gLinkChildRightFootNearDL, "Link_Boots13", linkBoots.changedCvar, 30, gsSPGrayscale(true)); - PATCH_GFX(gLinkChildRightFootFarDL, "Link_Boots14", linkBoots.changedCvar, 30, gsSPGrayscale(true)); - PATCH_GFX(gLinkChildLeftFootNearDL, "Link_Boots15", linkBoots.changedCvar, 30, gsSPGrayscale(true)); - PATCH_GFX(gLinkChildLeftFootFarDL, "Link_Boots16", linkBoots.changedCvar, 30, gsSPGrayscale(true)); - PATCH_GFX(gLinkChildLeftThighNearDL, "Link_Boots17", linkBoots.changedCvar, 10, gsSPGrayscale(false)); - PATCH_GFX(gLinkChildLeftThighFarDL, "Link_Boots18", linkBoots.changedCvar, 10, gsSPGrayscale(false)); - PATCH_GFX(gLinkChildHeadNearDL, "Link_Boots19", linkBoots.changedCvar, 20, gsSPGrayscale(false)); - PATCH_GFX(gLinkChildHeadFarDL, "Link_Boots20", linkBoots.changedCvar, 20, gsSPGrayscale(false)); - PATCH_GFX(gLinkAdultRightLegNearDL, "Link_Boots21", linkBoots.changedCvar, 57, gsSPGrayscale(true)); - PATCH_GFX(gLinkAdultRightLegFarDL, "Link_Boots22", linkBoots.changedCvar, 52, gsSPGrayscale(true)); - PATCH_GFX(gLinkAdultLeftLegNearDL, "Link_Boots23", linkBoots.changedCvar, 57, gsSPGrayscale(true)); - PATCH_GFX(gLinkAdultLeftLegFarDL, "Link_Boots24", linkBoots.changedCvar, 52, gsSPGrayscale(true)); - PATCH_GFX(gLinkAdultLeftThighNearDL, "Link_Boots25", linkBoots.changedCvar, 10, gsSPGrayscale(false)); - PATCH_GFX(gLinkAdultLeftThighFarDL, "Link_Boots26", linkBoots.changedCvar, 10, gsSPGrayscale(false)); - PATCH_GFX(gLinkAdultHeadNearDL, "Link_Boots27", linkBoots.changedCvar, 20, gsSPGrayscale(false)); - PATCH_GFX(gLinkAdultHeadFarDL, "Link_Boots28", linkBoots.changedCvar, 20, gsSPGrayscale(false)); + PATCH_GFX(gLinkChildRightShinNearDL, "Link_Boots5", linkBoots.changedCvar, 53, gsSPGrayscale(true)); + PATCH_GFX(gLinkChildRightShinNearDL, "Link_Boots6", linkBoots.changedCvar, 69, gsSPGrayscale(false)); + PATCH_GFX(gLinkChildRightShinFarDL, "Link_Boots7", linkBoots.changedCvar, 52, gsSPGrayscale(true)); + PATCH_GFX(gLinkChildRightShinFarDL, "Link_Boots8", linkBoots.changedCvar, 61, gsSPGrayscale(false)); + PATCH_GFX(gLinkChildLeftShinNearDL, "Link_Boots9", linkBoots.changedCvar, 53, gsSPGrayscale(true)); + PATCH_GFX(gLinkChildLeftShinNearDL, "Link_Boots10", linkBoots.changedCvar, 69, gsSPGrayscale(false)); + PATCH_GFX(gLinkChildLeftShinFarDL, "Link_Boots11", linkBoots.changedCvar, 52, gsSPGrayscale(true)); + PATCH_GFX(gLinkChildLeftShinFarDL, "Link_Boots12", linkBoots.changedCvar, 61, gsSPGrayscale(false)); + PATCH_GFX(gLinkChildRightFootNearDL, "Link_Boots13", linkBoots.changedCvar, 30, gsSPGrayscale(true)); + PATCH_GFX(gLinkChildRightFootFarDL, "Link_Boots14", linkBoots.changedCvar, 30, gsSPGrayscale(true)); + PATCH_GFX(gLinkChildLeftFootNearDL, "Link_Boots15", linkBoots.changedCvar, 30, gsSPGrayscale(true)); + PATCH_GFX(gLinkChildLeftFootFarDL, "Link_Boots16", linkBoots.changedCvar, 30, gsSPGrayscale(true)); + PATCH_GFX(gLinkChildLeftThighNearDL, "Link_Boots17", linkBoots.changedCvar, 10, gsSPGrayscale(false)); + PATCH_GFX(gLinkChildLeftThighFarDL, "Link_Boots18", linkBoots.changedCvar, 10, gsSPGrayscale(false)); + PATCH_GFX(gLinkChildHeadNearDL, "Link_Boots19", linkBoots.changedCvar, 20, gsSPGrayscale(false)); + PATCH_GFX(gLinkChildHeadFarDL, "Link_Boots20", linkBoots.changedCvar, 20, gsSPGrayscale(false)); + PATCH_GFX(gLinkAdultRightLegNearDL, "Link_Boots21", linkBoots.changedCvar, 57, gsSPGrayscale(true)); + PATCH_GFX(gLinkAdultRightLegFarDL, "Link_Boots22", linkBoots.changedCvar, 52, gsSPGrayscale(true)); + PATCH_GFX(gLinkAdultLeftLegNearDL, "Link_Boots23", linkBoots.changedCvar, 57, gsSPGrayscale(true)); + PATCH_GFX(gLinkAdultLeftLegFarDL, "Link_Boots24", linkBoots.changedCvar, 52, gsSPGrayscale(true)); + PATCH_GFX(gLinkAdultLeftThighNearDL, "Link_Boots25", linkBoots.changedCvar, 10, gsSPGrayscale(false)); + PATCH_GFX(gLinkAdultLeftThighFarDL, "Link_Boots26", linkBoots.changedCvar, 10, gsSPGrayscale(false)); + PATCH_GFX(gLinkAdultHeadNearDL, "Link_Boots27", linkBoots.changedCvar, 20, gsSPGrayscale(false)); + PATCH_GFX(gLinkAdultHeadFarDL, "Link_Boots28", linkBoots.changedCvar, 20, gsSPGrayscale(false)); } } static CosmeticOption& mirrorShieldBody = cosmeticOptions.at("MirrorShield.Body"); if (manualChange || CVarGetInteger(mirrorShieldBody.rainbowCvar, 0)) { Color_RGBA8 color = CVarGetColor(mirrorShieldBody.valuesCvar, mirrorShieldBody.defaultColor); - PATCH_GFX(gGiMirrorShieldDL, "MirrorShield_Body1", mirrorShieldBody.changedCvar, 5, gsDPSetPrimColor(0, 0, color.r, color.g, color.b, 255)); - PATCH_GFX(gGiMirrorShieldDL, "MirrorShield_Body2", mirrorShieldBody.changedCvar, 6, gsDPSetEnvColor(color.r / 3, color.g / 3, color.b / 3, 255)); - PATCH_GFX(gLinkAdultMirrorShieldSwordAndSheathNearDL, "MirrorShield_Body3", mirrorShieldBody.changedCvar, 28, gsDPSetPrimColor(0, 0, color.r, color.g, color.b, 255)); - PATCH_GFX(gLinkAdultMirrorShieldSwordAndSheathFarDL, "MirrorShield_Body4", mirrorShieldBody.changedCvar, 17, gsDPSetPrimColor(0, 0, color.r, color.g, color.b, 255)); - PATCH_GFX(gLinkAdultMirrorShieldAndSheathNearDL, "MirrorShield_Body5", mirrorShieldBody.changedCvar, 28, gsDPSetPrimColor(0, 0, color.r, color.g, color.b, 255)); - PATCH_GFX(gLinkAdultMirrorShieldAndSheathFarDL, "MirrorShield_Body6", mirrorShieldBody.changedCvar, 17, gsDPSetPrimColor(0, 0, color.r, color.g, color.b, 255)); - PATCH_GFX(gLinkAdultRightHandHoldingMirrorShieldNearDL, "MirrorShield_Body7", mirrorShieldBody.changedCvar, 28, gsDPSetPrimColor(0, 0, color.r, color.g, color.b, 255)); - PATCH_GFX(gLinkAdultRightHandHoldingMirrorShieldFarDL, "MirrorShield_Body8", mirrorShieldBody.changedCvar, 95, gsDPSetPrimColor(0, 0, color.r, color.g, color.b, 255)); + PATCH_GFX(gGiMirrorShieldDL, "MirrorShield_Body1", mirrorShieldBody.changedCvar, 5, + gsDPSetPrimColor(0, 0, color.r, color.g, color.b, 255)); + PATCH_GFX(gGiMirrorShieldDL, "MirrorShield_Body2", mirrorShieldBody.changedCvar, 6, + gsDPSetEnvColor(color.r / 3, color.g / 3, color.b / 3, 255)); + PATCH_GFX(gLinkAdultMirrorShieldSwordAndSheathNearDL, "MirrorShield_Body3", mirrorShieldBody.changedCvar, 28, + gsDPSetPrimColor(0, 0, color.r, color.g, color.b, 255)); + PATCH_GFX(gLinkAdultMirrorShieldSwordAndSheathFarDL, "MirrorShield_Body4", mirrorShieldBody.changedCvar, 17, + gsDPSetPrimColor(0, 0, color.r, color.g, color.b, 255)); + PATCH_GFX(gLinkAdultMirrorShieldAndSheathNearDL, "MirrorShield_Body5", mirrorShieldBody.changedCvar, 28, + gsDPSetPrimColor(0, 0, color.r, color.g, color.b, 255)); + PATCH_GFX(gLinkAdultMirrorShieldAndSheathFarDL, "MirrorShield_Body6", mirrorShieldBody.changedCvar, 17, + gsDPSetPrimColor(0, 0, color.r, color.g, color.b, 255)); + PATCH_GFX(gLinkAdultRightHandHoldingMirrorShieldNearDL, "MirrorShield_Body7", mirrorShieldBody.changedCvar, 28, + gsDPSetPrimColor(0, 0, color.r, color.g, color.b, 255)); + PATCH_GFX(gLinkAdultRightHandHoldingMirrorShieldFarDL, "MirrorShield_Body8", mirrorShieldBody.changedCvar, 95, + gsDPSetPrimColor(0, 0, color.r, color.g, color.b, 255)); } static CosmeticOption& mirrorShieldMirror = cosmeticOptions.at("MirrorShield.Mirror"); if (manualChange || CVarGetInteger(mirrorShieldMirror.rainbowCvar, 0)) { Color_RGBA8 color = CVarGetColor(mirrorShieldMirror.valuesCvar, mirrorShieldMirror.defaultColor); - PATCH_GFX(gGiMirrorShieldDL, "MirrorShield_Mirror1", mirrorShieldMirror.changedCvar, 47, gsDPSetPrimColor(0, 0, color.r, color.g, color.b, 255)); - PATCH_GFX(gGiMirrorShieldDL, "MirrorShield_Mirror2", mirrorShieldMirror.changedCvar, 48, gsDPSetEnvColor(color.r / 3, color.g / 3, color.b / 3, 255)); - PATCH_GFX(gLinkAdultMirrorShieldSwordAndSheathNearDL, "MirrorShield_Mirror3", mirrorShieldMirror.changedCvar, 17, gsDPSetPrimColor(0, 0, color.r, color.g, color.b, 255)); - PATCH_GFX(gLinkAdultMirrorShieldSwordAndSheathFarDL, "MirrorShield_Mirror4", mirrorShieldMirror.changedCvar, 33, gsDPSetPrimColor(0, 0, color.r, color.g, color.b, 255)); - PATCH_GFX(gLinkAdultMirrorShieldAndSheathNearDL, "MirrorShield_Mirror5", mirrorShieldMirror.changedCvar, 17, gsDPSetPrimColor(0, 0, color.r, color.g, color.b, 255)); - PATCH_GFX(gLinkAdultMirrorShieldAndSheathFarDL, "MirrorShield_Mirror6", mirrorShieldMirror.changedCvar, 33, gsDPSetPrimColor(0, 0, color.r, color.g, color.b, 255)); - PATCH_GFX(gLinkAdultRightHandHoldingMirrorShieldNearDL, "MirrorShield_Mirror7", mirrorShieldMirror.changedCvar, 17, gsDPSetPrimColor(0, 0, color.r, color.g, color.b, 255)); - PATCH_GFX(gLinkAdultRightHandHoldingMirrorShieldFarDL, "MirrorShield_Mirror8", mirrorShieldMirror.changedCvar, 111, gsDPSetPrimColor(0, 0, color.r, color.g, color.b, 255)); + PATCH_GFX(gGiMirrorShieldDL, "MirrorShield_Mirror1", mirrorShieldMirror.changedCvar, 47, + gsDPSetPrimColor(0, 0, color.r, color.g, color.b, 255)); + PATCH_GFX(gGiMirrorShieldDL, "MirrorShield_Mirror2", mirrorShieldMirror.changedCvar, 48, + gsDPSetEnvColor(color.r / 3, color.g / 3, color.b / 3, 255)); + PATCH_GFX(gLinkAdultMirrorShieldSwordAndSheathNearDL, "MirrorShield_Mirror3", mirrorShieldMirror.changedCvar, + 17, gsDPSetPrimColor(0, 0, color.r, color.g, color.b, 255)); + PATCH_GFX(gLinkAdultMirrorShieldSwordAndSheathFarDL, "MirrorShield_Mirror4", mirrorShieldMirror.changedCvar, 33, + gsDPSetPrimColor(0, 0, color.r, color.g, color.b, 255)); + PATCH_GFX(gLinkAdultMirrorShieldAndSheathNearDL, "MirrorShield_Mirror5", mirrorShieldMirror.changedCvar, 17, + gsDPSetPrimColor(0, 0, color.r, color.g, color.b, 255)); + PATCH_GFX(gLinkAdultMirrorShieldAndSheathFarDL, "MirrorShield_Mirror6", mirrorShieldMirror.changedCvar, 33, + gsDPSetPrimColor(0, 0, color.r, color.g, color.b, 255)); + PATCH_GFX(gLinkAdultRightHandHoldingMirrorShieldNearDL, "MirrorShield_Mirror7", mirrorShieldMirror.changedCvar, + 17, gsDPSetPrimColor(0, 0, color.r, color.g, color.b, 255)); + PATCH_GFX(gLinkAdultRightHandHoldingMirrorShieldFarDL, "MirrorShield_Mirror8", mirrorShieldMirror.changedCvar, + 111, gsDPSetPrimColor(0, 0, color.r, color.g, color.b, 255)); } static CosmeticOption& mirrorShieldEmblem = cosmeticOptions.at("MirrorShield.Emblem"); if (manualChange || CVarGetInteger(mirrorShieldEmblem.rainbowCvar, 0)) { Color_RGBA8 color = CVarGetColor(mirrorShieldEmblem.valuesCvar, mirrorShieldEmblem.defaultColor); - PATCH_GFX(gGiMirrorShieldSymbolDL, "MirrorShield_Emblem1", mirrorShieldEmblem.changedCvar, 5, gsDPSetPrimColor(0, 0, color.r, color.g, color.b, 140)); - PATCH_GFX(gGiMirrorShieldSymbolDL, "MirrorShield_Emblem2", mirrorShieldEmblem.changedCvar, 6, gsDPSetEnvColor(color.r / 3, color.g / 3, color.b / 3, 255)); - PATCH_GFX(gLinkAdultMirrorShieldSwordAndSheathNearDL, "MirrorShield_Emblem3", mirrorShieldEmblem.changedCvar, 165, gsDPSetPrimColor(0, 0, color.r, color.g, color.b, 255)); - PATCH_GFX(gLinkAdultMirrorShieldSwordAndSheathFarDL, "MirrorShield_Emblem4", mirrorShieldEmblem.changedCvar, 135, gsDPSetPrimColor(0, 0, color.r, color.g, color.b, 255)); - PATCH_GFX(gLinkAdultMirrorShieldAndSheathNearDL, "MirrorShield_Emblem5", mirrorShieldEmblem.changedCvar, 129, gsDPSetPrimColor(0, 0, color.r, color.g, color.b, 255)); - PATCH_GFX(gLinkAdultMirrorShieldAndSheathFarDL, "MirrorShield_Emblem6", mirrorShieldEmblem.changedCvar, 103, gsDPSetPrimColor(0, 0, color.r, color.g, color.b, 255)); - PATCH_GFX(gLinkAdultRightHandHoldingMirrorShieldNearDL, "MirrorShield_Emblem7", mirrorShieldEmblem.changedCvar, 162, gsDPSetPrimColor(0, 0, color.r, color.g, color.b, 255)); - PATCH_GFX(gLinkAdultRightHandHoldingMirrorShieldFarDL, "MirrorShield_Emblem8", mirrorShieldEmblem.changedCvar, 133, gsDPSetPrimColor(0, 0, color.r, color.g, color.b, 255)); + PATCH_GFX(gGiMirrorShieldSymbolDL, "MirrorShield_Emblem1", mirrorShieldEmblem.changedCvar, 5, + gsDPSetPrimColor(0, 0, color.r, color.g, color.b, 140)); + PATCH_GFX(gGiMirrorShieldSymbolDL, "MirrorShield_Emblem2", mirrorShieldEmblem.changedCvar, 6, + gsDPSetEnvColor(color.r / 3, color.g / 3, color.b / 3, 255)); + PATCH_GFX(gLinkAdultMirrorShieldSwordAndSheathNearDL, "MirrorShield_Emblem3", mirrorShieldEmblem.changedCvar, + 165, gsDPSetPrimColor(0, 0, color.r, color.g, color.b, 255)); + PATCH_GFX(gLinkAdultMirrorShieldSwordAndSheathFarDL, "MirrorShield_Emblem4", mirrorShieldEmblem.changedCvar, + 135, gsDPSetPrimColor(0, 0, color.r, color.g, color.b, 255)); + PATCH_GFX(gLinkAdultMirrorShieldAndSheathNearDL, "MirrorShield_Emblem5", mirrorShieldEmblem.changedCvar, 129, + gsDPSetPrimColor(0, 0, color.r, color.g, color.b, 255)); + PATCH_GFX(gLinkAdultMirrorShieldAndSheathFarDL, "MirrorShield_Emblem6", mirrorShieldEmblem.changedCvar, 103, + gsDPSetPrimColor(0, 0, color.r, color.g, color.b, 255)); + PATCH_GFX(gLinkAdultRightHandHoldingMirrorShieldNearDL, "MirrorShield_Emblem7", mirrorShieldEmblem.changedCvar, + 162, gsDPSetPrimColor(0, 0, color.r, color.g, color.b, 255)); + PATCH_GFX(gLinkAdultRightHandHoldingMirrorShieldFarDL, "MirrorShield_Emblem8", mirrorShieldEmblem.changedCvar, + 133, gsDPSetPrimColor(0, 0, color.r, color.g, color.b, 255)); } static CosmeticOption& swordsKokiriBlade = cosmeticOptions.at("Swords.KokiriBlade"); if (manualChange || CVarGetInteger(swordsKokiriBlade.rainbowCvar, 0)) { Color_RGBA8 color = CVarGetColor(swordsKokiriBlade.valuesCvar, swordsKokiriBlade.defaultColor); - PATCH_GFX(gLinkChildLeftFistAndKokiriSwordNearDL, "Swords_KokiriBlade1", swordsKokiriBlade.changedCvar, 79, gsDPSetPrimColor(0, 0, color.r, color.g, color.b, 255)); - PATCH_GFX(gLinkChildLeftFistAndKokiriSwordFarDL, "Swords_KokiriBlade2", swordsKokiriBlade.changedCvar, 75, gsDPSetPrimColor(0, 0, color.r, color.g, color.b, 255)); - PATCH_GFX(gGiKokiriSwordDL, "Swords_KokiriBlade3", swordsKokiriBlade.changedCvar, 5, gsDPSetPrimColor(0, 0, color.r, color.g, color.b, 255)); - PATCH_GFX(gGiKokiriSwordDL, "Swords_KokiriBlade4", swordsKokiriBlade.changedCvar, 6, gsDPSetEnvColor(color.r / 4, color.g / 4, color.b / 4, 255)); + PATCH_GFX(gLinkChildLeftFistAndKokiriSwordNearDL, "Swords_KokiriBlade1", swordsKokiriBlade.changedCvar, 79, + gsDPSetPrimColor(0, 0, color.r, color.g, color.b, 255)); + PATCH_GFX(gLinkChildLeftFistAndKokiriSwordFarDL, "Swords_KokiriBlade2", swordsKokiriBlade.changedCvar, 75, + gsDPSetPrimColor(0, 0, color.r, color.g, color.b, 255)); + PATCH_GFX(gGiKokiriSwordDL, "Swords_KokiriBlade3", swordsKokiriBlade.changedCvar, 5, + gsDPSetPrimColor(0, 0, color.r, color.g, color.b, 255)); + PATCH_GFX(gGiKokiriSwordDL, "Swords_KokiriBlade4", swordsKokiriBlade.changedCvar, 6, + gsDPSetEnvColor(color.r / 4, color.g / 4, color.b / 4, 255)); } /* static CosmeticOption& swordsKokiriHilt = cosmeticOptions.at("Swords.KokiriHilt"); if (manualChange || CVarGetInteger(swordsKokiriHilt.rainbowCvar, 0)) { Color_RGBA8 color = CVarGetColor(swordsKokiriHilt.valuesCvar, swordsKokiriHilt.defaultColor); - PATCH_GFX(gLinkChildLeftFistAndKokiriSwordNearDL, "Swords_KokiriHilt1", swordsKokiriHilt.changedCvar, 4, gsDPSetGrayscaleColor(color.r, color.g, color.b, 255)); - PATCH_GFX(gLinkChildLeftFistAndKokiriSwordFarDL, "Swords_KokiriHilt2", swordsKokiriHilt.changedCvar, 4, gsDPSetGrayscaleColor(color.r, color.g, color.b, 255)); - PATCH_GFX(gLinkChildSwordAndSheathNearDL, "Swords_KokiriHilt3", swordsKokiriHilt.changedCvar, 4, gsDPSetGrayscaleColor(color.r, color.g, color.b, 255)); - PATCH_GFX(gLinkChildSwordAndSheathFarDL, "Swords_KokiriHilt4", swordsKokiriHilt.changedCvar, 4, gsDPSetGrayscaleColor(color.r, color.g, color.b, 255)); - PATCH_GFX(gLinkChildDekuShieldSwordAndSheathNearDL, "Swords_KokiriHilt5", swordsKokiriHilt.changedCvar, 4, gsDPSetGrayscaleColor(color.r, color.g, color.b, 255)); - PATCH_GFX(gLinkChildDekuShieldSwordAndSheathFarDL, "Swords_KokiriHilt6", swordsKokiriHilt.changedCvar, 4, gsDPSetGrayscaleColor(color.r, color.g, color.b, 255)); - PATCH_GFX(gLinkChildHylianShieldSwordAndSheathNearDL, "Swords_KokiriHilt7", swordsKokiriHilt.changedCvar, 4, gsDPSetGrayscaleColor(color.r, color.g, color.b, 255)); - PATCH_GFX(gLinkChildHylianShieldSwordAndSheathFarDL, "Swords_KokiriHilt8", swordsKokiriHilt.changedCvar, 4, gsDPSetGrayscaleColor(color.r, color.g, color.b, 255)); - PATCH_GFX(gGiKokiriSwordDL, "Swords_KokiriHilt9", swordsKokiriHilt.changedCvar, 64, gsDPSetPrimColor(0, 0, MAX(color.r - 50, 0), MAX(color.g - 50, 0), MAX(color.b - 50, 0), 255)); - PATCH_GFX(gGiKokiriSwordDL, "Swords_KokiriHilt10", swordsKokiriHilt.changedCvar, 66, gsDPSetEnvColor(MAX(color.r - 50, 0) / 3, MAX(color.g - 50, 0) / 3, MAX(color.b - 50, 0) / 3, 255)); - PATCH_GFX(gGiKokiriSwordDL, "Swords_KokiriHilt11", swordsKokiriHilt.changedCvar, 162, gsDPSetPrimColor(0, 0, color.r, color.g, color.b, 255)); - PATCH_GFX(gGiKokiriSwordDL, "Swords_KokiriHilt12", swordsKokiriHilt.changedCvar, 164, gsDPSetEnvColor(color.r / 3, color.g / 3, color.b / 3, 255)); + PATCH_GFX(gLinkChildLeftFistAndKokiriSwordNearDL, "Swords_KokiriHilt1", swordsKokiriHilt.changedCvar, 4, + gsDPSetGrayscaleColor(color.r, color.g, color.b, 255)); PATCH_GFX(gLinkChildLeftFistAndKokiriSwordFarDL, + "Swords_KokiriHilt2", swordsKokiriHilt.changedCvar, 4, gsDPSetGrayscaleColor(color.r, color.g, + color.b, 255)); PATCH_GFX(gLinkChildSwordAndSheathNearDL, "Swords_KokiriHilt3", + swordsKokiriHilt.changedCvar, 4, gsDPSetGrayscaleColor(color.r, color.g, color.b, 255)); + PATCH_GFX(gLinkChildSwordAndSheathFarDL, "Swords_KokiriHilt4", swordsKokiriHilt.changedCvar, 4, + gsDPSetGrayscaleColor(color.r, color.g, color.b, 255)); PATCH_GFX(gLinkChildDekuShieldSwordAndSheathNearDL, + "Swords_KokiriHilt5", swordsKokiriHilt.changedCvar, 4, gsDPSetGrayscaleColor(color.r, color.g, + color.b, 255)); PATCH_GFX(gLinkChildDekuShieldSwordAndSheathFarDL, "Swords_KokiriHilt6", + swordsKokiriHilt.changedCvar, 4, gsDPSetGrayscaleColor(color.r, color.g, color.b, 255)); + PATCH_GFX(gLinkChildHylianShieldSwordAndSheathNearDL, "Swords_KokiriHilt7", swordsKokiriHilt.changedCvar, 4, + gsDPSetGrayscaleColor(color.r, color.g, color.b, 255)); PATCH_GFX(gLinkChildHylianShieldSwordAndSheathFarDL, + "Swords_KokiriHilt8", swordsKokiriHilt.changedCvar, 4, gsDPSetGrayscaleColor(color.r, color.g, + color.b, 255)); PATCH_GFX(gGiKokiriSwordDL, "Swords_KokiriHilt9", + swordsKokiriHilt.changedCvar, 64, gsDPSetPrimColor(0, 0, MAX(color.r - 50, 0), MAX(color.g - 50, 0), + MAX(color.b - 50, 0), 255)); PATCH_GFX(gGiKokiriSwordDL, "Swords_KokiriHilt10", + swordsKokiriHilt.changedCvar, 66, gsDPSetEnvColor(MAX(color.r - 50, 0) / 3, MAX(color.g - 50, 0) / 3, + MAX(color.b - 50, 0) / 3, 255)); PATCH_GFX(gGiKokiriSwordDL, "Swords_KokiriHilt11", + swordsKokiriHilt.changedCvar, 162, gsDPSetPrimColor(0, 0, color.r, color.g, color.b, 255)); + PATCH_GFX(gGiKokiriSwordDL, "Swords_KokiriHilt12", swordsKokiriHilt.changedCvar, + 164, gsDPSetEnvColor(color.r / 3, color.g / 3, color.b / 3, 255)); if (manualChange) { - PATCH_GFX(gLinkChildLeftFistAndKokiriSwordNearDL, "Swords_KokiriHilt13", swordsKokiriHilt.changedCvar, 108, gsSPGrayscale(true)); - PATCH_GFX(gLinkChildLeftFistAndKokiriSwordNearDL, "Swords_KokiriHilt14", swordsKokiriHilt.changedCvar, 134, gsSPGrayscale(false)); - PATCH_GFX(gLinkChildLeftFistAndKokiriSwordFarDL, "Swords_KokiriHilt15", swordsKokiriHilt.changedCvar, 106, gsSPGrayscale(true)); - PATCH_GFX(gLinkChildLeftFistAndKokiriSwordFarDL, "Swords_KokiriHilt16", swordsKokiriHilt.changedCvar, 126, gsSPGrayscale(false)); - PATCH_GFX(gLinkChildSwordAndSheathNearDL, "Swords_KokiriHilt17", swordsKokiriHilt.changedCvar, 100, gsSPGrayscale(true)); - PATCH_GFX(gLinkChildSwordAndSheathNearDL, "Swords_KokiriHilt18", swordsKokiriHilt.changedCvar, 126, gsSPGrayscale(false)); - PATCH_GFX(gLinkChildSwordAndSheathNearDL, "Swords_KokiriHilt19", swordsKokiriHilt.changedCvar, 128, gsSPEndDisplayList()); - PATCH_GFX(gLinkChildSwordAndSheathFarDL, "Swords_KokiriHilt20", swordsKokiriHilt.changedCvar, 98, gsSPGrayscale(true)); - PATCH_GFX(gLinkChildSwordAndSheathFarDL, "Swords_KokiriHilt21", swordsKokiriHilt.changedCvar, 118, gsSPGrayscale(false)); - PATCH_GFX(gLinkChildSwordAndSheathFarDL, "Swords_KokiriHilt22", swordsKokiriHilt.changedCvar, 120, gsSPEndDisplayList()); - PATCH_GFX(gLinkChildDekuShieldSwordAndSheathNearDL, "Swords_KokiriHilt23", swordsKokiriHilt.changedCvar, 166, gsSPGrayscale(true)); - PATCH_GFX(gLinkChildDekuShieldSwordAndSheathNearDL, "Swords_KokiriHilt24", swordsKokiriHilt.changedCvar, 192, gsSPGrayscale(false)); - PATCH_GFX(gLinkChildDekuShieldSwordAndSheathNearDL, "Swords_KokiriHilt25", swordsKokiriHilt.changedCvar, 194, gsSPEndDisplayList()); - PATCH_GFX(gLinkChildDekuShieldSwordAndSheathFarDL, "Swords_KokiriHilt26", swordsKokiriHilt.changedCvar, 156, gsSPGrayscale(true)); - PATCH_GFX(gLinkChildDekuShieldSwordAndSheathFarDL, "Swords_KokiriHilt27", swordsKokiriHilt.changedCvar, 176, gsSPGrayscale(false)); - PATCH_GFX(gLinkChildDekuShieldSwordAndSheathFarDL, "Swords_KokiriHilt28", swordsKokiriHilt.changedCvar, 178, gsSPEndDisplayList()); - PATCH_GFX(gLinkChildHylianShieldSwordAndSheathNearDL, "Swords_KokiriHilt29", swordsKokiriHilt.changedCvar, 162, gsSPGrayscale(true)); - PATCH_GFX(gLinkChildHylianShieldSwordAndSheathNearDL, "Swords_KokiriHilt30", swordsKokiriHilt.changedCvar, 188, gsSPGrayscale(false)); - PATCH_GFX(gLinkChildHylianShieldSwordAndSheathNearDL, "Swords_KokiriHilt31", swordsKokiriHilt.changedCvar, 190, gsSPEndDisplayList()); - PATCH_GFX(gLinkChildHylianShieldSwordAndSheathFarDL, "Swords_KokiriHilt32", swordsKokiriHilt.changedCvar, 98, gsSPGrayscale(true)); - PATCH_GFX(gLinkChildHylianShieldSwordAndSheathFarDL, "Swords_KokiriHilt33", swordsKokiriHilt.changedCvar, 118, gsSPGrayscale(false)); + PATCH_GFX(gLinkChildLeftFistAndKokiriSwordNearDL, "Swords_KokiriHilt13", swordsKokiriHilt.changedCvar, + 108, gsSPGrayscale(true)); PATCH_GFX(gLinkChildLeftFistAndKokiriSwordNearDL, "Swords_KokiriHilt14", + swordsKokiriHilt.changedCvar, 134, gsSPGrayscale(false)); PATCH_GFX(gLinkChildLeftFistAndKokiriSwordFarDL, + "Swords_KokiriHilt15", swordsKokiriHilt.changedCvar, 106, gsSPGrayscale(true)); + PATCH_GFX(gLinkChildLeftFistAndKokiriSwordFarDL, "Swords_KokiriHilt16", swordsKokiriHilt.changedCvar, + 126, gsSPGrayscale(false)); PATCH_GFX(gLinkChildSwordAndSheathNearDL, "Swords_KokiriHilt17", + swordsKokiriHilt.changedCvar, 100, gsSPGrayscale(true)); PATCH_GFX(gLinkChildSwordAndSheathNearDL, + "Swords_KokiriHilt18", swordsKokiriHilt.changedCvar, 126, gsSPGrayscale(false)); + PATCH_GFX(gLinkChildSwordAndSheathNearDL, "Swords_KokiriHilt19", swordsKokiriHilt.changedCvar, + 128, gsSPEndDisplayList()); PATCH_GFX(gLinkChildSwordAndSheathFarDL, "Swords_KokiriHilt20", + swordsKokiriHilt.changedCvar, 98, gsSPGrayscale(true)); PATCH_GFX(gLinkChildSwordAndSheathFarDL, + "Swords_KokiriHilt21", swordsKokiriHilt.changedCvar, 118, gsSPGrayscale(false)); + PATCH_GFX(gLinkChildSwordAndSheathFarDL, "Swords_KokiriHilt22", swordsKokiriHilt.changedCvar, + 120, gsSPEndDisplayList()); PATCH_GFX(gLinkChildDekuShieldSwordAndSheathNearDL, "Swords_KokiriHilt23", + swordsKokiriHilt.changedCvar, 166, gsSPGrayscale(true)); PATCH_GFX(gLinkChildDekuShieldSwordAndSheathNearDL, + "Swords_KokiriHilt24", swordsKokiriHilt.changedCvar, 192, gsSPGrayscale(false)); + PATCH_GFX(gLinkChildDekuShieldSwordAndSheathNearDL, "Swords_KokiriHilt25", swordsKokiriHilt.changedCvar, + 194, gsSPEndDisplayList()); PATCH_GFX(gLinkChildDekuShieldSwordAndSheathFarDL, "Swords_KokiriHilt26", + swordsKokiriHilt.changedCvar, 156, gsSPGrayscale(true)); PATCH_GFX(gLinkChildDekuShieldSwordAndSheathFarDL, + "Swords_KokiriHilt27", swordsKokiriHilt.changedCvar, 176, gsSPGrayscale(false)); + PATCH_GFX(gLinkChildDekuShieldSwordAndSheathFarDL, "Swords_KokiriHilt28", swordsKokiriHilt.changedCvar, + 178, gsSPEndDisplayList()); PATCH_GFX(gLinkChildHylianShieldSwordAndSheathNearDL, "Swords_KokiriHilt29", + swordsKokiriHilt.changedCvar, 162, gsSPGrayscale(true)); PATCH_GFX(gLinkChildHylianShieldSwordAndSheathNearDL, + "Swords_KokiriHilt30", swordsKokiriHilt.changedCvar, 188, gsSPGrayscale(false)); + PATCH_GFX(gLinkChildHylianShieldSwordAndSheathNearDL, "Swords_KokiriHilt31", swordsKokiriHilt.changedCvar, + 190, gsSPEndDisplayList()); PATCH_GFX(gLinkChildHylianShieldSwordAndSheathFarDL, "Swords_KokiriHilt32", + swordsKokiriHilt.changedCvar, 98, gsSPGrayscale(true)); PATCH_GFX(gLinkChildHylianShieldSwordAndSheathFarDL, + "Swords_KokiriHilt33", swordsKokiriHilt.changedCvar, 118, gsSPGrayscale(false)); } } */ static CosmeticOption& swordsMasterBlade = cosmeticOptions.at("Swords.MasterBlade"); if (manualChange || CVarGetInteger(swordsMasterBlade.rainbowCvar, 0)) { Color_RGBA8 color = CVarGetColor(swordsMasterBlade.valuesCvar, swordsMasterBlade.defaultColor); - PATCH_GFX(gLinkAdultLeftHandHoldingMasterSwordFarDL, "Swords_MasterBlade1", swordsMasterBlade.changedCvar, 60, gsDPSetPrimColor(0, 0, color.r, color.g, color.b, 255)); - PATCH_GFX(gLinkAdultLeftHandHoldingMasterSwordNearDL, "Swords_MasterBlade2", swordsMasterBlade.changedCvar, 17, gsDPSetPrimColor(0, 0, color.r, color.g, color.b, 255)); - PATCH_GFX(object_toki_objects_DL_001BD0, "Swords_MasterBlade3", swordsMasterBlade.changedCvar, 13, gsDPSetPrimColor(0, 0, color.r, color.g, color.b, 255)); - PATCH_GFX(object_toki_objects_DL_001BD0, "Swords_MasterBlade4", swordsMasterBlade.changedCvar, 14, gsDPSetEnvColor(color.r / 2, color.g / 2, color.b / 2, 255)); - PATCH_GFX(gGanonMasterSwordDL, "Swords_MasterBlade5", swordsMasterBlade.changedCvar, 13, gsDPSetPrimColor(0, 0, color.r, color.g, color.b, 255)); - PATCH_GFX(gGanonMasterSwordDL, "Swords_MasterBlade6", swordsMasterBlade.changedCvar, 14, gsDPSetEnvColor(color.r / 2, color.g / 2, color.b / 2, 255)); + PATCH_GFX(gLinkAdultLeftHandHoldingMasterSwordFarDL, "Swords_MasterBlade1", swordsMasterBlade.changedCvar, 60, + gsDPSetPrimColor(0, 0, color.r, color.g, color.b, 255)); + PATCH_GFX(gLinkAdultLeftHandHoldingMasterSwordNearDL, "Swords_MasterBlade2", swordsMasterBlade.changedCvar, 17, + gsDPSetPrimColor(0, 0, color.r, color.g, color.b, 255)); + PATCH_GFX(object_toki_objects_DL_001BD0, "Swords_MasterBlade3", swordsMasterBlade.changedCvar, 13, + gsDPSetPrimColor(0, 0, color.r, color.g, color.b, 255)); + PATCH_GFX(object_toki_objects_DL_001BD0, "Swords_MasterBlade4", swordsMasterBlade.changedCvar, 14, + gsDPSetEnvColor(color.r / 2, color.g / 2, color.b / 2, 255)); + PATCH_GFX(gGanonMasterSwordDL, "Swords_MasterBlade5", swordsMasterBlade.changedCvar, 13, + gsDPSetPrimColor(0, 0, color.r, color.g, color.b, 255)); + PATCH_GFX(gGanonMasterSwordDL, "Swords_MasterBlade6", swordsMasterBlade.changedCvar, 14, + gsDPSetEnvColor(color.r / 2, color.g / 2, color.b / 2, 255)); } /* static CosmeticOption& swordsMasterHilt = cosmeticOptions.at("Swords.MasterHilt"); if (manualChange || CVarGetInteger(swordsMasterHilt.rainbowCvar, 0)) { Color_RGBA8 color = CVarGetColor(swordsMasterHilt.valuesCvar, swordsMasterHilt.defaultColor); - PATCH_GFX(gLinkAdultLeftHandHoldingMasterSwordNearDL, "Swords_MasterHilt1", swordsMasterHilt.changedCvar, 20, gsDPSetGrayscaleColor(color.r, color.g, color.b, 255)); - PATCH_GFX(gLinkAdultLeftHandHoldingMasterSwordFarDL, "Swords_MasterHilt2", swordsMasterHilt.changedCvar, 20, gsDPSetGrayscaleColor(color.r, color.g, color.b, 255)); - PATCH_GFX(object_toki_objects_DL_001BD0, "Swords_MasterHilt3", swordsMasterHilt.changedCvar, 16, gsDPSetGrayscaleColor(color.r, color.g, color.b, 255)); - PATCH_GFX(gLinkAdultMasterSwordAndSheathNearDL, "Swords_MasterHilt4", swordsMasterHilt.changedCvar, 4, gsDPSetGrayscaleColor(color.r, color.g, color.b, 255)); - PATCH_GFX(gLinkAdultMasterSwordAndSheathFarDL, "Swords_MasterHilt5", swordsMasterHilt.changedCvar, 4, gsDPSetGrayscaleColor(color.r, color.g, color.b, 255)); - PATCH_GFX(gLinkAdultMirrorShieldSwordAndSheathNearDL, "Swords_MasterHilt6", swordsMasterHilt.changedCvar, 4, gsDPSetGrayscaleColor(color.r, color.g, color.b, 255)); - PATCH_GFX(gLinkAdultMirrorShieldSwordAndSheathFarDL, "Swords_MasterHilt7", swordsMasterHilt.changedCvar, 4, gsDPSetGrayscaleColor(color.r, color.g, color.b, 255)); - PATCH_GFX(gLinkAdultHylianShieldSwordAndSheathNearDL, "Swords_MasterHilt8", swordsMasterHilt.changedCvar, 4, gsDPSetGrayscaleColor(color.r, color.g, color.b, 255)); - PATCH_GFX(gLinkAdultHylianShieldSwordAndSheathFarDL, "Swords_MasterHilt9", swordsMasterHilt.changedCvar, 4, gsDPSetGrayscaleColor(color.r, color.g, color.b, 255)); - PATCH_GFX(gGanonMasterSwordDL, "Swords_MasterHilt10", swordsMasterHilt.changedCvar, 16, gsDPSetGrayscaleColor(color.r, color.g, color.b, 255)); + PATCH_GFX(gLinkAdultLeftHandHoldingMasterSwordNearDL, "Swords_MasterHilt1", swordsMasterHilt.changedCvar, + 20, gsDPSetGrayscaleColor(color.r, color.g, color.b, 255)); PATCH_GFX(gLinkAdultLeftHandHoldingMasterSwordFarDL, + "Swords_MasterHilt2", swordsMasterHilt.changedCvar, 20, gsDPSetGrayscaleColor(color.r, color.g, + color.b, 255)); PATCH_GFX(object_toki_objects_DL_001BD0, "Swords_MasterHilt3", + swordsMasterHilt.changedCvar, 16, gsDPSetGrayscaleColor(color.r, color.g, color.b, 255)); + PATCH_GFX(gLinkAdultMasterSwordAndSheathNearDL, "Swords_MasterHilt4", swordsMasterHilt.changedCvar, 4, + gsDPSetGrayscaleColor(color.r, color.g, color.b, 255)); PATCH_GFX(gLinkAdultMasterSwordAndSheathFarDL, + "Swords_MasterHilt5", swordsMasterHilt.changedCvar, 4, gsDPSetGrayscaleColor(color.r, color.g, + color.b, 255)); PATCH_GFX(gLinkAdultMirrorShieldSwordAndSheathNearDL, "Swords_MasterHilt6", + swordsMasterHilt.changedCvar, 4, gsDPSetGrayscaleColor(color.r, color.g, color.b, 255)); + PATCH_GFX(gLinkAdultMirrorShieldSwordAndSheathFarDL, "Swords_MasterHilt7", swordsMasterHilt.changedCvar, 4, + gsDPSetGrayscaleColor(color.r, color.g, color.b, 255)); PATCH_GFX(gLinkAdultHylianShieldSwordAndSheathNearDL, + "Swords_MasterHilt8", swordsMasterHilt.changedCvar, 4, gsDPSetGrayscaleColor(color.r, color.g, + color.b, 255)); PATCH_GFX(gLinkAdultHylianShieldSwordAndSheathFarDL, "Swords_MasterHilt9", + swordsMasterHilt.changedCvar, 4, gsDPSetGrayscaleColor(color.r, color.g, color.b, 255)); + PATCH_GFX(gGanonMasterSwordDL, "Swords_MasterHilt10", swordsMasterHilt.changedCvar, + 16, gsDPSetGrayscaleColor(color.r, color.g, color.b, 255)); if (manualChange) { - PATCH_GFX(gLinkAdultMasterSwordAndSheathFarDL, "Swords_MasterHilt11", swordsMasterHilt.changedCvar, 38, gsSPGrayscale(true)); - PATCH_GFX(gLinkAdultMasterSwordAndSheathFarDL, "Swords_MasterHilt12", swordsMasterHilt.changedCvar, 64, gsSPGrayscale(false)); - PATCH_GFX(gLinkAdultMasterSwordAndSheathFarDL, "Swords_MasterHilt13", swordsMasterHilt.changedCvar, 106, gsSPGrayscale(true)); - PATCH_GFX(gLinkAdultMasterSwordAndSheathFarDL, "Swords_MasterHilt14", swordsMasterHilt.changedCvar, 120, gsSPGrayscale(false)); - PATCH_GFX(gLinkAdultMasterSwordAndSheathNearDL, "Swords_MasterHilt15", swordsMasterHilt.changedCvar, 104, gsSPGrayscale(true)); - PATCH_GFX(gLinkAdultMasterSwordAndSheathNearDL, "Swords_MasterHilt16", swordsMasterHilt.changedCvar, 182, gsSPGrayscale(false)); - PATCH_GFX(gLinkAdultMasterSwordAndSheathNearDL, "Swords_MasterHilt17", swordsMasterHilt.changedCvar, 184, gsSPEndDisplayList()); - PATCH_GFX(gLinkAdultHylianShieldSwordAndSheathFarDL, "Swords_MasterHilt18", swordsMasterHilt.changedCvar, 80, gsSPGrayscale(true)); - PATCH_GFX(gLinkAdultHylianShieldSwordAndSheathFarDL, "Swords_MasterHilt19", swordsMasterHilt.changedCvar, 94, gsSPGrayscale(false)); - PATCH_GFX(gLinkAdultHylianShieldSwordAndSheathFarDL, "Swords_MasterHilt20", swordsMasterHilt.changedCvar, 162, gsSPGrayscale(true)); - PATCH_GFX(gLinkAdultHylianShieldSwordAndSheathFarDL, "Swords_MasterHilt21", swordsMasterHilt.changedCvar, 180, gsSPGrayscale(false)); - PATCH_GFX(gLinkAdultHylianShieldSwordAndSheathNearDL, "Swords_MasterHilt22", swordsMasterHilt.changedCvar, 154, gsSPGrayscale(true)); - PATCH_GFX(gLinkAdultHylianShieldSwordAndSheathNearDL, "Swords_MasterHilt23", swordsMasterHilt.changedCvar, 232, gsSPGrayscale(false)); - PATCH_GFX(gLinkAdultMirrorShieldSwordAndSheathFarDL, "Swords_MasterHilt24", swordsMasterHilt.changedCvar, 112, gsSPGrayscale(true)); - PATCH_GFX(gLinkAdultMirrorShieldSwordAndSheathFarDL, "Swords_MasterHilt25", swordsMasterHilt.changedCvar, 130, gsSPGrayscale(false)); - PATCH_GFX(gLinkAdultMirrorShieldSwordAndSheathFarDL, "Swords_MasterHilt26", swordsMasterHilt.changedCvar, 172, gsSPGrayscale(true)); - PATCH_GFX(gLinkAdultMirrorShieldSwordAndSheathFarDL, "Swords_MasterHilt27", swordsMasterHilt.changedCvar, 186, gsSPGrayscale(false)); - PATCH_GFX(gLinkAdultMirrorShieldSwordAndSheathNearDL, "Swords_MasterHilt28", swordsMasterHilt.changedCvar, 220, gsSPGrayscale(true)); - PATCH_GFX(gLinkAdultMirrorShieldSwordAndSheathNearDL, "Swords_MasterHilt29", swordsMasterHilt.changedCvar, 298, gsSPGrayscale(false)); - PATCH_GFX(gLinkAdultLeftHandHoldingMasterSwordFarDL, "Swords_MasterHilt30", swordsMasterHilt.changedCvar, 38, gsSPGrayscale(true)); - PATCH_GFX(gLinkAdultLeftHandHoldingMasterSwordFarDL, "Swords_MasterHilt31", swordsMasterHilt.changedCvar, 112, gsSPGrayscale(false)); - PATCH_GFX(gLinkAdultLeftHandHoldingMasterSwordNearDL, "Swords_MasterHilt32", swordsMasterHilt.changedCvar, 86, gsSPGrayscale(true)); - PATCH_GFX(gLinkAdultLeftHandHoldingMasterSwordNearDL, "Swords_MasterHilt33", swordsMasterHilt.changedCvar, 208, gsSPGrayscale(false)); - PATCH_GFX(object_toki_objects_DL_001BD0, "Swords_MasterHilt34", swordsMasterHilt.changedCvar, 112, gsSPGrayscale(true)); - PATCH_GFX(object_toki_objects_DL_001BD0, "Swords_MasterHilt35", swordsMasterHilt.changedCvar, 278, gsSPGrayscale(false)); - PATCH_GFX(object_toki_objects_DL_001BD0, "Swords_MasterHilt36", swordsMasterHilt.changedCvar, 280, gsSPEndDisplayList()); - PATCH_GFX(gGanonMasterSwordDL, "Swords_MasterHilt37", swordsMasterHilt.changedCvar, 112, gsSPGrayscale(true)); - PATCH_GFX(gGanonMasterSwordDL, "Swords_MasterHilt38", swordsMasterHilt.changedCvar, 278, gsSPGrayscale(false)); - PATCH_GFX(gGanonMasterSwordDL, "Swords_MasterHilt39", swordsMasterHilt.changedCvar, 280, gsSPEndDisplayList()); + PATCH_GFX(gLinkAdultMasterSwordAndSheathFarDL, "Swords_MasterHilt11", swordsMasterHilt.changedCvar, + 38, gsSPGrayscale(true)); PATCH_GFX(gLinkAdultMasterSwordAndSheathFarDL, "Swords_MasterHilt12", + swordsMasterHilt.changedCvar, 64, gsSPGrayscale(false)); PATCH_GFX(gLinkAdultMasterSwordAndSheathFarDL, + "Swords_MasterHilt13", swordsMasterHilt.changedCvar, 106, gsSPGrayscale(true)); + PATCH_GFX(gLinkAdultMasterSwordAndSheathFarDL, "Swords_MasterHilt14", swordsMasterHilt.changedCvar, + 120, gsSPGrayscale(false)); PATCH_GFX(gLinkAdultMasterSwordAndSheathNearDL, "Swords_MasterHilt15", + swordsMasterHilt.changedCvar, 104, gsSPGrayscale(true)); PATCH_GFX(gLinkAdultMasterSwordAndSheathNearDL, + "Swords_MasterHilt16", swordsMasterHilt.changedCvar, 182, gsSPGrayscale(false)); + PATCH_GFX(gLinkAdultMasterSwordAndSheathNearDL, "Swords_MasterHilt17", swordsMasterHilt.changedCvar, + 184, gsSPEndDisplayList()); PATCH_GFX(gLinkAdultHylianShieldSwordAndSheathFarDL, "Swords_MasterHilt18", + swordsMasterHilt.changedCvar, 80, gsSPGrayscale(true)); PATCH_GFX(gLinkAdultHylianShieldSwordAndSheathFarDL, + "Swords_MasterHilt19", swordsMasterHilt.changedCvar, 94, gsSPGrayscale(false)); + PATCH_GFX(gLinkAdultHylianShieldSwordAndSheathFarDL, "Swords_MasterHilt20", swordsMasterHilt.changedCvar, + 162, gsSPGrayscale(true)); PATCH_GFX(gLinkAdultHylianShieldSwordAndSheathFarDL, "Swords_MasterHilt21", + swordsMasterHilt.changedCvar, 180, gsSPGrayscale(false)); + PATCH_GFX(gLinkAdultHylianShieldSwordAndSheathNearDL, "Swords_MasterHilt22", swordsMasterHilt.changedCvar, + 154, gsSPGrayscale(true)); PATCH_GFX(gLinkAdultHylianShieldSwordAndSheathNearDL, "Swords_MasterHilt23", + swordsMasterHilt.changedCvar, 232, gsSPGrayscale(false)); PATCH_GFX(gLinkAdultMirrorShieldSwordAndSheathFarDL, + "Swords_MasterHilt24", swordsMasterHilt.changedCvar, 112, gsSPGrayscale(true)); + PATCH_GFX(gLinkAdultMirrorShieldSwordAndSheathFarDL, "Swords_MasterHilt25", swordsMasterHilt.changedCvar, + 130, gsSPGrayscale(false)); PATCH_GFX(gLinkAdultMirrorShieldSwordAndSheathFarDL, "Swords_MasterHilt26", + swordsMasterHilt.changedCvar, 172, gsSPGrayscale(true)); PATCH_GFX(gLinkAdultMirrorShieldSwordAndSheathFarDL, + "Swords_MasterHilt27", swordsMasterHilt.changedCvar, 186, gsSPGrayscale(false)); + PATCH_GFX(gLinkAdultMirrorShieldSwordAndSheathNearDL, "Swords_MasterHilt28", swordsMasterHilt.changedCvar, + 220, gsSPGrayscale(true)); PATCH_GFX(gLinkAdultMirrorShieldSwordAndSheathNearDL, "Swords_MasterHilt29", + swordsMasterHilt.changedCvar, 298, gsSPGrayscale(false)); PATCH_GFX(gLinkAdultLeftHandHoldingMasterSwordFarDL, + "Swords_MasterHilt30", swordsMasterHilt.changedCvar, 38, gsSPGrayscale(true)); + PATCH_GFX(gLinkAdultLeftHandHoldingMasterSwordFarDL, "Swords_MasterHilt31", swordsMasterHilt.changedCvar, + 112, gsSPGrayscale(false)); PATCH_GFX(gLinkAdultLeftHandHoldingMasterSwordNearDL, "Swords_MasterHilt32", + swordsMasterHilt.changedCvar, 86, gsSPGrayscale(true)); PATCH_GFX(gLinkAdultLeftHandHoldingMasterSwordNearDL, + "Swords_MasterHilt33", swordsMasterHilt.changedCvar, 208, gsSPGrayscale(false)); + PATCH_GFX(object_toki_objects_DL_001BD0, "Swords_MasterHilt34", swordsMasterHilt.changedCvar, + 112, gsSPGrayscale(true)); PATCH_GFX(object_toki_objects_DL_001BD0, "Swords_MasterHilt35", + swordsMasterHilt.changedCvar, 278, gsSPGrayscale(false)); PATCH_GFX(object_toki_objects_DL_001BD0, + "Swords_MasterHilt36", swordsMasterHilt.changedCvar, 280, gsSPEndDisplayList()); + PATCH_GFX(gGanonMasterSwordDL, "Swords_MasterHilt37", swordsMasterHilt.changedCvar, + 112, gsSPGrayscale(true)); PATCH_GFX(gGanonMasterSwordDL, "Swords_MasterHilt38", + swordsMasterHilt.changedCvar, 278, gsSPGrayscale(false)); PATCH_GFX(gGanonMasterSwordDL, + "Swords_MasterHilt39", swordsMasterHilt.changedCvar, 280, gsSPEndDisplayList()); } } */ static CosmeticOption& swordsBiggoronBlade = cosmeticOptions.at("Swords.BiggoronBlade"); if (manualChange || CVarGetInteger(swordsBiggoronBlade.rainbowCvar, 0)) { Color_RGBA8 color = CVarGetColor(swordsBiggoronBlade.valuesCvar, swordsBiggoronBlade.defaultColor); - PATCH_GFX(gLinkAdultLeftHandHoldingBgsFarDL, "Swords_BiggoronBlade1", swordsBiggoronBlade.changedCvar, 108, gsDPSetPrimColor(0, 0, color.r, color.g, color.b, 255)); - PATCH_GFX(gLinkAdultLeftHandHoldingBgsNearDL, "Swords_BiggoronBlade2", swordsBiggoronBlade.changedCvar, 63, gsDPSetPrimColor(0, 0, color.r, color.g, color.b, 255)); - PATCH_GFX(gGiBiggoronSwordDL, "Swords_BiggoronBlade3", swordsBiggoronBlade.changedCvar, 5, gsDPSetPrimColor(0, 0, color.r, color.g, color.b, 255)); - PATCH_GFX(gGiBiggoronSwordDL, "Swords_BiggoronBlade4", swordsBiggoronBlade.changedCvar, 6, gsDPSetEnvColor(color.r / 3, color.g / 3, color.b / 3, 255)); + PATCH_GFX(gLinkAdultLeftHandHoldingBgsFarDL, "Swords_BiggoronBlade1", swordsBiggoronBlade.changedCvar, 108, + gsDPSetPrimColor(0, 0, color.r, color.g, color.b, 255)); + PATCH_GFX(gLinkAdultLeftHandHoldingBgsNearDL, "Swords_BiggoronBlade2", swordsBiggoronBlade.changedCvar, 63, + gsDPSetPrimColor(0, 0, color.r, color.g, color.b, 255)); + PATCH_GFX(gGiBiggoronSwordDL, "Swords_BiggoronBlade3", swordsBiggoronBlade.changedCvar, 5, + gsDPSetPrimColor(0, 0, color.r, color.g, color.b, 255)); + PATCH_GFX(gGiBiggoronSwordDL, "Swords_BiggoronBlade4", swordsBiggoronBlade.changedCvar, 6, + gsDPSetEnvColor(color.r / 3, color.g / 3, color.b / 3, 255)); } /* static CosmeticOption& swordsBiggoronHilt = cosmeticOptions.at("Swords.BiggoronHilt"); if (manualChange || CVarGetInteger(swordsBiggoronHilt.rainbowCvar, 0)) { Color_RGBA8 color = CVarGetColor(swordsBiggoronHilt.valuesCvar, swordsBiggoronHilt.defaultColor); - PATCH_GFX(gLinkAdultLeftHandHoldingBgsNearDL, "Swords_BiggoronHilt1", swordsBiggoronHilt.changedCvar, 20, gsDPSetGrayscaleColor(color.r, color.g, color.b, 255)); - PATCH_GFX(gLinkAdultLeftHandHoldingBgsFarDL, "Swords_BiggoronHilt2", swordsBiggoronHilt.changedCvar, 20, gsDPSetGrayscaleColor(color.r, color.g, color.b, 255)); - PATCH_GFX(gGiBiggoronSwordDL, "Swords_BiggoronHilt3", swordsBiggoronHilt.changedCvar, 74, gsDPSetPrimColor(0, 0, color.r, color.g, color.b, 255)); - PATCH_GFX(gGiBiggoronSwordDL, "Swords_BiggoronHilt4", swordsBiggoronHilt.changedCvar, 76, gsDPSetEnvColor(color.r / 3, color.g / 3, color.b / 3, 255)); - PATCH_GFX(gGiBiggoronSwordDL, "Swords_BiggoronHilt5", swordsBiggoronHilt.changedCvar, 154, gsDPSetPrimColor(0, 0, color.r, color.g, color.b, 255)); - PATCH_GFX(gGiBiggoronSwordDL, "Swords_BiggoronHilt6", swordsBiggoronHilt.changedCvar, 156, gsDPSetEnvColor(color.r / 3, color.g / 3, color.b / 3, 255)); + PATCH_GFX(gLinkAdultLeftHandHoldingBgsNearDL, "Swords_BiggoronHilt1", + swordsBiggoronHilt.changedCvar, 20, gsDPSetGrayscaleColor(color.r, color.g, color.b, 255)); + PATCH_GFX(gLinkAdultLeftHandHoldingBgsFarDL, "Swords_BiggoronHilt2", + swordsBiggoronHilt.changedCvar, 20, gsDPSetGrayscaleColor(color.r, color.g, color.b, 255)); + PATCH_GFX(gGiBiggoronSwordDL, "Swords_BiggoronHilt3", + swordsBiggoronHilt.changedCvar, 74, gsDPSetPrimColor(0, 0, color.r, color.g, color.b, 255)); + PATCH_GFX(gGiBiggoronSwordDL, "Swords_BiggoronHilt4", + swordsBiggoronHilt.changedCvar, 76, gsDPSetEnvColor(color.r / 3, color.g / 3, color.b / 3, 255)); + PATCH_GFX(gGiBiggoronSwordDL, "Swords_BiggoronHilt5", + swordsBiggoronHilt.changedCvar, 154, gsDPSetPrimColor(0, 0, color.r, color.g, color.b, 255)); + PATCH_GFX(gGiBiggoronSwordDL, "Swords_BiggoronHilt6", + swordsBiggoronHilt.changedCvar, 156, gsDPSetEnvColor(color.r / 3, color.g / 3, color.b / 3, 255)); if (manualChange) { - PATCH_GFX(gLinkAdultLeftHandHoldingBgsFarDL, "Swords_BiggoronHilt7", swordsBiggoronHilt.changedCvar, 278, gsSPGrayscale(true)); - PATCH_GFX(gLinkAdultLeftHandHoldingBgsFarDL, "Swords_BiggoronHilt8", swordsBiggoronHilt.changedCvar, 332, gsSPGrayscale(false)); - PATCH_GFX(gLinkAdultLeftHandHoldingBgsFarDL, "Swords_BiggoronHilt9", swordsBiggoronHilt.changedCvar, 334, gsSPEndDisplayList()); - PATCH_GFX(gLinkAdultLeftHandHoldingBgsNearDL, "Swords_BiggoronHilt10", swordsBiggoronHilt.changedCvar, 38, gsSPGrayscale(true)); - PATCH_GFX(gLinkAdultLeftHandHoldingBgsNearDL, "Swords_BiggoronHilt11", swordsBiggoronHilt.changedCvar, 118, gsSPGrayscale(false)); + PATCH_GFX(gLinkAdultLeftHandHoldingBgsFarDL, "Swords_BiggoronHilt7", + swordsBiggoronHilt.changedCvar, 278, gsSPGrayscale(true)); PATCH_GFX(gLinkAdultLeftHandHoldingBgsFarDL, + "Swords_BiggoronHilt8", swordsBiggoronHilt.changedCvar, 332, gsSPGrayscale(false)); + PATCH_GFX(gLinkAdultLeftHandHoldingBgsFarDL, "Swords_BiggoronHilt9", + swordsBiggoronHilt.changedCvar, 334, gsSPEndDisplayList()); PATCH_GFX(gLinkAdultLeftHandHoldingBgsNearDL, + "Swords_BiggoronHilt10", swordsBiggoronHilt.changedCvar, 38, gsSPGrayscale(true)); + PATCH_GFX(gLinkAdultLeftHandHoldingBgsNearDL, "Swords_BiggoronHilt11", + swordsBiggoronHilt.changedCvar, 118, gsSPGrayscale(false)); } } */ static CosmeticOption& glovesGoronBracelet = cosmeticOptions.at("Gloves.GoronBracelet"); if (manualChange || CVarGetInteger(glovesGoronBracelet.rainbowCvar, 0)) { Color_RGBA8 color = CVarGetColor(glovesGoronBracelet.valuesCvar, glovesGoronBracelet.defaultColor); - PATCH_GFX(gGiGoronBraceletDL, "Gloves_GoronBracelet1", glovesGoronBracelet.changedCvar, 5, gsDPSetPrimColor(0, 0, color.r, color.g, color.b, 255)); - PATCH_GFX(gGiGoronBraceletDL, "Gloves_GoronBracelet2", glovesGoronBracelet.changedCvar, 6, gsDPSetEnvColor(color.r / 3, color.g / 3, color.b / 3, 255)); - PATCH_GFX(gLinkChildGoronBraceletDL, "Gloves_GoronBracelet3", glovesGoronBracelet.changedCvar, 3, gsDPSetGrayscaleColor(color.r, color.g, color.b, 255)); + PATCH_GFX(gGiGoronBraceletDL, "Gloves_GoronBracelet1", glovesGoronBracelet.changedCvar, 5, + gsDPSetPrimColor(0, 0, color.r, color.g, color.b, 255)); + PATCH_GFX(gGiGoronBraceletDL, "Gloves_GoronBracelet2", glovesGoronBracelet.changedCvar, 6, + gsDPSetEnvColor(color.r / 3, color.g / 3, color.b / 3, 255)); + PATCH_GFX(gLinkChildGoronBraceletDL, "Gloves_GoronBracelet3", glovesGoronBracelet.changedCvar, 3, + gsDPSetGrayscaleColor(color.r, color.g, color.b, 255)); if (manualChange) { - PATCH_GFX(gLinkChildGoronBraceletDL, "Gloves_GoronBracelet4", glovesGoronBracelet.changedCvar, 11, gsSPGrayscale(true)); - PATCH_GFX(gLinkChildGoronBraceletDL, "Gloves_GoronBracelet5", glovesGoronBracelet.changedCvar, 39, gsSPGrayscale(false)); + PATCH_GFX(gLinkChildGoronBraceletDL, "Gloves_GoronBracelet4", glovesGoronBracelet.changedCvar, 11, + gsSPGrayscale(true)); + PATCH_GFX(gLinkChildGoronBraceletDL, "Gloves_GoronBracelet5", glovesGoronBracelet.changedCvar, 39, + gsSPGrayscale(false)); } } static CosmeticOption& glovesSilverGauntlets = cosmeticOptions.at("Gloves.SilverGauntlets"); if (manualChange || CVarGetInteger(glovesSilverGauntlets.rainbowCvar, 0)) { Color_RGBA8 color = CVarGetColor(glovesSilverGauntlets.valuesCvar, glovesSilverGauntlets.defaultColor); - PATCH_GFX(gGiSilverGauntletsColorDL, "Gloves_SilverGauntlets1", glovesSilverGauntlets.changedCvar, 3, gsDPSetPrimColor(0, 0, color.r, color.g, color.b, 255)); - PATCH_GFX(gGiSilverGauntletsColorDL, "Gloves_SilverGauntlets2", glovesSilverGauntlets.changedCvar, 4, gsDPSetEnvColor(color.r / 3, color.g / 3, color.b / 3, 255)); + PATCH_GFX(gGiSilverGauntletsColorDL, "Gloves_SilverGauntlets1", glovesSilverGauntlets.changedCvar, 3, + gsDPSetPrimColor(0, 0, color.r, color.g, color.b, 255)); + PATCH_GFX(gGiSilverGauntletsColorDL, "Gloves_SilverGauntlets2", glovesSilverGauntlets.changedCvar, 4, + gsDPSetEnvColor(color.r / 3, color.g / 3, color.b / 3, 255)); } static CosmeticOption& glovesGoldenGauntlets = cosmeticOptions.at("Gloves.GoldenGauntlets"); if (manualChange || CVarGetInteger(glovesGoldenGauntlets.rainbowCvar, 0)) { Color_RGBA8 color = CVarGetColor(glovesGoldenGauntlets.valuesCvar, glovesGoldenGauntlets.defaultColor); - PATCH_GFX(gGiGoldenGauntletsColorDL, "Gloves_GoldenGauntlets1", glovesGoldenGauntlets.changedCvar, 3, gsDPSetPrimColor(0, 0, color.r, color.g, color.b, 255)); - PATCH_GFX(gGiGoldenGauntletsColorDL, "Gloves_GoldenGauntlets2", glovesGoldenGauntlets.changedCvar, 4, gsDPSetEnvColor(color.r / 3, color.g / 3, color.b / 3, 255)); + PATCH_GFX(gGiGoldenGauntletsColorDL, "Gloves_GoldenGauntlets1", glovesGoldenGauntlets.changedCvar, 3, + gsDPSetPrimColor(0, 0, color.r, color.g, color.b, 255)); + PATCH_GFX(gGiGoldenGauntletsColorDL, "Gloves_GoldenGauntlets2", glovesGoldenGauntlets.changedCvar, 4, + gsDPSetEnvColor(color.r / 3, color.g / 3, color.b / 3, 255)); } static CosmeticOption& glovesGauntletsGem = cosmeticOptions.at("Gloves.GauntletsGem"); if (manualChange || CVarGetInteger(glovesGauntletsGem.rainbowCvar, 0)) { Color_RGBA8 color = CVarGetColor(glovesGauntletsGem.valuesCvar, glovesGauntletsGem.defaultColor); - PATCH_GFX(gGiGauntletsDL, "Gloves_GauntletsGem1", glovesGauntletsGem.changedCvar, 84, gsDPSetPrimColor(0, 0, color.r, color.g, color.b, 255)); - PATCH_GFX(gGiGauntletsDL, "Gloves_GauntletsGem2", glovesGauntletsGem.changedCvar, 85, gsDPSetEnvColor(color.r / 3, color.g / 3, color.b / 3, 255)); - PATCH_GFX(gLinkAdultLeftGauntletPlate2DL, "Gloves_GauntletsGem3", glovesGauntletsGem.changedCvar, 42, gsDPSetPrimColor(0, 0, color.r, color.g, color.b, 255)); - PATCH_GFX(gLinkAdultRightGauntletPlate2DL, "Gloves_GauntletsGem4", glovesGauntletsGem.changedCvar, 42, gsDPSetPrimColor(0, 0, color.r, color.g, color.b, 255)); - PATCH_GFX(gLinkAdultLeftGauntletPlate3DL, "Gloves_GauntletsGem5", glovesGauntletsGem.changedCvar, 42, gsDPSetPrimColor(0, 0, color.r, color.g, color.b, 255)); - PATCH_GFX(gLinkAdultRightGauntletPlate3DL, "Gloves_GauntletsGem6", glovesGauntletsGem.changedCvar, 42, gsDPSetPrimColor(0, 0, color.r, color.g, color.b, 255)); + PATCH_GFX(gGiGauntletsDL, "Gloves_GauntletsGem1", glovesGauntletsGem.changedCvar, 84, + gsDPSetPrimColor(0, 0, color.r, color.g, color.b, 255)); + PATCH_GFX(gGiGauntletsDL, "Gloves_GauntletsGem2", glovesGauntletsGem.changedCvar, 85, + gsDPSetEnvColor(color.r / 3, color.g / 3, color.b / 3, 255)); + PATCH_GFX(gLinkAdultLeftGauntletPlate2DL, "Gloves_GauntletsGem3", glovesGauntletsGem.changedCvar, 42, + gsDPSetPrimColor(0, 0, color.r, color.g, color.b, 255)); + PATCH_GFX(gLinkAdultRightGauntletPlate2DL, "Gloves_GauntletsGem4", glovesGauntletsGem.changedCvar, 42, + gsDPSetPrimColor(0, 0, color.r, color.g, color.b, 255)); + PATCH_GFX(gLinkAdultLeftGauntletPlate3DL, "Gloves_GauntletsGem5", glovesGauntletsGem.changedCvar, 42, + gsDPSetPrimColor(0, 0, color.r, color.g, color.b, 255)); + PATCH_GFX(gLinkAdultRightGauntletPlate3DL, "Gloves_GauntletsGem6", glovesGauntletsGem.changedCvar, 42, + gsDPSetPrimColor(0, 0, color.r, color.g, color.b, 255)); } static CosmeticOption& equipmentBoomerangBody = cosmeticOptions.at("Equipment.BoomerangBody"); if (manualChange || CVarGetInteger(equipmentBoomerangBody.rainbowCvar, 0)) { Color_RGBA8 color = CVarGetColor(equipmentBoomerangBody.valuesCvar, equipmentBoomerangBody.defaultColor); - PATCH_GFX(gGiBoomerangDL, "Equipment_BoomerangBody1", equipmentBoomerangBody.changedCvar, 5, gsDPSetPrimColor(0, 0, color.r, color.g, color.b, 255)); - PATCH_GFX(gGiBoomerangDL, "Equipment_BoomerangBody2", equipmentBoomerangBody.changedCvar, 6, gsDPSetEnvColor(color.r / 3, color.g / 3, color.b / 3, 255)); - PATCH_GFX(gLinkChildLeftFistAndBoomerangNearDL, "Equipment_BoomerangBody3", equipmentBoomerangBody.changedCvar, 34, gsDPSetPrimColor(0, 0, color.r, color.g, color.b, 255)); - PATCH_GFX(gLinkChildLeftFistAndBoomerangFarDL, "Equipment_BoomerangBody4", equipmentBoomerangBody.changedCvar, 9, gsDPSetPrimColor(0, 0, color.r, color.g, color.b, 255)); - PATCH_GFX(gBoomerangDL, "Equipment_BoomerangBody5", equipmentBoomerangBody.changedCvar, 39, gsDPSetPrimColor(0, 0, color.r, color.g, color.b, 255)); + PATCH_GFX(gGiBoomerangDL, "Equipment_BoomerangBody1", equipmentBoomerangBody.changedCvar, 5, + gsDPSetPrimColor(0, 0, color.r, color.g, color.b, 255)); + PATCH_GFX(gGiBoomerangDL, "Equipment_BoomerangBody2", equipmentBoomerangBody.changedCvar, 6, + gsDPSetEnvColor(color.r / 3, color.g / 3, color.b / 3, 255)); + PATCH_GFX(gLinkChildLeftFistAndBoomerangNearDL, "Equipment_BoomerangBody3", equipmentBoomerangBody.changedCvar, + 34, gsDPSetPrimColor(0, 0, color.r, color.g, color.b, 255)); + PATCH_GFX(gLinkChildLeftFistAndBoomerangFarDL, "Equipment_BoomerangBody4", equipmentBoomerangBody.changedCvar, + 9, gsDPSetPrimColor(0, 0, color.r, color.g, color.b, 255)); + PATCH_GFX(gBoomerangDL, "Equipment_BoomerangBody5", equipmentBoomerangBody.changedCvar, 39, + gsDPSetPrimColor(0, 0, color.r, color.g, color.b, 255)); } static CosmeticOption& equipmentBoomerangGem = cosmeticOptions.at("Equipment.BoomerangGem"); if (manualChange || CVarGetInteger(equipmentBoomerangGem.rainbowCvar, 0)) { Color_RGBA8 color = CVarGetColor(equipmentBoomerangGem.valuesCvar, equipmentBoomerangGem.defaultColor); - PATCH_GFX(gGiBoomerangDL, "Equipment_BoomerangGem1", equipmentBoomerangGem.changedCvar, 84, gsDPSetPrimColor(0, 0, color.r, color.g, color.b, 255)); - PATCH_GFX(gGiBoomerangDL, "Equipment_BoomerangGem2", equipmentBoomerangGem.changedCvar, 85, gsDPSetEnvColor(color.r / 3, color.g / 3, color.b / 3, 255)); - PATCH_GFX(gLinkChildLeftFistAndBoomerangNearDL, "Equipment_BoomerangGem3", equipmentBoomerangGem.changedCvar, 16, gsDPSetPrimColor(0, 0, color.r, color.g, color.b, 255)); - PATCH_GFX(gBoomerangDL, "Equipment_BoomerangGem4", equipmentBoomerangGem.changedCvar, 23, gsDPSetPrimColor(0, 0, color.r, color.g, color.b, 255)); + PATCH_GFX(gGiBoomerangDL, "Equipment_BoomerangGem1", equipmentBoomerangGem.changedCvar, 84, + gsDPSetPrimColor(0, 0, color.r, color.g, color.b, 255)); + PATCH_GFX(gGiBoomerangDL, "Equipment_BoomerangGem2", equipmentBoomerangGem.changedCvar, 85, + gsDPSetEnvColor(color.r / 3, color.g / 3, color.b / 3, 255)); + PATCH_GFX(gLinkChildLeftFistAndBoomerangNearDL, "Equipment_BoomerangGem3", equipmentBoomerangGem.changedCvar, + 16, gsDPSetPrimColor(0, 0, color.r, color.g, color.b, 255)); + PATCH_GFX(gBoomerangDL, "Equipment_BoomerangGem4", equipmentBoomerangGem.changedCvar, 23, + gsDPSetPrimColor(0, 0, color.r, color.g, color.b, 255)); // There appears to be no gem rendered on the far LOD variant, not sure if this is an SOH bug or what. - // PATCH_GFX(gLinkChildLeftFistAndBoomerangFarDL, "Equipment_BoomerangGem5", equipmentBoomerangGem.changedCvar, 32, gsDPSetPrimColor(0, 0, color.r, color.g, color.b, 255)); + // PATCH_GFX(gLinkChildLeftFistAndBoomerangFarDL, "Equipment_BoomerangGem5", equipmentBoomerangGem.changedCvar, + // 32, gsDPSetPrimColor(0, 0, color.r, color.g, color.b, 255)); } /* static CosmeticOption& equipmentSlingshotBody = cosmeticOptions.at("Equipment.SlingshotBody"); if (manualChange || CVarGetInteger(equipmentSlingshotBody.rainbowCvar, 0)) { Color_RGBA8 color = CVarGetColor(equipmentSlingshotBody.valuesCvar, equipmentSlingshotBody.defaultColor); - PATCH_GFX(gGiSlingshotDL, "Equipment_SlingshotBody1", equipmentSlingshotBody.changedCvar, 10, gsDPSetPrimColor(0, 0, MAX(color.r - 100, 0), MAX(color.g - 100, 0), MAX(color.b - 100, 0), 255)); - PATCH_GFX(gGiSlingshotDL, "Equipment_SlingshotBody2", equipmentSlingshotBody.changedCvar, 12, gsDPSetEnvColor(MAX(color.r - 100, 0) / 3, MAX(color.g - 100, 0) / 3, MAX(color.b - 100, 0) / 3, 255)); - PATCH_GFX(gGiSlingshotDL, "Equipment_SlingshotBody3", equipmentSlingshotBody.changedCvar, 74, gsDPSetPrimColor(0, 0, color.r, color.g, color.b, 255)); - PATCH_GFX(gGiSlingshotDL, "Equipment_SlingshotBody4", equipmentSlingshotBody.changedCvar, 76, gsDPSetEnvColor(color.r / 3, color.g / 3, color.b / 3, 255)); - PATCH_GFX(gGiSlingshotDL, "Equipment_SlingshotBody5", equipmentSlingshotBody.changedCvar, 128, gsDPSetPrimColor(0, 0, MAX(color.r - 100, 0), MAX(color.g - 100, 0), MAX(color.b - 100, 0), 255)); - PATCH_GFX(gGiSlingshotDL, "Equipment_SlingshotBody6", equipmentSlingshotBody.changedCvar, 130, gsDPSetEnvColor(MAX(color.r - 100, 0) / 3, MAX(color.g - 100, 0) / 3, MAX(color.b - 100, 0) / 3, 255)); - PATCH_GFX(gLinkChildRightArmStretchedSlingshotDL, "Equipment_SlingshotBody7", equipmentSlingshotBody.changedCvar, 4, gsDPSetGrayscaleColor(color.r, color.g, color.b, 255)); - PATCH_GFX(gLinkChildRightHandHoldingSlingshotNearDL, "Equipment_SlingshotBody8", equipmentSlingshotBody.changedCvar, 4, gsDPSetGrayscaleColor(color.r, color.g, color.b, 255)); - PATCH_GFX(gLinkChildRightHandHoldingSlingshotFarDL, "Equipment_SlingshotBody9", equipmentSlingshotBody.changedCvar, 4, gsDPSetGrayscaleColor(color.r, color.g, color.b, 255)); + PATCH_GFX(gGiSlingshotDL, "Equipment_SlingshotBody1", + equipmentSlingshotBody.changedCvar, 10, gsDPSetPrimColor(0, 0, MAX(color.r - 100, 0), MAX(color.g - 100, 0), + MAX(color.b - 100, 0), 255)); PATCH_GFX(gGiSlingshotDL, "Equipment_SlingshotBody2", + equipmentSlingshotBody.changedCvar, 12, gsDPSetEnvColor(MAX(color.r - 100, 0) / 3, MAX(color.g - 100, 0) / 3, + MAX(color.b - 100, 0) / 3, 255)); PATCH_GFX(gGiSlingshotDL, "Equipment_SlingshotBody3", + equipmentSlingshotBody.changedCvar, 74, gsDPSetPrimColor(0, 0, color.r, color.g, color.b, 255)); + PATCH_GFX(gGiSlingshotDL, "Equipment_SlingshotBody4", + equipmentSlingshotBody.changedCvar, 76, gsDPSetEnvColor(color.r / 3, color.g / 3, color.b / 3, 255)); + PATCH_GFX(gGiSlingshotDL, "Equipment_SlingshotBody5", + equipmentSlingshotBody.changedCvar, 128, gsDPSetPrimColor(0, 0, MAX(color.r - 100, 0), MAX(color.g - 100, 0), + MAX(color.b - 100, 0), 255)); PATCH_GFX(gGiSlingshotDL, "Equipment_SlingshotBody6", + equipmentSlingshotBody.changedCvar, 130, gsDPSetEnvColor(MAX(color.r - 100, 0) / 3, MAX(color.g - 100, 0) / 3, + MAX(color.b - 100, 0) / 3, 255)); PATCH_GFX(gLinkChildRightArmStretchedSlingshotDL, "Equipment_SlingshotBody7", + equipmentSlingshotBody.changedCvar, 4, gsDPSetGrayscaleColor(color.r, color.g, color.b, 255)); + PATCH_GFX(gLinkChildRightHandHoldingSlingshotNearDL, "Equipment_SlingshotBody8", + equipmentSlingshotBody.changedCvar, 4, gsDPSetGrayscaleColor(color.r, color.g, color.b, 255)); + PATCH_GFX(gLinkChildRightHandHoldingSlingshotFarDL, "Equipment_SlingshotBody9", + equipmentSlingshotBody.changedCvar, 4, gsDPSetGrayscaleColor(color.r, color.g, color.b, 255)); if (manualChange) { - PATCH_GFX(gLinkChildRightArmStretchedSlingshotDL, "Equipment_SlingshotBody10",equipmentSlingshotBody.changedCvar, 20, gsSPGrayscale(true)); - PATCH_GFX(gLinkChildRightArmStretchedSlingshotDL, "Equipment_SlingshotBody11",equipmentSlingshotBody.changedCvar, 74, gsSPGrayscale(false)); - PATCH_GFX(gLinkChildRightHandHoldingSlingshotFarDL, "Equipment_SlingshotBody12",equipmentSlingshotBody.changedCvar, 20, gsSPGrayscale(true)); - PATCH_GFX(gLinkChildRightHandHoldingSlingshotFarDL, "Equipment_SlingshotBody13",equipmentSlingshotBody.changedCvar, 66, gsSPGrayscale(false)); - PATCH_GFX(gLinkChildRightHandHoldingSlingshotNearDL, "Equipment_SlingshotBody14",equipmentSlingshotBody.changedCvar, 96, gsSPGrayscale(true)); - PATCH_GFX(gLinkChildRightHandHoldingSlingshotNearDL, "Equipment_SlingshotBody15",equipmentSlingshotBody.changedCvar, 136, gsSPGrayscale(false)); - PATCH_GFX(gLinkChildRightHandHoldingSlingshotNearDL, "Equipment_SlingshotBody16",equipmentSlingshotBody.changedCvar, 138, gsSPEndDisplayList()); + PATCH_GFX(gLinkChildRightArmStretchedSlingshotDL, + "Equipment_SlingshotBody10",equipmentSlingshotBody.changedCvar, 20, gsSPGrayscale(true)); + PATCH_GFX(gLinkChildRightArmStretchedSlingshotDL, + "Equipment_SlingshotBody11",equipmentSlingshotBody.changedCvar, 74, gsSPGrayscale(false)); + PATCH_GFX(gLinkChildRightHandHoldingSlingshotFarDL, + "Equipment_SlingshotBody12",equipmentSlingshotBody.changedCvar, 20, gsSPGrayscale(true)); + PATCH_GFX(gLinkChildRightHandHoldingSlingshotFarDL, + "Equipment_SlingshotBody13",equipmentSlingshotBody.changedCvar, 66, gsSPGrayscale(false)); + PATCH_GFX(gLinkChildRightHandHoldingSlingshotNearDL, + "Equipment_SlingshotBody14",equipmentSlingshotBody.changedCvar, 96, gsSPGrayscale(true)); + PATCH_GFX(gLinkChildRightHandHoldingSlingshotNearDL, + "Equipment_SlingshotBody15",equipmentSlingshotBody.changedCvar, 136, gsSPGrayscale(false)); + PATCH_GFX(gLinkChildRightHandHoldingSlingshotNearDL, + "Equipment_SlingshotBody16",equipmentSlingshotBody.changedCvar, 138, gsSPEndDisplayList()); } } */ static CosmeticOption& equipmentSlingshotString = cosmeticOptions.at("Equipment.SlingshotString"); if (manualChange || CVarGetInteger(equipmentSlingshotString.rainbowCvar, 0)) { Color_RGBA8 color = CVarGetColor(equipmentSlingshotString.valuesCvar, equipmentSlingshotString.defaultColor); - PATCH_GFX(gGiSlingshotDL, "Equipment_SlingshotString1",equipmentSlingshotString.changedCvar, 75, gsDPSetPrimColor(0, 0, color.r, color.g, color.b, 255)); - PATCH_GFX(gGiSlingshotDL, "Equipment_SlingshotString2",equipmentSlingshotString.changedCvar, 76, gsDPSetEnvColor(color.r / 2, color.g / 2, color.b / 2, 255)); - PATCH_GFX(gLinkChildSlingshotStringDL, "Equipment_SlingshotString3",equipmentSlingshotString.changedCvar, 9, gsDPSetPrimColor(0, 0, color.r, color.g, color.b, 255)); + PATCH_GFX(gGiSlingshotDL, "Equipment_SlingshotString1", equipmentSlingshotString.changedCvar, 75, + gsDPSetPrimColor(0, 0, color.r, color.g, color.b, 255)); + PATCH_GFX(gGiSlingshotDL, "Equipment_SlingshotString2", equipmentSlingshotString.changedCvar, 76, + gsDPSetEnvColor(color.r / 2, color.g / 2, color.b / 2, 255)); + PATCH_GFX(gLinkChildSlingshotStringDL, "Equipment_SlingshotString3", equipmentSlingshotString.changedCvar, 9, + gsDPSetPrimColor(0, 0, color.r, color.g, color.b, 255)); } static CosmeticOption& equipmentBowTips = cosmeticOptions.at("Equipment.BowTips"); if (manualChange || CVarGetInteger(equipmentBowTips.rainbowCvar, 0)) { Color_RGBA8 color = CVarGetColor(equipmentBowTips.valuesCvar, equipmentBowTips.defaultColor); - PATCH_GFX(gGiBowDL, "Equipment_BowTips1", equipmentBowTips.changedCvar, 86, gsDPSetPrimColor(0, 0, color.r, color.g, color.b, 255)); - PATCH_GFX(gGiBowDL, "Equipment_BowTips2", equipmentBowTips.changedCvar, 87, gsDPSetEnvColor(color.r / 3, color.g / 3, color.b / 3, 255)); - PATCH_GFX(gLinkAdultRightHandHoldingBowFirstPersonDL, "Equipment_BowTips3", equipmentBowTips.changedCvar, 34, gsDPSetPrimColor(0, 0, color.r, color.g, color.b, 255)); - PATCH_GFX(gLinkAdultRightHandHoldingBowNearDL, "Equipment_BowTips4", equipmentBowTips.changedCvar, 26, gsDPSetPrimColor(0, 0, color.r, color.g, color.b, 255)); - PATCH_GFX(gLinkAdultRightHandHoldingBowFarDL, "Equipment_BowTips5", equipmentBowTips.changedCvar, 25, gsDPSetPrimColor(0, 0, color.r, color.g, color.b, 255)); + PATCH_GFX(gGiBowDL, "Equipment_BowTips1", equipmentBowTips.changedCvar, 86, + gsDPSetPrimColor(0, 0, color.r, color.g, color.b, 255)); + PATCH_GFX(gGiBowDL, "Equipment_BowTips2", equipmentBowTips.changedCvar, 87, + gsDPSetEnvColor(color.r / 3, color.g / 3, color.b / 3, 255)); + PATCH_GFX(gLinkAdultRightHandHoldingBowFirstPersonDL, "Equipment_BowTips3", equipmentBowTips.changedCvar, 34, + gsDPSetPrimColor(0, 0, color.r, color.g, color.b, 255)); + PATCH_GFX(gLinkAdultRightHandHoldingBowNearDL, "Equipment_BowTips4", equipmentBowTips.changedCvar, 26, + gsDPSetPrimColor(0, 0, color.r, color.g, color.b, 255)); + PATCH_GFX(gLinkAdultRightHandHoldingBowFarDL, "Equipment_BowTips5", equipmentBowTips.changedCvar, 25, + gsDPSetPrimColor(0, 0, color.r, color.g, color.b, 255)); } static CosmeticOption& equipmentBowString = cosmeticOptions.at("Equipment.BowString"); if (manualChange || CVarGetInteger(equipmentBowString.rainbowCvar, 0)) { Color_RGBA8 color = CVarGetColor(equipmentBowString.valuesCvar, equipmentBowString.defaultColor); - PATCH_GFX(gGiBowDL, "Equipment_BowString1", equipmentBowString.changedCvar, 105, gsDPSetPrimColor(0, 0, color.r, color.g, color.b, 255)); - PATCH_GFX(gGiBowDL, "Equipment_BowString2", equipmentBowString.changedCvar, 106, gsDPSetEnvColor(color.r / 3, color.g / 3, color.b / 3, 255)); - PATCH_GFX(gLinkAdultBowStringDL, "Equipment_BowString3", equipmentBowString.changedCvar, 9, gsDPSetPrimColor(0, 0, color.r, color.g, color.b, 255)); + PATCH_GFX(gGiBowDL, "Equipment_BowString1", equipmentBowString.changedCvar, 105, + gsDPSetPrimColor(0, 0, color.r, color.g, color.b, 255)); + PATCH_GFX(gGiBowDL, "Equipment_BowString2", equipmentBowString.changedCvar, 106, + gsDPSetEnvColor(color.r / 3, color.g / 3, color.b / 3, 255)); + PATCH_GFX(gLinkAdultBowStringDL, "Equipment_BowString3", equipmentBowString.changedCvar, 9, + gsDPSetPrimColor(0, 0, color.r, color.g, color.b, 255)); } static CosmeticOption& equipmentBowBody = cosmeticOptions.at("Equipment.BowBody"); if (manualChange || CVarGetInteger(equipmentBowBody.rainbowCvar, 0)) { Color_RGBA8 color = CVarGetColor(equipmentBowBody.valuesCvar, equipmentBowBody.defaultColor); - PATCH_GFX(gGiBowDL, "Equipment_BowBody1", equipmentBowBody.changedCvar, 5, gsDPSetPrimColor(0, 0, color.r, color.g, color.b, 255)); - PATCH_GFX(gGiBowDL, "Equipment_BowBody2", equipmentBowBody.changedCvar, 6, gsDPSetEnvColor(color.r / 3, color.g / 3, color.b / 3, 255)); - PATCH_GFX(gLinkAdultRightHandHoldingBowFirstPersonDL, "Equipment_BowBody3", equipmentBowBody.changedCvar, 42, gsDPSetPrimColor(0, 0, color.r, color.g, color.b, 255)); - PATCH_GFX(gLinkAdultRightHandHoldingBowNearDL, "Equipment_BowBody4", equipmentBowBody.changedCvar, 33, gsDPSetPrimColor(0, 0, color.r, color.g, color.b, 255)); - PATCH_GFX(gLinkAdultRightHandHoldingBowFarDL, "Equipment_BowBody5", equipmentBowBody.changedCvar, 31, gsDPSetPrimColor(0, 0, color.r, color.g, color.b, 255)); + PATCH_GFX(gGiBowDL, "Equipment_BowBody1", equipmentBowBody.changedCvar, 5, + gsDPSetPrimColor(0, 0, color.r, color.g, color.b, 255)); + PATCH_GFX(gGiBowDL, "Equipment_BowBody2", equipmentBowBody.changedCvar, 6, + gsDPSetEnvColor(color.r / 3, color.g / 3, color.b / 3, 255)); + PATCH_GFX(gLinkAdultRightHandHoldingBowFirstPersonDL, "Equipment_BowBody3", equipmentBowBody.changedCvar, 42, + gsDPSetPrimColor(0, 0, color.r, color.g, color.b, 255)); + PATCH_GFX(gLinkAdultRightHandHoldingBowNearDL, "Equipment_BowBody4", equipmentBowBody.changedCvar, 33, + gsDPSetPrimColor(0, 0, color.r, color.g, color.b, 255)); + PATCH_GFX(gLinkAdultRightHandHoldingBowFarDL, "Equipment_BowBody5", equipmentBowBody.changedCvar, 31, + gsDPSetPrimColor(0, 0, color.r, color.g, color.b, 255)); } static CosmeticOption& equipmentBowHandle = cosmeticOptions.at("Equipment.BowHandle"); if (manualChange || CVarGetInteger(equipmentBowHandle.rainbowCvar, 0)) { Color_RGBA8 color = CVarGetColor(equipmentBowHandle.valuesCvar, equipmentBowHandle.defaultColor); - PATCH_GFX(gGiBowDL, "Equipment_BowHandle1", equipmentBowHandle.changedCvar, 51, gsDPSetPrimColor(0, 0, color.r, color.g, color.b, 255)); - PATCH_GFX(gGiBowDL, "Equipment_BowHandle2", equipmentBowHandle.changedCvar, 52, gsDPSetEnvColor(color.r / 3, color.g / 3, color.b / 3, 255)); - PATCH_GFX(gLinkAdultRightHandHoldingBowFirstPersonDL, "Equipment_BowHandle3", equipmentBowHandle.changedCvar, 18, gsDPSetPrimColor(0, 0, color.r, color.g, color.b, 255)); - PATCH_GFX(gLinkAdultRightHandHoldingBowNearDL, "Equipment_BowHandle4", equipmentBowHandle.changedCvar, 18, gsDPSetPrimColor(0, 0, color.r, color.g, color.b, 255)); - PATCH_GFX(gLinkAdultRightHandHoldingBowFarDL, "Equipment_BowHandle5", equipmentBowHandle.changedCvar, 18, gsDPSetPrimColor(0, 0, color.r, color.g, color.b, 255)); + PATCH_GFX(gGiBowDL, "Equipment_BowHandle1", equipmentBowHandle.changedCvar, 51, + gsDPSetPrimColor(0, 0, color.r, color.g, color.b, 255)); + PATCH_GFX(gGiBowDL, "Equipment_BowHandle2", equipmentBowHandle.changedCvar, 52, + gsDPSetEnvColor(color.r / 3, color.g / 3, color.b / 3, 255)); + PATCH_GFX(gLinkAdultRightHandHoldingBowFirstPersonDL, "Equipment_BowHandle3", equipmentBowHandle.changedCvar, + 18, gsDPSetPrimColor(0, 0, color.r, color.g, color.b, 255)); + PATCH_GFX(gLinkAdultRightHandHoldingBowNearDL, "Equipment_BowHandle4", equipmentBowHandle.changedCvar, 18, + gsDPSetPrimColor(0, 0, color.r, color.g, color.b, 255)); + PATCH_GFX(gLinkAdultRightHandHoldingBowFarDL, "Equipment_BowHandle5", equipmentBowHandle.changedCvar, 18, + gsDPSetPrimColor(0, 0, color.r, color.g, color.b, 255)); } static CosmeticOption& equipmentHammerHead = cosmeticOptions.at("Equipment.HammerHead"); if (manualChange || CVarGetInteger(equipmentHammerHead.rainbowCvar, 0)) { Color_RGBA8 color = CVarGetColor(equipmentHammerHead.valuesCvar, equipmentHammerHead.defaultColor); - PATCH_GFX(gGiHammerDL, "Equipment_HammerHead1", equipmentHammerHead.changedCvar, 5, gsDPSetPrimColor(0, 0, color.r, color.g, color.b, 255)); - PATCH_GFX(gGiHammerDL, "Equipment_HammerHead2", equipmentHammerHead.changedCvar, 6, gsDPSetEnvColor(color.r / 5, color.g / 5, color.b / 5, 255)); - PATCH_GFX(gGiHammerDL, "Equipment_HammerHead3", equipmentHammerHead.changedCvar, 68, gsDPSetPrimColor(0, 0, color.r, color.g, color.b, 255)); - PATCH_GFX(gGiHammerDL, "Equipment_HammerHead4", equipmentHammerHead.changedCvar, 69, gsDPSetEnvColor(color.r / 5, color.g / 5, color.b / 5, 255)); - PATCH_GFX(gLinkAdultLeftHandHoldingHammerNearDL, "Equipment_HammerHead5", equipmentHammerHead.changedCvar, 38, gsDPSetPrimColor(0, 0, color.r, color.g, color.b, 255)); - PATCH_GFX(gLinkAdultLeftHandHoldingHammerFarDL, "Equipment_HammerHead6", equipmentHammerHead.changedCvar, 38, gsDPSetPrimColor(0, 0, color.r, color.g, color.b, 255)); + PATCH_GFX(gGiHammerDL, "Equipment_HammerHead1", equipmentHammerHead.changedCvar, 5, + gsDPSetPrimColor(0, 0, color.r, color.g, color.b, 255)); + PATCH_GFX(gGiHammerDL, "Equipment_HammerHead2", equipmentHammerHead.changedCvar, 6, + gsDPSetEnvColor(color.r / 5, color.g / 5, color.b / 5, 255)); + PATCH_GFX(gGiHammerDL, "Equipment_HammerHead3", equipmentHammerHead.changedCvar, 68, + gsDPSetPrimColor(0, 0, color.r, color.g, color.b, 255)); + PATCH_GFX(gGiHammerDL, "Equipment_HammerHead4", equipmentHammerHead.changedCvar, 69, + gsDPSetEnvColor(color.r / 5, color.g / 5, color.b / 5, 255)); + PATCH_GFX(gLinkAdultLeftHandHoldingHammerNearDL, "Equipment_HammerHead5", equipmentHammerHead.changedCvar, 38, + gsDPSetPrimColor(0, 0, color.r, color.g, color.b, 255)); + PATCH_GFX(gLinkAdultLeftHandHoldingHammerFarDL, "Equipment_HammerHead6", equipmentHammerHead.changedCvar, 38, + gsDPSetPrimColor(0, 0, color.r, color.g, color.b, 255)); } static CosmeticOption& equipmentHammerHandle = cosmeticOptions.at("Equipment.HammerHandle"); if (manualChange || CVarGetInteger(equipmentHammerHandle.rainbowCvar, 0)) { Color_RGBA8 color = CVarGetColor(equipmentHammerHandle.valuesCvar, equipmentHammerHandle.defaultColor); - PATCH_GFX(gGiHammerDL, "Equipment_HammerHandle1", equipmentHammerHandle.changedCvar, 84, gsDPSetPrimColor(0, 0, color.r, color.g, color.b, 255)); - PATCH_GFX(gGiHammerDL, "Equipment_HammerHandle2", equipmentHammerHandle.changedCvar, 85, gsDPSetEnvColor(color.r / 2, color.g / 2, color.b / 2, 255)); - PATCH_GFX(gLinkAdultLeftHandHoldingHammerNearDL, "Equipment_HammerHandle5", equipmentHammerHandle.changedCvar, 18, gsDPSetPrimColor(0, 0, color.r, color.g, color.b, 255)); - PATCH_GFX(gLinkAdultLeftHandHoldingHammerFarDL, "Equipment_HammerHandle6", equipmentHammerHandle.changedCvar, 18, gsDPSetPrimColor(0, 0, color.r, color.g, color.b, 255)); + PATCH_GFX(gGiHammerDL, "Equipment_HammerHandle1", equipmentHammerHandle.changedCvar, 84, + gsDPSetPrimColor(0, 0, color.r, color.g, color.b, 255)); + PATCH_GFX(gGiHammerDL, "Equipment_HammerHandle2", equipmentHammerHandle.changedCvar, 85, + gsDPSetEnvColor(color.r / 2, color.g / 2, color.b / 2, 255)); + PATCH_GFX(gLinkAdultLeftHandHoldingHammerNearDL, "Equipment_HammerHandle5", equipmentHammerHandle.changedCvar, + 18, gsDPSetPrimColor(0, 0, color.r, color.g, color.b, 255)); + PATCH_GFX(gLinkAdultLeftHandHoldingHammerFarDL, "Equipment_HammerHandle6", equipmentHammerHandle.changedCvar, + 18, gsDPSetPrimColor(0, 0, color.r, color.g, color.b, 255)); } static CosmeticOption& equipmentHookshotChain = cosmeticOptions.at("Equipment.HookshotChain"); if (manualChange || CVarGetInteger(equipmentHookshotChain.rainbowCvar, 0)) { Color_RGBA8 color = CVarGetColor(equipmentHookshotChain.valuesCvar, equipmentHookshotChain.defaultColor); - PATCH_GFX(gLinkAdultHookshotChainDL, "Equipment_HookshotChain1", equipmentHookshotChain.changedCvar, 17, gsDPSetPrimColor(0, 0, color.r, color.g, color.b, 255)); + PATCH_GFX(gLinkAdultHookshotChainDL, "Equipment_HookshotChain1", equipmentHookshotChain.changedCvar, 17, + gsDPSetPrimColor(0, 0, color.r, color.g, color.b, 255)); } static CosmeticOption& equipmentChuFace = cosmeticOptions.at("Equipment.ChuFace"); if (manualChange || CVarGetInteger(equipmentChuFace.rainbowCvar, 0)) { Color_RGBA8 color = CVarGetColor(equipmentChuFace.valuesCvar, equipmentChuFace.defaultColor); - PATCH_GFX(gGiBombchuDL, "Equipment_ChuFace1", equipmentChuFace.changedCvar, 5, gsDPSetPrimColor(0, 0, color.r, color.g, color.b, 255)); - PATCH_GFX(gGiBombchuDL, "Equipment_ChuFace2", equipmentChuFace.changedCvar, 6, gsDPSetEnvColor(color.r / 3, color.g / 3, color.b / 3, 255)); - PATCH_GFX(gBombchuDL, "Equipment_ChuFace3", equipmentChuFace.changedCvar, 2, gsDPSetGrayscaleColor(color.r, color.g, color.b, 255)); + PATCH_GFX(gGiBombchuDL, "Equipment_ChuFace1", equipmentChuFace.changedCvar, 5, + gsDPSetPrimColor(0, 0, color.r, color.g, color.b, 255)); + PATCH_GFX(gGiBombchuDL, "Equipment_ChuFace2", equipmentChuFace.changedCvar, 6, + gsDPSetEnvColor(color.r / 3, color.g / 3, color.b / 3, 255)); + PATCH_GFX(gBombchuDL, "Equipment_ChuFace3", equipmentChuFace.changedCvar, 2, + gsDPSetGrayscaleColor(color.r, color.g, color.b, 255)); if (manualChange) { - PATCH_GFX(gBombchuDL, "Equipment_ChuFace4", equipmentChuFace.changedCvar, 10, gsSPGrayscale(true)); - PATCH_GFX(gBombchuDL, "Equipment_ChuFace5", equipmentChuFace.changedCvar, 27, gsSPGrayscale(false)); + PATCH_GFX(gBombchuDL, "Equipment_ChuFace4", equipmentChuFace.changedCvar, 10, gsSPGrayscale(true)); + PATCH_GFX(gBombchuDL, "Equipment_ChuFace5", equipmentChuFace.changedCvar, 27, gsSPGrayscale(false)); } } static CosmeticOption& equipmentChuBody = cosmeticOptions.at("Equipment.ChuBody"); if (manualChange || CVarGetInteger(equipmentChuBody.rainbowCvar, 0)) { Color_RGBA8 color = CVarGetColor(equipmentChuBody.valuesCvar, equipmentChuBody.defaultColor); - PATCH_GFX(gGiBombchuDL, "Equipment_ChuBody1", equipmentChuBody.changedCvar, 39, gsDPSetPrimColor(0, 0, color.r, color.g, color.b, 255)); - PATCH_GFX(gGiBombchuDL, "Equipment_ChuBody2", equipmentChuBody.changedCvar, 40, gsDPSetEnvColor(color.r / 3, color.g / 3, color.b / 3, 255)); - PATCH_GFX(gGiBombchuDL, "Equipment_ChuBody3", equipmentChuBody.changedCvar, 60, gsDPSetPrimColor(0, 0, color.r, color.g, color.b, 255)); - PATCH_GFX(gGiBombchuDL, "Equipment_ChuBody4", equipmentChuBody.changedCvar, 61, gsDPSetEnvColor(color.r / 3, color.g / 3, color.b / 3, 255)); - PATCH_GFX(gBombchuDL, "Equipment_ChuBody5", equipmentChuBody.changedCvar, 46, gsDPSetPrimColor(0, 0, color.r, color.g, color.b, 255)); + PATCH_GFX(gGiBombchuDL, "Equipment_ChuBody1", equipmentChuBody.changedCvar, 39, + gsDPSetPrimColor(0, 0, color.r, color.g, color.b, 255)); + PATCH_GFX(gGiBombchuDL, "Equipment_ChuBody2", equipmentChuBody.changedCvar, 40, + gsDPSetEnvColor(color.r / 3, color.g / 3, color.b / 3, 255)); + PATCH_GFX(gGiBombchuDL, "Equipment_ChuBody3", equipmentChuBody.changedCvar, 60, + gsDPSetPrimColor(0, 0, color.r, color.g, color.b, 255)); + PATCH_GFX(gGiBombchuDL, "Equipment_ChuBody4", equipmentChuBody.changedCvar, 61, + gsDPSetEnvColor(color.r / 3, color.g / 3, color.b / 3, 255)); + PATCH_GFX(gBombchuDL, "Equipment_ChuBody5", equipmentChuBody.changedCvar, 46, + gsDPSetPrimColor(0, 0, color.r, color.g, color.b, 255)); } static CosmeticOption& equipmentBunnyHood = cosmeticOptions.at("Equipment.BunnyHood"); if (manualChange || CVarGetInteger(equipmentBunnyHood.rainbowCvar, 0)) { Color_RGBA8 color = CVarGetColor(equipmentBunnyHood.valuesCvar, equipmentBunnyHood.defaultColor); - PATCH_GFX(gGiBunnyHoodDL, "Equipment_BunnyHood1", equipmentBunnyHood.changedCvar, 5, gsDPSetPrimColor(0, 0, color.r, color.g, color.b, 255)); - PATCH_GFX(gGiBunnyHoodDL, "Equipment_BunnyHood2", equipmentBunnyHood.changedCvar, 6, gsDPSetEnvColor(color.r / 3, color.g / 3, color.b / 3, 255)); - PATCH_GFX(gGiBunnyHoodDL, "Equipment_BunnyHood3", equipmentBunnyHood.changedCvar, 83, gsDPSetPrimColor(0, 0, color.r, color.g, color.b, 255)); - PATCH_GFX(gGiBunnyHoodDL, "Equipment_BunnyHood4", equipmentBunnyHood.changedCvar, 84, gsDPSetEnvColor(color.r / 3, color.g / 3, color.b / 3, 255)); - PATCH_GFX(gLinkChildBunnyHoodDL, "Equipment_BunnyHood5", equipmentBunnyHood.changedCvar, 4, gsDPSetGrayscaleColor(color.r, color.g, color.b, 255)); + PATCH_GFX(gGiBunnyHoodDL, "Equipment_BunnyHood1", equipmentBunnyHood.changedCvar, 5, + gsDPSetPrimColor(0, 0, color.r, color.g, color.b, 255)); + PATCH_GFX(gGiBunnyHoodDL, "Equipment_BunnyHood2", equipmentBunnyHood.changedCvar, 6, + gsDPSetEnvColor(color.r / 3, color.g / 3, color.b / 3, 255)); + PATCH_GFX(gGiBunnyHoodDL, "Equipment_BunnyHood3", equipmentBunnyHood.changedCvar, 83, + gsDPSetPrimColor(0, 0, color.r, color.g, color.b, 255)); + PATCH_GFX(gGiBunnyHoodDL, "Equipment_BunnyHood4", equipmentBunnyHood.changedCvar, 84, + gsDPSetEnvColor(color.r / 3, color.g / 3, color.b / 3, 255)); + PATCH_GFX(gLinkChildBunnyHoodDL, "Equipment_BunnyHood5", equipmentBunnyHood.changedCvar, 4, + gsDPSetGrayscaleColor(color.r, color.g, color.b, 255)); if (manualChange) { - PATCH_GFX(gLinkChildBunnyHoodDL, "Equipment_BunnyHood6", equipmentBunnyHood.changedCvar, 13, gsSPGrayscale(true)); + PATCH_GFX(gLinkChildBunnyHoodDL, "Equipment_BunnyHood6", equipmentBunnyHood.changedCvar, 13, + gsSPGrayscale(true)); if (CVarGetInteger(equipmentBunnyHood.changedCvar, 0)) { - ResourceMgr_PatchGfxByName(gLinkChildBunnyHoodDL, "Equipment_BunnyHood7", 125, gsSPBranchListOTRFilePath(gEndGrayscaleAndEndDlistDL)); + ResourceMgr_PatchGfxByName(gLinkChildBunnyHoodDL, "Equipment_BunnyHood7", 125, + gsSPBranchListOTRFilePath(gEndGrayscaleAndEndDlistDL)); } else { ResourceMgr_UnpatchGfxByName(gLinkChildBunnyHoodDL, "Equipment_BunnyHood7"); } @@ -1072,16 +1282,23 @@ void ApplyOrResetCustomGfxPatches(bool manualChange) { static CosmeticOption& consumableGreenRupee = cosmeticOptions.at("Consumable.GreenRupee"); if (manualChange || CVarGetInteger(consumableGreenRupee.rainbowCvar, 0)) { Color_RGBA8 color = CVarGetColor(consumableGreenRupee.valuesCvar, consumableGreenRupee.defaultColor); - PATCH_GFX(gGiGreenRupeeInnerColorDL, "Consumable_GreenRupee1", consumableGreenRupee.changedCvar, 3, gsDPSetPrimColor(0, 0, color.r, color.g, color.b, 255)); - PATCH_GFX(gGiGreenRupeeInnerColorDL, "Consumable_GreenRupee2", consumableGreenRupee.changedCvar, 4, gsDPSetEnvColor(color.r / 5, color.g / 5, color.b / 5, 255)); - PATCH_GFX(gGiGreenRupeeOuterColorDL, "Consumable_GreenRupee3", consumableGreenRupee.changedCvar, 3, gsDPSetPrimColor(0, 0, MIN(color.r + 100, 255), MIN(color.g + 100, 255), MIN(color.b + 100, 255), 255)); - PATCH_GFX(gGiGreenRupeeOuterColorDL, "Consumable_GreenRupee4", consumableGreenRupee.changedCvar, 4, gsDPSetEnvColor(color.r * 0.75f, color.g * 0.75f, color.b * 0.75f, 255)); + PATCH_GFX(gGiGreenRupeeInnerColorDL, "Consumable_GreenRupee1", consumableGreenRupee.changedCvar, 3, + gsDPSetPrimColor(0, 0, color.r, color.g, color.b, 255)); + PATCH_GFX(gGiGreenRupeeInnerColorDL, "Consumable_GreenRupee2", consumableGreenRupee.changedCvar, 4, + gsDPSetEnvColor(color.r / 5, color.g / 5, color.b / 5, 255)); + PATCH_GFX( + gGiGreenRupeeOuterColorDL, "Consumable_GreenRupee3", consumableGreenRupee.changedCvar, 3, + gsDPSetPrimColor(0, 0, MIN(color.r + 100, 255), MIN(color.g + 100, 255), MIN(color.b + 100, 255), 255)); + PATCH_GFX(gGiGreenRupeeOuterColorDL, "Consumable_GreenRupee4", consumableGreenRupee.changedCvar, 4, + gsDPSetEnvColor(color.r * 0.75f, color.g * 0.75f, color.b * 0.75f, 255)); // Greg Bridge if (Randomizer_GetSettingValue(RSK_RAINBOW_BRIDGE) == RO_BRIDGE_GREG) { ResourceMgr_PatchGfxByName(gRainbowBridgeDL, "RainbowBridge_StartGrayscale", 2, gsSPGrayscale(true)); - ResourceMgr_PatchGfxByName(gRainbowBridgeDL, "RainbowBridge_MakeGreen", 10, gsDPSetGrayscaleColor(color.r, color.g, color.b, color.a)); - ResourceMgr_PatchGfxByName(gRainbowBridgeDL, "RainbowBridge_EndGrayscaleAndEndDlist", 79, gsSPBranchListOTRFilePath(gEndGrayscaleAndEndDlistDL)); + ResourceMgr_PatchGfxByName(gRainbowBridgeDL, "RainbowBridge_MakeGreen", 10, + gsDPSetGrayscaleColor(color.r, color.g, color.b, color.a)); + ResourceMgr_PatchGfxByName(gRainbowBridgeDL, "RainbowBridge_EndGrayscaleAndEndDlist", 79, + gsSPBranchListOTRFilePath(gEndGrayscaleAndEndDlistDL)); } else { ResourceMgr_UnpatchGfxByName(gRainbowBridgeDL, "RainbowBridge_StartGrayscale"); ResourceMgr_UnpatchGfxByName(gRainbowBridgeDL, "RainbowBridge_MakeGreen"); @@ -1091,120 +1308,181 @@ void ApplyOrResetCustomGfxPatches(bool manualChange) { static CosmeticOption& consumableBlueRupee = cosmeticOptions.at("Consumable.BlueRupee"); if (manualChange || CVarGetInteger(consumableBlueRupee.rainbowCvar, 0)) { Color_RGBA8 color = CVarGetColor(consumableBlueRupee.valuesCvar, consumableBlueRupee.defaultColor); - PATCH_GFX(gGiBlueRupeeInnerColorDL, "Consumable_BlueRupee1", consumableBlueRupee.changedCvar, 3, gsDPSetPrimColor(0, 0, color.r, color.g, color.b, 255)); - PATCH_GFX(gGiBlueRupeeInnerColorDL, "Consumable_BlueRupee2", consumableBlueRupee.changedCvar, 4, gsDPSetEnvColor(color.r / 5, color.g / 5, color.b / 5, 255)); - PATCH_GFX(gGiBlueRupeeOuterColorDL, "Consumable_BlueRupee3", consumableBlueRupee.changedCvar, 3, gsDPSetPrimColor(0, 0, MIN(color.r + 100, 255), MIN(color.g + 100, 255), MIN(color.b + 100, 255), 255)); - PATCH_GFX(gGiBlueRupeeOuterColorDL, "Consumable_BlueRupee4", consumableBlueRupee.changedCvar, 4, gsDPSetEnvColor(color.r * 0.75f, color.g * 0.75f, color.b * 0.75f, 255)); + PATCH_GFX(gGiBlueRupeeInnerColorDL, "Consumable_BlueRupee1", consumableBlueRupee.changedCvar, 3, + gsDPSetPrimColor(0, 0, color.r, color.g, color.b, 255)); + PATCH_GFX(gGiBlueRupeeInnerColorDL, "Consumable_BlueRupee2", consumableBlueRupee.changedCvar, 4, + gsDPSetEnvColor(color.r / 5, color.g / 5, color.b / 5, 255)); + PATCH_GFX( + gGiBlueRupeeOuterColorDL, "Consumable_BlueRupee3", consumableBlueRupee.changedCvar, 3, + gsDPSetPrimColor(0, 0, MIN(color.r + 100, 255), MIN(color.g + 100, 255), MIN(color.b + 100, 255), 255)); + PATCH_GFX(gGiBlueRupeeOuterColorDL, "Consumable_BlueRupee4", consumableBlueRupee.changedCvar, 4, + gsDPSetEnvColor(color.r * 0.75f, color.g * 0.75f, color.b * 0.75f, 255)); } static CosmeticOption& consumableRedRupee = cosmeticOptions.at("Consumable.RedRupee"); if (manualChange || CVarGetInteger(consumableRedRupee.rainbowCvar, 0)) { Color_RGBA8 color = CVarGetColor(consumableRedRupee.valuesCvar, consumableRedRupee.defaultColor); - PATCH_GFX(gGiRedRupeeInnerColorDL, "Consumable_RedRupee1", consumableRedRupee.changedCvar, 3, gsDPSetPrimColor(0, 0, color.r, color.g, color.b, 255)); - PATCH_GFX(gGiRedRupeeInnerColorDL, "Consumable_RedRupee2", consumableRedRupee.changedCvar, 4, gsDPSetEnvColor(color.r / 5, color.g / 5, color.b / 5, 255)); - PATCH_GFX(gGiRedRupeeOuterColorDL, "Consumable_RedRupee3", consumableRedRupee.changedCvar, 3, gsDPSetPrimColor(0, 0, MIN(color.r + 100, 255), MIN(color.g + 100, 255), MIN(color.b + 100, 255), 255)); - PATCH_GFX(gGiRedRupeeOuterColorDL, "Consumable_RedRupee4", consumableRedRupee.changedCvar, 4, gsDPSetEnvColor(color.r * 0.75f, color.g * 0.75f, color.b * 0.75f, 255)); + PATCH_GFX(gGiRedRupeeInnerColorDL, "Consumable_RedRupee1", consumableRedRupee.changedCvar, 3, + gsDPSetPrimColor(0, 0, color.r, color.g, color.b, 255)); + PATCH_GFX(gGiRedRupeeInnerColorDL, "Consumable_RedRupee2", consumableRedRupee.changedCvar, 4, + gsDPSetEnvColor(color.r / 5, color.g / 5, color.b / 5, 255)); + PATCH_GFX( + gGiRedRupeeOuterColorDL, "Consumable_RedRupee3", consumableRedRupee.changedCvar, 3, + gsDPSetPrimColor(0, 0, MIN(color.r + 100, 255), MIN(color.g + 100, 255), MIN(color.b + 100, 255), 255)); + PATCH_GFX(gGiRedRupeeOuterColorDL, "Consumable_RedRupee4", consumableRedRupee.changedCvar, 4, + gsDPSetEnvColor(color.r * 0.75f, color.g * 0.75f, color.b * 0.75f, 255)); } static CosmeticOption& consumablePurpleRupee = cosmeticOptions.at("Consumable.PurpleRupee"); if (manualChange || CVarGetInteger(consumablePurpleRupee.rainbowCvar, 0)) { Color_RGBA8 color = CVarGetColor(consumablePurpleRupee.valuesCvar, consumablePurpleRupee.defaultColor); - PATCH_GFX(gGiPurpleRupeeInnerColorDL, "Consumable_PurpleRupee1", consumablePurpleRupee.changedCvar, 3, gsDPSetPrimColor(0, 0, color.r, color.g, color.b, 255)); - PATCH_GFX(gGiPurpleRupeeInnerColorDL, "Consumable_PurpleRupee2", consumablePurpleRupee.changedCvar, 4, gsDPSetEnvColor(color.r / 5, color.g / 5, color.b / 5, 255)); - PATCH_GFX(gGiPurpleRupeeOuterColorDL, "Consumable_PurpleRupee3", consumablePurpleRupee.changedCvar, 3, gsDPSetPrimColor(0, 0, MIN(color.r + 100, 255), MIN(color.g + 100, 255), MIN(color.b + 100, 255), 255)); - PATCH_GFX(gGiPurpleRupeeOuterColorDL, "Consumable_PurpleRupee4", consumablePurpleRupee.changedCvar, 4, gsDPSetEnvColor(color.r * 0.75f, color.g * 0.75f, color.b * 0.75f, 255)); + PATCH_GFX(gGiPurpleRupeeInnerColorDL, "Consumable_PurpleRupee1", consumablePurpleRupee.changedCvar, 3, + gsDPSetPrimColor(0, 0, color.r, color.g, color.b, 255)); + PATCH_GFX(gGiPurpleRupeeInnerColorDL, "Consumable_PurpleRupee2", consumablePurpleRupee.changedCvar, 4, + gsDPSetEnvColor(color.r / 5, color.g / 5, color.b / 5, 255)); + PATCH_GFX( + gGiPurpleRupeeOuterColorDL, "Consumable_PurpleRupee3", consumablePurpleRupee.changedCvar, 3, + gsDPSetPrimColor(0, 0, MIN(color.r + 100, 255), MIN(color.g + 100, 255), MIN(color.b + 100, 255), 255)); + PATCH_GFX(gGiPurpleRupeeOuterColorDL, "Consumable_PurpleRupee4", consumablePurpleRupee.changedCvar, 4, + gsDPSetEnvColor(color.r * 0.75f, color.g * 0.75f, color.b * 0.75f, 255)); } static CosmeticOption& consumableGoldRupee = cosmeticOptions.at("Consumable.GoldRupee"); if (manualChange || CVarGetInteger(consumableGoldRupee.rainbowCvar, 0)) { Color_RGBA8 color = CVarGetColor(consumableGoldRupee.valuesCvar, consumableGoldRupee.defaultColor); - PATCH_GFX(gGiGoldRupeeInnerColorDL, "Consumable_GoldRupee1", consumableGoldRupee.changedCvar, 3, gsDPSetPrimColor(0, 0, color.r, color.g, color.b, 255)); - PATCH_GFX(gGiGoldRupeeInnerColorDL, "Consumable_GoldRupee2", consumableGoldRupee.changedCvar, 4, gsDPSetEnvColor(color.r / 5, color.g / 5, color.b / 5, 255)); - PATCH_GFX(gGiGoldRupeeOuterColorDL, "Consumable_GoldRupee3", consumableGoldRupee.changedCvar, 3, gsDPSetPrimColor(0, 0, MIN(color.r + 100, 255), MIN(color.g + 100, 255), MIN(color.b + 100, 255), 255)); - PATCH_GFX(gGiGoldRupeeOuterColorDL, "Consumable_GoldRupee4", consumableGoldRupee.changedCvar, 4, gsDPSetEnvColor(color.r * 0.75f, color.g * 0.75f, color.b * 0.75f, 255)); + PATCH_GFX(gGiGoldRupeeInnerColorDL, "Consumable_GoldRupee1", consumableGoldRupee.changedCvar, 3, + gsDPSetPrimColor(0, 0, color.r, color.g, color.b, 255)); + PATCH_GFX(gGiGoldRupeeInnerColorDL, "Consumable_GoldRupee2", consumableGoldRupee.changedCvar, 4, + gsDPSetEnvColor(color.r / 5, color.g / 5, color.b / 5, 255)); + PATCH_GFX( + gGiGoldRupeeOuterColorDL, "Consumable_GoldRupee3", consumableGoldRupee.changedCvar, 3, + gsDPSetPrimColor(0, 0, MIN(color.r + 100, 255), MIN(color.g + 100, 255), MIN(color.b + 100, 255), 255)); + PATCH_GFX(gGiGoldRupeeOuterColorDL, "Consumable_GoldRupee4", consumableGoldRupee.changedCvar, 4, + gsDPSetEnvColor(color.r * 0.75f, color.g * 0.75f, color.b * 0.75f, 255)); } static CosmeticOption& consumableHearts = cosmeticOptions.at("Consumable.Hearts"); if (manualChange || CVarGetInteger(consumableHearts.rainbowCvar, 0)) { Color_RGBA8 color = CVarGetColor(consumableHearts.valuesCvar, consumableHearts.defaultColor); /* - PATCH_GFX(gGiRecoveryHeartDL, "Consumable_Hearts1", consumableHearts.changedCvar, 4, gsDPSetGrayscaleColor(color.r, color.g, color.b, 255)); - PATCH_GFX(gGiRecoveryHeartDL, "Consumable_Hearts2", consumableHearts.changedCvar, 26, gsSPGrayscale(true)); - PATCH_GFX(gGiRecoveryHeartDL, "Consumable_Hearts3", consumableHearts.changedCvar, 72, gsSPGrayscale(false)); - PATCH_GFX(gGiRecoveryHeartDL, "Consumable_Hearts4", consumableHearts.changedCvar, 74, gsSPEndDisplayList()); + PATCH_GFX(gGiRecoveryHeartDL, "Consumable_Hearts1", consumableHearts.changedCvar, 4, + gsDPSetGrayscaleColor(color.r, color.g, color.b, 255)); PATCH_GFX(gGiRecoveryHeartDL, "Consumable_Hearts2", + consumableHearts.changedCvar, 26, gsSPGrayscale(true)); PATCH_GFX(gGiRecoveryHeartDL, + "Consumable_Hearts3", consumableHearts.changedCvar, 72, gsSPGrayscale(false)); + PATCH_GFX(gGiRecoveryHeartDL, "Consumable_Hearts4", consumableHearts.changedCvar, + 74, gsSPEndDisplayList()); */ - PATCH_GFX(gGiHeartPieceDL, "Consumable_Hearts5", consumableHearts.changedCvar, 2, gsDPSetPrimColor(0, 0, color.r, color.g, color.b, 255)); - PATCH_GFX(gGiHeartPieceDL, "Consumable_Hearts6", consumableHearts.changedCvar, 6, gsDPSetEnvColor(color.r / 2, color.g / 2, color.b / 2, 255)); - PATCH_GFX(gGiHeartContainerDL, "Consumable_Hearts7", consumableHearts.changedCvar, 2, gsDPSetPrimColor(0, 0, color.r, color.g, color.b, 255)); - PATCH_GFX(gGiHeartContainerDL, "Consumable_Hearts8", consumableHearts.changedCvar, 6, gsDPSetEnvColor(color.r / 2, color.g / 2, color.b / 2, 255)); - PATCH_GFX(gGiRedPotColorDL, "Consumable_Hearts9", consumableHearts.changedCvar, 3, gsDPSetPrimColor(0, 0, color.r, color.g, color.b, 255)); - PATCH_GFX(gGiRedPotColorDL, "Consumable_Hearts10", consumableHearts.changedCvar, 4, gsDPSetEnvColor(color.r / 2, color.g / 2, color.b / 2, 255)); + PATCH_GFX(gGiHeartPieceDL, "Consumable_Hearts5", consumableHearts.changedCvar, 2, + gsDPSetPrimColor(0, 0, color.r, color.g, color.b, 255)); + PATCH_GFX(gGiHeartPieceDL, "Consumable_Hearts6", consumableHearts.changedCvar, 6, + gsDPSetEnvColor(color.r / 2, color.g / 2, color.b / 2, 255)); + PATCH_GFX(gGiHeartContainerDL, "Consumable_Hearts7", consumableHearts.changedCvar, 2, + gsDPSetPrimColor(0, 0, color.r, color.g, color.b, 255)); + PATCH_GFX(gGiHeartContainerDL, "Consumable_Hearts8", consumableHearts.changedCvar, 6, + gsDPSetEnvColor(color.r / 2, color.g / 2, color.b / 2, 255)); + PATCH_GFX(gGiRedPotColorDL, "Consumable_Hearts9", consumableHearts.changedCvar, 3, + gsDPSetPrimColor(0, 0, color.r, color.g, color.b, 255)); + PATCH_GFX(gGiRedPotColorDL, "Consumable_Hearts10", consumableHearts.changedCvar, 4, + gsDPSetEnvColor(color.r / 2, color.g / 2, color.b / 2, 255)); } static CosmeticOption& consumableMagic = cosmeticOptions.at("Consumable.Magic"); if (manualChange || CVarGetInteger(consumableMagic.rainbowCvar, 0)) { Color_RGBA8 color = CVarGetColor(consumableMagic.valuesCvar, consumableMagic.defaultColor); - PATCH_GFX(gGiMagicJarSmallDL, "Consumable_Magic1", consumableMagic.changedCvar, 31, gsDPSetPrimColor(0, 0, color.r, color.g, color.b, 255)); - PATCH_GFX(gGiMagicJarSmallDL, "Consumable_Magic2", consumableMagic.changedCvar, 32, gsDPSetEnvColor(color.r / 2, color.g / 2, color.b / 2, 255)); - PATCH_GFX(gGiMagicJarLargeDL, "Consumable_Magic3", consumableMagic.changedCvar, 31, gsDPSetPrimColor(0, 0, color.r, color.g, color.b, 255)); - PATCH_GFX(gGiMagicJarLargeDL, "Consumable_Magic4", consumableMagic.changedCvar, 32, gsDPSetEnvColor(color.r / 2, color.g / 2, color.b / 2, 255)); - PATCH_GFX(gGiGreenPotColorDL, "Consumable_Magic5", consumableMagic.changedCvar, 3, gsDPSetPrimColor(0, 0, color.r, color.g, color.b, 255)); - PATCH_GFX(gGiGreenPotColorDL, "Consumable_Magic6", consumableMagic.changedCvar, 4, gsDPSetEnvColor(color.r / 2, color.g / 2, color.b / 2, 255)); + PATCH_GFX(gGiMagicJarSmallDL, "Consumable_Magic1", consumableMagic.changedCvar, 31, + gsDPSetPrimColor(0, 0, color.r, color.g, color.b, 255)); + PATCH_GFX(gGiMagicJarSmallDL, "Consumable_Magic2", consumableMagic.changedCvar, 32, + gsDPSetEnvColor(color.r / 2, color.g / 2, color.b / 2, 255)); + PATCH_GFX(gGiMagicJarLargeDL, "Consumable_Magic3", consumableMagic.changedCvar, 31, + gsDPSetPrimColor(0, 0, color.r, color.g, color.b, 255)); + PATCH_GFX(gGiMagicJarLargeDL, "Consumable_Magic4", consumableMagic.changedCvar, 32, + gsDPSetEnvColor(color.r / 2, color.g / 2, color.b / 2, 255)); + PATCH_GFX(gGiGreenPotColorDL, "Consumable_Magic5", consumableMagic.changedCvar, 3, + gsDPSetPrimColor(0, 0, color.r, color.g, color.b, 255)); + PATCH_GFX(gGiGreenPotColorDL, "Consumable_Magic6", consumableMagic.changedCvar, 4, + gsDPSetEnvColor(color.r / 2, color.g / 2, color.b / 2, 255)); } static CosmeticOption& npcGoldenSkulltula = cosmeticOptions.at("NPC.GoldenSkulltula"); if (manualChange || CVarGetInteger(npcGoldenSkulltula.rainbowCvar, 0)) { Color_RGBA8 color = CVarGetColor(npcGoldenSkulltula.valuesCvar, npcGoldenSkulltula.defaultColor); - PATCH_GFX(gSkulltulaTokenDL, "NPC_GoldenSkulltula1", npcGoldenSkulltula.changedCvar, 5, gsDPSetPrimColor(0, 0, color.r, color.g, color.b, 255)); - PATCH_GFX(gSkulltulaTokenDL, "NPC_GoldenSkulltula2", npcGoldenSkulltula.changedCvar, 6, gsDPSetEnvColor(color.r / 2, color.g / 2, color.b / 2, 255)); - PATCH_GFX(gSkulltulaTokenFlameDL, "NPC_GoldenSkulltula3", npcGoldenSkulltula.changedCvar, 32, gsDPSetPrimColor(0, 0, color.r, color.g, color.b, 255)); - PATCH_GFX(gSkulltulaTokenFlameDL, "NPC_GoldenSkulltula4", npcGoldenSkulltula.changedCvar, 33, gsDPSetEnvColor(color.r / 2, color.g / 2, color.b / 2, 255)); - PATCH_GFX(gGiSkulltulaTokenDL, "NPC_GoldenSkulltula5", npcGoldenSkulltula.changedCvar, 5, gsDPSetPrimColor(0, 0, color.r, color.g, color.b, 255)); - PATCH_GFX(gGiSkulltulaTokenDL, "NPC_GoldenSkulltula6", npcGoldenSkulltula.changedCvar, 6, gsDPSetEnvColor(color.r / 2, color.g / 2, color.b / 2, 255)); - PATCH_GFX(gGiSkulltulaTokenFlameDL, "NPC_GoldenSkulltula7", npcGoldenSkulltula.changedCvar, 32, gsDPSetPrimColor(0, 0, color.r, color.g, color.b, 255)); - PATCH_GFX(gGiSkulltulaTokenFlameDL, "NPC_GoldenSkulltula8", npcGoldenSkulltula.changedCvar, 33, gsDPSetEnvColor(color.r / 2, color.g / 2, color.b / 2, 255)); - PATCH_GFX(object_st_DL_003FB0, "NPC_GoldenSkulltula9", npcGoldenSkulltula.changedCvar, 118, gsDPSetPrimColor(0, 0, color.r, color.g, color.b, 255)); - PATCH_GFX(object_st_DL_003FB0, "NPC_GoldenSkulltula10", npcGoldenSkulltula.changedCvar, 119, gsDPSetEnvColor(color.r / 4, color.g / 4, color.b / 4, 255)); + PATCH_GFX(gSkulltulaTokenDL, "NPC_GoldenSkulltula1", npcGoldenSkulltula.changedCvar, 5, + gsDPSetPrimColor(0, 0, color.r, color.g, color.b, 255)); + PATCH_GFX(gSkulltulaTokenDL, "NPC_GoldenSkulltula2", npcGoldenSkulltula.changedCvar, 6, + gsDPSetEnvColor(color.r / 2, color.g / 2, color.b / 2, 255)); + PATCH_GFX(gSkulltulaTokenFlameDL, "NPC_GoldenSkulltula3", npcGoldenSkulltula.changedCvar, 32, + gsDPSetPrimColor(0, 0, color.r, color.g, color.b, 255)); + PATCH_GFX(gSkulltulaTokenFlameDL, "NPC_GoldenSkulltula4", npcGoldenSkulltula.changedCvar, 33, + gsDPSetEnvColor(color.r / 2, color.g / 2, color.b / 2, 255)); + PATCH_GFX(gGiSkulltulaTokenDL, "NPC_GoldenSkulltula5", npcGoldenSkulltula.changedCvar, 5, + gsDPSetPrimColor(0, 0, color.r, color.g, color.b, 255)); + PATCH_GFX(gGiSkulltulaTokenDL, "NPC_GoldenSkulltula6", npcGoldenSkulltula.changedCvar, 6, + gsDPSetEnvColor(color.r / 2, color.g / 2, color.b / 2, 255)); + PATCH_GFX(gGiSkulltulaTokenFlameDL, "NPC_GoldenSkulltula7", npcGoldenSkulltula.changedCvar, 32, + gsDPSetPrimColor(0, 0, color.r, color.g, color.b, 255)); + PATCH_GFX(gGiSkulltulaTokenFlameDL, "NPC_GoldenSkulltula8", npcGoldenSkulltula.changedCvar, 33, + gsDPSetEnvColor(color.r / 2, color.g / 2, color.b / 2, 255)); + PATCH_GFX(object_st_DL_003FB0, "NPC_GoldenSkulltula9", npcGoldenSkulltula.changedCvar, 118, + gsDPSetPrimColor(0, 0, color.r, color.g, color.b, 255)); + PATCH_GFX(object_st_DL_003FB0, "NPC_GoldenSkulltula10", npcGoldenSkulltula.changedCvar, 119, + gsDPSetEnvColor(color.r / 4, color.g / 4, color.b / 4, 255)); } static CosmeticOption& npcGerudo = cosmeticOptions.at("NPC.Gerudo"); if (manualChange || CVarGetInteger(npcGerudo.rainbowCvar, 0)) { Color_RGBA8 color = CVarGetColor(npcGerudo.valuesCvar, npcGerudo.defaultColor); - PATCH_GFX(gGerudoPurpleTorsoDL, "NPC_Gerudo1", npcGerudo.changedCvar, 139, gsDPSetEnvColor( color.r, color.g, color.b, 255)); - PATCH_GFX(gGerudoPurpleRightThighDL, "NPC_Gerudo2", npcGerudo.changedCvar, 11, gsDPSetEnvColor(color.r, color.g, color.b, 255)); - PATCH_GFX(gGerudoPurpleLeftThighDL, "NPC_Gerudo3", npcGerudo.changedCvar, 11, gsDPSetEnvColor(color.r, color.g, color.b, 255)); - PATCH_GFX(gGerudoPurpleVeilDL, "NPC_Gerudo4", npcGerudo.changedCvar, 17, gsDPSetPrimColor(0, 0, color.r, color.g, color.b, 255)); - PATCH_GFX(gGerudoPurpleLeftShinDL, "NPC_Gerudo5", npcGerudo.changedCvar, 11, gsDPSetEnvColor(color.r, color.g, color.b, 255)); - PATCH_GFX(gGerudoPurpleRightShinDL, "NPC_Gerudo6", npcGerudo.changedCvar, 11, gsDPSetEnvColor(color.r, color.g, color.b, 255)); - PATCH_GFX(gGerudoPurpleLeftHandDL, "NPC_Gerudo7", npcGerudo.changedCvar, 17, gsDPSetPrimColor(0, 0, color.r, color.g, color.b, 255)); - PATCH_GFX(gGerudoPurpleRightHandDL, "NPC_Gerudo8", npcGerudo.changedCvar, 17, gsDPSetPrimColor(0, 0, color.r, color.g, color.b, 255)); + PATCH_GFX(gGerudoPurpleTorsoDL, "NPC_Gerudo1", npcGerudo.changedCvar, 139, + gsDPSetEnvColor(color.r, color.g, color.b, 255)); + PATCH_GFX(gGerudoPurpleRightThighDL, "NPC_Gerudo2", npcGerudo.changedCvar, 11, + gsDPSetEnvColor(color.r, color.g, color.b, 255)); + PATCH_GFX(gGerudoPurpleLeftThighDL, "NPC_Gerudo3", npcGerudo.changedCvar, 11, + gsDPSetEnvColor(color.r, color.g, color.b, 255)); + PATCH_GFX(gGerudoPurpleVeilDL, "NPC_Gerudo4", npcGerudo.changedCvar, 17, + gsDPSetPrimColor(0, 0, color.r, color.g, color.b, 255)); + PATCH_GFX(gGerudoPurpleLeftShinDL, "NPC_Gerudo5", npcGerudo.changedCvar, 11, + gsDPSetEnvColor(color.r, color.g, color.b, 255)); + PATCH_GFX(gGerudoPurpleRightShinDL, "NPC_Gerudo6", npcGerudo.changedCvar, 11, + gsDPSetEnvColor(color.r, color.g, color.b, 255)); + PATCH_GFX(gGerudoPurpleLeftHandDL, "NPC_Gerudo7", npcGerudo.changedCvar, 17, + gsDPSetPrimColor(0, 0, color.r, color.g, color.b, 255)); + PATCH_GFX(gGerudoPurpleRightHandDL, "NPC_Gerudo8", npcGerudo.changedCvar, 17, + gsDPSetPrimColor(0, 0, color.r, color.g, color.b, 255)); } static CosmeticOption& npcMetalTrap = cosmeticOptions.at("NPC.MetalTrap"); if (manualChange || CVarGetInteger(npcMetalTrap.rainbowCvar, 0)) { Color_RGBA8 color = CVarGetColor(npcMetalTrap.valuesCvar, npcMetalTrap.defaultColor); - PATCH_GFX(gSlidingBladeTrapDL, "NPC_MetalTrap1", npcMetalTrap.changedCvar, 59, gsDPSetPrimColor(0, 0, color.r, color.g, color.b, 255)); + PATCH_GFX(gSlidingBladeTrapDL, "NPC_MetalTrap1", npcMetalTrap.changedCvar, 59, + gsDPSetPrimColor(0, 0, color.r, color.g, color.b, 255)); } static CosmeticOption& n64LogoRed = cosmeticOptions.at("Title.N64LogoRed"); if (manualChange || CVarGetInteger(n64LogoRed.rainbowCvar, 0)) { Color_RGBA8 color = CVarGetColor(n64LogoRed.valuesCvar, n64LogoRed.defaultColor); - PATCH_GFX(gNintendo64LogoDL, "Title_N64LogoRed1", n64LogoRed.changedCvar, 17, gsDPSetPrimColor(0, 0, 255, 255, 255, 255)) - PATCH_GFX(gNintendo64LogoDL, "Title_N64LogoRed2", n64LogoRed.changedCvar, 18, gsDPSetEnvColor(color.r, color.g, color.b, 128)); + PATCH_GFX(gNintendo64LogoDL, "Title_N64LogoRed1", n64LogoRed.changedCvar, 17, + gsDPSetPrimColor(0, 0, 255, 255, 255, 255)) + PATCH_GFX(gNintendo64LogoDL, "Title_N64LogoRed2", n64LogoRed.changedCvar, 18, + gsDPSetEnvColor(color.r, color.g, color.b, 128)); } static CosmeticOption& n64LogoBlue = cosmeticOptions.at("Title.N64LogoBlue"); if (manualChange || CVarGetInteger(n64LogoBlue.rainbowCvar, 0)) { Color_RGBA8 color = CVarGetColor(n64LogoBlue.valuesCvar, n64LogoBlue.defaultColor); - PATCH_GFX(gNintendo64LogoDL, "Title_N64LogoBlue1", n64LogoBlue.changedCvar, 29, gsDPSetPrimColor(0, 0, 255, 255, 255, 255)) - PATCH_GFX(gNintendo64LogoDL, "Title_N64LogoBlue2", n64LogoBlue.changedCvar, 30, gsDPSetEnvColor(color.r, color.g, color.b, 128)); + PATCH_GFX(gNintendo64LogoDL, "Title_N64LogoBlue1", n64LogoBlue.changedCvar, 29, + gsDPSetPrimColor(0, 0, 255, 255, 255, 255)) + PATCH_GFX(gNintendo64LogoDL, "Title_N64LogoBlue2", n64LogoBlue.changedCvar, 30, + gsDPSetEnvColor(color.r, color.g, color.b, 128)); } static CosmeticOption& n64LogoGreen = cosmeticOptions.at("Title.N64LogoGreen"); if (manualChange || CVarGetInteger(n64LogoGreen.rainbowCvar, 0)) { Color_RGBA8 color = CVarGetColor(n64LogoGreen.valuesCvar, n64LogoGreen.defaultColor); - PATCH_GFX(gNintendo64LogoDL, "Title_N64LogoGreen1", n64LogoGreen.changedCvar, 56, gsDPSetPrimColor(0, 0, 255, 255, 255, 255)) - PATCH_GFX(gNintendo64LogoDL, "Title_N64LogoGreen2", n64LogoGreen.changedCvar, 57, gsDPSetEnvColor(color.r, color.g, color.b, 128)); + PATCH_GFX(gNintendo64LogoDL, "Title_N64LogoGreen1", n64LogoGreen.changedCvar, 56, + gsDPSetPrimColor(0, 0, 255, 255, 255, 255)) + PATCH_GFX(gNintendo64LogoDL, "Title_N64LogoGreen2", n64LogoGreen.changedCvar, 57, + gsDPSetEnvColor(color.r, color.g, color.b, 128)); } static CosmeticOption& n64LogoYellow = cosmeticOptions.at("Title.N64LogoYellow"); if (manualChange || CVarGetInteger(n64LogoYellow.rainbowCvar, 0)) { Color_RGBA8 color = CVarGetColor(n64LogoYellow.valuesCvar, n64LogoYellow.defaultColor); - PATCH_GFX(gNintendo64LogoDL, "Title_N64LogoYellow1", n64LogoYellow.changedCvar, 81, gsDPSetPrimColor(0, 0, 255, 255, 255, 255)) - PATCH_GFX(gNintendo64LogoDL, "Title_N64LogoYellow2", n64LogoYellow.changedCvar, 82, gsDPSetEnvColor(color.r, color.g, color.b, 128)); + PATCH_GFX(gNintendo64LogoDL, "Title_N64LogoYellow1", n64LogoYellow.changedCvar, 81, + gsDPSetPrimColor(0, 0, 255, 255, 255, 255)) + PATCH_GFX(gNintendo64LogoDL, "Title_N64LogoYellow2", n64LogoYellow.changedCvar, 82, + gsDPSetEnvColor(color.r, color.g, color.b, 128)); } if (gPlayState != nullptr) { @@ -1219,12 +1497,10 @@ void ApplyOrResetCustomGfxPatches(bool manualChange) { } extern "C" Color_RGBA8 CosmeticsEditor_GetDefaultValue(const char* id) { - return Color_RGBA8 { - (uint8_t)(cosmeticOptions[id].defaultColor.r * 255.0f), + return Color_RGBA8{ (uint8_t)(cosmeticOptions[id].defaultColor.r * 255.0f), (uint8_t)(cosmeticOptions[id].defaultColor.g * 255.0f), (uint8_t)(cosmeticOptions[id].defaultColor.b * 255.0f), - (uint8_t)(cosmeticOptions[id].defaultColor.a * 255.0f) - }; + (uint8_t)(cosmeticOptions[id].defaultColor.a * 255.0f) }; } void Table_InitHeader(bool has_header = true) { @@ -1233,34 +1509,34 @@ void Table_InitHeader(bool has_header = true) { } ImGui::TableNextRow(); ImGui::TableNextColumn(); - ImGui::AlignTextToFramePadding(); //This is to adjust Vertical pos of item in a cell to be normlized. + ImGui::AlignTextToFramePadding(); // This is to adjust Vertical pos of item in a cell to be normlized. ImGui::SetCursorPosX(ImGui::GetCursorPosX() - 2); ImGui::PushItemWidth(ImGui::GetContentRegionAvail().x - 60); } -void DrawUseMarginsSlider(const std::string ElementName, const std::string CvarName){ +void DrawUseMarginsSlider(const std::string ElementName, const std::string CvarName) { std::string CvarLabel = CvarName + ".UseMargins"; std::string Label = ElementName + " use margins"; UIWidgets::CVarCheckbox(Label.c_str(), CvarLabel.c_str(), - UIWidgets::CheckboxOptions() - .Color(THEME_COLOR) - .Tooltip("Using this allow you move the element with General margins sliders")); + UIWidgets::CheckboxOptions() + .Color(THEME_COLOR) + .Tooltip("Using this allow you move the element with General margins sliders")); } void DrawPositionsRadioBoxes(const std::string CvarName, bool NoAnchorEnabled = true) { std::string CvarLabel = CvarName + ".PosType"; UIWidgets::CVarRadioButton("Original position", CvarLabel.c_str(), 0, - UIWidgets::RadioButtonsOptions() - .Color(THEME_COLOR) - .Tooltip("This will use original intended elements position")); + UIWidgets::RadioButtonsOptions() + .Color(THEME_COLOR) + .Tooltip("This will use original intended elements position")); UIWidgets::CVarRadioButton("Anchor to the left", CvarLabel.c_str(), 1, - UIWidgets::RadioButtonsOptions() - .Color(THEME_COLOR) - .Tooltip("This will make your elements follow the left side of your game window")); + UIWidgets::RadioButtonsOptions() + .Color(THEME_COLOR) + .Tooltip("This will make your elements follow the left side of your game window")); UIWidgets::CVarRadioButton("Anchor to the right", CvarLabel.c_str(), 2, - UIWidgets::RadioButtonsOptions() - .Color(THEME_COLOR) - .Tooltip("This will make your elements follow the right side of your game window")); + UIWidgets::RadioButtonsOptions() + .Color(THEME_COLOR) + .Tooltip("This will make your elements follow the right side of your game window")); if (NoAnchorEnabled) { UIWidgets::CVarRadioButton( "No anchors", CvarLabel.c_str(), 3, @@ -1273,37 +1549,40 @@ void DrawPositionsRadioBoxes(const std::string CvarName, bool NoAnchorEnabled = UIWidgets::RadioButtonsOptions().Color(THEME_COLOR).Tooltip("This will make your elements hidden")); } -void DrawPositionSlider(const std::string CvarName, int MinY, int MaxY, int MinX, int MaxX){ +void DrawPositionSlider(const std::string CvarName, int MinY, int MaxY, int MinX, int MaxX) { std::string PosXCvar = CvarName + ".PosX"; std::string PosYCvar = CvarName + ".PosY"; std::string InvisibleLabelX = "##" + PosXCvar; std::string InvisibleLabelY = "##" + PosYCvar; UIWidgets::CVarSliderInt("Up <-> Down : %d", PosYCvar.c_str(), - UIWidgets::IntSliderOptions() - .Min(MinY) - .Max(MaxY) - .DefaultValue(0) - .Size(ImVec2(300.0f, 0.0f)) - .Color(THEME_COLOR) - .Tooltip("This slider is used to move Up and Down your elements.")); + UIWidgets::IntSliderOptions() + .Min(MinY) + .Max(MaxY) + .DefaultValue(0) + .Size(ImVec2(300.0f, 0.0f)) + .Color(THEME_COLOR) + .Tooltip("This slider is used to move Up and Down your elements.")); UIWidgets::CVarSliderInt("Left <-> Right : %d", PosXCvar.c_str(), - UIWidgets::IntSliderOptions() - .Min(MinX) - .Max(MaxX) - .DefaultValue(0) - .Size(ImVec2(300.0f, 0.0f)) - .Color(THEME_COLOR) - .Tooltip("This slider is used to move Left and Right your elements.")); + UIWidgets::IntSliderOptions() + .Min(MinX) + .Max(MaxX) + .DefaultValue(0) + .Size(ImVec2(300.0f, 0.0f)) + .Color(THEME_COLOR) + .Tooltip("This slider is used to move Left and Right your elements.")); } -void DrawScaleSlider(const std::string CvarName, float DefaultValue){ +void DrawScaleSlider(const std::string CvarName, float DefaultValue) { std::string InvisibleLabel = "##" + CvarName; std::string CvarLabel = CvarName + ".Scale"; - //Disabled for now. feature not done and several fixes needed to be merged. - //UIWidgets::EnhancementSliderFloat("Scale : %dx", InvisibleLabel.c_str(), CvarLabel.c_str(), 0.1f, 3.0f,"",DefaultValue,true); + // Disabled for now. feature not done and several fixes needed to be merged. + // UIWidgets::EnhancementSliderFloat("Scale : %dx", InvisibleLabel.c_str(), CvarLabel.c_str(), + // 0.1f, 3.0f,"",DefaultValue,true); } -void Draw_Table_Dropdown(const char* Header_Title, const char* Table_ID, const char* Column_Title, const char* Slider_Title, const char* Slider_ID, int MinY, int MaxY, int MinX, int MaxX, float Default_Value) { +void Draw_Table_Dropdown(const char* Header_Title, const char* Table_ID, const char* Column_Title, + const char* Slider_Title, const char* Slider_ID, int MinY, int MaxY, int MinX, int MaxX, + float Default_Value) { UIWidgets::PushStyleHeader(THEME_COLOR); if (ImGui::CollapsingHeader(Header_Title)) { if (ImGui::BeginTable(Table_ID, 1, FlagsTable)) { @@ -1319,7 +1598,9 @@ void Draw_Table_Dropdown(const char* Header_Title, const char* Table_ID, const c UIWidgets::PopStyleHeader(); } -void C_Button_Dropdown(const char* Header_Title, const char* Table_ID, const char* Column_Title, const char* Slider_Title, const char* Slider_ID, const char* Int_Type, float Slider_Scale_Value) { +void C_Button_Dropdown(const char* Header_Title, const char* Table_ID, const char* Column_Title, + const char* Slider_Title, const char* Slider_ID, const char* Int_Type, + float Slider_Scale_Value) { UIWidgets::PushStyleHeader(THEME_COLOR); if (ImGui::CollapsingHeader(Header_Title)) { if (ImGui::BeginTable(Table_ID, 1, FlagsTable)) { @@ -1329,18 +1610,20 @@ void C_Button_Dropdown(const char* Header_Title, const char* Table_ID, const cha DrawPositionsRadioBoxes(Slider_ID); s16 Min_X_CU = 0; s16 Max_X_CU = static_cast(ImGui::GetWindowViewport()->Size.x / 2); - if(CVarGetInteger(Int_Type, 0) == 2){ + if (CVarGetInteger(Int_Type, 0) == 2) { Max_X_CU = 294; - } else if(CVarGetInteger(Int_Type, 0) == 3){ + } else if (CVarGetInteger(Int_Type, 0) == 3) { Max_X_CU = static_cast(ImGui::GetWindowViewport()->Size.x / 2); - } else if(CVarGetInteger(Int_Type, 0) == 4){ + } else if (CVarGetInteger(Int_Type, 0) == 4) { Min_X_CU = static_cast(ImGui::GetWindowViewport()->Size.x / 2) * -1; } - DrawPositionSlider(Slider_ID, 0, static_cast(ImGui::GetWindowViewport()->Size.y / 2), Min_X_CU, Max_X_CU); + DrawPositionSlider(Slider_ID, 0, static_cast(ImGui::GetWindowViewport()->Size.y / 2), Min_X_CU, + Max_X_CU); DrawScaleSlider(Slider_ID, Slider_Scale_Value); ImGui::EndTable(); } - std::shared_ptr controller = Ship::Context::GetInstance()->GetControlDeck()->GetControllerByPort(0); + std::shared_ptr controller = + Ship::Context::GetInstance()->GetControlDeck()->GetControllerByPort(0); for (auto [id, mapping] : controller->GetButton(BTN_DDOWN)->GetAllButtonMappings()) { controller->GetButton(BTN_CUSTOM_OCARINA_NOTE_F4)->AddButtonMapping(mapping); } @@ -1357,37 +1640,37 @@ void C_Button_Dropdown(const char* Header_Title, const char* Table_ID, const cha UIWidgets::PopStyleHeader(); } -void Draw_Placements(){ +void Draw_Placements() { UIWidgets::PushStyleHeader(THEME_COLOR); ImGui::SeparatorText("General Margins Settings"); UIWidgets::CVarSliderInt("Top: %dpx", CVAR_COSMETIC("HUD.Margin.T"), - UIWidgets::IntSliderOptions() - .Min(static_cast(ImGui::GetWindowViewport()->Size.y / 2) * -1) - .Max(25) - .DefaultValue(0) - .Size(ImVec2(300.0f, 0.0f)) - .Color(THEME_COLOR)); + UIWidgets::IntSliderOptions() + .Min(static_cast(ImGui::GetWindowViewport()->Size.y / 2) * -1) + .Max(25) + .DefaultValue(0) + .Size(ImVec2(300.0f, 0.0f)) + .Color(THEME_COLOR)); UIWidgets::CVarSliderInt("Left: %dpx", CVAR_COSMETIC("HUD.Margin.L"), - UIWidgets::IntSliderOptions() - .Min(-25) - .Max(static_cast(ImGui::GetWindowViewport()->Size.x)) - .DefaultValue(0) - .Size(ImVec2(300.0f, 0.0f)) - .Color(THEME_COLOR)); + UIWidgets::IntSliderOptions() + .Min(-25) + .Max(static_cast(ImGui::GetWindowViewport()->Size.x)) + .DefaultValue(0) + .Size(ImVec2(300.0f, 0.0f)) + .Color(THEME_COLOR)); UIWidgets::CVarSliderInt("Right: %dpx", CVAR_COSMETIC("HUD.Margin.R"), - UIWidgets::IntSliderOptions() - .Min(static_cast(ImGui::GetWindowViewport()->Size.x) * -1) - .Max(25) - .DefaultValue(0) - .Size(ImVec2(300.0f, 0.0f)) - .Color(THEME_COLOR)); + UIWidgets::IntSliderOptions() + .Min(static_cast(ImGui::GetWindowViewport()->Size.x) * -1) + .Max(25) + .DefaultValue(0) + .Size(ImVec2(300.0f, 0.0f)) + .Color(THEME_COLOR)); UIWidgets::CVarSliderInt("Bottom: %dpx", CVAR_COSMETIC("HUD.Margin.B"), - UIWidgets::IntSliderOptions() - .Min(static_cast(ImGui::GetWindowViewport()->Size.y / 2) * -1) - .Max(25) - .DefaultValue(0) - .Size(ImVec2(300.0f, 0.0f)) - .Color(THEME_COLOR)); + UIWidgets::IntSliderOptions() + .Min(static_cast(ImGui::GetWindowViewport()->Size.y / 2) * -1) + .Max(25) + .DefaultValue(0) + .Size(ImVec2(300.0f, 0.0f)) + .Color(THEME_COLOR)); SetMarginAll("All margins on", true, "Set most of the elements to use margins\nSome elements with default position will not be " "affected\nElements without Anchor or Hidden will not be turned on"); @@ -1402,16 +1685,19 @@ void Draw_Placements(){ Table_InitHeader(false); DrawUseMarginsSlider("Hearts counts", CVAR_COSMETIC("HUD.Hearts")); DrawPositionsRadioBoxes(CVAR_COSMETIC("HUD.HeartsCount")); - DrawPositionSlider(CVAR_COSMETIC("HUD.HeartsCount"), -22, static_cast(ImGui::GetWindowViewport()->Size.y), -125, static_cast(ImGui::GetWindowViewport()->Size.x)); + DrawPositionSlider(CVAR_COSMETIC("HUD.HeartsCount"), -22, + static_cast(ImGui::GetWindowViewport()->Size.y), -125, + static_cast(ImGui::GetWindowViewport()->Size.x)); DrawScaleSlider(CVAR_COSMETIC("HUD.HeartsCount"), 0.7f); - UIWidgets::CVarSliderInt("Heart line length : %d", CVAR_COSMETIC("HUD.Hearts.LineLength"), - UIWidgets::IntSliderOptions() - .Min(0) - .Max(20) - .DefaultValue(0) - .Size(ImVec2(300.0f, 0.0f)) - .Color(THEME_COLOR) - .Tooltip("This will set the length of a row of hearts. Set to 0 for unlimited length.")); + UIWidgets::CVarSliderInt( + "Heart line length : %d", CVAR_COSMETIC("HUD.Hearts.LineLength"), + UIWidgets::IntSliderOptions() + .Min(0) + .Max(20) + .DefaultValue(0) + .Size(ImVec2(300.0f, 0.0f)) + .Color(THEME_COLOR) + .Tooltip("This will set the length of a row of hearts. Set to 0 for unlimited length.")); ImGui::EndTable(); } } @@ -1426,12 +1712,15 @@ void Draw_Placements(){ UIWidgets::RadioButtonsOptions() .Color(THEME_COLOR) .Tooltip("This will make your elements follow the bottom of the life meter")); - DrawPositionSlider(CVAR_COSMETIC("HUD.MagicBar"), 0, static_cast(ImGui::GetWindowViewport()->Size.y / 2), -5, static_cast(ImGui::GetWindowViewport()->Size.x / 2)); + DrawPositionSlider(CVAR_COSMETIC("HUD.MagicBar"), 0, + static_cast(ImGui::GetWindowViewport()->Size.y / 2), -5, + static_cast(ImGui::GetWindowViewport()->Size.x / 2)); DrawScaleSlider(CVAR_COSMETIC("HUD.MagicBar"), 1.0f); ImGui::EndTable(); } } - if (CVarGetInteger(CVAR_ENHANCEMENT("VisualAgony"), 0) && ImGui::CollapsingHeader("Visual stone of agony position")) { + if (CVarGetInteger(CVAR_ENHANCEMENT("VisualAgony"), 0) && + ImGui::CollapsingHeader("Visual stone of agony position")) { if (ImGui::BeginTable("tabledvisualstoneofagony", 1, FlagsTable)) { ImGui::TableSetupColumn("Visual stone of agony settings", FlagsCell, TablesCellsWidth); Table_InitHeader(false); @@ -1439,23 +1728,34 @@ void Draw_Placements(){ DrawPositionsRadioBoxes(CVAR_COSMETIC("HUD.VisualSoA")); s16 Min_X_VSOA = 0; s16 Max_X_VSOA = static_cast(ImGui::GetWindowViewport()->Size.x / 2); - if (CVarGetInteger(CVAR_COSMETIC("HUD.VisualSoA.PosType"), 0) == ANCHOR_RIGHT){ + if (CVarGetInteger(CVAR_COSMETIC("HUD.VisualSoA.PosType"), 0) == ANCHOR_RIGHT) { Max_X_VSOA = 290; - } else if (CVarGetInteger(CVAR_COSMETIC("HUD.VisualSoA.PosType"), 0) == HIDDEN){ + } else if (CVarGetInteger(CVAR_COSMETIC("HUD.VisualSoA.PosType"), 0) == HIDDEN) { Min_X_VSOA = static_cast(ImGui::GetWindowViewport()->Size.x / 2) * -1; } - DrawPositionSlider(CVAR_COSMETIC("HUD.VisualSoA"), 0, static_cast(ImGui::GetWindowViewport()->Size.y / 2), Min_X_VSOA, Max_X_VSOA); + DrawPositionSlider(CVAR_COSMETIC("HUD.VisualSoA"), 0, + static_cast(ImGui::GetWindowViewport()->Size.y / 2), Min_X_VSOA, Max_X_VSOA); DrawScaleSlider(CVAR_COSMETIC("HUD.VisualSoA"), 1.0f); ImGui::EndTable(); } } - Draw_Table_Dropdown("B Button position", "tablebbtn", "B Button settings", "B Button", CVAR_COSMETIC("HUD.BButton"), 0, static_cast(ImGui::GetWindowViewport()->Size.y / 4) + 50, -1, static_cast(ImGui::GetWindowViewport()->Size.x) - 50, 0.95f); - Draw_Table_Dropdown("A Button position", "tableabtn", "A Button settings", "A Button", CVAR_COSMETIC("HUD.AButton"), -10, static_cast(ImGui::GetWindowViewport()->Size.y / 4) + 50, -20, static_cast(ImGui::GetWindowViewport()->Size.x) - 50, 0.95f); - Draw_Table_Dropdown("Start Button position", "tablestartbtn", "Start Button settings", "Start Button", CVAR_COSMETIC("HUD.StartButton"), 0, static_cast(ImGui::GetWindowViewport()->Size.y / 2), 0, static_cast(ImGui::GetWindowViewport()->Size.x / 2) + 70, 0.75f); - C_Button_Dropdown("C Button Up position", "tablecubtn", "C Button Up settings", "C Button Up", CVAR_COSMETIC("HUD.CUpButton"), CVAR_COSMETIC("HUD.CUpButton.PosType"), 0.5f); - C_Button_Dropdown("C Button Down position", "tablecdbtn", "C Button Down settings", "C Button Down", CVAR_COSMETIC("HUD.CDownButton"), CVAR_COSMETIC("HUD.CDownButton.PosType"), 0.87f); - C_Button_Dropdown("C Button Left position", "tableclbtn", "C Button Left settings", "C Button Left", CVAR_COSMETIC("HUD.CLeftButton"), CVAR_COSMETIC("HUD.CLeftButton.PosType"), 0.87f); - C_Button_Dropdown("C Button Right position", "tablecrbtn", "C Button Right settings", "C Button Right", CVAR_COSMETIC("HUD.CRightButton"), CVAR_COSMETIC("HUD.CRightButton.PosType"), 0.87f); + Draw_Table_Dropdown("B Button position", "tablebbtn", "B Button settings", "B Button", CVAR_COSMETIC("HUD.BButton"), + 0, static_cast(ImGui::GetWindowViewport()->Size.y / 4) + 50, -1, + static_cast(ImGui::GetWindowViewport()->Size.x) - 50, 0.95f); + Draw_Table_Dropdown("A Button position", "tableabtn", "A Button settings", "A Button", CVAR_COSMETIC("HUD.AButton"), + -10, static_cast(ImGui::GetWindowViewport()->Size.y / 4) + 50, -20, + static_cast(ImGui::GetWindowViewport()->Size.x) - 50, 0.95f); + Draw_Table_Dropdown("Start Button position", "tablestartbtn", "Start Button settings", "Start Button", + CVAR_COSMETIC("HUD.StartButton"), 0, static_cast(ImGui::GetWindowViewport()->Size.y / 2), + 0, static_cast(ImGui::GetWindowViewport()->Size.x / 2) + 70, 0.75f); + C_Button_Dropdown("C Button Up position", "tablecubtn", "C Button Up settings", "C Button Up", + CVAR_COSMETIC("HUD.CUpButton"), CVAR_COSMETIC("HUD.CUpButton.PosType"), 0.5f); + C_Button_Dropdown("C Button Down position", "tablecdbtn", "C Button Down settings", "C Button Down", + CVAR_COSMETIC("HUD.CDownButton"), CVAR_COSMETIC("HUD.CDownButton.PosType"), 0.87f); + C_Button_Dropdown("C Button Left position", "tableclbtn", "C Button Left settings", "C Button Left", + CVAR_COSMETIC("HUD.CLeftButton"), CVAR_COSMETIC("HUD.CLeftButton.PosType"), 0.87f); + C_Button_Dropdown("C Button Right position", "tablecrbtn", "C Button Right settings", "C Button Right", + CVAR_COSMETIC("HUD.CRightButton"), CVAR_COSMETIC("HUD.CRightButton.PosType"), 0.87f); if (CVarGetInteger(CVAR_ENHANCEMENT("DpadEquips"), 0) && ImGui::CollapsingHeader("DPad items position")) { if (ImGui::BeginTable("tabledpaditems", 1, FlagsTable)) { ImGui::TableSetupColumn("DPad items settings", FlagsCell, TablesCellsWidth); @@ -1469,39 +1769,53 @@ void Draw_Placements(){ } else if (CVarGetInteger(CVAR_COSMETIC("HUD.Dpad.PosType"), 0) == HIDDEN) { Min_X_Dpad = static_cast(ImGui::GetWindowViewport()->Size.x / 2) * -1; } - DrawPositionSlider(CVAR_COSMETIC("HUD.Dpad"), 0, static_cast(ImGui::GetWindowViewport()->Size.y / 2), Min_X_Dpad, Max_X_Dpad); + DrawPositionSlider(CVAR_COSMETIC("HUD.Dpad"), 0, static_cast(ImGui::GetWindowViewport()->Size.y / 2), + Min_X_Dpad, Max_X_Dpad); DrawScaleSlider(CVAR_COSMETIC("HUD.Dpad"), 1.0f); ImGui::EndTable(); } } - Draw_Table_Dropdown("Minimaps position", "tableminimapspos", "minimaps settings", "Minimap", CVAR_COSMETIC("HUD.Minimap"), - static_cast(ImGui::GetWindowViewport()->Size.y / 3) * -1, static_cast(ImGui::GetWindowViewport()->Size.y / 3), static_cast(ImGui::GetWindowViewport()->Size.x) * -1, static_cast(ImGui::GetWindowViewport()->Size.x / 2), 1.0f); - Draw_Table_Dropdown("Small Keys counter position", "tablesmolekeys", "Small Keys counter settings", "Small Keys counter", CVAR_COSMETIC("HUD.SmallKey"), - 0, static_cast(ImGui::GetWindowViewport()->Size.y / 3), -1, static_cast(ImGui::GetWindowViewport()->Size.x / 2), 1.0f); - Draw_Table_Dropdown("Rupee counter position", "tablerupeecount", "Rupee counter settings", "Rupee counter", CVAR_COSMETIC("HUD.Rupees"), - -2, static_cast(ImGui::GetWindowViewport()->Size.y / 3), -3, static_cast(ImGui::GetWindowViewport()->Size.x / 2), 1.0f); + Draw_Table_Dropdown("Minimaps position", "tableminimapspos", "minimaps settings", "Minimap", + CVAR_COSMETIC("HUD.Minimap"), static_cast(ImGui::GetWindowViewport()->Size.y / 3) * -1, + static_cast(ImGui::GetWindowViewport()->Size.y / 3), + static_cast(ImGui::GetWindowViewport()->Size.x) * -1, + static_cast(ImGui::GetWindowViewport()->Size.x / 2), 1.0f); + Draw_Table_Dropdown("Small Keys counter position", "tablesmolekeys", "Small Keys counter settings", + "Small Keys counter", CVAR_COSMETIC("HUD.SmallKey"), 0, + static_cast(ImGui::GetWindowViewport()->Size.y / 3), -1, + static_cast(ImGui::GetWindowViewport()->Size.x / 2), 1.0f); + Draw_Table_Dropdown("Rupee counter position", "tablerupeecount", "Rupee counter settings", "Rupee counter", + CVAR_COSMETIC("HUD.Rupees"), -2, static_cast(ImGui::GetWindowViewport()->Size.y / 3), -3, + static_cast(ImGui::GetWindowViewport()->Size.x / 2), 1.0f); Draw_Table_Dropdown("Carrots position", "tableCarrots", "Carrots settings", "Carrots", CVAR_COSMETIC("HUD.Carrots"), - 0, static_cast(ImGui::GetWindowViewport()->Size.y / 2), -50, static_cast(ImGui::GetWindowViewport()->Size.x / 2) + 25, 1.0f); - Draw_Table_Dropdown("Timers position", "tabletimers", "Timers settings", "Timers", CVAR_COSMETIC("HUD.Timers"), - 0, static_cast(ImGui::GetWindowViewport()->Size.y / 2), -50, static_cast(ImGui::GetWindowViewport()->Size.x / 2) - 50, 1.0f); - Draw_Table_Dropdown("Archery Scores position", "tablearchery", "Archery Scores settings", "Archery scores", CVAR_COSMETIC("HUD.ArcheryScore"), - 0, static_cast(ImGui::GetWindowViewport()->Size.y / 2), -50, static_cast(ImGui::GetWindowViewport()->Size.x / 2) - 50, 1.0f); - Draw_Table_Dropdown("Title cards (Maps) position", "tabletcmaps", "Titlecard maps settings", "Title cards (overworld)", CVAR_COSMETIC("HUD.TitleCard.Map"), - 0, static_cast(ImGui::GetWindowViewport()->Size.y / 2), -50, static_cast(ImGui::GetWindowViewport()->Size.x / 2) + 10, 1.0f); - Draw_Table_Dropdown("Title cards (Bosses) position", "tabletcbosses", "Title cards (Bosses) settings", "Title cards (Bosses)", CVAR_COSMETIC("HUD.TitleCard.Boss"), - 0, static_cast(ImGui::GetWindowViewport()->Size.y / 2), -50, static_cast(ImGui::GetWindowViewport()->Size.x / 2) + 10, 1.0f); - Draw_Table_Dropdown("In-game Gameplay Timer position", "tablegameplaytimer", "In-game Gameplay Timer settings", "In-game Gameplay Timer", CVAR_COSMETIC("HUD.IGT"), - 0, static_cast(ImGui::GetWindowViewport()->Size.y / 2), -50, static_cast(ImGui::GetWindowViewport()->Size.x / 2) + 10, 1.0f); + 0, static_cast(ImGui::GetWindowViewport()->Size.y / 2), -50, + static_cast(ImGui::GetWindowViewport()->Size.x / 2) + 25, 1.0f); + Draw_Table_Dropdown("Timers position", "tabletimers", "Timers settings", "Timers", CVAR_COSMETIC("HUD.Timers"), 0, + static_cast(ImGui::GetWindowViewport()->Size.y / 2), -50, + static_cast(ImGui::GetWindowViewport()->Size.x / 2) - 50, 1.0f); + Draw_Table_Dropdown("Archery Scores position", "tablearchery", "Archery Scores settings", "Archery scores", + CVAR_COSMETIC("HUD.ArcheryScore"), 0, static_cast(ImGui::GetWindowViewport()->Size.y / 2), + -50, static_cast(ImGui::GetWindowViewport()->Size.x / 2) - 50, 1.0f); + Draw_Table_Dropdown("Title cards (Maps) position", "tabletcmaps", "Titlecard maps settings", + "Title cards (overworld)", CVAR_COSMETIC("HUD.TitleCard.Map"), 0, + static_cast(ImGui::GetWindowViewport()->Size.y / 2), -50, + static_cast(ImGui::GetWindowViewport()->Size.x / 2) + 10, 1.0f); + Draw_Table_Dropdown("Title cards (Bosses) position", "tabletcbosses", "Title cards (Bosses) settings", + "Title cards (Bosses)", CVAR_COSMETIC("HUD.TitleCard.Boss"), 0, + static_cast(ImGui::GetWindowViewport()->Size.y / 2), -50, + static_cast(ImGui::GetWindowViewport()->Size.x / 2) + 10, 1.0f); + Draw_Table_Dropdown("In-game Gameplay Timer position", "tablegameplaytimer", "In-game Gameplay Timer settings", + "In-game Gameplay Timer", CVAR_COSMETIC("HUD.IGT"), 0, + static_cast(ImGui::GetWindowViewport()->Size.y / 2), -50, + static_cast(ImGui::GetWindowViewport()->Size.x / 2) + 10, 1.0f); if (ImGui::CollapsingHeader("Enemy Health Bar position")) { if (ImGui::BeginTable("enemyhealthbar", 1, FlagsTable)) { ImGui::TableSetupColumn("Enemy Health Bar settings", FlagsCell, TablesCellsWidth); Table_InitHeader(false); std::string posTypeCVar = CVAR_COSMETIC("HUD.EnemyHealthBar.PosType"); - UIWidgets::CVarRadioButton("Anchor to Enemy", CVAR_COSMETIC("HUD.EnemyHealthBar.PosType"), - ENEMYHEALTH_ANCHOR_ACTOR, - UIWidgets::RadioButtonsOptions() - .Color(THEME_COLOR) - .Tooltip("This will use enemy on screen position")); + UIWidgets::CVarRadioButton( + "Anchor to Enemy", CVAR_COSMETIC("HUD.EnemyHealthBar.PosType"), ENEMYHEALTH_ANCHOR_ACTOR, + UIWidgets::RadioButtonsOptions().Color(THEME_COLOR).Tooltip("This will use enemy on screen position")); UIWidgets::CVarRadioButton( "Anchor to the top", CVAR_COSMETIC("HUD.EnemyHealthBar.PosType"), ENEMYHEALTH_ANCHOR_TOP, UIWidgets::RadioButtonsOptions() @@ -1512,22 +1826,23 @@ void Draw_Placements(){ UIWidgets::RadioButtonsOptions() .Color(THEME_COLOR) .Tooltip("This will make your elements follow the bottom edge of your game window")); - DrawPositionSlider(CVAR_COSMETIC("HUD.EnemyHealthBar."), -SCREEN_HEIGHT, SCREEN_HEIGHT, -static_cast(ImGui::GetWindowViewport()->Size.x / 2), static_cast(ImGui::GetWindowViewport()->Size.x / 2)); - if (UIWidgets::CVarSliderInt( - "Health Bar Width: %d", CVAR_COSMETIC("HUD.EnemyHealthBar.Width.Value"), - UIWidgets::IntSliderOptions() - .Min(32) - .Max(128) - .DefaultValue(64) - .Size(ImVec2(300.0f, 0.0f)) - .Color(THEME_COLOR) - .Tooltip("This will change the width of the health bar"))) { + DrawPositionSlider(CVAR_COSMETIC("HUD.EnemyHealthBar."), -SCREEN_HEIGHT, SCREEN_HEIGHT, + -static_cast(ImGui::GetWindowViewport()->Size.x / 2), + static_cast(ImGui::GetWindowViewport()->Size.x / 2)); + if (UIWidgets::CVarSliderInt("Health Bar Width: %d", CVAR_COSMETIC("HUD.EnemyHealthBar.Width.Value"), + UIWidgets::IntSliderOptions() + .Min(32) + .Max(128) + .DefaultValue(64) + .Size(ImVec2(300.0f, 0.0f)) + .Color(THEME_COLOR) + .Tooltip("This will change the width of the health bar"))) { CVarSetInteger(CVAR_COSMETIC("HUD.EnemyHealthBar.Width.Changed"), 1); } ImGui::SameLine(); ImGui::SetCursorPosY(ImGui::GetCursorPosY() + (ImGui::CalcTextSize("g").y * 2)); if (UIWidgets::Button("Reset##EnemyHealthBarWidth", - UIWidgets::ButtonOptions().Size(ImVec2(80, 36)).Padding(ImVec2(5.0f, 0.0f)))) { + UIWidgets::ButtonOptions().Size(ImVec2(80, 36)).Padding(ImVec2(5.0f, 0.0f)))) { CVarClear(CVAR_COSMETIC("HUD.EnemyHealthBar.Width.Value")); CVarClear(CVAR_COSMETIC("HUD.EnemyHealthBar.Width.Changed")); } @@ -1540,8 +1855,7 @@ void Draw_Placements(){ void Reset_Option_Single(const char* Button_Title, const char* name) { ImGui::SameLine(); ImGui::SetCursorPosY(ImGui::GetCursorPosY() + (ImGui::CalcTextSize("g").y * 2)); - if (UIWidgets::Button(Button_Title, - UIWidgets::ButtonOptions().Size(ImVec2(80, 36)).Padding(ImVec2(5.0f, 0.0f)))) { + if (UIWidgets::Button(Button_Title, UIWidgets::ButtonOptions().Size(ImVec2(80, 36)).Padding(ImVec2(5.0f, 0.0f)))) { CVarClear(name); } } @@ -1549,8 +1863,7 @@ void Reset_Option_Single(const char* Button_Title, const char* name) { void Reset_Option_Double(const char* Button_Title, const char* name) { ImGui::SameLine(); ImGui::SetCursorPosY(ImGui::GetCursorPosY() + (ImGui::CalcTextSize("g").y * 2)); - if (UIWidgets::Button(Button_Title, - UIWidgets::ButtonOptions().Size(ImVec2(80, 36)).Padding(ImVec2(5.0f, 0.0f)))) { + if (UIWidgets::Button(Button_Title, UIWidgets::ButtonOptions().Size(ImVec2(80, 36)).Padding(ImVec2(5.0f, 0.0f)))) { CVarClear((std::string(name) + ".Value").c_str()); CVarClear((std::string(name) + ".Changed").c_str()); } @@ -1562,27 +1875,28 @@ void DrawSillyTab() { UIWidgets::Separator(true, true, 2.0f, 2.0f); UIWidgets::CVarCheckbox("Let It Snow", CVAR_GENERAL("LetItSnow"), - UIWidgets::CheckboxOptions() - .Color(THEME_COLOR) - .Tooltip("Makes snow fall, changes chest texture colors to red and green, etc, for December holidays.\nWill reset on restart outside of December 23-25.")); + UIWidgets::CheckboxOptions() + .Color(THEME_COLOR) + .Tooltip("Makes snow fall, changes chest texture colors to red and green, etc, for " + "December holidays.\nWill reset on restart outside of December 23-25.")); UIWidgets::Separator(true, true, 2.0f, 2.0f); if (UIWidgets::CVarSliderFloat("Link Body Size", CVAR_COSMETIC("Link.BodySize.Value"), - UIWidgets::FloatSliderOptions() - .Format("%.3f") - .Min(0.001f) - .Max(0.05f) - .DefaultValue(0.01f) - .Step(0.001f) - .Size(ImVec2(300.0f, 0.0f)) - .Color(THEME_COLOR))) { + UIWidgets::FloatSliderOptions() + .Format("%.3f") + .Min(0.001f) + .Max(0.05f) + .DefaultValue(0.01f) + .Step(0.001f) + .Size(ImVec2(300.0f, 0.0f)) + .Color(THEME_COLOR))) { CVarSetInteger(CVAR_COSMETIC("Link.BodySize.Changed"), 1); } ImGui::SameLine(); ImGui::SetCursorPosY(ImGui::GetCursorPosY() + (ImGui::CalcTextSize("g").y * 2)); if (UIWidgets::Button("Reset##Link_BodySize", - UIWidgets::ButtonOptions().Size(ImVec2(80, 36)).Padding(ImVec2(5.0f, 0.0f)))) { + UIWidgets::ButtonOptions().Size(ImVec2(80, 36)).Padding(ImVec2(5.0f, 0.0f)))) { CVarClear(CVAR_COSMETIC("Link.BodySize.Value")); CVarClear(CVAR_COSMETIC("Link.BodySize.Changed")); if (gPlayState != nullptr) { @@ -1595,14 +1909,14 @@ void DrawSillyTab() { UIWidgets::Separator(true, true, 2.0f, 2.0f); if (UIWidgets::CVarSliderFloat("Link Head Scale", CVAR_COSMETIC("Link.HeadScale.Value"), - UIWidgets::FloatSliderOptions() - .Format("%.1fx") - .Min(0.1f) - .Max(5.0f) - .DefaultValue(1.0f) - .Step(0.1f) - .Size(ImVec2(300.0f, 0.0f)) - .Color(THEME_COLOR))) { + UIWidgets::FloatSliderOptions() + .Format("%.1fx") + .Min(0.1f) + .Max(5.0f) + .DefaultValue(1.0f) + .Step(0.1f) + .Size(ImVec2(300.0f, 0.0f)) + .Color(THEME_COLOR))) { CVarSetInteger(CVAR_COSMETIC("Link.HeadScale.Changed"), 1); } Reset_Option_Double("Reset##Link_HeadScale", CVAR_COSMETIC("Link.HeadScale")); @@ -1610,14 +1924,14 @@ void DrawSillyTab() { UIWidgets::Separator(true, true, 2.0f, 2.0f); if (UIWidgets::CVarSliderFloat("Link Sword Scale", CVAR_COSMETIC("Link.SwordScale.Value"), - UIWidgets::FloatSliderOptions() - .Format("%.1fx") - .Min(0.1f) - .Max(5.0f) - .DefaultValue(1.0f) - .Step(0.1f) - .Size(ImVec2(300.0f, 0.0f)) - .Color(THEME_COLOR))) { + UIWidgets::FloatSliderOptions() + .Format("%.1fx") + .Min(0.1f) + .Max(5.0f) + .DefaultValue(1.0f) + .Step(0.1f) + .Size(ImVec2(300.0f, 0.0f)) + .Color(THEME_COLOR))) { CVarSetInteger(CVAR_COSMETIC("Link.SwordScale.Changed"), 1); } Reset_Option_Double("Reset##Link_SwordScale", CVAR_COSMETIC("Link.SwordScale")); @@ -1625,98 +1939,97 @@ void DrawSillyTab() { UIWidgets::Separator(true, true, 2.0f, 2.0f); UIWidgets::CVarSliderFloat("Bunny Hood Length", CVAR_COSMETIC("BunnyHood.EarLength"), - UIWidgets::FloatSliderOptions() - .Format("%.0f") - .Min(-300.0f) - .Max(1000.0f) - .DefaultValue(0.0f) - .Step(10.0f) - .Size(ImVec2(300.0f, 0.0f)) - .Color(THEME_COLOR)); + UIWidgets::FloatSliderOptions() + .Format("%.0f") + .Min(-300.0f) + .Max(1000.0f) + .DefaultValue(0.0f) + .Step(10.0f) + .Size(ImVec2(300.0f, 0.0f)) + .Color(THEME_COLOR)); Reset_Option_Single("Reset##BunnyHood_EarLength", CVAR_COSMETIC("BunnyHood.EarLength")); UIWidgets::Separator(true, true, 2.0f, 2.0f); UIWidgets::CVarSliderFloat("Bunny Hood Spread", CVAR_COSMETIC("BunnyHood.EarSpread"), - UIWidgets::FloatSliderOptions() - .Format("%.0f") - .Min(-300.0f) - .Max(500.0f) - .DefaultValue(0.0f) - .Step(10.0f) - .Size(ImVec2(300.0f, 0.0f)) - .Color(THEME_COLOR)); + UIWidgets::FloatSliderOptions() + .Format("%.0f") + .Min(-300.0f) + .Max(500.0f) + .DefaultValue(0.0f) + .Step(10.0f) + .Size(ImVec2(300.0f, 0.0f)) + .Color(THEME_COLOR)); Reset_Option_Single("Reset##BunnyHood_EarSpread", CVAR_COSMETIC("BunnyHood.EarSpread")); UIWidgets::Separator(true, true, 2.0f, 2.0f); UIWidgets::CVarSliderFloat("Goron Neck Length", CVAR_COSMETIC("Goron.NeckLength"), - UIWidgets::FloatSliderOptions() - .Format("%.0f") - .Min(0.0f) - .Max(5000.0f) - .DefaultValue(0.0f) - .Step(10.0f) - .Size(ImVec2(300.0f, 0.0f)) - .Color(THEME_COLOR)); + UIWidgets::FloatSliderOptions() + .Format("%.0f") + .Min(0.0f) + .Max(5000.0f) + .DefaultValue(0.0f) + .Step(10.0f) + .Size(ImVec2(300.0f, 0.0f)) + .Color(THEME_COLOR)); Reset_Option_Single("Reset##Goron_NeckLength", CVAR_COSMETIC("Goron.NeckLength")); UIWidgets::Separator(true, true, 2.0f, 2.0f); UIWidgets::CVarCheckbox("Unfix Goron Spin", CVAR_COSMETIC("UnfixGoronSpin"), - UIWidgets::CheckboxOptions() - .Color(THEME_COLOR)); + UIWidgets::CheckboxOptions().Color(THEME_COLOR)); UIWidgets::Separator(true, true, 2.0f, 2.0f); UIWidgets::CVarSliderFloat("Fairies Size", CVAR_COSMETIC("Fairies.Size"), - UIWidgets::FloatSliderOptions() - .Format("%.1fx") - .Min(0.1f) - .Max(5.0f) - .DefaultValue(1.0f) - .Step(0.1f) - .Size(ImVec2(300.0f, 0.0f)) - .Color(THEME_COLOR)); + UIWidgets::FloatSliderOptions() + .Format("%.1fx") + .Min(0.1f) + .Max(5.0f) + .DefaultValue(1.0f) + .Step(0.1f) + .Size(ImVec2(300.0f, 0.0f)) + .Color(THEME_COLOR)); Reset_Option_Single("Reset##Fairies_Size", CVAR_COSMETIC("Fairies.Size")); UIWidgets::Separator(true, true, 2.0f, 2.0f); UIWidgets::CVarSliderFloat("N64 Logo Spin Speed", CVAR_COSMETIC("N64Logo.SpinSpeed"), - UIWidgets::FloatSliderOptions() - .Format("%.1fx") - .Min(0.1f) - .Max(5.0f) - .DefaultValue(1.0f) - .Step(0.1f) - .Size(ImVec2(300.0f, 0.0f)) - .Color(THEME_COLOR)); + UIWidgets::FloatSliderOptions() + .Format("%.1fx") + .Min(0.1f) + .Max(5.0f) + .DefaultValue(1.0f) + .Step(0.1f) + .Size(ImVec2(300.0f, 0.0f)) + .Color(THEME_COLOR)); Reset_Option_Single("Reset##N64Logo_SpinSpeed", CVAR_COSMETIC("N64Logo.SpinSpeed")); UIWidgets::Separator(true, true, 2.0f, 2.0f); UIWidgets::CVarSliderFloat("Moon Size", CVAR_COSMETIC("Moon.Size"), - UIWidgets::FloatSliderOptions() - .Format("%.1fx") - .Min(0.1f) - .Max(5.0f) - .DefaultValue(1.0f) - .Step(0.1f) - .Size(ImVec2(300.0f, 0.0f)) - .Color(THEME_COLOR)); + UIWidgets::FloatSliderOptions() + .Format("%.1fx") + .Min(0.1f) + .Max(5.0f) + .DefaultValue(1.0f) + .Step(0.1f) + .Size(ImVec2(300.0f, 0.0f)) + .Color(THEME_COLOR)); Reset_Option_Single("Reset##Moon_Size", CVAR_COSMETIC("Moon.Size")); UIWidgets::Separator(true, true, 2.0f, 2.0f); if (UIWidgets::CVarSliderFloat("Kak Windmill Speed", CVAR_COSMETIC("Kak.Windmill_Speed.Value"), - UIWidgets::FloatSliderOptions() - .Format("%.0f") - .Min(100.0f) - .Max(6000.0f) - .DefaultValue(100.0f) - .Step(10.0f) - .Size(ImVec2(300.0f, 0.0f)) - .Color(THEME_COLOR))) { + UIWidgets::FloatSliderOptions() + .Format("%.0f") + .Min(100.0f) + .Max(6000.0f) + .DefaultValue(100.0f) + .Step(10.0f) + .Size(ImVec2(300.0f, 0.0f)) + .Color(THEME_COLOR))) { CVarSetInteger(CVAR_COSMETIC("Kak.Windmill_Speed.Changed"), 1); } Reset_Option_Double("Reset##Kak_Windmill_Speed", CVAR_COSMETIC("Kak.Windmill_Speed")); @@ -1728,7 +2041,8 @@ void DrawSillyTab() { // Copies the RGB values from one cosmetic option to another, multiplied by the passed in amount, this // allows you create and use multiple shades of the same color. -void CopyMultipliedColor(CosmeticOption& cosmeticOptionSrc, CosmeticOption& cosmeticOptionTarget, float amount = 0.75f) { +void CopyMultipliedColor(CosmeticOption& cosmeticOptionSrc, CosmeticOption& cosmeticOptionTarget, + float amount = 0.75f) { Color_RGBA8 newColor; newColor.r = static_cast(MIN((cosmeticOptionSrc.currentColor.x * 255.0f) * amount, 255)); newColor.g = static_cast(MIN((cosmeticOptionSrc.currentColor.y * 255.0f) * amount, 255)); @@ -1807,7 +2121,8 @@ void RandomizeColor(CosmeticOption& cosmeticOption) { } void ResetColor(CosmeticOption& cosmeticOption) { - Color_RGBA8 defaultColor = {cosmeticOption.defaultColor.r, cosmeticOption.defaultColor.g, cosmeticOption.defaultColor.b, cosmeticOption.defaultColor.a}; + Color_RGBA8 defaultColor = { cosmeticOption.defaultColor.r, cosmeticOption.defaultColor.g, + cosmeticOption.defaultColor.b, cosmeticOption.defaultColor.a }; cosmeticOption.currentColor.x = defaultColor.r / 255.0f; cosmeticOption.currentColor.y = defaultColor.g / 255.0f; cosmeticOption.currentColor.z = defaultColor.b / 255.0f; @@ -1867,16 +2182,15 @@ void ResetColor(CosmeticOption& cosmeticOption) { } void DrawCosmeticRow(CosmeticOption& cosmeticOption) { - if (UIWidgets::CVarColorPicker(cosmeticOption.label.c_str(), cosmeticOption.cvar, - cosmeticOption.defaultColor, - cosmeticOption.supportsAlpha, 0, THEME_COLOR)) { + if (UIWidgets::CVarColorPicker(cosmeticOption.label.c_str(), cosmeticOption.cvar, cosmeticOption.defaultColor, + cosmeticOption.supportsAlpha, 0, THEME_COLOR)) { CVarSetInteger((cosmeticOption.rainbowCvar), 0); CVarSetInteger((cosmeticOption.changedCvar), 1); ApplySideEffects(cosmeticOption); ApplyOrResetCustomGfxPatches(); Ship::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesNextFrame(); } - //the longest option name + // the longest option name ImGui::SameLine((ImGui::CalcTextSize("Message Light Blue (None No Shadow)").x * 1.0f) + 60.0f); if (UIWidgets::Button( ("Random##" + cosmeticOption.label).c_str(), @@ -1888,7 +2202,7 @@ void DrawCosmeticRow(CosmeticOption& cosmeticOption) { if (cosmeticOption.supportsRainbow) { ImGui::SameLine(); if (UIWidgets::CVarCheckbox(("Rainbow##" + cosmeticOption.label).c_str(), cosmeticOption.rainbowCvar, - UIWidgets::CheckboxOptions().Color(THEME_COLOR))) { + UIWidgets::CheckboxOptions().Color(THEME_COLOR))) { CVarSetInteger((cosmeticOption.changedCvar), 1); ApplySideEffects(cosmeticOption); ApplyOrResetCustomGfxPatches(); @@ -1898,12 +2212,12 @@ void DrawCosmeticRow(CosmeticOption& cosmeticOption) { ImGui::SameLine(); UIWidgets::CVarCheckbox(("Locked##" + cosmeticOption.label).c_str(), cosmeticOption.lockedCvar, - UIWidgets::CheckboxOptions().Color(THEME_COLOR)); + UIWidgets::CheckboxOptions().Color(THEME_COLOR)); if (CVarGetInteger((cosmeticOption.changedCvar), 0)) { ImGui::SameLine(); if (UIWidgets::Button(("Reset##" + cosmeticOption.label).c_str(), - UIWidgets::ButtonOptions().Size(ImVec2(80, 31)).Padding(ImVec2(2.0f, 0.0f)))) { + UIWidgets::ButtonOptions().Size(ImVec2(80, 31)).Padding(ImVec2(2.0f, 0.0f)))) { ResetColor(cosmeticOption); ApplyOrResetCustomGfxPatches(); Ship::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesNextFrame(); @@ -1916,7 +2230,8 @@ void DrawCosmeticGroup(CosmeticGroup cosmeticGroup) { ImGui::Text("%s", label.c_str()); // the longest option name ImGui::SameLine((ImGui::CalcTextSize("Message Light Blue (None No Shadow)").x * 1.0f) + 60.0f); - if (UIWidgets::Button(("Random##" + label).c_str(), + if (UIWidgets::Button( + ("Random##" + label).c_str(), UIWidgets::ButtonOptions().Size(ImVec2(80, 31)).Padding(ImVec2(2.0f, 0.0f)).Color(THEME_COLOR))) { for (auto& [id, cosmeticOption] : cosmeticOptions) { if (cosmeticOption.group == cosmeticGroup && @@ -1929,7 +2244,7 @@ void DrawCosmeticGroup(CosmeticGroup cosmeticGroup) { } ImGui::SameLine(); if (UIWidgets::Button(("Reset##" + label).c_str(), - UIWidgets::ButtonOptions().Size(ImVec2(80, 31)).Padding(ImVec2(2.0f, 0.0f)))) { + UIWidgets::ButtonOptions().Size(ImVec2(80, 31)).Padding(ImVec2(2.0f, 0.0f)))) { for (auto& [id, cosmeticOption] : cosmeticOptions) { if (cosmeticOption.group == cosmeticGroup && !CVarGetInteger(cosmeticOption.lockedCvar, 0)) { ResetColor(cosmeticOption); @@ -1939,7 +2254,8 @@ void DrawCosmeticGroup(CosmeticGroup cosmeticGroup) { } UIWidgets::Spacer(); for (auto& [id, cosmeticOption] : cosmeticOptions) { - if (cosmeticOption.group == cosmeticGroup && (!cosmeticOption.advancedOption || CVarGetInteger(CVAR_COSMETIC("AdvancedMode"), 0))) { + if (cosmeticOption.group == cosmeticGroup && + (!cosmeticOption.advancedOption || CVarGetInteger(CVAR_COSMETIC("AdvancedMode"), 0))) { DrawCosmeticRow(cosmeticOption); } } @@ -2044,27 +2360,26 @@ void CosmeticsEditorWindow::ApplyDungeonKeyColors() { void CosmeticsEditorWindow::DrawElement() { UIWidgets::CVarCombobox("Color Scheme", CVAR_COSMETIC("DefaultColorScheme"), colorSchemes, - UIWidgets::ComboboxOptions() - .DefaultIndex(COLORSCHEME_N64) - .Color(THEME_COLOR) - .LabelPosition(UIWidgets::LabelPositions::Near) - .ComponentAlignment(UIWidgets::ComponentAlignments::Right)); + UIWidgets::ComboboxOptions() + .DefaultIndex(COLORSCHEME_N64) + .Color(THEME_COLOR) + .LabelPosition(UIWidgets::LabelPositions::Near) + .ComponentAlignment(UIWidgets::ComponentAlignments::Right)); UIWidgets::CVarCheckbox("Sync Rainbow colors", CVAR_COSMETIC("RainbowSync"), - UIWidgets::CheckboxOptions() - .Color(THEME_COLOR)); + UIWidgets::CheckboxOptions().Color(THEME_COLOR)); UIWidgets::CVarSliderFloat("Rainbow Speed", CVAR_COSMETIC("RainbowSpeed"), - UIWidgets::FloatSliderOptions() - .Format("%.2f") - .Min(0.01f) - .Max(1.0f) - .DefaultValue(0.6f) - .Step(0.01f) - .Size(ImVec2(300.0f, 0.0f)) - .Color(THEME_COLOR)); + UIWidgets::FloatSliderOptions() + .Format("%.2f") + .Min(0.01f) + .Max(1.0f) + .DefaultValue(0.6f) + .Step(0.01f) + .Size(ImVec2(300.0f, 0.0f)) + .Color(THEME_COLOR)); UIWidgets::CVarCheckbox("Randomize All on New Scene", CVAR_COSMETIC("RandomizeAllOnNewScene"), - UIWidgets::CheckboxOptions() - .Color(THEME_COLOR) - .Tooltip("Enables randomizing all unlocked cosmetics when you enter a new scene.")); + UIWidgets::CheckboxOptions() + .Color(THEME_COLOR) + .Tooltip("Enables randomizing all unlocked cosmetics when you enter a new scene.")); UIWidgets::CVarCheckbox( "Advanced Mode", CVAR_COSMETIC("AdvancedMode"), UIWidgets::CheckboxOptions() @@ -2076,7 +2391,7 @@ void CosmeticsEditorWindow::DrawElement() { "apply.")); if (CVarGetInteger(CVAR_COSMETIC("AdvancedMode"), 0)) { if (UIWidgets::Button("Lock All Advanced", - UIWidgets::ButtonOptions().Size(ImVec2(250.0f, 0.0f)).Color(THEME_COLOR))) { + UIWidgets::ButtonOptions().Size(ImVec2(250.0f, 0.0f)).Color(THEME_COLOR))) { for (auto& [id, cosmeticOption] : cosmeticOptions) { if (cosmeticOption.advancedOption) { CVarSetInteger(cosmeticOption.lockedCvar, 1); @@ -2085,7 +2400,7 @@ void CosmeticsEditorWindow::DrawElement() { } ImGui::SameLine(); if (UIWidgets::Button("Unlock All Advanced", - UIWidgets::ButtonOptions().Size(ImVec2(250.0f, 0.0f)).Color(THEME_COLOR))) { + UIWidgets::ButtonOptions().Size(ImVec2(250.0f, 0.0f)).Color(THEME_COLOR))) { for (auto& [id, cosmeticOption] : cosmeticOptions) { if (cosmeticOption.advancedOption) { CVarSetInteger(cosmeticOption.lockedCvar, 0); @@ -2093,18 +2408,15 @@ void CosmeticsEditorWindow::DrawElement() { } } } - if (UIWidgets::Button("Randomize All", - UIWidgets::ButtonOptions().Size(ImVec2(250.0f, 0.0f)).Color(THEME_COLOR))) { + if (UIWidgets::Button("Randomize All", UIWidgets::ButtonOptions().Size(ImVec2(250.0f, 0.0f)).Color(THEME_COLOR))) { CosmeticsEditor_RandomizeAll(); } ImGui::SameLine(); - if (UIWidgets::Button("Reset All", - UIWidgets::ButtonOptions().Size(ImVec2(250.0f, 0.0f)).Color(THEME_COLOR))) { + if (UIWidgets::Button("Reset All", UIWidgets::ButtonOptions().Size(ImVec2(250.0f, 0.0f)).Color(THEME_COLOR))) { CVarClearBlock("gCosmetics"); ApplyOrResetCustomGfxPatches(); } - if (UIWidgets::Button("Lock All", - UIWidgets::ButtonOptions().Size(ImVec2(250.0f, 0.0f)).Color(THEME_COLOR))) { + if (UIWidgets::Button("Lock All", UIWidgets::ButtonOptions().Size(ImVec2(250.0f, 0.0f)).Color(THEME_COLOR))) { for (auto& [id, cosmeticOption] : cosmeticOptions) { if (!cosmeticOption.advancedOption || CVarGetInteger(CVAR_COSMETIC("AdvancedMode"), 0)) { CVarSetInteger(cosmeticOption.lockedCvar, 1); @@ -2112,8 +2424,7 @@ void CosmeticsEditorWindow::DrawElement() { } } ImGui::SameLine(); - if (UIWidgets::Button("Unlock All", - UIWidgets::ButtonOptions().Size(ImVec2(250.0f, 0.0f)).Color(THEME_COLOR))) { + if (UIWidgets::Button("Unlock All", UIWidgets::ButtonOptions().Size(ImVec2(250.0f, 0.0f)).Color(THEME_COLOR))) { for (auto& [id, cosmeticOption] : cosmeticOptions) { if (!cosmeticOption.advancedOption || CVarGetInteger(CVAR_COSMETIC("AdvancedMode"), 0)) { CVarSetInteger(cosmeticOption.lockedCvar, 0); @@ -2121,8 +2432,7 @@ void CosmeticsEditorWindow::DrawElement() { } } - if (UIWidgets::Button("Rainbow All", - UIWidgets::ButtonOptions().Size(ImVec2(250.0f, 0.0f)).Color(THEME_COLOR))) { + if (UIWidgets::Button("Rainbow All", UIWidgets::ButtonOptions().Size(ImVec2(250.0f, 0.0f)).Color(THEME_COLOR))) { for (auto& [id, cosmeticOption] : cosmeticOptions) { if (!CVarGetInteger(cosmeticOption.lockedCvar, 0) && (!cosmeticOption.advancedOption || CVarGetInteger(CVAR_COSMETIC("AdvancedMode"), 0))) { @@ -2132,8 +2442,7 @@ void CosmeticsEditorWindow::DrawElement() { } } ImGui::SameLine(); - if (UIWidgets::Button("Un-Rainbow All", - UIWidgets::ButtonOptions().Size(ImVec2(250.0f, 0.0f)).Color(THEME_COLOR))) { + if (UIWidgets::Button("Un-Rainbow All", UIWidgets::ButtonOptions().Size(ImVec2(250.0f, 0.0f)).Color(THEME_COLOR))) { for (auto& [id, cosmeticOption] : cosmeticOptions) { if (!CVarGetInteger(cosmeticOption.lockedCvar, 0) && (!cosmeticOption.advancedOption || CVarGetInteger(CVAR_COSMETIC("AdvancedMode"), 0))) { @@ -2163,9 +2472,8 @@ void CosmeticsEditorWindow::DrawElement() { UIWidgets::Separator(true, true, 2.0f, 2.0f); - if (UIWidgets::Button( - "Give all keys dungeon-specific colors", - UIWidgets::ButtonOptions().Color(THEME_COLOR).Size(UIWidgets::Sizes::Inline))) { + if (UIWidgets::Button("Give all keys dungeon-specific colors", + UIWidgets::ButtonOptions().Color(THEME_COLOR).Size(UIWidgets::Sizes::Inline))) { ApplyDungeonKeyColors(); } @@ -2187,19 +2495,18 @@ void CosmeticsEditorWindow::DrawElement() { DrawCosmeticGroup(COSMETICS_GROUP_SPIN_ATTACK); DrawCosmeticGroup(COSMETICS_GROUP_TRAILS); if (UIWidgets::CVarSliderInt("Trails Duration: %d", CVAR_COSMETIC("Trails.Duration.Value"), - UIWidgets::IntSliderOptions() - .Min(2) - .Max(20) - .DefaultValue(4) - .Size(ImVec2(300.0f, 0.0f)) - .Color(THEME_COLOR))) { + UIWidgets::IntSliderOptions() + .Min(2) + .Max(20) + .DefaultValue(4) + .Size(ImVec2(300.0f, 0.0f)) + .Color(THEME_COLOR))) { CVarSetInteger(CVAR_COSMETIC("Trails.Duration.Changed"), 1); } ImGui::SameLine(); ImGui::SetCursorPosY(ImGui::GetCursorPosY() + (ImGui::CalcTextSize("g").y * 2)); - if (UIWidgets::Button("Reset##Trails_Duration", UIWidgets::ButtonOptions() - .Size(ImVec2(80, 36)) - .Padding(ImVec2(5.0f, 0.0f)))) { + if (UIWidgets::Button("Reset##Trails_Duration", + UIWidgets::ButtonOptions().Size(ImVec2(80, 36)).Padding(ImVec2(5.0f, 0.0f)))) { CVarClear(CVAR_COSMETIC("Trails.Duration.Value")); CVarClear(CVAR_COSMETIC("Trails.Duration.Changed")); } @@ -2257,15 +2564,12 @@ void CosmeticsEditorWindow::DrawElement() { } void RegisterOnLoadGameHook() { - GameInteractor::Instance->RegisterGameHook([](int32_t fileNum) { - ApplyOrResetCustomGfxPatches(); - }); + GameInteractor::Instance->RegisterGameHook( + [](int32_t fileNum) { ApplyOrResetCustomGfxPatches(); }); } void RegisterOnGameFrameUpdateHook() { - GameInteractor::Instance->RegisterGameHook([]() { - CosmeticsUpdateTick(); - }); + GameInteractor::Instance->RegisterGameHook([]() { CosmeticsUpdateTick(); }); } void Cosmetics_RegisterOnSceneInitHook() { @@ -2279,7 +2583,8 @@ void Cosmetics_RegisterOnSceneInitHook() { void CosmeticsEditorWindow::InitElement() { // Convert the `current color` into the format that the ImGui color picker expects for (auto& [id, cosmeticOption] : cosmeticOptions) { - Color_RGBA8 defaultColor = {cosmeticOption.defaultColor.r, cosmeticOption.defaultColor.g, cosmeticOption.defaultColor.b, cosmeticOption.defaultColor.a}; + Color_RGBA8 defaultColor = { cosmeticOption.defaultColor.r, cosmeticOption.defaultColor.g, + cosmeticOption.defaultColor.b, cosmeticOption.defaultColor.a }; Color_RGBA8 cvarColor = CVarGetColor(cosmeticOption.valuesCvar, defaultColor); cosmeticOption.currentColor.x = cvarColor.r / 255.0f; diff --git a/soh/soh/Enhancements/cosmetics/CosmeticsEditor.h b/soh/soh/Enhancements/cosmetics/CosmeticsEditor.h index a0a836ce3..6a2b1efd1 100644 --- a/soh/soh/Enhancements/cosmetics/CosmeticsEditor.h +++ b/soh/soh/Enhancements/cosmetics/CosmeticsEditor.h @@ -1,8 +1,9 @@ #pragma once #include -// Not to be confused with tabs, groups are 1:1 with the boxes shown in the UI, grouping them allows us to reset/randomize -// every item in a group at once. If you are looking for tabs they are rendered manually in ImGui in `DrawCosmeticsEditor` +// Not to be confused with tabs, groups are 1:1 with the boxes shown in the UI, grouping them allows us to +// reset/randomize every item in a group at once. If you are looking for tabs they are rendered manually in ImGui in +// `DrawCosmeticsEditor` typedef enum { COSMETICS_GROUP_LINK, COSMETICS_GROUP_MIRRORSHIELD, @@ -32,7 +33,7 @@ typedef enum { extern "C" { #endif //__cplusplus - Color_RGBA8 CosmeticsEditor_GetDefaultValue(const char* id); +Color_RGBA8 CosmeticsEditor_GetDefaultValue(const char* id); #ifdef __cplusplus } @@ -50,7 +51,8 @@ typedef struct { static float TablesCellsWidth = 300.0f; static ImGuiTableColumnFlags FlagsTable = ImGuiTableFlags_BordersH | ImGuiTableFlags_BordersV; -static ImGuiTableColumnFlags FlagsCell = ImGuiTableColumnFlags_WidthStretch | ImGuiTableColumnFlags_IndentEnable | ImGuiTableColumnFlags_NoSort; +static ImGuiTableColumnFlags FlagsCell = + ImGuiTableColumnFlags_WidthStretch | ImGuiTableColumnFlags_IndentEnable | ImGuiTableColumnFlags_NoSort; void CosmeticsEditor_RandomizeAll(); void CosmeticsEditor_RandomizeGroup(CosmeticGroup group); @@ -65,6 +67,6 @@ class CosmeticsEditorWindow : public Ship::GuiWindow { void InitElement() override; void DrawElement() override; void ApplyDungeonKeyColors(); - void UpdateElement() override {}; + void UpdateElement() override{}; }; #endif //__cplusplus \ No newline at end of file diff --git a/soh/soh/Enhancements/cosmetics/CustomLogoTitle.cpp b/soh/soh/Enhancements/cosmetics/CustomLogoTitle.cpp index 7ecdc1f4b..029284fa4 100644 --- a/soh/soh/Enhancements/cosmetics/CustomLogoTitle.cpp +++ b/soh/soh/Enhancements/cosmetics/CustomLogoTitle.cpp @@ -68,9 +68,10 @@ extern "C" void CustomLogoTitle_Draw(TitleContext* titleContext, uint8_t logoToD gDPSetCycleType(POLY_OPA_DISP++, G_CYC_2CYCLE); gDPSetRenderMode(POLY_OPA_DISP++, G_RM_XLU_SURF2, G_RM_OPA_CI | CVG_DST_WRAP); gDPSetCombineLERP(POLY_OPA_DISP++, TEXEL1, PRIMITIVE, ENV_ALPHA, TEXEL0, 0, 0, 0, TEXEL0, PRIMITIVE, ENVIRONMENT, - COMBINED, ENVIRONMENT, COMBINED, 0, PRIMITIVE, 0); + COMBINED, ENVIRONMENT, COMBINED, 0, PRIMITIVE, 0); if (CVarGetInteger(CVAR_COSMETIC("Title.NintendoLogo.Changed"), 0)) { - Color_RGB8 nintendoLogoColor = CVarGetColor24(CVAR_COSMETIC("Title.NintendoLogo.Value"), Color_RGB8{0, 0, 255}); + Color_RGB8 nintendoLogoColor = + CVarGetColor24(CVAR_COSMETIC("Title.NintendoLogo.Value"), Color_RGB8{ 0, 0, 255 }); gDPSetPrimColor(POLY_OPA_DISP++, 0, 0, 255, 255, 255, 255); gDPSetEnvColor(POLY_OPA_DISP++, nintendoLogoColor.r, nintendoLogoColor.g, nintendoLogoColor.b, 128); } else { @@ -79,16 +80,16 @@ extern "C" void CustomLogoTitle_Draw(TitleContext* titleContext, uint8_t logoToD } gDPLoadMultiBlock(POLY_OPA_DISP++, nintendo_rogo_static_Tex_001800, 0x100, 1, G_IM_FMT_I, G_IM_SIZ_8b, 32, 32, 0, - G_TX_NOMIRROR | G_TX_WRAP, G_TX_NOMIRROR | G_TX_WRAP, 5, 5, 2, 11); + G_TX_NOMIRROR | G_TX_WRAP, G_TX_NOMIRROR | G_TX_WRAP, 5, 5, 2, 11); - for (idx = 0, y = 94; idx < 16; idx++, y += 2) - { - gDPLoadMultiTile(POLY_OPA_DISP++, (logoToDraw == LOGO_TO_DRAW_N64) ? nintendo_rogo_static_Tex_000000 : nintendo_rogo_static_Tex_LUS_000000, 0, G_TX_RENDERTILE, G_IM_FMT_I, G_IM_SIZ_8b, 192, 32, - 0, idx * 2, 192 - 1, (idx + 1) * 2 - 1, 0, G_TX_NOMIRROR | G_TX_WRAP, G_TX_NOMIRROR | G_TX_WRAP, G_TX_NOMASK, - G_TX_NOMASK, G_TX_NOLOD, G_TX_NOLOD); - - gDPSetTileSize(POLY_OPA_DISP++, 0, 0, 0, (192 - 1) << G_TEXTURE_IMAGE_FRAC, - (2 - 1) << G_TEXTURE_IMAGE_FRAC); + for (idx = 0, y = 94; idx < 16; idx++, y += 2) { + gDPLoadMultiTile( + POLY_OPA_DISP++, + (logoToDraw == LOGO_TO_DRAW_N64) ? nintendo_rogo_static_Tex_000000 : nintendo_rogo_static_Tex_LUS_000000, 0, + G_TX_RENDERTILE, G_IM_FMT_I, G_IM_SIZ_8b, 192, 32, 0, idx * 2, 192 - 1, (idx + 1) * 2 - 1, 0, + G_TX_NOMIRROR | G_TX_WRAP, G_TX_NOMIRROR | G_TX_WRAP, G_TX_NOMASK, G_TX_NOMASK, G_TX_NOLOD, G_TX_NOLOD); + + gDPSetTileSize(POLY_OPA_DISP++, 0, 0, 0, (192 - 1) << G_TEXTURE_IMAGE_FRAC, (2 - 1) << G_TEXTURE_IMAGE_FRAC); gDPSetTileSize(POLY_OPA_DISP++, 1, titleContext->uls, (titleContext->ult & 0x7F) - idx * 4, 0, 0); gSPTextureRectangle(POLY_OPA_DISP++, 388, y << 2, 1156, (y + 2) << 2, G_TX_RENDERTILE, 0, 0, 1 << 10, 1 << 10); @@ -99,13 +100,13 @@ extern "C" void CustomLogoTitle_Draw(TitleContext* titleContext, uint8_t logoToD f32 scale = 0.4f; gSPSegment(POLY_OPA_DISP++, 0x08, - (uintptr_t)Gfx_TwoTexScroll(titleContext->state.gfxCtx, 0, 0, (0 - 1) % 128, 32, 32, 1, - 0, (1 * -2) % 128, 32, 32)); + (uintptr_t)Gfx_TwoTexScroll(titleContext->state.gfxCtx, 0, 0, (0 - 1) % 128, 32, 32, 1, 0, + (1 * -2) % 128, 32, 32)); Matrix_Translate(0.0f, -10.0f, 0.0f, MTXMODE_APPLY); Matrix_Scale(scale, scale, scale, MTXMODE_APPLY); gSPMatrix(POLY_OPA_DISP++, MATRIX_NEWMTX(titleContext->state.gfxCtx), - G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); gDPSetEnvColor(POLY_OPA_DISP++, 0, 50, 100, 255); gSPDisplayList(POLY_OPA_DISP++, (Gfx*)gEffIceFragment3DL); } @@ -150,7 +151,7 @@ extern "C" void CustomLogoTitle_Main(TitleContext* titleContext) { gSaveContext.natureAmbienceId = 0xFF; gSaveContext.gameMode = GAMEMODE_TITLE_SCREEN; titleContext->state.running = false; - + logosSeen++; if (CVAR_BOOTSEQUENCE_VALUE == BOOTSEQUENCE_DEFAULT && logosSeen == 1) { @@ -171,7 +172,7 @@ extern "C" void CustomLogoTitle_Main(TitleContext* titleContext) { // // // // // Always -// +// void OnZTitleInitReplaceTitleMainWithCustom(void* gameState) { TitleContext* titleContext = (TitleContext*)gameState; @@ -198,7 +199,7 @@ static RegisterShipInitFunc initFuncAlways(RegisterCustomLogoTitle); // // // // // // // Bootsequence -// +// void OnZTitleUpdateSkipToFileSelect(void* gameState) { TitleContext* titleContext = (TitleContext*)gameState; @@ -219,7 +220,7 @@ static RegisterShipInitFunc initFuncBootsequence(RegisterCustomLogoTitleBootsequ // // // // // // // Let it Snow -// +// #define CVAR_LETITSNOW_NAME CVAR_GENERAL("LetItSnow") #define CVAR_LETITSNOW_DEFAULT 0 diff --git a/soh/soh/Enhancements/cosmetics/NoMasterSword.cpp b/soh/soh/Enhancements/cosmetics/NoMasterSword.cpp index 4d4b26715..be011c675 100644 --- a/soh/soh/Enhancements/cosmetics/NoMasterSword.cpp +++ b/soh/soh/Enhancements/cosmetics/NoMasterSword.cpp @@ -19,10 +19,10 @@ void UpdateNoMSPatch() { bool shouldPatch = (gSaveContext.equips.buttonItems[0] != ITEM_SWORD_MASTER && gSaveContext.equips.buttonItems[0] != ITEM_SWORD_BGS && gSaveContext.equips.buttonItems[0] != ITEM_SWORD_KNIFE && - (gSaveContext.equips.buttonItems[0] != ITEM_FISHING_POLE || - (!CHECK_OWNED_EQUIP(EQUIP_TYPE_SWORD, EQUIP_INV_SWORD_MASTER) && - !CHECK_OWNED_EQUIP(EQUIP_TYPE_SWORD, EQUIP_INV_SWORD_BIGGORON) && - !CHECK_OWNED_EQUIP(EQUIP_TYPE_SWORD, EQUIP_INV_SWORD_BROKENGIANTKNIFE)))); + (gSaveContext.equips.buttonItems[0] != ITEM_FISHING_POLE || + (!CHECK_OWNED_EQUIP(EQUIP_TYPE_SWORD, EQUIP_INV_SWORD_MASTER) && + !CHECK_OWNED_EQUIP(EQUIP_TYPE_SWORD, EQUIP_INV_SWORD_BIGGORON) && + !CHECK_OWNED_EQUIP(EQUIP_TYPE_SWORD, EQUIP_INV_SWORD_BROKENGIANTKNIFE)))); if (OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_SHUFFLE_MASTER_SWORD) && shouldPatch) { // Patching if conditions are met @@ -38,9 +38,12 @@ void UpdateNoMSPatch() { std::string patchName = "adultNoMS." + std::to_string(3) + "." + std::to_string(i); ResourceMgr_PatchGfxByName(gLinkAdultMirrorShieldSwordAndSheathFarDL, patchName.c_str(), i, gsDPNoOp()); } - ResourceMgr_PatchGfxByName(gLinkAdultHylianShieldSwordAndSheathNearDL, "adultNoMSHylianShield1", 75, gsSPEndDisplayList()); - ResourceMgr_PatchGfxByName(gLinkAdultHylianShieldSwordAndSheathFarDL, "adultNoMSHylianShield2", 71, gsSPEndDisplayList()); - ResourceMgr_PatchGfxByName(gLinkAdultMasterSwordAndSheathNearDL, "adultNoMasterSword1", 2, gsSPEndDisplayList()); + ResourceMgr_PatchGfxByName(gLinkAdultHylianShieldSwordAndSheathNearDL, "adultNoMSHylianShield1", 75, + gsSPEndDisplayList()); + ResourceMgr_PatchGfxByName(gLinkAdultHylianShieldSwordAndSheathFarDL, "adultNoMSHylianShield2", 71, + gsSPEndDisplayList()); + ResourceMgr_PatchGfxByName(gLinkAdultMasterSwordAndSheathNearDL, "adultNoMasterSword1", 2, + gsSPEndDisplayList()); ResourceMgr_PatchGfxByName(gLinkAdultMasterSwordAndSheathFarDL, "adultNoMasterSword2", 2, gsSPEndDisplayList()); } else { // Unpatching if conditions are not met @@ -80,26 +83,27 @@ void RegisterNoMasterSword() { *should = false; } }); - + // skip post pedestal animation when we don't have a master sword COND_VB_SHOULD(VB_EXECUTE_PLAYER_STARTMODE_FUNC, IS_RANDO && MASTER_SWORD_SHUFFLED, { int32_t startMode = va_arg(args, int32_t); Player* player = GET_PLAYER(gPlayState); - if (startMode == PLAYER_START_MODE_TIME_TRAVEL && !CHECK_OWNED_EQUIP(EQUIP_TYPE_SWORD, EQUIP_INV_SWORD_MASTER)) { + if (startMode == PLAYER_START_MODE_TIME_TRAVEL && + !CHECK_OWNED_EQUIP(EQUIP_TYPE_SWORD, EQUIP_INV_SWORD_MASTER)) { // don't run the vanilla startMode func *should = false; - + // position link correctly Math_Vec3f_Copy(&player->actor.world.pos, &D_808546F4); player->yaw = player->actor.shape.rot.y = -0x8000; - + // execute the idle startMode func Player_StartMode_Idle(gPlayState, player); } }); - COND_HOOK(OnPlayerUpdate, IS_RANDO, []{ + COND_HOOK(OnPlayerUpdate, IS_RANDO, [] { static uint16_t lastItemOnB = gSaveContext.equips.buttonItems[0]; if (lastItemOnB != gSaveContext.equips.buttonItems[0]) { UpdateNoMSPatch(); diff --git a/soh/soh/Enhancements/cosmetics/authenticGfxPatches.cpp b/soh/soh/Enhancements/cosmetics/authenticGfxPatches.cpp index 85e569b33..477fe6f0a 100644 --- a/soh/soh/Enhancements/cosmetics/authenticGfxPatches.cpp +++ b/soh/soh/Enhancements/cosmetics/authenticGfxPatches.cpp @@ -19,10 +19,8 @@ typedef struct { } DListPatchInfo; static DListPatchInfo freezardBodyDListPatchInfos[] = { - { gFreezardIntactDL, 5 }, - { gFreezardTopRightHornChippedDL, 5 }, - { gFreezardHeadChippedDL, 5 }, - { gFreezardIceTriangleDL, 5 }, + { gFreezardIntactDL, 5 }, { gFreezardTopRightHornChippedDL, 5 }, + { gFreezardHeadChippedDL, 5 }, { gFreezardIceTriangleDL, 5 }, { gFreezardIceRockDL, 5 }, }; @@ -339,7 +337,8 @@ void PatchMirroredSoldOutGI() { void PatchMirroredSunSongEtching() { // Only using these strings for graphics patching lookup, we don't need aligned assets here static const char gRoyalGraveBackRoomDL[] = "__OTR__scenes/shared/hakaana_ouke_scene/hakaana_ouke_room_2DL_005040"; - static const char gRoyalGraveBackRoomSongVtx[] = "__OTR__scenes/shared/hakaana_ouke_scene/hakaana_ouke_room_2Vtx_004F80"; + static const char gRoyalGraveBackRoomSongVtx[] = + "__OTR__scenes/shared/hakaana_ouke_scene/hakaana_ouke_room_2Vtx_004F80"; static Vtx* mirroredSunSongVtx; @@ -365,7 +364,8 @@ void PatchMirroredSunSongEtching() { ResourceMgr_PatchGfxByName(gRoyalGraveBackRoomDL, "RoyalGraveSunSongTexture_1", 13, mirroredSunSongTex[1]); ResourceMgr_PatchGfxByName(gRoyalGraveBackRoomDL, "RoyalGraveSunSongTexture_2", 17, mirroredSunSongTex[5]); - ResourceMgr_PatchGfxByName(gRoyalGraveBackRoomDL, "RoyalGraveSunSongTextureCords_1", 24, gsSPVertex(mirroredSunSongVtx, 4, 0)); + ResourceMgr_PatchGfxByName(gRoyalGraveBackRoomDL, "RoyalGraveSunSongTextureCords_1", 24, + gsSPVertex(mirroredSunSongVtx, 4, 0)); // noop as the original vertex command is 128 bit wide ResourceMgr_PatchGfxByName(gRoyalGraveBackRoomDL, "RoyalGraveSunSongTextureCords_2", 25, gsSPNoOp()); } else { diff --git a/soh/soh/Enhancements/cosmetics/cosmeticsTypes.h b/soh/soh/Enhancements/cosmetics/cosmeticsTypes.h index 0b7eed3e8..fec112c42 100644 --- a/soh/soh/Enhancements/cosmetics/cosmeticsTypes.h +++ b/soh/soh/Enhancements/cosmetics/cosmeticsTypes.h @@ -9,11 +9,11 @@ typedef enum { ENEMYHEALTH_ANCHOR_BOTTOM, } EnemyHealthBarAnchorType; -typedef enum { - ORIGINAL_LOCATION, - ANCHOR_LEFT, - ANCHOR_RIGHT, - ANCHOR_NONE, - HIDDEN, +typedef enum { + ORIGINAL_LOCATION, + ANCHOR_LEFT, + ANCHOR_RIGHT, + ANCHOR_NONE, + HIDDEN, ANCHOR_TO_LIFE_METER, } PosType; diff --git a/soh/soh/Enhancements/custom-message/CustomMessageManager.cpp b/soh/soh/Enhancements/custom-message/CustomMessageManager.cpp index 9d4aec45b..d4c478657 100644 --- a/soh/soh/Enhancements/custom-message/CustomMessageManager.cpp +++ b/soh/soh/Enhancements/custom-message/CustomMessageManager.cpp @@ -16,35 +16,24 @@ static const std::unordered_map textBoxSpecialCharacters = { { "è", 0x95 }, { "é", 0x96 }, { "ê", 0x97 }, { "ë", 0x98 }, { "ï", 0x99 }, { "ô", 0x9A }, { "ö", 0x9B }, { "ù", 0x9C }, { "û", 0x9D }, { "ü", 0x9E } }; -static const std::unordered_map percentColors = { { "w", QM_WHITE }, { "r", QM_RED }, { "g", QM_GREEN }, - { "b", QM_BLUE }, { "c", QM_LBLUE }, { "p", QM_PINK }, - { "y", QM_YELLOW }, { "B", QM_BLACK }, }; +static const std::unordered_map percentColors = { + { "w", QM_WHITE }, { "r", QM_RED }, { "g", QM_GREEN }, { "b", QM_BLUE }, + { "c", QM_LBLUE }, { "p", QM_PINK }, { "y", QM_YELLOW }, { "B", QM_BLACK }, +}; -static const std::unordered_map colorToPercent = { { QM_WHITE, "%w" }, { QM_RED, "%r"}, { QM_GREEN, "%g" }, - { QM_BLUE, "%b" }, { QM_LBLUE, "%c"}, { QM_PINK, "%p" }, - { QM_YELLOW, "%y" }, { QM_BLACK, "%B" }, }; +static const std::unordered_map colorToPercent = { + { QM_WHITE, "%w" }, { QM_RED, "%r" }, { QM_GREEN, "%g" }, { QM_BLUE, "%b" }, + { QM_LBLUE, "%c" }, { QM_PINK, "%p" }, { QM_YELLOW, "%y" }, { QM_BLACK, "%B" }, +}; static const std::unordered_map altarIcons = { - { "0", ITEM_KOKIRI_EMERALD }, - { "1", ITEM_GORON_RUBY }, - { "2", ITEM_ZORA_SAPPHIRE }, - { "8", ITEM_MEDALLION_LIGHT }, - { "3", ITEM_MEDALLION_FOREST }, - { "4", ITEM_MEDALLION_FIRE }, - { "5", ITEM_MEDALLION_WATER }, - { "6", ITEM_MEDALLION_SPIRIT }, - { "7", ITEM_MEDALLION_SHADOW }, - { "l", ITEM_ARROW_LIGHT }, - { "b", ITEM_KEY_BOSS }, - { "o", ITEM_SWORD_MASTER }, - { "c", ITEM_OCARINA_FAIRY }, - { "i", ITEM_OCARINA_TIME }, - { "L", ITEM_BOW_ARROW_LIGHT }, - { "k", ITEM_TUNIC_KOKIRI }, - { "m", ITEM_DUNGEON_MAP }, - { "C", ITEM_COMPASS }, - { "s", ITEM_SKULL_TOKEN }, - { "g", ITEM_MASK_GORON }, + { "0", ITEM_KOKIRI_EMERALD }, { "1", ITEM_GORON_RUBY }, { "2", ITEM_ZORA_SAPPHIRE }, + { "8", ITEM_MEDALLION_LIGHT }, { "3", ITEM_MEDALLION_FOREST }, { "4", ITEM_MEDALLION_FIRE }, + { "5", ITEM_MEDALLION_WATER }, { "6", ITEM_MEDALLION_SPIRIT }, { "7", ITEM_MEDALLION_SHADOW }, + { "l", ITEM_ARROW_LIGHT }, { "b", ITEM_KEY_BOSS }, { "o", ITEM_SWORD_MASTER }, + { "c", ITEM_OCARINA_FAIRY }, { "i", ITEM_OCARINA_TIME }, { "L", ITEM_BOW_ARROW_LIGHT }, + { "k", ITEM_TUNIC_KOKIRI }, { "m", ITEM_DUNGEON_MAP }, { "C", ITEM_COMPASS }, + { "s", ITEM_SKULL_TOKEN }, { "g", ITEM_MASK_GORON }, }; static std::map pixelWidthTable = { @@ -77,14 +66,15 @@ static std::map pixelWidthTable = { CustomMessage::CustomMessage(std::string english_, std::string german_, std::string french_, TextBoxType type_, TextBoxPosition position_) - : type(type_), position(position_){ + : type(type_), position(position_) { messages[LANGUAGE_ENG] = std::move(english_); messages[LANGUAGE_GER] = std::move(german_); messages[LANGUAGE_FRA] = std::move(french_); } -CustomMessage::CustomMessage(std::string english_, std::string german_, std::string french_, std::vector colors_, - std::vector capital_, TextBoxType type_, TextBoxPosition position_) { +CustomMessage::CustomMessage(std::string english_, std::string german_, std::string french_, + std::vector colors_, std::vector capital_, TextBoxType type_, + TextBoxPosition position_) { messages[LANGUAGE_ENG] = std::move(english_); messages[LANGUAGE_GER] = std::move(german_); messages[LANGUAGE_FRA] = std::move(french_); @@ -99,7 +89,8 @@ CustomMessage::CustomMessage(std::string english_, TextBoxType type_, TextBoxPos messages[LANGUAGE_ENG] = std::move(english_); } -CustomMessage::CustomMessage(std::string english_, std::vector colors_, std::vector capital_, TextBoxType type_, TextBoxPosition position_){ +CustomMessage::CustomMessage(std::string english_, std::vector colors_, std::vector capital_, + TextBoxType type_, TextBoxPosition position_) { messages[LANGUAGE_ENG] = std::move(english_); colors = colors_; capital = capital_; @@ -107,7 +98,7 @@ CustomMessage::CustomMessage(std::string english_, std::vector colo position = position_; } -CustomMessage::CustomMessage(Text text, TextBoxType type_,TextBoxPosition position_) +CustomMessage::CustomMessage(Text text, TextBoxType type_, TextBoxPosition position_) : type(type_), position(position_) { messages[LANGUAGE_ENG] = text.GetEnglish(); messages[LANGUAGE_GER] = text.GetGerman(); @@ -141,7 +132,7 @@ CustomMessage CustomMessage::LoadVanillaMessageTableEntry(uint16_t textId) { TextBoxPosition position = static_cast(msgEntry->typePos & 0xF); TextBoxType type = static_cast(msgEntry->typePos >> 4); // uint8_t icon = msgEntry->segment[1]; - std::string message = std::string(msgEntry->segment , msgEntry->msgSize); + std::string message = std::string(msgEntry->segment, msgEntry->msgSize); msg = CustomMessage(message, type, position); // msg.Format(static_cast(icon)); return msg; @@ -151,7 +142,6 @@ CustomMessage CustomMessage::LoadVanillaMessageTableEntry(uint16_t textId) { return CustomMessage(); } - const std::string CustomMessage::GetEnglish(MessageFormat format) const { return GetForLanguage(LANGUAGE_ENG, format); } @@ -174,22 +164,22 @@ const std::string CustomMessage::GetForLanguage(uint8_t language, MessageFormat return output; } -const std::vector CustomMessage::GetAllMessages(MessageFormat format) const{ +const std::vector CustomMessage::GetAllMessages(MessageFormat format) const { std::vector output = messages; - for (auto str : output){ + for (auto str : output) { ProcessMessageFormat(str, format); } return output; } void CustomMessage::ProcessMessageFormat(std::string& str, MessageFormat format) const { - if (format == MF_FORMATTED){ + if (format == MF_FORMATTED) { FormatString(str); - } else if (format == MF_CLEAN){ + } else if (format == MF_CLEAN) { CleanString(str); - } else if (format == MF_AUTO_FORMAT){ + } else if (format == MF_AUTO_FORMAT) { AutoFormatString(str); - }else if (format == MF_ENCODE){ + } else if (format == MF_ENCODE) { EncodeColors(str); } } @@ -198,14 +188,14 @@ const std::vector& CustomMessage::GetCapital() const { return capital; } -void CustomMessage::SetCapital(std::vector capital_){ +void CustomMessage::SetCapital(std::vector capital_) { capital = capital_; } const std::vector& CustomMessage::GetColors() const { return colors; } -void CustomMessage::SetColors(std::vector colors_){ +void CustomMessage::SetColors(std::vector colors_) { colors = colors_; } @@ -213,7 +203,7 @@ const TextBoxType& CustomMessage::GetTextBoxType() const { return type; } -void CustomMessage::SetTextBoxType(TextBoxType boxType){ +void CustomMessage::SetTextBoxType(TextBoxType boxType) { type = boxType; } @@ -224,19 +214,19 @@ const TextBoxPosition& CustomMessage::GetTextBoxPosition() const { CustomMessage CustomMessage::operator+(const CustomMessage& right) const { std::vector newColors = colors; std::vector rColors = right.GetColors(); - for (auto color: rColors){ + for (auto color : rColors) { newColors.push_back(color); } std::vector newCapital = capital; newCapital.insert(newCapital.end(), right.GetCapital().begin(), right.GetCapital().end()); return CustomMessage(messages[LANGUAGE_ENG] + right.GetEnglish(MF_RAW), messages[LANGUAGE_GER] + right.GetGerman(MF_RAW), - messages[LANGUAGE_FRA] + right.GetFrench(MF_RAW), - newColors, newCapital, type, position); + messages[LANGUAGE_FRA] + right.GetFrench(MF_RAW), newColors, newCapital, type, position); } CustomMessage CustomMessage::operator+(const std::string& right) const { - return CustomMessage(messages[LANGUAGE_ENG] + right, messages[LANGUAGE_GER] + right, messages[LANGUAGE_FRA] + right); + return CustomMessage(messages[LANGUAGE_ENG] + right, messages[LANGUAGE_GER] + right, + messages[LANGUAGE_FRA] + right); } void CustomMessage::operator+=(const CustomMessage& right) { @@ -258,8 +248,8 @@ bool CustomMessage::operator==(const CustomMessage& operand) const { } bool CustomMessage::operator==(const std::string& operand) const { - for (auto str: messages){ - if (str == operand){ + for (auto str : messages) { + if (str == operand) { return true; } } @@ -291,7 +281,7 @@ void CustomMessage::Replace(std::string&& oldStr, CustomMessage newMessage) { } void CustomMessage::Format(ItemID iid) { - for (std::string &str : messages) { + for (std::string& str : messages) { str.insert(0, ITEM_OBTAINED(iid)); size_t start_pos = 0; std::replace(str.begin(), str.end(), '&', NEWLINE()[0]); @@ -341,7 +331,7 @@ void CustomMessage::FormatString(std::string& str) const { str += MESSAGE_END(); } -void DeleteControlCode(std::string& str, std::string code){ +void DeleteControlCode(std::string& str, std::string code) { size_t start_pos = 0; while ((start_pos = str.find(code, start_pos)) != std::string::npos) { str.replace(start_pos, code.length(), ""); @@ -362,56 +352,57 @@ void CustomMessage::CleanString(std::string& str) const { } static size_t NextLineLength(const std::string* textStr, const size_t lastNewline, bool hasIcon = false) { - const size_t maxLinePixelWidth = hasIcon ? 200 : 216; + const size_t maxLinePixelWidth = hasIcon ? 200 : 216; - size_t totalPixelWidth = 0; - size_t currentPos = lastNewline; + size_t totalPixelWidth = 0; + size_t currentPos = lastNewline; - // Looping through the string from the lastNewline until the total - // width of counted characters exceeds the maximum pixels in a line. - size_t nextPosJump = 0; - while (totalPixelWidth < maxLinePixelWidth && currentPos < textStr->length()) { - // Skip over control codes - if (textStr->at(currentPos) == '%') { - nextPosJump = 2; - } else if (textStr->at(currentPos) == '$') { - nextPosJump = 2; - } else if (textStr->at(currentPos) == '@') { - nextPosJump = 1; - // Assume worst case for player name 12 * 8 (widest character * longest name length) - totalPixelWidth += 96; - } else if (textStr->at(currentPos) == '\x05') { - // Skip colour control characters. - nextPosJump = 2; - } else if (textStr->at(currentPos) == '\x1E') { - //For the high score char, we have to take the next Char, then use that to get a worst case scenario. - if (textStr->at(currentPos+1) == '\x01'){ - totalPixelWidth += 28; - } - nextPosJump = 2; - } else { - // Some characters only one byte while others are two bytes - // So check both possibilities when checking for a character - if (pixelWidthTable.count(textStr->substr(currentPos, 1))) { - totalPixelWidth += pixelWidthTable[textStr->substr(currentPos, 1)]; - nextPosJump = 1; - } else if (pixelWidthTable.count(textStr->substr(currentPos, 2))) { - totalPixelWidth += pixelWidthTable[textStr->substr(currentPos, 2)]; - nextPosJump = 2; - } else { - SPDLOG_DEBUG("Table does not contain " + textStr->substr(currentPos, 1) + "/" + textStr->substr(currentPos, 2)); - SPDLOG_DEBUG("Full string: " + *textStr); - nextPosJump = 1; - } + // Looping through the string from the lastNewline until the total + // width of counted characters exceeds the maximum pixels in a line. + size_t nextPosJump = 0; + while (totalPixelWidth < maxLinePixelWidth && currentPos < textStr->length()) { + // Skip over control codes + if (textStr->at(currentPos) == '%') { + nextPosJump = 2; + } else if (textStr->at(currentPos) == '$') { + nextPosJump = 2; + } else if (textStr->at(currentPos) == '@') { + nextPosJump = 1; + // Assume worst case for player name 12 * 8 (widest character * longest name length) + totalPixelWidth += 96; + } else if (textStr->at(currentPos) == '\x05') { + // Skip colour control characters. + nextPosJump = 2; + } else if (textStr->at(currentPos) == '\x1E') { + // For the high score char, we have to take the next Char, then use that to get a worst case scenario. + if (textStr->at(currentPos + 1) == '\x01') { + totalPixelWidth += 28; + } + nextPosJump = 2; + } else { + // Some characters only one byte while others are two bytes + // So check both possibilities when checking for a character + if (pixelWidthTable.count(textStr->substr(currentPos, 1))) { + totalPixelWidth += pixelWidthTable[textStr->substr(currentPos, 1)]; + nextPosJump = 1; + } else if (pixelWidthTable.count(textStr->substr(currentPos, 2))) { + totalPixelWidth += pixelWidthTable[textStr->substr(currentPos, 2)]; + nextPosJump = 2; + } else { + SPDLOG_DEBUG("Table does not contain " + textStr->substr(currentPos, 1) + "/" + + textStr->substr(currentPos, 2)); + SPDLOG_DEBUG("Full string: " + *textStr); + nextPosJump = 1; + } + } + currentPos += nextPosJump; + } + // return the total number of characters we looped through + if (totalPixelWidth > maxLinePixelWidth && textStr->at(currentPos - nextPosJump) != ' ') { + return currentPos - lastNewline - nextPosJump; + } else { + return currentPos - lastNewline; } - currentPos += nextPosJump; - } - // return the total number of characters we looped through - if (totalPixelWidth > maxLinePixelWidth && textStr->at(currentPos - nextPosJump) != ' ') { - return currentPos - lastNewline - nextPosJump; - } else { - return currentPos - lastNewline; - } } size_t CustomMessage::FindNEWLINE(std::string& str, size_t lastNewline) const { @@ -488,19 +479,19 @@ void CustomMessage::AutoFormatString(std::string& str) const { const size_t lastSpace = str.rfind(' ', lastNewline + lineLength); size_t waitForInput = str.find(WAIT_FOR_INPUT()[0], lastNewline); size_t newLine = FindNEWLINE(str, lastNewline); - if (carrot < waitForInput){ + if (carrot < waitForInput) { waitForInput = carrot; } - if (ampersand < newLine){ + if (ampersand < newLine) { newLine = ampersand; } - if (lineCount != 3 && yesNo < lastNewline + lineLength && yesNo < waitForInput && yesNo < newLine){ - if (lineCount >= 4){ + if (lineCount != 3 && yesNo < lastNewline + lineLength && yesNo < waitForInput && yesNo < newLine) { + if (lineCount >= 4) { str.replace(yesNo, 1, "^&&\x1B"); lineCount = 3; lastNewline = yesNo + 3; } else { - while(lineCount < 3){ + while (lineCount < 3) { str.replace(yesNo, 1, "&\x1B"); yesNo++; lineCount++; @@ -508,7 +499,7 @@ void CustomMessage::AutoFormatString(std::string& str) const { lastNewline = yesNo; } } else { - if (lineCount < 4){ + if (lineCount < 4) { // replace '&' first if it's within the newline range if (newLine < lastNewline + lineLength) { lastNewline = newLine + 1; @@ -526,12 +517,12 @@ void CustomMessage::AutoFormatString(std::string& str) const { lastNewline = lastSpace + 1; } lineCount += 1; - } else { + } else { const size_t lastColor = str.rfind("\x05"s, lastNewline + lineLength); std::string colorText = ""; - //check if we are on a non default colour, as ^ resets it, and readd if needed - if (lastColor != std::string::npos && str[lastColor+1] != 0){ - colorText = "\x05"s + str[lastColor+1]; + // check if we are on a non default colour, as ^ resets it, and readd if needed + if (lastColor != std::string::npos && str[lastColor + 1] != 0) { + colorText = "\x05"s + str[lastColor + 1]; } // replace '&' first if it's within the newline range if (ampersand < lastNewline + lineLength) { @@ -564,7 +555,7 @@ void CustomMessage::AutoFormatString(std::string& str) const { str += MESSAGE_END(); } -void CustomMessage::InsertNumber(uint8_t num){ +void CustomMessage::InsertNumber(uint8_t num) { for (std::string& str : messages) { size_t firstBar = str.find('|'); if (firstBar != std::string::npos) { @@ -581,12 +572,11 @@ void CustomMessage::InsertNumber(uint8_t num){ } } } - //remove the remaining bar + // remove the remaining bar this->Replace("|", ""); Replace("[[d]]", std::to_string(num)); } - void CustomMessage::Capitalize() { for (std::string str : messages) { (str)[0] = std::toupper((str)[0]); @@ -625,7 +615,7 @@ const char* Interface_ReplaceSpecialCharacters(char text[]) { } void CustomMessage::EncodeColors(std::string& str) const { - for (std::string color: colors) { + for (std::string color : colors) { if (const size_t firstHashtag = str.find('#'); firstHashtag != std::string::npos) { str.replace(firstHashtag, 1, colorToPercent.at(color)); if (const size_t secondHashtag = str.find('#', firstHashtag + 1); secondHashtag != std::string::npos) { @@ -664,13 +654,13 @@ void CustomMessage::ReplaceAltarIcons(std::string& str) const { } } -void CustomMessage::InsertNames(std::vector toInsert){ - for(uint8_t a = 0; a < toInsert.size(); a++){ +void CustomMessage::InsertNames(std::vector toInsert) { + for (uint8_t a = 0; a < toInsert.size(); a++) { CustomMessage temp = toInsert[a]; - if ((capital.size() > a) && (capital[a] = true)){ + if ((capital.size() > a) && (capital[a] = true)) { temp.Capitalize(); - } - Replace("[[" + std::to_string(a+1) + "]]", temp); + } + Replace("[[" + std::to_string(a + 1) + "]]", temp); } } @@ -735,16 +725,16 @@ CustomMessage CustomMessageManager::RetrieveMessage(std::string tableID, uint16_ } CustomMessage message = foundMessage->second; - if (format == MF_FORMATTED){ + if (format == MF_FORMATTED) { message.Format(); - } else if (format == MF_AUTO_FORMAT){ + } else if (format == MF_AUTO_FORMAT) { message.AutoFormat(); - } else if (format == MF_CLEAN){ + } else if (format == MF_CLEAN) { message.Clean(); - } else if (format == MF_ENCODE){ + } else if (format == MF_ENCODE) { message.Encode(); } - + return message; } @@ -758,7 +748,7 @@ bool CustomMessageManager::ClearMessageTable(std::string tableID) { return true; } -bool CustomMessageManager::AddCustomMessageTable(std::string tableID) { +bool CustomMessageManager::AddCustomMessageTable(std::string tableID) { CustomMessageTable newMessageTable; return messageTables.emplace(tableID, newMessageTable).second; } diff --git a/soh/soh/Enhancements/custom-message/CustomMessageManager.h b/soh/soh/Enhancements/custom-message/CustomMessageManager.h index 0720d8ac4..71ae423b5 100644 --- a/soh/soh/Enhancements/custom-message/CustomMessageManager.h +++ b/soh/soh/Enhancements/custom-message/CustomMessageManager.h @@ -20,7 +20,7 @@ #define QM_YELLOW "\x46" #define QM_BLACK "\x47" -#define HS_HORSE_ARCHERY "\x00"s //HS_HBA is an enum already +#define HS_HORSE_ARCHERY "\x00"s // HS_HBA is an enum already typedef enum { MF_FORMATTED, @@ -41,21 +41,24 @@ class CustomMessage { CustomMessage() = default; CustomMessage(std::string english_, std::string german_, std::string french_, TextBoxType type_ = TEXTBOX_TYPE_BLACK, TextBoxPosition position_ = TEXTBOX_POS_BOTTOM); - CustomMessage(std::string english_, std::string german_, std::string french_, std::vector colors_, std::vector capital_ = {}, - TextBoxType type_ = TEXTBOX_TYPE_BLACK, TextBoxPosition position_ = TEXTBOX_POS_BOTTOM); - CustomMessage(std::string english_, TextBoxType type_ = TEXTBOX_TYPE_BLACK, TextBoxPosition position_ = TEXTBOX_POS_BOTTOM); - CustomMessage(std::string english_, std::vector colors_, std::vector capital_ = {}, TextBoxType type_ = TEXTBOX_TYPE_BLACK, TextBoxPosition position_ = TEXTBOX_POS_BOTTOM); + CustomMessage(std::string english_, std::string german_, std::string french_, std::vector colors_, + std::vector capital_ = {}, TextBoxType type_ = TEXTBOX_TYPE_BLACK, + TextBoxPosition position_ = TEXTBOX_POS_BOTTOM); + CustomMessage(std::string english_, TextBoxType type_ = TEXTBOX_TYPE_BLACK, + TextBoxPosition position_ = TEXTBOX_POS_BOTTOM); + CustomMessage(std::string english_, std::vector colors_, std::vector capital_ = {}, + TextBoxType type_ = TEXTBOX_TYPE_BLACK, TextBoxPosition position_ = TEXTBOX_POS_BOTTOM); CustomMessage(Text text, TextBoxType type_ = TEXTBOX_TYPE_BLACK, TextBoxPosition position_ = TEXTBOX_POS_BOTTOM); static CustomMessage LoadVanillaMessageTableEntry(uint16_t textId); - static std::string MESSAGE_END() ; - static std::string ITEM_OBTAINED(uint8_t x) ; - static std::string NEWLINE() ; - static std::string COLOR(std::string x) ; - static std::string POINTS(std::string x) ;//HIGH_SCORE is also a macro - static std::string WAIT_FOR_INPUT() ; - static std::string PLAYER_NAME() ; + static std::string MESSAGE_END(); + static std::string ITEM_OBTAINED(uint8_t x); + static std::string NEWLINE(); + static std::string COLOR(std::string x); + static std::string POINTS(std::string x); // HIGH_SCORE is also a macro + static std::string WAIT_FOR_INPUT(); + static std::string PLAYER_NAME(); const std::string GetEnglish(MessageFormat format = MF_FORMATTED) const; const std::string GetFrench(MessageFormat format = MF_FORMATTED) const; @@ -157,13 +160,13 @@ class CustomMessage { void Format(); /** - * @brief formats the message specifically to fit in OoT's + * @brief formats the message specifically to fit in OoT's * textboxes, and use it's formatting. */ void AutoFormat(); /** - * @brief Removes all OoT formatting from the message, + * @brief Removes all OoT formatting from the message, * making it a good form for writing into spoiler logs. */ void Clean(); @@ -179,15 +182,15 @@ class CustomMessage { * . i.e. special characters, colors, newlines, wait for input, etc. */ void FormatString(std::string& str) const; - + /** * @brief finds NEWLINEs in a string, while filtering * /x01's that are used as opperands */ size_t FindNEWLINE(std::string& str, size_t lastNewline) const; - + /** - * @brief formats the string specifically to fit in OoT's + * @brief formats the string specifically to fit in OoT's * textboxes, and use it's formatting. * RANDOTODO whoever knows exactly what this does check my adaption */ @@ -200,7 +203,7 @@ class CustomMessage { void CleanString(std::string& str) const; private: - std::vector messages = {"","",""}; + std::vector messages = { "", "", "" }; TextBoxType type = TEXTBOX_TYPE_BLACK; TextBoxPosition position = TEXTBOX_POS_BOTTOM; std::vector colors = {}; diff --git a/soh/soh/Enhancements/custom-message/CustomMessageTypes.h b/soh/soh/Enhancements/custom-message/CustomMessageTypes.h index 4a039987e..e7c559857 100644 --- a/soh/soh/Enhancements/custom-message/CustomMessageTypes.h +++ b/soh/soh/Enhancements/custom-message/CustomMessageTypes.h @@ -11,7 +11,7 @@ typedef enum { TEXT_SKULLTULA_PEOPLE_STARTING_TO_WEAKEN = 0x0024, TEXT_SKULLTULA_PEOPLE_WE_LOOK_LIKE_THIS = 0x0025, TEXT_SKULLTULA_PEOPLE_GS_TUTORIAL = 0x0026, - TEXT_SKULLTULA_PEOPLE_MAKE_YOU_VERY_RICH = 0x0027, + TEXT_SKULLTULA_PEOPLE_MAKE_YOU_VERY_RICH = 0x0027, TEXT_SKULLTULA_PEOPLE_CURSE_HAS_BEEN_BROKEN = 0x0028, TEXT_SKULLTULA_PEOPLE_SAVING_MY_KIDS = 0x0029, TEXT_ITEM_KEY_SMALL = 0x0060, @@ -96,7 +96,7 @@ typedef enum { TEXT_MALON_HOW_IS_EPONA_DOING = 0x2001, TEXT_MALON_EPONA_LOOKS_GREAT = 0x2002, TEXT_MALON_OBSTICLE_COURSE = 0x2003, - TEXT_MALON_EVERYONE_TURNING_EVIL = 0x204C, + TEXT_MALON_EVERYONE_TURNING_EVIL = 0x204C, TEXT_MALON_I_SING_THIS_SONG = 0x2050, TEXT_MALON_EVERYONE_LIKED_SONG = 0x2051, TEXT_MALON_EPONA_LIKED_SONG = 0x2052, @@ -211,6 +211,6 @@ typedef struct { { giid, iid, message, message, message } #define GIMESSAGE_NO_GERMAN(giid, iid, english, french) \ - { giid, iid, english, english, french } + { giid, iid, english, english, french } #endif diff --git a/soh/soh/Enhancements/debugconsole.cpp b/soh/soh/Enhancements/debugconsole.cpp index 1420ad287..db5cc824f 100644 --- a/soh/soh/Enhancements/debugconsole.cpp +++ b/soh/soh/Enhancements/debugconsole.cpp @@ -36,10 +36,17 @@ extern PlayState* gPlayState; #define CMD_REGISTER Ship::Context::GetInstance()->GetConsole()->AddCommand // TODO: Commands should be using the output passed in. -#define ERROR_MESSAGE std::reinterpret_pointer_cast(Ship::Context::GetInstance()->GetWindow()->GetGui()->GetGuiWindow("Console"))->SendErrorMessage -#define INFO_MESSAGE std::reinterpret_pointer_cast(Ship::Context::GetInstance()->GetWindow()->GetGui()->GetGuiWindow("Console"))->SendInfoMessage +#define ERROR_MESSAGE \ + std::reinterpret_pointer_cast( \ + Ship::Context::GetInstance()->GetWindow()->GetGui()->GetGuiWindow("Console")) \ + ->SendErrorMessage +#define INFO_MESSAGE \ + std::reinterpret_pointer_cast( \ + Ship::Context::GetInstance()->GetWindow()->GetGui()->GetGuiWindow("Console")) \ + ->SendInfoMessage -static bool ActorSpawnHandler(std::shared_ptr Console, const std::vector& args, std::string* output) { +static bool ActorSpawnHandler(std::shared_ptr Console, const std::vector& args, + std::string* output) { if ((args.size() != 9) && (args.size() != 3) && (args.size() != 6)) { ERROR_MESSAGE("Not enough arguments passed to actorspawn"); return 1; @@ -100,7 +107,8 @@ static bool ActorSpawnHandler(std::shared_ptr Console, const std: return 0; } -static bool KillPlayerHandler(std::shared_ptr Console, const std::vector&, std::string* output) { +static bool KillPlayerHandler(std::shared_ptr Console, const std::vector&, + std::string* output) { GameInteractionEffectBase* effect = new GameInteractionEffect::SetPlayerHealth(); dynamic_cast(effect)->parameters[0] = 0; GameInteractionEffectQueryResult result = GameInteractor::ApplyEffect(effect); @@ -113,7 +121,8 @@ static bool KillPlayerHandler(std::shared_ptr Console, const std: } } -static bool SetPlayerHealthHandler(std::shared_ptr Console, const std::vector& args, std::string* output) { +static bool SetPlayerHealthHandler(std::shared_ptr Console, const std::vector& args, + std::string* output) { if (args.size() < 2) { ERROR_MESSAGE("[SOH] Unexpected arguments passed"); return 1; @@ -144,7 +153,8 @@ static bool SetPlayerHealthHandler(std::shared_ptr Console, const } } -static bool LoadSceneHandler(std::shared_ptr Console, const std::vector&, std::string* output) { +static bool LoadSceneHandler(std::shared_ptr Console, const std::vector&, + std::string* output) { gSaveContext.respawnFlag = 0; gSaveContext.seqId = 0xFF; gSaveContext.gameMode = GAMEMODE_NORMAL; @@ -152,7 +162,8 @@ static bool LoadSceneHandler(std::shared_ptr Console, const std:: return 0; } -static bool RupeeHandler(std::shared_ptr Console, const std::vector& args, std::string* output) { +static bool RupeeHandler(std::shared_ptr Console, const std::vector& args, + std::string* output) { if (args.size() < 2) { return 1; } @@ -160,8 +171,7 @@ static bool RupeeHandler(std::shared_ptr Console, const std::vect int rupeeAmount; try { rupeeAmount = std::stoi(args[1]); - } - catch (std::invalid_argument const& ex) { + } catch (std::invalid_argument const& ex) { ERROR_MESSAGE("[SOH] Rupee count must be an integer."); return 1; } @@ -171,13 +181,14 @@ static bool RupeeHandler(std::shared_ptr Console, const std::vect return 1; } - gSaveContext.rupees = rupeeAmount; + gSaveContext.rupees = rupeeAmount; INFO_MESSAGE("Set rupee count to %u", rupeeAmount); return 0; } -static bool SetPosHandler(std::shared_ptr Console, const std::vector args, std::string* output) { +static bool SetPosHandler(std::shared_ptr Console, const std::vector args, + std::string* output) { if (gPlayState == nullptr) { ERROR_MESSAGE("PlayState == nullptr"); return 1; @@ -186,9 +197,8 @@ static bool SetPosHandler(std::shared_ptr Console, const std::vec Player* player = GET_PLAYER(gPlayState); if (args.size() == 1) { - INFO_MESSAGE("Player position is [ %.2f, %.2f, %.2f ]", player->actor.world.pos.x, - player->actor.world.pos.y, - player->actor.world.pos.z); + INFO_MESSAGE("Player position is [ %.2f, %.2f, %.2f ]", player->actor.world.pos.x, player->actor.world.pos.y, + player->actor.world.pos.z); return 0; } if (args.size() < 4) @@ -198,9 +208,8 @@ static bool SetPosHandler(std::shared_ptr Console, const std::vec player->actor.world.pos.y = std::stof(args[2]); player->actor.world.pos.z = std::stof(args[3]); - INFO_MESSAGE("Set player position to [ %.2f, %.2f, %.2f ]", player->actor.world.pos.x, - player->actor.world.pos.y, - player->actor.world.pos.z); + INFO_MESSAGE("Set player position to [ %.2f, %.2f, %.2f ]", player->actor.world.pos.x, player->actor.world.pos.y, + player->actor.world.pos.z); return 0; } @@ -215,14 +224,13 @@ static bool ResetHandler(std::shared_ptr Console, std::vector ammoItems{ - { "sticks", ITEM_STICK }, { "nuts", ITEM_NUT }, - { "bombs", ITEM_BOMB }, { "seeds", ITEM_SLINGSHOT }, - { "arrows", ITEM_BOW }, { "bombchus", ITEM_BOMBCHU }, - { "beans", ITEM_BEAN }, +const static std::map ammoItems{ + { "sticks", ITEM_STICK }, { "nuts", ITEM_NUT }, { "bombs", ITEM_BOMB }, { "seeds", ITEM_SLINGSHOT }, + { "arrows", ITEM_BOW }, { "bombchus", ITEM_BOMBCHU }, { "beans", ITEM_BEAN }, }; -static bool AddAmmoHandler(std::shared_ptr Console, const std::vector& args, std::string* output) { +static bool AddAmmoHandler(std::shared_ptr Console, const std::vector& args, + std::string* output) { if (args.size() < 3) { ERROR_MESSAGE("[SOH] Unexpected arguments passed"); return 1; @@ -243,7 +251,8 @@ static bool AddAmmoHandler(std::shared_ptr Console, const std::ve const auto& it = ammoItems.find(args[1]); if (it == ammoItems.end()) { - ERROR_MESSAGE("Invalid ammo type. Options are 'sticks', 'nuts', 'bombs', 'seeds', 'arrows', 'bombchus' and 'beans'"); + ERROR_MESSAGE( + "Invalid ammo type. Options are 'sticks', 'nuts', 'bombs', 'seeds', 'arrows', 'bombchus' and 'beans'"); return 1; } @@ -261,7 +270,8 @@ static bool AddAmmoHandler(std::shared_ptr Console, const std::ve } } -static bool TakeAmmoHandler(std::shared_ptr Console, const std::vector& args, std::string* output) { +static bool TakeAmmoHandler(std::shared_ptr Console, const std::vector& args, + std::string* output) { if (args.size() < 3) { ERROR_MESSAGE("[SOH] Unexpected arguments passed"); return 1; @@ -302,13 +312,22 @@ static bool TakeAmmoHandler(std::shared_ptr Console, const std::v } const static std::map bottleItems{ - { "green_potion", ITEM_POTION_GREEN }, { "red_potion", ITEM_POTION_RED }, { "blue_potion", ITEM_POTION_BLUE }, - { "milk", ITEM_MILK }, { "half_milk", ITEM_MILK_HALF }, { "fairy", ITEM_FAIRY }, - { "bugs", ITEM_BUG }, { "fish", ITEM_FISH }, { "poe", ITEM_POE }, - { "big_poe", ITEM_BIG_POE }, { "blue_fire", ITEM_BLUE_FIRE }, { "rutos_letter", ITEM_LETTER_RUTO }, + { "green_potion", ITEM_POTION_GREEN }, + { "red_potion", ITEM_POTION_RED }, + { "blue_potion", ITEM_POTION_BLUE }, + { "milk", ITEM_MILK }, + { "half_milk", ITEM_MILK_HALF }, + { "fairy", ITEM_FAIRY }, + { "bugs", ITEM_BUG }, + { "fish", ITEM_FISH }, + { "poe", ITEM_POE }, + { "big_poe", ITEM_BIG_POE }, + { "blue_fire", ITEM_BLUE_FIRE }, + { "rutos_letter", ITEM_LETTER_RUTO }, }; -static bool BottleHandler(std::shared_ptr Console, const std::vector& args, std::string* output) { +static bool BottleHandler(std::shared_ptr Console, const std::vector& args, + std::string* output) { if (args.size() < 3) { ERROR_MESSAGE("[SOH] Unexpected arguments passed"); return 1; @@ -329,7 +348,7 @@ static bool BottleHandler(std::shared_ptr Console, const std::vec const auto& it = bottleItems.find(args[1]); - if (it == bottleItems.end()) { + if (it == bottleItems.end()) { ERROR_MESSAGE("Invalid item passed"); return 1; } @@ -340,7 +359,8 @@ static bool BottleHandler(std::shared_ptr Console, const std::vec return 0; } -static bool BHandler(std::shared_ptr Console, const std::vector& args, std::string* output) { +static bool BHandler(std::shared_ptr Console, const std::vector& args, + std::string* output) { if (args.size() < 2) { ERROR_MESSAGE("[SOH] Unexpected arguments passed"); return 1; @@ -350,7 +370,8 @@ static bool BHandler(std::shared_ptr Console, const std::vector Console, const std::vector& args, std::string* output) { +static bool ItemHandler(std::shared_ptr Console, const std::vector& args, + std::string* output) { if (args.size() < 3) { ERROR_MESSAGE("[SOH] Unexpected arguments passed"); return 1; @@ -361,7 +382,8 @@ static bool ItemHandler(std::shared_ptr Console, const std::vecto return 0; } -static bool GiveItemHandler(std::shared_ptr Console, const std::vector args, std::string* output) { +static bool GiveItemHandler(std::shared_ptr Console, const std::vector args, + std::string* output) { if (args.size() < 3) { ERROR_MESSAGE("[SOH] Unexpected arguments passed"); return 1; @@ -382,7 +404,8 @@ static bool GiveItemHandler(std::shared_ptr Console, const std::v return 0; } -static bool EntranceHandler(std::shared_ptr Console, const std::vector& args, std::string* output) { +static bool EntranceHandler(std::shared_ptr Console, const std::vector& args, + std::string* output) { if (args.size() < 2) { ERROR_MESSAGE("[SOH] Unexpected arguments passed"); return 1; @@ -404,15 +427,16 @@ static bool EntranceHandler(std::shared_ptr Console, const std::v return 0; } -static bool VoidHandler(std::shared_ptr Console, const std::vector& args, std::string* output) { +static bool VoidHandler(std::shared_ptr Console, const std::vector& args, + std::string* output) { if (gPlayState != nullptr) { - gSaveContext.respawn[RESPAWN_MODE_DOWN].tempSwchFlags = gPlayState->actorCtx.flags.tempSwch; - gSaveContext.respawn[RESPAWN_MODE_DOWN].tempCollectFlags = gPlayState->actorCtx.flags.tempCollect; - gSaveContext.respawnFlag = 1; - gPlayState->transitionTrigger = TRANS_TRIGGER_START; - gPlayState->nextEntranceIndex = gSaveContext.respawn[RESPAWN_MODE_DOWN].entranceIndex; - gPlayState->transitionType = TRANS_TYPE_FADE_BLACK; - gSaveContext.nextTransitionType = TRANS_TYPE_FADE_BLACK; + gSaveContext.respawn[RESPAWN_MODE_DOWN].tempSwchFlags = gPlayState->actorCtx.flags.tempSwch; + gSaveContext.respawn[RESPAWN_MODE_DOWN].tempCollectFlags = gPlayState->actorCtx.flags.tempCollect; + gSaveContext.respawnFlag = 1; + gPlayState->transitionTrigger = TRANS_TRIGGER_START; + gPlayState->nextEntranceIndex = gSaveContext.respawn[RESPAWN_MODE_DOWN].entranceIndex; + gPlayState->transitionType = TRANS_TYPE_FADE_BLACK; + gSaveContext.nextTransitionType = TRANS_TYPE_FADE_BLACK; } else { ERROR_MESSAGE("gPlayState == nullptr"); return 1; @@ -420,7 +444,8 @@ static bool VoidHandler(std::shared_ptr Console, const std::vecto return 0; } -static bool ReloadHandler(std::shared_ptr Console, const std::vector& args, std::string* output) { +static bool ReloadHandler(std::shared_ptr Console, const std::vector& args, + std::string* output) { if (gPlayState != nullptr) { gPlayState->nextEntranceIndex = gSaveContext.entranceIndex; gPlayState->transitionTrigger = TRANS_TRIGGER_START; @@ -433,11 +458,10 @@ static bool ReloadHandler(std::shared_ptr Console, const std::vec return 0; } -const static std::map fw_options { - { "clear", 0}, {"warp", 1}, {"backup", 2} -}; +const static std::map fw_options{ { "clear", 0 }, { "warp", 1 }, { "backup", 2 } }; -static bool FWHandler(std::shared_ptr Console, const std::vector& args, std::string* output) { +static bool FWHandler(std::shared_ptr Console, const std::vector& args, + std::string* output) { if (args.size() < 2) { ERROR_MESSAGE("[SOH] Unexpected arguments passed"); return 1; @@ -448,16 +472,16 @@ static bool FWHandler(std::shared_ptr Console, const std::vector< ERROR_MESSAGE("[SOH] Invalid option. Options are 'clear', 'warp', 'backup'"); return 1; } - + if (gPlayState != nullptr) { FaroresWindData clear = {}; - switch(it->second) { - case 0: //clear + switch (it->second) { + case 0: // clear gSaveContext.fw = clear; INFO_MESSAGE("[SOH] Farore's wind point cleared! Reload scene to take effect."); return 0; break; - case 1: //warp + case 1: // warp if (gSaveContext.respawn[RESPAWN_MODE_TOP].data > 0) { gPlayState->transitionTrigger = TRANS_TRIGGER_START; gPlayState->nextEntranceIndex = gSaveContext.respawn[RESPAWN_MODE_TOP].entranceIndex; @@ -468,7 +492,7 @@ static bool FWHandler(std::shared_ptr Console, const std::vector< } return 0; break; - case 2: //backup + case 2: // backup if (CVarGetInteger(CVAR_ENHANCEMENT("BetterFarore"), 0)) { gSaveContext.fw = gSaveContext.ship.backupFW; gSaveContext.fw.set = 1; @@ -480,16 +504,16 @@ static bool FWHandler(std::shared_ptr Console, const std::vector< } break; } - } - else { + } else { ERROR_MESSAGE("gPlayState == nullptr"); return 1; } - + return 0; } -static bool FileSelectHandler(std::shared_ptr Console, const std::vector& args, std::string* output) { +static bool FileSelectHandler(std::shared_ptr Console, const std::vector& args, + std::string* output) { if (gGameState == nullptr) { ERROR_MESSAGE("gGameState == nullptr"); return 1; @@ -501,12 +525,14 @@ static bool FileSelectHandler(std::shared_ptr Console, const std: return 0; } -static bool QuitHandler(std::shared_ptr Console, const std::vector& args, std::string* output) { +static bool QuitHandler(std::shared_ptr Console, const std::vector& args, + std::string* output) { Ship::Context::GetInstance()->GetWindow()->Close(); return 0; } -static bool SaveStateHandler(std::shared_ptr Console, const std::vector& args, std::string* output) { +static bool SaveStateHandler(std::shared_ptr Console, const std::vector& args, + std::string* output) { unsigned int slot = OTRGlobals::Instance->gSaveStateMgr->GetCurrentSlot(); const SaveStateReturn rtn = OTRGlobals::Instance->gSaveStateMgr->AddRequest({ slot, RequestType::SAVE }); @@ -522,7 +548,8 @@ static bool SaveStateHandler(std::shared_ptr Console, const std:: } } -static bool LoadStateHandler(std::shared_ptr Console, const std::vector& args, std::string* output) { +static bool LoadStateHandler(std::shared_ptr Console, const std::vector& args, + std::string* output) { unsigned int slot = OTRGlobals::Instance->gSaveStateMgr->GetCurrentSlot(); const SaveStateReturn rtn = OTRGlobals::Instance->gSaveStateMgr->AddRequest({ slot, RequestType::LOAD }); @@ -542,10 +569,10 @@ static bool LoadStateHandler(std::shared_ptr Console, const std:: default: return 1; } - } -static bool StateSlotSelectHandler(std::shared_ptr Console, const std::vector& args, std::string* output) { +static bool StateSlotSelectHandler(std::shared_ptr Console, const std::vector& args, + std::string* output) { if (args.size() < 2) { ERROR_MESSAGE("[SOH] Unexpected arguments passed"); return 1; @@ -565,12 +592,12 @@ static bool StateSlotSelectHandler(std::shared_ptr Console, const } OTRGlobals::Instance->gSaveStateMgr->SetCurrentSlot(slot); - INFO_MESSAGE("[SOH] Slot %u selected", - OTRGlobals::Instance->gSaveStateMgr->GetCurrentSlot()); + INFO_MESSAGE("[SOH] Slot %u selected", OTRGlobals::Instance->gSaveStateMgr->GetCurrentSlot()); return 0; } -static bool InvisibleHandler(std::shared_ptr Console, const std::vector& args, std::string* output) { +static bool InvisibleHandler(std::shared_ptr Console, const std::vector& args, + std::string* output) { if (args.size() < 2) { ERROR_MESSAGE("[SOH] Unexpected arguments passed"); return 1; @@ -585,19 +612,19 @@ static bool InvisibleHandler(std::shared_ptr Console, const std:: } RemovableGameInteractionEffect* effect = new GameInteractionEffect::InvisibleLink(); - GameInteractionEffectQueryResult result = + GameInteractionEffectQueryResult result = state ? GameInteractor::ApplyEffect(effect) : GameInteractor::RemoveEffect(effect); if (result == GameInteractionEffectQueryResult::Possible) { INFO_MESSAGE("[SOH] Invisible Link %s", state ? "enabled" : "disabled"); return 0; } else { - INFO_MESSAGE("[SOH] Command failed: Could not %s Invisible Link.", - state ? "enable" : "disable"); + INFO_MESSAGE("[SOH] Command failed: Could not %s Invisible Link.", state ? "enable" : "disable"); return 1; } } -static bool GiantLinkHandler(std::shared_ptr Console, const std::vector& args, std::string* output) { +static bool GiantLinkHandler(std::shared_ptr Console, const std::vector& args, + std::string* output) { if (args.size() < 2) { ERROR_MESSAGE("[SOH] Unexpected arguments passed"); return 1; @@ -619,13 +646,13 @@ static bool GiantLinkHandler(std::shared_ptr Console, const std:: INFO_MESSAGE("[SOH] Giant Link %s", state ? "enabled" : "disabled"); return 0; } else { - INFO_MESSAGE("[SOH] Command failed: Could not %s Giant Link.", - state ? "enable" : "disable"); + INFO_MESSAGE("[SOH] Command failed: Could not %s Giant Link.", state ? "enable" : "disable"); return 1; } } -static bool MinishLinkHandler(std::shared_ptr Console, const std::vector& args, std::string* output) { +static bool MinishLinkHandler(std::shared_ptr Console, const std::vector& args, + std::string* output) { if (args.size() < 2) { ERROR_MESSAGE("[SOH] Unexpected arguments passed"); return 1; @@ -647,13 +674,13 @@ static bool MinishLinkHandler(std::shared_ptr Console, const std: INFO_MESSAGE("[SOH] Minish Link %s", state ? "enabled" : "disabled"); return 0; } else { - INFO_MESSAGE("[SOH] Command failed: Could not %s Minish Link.", - state ? "enable" : "disable"); + INFO_MESSAGE("[SOH] Command failed: Could not %s Minish Link.", state ? "enable" : "disable"); return 1; } } -static bool AddHeartContainerHandler(std::shared_ptr Console, const std::vector& args, std::string* output) { +static bool AddHeartContainerHandler(std::shared_ptr Console, const std::vector& args, + std::string* output) { if (args.size() < 2) { ERROR_MESSAGE("[SOH] Unexpected arguments passed"); return 1; @@ -684,7 +711,8 @@ static bool AddHeartContainerHandler(std::shared_ptr Console, con } } -static bool RemoveHeartContainerHandler(std::shared_ptr Console, const std::vector& args, std::string* output) { +static bool RemoveHeartContainerHandler(std::shared_ptr Console, const std::vector& args, + std::string* output) { if (args.size() < 2) { ERROR_MESSAGE("[SOH] Unexpected arguments passed"); return 1; @@ -715,7 +743,8 @@ static bool RemoveHeartContainerHandler(std::shared_ptr Console, } } -static bool GravityHandler(std::shared_ptr Console, const std::vector& args, std::string* output) { +static bool GravityHandler(std::shared_ptr Console, const std::vector& args, + std::string* output) { if (args.size() < 2) { ERROR_MESSAGE("[SOH] Unexpected arguments passed"); return 1; @@ -724,12 +753,13 @@ static bool GravityHandler(std::shared_ptr Console, const std::ve GameInteractionEffectBase* effect = new GameInteractionEffect::ModifyGravity(); try { - dynamic_cast(effect)->parameters[0] = Ship::Math::clamp(std::stoi(args[1], nullptr, 10), GI_GRAVITY_LEVEL_LIGHT, GI_GRAVITY_LEVEL_HEAVY); + dynamic_cast(effect)->parameters[0] = + Ship::Math::clamp(std::stoi(args[1], nullptr, 10), GI_GRAVITY_LEVEL_LIGHT, GI_GRAVITY_LEVEL_HEAVY); } catch (std::invalid_argument const& ex) { ERROR_MESSAGE("[SOH] Gravity value must be a number."); return 1; } - + GameInteractionEffectQueryResult result = GameInteractor::ApplyEffect(effect); if (result == GameInteractionEffectQueryResult::Possible) { INFO_MESSAGE("[SOH] Updated gravity."); @@ -740,7 +770,8 @@ static bool GravityHandler(std::shared_ptr Console, const std::ve } } -static bool NoUIHandler(std::shared_ptr Console, const std::vector& args, std::string* output) { +static bool NoUIHandler(std::shared_ptr Console, const std::vector& args, + std::string* output) { if (args.size() < 2) { ERROR_MESSAGE("[SOH] Unexpected arguments passed"); return 1; @@ -753,7 +784,7 @@ static bool NoUIHandler(std::shared_ptr Console, const std::vecto ERROR_MESSAGE("[SOH] No UI value must be a number."); return 1; } - + RemovableGameInteractionEffect* effect = new GameInteractionEffect::NoUI(); GameInteractionEffectQueryResult result = state ? GameInteractor::ApplyEffect(effect) : GameInteractor::RemoveEffect(effect); @@ -762,13 +793,13 @@ static bool NoUIHandler(std::shared_ptr Console, const std::vecto INFO_MESSAGE("[SOH] No UI %s", state ? "enabled" : "disabled"); return 0; } else { - INFO_MESSAGE("[SOH] Command failed: Could not %s No UI.", - state ? "enable" : "disable"); + INFO_MESSAGE("[SOH] Command failed: Could not %s No UI.", state ? "enable" : "disable"); return 1; } } -static bool FreezeHandler(std::shared_ptr Console, const std::vector& args, std::string* output) { +static bool FreezeHandler(std::shared_ptr Console, const std::vector& args, + std::string* output) { GameInteractionEffectBase* effect = new GameInteractionEffect::FreezePlayer(); GameInteractionEffectQueryResult result = GameInteractor::ApplyEffect(effect); @@ -781,7 +812,8 @@ static bool FreezeHandler(std::shared_ptr Console, const std::vec } } -static bool DefenseModifierHandler(std::shared_ptr Console, const std::vector& args, std::string* output) { +static bool DefenseModifierHandler(std::shared_ptr Console, const std::vector& args, + std::string* output) { if (args.size() < 2) { ERROR_MESSAGE("[SOH] Unexpected arguments passed"); return 1; @@ -797,7 +829,8 @@ static bool DefenseModifierHandler(std::shared_ptr Console, const GameInteractionEffectQueryResult result = GameInteractor::ApplyEffect(effect); if (result == GameInteractionEffectQueryResult::Possible) { - INFO_MESSAGE("[SOH] Defense modifier set to %d", dynamic_cast(effect)->parameters[0]); + INFO_MESSAGE("[SOH] Defense modifier set to %d", + dynamic_cast(effect)->parameters[0]); return 0; } else { INFO_MESSAGE("[SOH] Command failed: Could not set defense modifier."); @@ -805,7 +838,8 @@ static bool DefenseModifierHandler(std::shared_ptr Console, const } } -static bool DamageHandler(std::shared_ptr Console, const std::vector& args, std::string* output) { +static bool DamageHandler(std::shared_ptr Console, const std::vector& args, + std::string* output) { if (args.size() < 2) { ERROR_MESSAGE("[SOH] Unexpected arguments passed"); return 1; @@ -835,7 +869,8 @@ static bool DamageHandler(std::shared_ptr Console, const std::vec } } -static bool HealHandler(std::shared_ptr Console, const std::vector& args, std::string* output) { +static bool HealHandler(std::shared_ptr Console, const std::vector& args, + std::string* output) { if (args.size() < 2) { ERROR_MESSAGE("[SOH] Unexpected arguments passed"); return 1; @@ -865,7 +900,8 @@ static bool HealHandler(std::shared_ptr Console, const std::vecto } } -static bool FillMagicHandler(std::shared_ptr Console, const std::vector& args, std::string* output) { +static bool FillMagicHandler(std::shared_ptr Console, const std::vector& args, + std::string* output) { GameInteractionEffectBase* effect = new GameInteractionEffect::FillMagic(); GameInteractionEffectQueryResult result = GameInteractor::ApplyEffect(effect); @@ -878,7 +914,8 @@ static bool FillMagicHandler(std::shared_ptr Console, const std:: } } -static bool EmptyMagicHandler(std::shared_ptr Console, const std::vector& args, std::string* output) { +static bool EmptyMagicHandler(std::shared_ptr Console, const std::vector& args, + std::string* output) { GameInteractionEffectBase* effect = new GameInteractionEffect::EmptyMagic(); GameInteractionEffectQueryResult result = GameInteractor::ApplyEffect(effect); @@ -891,12 +928,13 @@ static bool EmptyMagicHandler(std::shared_ptr Console, const std: } } -static bool NoZHandler(std::shared_ptr Console, const std::vector& args, std::string* output) { - if (args.size() < 2) { +static bool NoZHandler(std::shared_ptr Console, const std::vector& args, + std::string* output) { + if (args.size() < 2) { ERROR_MESSAGE("[SOH] Unexpected arguments passed"); return 1; } - uint8_t state; + uint8_t state; try { state = std::stoi(args[1], nullptr, 10) == 0 ? 0 : 1; @@ -913,13 +951,13 @@ static bool NoZHandler(std::shared_ptr Console, const std::vector INFO_MESSAGE("[SOH] NoZ " + std::string(state ? "enabled" : "disabled")); return 0; } else { - INFO_MESSAGE("[SOH] Command failed: Could not " + - std::string(state ? "enable" : "disable") + " NoZ."); + INFO_MESSAGE("[SOH] Command failed: Could not " + std::string(state ? "enable" : "disable") + " NoZ."); return 1; } } -static bool OneHitKOHandler(std::shared_ptr Console, const std::vector& args, std::string* output) { +static bool OneHitKOHandler(std::shared_ptr Console, const std::vector& args, + std::string* output) { if (args.size() < 2) { ERROR_MESSAGE("[SOH] Unexpected arguments passed"); return 1; @@ -941,13 +979,13 @@ static bool OneHitKOHandler(std::shared_ptr Console, const std::v INFO_MESSAGE("[SOH] One-hit KO " + std::string(state ? "enabled" : "disabled")); return 0; } else { - INFO_MESSAGE("[SOH] Command failed: Could not " + - std::string(state ? "enable" : "disable") + " One-hit KO."); + INFO_MESSAGE("[SOH] Command failed: Could not " + std::string(state ? "enable" : "disable") + " One-hit KO."); return 1; } } -static bool PacifistHandler(std::shared_ptr Console, const std::vector& args, std::string* output) { +static bool PacifistHandler(std::shared_ptr Console, const std::vector& args, + std::string* output) { if (args.size() < 2) { ERROR_MESSAGE("[SOH] Unexpected arguments passed"); return 1; @@ -969,13 +1007,13 @@ static bool PacifistHandler(std::shared_ptr Console, const std::v INFO_MESSAGE("[SOH] Pacifist " + std::string(state ? "enabled" : "disabled")); return 0; } else { - INFO_MESSAGE("[SOH] Command failed: Could not " + - std::string(state ? "enable" : "disable") + " Pacifist."); + INFO_MESSAGE("[SOH] Command failed: Could not " + std::string(state ? "enable" : "disable") + " Pacifist."); return 1; } } -static bool PaperLinkHandler(std::shared_ptr Console, const std::vector& args, std::string* output) { +static bool PaperLinkHandler(std::shared_ptr Console, const std::vector& args, + std::string* output) { if (args.size() < 2) { ERROR_MESSAGE("[SOH] Unexpected arguments passed"); return 1; @@ -998,13 +1036,13 @@ static bool PaperLinkHandler(std::shared_ptr Console, const std:: INFO_MESSAGE("[SOH] Paper Link " + std::string(state ? "enabled" : "disabled")); return 0; } else { - INFO_MESSAGE("[SOH] Command failed: Could not " + - std::string(state ? "enable" : "disable") + " Paper Link."); + INFO_MESSAGE("[SOH] Command failed: Could not " + std::string(state ? "enable" : "disable") + " Paper Link."); return 1; } } -static bool RainstormHandler(std::shared_ptr Console, const std::vector& args, std::string* output) { +static bool RainstormHandler(std::shared_ptr Console, const std::vector& args, + std::string* output) { if (args.size() < 2) { ERROR_MESSAGE("[SOH] Unexpected arguments passed"); return 1; @@ -1026,13 +1064,13 @@ static bool RainstormHandler(std::shared_ptr Console, const std:: INFO_MESSAGE("[SOH] Rainstorm " + std::string(state ? "enabled" : "disabled")); return 0; } else { - INFO_MESSAGE("[SOH] Command failed: Could not " + - std::string(state ? "enable" : "disable") + " Rainstorm."); + INFO_MESSAGE("[SOH] Command failed: Could not " + std::string(state ? "enable" : "disable") + " Rainstorm."); return 1; } } -static bool ReverseControlsHandler(std::shared_ptr Console, const std::vector& args, std::string* output) { +static bool ReverseControlsHandler(std::shared_ptr Console, const std::vector& args, + std::string* output) { if (args.size() < 2) { ERROR_MESSAGE("[SOH] Unexpected arguments passed"); return 1; @@ -1051,17 +1089,17 @@ static bool ReverseControlsHandler(std::shared_ptr Console, const state ? GameInteractor::ApplyEffect(effect) : GameInteractor::RemoveEffect(effect); if (result == GameInteractionEffectQueryResult::Possible) { - INFO_MESSAGE("[SOH] Reverse controls " + - std::string(state ? "enabled" : "disabled")); + INFO_MESSAGE("[SOH] Reverse controls " + std::string(state ? "enabled" : "disabled")); return 0; } else { - INFO_MESSAGE("[SOH] Command failed: Could not " + - std::string(state ? "enable" : "disable") + " Reverse controls."); + INFO_MESSAGE("[SOH] Command failed: Could not " + std::string(state ? "enable" : "disable") + + " Reverse controls."); return 1; } } -static bool UpdateRupeesHandler(std::shared_ptr Console, const std::vector& args, std::string* output) { +static bool UpdateRupeesHandler(std::shared_ptr Console, const std::vector& args, + std::string* output) { if (args.size() < 2) { ERROR_MESSAGE("[SOH] Unexpected arguments passed"); return 1; @@ -1085,7 +1123,8 @@ static bool UpdateRupeesHandler(std::shared_ptr Console, const st } } -static bool SpeedModifierHandler(std::shared_ptr Console, const std::vector& args, std::string* output) { +static bool SpeedModifierHandler(std::shared_ptr Console, const std::vector& args, + std::string* output) { if (args.size() < 2) { ERROR_MESSAGE("[SOH] Unexpected arguments passed"); return 1; @@ -1109,13 +1148,14 @@ static bool SpeedModifierHandler(std::shared_ptr Console, const s } } -const static std::map boots { +const static std::map boots{ { "kokiri", EQUIP_VALUE_BOOTS_KOKIRI }, { "iron", EQUIP_VALUE_BOOTS_IRON }, { "hover", EQUIP_VALUE_BOOTS_HOVER }, }; -static bool BootsHandler(std::shared_ptr Console, const std::vector& args, std::string* output) { +static bool BootsHandler(std::shared_ptr Console, const std::vector& args, + std::string* output) { if (args.size() < 2) { ERROR_MESSAGE("[SOH] Unexpected arguments passed"); return 1; @@ -1140,13 +1180,14 @@ static bool BootsHandler(std::shared_ptr Console, const std::vect } } -const static std::map shields { +const static std::map shields{ { "deku", ITEM_SHIELD_DEKU }, { "hylian", ITEM_SHIELD_HYLIAN }, { "mirror", ITEM_SHIELD_MIRROR }, }; -static bool GiveShieldHandler(std::shared_ptr Console, const std::vector& args, std::string* output) { +static bool GiveShieldHandler(std::shared_ptr Console, const std::vector& args, + std::string* output) { if (args.size() < 2) { ERROR_MESSAGE("[SOH] Unexpected arguments passed"); return 1; @@ -1171,7 +1212,8 @@ static bool GiveShieldHandler(std::shared_ptr Console, const std: } } -static bool TakeShieldHandler(std::shared_ptr Console, const std::vector& args, std::string* output) { +static bool TakeShieldHandler(std::shared_ptr Console, const std::vector& args, + std::string* output) { if (args.size() < 2) { ERROR_MESSAGE("[SOH] Unexpected arguments passed"); return 1; @@ -1196,7 +1238,8 @@ static bool TakeShieldHandler(std::shared_ptr Console, const std: } } -static bool KnockbackHandler(std::shared_ptr Console, const std::vector& args, std::string* output) { +static bool KnockbackHandler(std::shared_ptr Console, const std::vector& args, + std::string* output) { if (args.size() < 2) { ERROR_MESSAGE("[SOH] Unexpected arguments passed"); return 1; @@ -1226,7 +1269,8 @@ static bool KnockbackHandler(std::shared_ptr Console, const std:: } } -static bool ElectrocuteHandler(std::shared_ptr Console, const std::vector& args, std::string* output) { +static bool ElectrocuteHandler(std::shared_ptr Console, const std::vector& args, + std::string* output) { GameInteractionEffectBase* effect = new GameInteractionEffect::ElectrocutePlayer(); GameInteractionEffectQueryResult result = GameInteractor::ApplyEffect(effect); @@ -1239,7 +1283,8 @@ static bool ElectrocuteHandler(std::shared_ptr Console, const std } } -static bool BurnHandler(std::shared_ptr Console, const std::vector& args, std::string* output) { +static bool BurnHandler(std::shared_ptr Console, const std::vector& args, + std::string* output) { GameInteractionEffectBase* effect = new GameInteractionEffect::BurnPlayer(); GameInteractionEffectQueryResult result = GameInteractor::ApplyEffect(effect); @@ -1252,7 +1297,8 @@ static bool BurnHandler(std::shared_ptr Console, const std::vecto } } -static bool CuccoStormHandler(std::shared_ptr Console, const std::vector& args, std::string* output) { +static bool CuccoStormHandler(std::shared_ptr Console, const std::vector& args, + std::string* output) { GameInteractionEffectQueryResult result = GameInteractor::RawAction::SpawnActor(ACTOR_EN_NIW, 0); if (result == GameInteractionEffectQueryResult::Possible) { @@ -1264,7 +1310,8 @@ static bool CuccoStormHandler(std::shared_ptr Console, const std: } } -static bool GenerateRandoHandler(std::shared_ptr Console, const std::vector& args, std::string* output) { +static bool GenerateRandoHandler(std::shared_ptr Console, const std::vector& args, + std::string* output) { if (args.size() == 1) { if (GenerateRandomizer()) { return 0; @@ -1279,7 +1326,7 @@ static bool GenerateRandoHandler(std::shared_ptr Console, const s seed = "seed_testing_count"; } - if (GenerateRandomizer(seed + std::to_string(value))){ + if (GenerateRandomizer(seed + std::to_string(value))) { return 0; } } catch (std::invalid_argument const& ex) { @@ -1287,36 +1334,36 @@ static bool GenerateRandoHandler(std::shared_ptr Console, const s return 1; } - ERROR_MESSAGE("[SOH] Rando generation already in progress"); return 1; } -static constexpr std::array, COSMETICS_GROUP_MAX> cosmetic_groups = {{ - {"link", COSMETICS_GROUP_LINK}, - {"mirror_shield", COSMETICS_GROUP_MIRRORSHIELD}, - {"swords", COSMETICS_GROUP_SWORDS}, - {"gloves", COSMETICS_GROUP_GLOVES}, - {"equipment", COSMETICS_GROUP_EQUIPMENT}, - {"keyring", COSMETICS_GROUP_KEYRING}, - {"small_keys", COSMETICS_GROUP_SMALL_KEYS }, - {"boss_keys", COSMETICS_GROUP_BOSS_KEYS }, - {"consumable", COSMETICS_GROUP_CONSUMABLE}, - {"hud", COSMETICS_GROUP_HUD}, - {"kaleido", COSMETICS_GROUP_KALEIDO}, - {"title", COSMETICS_GROUP_TITLE}, - {"npc", COSMETICS_GROUP_NPC}, - {"world", COSMETICS_GROUP_WORLD}, - {"magic", COSMETICS_GROUP_MAGIC}, - {"arrows", COSMETICS_GROUP_ARROWS}, - {"spin_attack", COSMETICS_GROUP_SPIN_ATTACK}, - {"trials", COSMETICS_GROUP_TRAILS}, - {"navi", COSMETICS_GROUP_NAVI}, - {"ivan", COSMETICS_GROUP_IVAN}, - {"message", COSMETICS_GROUP_MESSAGE}, -}}; +static constexpr std::array, COSMETICS_GROUP_MAX> cosmetic_groups = { { + { "link", COSMETICS_GROUP_LINK }, + { "mirror_shield", COSMETICS_GROUP_MIRRORSHIELD }, + { "swords", COSMETICS_GROUP_SWORDS }, + { "gloves", COSMETICS_GROUP_GLOVES }, + { "equipment", COSMETICS_GROUP_EQUIPMENT }, + { "keyring", COSMETICS_GROUP_KEYRING }, + { "small_keys", COSMETICS_GROUP_SMALL_KEYS }, + { "boss_keys", COSMETICS_GROUP_BOSS_KEYS }, + { "consumable", COSMETICS_GROUP_CONSUMABLE }, + { "hud", COSMETICS_GROUP_HUD }, + { "kaleido", COSMETICS_GROUP_KALEIDO }, + { "title", COSMETICS_GROUP_TITLE }, + { "npc", COSMETICS_GROUP_NPC }, + { "world", COSMETICS_GROUP_WORLD }, + { "magic", COSMETICS_GROUP_MAGIC }, + { "arrows", COSMETICS_GROUP_ARROWS }, + { "spin_attack", COSMETICS_GROUP_SPIN_ATTACK }, + { "trials", COSMETICS_GROUP_TRAILS }, + { "navi", COSMETICS_GROUP_NAVI }, + { "ivan", COSMETICS_GROUP_IVAN }, + { "message", COSMETICS_GROUP_MESSAGE }, +} }; -static bool CosmeticsHandler(std::shared_ptr Console, const std::vector& args, std::string* output) { +static bool CosmeticsHandler(std::shared_ptr Console, const std::vector& args, + std::string* output) { if (args.size() < 2) { ERROR_MESSAGE("[SOH] Unexpected arguments passed"); return 1; @@ -1357,18 +1404,13 @@ static bool CosmeticsHandler(std::shared_ptr Console, const std:: } static std::map sfx_groups = { - {"bgm", SEQ_BGM_WORLD}, - {"fanfares", SEQ_FANFARE}, - {"events", SEQ_BGM_EVENT}, - {"battle", SEQ_BGM_BATTLE}, - {"ocarina", SEQ_OCARINA}, - {"instruments", SEQ_INSTRUMENT}, - {"sfx", SEQ_SFX}, - {"voices", SEQ_VOICE}, - {"custom", SEQ_BGM_CUSTOM}, + { "bgm", SEQ_BGM_WORLD }, { "fanfares", SEQ_FANFARE }, { "events", SEQ_BGM_EVENT }, + { "battle", SEQ_BGM_BATTLE }, { "ocarina", SEQ_OCARINA }, { "instruments", SEQ_INSTRUMENT }, + { "sfx", SEQ_SFX }, { "voices", SEQ_VOICE }, { "custom", SEQ_BGM_CUSTOM }, }; -static bool SfxHandler(std::shared_ptr Console, const std::vector& args, std::string* output) { +static bool SfxHandler(std::shared_ptr Console, const std::vector& args, + std::string* output) { if (args.size() < 2) { ERROR_MESSAGE("[SOH] Unexpected arguments passed"); return 1; @@ -1410,192 +1452,261 @@ static bool SfxHandler(std::shared_ptr Console, const std::vector void DebugConsole_Init(void) { // Console - CMD_REGISTER("file_select", {FileSelectHandler, "Returns to the file select."}); - CMD_REGISTER("reset", {ResetHandler, "Resets the game."}); - CMD_REGISTER("quit", {QuitHandler, "Quits the game."}); + CMD_REGISTER("file_select", { FileSelectHandler, "Returns to the file select." }); + CMD_REGISTER("reset", { ResetHandler, "Resets the game." }); + CMD_REGISTER("quit", { QuitHandler, "Quits the game." }); // Save States - CMD_REGISTER("save_state", {SaveStateHandler, "Save a state."}); - CMD_REGISTER("load_state", {LoadStateHandler, "Load a state."}); - CMD_REGISTER("set_slot", {StateSlotSelectHandler, "Selects a SaveState slot", { - {"Slot number", Ship::ArgumentType::NUMBER}, - }}); + CMD_REGISTER("save_state", { SaveStateHandler, "Save a state." }); + CMD_REGISTER("load_state", { LoadStateHandler, "Load a state." }); + CMD_REGISTER("set_slot", { StateSlotSelectHandler, + "Selects a SaveState slot", + { + { "Slot number", Ship::ArgumentType::NUMBER }, + } }); // Map & Location - CMD_REGISTER("void", {VoidHandler, "Voids out of the current map."}); - CMD_REGISTER("reload", {ReloadHandler, "Reloads the current map."}); - CMD_REGISTER("fw", {FWHandler, "Spawns the player where Farore's Wind is set.", { - {"clear|warp|backup", Ship::ArgumentType::TEXT}, - }}); - CMD_REGISTER("entrance", {EntranceHandler, "Sends player to the entered entrance (hex)", { - {"entrance", Ship::ArgumentType::NUMBER}, - }}); + CMD_REGISTER("void", { VoidHandler, "Voids out of the current map." }); + CMD_REGISTER("reload", { ReloadHandler, "Reloads the current map." }); + CMD_REGISTER("fw", { FWHandler, + "Spawns the player where Farore's Wind is set.", + { + { "clear|warp|backup", Ship::ArgumentType::TEXT }, + } }); + CMD_REGISTER("entrance", { EntranceHandler, + "Sends player to the entered entrance (hex)", + { + { "entrance", Ship::ArgumentType::NUMBER }, + } }); // Gameplay - CMD_REGISTER("kill", {KillPlayerHandler, "Commit suicide."}); + CMD_REGISTER("kill", { KillPlayerHandler, "Commit suicide." }); - CMD_REGISTER("map", {LoadSceneHandler, "Load up kak?"}); + CMD_REGISTER("map", { LoadSceneHandler, "Load up kak?" }); - CMD_REGISTER("rupee", {RupeeHandler, "Set your rupee counter.", { - {"amount", Ship::ArgumentType::NUMBER}, - }}); + CMD_REGISTER("rupee", { RupeeHandler, + "Set your rupee counter.", + { + { "amount", Ship::ArgumentType::NUMBER }, + } }); - CMD_REGISTER("bItem", {BHandler, "Set an item to the B button.", { - {"Item ID", Ship::ArgumentType::NUMBER}, - }}); + CMD_REGISTER("bItem", { BHandler, + "Set an item to the B button.", + { + { "Item ID", Ship::ArgumentType::NUMBER }, + } }); - CMD_REGISTER("spawn", { ActorSpawnHandler, "Spawn an actor.", { { "actor name/id", Ship::ArgumentType::NUMBER }, // TODO there should be an actor_id arg type - {"data", Ship::ArgumentType::NUMBER}, - {"x", Ship::ArgumentType::NUMBER, true}, - {"y", Ship::ArgumentType::NUMBER, true}, - {"z", Ship::ArgumentType::NUMBER, true}, - {"rx", Ship::ArgumentType::NUMBER, true}, - {"ry", Ship::ArgumentType::NUMBER, true}, - {"rz", Ship::ArgumentType::NUMBER, true}, - }}); + CMD_REGISTER("spawn", + { ActorSpawnHandler, + "Spawn an actor.", + { + { "actor name/id", Ship::ArgumentType::NUMBER }, // TODO there should be an actor_id arg type + { "data", Ship::ArgumentType::NUMBER }, + { "x", Ship::ArgumentType::NUMBER, true }, + { "y", Ship::ArgumentType::NUMBER, true }, + { "z", Ship::ArgumentType::NUMBER, true }, + { "rx", Ship::ArgumentType::NUMBER, true }, + { "ry", Ship::ArgumentType::NUMBER, true }, + { "rz", Ship::ArgumentType::NUMBER, true }, + } }); - CMD_REGISTER("pos", {SetPosHandler, "Sets the position of the player.", { - {"x", Ship::ArgumentType::NUMBER, true}, - {"y", Ship::ArgumentType::NUMBER, true}, - {"z", Ship::ArgumentType::NUMBER, true}, - }}); + CMD_REGISTER("pos", { SetPosHandler, + "Sets the position of the player.", + { + { "x", Ship::ArgumentType::NUMBER, true }, + { "y", Ship::ArgumentType::NUMBER, true }, + { "z", Ship::ArgumentType::NUMBER, true }, + } }); - CMD_REGISTER("addammo", {AddAmmoHandler, "Adds ammo of an item.", { - {"sticks|nuts|bombs|seeds|arrows|bombchus|beans", Ship::ArgumentType::TEXT}, - {"count", Ship::ArgumentType::NUMBER}, - }}); + CMD_REGISTER("addammo", { AddAmmoHandler, + "Adds ammo of an item.", + { + { "sticks|nuts|bombs|seeds|arrows|bombchus|beans", Ship::ArgumentType::TEXT }, + { "count", Ship::ArgumentType::NUMBER }, + } }); - CMD_REGISTER("takeammo", {TakeAmmoHandler, "Removes ammo of an item.", { - {"sticks|nuts|bombs|seeds|arrows|bombchus|beans", Ship::ArgumentType::TEXT}, - {"count", Ship::ArgumentType::NUMBER}, - }}); + CMD_REGISTER("takeammo", { TakeAmmoHandler, + "Removes ammo of an item.", + { + { "sticks|nuts|bombs|seeds|arrows|bombchus|beans", Ship::ArgumentType::TEXT }, + { "count", Ship::ArgumentType::NUMBER }, + } }); - CMD_REGISTER("bottle", {BottleHandler, "Changes item in a bottle slot.", { - {"item", Ship::ArgumentType::TEXT}, - {"slot", Ship::ArgumentType::NUMBER}, - }}); + CMD_REGISTER("bottle", { BottleHandler, + "Changes item in a bottle slot.", + { + { "item", Ship::ArgumentType::TEXT }, + { "slot", Ship::ArgumentType::NUMBER }, + } }); - CMD_REGISTER("give_item", {GiveItemHandler, "Gives an item to the player as if it was given from an actor", { - {"vanilla|randomizer", Ship::ArgumentType::TEXT}, - {"giveItemID", Ship::ArgumentType::NUMBER}, - }}); + CMD_REGISTER("give_item", { GiveItemHandler, + "Gives an item to the player as if it was given from an actor", + { + { "vanilla|randomizer", Ship::ArgumentType::TEXT }, + { "giveItemID", Ship::ArgumentType::NUMBER }, + } }); - CMD_REGISTER("item", {ItemHandler, "Sets item ID in arg 1 into slot arg 2. No boundary checks. Use with caution.", { - {"slot", Ship::ArgumentType::NUMBER}, - {"item id", Ship::ArgumentType::NUMBER}, - }}); + CMD_REGISTER("item", { ItemHandler, + "Sets item ID in arg 1 into slot arg 2. No boundary checks. Use with caution.", + { + { "slot", Ship::ArgumentType::NUMBER }, + { "item id", Ship::ArgumentType::NUMBER }, + } }); - CMD_REGISTER("invisible", {InvisibleHandler, "Activate Link's Elvish cloak, making him appear invisible.", { - {"value", Ship::ArgumentType::NUMBER}, - }}); + CMD_REGISTER("invisible", { InvisibleHandler, + "Activate Link's Elvish cloak, making him appear invisible.", + { + { "value", Ship::ArgumentType::NUMBER }, + } }); - CMD_REGISTER("giant_link", {GiantLinkHandler, "Turn Link into a giant Lonky boi.", { - {"value", Ship::ArgumentType::NUMBER}, - }}); + CMD_REGISTER("giant_link", { GiantLinkHandler, + "Turn Link into a giant Lonky boi.", + { + { "value", Ship::ArgumentType::NUMBER }, + } }); - CMD_REGISTER("minish_link", {MinishLinkHandler, "Turn Link into a minish boi.", { - {"value", Ship::ArgumentType::NUMBER}, - }}); + CMD_REGISTER("minish_link", { MinishLinkHandler, + "Turn Link into a minish boi.", + { + { "value", Ship::ArgumentType::NUMBER }, + } }); CMD_REGISTER("add_heart_container", - {AddHeartContainerHandler, "Give Link a heart! The maximum amount of hearts is 20!"}); + { AddHeartContainerHandler, "Give Link a heart! The maximum amount of hearts is 20!" }); CMD_REGISTER("remove_heart_container", - {RemoveHeartContainerHandler, "Remove a heart from Link. The minimal amount of hearts is 3."}); + { RemoveHeartContainerHandler, "Remove a heart from Link. The minimal amount of hearts is 3." }); - CMD_REGISTER("gravity", {GravityHandler, "Set gravity level.", { - {"value", Ship::ArgumentType::NUMBER}, - }}); + CMD_REGISTER("gravity", { GravityHandler, + "Set gravity level.", + { + { "value", Ship::ArgumentType::NUMBER }, + } }); - CMD_REGISTER("no_ui", {NoUIHandler, "Disables the UI.", { - {"value", Ship::ArgumentType::NUMBER}, - }}); + CMD_REGISTER("no_ui", { NoUIHandler, + "Disables the UI.", + { + { "value", Ship::ArgumentType::NUMBER }, + } }); - CMD_REGISTER("freeze", {FreezeHandler, "Freezes Link in place"}); + CMD_REGISTER("freeze", { FreezeHandler, "Freezes Link in place" }); - CMD_REGISTER("defense_modifier", {DefenseModifierHandler, "Sets the defense modifier.", { - {"value", Ship::ArgumentType::NUMBER}, - }}); + CMD_REGISTER("defense_modifier", { DefenseModifierHandler, + "Sets the defense modifier.", + { + { "value", Ship::ArgumentType::NUMBER }, + } }); - CMD_REGISTER("damage", {DamageHandler, "Deal damage to Link.", { - {"value", Ship::ArgumentType::NUMBER}, - }}); + CMD_REGISTER("damage", { DamageHandler, + "Deal damage to Link.", + { + { "value", Ship::ArgumentType::NUMBER }, + } }); - CMD_REGISTER("heal", {HealHandler, "Heals Link.", { - {"value", Ship::ArgumentType::NUMBER}, - }}); + CMD_REGISTER("heal", { HealHandler, + "Heals Link.", + { + { "value", Ship::ArgumentType::NUMBER }, + } }); - CMD_REGISTER("fill_magic", {FillMagicHandler, "Fills magic."}); + CMD_REGISTER("fill_magic", { FillMagicHandler, "Fills magic." }); - CMD_REGISTER("empty_magic", {EmptyMagicHandler, "Empties magic."}); + CMD_REGISTER("empty_magic", { EmptyMagicHandler, "Empties magic." }); - CMD_REGISTER("no_z", {NoZHandler, "Disables Z-button presses.", { - {"value", Ship::ArgumentType::NUMBER}, - }}); + CMD_REGISTER("no_z", { NoZHandler, + "Disables Z-button presses.", + { + { "value", Ship::ArgumentType::NUMBER }, + } }); - CMD_REGISTER("ohko", {OneHitKOHandler, - "Activates one hit KO. Any damage kills Link and he cannot gain health in this mode.", { - {"value", Ship::ArgumentType::NUMBER}, - }}); + CMD_REGISTER("ohko", { OneHitKOHandler, + "Activates one hit KO. Any damage kills Link and he cannot gain health in this mode.", + { + { "value", Ship::ArgumentType::NUMBER }, + } }); - CMD_REGISTER("pacifist", {PacifistHandler, "Activates pacifist mode. Prevents Link from using his weapon.", { - {"value", Ship::ArgumentType::NUMBER}, - }}); + CMD_REGISTER("pacifist", { PacifistHandler, + "Activates pacifist mode. Prevents Link from using his weapon.", + { + { "value", Ship::ArgumentType::NUMBER }, + } }); - CMD_REGISTER("paper_link", {PaperLinkHandler, "Link but made out of paper.", { - {"value", Ship::ArgumentType::NUMBER}, - }}); + CMD_REGISTER("paper_link", { PaperLinkHandler, + "Link but made out of paper.", + { + { "value", Ship::ArgumentType::NUMBER }, + } }); - CMD_REGISTER("rainstorm", {RainstormHandler, "Activates rainstorm."}); + CMD_REGISTER("rainstorm", { RainstormHandler, "Activates rainstorm." }); - CMD_REGISTER("reverse_controls", {ReverseControlsHandler, "Reverses the controls.", { - {"value", Ship::ArgumentType::NUMBER}, - }}); + CMD_REGISTER("reverse_controls", { ReverseControlsHandler, + "Reverses the controls.", + { + { "value", Ship::ArgumentType::NUMBER }, + } }); - CMD_REGISTER("update_rupees", {UpdateRupeesHandler, "Adds rupees.", { - {"value", Ship::ArgumentType::NUMBER}, - }}); + CMD_REGISTER("update_rupees", { UpdateRupeesHandler, + "Adds rupees.", + { + { "value", Ship::ArgumentType::NUMBER }, + } }); - CMD_REGISTER("speed_modifier", {SpeedModifierHandler, "Sets the speed modifier.", { - {"value", Ship::ArgumentType::NUMBER}, - }}); + CMD_REGISTER("speed_modifier", { SpeedModifierHandler, + "Sets the speed modifier.", + { + { "value", Ship::ArgumentType::NUMBER }, + } }); - CMD_REGISTER("boots", {BootsHandler, "Activates boots.", { - {"kokiri|iron|hover", Ship::ArgumentType::TEXT}, - }}); + CMD_REGISTER("boots", { BootsHandler, + "Activates boots.", + { + { "kokiri|iron|hover", Ship::ArgumentType::TEXT }, + } }); - CMD_REGISTER("giveshield", {GiveShieldHandler, "Gives a shield and equips it when Link is the right age for it.", { - {"deku|hylian|mirror", Ship::ArgumentType::TEXT}, - }}); + CMD_REGISTER("giveshield", { GiveShieldHandler, + "Gives a shield and equips it when Link is the right age for it.", + { + { "deku|hylian|mirror", Ship::ArgumentType::TEXT }, + } }); - CMD_REGISTER("takeshield", {TakeShieldHandler, "Takes a shield and unequips it if Link is wearing it.", { - {"deku|hylian|mirror", Ship::ArgumentType::TEXT}, - }}); + CMD_REGISTER("takeshield", { TakeShieldHandler, + "Takes a shield and unequips it if Link is wearing it.", + { + { "deku|hylian|mirror", Ship::ArgumentType::TEXT }, + } }); - CMD_REGISTER("knockback", {KnockbackHandler, "Knocks Link back.", { - {"value", Ship::ArgumentType::NUMBER}, - }}); + CMD_REGISTER("knockback", { KnockbackHandler, + "Knocks Link back.", + { + { "value", Ship::ArgumentType::NUMBER }, + } }); - CMD_REGISTER("electrocute", {ElectrocuteHandler, "Electrocutes Link."}); + CMD_REGISTER("electrocute", { ElectrocuteHandler, "Electrocutes Link." }); - CMD_REGISTER("burn", {BurnHandler, "Burns Link."}); + CMD_REGISTER("burn", { BurnHandler, "Burns Link." }); - CMD_REGISTER("cucco_storm", {CuccoStormHandler, "Cucco Storm"}); + CMD_REGISTER("cucco_storm", { CuccoStormHandler, "Cucco Storm" }); - CMD_REGISTER("gen_rando", {GenerateRandoHandler, "Generate a randomizer seed", { - {"seed|count", Ship::ArgumentType::NUMBER, true}, - {"testing", Ship::ArgumentType::NUMBER, true}, - }}); + CMD_REGISTER("gen_rando", { GenerateRandoHandler, + "Generate a randomizer seed", + { + { "seed|count", Ship::ArgumentType::NUMBER, true }, + { "testing", Ship::ArgumentType::NUMBER, true }, + } }); - CMD_REGISTER("cosmetics", {CosmeticsHandler, "Change cosmetics.", { - {"reset|randomize", Ship::ArgumentType::TEXT}, - {"group name", Ship::ArgumentType::TEXT, true}, - }}); + CMD_REGISTER("cosmetics", { CosmeticsHandler, + "Change cosmetics.", + { + { "reset|randomize", Ship::ArgumentType::TEXT }, + { "group name", Ship::ArgumentType::TEXT, true }, + } }); - CMD_REGISTER("sfx", {SfxHandler, "Change SFX.", { - {"reset|randomize", Ship::ArgumentType::TEXT}, - {"group_name", Ship::ArgumentType::TEXT, true}, - }}); + CMD_REGISTER("sfx", { SfxHandler, + "Change SFX.", + { + { "reset|randomize", Ship::ArgumentType::TEXT }, + { "group_name", Ship::ArgumentType::TEXT, true }, + } }); Ship::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesNextFrame(); } diff --git a/soh/soh/Enhancements/debugger/MessageViewer.cpp b/soh/soh/Enhancements/debugger/MessageViewer.cpp index c7d83e6ea..fef875e94 100644 --- a/soh/soh/Enhancements/debugger/MessageViewer.cpp +++ b/soh/soh/Enhancements/debugger/MessageViewer.cpp @@ -29,7 +29,8 @@ void MessageViewer::DrawElement() { ImGui::Text("Table ID"); ImGui::SameLine(); PushStyleInput(THEME_COLOR); - ImGui::InputText("##TableID", mTableIdBuf, MAX_STRING_SIZE, ImGuiInputTextFlags_CallbackCharFilter, UIWidgets::TextFilters::FilterAlphaNum); + ImGui::InputText("##TableID", mTableIdBuf, MAX_STRING_SIZE, ImGuiInputTextFlags_CallbackCharFilter, + UIWidgets::TextFilters::FilterAlphaNum); UIWidgets::InsertHelpHoverText("Leave blank for vanilla table"); ImGui::Text("Text ID"); ImGui::SameLine(); @@ -41,7 +42,8 @@ void MessageViewer::DrawElement() { case HEXADECIMAL: default: ImGui::InputText("##TextID", mTextIdBuf, MAX_STRING_SIZE, ImGuiInputTextFlags_CharsHexadecimal); - UIWidgets::InsertHelpHoverText("Hexadecimal Text ID of the message to load. Hexadecimal digits only (0-9/A-F)."); + UIWidgets::InsertHelpHoverText( + "Hexadecimal Text ID of the message to load. Hexadecimal digits only (0-9/A-F)."); break; } PopStyleInput(); @@ -169,8 +171,7 @@ void FindMessage(PlayState* play, const uint16_t textId, const uint8_t language) font->msgLength = nextSeg - foundSeg; } -static const char* msgStaticTbl[] = -{ +static const char* msgStaticTbl[] = { gDefaultMessageBackgroundTex, gSignMessageBackgroundTex, gNoteStaffMessageBackgroundTex, @@ -201,13 +202,14 @@ void MessageDebug_StartTextBox(const char* tableId, uint16_t textId, uint8_t lan FindMessage(play, textId, language); msgCtx->msgLength = static_cast(font->msgLength); const uintptr_t src = font->msgOffset; - memcpy(font->msgBuf, reinterpret_cast(src), font->msgLength); + memcpy(font->msgBuf, reinterpret_cast(src), font->msgLength); } else { constexpr int maxBufferSize = sizeof(font->msgBuf); const CustomMessage messageEntry = CustomMessageManager::Instance->RetrieveMessage(tableId, textId); font->charTexBuf[0] = (messageEntry.GetTextBoxType() << 4) | messageEntry.GetTextBoxPosition(); switch (language) { - font->msgLength = SohUtils::CopyStringToCharBuffer(buffer, messageEntry.GetForLanguage(language), maxBufferSize); + font->msgLength = + SohUtils::CopyStringToCharBuffer(buffer, messageEntry.GetForLanguage(language), maxBufferSize); } msgCtx->msgLength = static_cast(font->msgLength); } @@ -258,8 +260,6 @@ void MessageDebug_StartTextBox(const char* tableId, uint16_t textId, uint8_t lan void MessageDebug_DisplayCustomMessage(const char* customMessage) { CustomMessageManager::Instance->ClearMessageTable(MessageViewer::TABLE_ID); CustomMessageManager::Instance->CreateMessage(MessageViewer::TABLE_ID, 0, - CustomMessage(customMessage, customMessage, customMessage)); + CustomMessage(customMessage, customMessage, customMessage)); MessageDebug_StartTextBox(MessageViewer::TABLE_ID, 0, 0); } - - diff --git a/soh/soh/Enhancements/debugger/MessageViewer.h b/soh/soh/Enhancements/debugger/MessageViewer.h index 43ae55aa7..20924a0b6 100644 --- a/soh/soh/Enhancements/debugger/MessageViewer.h +++ b/soh/soh/Enhancements/debugger/MessageViewer.h @@ -25,9 +25,8 @@ void MessageDebug_DisplayCustomMessage(const char* customMessage); #ifdef __cplusplus } - class MessageViewer : public Ship::GuiWindow { -public: + public: static inline const char* TABLE_ID = "MessageViewer"; using GuiWindow::GuiWindow; @@ -37,12 +36,12 @@ public: virtual ~MessageViewer() = default; -private: + private: void DisplayExistingMessage() const; void DisplayCustomMessage() const; static constexpr uint16_t MAX_STRING_SIZE = 1024; - static constexpr std::array mLanguages = {"English", "German", "French"}; + static constexpr std::array mLanguages = { "English", "German", "French" }; static constexpr int HEXADECIMAL = 0; static constexpr int DECIMAL = 1; char* mTableIdBuf; @@ -57,6 +56,5 @@ private: bool mDisplayCustomMessageClicked = false; }; - #endif //__cplusplus -#endif //CUSTOMMESSAGEDEBUGGER_H +#endif // CUSTOMMESSAGEDEBUGGER_H diff --git a/soh/soh/Enhancements/debugger/SohStatsWindow.h b/soh/soh/Enhancements/debugger/SohStatsWindow.h index d68953573..227ca5500 100644 --- a/soh/soh/Enhancements/debugger/SohStatsWindow.h +++ b/soh/soh/Enhancements/debugger/SohStatsWindow.h @@ -6,12 +6,12 @@ class SohStatsWindow : public Ship::GuiWindow { public: using GuiWindow::GuiWindow; - ~SohStatsWindow() {}; + ~SohStatsWindow(){}; protected: - void InitElement() override {}; + void InitElement() override{}; void DrawElement() override; - void UpdateElement() override {}; + void UpdateElement() override{}; }; #endif // SOH_STATS_H diff --git a/soh/soh/Enhancements/debugger/actorViewer.cpp b/soh/soh/Enhancements/debugger/actorViewer.cpp index 8be4fcc4d..8ae940ffb 100644 --- a/soh/soh/Enhancements/debugger/actorViewer.cpp +++ b/soh/soh/Enhancements/debugger/actorViewer.cpp @@ -45,19 +45,13 @@ typedef enum { INTERACT, } RetrievalMethod; -std::array acMapping = { - "Switch", - "Background (Prop type 1)", - "Player", - "Bomb", - "NPC", - "Enemy", - "Prop type 2", - "Item/Action", - "Misc.", - "Boss", - "Door", - "Chest", +std::array acMapping = { + "Switch", "Background (Prop type 1)", + "Player", "Bomb", + "NPC", "Enemy", + "Prop type 2", "Item/Action", + "Misc.", "Boss", + "Door", "Chest", }; using namespace UIWidgets; @@ -76,7 +70,8 @@ const std::string GetActorDescription(u16 id) { template void DrawGroupWithBorder(T&& drawFunc, std::string section) { // First group encapsulates the inner portion and border ImGui::BeginChild(std::string("##" + section).c_str(), ImVec2(0, 0), - ImGuiChildFlags_AlwaysAutoResize | ImGuiChildFlags_Borders | ImGuiChildFlags_AutoResizeX | ImGuiChildFlags_AutoResizeY); + ImGuiChildFlags_AlwaysAutoResize | ImGuiChildFlags_Borders | ImGuiChildFlags_AutoResizeX | + ImGuiChildFlags_AutoResizeY); // Second group encapsulates just the inner portion ImGui::BeginGroup(); @@ -103,7 +98,7 @@ void PopulateActorDropdown(int i, std::vector& data) { } } -//actors that don't use params at all +// actors that don't use params at all static std::vector noParamsActors = { ACTOR_ARMS_HOOK, ACTOR_ARROW_FIRE, @@ -250,7 +245,7 @@ void CreateActorSpecificData() { if (!isFlower) { ImGui::InputScalar("Shots Per Round", ImGuiDataType_S16, &shotsPerRound); } - + return isFlower ? DEKUNUTS_FLOWER : (shotsPerRound << 8); }; @@ -259,12 +254,12 @@ void CreateActorSpecificData() { if (params == 0) { params = -2; } - //the + 2 is because the params are -2 & -1 instead of 0 & 1 + // the + 2 is because the params are -2 & -1 instead of 0 & 1 int selectedItem = params + 2; if (ImGui::Combo("Type", &selectedItem, items, IM_ARRAYSIZE(items))) { return selectedItem - 2; } - + return params; }; @@ -274,7 +269,7 @@ void CreateActorSpecificData() { if (ImGui::Combo("Type", &selectedItem, items, IM_ARRAYSIZE(items))) { return selectedItem; } - + return params; }; @@ -284,7 +279,7 @@ void CreateActorSpecificData() { if (ImGui::Combo("Type", &selectedItem, items, IM_ARRAYSIZE(items))) { return selectedItem; } - + return params; }; @@ -294,7 +289,7 @@ void CreateActorSpecificData() { if (ImGui::Combo("Type", &selectedItem, items, IM_ARRAYSIZE(items))) { return selectedItem; } - + return params; }; @@ -304,7 +299,7 @@ void CreateActorSpecificData() { if (ImGui::Combo("Type", &selectedItem, items, IM_ARRAYSIZE(items))) { return selectedItem; } - + return params; }; @@ -314,7 +309,7 @@ void CreateActorSpecificData() { if (ImGui::Combo("Type", &selectedItem, items, IM_ARRAYSIZE(items))) { return selectedItem; } - + return params; }; @@ -324,7 +319,7 @@ void CreateActorSpecificData() { if (ImGui::Combo("Type", &selectedItem, items, IM_ARRAYSIZE(items))) { return selectedItem; } - + return params; }; @@ -333,12 +328,12 @@ void CreateActorSpecificData() { if (params == 0) { params = 0x40; } - //the - 0x40 is because the params are 0x40 & 0x41 instead of 0 & 1 + // the - 0x40 is because the params are 0x40 & 0x41 instead of 0 & 1 int selectedItem = params - 0x40; if (ImGui::Combo("Type", &selectedItem, items, IM_ARRAYSIZE(items))) { return selectedItem + 0x40; } - + return params; }; @@ -348,21 +343,21 @@ void CreateActorSpecificData() { if (ImGui::Combo("Type", &selectedItem, items, IM_ARRAYSIZE(items))) { return selectedItem; } - + return params; }; actorSpecificData[ACTOR_EN_REEBA] = [](s16 params) -> s16 { bool isBig = params != 0; ImGui::Checkbox("Big", &isBig); - + return isBig; }; actorSpecificData[ACTOR_EN_TK] = [](s16 params) -> s16 { bool canTurn = params >= 0; ImGui::Checkbox("Can Turn", &canTurn); - + return canTurn ? 0 : -1; }; @@ -374,35 +369,13 @@ void CreateActorSpecificData() { if (collectibleFlag > 0x3F) { collectibleFlag = 0x3F; } - + static const char* items[] = { - "Green Rupee", - "Blue Rupee", - "Red Rupee", - "Recovery Heart", - "Bombs (A)", - "Arrow", - "Heart Piece", - "Heart Container", - "Arrows (5)", - "Arrows (10)", - "Arrows (30)", - "Bombs (B)", - "Deku Nuts (5)", - "Deku Stick", - "Magic (Large)", - "Magic (Small)", - "Deku Seeds (5)", - "Small Key", - "Flexible", - "Gold Rupee", - "Purple Rupee", - "Deku Shield", - "Hylian Shield", - "Zora Tunic", - "Goron Tunic", - "Bombs (Special)", - "Bombchus", + "Green Rupee", "Blue Rupee", "Red Rupee", "Recovery Heart", "Bombs (A)", "Arrow", + "Heart Piece", "Heart Container", "Arrows (5)", "Arrows (10)", "Arrows (30)", "Bombs (B)", + "Deku Nuts (5)", "Deku Stick", "Magic (Large)", "Magic (Small)", "Deku Seeds (5)", "Small Key", + "Flexible", "Gold Rupee", "Purple Rupee", "Deku Shield", "Hylian Shield", "Zora Tunic", + "Goron Tunic", "Bombs (Special)", "Bombchus", }; int selectedItem = params & 0xFF; @@ -413,33 +386,11 @@ void CreateActorSpecificData() { actorSpecificData[ACTOR_OBJ_COMB] = [](s16 params) -> s16 { static const char* items[] = { - "Green Rupee", - "Blue Rupee", - "Red Rupee", - "Recovery Heart", - "Bombs (A)", - "Arrow", - "Heart Piece", - "Heart Container", - "Arrows (5)", - "Arrows (10)", - "Arrows (30)", - "Bombs (B)", - "Deku Nuts (5)", - "Deku Stick", - "Magic (Large)", - "Magic (Small)", - "Deku Seeds (5)", - "Small Key", - "Flexible", - "Gold Rupee", - "Purple Rupee", - "Deku Shield", - "Hylian Shield", - "Zora Tunic", - "Goron Tunic", - "Bombs (Special)", - "Bombchus", + "Green Rupee", "Blue Rupee", "Red Rupee", "Recovery Heart", "Bombs (A)", "Arrow", + "Heart Piece", "Heart Container", "Arrows (5)", "Arrows (10)", "Arrows (30)", "Bombs (B)", + "Deku Nuts (5)", "Deku Stick", "Magic (Large)", "Magic (Small)", "Deku Seeds (5)", "Small Key", + "Flexible", "Gold Rupee", "Purple Rupee", "Deku Shield", "Hylian Shield", "Zora Tunic", + "Goron Tunic", "Bombs (Special)", "Bombchus", }; int selectedItem = params & 0xFF; @@ -452,18 +403,18 @@ void CreateActorSpecificData() { collectibleFlag = 0x3F; } } - + return (collectibleFlag << 8) + selectedItem; }; actorSpecificData[ACTOR_EN_GM] = [](s16 params) -> s16 { u8 switchFlag = (params & 0x3F00) >> 8; - + ImGui::InputScalar("Switch Flag", ImGuiDataType_U8, &switchFlag); if (switchFlag > 0x3F) { switchFlag = 0x3F; } - + return switchFlag << 8; }; @@ -525,7 +476,7 @@ void CreateActorSpecificData() { if (ImGui::Combo("Type", &selectedItem, items, IM_ARRAYSIZE(items))) { return selectedItem; } - + return params; }; @@ -543,7 +494,7 @@ void CreateActorSpecificData() { if (ImGui::Combo("Type", &selectedItem, items, IM_ARRAYSIZE(items))) { return selectedItem > 3 ? selectedItem + 1 : selectedItem; } - + return params; }; @@ -574,113 +525,102 @@ void CreateActorSpecificData() { if (ImGui::Combo("Type", &selectedItem, items, IM_ARRAYSIZE(items))) { return selectedItem; } - + return params; }; actorSpecificData[ACTOR_EN_ELF] = [](s16 params) -> s16 { static const char* items[] = { - "Navi", - "Revive Bottle", - "Heal Timed", - "Kokiri", - "Spawner", - "Revive Death", - "Heal", - "Heal Big", + "Navi", "Revive Bottle", "Heal Timed", "Kokiri", "Spawner", "Revive Death", "Heal", "Heal Big", }; int selectedItem = params; if (ImGui::Combo("Type", &selectedItem, items, IM_ARRAYSIZE(items))) { return selectedItem; } - + return params; }; actorSpecificData[ACTOR_EN_CLEAR_TAG] = [](s16 params) -> s16 { static const char* items[] = { - "Cutscene", //0 - "Normal", //1 - "Laser", //100 + "Cutscene", // 0 + "Normal", // 1 + "Laser", // 100 }; int selectedItem = params == 100 ? 2 : params; if (ImGui::Combo("Type", &selectedItem, items, IM_ARRAYSIZE(items))) { return selectedItem == 2 ? 100 : selectedItem; } - + return params; }; actorSpecificData[ACTOR_EN_BOMBF] = [](s16 params) -> s16 { static const char* items[] = { "Flower", "Body", "Explosion" }; - //the + 1 is because the params are -1, 0 & 1 instead of 0, 1 & 2 + // the + 1 is because the params are -1, 0 & 1 instead of 0, 1 & 2 int selectedItem = params + 1; if (ImGui::Combo("Type", &selectedItem, items, IM_ARRAYSIZE(items))) { return selectedItem - 1; } - + return params; }; actorSpecificData[ACTOR_EN_BOM] = [](s16 params) -> s16 { static const char* items[] = { "Body", "Explosion" }; - + int selectedItem = params; if (ImGui::Combo("Type", &selectedItem, items, IM_ARRAYSIZE(items))) { return selectedItem; } - + return params; }; actorSpecificData[ACTOR_DOOR_WARP1] = [](s16 params) -> s16 { static const char* items[] = { - "Blue Crystal", // -2 - "Dungeon Adult", - "Dungeon Child", - "Clear Flag", // Activate on temp clear flag - "Sages", // Used by sages warping into chamber of sages during their cutscene + "Blue Crystal", // -2 + "Dungeon Adult", "Dungeon Child", + "Clear Flag", // Activate on temp clear flag + "Sages", // Used by sages warping into chamber of sages during their cutscene "Purple Crystal", - "Yellow", // The colored variants don't warp, they are cutscene setpieces + "Yellow", // The colored variants don't warp, they are cutscene setpieces "Blue Ruto", - "Destination", // Spawning in after having taken a warp - "UNK 7", - "Orange", - "Green", - "Red", + "Destination", // Spawning in after having taken a warp + "UNK 7", "Orange", "Green", "Red", }; int selectedItem = params + 2; if (ImGui::Combo("Type", &selectedItem, items, IM_ARRAYSIZE(items))) { return selectedItem - 2; } - + return params; }; actorSpecificData[ACTOR_EN_DY_EXTRA] = [](s16 params) -> s16 { static const char* items[] = { "Orange", "Green" }; - + int selectedItem = params; if (ImGui::Combo("Color", &selectedItem, items, IM_ARRAYSIZE(items))) { return selectedItem; } - + return params; }; actorSpecificData[ACTOR_EN_SKB] = [](s16 params) -> s16 { u8 size = params; ImGui::InputScalar("Size", ImGuiDataType_U8, &size); - + return size; }; actorSpecificData[ACTOR_EN_WF] = [](s16 params) -> s16 { static const char* items[] = { "Normal", "White" }; - + int selectedItem = params; ImGui::Combo("Type", &selectedItem, items, IM_ARRAYSIZE(items)); - + u8 switchFlag = (params & 0x3F00) >> 8; ImGui::InputScalar("Switch Flag", ImGuiDataType_U8, &switchFlag); return (switchFlag << 8) + selectedItem; @@ -703,7 +643,7 @@ void CreateActorSpecificData() { if (itemId > 0x7F) { itemId = 0x7F; } - + static const char* items[] = { "Big (Default)", "Room Clear Big", @@ -751,7 +691,7 @@ void CreateActorSpecificData() { if (transitionIndex > 0x3F) { transitionIndex = 0x3F; } - + static const char* items[] = { "Room Load", // loads rooms "Locked", // small key locked door @@ -792,9 +732,9 @@ void CreateActorSpecificData() { actorSpecificData[ACTOR_EN_PO_DESERT] = [](s16 params) -> s16 { u8 switchFlag = params >> 8; - + ImGui::InputScalar("Path", ImGuiDataType_U8, &switchFlag); - + return switchFlag << 8; }; @@ -807,30 +747,26 @@ void CreateActorSpecificData() { if (ImGui::Checkbox("Fishing Sign", &fishingSign)) { piece = false; } - + u8 textId = params; if (!piece && !fishingSign) { if (ImGui::InputScalar("Text ID", ImGuiDataType_U8, &textId)) { textId |= 0x300; } } - + return piece ? (s16)0xFFDD : (fishingSign ? 0x300 : textId); }; actorSpecificData[ACTOR_EN_KUSA] = [](s16 params) -> s16 { - static const char* items[] = { - "0", - "1", - "2" - }; + static const char* items[] = { "0", "1", "2" }; int type = params & 3; ImGui::Combo("Type", &type, items, IM_ARRAYSIZE(items)); bool bugs = ((params >> 4) & 1) != 0; ImGui::Checkbox("Bugs", &bugs); - + u8 drop = (params >> 8) & 0xF; if (type == 2) { ImGui::InputScalar("Random Drop Params", ImGuiDataType_U8, &drop); @@ -845,17 +781,12 @@ void CreateActorSpecificData() { }; actorSpecificData[ActorDB::Instance->RetrieveId("En_Partner")] = [](s16 params) -> s16 { - static const char* items[] = { - "Port 1", - "Port 2", - "Port 3", - "Port 4" - }; + static const char* items[] = { "Port 1", "Port 2", "Port 3", "Port 4" }; int selectedItem = params; if (ImGui::Combo("Controller Port", &selectedItem, items, IM_ARRAYSIZE(items))) { return selectedItem; } - + return params; }; } @@ -921,7 +852,7 @@ void ActorViewerWindow::DrawElement() { static Actor* display; static Actor empty{}; static Actor* fetch = NULL; - static ActorInfo newActor = {0,0, {0, 0, 0}, {0, 0, 0}}; + static ActorInfo newActor = { 0, 0, { 0, 0, 0 }, { 0, 0, 0 } }; static bool needs_reset = false; static ImU16 one = 1; static int actor; @@ -948,7 +879,7 @@ void ActorViewerWindow::DrawElement() { actors.clear(); } lastSceneId = gPlayState->sceneNum; - + PushStyleCombobox(THEME_COLOR); if (ImGui::BeginCombo("Actor Type", acMapping[category])) { for (int i = 0; i < acMapping.size(); i++) { @@ -986,37 +917,43 @@ void ActorViewerWindow::DrawElement() { PushStyleHeader(THEME_COLOR); if (ImGui::TreeNode("Selected Actor")) { - DrawGroupWithBorder([&]() { - ImGui::Text("Name: %s", ActorDB::Instance->RetrieveEntry(display->id).name.c_str()); - ImGui::Text("Description: %s", GetActorDescription(display->id).c_str()); - ImGui::Text("Category: %s", acMapping[display->category]); - ImGui::Text("ID: %d", display->id); - ImGui::Text("Parameters: %d", display->params); - }, "Selected Actor"); + DrawGroupWithBorder( + [&]() { + ImGui::Text("Name: %s", ActorDB::Instance->RetrieveEntry(display->id).name.c_str()); + ImGui::Text("Description: %s", GetActorDescription(display->id).c_str()); + ImGui::Text("Category: %s", acMapping[display->category]); + ImGui::Text("ID: %d", display->id); + ImGui::Text("Parameters: %d", display->params); + }, + "Selected Actor"); ImGui::SameLine(); ImGui::PushItemWidth(ImGui::GetFontSize() * 6); - DrawGroupWithBorder([&]() { - ImGui::PushItemWidth(ImGui::GetFontSize() * 6); - PushStyleInput(THEME_COLOR); - ImGui::Text("Actor Position"); - ImGui::InputScalar("X##CurPos", ImGuiDataType_Float, &display->world.pos.x); - ImGui::InputScalar("Y##CurPos", ImGuiDataType_Float, &display->world.pos.y); - ImGui::InputScalar("Z##CurPos", ImGuiDataType_Float, &display->world.pos.z); - ImGui::PopItemWidth(); - PopStyleInput(); - }, "Actor Position"); + DrawGroupWithBorder( + [&]() { + ImGui::PushItemWidth(ImGui::GetFontSize() * 6); + PushStyleInput(THEME_COLOR); + ImGui::Text("Actor Position"); + ImGui::InputScalar("X##CurPos", ImGuiDataType_Float, &display->world.pos.x); + ImGui::InputScalar("Y##CurPos", ImGuiDataType_Float, &display->world.pos.y); + ImGui::InputScalar("Z##CurPos", ImGuiDataType_Float, &display->world.pos.z); + ImGui::PopItemWidth(); + PopStyleInput(); + }, + "Actor Position"); ImGui::SameLine(); - DrawGroupWithBorder([&]() { - PushStyleInput(THEME_COLOR); - ImGui::PushItemWidth(ImGui::GetFontSize() * 6); - ImGui::Text("Actor Rotation"); - ImGui::InputScalar("X##CurRot", ImGuiDataType_S16, &display->world.rot.x); - ImGui::InputScalar("Y##CurRot", ImGuiDataType_S16, &display->world.rot.y); - ImGui::InputScalar("Z##CurRot", ImGuiDataType_S16, &display->world.rot.z); - ImGui::PopItemWidth(); - PopStyleInput(); - }, "Actor Rotation"); + DrawGroupWithBorder( + [&]() { + PushStyleInput(THEME_COLOR); + ImGui::PushItemWidth(ImGui::GetFontSize() * 6); + ImGui::Text("Actor Rotation"); + ImGui::InputScalar("X##CurRot", ImGuiDataType_S16, &display->world.rot.x); + ImGui::InputScalar("Y##CurRot", ImGuiDataType_S16, &display->world.rot.y); + ImGui::InputScalar("Z##CurRot", ImGuiDataType_S16, &display->world.rot.z); + ImGui::PopItemWidth(); + PopStyleInput(); + }, + "Actor Rotation"); if (display->category == ACTORCAT_BOSS || display->category == ACTORCAT_ENEMY) { PushStyleInput(THEME_COLOR); @@ -1025,17 +962,21 @@ void ActorViewerWindow::DrawElement() { UIWidgets::InsertHelpHoverText("Some actors might not use this!"); } - DrawGroupWithBorder([&]() { - ImGui::Text("flags"); - UIWidgets::DrawFlagArray32("flags", display->flags); - }, "flags"); + DrawGroupWithBorder( + [&]() { + ImGui::Text("flags"); + UIWidgets::DrawFlagArray32("flags", display->flags); + }, + "flags"); ImGui::SameLine(); - DrawGroupWithBorder([&]() { - ImGui::Text("bgCheckFlags"); - UIWidgets::DrawFlagArray16("bgCheckFlags", display->bgCheckFlags); - }, "bgCheckFlags"); + DrawGroupWithBorder( + [&]() { + ImGui::Text("bgCheckFlags"); + UIWidgets::DrawFlagArray16("bgCheckFlags", display->bgCheckFlags); + }, + "bgCheckFlags"); if (Button("Refresh", ButtonOptions().Color(THEME_COLOR))) { PopulateActorDropdown(category, list); @@ -1059,7 +1000,10 @@ void ActorViewerWindow::DrawElement() { Math_Vec3f_Copy(&player->actor.home.pos, &player->actor.world.pos); } - if (Button("Fetch from Target", ButtonOptions().Color(THEME_COLOR).Tooltip("Grabs actor with target arrow above it. You might need C-Up for enemies"))) { + if (Button("Fetch from Target", + ButtonOptions() + .Color(THEME_COLOR) + .Tooltip("Grabs actor with target arrow above it. You might need C-Up for enemies"))) { Player* player = GET_PLAYER(gPlayState); fetch = player->talkActor; if (fetch != NULL) { @@ -1069,7 +1013,8 @@ void ActorViewerWindow::DrawElement() { rm = TARGET; } } - if (Button("Fetch from Held", ButtonOptions().Color(THEME_COLOR).Tooltip("Grabs actor that Link is holding"))) { + if (Button("Fetch from Held", + ButtonOptions().Color(THEME_COLOR).Tooltip("Grabs actor that Link is holding"))) { Player* player = GET_PLAYER(gPlayState); fetch = player->heldActor; if (fetch != NULL) { @@ -1079,7 +1024,8 @@ void ActorViewerWindow::DrawElement() { rm = HELD; } } - if (Button("Fetch from Interaction", ButtonOptions().Color(THEME_COLOR).Tooltip("Grabs actor from \"interaction range\""))) { + if (Button("Fetch from Interaction", + ButtonOptions().Color(THEME_COLOR).Tooltip("Grabs actor from \"interaction range\""))) { Player* player = GET_PLAYER(gPlayState); fetch = player->interactRangeActor; if (fetch != NULL) { @@ -1094,7 +1040,7 @@ void ActorViewerWindow::DrawElement() { } if (ImGui::TreeNode("New...")) { - //ImGui::PushItemWidth(ImGui::GetFontSize() * 10); + // ImGui::PushItemWidth(ImGui::GetFontSize() * 10); if (InputString("Search Actor", &searchString, InputOptions().Color(THEME_COLOR))) { actors = GetActorsWithDescriptionContainingString(searchString); @@ -1102,14 +1048,14 @@ void ActorViewerWindow::DrawElement() { } if (!SohUtils::IsStringEmpty(searchString) && !actors.empty()) { - std::string preview = currentSelectedInDropdown == -1 ? "Please Select" : ActorDB::Instance->RetrieveEntry(actors[currentSelectedInDropdown]).desc; + std::string preview = currentSelectedInDropdown == -1 + ? "Please Select" + : ActorDB::Instance->RetrieveEntry(actors[currentSelectedInDropdown]).desc; PushStyleCombobox(THEME_COLOR); if (ImGui::BeginCombo("Results", preview.c_str())) { for (u8 i = 0; i < actors.size(); i++) { - if (ImGui::Selectable( - ActorDB::Instance->RetrieveEntry(actors[i]).desc.c_str(), - i == currentSelectedInDropdown - )) { + if (ImGui::Selectable(ActorDB::Instance->RetrieveEntry(actors[i]).desc.c_str(), + i == currentSelectedInDropdown)) { currentSelectedInDropdown = i; newActor.id = actors[i]; } @@ -1124,7 +1070,8 @@ void ActorViewerWindow::DrawElement() { newActor.params = 0; } - CVarCheckbox("Advanced mode", CVAR_DEVELOPER_TOOLS("ActorViewer.AdvancedParams"), CheckboxOptions().Tooltip("Changes the actor specific param menus with a direct input")); + CVarCheckbox("Advanced mode", CVAR_DEVELOPER_TOOLS("ActorViewer.AdvancedParams"), + CheckboxOptions().Tooltip("Changes the actor specific param menus with a direct input")); if (CVarGetInteger(CVAR_DEVELOPER_TOOLS("ActorViewer.AdvancedParams"), 0)) { PushStyleInput(THEME_COLOR); @@ -1137,36 +1084,42 @@ void ActorViewerWindow::DrawElement() { ImGui::InputScalar("params", ImGuiDataType_S16, &newActor.params, &one); PopStyleInput(); } else { - DrawGroupWithBorder([&]() { - ImGui::Text("Actor Specific Data"); - newActor.params = actorSpecificData[newActor.id](newActor.params); - }, "Actor Specific Data"); + DrawGroupWithBorder( + [&]() { + ImGui::Text("Actor Specific Data"); + newActor.params = actorSpecificData[newActor.id](newActor.params); + }, + "Actor Specific Data"); } } ImGui::PushItemWidth(ImGui::GetFontSize() * 6); - DrawGroupWithBorder([&]() { - PushStyleInput(THEME_COLOR); - ImGui::Text("New Actor Position"); - ImGui::PushItemWidth(ImGui::GetFontSize() * 6); - ImGui::InputScalar("X##NewPos", ImGuiDataType_Float, &newActor.pos.x); - ImGui::InputScalar("Y##NewPos", ImGuiDataType_Float, &newActor.pos.y); - ImGui::InputScalar("Z##NewPos", ImGuiDataType_Float, &newActor.pos.z); - ImGui::PopItemWidth(); - PopStyleInput(); - }, "New Actor Position"); + DrawGroupWithBorder( + [&]() { + PushStyleInput(THEME_COLOR); + ImGui::Text("New Actor Position"); + ImGui::PushItemWidth(ImGui::GetFontSize() * 6); + ImGui::InputScalar("X##NewPos", ImGuiDataType_Float, &newActor.pos.x); + ImGui::InputScalar("Y##NewPos", ImGuiDataType_Float, &newActor.pos.y); + ImGui::InputScalar("Z##NewPos", ImGuiDataType_Float, &newActor.pos.z); + ImGui::PopItemWidth(); + PopStyleInput(); + }, + "New Actor Position"); ImGui::SameLine(); - DrawGroupWithBorder([&]() { - PushStyleInput(THEME_COLOR); - ImGui::Text("New Actor Rotation"); - ImGui::PushItemWidth(ImGui::GetFontSize() * 6); - ImGui::InputScalar("X##NewRot", ImGuiDataType_S16, &newActor.rot.x); - ImGui::InputScalar("Y##NewRot", ImGuiDataType_S16, &newActor.rot.y); - ImGui::InputScalar("Z##NewRot", ImGuiDataType_S16, &newActor.rot.z); - ImGui::PopItemWidth(); - PopStyleInput(); - }, "New Actor Rotation"); + DrawGroupWithBorder( + [&]() { + PushStyleInput(THEME_COLOR); + ImGui::Text("New Actor Rotation"); + ImGui::PushItemWidth(ImGui::GetFontSize() * 6); + ImGui::InputScalar("X##NewRot", ImGuiDataType_S16, &newActor.rot.x); + ImGui::InputScalar("Y##NewRot", ImGuiDataType_S16, &newActor.rot.y); + ImGui::InputScalar("Z##NewRot", ImGuiDataType_S16, &newActor.rot.z); + ImGui::PopItemWidth(); + PopStyleInput(); + }, + "New Actor Rotation"); if (Button("Fetch from Link", ButtonOptions().Color(THEME_COLOR))) { Player* player = GET_PLAYER(gPlayState); @@ -1214,8 +1167,9 @@ void ActorViewerWindow::DrawElement() { { 3, "Both" }, }; - if (CVarCombobox("Actor Name Tags", CVAR_DEVELOPER_TOOLS("ActorViewer.NameTags"), nameTagOptions, - ComboboxOptions().Color(THEME_COLOR).Tooltip("Adds \"name tags\" above actors for identification"))) { + if (CVarCombobox( + "Actor Name Tags", CVAR_DEVELOPER_TOOLS("ActorViewer.NameTags"), nameTagOptions, + ComboboxOptions().Color(THEME_COLOR).Tooltip("Adds \"name tags\" above actors for identification"))) { NameTag_RemoveAllByTag(DEBUG_ACTOR_NAMETAG_TAG); ActorViewer_AddTagForAllActors(); } diff --git a/soh/soh/Enhancements/debugger/actorViewer.h b/soh/soh/Enhancements/debugger/actorViewer.h index 2f4ca680a..bab7d1646 100644 --- a/soh/soh/Enhancements/debugger/actorViewer.h +++ b/soh/soh/Enhancements/debugger/actorViewer.h @@ -8,5 +8,5 @@ class ActorViewerWindow : public Ship::GuiWindow { void DrawElement() override; void InitElement() override; - void UpdateElement() override {}; + void UpdateElement() override{}; }; diff --git a/soh/soh/Enhancements/debugger/colViewer.cpp b/soh/soh/Enhancements/debugger/colViewer.cpp index de2272598..e3abba484 100644 --- a/soh/soh/Enhancements/debugger/colViewer.cpp +++ b/soh/soh/Enhancements/debugger/colViewer.cpp @@ -20,7 +20,7 @@ extern "C" { extern PlayState* gPlayState; } -typedef enum ColRenderSetting { ColRenderDisabled, ColRenderSolid, ColRenderTransparent } ColRenderSetting ; +typedef enum ColRenderSetting { ColRenderDisabled, ColRenderSolid, ColRenderTransparent } ColRenderSetting; static std::unordered_map ColRenderSettingNames = { { ColRenderDisabled, "Disabled" }, @@ -68,9 +68,11 @@ void ColViewerWindow::DrawElement() { CVarCombobox("Waterbox", CVAR_DEVELOPER_TOOLS("ColViewer.Waterbox"), ColRenderSettingNames, comboOpt); CVarCheckbox("Apply as decal", CVAR_DEVELOPER_TOOLS("ColViewer.Decal"), - checkOpt.DefaultValue(true).Tooltip("Applies the collision as a decal display. This can be useful if there is z-fighting occuring " - "with the scene geometry, but can cause other artifacts.")); - CVarCheckbox("Shaded", CVAR_DEVELOPER_TOOLS("ColViewer.Shaded"), checkOpt.DefaultValue(false).Tooltip("Applies the scene's shading to the collision display.")); + checkOpt.DefaultValue(true).Tooltip( + "Applies the collision as a decal display. This can be useful if there is z-fighting occuring " + "with the scene geometry, but can cause other artifacts.")); + CVarCheckbox("Shaded", CVAR_DEVELOPER_TOOLS("ColViewer.Shaded"), + checkOpt.DefaultValue(false).Tooltip("Applies the scene's shading to the collision display.")); // This has to be duplicated in both code paths due to the nature of ImGui::IsItemHovered() const std::string colorHelpText = "View and change the colors used for collision display."; @@ -78,38 +80,58 @@ void ColViewerWindow::DrawElement() { if (ImGui::TreeNode("Colors")) { UIWidgets::Tooltip(colorHelpText.c_str()); - if (CVarColorPicker("Normal", CVAR_DEVELOPER_TOOLS("ColViewer.ColorNormal"), { 255, 255, 255, 255 }, false, ColorPickerResetButton | ColorPickerRandomButton, THEME_COLOR)) { - scene_col = VecFromRGBA8(CVarGetColor(CVAR_DEVELOPER_TOOLS("ColViewer.ColorNormal"), { 255, 255, 255, 255 })); + if (CVarColorPicker("Normal", CVAR_DEVELOPER_TOOLS("ColViewer.ColorNormal"), { 255, 255, 255, 255 }, false, + ColorPickerResetButton | ColorPickerRandomButton, THEME_COLOR)) { + scene_col = + VecFromRGBA8(CVarGetColor(CVAR_DEVELOPER_TOOLS("ColViewer.ColorNormal"), { 255, 255, 255, 255 })); } - if (CVarColorPicker("Hookshot", CVAR_DEVELOPER_TOOLS("ColViewer.ColorHookshot"), { 128, 128, 255, 255 }, false, ColorPickerResetButton | ColorPickerRandomButton, THEME_COLOR)) { - hookshot_col = VecFromRGBA8(CVarGetColor(CVAR_DEVELOPER_TOOLS("ColViewer.ColorHookshot"), { 128, 128, 255, 255 })); + if (CVarColorPicker("Hookshot", CVAR_DEVELOPER_TOOLS("ColViewer.ColorHookshot"), { 128, 128, 255, 255 }, false, + ColorPickerResetButton | ColorPickerRandomButton, THEME_COLOR)) { + hookshot_col = + VecFromRGBA8(CVarGetColor(CVAR_DEVELOPER_TOOLS("ColViewer.ColorHookshot"), { 128, 128, 255, 255 })); } - if (CVarColorPicker("Entrance", CVAR_DEVELOPER_TOOLS("ColViewer.ColorEntrance"), { 0, 255, 0, 255 }, false, ColorPickerResetButton | ColorPickerRandomButton, THEME_COLOR)) { - entrance_col = VecFromRGBA8(CVarGetColor(CVAR_DEVELOPER_TOOLS("ColViewer.ColorEntrance"), { 0, 255, 0, 255 })); + if (CVarColorPicker("Entrance", CVAR_DEVELOPER_TOOLS("ColViewer.ColorEntrance"), { 0, 255, 0, 255 }, false, + ColorPickerResetButton | ColorPickerRandomButton, THEME_COLOR)) { + entrance_col = + VecFromRGBA8(CVarGetColor(CVAR_DEVELOPER_TOOLS("ColViewer.ColorEntrance"), { 0, 255, 0, 255 })); } - if (CVarColorPicker("Special Surface (Grass/Sand/Etc)", CVAR_DEVELOPER_TOOLS("ColViewer.ColorSpecialSurface"), { 192, 255, 192, 255 }, false, ColorPickerResetButton | ColorPickerRandomButton, THEME_COLOR)) { - specialSurface_col = VecFromRGBA8(CVarGetColor(CVAR_DEVELOPER_TOOLS("ColViewer.ColorSpecialSurface"), { 192, 255, 192, 255 })); + if (CVarColorPicker("Special Surface (Grass/Sand/Etc)", CVAR_DEVELOPER_TOOLS("ColViewer.ColorSpecialSurface"), + { 192, 255, 192, 255 }, false, ColorPickerResetButton | ColorPickerRandomButton, + THEME_COLOR)) { + specialSurface_col = VecFromRGBA8( + CVarGetColor(CVAR_DEVELOPER_TOOLS("ColViewer.ColorSpecialSurface"), { 192, 255, 192, 255 })); } - if (CVarColorPicker("Interactable (Vines/Crawlspace/Etc)", CVAR_DEVELOPER_TOOLS("ColViewer.ColorInteractable"), { 192, 0, 192, 255 }, false, ColorPickerResetButton | ColorPickerRandomButton, THEME_COLOR)) { - interactable_col = VecFromRGBA8(CVarGetColor(CVAR_DEVELOPER_TOOLS("ColViewer.ColorInteractable"), { 192, 0, 192, 255 })); + if (CVarColorPicker("Interactable (Vines/Crawlspace/Etc)", CVAR_DEVELOPER_TOOLS("ColViewer.ColorInteractable"), + { 192, 0, 192, 255 }, false, ColorPickerResetButton | ColorPickerRandomButton, + THEME_COLOR)) { + interactable_col = + VecFromRGBA8(CVarGetColor(CVAR_DEVELOPER_TOOLS("ColViewer.ColorInteractable"), { 192, 0, 192, 255 })); } - if (CVarColorPicker("Slope", CVAR_DEVELOPER_TOOLS("ColViewer.ColorSlope"), { 255, 255, 128, 255 }, false, ColorPickerResetButton | ColorPickerRandomButton, THEME_COLOR)) { - slope_col = VecFromRGBA8(CVarGetColor(CVAR_DEVELOPER_TOOLS("ColViewer.ColorSlope"), { 255, 255, 128, 255 })); + if (CVarColorPicker("Slope", CVAR_DEVELOPER_TOOLS("ColViewer.ColorSlope"), { 255, 255, 128, 255 }, false, + ColorPickerResetButton | ColorPickerRandomButton, THEME_COLOR)) { + slope_col = + VecFromRGBA8(CVarGetColor(CVAR_DEVELOPER_TOOLS("ColViewer.ColorSlope"), { 255, 255, 128, 255 })); } - if (CVarColorPicker("Void", CVAR_DEVELOPER_TOOLS("ColViewer.ColorVoid"), { 255, 0, 0, 255 }, false, ColorPickerResetButton | ColorPickerRandomButton, THEME_COLOR)) { + if (CVarColorPicker("Void", CVAR_DEVELOPER_TOOLS("ColViewer.ColorVoid"), { 255, 0, 0, 255 }, false, + ColorPickerResetButton | ColorPickerRandomButton, THEME_COLOR)) { void_col = VecFromRGBA8(CVarGetColor(CVAR_DEVELOPER_TOOLS("ColViewer.ColorVoid"), { 255, 0, 0, 255 })); } - if (CVarColorPicker("OC", CVAR_DEVELOPER_TOOLS("ColViewer.ColorOC"), { 255, 255, 255, 255 }, false, ColorPickerResetButton | ColorPickerRandomButton, THEME_COLOR)) { + if (CVarColorPicker("OC", CVAR_DEVELOPER_TOOLS("ColViewer.ColorOC"), { 255, 255, 255, 255 }, false, + ColorPickerResetButton | ColorPickerRandomButton, THEME_COLOR)) { oc_col = VecFromRGBA8(CVarGetColor(CVAR_DEVELOPER_TOOLS("ColViewer.ColorOC"), { 255, 255, 255, 255 })); } - if (CVarColorPicker("AC", CVAR_DEVELOPER_TOOLS("ColViewer.ColorAC"), { 0, 0, 255, 255 }, false, ColorPickerResetButton | ColorPickerRandomButton, THEME_COLOR)) { + if (CVarColorPicker("AC", CVAR_DEVELOPER_TOOLS("ColViewer.ColorAC"), { 0, 0, 255, 255 }, false, + ColorPickerResetButton | ColorPickerRandomButton, THEME_COLOR)) { ac_col = VecFromRGBA8(CVarGetColor(CVAR_DEVELOPER_TOOLS("ColViewer.ColorAC"), { 0, 0, 255, 255 })); } - if (CVarColorPicker("AT", CVAR_DEVELOPER_TOOLS("ColViewer.ColorAT"), { 255, 0, 0, 255 }, false, ColorPickerResetButton | ColorPickerRandomButton, THEME_COLOR)) { + if (CVarColorPicker("AT", CVAR_DEVELOPER_TOOLS("ColViewer.ColorAT"), { 255, 0, 0, 255 }, false, + ColorPickerResetButton | ColorPickerRandomButton, THEME_COLOR)) { at_col = VecFromRGBA8(CVarGetColor(CVAR_DEVELOPER_TOOLS("ColViewer.ColorAT"), { 255, 0, 0, 255 })); } - if (CVarColorPicker("Waterbox", CVAR_DEVELOPER_TOOLS("ColViewer.ColorWaterbox"), { 0, 0, 255, 255 }, false, ColorPickerResetButton | ColorPickerRandomButton, THEME_COLOR)) { - waterbox_col = VecFromRGBA8(CVarGetColor(CVAR_DEVELOPER_TOOLS("ColViewer.ColorWaterbox"), { 0, 0, 255, 255 })); + if (CVarColorPicker("Waterbox", CVAR_DEVELOPER_TOOLS("ColViewer.ColorWaterbox"), { 0, 0, 255, 255 }, false, + ColorPickerResetButton | ColorPickerRandomButton, THEME_COLOR)) { + waterbox_col = + VecFromRGBA8(CVarGetColor(CVAR_DEVELOPER_TOOLS("ColViewer.ColorWaterbox"), { 0, 0, 255, 255 })); } ImGui::TreePop(); @@ -210,9 +232,9 @@ void CreateSphereFace(std::vector>& faces, in // Create 3 new verticies at the midpoints Vec3f vs[3] = { - Vec3f{(v0.n.ob[0] + v1.n.ob[0]) / 2.0f, (v0.n.ob[1] + v1.n.ob[1]) / 2.0f, (v0.n.ob[2] + v1.n.ob[2]) / 2.0f}, - Vec3f{(v1.n.ob[0] + v2.n.ob[0]) / 2.0f, (v1.n.ob[1] + v2.n.ob[1]) / 2.0f, (v1.n.ob[2] + v2.n.ob[2]) / 2.0f}, - Vec3f{(v2.n.ob[0] + v0.n.ob[0]) / 2.0f, (v2.n.ob[1] + v0.n.ob[1]) / 2.0f, (v2.n.ob[2] + v0.n.ob[2]) / 2.0f} + Vec3f{ (v0.n.ob[0] + v1.n.ob[0]) / 2.0f, (v0.n.ob[1] + v1.n.ob[1]) / 2.0f, (v0.n.ob[2] + v1.n.ob[2]) / 2.0f }, + Vec3f{ (v1.n.ob[0] + v2.n.ob[0]) / 2.0f, (v1.n.ob[1] + v2.n.ob[1]) / 2.0f, (v1.n.ob[2] + v2.n.ob[2]) / 2.0f }, + Vec3f{ (v2.n.ob[0] + v0.n.ob[0]) / 2.0f, (v2.n.ob[1] + v0.n.ob[1]) / 2.0f, (v2.n.ob[2] + v0.n.ob[2]) / 2.0f } }; // Normalize vertex positions so they are on the sphere @@ -237,20 +259,20 @@ void CreateSphereData() { float d = (1.0f + sqrtf(5.0f)) / 2.0f; // Create the 12 starting verticies, 4 on each rectangle - base.emplace_back(Vec3f({-1, d, 0})); - base.emplace_back(Vec3f({1, d, 0})); - base.emplace_back(Vec3f({-1, -d, 0})); - base.emplace_back(Vec3f({1, -d, 0})); + base.emplace_back(Vec3f({ -1, d, 0 })); + base.emplace_back(Vec3f({ 1, d, 0 })); + base.emplace_back(Vec3f({ -1, -d, 0 })); + base.emplace_back(Vec3f({ 1, -d, 0 })); - base.emplace_back(Vec3f({0, -1, d})); - base.emplace_back(Vec3f({0, 1, d})); - base.emplace_back(Vec3f({0, -1, -d})); - base.emplace_back(Vec3f({0, 1, -d})); + base.emplace_back(Vec3f({ 0, -1, d })); + base.emplace_back(Vec3f({ 0, 1, d })); + base.emplace_back(Vec3f({ 0, -1, -d })); + base.emplace_back(Vec3f({ 0, 1, -d })); - base.emplace_back(Vec3f({d, 0, -1})); - base.emplace_back(Vec3f({d, 0, 1})); - base.emplace_back(Vec3f({-d, 0, -1})); - base.emplace_back(Vec3f({-d, 0, 1})); + base.emplace_back(Vec3f({ d, 0, -1 })); + base.emplace_back(Vec3f({ d, 0, 1 })); + base.emplace_back(Vec3f({ -d, 0, -1 })); + base.emplace_back(Vec3f({ -d, 0, 1 })); // Normalize verticies so they are on the unit sphere for (Vec3f& v : base) { @@ -349,7 +371,7 @@ void InitGfx(std::vector& gfx, ColRenderSetting setting) { // Draws a dynapoly structure (scenes or Bg Actors) void DrawDynapoly(std::vector& dl, CollisionHeader* col, int32_t bgId) { - Color_RGBA8 color = {255, 255, 255, 255}; + Color_RGBA8 color = { 255, 255, 255, 255 }; uint32_t lastColorR = color.r; uint32_t lastColorG = color.g; @@ -367,7 +389,7 @@ void DrawDynapoly(std::vector& dl, CollisionHeader* col, int32_t bgId) { if (SurfaceType_IsHookshotSurface(&gPlayState->colCtx, poly, bgId)) { color = CVarGetColor(CVAR_DEVELOPER_TOOLS("ColViewer.ColorHookshot.Value"), { 128, 128, 255, 255 }); } else if (func_80041D94(&gPlayState->colCtx, poly, bgId) > 0x01) { - color = CVarGetColor(CVAR_DEVELOPER_TOOLS("ColViewer.ColorInteractable.Value"), {192, 0, 192, 255}); + color = CVarGetColor(CVAR_DEVELOPER_TOOLS("ColViewer.ColorInteractable.Value"), { 192, 0, 192, 255 }); } else if (func_80041E80(&gPlayState->colCtx, poly, bgId) == 0x0C) { color = CVarGetColor(CVAR_DEVELOPER_TOOLS("ColViewer.ColorVoid.Value"), { 255, 0, 0, 255 }); } else if (SurfaceType_GetSceneExitIndex(&gPlayState->colCtx, poly, bgId) || @@ -427,7 +449,8 @@ void DrawDynapoly(std::vector& dl, CollisionHeader* col, int32_t bgId) { // Draws the scene void DrawSceneCollision() { - ColRenderSetting showSceneColSetting = (ColRenderSetting)CVarGetInteger(CVAR_DEVELOPER_TOOLS("ColViewer.Scene"), COLVIEW_DISABLED); + ColRenderSetting showSceneColSetting = + (ColRenderSetting)CVarGetInteger(CVAR_DEVELOPER_TOOLS("ColViewer.Scene"), COLVIEW_DISABLED); if (showSceneColSetting == ColRenderDisabled || !CVarGetInteger(CVAR_DEVELOPER_TOOLS("ColViewer.Enabled"), 0)) { return; @@ -442,7 +465,8 @@ void DrawSceneCollision() { // Draws all Bg Actors void DrawBgActorCollision() { - ColRenderSetting showBgActorSetting = (ColRenderSetting)CVarGetInteger(CVAR_DEVELOPER_TOOLS("ColViewer.BGActors"), COLVIEW_DISABLED); + ColRenderSetting showBgActorSetting = + (ColRenderSetting)CVarGetInteger(CVAR_DEVELOPER_TOOLS("ColViewer.BGActors"), COLVIEW_DISABLED); if (showBgActorSetting == ColRenderDisabled || !CVarGetInteger(CVAR_DEVELOPER_TOOLS("ColViewer.Enabled"), 0)) { return; } @@ -567,7 +591,8 @@ void DrawColCheckList(std::vector& dl, Collider** objects, int32_t count) { // Draws all Col Check objects void DrawColCheckCollision() { - ColRenderSetting showColCheckSetting = (ColRenderSetting)CVarGetInteger(CVAR_DEVELOPER_TOOLS("ColViewer.ColCheck"), COLVIEW_DISABLED); + ColRenderSetting showColCheckSetting = + (ColRenderSetting)CVarGetInteger(CVAR_DEVELOPER_TOOLS("ColViewer.ColCheck"), COLVIEW_DISABLED); if (showColCheckSetting == ColRenderDisabled || !CVarGetInteger(CVAR_DEVELOPER_TOOLS("ColViewer.Enabled"), 0)) { return; } @@ -619,7 +644,8 @@ extern "C" f32 zdWaterBoxMinY; // Draws all waterboxes void DrawWaterboxList() { - ColRenderSetting showWaterboxSetting = (ColRenderSetting)CVarGetInteger(CVAR_DEVELOPER_TOOLS("ColViewer.Waterbox"), COLVIEW_DISABLED); + ColRenderSetting showWaterboxSetting = + (ColRenderSetting)CVarGetInteger(CVAR_DEVELOPER_TOOLS("ColViewer.Waterbox"), COLVIEW_DISABLED); if (showWaterboxSetting == ColRenderDisabled || !CVarGetInteger(CVAR_DEVELOPER_TOOLS("ColViewer.Enabled"), 0)) { return; } diff --git a/soh/soh/Enhancements/debugger/colViewer.h b/soh/soh/Enhancements/debugger/colViewer.h index b4807e873..eeaca7e43 100644 --- a/soh/soh/Enhancements/debugger/colViewer.h +++ b/soh/soh/Enhancements/debugger/colViewer.h @@ -2,11 +2,7 @@ #include -typedef enum { - COLVIEW_DISABLED, - COLVIEW_SOLID, - COLVIEW_TRANSPARENT -} ColViewerRenderSetting; +typedef enum { COLVIEW_DISABLED, COLVIEW_SOLID, COLVIEW_TRANSPARENT } ColViewerRenderSetting; #ifdef __cplusplus class ColViewerWindow : public Ship::GuiWindow { @@ -15,7 +11,7 @@ class ColViewerWindow : public Ship::GuiWindow { void InitElement() override; void DrawElement() override; - void UpdateElement() override {}; + void UpdateElement() override{}; }; #endif diff --git a/soh/soh/Enhancements/debugger/debugSaveEditor.cpp b/soh/soh/Enhancements/debugger/debugSaveEditor.cpp index 1d5d08bee..534201f8e 100644 --- a/soh/soh/Enhancements/debugger/debugSaveEditor.cpp +++ b/soh/soh/Enhancements/debugger/debugSaveEditor.cpp @@ -74,11 +74,11 @@ u8 gAllAmmoItems[] = { }; // Encapsulates what is drawn by the passed-in function within a border -template -void DrawGroupWithBorder(T&& drawFunc, std::string section) { +template void DrawGroupWithBorder(T&& drawFunc, std::string section) { // First group encapsulates the inner portion and border ImGui::BeginChild(std::string("##" + section).c_str(), ImVec2(0, 0), - ImGuiChildFlags_AlwaysAutoResize | ImGuiChildFlags_Borders | ImGuiChildFlags_AutoResizeX | ImGuiChildFlags_AutoResizeY); + ImGuiChildFlags_AlwaysAutoResize | ImGuiChildFlags_Borders | ImGuiChildFlags_AutoResizeX | + ImGuiChildFlags_AutoResizeY); ImGui::BeginGroup(); ImGui::AlignTextToFramePadding(); @@ -90,13 +90,13 @@ void DrawGroupWithBorder(T&& drawFunc, std::string section) { char z2ASCII(int code) { int ret; - if (code < 10) { //Digits + if (code < 10) { // Digits ret = code + 0x30; - } else if (code >= 10 && code < 36) { //Uppercase letters + } else if (code >= 10 && code < 36) { // Uppercase letters ret = code + 0x37; - } else if (code >= 36 && code < 62) { //Lowercase letters + } else if (code >= 36 && code < 62) { // Lowercase letters ret = code + 0x3D; - } else if (code == 62) { //Space + } else if (code == 62) { // Space ret = code - 0x1E; } else if (code == 63 || code == 64) { // _ and . ret = code - 0x12; @@ -104,17 +104,12 @@ char z2ASCII(int code) { ret = code; } return char(ret); - } -typedef enum MagicLevel { - MAGIC_LEVEL_NONE, - MAGIC_LEVEL_SINGLE, - MAGIC_LEVEL_DOUBLE -}; +typedef enum MagicLevel { MAGIC_LEVEL_NONE, MAGIC_LEVEL_SINGLE, MAGIC_LEVEL_DOUBLE }; std::unordered_map magicLevelMap = { - { MAGIC_LEVEL_NONE, "None" }, + { MAGIC_LEVEL_NONE, "None" }, { MAGIC_LEVEL_SINGLE, "Single" }, { MAGIC_LEVEL_DOUBLE, "Double" }, }; @@ -182,18 +177,22 @@ void DrawInfoTab() { gSaveContext.health = gSaveContext.healthCapacity; // Clamp health to new max } int32_t health = (int32_t)gSaveContext.health; - if (SliderInt("Health", &health, intSliderOptionsBase.Tooltip("Current health. 16 units per full heart") - .Min(0).Max(gSaveContext.healthCapacity))) { + if (SliderInt("Health", &health, + intSliderOptionsBase.Tooltip("Current health. 16 units per full heart") + .Min(0) + .Max(gSaveContext.healthCapacity))) { gSaveContext.health = (int16_t)health; } bool isDoubleDefenseAcquired = gSaveContext.isDoubleDefenseAcquired != 0; - if (Checkbox("Double Defense", &isDoubleDefenseAcquired, checkboxOptionsBase.Tooltip("Is double defense unlocked?"))) { + if (Checkbox("Double Defense", &isDoubleDefenseAcquired, + checkboxOptionsBase.Tooltip("Is double defense unlocked?"))) { gSaveContext.isDoubleDefenseAcquired = isDoubleDefenseAcquired; gSaveContext.inventory.defenseHearts = gSaveContext.isDoubleDefenseAcquired ? 20 : 0; // Set to get the border drawn in the UI } - if (Combobox("Magic Level", &gSaveContext.magicLevel, magicLevelMap, comboboxOptionsBase.Tooltip("Current magic level"))) { + if (Combobox("Magic Level", &gSaveContext.magicLevel, magicLevelMap, + comboboxOptionsBase.Tooltip("Current magic level"))) { gSaveContext.isMagicAcquired = gSaveContext.magicLevel > 0; gSaveContext.isDoubleMagicAcquired = gSaveContext.magicLevel == 2; } @@ -203,7 +202,10 @@ void DrawInfoTab() { } int32_t magic = (int32_t)gSaveContext.magic; - if (SliderInt("Magic", &magic, intSliderOptionsBase.Min(0).Max(gSaveContext.magicCapacity).Tooltip("Current magic. 48 units per magic level"))) { + if (SliderInt("Magic", &magic, + intSliderOptionsBase.Min(0) + .Max(gSaveContext.magicCapacity) + .Tooltip("Current magic. 48 units per magic level"))) { gSaveContext.magic = (int8_t)magic; } @@ -212,7 +214,7 @@ void DrawInfoTab() { Tooltip("Current rupees"); PopStyleInput(); - SliderInt("Time", (int32_t*) &gSaveContext.dayTime, intSliderOptionsBase.Min(0).Max(0xFFFF).Tooltip("Time of day")); + SliderInt("Time", (int32_t*)&gSaveContext.dayTime, intSliderOptionsBase.Min(0).Max(0xFFFF).Tooltip("Time of day")); if (Button("Dawn", buttonOptionsBase)) { gSaveContext.dayTime = 0x4000; } @@ -239,7 +241,8 @@ void DrawInfoTab() { Tooltip("Total number of deaths"); PopStyleInput(); - Checkbox("Has BGS", (bool*) &gSaveContext.bgsFlag, checkboxOptionsBase.Tooltip("Is Biggoron sword unlocked? Replaces Giant's knife")); + Checkbox("Has BGS", (bool*)&gSaveContext.bgsFlag, + checkboxOptionsBase.Tooltip("Is Biggoron sword unlocked? Replaces Giant's knife")); PushStyleInput(THEME_COLOR); ImGui::InputScalar("Sword Health", ImGuiDataType_U16, &gSaveContext.swordHealth); @@ -287,98 +290,108 @@ void DrawInfoTab() { PopStyleInput(); Combobox("Audio", &gSaveContext.audioSetting, audioMap, comboboxOptionsBase.Tooltip("Sound setting")); - - Checkbox("64 DD file?", (bool*) &gSaveContext.n64ddFlag, checkboxOptionsBase.Tooltip("WARNING! If you save, your file may be locked! Use caution!")); - - Combobox("Z Target Mode", &gSaveContext.zTargetSetting, zTargetMap, comboboxOptionsBase.Tooltip("Z-Targeting behavior")); + + Checkbox("64 DD file?", (bool*)&gSaveContext.n64ddFlag, + checkboxOptionsBase.Tooltip("WARNING! If you save, your file may be locked! Use caution!")); + + Combobox("Z Target Mode", &gSaveContext.zTargetSetting, zTargetMap, + comboboxOptionsBase.Tooltip("Z-Targeting behavior")); if (IS_RANDO && OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_TRIFORCE_HUNT)) { PushStyleInput(THEME_COLOR); - ImGui::InputScalar("Triforce Pieces", ImGuiDataType_U8, &gSaveContext.ship.quest.data.randomizer.triforcePiecesCollected); + ImGui::InputScalar("Triforce Pieces", ImGuiDataType_U8, + &gSaveContext.ship.quest.data.randomizer.triforcePiecesCollected); Tooltip("Currently obtained Triforce Pieces. For Triforce Hunt."); PopStyleInput(); } ImGui::PushItemWidth(ImGui::GetFontSize() * 10); - static std::array minigameHS = { "Horseback Archery", - "Big Poe Points", - "Fishing", - "Malon's Obstacle Course", - "Running Man Race", - "?", - "Dampe's Race" }; - + static std::array minigameHS = { "Horseback Archery", "Big Poe Points", + "Fishing", "Malon's Obstacle Course", + "Running Man Race", "?", + "Dampe's Race" }; + if (ImGui::TreeNode("Minigames")) { for (int i = 0; i < 7; i++) { - if(i == 2 && ImGui::TreeNode("Fishing") ){ //fishing has a few more flags to it + if (i == 2 && ImGui::TreeNode("Fishing")) { // fishing has a few more flags to it u8 fishSize = gSaveContext.highScores[i] & 0x7F; PushStyleInput(THEME_COLOR); - if(ImGui::InputScalar("Child Size Record",ImGuiDataType_U8,&fishSize)){ - gSaveContext.highScores[i]&=~0x7F; - gSaveContext.highScores[i]|=fishSize & 0x7F; + if (ImGui::InputScalar("Child Size Record", ImGuiDataType_U8, &fishSize)) { + gSaveContext.highScores[i] &= ~0x7F; + gSaveContext.highScores[i] |= fishSize & 0x7F; } char fishMsg[64]; - std::sprintf(fishMsg,"Weight: %2.0f lbs",((SQ(fishSize)*.0036)+.5)); + std::sprintf(fishMsg, "Weight: %2.0f lbs", ((SQ(fishSize) * .0036) + .5)); Tooltip(fishMsg); PopStyleInput(); - bool FishBool = gSaveContext.highScores[i]&0x80; - if (Checkbox("Cheated as Child", &FishBool, checkboxOptionsBase.Tooltip("Used the Sinking lure to catch it."))) { - gSaveContext.highScores[i] &= ~0x80; - gSaveContext.highScores[i] |= (0x80 * FishBool); + bool FishBool = gSaveContext.highScores[i] & 0x80; + if (Checkbox("Cheated as Child", &FishBool, + checkboxOptionsBase.Tooltip("Used the Sinking lure to catch it."))) { + gSaveContext.highScores[i] &= ~0x80; + gSaveContext.highScores[i] |= (0x80 * FishBool); } - fishSize=(gSaveContext.highScores[i] & 0x7F000000)>>0x18; + fishSize = (gSaveContext.highScores[i] & 0x7F000000) >> 0x18; PushStyleInput(THEME_COLOR); - if(ImGui::InputScalar("Adult Size Record",ImGuiDataType_U8,&fishSize)){ - gSaveContext.highScores[i]&=~0x7F000000; - gSaveContext.highScores[i]|=(fishSize & 0x7F) << 0x18; + if (ImGui::InputScalar("Adult Size Record", ImGuiDataType_U8, &fishSize)) { + gSaveContext.highScores[i] &= ~0x7F000000; + gSaveContext.highScores[i] |= (fishSize & 0x7F) << 0x18; } - std::sprintf(fishMsg,"Weight: %2.0f lbs",((SQ(fishSize)*.0036)+.5)); + std::sprintf(fishMsg, "Weight: %2.0f lbs", ((SQ(fishSize) * .0036) + .5)); Tooltip(fishMsg); PopStyleInput(); FishBool = gSaveContext.highScores[i] & 0x80000000; - if (Checkbox("Cheated as Adult", &FishBool, checkboxOptionsBase.Tooltip("Used the Sinking lure to catch it."))) { - gSaveContext.highScores[i] &= ~0x80000000; - gSaveContext.highScores[i] |= (0x80000000 * FishBool); + if (Checkbox("Cheated as Adult", &FishBool, + checkboxOptionsBase.Tooltip("Used the Sinking lure to catch it."))) { + gSaveContext.highScores[i] &= ~0x80000000; + gSaveContext.highScores[i] |= (0x80000000 * FishBool); } - FishBool = gSaveContext.highScores[i]&0x100; - if (Checkbox("Played as Child", &FishBool, checkboxOptionsBase.Tooltip("Played at least one game as a child"))) { - gSaveContext.highScores[i] &= ~0x100; - gSaveContext.highScores[i] |= (0x100 * FishBool); + FishBool = gSaveContext.highScores[i] & 0x100; + if (Checkbox("Played as Child", &FishBool, + checkboxOptionsBase.Tooltip("Played at least one game as a child"))) { + gSaveContext.highScores[i] &= ~0x100; + gSaveContext.highScores[i] |= (0x100 * FishBool); } - FishBool = gSaveContext.highScores[i]&0x200; - if (Checkbox("Played as Adult", &FishBool, checkboxOptionsBase.Tooltip("Played at least one game as an adult"))) { - gSaveContext.highScores[i] &= ~0x200; - gSaveContext.highScores[i] |= (0x200 * FishBool); + FishBool = gSaveContext.highScores[i] & 0x200; + if (Checkbox("Played as Adult", &FishBool, + checkboxOptionsBase.Tooltip("Played at least one game as an adult"))) { + gSaveContext.highScores[i] &= ~0x200; + gSaveContext.highScores[i] |= (0x200 * FishBool); } - FishBool = gSaveContext.highScores[i]&0x400; - if (Checkbox("Got Prize as Child", &FishBool, checkboxOptionsBase.Tooltip("Got the prize item (Heart Piece, unless rando.)\nunlocks Sinking Lure for Child Link."))) { - gSaveContext.highScores[i] &= ~0x400; - gSaveContext.highScores[i] |= (0x400 * FishBool); + FishBool = gSaveContext.highScores[i] & 0x400; + if (Checkbox( + "Got Prize as Child", &FishBool, + checkboxOptionsBase.Tooltip( + "Got the prize item (Heart Piece, unless rando.)\nunlocks Sinking Lure for Child Link."))) { + gSaveContext.highScores[i] &= ~0x400; + gSaveContext.highScores[i] |= (0x400 * FishBool); } - FishBool = gSaveContext.highScores[i]&0x800; - if (Checkbox("Got Prize as Adult", &FishBool, checkboxOptionsBase.Tooltip("Got the prize item (Golden Scale, unless rando.)\nUnlocks Sinking Lure for Adult Link."))) { - gSaveContext.highScores[i] &= ~0x800; - gSaveContext.highScores[i] |= (0x800 * FishBool); + FishBool = gSaveContext.highScores[i] & 0x800; + if (Checkbox("Got Prize as Adult", &FishBool, + checkboxOptionsBase.Tooltip("Got the prize item (Golden Scale, unless rando.)\nUnlocks " + "Sinking Lure for Adult Link."))) { + gSaveContext.highScores[i] &= ~0x800; + gSaveContext.highScores[i] |= (0x800 * FishBool); } FishBool = gSaveContext.highScores[i] & 0x1000; - if (Checkbox("Stole Owner's Hat", &FishBool, checkboxOptionsBase.Tooltip("The owner's now visibly bald when Adult Link."))) { - gSaveContext.highScores[i] &= ~0x1000; - gSaveContext.highScores[i] |= (0x1000 * FishBool); + if (Checkbox("Stole Owner's Hat", &FishBool, + checkboxOptionsBase.Tooltip("The owner's now visibly bald when Adult Link."))) { + gSaveContext.highScores[i] &= ~0x1000; + gSaveContext.highScores[i] |= (0x1000 * FishBool); } - fishSize=(gSaveContext.highScores[i] & 0xFF0000)>>16; + fishSize = (gSaveContext.highScores[i] & 0xFF0000) >> 16; PushStyleInput(THEME_COLOR); - if(ImGui::InputScalar("Times Played",ImGuiDataType_U8,&fishSize)){ - gSaveContext.highScores[i]&=~0xFF0000; - gSaveContext.highScores[i]|=(fishSize) << 16; + if (ImGui::InputScalar("Times Played", ImGuiDataType_U8, &fishSize)) { + gSaveContext.highScores[i] &= ~0xFF0000; + gSaveContext.highScores[i] |= (fishSize) << 16; } Tooltip("Determines weather and school size during dawn/dusk."); PopStyleInput(); - + ImGui::TreePop(); continue; } - - if (i == 5 || i == 2) { //HS_UNK_05 is unused + + if (i == 5 || i == 2) { // HS_UNK_05 is unused continue; } std::string minigameLbl = minigameHS[i]; @@ -386,10 +399,10 @@ void DrawInfoTab() { ImGui::InputScalar(minigameLbl.c_str(), ImGuiDataType_S32, &gSaveContext.highScores[i], &one, NULL); PopStyleInput(); } - + ImGui::TreePop(); } - + ImGui::PopItemWidth(); } @@ -402,7 +415,9 @@ void DrawBGSItemFlag(uint8_t itemID) { void DrawInventoryTab() { static bool restrictToValid = true; - Checkbox("Restrict to valid items", &restrictToValid, checkboxOptionsBase.Tooltip("Restricts items and ammo to only what is possible to legally acquire in-game")); + Checkbox( + "Restrict to valid items", &restrictToValid, + checkboxOptionsBase.Tooltip("Restricts items and ammo to only what is possible to legally acquire in-game")); for (int32_t y = 0; y < 4; y++) { for (int32_t x = 0; x < 6; x++) { @@ -420,8 +435,10 @@ void DrawInventoryTab() { PushStyleButton(Colors::DarkGray); if (item != ITEM_NONE) { const ItemMapEntry& slotEntry = itemMapping.find(item)->second; - auto ret = ImGui::ImageButton(slotEntry.name.c_str(), Ship::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName(slotEntry.name), - ImVec2(48.0f, 48.0f), ImVec2(0, 0), ImVec2(1, 1)); + auto ret = ImGui::ImageButton( + slotEntry.name.c_str(), + Ship::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName(slotEntry.name), + ImVec2(48.0f, 48.0f), ImVec2(0, 0), ImVec2(1, 1)); if (ret) { selectedIndex = index; ImGui::OpenPopup(itemPopupPicker); @@ -437,7 +454,8 @@ void DrawInventoryTab() { ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacing, ImVec2(0, 0)); if (ImGui::BeginPopup(itemPopupPicker)) { PushStyleButton(Colors::DarkGray); - if (ImGui::Button("##itemNonePicker", ImVec2(IMAGE_SIZE, IMAGE_SIZE) + ImGui::GetStyle().FramePadding * 2)) { + if (ImGui::Button("##itemNonePicker", + ImVec2(IMAGE_SIZE, IMAGE_SIZE) + ImGui::GetStyle().FramePadding * 2)) { gSaveContext.inventory.items[selectedIndex] = ITEM_NONE; ImGui::CloseCurrentPopup(); } @@ -468,8 +486,10 @@ void DrawInventoryTab() { } const ItemMapEntry& slotEntry = possibleItems[pickerIndex]; PushStyleButton(Colors::DarkGray); - auto ret = ImGui::ImageButton(slotEntry.name.c_str(), Ship::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName(slotEntry.name), - ImVec2(IMAGE_SIZE, IMAGE_SIZE), ImVec2(0, 0), ImVec2(1, 1)); + auto ret = ImGui::ImageButton( + slotEntry.name.c_str(), + Ship::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName(slotEntry.name), + ImVec2(IMAGE_SIZE, IMAGE_SIZE), ImVec2(0, 0), ImVec2(1, 1)); PopStyleButton(); if (ret) { gSaveContext.inventory.items[selectedIndex] = slotEntry.id; @@ -501,7 +521,8 @@ void DrawInventoryTab() { ImGui::PushItemWidth(IMAGE_SIZE); ImGui::BeginGroup(); - ImGui::Image(Ship::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName(itemMapping[item].name), ImVec2(IMAGE_SIZE, IMAGE_SIZE)); + ImGui::Image(Ship::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName(itemMapping[item].name), + ImVec2(IMAGE_SIZE, IMAGE_SIZE)); PushStyleInput(THEME_COLOR); ImGui::InputScalar("##ammoInput", ImGuiDataType_S8, &AMMO(item)); PopStyleInput(); @@ -511,11 +532,11 @@ void DrawInventoryTab() { ImGui::PopID(); } } - + // Trade quest flags are only used when shuffling the trade sequence, so // don't show this if it isn't needed. - if (IS_RANDO && OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_SHUFFLE_ADULT_TRADE) - && ImGui::TreeNode("Adult trade quest items")) { + if (IS_RANDO && OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_SHUFFLE_ADULT_TRADE) && + ImGui::TreeNode("Adult trade quest items")) { for (int i = ITEM_POCKET_EGG; i <= ITEM_CLAIM_CHECK; i++) { DrawBGSItemFlag(i); } @@ -532,7 +553,7 @@ void DrawFlagTableArray16(const FlagTable& flagTable, uint16_t row, uint16_t& fl bool hasDescription = !!flagTable.flagDescriptions.contains(row * 16 + flagIndex); uint32_t bitMask = 1 << flagIndex; ImVec4 themeColor = ColorValues.at(THEME_COLOR); - ImVec4 colorDark = { themeColor.x * 0.4f, themeColor.y * 0.4f, themeColor.z * 0.4f , themeColor.z }; + ImVec4 colorDark = { themeColor.x * 0.4f, themeColor.y * 0.4f, themeColor.z * 0.4f, themeColor.z }; PushStyleCheckbox(hasDescription ? themeColor : colorDark); ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, ImVec2(4.0f, 3.0f)); bool flag = (flags & bitMask) != 0; @@ -560,158 +581,182 @@ void DrawFlagsTab() { if (gPlayState != nullptr) { Player* player = GET_PLAYER(gPlayState); - DrawGroupWithBorder([&]() { - ImGui::Text("stateFlags1"); - DrawFlagArray32("stateFlags1", player->stateFlags1, THEME_COLOR); - }, "stateFlags1"); + DrawGroupWithBorder( + [&]() { + ImGui::Text("stateFlags1"); + DrawFlagArray32("stateFlags1", player->stateFlags1, THEME_COLOR); + }, + "stateFlags1"); ImGui::SameLine(); - DrawGroupWithBorder([&]() { - ImGui::Text("stateFlags2"); - DrawFlagArray32("stateFlags2", player->stateFlags2, THEME_COLOR); - }, "stateFlags2"); + DrawGroupWithBorder( + [&]() { + ImGui::Text("stateFlags2"); + DrawFlagArray32("stateFlags2", player->stateFlags2, THEME_COLOR); + }, + "stateFlags2"); + + DrawGroupWithBorder( + [&]() { + ImGui::Text("stateFlags3"); + DrawFlagArray8("stateFlags3", player->stateFlags3, THEME_COLOR); + }, + "stateFlags3"); - DrawGroupWithBorder([&]() { - ImGui::Text("stateFlags3"); - DrawFlagArray8("stateFlags3", player->stateFlags3, THEME_COLOR); - }, "stateFlags3"); - ImGui::SameLine(); - - DrawGroupWithBorder([&]() { - ImGui::Text("unk_6AE_rotFlags"); - DrawFlagArray16("unk_6AE_rotFlags", player->unk_6AE_rotFlags, THEME_COLOR); - }, "unk_6AE_rotFlags"); + + DrawGroupWithBorder( + [&]() { + ImGui::Text("unk_6AE_rotFlags"); + DrawFlagArray16("unk_6AE_rotFlags", player->unk_6AE_rotFlags, THEME_COLOR); + }, + "unk_6AE_rotFlags"); } ImGui::TreePop(); } if (ImGui::TreeNode("Current Scene")) { if (gPlayState != nullptr) { ActorContext* act = &gPlayState->actorCtx; - DrawGroupWithBorder([&]() { - ImGui::Text("Switch"); - InsertHelpHoverText("Permanently-saved switch flags"); - if (Button("Set All##Switch", buttonOptionsBase.Tooltip(""))) { - act->flags.swch = UINT32_MAX; - } - ImGui::SameLine(); - if (Button("Clear All##Switch", buttonOptionsBase.Tooltip(""))) { - act->flags.swch = 0; - } - DrawFlagArray32("Switch", act->flags.swch, THEME_COLOR); - }, "Switch"); + DrawGroupWithBorder( + [&]() { + ImGui::Text("Switch"); + InsertHelpHoverText("Permanently-saved switch flags"); + if (Button("Set All##Switch", buttonOptionsBase.Tooltip(""))) { + act->flags.swch = UINT32_MAX; + } + ImGui::SameLine(); + if (Button("Clear All##Switch", buttonOptionsBase.Tooltip(""))) { + act->flags.swch = 0; + } + DrawFlagArray32("Switch", act->flags.swch, THEME_COLOR); + }, + "Switch"); ImGui::SameLine(); - DrawGroupWithBorder([&]() { - ImGui::Text("Temp Switch"); - InsertHelpHoverText("Temporary switch flags. Unset on scene transitions"); - if (Button("Set All##Temp Switch", buttonOptionsBase.Tooltip(""))) { - act->flags.tempSwch = UINT32_MAX; - } - ImGui::SameLine(); - if (Button("Clear All##Temp Switch", buttonOptionsBase.Tooltip(""))) { - act->flags.tempSwch = 0; - } - DrawFlagArray32("Temp Switch", act->flags.tempSwch, THEME_COLOR); - }, "Temp Switch"); + DrawGroupWithBorder( + [&]() { + ImGui::Text("Temp Switch"); + InsertHelpHoverText("Temporary switch flags. Unset on scene transitions"); + if (Button("Set All##Temp Switch", buttonOptionsBase.Tooltip(""))) { + act->flags.tempSwch = UINT32_MAX; + } + ImGui::SameLine(); + if (Button("Clear All##Temp Switch", buttonOptionsBase.Tooltip(""))) { + act->flags.tempSwch = 0; + } + DrawFlagArray32("Temp Switch", act->flags.tempSwch, THEME_COLOR); + }, + "Temp Switch"); - DrawGroupWithBorder([&]() { - ImGui::Text("Clear"); - InsertHelpHoverText("Permanently-saved room-clear flags"); - if (Button("Set All##Clear", buttonOptionsBase.Tooltip(""))) { - act->flags.clear = UINT32_MAX; - } - ImGui::SameLine(); - if (Button("Clear All##Clear", buttonOptionsBase.Tooltip(""))) { - act->flags.clear = 0; - } - DrawFlagArray32("Clear", act->flags.clear, THEME_COLOR); - }, "Clear"); + DrawGroupWithBorder( + [&]() { + ImGui::Text("Clear"); + InsertHelpHoverText("Permanently-saved room-clear flags"); + if (Button("Set All##Clear", buttonOptionsBase.Tooltip(""))) { + act->flags.clear = UINT32_MAX; + } + ImGui::SameLine(); + if (Button("Clear All##Clear", buttonOptionsBase.Tooltip(""))) { + act->flags.clear = 0; + } + DrawFlagArray32("Clear", act->flags.clear, THEME_COLOR); + }, + "Clear"); ImGui::SameLine(); - DrawGroupWithBorder([&]() { - ImGui::Text("Temp Clear"); - InsertHelpHoverText("Temporary room-clear flags. Unset on scene transitions"); - if (Button("Set All##Temp Clear", buttonOptionsBase.Tooltip(""))) { - act->flags.tempClear = UINT32_MAX; - } - ImGui::SameLine(); - if (Button("Clear All##Temp Clear", buttonOptionsBase.Tooltip(""))) { - act->flags.tempClear = 0; - } - DrawFlagArray32("Temp Clear", act->flags.tempClear, THEME_COLOR); - }, "Temp Clear"); + DrawGroupWithBorder( + [&]() { + ImGui::Text("Temp Clear"); + InsertHelpHoverText("Temporary room-clear flags. Unset on scene transitions"); + if (Button("Set All##Temp Clear", buttonOptionsBase.Tooltip(""))) { + act->flags.tempClear = UINT32_MAX; + } + ImGui::SameLine(); + if (Button("Clear All##Temp Clear", buttonOptionsBase.Tooltip(""))) { + act->flags.tempClear = 0; + } + DrawFlagArray32("Temp Clear", act->flags.tempClear, THEME_COLOR); + }, + "Temp Clear"); - DrawGroupWithBorder([&]() { - ImGui::Text("Collect"); - InsertHelpHoverText("Permanently-saved collect flags"); - if (Button("Set All##Collect", buttonOptionsBase.Tooltip(""))) { - act->flags.collect = UINT32_MAX; - } - ImGui::SameLine(); - if (Button("Clear All##Collect", buttonOptionsBase.Tooltip(""))) { - act->flags.collect = 0; - } - DrawFlagArray32("Collect", act->flags.collect, THEME_COLOR); - }, "Collect"); + DrawGroupWithBorder( + [&]() { + ImGui::Text("Collect"); + InsertHelpHoverText("Permanently-saved collect flags"); + if (Button("Set All##Collect", buttonOptionsBase.Tooltip(""))) { + act->flags.collect = UINT32_MAX; + } + ImGui::SameLine(); + if (Button("Clear All##Collect", buttonOptionsBase.Tooltip(""))) { + act->flags.collect = 0; + } + DrawFlagArray32("Collect", act->flags.collect, THEME_COLOR); + }, + "Collect"); ImGui::SameLine(); - DrawGroupWithBorder([&]() { - ImGui::Text("Temp Collect"); - InsertHelpHoverText("Temporary collect flags. Unset on scene transitions"); - if (Button("Set All##Temp Collect", buttonOptionsBase.Tooltip(""))) { - act->flags.tempCollect = UINT32_MAX; - } - ImGui::SameLine(); - if (Button("Clear All##Temp Collect", buttonOptionsBase.Tooltip(""))) { - act->flags.tempCollect = 0; - } - DrawFlagArray32("Temp Collect", act->flags.tempCollect, THEME_COLOR); - }, "Temp Collect"); + DrawGroupWithBorder( + [&]() { + ImGui::Text("Temp Collect"); + InsertHelpHoverText("Temporary collect flags. Unset on scene transitions"); + if (Button("Set All##Temp Collect", buttonOptionsBase.Tooltip(""))) { + act->flags.tempCollect = UINT32_MAX; + } + ImGui::SameLine(); + if (Button("Clear All##Temp Collect", buttonOptionsBase.Tooltip(""))) { + act->flags.tempCollect = 0; + } + DrawFlagArray32("Temp Collect", act->flags.tempCollect, THEME_COLOR); + }, + "Temp Collect"); - DrawGroupWithBorder([&]() { - ImGui::Text("Chest"); - InsertHelpHoverText("Permanently-saved chest flags"); - if (Button("Set All##Chest", buttonOptionsBase.Tooltip(""))) { - act->flags.chest = UINT32_MAX; - } - ImGui::SameLine(); - if (Button("Clear All##Chest", buttonOptionsBase.Tooltip(""))) { - act->flags.chest = 0; - } - DrawFlagArray32("Chest", act->flags.chest, THEME_COLOR); - }, "Chest"); + DrawGroupWithBorder( + [&]() { + ImGui::Text("Chest"); + InsertHelpHoverText("Permanently-saved chest flags"); + if (Button("Set All##Chest", buttonOptionsBase.Tooltip(""))) { + act->flags.chest = UINT32_MAX; + } + ImGui::SameLine(); + if (Button("Clear All##Chest", buttonOptionsBase.Tooltip(""))) { + act->flags.chest = 0; + } + DrawFlagArray32("Chest", act->flags.chest, THEME_COLOR); + }, + "Chest"); ImGui::SameLine(); ImGui::BeginGroup(); - if (Button("Reload Flags", buttonOptionsBase.Tooltip("Load flags from saved scene flags. Normally happens on scene load"))) { + if (Button("Reload Flags", buttonOptionsBase.Tooltip( + "Load flags from saved scene flags. Normally happens on scene load"))) { act->flags.swch = gSaveContext.sceneFlags[gPlayState->sceneNum].swch; act->flags.clear = gSaveContext.sceneFlags[gPlayState->sceneNum].clear; act->flags.collect = gSaveContext.sceneFlags[gPlayState->sceneNum].collect; act->flags.chest = gSaveContext.sceneFlags[gPlayState->sceneNum].chest; } - if (Button("Save Flags", buttonOptionsBase.Tooltip("Save current scene flags. Normally happens on scene exit"))) { + if (Button("Save Flags", + buttonOptionsBase.Tooltip("Save current scene flags. Normally happens on scene exit"))) { gSaveContext.sceneFlags[gPlayState->sceneNum].swch = act->flags.swch; gSaveContext.sceneFlags[gPlayState->sceneNum].clear = act->flags.clear; gSaveContext.sceneFlags[gPlayState->sceneNum].collect = act->flags.collect; gSaveContext.sceneFlags[gPlayState->sceneNum].chest = act->flags.chest; } - - if (Button("Clear Flags", buttonOptionsBase.Tooltip("Clear current scene flags. Reload scene to see changes"))) { + + if (Button("Clear Flags", + buttonOptionsBase.Tooltip("Clear current scene flags. Reload scene to see changes"))) { act->flags.swch = 0; act->flags.clear = 0; act->flags.collect = 0; act->flags.chest = 0; } - ImGui::EndGroup(); } else { ImGui::Text("Current game state does not have an active scene"); @@ -745,105 +790,121 @@ void DrawFlagsTab() { } } - DrawGroupWithBorder([&]() { - ImGui::Text("Switch"); - InsertHelpHoverText("Switch flags"); - DrawFlagArray32("Switch", gSaveContext.sceneFlags[selectedSceneFlagMap].swch, THEME_COLOR); - }, "Saved Switch"); + DrawGroupWithBorder( + [&]() { + ImGui::Text("Switch"); + InsertHelpHoverText("Switch flags"); + DrawFlagArray32("Switch", gSaveContext.sceneFlags[selectedSceneFlagMap].swch, THEME_COLOR); + }, + "Saved Switch"); ImGui::SameLine(); - DrawGroupWithBorder([&]() { - ImGui::Text("Clear"); - InsertHelpHoverText("Room-clear flags"); - DrawFlagArray32("Clear", gSaveContext.sceneFlags[selectedSceneFlagMap].clear, THEME_COLOR); - }, "Saved Clear"); + DrawGroupWithBorder( + [&]() { + ImGui::Text("Clear"); + InsertHelpHoverText("Room-clear flags"); + DrawFlagArray32("Clear", gSaveContext.sceneFlags[selectedSceneFlagMap].clear, THEME_COLOR); + }, + "Saved Clear"); - DrawGroupWithBorder([&]() { - ImGui::Text("Collect"); - InsertHelpHoverText("Collect flags"); - DrawFlagArray32("Collect", gSaveContext.sceneFlags[selectedSceneFlagMap].collect, THEME_COLOR); - }, "Saved Collect"); + DrawGroupWithBorder( + [&]() { + ImGui::Text("Collect"); + InsertHelpHoverText("Collect flags"); + DrawFlagArray32("Collect", gSaveContext.sceneFlags[selectedSceneFlagMap].collect, THEME_COLOR); + }, + "Saved Collect"); ImGui::SameLine(); - DrawGroupWithBorder([&]() { - ImGui::Text("Chest"); - InsertHelpHoverText("Chest flags"); - DrawFlagArray32("Chest", gSaveContext.sceneFlags[selectedSceneFlagMap].chest, THEME_COLOR); - }, "Saved Chest"); + DrawGroupWithBorder( + [&]() { + ImGui::Text("Chest"); + InsertHelpHoverText("Chest flags"); + DrawFlagArray32("Chest", gSaveContext.sceneFlags[selectedSceneFlagMap].chest, THEME_COLOR); + }, + "Saved Chest"); - DrawGroupWithBorder([&]() { - ImGui::Text("Rooms"); - InsertHelpHoverText("Flags for visted rooms"); - DrawFlagArray32("Rooms", gSaveContext.sceneFlags[selectedSceneFlagMap].rooms, THEME_COLOR); - }, "Saved Rooms"); + DrawGroupWithBorder( + [&]() { + ImGui::Text("Rooms"); + InsertHelpHoverText("Flags for visted rooms"); + DrawFlagArray32("Rooms", gSaveContext.sceneFlags[selectedSceneFlagMap].rooms, THEME_COLOR); + }, + "Saved Rooms"); ImGui::SameLine(); - DrawGroupWithBorder([&]() { - ImGui::Text("Floors"); - InsertHelpHoverText("Flags for visted floors"); - DrawFlagArray32("Floors", gSaveContext.sceneFlags[selectedSceneFlagMap].floors, THEME_COLOR); - }, "Saved Floors"); + DrawGroupWithBorder( + [&]() { + ImGui::Text("Floors"); + InsertHelpHoverText("Flags for visted floors"); + DrawFlagArray32("Floors", gSaveContext.sceneFlags[selectedSceneFlagMap].floors, THEME_COLOR); + }, + "Saved Floors"); ImGui::TreePop(); } - DrawGroupWithBorder([&]() { - size_t selectedGsMap = 0; - ImGui::Text("Gold Skulltulas"); - Combobox("Map##Gold Skulltulas", &selectedGsMap, gsMapping, comboboxOptionsBase.Tooltip("")); + DrawGroupWithBorder( + [&]() { + size_t selectedGsMap = 0; + ImGui::Text("Gold Skulltulas"); + Combobox("Map##Gold Skulltulas", &selectedGsMap, gsMapping, comboboxOptionsBase.Tooltip("")); - // TODO We should write out descriptions for each one... ugh - ImGui::AlignTextToFramePadding(); - ImGui::Text("Flags"); - uint32_t currentFlags = GET_GS_FLAGS(selectedGsMap); - uint32_t allFlags = gAreaGsFlags[selectedGsMap]; - uint32_t setMask = 1; - // Iterate over bitfield and create a checkbox for each skulltula - while (allFlags != 0) { - bool isThisSet = (currentFlags & 0x1) == 0x1; + // TODO We should write out descriptions for each one... ugh + ImGui::AlignTextToFramePadding(); + ImGui::Text("Flags"); + uint32_t currentFlags = GET_GS_FLAGS(selectedGsMap); + uint32_t allFlags = gAreaGsFlags[selectedGsMap]; + uint32_t setMask = 1; + // Iterate over bitfield and create a checkbox for each skulltula + while (allFlags != 0) { + bool isThisSet = (currentFlags & 0x1) == 0x1; - ImGui::SameLine(); - ImGui::PushID(allFlags); - PushStyleCheckbox(THEME_COLOR); - ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, ImVec2(4.0f, 3.0f)); - if (ImGui::Checkbox("##gs", &isThisSet)) { - if (isThisSet) { - SET_GS_FLAGS(selectedGsMap, setMask); - } else { - // Have to do this roundabout method as the macro does not support clearing flags - uint32_t currentFlagsBase = GET_GS_FLAGS(selectedGsMap); - gSaveContext.gsFlags[selectedGsMap >> 2] &= ~gGsFlagsMasks[selectedGsMap & 3]; - SET_GS_FLAGS(selectedGsMap, currentFlagsBase & ~setMask); + ImGui::SameLine(); + ImGui::PushID(allFlags); + PushStyleCheckbox(THEME_COLOR); + ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, ImVec2(4.0f, 3.0f)); + if (ImGui::Checkbox("##gs", &isThisSet)) { + if (isThisSet) { + SET_GS_FLAGS(selectedGsMap, setMask); + } else { + // Have to do this roundabout method as the macro does not support clearing flags + uint32_t currentFlagsBase = GET_GS_FLAGS(selectedGsMap); + gSaveContext.gsFlags[selectedGsMap >> 2] &= ~gGsFlagsMasks[selectedGsMap & 3]; + SET_GS_FLAGS(selectedGsMap, currentFlagsBase & ~setMask); + } + } + ImGui::PopStyleVar(); + PopStyleCheckbox(); + + ImGui::PopID(); + + allFlags >>= 1; + currentFlags >>= 1; + setMask <<= 1; + } + + // If playing a Randomizer Save with Shuffle Skull Tokens on anything other than "Off" we don't want to keep + // GS Token Count updated, since Gold Skulltulas killed will not correlate to GS Tokens Collected. + if (!(IS_RANDO && + OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_SHUFFLE_TOKENS) != RO_TOKENSANITY_OFF)) { + static bool keepGsCountUpdated = true; + Checkbox("Keep GS Count Updated", &keepGsCountUpdated, + checkboxOptionsBase.Tooltip( + "Automatically adjust the number of gold skulltula tokens acquired based on set flags.")); + int32_t gsCount = 0; + if (keepGsCountUpdated) { + for (int32_t gsFlagIndex = 0; gsFlagIndex < 6; gsFlagIndex++) { + gsCount += std::popcount(static_cast(gSaveContext.gsFlags[gsFlagIndex])); + } + gSaveContext.inventory.gsTokens = gsCount; } } - ImGui::PopStyleVar(); - PopStyleCheckbox(); - - ImGui::PopID(); - - allFlags >>= 1; - currentFlags >>= 1; - setMask <<= 1; - } - - // If playing a Randomizer Save with Shuffle Skull Tokens on anything other than "Off" we don't want to keep - // GS Token Count updated, since Gold Skulltulas killed will not correlate to GS Tokens Collected. - if (!(IS_RANDO && OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_SHUFFLE_TOKENS) != RO_TOKENSANITY_OFF)) { - static bool keepGsCountUpdated = true; - Checkbox("Keep GS Count Updated", &keepGsCountUpdated, - checkboxOptionsBase.Tooltip("Automatically adjust the number of gold skulltula tokens acquired based on set flags.")); - int32_t gsCount = 0; - if (keepGsCountUpdated) { - for (int32_t gsFlagIndex = 0; gsFlagIndex < 6; gsFlagIndex++) { - gsCount += std::popcount(static_cast(gSaveContext.gsFlags[gsFlagIndex])); - } - gSaveContext.inventory.gsTokens = gsCount; - } - } - }, "Gold Skulltulas"); + }, + "Gold Skulltulas"); for (int i = 0; i < flagTables.size(); i++) { const FlagTable& flagTable = flagTables[i]; @@ -853,32 +914,34 @@ void DrawFlagsTab() { if (ImGui::TreeNode(flagTable.name)) { for (int j = 0; j < flagTable.size + 1; j++) { - DrawGroupWithBorder([&]() { - ImGui::Text("%s", fmt::format("{:<2x}", j).c_str()); - switch (flagTable.flagTableType) { - case EVENT_CHECK_INF: - DrawFlagTableArray16(flagTable, j, gSaveContext.eventChkInf[j]); - break; - case ITEM_GET_INF: - DrawFlagTableArray16(flagTable, j, gSaveContext.itemGetInf[j]); - break; - case INF_TABLE: - DrawFlagTableArray16(flagTable, j, gSaveContext.infTable[j]); - break; - case EVENT_INF: - DrawFlagTableArray16(flagTable, j, gSaveContext.eventInf[j]); - break; - case RANDOMIZER_INF: - DrawFlagTableArray16(flagTable, j, gSaveContext.ship.randomizerInf[j]); - break; - } - }, flagTable.name); + DrawGroupWithBorder( + [&]() { + ImGui::Text("%s", fmt::format("{:<2x}", j).c_str()); + switch (flagTable.flagTableType) { + case EVENT_CHECK_INF: + DrawFlagTableArray16(flagTable, j, gSaveContext.eventChkInf[j]); + break; + case ITEM_GET_INF: + DrawFlagTableArray16(flagTable, j, gSaveContext.itemGetInf[j]); + break; + case INF_TABLE: + DrawFlagTableArray16(flagTable, j, gSaveContext.infTable[j]); + break; + case EVENT_INF: + DrawFlagTableArray16(flagTable, j, gSaveContext.eventInf[j]); + break; + case RANDOMIZER_INF: + DrawFlagTableArray16(flagTable, j, gSaveContext.ship.randomizerInf[j]); + break; + } + }, + flagTable.name); } // make some buttons to help with fishsanity debugging uint8_t fsMode = OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_FISHSANITY); - if (flagTable.flagTableType == RANDOMIZER_INF && - fsMode != RO_FISHSANITY_OFF && fsMode != RO_FISHSANITY_OVERWORLD) { + if (flagTable.flagTableType == RANDOMIZER_INF && fsMode != RO_FISHSANITY_OFF && + fsMode != RO_FISHSANITY_OVERWORLD) { if (ImGui::Button("Catch All (Child)")) { for (int k = RAND_INF_CHILD_FISH_1; k <= RAND_INF_CHILD_LOACH_2; k++) { Flags_SetRandomizerInf((RandomizerInf)k); @@ -935,13 +998,14 @@ void DrawUpgradeIcon(const std::string& categoryName, int32_t categoryId, const static const char* upgradePopupPicker = "upgradePopupPicker"; ImGui::PushID(categoryName.c_str()); - - PushStyleButton(Colors::DarkGray); + + PushStyleButton(Colors::DarkGray); uint8_t item = items[CUR_UPG_VALUE(categoryId)]; if (item != ITEM_NONE) { const ItemMapEntry& slotEntry = itemMapping[item]; - if (ImGui::ImageButton(slotEntry.name.c_str(), Ship::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName(slotEntry.name), - ImVec2(IMAGE_SIZE, IMAGE_SIZE), ImVec2(0, 0), ImVec2(1, 1))) { + if (ImGui::ImageButton(slotEntry.name.c_str(), + Ship::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName(slotEntry.name), + ImVec2(IMAGE_SIZE, IMAGE_SIZE), ImVec2(0, 0), ImVec2(1, 1))) { ImGui::OpenPopup(upgradePopupPicker); } } else { @@ -957,18 +1021,21 @@ void DrawUpgradeIcon(const std::string& categoryName, int32_t categoryId, const if ((pickerIndex % 8) != 0) { ImGui::SameLine(); } - + PushStyleButton(Colors::DarkGray); if (items[pickerIndex] == ITEM_NONE) { - if (ImGui::Button("##upgradePopupPicker", ImVec2(IMAGE_SIZE, IMAGE_SIZE) + ImGui::GetStyle().FramePadding * 2)) { + if (ImGui::Button("##upgradePopupPicker", + ImVec2(IMAGE_SIZE, IMAGE_SIZE) + ImGui::GetStyle().FramePadding * 2)) { Inventory_ChangeUpgrade(categoryId, pickerIndex); ImGui::CloseCurrentPopup(); } Tooltip("None"); } else { const ItemMapEntry& slotEntry = itemMapping[items[pickerIndex]]; - auto ret = ImGui::ImageButton(slotEntry.name.c_str(), Ship::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName(slotEntry.name), - ImVec2(IMAGE_SIZE, IMAGE_SIZE), ImVec2(0, 0), ImVec2(1, 1)); + auto ret = ImGui::ImageButton( + slotEntry.name.c_str(), + Ship::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName(slotEntry.name), + ImVec2(IMAGE_SIZE, IMAGE_SIZE), ImVec2(0, 0), ImVec2(1, 1)); if (ret) { Inventory_ChangeUpgrade(categoryId, pickerIndex); ImGui::CloseCurrentPopup(); @@ -1003,7 +1070,9 @@ void DrawEquipmentTab() { bool hasEquip = (bitMask & gSaveContext.inventory.equipment) != 0; const ItemMapEntry& entry = itemMapping[equipmentValues[i]]; PushStyleButton(Colors::DarkGray); - auto ret = ImGui::ImageButton(entry.name.c_str(), Ship::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName(hasEquip ? entry.name : entry.nameFaded), + auto ret = ImGui::ImageButton(entry.name.c_str(), + Ship::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName( + hasEquip ? entry.name : entry.nameFaded), ImVec2(IMAGE_SIZE, IMAGE_SIZE), ImVec2(0, 0), ImVec2(1, 1)); if (ret) { if (hasEquip) { @@ -1103,8 +1172,10 @@ void DrawQuestItemButton(uint32_t item) { uint32_t bitMask = 1 << entry.id; bool hasQuestItem = (bitMask & gSaveContext.inventory.questItems) != 0; PushStyleButton(Colors::DarkGray); - auto ret = ImGui::ImageButton(entry.name.c_str(), Ship::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName(hasQuestItem ? entry.name : entry.nameFaded), - ImVec2(IMAGE_SIZE, IMAGE_SIZE), ImVec2(0, 0), ImVec2(1, 1)); + auto ret = ImGui::ImageButton(entry.name.c_str(), + Ship::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName( + hasQuestItem ? entry.name : entry.nameFaded), + ImVec2(IMAGE_SIZE, IMAGE_SIZE), ImVec2(0, 0), ImVec2(1, 1)); if (ret) { if (hasQuestItem) { gSaveContext.inventory.questItems &= ~bitMask; @@ -1122,8 +1193,10 @@ void DrawDungeonItemButton(uint32_t item, uint32_t scene) { uint32_t bitMask = 1 << (entry.id - ITEM_KEY_BOSS); // Bitset starts at ITEM_KEY_BOSS == 0. the rest are sequential bool hasItem = (bitMask & gSaveContext.inventory.dungeonItems[scene]) != 0; PushStyleButton(Colors::DarkGray); - auto ret = ImGui::ImageButton(entry.name.c_str(), Ship::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName(hasItem ? entry.name : entry.nameFaded), - ImVec2(IMAGE_SIZE, IMAGE_SIZE), ImVec2(0, 0), ImVec2(1, 1)); + auto ret = ImGui::ImageButton( + entry.name.c_str(), + Ship::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName(hasItem ? entry.name : entry.nameFaded), + ImVec2(IMAGE_SIZE, IMAGE_SIZE), ImVec2(0, 0), ImVec2(1, 1)); if (ret) { if (hasItem) { gSaveContext.inventory.dungeonItems[scene] &= ~bitMask; @@ -1168,7 +1241,9 @@ void DrawQuestStatusTab() { uint32_t bitMask = 1 << entry.id; bool hasQuestItem = (bitMask & gSaveContext.inventory.questItems) != 0; PushStyleButton(Colors::DarkGray); - auto ret = ImGui::ImageButton(entry.name.c_str(), Ship::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName(hasQuestItem ? entry.name : entry.nameFaded), + auto ret = ImGui::ImageButton(entry.name.c_str(), + Ship::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName( + hasQuestItem ? entry.name : entry.nameFaded), ImVec2(32.0f, 48.0f), ImVec2(0, 0), ImVec2(1, 1)); if (ret) { if (hasQuestItem) { @@ -1211,44 +1286,50 @@ void DrawQuestStatusTab() { InsertHelpHoverText("The number of pieces of heart acquired towards the next heart container"); PopStyleCombobox(); - DrawGroupWithBorder([&]() { - ImGui::Text("Dungeon Items"); + DrawGroupWithBorder( + [&]() { + ImGui::Text("Dungeon Items"); - static int32_t dungeonItemsScene = SCENE_DEKU_TREE; - PushStyleCombobox(THEME_COLOR); - if (ImGui::BeginCombo("##DungeonSelect", SohUtils::GetSceneName(dungeonItemsScene).c_str())) { - for (int32_t dungeonIndex = SCENE_DEKU_TREE; dungeonIndex < SCENE_JABU_JABU_BOSS + 1; dungeonIndex++) { - if (ImGui::Selectable(SohUtils::GetSceneName(dungeonIndex).c_str(), - dungeonIndex == dungeonItemsScene)) { - dungeonItemsScene = dungeonIndex; + static int32_t dungeonItemsScene = SCENE_DEKU_TREE; + PushStyleCombobox(THEME_COLOR); + if (ImGui::BeginCombo("##DungeonSelect", SohUtils::GetSceneName(dungeonItemsScene).c_str())) { + for (int32_t dungeonIndex = SCENE_DEKU_TREE; dungeonIndex < SCENE_JABU_JABU_BOSS + 1; dungeonIndex++) { + if (ImGui::Selectable(SohUtils::GetSceneName(dungeonIndex).c_str(), + dungeonIndex == dungeonItemsScene)) { + dungeonItemsScene = dungeonIndex; + } } + + ImGui::EndCombo(); } + PopStyleCombobox(); - ImGui::EndCombo(); - } - PopStyleCombobox(); - - DrawDungeonItemButton(ITEM_KEY_BOSS, dungeonItemsScene); - ImGui::SameLine(); - DrawDungeonItemButton(ITEM_COMPASS, dungeonItemsScene); - ImGui::SameLine(); - DrawDungeonItemButton(ITEM_DUNGEON_MAP, dungeonItemsScene); - - if (dungeonItemsScene != SCENE_JABU_JABU_BOSS) { - float lineHeight = ImGui::GetTextLineHeightWithSpacing(); - ImGui::Image(Ship::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName(itemMapping[ITEM_KEY_SMALL].name), ImVec2(lineHeight, lineHeight)); + DrawDungeonItemButton(ITEM_KEY_BOSS, dungeonItemsScene); ImGui::SameLine(); - PushStyleInput(THEME_COLOR); - if (ImGui::InputScalar("##Keys", ImGuiDataType_S8, gSaveContext.inventory.dungeonKeys + dungeonItemsScene)) { - gSaveContext.ship.stats.dungeonKeys[dungeonItemsScene] = gSaveContext.inventory.dungeonKeys[dungeonItemsScene]; - }; - PopStyleInput(); - } else { - // dungeonItems is size 20 but dungeonKeys is size 19, so there are no keys for the last scene (Barinade's Lair) - ImGui::Text("Barinade's Lair does not have small keys"); - } - }, "Dungeon Items"); + DrawDungeonItemButton(ITEM_COMPASS, dungeonItemsScene); + ImGui::SameLine(); + DrawDungeonItemButton(ITEM_DUNGEON_MAP, dungeonItemsScene); + if (dungeonItemsScene != SCENE_JABU_JABU_BOSS) { + float lineHeight = ImGui::GetTextLineHeightWithSpacing(); + ImGui::Image(Ship::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName( + itemMapping[ITEM_KEY_SMALL].name), + ImVec2(lineHeight, lineHeight)); + ImGui::SameLine(); + PushStyleInput(THEME_COLOR); + if (ImGui::InputScalar("##Keys", ImGuiDataType_S8, + gSaveContext.inventory.dungeonKeys + dungeonItemsScene)) { + gSaveContext.ship.stats.dungeonKeys[dungeonItemsScene] = + gSaveContext.inventory.dungeonKeys[dungeonItemsScene]; + }; + PopStyleInput(); + } else { + // dungeonItems is size 20 but dungeonKeys is size 19, so there are no keys for the last scene + // (Barinade's Lair) + ImGui::Text("Barinade's Lair does not have small keys"); + } + }, + "Dungeon Items"); } void DrawPlayerTab() { @@ -1261,7 +1342,7 @@ void DrawPlayerTab() { switch (player->currentSwordItemId) { case ITEM_SWORD_KOKIRI: - curSword = "Kokiri Sword"; + curSword = "Kokiri Sword"; break; case ITEM_SWORD_MASTER: curSword = "Master Sword"; @@ -1327,34 +1408,40 @@ void DrawPlayerTab() { ImGui::PushItemWidth(ImGui::GetFontSize() * 6); PushStyleInput(THEME_COLOR); - DrawGroupWithBorder([&]() { - ImGui::Text("Link's Position"); - ImGui::PushItemWidth(ImGui::GetFontSize() * 12); - ImGui::InputScalar("X##Pos", ImGuiDataType_Float, &player->actor.world.pos.x); - ImGui::InputScalar("Y##Pos", ImGuiDataType_Float, &player->actor.world.pos.y); - ImGui::InputScalar("Z##Pos", ImGuiDataType_Float, &player->actor.world.pos.z); - ImGui::PopItemWidth(); - }, "Link's Position"); + DrawGroupWithBorder( + [&]() { + ImGui::Text("Link's Position"); + ImGui::PushItemWidth(ImGui::GetFontSize() * 12); + ImGui::InputScalar("X##Pos", ImGuiDataType_Float, &player->actor.world.pos.x); + ImGui::InputScalar("Y##Pos", ImGuiDataType_Float, &player->actor.world.pos.y); + ImGui::InputScalar("Z##Pos", ImGuiDataType_Float, &player->actor.world.pos.z); + ImGui::PopItemWidth(); + }, + "Link's Position"); ImGui::SameLine(); - DrawGroupWithBorder([&]() { - ImGui::Text("Link's Rotation"); - InsertHelpHoverText("For Link's rotation in relation to the world"); - ImGui::PushItemWidth(ImGui::GetFontSize() * 12); - ImGui::InputScalar("X##Rot", ImGuiDataType_S16, &player->actor.world.rot.x); - ImGui::InputScalar("Y##Rot", ImGuiDataType_S16, &player->actor.world.rot.y); - ImGui::InputScalar("Z##Rot", ImGuiDataType_S16, &player->actor.world.rot.z); - ImGui::PopItemWidth(); - }, "Link's Rotation"); + DrawGroupWithBorder( + [&]() { + ImGui::Text("Link's Rotation"); + InsertHelpHoverText("For Link's rotation in relation to the world"); + ImGui::PushItemWidth(ImGui::GetFontSize() * 12); + ImGui::InputScalar("X##Rot", ImGuiDataType_S16, &player->actor.world.rot.x); + ImGui::InputScalar("Y##Rot", ImGuiDataType_S16, &player->actor.world.rot.y); + ImGui::InputScalar("Z##Rot", ImGuiDataType_S16, &player->actor.world.rot.z); + ImGui::PopItemWidth(); + }, + "Link's Rotation"); ImGui::SameLine(); - DrawGroupWithBorder([&]() { - ImGui::Text("Link's Model Rotation"); - InsertHelpHoverText("For Link's actual model"); - ImGui::PushItemWidth(ImGui::GetFontSize() * 12); - ImGui::InputScalar("X##ModRot", ImGuiDataType_S16, &player->actor.shape.rot.x); - ImGui::InputScalar("Y##ModRot", ImGuiDataType_S16, &player->actor.shape.rot.y); - ImGui::InputScalar("Z##ModRot", ImGuiDataType_S16, &player->actor.shape.rot.z); - ImGui::PopItemWidth(); - }, "Link's Model Rotation"); + DrawGroupWithBorder( + [&]() { + ImGui::Text("Link's Model Rotation"); + InsertHelpHoverText("For Link's actual model"); + ImGui::PushItemWidth(ImGui::GetFontSize() * 12); + ImGui::InputScalar("X##ModRot", ImGuiDataType_S16, &player->actor.shape.rot.x); + ImGui::InputScalar("Y##ModRot", ImGuiDataType_S16, &player->actor.shape.rot.y); + ImGui::InputScalar("Z##ModRot", ImGuiDataType_S16, &player->actor.shape.rot.z); + ImGui::PopItemWidth(); + }, + "Link's Model Rotation"); ImGui::InputScalar("Linear Velocity", ImGuiDataType_Float, &player->linearVelocity); InsertHelpHoverText("Link's speed along the XZ plane"); @@ -1385,136 +1472,141 @@ void DrawPlayerTab() { InsertHelpHoverText("This will change Link's age when you load a map"); PopStyleCombobox(); ImGui::Separator(); - - DrawGroupWithBorder([&]() { - PushStyleCombobox(THEME_COLOR); - ImGui::Text("Link's Current Equipment"); - ImGui::PushItemWidth(ImGui::GetFontSize() * 12); - if (ImGui::BeginCombo("Sword", curSword)) { - if (ImGui::Selectable("None")) { - player->currentSwordItemId = ITEM_NONE; - gSaveContext.equips.buttonItems[0] = ITEM_NONE; - Inventory_ChangeEquipment(EQUIP_TYPE_SWORD, EQUIP_VALUE_SWORD_NONE); - } - if (ImGui::Selectable("Kokiri Sword")) { - player->currentSwordItemId = ITEM_SWORD_KOKIRI; - gSaveContext.equips.buttonItems[0] = ITEM_SWORD_KOKIRI; - Inventory_ChangeEquipment(EQUIP_TYPE_SWORD, EQUIP_VALUE_SWORD_KOKIRI); - } - if (ImGui::Selectable("Master Sword")) { - player->currentSwordItemId = ITEM_SWORD_MASTER; - gSaveContext.equips.buttonItems[0] = ITEM_SWORD_MASTER; - Inventory_ChangeEquipment(EQUIP_TYPE_SWORD, EQUIP_VALUE_SWORD_MASTER); - } - if (ImGui::Selectable("Biggoron's Sword")) { - if (gSaveContext.bgsFlag) { - if (gSaveContext.swordHealth < 8) { - gSaveContext.swordHealth = 8; - } - player->currentSwordItemId = ITEM_SWORD_BGS; - gSaveContext.equips.buttonItems[0] = ITEM_SWORD_BGS; + + DrawGroupWithBorder( + [&]() { + PushStyleCombobox(THEME_COLOR); + ImGui::Text("Link's Current Equipment"); + ImGui::PushItemWidth(ImGui::GetFontSize() * 12); + if (ImGui::BeginCombo("Sword", curSword)) { + if (ImGui::Selectable("None")) { + player->currentSwordItemId = ITEM_NONE; + gSaveContext.equips.buttonItems[0] = ITEM_NONE; + Inventory_ChangeEquipment(EQUIP_TYPE_SWORD, EQUIP_VALUE_SWORD_NONE); } - else { - if (gSaveContext.swordHealth < 8) { - gSaveContext.swordHealth = 8; - } - player->currentSwordItemId = ITEM_SWORD_BGS; - gSaveContext.equips.buttonItems[0] = ITEM_SWORD_KNIFE; + if (ImGui::Selectable("Kokiri Sword")) { + player->currentSwordItemId = ITEM_SWORD_KOKIRI; + gSaveContext.equips.buttonItems[0] = ITEM_SWORD_KOKIRI; + Inventory_ChangeEquipment(EQUIP_TYPE_SWORD, EQUIP_VALUE_SWORD_KOKIRI); } + if (ImGui::Selectable("Master Sword")) { + player->currentSwordItemId = ITEM_SWORD_MASTER; + gSaveContext.equips.buttonItems[0] = ITEM_SWORD_MASTER; + Inventory_ChangeEquipment(EQUIP_TYPE_SWORD, EQUIP_VALUE_SWORD_MASTER); + } + if (ImGui::Selectable("Biggoron's Sword")) { + if (gSaveContext.bgsFlag) { + if (gSaveContext.swordHealth < 8) { + gSaveContext.swordHealth = 8; + } + player->currentSwordItemId = ITEM_SWORD_BGS; + gSaveContext.equips.buttonItems[0] = ITEM_SWORD_BGS; + } else { + if (gSaveContext.swordHealth < 8) { + gSaveContext.swordHealth = 8; + } + player->currentSwordItemId = ITEM_SWORD_BGS; + gSaveContext.equips.buttonItems[0] = ITEM_SWORD_KNIFE; + } - Inventory_ChangeEquipment(EQUIP_TYPE_SWORD, EQUIP_VALUE_SWORD_BIGGORON); + Inventory_ChangeEquipment(EQUIP_TYPE_SWORD, EQUIP_VALUE_SWORD_BIGGORON); + } + if (ImGui::Selectable("Fishing Pole")) { + player->currentSwordItemId = ITEM_FISHING_POLE; + gSaveContext.equips.buttonItems[0] = ITEM_FISHING_POLE; + Inventory_ChangeEquipment(EQUIP_TYPE_SWORD, EQUIP_VALUE_SWORD_MASTER); + } + ImGui::EndCombo(); } - if (ImGui::Selectable("Fishing Pole")) { - player->currentSwordItemId = ITEM_FISHING_POLE; - gSaveContext.equips.buttonItems[0] = ITEM_FISHING_POLE; - Inventory_ChangeEquipment(EQUIP_TYPE_SWORD, EQUIP_VALUE_SWORD_MASTER); + if (ImGui::BeginCombo("Shield", curShield)) { + if (ImGui::Selectable("None")) { + player->currentShield = PLAYER_SHIELD_NONE; + Inventory_ChangeEquipment(EQUIP_TYPE_SHIELD, EQUIP_VALUE_SHIELD_NONE); + } + if (ImGui::Selectable("Deku Shield")) { + player->currentShield = PLAYER_SHIELD_DEKU; + Inventory_ChangeEquipment(EQUIP_TYPE_SHIELD, EQUIP_VALUE_SHIELD_DEKU); + } + if (ImGui::Selectable("Hylian Shield")) { + player->currentShield = PLAYER_SHIELD_HYLIAN; + Inventory_ChangeEquipment(EQUIP_TYPE_SHIELD, EQUIP_VALUE_SHIELD_HYLIAN); + } + if (ImGui::Selectable("Mirror Shield")) { + player->currentShield = PLAYER_SHIELD_MIRROR; + Inventory_ChangeEquipment(EQUIP_TYPE_SHIELD, EQUIP_VALUE_SHIELD_MIRROR); + } + ImGui::EndCombo(); } - ImGui::EndCombo(); - } - if (ImGui::BeginCombo("Shield", curShield)) { - if (ImGui::Selectable("None")) { - player->currentShield = PLAYER_SHIELD_NONE; - Inventory_ChangeEquipment(EQUIP_TYPE_SHIELD, EQUIP_VALUE_SHIELD_NONE); + if (ImGui::BeginCombo("Tunic", curTunic)) { + if (ImGui::Selectable("Kokiri Tunic")) { + player->currentTunic = PLAYER_TUNIC_KOKIRI; + Inventory_ChangeEquipment(EQUIP_TYPE_TUNIC, EQUIP_VALUE_TUNIC_KOKIRI); + } + if (ImGui::Selectable("Goron Tunic")) { + player->currentTunic = PLAYER_TUNIC_GORON; + Inventory_ChangeEquipment(EQUIP_TYPE_TUNIC, EQUIP_VALUE_TUNIC_GORON); + } + if (ImGui::Selectable("Zora Tunic")) { + player->currentTunic = PLAYER_TUNIC_ZORA; + Inventory_ChangeEquipment(EQUIP_TYPE_TUNIC, EQUIP_VALUE_TUNIC_ZORA); + } + ImGui::EndCombo(); } - if (ImGui::Selectable("Deku Shield")) { - player->currentShield = PLAYER_SHIELD_DEKU; - Inventory_ChangeEquipment(EQUIP_TYPE_SHIELD, EQUIP_VALUE_SHIELD_DEKU); - } - if (ImGui::Selectable("Hylian Shield")) { - player->currentShield = PLAYER_SHIELD_HYLIAN; - Inventory_ChangeEquipment(EQUIP_TYPE_SHIELD, EQUIP_VALUE_SHIELD_HYLIAN); - } - if (ImGui::Selectable("Mirror Shield")) { - player->currentShield = PLAYER_SHIELD_MIRROR; - Inventory_ChangeEquipment(EQUIP_TYPE_SHIELD, EQUIP_VALUE_SHIELD_MIRROR); - } - ImGui::EndCombo(); - } - if (ImGui::BeginCombo("Tunic", curTunic)) { - if (ImGui::Selectable("Kokiri Tunic")) { - player->currentTunic = PLAYER_TUNIC_KOKIRI; - Inventory_ChangeEquipment(EQUIP_TYPE_TUNIC, EQUIP_VALUE_TUNIC_KOKIRI); + if (ImGui::BeginCombo("Boots", curBoots)) { + if (ImGui::Selectable("Kokiri Boots")) { + player->currentBoots = PLAYER_BOOTS_KOKIRI; + Inventory_ChangeEquipment(EQUIP_TYPE_BOOTS, EQUIP_VALUE_BOOTS_KOKIRI); + } + if (ImGui::Selectable("Iron Boots")) { + player->currentBoots = PLAYER_BOOTS_IRON; + Inventory_ChangeEquipment(EQUIP_TYPE_BOOTS, EQUIP_VALUE_BOOTS_IRON); + } + if (ImGui::Selectable("Hover Boots")) { + player->currentBoots = PLAYER_BOOTS_HOVER; + Inventory_ChangeEquipment(EQUIP_TYPE_BOOTS, EQUIP_VALUE_BOOTS_HOVER); + } + ImGui::EndCombo(); } - if (ImGui::Selectable("Goron Tunic")) { - player->currentTunic = PLAYER_TUNIC_GORON; - Inventory_ChangeEquipment(EQUIP_TYPE_TUNIC, EQUIP_VALUE_TUNIC_GORON); - } - if (ImGui::Selectable("Zora Tunic")) { - player->currentTunic = PLAYER_TUNIC_ZORA; - Inventory_ChangeEquipment(EQUIP_TYPE_TUNIC, EQUIP_VALUE_TUNIC_ZORA); - } - ImGui::EndCombo(); - } - - if (ImGui::BeginCombo("Boots", curBoots)) { - if (ImGui::Selectable("Kokiri Boots")) { - player->currentBoots = PLAYER_BOOTS_KOKIRI; - Inventory_ChangeEquipment(EQUIP_TYPE_BOOTS, EQUIP_VALUE_BOOTS_KOKIRI); - } - if (ImGui::Selectable("Iron Boots")) { - player->currentBoots = PLAYER_BOOTS_IRON; - Inventory_ChangeEquipment(EQUIP_TYPE_BOOTS, EQUIP_VALUE_BOOTS_IRON); - } - if (ImGui::Selectable("Hover Boots")) { - player->currentBoots = PLAYER_BOOTS_HOVER; - Inventory_ChangeEquipment(EQUIP_TYPE_BOOTS, EQUIP_VALUE_BOOTS_HOVER); - } - ImGui::EndCombo(); - } - ImGui::PopItemWidth(); - PopStyleCombobox(); - }, "Current Equipment"); + ImGui::PopItemWidth(); + PopStyleCombobox(); + }, + "Current Equipment"); ImGui::SameLine(); ImU16 one = 1; - DrawGroupWithBorder([&]() { - ImGui::PushItemWidth(ImGui::GetFontSize() * 6); - PushStyleInput(THEME_COLOR); - ImGui::Text("Current Items"); - ImGui::InputScalar("B Button", ImGuiDataType_U8, &gSaveContext.equips.buttonItems[0], &one, NULL); - ImGui::InputScalar("C Left", ImGuiDataType_U8, &gSaveContext.equips.buttonItems[1], &one, NULL); - ImGui::InputScalar("C Down", ImGuiDataType_U8, &gSaveContext.equips.buttonItems[2], &one, NULL); - ImGui::InputScalar("C Right", ImGuiDataType_U8, &gSaveContext.equips.buttonItems[3], &one, NULL); - PopStyleInput(); - ImGui::PopItemWidth(); - }, "Current Items"); - - if (CVarGetInteger(CVAR_ENHANCEMENT("DpadEquips"), 0)) { - ImGui::SameLine(); - DrawGroupWithBorder([&]() { + DrawGroupWithBorder( + [&]() { ImGui::PushItemWidth(ImGui::GetFontSize() * 6); PushStyleInput(THEME_COLOR); - ImGui::Text("Current D-pad Items"); - // Two spaces at the end for aligning, not elegant but it's working - ImGui::InputScalar("D-pad Up ", ImGuiDataType_U8, &gSaveContext.equips.buttonItems[4], &one, NULL); - ImGui::InputScalar("D-pad Down", ImGuiDataType_U8, &gSaveContext.equips.buttonItems[5], &one, NULL); - ImGui::InputScalar("D-pad Left", ImGuiDataType_U8, &gSaveContext.equips.buttonItems[6], &one, NULL); - ImGui::InputScalar("D-pad Right", ImGuiDataType_U8, &gSaveContext.equips.buttonItems[7], &one, NULL); + ImGui::Text("Current Items"); + ImGui::InputScalar("B Button", ImGuiDataType_U8, &gSaveContext.equips.buttonItems[0], &one, NULL); + ImGui::InputScalar("C Left", ImGuiDataType_U8, &gSaveContext.equips.buttonItems[1], &one, NULL); + ImGui::InputScalar("C Down", ImGuiDataType_U8, &gSaveContext.equips.buttonItems[2], &one, NULL); + ImGui::InputScalar("C Right", ImGuiDataType_U8, &gSaveContext.equips.buttonItems[3], &one, NULL); PopStyleInput(); ImGui::PopItemWidth(); - }, "Current D-pad Items"); + }, + "Current Items"); + + if (CVarGetInteger(CVAR_ENHANCEMENT("DpadEquips"), 0)) { + ImGui::SameLine(); + DrawGroupWithBorder( + [&]() { + ImGui::PushItemWidth(ImGui::GetFontSize() * 6); + PushStyleInput(THEME_COLOR); + ImGui::Text("Current D-pad Items"); + // Two spaces at the end for aligning, not elegant but it's working + ImGui::InputScalar("D-pad Up ", ImGuiDataType_U8, &gSaveContext.equips.buttonItems[4], &one, NULL); + ImGui::InputScalar("D-pad Down", ImGuiDataType_U8, &gSaveContext.equips.buttonItems[5], &one, NULL); + ImGui::InputScalar("D-pad Left", ImGuiDataType_U8, &gSaveContext.equips.buttonItems[6], &one, NULL); + ImGui::InputScalar("D-pad Right", ImGuiDataType_U8, &gSaveContext.equips.buttonItems[7], &one, + NULL); + PopStyleInput(); + ImGui::PopItemWidth(); + }, + "Current D-pad Items"); } ImGui::Text("Player State"); @@ -1524,22 +1616,26 @@ void DrawPlayerTab() { for (int j = 0; j <= 2; j++) { std::string label = fmt::format("State Flags {}", j + 1); - DrawGroupWithBorder([&]() { - ImGui::Text("%s", label.c_str()); - std::vector state = flag_strs[j]; - for (int i = 0; i <= 31; i++) { - bit[i] = ((flags[j] >> i) & 1); - if (bit[i] != 0) { - ImGui::Text("%s", state[i].c_str()); + DrawGroupWithBorder( + [&]() { + ImGui::Text("%s", label.c_str()); + std::vector state = flag_strs[j]; + for (int i = 0; i <= 31; i++) { + bit[i] = ((flags[j] >> i) & 1); + if (bit[i] != 0) { + ImGui::Text("%s", state[i].c_str()); + } } - } - }, label.c_str()); + }, + label.c_str()); ImGui::SameLine(); } - DrawGroupWithBorder([&]() { - ImGui::Text("Sword"); - ImGui::Text(" %d", player->meleeWeaponState); - }, "Sword"); + DrawGroupWithBorder( + [&]() { + ImGui::Text("Sword"); + ImGui::Text(" %d", player->meleeWeaponState); + }, + "Sword"); } else { ImGui::Text("Global Context needed for player info!"); @@ -1547,10 +1643,13 @@ void DrawPlayerTab() { } void ResetBaseOptions() { - intSliderOptionsBase.Color(THEME_COLOR).Size({320.0f, 0.0f}).Tooltip(""); + intSliderOptionsBase.Color(THEME_COLOR).Size({ 320.0f, 0.0f }).Tooltip(""); buttonOptionsBase.Color(THEME_COLOR).Size(Sizes::Inline).Tooltip(""); checkboxOptionsBase.Color(THEME_COLOR).Tooltip(""); - comboboxOptionsBase.Color(THEME_COLOR).ComponentAlignment(ComponentAlignments::Left).LabelPosition(LabelPositions::Near).Tooltip(""); + comboboxOptionsBase.Color(THEME_COLOR) + .ComponentAlignment(ComponentAlignments::Left) + .LabelPosition(LabelPositions::Near) + .Tooltip(""); } void SaveEditorWindow::DrawElement() { @@ -1601,4 +1700,5 @@ void SaveEditorWindow::DrawElement() { PopStyleTabs(); } -void SaveEditorWindow::InitElement() {} +void SaveEditorWindow::InitElement() { +} diff --git a/soh/soh/Enhancements/debugger/debugSaveEditor.h b/soh/soh/Enhancements/debugger/debugSaveEditor.h index 04e01917d..9c0819e19 100644 --- a/soh/soh/Enhancements/debugger/debugSaveEditor.h +++ b/soh/soh/Enhancements/debugger/debugSaveEditor.h @@ -26,1608 +26,1667 @@ typedef struct { // Reference https://tcrf.net/Proto:The_Legend_of_Zelda:_Ocarina_of_Time_Master_Quest/Event_Editor // The source was last referenced on 2022-09-03 and had a last updated value of 2020-05-02 const std::vector flagTables = { - { "Event Check Inf Flags", EVENT_CHECK_INF, 0x0D, { - { 0x02, "First Spoke to Mido" }, - { 0x03, "Complained About Mido to Saria" }, - { 0x04, "Showed Mido Sword & Shield" }, - { 0x05, "Deku Tree Opened Mouth" }, - { 0x06, "Spoke to Saria After Deku Tree's Death" }, - { 0x07, "Obtained Kokiri Emerald & Deku Tree Dead" }, - { 0x09, "Used Deku Tree Blue Warp" }, - { 0x0A, "Played Saria's Song for Mido as Adult" }, - { 0x0C, "Met Deku Tree" }, - { 0x0F, "Spoke to Mido about Saria's whereabouts" }, - { 0x10, "Spoke to Child Malon at Castle or Market" }, - { 0x11, "Spoke to Ingo at Ranch before Talon returns" }, - { 0x12, "Obtained Pocket Egg" }, - { 0x13, "Woke Talon" }, - { 0x14, "Talon Fled Hyrule Castle" }, - { 0x15, "Spoke to Child Malon at Ranch" }, - { 0x16, "Invited to Sing With Child Malon" }, - { 0x17, "Great Deku Tree is Dead" }, - { 0x18, "Obtained Epona" }, - { 0x19, "Obtained Kokiri's Emerald" }, - { 0x1B, "Rented Horse From Ingo" }, - { 0x1C, "Spoke to Mido After Deku Tree's Death" }, - { 0x1D, "Destroyed the Royal Family's Tomb" }, - { 0x1E, "Won the Cow in Malon's Race" }, - { 0x23, "Bombed Dodongo's Cavern Entrance" }, - { 0x25, "Used Dodongo's Cavern Blue Warp" }, - { 0x2F, "Death Mountain Erupted" }, - { 0x30, "Spoke to a Zora" }, - { 0x31, "Obtained Ruto's Letter" }, - { 0x33, "King Zora Moved Aside" }, - { 0x37, "Used Jabu-Jabu Blue Warp" }, - { 0x38, "Obtained Silver Scale" }, - { 0x39, "Opened Entrance to Zora's Domain" }, - { 0x3A, "Offered Fish to Jabu-Jabu" }, - { 0x3B, "Began Nabooru Battle" }, - { 0x3C, "Finished Nabooru Battle" }, - { 0x40, "Obtained Zelda's Letter" }, - { 0x43, "Obtained Ocarina of Time" }, - { 0x45, "Pulled Master Sword from Pedestal" }, - { 0x48, "Used Forest Temple Blue Warp" }, - { 0x49, "Used Fire Temple Blue Warp" }, - { 0x4A, "Used Water Temple Blue Warp" }, - { 0x4B, "Opened the Door of Time" }, - { 0x4D, "Rainbow Bridge Built by Sages" }, - { 0x4E, "Caught by Hyrule Castle Guards" }, - { 0x4F, "Entered the Master Sword Chamber" }, - { 0x50, "Learned Minuet of Forest" }, - { 0x51, "Learned Bolero of Fire" }, - { 0x52, "Learned Serenade of Water" }, - { 0x54, "Learned Nocturne of Shadow" }, - { 0x55, "Sheik Moved From Sword Pedestal" }, - { 0x57, "Learned Saria's Song" }, - { 0x59, "Learned Zelda's Lullaby" }, - { 0x5A, "Learned Sun's Song" }, - { 0x5B, "Learned Song of Storms" }, - { 0x65, "Played Song of Storms in Windmill" }, - { 0x67, "Drained Well in Kakariko Village" }, - { 0x68, "Played Gerudo Archery Minigame" }, - { 0x69, "Restored Lake Hylia's Water" }, - { 0x6A, "Woke Talon in Kakariko" }, - { 0x6B, "Spoke to Talon After Saving Ranch" }, - { 0x6F, "Spoke to Kaepora Gaebora by Lost Woods" }, - { 0x70, "Began Gohma Battle" }, - { 0x71, "Began King Dodongo Battle" }, - { 0x72, "Began Phantom Ganon Battle" }, - { 0x73, "Began Volvagia Battle" }, - { 0x74, "Began Morpha Battle" }, - { 0x75, "Began Twinrova Battle" }, - { 0x76, "Began Barinade Battle" }, - { 0x77, "Began Bongo Bongo Battle" }, - { 0x78, "Began Ganondorf Battle" }, - { 0x80, "Zelda Fled Hyrule Castle" }, - { 0x82, "Bridge Unlocked (After Zelda Escape Cutscene)" }, - { 0x8C, "Paid Back Keaton Mask Fee" }, - { 0x8D, "Paid Back Skull Mask Fee" }, - { 0x8E, "Paid Back Spooky Mask Fee" }, - { 0x8F, "Paid Back Bunny Hood Fee" }, - { 0x90, "Rescued Red Carpenter" }, - { 0x91, "Rescued Yellow Carpenter" }, - { 0x92, "Rescued Blue Carpenter" }, - { 0x93, "Rescued Green Carpenter" }, - { 0x94, "Spoke to Nabooru in Spirit Temple" }, - { 0x95, "Nabooru Captured by Twinrova" }, - { 0x96, "Spoke to Cursed Man in Skulltula House" }, - { 0x9C, "Played Song for Scarecrow as Adult" }, - { 0xA0, "Entered Hyrule Field" }, - { 0xA1, "Entered Death Mountain Trail" }, - { 0xA3, "Entered Kakariko Village" }, - { 0xA4, "Entered Zora's Domain" }, - { 0xA5, "Entered Hyrule Castle" }, - { 0xA6, "Entered Goron City" }, - { 0xA7, "Entered Temple of Time" }, - { 0xA8, "Entered Deku Tree" }, - { 0xA9, "Learned Song of Time" }, - { 0xAA, "Bongo Bongo Escaped Well" }, - { 0xAC, "Learned Requiem of Spirit" }, - { 0xAD, "Completed Spirit Trial" }, - { 0xB0, "Entered Dodongo's Cavern" }, - { 0xB1, "Entered Lake Hylia" }, - { 0xB2, "Entered Gerudo Valley" }, - { 0xB3, "Entered Gerudo's Fortress" }, - { 0xB4, "Entered Lon Lon Ranch" }, - { 0xB5, "Entered Jabu-Jabu's Belly" }, - { 0xB6, "Entered Graveyard" }, - { 0xB7, "Entered Zora's Fountain" }, - { 0xB8, "Entered Desert Colossus" }, - { 0xB9, "Entered Death Mountain Crater" }, - { 0xBA, "Entered Ganon's Castle (Exterior)" }, - { 0xBB, "Completed Forest Trial" }, - { 0xBC, "Completed Water Trial" }, - { 0xBD, "Completed Shadow Trial" }, - { 0xBE, "Completed Fire Trial" }, - { 0xBF, "Completed Light Trial" }, - { 0xC0, "Nabooru Ordered to Fight by Twinrova" }, - { 0xC1, "Spoke to Saria on Lost Woods Bridge" }, - { 0xC3, "Dispelled Ganon's Tower Barrier" }, - { 0xC4, "Returned to Temple of Time With All Medallions" }, - { 0xC5, "Sheik, Spawned at Master Sword Pedestal as Adult" }, - { 0xC6, "Spoke to Deku Tree Sprout" }, - { 0xC7, "Watched Ganon's Tower Collapse / Caught by Gerudo" }, - { 0xC8, "Obtained Spirit Medallion" }, - { 0xC9, "Demo_Effect, Temple of Time Warp in blue aura + sfx the first time you spawn as Adult" }, - { 0xD0, "Obtained Frogs' Piece of Heart" }, - { 0xD1, "Played Zelda's Lullaby for Frogs" }, - { 0xD2, "Played Epona's Song for Frogs" }, - { 0xD3, "Played Sun's Song for Frogs" }, - { 0xD4, "Played Saria's Song for Frogs" }, - { 0xD5, "Played Song of Time for Frogs" }, - { 0xD6, "Played Song of Storms for Frogs" }, - { 0xDA, "Obtained Adult's Wallet" }, - { 0xDB, "Obtained Stone of Agony" }, - { 0xDC, "Obtained Giant's Wallet" }, - { 0xDD, "Obtained Skulltula House's Bombchu" }, - { 0xDE, "Obtained Skulltula House's Piece of Heart" }, - } }, - { "Item Get Inf Flags", ITEM_GET_INF, 0x03, { - { 0x02, "Obtained Super Cucco Bottle" }, - { 0x03, "Bought Bombchu (Shelf 2: Top Right)" }, - { 0x04, "Bought Bombchu (Shelf 1: Bot. Right)" }, - { 0x05, "Bought Bombchu (Shelf 1: Top Left)" }, - { 0x06, "Bought Bombchu (Shelf 2: Bot. Left)" }, - { 0x07, "Bought Bombchu (Shelf 2: Bot. Right)" }, - { 0x08, "Bought Bombchu (Shelf 1: Top Right)" }, - { 0x09, "Bought Bombchu (Shelf 1: Bot. Left)" }, - { 0x0A, "Bought Bombchu (Shelf 2: Top Left)" }, - { 0x0B, "Obtained Scrub's Heart Piece" }, - { 0x0C, "Obtained Cucco Lady's Bottle" }, - { 0x0D, "Obtained Bullet Bag Upgrade (Market)" }, - { 0x0E, "Obtained Big Quiver" }, - { 0x0F, "Obtained Biggest Quiver" }, - { 0x10, "Obtained Scientist's Heart Piece" }, - { 0x11, "Obtained Bowling Bomb Bag Upgrade" }, - { 0x12, "Obtained Bowling Heart Piece" }, - { 0x13, "Obtained Deku Seeds" }, - { 0x15, "Obtained Roof Guy's Heart Piece" }, - { 0x16, "Obtained Skullkid's Heart Piece" }, - { 0x17, "Obtained Skullkids' Heart Piece" }, - { 0x18, "Obtained Farore's Wind" }, - { 0x19, "Obtained Din's Fire" }, - { 0x1A, "Obtained Nayru's Love" }, - { 0x1B, "Obtained Treasure Chest Game Reward" }, - { 0x1C, "Obtained Grave-Dig Heart Piece" }, - { 0x1D, "Obtained Bullet Bag Upgrade (Woods)" }, - { 0x1E, "Obtained Deku Stick Upgrade (Stage)" }, - { 0x1F, "Obtained Deku Nut Upgrade (Stage)" }, - { 0x23, "Obtained Keaton Mask" }, - { 0x24, "Obtained Skull Mask" }, - { 0x25, "Obtained Spooky Mask" }, - { 0x26, "Obtained Bunny Hood" }, - { 0x2A, "Obtained Mask of Truth" }, - { 0x2C, "Obtained Pocket Egg" }, - { 0x2E, "Obtained Cojiro" }, - { 0x30, "Obtained Odd Potion" }, - { 0x31, "Obtained Poacher's Saw" }, - { 0x38, "Sold Keaton Mask" }, - { 0x39, "Sold Skull Mask" }, - { 0x3A, "Sold Spooky Mask" }, - { 0x3B, "Sold Bunny Hood" }, - { 0x3F, "Obtained Mask of Truth" }, - } }, - { "Inf Flags", INF_TABLE, 0x1D, { - { 0x00, "Greeted by Saria" }, - { 0x01, "Spoke to Saria About Obtaining Fairy" }, - { 0x03, "Complained About Mido to Saria" }, - { 0x05, "Spoke to Saria in Saria's House" }, - { 0x0C, "Mido Asked to See Sword & Shield" }, - { 0x15, "Spoke to Mido in Lost Woods as Adult" }, - { 0x19, "Told Mido Saria Won't Return" }, - { 0x1E, "Spoke to Kokiri Girl by Jumping Stones" }, - { 0x22, "Spoke to Kokiri Boy Guarding Forest Exit" }, - { 0x24, "Spoke to Kokiri Boy Cutting Grass" }, - { 0x26, "Spoke to Kokiri Girl on Shop Awning" }, - { 0x28, "Spoke to Kokiri Girl About Training Center" }, - { 0x41, "Spoke to Kokiri Boy on Bed in Mido's House" }, - { 0x51, "Spoke to Kokiri Girl in Saria's House" }, - { 0x59, "Spoke to Know-It-All Bro. About Temple" }, - { 0x61, "Spoke to Know-It-All Bro. About Saria" }, - { 0x66, "Spoke to Deku Tree Sprout After Cutscene" }, - { 0x6C, "Spoke to Dying Knight" }, - { 0x76, "Showed Zelda's Letter to Gate Guard" }, - { 0x77, "Gate Guard Put On Keaton Mask" }, - { 0x7E, "Spoke to Talon in Lon Lon Ranch House" }, - { 0x84, "Spoke to Child Malon at Castle or Market" }, - { 0x85, "Child Malon Said Epona Was Afraid of You" }, - { 0x8B, "Entered Hyrule Castle" }, - { 0x94, "Spoke to Ingo at Ranch Before Talon's Return" }, - { 0x97, "Spoke to Ingo at Ranch" }, - { 0x9A, "Spoke to Ingo as Adult" }, - { 0xA2, "Refused Ingo's 50 Rupee Rental Request" }, - { 0xAB, "Rode a Horse at Ingo's Ranch" }, - { 0xB0, "Spoke to Medigoron as Child" }, - { 0xB1, "Spoke to Medigoron as Adult" }, - { 0xB6, "Spoke to Poe Collector in Ruined Market" }, - { 0xB7, "Spoke to Fado in Kokiri Forest as Child" }, - { 0xB8, "Spoke to Malon After Saving Ranch" }, - { 0xB9, "Spoke to Malon on Horseback" }, - { 0xBC, "Fado requested Odd Potion" }, - { 0xC0, "Spoke to Fat Woman by Market Potion Shop" }, - { 0xC1, "Spoke to Fat Woman After Zelda's Escape" }, - { 0xC2, "Spoke to Burly Man About Talon Search" }, - { 0xC3, "Spoke to Burly Man After Zelda's Escape" }, - { 0xC4, "Spoke to Thief After Zelda's Escape" }, - { 0xC5, "Spoke to Thin Man by Market Target Shop" }, - { 0xC6, "Spoke to Old Woman by Market Fountain" }, - { 0xC7, "Spoke to Old Man by Bombchu Bowling" }, - { 0xC8, "Spoke to Thin Lady by Bombchu Bowling" }, - { 0xC9, "Spoke to Thin Lady After Zelda's Escape (1.0)" }, - { 0xCA, "Spoke to Red Joker in Market" }, - { 0xCB, "Spoke to Blue Joker in Market (1.0) / Dog Lady as Adult (DBG)" }, - { 0xCC, "Spoke to Itchy Lady After Malon Left Town" }, - { 0xCD, "Spoke to Blue Jokester in Market (DBG)" }, - { 0xCE, "Spoke to Thin Lady After Zelda's Escape (DBG)" }, - { 0xD9, "Spoke to Dampé as Child" }, - { 0xE0, "Spoke to Goron by Cavern" }, - { 0xE3, "Spoke to Goron Hiding Stick" }, - { 0xE6, "Spoke to Goron by Woods Exit" }, - { 0xEB, "Spoke to Goron by Bomb Flowers" }, - { 0xF0, "Spoke to Goron at City? Entrance" }, - { 0xF4, "Spoke to Ruby-Crazed Goron" }, - { 0xFC, "Spoke to Goron Shop Owner" }, - { 0x109, "Goron City Doors Unlocked" }, - { 0x10B, "Spoke to Goron Link About Volvagia" }, - { 0x10C, "Stopped Goron Link's Rolling" }, - { 0x10E, "Spoke to Goron Link" }, - { 0x113, "Spoke to Darunia in Goron City" }, - { 0x11A, "Spoke to Darunia in Fire Temple" }, - { 0x11E, "Obtained Bomb Bag Upgrade (Goron City)" }, - { 0x124, "Spoke to Zora Near Zora Shop?" }, - { 0x128, "Spoke to Zora Beside Zora Shop?" }, - { 0x129, "Spoke to Zora Swimming Behind Zora Shop" }, - { 0x138, "Thawed King Zora" }, - { 0x139, "Obtained Zora Tunic" }, - { 0x140, "Ruto in JJ (M7) on Blue Switch" }, - { 0x141, "Ruto in JJ (M2) Meet Ruto" }, - { 0x142, "Ruto in JJ (M3) Talk First Time" }, - { 0x143, "Ruto in JJ (M10) Can Be Escorted" }, - { 0x144, "Ruto in JJ (?) Wants to be Tossed to Sapphire" }, - { 0x145, "Ruto in JJ (M6) on Sapphire platform" }, - { 0x146, "Ruto in JJ (M6) Kidnapped" }, - { 0x147, "Ruto in JJ, Spawns on F1 Instead of B1" }, - { 0x160, "Spoke to Man in Impa's House During Day" }, - { 0x161, "Spoke to Man in Impa's House at Night" }, - { 0x162, "Spoke to Man in Impa's House as Adult" }, - { 0x163, "Spoke to Carpenter Boss's Wife as Child" }, - { 0x164, "Spoke to Carpenter Boss's Wife as Adult" }, - { 0x16C, "Refused Nabooru's Request" }, - { 0x170, "Spoke to Carpenter Boss in Valley" }, - { 0x172, "Spoke to Carpenter Boss in Kakariko" }, - { 0x176, "Spoke to Blue Carpenter in Tent" }, - { 0x178, "Spoke to Green Carpenter in Tent" }, - { 0x17F, "Running Man Suggested a Race" }, - { 0x190, "Obtained Gerudo Archery Piece of Heart" }, - { 0x191, "Obtained Dog Lady's Piece of Heart" }, - { 0x192, "Obtained Deku Stick Upgrade (Lost Woods)" }, - { 0x193, "Obtained Deku Nut Upgrade (Grotto)" }, - { 0x195, "Spoke to Kaepora in Lake Hylia" }, - { 0x196, "Spoke to Cursed Man With <10 Tokens" }, - { 0x197, "Spoke to Cursed Man With 10 Tokens" }, - { 0x198, "Obtained Small Magic Jar" }, - { 0x199, "Caught Cucco by Field Entrance" }, - { 0x19A, "Caught Cucco by Bazaar" }, - { 0x19B, "Caught Cucco by Cucco Pen" }, - { 0x19C, "Caught Cucco Behind Windmill" }, - { 0x19D, "Caught Cucco in Crate" }, - { 0x19E, "Caught Cucco by Skulltula House" }, - { 0x19F, "Caught Cucco Behind Potion Shop" }, - { 0x1A0, "Entered Deku Tree" }, - { 0x1A1, "Entered Dodongo's Cavern" }, - { 0x1A2, "Entered Jabu-Jabu's Belly" }, - { 0x1A3, "Entered Forest Temple" }, - { 0x1A4, "Entered Fire Temple" }, - { 0x1A5, "Entered Water Temple" }, - { 0x1A6, "Entered Spirit Temple" }, - { 0x1A7, "Entered Shadow Temple" }, - { 0x1A8, "Entered Bottom of the Well" }, - { 0x1A9, "Entered Ice Cavern" }, - { 0x1AA, "Entered Ganon's Tower" }, - { 0x1AB, "Entered Gerudo Training Ground" }, - { 0x1AC, "Entered Thieves' Hideout" }, - { 0x1AD, "Entered Ganon's Castle" }, - { 0x1AE, "Entered Ganon's Tower (Collapsing)" }, - { 0x1AF, "Entered Ganon's Castle (Collapsing)" }, - { 0x1D0, "No Sword on B" }, - } }, - { "Event Inf Flags", EVENT_INF, 0x03, { - { 0x00, "Rented Horse From Ingo" }, - { 0x01, "Racing Ingo" }, - { 0x02, "Won First Race With Ingo?" }, - { 0x05, "Lost Race With Ingo?" }, - { 0x06, "Racing Ingo For the Second Time" }, - { 0x08, "Finished Special Cucco Minigame / Began Gerudo Archery" }, - { 0x0A, "Won Special Cucco Minigame?" }, - { 0x0F, "Rented Horse From Ingo" }, - { 0x10, "Racing Running Man" }, - { 0x20, "Market Crowd Text Randomizer" }, - { 0x21, "Market Crowd Text Randomizer" }, - { 0x22, "Market Crowd Text Randomizer" }, - { 0x23, "Market Crowd Text Randomizer" }, - { 0x24, "Market Crowd Text Randomizer" }, - { 0x30, "Entered the Market" }, - } }, - { "Randomizer Inf Flags", RANDOMIZER_INF, (RAND_INF_MAX + 15) / 16, { - { RAND_INF_DUNGEONS_DONE_SPIRIT_TEMPLE, "DUNGEONS_DONE_SPIRIT_TEMPLE" }, - { RAND_INF_DUNGEONS_DONE_SHADOW_TEMPLE, "DUNGEONS_DONE_SHADOW_TEMPLE" }, + { "Event Check Inf Flags", + EVENT_CHECK_INF, + 0x0D, + { + { 0x02, "First Spoke to Mido" }, + { 0x03, "Complained About Mido to Saria" }, + { 0x04, "Showed Mido Sword & Shield" }, + { 0x05, "Deku Tree Opened Mouth" }, + { 0x06, "Spoke to Saria After Deku Tree's Death" }, + { 0x07, "Obtained Kokiri Emerald & Deku Tree Dead" }, + { 0x09, "Used Deku Tree Blue Warp" }, + { 0x0A, "Played Saria's Song for Mido as Adult" }, + { 0x0C, "Met Deku Tree" }, + { 0x0F, "Spoke to Mido about Saria's whereabouts" }, + { 0x10, "Spoke to Child Malon at Castle or Market" }, + { 0x11, "Spoke to Ingo at Ranch before Talon returns" }, + { 0x12, "Obtained Pocket Egg" }, + { 0x13, "Woke Talon" }, + { 0x14, "Talon Fled Hyrule Castle" }, + { 0x15, "Spoke to Child Malon at Ranch" }, + { 0x16, "Invited to Sing With Child Malon" }, + { 0x17, "Great Deku Tree is Dead" }, + { 0x18, "Obtained Epona" }, + { 0x19, "Obtained Kokiri's Emerald" }, + { 0x1B, "Rented Horse From Ingo" }, + { 0x1C, "Spoke to Mido After Deku Tree's Death" }, + { 0x1D, "Destroyed the Royal Family's Tomb" }, + { 0x1E, "Won the Cow in Malon's Race" }, + { 0x23, "Bombed Dodongo's Cavern Entrance" }, + { 0x25, "Used Dodongo's Cavern Blue Warp" }, + { 0x2F, "Death Mountain Erupted" }, + { 0x30, "Spoke to a Zora" }, + { 0x31, "Obtained Ruto's Letter" }, + { 0x33, "King Zora Moved Aside" }, + { 0x37, "Used Jabu-Jabu Blue Warp" }, + { 0x38, "Obtained Silver Scale" }, + { 0x39, "Opened Entrance to Zora's Domain" }, + { 0x3A, "Offered Fish to Jabu-Jabu" }, + { 0x3B, "Began Nabooru Battle" }, + { 0x3C, "Finished Nabooru Battle" }, + { 0x40, "Obtained Zelda's Letter" }, + { 0x43, "Obtained Ocarina of Time" }, + { 0x45, "Pulled Master Sword from Pedestal" }, + { 0x48, "Used Forest Temple Blue Warp" }, + { 0x49, "Used Fire Temple Blue Warp" }, + { 0x4A, "Used Water Temple Blue Warp" }, + { 0x4B, "Opened the Door of Time" }, + { 0x4D, "Rainbow Bridge Built by Sages" }, + { 0x4E, "Caught by Hyrule Castle Guards" }, + { 0x4F, "Entered the Master Sword Chamber" }, + { 0x50, "Learned Minuet of Forest" }, + { 0x51, "Learned Bolero of Fire" }, + { 0x52, "Learned Serenade of Water" }, + { 0x54, "Learned Nocturne of Shadow" }, + { 0x55, "Sheik Moved From Sword Pedestal" }, + { 0x57, "Learned Saria's Song" }, + { 0x59, "Learned Zelda's Lullaby" }, + { 0x5A, "Learned Sun's Song" }, + { 0x5B, "Learned Song of Storms" }, + { 0x65, "Played Song of Storms in Windmill" }, + { 0x67, "Drained Well in Kakariko Village" }, + { 0x68, "Played Gerudo Archery Minigame" }, + { 0x69, "Restored Lake Hylia's Water" }, + { 0x6A, "Woke Talon in Kakariko" }, + { 0x6B, "Spoke to Talon After Saving Ranch" }, + { 0x6F, "Spoke to Kaepora Gaebora by Lost Woods" }, + { 0x70, "Began Gohma Battle" }, + { 0x71, "Began King Dodongo Battle" }, + { 0x72, "Began Phantom Ganon Battle" }, + { 0x73, "Began Volvagia Battle" }, + { 0x74, "Began Morpha Battle" }, + { 0x75, "Began Twinrova Battle" }, + { 0x76, "Began Barinade Battle" }, + { 0x77, "Began Bongo Bongo Battle" }, + { 0x78, "Began Ganondorf Battle" }, + { 0x80, "Zelda Fled Hyrule Castle" }, + { 0x82, "Bridge Unlocked (After Zelda Escape Cutscene)" }, + { 0x8C, "Paid Back Keaton Mask Fee" }, + { 0x8D, "Paid Back Skull Mask Fee" }, + { 0x8E, "Paid Back Spooky Mask Fee" }, + { 0x8F, "Paid Back Bunny Hood Fee" }, + { 0x90, "Rescued Red Carpenter" }, + { 0x91, "Rescued Yellow Carpenter" }, + { 0x92, "Rescued Blue Carpenter" }, + { 0x93, "Rescued Green Carpenter" }, + { 0x94, "Spoke to Nabooru in Spirit Temple" }, + { 0x95, "Nabooru Captured by Twinrova" }, + { 0x96, "Spoke to Cursed Man in Skulltula House" }, + { 0x9C, "Played Song for Scarecrow as Adult" }, + { 0xA0, "Entered Hyrule Field" }, + { 0xA1, "Entered Death Mountain Trail" }, + { 0xA3, "Entered Kakariko Village" }, + { 0xA4, "Entered Zora's Domain" }, + { 0xA5, "Entered Hyrule Castle" }, + { 0xA6, "Entered Goron City" }, + { 0xA7, "Entered Temple of Time" }, + { 0xA8, "Entered Deku Tree" }, + { 0xA9, "Learned Song of Time" }, + { 0xAA, "Bongo Bongo Escaped Well" }, + { 0xAC, "Learned Requiem of Spirit" }, + { 0xAD, "Completed Spirit Trial" }, + { 0xB0, "Entered Dodongo's Cavern" }, + { 0xB1, "Entered Lake Hylia" }, + { 0xB2, "Entered Gerudo Valley" }, + { 0xB3, "Entered Gerudo's Fortress" }, + { 0xB4, "Entered Lon Lon Ranch" }, + { 0xB5, "Entered Jabu-Jabu's Belly" }, + { 0xB6, "Entered Graveyard" }, + { 0xB7, "Entered Zora's Fountain" }, + { 0xB8, "Entered Desert Colossus" }, + { 0xB9, "Entered Death Mountain Crater" }, + { 0xBA, "Entered Ganon's Castle (Exterior)" }, + { 0xBB, "Completed Forest Trial" }, + { 0xBC, "Completed Water Trial" }, + { 0xBD, "Completed Shadow Trial" }, + { 0xBE, "Completed Fire Trial" }, + { 0xBF, "Completed Light Trial" }, + { 0xC0, "Nabooru Ordered to Fight by Twinrova" }, + { 0xC1, "Spoke to Saria on Lost Woods Bridge" }, + { 0xC3, "Dispelled Ganon's Tower Barrier" }, + { 0xC4, "Returned to Temple of Time With All Medallions" }, + { 0xC5, "Sheik, Spawned at Master Sword Pedestal as Adult" }, + { 0xC6, "Spoke to Deku Tree Sprout" }, + { 0xC7, "Watched Ganon's Tower Collapse / Caught by Gerudo" }, + { 0xC8, "Obtained Spirit Medallion" }, + { 0xC9, "Demo_Effect, Temple of Time Warp in blue aura + sfx the first time you spawn as Adult" }, + { 0xD0, "Obtained Frogs' Piece of Heart" }, + { 0xD1, "Played Zelda's Lullaby for Frogs" }, + { 0xD2, "Played Epona's Song for Frogs" }, + { 0xD3, "Played Sun's Song for Frogs" }, + { 0xD4, "Played Saria's Song for Frogs" }, + { 0xD5, "Played Song of Time for Frogs" }, + { 0xD6, "Played Song of Storms for Frogs" }, + { 0xDA, "Obtained Adult's Wallet" }, + { 0xDB, "Obtained Stone of Agony" }, + { 0xDC, "Obtained Giant's Wallet" }, + { 0xDD, "Obtained Skulltula House's Bombchu" }, + { 0xDE, "Obtained Skulltula House's Piece of Heart" }, + } }, + { "Item Get Inf Flags", + ITEM_GET_INF, + 0x03, + { + { 0x02, "Obtained Super Cucco Bottle" }, + { 0x03, "Bought Bombchu (Shelf 2: Top Right)" }, + { 0x04, "Bought Bombchu (Shelf 1: Bot. Right)" }, + { 0x05, "Bought Bombchu (Shelf 1: Top Left)" }, + { 0x06, "Bought Bombchu (Shelf 2: Bot. Left)" }, + { 0x07, "Bought Bombchu (Shelf 2: Bot. Right)" }, + { 0x08, "Bought Bombchu (Shelf 1: Top Right)" }, + { 0x09, "Bought Bombchu (Shelf 1: Bot. Left)" }, + { 0x0A, "Bought Bombchu (Shelf 2: Top Left)" }, + { 0x0B, "Obtained Scrub's Heart Piece" }, + { 0x0C, "Obtained Cucco Lady's Bottle" }, + { 0x0D, "Obtained Bullet Bag Upgrade (Market)" }, + { 0x0E, "Obtained Big Quiver" }, + { 0x0F, "Obtained Biggest Quiver" }, + { 0x10, "Obtained Scientist's Heart Piece" }, + { 0x11, "Obtained Bowling Bomb Bag Upgrade" }, + { 0x12, "Obtained Bowling Heart Piece" }, + { 0x13, "Obtained Deku Seeds" }, + { 0x15, "Obtained Roof Guy's Heart Piece" }, + { 0x16, "Obtained Skullkid's Heart Piece" }, + { 0x17, "Obtained Skullkids' Heart Piece" }, + { 0x18, "Obtained Farore's Wind" }, + { 0x19, "Obtained Din's Fire" }, + { 0x1A, "Obtained Nayru's Love" }, + { 0x1B, "Obtained Treasure Chest Game Reward" }, + { 0x1C, "Obtained Grave-Dig Heart Piece" }, + { 0x1D, "Obtained Bullet Bag Upgrade (Woods)" }, + { 0x1E, "Obtained Deku Stick Upgrade (Stage)" }, + { 0x1F, "Obtained Deku Nut Upgrade (Stage)" }, + { 0x23, "Obtained Keaton Mask" }, + { 0x24, "Obtained Skull Mask" }, + { 0x25, "Obtained Spooky Mask" }, + { 0x26, "Obtained Bunny Hood" }, + { 0x2A, "Obtained Mask of Truth" }, + { 0x2C, "Obtained Pocket Egg" }, + { 0x2E, "Obtained Cojiro" }, + { 0x30, "Obtained Odd Potion" }, + { 0x31, "Obtained Poacher's Saw" }, + { 0x38, "Sold Keaton Mask" }, + { 0x39, "Sold Skull Mask" }, + { 0x3A, "Sold Spooky Mask" }, + { 0x3B, "Sold Bunny Hood" }, + { 0x3F, "Obtained Mask of Truth" }, + } }, + { "Inf Flags", + INF_TABLE, + 0x1D, + { + { 0x00, "Greeted by Saria" }, + { 0x01, "Spoke to Saria About Obtaining Fairy" }, + { 0x03, "Complained About Mido to Saria" }, + { 0x05, "Spoke to Saria in Saria's House" }, + { 0x0C, "Mido Asked to See Sword & Shield" }, + { 0x15, "Spoke to Mido in Lost Woods as Adult" }, + { 0x19, "Told Mido Saria Won't Return" }, + { 0x1E, "Spoke to Kokiri Girl by Jumping Stones" }, + { 0x22, "Spoke to Kokiri Boy Guarding Forest Exit" }, + { 0x24, "Spoke to Kokiri Boy Cutting Grass" }, + { 0x26, "Spoke to Kokiri Girl on Shop Awning" }, + { 0x28, "Spoke to Kokiri Girl About Training Center" }, + { 0x41, "Spoke to Kokiri Boy on Bed in Mido's House" }, + { 0x51, "Spoke to Kokiri Girl in Saria's House" }, + { 0x59, "Spoke to Know-It-All Bro. About Temple" }, + { 0x61, "Spoke to Know-It-All Bro. About Saria" }, + { 0x66, "Spoke to Deku Tree Sprout After Cutscene" }, + { 0x6C, "Spoke to Dying Knight" }, + { 0x76, "Showed Zelda's Letter to Gate Guard" }, + { 0x77, "Gate Guard Put On Keaton Mask" }, + { 0x7E, "Spoke to Talon in Lon Lon Ranch House" }, + { 0x84, "Spoke to Child Malon at Castle or Market" }, + { 0x85, "Child Malon Said Epona Was Afraid of You" }, + { 0x8B, "Entered Hyrule Castle" }, + { 0x94, "Spoke to Ingo at Ranch Before Talon's Return" }, + { 0x97, "Spoke to Ingo at Ranch" }, + { 0x9A, "Spoke to Ingo as Adult" }, + { 0xA2, "Refused Ingo's 50 Rupee Rental Request" }, + { 0xAB, "Rode a Horse at Ingo's Ranch" }, + { 0xB0, "Spoke to Medigoron as Child" }, + { 0xB1, "Spoke to Medigoron as Adult" }, + { 0xB6, "Spoke to Poe Collector in Ruined Market" }, + { 0xB7, "Spoke to Fado in Kokiri Forest as Child" }, + { 0xB8, "Spoke to Malon After Saving Ranch" }, + { 0xB9, "Spoke to Malon on Horseback" }, + { 0xBC, "Fado requested Odd Potion" }, + { 0xC0, "Spoke to Fat Woman by Market Potion Shop" }, + { 0xC1, "Spoke to Fat Woman After Zelda's Escape" }, + { 0xC2, "Spoke to Burly Man About Talon Search" }, + { 0xC3, "Spoke to Burly Man After Zelda's Escape" }, + { 0xC4, "Spoke to Thief After Zelda's Escape" }, + { 0xC5, "Spoke to Thin Man by Market Target Shop" }, + { 0xC6, "Spoke to Old Woman by Market Fountain" }, + { 0xC7, "Spoke to Old Man by Bombchu Bowling" }, + { 0xC8, "Spoke to Thin Lady by Bombchu Bowling" }, + { 0xC9, "Spoke to Thin Lady After Zelda's Escape (1.0)" }, + { 0xCA, "Spoke to Red Joker in Market" }, + { 0xCB, "Spoke to Blue Joker in Market (1.0) / Dog Lady as Adult (DBG)" }, + { 0xCC, "Spoke to Itchy Lady After Malon Left Town" }, + { 0xCD, "Spoke to Blue Jokester in Market (DBG)" }, + { 0xCE, "Spoke to Thin Lady After Zelda's Escape (DBG)" }, + { 0xD9, "Spoke to Dampé as Child" }, + { 0xE0, "Spoke to Goron by Cavern" }, + { 0xE3, "Spoke to Goron Hiding Stick" }, + { 0xE6, "Spoke to Goron by Woods Exit" }, + { 0xEB, "Spoke to Goron by Bomb Flowers" }, + { 0xF0, "Spoke to Goron at City? Entrance" }, + { 0xF4, "Spoke to Ruby-Crazed Goron" }, + { 0xFC, "Spoke to Goron Shop Owner" }, + { 0x109, "Goron City Doors Unlocked" }, + { 0x10B, "Spoke to Goron Link About Volvagia" }, + { 0x10C, "Stopped Goron Link's Rolling" }, + { 0x10E, "Spoke to Goron Link" }, + { 0x113, "Spoke to Darunia in Goron City" }, + { 0x11A, "Spoke to Darunia in Fire Temple" }, + { 0x11E, "Obtained Bomb Bag Upgrade (Goron City)" }, + { 0x124, "Spoke to Zora Near Zora Shop?" }, + { 0x128, "Spoke to Zora Beside Zora Shop?" }, + { 0x129, "Spoke to Zora Swimming Behind Zora Shop" }, + { 0x138, "Thawed King Zora" }, + { 0x139, "Obtained Zora Tunic" }, + { 0x140, "Ruto in JJ (M7) on Blue Switch" }, + { 0x141, "Ruto in JJ (M2) Meet Ruto" }, + { 0x142, "Ruto in JJ (M3) Talk First Time" }, + { 0x143, "Ruto in JJ (M10) Can Be Escorted" }, + { 0x144, "Ruto in JJ (?) Wants to be Tossed to Sapphire" }, + { 0x145, "Ruto in JJ (M6) on Sapphire platform" }, + { 0x146, "Ruto in JJ (M6) Kidnapped" }, + { 0x147, "Ruto in JJ, Spawns on F1 Instead of B1" }, + { 0x160, "Spoke to Man in Impa's House During Day" }, + { 0x161, "Spoke to Man in Impa's House at Night" }, + { 0x162, "Spoke to Man in Impa's House as Adult" }, + { 0x163, "Spoke to Carpenter Boss's Wife as Child" }, + { 0x164, "Spoke to Carpenter Boss's Wife as Adult" }, + { 0x16C, "Refused Nabooru's Request" }, + { 0x170, "Spoke to Carpenter Boss in Valley" }, + { 0x172, "Spoke to Carpenter Boss in Kakariko" }, + { 0x176, "Spoke to Blue Carpenter in Tent" }, + { 0x178, "Spoke to Green Carpenter in Tent" }, + { 0x17F, "Running Man Suggested a Race" }, + { 0x190, "Obtained Gerudo Archery Piece of Heart" }, + { 0x191, "Obtained Dog Lady's Piece of Heart" }, + { 0x192, "Obtained Deku Stick Upgrade (Lost Woods)" }, + { 0x193, "Obtained Deku Nut Upgrade (Grotto)" }, + { 0x195, "Spoke to Kaepora in Lake Hylia" }, + { 0x196, "Spoke to Cursed Man With <10 Tokens" }, + { 0x197, "Spoke to Cursed Man With 10 Tokens" }, + { 0x198, "Obtained Small Magic Jar" }, + { 0x199, "Caught Cucco by Field Entrance" }, + { 0x19A, "Caught Cucco by Bazaar" }, + { 0x19B, "Caught Cucco by Cucco Pen" }, + { 0x19C, "Caught Cucco Behind Windmill" }, + { 0x19D, "Caught Cucco in Crate" }, + { 0x19E, "Caught Cucco by Skulltula House" }, + { 0x19F, "Caught Cucco Behind Potion Shop" }, + { 0x1A0, "Entered Deku Tree" }, + { 0x1A1, "Entered Dodongo's Cavern" }, + { 0x1A2, "Entered Jabu-Jabu's Belly" }, + { 0x1A3, "Entered Forest Temple" }, + { 0x1A4, "Entered Fire Temple" }, + { 0x1A5, "Entered Water Temple" }, + { 0x1A6, "Entered Spirit Temple" }, + { 0x1A7, "Entered Shadow Temple" }, + { 0x1A8, "Entered Bottom of the Well" }, + { 0x1A9, "Entered Ice Cavern" }, + { 0x1AA, "Entered Ganon's Tower" }, + { 0x1AB, "Entered Gerudo Training Ground" }, + { 0x1AC, "Entered Thieves' Hideout" }, + { 0x1AD, "Entered Ganon's Castle" }, + { 0x1AE, "Entered Ganon's Tower (Collapsing)" }, + { 0x1AF, "Entered Ganon's Castle (Collapsing)" }, + { 0x1D0, "No Sword on B" }, + } }, + { "Event Inf Flags", + EVENT_INF, + 0x03, + { + { 0x00, "Rented Horse From Ingo" }, + { 0x01, "Racing Ingo" }, + { 0x02, "Won First Race With Ingo?" }, + { 0x05, "Lost Race With Ingo?" }, + { 0x06, "Racing Ingo For the Second Time" }, + { 0x08, "Finished Special Cucco Minigame / Began Gerudo Archery" }, + { 0x0A, "Won Special Cucco Minigame?" }, + { 0x0F, "Rented Horse From Ingo" }, + { 0x10, "Racing Running Man" }, + { 0x20, "Market Crowd Text Randomizer" }, + { 0x21, "Market Crowd Text Randomizer" }, + { 0x22, "Market Crowd Text Randomizer" }, + { 0x23, "Market Crowd Text Randomizer" }, + { 0x24, "Market Crowd Text Randomizer" }, + { 0x30, "Entered the Market" }, + } }, + { "Randomizer Inf Flags", + RANDOMIZER_INF, + (RAND_INF_MAX + 15) / 16, + { + { RAND_INF_DUNGEONS_DONE_SPIRIT_TEMPLE, "DUNGEONS_DONE_SPIRIT_TEMPLE" }, + { RAND_INF_DUNGEONS_DONE_SHADOW_TEMPLE, "DUNGEONS_DONE_SHADOW_TEMPLE" }, - { RAND_INF_COWS_MILKED_KF_LINKS_HOUSE_COW, "COWS_MILKED_KF_LINKS_HOUSE_COW" }, - { RAND_INF_COWS_MILKED_HF_COW_GROTTO_COW, "COWS_MILKED_HF_COW_GROTTO_COW" }, - { RAND_INF_COWS_MILKED_LLR_STABLES_LEFT_COW, "COWS_MILKED_LLR_STABLES_LEFT_COW" }, - { RAND_INF_COWS_MILKED_LLR_STABLES_RIGHT_COW, "COWS_MILKED_LLR_STABLES_RIGHT_COW" }, - { RAND_INF_COWS_MILKED_LLR_TOWER_LEFT_COW, "COWS_MILKED_LLR_TOWER_LEFT_COW" }, - { RAND_INF_COWS_MILKED_LLR_TOWER_RIGHT_COW, "COWS_MILKED_LLR_TOWER_RIGHT_COW" }, - { RAND_INF_COWS_MILKED_KAK_IMPAS_HOUSE_COW, "COWS_MILKED_KAK_IMPAS_HOUSE_COW" }, - { RAND_INF_COWS_MILKED_DMT_COW_GROTTO_COW, "COWS_MILKED_DMT_COW_GROTTO_COW" }, - { RAND_INF_COWS_MILKED_GV_COW, "COWS_MILKED_GV_COW" }, - { RAND_INF_COWS_MILKED_JABU_JABUS_BELLY_MQ_COW, "COWS_MILKED_JABU_JABUS_BELLY_MQ_COW" }, + { RAND_INF_COWS_MILKED_KF_LINKS_HOUSE_COW, "COWS_MILKED_KF_LINKS_HOUSE_COW" }, + { RAND_INF_COWS_MILKED_HF_COW_GROTTO_COW, "COWS_MILKED_HF_COW_GROTTO_COW" }, + { RAND_INF_COWS_MILKED_LLR_STABLES_LEFT_COW, "COWS_MILKED_LLR_STABLES_LEFT_COW" }, + { RAND_INF_COWS_MILKED_LLR_STABLES_RIGHT_COW, "COWS_MILKED_LLR_STABLES_RIGHT_COW" }, + { RAND_INF_COWS_MILKED_LLR_TOWER_LEFT_COW, "COWS_MILKED_LLR_TOWER_LEFT_COW" }, + { RAND_INF_COWS_MILKED_LLR_TOWER_RIGHT_COW, "COWS_MILKED_LLR_TOWER_RIGHT_COW" }, + { RAND_INF_COWS_MILKED_KAK_IMPAS_HOUSE_COW, "COWS_MILKED_KAK_IMPAS_HOUSE_COW" }, + { RAND_INF_COWS_MILKED_DMT_COW_GROTTO_COW, "COWS_MILKED_DMT_COW_GROTTO_COW" }, + { RAND_INF_COWS_MILKED_GV_COW, "COWS_MILKED_GV_COW" }, + { RAND_INF_COWS_MILKED_JABU_JABUS_BELLY_MQ_COW, "COWS_MILKED_JABU_JABUS_BELLY_MQ_COW" }, - { RAND_INF_SCRUBS_PURCHASED_DODONGOS_CAVERN_DEKU_SCRUB_NEAR_BOMB_BAG_LEFT, "SCRUBS_PURCHASED_DODONGOS_CAVERN_DEKU_SCRUB_NEAR_BOMB_BAG_LEFT" }, - { RAND_INF_SCRUBS_PURCHASED_DODONGOS_CAVERN_DEKU_SCRUB_SIDE_ROOM_NEAR_DODONGOS, "SCRUBS_PURCHASED_DODONGOS_CAVERN_DEKU_SCRUB_SIDE_ROOM_NEAR_DODONGOS" }, - { RAND_INF_SCRUBS_PURCHASED_DODONGOS_CAVERN_DEKU_SCRUB_NEAR_BOMB_BAG_RIGHT, "SCRUBS_PURCHASED_DODONGOS_CAVERN_DEKU_SCRUB_NEAR_BOMB_BAG_RIGHT" }, - { RAND_INF_SCRUBS_PURCHASED_DODONGOS_CAVERN_DEKU_SCRUB_LOBBY, "SCRUBS_PURCHASED_DODONGOS_CAVERN_DEKU_SCRUB_LOBBY" }, - { RAND_INF_SCRUBS_PURCHASED_JABU_JABUS_BELLY_DEKU_SCRUB, "SCRUBS_PURCHASED_JABU_JABUS_BELLY_DEKU_SCRUB" }, - { RAND_INF_SCRUBS_PURCHASED_GANONS_CASTLE_DEKU_SCRUB_CENTER_LEFT, "SCRUBS_PURCHASED_GANONS_CASTLE_DEKU_SCRUB_CENTER_LEFT" }, - { RAND_INF_SCRUBS_PURCHASED_GANONS_CASTLE_DEKU_SCRUB_CENTER_RIGHT, "SCRUBS_PURCHASED_GANONS_CASTLE_DEKU_SCRUB_CENTER_RIGHT" }, - { RAND_INF_SCRUBS_PURCHASED_GANONS_CASTLE_DEKU_SCRUB_RIGHT, "SCRUBS_PURCHASED_GANONS_CASTLE_DEKU_SCRUB_RIGHT" }, - { RAND_INF_SCRUBS_PURCHASED_GANONS_CASTLE_DEKU_SCRUB_LEFT, "SCRUBS_PURCHASED_GANONS_CASTLE_DEKU_SCRUB_LEFT" }, - { RAND_INF_SCRUBS_PURCHASED_HF_DEKU_SCRUB_GROTTO, "SCRUBS_PURCHASED_HF_DEKU_SCRUB_GROTTO" }, - { RAND_INF_SCRUBS_PURCHASED_ZR_DEKU_SCRUB_GROTTO_REAR, "SCRUBS_PURCHASED_ZR_DEKU_SCRUB_GROTTO_REAR" }, - { RAND_INF_SCRUBS_PURCHASED_ZR_DEKU_SCRUB_GROTTO_FRONT, "SCRUBS_PURCHASED_ZR_DEKU_SCRUB_GROTTO_FRONT" }, - { RAND_INF_SCRUBS_PURCHASED_SFM_DEKU_SCRUB_GROTTO_REAR, "SCRUBS_PURCHASED_SFM_DEKU_SCRUB_GROTTO_REAR" }, - { RAND_INF_SCRUBS_PURCHASED_SFM_DEKU_SCRUB_GROTTO_FRONT, "SCRUBS_PURCHASED_SFM_DEKU_SCRUB_GROTTO_FRONT" }, - { RAND_INF_SCRUBS_PURCHASED_LH_DEKU_SCRUB_GROTTO_LEFT, "SCRUBS_PURCHASED_LH_DEKU_SCRUB_GROTTO_LEFT" }, - { RAND_INF_SCRUBS_PURCHASED_LH_DEKU_SCRUB_GROTTO_RIGHT, "SCRUBS_PURCHASED_LH_DEKU_SCRUB_GROTTO_RIGHT" }, - { RAND_INF_SCRUBS_PURCHASED_LH_DEKU_SCRUB_GROTTO_CENTER, "SCRUBS_PURCHASED_LH_DEKU_SCRUB_GROTTO_CENTER" }, - { RAND_INF_SCRUBS_PURCHASED_GV_DEKU_SCRUB_GROTTO_REAR, "SCRUBS_PURCHASED_GV_DEKU_SCRUB_GROTTO_REAR" }, - { RAND_INF_SCRUBS_PURCHASED_GV_DEKU_SCRUB_GROTTO_FRONT, "SCRUBS_PURCHASED_GV_DEKU_SCRUB_GROTTO_FRONT" }, - { RAND_INF_SCRUBS_PURCHASED_LW_DEKU_SCRUB_GROTTO_REAR, "SCRUBS_PURCHASED_LW_DEKU_SCRUB_GROTTO_REAR" }, - { RAND_INF_SCRUBS_PURCHASED_LW_DEKU_SCRUB_GROTTO_FRONT, "SCRUBS_PURCHASED_LW_DEKU_SCRUB_GROTTO_FRONT" }, - { RAND_INF_SCRUBS_PURCHASED_DMC_DEKU_SCRUB_GROTTO_LEFT, "SCRUBS_PURCHASED_DMC_DEKU_SCRUB_GROTTO_LEFT" }, - { RAND_INF_SCRUBS_PURCHASED_DMC_DEKU_SCRUB_GROTTO_RIGHT, "SCRUBS_PURCHASED_DMC_DEKU_SCRUB_GROTTO_RIGHT" }, - { RAND_INF_SCRUBS_PURCHASED_DMC_DEKU_SCRUB_GROTTO_CENTER, "SCRUBS_PURCHASED_DMC_DEKU_SCRUB_GROTTO_CENTER" }, - { RAND_INF_SCRUBS_PURCHASED_GC_DEKU_SCRUB_GROTTO_LEFT, "SCRUBS_PURCHASED_GC_DEKU_SCRUB_GROTTO_LEFT" }, - { RAND_INF_SCRUBS_PURCHASED_GC_DEKU_SCRUB_GROTTO_RIGHT, "SCRUBS_PURCHASED_GC_DEKU_SCRUB_GROTTO_RIGHT" }, - { RAND_INF_SCRUBS_PURCHASED_GC_DEKU_SCRUB_GROTTO_CENTER, "SCRUBS_PURCHASED_GC_DEKU_SCRUB_GROTTO_CENTER" }, - { RAND_INF_SCRUBS_PURCHASED_LLR_DEKU_SCRUB_GROTTO_LEFT, "SCRUBS_PURCHASED_LLR_DEKU_SCRUB_GROTTO_LEFT" }, - { RAND_INF_SCRUBS_PURCHASED_LLR_DEKU_SCRUB_GROTTO_RIGHT, "SCRUBS_PURCHASED_LLR_DEKU_SCRUB_GROTTO_RIGHT" }, - { RAND_INF_SCRUBS_PURCHASED_LLR_DEKU_SCRUB_GROTTO_CENTER, "SCRUBS_PURCHASED_LLR_DEKU_SCRUB_GROTTO_CENTER" }, - { RAND_INF_SCRUBS_PURCHASED_COLOSSUS_DEKU_SCRUB_GROTTO_REAR, "SCRUBS_PURCHASED_COLOSSUS_DEKU_SCRUB_GROTTO_REAR" }, - { RAND_INF_SCRUBS_PURCHASED_COLOSSUS_DEKU_SCRUB_GROTTO_FRONT, "SCRUBS_PURCHASED_COLOSSUS_DEKU_SCRUB_GROTTO_FRONT" }, - { RAND_INF_SCRUBS_PURCHASED_LW_DEKU_SCRUB_NEAR_DEKU_THEATER_RIGHT, "SCRUBS_PURCHASED_LW_DEKU_SCRUB_NEAR_DEKU_THEATER_RIGHT" }, - { RAND_INF_SCRUBS_PURCHASED_LW_DEKU_SCRUB_NEAR_DEKU_THEATER_LEFT, "SCRUBS_PURCHASED_LW_DEKU_SCRUB_NEAR_DEKU_THEATER_LEFT" }, - { RAND_INF_SCRUBS_PURCHASED_LW_DEKU_SCRUB_NEAR_BRIDGE, "SCRUBS_PURCHASED_LW_DEKU_SCRUB_NEAR_BRIDGE" }, - { RAND_INF_SCRUBS_PURCHASED_DMC_DEKU_SCRUB, "SCRUBS_PURCHASED_DMC_DEKU_SCRUB" }, - { RAND_INF_SCRUBS_PURCHASED_DEKU_TREE_MQ_DEKU_SCRUB, "SCRUBS_PURCHASED_DEKU_TREE_MQ_DEKU_SCRUB" }, - { RAND_INF_SCRUBS_PURCHASED_DODONGOS_CAVERN_MQ_DEKU_SCRUB_LOBBY_REAR, "SCRUBS_PURCHASED_DODONGOS_CAVERN_MQ_DEKU_SCRUB_LOBBY_REAR" }, - { RAND_INF_SCRUBS_PURCHASED_DODONGOS_CAVERN_MQ_DEKU_SCRUB_LOBBY_FRONT, "SCRUBS_PURCHASED_DODONGOS_CAVERN_MQ_DEKU_SCRUB_LOBBY_FRONT" }, - { RAND_INF_SCRUBS_PURCHASED_DODONGOS_CAVERN_MQ_DEKU_SCRUB_STAIRCASE, "SCRUBS_PURCHASED_DODONGOS_CAVERN_MQ_DEKU_SCRUB_STAIRCASE" }, - { RAND_INF_SCRUBS_PURCHASED_DODONGOS_CAVERN_MQ_DEKU_SCRUB_SIDE_ROOM_NEAR_LOWER_LIZALFOS, "SCRUBS_PURCHASED_DODONGOS_CAVERN_MQ_DEKU_SCRUB_SIDE_ROOM_NEAR_LOWER_LIZALFOS" }, - { RAND_INF_SCRUBS_PURCHASED_GANONS_CASTLE_MQ_DEKU_SCRUB_RIGHT, "SCRUBS_PURCHASED_GANONS_CASTLE_MQ_DEKU_SCRUB_RIGHT" }, - { RAND_INF_SCRUBS_PURCHASED_GANONS_CASTLE_MQ_DEKU_SCRUB_CENTER_LEFT, "SCRUBS_PURCHASED_GANONS_CASTLE_MQ_DEKU_SCRUB_CENTER_LEFT" }, - { RAND_INF_SCRUBS_PURCHASED_GANONS_CASTLE_MQ_DEKU_SCRUB_CENTER, "SCRUBS_PURCHASED_GANONS_CASTLE_MQ_DEKU_SCRUB_CENTER" }, - { RAND_INF_SCRUBS_PURCHASED_GANONS_CASTLE_MQ_DEKU_SCRUB_CENTER_RIGHT, "SCRUBS_PURCHASED_GANONS_CASTLE_MQ_DEKU_SCRUB_CENTER_RIGHT" }, - { RAND_INF_SCRUBS_PURCHASED_GANONS_CASTLE_MQ_DEKU_SCRUB_LEFT, "SCRUBS_PURCHASED_GANONS_CASTLE_MQ_DEKU_SCRUB_LEFT" }, + { RAND_INF_SCRUBS_PURCHASED_DODONGOS_CAVERN_DEKU_SCRUB_NEAR_BOMB_BAG_LEFT, + "SCRUBS_PURCHASED_DODONGOS_CAVERN_DEKU_SCRUB_NEAR_BOMB_BAG_LEFT" }, + { RAND_INF_SCRUBS_PURCHASED_DODONGOS_CAVERN_DEKU_SCRUB_SIDE_ROOM_NEAR_DODONGOS, + "SCRUBS_PURCHASED_DODONGOS_CAVERN_DEKU_SCRUB_SIDE_ROOM_NEAR_DODONGOS" }, + { RAND_INF_SCRUBS_PURCHASED_DODONGOS_CAVERN_DEKU_SCRUB_NEAR_BOMB_BAG_RIGHT, + "SCRUBS_PURCHASED_DODONGOS_CAVERN_DEKU_SCRUB_NEAR_BOMB_BAG_RIGHT" }, + { RAND_INF_SCRUBS_PURCHASED_DODONGOS_CAVERN_DEKU_SCRUB_LOBBY, + "SCRUBS_PURCHASED_DODONGOS_CAVERN_DEKU_SCRUB_LOBBY" }, + { RAND_INF_SCRUBS_PURCHASED_JABU_JABUS_BELLY_DEKU_SCRUB, "SCRUBS_PURCHASED_JABU_JABUS_BELLY_DEKU_SCRUB" }, + { RAND_INF_SCRUBS_PURCHASED_GANONS_CASTLE_DEKU_SCRUB_CENTER_LEFT, + "SCRUBS_PURCHASED_GANONS_CASTLE_DEKU_SCRUB_CENTER_LEFT" }, + { RAND_INF_SCRUBS_PURCHASED_GANONS_CASTLE_DEKU_SCRUB_CENTER_RIGHT, + "SCRUBS_PURCHASED_GANONS_CASTLE_DEKU_SCRUB_CENTER_RIGHT" }, + { RAND_INF_SCRUBS_PURCHASED_GANONS_CASTLE_DEKU_SCRUB_RIGHT, + "SCRUBS_PURCHASED_GANONS_CASTLE_DEKU_SCRUB_RIGHT" }, + { RAND_INF_SCRUBS_PURCHASED_GANONS_CASTLE_DEKU_SCRUB_LEFT, "SCRUBS_PURCHASED_GANONS_CASTLE_DEKU_SCRUB_LEFT" }, + { RAND_INF_SCRUBS_PURCHASED_HF_DEKU_SCRUB_GROTTO, "SCRUBS_PURCHASED_HF_DEKU_SCRUB_GROTTO" }, + { RAND_INF_SCRUBS_PURCHASED_ZR_DEKU_SCRUB_GROTTO_REAR, "SCRUBS_PURCHASED_ZR_DEKU_SCRUB_GROTTO_REAR" }, + { RAND_INF_SCRUBS_PURCHASED_ZR_DEKU_SCRUB_GROTTO_FRONT, "SCRUBS_PURCHASED_ZR_DEKU_SCRUB_GROTTO_FRONT" }, + { RAND_INF_SCRUBS_PURCHASED_SFM_DEKU_SCRUB_GROTTO_REAR, "SCRUBS_PURCHASED_SFM_DEKU_SCRUB_GROTTO_REAR" }, + { RAND_INF_SCRUBS_PURCHASED_SFM_DEKU_SCRUB_GROTTO_FRONT, "SCRUBS_PURCHASED_SFM_DEKU_SCRUB_GROTTO_FRONT" }, + { RAND_INF_SCRUBS_PURCHASED_LH_DEKU_SCRUB_GROTTO_LEFT, "SCRUBS_PURCHASED_LH_DEKU_SCRUB_GROTTO_LEFT" }, + { RAND_INF_SCRUBS_PURCHASED_LH_DEKU_SCRUB_GROTTO_RIGHT, "SCRUBS_PURCHASED_LH_DEKU_SCRUB_GROTTO_RIGHT" }, + { RAND_INF_SCRUBS_PURCHASED_LH_DEKU_SCRUB_GROTTO_CENTER, "SCRUBS_PURCHASED_LH_DEKU_SCRUB_GROTTO_CENTER" }, + { RAND_INF_SCRUBS_PURCHASED_GV_DEKU_SCRUB_GROTTO_REAR, "SCRUBS_PURCHASED_GV_DEKU_SCRUB_GROTTO_REAR" }, + { RAND_INF_SCRUBS_PURCHASED_GV_DEKU_SCRUB_GROTTO_FRONT, "SCRUBS_PURCHASED_GV_DEKU_SCRUB_GROTTO_FRONT" }, + { RAND_INF_SCRUBS_PURCHASED_LW_DEKU_SCRUB_GROTTO_REAR, "SCRUBS_PURCHASED_LW_DEKU_SCRUB_GROTTO_REAR" }, + { RAND_INF_SCRUBS_PURCHASED_LW_DEKU_SCRUB_GROTTO_FRONT, "SCRUBS_PURCHASED_LW_DEKU_SCRUB_GROTTO_FRONT" }, + { RAND_INF_SCRUBS_PURCHASED_DMC_DEKU_SCRUB_GROTTO_LEFT, "SCRUBS_PURCHASED_DMC_DEKU_SCRUB_GROTTO_LEFT" }, + { RAND_INF_SCRUBS_PURCHASED_DMC_DEKU_SCRUB_GROTTO_RIGHT, "SCRUBS_PURCHASED_DMC_DEKU_SCRUB_GROTTO_RIGHT" }, + { RAND_INF_SCRUBS_PURCHASED_DMC_DEKU_SCRUB_GROTTO_CENTER, "SCRUBS_PURCHASED_DMC_DEKU_SCRUB_GROTTO_CENTER" }, + { RAND_INF_SCRUBS_PURCHASED_GC_DEKU_SCRUB_GROTTO_LEFT, "SCRUBS_PURCHASED_GC_DEKU_SCRUB_GROTTO_LEFT" }, + { RAND_INF_SCRUBS_PURCHASED_GC_DEKU_SCRUB_GROTTO_RIGHT, "SCRUBS_PURCHASED_GC_DEKU_SCRUB_GROTTO_RIGHT" }, + { RAND_INF_SCRUBS_PURCHASED_GC_DEKU_SCRUB_GROTTO_CENTER, "SCRUBS_PURCHASED_GC_DEKU_SCRUB_GROTTO_CENTER" }, + { RAND_INF_SCRUBS_PURCHASED_LLR_DEKU_SCRUB_GROTTO_LEFT, "SCRUBS_PURCHASED_LLR_DEKU_SCRUB_GROTTO_LEFT" }, + { RAND_INF_SCRUBS_PURCHASED_LLR_DEKU_SCRUB_GROTTO_RIGHT, "SCRUBS_PURCHASED_LLR_DEKU_SCRUB_GROTTO_RIGHT" }, + { RAND_INF_SCRUBS_PURCHASED_LLR_DEKU_SCRUB_GROTTO_CENTER, "SCRUBS_PURCHASED_LLR_DEKU_SCRUB_GROTTO_CENTER" }, + { RAND_INF_SCRUBS_PURCHASED_COLOSSUS_DEKU_SCRUB_GROTTO_REAR, + "SCRUBS_PURCHASED_COLOSSUS_DEKU_SCRUB_GROTTO_REAR" }, + { RAND_INF_SCRUBS_PURCHASED_COLOSSUS_DEKU_SCRUB_GROTTO_FRONT, + "SCRUBS_PURCHASED_COLOSSUS_DEKU_SCRUB_GROTTO_FRONT" }, + { RAND_INF_SCRUBS_PURCHASED_LW_DEKU_SCRUB_NEAR_DEKU_THEATER_RIGHT, + "SCRUBS_PURCHASED_LW_DEKU_SCRUB_NEAR_DEKU_THEATER_RIGHT" }, + { RAND_INF_SCRUBS_PURCHASED_LW_DEKU_SCRUB_NEAR_DEKU_THEATER_LEFT, + "SCRUBS_PURCHASED_LW_DEKU_SCRUB_NEAR_DEKU_THEATER_LEFT" }, + { RAND_INF_SCRUBS_PURCHASED_LW_DEKU_SCRUB_NEAR_BRIDGE, "SCRUBS_PURCHASED_LW_DEKU_SCRUB_NEAR_BRIDGE" }, + { RAND_INF_SCRUBS_PURCHASED_DMC_DEKU_SCRUB, "SCRUBS_PURCHASED_DMC_DEKU_SCRUB" }, + { RAND_INF_SCRUBS_PURCHASED_DEKU_TREE_MQ_DEKU_SCRUB, "SCRUBS_PURCHASED_DEKU_TREE_MQ_DEKU_SCRUB" }, + { RAND_INF_SCRUBS_PURCHASED_DODONGOS_CAVERN_MQ_DEKU_SCRUB_LOBBY_REAR, + "SCRUBS_PURCHASED_DODONGOS_CAVERN_MQ_DEKU_SCRUB_LOBBY_REAR" }, + { RAND_INF_SCRUBS_PURCHASED_DODONGOS_CAVERN_MQ_DEKU_SCRUB_LOBBY_FRONT, + "SCRUBS_PURCHASED_DODONGOS_CAVERN_MQ_DEKU_SCRUB_LOBBY_FRONT" }, + { RAND_INF_SCRUBS_PURCHASED_DODONGOS_CAVERN_MQ_DEKU_SCRUB_STAIRCASE, + "SCRUBS_PURCHASED_DODONGOS_CAVERN_MQ_DEKU_SCRUB_STAIRCASE" }, + { RAND_INF_SCRUBS_PURCHASED_DODONGOS_CAVERN_MQ_DEKU_SCRUB_SIDE_ROOM_NEAR_LOWER_LIZALFOS, + "SCRUBS_PURCHASED_DODONGOS_CAVERN_MQ_DEKU_SCRUB_SIDE_ROOM_NEAR_LOWER_LIZALFOS" }, + { RAND_INF_SCRUBS_PURCHASED_GANONS_CASTLE_MQ_DEKU_SCRUB_RIGHT, + "SCRUBS_PURCHASED_GANONS_CASTLE_MQ_DEKU_SCRUB_RIGHT" }, + { RAND_INF_SCRUBS_PURCHASED_GANONS_CASTLE_MQ_DEKU_SCRUB_CENTER_LEFT, + "SCRUBS_PURCHASED_GANONS_CASTLE_MQ_DEKU_SCRUB_CENTER_LEFT" }, + { RAND_INF_SCRUBS_PURCHASED_GANONS_CASTLE_MQ_DEKU_SCRUB_CENTER, + "SCRUBS_PURCHASED_GANONS_CASTLE_MQ_DEKU_SCRUB_CENTER" }, + { RAND_INF_SCRUBS_PURCHASED_GANONS_CASTLE_MQ_DEKU_SCRUB_CENTER_RIGHT, + "SCRUBS_PURCHASED_GANONS_CASTLE_MQ_DEKU_SCRUB_CENTER_RIGHT" }, + { RAND_INF_SCRUBS_PURCHASED_GANONS_CASTLE_MQ_DEKU_SCRUB_LEFT, + "SCRUBS_PURCHASED_GANONS_CASTLE_MQ_DEKU_SCRUB_LEFT" }, - { RAND_INF_SHOP_ITEMS_KF_SHOP_ITEM_1, "SHOP_ITEMS_KF_SHOP_ITEM_1" }, - { RAND_INF_SHOP_ITEMS_KF_SHOP_ITEM_2, "SHOP_ITEMS_KF_SHOP_ITEM_2" }, - { RAND_INF_SHOP_ITEMS_KF_SHOP_ITEM_3, "SHOP_ITEMS_KF_SHOP_ITEM_3" }, - { RAND_INF_SHOP_ITEMS_KF_SHOP_ITEM_4, "SHOP_ITEMS_KF_SHOP_ITEM_4" }, - { RAND_INF_SHOP_ITEMS_KF_SHOP_ITEM_5, "SHOP_ITEMS_KF_SHOP_ITEM_5" }, - { RAND_INF_SHOP_ITEMS_KF_SHOP_ITEM_6, "SHOP_ITEMS_KF_SHOP_ITEM_6" }, - { RAND_INF_SHOP_ITEMS_KF_SHOP_ITEM_7, "SHOP_ITEMS_KF_SHOP_ITEM_7" }, - { RAND_INF_SHOP_ITEMS_KF_SHOP_ITEM_8, "SHOP_ITEMS_KF_SHOP_ITEM_8" }, - { RAND_INF_SHOP_ITEMS_GC_SHOP_ITEM_1, "SHOP_ITEMS_GC_SHOP_ITEM_1" }, - { RAND_INF_SHOP_ITEMS_GC_SHOP_ITEM_2, "SHOP_ITEMS_GC_SHOP_ITEM_2" }, - { RAND_INF_SHOP_ITEMS_GC_SHOP_ITEM_3, "SHOP_ITEMS_GC_SHOP_ITEM_3" }, - { RAND_INF_SHOP_ITEMS_GC_SHOP_ITEM_4, "SHOP_ITEMS_GC_SHOP_ITEM_4" }, - { RAND_INF_SHOP_ITEMS_GC_SHOP_ITEM_5, "SHOP_ITEMS_GC_SHOP_ITEM_5" }, - { RAND_INF_SHOP_ITEMS_GC_SHOP_ITEM_6, "SHOP_ITEMS_GC_SHOP_ITEM_6" }, - { RAND_INF_SHOP_ITEMS_GC_SHOP_ITEM_7, "SHOP_ITEMS_GC_SHOP_ITEM_7" }, - { RAND_INF_SHOP_ITEMS_GC_SHOP_ITEM_8, "SHOP_ITEMS_GC_SHOP_ITEM_8" }, - { RAND_INF_SHOP_ITEMS_ZD_SHOP_ITEM_1, "SHOP_ITEMS_ZD_SHOP_ITEM_1" }, - { RAND_INF_SHOP_ITEMS_ZD_SHOP_ITEM_2, "SHOP_ITEMS_ZD_SHOP_ITEM_2" }, - { RAND_INF_SHOP_ITEMS_ZD_SHOP_ITEM_3, "SHOP_ITEMS_ZD_SHOP_ITEM_3" }, - { RAND_INF_SHOP_ITEMS_ZD_SHOP_ITEM_4, "SHOP_ITEMS_ZD_SHOP_ITEM_4" }, - { RAND_INF_SHOP_ITEMS_ZD_SHOP_ITEM_5, "SHOP_ITEMS_ZD_SHOP_ITEM_5" }, - { RAND_INF_SHOP_ITEMS_ZD_SHOP_ITEM_6, "SHOP_ITEMS_ZD_SHOP_ITEM_6" }, - { RAND_INF_SHOP_ITEMS_ZD_SHOP_ITEM_7, "SHOP_ITEMS_ZD_SHOP_ITEM_7" }, - { RAND_INF_SHOP_ITEMS_ZD_SHOP_ITEM_8, "SHOP_ITEMS_ZD_SHOP_ITEM_8" }, - { RAND_INF_SHOP_ITEMS_KAK_BAZAAR_ITEM_1, "SHOP_ITEMS_KAK_BAZAAR_ITEM_1" }, - { RAND_INF_SHOP_ITEMS_KAK_BAZAAR_ITEM_2, "SHOP_ITEMS_KAK_BAZAAR_ITEM_2" }, - { RAND_INF_SHOP_ITEMS_KAK_BAZAAR_ITEM_3, "SHOP_ITEMS_KAK_BAZAAR_ITEM_3" }, - { RAND_INF_SHOP_ITEMS_KAK_BAZAAR_ITEM_4, "SHOP_ITEMS_KAK_BAZAAR_ITEM_4" }, - { RAND_INF_SHOP_ITEMS_KAK_BAZAAR_ITEM_5, "SHOP_ITEMS_KAK_BAZAAR_ITEM_5" }, - { RAND_INF_SHOP_ITEMS_KAK_BAZAAR_ITEM_6, "SHOP_ITEMS_KAK_BAZAAR_ITEM_6" }, - { RAND_INF_SHOP_ITEMS_KAK_BAZAAR_ITEM_7, "SHOP_ITEMS_KAK_BAZAAR_ITEM_7" }, - { RAND_INF_SHOP_ITEMS_KAK_BAZAAR_ITEM_8, "SHOP_ITEMS_KAK_BAZAAR_ITEM_8" }, - { RAND_INF_SHOP_ITEMS_KAK_POTION_SHOP_ITEM_1, "SHOP_ITEMS_KAK_POTION_SHOP_ITEM_1" }, - { RAND_INF_SHOP_ITEMS_KAK_POTION_SHOP_ITEM_2, "SHOP_ITEMS_KAK_POTION_SHOP_ITEM_2" }, - { RAND_INF_SHOP_ITEMS_KAK_POTION_SHOP_ITEM_3, "SHOP_ITEMS_KAK_POTION_SHOP_ITEM_3" }, - { RAND_INF_SHOP_ITEMS_KAK_POTION_SHOP_ITEM_4, "SHOP_ITEMS_KAK_POTION_SHOP_ITEM_4" }, - { RAND_INF_SHOP_ITEMS_KAK_POTION_SHOP_ITEM_5, "SHOP_ITEMS_KAK_POTION_SHOP_ITEM_5" }, - { RAND_INF_SHOP_ITEMS_KAK_POTION_SHOP_ITEM_6, "SHOP_ITEMS_KAK_POTION_SHOP_ITEM_6" }, - { RAND_INF_SHOP_ITEMS_KAK_POTION_SHOP_ITEM_7, "SHOP_ITEMS_KAK_POTION_SHOP_ITEM_7" }, - { RAND_INF_SHOP_ITEMS_KAK_POTION_SHOP_ITEM_8, "SHOP_ITEMS_KAK_POTION_SHOP_ITEM_8" }, - { RAND_INF_SHOP_ITEMS_MARKET_BAZAAR_ITEM_1, "SHOP_ITEMS_MARKET_BAZAAR_ITEM_1" }, - { RAND_INF_SHOP_ITEMS_MARKET_BAZAAR_ITEM_2, "SHOP_ITEMS_MARKET_BAZAAR_ITEM_2" }, - { RAND_INF_SHOP_ITEMS_MARKET_BAZAAR_ITEM_3, "SHOP_ITEMS_MARKET_BAZAAR_ITEM_3" }, - { RAND_INF_SHOP_ITEMS_MARKET_BAZAAR_ITEM_4, "SHOP_ITEMS_MARKET_BAZAAR_ITEM_4" }, - { RAND_INF_SHOP_ITEMS_MARKET_BAZAAR_ITEM_5, "SHOP_ITEMS_MARKET_BAZAAR_ITEM_5" }, - { RAND_INF_SHOP_ITEMS_MARKET_BAZAAR_ITEM_6, "SHOP_ITEMS_MARKET_BAZAAR_ITEM_6" }, - { RAND_INF_SHOP_ITEMS_MARKET_BAZAAR_ITEM_7, "SHOP_ITEMS_MARKET_BAZAAR_ITEM_7" }, - { RAND_INF_SHOP_ITEMS_MARKET_BAZAAR_ITEM_8, "SHOP_ITEMS_MARKET_BAZAAR_ITEM_8" }, - { RAND_INF_SHOP_ITEMS_MARKET_POTION_SHOP_ITEM_1, "SHOP_ITEMS_MARKET_POTION_SHOP_ITEM_1" }, - { RAND_INF_SHOP_ITEMS_MARKET_POTION_SHOP_ITEM_2, "SHOP_ITEMS_MARKET_POTION_SHOP_ITEM_2" }, - { RAND_INF_SHOP_ITEMS_MARKET_POTION_SHOP_ITEM_3, "SHOP_ITEMS_MARKET_POTION_SHOP_ITEM_3" }, - { RAND_INF_SHOP_ITEMS_MARKET_POTION_SHOP_ITEM_4, "SHOP_ITEMS_MARKET_POTION_SHOP_ITEM_4" }, - { RAND_INF_SHOP_ITEMS_MARKET_POTION_SHOP_ITEM_5, "SHOP_ITEMS_MARKET_POTION_SHOP_ITEM_5" }, - { RAND_INF_SHOP_ITEMS_MARKET_POTION_SHOP_ITEM_6, "SHOP_ITEMS_MARKET_POTION_SHOP_ITEM_6" }, - { RAND_INF_SHOP_ITEMS_MARKET_POTION_SHOP_ITEM_7, "SHOP_ITEMS_MARKET_POTION_SHOP_ITEM_7" }, - { RAND_INF_SHOP_ITEMS_MARKET_POTION_SHOP_ITEM_8, "SHOP_ITEMS_MARKET_POTION_SHOP_ITEM_8" }, - { RAND_INF_SHOP_ITEMS_MARKET_BOMBCHU_SHOP_ITEM_1, "SHOP_ITEMS_MARKET_BOMBCHU_SHOP_ITEM_1" }, - { RAND_INF_SHOP_ITEMS_MARKET_BOMBCHU_SHOP_ITEM_2, "SHOP_ITEMS_MARKET_BOMBCHU_SHOP_ITEM_2" }, - { RAND_INF_SHOP_ITEMS_MARKET_BOMBCHU_SHOP_ITEM_3, "SHOP_ITEMS_MARKET_BOMBCHU_SHOP_ITEM_3" }, - { RAND_INF_SHOP_ITEMS_MARKET_BOMBCHU_SHOP_ITEM_4, "SHOP_ITEMS_MARKET_BOMBCHU_SHOP_ITEM_4" }, - { RAND_INF_SHOP_ITEMS_MARKET_BOMBCHU_SHOP_ITEM_5, "SHOP_ITEMS_MARKET_BOMBCHU_SHOP_ITEM_5" }, - { RAND_INF_SHOP_ITEMS_MARKET_BOMBCHU_SHOP_ITEM_6, "SHOP_ITEMS_MARKET_BOMBCHU_SHOP_ITEM_6" }, - { RAND_INF_SHOP_ITEMS_MARKET_BOMBCHU_SHOP_ITEM_7, "SHOP_ITEMS_MARKET_BOMBCHU_SHOP_ITEM_7" }, - { RAND_INF_SHOP_ITEMS_MARKET_BOMBCHU_SHOP_ITEM_8, "SHOP_ITEMS_MARKET_BOMBCHU_SHOP_ITEM_8" }, + { RAND_INF_SHOP_ITEMS_KF_SHOP_ITEM_1, "SHOP_ITEMS_KF_SHOP_ITEM_1" }, + { RAND_INF_SHOP_ITEMS_KF_SHOP_ITEM_2, "SHOP_ITEMS_KF_SHOP_ITEM_2" }, + { RAND_INF_SHOP_ITEMS_KF_SHOP_ITEM_3, "SHOP_ITEMS_KF_SHOP_ITEM_3" }, + { RAND_INF_SHOP_ITEMS_KF_SHOP_ITEM_4, "SHOP_ITEMS_KF_SHOP_ITEM_4" }, + { RAND_INF_SHOP_ITEMS_KF_SHOP_ITEM_5, "SHOP_ITEMS_KF_SHOP_ITEM_5" }, + { RAND_INF_SHOP_ITEMS_KF_SHOP_ITEM_6, "SHOP_ITEMS_KF_SHOP_ITEM_6" }, + { RAND_INF_SHOP_ITEMS_KF_SHOP_ITEM_7, "SHOP_ITEMS_KF_SHOP_ITEM_7" }, + { RAND_INF_SHOP_ITEMS_KF_SHOP_ITEM_8, "SHOP_ITEMS_KF_SHOP_ITEM_8" }, + { RAND_INF_SHOP_ITEMS_GC_SHOP_ITEM_1, "SHOP_ITEMS_GC_SHOP_ITEM_1" }, + { RAND_INF_SHOP_ITEMS_GC_SHOP_ITEM_2, "SHOP_ITEMS_GC_SHOP_ITEM_2" }, + { RAND_INF_SHOP_ITEMS_GC_SHOP_ITEM_3, "SHOP_ITEMS_GC_SHOP_ITEM_3" }, + { RAND_INF_SHOP_ITEMS_GC_SHOP_ITEM_4, "SHOP_ITEMS_GC_SHOP_ITEM_4" }, + { RAND_INF_SHOP_ITEMS_GC_SHOP_ITEM_5, "SHOP_ITEMS_GC_SHOP_ITEM_5" }, + { RAND_INF_SHOP_ITEMS_GC_SHOP_ITEM_6, "SHOP_ITEMS_GC_SHOP_ITEM_6" }, + { RAND_INF_SHOP_ITEMS_GC_SHOP_ITEM_7, "SHOP_ITEMS_GC_SHOP_ITEM_7" }, + { RAND_INF_SHOP_ITEMS_GC_SHOP_ITEM_8, "SHOP_ITEMS_GC_SHOP_ITEM_8" }, + { RAND_INF_SHOP_ITEMS_ZD_SHOP_ITEM_1, "SHOP_ITEMS_ZD_SHOP_ITEM_1" }, + { RAND_INF_SHOP_ITEMS_ZD_SHOP_ITEM_2, "SHOP_ITEMS_ZD_SHOP_ITEM_2" }, + { RAND_INF_SHOP_ITEMS_ZD_SHOP_ITEM_3, "SHOP_ITEMS_ZD_SHOP_ITEM_3" }, + { RAND_INF_SHOP_ITEMS_ZD_SHOP_ITEM_4, "SHOP_ITEMS_ZD_SHOP_ITEM_4" }, + { RAND_INF_SHOP_ITEMS_ZD_SHOP_ITEM_5, "SHOP_ITEMS_ZD_SHOP_ITEM_5" }, + { RAND_INF_SHOP_ITEMS_ZD_SHOP_ITEM_6, "SHOP_ITEMS_ZD_SHOP_ITEM_6" }, + { RAND_INF_SHOP_ITEMS_ZD_SHOP_ITEM_7, "SHOP_ITEMS_ZD_SHOP_ITEM_7" }, + { RAND_INF_SHOP_ITEMS_ZD_SHOP_ITEM_8, "SHOP_ITEMS_ZD_SHOP_ITEM_8" }, + { RAND_INF_SHOP_ITEMS_KAK_BAZAAR_ITEM_1, "SHOP_ITEMS_KAK_BAZAAR_ITEM_1" }, + { RAND_INF_SHOP_ITEMS_KAK_BAZAAR_ITEM_2, "SHOP_ITEMS_KAK_BAZAAR_ITEM_2" }, + { RAND_INF_SHOP_ITEMS_KAK_BAZAAR_ITEM_3, "SHOP_ITEMS_KAK_BAZAAR_ITEM_3" }, + { RAND_INF_SHOP_ITEMS_KAK_BAZAAR_ITEM_4, "SHOP_ITEMS_KAK_BAZAAR_ITEM_4" }, + { RAND_INF_SHOP_ITEMS_KAK_BAZAAR_ITEM_5, "SHOP_ITEMS_KAK_BAZAAR_ITEM_5" }, + { RAND_INF_SHOP_ITEMS_KAK_BAZAAR_ITEM_6, "SHOP_ITEMS_KAK_BAZAAR_ITEM_6" }, + { RAND_INF_SHOP_ITEMS_KAK_BAZAAR_ITEM_7, "SHOP_ITEMS_KAK_BAZAAR_ITEM_7" }, + { RAND_INF_SHOP_ITEMS_KAK_BAZAAR_ITEM_8, "SHOP_ITEMS_KAK_BAZAAR_ITEM_8" }, + { RAND_INF_SHOP_ITEMS_KAK_POTION_SHOP_ITEM_1, "SHOP_ITEMS_KAK_POTION_SHOP_ITEM_1" }, + { RAND_INF_SHOP_ITEMS_KAK_POTION_SHOP_ITEM_2, "SHOP_ITEMS_KAK_POTION_SHOP_ITEM_2" }, + { RAND_INF_SHOP_ITEMS_KAK_POTION_SHOP_ITEM_3, "SHOP_ITEMS_KAK_POTION_SHOP_ITEM_3" }, + { RAND_INF_SHOP_ITEMS_KAK_POTION_SHOP_ITEM_4, "SHOP_ITEMS_KAK_POTION_SHOP_ITEM_4" }, + { RAND_INF_SHOP_ITEMS_KAK_POTION_SHOP_ITEM_5, "SHOP_ITEMS_KAK_POTION_SHOP_ITEM_5" }, + { RAND_INF_SHOP_ITEMS_KAK_POTION_SHOP_ITEM_6, "SHOP_ITEMS_KAK_POTION_SHOP_ITEM_6" }, + { RAND_INF_SHOP_ITEMS_KAK_POTION_SHOP_ITEM_7, "SHOP_ITEMS_KAK_POTION_SHOP_ITEM_7" }, + { RAND_INF_SHOP_ITEMS_KAK_POTION_SHOP_ITEM_8, "SHOP_ITEMS_KAK_POTION_SHOP_ITEM_8" }, + { RAND_INF_SHOP_ITEMS_MARKET_BAZAAR_ITEM_1, "SHOP_ITEMS_MARKET_BAZAAR_ITEM_1" }, + { RAND_INF_SHOP_ITEMS_MARKET_BAZAAR_ITEM_2, "SHOP_ITEMS_MARKET_BAZAAR_ITEM_2" }, + { RAND_INF_SHOP_ITEMS_MARKET_BAZAAR_ITEM_3, "SHOP_ITEMS_MARKET_BAZAAR_ITEM_3" }, + { RAND_INF_SHOP_ITEMS_MARKET_BAZAAR_ITEM_4, "SHOP_ITEMS_MARKET_BAZAAR_ITEM_4" }, + { RAND_INF_SHOP_ITEMS_MARKET_BAZAAR_ITEM_5, "SHOP_ITEMS_MARKET_BAZAAR_ITEM_5" }, + { RAND_INF_SHOP_ITEMS_MARKET_BAZAAR_ITEM_6, "SHOP_ITEMS_MARKET_BAZAAR_ITEM_6" }, + { RAND_INF_SHOP_ITEMS_MARKET_BAZAAR_ITEM_7, "SHOP_ITEMS_MARKET_BAZAAR_ITEM_7" }, + { RAND_INF_SHOP_ITEMS_MARKET_BAZAAR_ITEM_8, "SHOP_ITEMS_MARKET_BAZAAR_ITEM_8" }, + { RAND_INF_SHOP_ITEMS_MARKET_POTION_SHOP_ITEM_1, "SHOP_ITEMS_MARKET_POTION_SHOP_ITEM_1" }, + { RAND_INF_SHOP_ITEMS_MARKET_POTION_SHOP_ITEM_2, "SHOP_ITEMS_MARKET_POTION_SHOP_ITEM_2" }, + { RAND_INF_SHOP_ITEMS_MARKET_POTION_SHOP_ITEM_3, "SHOP_ITEMS_MARKET_POTION_SHOP_ITEM_3" }, + { RAND_INF_SHOP_ITEMS_MARKET_POTION_SHOP_ITEM_4, "SHOP_ITEMS_MARKET_POTION_SHOP_ITEM_4" }, + { RAND_INF_SHOP_ITEMS_MARKET_POTION_SHOP_ITEM_5, "SHOP_ITEMS_MARKET_POTION_SHOP_ITEM_5" }, + { RAND_INF_SHOP_ITEMS_MARKET_POTION_SHOP_ITEM_6, "SHOP_ITEMS_MARKET_POTION_SHOP_ITEM_6" }, + { RAND_INF_SHOP_ITEMS_MARKET_POTION_SHOP_ITEM_7, "SHOP_ITEMS_MARKET_POTION_SHOP_ITEM_7" }, + { RAND_INF_SHOP_ITEMS_MARKET_POTION_SHOP_ITEM_8, "SHOP_ITEMS_MARKET_POTION_SHOP_ITEM_8" }, + { RAND_INF_SHOP_ITEMS_MARKET_BOMBCHU_SHOP_ITEM_1, "SHOP_ITEMS_MARKET_BOMBCHU_SHOP_ITEM_1" }, + { RAND_INF_SHOP_ITEMS_MARKET_BOMBCHU_SHOP_ITEM_2, "SHOP_ITEMS_MARKET_BOMBCHU_SHOP_ITEM_2" }, + { RAND_INF_SHOP_ITEMS_MARKET_BOMBCHU_SHOP_ITEM_3, "SHOP_ITEMS_MARKET_BOMBCHU_SHOP_ITEM_3" }, + { RAND_INF_SHOP_ITEMS_MARKET_BOMBCHU_SHOP_ITEM_4, "SHOP_ITEMS_MARKET_BOMBCHU_SHOP_ITEM_4" }, + { RAND_INF_SHOP_ITEMS_MARKET_BOMBCHU_SHOP_ITEM_5, "SHOP_ITEMS_MARKET_BOMBCHU_SHOP_ITEM_5" }, + { RAND_INF_SHOP_ITEMS_MARKET_BOMBCHU_SHOP_ITEM_6, "SHOP_ITEMS_MARKET_BOMBCHU_SHOP_ITEM_6" }, + { RAND_INF_SHOP_ITEMS_MARKET_BOMBCHU_SHOP_ITEM_7, "SHOP_ITEMS_MARKET_BOMBCHU_SHOP_ITEM_7" }, + { RAND_INF_SHOP_ITEMS_MARKET_BOMBCHU_SHOP_ITEM_8, "SHOP_ITEMS_MARKET_BOMBCHU_SHOP_ITEM_8" }, - { RAND_INF_MERCHANTS_CARPET_SALESMAN, "RAND_INF_MERCHANTS_CARPET_SALESMAN" }, - { RAND_INF_MERCHANTS_MEDIGORON, "RAND_INF_MERCHANTS_MEDIGORON" }, - { RAND_INF_MERCHANTS_GRANNYS_SHOP, "RAND_INF_MERCHANTS_GRANNY_SHOP"}, - { RAND_INF_MERCHANTS_MAGIC_BEAN_SALESMAN, "RAND_INF_MERCHANTS_MAGIC_BEAN_SALESMAN"}, + { RAND_INF_MERCHANTS_CARPET_SALESMAN, "RAND_INF_MERCHANTS_CARPET_SALESMAN" }, + { RAND_INF_MERCHANTS_MEDIGORON, "RAND_INF_MERCHANTS_MEDIGORON" }, + { RAND_INF_MERCHANTS_GRANNYS_SHOP, "RAND_INF_MERCHANTS_GRANNY_SHOP" }, + { RAND_INF_MERCHANTS_MAGIC_BEAN_SALESMAN, "RAND_INF_MERCHANTS_MAGIC_BEAN_SALESMAN" }, - { RAND_INF_ADULT_TRADES_LW_TRADE_COJIRO, "ADULT_TRADES_LW_TRADE_COJIRO" }, - { RAND_INF_ADULT_TRADES_GV_TRADE_SAW, "ADULT_TRADES_GV_TRADE_SAW" }, - { RAND_INF_ADULT_TRADES_DMT_TRADE_BROKEN_SWORD, "ADULT_TRADES_DMT_TRADE_BROKEN_SWORD" }, - { RAND_INF_ADULT_TRADES_LH_TRADE_FROG, "ADULT_TRADES_LH_TRADE_FROG" }, - { RAND_INF_ADULT_TRADES_DMT_TRADE_EYEDROPS, "ADULT_TRADES_DMT_TRADE_EYEDROPS" }, + { RAND_INF_ADULT_TRADES_LW_TRADE_COJIRO, "ADULT_TRADES_LW_TRADE_COJIRO" }, + { RAND_INF_ADULT_TRADES_GV_TRADE_SAW, "ADULT_TRADES_GV_TRADE_SAW" }, + { RAND_INF_ADULT_TRADES_DMT_TRADE_BROKEN_SWORD, "ADULT_TRADES_DMT_TRADE_BROKEN_SWORD" }, + { RAND_INF_ADULT_TRADES_LH_TRADE_FROG, "ADULT_TRADES_LH_TRADE_FROG" }, + { RAND_INF_ADULT_TRADES_DMT_TRADE_EYEDROPS, "ADULT_TRADES_DMT_TRADE_EYEDROPS" }, - { RAND_INF_KAK_100_GOLD_SKULLTULA_REWARD, "KAK_100_GOLD_SKULLTULA_REWARD" }, - { RAND_INF_GREG_FOUND, "RAND_INF_GREG_FOUND" }, + { RAND_INF_KAK_100_GOLD_SKULLTULA_REWARD, "KAK_100_GOLD_SKULLTULA_REWARD" }, + { RAND_INF_GREG_FOUND, "RAND_INF_GREG_FOUND" }, - { RAND_INF_TOT_MASTER_SWORD, "RAND_INF_TOT_MASTER_SWORD"}, - { RAND_INF_CHILD_FISHING, "RAND_INF_CHILD_FISHING" }, - { RAND_INF_ADULT_FISHING, "RAND_INF_ADULT_FISHING" }, - { RAND_INF_10_BIG_POES, "RAND_INF_10_BIG_POES" }, - { RAND_INF_GRANT_GANONS_BOSSKEY, "RAND_INF_GRANT_GANONS_BOSSKEY" }, + { RAND_INF_TOT_MASTER_SWORD, "RAND_INF_TOT_MASTER_SWORD" }, + { RAND_INF_CHILD_FISHING, "RAND_INF_CHILD_FISHING" }, + { RAND_INF_ADULT_FISHING, "RAND_INF_ADULT_FISHING" }, + { RAND_INF_10_BIG_POES, "RAND_INF_10_BIG_POES" }, + { RAND_INF_GRANT_GANONS_BOSSKEY, "RAND_INF_GRANT_GANONS_BOSSKEY" }, - { RAND_INF_GOHMA_SOUL, "RAND_INF_GOHMA_SOUL" }, - { RAND_INF_KING_DODONGO_SOUL, "RAND_INF_KING_DODONGO_SOUL" }, - { RAND_INF_BARINADE_SOUL, "RAND_INF_BARINADE_SOUL" }, - { RAND_INF_PHANTOM_GANON_SOUL, "RAND_INF_PHANTOM_GANON_SOUL" }, - { RAND_INF_VOLVAGIA_SOUL, "RAND_INF_VOLVAGIA_SOUL" }, - { RAND_INF_MORPHA_SOUL, "RAND_INF_MORPHA_SOUL" }, - { RAND_INF_BONGO_BONGO_SOUL, "RAND_INF_BONGO_BONGO_SOUL" }, - { RAND_INF_TWINROVA_SOUL, "RAND_INF_TWINROVA_SOUL" }, - { RAND_INF_GANON_SOUL, "RAND_INF_GANON_SOUL" }, + { RAND_INF_GOHMA_SOUL, "RAND_INF_GOHMA_SOUL" }, + { RAND_INF_KING_DODONGO_SOUL, "RAND_INF_KING_DODONGO_SOUL" }, + { RAND_INF_BARINADE_SOUL, "RAND_INF_BARINADE_SOUL" }, + { RAND_INF_PHANTOM_GANON_SOUL, "RAND_INF_PHANTOM_GANON_SOUL" }, + { RAND_INF_VOLVAGIA_SOUL, "RAND_INF_VOLVAGIA_SOUL" }, + { RAND_INF_MORPHA_SOUL, "RAND_INF_MORPHA_SOUL" }, + { RAND_INF_BONGO_BONGO_SOUL, "RAND_INF_BONGO_BONGO_SOUL" }, + { RAND_INF_TWINROVA_SOUL, "RAND_INF_TWINROVA_SOUL" }, + { RAND_INF_GANON_SOUL, "RAND_INF_GANON_SOUL" }, - { RAND_INF_HAS_OCARINA_A, "RAND_INF_HAS_OCARINA_A"}, - { RAND_INF_HAS_OCARINA_C_UP, "RAND_INF_HAS_OCARINA_C_UP" }, - { RAND_INF_HAS_OCARINA_C_DOWN, "RAND_INF_HAS_OCARINA_C_DOWN" }, - { RAND_INF_HAS_OCARINA_C_LEFT, "RAND_INF_HAS_OCARINA_C_LEFT"}, - { RAND_INF_HAS_OCARINA_C_RIGHT, "RAND_INF_HAS_OCARINA_C_RIGHT"}, + { RAND_INF_HAS_OCARINA_A, "RAND_INF_HAS_OCARINA_A" }, + { RAND_INF_HAS_OCARINA_C_UP, "RAND_INF_HAS_OCARINA_C_UP" }, + { RAND_INF_HAS_OCARINA_C_DOWN, "RAND_INF_HAS_OCARINA_C_DOWN" }, + { RAND_INF_HAS_OCARINA_C_LEFT, "RAND_INF_HAS_OCARINA_C_LEFT" }, + { RAND_INF_HAS_OCARINA_C_RIGHT, "RAND_INF_HAS_OCARINA_C_RIGHT" }, - { RAND_INF_KF_LINKS_HOUSE_POT, "RAND_INF_KF_LINKS_HOUSE_POT" }, - { RAND_INF_KF_TWINS_HOUSE_POT_1, "RAND_INF_KF_TWINS_HOUSE_POT_1" }, - { RAND_INF_KF_TWINS_HOUSE_POT_2, "RAND_INF_KF_TWINS_HOUSE_POT_2" }, - { RAND_INF_KF_BROTHERS_HOUSE_POT_1, "RAND_INF_KF_BROTHERS_HOUSE_POT_1" }, - { RAND_INF_KF_BROTHERS_HOUSE_POT_2, "RAND_INF_KF_BROTHERS_HOUSE_POT_2" }, - { RAND_INF_GF_BREAK_ROOM_POT_1, "RAND_INF_GF_BREAK_ROOM_POT_1" }, - { RAND_INF_GF_BREAK_ROOM_POT_2, "RAND_INF_GF_BREAK_ROOM_POT_2" }, - { RAND_INF_GF_KITCHEN_POT_1, "RAND_INF_GF_KITCHEN_POT_1" }, - { RAND_INF_GF_KITCHEN_POT_2, "RAND_INF_GF_KITCHEN_POT_2" }, - { RAND_INF_GF_NORTH_F1_CARPENTER_POT_1, "RAND_INF_GF_NORTH_F1_CARPENTER_POT_1" }, - { RAND_INF_GF_NORTH_F1_CARPENTER_POT_2, "RAND_INF_GF_NORTH_F1_CARPENTER_POT_2" }, - { RAND_INF_GF_NORTH_F1_CARPENTER_POT_3, "RAND_INF_GF_NORTH_F1_CARPENTER_POT_3" }, - { RAND_INF_GF_NORTH_F2_CARPENTER_POT_1, "RAND_INF_GF_NORTH_F2_CARPENTER_POT_1" }, - { RAND_INF_GF_NORTH_F2_CARPENTER_POT_2, "RAND_INF_GF_NORTH_F2_CARPENTER_POT_2" }, - { RAND_INF_GF_SOUTH_F1_CARPENTER_POT_1, "RAND_INF_GF_SOUTH_F1_CARPENTER_POT_1" }, - { RAND_INF_GF_SOUTH_F1_CARPENTER_POT_2, "RAND_INF_GF_SOUTH_F1_CARPENTER_POT_2" }, - { RAND_INF_GF_SOUTH_F1_CARPENTER_POT_3, "RAND_INF_GF_SOUTH_F1_CARPENTER_POT_3" }, - { RAND_INF_GF_SOUTH_F1_CARPENTER_CELL_POT_1, "RAND_INF_GF_SOUTH_F1_CARPENTER_CELL_POT_1" }, - { RAND_INF_GF_SOUTH_F1_CARPENTER_CELL_POT_2, "RAND_INF_GF_SOUTH_F1_CARPENTER_CELL_POT_2" }, - { RAND_INF_GF_SOUTH_F1_CARPENTER_CELL_POT_3, "RAND_INF_GF_SOUTH_F1_CARPENTER_CELL_POT_3" }, - { RAND_INF_GF_SOUTH_F1_CARPENTER_CELL_POT_4, "RAND_INF_GF_SOUTH_F1_CARPENTER_CELL_POT_4" }, - { RAND_INF_WASTELAND_NEAR_GS_POT_1, "RAND_INF_WASTELAND_NEAR_GS_POT_1" }, - { RAND_INF_WASTELAND_NEAR_GS_POT_2, "RAND_INF_WASTELAND_NEAR_GS_POT_2" }, - { RAND_INF_WASTELAND_NEAR_GS_POT_3, "RAND_INF_WASTELAND_NEAR_GS_POT_3" }, - { RAND_INF_WASTELAND_NEAR_GS_POT_4, "RAND_INF_WASTELAND_NEAR_GS_POT_4" }, - { RAND_INF_MK_GUARD_HOUSE_CHILD_POT_1, "RAND_INF_MK_GUARD_HOUSE_CHILD_POT_1" }, - { RAND_INF_MK_GUARD_HOUSE_CHILD_POT_2, "RAND_INF_MK_GUARD_HOUSE_CHILD_POT_2" }, - { RAND_INF_MK_GUARD_HOUSE_CHILD_POT_3, "RAND_INF_MK_GUARD_HOUSE_CHILD_POT_3" }, - { RAND_INF_MK_GUARD_HOUSE_CHILD_POT_4, "RAND_INF_MK_GUARD_HOUSE_CHILD_POT_4" }, - { RAND_INF_MK_GUARD_HOUSE_CHILD_POT_5, "RAND_INF_MK_GUARD_HOUSE_CHILD_POT_5" }, - { RAND_INF_MK_GUARD_HOUSE_CHILD_POT_6, "RAND_INF_MK_GUARD_HOUSE_CHILD_POT_6" }, - { RAND_INF_MK_GUARD_HOUSE_CHILD_POT_7, "RAND_INF_MK_GUARD_HOUSE_CHILD_POT_7" }, - { RAND_INF_MK_GUARD_HOUSE_CHILD_POT_8, "RAND_INF_MK_GUARD_HOUSE_CHILD_POT_8" }, - { RAND_INF_MK_GUARD_HOUSE_CHILD_POT_9, "RAND_INF_MK_GUARD_HOUSE_CHILD_POT_9" }, - { RAND_INF_MK_GUARD_HOUSE_CHILD_POT_10, "RAND_INF_MK_GUARD_HOUSE_CHILD_POT_10" }, - { RAND_INF_MK_GUARD_HOUSE_CHILD_POT_11, "RAND_INF_MK_GUARD_HOUSE_CHILD_POT_11" }, - { RAND_INF_MK_GUARD_HOUSE_CHILD_POT_12, "RAND_INF_MK_GUARD_HOUSE_CHILD_POT_12" }, - { RAND_INF_MK_GUARD_HOUSE_CHILD_POT_13, "RAND_INF_MK_GUARD_HOUSE_CHILD_POT_13" }, - { RAND_INF_MK_GUARD_HOUSE_CHILD_POT_14, "RAND_INF_MK_GUARD_HOUSE_CHILD_POT_14" }, - { RAND_INF_MK_GUARD_HOUSE_CHILD_POT_15, "RAND_INF_MK_GUARD_HOUSE_CHILD_POT_15" }, - { RAND_INF_MK_GUARD_HOUSE_CHILD_POT_16, "RAND_INF_MK_GUARD_HOUSE_CHILD_POT_16" }, - { RAND_INF_MK_GUARD_HOUSE_CHILD_POT_17, "RAND_INF_MK_GUARD_HOUSE_CHILD_POT_17" }, - { RAND_INF_MK_GUARD_HOUSE_CHILD_POT_18, "RAND_INF_MK_GUARD_HOUSE_CHILD_POT_18" }, - { RAND_INF_MK_GUARD_HOUSE_CHILD_POT_19, "RAND_INF_MK_GUARD_HOUSE_CHILD_POT_19" }, - { RAND_INF_MK_GUARD_HOUSE_CHILD_POT_20, "RAND_INF_MK_GUARD_HOUSE_CHILD_POT_20" }, - { RAND_INF_MK_GUARD_HOUSE_CHILD_POT_21, "RAND_INF_MK_GUARD_HOUSE_CHILD_POT_21" }, - { RAND_INF_MK_GUARD_HOUSE_CHILD_POT_22, "RAND_INF_MK_GUARD_HOUSE_CHILD_POT_22" }, - { RAND_INF_MK_GUARD_HOUSE_CHILD_POT_23, "RAND_INF_MK_GUARD_HOUSE_CHILD_POT_23" }, - { RAND_INF_MK_GUARD_HOUSE_CHILD_POT_24, "RAND_INF_MK_GUARD_HOUSE_CHILD_POT_24" }, - { RAND_INF_MK_GUARD_HOUSE_CHILD_POT_25, "RAND_INF_MK_GUARD_HOUSE_CHILD_POT_25" }, - { RAND_INF_MK_GUARD_HOUSE_CHILD_POT_26, "RAND_INF_MK_GUARD_HOUSE_CHILD_POT_26" }, - { RAND_INF_MK_GUARD_HOUSE_CHILD_POT_27, "RAND_INF_MK_GUARD_HOUSE_CHILD_POT_27" }, - { RAND_INF_MK_GUARD_HOUSE_CHILD_POT_28, "RAND_INF_MK_GUARD_HOUSE_CHILD_POT_28" }, - { RAND_INF_MK_GUARD_HOUSE_CHILD_POT_29, "RAND_INF_MK_GUARD_HOUSE_CHILD_POT_29" }, - { RAND_INF_MK_GUARD_HOUSE_CHILD_POT_30, "RAND_INF_MK_GUARD_HOUSE_CHILD_POT_30" }, - { RAND_INF_MK_GUARD_HOUSE_CHILD_POT_31, "RAND_INF_MK_GUARD_HOUSE_CHILD_POT_31" }, - { RAND_INF_MK_GUARD_HOUSE_CHILD_POT_32, "RAND_INF_MK_GUARD_HOUSE_CHILD_POT_32" }, - { RAND_INF_MK_GUARD_HOUSE_CHILD_POT_33, "RAND_INF_MK_GUARD_HOUSE_CHILD_POT_33" }, - { RAND_INF_MK_GUARD_HOUSE_CHILD_POT_34, "RAND_INF_MK_GUARD_HOUSE_CHILD_POT_34" }, - { RAND_INF_MK_GUARD_HOUSE_CHILD_POT_35, "RAND_INF_MK_GUARD_HOUSE_CHILD_POT_35" }, - { RAND_INF_MK_GUARD_HOUSE_CHILD_POT_36, "RAND_INF_MK_GUARD_HOUSE_CHILD_POT_36" }, - { RAND_INF_MK_GUARD_HOUSE_CHILD_POT_37, "RAND_INF_MK_GUARD_HOUSE_CHILD_POT_37" }, - { RAND_INF_MK_GUARD_HOUSE_CHILD_POT_38, "RAND_INF_MK_GUARD_HOUSE_CHILD_POT_38" }, - { RAND_INF_MK_GUARD_HOUSE_CHILD_POT_39, "RAND_INF_MK_GUARD_HOUSE_CHILD_POT_39" }, - { RAND_INF_MK_GUARD_HOUSE_CHILD_POT_40, "RAND_INF_MK_GUARD_HOUSE_CHILD_POT_40" }, - { RAND_INF_MK_GUARD_HOUSE_CHILD_POT_41, "RAND_INF_MK_GUARD_HOUSE_CHILD_POT_41" }, - { RAND_INF_MK_GUARD_HOUSE_CHILD_POT_42, "RAND_INF_MK_GUARD_HOUSE_CHILD_POT_42" }, - { RAND_INF_MK_GUARD_HOUSE_CHILD_POT_43, "RAND_INF_MK_GUARD_HOUSE_CHILD_POT_43" }, - { RAND_INF_MK_GUARD_HOUSE_CHILD_POT_44, "RAND_INF_MK_GUARD_HOUSE_CHILD_POT_44" }, - { RAND_INF_MK_GUARD_HOUSE_ADULT_POT_1, "RAND_INF_MK_GUARD_HOUSE_ADULT_POT_1" }, - { RAND_INF_MK_GUARD_HOUSE_ADULT_POT_2, "RAND_INF_MK_GUARD_HOUSE_ADULT_POT_2" }, - { RAND_INF_MK_GUARD_HOUSE_ADULT_POT_3, "RAND_INF_MK_GUARD_HOUSE_ADULT_POT_3" }, - { RAND_INF_MK_GUARD_HOUSE_ADULT_POT_4, "RAND_INF_MK_GUARD_HOUSE_ADULT_POT_4" }, - { RAND_INF_MK_GUARD_HOUSE_ADULT_POT_5, "RAND_INF_MK_GUARD_HOUSE_ADULT_POT_5" }, - { RAND_INF_MK_GUARD_HOUSE_ADULT_POT_6, "RAND_INF_MK_GUARD_HOUSE_ADULT_POT_6" }, - { RAND_INF_MK_GUARD_HOUSE_ADULT_POT_7, "RAND_INF_MK_GUARD_HOUSE_ADULT_POT_7" }, - { RAND_INF_MK_GUARD_HOUSE_ADULT_POT_8, "RAND_INF_MK_GUARD_HOUSE_ADULT_POT_8" }, - { RAND_INF_MK_GUARD_HOUSE_ADULT_POT_9, "RAND_INF_MK_GUARD_HOUSE_ADULT_POT_9" }, - { RAND_INF_MK_GUARD_HOUSE_ADULT_POT_10, "RAND_INF_MK_GUARD_HOUSE_ADULT_POT_10" }, - { RAND_INF_MK_GUARD_HOUSE_ADULT_POT_11, "RAND_INF_MK_GUARD_HOUSE_ADULT_POT_11" }, - { RAND_INF_MK_BACK_ALLEY_HOUSE_POT_1, "RAND_INF_MK_BACK_ALLEY_HOUSE_POT_1" }, - { RAND_INF_MK_BACK_ALLEY_HOUSE_POT_2, "RAND_INF_MK_BACK_ALLEY_HOUSE_POT_2" }, - { RAND_INF_MK_BACK_ALLEY_HOUSE_POT_3, "RAND_INF_MK_BACK_ALLEY_HOUSE_POT_3" }, - { RAND_INF_KAK_NEAR_POTION_SHOP_POT_1, "RAND_INF_KAK_NEAR_POTION_SHOP_POT_1" }, - { RAND_INF_KAK_NEAR_POTION_SHOP_POT_2, "RAND_INF_KAK_NEAR_POTION_SHOP_POT_2" }, - { RAND_INF_KAK_NEAR_POTION_SHOP_POT_3, "RAND_INF_KAK_NEAR_POTION_SHOP_POT_3" }, - { RAND_INF_KAK_NEAR_IMPAS_HOUSE_POT_1, "RAND_INF_KAK_NEAR_IMPAS_HOUSE_POT_1" }, - { RAND_INF_KAK_NEAR_IMPAS_HOUSE_POT_2, "RAND_INF_KAK_NEAR_IMPAS_HOUSE_POT_2" }, - { RAND_INF_KAK_NEAR_IMPAS_HOUSE_POT_3, "RAND_INF_KAK_NEAR_IMPAS_HOUSE_POT_3" }, - { RAND_INF_KAK_NEAR_GUARDS_HOUSE_POT_1, "RAND_INF_KAK_NEAR_GUARDS_HOUSE_POT_1" }, - { RAND_INF_KAK_NEAR_GUARDS_HOUSE_POT_2, "RAND_INF_KAK_NEAR_GUARDS_HOUSE_POT_2" }, - { RAND_INF_KAK_NEAR_GUARDS_HOUSE_POT_3, "RAND_INF_KAK_NEAR_GUARDS_HOUSE_POT_3" }, - { RAND_INF_KAK_NEAR_MEDICINE_SHOP_POT_1, "RAND_INF_KAK_NEAR_MEDICINE_SHOP_POT_1" }, - { RAND_INF_KAK_NEAR_MEDICINE_SHOP_POT_2, "RAND_INF_KAK_NEAR_MEDICINE_SHOP_POT_2" }, - { RAND_INF_GY_DAMPES_GRAVE_POT_1, "RAND_INF_GY_DAMPES_GRAVE_POT_1" }, - { RAND_INF_GY_DAMPES_GRAVE_POT_2, "RAND_INF_GY_DAMPES_GRAVE_POT_2" }, - { RAND_INF_GY_DAMPES_GRAVE_POT_3, "RAND_INF_GY_DAMPES_GRAVE_POT_3" }, - { RAND_INF_GY_DAMPES_GRAVE_POT_4, "RAND_INF_GY_DAMPES_GRAVE_POT_4" }, - { RAND_INF_GY_DAMPES_GRAVE_POT_5, "RAND_INF_GY_DAMPES_GRAVE_POT_5" }, - { RAND_INF_GY_DAMPES_GRAVE_POT_6, "RAND_INF_GY_DAMPES_GRAVE_POT_6" }, - { RAND_INF_GC_LOWER_STAIRCASE_POT_1, "RAND_INF_GC_LOWER_STAIRCASE_POT_1" }, - { RAND_INF_GC_LOWER_STAIRCASE_POT_2, "RAND_INF_GC_LOWER_STAIRCASE_POT_2" }, - { RAND_INF_GC_UPPER_STAIRCASE_POT_1, "RAND_INF_GC_UPPER_STAIRCASE_POT_1" }, - { RAND_INF_GC_UPPER_STAIRCASE_POT_2, "RAND_INF_GC_UPPER_STAIRCASE_POT_2" }, - { RAND_INF_GC_UPPER_STAIRCASE_POT_3, "RAND_INF_GC_UPPER_STAIRCASE_POT_3" }, - { RAND_INF_GC_MEDIGORON_POT_1, "RAND_INF_GC_MEDIGORON_POT_1" }, - { RAND_INF_GC_DARUNIA_POT_1, "RAND_INF_GC_DARUNIA_POT_1" }, - { RAND_INF_GC_DARUNIA_POT_2, "RAND_INF_GC_DARUNIA_POT_2" }, - { RAND_INF_GC_DARUNIA_POT_3, "RAND_INF_GC_DARUNIA_POT_3" }, - { RAND_INF_DMC_NEAR_GC_POT_1, "RAND_INF_DMC_NEAR_GC_POT_1" }, - { RAND_INF_DMC_NEAR_GC_POT_2, "RAND_INF_DMC_NEAR_GC_POT_2" }, - { RAND_INF_DMC_NEAR_GC_POT_3, "RAND_INF_DMC_NEAR_GC_POT_3" }, - { RAND_INF_DMC_NEAR_GC_POT_4, "RAND_INF_DMC_NEAR_GC_POT_4" }, - { RAND_INF_ZD_NEAR_SHOP_POT_1, "RAND_INF_ZD_NEAR_SHOP_POT_1" }, - { RAND_INF_ZD_NEAR_SHOP_POT_2, "RAND_INF_ZD_NEAR_SHOP_POT_2" }, - { RAND_INF_ZD_NEAR_SHOP_POT_3, "RAND_INF_ZD_NEAR_SHOP_POT_3" }, - { RAND_INF_ZD_NEAR_SHOP_POT_4, "RAND_INF_ZD_NEAR_SHOP_POT_4" }, - { RAND_INF_ZD_NEAR_SHOP_POT_5, "RAND_INF_ZD_NEAR_SHOP_POT_5" }, - { RAND_INF_ZF_HIDDEN_CAVE_POT_1, "RAND_INF_ZF_HIDDEN_CAVE_POT_1" }, - { RAND_INF_ZF_HIDDEN_CAVE_POT_2, "RAND_INF_ZF_HIDDEN_CAVE_POT_2" }, - { RAND_INF_ZF_HIDDEN_CAVE_POT_3, "RAND_INF_ZF_HIDDEN_CAVE_POT_3" }, - { RAND_INF_ZF_NEAR_JABU_POT_1, "RAND_INF_ZF_NEAR_JABU_POT_1" }, - { RAND_INF_ZF_NEAR_JABU_POT_2, "RAND_INF_ZF_NEAR_JABU_POT_2" }, - { RAND_INF_ZF_NEAR_JABU_POT_3, "RAND_INF_ZF_NEAR_JABU_POT_3" }, - { RAND_INF_ZF_NEAR_JABU_POT_4, "RAND_INF_ZF_NEAR_JABU_POT_4" }, - { RAND_INF_LLR_FRONT_POT_1, "RAND_INF_LLR_FRONT_POT_1" }, - { RAND_INF_LLR_FRONT_POT_2, "RAND_INF_LLR_FRONT_POT_2" }, - { RAND_INF_LLR_FRONT_POT_3, "RAND_INF_LLR_FRONT_POT_3" }, - { RAND_INF_LLR_FRONT_POT_4, "RAND_INF_LLR_FRONT_POT_4" }, - { RAND_INF_LLR_RAIN_SHED_POT_1, "RAND_INF_LLR_RAIN_SHED_POT_1" }, - { RAND_INF_LLR_RAIN_SHED_POT_2, "RAND_INF_LLR_RAIN_SHED_POT_2" }, - { RAND_INF_LLR_RAIN_SHED_POT_3, "RAND_INF_LLR_RAIN_SHED_POT_3" }, - { RAND_INF_LLR_TALONS_HOUSE_POT_1, "RAND_INF_LLR_TALONS_HOUSE_POT_1" }, - { RAND_INF_LLR_TALONS_HOUSE_POT_2, "RAND_INF_LLR_TALONS_HOUSE_POT_2" }, - { RAND_INF_LLR_TALONS_HOUSE_POT_3, "RAND_INF_LLR_TALONS_HOUSE_POT_3" }, - { RAND_INF_HF_COW_GROTTO_POT_1, "RAND_INF_HF_COW_GROTTO_POT_1" }, - { RAND_INF_HF_COW_GROTTO_POT_2, "RAND_INF_HF_COW_GROTTO_POT_2" }, - { RAND_INF_HC_STORMS_GROTTO_POT_1, "RAND_INF_HC_STORMS_GROTTO_POT_1" }, - { RAND_INF_HC_STORMS_GROTTO_POT_2, "RAND_INF_HC_STORMS_GROTTO_POT_2" }, - { RAND_INF_HC_STORMS_GROTTO_POT_3, "RAND_INF_HC_STORMS_GROTTO_POT_3" }, - { RAND_INF_HC_STORMS_GROTTO_POT_4, "RAND_INF_HC_STORMS_GROTTO_POT_4" }, - { RAND_INF_DODONGOS_CAVERN_LIZALFOS_POT_1, "RAND_INF_DODONGOS_CAVERN_LIZALFOS_POT_1" }, - { RAND_INF_DODONGOS_CAVERN_LIZALFOS_POT_2, "RAND_INF_DODONGOS_CAVERN_LIZALFOS_POT_2" }, - { RAND_INF_DODONGOS_CAVERN_LIZALFOS_POT_3, "RAND_INF_DODONGOS_CAVERN_LIZALFOS_POT_3" }, - { RAND_INF_DODONGOS_CAVERN_LIZALFOS_POT_4, "RAND_INF_DODONGOS_CAVERN_LIZALFOS_POT_4" }, - { RAND_INF_DODONGOS_CAVERN_SIDE_ROOM_POT_1, "RAND_INF_DODONGOS_CAVERN_SIDE_ROOM_POT_1" }, - { RAND_INF_DODONGOS_CAVERN_SIDE_ROOM_POT_2, "RAND_INF_DODONGOS_CAVERN_SIDE_ROOM_POT_2" }, - { RAND_INF_DODONGOS_CAVERN_SIDE_ROOM_POT_3, "RAND_INF_DODONGOS_CAVERN_SIDE_ROOM_POT_3" }, - { RAND_INF_DODONGOS_CAVERN_SIDE_ROOM_POT_4, "RAND_INF_DODONGOS_CAVERN_SIDE_ROOM_POT_4" }, - { RAND_INF_DODONGOS_CAVERN_SIDE_ROOM_POT_5, "RAND_INF_DODONGOS_CAVERN_SIDE_ROOM_POT_5" }, - { RAND_INF_DODONGOS_CAVERN_SIDE_ROOM_POT_6, "RAND_INF_DODONGOS_CAVERN_SIDE_ROOM_POT_6" }, - { RAND_INF_DODONGOS_CAVERN_TORCH_ROOM_POT_1, "RAND_INF_DODONGOS_CAVERN_TORCH_ROOM_POT_1" }, - { RAND_INF_DODONGOS_CAVERN_TORCH_ROOM_POT_2, "RAND_INF_DODONGOS_CAVERN_TORCH_ROOM_POT_2" }, - { RAND_INF_DODONGOS_CAVERN_TORCH_ROOM_POT_3, "RAND_INF_DODONGOS_CAVERN_TORCH_ROOM_POT_3" }, - { RAND_INF_DODONGOS_CAVERN_TORCH_ROOM_POT_4, "RAND_INF_DODONGOS_CAVERN_TORCH_ROOM_POT_4" }, - { RAND_INF_DODONGOS_CAVERN_STAIRCASE_POT_1, "RAND_INF_DODONGOS_CAVERN_STAIRCASE_POT_1" }, - { RAND_INF_DODONGOS_CAVERN_STAIRCASE_POT_2, "RAND_INF_DODONGOS_CAVERN_STAIRCASE_POT_2" }, - { RAND_INF_DODONGOS_CAVERN_STAIRCASE_POT_3, "RAND_INF_DODONGOS_CAVERN_STAIRCASE_POT_3" }, - { RAND_INF_DODONGOS_CAVERN_STAIRCASE_POT_4, "RAND_INF_DODONGOS_CAVERN_STAIRCASE_POT_4" }, - { RAND_INF_DODONGOS_CAVERN_SINGLE_EYE_POT_1, "RAND_INF_DODONGOS_CAVERN_SINGLE_EYE_POT_1" }, - { RAND_INF_DODONGOS_CAVERN_SINGLE_EYE_POT_2, "RAND_INF_DODONGOS_CAVERN_SINGLE_EYE_POT_2" }, - { RAND_INF_DODONGOS_CAVERN_BLADE_POT_1, "RAND_INF_DODONGOS_CAVERN_BLADE_POT_1" }, - { RAND_INF_DODONGOS_CAVERN_BLADE_POT_2, "RAND_INF_DODONGOS_CAVERN_BLADE_POT_2" }, - { RAND_INF_DODONGOS_CAVERN_DOUBLE_EYE_POT_1, "RAND_INF_DODONGOS_CAVERN_DOUBLE_EYE_POT_1" }, - { RAND_INF_DODONGOS_CAVERN_DOUBLE_EYE_POT_2, "RAND_INF_DODONGOS_CAVERN_DOUBLE_EYE_POT_2" }, - { RAND_INF_DODONGOS_CAVERN_BACK_ROOM_POT_1, "RAND_INF_DODONGOS_CAVERN_BACK_ROOM_POT_1" }, - { RAND_INF_DODONGOS_CAVERN_BACK_ROOM_POT_2, "RAND_INF_DODONGOS_CAVERN_BACK_ROOM_POT_2" }, - { RAND_INF_DODONGOS_CAVERN_BACK_ROOM_POT_3, "RAND_INF_DODONGOS_CAVERN_BACK_ROOM_POT_3" }, - { RAND_INF_DODONGOS_CAVERN_BACK_ROOM_POT_4, "RAND_INF_DODONGOS_CAVERN_BACK_ROOM_POT_4" }, - { RAND_INF_JABU_JABUS_BELLY_ABOVE_BIG_OCTO_POT_1, "RAND_INF_JABU_JABUS_BELLY_ABOVE_BIG_OCTO_POT_1" }, - { RAND_INF_JABU_JABUS_BELLY_ABOVE_BIG_OCTO_POT_2, "RAND_INF_JABU_JABUS_BELLY_ABOVE_BIG_OCTO_POT_2" }, - { RAND_INF_JABU_JABUS_BELLY_ABOVE_BIG_OCTO_POT_3, "RAND_INF_JABU_JABUS_BELLY_ABOVE_BIG_OCTO_POT_3" }, - { RAND_INF_JABU_JABUS_BELLY_BARINADE_POT_1, "RAND_INF_JABU_JABUS_BELLY_BARINADE_POT_1" }, - { RAND_INF_JABU_JABUS_BELLY_BARINADE_POT_2, "RAND_INF_JABU_JABUS_BELLY_BARINADE_POT_2" }, - { RAND_INF_JABU_JABUS_BELLY_BARINADE_POT_3, "RAND_INF_JABU_JABUS_BELLY_BARINADE_POT_3" }, - { RAND_INF_JABU_JABUS_BELLY_BARINADE_POT_4, "RAND_INF_JABU_JABUS_BELLY_BARINADE_POT_4" }, - { RAND_INF_JABU_JABUS_BELLY_BARINADE_POT_5, "RAND_INF_JABU_JABUS_BELLY_BARINADE_POT_5" }, - { RAND_INF_JABU_JABUS_BELLY_BARINADE_POT_6, "RAND_INF_JABU_JABUS_BELLY_BARINADE_POT_6" }, - { RAND_INF_JABU_JABUS_BELLY_BASEMENT_POT_1, "RAND_INF_JABU_JABUS_BELLY_BASEMENT_POT_1" }, - { RAND_INF_JABU_JABUS_BELLY_BASEMENT_POT_2, "RAND_INF_JABU_JABUS_BELLY_BASEMENT_POT_2" }, - { RAND_INF_JABU_JABUS_BELLY_BASEMENT_POT_3, "RAND_INF_JABU_JABUS_BELLY_BASEMENT_POT_3" }, - { RAND_INF_JABU_JABUS_BELLY_TWO_OCTOROK_POT_1, "RAND_INF_JABU_JABUS_BELLY_TWO_OCTOROK_POT_1" }, - { RAND_INF_JABU_JABUS_BELLY_TWO_OCTOROK_POT_2, "RAND_INF_JABU_JABUS_BELLY_TWO_OCTOROK_POT_2" }, - { RAND_INF_JABU_JABUS_BELLY_TWO_OCTOROK_POT_3, "RAND_INF_JABU_JABUS_BELLY_TWO_OCTOROK_POT_3" }, - { RAND_INF_JABU_JABUS_BELLY_TWO_OCTOROK_POT_4, "RAND_INF_JABU_JABUS_BELLY_TWO_OCTOROK_POT_4" }, - { RAND_INF_JABU_JABUS_BELLY_TWO_OCTOROK_POT_5, "RAND_INF_JABU_JABUS_BELLY_TWO_OCTOROK_POT_5" }, - { RAND_INF_FOREST_TEMPLE_LOBBY_POT_1, "RAND_INF_FOREST_TEMPLE_LOBBY_POT_1" }, - { RAND_INF_FOREST_TEMPLE_LOBBY_POT_2, "RAND_INF_FOREST_TEMPLE_LOBBY_POT_2" }, - { RAND_INF_FOREST_TEMPLE_LOBBY_POT_3, "RAND_INF_FOREST_TEMPLE_LOBBY_POT_3" }, - { RAND_INF_FOREST_TEMPLE_LOBBY_POT_4, "RAND_INF_FOREST_TEMPLE_LOBBY_POT_4" }, - { RAND_INF_FOREST_TEMPLE_LOBBY_POT_5, "RAND_INF_FOREST_TEMPLE_LOBBY_POT_5" }, - { RAND_INF_FOREST_TEMPLE_LOBBY_POT_6, "RAND_INF_FOREST_TEMPLE_LOBBY_POT_6" }, - { RAND_INF_FOREST_TEMPLE_LOWER_STALFOS_POT_1, "RAND_INF_FOREST_TEMPLE_LOWER_STALFOS_POT_1" }, - { RAND_INF_FOREST_TEMPLE_LOWER_STALFOS_POT_2, "RAND_INF_FOREST_TEMPLE_LOWER_STALFOS_POT_2" }, - { RAND_INF_FOREST_TEMPLE_GREEN_POE_POT_1, "RAND_INF_FOREST_TEMPLE_GREEN_POE_POT_1" }, - { RAND_INF_FOREST_TEMPLE_GREEN_POE_POT_2, "RAND_INF_FOREST_TEMPLE_GREEN_POE_POT_2" }, - { RAND_INF_FOREST_TEMPLE_UPPER_STALFOS_POT_1, "RAND_INF_FOREST_TEMPLE_UPPER_STALFOS_POT_1" }, - { RAND_INF_FOREST_TEMPLE_UPPER_STALFOS_POT_2, "RAND_INF_FOREST_TEMPLE_UPPER_STALFOS_POT_2" }, - { RAND_INF_FOREST_TEMPLE_UPPER_STALFOS_POT_3, "RAND_INF_FOREST_TEMPLE_UPPER_STALFOS_POT_3" }, - { RAND_INF_FOREST_TEMPLE_UPPER_STALFOS_POT_4, "RAND_INF_FOREST_TEMPLE_UPPER_STALFOS_POT_4" }, - { RAND_INF_FOREST_TEMPLE_BLUE_POE_POT_1, "RAND_INF_FOREST_TEMPLE_BLUE_POE_POT_1" }, - { RAND_INF_FOREST_TEMPLE_BLUE_POE_POT_2, "RAND_INF_FOREST_TEMPLE_BLUE_POE_POT_2" }, - { RAND_INF_FOREST_TEMPLE_BLUE_POE_POT_3, "RAND_INF_FOREST_TEMPLE_BLUE_POE_POT_3" }, - { RAND_INF_FOREST_TEMPLE_FROZEN_EYE_POT_1, "RAND_INF_FOREST_TEMPLE_FROZEN_EYE_POT_1" }, - { RAND_INF_FOREST_TEMPLE_FROZEN_EYE_POT_2, "RAND_INF_FOREST_TEMPLE_FROZEN_EYE_POT_2" }, - { RAND_INF_FIRE_TEMPLE_NEAR_BOSS_POT_1, "RAND_INF_FIRE_TEMPLE_NEAR_BOSS_POT_1" }, - { RAND_INF_FIRE_TEMPLE_NEAR_BOSS_POT_2, "RAND_INF_FIRE_TEMPLE_NEAR_BOSS_POT_2" }, - { RAND_INF_FIRE_TEMPLE_NEAR_BOSS_POT_3, "RAND_INF_FIRE_TEMPLE_NEAR_BOSS_POT_3" }, - { RAND_INF_FIRE_TEMPLE_NEAR_BOSS_POT_4, "RAND_INF_FIRE_TEMPLE_NEAR_BOSS_POT_4" }, - { RAND_INF_FIRE_TEMPLE_BIG_LAVA_POT_1, "RAND_INF_FIRE_TEMPLE_BIG_LAVA_POT_1" }, - { RAND_INF_FIRE_TEMPLE_BIG_LAVA_POT_2, "RAND_INF_FIRE_TEMPLE_BIG_LAVA_POT_2" }, - { RAND_INF_FIRE_TEMPLE_BIG_LAVA_POT_3, "RAND_INF_FIRE_TEMPLE_BIG_LAVA_POT_3" }, - { RAND_INF_FIRE_TEMPLE_FLAME_MAZE_LEFT_POT_1, "RAND_INF_FIRE_TEMPLE_FLAME_MAZE_LEFT_POT_1" }, - { RAND_INF_FIRE_TEMPLE_FLAME_MAZE_LEFT_POT_2, "RAND_INF_FIRE_TEMPLE_FLAME_MAZE_LEFT_POT_2" }, - { RAND_INF_FIRE_TEMPLE_FLAME_MAZE_LEFT_POT_3, "RAND_INF_FIRE_TEMPLE_FLAME_MAZE_LEFT_POT_3" }, - { RAND_INF_FIRE_TEMPLE_FLAME_MAZE_LEFT_POT_4, "RAND_INF_FIRE_TEMPLE_FLAME_MAZE_LEFT_POT_4" }, - { RAND_INF_FIRE_TEMPLE_FLAME_MAZE_RIGHT_POT_1, "RAND_INF_FIRE_TEMPLE_FLAME_MAZE_RIGHT_POT_1" }, - { RAND_INF_FIRE_TEMPLE_FLAME_MAZE_RIGHT_POT_2, "RAND_INF_FIRE_TEMPLE_FLAME_MAZE_RIGHT_POT_2" }, - { RAND_INF_FIRE_TEMPLE_FLAME_MAZE_RIGHT_POT_3, "RAND_INF_FIRE_TEMPLE_FLAME_MAZE_RIGHT_POT_3" }, - { RAND_INF_FIRE_TEMPLE_FLAME_MAZE_RIGHT_POT_4, "RAND_INF_FIRE_TEMPLE_FLAME_MAZE_RIGHT_POT_4" }, - { RAND_INF_WATER_TEMPLE_MAIN_LEVEL_2_POT_1, "RAND_INF_WATER_TEMPLE_MAIN_LEVEL_2_POT_1" }, - { RAND_INF_WATER_TEMPLE_MAIN_LEVEL_2_POT_2, "RAND_INF_WATER_TEMPLE_MAIN_LEVEL_2_POT_2" }, - { RAND_INF_WATER_TEMPLE_MAIN_LEVEL_1_POT_1, "RAND_INF_WATER_TEMPLE_MAIN_LEVEL_1_POT_1" }, - { RAND_INF_WATER_TEMPLE_MAIN_LEVEL_1_POT_2, "RAND_INF_WATER_TEMPLE_MAIN_LEVEL_1_POT_2" }, - { RAND_INF_WATER_TEMPLE_TORCH_POT_1, "RAND_INF_WATER_TEMPLE_TORCH_POT_1" }, - { RAND_INF_WATER_TEMPLE_TORCH_POT_2, "RAND_INF_WATER_TEMPLE_TORCH_POT_2" }, - { RAND_INF_WATER_TEMPLE_NEAR_COMPASS_POT_1, "RAND_INF_WATER_TEMPLE_NEAR_COMPASS_POT_1" }, - { RAND_INF_WATER_TEMPLE_NEAR_COMPASS_POT_2, "RAND_INF_WATER_TEMPLE_NEAR_COMPASS_POT_2" }, - { RAND_INF_WATER_TEMPLE_NEAR_COMPASS_POT_3, "RAND_INF_WATER_TEMPLE_NEAR_COMPASS_POT_3" }, - { RAND_INF_WATER_TEMPLE_CENTRAL_BOW_POT_1, "RAND_INF_WATER_TEMPLE_CENTRAL_BOW_POT_1" }, - { RAND_INF_WATER_TEMPLE_CENTRAL_BOW_POT_2, "RAND_INF_WATER_TEMPLE_CENTRAL_BOW_POT_2" }, - { RAND_INF_WATER_TEMPLE_BEHIND_GATE_POT_1, "RAND_INF_WATER_TEMPLE_BEHIND_GATE_POT_1" }, - { RAND_INF_WATER_TEMPLE_BEHIND_GATE_POT_2, "RAND_INF_WATER_TEMPLE_BEHIND_GATE_POT_2" }, - { RAND_INF_WATER_TEMPLE_BEHIND_GATE_POT_3, "RAND_INF_WATER_TEMPLE_BEHIND_GATE_POT_3" }, - { RAND_INF_WATER_TEMPLE_BEHIND_GATE_POT_4, "RAND_INF_WATER_TEMPLE_BEHIND_GATE_POT_4" }, - { RAND_INF_WATER_TEMPLE_BASEMENT_BLOCK_PUZZLE_POT_1, "RAND_INF_WATER_TEMPLE_BASEMENT_BLOCK_PUZZLE_POT_1" }, - { RAND_INF_WATER_TEMPLE_BASEMENT_BLOCK_PUZZLE_POT_2, "RAND_INF_WATER_TEMPLE_BASEMENT_BLOCK_PUZZLE_POT_2" }, - { RAND_INF_WATER_TEMPLE_RIVER_POT_1, "RAND_INF_WATER_TEMPLE_RIVER_POT_1" }, - { RAND_INF_WATER_TEMPLE_RIVER_POT_2, "RAND_INF_WATER_TEMPLE_RIVER_POT_2" }, - { RAND_INF_WATER_TEMPLE_LIKE_LIKE_POT_1, "RAND_INF_WATER_TEMPLE_LIKE_LIKE_POT_1" }, - { RAND_INF_WATER_TEMPLE_LIKE_LIKE_POT_2, "RAND_INF_WATER_TEMPLE_LIKE_LIKE_POT_2" }, - { RAND_INF_WATER_TEMPLE_BOSS_KEY_POT_1, "RAND_INF_WATER_TEMPLE_BOSS_KEY_POT_1" }, - { RAND_INF_WATER_TEMPLE_BOSS_KEY_POT_2, "RAND_INF_WATER_TEMPLE_BOSS_KEY_POT_2" }, - { RAND_INF_SHADOW_TEMPLE_NEAR_DEAD_HAND_POT_1, "RAND_INF_SHADOW_TEMPLE_NEAR_DEAD_HAND_POT_1" }, - { RAND_INF_SHADOW_TEMPLE_WHISPERING_WALLS_POT_1, "RAND_INF_SHADOW_TEMPLE_WHISPERING_WALLS_POT_1" }, - { RAND_INF_SHADOW_TEMPLE_WHISPERING_WALLS_POT_2, "RAND_INF_SHADOW_TEMPLE_WHISPERING_WALLS_POT_2" }, - { RAND_INF_SHADOW_TEMPLE_WHISPERING_WALLS_POT_3, "RAND_INF_SHADOW_TEMPLE_WHISPERING_WALLS_POT_3" }, - { RAND_INF_SHADOW_TEMPLE_WHISPERING_WALLS_POT_4, "RAND_INF_SHADOW_TEMPLE_WHISPERING_WALLS_POT_4" }, - { RAND_INF_SHADOW_TEMPLE_WHISPERING_WALLS_POT_5, "RAND_INF_SHADOW_TEMPLE_WHISPERING_WALLS_POT_5" }, - { RAND_INF_SHADOW_TEMPLE_MAP_CHEST_POT_1, "RAND_INF_SHADOW_TEMPLE_MAP_CHEST_POT_1" }, - { RAND_INF_SHADOW_TEMPLE_MAP_CHEST_POT_2, "RAND_INF_SHADOW_TEMPLE_MAP_CHEST_POT_2" }, - { RAND_INF_SHADOW_TEMPLE_FALLING_SPIKES_POT_1, "RAND_INF_SHADOW_TEMPLE_FALLING_SPIKES_POT_1" }, - { RAND_INF_SHADOW_TEMPLE_FALLING_SPIKES_POT_2, "RAND_INF_SHADOW_TEMPLE_FALLING_SPIKES_POT_2" }, - { RAND_INF_SHADOW_TEMPLE_FALLING_SPIKES_POT_3, "RAND_INF_SHADOW_TEMPLE_FALLING_SPIKES_POT_3" }, - { RAND_INF_SHADOW_TEMPLE_FALLING_SPIKES_POT_4, "RAND_INF_SHADOW_TEMPLE_FALLING_SPIKES_POT_4" }, - { RAND_INF_SHADOW_TEMPLE_AFTER_WIND_POT_1, "RAND_INF_SHADOW_TEMPLE_AFTER_WIND_POT_1" }, - { RAND_INF_SHADOW_TEMPLE_AFTER_WIND_POT_2, "RAND_INF_SHADOW_TEMPLE_AFTER_WIND_POT_2" }, - { RAND_INF_SHADOW_TEMPLE_SPIKE_WALLS_POT_1, "RAND_INF_SHADOW_TEMPLE_SPIKE_WALLS_POT_1" }, - { RAND_INF_SHADOW_TEMPLE_FLOORMASTER_POT_1, "RAND_INF_SHADOW_TEMPLE_FLOORMASTER_POT_1" }, - { RAND_INF_SHADOW_TEMPLE_FLOORMASTER_POT_2, "RAND_INF_SHADOW_TEMPLE_FLOORMASTER_POT_2" }, - { RAND_INF_SHADOW_TEMPLE_AFTER_BOAT_POT_1, "RAND_INF_SHADOW_TEMPLE_AFTER_BOAT_POT_1" }, - { RAND_INF_SHADOW_TEMPLE_AFTER_BOAT_POT_2, "RAND_INF_SHADOW_TEMPLE_AFTER_BOAT_POT_2" }, - { RAND_INF_SHADOW_TEMPLE_AFTER_BOAT_POT_3, "RAND_INF_SHADOW_TEMPLE_AFTER_BOAT_POT_3" }, - { RAND_INF_SHADOW_TEMPLE_AFTER_BOAT_POT_4, "RAND_INF_SHADOW_TEMPLE_AFTER_BOAT_POT_4" }, - { RAND_INF_SPIRIT_TEMPLE_LOBBY_POT_1, "RAND_INF_SPIRIT_TEMPLE_LOBBY_POT_1" }, - { RAND_INF_SPIRIT_TEMPLE_LOBBY_POT_2, "RAND_INF_SPIRIT_TEMPLE_LOBBY_POT_2" }, - { RAND_INF_SPIRIT_TEMPLE_ANUBIS_POT_1, "RAND_INF_SPIRIT_TEMPLE_ANUBIS_POT_1" }, - { RAND_INF_SPIRIT_TEMPLE_ANUBIS_POT_2, "RAND_INF_SPIRIT_TEMPLE_ANUBIS_POT_2" }, - { RAND_INF_SPIRIT_TEMPLE_ANUBIS_POT_3, "RAND_INF_SPIRIT_TEMPLE_ANUBIS_POT_3" }, - { RAND_INF_SPIRIT_TEMPLE_ANUBIS_POT_4, "RAND_INF_SPIRIT_TEMPLE_ANUBIS_POT_4" }, - { RAND_INF_SPIRIT_TEMPLE_CHILD_CLIMB_POT_1, "RAND_INF_SPIRIT_TEMPLE_CHILD_CLIMB_POT_1" }, - { RAND_INF_SPIRIT_TEMPLE_AFTER_SUN_BLOCK_POT_1, "RAND_INF_SPIRIT_TEMPLE_AFTER_SUN_BLOCK_POT_1" }, - { RAND_INF_SPIRIT_TEMPLE_AFTER_SUN_BLOCK_POT_2, "RAND_INF_SPIRIT_TEMPLE_AFTER_SUN_BLOCK_POT_2" }, - { RAND_INF_SPIRIT_TEMPLE_CENTRAL_CHAMBER_POT_1, "RAND_INF_SPIRIT_TEMPLE_CENTRAL_CHAMBER_POT_1" }, - { RAND_INF_SPIRIT_TEMPLE_CENTRAL_CHAMBER_POT_2, "RAND_INF_SPIRIT_TEMPLE_CENTRAL_CHAMBER_POT_2" }, - { RAND_INF_SPIRIT_TEMPLE_CENTRAL_CHAMBER_POT_3, "RAND_INF_SPIRIT_TEMPLE_CENTRAL_CHAMBER_POT_3" }, - { RAND_INF_SPIRIT_TEMPLE_CENTRAL_CHAMBER_POT_4, "RAND_INF_SPIRIT_TEMPLE_CENTRAL_CHAMBER_POT_4" }, - { RAND_INF_SPIRIT_TEMPLE_CENTRAL_CHAMBER_POT_5, "RAND_INF_SPIRIT_TEMPLE_CENTRAL_CHAMBER_POT_5" }, - { RAND_INF_SPIRIT_TEMPLE_CENTRAL_CHAMBER_POT_6, "RAND_INF_SPIRIT_TEMPLE_CENTRAL_CHAMBER_POT_6" }, - { RAND_INF_SPIRIT_TEMPLE_BEAMOS_HALL_POT_1, "RAND_INF_SPIRIT_TEMPLE_BEAMOS_HALL_POT_1" }, - { RAND_INF_GANONS_CASTLE_FOREST_TRIAL_POT_1, "RAND_INF_GANONS_CASTLE_FOREST_TRIAL_POT_1" }, - { RAND_INF_GANONS_CASTLE_FOREST_TRIAL_POT_2, "RAND_INF_GANONS_CASTLE_FOREST_TRIAL_POT_2" }, - { RAND_INF_GANONS_CASTLE_FIRE_TRIAL_POT_1, "RAND_INF_GANONS_CASTLE_FIRE_TRIAL_POT_1" }, - { RAND_INF_GANONS_CASTLE_FIRE_TRIAL_POT_2, "RAND_INF_GANONS_CASTLE_FIRE_TRIAL_POT_2" }, - { RAND_INF_GANONS_CASTLE_WATER_TRIAL_POT_1, "RAND_INF_GANONS_CASTLE_WATER_TRIAL_POT_1" }, - { RAND_INF_GANONS_CASTLE_WATER_TRIAL_POT_2, "RAND_INF_GANONS_CASTLE_WATER_TRIAL_POT_2" }, - { RAND_INF_GANONS_CASTLE_WATER_TRIAL_POT_3, "RAND_INF_GANONS_CASTLE_WATER_TRIAL_POT_3" }, - { RAND_INF_GANONS_CASTLE_SHADOW_TRIAL_POT_1, "RAND_INF_GANONS_CASTLE_SHADOW_TRIAL_POT_1" }, - { RAND_INF_GANONS_CASTLE_SHADOW_TRIAL_POT_2, "RAND_INF_GANONS_CASTLE_SHADOW_TRIAL_POT_2" }, - { RAND_INF_GANONS_CASTLE_SHADOW_TRIAL_POT_3, "RAND_INF_GANONS_CASTLE_SHADOW_TRIAL_POT_3" }, - { RAND_INF_GANONS_CASTLE_SHADOW_TRIAL_POT_4, "RAND_INF_GANONS_CASTLE_SHADOW_TRIAL_POT_4" }, - { RAND_INF_GANONS_CASTLE_SPIRIT_TRIAL_POT_1, "RAND_INF_GANONS_CASTLE_SPIRIT_TRIAL_POT_1" }, - { RAND_INF_GANONS_CASTLE_SPIRIT_TRIAL_POT_2, "RAND_INF_GANONS_CASTLE_SPIRIT_TRIAL_POT_2" }, - { RAND_INF_GANONS_CASTLE_LIGHT_TRIAL_BOULDER_POT_1, "RAND_INF_GANONS_CASTLE_LIGHT_TRIAL_BOULDER_POT_1" }, - { RAND_INF_GANONS_CASTLE_LIGHT_TRIAL_POT_1, "RAND_INF_GANONS_CASTLE_LIGHT_TRIAL_POT_1" }, - { RAND_INF_GANONS_CASTLE_LIGHT_TRIAL_POT_2, "RAND_INF_GANONS_CASTLE_LIGHT_TRIAL_POT_2" }, - { RAND_INF_GANONS_CASTLE_GANONS_TOWER_POT_1, "RAND_INF_GANONS_CASTLE_GANONS_TOWER_POT_1" }, - { RAND_INF_GANONS_CASTLE_GANONS_TOWER_POT_2, "RAND_INF_GANONS_CASTLE_GANONS_TOWER_POT_2" }, - { RAND_INF_GANONS_CASTLE_GANONS_TOWER_POT_3, "RAND_INF_GANONS_CASTLE_GANONS_TOWER_POT_3" }, - { RAND_INF_GANONS_CASTLE_GANONS_TOWER_POT_4, "RAND_INF_GANONS_CASTLE_GANONS_TOWER_POT_4" }, - { RAND_INF_GANONS_CASTLE_GANONS_TOWER_POT_5, "RAND_INF_GANONS_CASTLE_GANONS_TOWER_POT_5" }, - { RAND_INF_GANONS_CASTLE_GANONS_TOWER_POT_6, "RAND_INF_GANONS_CASTLE_GANONS_TOWER_POT_6" }, - { RAND_INF_GANONS_CASTLE_GANONS_TOWER_POT_7, "RAND_INF_GANONS_CASTLE_GANONS_TOWER_POT_7" }, - { RAND_INF_GANONS_CASTLE_GANONS_TOWER_POT_8, "RAND_INF_GANONS_CASTLE_GANONS_TOWER_POT_8" }, - { RAND_INF_GANONS_CASTLE_GANONS_TOWER_POT_9, "RAND_INF_GANONS_CASTLE_GANONS_TOWER_POT_9" }, - { RAND_INF_GANONS_CASTLE_GANONS_TOWER_POT_10, "RAND_INF_GANONS_CASTLE_GANONS_TOWER_POT_10" }, - { RAND_INF_GANONS_CASTLE_GANONS_TOWER_POT_11, "RAND_INF_GANONS_CASTLE_GANONS_TOWER_POT_11" }, - { RAND_INF_GANONS_CASTLE_GANONS_TOWER_POT_12, "RAND_INF_GANONS_CASTLE_GANONS_TOWER_POT_12" }, - { RAND_INF_GANONS_CASTLE_GANONS_TOWER_POT_13, "RAND_INF_GANONS_CASTLE_GANONS_TOWER_POT_13" }, - { RAND_INF_GANONS_CASTLE_GANONS_TOWER_POT_14, "RAND_INF_GANONS_CASTLE_GANONS_TOWER_POT_14" }, - { RAND_INF_GANONS_CASTLE_GANONS_TOWER_POT_15, "RAND_INF_GANONS_CASTLE_GANONS_TOWER_POT_15" }, - { RAND_INF_GANONS_CASTLE_GANONS_TOWER_POT_16, "RAND_INF_GANONS_CASTLE_GANONS_TOWER_POT_16" }, - { RAND_INF_GANONS_CASTLE_GANONS_TOWER_POT_17, "RAND_INF_GANONS_CASTLE_GANONS_TOWER_POT_17" }, - { RAND_INF_GANONS_CASTLE_GANONS_TOWER_POT_18, "RAND_INF_GANONS_CASTLE_GANONS_TOWER_POT_18" }, - { RAND_INF_BOTTOM_OF_THE_WELL_BASEMENT_POT_1, "RAND_INF_BOTTOM_OF_THE_WELL_BASEMENT_POT_1" }, - { RAND_INF_BOTTOM_OF_THE_WELL_BASEMENT_POT_2, "RAND_INF_BOTTOM_OF_THE_WELL_BASEMENT_POT_2" }, - { RAND_INF_BOTTOM_OF_THE_WELL_BASEMENT_POT_3, "RAND_INF_BOTTOM_OF_THE_WELL_BASEMENT_POT_3" }, - { RAND_INF_BOTTOM_OF_THE_WELL_BASEMENT_POT_4, "RAND_INF_BOTTOM_OF_THE_WELL_BASEMENT_POT_4" }, - { RAND_INF_BOTTOM_OF_THE_WELL_BASEMENT_POT_5, "RAND_INF_BOTTOM_OF_THE_WELL_BASEMENT_POT_5" }, - { RAND_INF_BOTTOM_OF_THE_WELL_BASEMENT_POT_6, "RAND_INF_BOTTOM_OF_THE_WELL_BASEMENT_POT_6" }, - { RAND_INF_BOTTOM_OF_THE_WELL_BASEMENT_POT_7, "RAND_INF_BOTTOM_OF_THE_WELL_BASEMENT_POT_7" }, - { RAND_INF_BOTTOM_OF_THE_WELL_BASEMENT_POT_8, "RAND_INF_BOTTOM_OF_THE_WELL_BASEMENT_POT_8" }, - { RAND_INF_BOTTOM_OF_THE_WELL_BASEMENT_POT_9, "RAND_INF_BOTTOM_OF_THE_WELL_BASEMENT_POT_9" }, - { RAND_INF_BOTTOM_OF_THE_WELL_BASEMENT_POT_10, "RAND_INF_BOTTOM_OF_THE_WELL_BASEMENT_POT_10" }, - { RAND_INF_BOTTOM_OF_THE_WELL_BASEMENT_POT_11, "RAND_INF_BOTTOM_OF_THE_WELL_BASEMENT_POT_11" }, - { RAND_INF_BOTTOM_OF_THE_WELL_BASEMENT_POT_12, "RAND_INF_BOTTOM_OF_THE_WELL_BASEMENT_POT_12" }, - { RAND_INF_BOTTOM_OF_THE_WELL_LEFT_SIDE_POT_1, "RAND_INF_BOTTOM_OF_THE_WELL_LEFT_SIDE_POT_1" }, - { RAND_INF_BOTTOM_OF_THE_WELL_LEFT_SIDE_POT_2, "RAND_INF_BOTTOM_OF_THE_WELL_LEFT_SIDE_POT_2" }, - { RAND_INF_BOTTOM_OF_THE_WELL_LEFT_SIDE_POT_3, "RAND_INF_BOTTOM_OF_THE_WELL_LEFT_SIDE_POT_3" }, - { RAND_INF_BOTTOM_OF_THE_WELL_NEAR_ENTRANCE_POT_1, "RAND_INF_BOTTOM_OF_THE_WELL_NEAR_ENTRANCE_POT_1" }, - { RAND_INF_BOTTOM_OF_THE_WELL_NEAR_ENTRANCE_POT_2, "RAND_INF_BOTTOM_OF_THE_WELL_NEAR_ENTRANCE_POT_2" }, - { RAND_INF_BOTTOM_OF_THE_WELL_FIRE_KEESE_POT_1, "RAND_INF_BOTTOM_OF_THE_WELL_FIRE_KEESE_POT_1" }, - { RAND_INF_BOTTOM_OF_THE_WELL_UNDERWATER_POT, "RAND_INF_BOTTOM_OF_THE_WELL_UNDERWATER_POT" }, - { RAND_INF_ICE_CAVERN_HALL_POT_1, "RAND_INF_ICE_CAVERN_HALL_POT_1" }, - { RAND_INF_ICE_CAVERN_HALL_POT_2, "RAND_INF_ICE_CAVERN_HALL_POT_2" }, - { RAND_INF_ICE_CAVERN_SPINNING_BLADE_POT_1, "RAND_INF_ICE_CAVERN_SPINNING_BLADE_POT_1" }, - { RAND_INF_ICE_CAVERN_SPINNING_BLADE_POT_2, "RAND_INF_ICE_CAVERN_SPINNING_BLADE_POT_2" }, - { RAND_INF_ICE_CAVERN_SPINNING_BLADE_POT_3, "RAND_INF_ICE_CAVERN_SPINNING_BLADE_POT_3" }, - { RAND_INF_ICE_CAVERN_NEAR_END_POT_1, "RAND_INF_ICE_CAVERN_NEAR_END_POT_1" }, - { RAND_INF_ICE_CAVERN_NEAR_END_POT_2, "RAND_INF_ICE_CAVERN_NEAR_END_POT_2" }, - { RAND_INF_ICE_CAVERN_FROZEN_POT_1, "RAND_INF_ICE_CAVERN_FROZEN_POT_1" }, + { RAND_INF_KF_LINKS_HOUSE_POT, "RAND_INF_KF_LINKS_HOUSE_POT" }, + { RAND_INF_KF_TWINS_HOUSE_POT_1, "RAND_INF_KF_TWINS_HOUSE_POT_1" }, + { RAND_INF_KF_TWINS_HOUSE_POT_2, "RAND_INF_KF_TWINS_HOUSE_POT_2" }, + { RAND_INF_KF_BROTHERS_HOUSE_POT_1, "RAND_INF_KF_BROTHERS_HOUSE_POT_1" }, + { RAND_INF_KF_BROTHERS_HOUSE_POT_2, "RAND_INF_KF_BROTHERS_HOUSE_POT_2" }, + { RAND_INF_GF_BREAK_ROOM_POT_1, "RAND_INF_GF_BREAK_ROOM_POT_1" }, + { RAND_INF_GF_BREAK_ROOM_POT_2, "RAND_INF_GF_BREAK_ROOM_POT_2" }, + { RAND_INF_GF_KITCHEN_POT_1, "RAND_INF_GF_KITCHEN_POT_1" }, + { RAND_INF_GF_KITCHEN_POT_2, "RAND_INF_GF_KITCHEN_POT_2" }, + { RAND_INF_GF_NORTH_F1_CARPENTER_POT_1, "RAND_INF_GF_NORTH_F1_CARPENTER_POT_1" }, + { RAND_INF_GF_NORTH_F1_CARPENTER_POT_2, "RAND_INF_GF_NORTH_F1_CARPENTER_POT_2" }, + { RAND_INF_GF_NORTH_F1_CARPENTER_POT_3, "RAND_INF_GF_NORTH_F1_CARPENTER_POT_3" }, + { RAND_INF_GF_NORTH_F2_CARPENTER_POT_1, "RAND_INF_GF_NORTH_F2_CARPENTER_POT_1" }, + { RAND_INF_GF_NORTH_F2_CARPENTER_POT_2, "RAND_INF_GF_NORTH_F2_CARPENTER_POT_2" }, + { RAND_INF_GF_SOUTH_F1_CARPENTER_POT_1, "RAND_INF_GF_SOUTH_F1_CARPENTER_POT_1" }, + { RAND_INF_GF_SOUTH_F1_CARPENTER_POT_2, "RAND_INF_GF_SOUTH_F1_CARPENTER_POT_2" }, + { RAND_INF_GF_SOUTH_F1_CARPENTER_POT_3, "RAND_INF_GF_SOUTH_F1_CARPENTER_POT_3" }, + { RAND_INF_GF_SOUTH_F1_CARPENTER_CELL_POT_1, "RAND_INF_GF_SOUTH_F1_CARPENTER_CELL_POT_1" }, + { RAND_INF_GF_SOUTH_F1_CARPENTER_CELL_POT_2, "RAND_INF_GF_SOUTH_F1_CARPENTER_CELL_POT_2" }, + { RAND_INF_GF_SOUTH_F1_CARPENTER_CELL_POT_3, "RAND_INF_GF_SOUTH_F1_CARPENTER_CELL_POT_3" }, + { RAND_INF_GF_SOUTH_F1_CARPENTER_CELL_POT_4, "RAND_INF_GF_SOUTH_F1_CARPENTER_CELL_POT_4" }, + { RAND_INF_WASTELAND_NEAR_GS_POT_1, "RAND_INF_WASTELAND_NEAR_GS_POT_1" }, + { RAND_INF_WASTELAND_NEAR_GS_POT_2, "RAND_INF_WASTELAND_NEAR_GS_POT_2" }, + { RAND_INF_WASTELAND_NEAR_GS_POT_3, "RAND_INF_WASTELAND_NEAR_GS_POT_3" }, + { RAND_INF_WASTELAND_NEAR_GS_POT_4, "RAND_INF_WASTELAND_NEAR_GS_POT_4" }, + { RAND_INF_MK_GUARD_HOUSE_CHILD_POT_1, "RAND_INF_MK_GUARD_HOUSE_CHILD_POT_1" }, + { RAND_INF_MK_GUARD_HOUSE_CHILD_POT_2, "RAND_INF_MK_GUARD_HOUSE_CHILD_POT_2" }, + { RAND_INF_MK_GUARD_HOUSE_CHILD_POT_3, "RAND_INF_MK_GUARD_HOUSE_CHILD_POT_3" }, + { RAND_INF_MK_GUARD_HOUSE_CHILD_POT_4, "RAND_INF_MK_GUARD_HOUSE_CHILD_POT_4" }, + { RAND_INF_MK_GUARD_HOUSE_CHILD_POT_5, "RAND_INF_MK_GUARD_HOUSE_CHILD_POT_5" }, + { RAND_INF_MK_GUARD_HOUSE_CHILD_POT_6, "RAND_INF_MK_GUARD_HOUSE_CHILD_POT_6" }, + { RAND_INF_MK_GUARD_HOUSE_CHILD_POT_7, "RAND_INF_MK_GUARD_HOUSE_CHILD_POT_7" }, + { RAND_INF_MK_GUARD_HOUSE_CHILD_POT_8, "RAND_INF_MK_GUARD_HOUSE_CHILD_POT_8" }, + { RAND_INF_MK_GUARD_HOUSE_CHILD_POT_9, "RAND_INF_MK_GUARD_HOUSE_CHILD_POT_9" }, + { RAND_INF_MK_GUARD_HOUSE_CHILD_POT_10, "RAND_INF_MK_GUARD_HOUSE_CHILD_POT_10" }, + { RAND_INF_MK_GUARD_HOUSE_CHILD_POT_11, "RAND_INF_MK_GUARD_HOUSE_CHILD_POT_11" }, + { RAND_INF_MK_GUARD_HOUSE_CHILD_POT_12, "RAND_INF_MK_GUARD_HOUSE_CHILD_POT_12" }, + { RAND_INF_MK_GUARD_HOUSE_CHILD_POT_13, "RAND_INF_MK_GUARD_HOUSE_CHILD_POT_13" }, + { RAND_INF_MK_GUARD_HOUSE_CHILD_POT_14, "RAND_INF_MK_GUARD_HOUSE_CHILD_POT_14" }, + { RAND_INF_MK_GUARD_HOUSE_CHILD_POT_15, "RAND_INF_MK_GUARD_HOUSE_CHILD_POT_15" }, + { RAND_INF_MK_GUARD_HOUSE_CHILD_POT_16, "RAND_INF_MK_GUARD_HOUSE_CHILD_POT_16" }, + { RAND_INF_MK_GUARD_HOUSE_CHILD_POT_17, "RAND_INF_MK_GUARD_HOUSE_CHILD_POT_17" }, + { RAND_INF_MK_GUARD_HOUSE_CHILD_POT_18, "RAND_INF_MK_GUARD_HOUSE_CHILD_POT_18" }, + { RAND_INF_MK_GUARD_HOUSE_CHILD_POT_19, "RAND_INF_MK_GUARD_HOUSE_CHILD_POT_19" }, + { RAND_INF_MK_GUARD_HOUSE_CHILD_POT_20, "RAND_INF_MK_GUARD_HOUSE_CHILD_POT_20" }, + { RAND_INF_MK_GUARD_HOUSE_CHILD_POT_21, "RAND_INF_MK_GUARD_HOUSE_CHILD_POT_21" }, + { RAND_INF_MK_GUARD_HOUSE_CHILD_POT_22, "RAND_INF_MK_GUARD_HOUSE_CHILD_POT_22" }, + { RAND_INF_MK_GUARD_HOUSE_CHILD_POT_23, "RAND_INF_MK_GUARD_HOUSE_CHILD_POT_23" }, + { RAND_INF_MK_GUARD_HOUSE_CHILD_POT_24, "RAND_INF_MK_GUARD_HOUSE_CHILD_POT_24" }, + { RAND_INF_MK_GUARD_HOUSE_CHILD_POT_25, "RAND_INF_MK_GUARD_HOUSE_CHILD_POT_25" }, + { RAND_INF_MK_GUARD_HOUSE_CHILD_POT_26, "RAND_INF_MK_GUARD_HOUSE_CHILD_POT_26" }, + { RAND_INF_MK_GUARD_HOUSE_CHILD_POT_27, "RAND_INF_MK_GUARD_HOUSE_CHILD_POT_27" }, + { RAND_INF_MK_GUARD_HOUSE_CHILD_POT_28, "RAND_INF_MK_GUARD_HOUSE_CHILD_POT_28" }, + { RAND_INF_MK_GUARD_HOUSE_CHILD_POT_29, "RAND_INF_MK_GUARD_HOUSE_CHILD_POT_29" }, + { RAND_INF_MK_GUARD_HOUSE_CHILD_POT_30, "RAND_INF_MK_GUARD_HOUSE_CHILD_POT_30" }, + { RAND_INF_MK_GUARD_HOUSE_CHILD_POT_31, "RAND_INF_MK_GUARD_HOUSE_CHILD_POT_31" }, + { RAND_INF_MK_GUARD_HOUSE_CHILD_POT_32, "RAND_INF_MK_GUARD_HOUSE_CHILD_POT_32" }, + { RAND_INF_MK_GUARD_HOUSE_CHILD_POT_33, "RAND_INF_MK_GUARD_HOUSE_CHILD_POT_33" }, + { RAND_INF_MK_GUARD_HOUSE_CHILD_POT_34, "RAND_INF_MK_GUARD_HOUSE_CHILD_POT_34" }, + { RAND_INF_MK_GUARD_HOUSE_CHILD_POT_35, "RAND_INF_MK_GUARD_HOUSE_CHILD_POT_35" }, + { RAND_INF_MK_GUARD_HOUSE_CHILD_POT_36, "RAND_INF_MK_GUARD_HOUSE_CHILD_POT_36" }, + { RAND_INF_MK_GUARD_HOUSE_CHILD_POT_37, "RAND_INF_MK_GUARD_HOUSE_CHILD_POT_37" }, + { RAND_INF_MK_GUARD_HOUSE_CHILD_POT_38, "RAND_INF_MK_GUARD_HOUSE_CHILD_POT_38" }, + { RAND_INF_MK_GUARD_HOUSE_CHILD_POT_39, "RAND_INF_MK_GUARD_HOUSE_CHILD_POT_39" }, + { RAND_INF_MK_GUARD_HOUSE_CHILD_POT_40, "RAND_INF_MK_GUARD_HOUSE_CHILD_POT_40" }, + { RAND_INF_MK_GUARD_HOUSE_CHILD_POT_41, "RAND_INF_MK_GUARD_HOUSE_CHILD_POT_41" }, + { RAND_INF_MK_GUARD_HOUSE_CHILD_POT_42, "RAND_INF_MK_GUARD_HOUSE_CHILD_POT_42" }, + { RAND_INF_MK_GUARD_HOUSE_CHILD_POT_43, "RAND_INF_MK_GUARD_HOUSE_CHILD_POT_43" }, + { RAND_INF_MK_GUARD_HOUSE_CHILD_POT_44, "RAND_INF_MK_GUARD_HOUSE_CHILD_POT_44" }, + { RAND_INF_MK_GUARD_HOUSE_ADULT_POT_1, "RAND_INF_MK_GUARD_HOUSE_ADULT_POT_1" }, + { RAND_INF_MK_GUARD_HOUSE_ADULT_POT_2, "RAND_INF_MK_GUARD_HOUSE_ADULT_POT_2" }, + { RAND_INF_MK_GUARD_HOUSE_ADULT_POT_3, "RAND_INF_MK_GUARD_HOUSE_ADULT_POT_3" }, + { RAND_INF_MK_GUARD_HOUSE_ADULT_POT_4, "RAND_INF_MK_GUARD_HOUSE_ADULT_POT_4" }, + { RAND_INF_MK_GUARD_HOUSE_ADULT_POT_5, "RAND_INF_MK_GUARD_HOUSE_ADULT_POT_5" }, + { RAND_INF_MK_GUARD_HOUSE_ADULT_POT_6, "RAND_INF_MK_GUARD_HOUSE_ADULT_POT_6" }, + { RAND_INF_MK_GUARD_HOUSE_ADULT_POT_7, "RAND_INF_MK_GUARD_HOUSE_ADULT_POT_7" }, + { RAND_INF_MK_GUARD_HOUSE_ADULT_POT_8, "RAND_INF_MK_GUARD_HOUSE_ADULT_POT_8" }, + { RAND_INF_MK_GUARD_HOUSE_ADULT_POT_9, "RAND_INF_MK_GUARD_HOUSE_ADULT_POT_9" }, + { RAND_INF_MK_GUARD_HOUSE_ADULT_POT_10, "RAND_INF_MK_GUARD_HOUSE_ADULT_POT_10" }, + { RAND_INF_MK_GUARD_HOUSE_ADULT_POT_11, "RAND_INF_MK_GUARD_HOUSE_ADULT_POT_11" }, + { RAND_INF_MK_BACK_ALLEY_HOUSE_POT_1, "RAND_INF_MK_BACK_ALLEY_HOUSE_POT_1" }, + { RAND_INF_MK_BACK_ALLEY_HOUSE_POT_2, "RAND_INF_MK_BACK_ALLEY_HOUSE_POT_2" }, + { RAND_INF_MK_BACK_ALLEY_HOUSE_POT_3, "RAND_INF_MK_BACK_ALLEY_HOUSE_POT_3" }, + { RAND_INF_KAK_NEAR_POTION_SHOP_POT_1, "RAND_INF_KAK_NEAR_POTION_SHOP_POT_1" }, + { RAND_INF_KAK_NEAR_POTION_SHOP_POT_2, "RAND_INF_KAK_NEAR_POTION_SHOP_POT_2" }, + { RAND_INF_KAK_NEAR_POTION_SHOP_POT_3, "RAND_INF_KAK_NEAR_POTION_SHOP_POT_3" }, + { RAND_INF_KAK_NEAR_IMPAS_HOUSE_POT_1, "RAND_INF_KAK_NEAR_IMPAS_HOUSE_POT_1" }, + { RAND_INF_KAK_NEAR_IMPAS_HOUSE_POT_2, "RAND_INF_KAK_NEAR_IMPAS_HOUSE_POT_2" }, + { RAND_INF_KAK_NEAR_IMPAS_HOUSE_POT_3, "RAND_INF_KAK_NEAR_IMPAS_HOUSE_POT_3" }, + { RAND_INF_KAK_NEAR_GUARDS_HOUSE_POT_1, "RAND_INF_KAK_NEAR_GUARDS_HOUSE_POT_1" }, + { RAND_INF_KAK_NEAR_GUARDS_HOUSE_POT_2, "RAND_INF_KAK_NEAR_GUARDS_HOUSE_POT_2" }, + { RAND_INF_KAK_NEAR_GUARDS_HOUSE_POT_3, "RAND_INF_KAK_NEAR_GUARDS_HOUSE_POT_3" }, + { RAND_INF_KAK_NEAR_MEDICINE_SHOP_POT_1, "RAND_INF_KAK_NEAR_MEDICINE_SHOP_POT_1" }, + { RAND_INF_KAK_NEAR_MEDICINE_SHOP_POT_2, "RAND_INF_KAK_NEAR_MEDICINE_SHOP_POT_2" }, + { RAND_INF_GY_DAMPES_GRAVE_POT_1, "RAND_INF_GY_DAMPES_GRAVE_POT_1" }, + { RAND_INF_GY_DAMPES_GRAVE_POT_2, "RAND_INF_GY_DAMPES_GRAVE_POT_2" }, + { RAND_INF_GY_DAMPES_GRAVE_POT_3, "RAND_INF_GY_DAMPES_GRAVE_POT_3" }, + { RAND_INF_GY_DAMPES_GRAVE_POT_4, "RAND_INF_GY_DAMPES_GRAVE_POT_4" }, + { RAND_INF_GY_DAMPES_GRAVE_POT_5, "RAND_INF_GY_DAMPES_GRAVE_POT_5" }, + { RAND_INF_GY_DAMPES_GRAVE_POT_6, "RAND_INF_GY_DAMPES_GRAVE_POT_6" }, + { RAND_INF_GC_LOWER_STAIRCASE_POT_1, "RAND_INF_GC_LOWER_STAIRCASE_POT_1" }, + { RAND_INF_GC_LOWER_STAIRCASE_POT_2, "RAND_INF_GC_LOWER_STAIRCASE_POT_2" }, + { RAND_INF_GC_UPPER_STAIRCASE_POT_1, "RAND_INF_GC_UPPER_STAIRCASE_POT_1" }, + { RAND_INF_GC_UPPER_STAIRCASE_POT_2, "RAND_INF_GC_UPPER_STAIRCASE_POT_2" }, + { RAND_INF_GC_UPPER_STAIRCASE_POT_3, "RAND_INF_GC_UPPER_STAIRCASE_POT_3" }, + { RAND_INF_GC_MEDIGORON_POT_1, "RAND_INF_GC_MEDIGORON_POT_1" }, + { RAND_INF_GC_DARUNIA_POT_1, "RAND_INF_GC_DARUNIA_POT_1" }, + { RAND_INF_GC_DARUNIA_POT_2, "RAND_INF_GC_DARUNIA_POT_2" }, + { RAND_INF_GC_DARUNIA_POT_3, "RAND_INF_GC_DARUNIA_POT_3" }, + { RAND_INF_DMC_NEAR_GC_POT_1, "RAND_INF_DMC_NEAR_GC_POT_1" }, + { RAND_INF_DMC_NEAR_GC_POT_2, "RAND_INF_DMC_NEAR_GC_POT_2" }, + { RAND_INF_DMC_NEAR_GC_POT_3, "RAND_INF_DMC_NEAR_GC_POT_3" }, + { RAND_INF_DMC_NEAR_GC_POT_4, "RAND_INF_DMC_NEAR_GC_POT_4" }, + { RAND_INF_ZD_NEAR_SHOP_POT_1, "RAND_INF_ZD_NEAR_SHOP_POT_1" }, + { RAND_INF_ZD_NEAR_SHOP_POT_2, "RAND_INF_ZD_NEAR_SHOP_POT_2" }, + { RAND_INF_ZD_NEAR_SHOP_POT_3, "RAND_INF_ZD_NEAR_SHOP_POT_3" }, + { RAND_INF_ZD_NEAR_SHOP_POT_4, "RAND_INF_ZD_NEAR_SHOP_POT_4" }, + { RAND_INF_ZD_NEAR_SHOP_POT_5, "RAND_INF_ZD_NEAR_SHOP_POT_5" }, + { RAND_INF_ZF_HIDDEN_CAVE_POT_1, "RAND_INF_ZF_HIDDEN_CAVE_POT_1" }, + { RAND_INF_ZF_HIDDEN_CAVE_POT_2, "RAND_INF_ZF_HIDDEN_CAVE_POT_2" }, + { RAND_INF_ZF_HIDDEN_CAVE_POT_3, "RAND_INF_ZF_HIDDEN_CAVE_POT_3" }, + { RAND_INF_ZF_NEAR_JABU_POT_1, "RAND_INF_ZF_NEAR_JABU_POT_1" }, + { RAND_INF_ZF_NEAR_JABU_POT_2, "RAND_INF_ZF_NEAR_JABU_POT_2" }, + { RAND_INF_ZF_NEAR_JABU_POT_3, "RAND_INF_ZF_NEAR_JABU_POT_3" }, + { RAND_INF_ZF_NEAR_JABU_POT_4, "RAND_INF_ZF_NEAR_JABU_POT_4" }, + { RAND_INF_LLR_FRONT_POT_1, "RAND_INF_LLR_FRONT_POT_1" }, + { RAND_INF_LLR_FRONT_POT_2, "RAND_INF_LLR_FRONT_POT_2" }, + { RAND_INF_LLR_FRONT_POT_3, "RAND_INF_LLR_FRONT_POT_3" }, + { RAND_INF_LLR_FRONT_POT_4, "RAND_INF_LLR_FRONT_POT_4" }, + { RAND_INF_LLR_RAIN_SHED_POT_1, "RAND_INF_LLR_RAIN_SHED_POT_1" }, + { RAND_INF_LLR_RAIN_SHED_POT_2, "RAND_INF_LLR_RAIN_SHED_POT_2" }, + { RAND_INF_LLR_RAIN_SHED_POT_3, "RAND_INF_LLR_RAIN_SHED_POT_3" }, + { RAND_INF_LLR_TALONS_HOUSE_POT_1, "RAND_INF_LLR_TALONS_HOUSE_POT_1" }, + { RAND_INF_LLR_TALONS_HOUSE_POT_2, "RAND_INF_LLR_TALONS_HOUSE_POT_2" }, + { RAND_INF_LLR_TALONS_HOUSE_POT_3, "RAND_INF_LLR_TALONS_HOUSE_POT_3" }, + { RAND_INF_HF_COW_GROTTO_POT_1, "RAND_INF_HF_COW_GROTTO_POT_1" }, + { RAND_INF_HF_COW_GROTTO_POT_2, "RAND_INF_HF_COW_GROTTO_POT_2" }, + { RAND_INF_HC_STORMS_GROTTO_POT_1, "RAND_INF_HC_STORMS_GROTTO_POT_1" }, + { RAND_INF_HC_STORMS_GROTTO_POT_2, "RAND_INF_HC_STORMS_GROTTO_POT_2" }, + { RAND_INF_HC_STORMS_GROTTO_POT_3, "RAND_INF_HC_STORMS_GROTTO_POT_3" }, + { RAND_INF_HC_STORMS_GROTTO_POT_4, "RAND_INF_HC_STORMS_GROTTO_POT_4" }, + { RAND_INF_DODONGOS_CAVERN_LIZALFOS_POT_1, "RAND_INF_DODONGOS_CAVERN_LIZALFOS_POT_1" }, + { RAND_INF_DODONGOS_CAVERN_LIZALFOS_POT_2, "RAND_INF_DODONGOS_CAVERN_LIZALFOS_POT_2" }, + { RAND_INF_DODONGOS_CAVERN_LIZALFOS_POT_3, "RAND_INF_DODONGOS_CAVERN_LIZALFOS_POT_3" }, + { RAND_INF_DODONGOS_CAVERN_LIZALFOS_POT_4, "RAND_INF_DODONGOS_CAVERN_LIZALFOS_POT_4" }, + { RAND_INF_DODONGOS_CAVERN_SIDE_ROOM_POT_1, "RAND_INF_DODONGOS_CAVERN_SIDE_ROOM_POT_1" }, + { RAND_INF_DODONGOS_CAVERN_SIDE_ROOM_POT_2, "RAND_INF_DODONGOS_CAVERN_SIDE_ROOM_POT_2" }, + { RAND_INF_DODONGOS_CAVERN_SIDE_ROOM_POT_3, "RAND_INF_DODONGOS_CAVERN_SIDE_ROOM_POT_3" }, + { RAND_INF_DODONGOS_CAVERN_SIDE_ROOM_POT_4, "RAND_INF_DODONGOS_CAVERN_SIDE_ROOM_POT_4" }, + { RAND_INF_DODONGOS_CAVERN_SIDE_ROOM_POT_5, "RAND_INF_DODONGOS_CAVERN_SIDE_ROOM_POT_5" }, + { RAND_INF_DODONGOS_CAVERN_SIDE_ROOM_POT_6, "RAND_INF_DODONGOS_CAVERN_SIDE_ROOM_POT_6" }, + { RAND_INF_DODONGOS_CAVERN_TORCH_ROOM_POT_1, "RAND_INF_DODONGOS_CAVERN_TORCH_ROOM_POT_1" }, + { RAND_INF_DODONGOS_CAVERN_TORCH_ROOM_POT_2, "RAND_INF_DODONGOS_CAVERN_TORCH_ROOM_POT_2" }, + { RAND_INF_DODONGOS_CAVERN_TORCH_ROOM_POT_3, "RAND_INF_DODONGOS_CAVERN_TORCH_ROOM_POT_3" }, + { RAND_INF_DODONGOS_CAVERN_TORCH_ROOM_POT_4, "RAND_INF_DODONGOS_CAVERN_TORCH_ROOM_POT_4" }, + { RAND_INF_DODONGOS_CAVERN_STAIRCASE_POT_1, "RAND_INF_DODONGOS_CAVERN_STAIRCASE_POT_1" }, + { RAND_INF_DODONGOS_CAVERN_STAIRCASE_POT_2, "RAND_INF_DODONGOS_CAVERN_STAIRCASE_POT_2" }, + { RAND_INF_DODONGOS_CAVERN_STAIRCASE_POT_3, "RAND_INF_DODONGOS_CAVERN_STAIRCASE_POT_3" }, + { RAND_INF_DODONGOS_CAVERN_STAIRCASE_POT_4, "RAND_INF_DODONGOS_CAVERN_STAIRCASE_POT_4" }, + { RAND_INF_DODONGOS_CAVERN_SINGLE_EYE_POT_1, "RAND_INF_DODONGOS_CAVERN_SINGLE_EYE_POT_1" }, + { RAND_INF_DODONGOS_CAVERN_SINGLE_EYE_POT_2, "RAND_INF_DODONGOS_CAVERN_SINGLE_EYE_POT_2" }, + { RAND_INF_DODONGOS_CAVERN_BLADE_POT_1, "RAND_INF_DODONGOS_CAVERN_BLADE_POT_1" }, + { RAND_INF_DODONGOS_CAVERN_BLADE_POT_2, "RAND_INF_DODONGOS_CAVERN_BLADE_POT_2" }, + { RAND_INF_DODONGOS_CAVERN_DOUBLE_EYE_POT_1, "RAND_INF_DODONGOS_CAVERN_DOUBLE_EYE_POT_1" }, + { RAND_INF_DODONGOS_CAVERN_DOUBLE_EYE_POT_2, "RAND_INF_DODONGOS_CAVERN_DOUBLE_EYE_POT_2" }, + { RAND_INF_DODONGOS_CAVERN_BACK_ROOM_POT_1, "RAND_INF_DODONGOS_CAVERN_BACK_ROOM_POT_1" }, + { RAND_INF_DODONGOS_CAVERN_BACK_ROOM_POT_2, "RAND_INF_DODONGOS_CAVERN_BACK_ROOM_POT_2" }, + { RAND_INF_DODONGOS_CAVERN_BACK_ROOM_POT_3, "RAND_INF_DODONGOS_CAVERN_BACK_ROOM_POT_3" }, + { RAND_INF_DODONGOS_CAVERN_BACK_ROOM_POT_4, "RAND_INF_DODONGOS_CAVERN_BACK_ROOM_POT_4" }, + { RAND_INF_JABU_JABUS_BELLY_ABOVE_BIG_OCTO_POT_1, "RAND_INF_JABU_JABUS_BELLY_ABOVE_BIG_OCTO_POT_1" }, + { RAND_INF_JABU_JABUS_BELLY_ABOVE_BIG_OCTO_POT_2, "RAND_INF_JABU_JABUS_BELLY_ABOVE_BIG_OCTO_POT_2" }, + { RAND_INF_JABU_JABUS_BELLY_ABOVE_BIG_OCTO_POT_3, "RAND_INF_JABU_JABUS_BELLY_ABOVE_BIG_OCTO_POT_3" }, + { RAND_INF_JABU_JABUS_BELLY_BARINADE_POT_1, "RAND_INF_JABU_JABUS_BELLY_BARINADE_POT_1" }, + { RAND_INF_JABU_JABUS_BELLY_BARINADE_POT_2, "RAND_INF_JABU_JABUS_BELLY_BARINADE_POT_2" }, + { RAND_INF_JABU_JABUS_BELLY_BARINADE_POT_3, "RAND_INF_JABU_JABUS_BELLY_BARINADE_POT_3" }, + { RAND_INF_JABU_JABUS_BELLY_BARINADE_POT_4, "RAND_INF_JABU_JABUS_BELLY_BARINADE_POT_4" }, + { RAND_INF_JABU_JABUS_BELLY_BARINADE_POT_5, "RAND_INF_JABU_JABUS_BELLY_BARINADE_POT_5" }, + { RAND_INF_JABU_JABUS_BELLY_BARINADE_POT_6, "RAND_INF_JABU_JABUS_BELLY_BARINADE_POT_6" }, + { RAND_INF_JABU_JABUS_BELLY_BASEMENT_POT_1, "RAND_INF_JABU_JABUS_BELLY_BASEMENT_POT_1" }, + { RAND_INF_JABU_JABUS_BELLY_BASEMENT_POT_2, "RAND_INF_JABU_JABUS_BELLY_BASEMENT_POT_2" }, + { RAND_INF_JABU_JABUS_BELLY_BASEMENT_POT_3, "RAND_INF_JABU_JABUS_BELLY_BASEMENT_POT_3" }, + { RAND_INF_JABU_JABUS_BELLY_TWO_OCTOROK_POT_1, "RAND_INF_JABU_JABUS_BELLY_TWO_OCTOROK_POT_1" }, + { RAND_INF_JABU_JABUS_BELLY_TWO_OCTOROK_POT_2, "RAND_INF_JABU_JABUS_BELLY_TWO_OCTOROK_POT_2" }, + { RAND_INF_JABU_JABUS_BELLY_TWO_OCTOROK_POT_3, "RAND_INF_JABU_JABUS_BELLY_TWO_OCTOROK_POT_3" }, + { RAND_INF_JABU_JABUS_BELLY_TWO_OCTOROK_POT_4, "RAND_INF_JABU_JABUS_BELLY_TWO_OCTOROK_POT_4" }, + { RAND_INF_JABU_JABUS_BELLY_TWO_OCTOROK_POT_5, "RAND_INF_JABU_JABUS_BELLY_TWO_OCTOROK_POT_5" }, + { RAND_INF_FOREST_TEMPLE_LOBBY_POT_1, "RAND_INF_FOREST_TEMPLE_LOBBY_POT_1" }, + { RAND_INF_FOREST_TEMPLE_LOBBY_POT_2, "RAND_INF_FOREST_TEMPLE_LOBBY_POT_2" }, + { RAND_INF_FOREST_TEMPLE_LOBBY_POT_3, "RAND_INF_FOREST_TEMPLE_LOBBY_POT_3" }, + { RAND_INF_FOREST_TEMPLE_LOBBY_POT_4, "RAND_INF_FOREST_TEMPLE_LOBBY_POT_4" }, + { RAND_INF_FOREST_TEMPLE_LOBBY_POT_5, "RAND_INF_FOREST_TEMPLE_LOBBY_POT_5" }, + { RAND_INF_FOREST_TEMPLE_LOBBY_POT_6, "RAND_INF_FOREST_TEMPLE_LOBBY_POT_6" }, + { RAND_INF_FOREST_TEMPLE_LOWER_STALFOS_POT_1, "RAND_INF_FOREST_TEMPLE_LOWER_STALFOS_POT_1" }, + { RAND_INF_FOREST_TEMPLE_LOWER_STALFOS_POT_2, "RAND_INF_FOREST_TEMPLE_LOWER_STALFOS_POT_2" }, + { RAND_INF_FOREST_TEMPLE_GREEN_POE_POT_1, "RAND_INF_FOREST_TEMPLE_GREEN_POE_POT_1" }, + { RAND_INF_FOREST_TEMPLE_GREEN_POE_POT_2, "RAND_INF_FOREST_TEMPLE_GREEN_POE_POT_2" }, + { RAND_INF_FOREST_TEMPLE_UPPER_STALFOS_POT_1, "RAND_INF_FOREST_TEMPLE_UPPER_STALFOS_POT_1" }, + { RAND_INF_FOREST_TEMPLE_UPPER_STALFOS_POT_2, "RAND_INF_FOREST_TEMPLE_UPPER_STALFOS_POT_2" }, + { RAND_INF_FOREST_TEMPLE_UPPER_STALFOS_POT_3, "RAND_INF_FOREST_TEMPLE_UPPER_STALFOS_POT_3" }, + { RAND_INF_FOREST_TEMPLE_UPPER_STALFOS_POT_4, "RAND_INF_FOREST_TEMPLE_UPPER_STALFOS_POT_4" }, + { RAND_INF_FOREST_TEMPLE_BLUE_POE_POT_1, "RAND_INF_FOREST_TEMPLE_BLUE_POE_POT_1" }, + { RAND_INF_FOREST_TEMPLE_BLUE_POE_POT_2, "RAND_INF_FOREST_TEMPLE_BLUE_POE_POT_2" }, + { RAND_INF_FOREST_TEMPLE_BLUE_POE_POT_3, "RAND_INF_FOREST_TEMPLE_BLUE_POE_POT_3" }, + { RAND_INF_FOREST_TEMPLE_FROZEN_EYE_POT_1, "RAND_INF_FOREST_TEMPLE_FROZEN_EYE_POT_1" }, + { RAND_INF_FOREST_TEMPLE_FROZEN_EYE_POT_2, "RAND_INF_FOREST_TEMPLE_FROZEN_EYE_POT_2" }, + { RAND_INF_FIRE_TEMPLE_NEAR_BOSS_POT_1, "RAND_INF_FIRE_TEMPLE_NEAR_BOSS_POT_1" }, + { RAND_INF_FIRE_TEMPLE_NEAR_BOSS_POT_2, "RAND_INF_FIRE_TEMPLE_NEAR_BOSS_POT_2" }, + { RAND_INF_FIRE_TEMPLE_NEAR_BOSS_POT_3, "RAND_INF_FIRE_TEMPLE_NEAR_BOSS_POT_3" }, + { RAND_INF_FIRE_TEMPLE_NEAR_BOSS_POT_4, "RAND_INF_FIRE_TEMPLE_NEAR_BOSS_POT_4" }, + { RAND_INF_FIRE_TEMPLE_BIG_LAVA_POT_1, "RAND_INF_FIRE_TEMPLE_BIG_LAVA_POT_1" }, + { RAND_INF_FIRE_TEMPLE_BIG_LAVA_POT_2, "RAND_INF_FIRE_TEMPLE_BIG_LAVA_POT_2" }, + { RAND_INF_FIRE_TEMPLE_BIG_LAVA_POT_3, "RAND_INF_FIRE_TEMPLE_BIG_LAVA_POT_3" }, + { RAND_INF_FIRE_TEMPLE_FLAME_MAZE_LEFT_POT_1, "RAND_INF_FIRE_TEMPLE_FLAME_MAZE_LEFT_POT_1" }, + { RAND_INF_FIRE_TEMPLE_FLAME_MAZE_LEFT_POT_2, "RAND_INF_FIRE_TEMPLE_FLAME_MAZE_LEFT_POT_2" }, + { RAND_INF_FIRE_TEMPLE_FLAME_MAZE_LEFT_POT_3, "RAND_INF_FIRE_TEMPLE_FLAME_MAZE_LEFT_POT_3" }, + { RAND_INF_FIRE_TEMPLE_FLAME_MAZE_LEFT_POT_4, "RAND_INF_FIRE_TEMPLE_FLAME_MAZE_LEFT_POT_4" }, + { RAND_INF_FIRE_TEMPLE_FLAME_MAZE_RIGHT_POT_1, "RAND_INF_FIRE_TEMPLE_FLAME_MAZE_RIGHT_POT_1" }, + { RAND_INF_FIRE_TEMPLE_FLAME_MAZE_RIGHT_POT_2, "RAND_INF_FIRE_TEMPLE_FLAME_MAZE_RIGHT_POT_2" }, + { RAND_INF_FIRE_TEMPLE_FLAME_MAZE_RIGHT_POT_3, "RAND_INF_FIRE_TEMPLE_FLAME_MAZE_RIGHT_POT_3" }, + { RAND_INF_FIRE_TEMPLE_FLAME_MAZE_RIGHT_POT_4, "RAND_INF_FIRE_TEMPLE_FLAME_MAZE_RIGHT_POT_4" }, + { RAND_INF_WATER_TEMPLE_MAIN_LEVEL_2_POT_1, "RAND_INF_WATER_TEMPLE_MAIN_LEVEL_2_POT_1" }, + { RAND_INF_WATER_TEMPLE_MAIN_LEVEL_2_POT_2, "RAND_INF_WATER_TEMPLE_MAIN_LEVEL_2_POT_2" }, + { RAND_INF_WATER_TEMPLE_MAIN_LEVEL_1_POT_1, "RAND_INF_WATER_TEMPLE_MAIN_LEVEL_1_POT_1" }, + { RAND_INF_WATER_TEMPLE_MAIN_LEVEL_1_POT_2, "RAND_INF_WATER_TEMPLE_MAIN_LEVEL_1_POT_2" }, + { RAND_INF_WATER_TEMPLE_TORCH_POT_1, "RAND_INF_WATER_TEMPLE_TORCH_POT_1" }, + { RAND_INF_WATER_TEMPLE_TORCH_POT_2, "RAND_INF_WATER_TEMPLE_TORCH_POT_2" }, + { RAND_INF_WATER_TEMPLE_NEAR_COMPASS_POT_1, "RAND_INF_WATER_TEMPLE_NEAR_COMPASS_POT_1" }, + { RAND_INF_WATER_TEMPLE_NEAR_COMPASS_POT_2, "RAND_INF_WATER_TEMPLE_NEAR_COMPASS_POT_2" }, + { RAND_INF_WATER_TEMPLE_NEAR_COMPASS_POT_3, "RAND_INF_WATER_TEMPLE_NEAR_COMPASS_POT_3" }, + { RAND_INF_WATER_TEMPLE_CENTRAL_BOW_POT_1, "RAND_INF_WATER_TEMPLE_CENTRAL_BOW_POT_1" }, + { RAND_INF_WATER_TEMPLE_CENTRAL_BOW_POT_2, "RAND_INF_WATER_TEMPLE_CENTRAL_BOW_POT_2" }, + { RAND_INF_WATER_TEMPLE_BEHIND_GATE_POT_1, "RAND_INF_WATER_TEMPLE_BEHIND_GATE_POT_1" }, + { RAND_INF_WATER_TEMPLE_BEHIND_GATE_POT_2, "RAND_INF_WATER_TEMPLE_BEHIND_GATE_POT_2" }, + { RAND_INF_WATER_TEMPLE_BEHIND_GATE_POT_3, "RAND_INF_WATER_TEMPLE_BEHIND_GATE_POT_3" }, + { RAND_INF_WATER_TEMPLE_BEHIND_GATE_POT_4, "RAND_INF_WATER_TEMPLE_BEHIND_GATE_POT_4" }, + { RAND_INF_WATER_TEMPLE_BASEMENT_BLOCK_PUZZLE_POT_1, "RAND_INF_WATER_TEMPLE_BASEMENT_BLOCK_PUZZLE_POT_1" }, + { RAND_INF_WATER_TEMPLE_BASEMENT_BLOCK_PUZZLE_POT_2, "RAND_INF_WATER_TEMPLE_BASEMENT_BLOCK_PUZZLE_POT_2" }, + { RAND_INF_WATER_TEMPLE_RIVER_POT_1, "RAND_INF_WATER_TEMPLE_RIVER_POT_1" }, + { RAND_INF_WATER_TEMPLE_RIVER_POT_2, "RAND_INF_WATER_TEMPLE_RIVER_POT_2" }, + { RAND_INF_WATER_TEMPLE_LIKE_LIKE_POT_1, "RAND_INF_WATER_TEMPLE_LIKE_LIKE_POT_1" }, + { RAND_INF_WATER_TEMPLE_LIKE_LIKE_POT_2, "RAND_INF_WATER_TEMPLE_LIKE_LIKE_POT_2" }, + { RAND_INF_WATER_TEMPLE_BOSS_KEY_POT_1, "RAND_INF_WATER_TEMPLE_BOSS_KEY_POT_1" }, + { RAND_INF_WATER_TEMPLE_BOSS_KEY_POT_2, "RAND_INF_WATER_TEMPLE_BOSS_KEY_POT_2" }, + { RAND_INF_SHADOW_TEMPLE_NEAR_DEAD_HAND_POT_1, "RAND_INF_SHADOW_TEMPLE_NEAR_DEAD_HAND_POT_1" }, + { RAND_INF_SHADOW_TEMPLE_WHISPERING_WALLS_POT_1, "RAND_INF_SHADOW_TEMPLE_WHISPERING_WALLS_POT_1" }, + { RAND_INF_SHADOW_TEMPLE_WHISPERING_WALLS_POT_2, "RAND_INF_SHADOW_TEMPLE_WHISPERING_WALLS_POT_2" }, + { RAND_INF_SHADOW_TEMPLE_WHISPERING_WALLS_POT_3, "RAND_INF_SHADOW_TEMPLE_WHISPERING_WALLS_POT_3" }, + { RAND_INF_SHADOW_TEMPLE_WHISPERING_WALLS_POT_4, "RAND_INF_SHADOW_TEMPLE_WHISPERING_WALLS_POT_4" }, + { RAND_INF_SHADOW_TEMPLE_WHISPERING_WALLS_POT_5, "RAND_INF_SHADOW_TEMPLE_WHISPERING_WALLS_POT_5" }, + { RAND_INF_SHADOW_TEMPLE_MAP_CHEST_POT_1, "RAND_INF_SHADOW_TEMPLE_MAP_CHEST_POT_1" }, + { RAND_INF_SHADOW_TEMPLE_MAP_CHEST_POT_2, "RAND_INF_SHADOW_TEMPLE_MAP_CHEST_POT_2" }, + { RAND_INF_SHADOW_TEMPLE_FALLING_SPIKES_POT_1, "RAND_INF_SHADOW_TEMPLE_FALLING_SPIKES_POT_1" }, + { RAND_INF_SHADOW_TEMPLE_FALLING_SPIKES_POT_2, "RAND_INF_SHADOW_TEMPLE_FALLING_SPIKES_POT_2" }, + { RAND_INF_SHADOW_TEMPLE_FALLING_SPIKES_POT_3, "RAND_INF_SHADOW_TEMPLE_FALLING_SPIKES_POT_3" }, + { RAND_INF_SHADOW_TEMPLE_FALLING_SPIKES_POT_4, "RAND_INF_SHADOW_TEMPLE_FALLING_SPIKES_POT_4" }, + { RAND_INF_SHADOW_TEMPLE_AFTER_WIND_POT_1, "RAND_INF_SHADOW_TEMPLE_AFTER_WIND_POT_1" }, + { RAND_INF_SHADOW_TEMPLE_AFTER_WIND_POT_2, "RAND_INF_SHADOW_TEMPLE_AFTER_WIND_POT_2" }, + { RAND_INF_SHADOW_TEMPLE_SPIKE_WALLS_POT_1, "RAND_INF_SHADOW_TEMPLE_SPIKE_WALLS_POT_1" }, + { RAND_INF_SHADOW_TEMPLE_FLOORMASTER_POT_1, "RAND_INF_SHADOW_TEMPLE_FLOORMASTER_POT_1" }, + { RAND_INF_SHADOW_TEMPLE_FLOORMASTER_POT_2, "RAND_INF_SHADOW_TEMPLE_FLOORMASTER_POT_2" }, + { RAND_INF_SHADOW_TEMPLE_AFTER_BOAT_POT_1, "RAND_INF_SHADOW_TEMPLE_AFTER_BOAT_POT_1" }, + { RAND_INF_SHADOW_TEMPLE_AFTER_BOAT_POT_2, "RAND_INF_SHADOW_TEMPLE_AFTER_BOAT_POT_2" }, + { RAND_INF_SHADOW_TEMPLE_AFTER_BOAT_POT_3, "RAND_INF_SHADOW_TEMPLE_AFTER_BOAT_POT_3" }, + { RAND_INF_SHADOW_TEMPLE_AFTER_BOAT_POT_4, "RAND_INF_SHADOW_TEMPLE_AFTER_BOAT_POT_4" }, + { RAND_INF_SPIRIT_TEMPLE_LOBBY_POT_1, "RAND_INF_SPIRIT_TEMPLE_LOBBY_POT_1" }, + { RAND_INF_SPIRIT_TEMPLE_LOBBY_POT_2, "RAND_INF_SPIRIT_TEMPLE_LOBBY_POT_2" }, + { RAND_INF_SPIRIT_TEMPLE_ANUBIS_POT_1, "RAND_INF_SPIRIT_TEMPLE_ANUBIS_POT_1" }, + { RAND_INF_SPIRIT_TEMPLE_ANUBIS_POT_2, "RAND_INF_SPIRIT_TEMPLE_ANUBIS_POT_2" }, + { RAND_INF_SPIRIT_TEMPLE_ANUBIS_POT_3, "RAND_INF_SPIRIT_TEMPLE_ANUBIS_POT_3" }, + { RAND_INF_SPIRIT_TEMPLE_ANUBIS_POT_4, "RAND_INF_SPIRIT_TEMPLE_ANUBIS_POT_4" }, + { RAND_INF_SPIRIT_TEMPLE_CHILD_CLIMB_POT_1, "RAND_INF_SPIRIT_TEMPLE_CHILD_CLIMB_POT_1" }, + { RAND_INF_SPIRIT_TEMPLE_AFTER_SUN_BLOCK_POT_1, "RAND_INF_SPIRIT_TEMPLE_AFTER_SUN_BLOCK_POT_1" }, + { RAND_INF_SPIRIT_TEMPLE_AFTER_SUN_BLOCK_POT_2, "RAND_INF_SPIRIT_TEMPLE_AFTER_SUN_BLOCK_POT_2" }, + { RAND_INF_SPIRIT_TEMPLE_CENTRAL_CHAMBER_POT_1, "RAND_INF_SPIRIT_TEMPLE_CENTRAL_CHAMBER_POT_1" }, + { RAND_INF_SPIRIT_TEMPLE_CENTRAL_CHAMBER_POT_2, "RAND_INF_SPIRIT_TEMPLE_CENTRAL_CHAMBER_POT_2" }, + { RAND_INF_SPIRIT_TEMPLE_CENTRAL_CHAMBER_POT_3, "RAND_INF_SPIRIT_TEMPLE_CENTRAL_CHAMBER_POT_3" }, + { RAND_INF_SPIRIT_TEMPLE_CENTRAL_CHAMBER_POT_4, "RAND_INF_SPIRIT_TEMPLE_CENTRAL_CHAMBER_POT_4" }, + { RAND_INF_SPIRIT_TEMPLE_CENTRAL_CHAMBER_POT_5, "RAND_INF_SPIRIT_TEMPLE_CENTRAL_CHAMBER_POT_5" }, + { RAND_INF_SPIRIT_TEMPLE_CENTRAL_CHAMBER_POT_6, "RAND_INF_SPIRIT_TEMPLE_CENTRAL_CHAMBER_POT_6" }, + { RAND_INF_SPIRIT_TEMPLE_BEAMOS_HALL_POT_1, "RAND_INF_SPIRIT_TEMPLE_BEAMOS_HALL_POT_1" }, + { RAND_INF_GANONS_CASTLE_FOREST_TRIAL_POT_1, "RAND_INF_GANONS_CASTLE_FOREST_TRIAL_POT_1" }, + { RAND_INF_GANONS_CASTLE_FOREST_TRIAL_POT_2, "RAND_INF_GANONS_CASTLE_FOREST_TRIAL_POT_2" }, + { RAND_INF_GANONS_CASTLE_FIRE_TRIAL_POT_1, "RAND_INF_GANONS_CASTLE_FIRE_TRIAL_POT_1" }, + { RAND_INF_GANONS_CASTLE_FIRE_TRIAL_POT_2, "RAND_INF_GANONS_CASTLE_FIRE_TRIAL_POT_2" }, + { RAND_INF_GANONS_CASTLE_WATER_TRIAL_POT_1, "RAND_INF_GANONS_CASTLE_WATER_TRIAL_POT_1" }, + { RAND_INF_GANONS_CASTLE_WATER_TRIAL_POT_2, "RAND_INF_GANONS_CASTLE_WATER_TRIAL_POT_2" }, + { RAND_INF_GANONS_CASTLE_WATER_TRIAL_POT_3, "RAND_INF_GANONS_CASTLE_WATER_TRIAL_POT_3" }, + { RAND_INF_GANONS_CASTLE_SHADOW_TRIAL_POT_1, "RAND_INF_GANONS_CASTLE_SHADOW_TRIAL_POT_1" }, + { RAND_INF_GANONS_CASTLE_SHADOW_TRIAL_POT_2, "RAND_INF_GANONS_CASTLE_SHADOW_TRIAL_POT_2" }, + { RAND_INF_GANONS_CASTLE_SHADOW_TRIAL_POT_3, "RAND_INF_GANONS_CASTLE_SHADOW_TRIAL_POT_3" }, + { RAND_INF_GANONS_CASTLE_SHADOW_TRIAL_POT_4, "RAND_INF_GANONS_CASTLE_SHADOW_TRIAL_POT_4" }, + { RAND_INF_GANONS_CASTLE_SPIRIT_TRIAL_POT_1, "RAND_INF_GANONS_CASTLE_SPIRIT_TRIAL_POT_1" }, + { RAND_INF_GANONS_CASTLE_SPIRIT_TRIAL_POT_2, "RAND_INF_GANONS_CASTLE_SPIRIT_TRIAL_POT_2" }, + { RAND_INF_GANONS_CASTLE_LIGHT_TRIAL_BOULDER_POT_1, "RAND_INF_GANONS_CASTLE_LIGHT_TRIAL_BOULDER_POT_1" }, + { RAND_INF_GANONS_CASTLE_LIGHT_TRIAL_POT_1, "RAND_INF_GANONS_CASTLE_LIGHT_TRIAL_POT_1" }, + { RAND_INF_GANONS_CASTLE_LIGHT_TRIAL_POT_2, "RAND_INF_GANONS_CASTLE_LIGHT_TRIAL_POT_2" }, + { RAND_INF_GANONS_CASTLE_GANONS_TOWER_POT_1, "RAND_INF_GANONS_CASTLE_GANONS_TOWER_POT_1" }, + { RAND_INF_GANONS_CASTLE_GANONS_TOWER_POT_2, "RAND_INF_GANONS_CASTLE_GANONS_TOWER_POT_2" }, + { RAND_INF_GANONS_CASTLE_GANONS_TOWER_POT_3, "RAND_INF_GANONS_CASTLE_GANONS_TOWER_POT_3" }, + { RAND_INF_GANONS_CASTLE_GANONS_TOWER_POT_4, "RAND_INF_GANONS_CASTLE_GANONS_TOWER_POT_4" }, + { RAND_INF_GANONS_CASTLE_GANONS_TOWER_POT_5, "RAND_INF_GANONS_CASTLE_GANONS_TOWER_POT_5" }, + { RAND_INF_GANONS_CASTLE_GANONS_TOWER_POT_6, "RAND_INF_GANONS_CASTLE_GANONS_TOWER_POT_6" }, + { RAND_INF_GANONS_CASTLE_GANONS_TOWER_POT_7, "RAND_INF_GANONS_CASTLE_GANONS_TOWER_POT_7" }, + { RAND_INF_GANONS_CASTLE_GANONS_TOWER_POT_8, "RAND_INF_GANONS_CASTLE_GANONS_TOWER_POT_8" }, + { RAND_INF_GANONS_CASTLE_GANONS_TOWER_POT_9, "RAND_INF_GANONS_CASTLE_GANONS_TOWER_POT_9" }, + { RAND_INF_GANONS_CASTLE_GANONS_TOWER_POT_10, "RAND_INF_GANONS_CASTLE_GANONS_TOWER_POT_10" }, + { RAND_INF_GANONS_CASTLE_GANONS_TOWER_POT_11, "RAND_INF_GANONS_CASTLE_GANONS_TOWER_POT_11" }, + { RAND_INF_GANONS_CASTLE_GANONS_TOWER_POT_12, "RAND_INF_GANONS_CASTLE_GANONS_TOWER_POT_12" }, + { RAND_INF_GANONS_CASTLE_GANONS_TOWER_POT_13, "RAND_INF_GANONS_CASTLE_GANONS_TOWER_POT_13" }, + { RAND_INF_GANONS_CASTLE_GANONS_TOWER_POT_14, "RAND_INF_GANONS_CASTLE_GANONS_TOWER_POT_14" }, + { RAND_INF_GANONS_CASTLE_GANONS_TOWER_POT_15, "RAND_INF_GANONS_CASTLE_GANONS_TOWER_POT_15" }, + { RAND_INF_GANONS_CASTLE_GANONS_TOWER_POT_16, "RAND_INF_GANONS_CASTLE_GANONS_TOWER_POT_16" }, + { RAND_INF_GANONS_CASTLE_GANONS_TOWER_POT_17, "RAND_INF_GANONS_CASTLE_GANONS_TOWER_POT_17" }, + { RAND_INF_GANONS_CASTLE_GANONS_TOWER_POT_18, "RAND_INF_GANONS_CASTLE_GANONS_TOWER_POT_18" }, + { RAND_INF_BOTTOM_OF_THE_WELL_BASEMENT_POT_1, "RAND_INF_BOTTOM_OF_THE_WELL_BASEMENT_POT_1" }, + { RAND_INF_BOTTOM_OF_THE_WELL_BASEMENT_POT_2, "RAND_INF_BOTTOM_OF_THE_WELL_BASEMENT_POT_2" }, + { RAND_INF_BOTTOM_OF_THE_WELL_BASEMENT_POT_3, "RAND_INF_BOTTOM_OF_THE_WELL_BASEMENT_POT_3" }, + { RAND_INF_BOTTOM_OF_THE_WELL_BASEMENT_POT_4, "RAND_INF_BOTTOM_OF_THE_WELL_BASEMENT_POT_4" }, + { RAND_INF_BOTTOM_OF_THE_WELL_BASEMENT_POT_5, "RAND_INF_BOTTOM_OF_THE_WELL_BASEMENT_POT_5" }, + { RAND_INF_BOTTOM_OF_THE_WELL_BASEMENT_POT_6, "RAND_INF_BOTTOM_OF_THE_WELL_BASEMENT_POT_6" }, + { RAND_INF_BOTTOM_OF_THE_WELL_BASEMENT_POT_7, "RAND_INF_BOTTOM_OF_THE_WELL_BASEMENT_POT_7" }, + { RAND_INF_BOTTOM_OF_THE_WELL_BASEMENT_POT_8, "RAND_INF_BOTTOM_OF_THE_WELL_BASEMENT_POT_8" }, + { RAND_INF_BOTTOM_OF_THE_WELL_BASEMENT_POT_9, "RAND_INF_BOTTOM_OF_THE_WELL_BASEMENT_POT_9" }, + { RAND_INF_BOTTOM_OF_THE_WELL_BASEMENT_POT_10, "RAND_INF_BOTTOM_OF_THE_WELL_BASEMENT_POT_10" }, + { RAND_INF_BOTTOM_OF_THE_WELL_BASEMENT_POT_11, "RAND_INF_BOTTOM_OF_THE_WELL_BASEMENT_POT_11" }, + { RAND_INF_BOTTOM_OF_THE_WELL_BASEMENT_POT_12, "RAND_INF_BOTTOM_OF_THE_WELL_BASEMENT_POT_12" }, + { RAND_INF_BOTTOM_OF_THE_WELL_LEFT_SIDE_POT_1, "RAND_INF_BOTTOM_OF_THE_WELL_LEFT_SIDE_POT_1" }, + { RAND_INF_BOTTOM_OF_THE_WELL_LEFT_SIDE_POT_2, "RAND_INF_BOTTOM_OF_THE_WELL_LEFT_SIDE_POT_2" }, + { RAND_INF_BOTTOM_OF_THE_WELL_LEFT_SIDE_POT_3, "RAND_INF_BOTTOM_OF_THE_WELL_LEFT_SIDE_POT_3" }, + { RAND_INF_BOTTOM_OF_THE_WELL_NEAR_ENTRANCE_POT_1, "RAND_INF_BOTTOM_OF_THE_WELL_NEAR_ENTRANCE_POT_1" }, + { RAND_INF_BOTTOM_OF_THE_WELL_NEAR_ENTRANCE_POT_2, "RAND_INF_BOTTOM_OF_THE_WELL_NEAR_ENTRANCE_POT_2" }, + { RAND_INF_BOTTOM_OF_THE_WELL_FIRE_KEESE_POT_1, "RAND_INF_BOTTOM_OF_THE_WELL_FIRE_KEESE_POT_1" }, + { RAND_INF_BOTTOM_OF_THE_WELL_UNDERWATER_POT, "RAND_INF_BOTTOM_OF_THE_WELL_UNDERWATER_POT" }, + { RAND_INF_ICE_CAVERN_HALL_POT_1, "RAND_INF_ICE_CAVERN_HALL_POT_1" }, + { RAND_INF_ICE_CAVERN_HALL_POT_2, "RAND_INF_ICE_CAVERN_HALL_POT_2" }, + { RAND_INF_ICE_CAVERN_SPINNING_BLADE_POT_1, "RAND_INF_ICE_CAVERN_SPINNING_BLADE_POT_1" }, + { RAND_INF_ICE_CAVERN_SPINNING_BLADE_POT_2, "RAND_INF_ICE_CAVERN_SPINNING_BLADE_POT_2" }, + { RAND_INF_ICE_CAVERN_SPINNING_BLADE_POT_3, "RAND_INF_ICE_CAVERN_SPINNING_BLADE_POT_3" }, + { RAND_INF_ICE_CAVERN_NEAR_END_POT_1, "RAND_INF_ICE_CAVERN_NEAR_END_POT_1" }, + { RAND_INF_ICE_CAVERN_NEAR_END_POT_2, "RAND_INF_ICE_CAVERN_NEAR_END_POT_2" }, + { RAND_INF_ICE_CAVERN_FROZEN_POT_1, "RAND_INF_ICE_CAVERN_FROZEN_POT_1" }, - { RAND_INF_JABU_JABUS_BELLY_MQ_ENTRANCE_POT_1, "RAND_INF_JABU_JABUS_BELLY_MQ_ENTRANCE_POT_1" }, - { RAND_INF_JABU_JABUS_BELLY_MQ_ENTRANCE_POT_2, "RAND_INF_JABU_JABUS_BELLY_MQ_ENTRANCE_POT_2" }, - { RAND_INF_JABU_JABUS_BELLY_MQ_GEYSER_POT_1, "RAND_INF_JABU_JABUS_BELLY_MQ_GEYSER_POT_1" }, - { RAND_INF_JABU_JABUS_BELLY_MQ_GEYSER_POT_2, "RAND_INF_JABU_JABUS_BELLY_MQ_GEYSER_POT_2" }, - { RAND_INF_JABU_JABUS_BELLY_MQ_TIME_BLOCK_POT_1, "RAND_INF_JABU_JABUS_BELLY_MQ_TIME_BLOCK_POT_1" }, - { RAND_INF_JABU_JABUS_BELLY_MQ_TIME_BLOCK_POT_2, "RAND_INF_JABU_JABUS_BELLY_MQ_TIME_BLOCK_POT_2" }, - { RAND_INF_JABU_JABUS_BELLY_MQ_LIKE_LIKES_POT_1, "RAND_INF_JABU_JABUS_BELLY_MQ_LIKE_LIKES_POT_1" }, - { RAND_INF_JABU_JABUS_BELLY_MQ_LIKE_LIKES_POT_2, "RAND_INF_JABU_JABUS_BELLY_MQ_LIKE_LIKES_POT_2" }, - { RAND_INF_JABU_JABUS_BELLY_MQ_BEFORE_BOSS_POT_1, "RAND_INF_JABU_JABUS_BELLY_MQ_BEFORE_BOSS_POT_1" }, - { RAND_INF_FOREST_TEMPLE_MQ_LOBBY_POT_1, "RAND_INF_FOREST_TEMPLE_MQ_LOBBY_POT_1" }, - { RAND_INF_FOREST_TEMPLE_MQ_LOBBY_POT_2, "RAND_INF_FOREST_TEMPLE_MQ_LOBBY_POT_2" }, - { RAND_INF_FOREST_TEMPLE_MQ_LOBBY_POT_3, "RAND_INF_FOREST_TEMPLE_MQ_LOBBY_POT_3" }, - { RAND_INF_FOREST_TEMPLE_MQ_LOBBY_POT_4, "RAND_INF_FOREST_TEMPLE_MQ_LOBBY_POT_4" }, - { RAND_INF_FOREST_TEMPLE_MQ_LOBBY_POT_5, "RAND_INF_FOREST_TEMPLE_MQ_LOBBY_POT_5" }, - { RAND_INF_FOREST_TEMPLE_MQ_LOBBY_POT_6, "RAND_INF_FOREST_TEMPLE_MQ_LOBBY_POT_6" }, - { RAND_INF_FOREST_TEMPLE_MQ_LOWER_STALFOS_POT_1, "RAND_INF_FOREST_TEMPLE_MQ_LOWER_STALFOS_POT_1" }, - { RAND_INF_FOREST_TEMPLE_MQ_LOWER_STALFOS_POT_2, "RAND_INF_FOREST_TEMPLE_MQ_LOWER_STALFOS_POT_2" }, - { RAND_INF_FOREST_TEMPLE_MQ_UPPER_STALFOS_POT_1, "RAND_INF_FOREST_TEMPLE_MQ_UPPER_STALFOS_POT_1" }, - { RAND_INF_FOREST_TEMPLE_MQ_UPPER_STALFOS_POT_2, "RAND_INF_FOREST_TEMPLE_MQ_UPPER_STALFOS_POT_2" }, - { RAND_INF_FOREST_TEMPLE_MQ_UPPER_STALFOS_POT_3, "RAND_INF_FOREST_TEMPLE_MQ_UPPER_STALFOS_POT_3" }, - { RAND_INF_FOREST_TEMPLE_MQ_UPPER_STALFOS_POT_4, "RAND_INF_FOREST_TEMPLE_MQ_UPPER_STALFOS_POT_4" }, - { RAND_INF_FOREST_TEMPLE_MQ_BLUE_POE_POT_1, "RAND_INF_FOREST_TEMPLE_MQ_BLUE_POE_POT_1" }, - { RAND_INF_FOREST_TEMPLE_MQ_BLUE_POE_POT_2, "RAND_INF_FOREST_TEMPLE_MQ_BLUE_POE_POT_2" }, - { RAND_INF_FOREST_TEMPLE_MQ_BLUE_POE_POT_3, "RAND_INF_FOREST_TEMPLE_MQ_BLUE_POE_POT_3" }, - { RAND_INF_FOREST_TEMPLE_MQ_GREEN_POE_POT_1, "RAND_INF_FOREST_TEMPLE_MQ_GREEN_POE_POT_1" }, - { RAND_INF_FOREST_TEMPLE_MQ_GREEN_POE_POT_2, "RAND_INF_FOREST_TEMPLE_MQ_GREEN_POE_POT_2" }, - { RAND_INF_FOREST_TEMPLE_MQ_BASEMENT_POT_1, "RAND_INF_FOREST_TEMPLE_MQ_BASEMENT_POT_1" }, - { RAND_INF_FOREST_TEMPLE_MQ_BASEMENT_POT_2, "RAND_INF_FOREST_TEMPLE_MQ_BASEMENT_POT_2" }, - { RAND_INF_FOREST_TEMPLE_MQ_BASEMENT_POT_3, "RAND_INF_FOREST_TEMPLE_MQ_BASEMENT_POT_3" }, - { RAND_INF_FOREST_TEMPLE_MQ_BASEMENT_POT_4, "RAND_INF_FOREST_TEMPLE_MQ_BASEMENT_POT_4" }, - { RAND_INF_DODONGOS_CAVERN_MQ_RIGHT_SIDE_POT_1, "RAND_INF_DODONGOS_CAVERN_MQ_RIGHT_SIDE_POT_1" }, - { RAND_INF_DODONGOS_CAVERN_MQ_RIGHT_SIDE_POT_2, "RAND_INF_DODONGOS_CAVERN_MQ_RIGHT_SIDE_POT_2" }, - { RAND_INF_DODONGOS_CAVERN_MQ_RIGHT_SIDE_POT_3, "RAND_INF_DODONGOS_CAVERN_MQ_RIGHT_SIDE_POT_3" }, - { RAND_INF_DODONGOS_CAVERN_MQ_RIGHT_SIDE_POT_4, "RAND_INF_DODONGOS_CAVERN_MQ_RIGHT_SIDE_POT_4" }, - { RAND_INF_DODONGOS_CAVERN_MQ_UPPER_LIZALFOS_POT_1, "RAND_INF_DODONGOS_CAVERN_MQ_UPPER_LIZALFOS_POT_1" }, - { RAND_INF_DODONGOS_CAVERN_MQ_UPPER_LIZALFOS_POT_2, "RAND_INF_DODONGOS_CAVERN_MQ_UPPER_LIZALFOS_POT_2" }, - { RAND_INF_DODONGOS_CAVERN_MQ_UPPER_LIZALFOS_POT_3, "RAND_INF_DODONGOS_CAVERN_MQ_UPPER_LIZALFOS_POT_3" }, - { RAND_INF_DODONGOS_CAVERN_MQ_UPPER_LIZALFOS_POT_4, "RAND_INF_DODONGOS_CAVERN_MQ_UPPER_LIZALFOS_POT_4" }, - { RAND_INF_DODONGOS_CAVERN_MQ_POE_ROOM_POT_1, "RAND_INF_DODONGOS_CAVERN_MQ_POE_ROOM_POT_1" }, - { RAND_INF_DODONGOS_CAVERN_MQ_POE_ROOM_POT_2, "RAND_INF_DODONGOS_CAVERN_MQ_POE_ROOM_POT_2" }, - { RAND_INF_DODONGOS_CAVERN_MQ_POE_ROOM_POT_3, "RAND_INF_DODONGOS_CAVERN_MQ_POE_ROOM_POT_3" }, - { RAND_INF_DODONGOS_CAVERN_MQ_POE_ROOM_POT_4, "RAND_INF_DODONGOS_CAVERN_MQ_POE_ROOM_POT_4" }, - { RAND_INF_DODONGOS_CAVERN_MQ_BLOCK_ROOM_POT_1, "RAND_INF_DODONGOS_CAVERN_MQ_BLOCK_ROOM_POT_1" }, - { RAND_INF_DODONGOS_CAVERN_MQ_BLOCK_ROOM_POT_2, "RAND_INF_DODONGOS_CAVERN_MQ_BLOCK_ROOM_POT_2" }, - { RAND_INF_DODONGOS_CAVERN_MQ_TWO_FLAMES_POT_1, "RAND_INF_DODONGOS_CAVERN_MQ_TWO_FLAMES_POT_1" }, - { RAND_INF_DODONGOS_CAVERN_MQ_TWO_FLAMES_POT_2, "RAND_INF_DODONGOS_CAVERN_MQ_TWO_FLAMES_POT_2" }, - { RAND_INF_DODONGOS_CAVERN_MQ_SILVER_BLOCK_POT_1, "RAND_INF_DODONGOS_CAVERN_MQ_SILVER_BLOCK_POT_1" }, - { RAND_INF_DODONGOS_CAVERN_MQ_SILVER_BLOCK_POT_2, "RAND_INF_DODONGOS_CAVERN_MQ_SILVER_BLOCK_POT_2" }, - { RAND_INF_DODONGOS_CAVERN_MQ_STAIRCASE_POT_1, "RAND_INF_DODONGOS_CAVERN_MQ_STAIRCASE_POT_1" }, - { RAND_INF_DODONGOS_CAVERN_MQ_STAIRCASE_POT_2, "RAND_INF_DODONGOS_CAVERN_MQ_STAIRCASE_POT_2" }, - { RAND_INF_DODONGOS_CAVERN_MQ_STAIRCASE_POT_3, "RAND_INF_DODONGOS_CAVERN_MQ_STAIRCASE_POT_3" }, - { RAND_INF_DODONGOS_CAVERN_MQ_STAIRCASE_POT_4, "RAND_INF_DODONGOS_CAVERN_MQ_STAIRCASE_POT_4" }, - { RAND_INF_DODONGOS_CAVERN_MQ_ARMOS_POT_1, "RAND_INF_DODONGOS_CAVERN_MQ_ARMOS_POT_1" }, - { RAND_INF_DODONGOS_CAVERN_MQ_ARMOS_POT_2, "RAND_INF_DODONGOS_CAVERN_MQ_ARMOS_POT_2" }, - { RAND_INF_DODONGOS_CAVERN_MQ_ARMOS_POT_3, "RAND_INF_DODONGOS_CAVERN_MQ_ARMOS_POT_3" }, - { RAND_INF_DODONGOS_CAVERN_MQ_ARMOS_POT_4, "RAND_INF_DODONGOS_CAVERN_MQ_ARMOS_POT_4" }, - { RAND_INF_DODONGOS_CAVERN_MQ_BEFORE_BOSS_POT_1, "RAND_INF_DODONGOS_CAVERN_MQ_BEFORE_BOSS_POT_1" }, - { RAND_INF_DODONGOS_CAVERN_MQ_BEFORE_BOSS_POT_2, "RAND_INF_DODONGOS_CAVERN_MQ_BEFORE_BOSS_POT_2" }, - { RAND_INF_DODONGOS_CAVERN_MQ_BACKROOM_POT_1, "RAND_INF_DODONGOS_CAVERN_MQ_BACKROOM_POT_1" }, - { RAND_INF_DODONGOS_CAVERN_MQ_BACKROOM_POT_2, "RAND_INF_DODONGOS_CAVERN_MQ_BACKROOM_POT_2" }, - { RAND_INF_GANONS_CASTLE_MQ_FOREST_TRIAL_POT_1, "RAND_INF_GANONS_CASTLE_MQ_FOREST_TRIAL_POT_1" }, - { RAND_INF_GANONS_CASTLE_MQ_FOREST_TRIAL_POT_2, "RAND_INF_GANONS_CASTLE_MQ_FOREST_TRIAL_POT_2" }, - { RAND_INF_GANONS_CASTLE_MQ_WATER_TRIAL_POT_1, "RAND_INF_GANONS_CASTLE_MQ_WATER_TRIAL_POT_1" }, - { RAND_INF_GANONS_CASTLE_MQ_WATER_TRIAL_POT_2, "RAND_INF_GANONS_CASTLE_MQ_WATER_TRIAL_POT_2" }, - { RAND_INF_GANONS_CASTLE_MQ_SHADOW_TRIAL_POT_1, "RAND_INF_GANONS_CASTLE_MQ_SHADOW_TRIAL_POT_1" }, - { RAND_INF_GANONS_CASTLE_MQ_SHADOW_TRIAL_POT_2, "RAND_INF_GANONS_CASTLE_MQ_SHADOW_TRIAL_POT_2" }, - { RAND_INF_GANONS_CASTLE_MQ_FIRE_TRIAL_POT_1, "RAND_INF_GANONS_CASTLE_MQ_FIRE_TRIAL_POT_1" }, - { RAND_INF_GANONS_CASTLE_MQ_FIRE_TRIAL_POT_2, "RAND_INF_GANONS_CASTLE_MQ_FIRE_TRIAL_POT_2" }, - { RAND_INF_GANONS_CASTLE_MQ_LIGHT_TRIAL_POT_1, "RAND_INF_GANONS_CASTLE_MQ_LIGHT_TRIAL_POT_1" }, - { RAND_INF_GANONS_CASTLE_MQ_LIGHT_TRIAL_POT_2, "RAND_INF_GANONS_CASTLE_MQ_LIGHT_TRIAL_POT_2" }, - { RAND_INF_GANONS_CASTLE_MQ_SPIRIT_TRIAL_POT_1, "RAND_INF_GANONS_CASTLE_MQ_SPIRIT_TRIAL_POT_1" }, - { RAND_INF_GANONS_CASTLE_MQ_SPIRIT_TRIAL_POT_2, "RAND_INF_GANONS_CASTLE_MQ_SPIRIT_TRIAL_POT_2" }, - { RAND_INF_SHADOW_TEMPLE_MQ_WHISPERING_WALLS_POT_1, "RAND_INF_SHADOW_TEMPLE_MQ_WHISPERING_WALLS_POT_1" }, - { RAND_INF_SHADOW_TEMPLE_MQ_WHISPERING_WALLS_POT_2, "RAND_INF_SHADOW_TEMPLE_MQ_WHISPERING_WALLS_POT_2" }, - { RAND_INF_SHADOW_TEMPLE_MQ_ENTRANCE_REDEAD_POT_1, "RAND_INF_SHADOW_TEMPLE_MQ_ENTRANCE_REDEAD_POT_1" }, - { RAND_INF_SHADOW_TEMPLE_MQ_ENTRANCE_REDEAD_POT_2, "RAND_INF_SHADOW_TEMPLE_MQ_ENTRANCE_REDEAD_POT_2" }, - { RAND_INF_SHADOW_TEMPLE_MQ_FALLING_SPIKES_POT_1, "RAND_INF_SHADOW_TEMPLE_MQ_FALLING_SPIKES_POT_1" }, - { RAND_INF_SHADOW_TEMPLE_MQ_FALLING_SPIKES_POT_2, "RAND_INF_SHADOW_TEMPLE_MQ_FALLING_SPIKES_POT_2" }, - { RAND_INF_SHADOW_TEMPLE_MQ_FALLING_SPIKES_POT_3, "RAND_INF_SHADOW_TEMPLE_MQ_FALLING_SPIKES_POT_3" }, - { RAND_INF_SHADOW_TEMPLE_MQ_FALLING_SPIKES_POT_4, "RAND_INF_SHADOW_TEMPLE_MQ_FALLING_SPIKES_POT_4" }, - { RAND_INF_SHADOW_TEMPLE_MQ_BEFORE_BOAT_POT_1, "RAND_INF_SHADOW_TEMPLE_MQ_BEFORE_BOAT_POT_1" }, - { RAND_INF_SHADOW_TEMPLE_MQ_BEFORE_BOAT_POT_2, "RAND_INF_SHADOW_TEMPLE_MQ_BEFORE_BOAT_POT_2" }, - { RAND_INF_SHADOW_TEMPLE_MQ_AFTER_BOAT_POT_1, "RAND_INF_SHADOW_TEMPLE_MQ_AFTER_BOAT_POT_1" }, - { RAND_INF_SHADOW_TEMPLE_MQ_AFTER_BOAT_POT_2, "RAND_INF_SHADOW_TEMPLE_MQ_AFTER_BOAT_POT_2" }, - { RAND_INF_SHADOW_TEMPLE_MQ_AFTER_BOAT_POT_3, "RAND_INF_SHADOW_TEMPLE_MQ_AFTER_BOAT_POT_3" }, - { RAND_INF_SHADOW_TEMPLE_MQ_AFTER_BOAT_POT_4, "RAND_INF_SHADOW_TEMPLE_MQ_AFTER_BOAT_POT_4" }, - { RAND_INF_SHADOW_TEMPLE_MQ_SPIKE_BARICADE_POT, "RAND_INF_SHADOW_TEMPLE_MQ_SPIKE_BARICADE_POT" }, - { RAND_INF_SHADOW_TEMPLE_MQ_DEAD_HAND_POT_1, "RAND_INF_SHADOW_TEMPLE_MQ_DEAD_HAND_POT_1" }, - { RAND_INF_SHADOW_TEMPLE_MQ_DEAD_HAND_POT_2, "RAND_INF_SHADOW_TEMPLE_MQ_DEAD_HAND_POT_2" }, - { RAND_INF_BOTTOM_OF_THE_WELL_MQ_INNER_LOBBY_POT_1, "RAND_INF_BOTTOM_OF_THE_WELL_MQ_INNER_LOBBY_POT_1" }, - { RAND_INF_BOTTOM_OF_THE_WELL_MQ_INNER_LOBBY_POT_2, "RAND_INF_BOTTOM_OF_THE_WELL_MQ_INNER_LOBBY_POT_2" }, - { RAND_INF_BOTTOM_OF_THE_WELL_MQ_INNER_LOBBY_POT_3, "RAND_INF_BOTTOM_OF_THE_WELL_MQ_INNER_LOBBY_POT_3" }, - { RAND_INF_BOTTOM_OF_THE_WELL_MQ_OUTER_LOBBY_POT, "RAND_INF_BOTTOM_OF_THE_WELL_MQ_OUTER_LOBBY_POT" }, - { RAND_INF_BOTTOM_OF_THE_WELL_MQ_SOUTH_KEY_POT_1, "RAND_INF_BOTTOM_OF_THE_WELL_MQ_SOUTH_KEY_POT_1" }, - { RAND_INF_BOTTOM_OF_THE_WELL_MQ_SOUTH_KEY_POT_2, "RAND_INF_BOTTOM_OF_THE_WELL_MQ_SOUTH_KEY_POT_2" }, - { RAND_INF_BOTTOM_OF_THE_WELL_MQ_SOUTH_KEY_POT_3, "RAND_INF_BOTTOM_OF_THE_WELL_MQ_SOUTH_KEY_POT_3" }, - { RAND_INF_FIRE_TEMPLE_MQ_ENTRANCE_POT_1, "RAND_INF_FIRE_TEMPLE_MQ_ENTRANCE_POT_1" }, - { RAND_INF_FIRE_TEMPLE_MQ_ENTRANCE_POT_2, "RAND_INF_FIRE_TEMPLE_MQ_ENTRANCE_POT_2" }, - { RAND_INF_FIRE_TEMPLE_MQ_OUTSIDE_BOSS_POT_1, "RAND_INF_FIRE_TEMPLE_MQ_OUTSIDE_BOSS_POT_1" }, - { RAND_INF_FIRE_TEMPLE_MQ_OUTSIDE_BOSS_POT_2, "RAND_INF_FIRE_TEMPLE_MQ_OUTSIDE_BOSS_POT_2" }, - { RAND_INF_FIRE_TEMPLE_MQ_LAVA_POT_1, "RAND_INF_FIRE_TEMPLE_MQ_LAVA_POT_1" }, - { RAND_INF_FIRE_TEMPLE_MQ_LAVA_POT_2, "RAND_INF_FIRE_TEMPLE_MQ_LAVA_POT_2" }, - { RAND_INF_FIRE_TEMPLE_MQ_LAVA_POT_3, "RAND_INF_FIRE_TEMPLE_MQ_LAVA_POT_3" }, - { RAND_INF_FIRE_TEMPLE_MQ_LAVA_TORCH_POT_1, "RAND_INF_FIRE_TEMPLE_MQ_LAVA_TORCH_POT_1" }, - { RAND_INF_FIRE_TEMPLE_MQ_LAVA_TORCH_POT_2, "RAND_INF_FIRE_TEMPLE_MQ_LAVA_TORCH_POT_2" }, - { RAND_INF_FIRE_TEMPLE_MQ_ABOVE_LAVA_POT_1, "RAND_INF_FIRE_TEMPLE_MQ_ABOVE_LAVA_POT_1" }, - { RAND_INF_FIRE_TEMPLE_MQ_ABOVE_LAVA_POT_2, "RAND_INF_FIRE_TEMPLE_MQ_ABOVE_LAVA_POT_2" }, - { RAND_INF_FIRE_TEMPLE_MQ_ABOVE_LAVA_POT_3, "RAND_INF_FIRE_TEMPLE_MQ_ABOVE_LAVA_POT_3" }, - { RAND_INF_FIRE_TEMPLE_MQ_FLAME_WALL_POT_1, "RAND_INF_FIRE_TEMPLE_MQ_FLAME_WALL_POT_1" }, - { RAND_INF_FIRE_TEMPLE_MQ_FLAME_WALL_POT_2, "RAND_INF_FIRE_TEMPLE_MQ_FLAME_WALL_POT_2" }, - { RAND_INF_FIRE_TEMPLE_MQ_FIRE_MAZE_POT_1, "RAND_INF_FIRE_TEMPLE_MQ_FIRE_MAZE_POT_1" }, - { RAND_INF_FIRE_TEMPLE_MQ_FIRE_MAZE_POT_2, "RAND_INF_FIRE_TEMPLE_MQ_FIRE_MAZE_POT_2" }, - { RAND_INF_FIRE_TEMPLE_MQ_FIRE_MAZE_POT_3, "RAND_INF_FIRE_TEMPLE_MQ_FIRE_MAZE_POT_3" }, - { RAND_INF_FIRE_TEMPLE_MQ_FIRE_MAZE_POT_4, "RAND_INF_FIRE_TEMPLE_MQ_FIRE_MAZE_POT_4" }, - { RAND_INF_FIRE_TEMPLE_MQ_FIRE_MAZE_POT_5, "RAND_INF_FIRE_TEMPLE_MQ_FIRE_MAZE_POT_5" }, - { RAND_INF_FIRE_TEMPLE_MQ_FIRE_MAZE_POT_6, "RAND_INF_FIRE_TEMPLE_MQ_FIRE_MAZE_POT_6" }, - { RAND_INF_FIRE_TEMPLE_MQ_BEFORE_MINI_BOSS_POT_1, "RAND_INF_FIRE_TEMPLE_MQ_BEFORE_MINI_BOSS_POT_1" }, - { RAND_INF_FIRE_TEMPLE_MQ_BEFORE_MINI_BOSS_POT_2, "RAND_INF_FIRE_TEMPLE_MQ_BEFORE_MINI_BOSS_POT_2" }, - { RAND_INF_FIRE_TEMPLE_MQ_BEFORE_MINI_BOSS_POT_3, "RAND_INF_FIRE_TEMPLE_MQ_BEFORE_MINI_BOSS_POT_3" }, - { RAND_INF_FIRE_TEMPLE_MQ_BEFORE_MINI_BOSS_POT_4, "RAND_INF_FIRE_TEMPLE_MQ_BEFORE_MINI_BOSS_POT_4" }, - { RAND_INF_FIRE_TEMPLE_MQ_BEFORE_MINI_BOSS_POT_5, "RAND_INF_FIRE_TEMPLE_MQ_BEFORE_MINI_BOSS_POT_5" }, - { RAND_INF_FIRE_TEMPLE_MQ_BEFORE_MINI_BOSS_POT_6, "RAND_INF_FIRE_TEMPLE_MQ_BEFORE_MINI_BOSS_POT_6" }, - { RAND_INF_FIRE_TEMPLE_MQ_BEFORE_MINI_BOSS_POT_7, "RAND_INF_FIRE_TEMPLE_MQ_BEFORE_MINI_BOSS_POT_7" }, - { RAND_INF_FIRE_TEMPLE_MQ_BEFORE_MINI_BOSS_POT_8, "RAND_INF_FIRE_TEMPLE_MQ_BEFORE_MINI_BOSS_POT_8" }, - { RAND_INF_ICE_CAVERN_MQ_ENTRANCE_POT, "RAND_INF_ICE_CAVERN_MQ_ENTRANCE_POT" }, - { RAND_INF_ICE_CAVERN_MQ_FIRST_CRYSTAL_POT_1, "RAND_INF_ICE_CAVERN_MQ_FIRST_CRYSTAL_POT_1" }, - { RAND_INF_ICE_CAVERN_MQ_FIRST_CRYSTAL_POT_2, "RAND_INF_ICE_CAVERN_MQ_FIRST_CRYSTAL_POT_2" }, - { RAND_INF_ICE_CAVERN_MQ_EARLY_WOLFOS_POT_1, "RAND_INF_ICE_CAVERN_MQ_EARLY_WOLFOS_POT_1" }, - { RAND_INF_ICE_CAVERN_MQ_EARLY_WOLFOS_POT_2, "RAND_INF_ICE_CAVERN_MQ_EARLY_WOLFOS_POT_2" }, - { RAND_INF_ICE_CAVERN_MQ_EARLY_WOLFOS_POT_3, "RAND_INF_ICE_CAVERN_MQ_EARLY_WOLFOS_POT_3" }, - { RAND_INF_ICE_CAVERN_MQ_EARLY_WOLFOS_POT_4, "RAND_INF_ICE_CAVERN_MQ_EARLY_WOLFOS_POT_4" }, - { RAND_INF_ICE_CAVERN_MQ_PUSH_BLOCK_POT_1, "RAND_INF_ICE_CAVERN_MQ_PUSH_BLOCK_POT_1" }, - { RAND_INF_ICE_CAVERN_MQ_PUSH_BLOCK_POT_2, "RAND_INF_ICE_CAVERN_MQ_PUSH_BLOCK_POT_2" }, - { RAND_INF_ICE_CAVERN_MQ_COMPASS_POT_1, "RAND_INF_ICE_CAVERN_MQ_COMPASS_POT_1" }, - { RAND_INF_ICE_CAVERN_MQ_COMPASS_POT_2, "RAND_INF_ICE_CAVERN_MQ_COMPASS_POT_2" }, - { RAND_INF_SPIRIT_TEMPLE_MQ_ENTRANCE_POT_1, "RAND_INF_SPIRIT_TEMPLE_MQ_ENTRANCE_POT_1" }, - { RAND_INF_SPIRIT_TEMPLE_MQ_ENTRANCE_POT_2, "RAND_INF_SPIRIT_TEMPLE_MQ_ENTRANCE_POT_2" }, - { RAND_INF_SPIRIT_TEMPLE_MQ_ENTRANCE_POT_3, "RAND_INF_SPIRIT_TEMPLE_MQ_ENTRANCE_POT_3" }, - { RAND_INF_SPIRIT_TEMPLE_MQ_ENTRANCE_POT_4, "RAND_INF_SPIRIT_TEMPLE_MQ_ENTRANCE_POT_4" }, - { RAND_INF_SPIRIT_TEMPLE_MQ_CHILD_SLUGMA_POT, "RAND_INF_SPIRIT_TEMPLE_MQ_CHILD_SLUGMA_POT" }, - { RAND_INF_SPIRIT_TEMPLE_MQ_CHILD_GIBDO_POT_1, "RAND_INF_SPIRIT_TEMPLE_MQ_CHILD_GIBDO_POT_1" }, - { RAND_INF_SPIRIT_TEMPLE_MQ_CHILD_GIBDO_POT_2, "RAND_INF_SPIRIT_TEMPLE_MQ_CHILD_GIBDO_POT_2" }, - { RAND_INF_SPIRIT_TEMPLE_MQ_CHILD_LIKE_LIKE_POT, "RAND_INF_SPIRIT_TEMPLE_MQ_CHILD_LIKE_LIKE_POT" }, - { RAND_INF_SPIRIT_TEMPLE_MQ_CHILD_STALFOS_POT_1, "RAND_INF_SPIRIT_TEMPLE_MQ_CHILD_STALFOS_POT_1" }, - { RAND_INF_SPIRIT_TEMPLE_MQ_CHILD_STALFOS_POT_2, "RAND_INF_SPIRIT_TEMPLE_MQ_CHILD_STALFOS_POT_2" }, - { RAND_INF_SPIRIT_TEMPLE_MQ_CHILD_STALFOS_POT_3, "RAND_INF_SPIRIT_TEMPLE_MQ_CHILD_STALFOS_POT_3" }, - { RAND_INF_SPIRIT_TEMPLE_MQ_CHILD_STALFOS_POT_4, "RAND_INF_SPIRIT_TEMPLE_MQ_CHILD_STALFOS_POT_4" }, - { RAND_INF_SPIRIT_TEMPLE_MQ_CENTRAL_CHAMBER_POT_1, "RAND_INF_SPIRIT_TEMPLE_MQ_CENTRAL_CHAMBER_POT_1" }, - { RAND_INF_SPIRIT_TEMPLE_MQ_CENTRAL_CHAMBER_POT_2, "RAND_INF_SPIRIT_TEMPLE_MQ_CENTRAL_CHAMBER_POT_2" }, - { RAND_INF_SPIRIT_TEMPLE_MQ_CENTRAL_CHAMBER_POT_3, "RAND_INF_SPIRIT_TEMPLE_MQ_CENTRAL_CHAMBER_POT_3" }, - { RAND_INF_SPIRIT_TEMPLE_MQ_CENTRAL_CHAMBER_POT_4, "RAND_INF_SPIRIT_TEMPLE_MQ_CENTRAL_CHAMBER_POT_4" }, - { RAND_INF_SPIRIT_TEMPLE_MQ_CENTRAL_CHAMBER_POT_5, "RAND_INF_SPIRIT_TEMPLE_MQ_CENTRAL_CHAMBER_POT_5" }, - { RAND_INF_SPIRIT_TEMPLE_MQ_SUN_BLOCKS_POT_1, "RAND_INF_SPIRIT_TEMPLE_MQ_SUN_BLOCKS_POT_1" }, - { RAND_INF_SPIRIT_TEMPLE_MQ_SUN_BLOCKS_POT_2, "RAND_INF_SPIRIT_TEMPLE_MQ_SUN_BLOCKS_POT_2" }, - { RAND_INF_SPIRIT_TEMPLE_MQ_LONG_CLIMB_POT_1, "RAND_INF_SPIRIT_TEMPLE_MQ_LONG_CLIMB_POT_1" }, - { RAND_INF_SPIRIT_TEMPLE_MQ_LONG_CLIMB_POT_2, "RAND_INF_SPIRIT_TEMPLE_MQ_LONG_CLIMB_POT_2" }, - { RAND_INF_SPIRIT_TEMPLE_MQ_BIG_MIRROR_POT_1, "RAND_INF_SPIRIT_TEMPLE_MQ_BIG_MIRROR_POT_1" }, - { RAND_INF_SPIRIT_TEMPLE_MQ_BIG_MIRROR_POT_2, "RAND_INF_SPIRIT_TEMPLE_MQ_BIG_MIRROR_POT_2" }, - { RAND_INF_SPIRIT_TEMPLE_MQ_BIG_MIRROR_POT_3, "RAND_INF_SPIRIT_TEMPLE_MQ_BIG_MIRROR_POT_3" }, - { RAND_INF_SPIRIT_TEMPLE_MQ_BIG_MIRROR_POT_4, "RAND_INF_SPIRIT_TEMPLE_MQ_BIG_MIRROR_POT_4" }, - { RAND_INF_SPIRIT_TEMPLE_MQ_BEFORE_MIRROR_POT_1, "RAND_INF_SPIRIT_TEMPLE_MQ_BEFORE_MIRROR_POT_1" }, - { RAND_INF_SPIRIT_TEMPLE_MQ_BEFORE_MIRROR_POT_2, "RAND_INF_SPIRIT_TEMPLE_MQ_BEFORE_MIRROR_POT_2" }, - { RAND_INF_SPIRIT_TEMPLE_MQ_EARLY_ADULT_POT_1, "RAND_INF_SPIRIT_TEMPLE_MQ_EARLY_ADULT_POT_1" }, - { RAND_INF_SPIRIT_TEMPLE_MQ_EARLY_ADULT_POT_2, "RAND_INF_SPIRIT_TEMPLE_MQ_EARLY_ADULT_POT_2" }, - { RAND_INF_WATER_TEMPLE_MQ_CENTRAL_GATE_POT_1, "RAND_INF_WATER_TEMPLE_MQ_CENTRAL_GATE_POT_1" }, - { RAND_INF_WATER_TEMPLE_MQ_CENTRAL_GATE_POT_2, "RAND_INF_WATER_TEMPLE_MQ_CENTRAL_GATE_POT_2" }, - { RAND_INF_WATER_TEMPLE_MQ_CENTRAL_GATE_POT_3, "RAND_INF_WATER_TEMPLE_MQ_CENTRAL_GATE_POT_3" }, - { RAND_INF_WATER_TEMPLE_MQ_CENTRAL_GATE_POT_4, "RAND_INF_WATER_TEMPLE_MQ_CENTRAL_GATE_POT_4" }, - { RAND_INF_WATER_TEMPLE_MQ_CENTRAL_GATE_POT_5, "RAND_INF_WATER_TEMPLE_MQ_CENTRAL_GATE_POT_5" }, - { RAND_INF_WATER_TEMPLE_MQ_STORAGE_ROOM_A_POT_1, "RAND_INF_WATER_TEMPLE_MQ_STORAGE_ROOM_A_POT_1" }, - { RAND_INF_WATER_TEMPLE_MQ_STORAGE_ROOM_A_POT_2, "RAND_INF_WATER_TEMPLE_MQ_STORAGE_ROOM_A_POT_2" }, - { RAND_INF_WATER_TEMPLE_MQ_STORAGE_ROOM_A_POT_3, "RAND_INF_WATER_TEMPLE_MQ_STORAGE_ROOM_A_POT_3" }, - { RAND_INF_WATER_TEMPLE_MQ_BEFORE_DARK_LINK_POT_1, "RAND_INF_WATER_TEMPLE_MQ_BEFORE_DARK_LINK_POT_1" }, - { RAND_INF_WATER_TEMPLE_MQ_BEFORE_DARK_LINK_POT_2, "RAND_INF_WATER_TEMPLE_MQ_BEFORE_DARK_LINK_POT_2" }, - { RAND_INF_WATER_TEMPLE_MQ_BEFORE_DARK_LINK_POT_3, "RAND_INF_WATER_TEMPLE_MQ_BEFORE_DARK_LINK_POT_3" }, - { RAND_INF_WATER_TEMPLE_MQ_BEFORE_DARK_LINK_POT_4, "RAND_INF_WATER_TEMPLE_MQ_BEFORE_DARK_LINK_POT_4" }, - { RAND_INF_WATER_TEMPLE_MQ_BEFORE_DARK_LINK_POT_5, "RAND_INF_WATER_TEMPLE_MQ_BEFORE_DARK_LINK_POT_5" }, - { RAND_INF_WATER_TEMPLE_MQ_AFTER_DARK_LINK_POT_1, "RAND_INF_WATER_TEMPLE_MQ_AFTER_DARK_LINK_POT_1" }, - { RAND_INF_WATER_TEMPLE_MQ_AFTER_DARK_LINK_POT_2, "RAND_INF_WATER_TEMPLE_MQ_AFTER_DARK_LINK_POT_2" }, - { RAND_INF_WATER_TEMPLE_MQ_RIVER_POT_1, "RAND_INF_WATER_TEMPLE_MQ_RIVER_POT_1" }, - { RAND_INF_WATER_TEMPLE_MQ_RIVER_POT_2, "RAND_INF_WATER_TEMPLE_MQ_RIVER_POT_2" }, - { RAND_INF_WATER_TEMPLE_MQ_MINI_DODONGO_POT_1, "RAND_INF_WATER_TEMPLE_MQ_MINI_DODONGO_POT_1" }, - { RAND_INF_WATER_TEMPLE_MQ_MINI_DODONGO_POT_2, "RAND_INF_WATER_TEMPLE_MQ_MINI_DODONGO_POT_2" }, - { RAND_INF_WATER_TEMPLE_MQ_STORAGE_ROOM_B_POT_1, "RAND_INF_WATER_TEMPLE_MQ_STORAGE_ROOM_B_POT_1" }, - { RAND_INF_WATER_TEMPLE_MQ_STORAGE_ROOM_B_POT_2, "RAND_INF_WATER_TEMPLE_MQ_STORAGE_ROOM_B_POT_2" }, - { RAND_INF_WATER_TEMPLE_MQ_GS_STORAGE_ROOM_POT_1, "RAND_INF_WATER_TEMPLE_MQ_GS_STORAGE_ROOM_POT_1" }, - { RAND_INF_WATER_TEMPLE_MQ_GS_STORAGE_ROOM_POT_2, "RAND_INF_WATER_TEMPLE_MQ_GS_STORAGE_ROOM_POT_2" }, - { RAND_INF_WATER_TEMPLE_MQ_GS_STORAGE_ROOM_POT_3, "RAND_INF_WATER_TEMPLE_MQ_GS_STORAGE_ROOM_POT_3" }, - { RAND_INF_WATER_TEMPLE_MQ_LOWER_TORCHES_POT_1, "RAND_INF_WATER_TEMPLE_MQ_LOWER_TORCHES_POT_1" }, - { RAND_INF_WATER_TEMPLE_MQ_LOWER_TORCHES_POT_2, "RAND_INF_WATER_TEMPLE_MQ_LOWER_TORCHES_POT_2" }, - { RAND_INF_WATER_TEMPLE_MQ_LOWEST_GS_POT_1, "RAND_INF_WATER_TEMPLE_MQ_LOWEST_GS_POT_1" }, - { RAND_INF_WATER_TEMPLE_MQ_LOWEST_GS_POT_2, "RAND_INF_WATER_TEMPLE_MQ_LOWEST_GS_POT_2" }, - { RAND_INF_WATER_TEMPLE_MQ_LOWEST_GS_POT_3, "RAND_INF_WATER_TEMPLE_MQ_LOWEST_GS_POT_3" }, - { RAND_INF_WATER_TEMPLE_MQ_LOWEST_GS_POT_4, "RAND_INF_WATER_TEMPLE_MQ_LOWEST_GS_POT_4" }, - { RAND_INF_WATER_TEMPLE_MQ_BOSS_KEY_POT, "RAND_INF_WATER_TEMPLE_MQ_BOSS_KEY_POT" }, - { RAND_INF_GERUDO_TRAINING_GROUND_MQ_LOBBY_LEFT_POT_1, "RAND_INF_GERUDO_TRAINING_GROUND_MQ_LOBBY_LEFT_POT_1" }, - { RAND_INF_GERUDO_TRAINING_GROUND_MQ_LOBBY_LEFT_POT_2, "RAND_INF_GERUDO_TRAINING_GROUND_MQ_LOBBY_LEFT_POT_2" }, - { RAND_INF_GERUDO_TRAINING_GROUND_MQ_LOBBY_RIGHT_POT_1, "RAND_INF_GERUDO_TRAINING_GROUND_MQ_LOBBY_RIGHT_POT_1" }, - { RAND_INF_GERUDO_TRAINING_GROUND_MQ_LOBBY_RIGHT_POT_2, "RAND_INF_GERUDO_TRAINING_GROUND_MQ_LOBBY_RIGHT_POT_2" }, - - { RAND_INF_CAUGHT_LOACH, "RAND_INF_CAUGHT_LOACH" }, + { RAND_INF_JABU_JABUS_BELLY_MQ_ENTRANCE_POT_1, "RAND_INF_JABU_JABUS_BELLY_MQ_ENTRANCE_POT_1" }, + { RAND_INF_JABU_JABUS_BELLY_MQ_ENTRANCE_POT_2, "RAND_INF_JABU_JABUS_BELLY_MQ_ENTRANCE_POT_2" }, + { RAND_INF_JABU_JABUS_BELLY_MQ_GEYSER_POT_1, "RAND_INF_JABU_JABUS_BELLY_MQ_GEYSER_POT_1" }, + { RAND_INF_JABU_JABUS_BELLY_MQ_GEYSER_POT_2, "RAND_INF_JABU_JABUS_BELLY_MQ_GEYSER_POT_2" }, + { RAND_INF_JABU_JABUS_BELLY_MQ_TIME_BLOCK_POT_1, "RAND_INF_JABU_JABUS_BELLY_MQ_TIME_BLOCK_POT_1" }, + { RAND_INF_JABU_JABUS_BELLY_MQ_TIME_BLOCK_POT_2, "RAND_INF_JABU_JABUS_BELLY_MQ_TIME_BLOCK_POT_2" }, + { RAND_INF_JABU_JABUS_BELLY_MQ_LIKE_LIKES_POT_1, "RAND_INF_JABU_JABUS_BELLY_MQ_LIKE_LIKES_POT_1" }, + { RAND_INF_JABU_JABUS_BELLY_MQ_LIKE_LIKES_POT_2, "RAND_INF_JABU_JABUS_BELLY_MQ_LIKE_LIKES_POT_2" }, + { RAND_INF_JABU_JABUS_BELLY_MQ_BEFORE_BOSS_POT_1, "RAND_INF_JABU_JABUS_BELLY_MQ_BEFORE_BOSS_POT_1" }, + { RAND_INF_FOREST_TEMPLE_MQ_LOBBY_POT_1, "RAND_INF_FOREST_TEMPLE_MQ_LOBBY_POT_1" }, + { RAND_INF_FOREST_TEMPLE_MQ_LOBBY_POT_2, "RAND_INF_FOREST_TEMPLE_MQ_LOBBY_POT_2" }, + { RAND_INF_FOREST_TEMPLE_MQ_LOBBY_POT_3, "RAND_INF_FOREST_TEMPLE_MQ_LOBBY_POT_3" }, + { RAND_INF_FOREST_TEMPLE_MQ_LOBBY_POT_4, "RAND_INF_FOREST_TEMPLE_MQ_LOBBY_POT_4" }, + { RAND_INF_FOREST_TEMPLE_MQ_LOBBY_POT_5, "RAND_INF_FOREST_TEMPLE_MQ_LOBBY_POT_5" }, + { RAND_INF_FOREST_TEMPLE_MQ_LOBBY_POT_6, "RAND_INF_FOREST_TEMPLE_MQ_LOBBY_POT_6" }, + { RAND_INF_FOREST_TEMPLE_MQ_LOWER_STALFOS_POT_1, "RAND_INF_FOREST_TEMPLE_MQ_LOWER_STALFOS_POT_1" }, + { RAND_INF_FOREST_TEMPLE_MQ_LOWER_STALFOS_POT_2, "RAND_INF_FOREST_TEMPLE_MQ_LOWER_STALFOS_POT_2" }, + { RAND_INF_FOREST_TEMPLE_MQ_UPPER_STALFOS_POT_1, "RAND_INF_FOREST_TEMPLE_MQ_UPPER_STALFOS_POT_1" }, + { RAND_INF_FOREST_TEMPLE_MQ_UPPER_STALFOS_POT_2, "RAND_INF_FOREST_TEMPLE_MQ_UPPER_STALFOS_POT_2" }, + { RAND_INF_FOREST_TEMPLE_MQ_UPPER_STALFOS_POT_3, "RAND_INF_FOREST_TEMPLE_MQ_UPPER_STALFOS_POT_3" }, + { RAND_INF_FOREST_TEMPLE_MQ_UPPER_STALFOS_POT_4, "RAND_INF_FOREST_TEMPLE_MQ_UPPER_STALFOS_POT_4" }, + { RAND_INF_FOREST_TEMPLE_MQ_BLUE_POE_POT_1, "RAND_INF_FOREST_TEMPLE_MQ_BLUE_POE_POT_1" }, + { RAND_INF_FOREST_TEMPLE_MQ_BLUE_POE_POT_2, "RAND_INF_FOREST_TEMPLE_MQ_BLUE_POE_POT_2" }, + { RAND_INF_FOREST_TEMPLE_MQ_BLUE_POE_POT_3, "RAND_INF_FOREST_TEMPLE_MQ_BLUE_POE_POT_3" }, + { RAND_INF_FOREST_TEMPLE_MQ_GREEN_POE_POT_1, "RAND_INF_FOREST_TEMPLE_MQ_GREEN_POE_POT_1" }, + { RAND_INF_FOREST_TEMPLE_MQ_GREEN_POE_POT_2, "RAND_INF_FOREST_TEMPLE_MQ_GREEN_POE_POT_2" }, + { RAND_INF_FOREST_TEMPLE_MQ_BASEMENT_POT_1, "RAND_INF_FOREST_TEMPLE_MQ_BASEMENT_POT_1" }, + { RAND_INF_FOREST_TEMPLE_MQ_BASEMENT_POT_2, "RAND_INF_FOREST_TEMPLE_MQ_BASEMENT_POT_2" }, + { RAND_INF_FOREST_TEMPLE_MQ_BASEMENT_POT_3, "RAND_INF_FOREST_TEMPLE_MQ_BASEMENT_POT_3" }, + { RAND_INF_FOREST_TEMPLE_MQ_BASEMENT_POT_4, "RAND_INF_FOREST_TEMPLE_MQ_BASEMENT_POT_4" }, + { RAND_INF_DODONGOS_CAVERN_MQ_RIGHT_SIDE_POT_1, "RAND_INF_DODONGOS_CAVERN_MQ_RIGHT_SIDE_POT_1" }, + { RAND_INF_DODONGOS_CAVERN_MQ_RIGHT_SIDE_POT_2, "RAND_INF_DODONGOS_CAVERN_MQ_RIGHT_SIDE_POT_2" }, + { RAND_INF_DODONGOS_CAVERN_MQ_RIGHT_SIDE_POT_3, "RAND_INF_DODONGOS_CAVERN_MQ_RIGHT_SIDE_POT_3" }, + { RAND_INF_DODONGOS_CAVERN_MQ_RIGHT_SIDE_POT_4, "RAND_INF_DODONGOS_CAVERN_MQ_RIGHT_SIDE_POT_4" }, + { RAND_INF_DODONGOS_CAVERN_MQ_UPPER_LIZALFOS_POT_1, "RAND_INF_DODONGOS_CAVERN_MQ_UPPER_LIZALFOS_POT_1" }, + { RAND_INF_DODONGOS_CAVERN_MQ_UPPER_LIZALFOS_POT_2, "RAND_INF_DODONGOS_CAVERN_MQ_UPPER_LIZALFOS_POT_2" }, + { RAND_INF_DODONGOS_CAVERN_MQ_UPPER_LIZALFOS_POT_3, "RAND_INF_DODONGOS_CAVERN_MQ_UPPER_LIZALFOS_POT_3" }, + { RAND_INF_DODONGOS_CAVERN_MQ_UPPER_LIZALFOS_POT_4, "RAND_INF_DODONGOS_CAVERN_MQ_UPPER_LIZALFOS_POT_4" }, + { RAND_INF_DODONGOS_CAVERN_MQ_POE_ROOM_POT_1, "RAND_INF_DODONGOS_CAVERN_MQ_POE_ROOM_POT_1" }, + { RAND_INF_DODONGOS_CAVERN_MQ_POE_ROOM_POT_2, "RAND_INF_DODONGOS_CAVERN_MQ_POE_ROOM_POT_2" }, + { RAND_INF_DODONGOS_CAVERN_MQ_POE_ROOM_POT_3, "RAND_INF_DODONGOS_CAVERN_MQ_POE_ROOM_POT_3" }, + { RAND_INF_DODONGOS_CAVERN_MQ_POE_ROOM_POT_4, "RAND_INF_DODONGOS_CAVERN_MQ_POE_ROOM_POT_4" }, + { RAND_INF_DODONGOS_CAVERN_MQ_BLOCK_ROOM_POT_1, "RAND_INF_DODONGOS_CAVERN_MQ_BLOCK_ROOM_POT_1" }, + { RAND_INF_DODONGOS_CAVERN_MQ_BLOCK_ROOM_POT_2, "RAND_INF_DODONGOS_CAVERN_MQ_BLOCK_ROOM_POT_2" }, + { RAND_INF_DODONGOS_CAVERN_MQ_TWO_FLAMES_POT_1, "RAND_INF_DODONGOS_CAVERN_MQ_TWO_FLAMES_POT_1" }, + { RAND_INF_DODONGOS_CAVERN_MQ_TWO_FLAMES_POT_2, "RAND_INF_DODONGOS_CAVERN_MQ_TWO_FLAMES_POT_2" }, + { RAND_INF_DODONGOS_CAVERN_MQ_SILVER_BLOCK_POT_1, "RAND_INF_DODONGOS_CAVERN_MQ_SILVER_BLOCK_POT_1" }, + { RAND_INF_DODONGOS_CAVERN_MQ_SILVER_BLOCK_POT_2, "RAND_INF_DODONGOS_CAVERN_MQ_SILVER_BLOCK_POT_2" }, + { RAND_INF_DODONGOS_CAVERN_MQ_STAIRCASE_POT_1, "RAND_INF_DODONGOS_CAVERN_MQ_STAIRCASE_POT_1" }, + { RAND_INF_DODONGOS_CAVERN_MQ_STAIRCASE_POT_2, "RAND_INF_DODONGOS_CAVERN_MQ_STAIRCASE_POT_2" }, + { RAND_INF_DODONGOS_CAVERN_MQ_STAIRCASE_POT_3, "RAND_INF_DODONGOS_CAVERN_MQ_STAIRCASE_POT_3" }, + { RAND_INF_DODONGOS_CAVERN_MQ_STAIRCASE_POT_4, "RAND_INF_DODONGOS_CAVERN_MQ_STAIRCASE_POT_4" }, + { RAND_INF_DODONGOS_CAVERN_MQ_ARMOS_POT_1, "RAND_INF_DODONGOS_CAVERN_MQ_ARMOS_POT_1" }, + { RAND_INF_DODONGOS_CAVERN_MQ_ARMOS_POT_2, "RAND_INF_DODONGOS_CAVERN_MQ_ARMOS_POT_2" }, + { RAND_INF_DODONGOS_CAVERN_MQ_ARMOS_POT_3, "RAND_INF_DODONGOS_CAVERN_MQ_ARMOS_POT_3" }, + { RAND_INF_DODONGOS_CAVERN_MQ_ARMOS_POT_4, "RAND_INF_DODONGOS_CAVERN_MQ_ARMOS_POT_4" }, + { RAND_INF_DODONGOS_CAVERN_MQ_BEFORE_BOSS_POT_1, "RAND_INF_DODONGOS_CAVERN_MQ_BEFORE_BOSS_POT_1" }, + { RAND_INF_DODONGOS_CAVERN_MQ_BEFORE_BOSS_POT_2, "RAND_INF_DODONGOS_CAVERN_MQ_BEFORE_BOSS_POT_2" }, + { RAND_INF_DODONGOS_CAVERN_MQ_BACKROOM_POT_1, "RAND_INF_DODONGOS_CAVERN_MQ_BACKROOM_POT_1" }, + { RAND_INF_DODONGOS_CAVERN_MQ_BACKROOM_POT_2, "RAND_INF_DODONGOS_CAVERN_MQ_BACKROOM_POT_2" }, + { RAND_INF_GANONS_CASTLE_MQ_FOREST_TRIAL_POT_1, "RAND_INF_GANONS_CASTLE_MQ_FOREST_TRIAL_POT_1" }, + { RAND_INF_GANONS_CASTLE_MQ_FOREST_TRIAL_POT_2, "RAND_INF_GANONS_CASTLE_MQ_FOREST_TRIAL_POT_2" }, + { RAND_INF_GANONS_CASTLE_MQ_WATER_TRIAL_POT_1, "RAND_INF_GANONS_CASTLE_MQ_WATER_TRIAL_POT_1" }, + { RAND_INF_GANONS_CASTLE_MQ_WATER_TRIAL_POT_2, "RAND_INF_GANONS_CASTLE_MQ_WATER_TRIAL_POT_2" }, + { RAND_INF_GANONS_CASTLE_MQ_SHADOW_TRIAL_POT_1, "RAND_INF_GANONS_CASTLE_MQ_SHADOW_TRIAL_POT_1" }, + { RAND_INF_GANONS_CASTLE_MQ_SHADOW_TRIAL_POT_2, "RAND_INF_GANONS_CASTLE_MQ_SHADOW_TRIAL_POT_2" }, + { RAND_INF_GANONS_CASTLE_MQ_FIRE_TRIAL_POT_1, "RAND_INF_GANONS_CASTLE_MQ_FIRE_TRIAL_POT_1" }, + { RAND_INF_GANONS_CASTLE_MQ_FIRE_TRIAL_POT_2, "RAND_INF_GANONS_CASTLE_MQ_FIRE_TRIAL_POT_2" }, + { RAND_INF_GANONS_CASTLE_MQ_LIGHT_TRIAL_POT_1, "RAND_INF_GANONS_CASTLE_MQ_LIGHT_TRIAL_POT_1" }, + { RAND_INF_GANONS_CASTLE_MQ_LIGHT_TRIAL_POT_2, "RAND_INF_GANONS_CASTLE_MQ_LIGHT_TRIAL_POT_2" }, + { RAND_INF_GANONS_CASTLE_MQ_SPIRIT_TRIAL_POT_1, "RAND_INF_GANONS_CASTLE_MQ_SPIRIT_TRIAL_POT_1" }, + { RAND_INF_GANONS_CASTLE_MQ_SPIRIT_TRIAL_POT_2, "RAND_INF_GANONS_CASTLE_MQ_SPIRIT_TRIAL_POT_2" }, + { RAND_INF_SHADOW_TEMPLE_MQ_WHISPERING_WALLS_POT_1, "RAND_INF_SHADOW_TEMPLE_MQ_WHISPERING_WALLS_POT_1" }, + { RAND_INF_SHADOW_TEMPLE_MQ_WHISPERING_WALLS_POT_2, "RAND_INF_SHADOW_TEMPLE_MQ_WHISPERING_WALLS_POT_2" }, + { RAND_INF_SHADOW_TEMPLE_MQ_ENTRANCE_REDEAD_POT_1, "RAND_INF_SHADOW_TEMPLE_MQ_ENTRANCE_REDEAD_POT_1" }, + { RAND_INF_SHADOW_TEMPLE_MQ_ENTRANCE_REDEAD_POT_2, "RAND_INF_SHADOW_TEMPLE_MQ_ENTRANCE_REDEAD_POT_2" }, + { RAND_INF_SHADOW_TEMPLE_MQ_FALLING_SPIKES_POT_1, "RAND_INF_SHADOW_TEMPLE_MQ_FALLING_SPIKES_POT_1" }, + { RAND_INF_SHADOW_TEMPLE_MQ_FALLING_SPIKES_POT_2, "RAND_INF_SHADOW_TEMPLE_MQ_FALLING_SPIKES_POT_2" }, + { RAND_INF_SHADOW_TEMPLE_MQ_FALLING_SPIKES_POT_3, "RAND_INF_SHADOW_TEMPLE_MQ_FALLING_SPIKES_POT_3" }, + { RAND_INF_SHADOW_TEMPLE_MQ_FALLING_SPIKES_POT_4, "RAND_INF_SHADOW_TEMPLE_MQ_FALLING_SPIKES_POT_4" }, + { RAND_INF_SHADOW_TEMPLE_MQ_BEFORE_BOAT_POT_1, "RAND_INF_SHADOW_TEMPLE_MQ_BEFORE_BOAT_POT_1" }, + { RAND_INF_SHADOW_TEMPLE_MQ_BEFORE_BOAT_POT_2, "RAND_INF_SHADOW_TEMPLE_MQ_BEFORE_BOAT_POT_2" }, + { RAND_INF_SHADOW_TEMPLE_MQ_AFTER_BOAT_POT_1, "RAND_INF_SHADOW_TEMPLE_MQ_AFTER_BOAT_POT_1" }, + { RAND_INF_SHADOW_TEMPLE_MQ_AFTER_BOAT_POT_2, "RAND_INF_SHADOW_TEMPLE_MQ_AFTER_BOAT_POT_2" }, + { RAND_INF_SHADOW_TEMPLE_MQ_AFTER_BOAT_POT_3, "RAND_INF_SHADOW_TEMPLE_MQ_AFTER_BOAT_POT_3" }, + { RAND_INF_SHADOW_TEMPLE_MQ_AFTER_BOAT_POT_4, "RAND_INF_SHADOW_TEMPLE_MQ_AFTER_BOAT_POT_4" }, + { RAND_INF_SHADOW_TEMPLE_MQ_SPIKE_BARICADE_POT, "RAND_INF_SHADOW_TEMPLE_MQ_SPIKE_BARICADE_POT" }, + { RAND_INF_SHADOW_TEMPLE_MQ_DEAD_HAND_POT_1, "RAND_INF_SHADOW_TEMPLE_MQ_DEAD_HAND_POT_1" }, + { RAND_INF_SHADOW_TEMPLE_MQ_DEAD_HAND_POT_2, "RAND_INF_SHADOW_TEMPLE_MQ_DEAD_HAND_POT_2" }, + { RAND_INF_BOTTOM_OF_THE_WELL_MQ_INNER_LOBBY_POT_1, "RAND_INF_BOTTOM_OF_THE_WELL_MQ_INNER_LOBBY_POT_1" }, + { RAND_INF_BOTTOM_OF_THE_WELL_MQ_INNER_LOBBY_POT_2, "RAND_INF_BOTTOM_OF_THE_WELL_MQ_INNER_LOBBY_POT_2" }, + { RAND_INF_BOTTOM_OF_THE_WELL_MQ_INNER_LOBBY_POT_3, "RAND_INF_BOTTOM_OF_THE_WELL_MQ_INNER_LOBBY_POT_3" }, + { RAND_INF_BOTTOM_OF_THE_WELL_MQ_OUTER_LOBBY_POT, "RAND_INF_BOTTOM_OF_THE_WELL_MQ_OUTER_LOBBY_POT" }, + { RAND_INF_BOTTOM_OF_THE_WELL_MQ_SOUTH_KEY_POT_1, "RAND_INF_BOTTOM_OF_THE_WELL_MQ_SOUTH_KEY_POT_1" }, + { RAND_INF_BOTTOM_OF_THE_WELL_MQ_SOUTH_KEY_POT_2, "RAND_INF_BOTTOM_OF_THE_WELL_MQ_SOUTH_KEY_POT_2" }, + { RAND_INF_BOTTOM_OF_THE_WELL_MQ_SOUTH_KEY_POT_3, "RAND_INF_BOTTOM_OF_THE_WELL_MQ_SOUTH_KEY_POT_3" }, + { RAND_INF_FIRE_TEMPLE_MQ_ENTRANCE_POT_1, "RAND_INF_FIRE_TEMPLE_MQ_ENTRANCE_POT_1" }, + { RAND_INF_FIRE_TEMPLE_MQ_ENTRANCE_POT_2, "RAND_INF_FIRE_TEMPLE_MQ_ENTRANCE_POT_2" }, + { RAND_INF_FIRE_TEMPLE_MQ_OUTSIDE_BOSS_POT_1, "RAND_INF_FIRE_TEMPLE_MQ_OUTSIDE_BOSS_POT_1" }, + { RAND_INF_FIRE_TEMPLE_MQ_OUTSIDE_BOSS_POT_2, "RAND_INF_FIRE_TEMPLE_MQ_OUTSIDE_BOSS_POT_2" }, + { RAND_INF_FIRE_TEMPLE_MQ_LAVA_POT_1, "RAND_INF_FIRE_TEMPLE_MQ_LAVA_POT_1" }, + { RAND_INF_FIRE_TEMPLE_MQ_LAVA_POT_2, "RAND_INF_FIRE_TEMPLE_MQ_LAVA_POT_2" }, + { RAND_INF_FIRE_TEMPLE_MQ_LAVA_POT_3, "RAND_INF_FIRE_TEMPLE_MQ_LAVA_POT_3" }, + { RAND_INF_FIRE_TEMPLE_MQ_LAVA_TORCH_POT_1, "RAND_INF_FIRE_TEMPLE_MQ_LAVA_TORCH_POT_1" }, + { RAND_INF_FIRE_TEMPLE_MQ_LAVA_TORCH_POT_2, "RAND_INF_FIRE_TEMPLE_MQ_LAVA_TORCH_POT_2" }, + { RAND_INF_FIRE_TEMPLE_MQ_ABOVE_LAVA_POT_1, "RAND_INF_FIRE_TEMPLE_MQ_ABOVE_LAVA_POT_1" }, + { RAND_INF_FIRE_TEMPLE_MQ_ABOVE_LAVA_POT_2, "RAND_INF_FIRE_TEMPLE_MQ_ABOVE_LAVA_POT_2" }, + { RAND_INF_FIRE_TEMPLE_MQ_ABOVE_LAVA_POT_3, "RAND_INF_FIRE_TEMPLE_MQ_ABOVE_LAVA_POT_3" }, + { RAND_INF_FIRE_TEMPLE_MQ_FLAME_WALL_POT_1, "RAND_INF_FIRE_TEMPLE_MQ_FLAME_WALL_POT_1" }, + { RAND_INF_FIRE_TEMPLE_MQ_FLAME_WALL_POT_2, "RAND_INF_FIRE_TEMPLE_MQ_FLAME_WALL_POT_2" }, + { RAND_INF_FIRE_TEMPLE_MQ_FIRE_MAZE_POT_1, "RAND_INF_FIRE_TEMPLE_MQ_FIRE_MAZE_POT_1" }, + { RAND_INF_FIRE_TEMPLE_MQ_FIRE_MAZE_POT_2, "RAND_INF_FIRE_TEMPLE_MQ_FIRE_MAZE_POT_2" }, + { RAND_INF_FIRE_TEMPLE_MQ_FIRE_MAZE_POT_3, "RAND_INF_FIRE_TEMPLE_MQ_FIRE_MAZE_POT_3" }, + { RAND_INF_FIRE_TEMPLE_MQ_FIRE_MAZE_POT_4, "RAND_INF_FIRE_TEMPLE_MQ_FIRE_MAZE_POT_4" }, + { RAND_INF_FIRE_TEMPLE_MQ_FIRE_MAZE_POT_5, "RAND_INF_FIRE_TEMPLE_MQ_FIRE_MAZE_POT_5" }, + { RAND_INF_FIRE_TEMPLE_MQ_FIRE_MAZE_POT_6, "RAND_INF_FIRE_TEMPLE_MQ_FIRE_MAZE_POT_6" }, + { RAND_INF_FIRE_TEMPLE_MQ_BEFORE_MINI_BOSS_POT_1, "RAND_INF_FIRE_TEMPLE_MQ_BEFORE_MINI_BOSS_POT_1" }, + { RAND_INF_FIRE_TEMPLE_MQ_BEFORE_MINI_BOSS_POT_2, "RAND_INF_FIRE_TEMPLE_MQ_BEFORE_MINI_BOSS_POT_2" }, + { RAND_INF_FIRE_TEMPLE_MQ_BEFORE_MINI_BOSS_POT_3, "RAND_INF_FIRE_TEMPLE_MQ_BEFORE_MINI_BOSS_POT_3" }, + { RAND_INF_FIRE_TEMPLE_MQ_BEFORE_MINI_BOSS_POT_4, "RAND_INF_FIRE_TEMPLE_MQ_BEFORE_MINI_BOSS_POT_4" }, + { RAND_INF_FIRE_TEMPLE_MQ_BEFORE_MINI_BOSS_POT_5, "RAND_INF_FIRE_TEMPLE_MQ_BEFORE_MINI_BOSS_POT_5" }, + { RAND_INF_FIRE_TEMPLE_MQ_BEFORE_MINI_BOSS_POT_6, "RAND_INF_FIRE_TEMPLE_MQ_BEFORE_MINI_BOSS_POT_6" }, + { RAND_INF_FIRE_TEMPLE_MQ_BEFORE_MINI_BOSS_POT_7, "RAND_INF_FIRE_TEMPLE_MQ_BEFORE_MINI_BOSS_POT_7" }, + { RAND_INF_FIRE_TEMPLE_MQ_BEFORE_MINI_BOSS_POT_8, "RAND_INF_FIRE_TEMPLE_MQ_BEFORE_MINI_BOSS_POT_8" }, + { RAND_INF_ICE_CAVERN_MQ_ENTRANCE_POT, "RAND_INF_ICE_CAVERN_MQ_ENTRANCE_POT" }, + { RAND_INF_ICE_CAVERN_MQ_FIRST_CRYSTAL_POT_1, "RAND_INF_ICE_CAVERN_MQ_FIRST_CRYSTAL_POT_1" }, + { RAND_INF_ICE_CAVERN_MQ_FIRST_CRYSTAL_POT_2, "RAND_INF_ICE_CAVERN_MQ_FIRST_CRYSTAL_POT_2" }, + { RAND_INF_ICE_CAVERN_MQ_EARLY_WOLFOS_POT_1, "RAND_INF_ICE_CAVERN_MQ_EARLY_WOLFOS_POT_1" }, + { RAND_INF_ICE_CAVERN_MQ_EARLY_WOLFOS_POT_2, "RAND_INF_ICE_CAVERN_MQ_EARLY_WOLFOS_POT_2" }, + { RAND_INF_ICE_CAVERN_MQ_EARLY_WOLFOS_POT_3, "RAND_INF_ICE_CAVERN_MQ_EARLY_WOLFOS_POT_3" }, + { RAND_INF_ICE_CAVERN_MQ_EARLY_WOLFOS_POT_4, "RAND_INF_ICE_CAVERN_MQ_EARLY_WOLFOS_POT_4" }, + { RAND_INF_ICE_CAVERN_MQ_PUSH_BLOCK_POT_1, "RAND_INF_ICE_CAVERN_MQ_PUSH_BLOCK_POT_1" }, + { RAND_INF_ICE_CAVERN_MQ_PUSH_BLOCK_POT_2, "RAND_INF_ICE_CAVERN_MQ_PUSH_BLOCK_POT_2" }, + { RAND_INF_ICE_CAVERN_MQ_COMPASS_POT_1, "RAND_INF_ICE_CAVERN_MQ_COMPASS_POT_1" }, + { RAND_INF_ICE_CAVERN_MQ_COMPASS_POT_2, "RAND_INF_ICE_CAVERN_MQ_COMPASS_POT_2" }, + { RAND_INF_SPIRIT_TEMPLE_MQ_ENTRANCE_POT_1, "RAND_INF_SPIRIT_TEMPLE_MQ_ENTRANCE_POT_1" }, + { RAND_INF_SPIRIT_TEMPLE_MQ_ENTRANCE_POT_2, "RAND_INF_SPIRIT_TEMPLE_MQ_ENTRANCE_POT_2" }, + { RAND_INF_SPIRIT_TEMPLE_MQ_ENTRANCE_POT_3, "RAND_INF_SPIRIT_TEMPLE_MQ_ENTRANCE_POT_3" }, + { RAND_INF_SPIRIT_TEMPLE_MQ_ENTRANCE_POT_4, "RAND_INF_SPIRIT_TEMPLE_MQ_ENTRANCE_POT_4" }, + { RAND_INF_SPIRIT_TEMPLE_MQ_CHILD_SLUGMA_POT, "RAND_INF_SPIRIT_TEMPLE_MQ_CHILD_SLUGMA_POT" }, + { RAND_INF_SPIRIT_TEMPLE_MQ_CHILD_GIBDO_POT_1, "RAND_INF_SPIRIT_TEMPLE_MQ_CHILD_GIBDO_POT_1" }, + { RAND_INF_SPIRIT_TEMPLE_MQ_CHILD_GIBDO_POT_2, "RAND_INF_SPIRIT_TEMPLE_MQ_CHILD_GIBDO_POT_2" }, + { RAND_INF_SPIRIT_TEMPLE_MQ_CHILD_LIKE_LIKE_POT, "RAND_INF_SPIRIT_TEMPLE_MQ_CHILD_LIKE_LIKE_POT" }, + { RAND_INF_SPIRIT_TEMPLE_MQ_CHILD_STALFOS_POT_1, "RAND_INF_SPIRIT_TEMPLE_MQ_CHILD_STALFOS_POT_1" }, + { RAND_INF_SPIRIT_TEMPLE_MQ_CHILD_STALFOS_POT_2, "RAND_INF_SPIRIT_TEMPLE_MQ_CHILD_STALFOS_POT_2" }, + { RAND_INF_SPIRIT_TEMPLE_MQ_CHILD_STALFOS_POT_3, "RAND_INF_SPIRIT_TEMPLE_MQ_CHILD_STALFOS_POT_3" }, + { RAND_INF_SPIRIT_TEMPLE_MQ_CHILD_STALFOS_POT_4, "RAND_INF_SPIRIT_TEMPLE_MQ_CHILD_STALFOS_POT_4" }, + { RAND_INF_SPIRIT_TEMPLE_MQ_CENTRAL_CHAMBER_POT_1, "RAND_INF_SPIRIT_TEMPLE_MQ_CENTRAL_CHAMBER_POT_1" }, + { RAND_INF_SPIRIT_TEMPLE_MQ_CENTRAL_CHAMBER_POT_2, "RAND_INF_SPIRIT_TEMPLE_MQ_CENTRAL_CHAMBER_POT_2" }, + { RAND_INF_SPIRIT_TEMPLE_MQ_CENTRAL_CHAMBER_POT_3, "RAND_INF_SPIRIT_TEMPLE_MQ_CENTRAL_CHAMBER_POT_3" }, + { RAND_INF_SPIRIT_TEMPLE_MQ_CENTRAL_CHAMBER_POT_4, "RAND_INF_SPIRIT_TEMPLE_MQ_CENTRAL_CHAMBER_POT_4" }, + { RAND_INF_SPIRIT_TEMPLE_MQ_CENTRAL_CHAMBER_POT_5, "RAND_INF_SPIRIT_TEMPLE_MQ_CENTRAL_CHAMBER_POT_5" }, + { RAND_INF_SPIRIT_TEMPLE_MQ_SUN_BLOCKS_POT_1, "RAND_INF_SPIRIT_TEMPLE_MQ_SUN_BLOCKS_POT_1" }, + { RAND_INF_SPIRIT_TEMPLE_MQ_SUN_BLOCKS_POT_2, "RAND_INF_SPIRIT_TEMPLE_MQ_SUN_BLOCKS_POT_2" }, + { RAND_INF_SPIRIT_TEMPLE_MQ_LONG_CLIMB_POT_1, "RAND_INF_SPIRIT_TEMPLE_MQ_LONG_CLIMB_POT_1" }, + { RAND_INF_SPIRIT_TEMPLE_MQ_LONG_CLIMB_POT_2, "RAND_INF_SPIRIT_TEMPLE_MQ_LONG_CLIMB_POT_2" }, + { RAND_INF_SPIRIT_TEMPLE_MQ_BIG_MIRROR_POT_1, "RAND_INF_SPIRIT_TEMPLE_MQ_BIG_MIRROR_POT_1" }, + { RAND_INF_SPIRIT_TEMPLE_MQ_BIG_MIRROR_POT_2, "RAND_INF_SPIRIT_TEMPLE_MQ_BIG_MIRROR_POT_2" }, + { RAND_INF_SPIRIT_TEMPLE_MQ_BIG_MIRROR_POT_3, "RAND_INF_SPIRIT_TEMPLE_MQ_BIG_MIRROR_POT_3" }, + { RAND_INF_SPIRIT_TEMPLE_MQ_BIG_MIRROR_POT_4, "RAND_INF_SPIRIT_TEMPLE_MQ_BIG_MIRROR_POT_4" }, + { RAND_INF_SPIRIT_TEMPLE_MQ_BEFORE_MIRROR_POT_1, "RAND_INF_SPIRIT_TEMPLE_MQ_BEFORE_MIRROR_POT_1" }, + { RAND_INF_SPIRIT_TEMPLE_MQ_BEFORE_MIRROR_POT_2, "RAND_INF_SPIRIT_TEMPLE_MQ_BEFORE_MIRROR_POT_2" }, + { RAND_INF_SPIRIT_TEMPLE_MQ_EARLY_ADULT_POT_1, "RAND_INF_SPIRIT_TEMPLE_MQ_EARLY_ADULT_POT_1" }, + { RAND_INF_SPIRIT_TEMPLE_MQ_EARLY_ADULT_POT_2, "RAND_INF_SPIRIT_TEMPLE_MQ_EARLY_ADULT_POT_2" }, + { RAND_INF_WATER_TEMPLE_MQ_CENTRAL_GATE_POT_1, "RAND_INF_WATER_TEMPLE_MQ_CENTRAL_GATE_POT_1" }, + { RAND_INF_WATER_TEMPLE_MQ_CENTRAL_GATE_POT_2, "RAND_INF_WATER_TEMPLE_MQ_CENTRAL_GATE_POT_2" }, + { RAND_INF_WATER_TEMPLE_MQ_CENTRAL_GATE_POT_3, "RAND_INF_WATER_TEMPLE_MQ_CENTRAL_GATE_POT_3" }, + { RAND_INF_WATER_TEMPLE_MQ_CENTRAL_GATE_POT_4, "RAND_INF_WATER_TEMPLE_MQ_CENTRAL_GATE_POT_4" }, + { RAND_INF_WATER_TEMPLE_MQ_CENTRAL_GATE_POT_5, "RAND_INF_WATER_TEMPLE_MQ_CENTRAL_GATE_POT_5" }, + { RAND_INF_WATER_TEMPLE_MQ_STORAGE_ROOM_A_POT_1, "RAND_INF_WATER_TEMPLE_MQ_STORAGE_ROOM_A_POT_1" }, + { RAND_INF_WATER_TEMPLE_MQ_STORAGE_ROOM_A_POT_2, "RAND_INF_WATER_TEMPLE_MQ_STORAGE_ROOM_A_POT_2" }, + { RAND_INF_WATER_TEMPLE_MQ_STORAGE_ROOM_A_POT_3, "RAND_INF_WATER_TEMPLE_MQ_STORAGE_ROOM_A_POT_3" }, + { RAND_INF_WATER_TEMPLE_MQ_BEFORE_DARK_LINK_POT_1, "RAND_INF_WATER_TEMPLE_MQ_BEFORE_DARK_LINK_POT_1" }, + { RAND_INF_WATER_TEMPLE_MQ_BEFORE_DARK_LINK_POT_2, "RAND_INF_WATER_TEMPLE_MQ_BEFORE_DARK_LINK_POT_2" }, + { RAND_INF_WATER_TEMPLE_MQ_BEFORE_DARK_LINK_POT_3, "RAND_INF_WATER_TEMPLE_MQ_BEFORE_DARK_LINK_POT_3" }, + { RAND_INF_WATER_TEMPLE_MQ_BEFORE_DARK_LINK_POT_4, "RAND_INF_WATER_TEMPLE_MQ_BEFORE_DARK_LINK_POT_4" }, + { RAND_INF_WATER_TEMPLE_MQ_BEFORE_DARK_LINK_POT_5, "RAND_INF_WATER_TEMPLE_MQ_BEFORE_DARK_LINK_POT_5" }, + { RAND_INF_WATER_TEMPLE_MQ_AFTER_DARK_LINK_POT_1, "RAND_INF_WATER_TEMPLE_MQ_AFTER_DARK_LINK_POT_1" }, + { RAND_INF_WATER_TEMPLE_MQ_AFTER_DARK_LINK_POT_2, "RAND_INF_WATER_TEMPLE_MQ_AFTER_DARK_LINK_POT_2" }, + { RAND_INF_WATER_TEMPLE_MQ_RIVER_POT_1, "RAND_INF_WATER_TEMPLE_MQ_RIVER_POT_1" }, + { RAND_INF_WATER_TEMPLE_MQ_RIVER_POT_2, "RAND_INF_WATER_TEMPLE_MQ_RIVER_POT_2" }, + { RAND_INF_WATER_TEMPLE_MQ_MINI_DODONGO_POT_1, "RAND_INF_WATER_TEMPLE_MQ_MINI_DODONGO_POT_1" }, + { RAND_INF_WATER_TEMPLE_MQ_MINI_DODONGO_POT_2, "RAND_INF_WATER_TEMPLE_MQ_MINI_DODONGO_POT_2" }, + { RAND_INF_WATER_TEMPLE_MQ_STORAGE_ROOM_B_POT_1, "RAND_INF_WATER_TEMPLE_MQ_STORAGE_ROOM_B_POT_1" }, + { RAND_INF_WATER_TEMPLE_MQ_STORAGE_ROOM_B_POT_2, "RAND_INF_WATER_TEMPLE_MQ_STORAGE_ROOM_B_POT_2" }, + { RAND_INF_WATER_TEMPLE_MQ_GS_STORAGE_ROOM_POT_1, "RAND_INF_WATER_TEMPLE_MQ_GS_STORAGE_ROOM_POT_1" }, + { RAND_INF_WATER_TEMPLE_MQ_GS_STORAGE_ROOM_POT_2, "RAND_INF_WATER_TEMPLE_MQ_GS_STORAGE_ROOM_POT_2" }, + { RAND_INF_WATER_TEMPLE_MQ_GS_STORAGE_ROOM_POT_3, "RAND_INF_WATER_TEMPLE_MQ_GS_STORAGE_ROOM_POT_3" }, + { RAND_INF_WATER_TEMPLE_MQ_LOWER_TORCHES_POT_1, "RAND_INF_WATER_TEMPLE_MQ_LOWER_TORCHES_POT_1" }, + { RAND_INF_WATER_TEMPLE_MQ_LOWER_TORCHES_POT_2, "RAND_INF_WATER_TEMPLE_MQ_LOWER_TORCHES_POT_2" }, + { RAND_INF_WATER_TEMPLE_MQ_LOWEST_GS_POT_1, "RAND_INF_WATER_TEMPLE_MQ_LOWEST_GS_POT_1" }, + { RAND_INF_WATER_TEMPLE_MQ_LOWEST_GS_POT_2, "RAND_INF_WATER_TEMPLE_MQ_LOWEST_GS_POT_2" }, + { RAND_INF_WATER_TEMPLE_MQ_LOWEST_GS_POT_3, "RAND_INF_WATER_TEMPLE_MQ_LOWEST_GS_POT_3" }, + { RAND_INF_WATER_TEMPLE_MQ_LOWEST_GS_POT_4, "RAND_INF_WATER_TEMPLE_MQ_LOWEST_GS_POT_4" }, + { RAND_INF_WATER_TEMPLE_MQ_BOSS_KEY_POT, "RAND_INF_WATER_TEMPLE_MQ_BOSS_KEY_POT" }, + { RAND_INF_GERUDO_TRAINING_GROUND_MQ_LOBBY_LEFT_POT_1, + "RAND_INF_GERUDO_TRAINING_GROUND_MQ_LOBBY_LEFT_POT_1" }, + { RAND_INF_GERUDO_TRAINING_GROUND_MQ_LOBBY_LEFT_POT_2, + "RAND_INF_GERUDO_TRAINING_GROUND_MQ_LOBBY_LEFT_POT_2" }, + { RAND_INF_GERUDO_TRAINING_GROUND_MQ_LOBBY_RIGHT_POT_1, + "RAND_INF_GERUDO_TRAINING_GROUND_MQ_LOBBY_RIGHT_POT_1" }, + { RAND_INF_GERUDO_TRAINING_GROUND_MQ_LOBBY_RIGHT_POT_2, + "RAND_INF_GERUDO_TRAINING_GROUND_MQ_LOBBY_RIGHT_POT_2" }, - { RAND_INF_CAN_SWIM, "RAND_INF_CAN_SWIM" }, + { RAND_INF_CAUGHT_LOACH, "RAND_INF_CAUGHT_LOACH" }, - { RAND_INF_HAS_WALLET, "RAND_INF_HAS_WALLET" }, + { RAND_INF_CAN_SWIM, "RAND_INF_CAN_SWIM" }, - { RAND_INF_BEEHIVE_KF_STORMS_GROTTO_LEFT, "RAND_INF_BEEHIVE_KF_STORMS_GROTTO_LEFT" }, - { RAND_INF_BEEHIVE_KF_STORMS_GROTTO_RIGHT, "RAND_INF_BEEHIVE_KF_STORMS_GROTTO_RIGHT" }, - { RAND_INF_BEEHIVE_LW_NEAR_SHORTCUTS_GROTTO_LEFT, "RAND_INF_BEEHIVE_LW_NEAR_SHORTCUTS_GROTTO_LEFT" }, - { RAND_INF_BEEHIVE_LW_NEAR_SHORTCUTS_GROTTO_RIGHT, "RAND_INF_BEEHIVE_LW_NEAR_SHORTCUTS_GROTTO_RIGHT" }, - { RAND_INF_BEEHIVE_LW_DEKU_SCRUB_GROTTO, "RAND_INF_BEEHIVE_LW_DEKU_SCRUB_GROTTO" }, - { RAND_INF_BEEHIVE_SFM_STORMS_GROTTO, "RAND_INF_BEEHIVE_SFM_STORMS_GROTTO" }, - { RAND_INF_BEEHIVE_HF_NEAR_MARKET_GROTTO_LEFT, "RAND_INF_BEEHIVE_HF_NEAR_MARKET_GROTTO_LEFT" }, - { RAND_INF_BEEHIVE_HF_NEAR_MARKET_GROTTO_RIGHT, "RAND_INF_BEEHIVE_HF_NEAR_MARKET_GROTTO_RIGHT" }, - { RAND_INF_BEEHIVE_HF_OPEN_GROTTO_LEFT, "RAND_INF_BEEHIVE_HF_OPEN_GROTTO_LEFT" }, - { RAND_INF_BEEHIVE_HF_OPEN_GROTTO_RIGHT, "RAND_INF_BEEHIVE_HF_OPEN_GROTTO_RIGHT" }, - { RAND_INF_BEEHIVE_HF_SOUTHEAST_GROTTO_LEFT, "RAND_INF_BEEHIVE_HF_SOUTHEAST_GROTTO_LEFT" }, - { RAND_INF_BEEHIVE_HF_SOUTHEAST_GROTTO_RIGHT, "RAND_INF_BEEHIVE_HF_SOUTHEAST_GROTTO_RIGHT" }, - { RAND_INF_BEEHIVE_HF_INSIDE_FENCE_GROTTO, "RAND_INF_BEEHIVE_HF_INSIDE_FENCE_GROTTO" }, - { RAND_INF_BEEHIVE_LLR_GROTTO, "RAND_INF_BEEHIVE_LLR_GROTTO" }, - { RAND_INF_BEEHIVE_KAK_OPEN_GROTTO_LEFT, "RAND_INF_BEEHIVE_KAK_OPEN_GROTTO_LEFT" }, - { RAND_INF_BEEHIVE_KAK_OPEN_GROTTO_RIGHT, "RAND_INF_BEEHIVE_KAK_OPEN_GROTTO_RIGHT" }, - { RAND_INF_BEEHIVE_DMT_COW_GROTTO, "RAND_INF_BEEHIVE_DMT_COW_GROTTO" }, - { RAND_INF_BEEHIVE_DMT_STORMS_GROTTO_LEFT, "RAND_INF_BEEHIVE_DMT_STORMS_GROTTO_LEFT" }, - { RAND_INF_BEEHIVE_DMT_STORMS_GROTTO_RIGHT, "RAND_INF_BEEHIVE_DMT_STORMS_GROTTO_RIGHT" }, - { RAND_INF_BEEHIVE_GC_GROTTO, "RAND_INF_BEEHIVE_GC_GROTTO" }, - { RAND_INF_BEEHIVE_DMC_UPPER_GROTTO_LEFT, "RAND_INF_BEEHIVE_DMC_UPPER_GROTTO_LEFT" }, - { RAND_INF_BEEHIVE_DMC_UPPER_GROTTO_RIGHT, "RAND_INF_BEEHIVE_DMC_UPPER_GROTTO_RIGHT" }, - { RAND_INF_BEEHIVE_DMC_HAMMER_GROTTO, "RAND_INF_BEEHIVE_DMC_HAMMER_GROTTO" }, - { RAND_INF_BEEHIVE_ZR_OPEN_GROTTO_LEFT, "RAND_INF_BEEHIVE_ZR_OPEN_GROTTO_LEFT" }, - { RAND_INF_BEEHIVE_ZR_OPEN_GROTTO_RIGHT, "RAND_INF_BEEHIVE_ZR_OPEN_GROTTO_RIGHT" }, - { RAND_INF_BEEHIVE_ZR_STORMS_GROTTO, "RAND_INF_BEEHIVE_ZR_STORMS_GROTTO" }, - { RAND_INF_BEEHIVE_ZD_IN_FRONT_OF_KING_ZORA_LEFT, "RAND_INF_BEEHIVE_ZD_IN_FRONT_OF_KING_ZORA_LEFT" }, - { RAND_INF_BEEHIVE_ZD_IN_FRONT_OF_KING_ZORA_RIGHT, "RAND_INF_BEEHIVE_ZD_IN_FRONT_OF_KING_ZORA_RIGHT" }, - { RAND_INF_BEEHIVE_ZD_BEHIND_KING_ZORA, "RAND_INF_BEEHIVE_ZD_BEHIND_KING_ZORA" }, - { RAND_INF_BEEHIVE_LH_GROTTO, "RAND_INF_BEEHIVE_LH_GROTTO" }, - { RAND_INF_BEEHIVE_GV_DEKU_SCRUB_GROTTO, "RAND_INF_BEEHIVE_GV_DEKU_SCRUB_GROTTO" }, - { RAND_INF_BEEHIVE_COLOSSUS_GROTTO, "RAND_INF_BEEHIVE_COLOSSUS_GROTTO" }, + { RAND_INF_HAS_WALLET, "RAND_INF_HAS_WALLET" }, - { RAND_INF_CHILD_FISH_1, "RAND_INF_CHILD_FISH_1" }, - { RAND_INF_CHILD_FISH_2, "RAND_INF_CHILD_FISH_2" }, - { RAND_INF_CHILD_FISH_3, "RAND_INF_CHILD_FISH_3" }, - { RAND_INF_CHILD_FISH_4, "RAND_INF_CHILD_FISH_4" }, - { RAND_INF_CHILD_FISH_5, "RAND_INF_CHILD_FISH_5" }, - { RAND_INF_CHILD_FISH_6, "RAND_INF_CHILD_FISH_6" }, - { RAND_INF_CHILD_FISH_7, "RAND_INF_CHILD_FISH_7" }, - { RAND_INF_CHILD_FISH_8, "RAND_INF_CHILD_FISH_8" }, - { RAND_INF_CHILD_FISH_9, "RAND_INF_CHILD_FISH_9" }, - { RAND_INF_CHILD_FISH_10, "RAND_INF_CHILD_FISH_10" }, - { RAND_INF_CHILD_FISH_11, "RAND_INF_CHILD_FISH_11" }, - { RAND_INF_CHILD_FISH_12, "RAND_INF_CHILD_FISH_12" }, - { RAND_INF_CHILD_FISH_13, "RAND_INF_CHILD_FISH_13" }, - { RAND_INF_CHILD_FISH_14, "RAND_INF_CHILD_FISH_14" }, - { RAND_INF_CHILD_FISH_15, "RAND_INF_CHILD_FISH_15" }, - { RAND_INF_CHILD_LOACH_1, "RAND_INF_CHILD_LOACH_1" }, - { RAND_INF_CHILD_LOACH_2, "RAND_INF_CHILD_LOACH_2" }, - { RAND_INF_ADULT_FISH_1, "RAND_INF_ADULT_FISH_1" }, - { RAND_INF_ADULT_FISH_2, "RAND_INF_ADULT_FISH_2" }, - { RAND_INF_ADULT_FISH_3, "RAND_INF_ADULT_FISH_3" }, - { RAND_INF_ADULT_FISH_4, "RAND_INF_ADULT_FISH_4" }, - { RAND_INF_ADULT_FISH_5, "RAND_INF_ADULT_FISH_5" }, - { RAND_INF_ADULT_FISH_6, "RAND_INF_ADULT_FISH_6" }, - { RAND_INF_ADULT_FISH_7, "RAND_INF_ADULT_FISH_7" }, - { RAND_INF_ADULT_FISH_8, "RAND_INF_ADULT_FISH_8" }, - { RAND_INF_ADULT_FISH_9, "RAND_INF_ADULT_FISH_9" }, - { RAND_INF_ADULT_FISH_10, "RAND_INF_ADULT_FISH_10" }, - { RAND_INF_ADULT_FISH_11, "RAND_INF_ADULT_FISH_11" }, - { RAND_INF_ADULT_FISH_12, "RAND_INF_ADULT_FISH_12" }, - { RAND_INF_ADULT_FISH_13, "RAND_INF_ADULT_FISH_13" }, - { RAND_INF_ADULT_FISH_14, "RAND_INF_ADULT_FISH_14" }, - { RAND_INF_ADULT_FISH_15, "RAND_INF_ADULT_FISH_15" }, - { RAND_INF_ADULT_LOACH, "RAND_INF_ADULT_LOACH" }, - { RAND_INF_GROTTO_FISH_ZR_OPEN_GROTTO, "RAND_INF_GROTTO_FISH_ZR_OPEN_GROTTO" }, - { RAND_INF_GROTTO_FISH_DMC_UPPER_GROTTO, "RAND_INF_GROTTO_FISH_DMC_UPPER_GROTTO" }, - { RAND_INF_GROTTO_FISH_DMT_STORMS_GROTTO, "RAND_INF_GROTTO_FISH_DMT_STORMS_GROTTO" }, - { RAND_INF_GROTTO_FISH_KAK_OPEN_GROTTO, "RAND_INF_GROTTO_FISH_KAK_OPEN_GROTTO" }, - { RAND_INF_GROTTO_FISH_HF_NEAR_MARKET_GROTTO, "RAND_INF_GROTTO_FISH_HF_NEAR_MARKET_GROTTO" }, - { RAND_INF_GROTTO_FISH_HF_OPEN_GROTTO, "RAND_INF_GROTTO_FISH_HF_OPEN_GROTTO" }, - { RAND_INF_GROTTO_FISH_HF_SOUTHEAST_GROTTO, "RAND_INF_GROTTO_FISH_HF_SOUTHEAST_GROTTO" }, - { RAND_INF_GROTTO_FISH_LW_NEAR_SHORTCUTS_GROTTO, "RAND_INF_GROTTO_FISH_LW_NEAR_SHORTCUTS_GROTTO" }, - { RAND_INF_GROTTO_FISH_KF_STORMS_GROTTO, "RAND_INF_GROTTO_FISH_KF_STORMS_GROTTO" }, - { RAND_INF_FISHING_POLE_FOUND, "RAND_INF_FISHING_POLE_FOUND" }, - { RAND_INF_ZD_FISH_1, "RAND_INF_ZD_FISH_1" }, - { RAND_INF_ZD_FISH_2, "RAND_INF_ZD_FISH_2" }, - { RAND_INF_ZD_FISH_3, "RAND_INF_ZD_FISH_3" }, - { RAND_INF_ZD_FISH_4, "RAND_INF_ZD_FISH_4" }, - { RAND_INF_ZD_FISH_5, "RAND_INF_ZD_FISH_5" }, + { RAND_INF_BEEHIVE_KF_STORMS_GROTTO_LEFT, "RAND_INF_BEEHIVE_KF_STORMS_GROTTO_LEFT" }, + { RAND_INF_BEEHIVE_KF_STORMS_GROTTO_RIGHT, "RAND_INF_BEEHIVE_KF_STORMS_GROTTO_RIGHT" }, + { RAND_INF_BEEHIVE_LW_NEAR_SHORTCUTS_GROTTO_LEFT, "RAND_INF_BEEHIVE_LW_NEAR_SHORTCUTS_GROTTO_LEFT" }, + { RAND_INF_BEEHIVE_LW_NEAR_SHORTCUTS_GROTTO_RIGHT, "RAND_INF_BEEHIVE_LW_NEAR_SHORTCUTS_GROTTO_RIGHT" }, + { RAND_INF_BEEHIVE_LW_DEKU_SCRUB_GROTTO, "RAND_INF_BEEHIVE_LW_DEKU_SCRUB_GROTTO" }, + { RAND_INF_BEEHIVE_SFM_STORMS_GROTTO, "RAND_INF_BEEHIVE_SFM_STORMS_GROTTO" }, + { RAND_INF_BEEHIVE_HF_NEAR_MARKET_GROTTO_LEFT, "RAND_INF_BEEHIVE_HF_NEAR_MARKET_GROTTO_LEFT" }, + { RAND_INF_BEEHIVE_HF_NEAR_MARKET_GROTTO_RIGHT, "RAND_INF_BEEHIVE_HF_NEAR_MARKET_GROTTO_RIGHT" }, + { RAND_INF_BEEHIVE_HF_OPEN_GROTTO_LEFT, "RAND_INF_BEEHIVE_HF_OPEN_GROTTO_LEFT" }, + { RAND_INF_BEEHIVE_HF_OPEN_GROTTO_RIGHT, "RAND_INF_BEEHIVE_HF_OPEN_GROTTO_RIGHT" }, + { RAND_INF_BEEHIVE_HF_SOUTHEAST_GROTTO_LEFT, "RAND_INF_BEEHIVE_HF_SOUTHEAST_GROTTO_LEFT" }, + { RAND_INF_BEEHIVE_HF_SOUTHEAST_GROTTO_RIGHT, "RAND_INF_BEEHIVE_HF_SOUTHEAST_GROTTO_RIGHT" }, + { RAND_INF_BEEHIVE_HF_INSIDE_FENCE_GROTTO, "RAND_INF_BEEHIVE_HF_INSIDE_FENCE_GROTTO" }, + { RAND_INF_BEEHIVE_LLR_GROTTO, "RAND_INF_BEEHIVE_LLR_GROTTO" }, + { RAND_INF_BEEHIVE_KAK_OPEN_GROTTO_LEFT, "RAND_INF_BEEHIVE_KAK_OPEN_GROTTO_LEFT" }, + { RAND_INF_BEEHIVE_KAK_OPEN_GROTTO_RIGHT, "RAND_INF_BEEHIVE_KAK_OPEN_GROTTO_RIGHT" }, + { RAND_INF_BEEHIVE_DMT_COW_GROTTO, "RAND_INF_BEEHIVE_DMT_COW_GROTTO" }, + { RAND_INF_BEEHIVE_DMT_STORMS_GROTTO_LEFT, "RAND_INF_BEEHIVE_DMT_STORMS_GROTTO_LEFT" }, + { RAND_INF_BEEHIVE_DMT_STORMS_GROTTO_RIGHT, "RAND_INF_BEEHIVE_DMT_STORMS_GROTTO_RIGHT" }, + { RAND_INF_BEEHIVE_GC_GROTTO, "RAND_INF_BEEHIVE_GC_GROTTO" }, + { RAND_INF_BEEHIVE_DMC_UPPER_GROTTO_LEFT, "RAND_INF_BEEHIVE_DMC_UPPER_GROTTO_LEFT" }, + { RAND_INF_BEEHIVE_DMC_UPPER_GROTTO_RIGHT, "RAND_INF_BEEHIVE_DMC_UPPER_GROTTO_RIGHT" }, + { RAND_INF_BEEHIVE_DMC_HAMMER_GROTTO, "RAND_INF_BEEHIVE_DMC_HAMMER_GROTTO" }, + { RAND_INF_BEEHIVE_ZR_OPEN_GROTTO_LEFT, "RAND_INF_BEEHIVE_ZR_OPEN_GROTTO_LEFT" }, + { RAND_INF_BEEHIVE_ZR_OPEN_GROTTO_RIGHT, "RAND_INF_BEEHIVE_ZR_OPEN_GROTTO_RIGHT" }, + { RAND_INF_BEEHIVE_ZR_STORMS_GROTTO, "RAND_INF_BEEHIVE_ZR_STORMS_GROTTO" }, + { RAND_INF_BEEHIVE_ZD_IN_FRONT_OF_KING_ZORA_LEFT, "RAND_INF_BEEHIVE_ZD_IN_FRONT_OF_KING_ZORA_LEFT" }, + { RAND_INF_BEEHIVE_ZD_IN_FRONT_OF_KING_ZORA_RIGHT, "RAND_INF_BEEHIVE_ZD_IN_FRONT_OF_KING_ZORA_RIGHT" }, + { RAND_INF_BEEHIVE_ZD_BEHIND_KING_ZORA, "RAND_INF_BEEHIVE_ZD_BEHIND_KING_ZORA" }, + { RAND_INF_BEEHIVE_LH_GROTTO, "RAND_INF_BEEHIVE_LH_GROTTO" }, + { RAND_INF_BEEHIVE_GV_DEKU_SCRUB_GROTTO, "RAND_INF_BEEHIVE_GV_DEKU_SCRUB_GROTTO" }, + { RAND_INF_BEEHIVE_COLOSSUS_GROTTO, "RAND_INF_BEEHIVE_COLOSSUS_GROTTO" }, - { RAND_INF_HAS_INFINITE_QUIVER, "RAND_INF_HAS_INFINITE_QUIVER" }, - { RAND_INF_HAS_INFINITE_BOMB_BAG, "RAND_INF_HAS_INFINITE_BOMB_BAG" }, - { RAND_INF_HAS_INFINITE_BULLET_BAG, "RAND_INF_HAS_INFINITE_BULLET_BAG" }, - { RAND_INF_HAS_INFINITE_STICK_UPGRADE, "RAND_INF_HAS_INFINITE_STICK_UPGRADE" }, - { RAND_INF_HAS_INFINITE_NUT_UPGRADE, "RAND_INF_HAS_INFINITE_NUT_UPGRADE" }, - { RAND_INF_HAS_INFINITE_MAGIC_METER, "RAND_INF_HAS_INFINITE_MAGIC_METER" }, - { RAND_INF_HAS_INFINITE_BOMBCHUS, "RAND_INF_HAS_INFINITE_BOMBCHUS" }, - { RAND_INF_HAS_INFINITE_MONEY, "RAND_INF_HAS_INFINITE_MONEY" }, + { RAND_INF_CHILD_FISH_1, "RAND_INF_CHILD_FISH_1" }, + { RAND_INF_CHILD_FISH_2, "RAND_INF_CHILD_FISH_2" }, + { RAND_INF_CHILD_FISH_3, "RAND_INF_CHILD_FISH_3" }, + { RAND_INF_CHILD_FISH_4, "RAND_INF_CHILD_FISH_4" }, + { RAND_INF_CHILD_FISH_5, "RAND_INF_CHILD_FISH_5" }, + { RAND_INF_CHILD_FISH_6, "RAND_INF_CHILD_FISH_6" }, + { RAND_INF_CHILD_FISH_7, "RAND_INF_CHILD_FISH_7" }, + { RAND_INF_CHILD_FISH_8, "RAND_INF_CHILD_FISH_8" }, + { RAND_INF_CHILD_FISH_9, "RAND_INF_CHILD_FISH_9" }, + { RAND_INF_CHILD_FISH_10, "RAND_INF_CHILD_FISH_10" }, + { RAND_INF_CHILD_FISH_11, "RAND_INF_CHILD_FISH_11" }, + { RAND_INF_CHILD_FISH_12, "RAND_INF_CHILD_FISH_12" }, + { RAND_INF_CHILD_FISH_13, "RAND_INF_CHILD_FISH_13" }, + { RAND_INF_CHILD_FISH_14, "RAND_INF_CHILD_FISH_14" }, + { RAND_INF_CHILD_FISH_15, "RAND_INF_CHILD_FISH_15" }, + { RAND_INF_CHILD_LOACH_1, "RAND_INF_CHILD_LOACH_1" }, + { RAND_INF_CHILD_LOACH_2, "RAND_INF_CHILD_LOACH_2" }, + { RAND_INF_ADULT_FISH_1, "RAND_INF_ADULT_FISH_1" }, + { RAND_INF_ADULT_FISH_2, "RAND_INF_ADULT_FISH_2" }, + { RAND_INF_ADULT_FISH_3, "RAND_INF_ADULT_FISH_3" }, + { RAND_INF_ADULT_FISH_4, "RAND_INF_ADULT_FISH_4" }, + { RAND_INF_ADULT_FISH_5, "RAND_INF_ADULT_FISH_5" }, + { RAND_INF_ADULT_FISH_6, "RAND_INF_ADULT_FISH_6" }, + { RAND_INF_ADULT_FISH_7, "RAND_INF_ADULT_FISH_7" }, + { RAND_INF_ADULT_FISH_8, "RAND_INF_ADULT_FISH_8" }, + { RAND_INF_ADULT_FISH_9, "RAND_INF_ADULT_FISH_9" }, + { RAND_INF_ADULT_FISH_10, "RAND_INF_ADULT_FISH_10" }, + { RAND_INF_ADULT_FISH_11, "RAND_INF_ADULT_FISH_11" }, + { RAND_INF_ADULT_FISH_12, "RAND_INF_ADULT_FISH_12" }, + { RAND_INF_ADULT_FISH_13, "RAND_INF_ADULT_FISH_13" }, + { RAND_INF_ADULT_FISH_14, "RAND_INF_ADULT_FISH_14" }, + { RAND_INF_ADULT_FISH_15, "RAND_INF_ADULT_FISH_15" }, + { RAND_INF_ADULT_LOACH, "RAND_INF_ADULT_LOACH" }, + { RAND_INF_GROTTO_FISH_ZR_OPEN_GROTTO, "RAND_INF_GROTTO_FISH_ZR_OPEN_GROTTO" }, + { RAND_INF_GROTTO_FISH_DMC_UPPER_GROTTO, "RAND_INF_GROTTO_FISH_DMC_UPPER_GROTTO" }, + { RAND_INF_GROTTO_FISH_DMT_STORMS_GROTTO, "RAND_INF_GROTTO_FISH_DMT_STORMS_GROTTO" }, + { RAND_INF_GROTTO_FISH_KAK_OPEN_GROTTO, "RAND_INF_GROTTO_FISH_KAK_OPEN_GROTTO" }, + { RAND_INF_GROTTO_FISH_HF_NEAR_MARKET_GROTTO, "RAND_INF_GROTTO_FISH_HF_NEAR_MARKET_GROTTO" }, + { RAND_INF_GROTTO_FISH_HF_OPEN_GROTTO, "RAND_INF_GROTTO_FISH_HF_OPEN_GROTTO" }, + { RAND_INF_GROTTO_FISH_HF_SOUTHEAST_GROTTO, "RAND_INF_GROTTO_FISH_HF_SOUTHEAST_GROTTO" }, + { RAND_INF_GROTTO_FISH_LW_NEAR_SHORTCUTS_GROTTO, "RAND_INF_GROTTO_FISH_LW_NEAR_SHORTCUTS_GROTTO" }, + { RAND_INF_GROTTO_FISH_KF_STORMS_GROTTO, "RAND_INF_GROTTO_FISH_KF_STORMS_GROTTO" }, + { RAND_INF_FISHING_POLE_FOUND, "RAND_INF_FISHING_POLE_FOUND" }, + { RAND_INF_ZD_FISH_1, "RAND_INF_ZD_FISH_1" }, + { RAND_INF_ZD_FISH_2, "RAND_INF_ZD_FISH_2" }, + { RAND_INF_ZD_FISH_3, "RAND_INF_ZD_FISH_3" }, + { RAND_INF_ZD_FISH_4, "RAND_INF_ZD_FISH_4" }, + { RAND_INF_ZD_FISH_5, "RAND_INF_ZD_FISH_5" }, - { RAND_INF_HAS_SKELETON_KEY, "RAND_INF_HAS_SKELETON_KEY" }, + { RAND_INF_HAS_INFINITE_QUIVER, "RAND_INF_HAS_INFINITE_QUIVER" }, + { RAND_INF_HAS_INFINITE_BOMB_BAG, "RAND_INF_HAS_INFINITE_BOMB_BAG" }, + { RAND_INF_HAS_INFINITE_BULLET_BAG, "RAND_INF_HAS_INFINITE_BULLET_BAG" }, + { RAND_INF_HAS_INFINITE_STICK_UPGRADE, "RAND_INF_HAS_INFINITE_STICK_UPGRADE" }, + { RAND_INF_HAS_INFINITE_NUT_UPGRADE, "RAND_INF_HAS_INFINITE_NUT_UPGRADE" }, + { RAND_INF_HAS_INFINITE_MAGIC_METER, "RAND_INF_HAS_INFINITE_MAGIC_METER" }, + { RAND_INF_HAS_INFINITE_BOMBCHUS, "RAND_INF_HAS_INFINITE_BOMBCHUS" }, + { RAND_INF_HAS_INFINITE_MONEY, "RAND_INF_HAS_INFINITE_MONEY" }, - { RAND_INF_LINKS_POCKET, "RAND_INF_LINKS_POCKET" }, - { RAND_INF_LEARNED_EPONA_SONG, "RAND_INF_LEARNED_EPONA_SONG" }, - { RAND_INF_DARUNIAS_JOY, "RAND_INF_DARUNIAS_JOY" }, - { RAND_INF_KING_ZORA_THAWED, "RAND_INF_KING_ZORA_THAWED" }, + { RAND_INF_HAS_SKELETON_KEY, "RAND_INF_HAS_SKELETON_KEY" }, - { RAND_INF_HC_GREAT_FAIRY_REWARD, "RAND_INF_HC_GREAT_FAIRY_REWARD" }, - { RAND_INF_DMT_GREAT_FAIRY_REWARD, "RAND_INF_DMT_GREAT_FAIRY_REWARD" }, - { RAND_INF_DMC_GREAT_FAIRY_REWARD, "RAND_INF_DMC_GREAT_FAIRY_REWARD" }, - { RAND_INF_ZF_GREAT_FAIRY_REWARD, "RAND_INF_ZF_GREAT_FAIRY_REWARD" }, - { RAND_INF_COLOSSUS_GREAT_FAIRY_REWARD, "RAND_INF_COLOSSUS_GREAT_FAIRY_REWARD" }, - { RAND_INF_OGC_GREAT_FAIRY_REWARD, "RAND_INF_OGC_GREAT_FAIRY_REWARD" }, + { RAND_INF_LINKS_POCKET, "RAND_INF_LINKS_POCKET" }, + { RAND_INF_LEARNED_EPONA_SONG, "RAND_INF_LEARNED_EPONA_SONG" }, + { RAND_INF_DARUNIAS_JOY, "RAND_INF_DARUNIAS_JOY" }, + { RAND_INF_KING_ZORA_THAWED, "RAND_INF_KING_ZORA_THAWED" }, - { RAND_INF_ZELDAS_LETTER, "RAND_INF_ZELDAS_LETTER" }, - { RAND_INF_WEIRD_EGG, "RAND_INF_WEIRD_EGG" }, + { RAND_INF_HC_GREAT_FAIRY_REWARD, "RAND_INF_HC_GREAT_FAIRY_REWARD" }, + { RAND_INF_DMT_GREAT_FAIRY_REWARD, "RAND_INF_DMT_GREAT_FAIRY_REWARD" }, + { RAND_INF_DMC_GREAT_FAIRY_REWARD, "RAND_INF_DMC_GREAT_FAIRY_REWARD" }, + { RAND_INF_ZF_GREAT_FAIRY_REWARD, "RAND_INF_ZF_GREAT_FAIRY_REWARD" }, + { RAND_INF_COLOSSUS_GREAT_FAIRY_REWARD, "RAND_INF_COLOSSUS_GREAT_FAIRY_REWARD" }, + { RAND_INF_OGC_GREAT_FAIRY_REWARD, "RAND_INF_OGC_GREAT_FAIRY_REWARD" }, - { RAND_INF_KF_SOUTH_GRASS_WEST_RUPEE, "RAND_INF_KF_SOUTH_GRASS_WEST_RUPEE" }, - { RAND_INF_KF_NORTH_GRASS_WEST_RUPEE, "RAND_INF_KF_NORTH_GRASS_WEST_RUPEE" }, - { RAND_INF_KF_NORTH_GRASS_EAST_RUPEE, "RAND_INF_KF_NORTH_GRASS_EAST_RUPEE" }, - { RAND_INF_KF_SOUTH_GRASS_EAST_RUPEE, "RAND_INF_KF_SOUTH_GRASS_EAST_RUPEE" }, - { RAND_INF_KF_SARIAS_TOP_LEFT_HEART, "RAND_INF_KF_SARIAS_TOP_LEFT_HEART" }, - { RAND_INF_KF_SARIAS_TOP_RIGHT_HEART, "RAND_INF_KF_SARIAS_TOP_RIGHT_HEART" }, - { RAND_INF_KF_SARIAS_BOTTOM_LEFT_HEART, "RAND_INF_KF_SARIAS_BOTTOM_LEFT_HEART" }, - { RAND_INF_KF_SARIAS_BOTTOM_RIGHT_HEART, "RAND_INF_KF_SARIAS_BOTTOM_RIGHT_HEART" }, - { RAND_INF_KF_BEAN_RUPEE_1, "RAND_INF_KF_BEAN_RUPEE_1" }, - { RAND_INF_KF_BEAN_RUPEE_2, "RAND_INF_KF_BEAN_RUPEE_2" }, - { RAND_INF_KF_BEAN_RUPEE_3, "RAND_INF_KF_BEAN_RUPEE_3" }, - { RAND_INF_KF_BEAN_RUPEE_4, "RAND_INF_KF_BEAN_RUPEE_4" }, - { RAND_INF_KF_BEAN_RUPEE_5, "RAND_INF_KF_BEAN_RUPEE_5" }, - { RAND_INF_KF_BEAN_RUPEE_6, "RAND_INF_KF_BEAN_RUPEE_6" }, - { RAND_INF_KF_BEAN_RED_RUPEE, "RAND_INF_KF_BEAN_RED_RUPEE" }, - { RAND_INF_LW_SHORTCUT_RUPEE_1, "RAND_INF_LW_SHORTCUT_RUPEE_1" }, - { RAND_INF_LW_SHORTCUT_RUPEE_2, "RAND_INF_LW_SHORTCUT_RUPEE_2" }, - { RAND_INF_LW_SHORTCUT_RUPEE_3, "RAND_INF_LW_SHORTCUT_RUPEE_3" }, - { RAND_INF_LW_SHORTCUT_RUPEE_4, "RAND_INF_LW_SHORTCUT_RUPEE_4" }, - { RAND_INF_LW_SHORTCUT_RUPEE_5, "RAND_INF_LW_SHORTCUT_RUPEE_5" }, - { RAND_INF_LW_SHORTCUT_RUPEE_6, "RAND_INF_LW_SHORTCUT_RUPEE_6" }, - { RAND_INF_LW_SHORTCUT_RUPEE_7, "RAND_INF_LW_SHORTCUT_RUPEE_7" }, - { RAND_INF_LW_SHORTCUT_RUPEE_8, "RAND_INF_LW_SHORTCUT_RUPEE_8" }, - { RAND_INF_LH_FRONT_RUPEE, "RAND_INF_LH_FRONT_RUPEE" }, - { RAND_INF_LH_MIDDLE_RUPEE, "RAND_INF_LH_MIDDLE_RUPEE" }, - { RAND_INF_LH_BACK_RUPEE, "RAND_INF_LH_BACK_RUPEE" }, - { RAND_INF_GRAVEYARD_DAMPE_RACE_RUPEE_1, "RAND_INF_GRAVEYARD_DAMPE_RACE_RUPEE_1" }, - { RAND_INF_GRAVEYARD_DAMPE_RACE_RUPEE_2, "RAND_INF_GRAVEYARD_DAMPE_RACE_RUPEE_2" }, - { RAND_INF_GRAVEYARD_DAMPE_RACE_RUPEE_3, "RAND_INF_GRAVEYARD_DAMPE_RACE_RUPEE_3" }, - { RAND_INF_GRAVEYARD_DAMPE_RACE_RUPEE_4, "RAND_INF_GRAVEYARD_DAMPE_RACE_RUPEE_4" }, - { RAND_INF_GRAVEYARD_DAMPE_RACE_RUPEE_5, "RAND_INF_GRAVEYARD_DAMPE_RACE_RUPEE_5" }, - { RAND_INF_GRAVEYARD_DAMPE_RACE_RUPEE_6, "RAND_INF_GRAVEYARD_DAMPE_RACE_RUPEE_6" }, - { RAND_INF_GRAVEYARD_DAMPE_RACE_RUPEE_7, "RAND_INF_GRAVEYARD_DAMPE_RACE_RUPEE_7" }, - { RAND_INF_GRAVEYARD_DAMPE_RACE_RUPEE_8, "RAND_INF_GRAVEYARD_DAMPE_RACE_RUPEE_8" }, - { RAND_INF_GV_OCTOROK_GROTTO_FRONT_LEFT_BLUE_RUPEE, "RAND_INF_GV_OCTOROK_GROTTO_FRONT_LEFT_BLUE_RUPEE" }, - { RAND_INF_GV_OCTOROK_GROTTO_BACK_BLUE_RUPEE, "RAND_INF_GV_OCTOROK_GROTTO_BACK_BLUE_RUPEE" }, - { RAND_INF_GV_OCTOROK_GROTTO_FRONT_RIGHT_BLUE_RUPEE, "RAND_INF_GV_OCTOROK_GROTTO_FRONT_RIGHT_BLUE_RUPEE" }, - { RAND_INF_GV_OCTOROK_GROTTO_FRONT_LEFT_GREEN_RUPEE, "RAND_INF_GV_OCTOROK_GROTTO_FRONT_LEFT_GREEN_RUPEE" }, - { RAND_INF_GV_OCTOROK_GROTTO_FRONT_RIGHT_GREEN_RUPEE, "RAND_INF_GV_OCTOROK_GROTTO_FRONT_RIGHT_GREEN_RUPEE" }, - { RAND_INF_GV_OCTOROK_GROTTO_BACK_LEFT_GREEN_RUPEE, "RAND_INF_GV_OCTOROK_GROTTO_BACK_LEFT_GREEN_RUPEE" }, - { RAND_INF_GV_OCTOROK_GROTTO_BACK_RIGHT_GREEN_RUPEE, "RAND_INF_GV_OCTOROK_GROTTO_BACK_RIGHT_GREEN_RUPEE" }, - { RAND_INF_GV_OCTOROK_GROTTO_RED_RUPEE, "RAND_INF_GV_OCTOROK_GROTTO_RED_RUPEE" }, - { RAND_INF_DMT_BLUE_RUPEE, "RAND_INF_DMT_BLUE_RUPEE" }, - { RAND_INF_DMT_COW_GROTTO_LEFT_HEART, "RAND_INF_DMT_COW_GROTTO_LEFT_HEART" }, - { RAND_INF_DMT_COW_GROTTO_MIDDLE_LEFT_HEART, "RAND_INF_DMT_COW_GROTTO_MIDDLE_LEFT_HEART" }, - { RAND_INF_DMT_COW_GROTTO_MIDDLE_RIGHT_HEART, "RAND_INF_DMT_COW_GROTTO_MIDDLE_RIGHT_HEART" }, - { RAND_INF_DMT_COW_GROTTO_RIGHT_HEART, "RAND_INF_DMT_COW_GROTTO_RIGHT_HEART" }, - { RAND_INF_DMT_COW_GROTTO_RUPEE_1, "RAND_INF_DMT_COW_GROTTO_RUPEE_1" }, - { RAND_INF_DMT_COW_GROTTO_RUPEE_2, "RAND_INF_DMT_COW_GROTTO_RUPEE_2" }, - { RAND_INF_DMT_COW_GROTTO_RUPEE_3, "RAND_INF_DMT_COW_GROTTO_RUPEE_3" }, - { RAND_INF_DMT_COW_GROTTO_RUPEE_4, "RAND_INF_DMT_COW_GROTTO_RUPEE_4" }, - { RAND_INF_DMT_COW_GROTTO_RUPEE_5, "RAND_INF_DMT_COW_GROTTO_RUPEE_5" }, - { RAND_INF_DMT_COW_GROTTO_RUPEE_6, "RAND_INF_DMT_COW_GROTTO_RUPEE_6" }, - { RAND_INF_DMT_COW_GROTTO_RED_RUPEE, "RAND_INF_DMT_COW_GROTTO_RED_RUPEE" }, - { RAND_INF_DMC_NEAR_PLATFORM_RED_RUPEE, "RAND_INF_DMC_NEAR_PLATFORM_RED_RUPEE" }, - { RAND_INF_DMC_MIDDLE_PLATFORM_RED_RUPEE, "RAND_INF_DMC_MIDDLE_PLATFORM_RED_RUPEE" }, - { RAND_INF_DMC_MIDDLE_PLATFORM_BLUE_RUPEE_1, "RAND_INF_DMC_MIDDLE_PLATFORM_BLUE_RUPEE_1" }, - { RAND_INF_DMC_MIDDLE_PLATFORM_BLUE_RUPEE_2, "RAND_INF_DMC_MIDDLE_PLATFORM_BLUE_RUPEE_2" }, - { RAND_INF_DMC_MIDDLE_PLATFORM_BLUE_RUPEE_3, "RAND_INF_DMC_MIDDLE_PLATFORM_BLUE_RUPEE_3" }, - { RAND_INF_DMC_MIDDLE_PLATFORM_BLUE_RUPEE_4, "RAND_INF_DMC_MIDDLE_PLATFORM_BLUE_RUPEE_4" }, - { RAND_INF_DMC_MIDDLE_PLATFORM_BLUE_RUPEE_5, "RAND_INF_DMC_MIDDLE_PLATFORM_BLUE_RUPEE_5" }, - { RAND_INF_DMC_MIDDLE_PLATFORM_BLUE_RUPEE_6, "RAND_INF_DMC_MIDDLE_PLATFORM_BLUE_RUPEE_6" }, - { RAND_INF_DMC_DISTANT_PLATFORM_RUPEE_1, "RAND_INF_DMC_DISTANT_PLATFORM_RUPEE_1" }, - { RAND_INF_DMC_DISTANT_PLATFORM_RUPEE_2, "RAND_INF_DMC_DISTANT_PLATFORM_RUPEE_2" }, - { RAND_INF_DMC_DISTANT_PLATFORM_RUPEE_3, "RAND_INF_DMC_DISTANT_PLATFORM_RUPEE_3" }, - { RAND_INF_DMC_DISTANT_PLATFORM_RUPEE_4, "RAND_INF_DMC_DISTANT_PLATFORM_RUPEE_4" }, - { RAND_INF_DMC_DISTANT_PLATFORM_RUPEE_5, "RAND_INF_DMC_DISTANT_PLATFORM_RUPEE_5" }, - { RAND_INF_DMC_DISTANT_PLATFORM_RUPEE_6, "RAND_INF_DMC_DISTANT_PLATFORM_RUPEE_6" }, - { RAND_INF_DMC_DISTANT_PLATFORM_RED_RUPEE, "RAND_INF_DMC_DISTANT_PLATFORM_RED_RUPEE" }, - { RAND_INF_ZR_BENEATH_WATERFALL_LEFT_RUPEE, "RAND_INF_ZR_BENEATH_WATERFALL_LEFT_RUPEE" }, - { RAND_INF_ZR_BENEATH_WATERFALL_MIDDLE_LEFT_RUPEE, "RAND_INF_ZR_BENEATH_WATERFALL_MIDDLE_LEFT_RUPEE" }, - { RAND_INF_ZR_BENEATH_WATERFALL_MIDDLE_RIGHT_RUPEE, "RAND_INF_ZR_BENEATH_WATERFALL_MIDDLE_RIGHT_RUPEE" }, - { RAND_INF_ZR_BENEATH_WATERFALL_RIGHT_RUPEE, "RAND_INF_ZR_BENEATH_WATERFALL_RIGHT_RUPEE" }, - { RAND_INF_ZF_BOTTOM_NORTH_INNER_RUPEE, "RAND_INF_ZF_BOTTOM_NORTH_INNER_RUPEE" }, - { RAND_INF_ZF_BOTTOM_NORTHEAST_INNER_RUPEE, "RAND_INF_ZF_BOTTOM_NORTHEAST_INNER_RUPEE" }, - { RAND_INF_ZF_BOTTOM_SOUTHEAST_INNER_RUPEE, "RAND_INF_ZF_BOTTOM_SOUTHEAST_INNER_RUPEE" }, - { RAND_INF_ZF_BOTTOM_SOUTH_INNER_RUPEE, "RAND_INF_ZF_BOTTOM_SOUTH_INNER_RUPEE" }, - { RAND_INF_ZF_BOTTOM_SOUTHWEST_INNER_RUPEE, "RAND_INF_ZF_BOTTOM_SOUTHWEST_INNER_RUPEE" }, - { RAND_INF_ZF_BOTTOM_NORTHWEST_INNER_RUPEE, "RAND_INF_ZF_BOTTOM_NORTHWEST_INNER_RUPEE" }, - { RAND_INF_ZF_BOTTOM_NORTH_MIDDLE_RUPEE, "RAND_INF_ZF_BOTTOM_NORTH_MIDDLE_RUPEE" }, - { RAND_INF_ZF_BOTTOM_NORTHEAST_MIDDLE_RUPEE, "RAND_INF_ZF_BOTTOM_NORTHEAST_MIDDLE_RUPEE" }, - { RAND_INF_ZF_BOTTOM_SOUTHEAST_MIDDLE_RUPEE, "RAND_INF_ZF_BOTTOM_SOUTHEAST_MIDDLE_RUPEE" }, - { RAND_INF_ZF_BOTTOM_SOUTH_MIDDLE_RUPEE, "RAND_INF_ZF_BOTTOM_SOUTH_MIDDLE_RUPEE" }, - { RAND_INF_ZF_BOTTOM_SOUTHWEST_MIDDLE_RUPEE, "RAND_INF_ZF_BOTTOM_SOUTHWEST_MIDDLE_RUPEE" }, - { RAND_INF_ZF_BOTTOM_NORTHWEST_MIDDLE_RUPEE, "RAND_INF_ZF_BOTTOM_NORTHWEST_MIDDLE_RUPEE" }, - { RAND_INF_ZF_BOTTOM_NORTH_OUTER_RUPEE, "RAND_INF_ZF_BOTTOM_NORTH_OUTER_RUPEE" }, - { RAND_INF_ZF_BOTTOM_NORTHEAST_OUTER_RUPEE, "RAND_INF_ZF_BOTTOM_NORTHEAST_OUTER_RUPEE" }, - { RAND_INF_ZF_BOTTOM_SOUTHEAST_OUTER_RUPEE, "RAND_INF_ZF_BOTTOM_SOUTHEAST_OUTER_RUPEE" }, - { RAND_INF_ZF_BOTTOM_SOUTH_OUTER_RUPEE, "RAND_INF_ZF_BOTTOM_SOUTH_OUTER_RUPEE" }, - { RAND_INF_ZF_BOTTOM_SOUTHWEST_OUTER_RUPEE, "RAND_INF_ZF_BOTTOM_SOUTHWEST_OUTER_RUPEE" }, - { RAND_INF_ZF_BOTTOM_NORTHWEST_OUTER_RUPEE, "RAND_INF_ZF_BOTTOM_NORTHWEST_OUTER_RUPEE" }, - { RAND_INF_DEKU_TREE_LOBBY_LOWER_HEART, "RAND_INF_DEKU_TREE_LOBBY_LOWER_HEART" }, - { RAND_INF_DEKU_TREE_LOBBY_UPPER_HEART, "RAND_INF_DEKU_TREE_LOBBY_UPPER_HEART" }, - { RAND_INF_DEKU_TREE_BEFORE_BOSS_LEFT_HEART, "RAND_INF_DEKU_TREE_BEFORE_BOSS_LEFT_HEART" }, - { RAND_INF_DEKU_TREE_BEFORE_BOSS_MIDDLE_HEART, "RAND_INF_DEKU_TREE_BEFORE_BOSS_MIDDLE_HEART" }, - { RAND_INF_DEKU_TREE_BEFORE_BOSS_RIGHT_HEART, "RAND_INF_DEKU_TREE_BEFORE_BOSS_RIGHT_HEART" }, - { RAND_INF_DODONGOS_CAVERN_BLADE_ROOM_HEART, "RAND_INF_DODONGOS_CAVERN_BLADE_ROOM_HEART" }, - { RAND_INF_DODONGOS_CAVERN_UPPER_LIZALFOS_LEFT_HEART, "RAND_INF_DODONGOS_CAVERN_UPPER_LIZALFOS_LEFT_HEART" }, - { RAND_INF_DODONGOS_CAVERN_UPPER_LIZALFOS_RIGHT_HEART, "RAND_INF_DODONGOS_CAVERN_UPPER_LIZALFOS_RIGHT_HEART" }, - { RAND_INF_FOREST_TEMPLE_COURTYARD_RIGHT_HEART, "RAND_INF_FOREST_TEMPLE_COURTYARD_RIGHT_HEART" }, - { RAND_INF_FOREST_TEMPLE_COURTYARD_LEFT_HEART, "RAND_INF_FOREST_TEMPLE_COURTYARD_LEFT_HEART" }, - { RAND_INF_FOREST_TEMPLE_WELL_WEST_HEART, "RAND_INF_FOREST_TEMPLE_WELL_WEST_HEART" }, - { RAND_INF_FOREST_TEMPLE_WELL_EAST_HEART, "RAND_INF_FOREST_TEMPLE_WELL_EAST_HEART" }, - { RAND_INF_FIRE_TEMPLE_FIRE_PILLAR_LEFT_HEART, "RAND_INF_FIRE_TEMPLE_FIRE_PILLAR_LEFT_HEART" }, - { RAND_INF_FIRE_TEMPLE_FIRE_PILLAR_RIGHT_HEART, "RAND_INF_FIRE_TEMPLE_FIRE_PILLAR_RIGHT_HEART" }, - { RAND_INF_FIRE_TEMPLE_FIRE_PILLAR_BACK_HEART, "RAND_INF_FIRE_TEMPLE_FIRE_PILLAR_BACK_HEART" }, - { RAND_INF_FIRE_TEMPLE_EAST_CENTRAL_LEFT_HEART, "RAND_INF_FIRE_TEMPLE_EAST_CENTRAL_LEFT_HEART" }, - { RAND_INF_FIRE_TEMPLE_EAST_CENTRAL_RIGHT_HEART, "RAND_INF_FIRE_TEMPLE_EAST_CENTRAL_RIGHT_HEART" }, - { RAND_INF_FIRE_TEMPLE_EAST_CENTRAL_MIDDLE_HEART, "RAND_INF_FIRE_TEMPLE_EAST_CENTRAL_MIDDLE_HEART" }, - { RAND_INF_FIRE_TEMPLE_FIRE_WALL_EAST_HEART, "RAND_INF_FIRE_TEMPLE_FIRE_WALL_EAST_HEART" }, - { RAND_INF_FIRE_TEMPLE_FIRE_WALL_WEST_HEART, "RAND_INF_FIRE_TEMPLE_FIRE_WALL_WEST_HEART" }, - { RAND_INF_FIRE_TEMPLE_FIRE_WALL_EXIT_HEART, "RAND_INF_FIRE_TEMPLE_FIRE_WALL_EXIT_HEART" }, - { RAND_INF_WATER_TEMPLE_RIVER_HEART_1, "RAND_INF_WATER_TEMPLE_RIVER_HEART_1" }, - { RAND_INF_WATER_TEMPLE_RIVER_HEART_2, "RAND_INF_WATER_TEMPLE_RIVER_HEART_2" }, - { RAND_INF_WATER_TEMPLE_RIVER_HEART_3, "RAND_INF_WATER_TEMPLE_RIVER_HEART_3" }, - { RAND_INF_WATER_TEMPLE_RIVER_HEART_4, "RAND_INF_WATER_TEMPLE_RIVER_HEART_4" }, - { RAND_INF_SHADOW_TEMPLE_INVISIBLE_BLADES_LEFT_HEART, "RAND_INF_SHADOW_TEMPLE_INVISIBLE_BLADES_LEFT_HEART" }, - { RAND_INF_SHADOW_TEMPLE_INVISIBLE_BLADES_RIGHT_HEART, "RAND_INF_SHADOW_TEMPLE_INVISIBLE_BLADES_RIGHT_HEART" }, - { RAND_INF_SHADOW_TEMPLE_SCARECROW_NORTH_HEART, "RAND_INF_SHADOW_TEMPLE_SCARECROW_NORTH_HEART" }, - { RAND_INF_SHADOW_TEMPLE_SCARECROW_SOUTH_HEART, "RAND_INF_SHADOW_TEMPLE_SCARECROW_SOUTH_HEART" }, - { RAND_INF_SHADOW_TEMPLE_AFTER_SHIP_UPPER_LEFT_HEART, "RAND_INF_SHADOW_TEMPLE_AFTER_SHIP_UPPER_LEFT_HEART" }, - { RAND_INF_SHADOW_TEMPLE_AFTER_SHIP_UPPER_RIGHT_HEART, "RAND_INF_SHADOW_TEMPLE_AFTER_SHIP_UPPER_RIGHT_HEART" }, - { RAND_INF_SHADOW_TEMPLE_AFTER_SHIP_LOWER_HEART, "RAND_INF_SHADOW_TEMPLE_AFTER_SHIP_LOWER_HEART" }, - { RAND_INF_ICE_CAVERN_LOBBY_RUPEE, "RAND_INF_ICE_CAVERN_LOBBY_RUPEE" }, - { RAND_INF_ICE_CAVERN_MAP_ROOM_LEFT_HEART, "RAND_INF_ICE_CAVERN_MAP_ROOM_LEFT_HEART" }, - { RAND_INF_ICE_CAVERN_MAP_ROOM_MIDDLE_HEART, "RAND_INF_ICE_CAVERN_MAP_ROOM_MIDDLE_HEART" }, - { RAND_INF_ICE_CAVERN_MAP_ROOM_RIGHT_HEART, "RAND_INF_ICE_CAVERN_MAP_ROOM_RIGHT_HEART" }, - { RAND_INF_ICE_CAVERN_SLIDING_BLOCK_RUPEE_1, "RAND_INF_ICE_CAVERN_SLIDING_BLOCK_RUPEE_1" }, - { RAND_INF_ICE_CAVERN_SLIDING_BLOCK_RUPEE_2, "RAND_INF_ICE_CAVERN_SLIDING_BLOCK_RUPEE_2" }, - { RAND_INF_ICE_CAVERN_SLIDING_BLOCK_RUPEE_3, "RAND_INF_ICE_CAVERN_SLIDING_BLOCK_RUPEE_3" }, - { RAND_INF_BOTTOM_OF_THE_WELL_COFFIN_ROOM_MIDDLE_RIGHT_HEART, "RAND_INF_BOTTOM_OF_THE_WELL_COFFIN_ROOM_MIDDLE_RIGHT_HEART" }, - { RAND_INF_GERUDO_TRAINING_GROUND_BEAMOS_SOUTH_HEART, "RAND_INF_GERUDO_TRAINING_GROUND_BEAMOS_SOUTH_HEART" }, - { RAND_INF_GERUDO_TRAINING_GROUND_BEAMOS_EAST_HEART, "RAND_INF_GERUDO_TRAINING_GROUND_BEAMOS_EAST_HEART" }, - { RAND_INF_GANONS_CASTLE_SHADOW_TRIAL_HEART_1, "RAND_INF_GANONS_CASTLE_SHADOW_TRIAL_HEART_1" }, - { RAND_INF_GANONS_CASTLE_SHADOW_TRIAL_HEART_2, "RAND_INF_GANONS_CASTLE_SHADOW_TRIAL_HEART_2" }, - { RAND_INF_GANONS_CASTLE_SHADOW_TRIAL_HEART_3, "RAND_INF_GANONS_CASTLE_SHADOW_TRIAL_HEART_3" }, - { RAND_INF_GANONS_CASTLE_FIRE_TRIAL_HEART, "RAND_INF_GANONS_CASTLE_FIRE_TRIAL_HEART" }, - { RAND_INF_GANONS_CASTLE_SPIRIT_TRIAL_HEART, "RAND_INF_GANONS_CASTLE_SPIRIT_TRIAL_HEART" }, - { RAND_INF_DEKU_TREE_MQ_COMPASS_ROOM_HEART, "RAND_INF_DEKU_TREE_MQ_COMPASS_ROOM_HEART" }, - { RAND_INF_DEKU_TREE_MQ_DEKU_BABA_HEART, "RAND_INF_DEKU_TREE_MQ_DEKU_BABA_HEART" }, - { RAND_INF_DEKU_TREE_MQ_LOBBY_HEART, "RAND_INF_DEKU_TREE_MQ_LOBBY_HEART" }, - { RAND_INF_DEKU_TREE_MQ_SLINGSHOT_ROOM_HEART, "RAND_INF_DEKU_TREE_MQ_SLINGSHOT_ROOM_HEART" }, - { RAND_INF_DEKU_TREE_MQ_BEFORE_BOSS_LEFT_HEART, "RAND_INF_DEKU_TREE_MQ_BEFORE_BOSS_LEFT_HEART" }, - { RAND_INF_DEKU_TREE_MQ_BEFORE_BOSS_MIDDLE_HEART, "RAND_INF_DEKU_TREE_MQ_BEFORE_BOSS_MIDDLE_HEART" }, - { RAND_INF_DEKU_TREE_MQ_BEFORE_BOSS_RIGHT_HEART, "RAND_INF_DEKU_TREE_MQ_BEFORE_BOSS_RIGHT_HEART" }, - { RAND_INF_DODONGOS_CAVERN_MQ_TORCH_PUZZLE_ROOM_HEART, "RAND_INF_DODONGOS_CAVERN_MQ_TORCH_PUZZLE_ROOM_HEART" }, - { RAND_INF_JABU_JABUS_BELLY_MQ_LIFT_HEART_1, "RAND_INF_JABU_JABUS_BELLY_MQ_LIFT_HEART_1" }, - { RAND_INF_JABU_JABUS_BELLY_MQ_LIFT_HEART_2, "RAND_INF_JABU_JABUS_BELLY_MQ_LIFT_HEART_2" }, - { RAND_INF_FOREST_TEMPLE_MQ_COURTYARD_RIGHT_HEART, "RAND_INF_FOREST_TEMPLE_MQ_COURTYARD_RIGHT_HEART" }, - { RAND_INF_FOREST_TEMPLE_MQ_COURTYARD_MIDDLE_HEART, "RAND_INF_FOREST_TEMPLE_MQ_COURTYARD_MIDDLE_HEART" }, - { RAND_INF_FOREST_TEMPLE_MQ_COURTYARD_LEFT_HEART, "RAND_INF_FOREST_TEMPLE_MQ_COURTYARD_LEFT_HEART" }, - { RAND_INF_FOREST_TEMPLE_WELL_MQ_WEST_HEART, "RAND_INF_FOREST_TEMPLE_WELL_MQ_WEST_HEART" }, - { RAND_INF_FOREST_TEMPLE_WELL_MQ_MIDDLE_HEART, "RAND_INF_FOREST_TEMPLE_WELL_MQ_MIDDLE_HEART" }, - { RAND_INF_FOREST_TEMPLE_WELL_MQ_EAST_HEART, "RAND_INF_FOREST_TEMPLE_WELL_MQ_EAST_HEART" }, - { RAND_INF_FIRE_TEMPLE_MQ_FIRE_PILLAR_LEFT_HEART, "RAND_INF_FIRE_TEMPLE_MQ_FIRE_PILLAR_LEFT_HEART" }, - { RAND_INF_FIRE_TEMPLE_MQ_FIRE_PILLAR_RIGHT_HEART, "RAND_INF_FIRE_TEMPLE_MQ_FIRE_PILLAR_RIGHT_HEART" }, - { RAND_INF_FIRE_TEMPLE_MQ_FIRE_PILLAR_LOWER_HEART, "RAND_INF_FIRE_TEMPLE_MQ_FIRE_PILLAR_LOWER_HEART" }, - { RAND_INF_SHADOW_TEMPLE_MQ_INVISIBLE_BLADES_LEFT_HEART, "RAND_INF_SHADOW_TEMPLE_MQ_INVISIBLE_BLADES_LEFT_HEART" }, - { RAND_INF_SHADOW_TEMPLE_MQ_INVISIBLE_BLADES_RIGHT_HEART, "RAND_INF_SHADOW_TEMPLE_MQ_INVISIBLE_BLADES_RIGHT_HEART" }, - { RAND_INF_SHADOW_TEMPLE_MQ_SCARECROW_NORTH_HEART, "RAND_INF_SHADOW_TEMPLE_MQ_SCARECROW_NORTH_HEART" }, - { RAND_INF_SHADOW_TEMPLE_MQ_SCARECROW_SOUTH_HEART, "RAND_INF_SHADOW_TEMPLE_MQ_SCARECROW_SOUTH_HEART" }, - { RAND_INF_SHADOW_TEMPLE_MQ_AFTER_SHIP_UPPER_LEFT_HEART, "RAND_INF_SHADOW_TEMPLE_MQ_AFTER_SHIP_UPPER_LEFT_HEART" }, - { RAND_INF_SHADOW_TEMPLE_MQ_AFTER_SHIP_UPPER_RIGHT_HEART, "RAND_INF_SHADOW_TEMPLE_MQ_AFTER_SHIP_UPPER_RIGHT_HEART" }, - { RAND_INF_SHADOW_TEMPLE_MQ_AFTER_SHIP_LOWER_HEART, "RAND_INF_SHADOW_TEMPLE_MQ_AFTER_SHIP_LOWER_HEART" }, - { RAND_INF_BOTTOM_OF_THE_WELL_MQ_COFFIN_ROOM_FRONT_RIGHT_HEART, "RAND_INF_BOTTOM_OF_THE_WELL_MQ_COFFIN_ROOM_FRONT_RIGHT_HEART" }, - { RAND_INF_BOTTOM_OF_THE_WELL_MQ_BOMB_LEFT_HEART, "RAND_INF_BOTTOM_OF_THE_WELL_MQ_BOMB_LEFT_HEART" }, - { RAND_INF_BOTTOM_OF_THE_WELL_MQ_BOMB_RIGHT_HEART, "RAND_INF_BOTTOM_OF_THE_WELL_MQ_BOMB_RIGHT_HEART" }, - { RAND_INF_BOTTOM_OF_THE_WELL_MQ_COFFIN_ROOM_MIDDLE_LEFT_HEART, "RAND_INF_BOTTOM_OF_THE_WELL_MQ_COFFIN_ROOM_MIDDLE_LEFT_HEART" }, - { RAND_INF_BOTTOM_OF_THE_WELL_MQ_BASEMENT_HALLWAY_FRONT_HEART, "RAND_INF_BOTTOM_OF_THE_WELL_MQ_BASEMENT_HALLWAY_FRONT_HEART" }, - { RAND_INF_BOTTOM_OF_THE_WELL_MQ_BASEMENT_HALLWAY_LEFT_HEART, "RAND_INF_BOTTOM_OF_THE_WELL_MQ_BASEMENT_HALLWAY_LEFT_HEART" }, - { RAND_INF_BOTTOM_OF_THE_WELL_MQ_BASEMENT_HALLWAY_RIGHT_HEART, "RAND_INF_BOTTOM_OF_THE_WELL_MQ_BASEMENT_HALLWAY_RIGHT_HEART" }, - { RAND_INF_GANONS_CASTLE_MQ_WATER_TRIAL_HEART, "RAND_INF_GANONS_CASTLE_MQ_WATER_TRIAL_HEART" }, - { RAND_INF_GANONS_CASTLE_MQ_LIGHT_TRIAL_RIGHT_HEART, "RAND_INF_GANONS_CASTLE_MQ_LIGHT_TRIAL_RIGHT_HEART" }, - { RAND_INF_GANONS_CASTLE_MQ_LIGHT_TRIAL_LEFT_HEART, "RAND_INF_GANONS_CASTLE_MQ_LIGHT_TRIAL_LEFT_HEART" }, + { RAND_INF_ZELDAS_LETTER, "RAND_INF_ZELDAS_LETTER" }, + { RAND_INF_WEIRD_EGG, "RAND_INF_WEIRD_EGG" }, - { RAND_INF_SFM_FAIRY_GROTTO_FAIRY_1, "RAND_INF_SFM_FAIRY_GROTTO_FAIRY_1" }, - { RAND_INF_SFM_FAIRY_GROTTO_FAIRY_2, "RAND_INF_SFM_FAIRY_GROTTO_FAIRY_2" }, - { RAND_INF_SFM_FAIRY_GROTTO_FAIRY_3, "RAND_INF_SFM_FAIRY_GROTTO_FAIRY_3" }, - { RAND_INF_SFM_FAIRY_GROTTO_FAIRY_4, "RAND_INF_SFM_FAIRY_GROTTO_FAIRY_4" }, - { RAND_INF_SFM_FAIRY_GROTTO_FAIRY_5, "RAND_INF_SFM_FAIRY_GROTTO_FAIRY_5" }, - { RAND_INF_SFM_FAIRY_GROTTO_FAIRY_6, "RAND_INF_SFM_FAIRY_GROTTO_FAIRY_6" }, - { RAND_INF_SFM_FAIRY_GROTTO_FAIRY_7, "RAND_INF_SFM_FAIRY_GROTTO_FAIRY_7" }, - { RAND_INF_SFM_FAIRY_GROTTO_FAIRY_8, "RAND_INF_SFM_FAIRY_GROTTO_FAIRY_8" }, - { RAND_INF_ZR_FAIRY_GROTTO_FAIRY_1, "RAND_INF_ZR_FAIRY_GROTTO_FAIRY_1" }, - { RAND_INF_ZR_FAIRY_GROTTO_FAIRY_2, "RAND_INF_ZR_FAIRY_GROTTO_FAIRY_2" }, - { RAND_INF_ZR_FAIRY_GROTTO_FAIRY_3, "RAND_INF_ZR_FAIRY_GROTTO_FAIRY_3" }, - { RAND_INF_ZR_FAIRY_GROTTO_FAIRY_4, "RAND_INF_ZR_FAIRY_GROTTO_FAIRY_4" }, - { RAND_INF_ZR_FAIRY_GROTTO_FAIRY_5, "RAND_INF_ZR_FAIRY_GROTTO_FAIRY_5" }, - { RAND_INF_ZR_FAIRY_GROTTO_FAIRY_6, "RAND_INF_ZR_FAIRY_GROTTO_FAIRY_6" }, - { RAND_INF_ZR_FAIRY_GROTTO_FAIRY_7, "RAND_INF_ZR_FAIRY_GROTTO_FAIRY_7" }, - { RAND_INF_ZR_FAIRY_GROTTO_FAIRY_8, "RAND_INF_ZR_FAIRY_GROTTO_FAIRY_8" }, - { RAND_INF_HF_FAIRY_GROTTO_FAIRY_1, "RAND_INF_HF_FAIRY_GROTTO_FAIRY_1" }, - { RAND_INF_HF_FAIRY_GROTTO_FAIRY_2, "RAND_INF_HF_FAIRY_GROTTO_FAIRY_2" }, - { RAND_INF_HF_FAIRY_GROTTO_FAIRY_3, "RAND_INF_HF_FAIRY_GROTTO_FAIRY_3" }, - { RAND_INF_HF_FAIRY_GROTTO_FAIRY_4, "RAND_INF_HF_FAIRY_GROTTO_FAIRY_4" }, - { RAND_INF_HF_FAIRY_GROTTO_FAIRY_5, "RAND_INF_HF_FAIRY_GROTTO_FAIRY_5" }, - { RAND_INF_HF_FAIRY_GROTTO_FAIRY_6, "RAND_INF_HF_FAIRY_GROTTO_FAIRY_6" }, - { RAND_INF_HF_FAIRY_GROTTO_FAIRY_7, "RAND_INF_HF_FAIRY_GROTTO_FAIRY_7" }, - { RAND_INF_HF_FAIRY_GROTTO_FAIRY_8, "RAND_INF_HF_FAIRY_GROTTO_FAIRY_8" }, - { RAND_INF_ZD_FAIRY_GROTTO_FAIRY_1, "RAND_INF_ZD_FAIRY_GROTTO_FAIRY_1" }, - { RAND_INF_ZD_FAIRY_GROTTO_FAIRY_2, "RAND_INF_ZD_FAIRY_GROTTO_FAIRY_2" }, - { RAND_INF_ZD_FAIRY_GROTTO_FAIRY_3, "RAND_INF_ZD_FAIRY_GROTTO_FAIRY_3" }, - { RAND_INF_ZD_FAIRY_GROTTO_FAIRY_4, "RAND_INF_ZD_FAIRY_GROTTO_FAIRY_4" }, - { RAND_INF_ZD_FAIRY_GROTTO_FAIRY_5, "RAND_INF_ZD_FAIRY_GROTTO_FAIRY_5" }, - { RAND_INF_ZD_FAIRY_GROTTO_FAIRY_6, "RAND_INF_ZD_FAIRY_GROTTO_FAIRY_6" }, - { RAND_INF_ZD_FAIRY_GROTTO_FAIRY_7, "RAND_INF_ZD_FAIRY_GROTTO_FAIRY_7" }, - { RAND_INF_ZD_FAIRY_GROTTO_FAIRY_8, "RAND_INF_ZD_FAIRY_GROTTO_FAIRY_8" }, - { RAND_INF_GF_FAIRY_GROTTO_FAIRY_1, "RAND_INF_GF_FAIRY_GROTTO_FAIRY_1" }, - { RAND_INF_GF_FAIRY_GROTTO_FAIRY_2, "RAND_INF_GF_FAIRY_GROTTO_FAIRY_2" }, - { RAND_INF_GF_FAIRY_GROTTO_FAIRY_3, "RAND_INF_GF_FAIRY_GROTTO_FAIRY_3" }, - { RAND_INF_GF_FAIRY_GROTTO_FAIRY_4, "RAND_INF_GF_FAIRY_GROTTO_FAIRY_4" }, - { RAND_INF_GF_FAIRY_GROTTO_FAIRY_5, "RAND_INF_GF_FAIRY_GROTTO_FAIRY_5" }, - { RAND_INF_GF_FAIRY_GROTTO_FAIRY_6, "RAND_INF_GF_FAIRY_GROTTO_FAIRY_6" }, - { RAND_INF_GF_FAIRY_GROTTO_FAIRY_7, "RAND_INF_GF_FAIRY_GROTTO_FAIRY_7" }, - { RAND_INF_GF_FAIRY_GROTTO_FAIRY_8, "RAND_INF_GF_FAIRY_GROTTO_FAIRY_8" }, - { RAND_INF_GRAVEYARD_SHIELD_GRAVE_FAIRY_1, "RAND_INF_GRAVEYARD_SHIELD_GRAVE_FAIRY_1" }, - { RAND_INF_GRAVEYARD_SHIELD_GRAVE_FAIRY_2, "RAND_INF_GRAVEYARD_SHIELD_GRAVE_FAIRY_2" }, - { RAND_INF_GRAVEYARD_SHIELD_GRAVE_FAIRY_3, "RAND_INF_GRAVEYARD_SHIELD_GRAVE_FAIRY_3" }, - { RAND_INF_GRAVEYARD_SHIELD_GRAVE_FAIRY_4, "RAND_INF_GRAVEYARD_SHIELD_GRAVE_FAIRY_4" }, - { RAND_INF_GRAVEYARD_SHIELD_GRAVE_FAIRY_5, "RAND_INF_GRAVEYARD_SHIELD_GRAVE_FAIRY_5" }, - { RAND_INF_GRAVEYARD_SHIELD_GRAVE_FAIRY_6, "RAND_INF_GRAVEYARD_SHIELD_GRAVE_FAIRY_6" }, - { RAND_INF_GRAVEYARD_SHIELD_GRAVE_FAIRY_7, "RAND_INF_GRAVEYARD_SHIELD_GRAVE_FAIRY_7" }, - { RAND_INF_GRAVEYARD_SHIELD_GRAVE_FAIRY_8, "RAND_INF_GRAVEYARD_SHIELD_GRAVE_FAIRY_8" }, - { RAND_INF_GANONS_CASTLE_SCRUBS_FAIRY_1, "RAND_INF_GANONS_CASTLE_SCRUBS_FAIRY_1" }, - { RAND_INF_GANONS_CASTLE_SCRUBS_FAIRY_2, "RAND_INF_GANONS_CASTLE_SCRUBS_FAIRY_2" }, - { RAND_INF_GANONS_CASTLE_SCRUBS_FAIRY_3, "RAND_INF_GANONS_CASTLE_SCRUBS_FAIRY_3" }, - { RAND_INF_GANONS_CASTLE_SCRUBS_FAIRY_4, "RAND_INF_GANONS_CASTLE_SCRUBS_FAIRY_4" }, - { RAND_INF_GANONS_CASTLE_SCRUBS_FAIRY_5, "RAND_INF_GANONS_CASTLE_SCRUBS_FAIRY_5" }, - { RAND_INF_GANONS_CASTLE_SCRUBS_FAIRY_6, "RAND_INF_GANONS_CASTLE_SCRUBS_FAIRY_6" }, - { RAND_INF_GANONS_CASTLE_SCRUBS_FAIRY_7, "RAND_INF_GANONS_CASTLE_SCRUBS_FAIRY_7" }, - { RAND_INF_GANONS_CASTLE_SCRUBS_FAIRY_8, "RAND_INF_GANONS_CASTLE_SCRUBS_FAIRY_8" }, - { RAND_INF_GANONS_CASTLE_MQ_SCRUBS_FAIRY_1, "RAND_INF_GANONS_CASTLE_MQ_SCRUBS_FAIRY_1" }, - { RAND_INF_GANONS_CASTLE_MQ_SCRUBS_FAIRY_2, "RAND_INF_GANONS_CASTLE_MQ_SCRUBS_FAIRY_2" }, - { RAND_INF_GANONS_CASTLE_MQ_SCRUBS_FAIRY_3, "RAND_INF_GANONS_CASTLE_MQ_SCRUBS_FAIRY_3" }, - { RAND_INF_GANONS_CASTLE_MQ_SCRUBS_FAIRY_4, "RAND_INF_GANONS_CASTLE_MQ_SCRUBS_FAIRY_4" }, - { RAND_INF_GANONS_CASTLE_MQ_SCRUBS_FAIRY_5, "RAND_INF_GANONS_CASTLE_MQ_SCRUBS_FAIRY_5" }, - { RAND_INF_GANONS_CASTLE_MQ_SCRUBS_FAIRY_6, "RAND_INF_GANONS_CASTLE_MQ_SCRUBS_FAIRY_6" }, - { RAND_INF_GANONS_CASTLE_MQ_SCRUBS_FAIRY_7, "RAND_INF_GANONS_CASTLE_MQ_SCRUBS_FAIRY_7" }, - { RAND_INF_GANONS_CASTLE_MQ_SCRUBS_FAIRY_8, "RAND_INF_GANONS_CASTLE_MQ_SCRUBS_FAIRY_8" }, - { RAND_INF_COLOSSUS_OASIS_FAIRY_1, "RAND_INF_COLOSSUS_OASIS_FAIRY_1" }, - { RAND_INF_COLOSSUS_OASIS_FAIRY_2, "RAND_INF_COLOSSUS_OASIS_FAIRY_2" }, - { RAND_INF_COLOSSUS_OASIS_FAIRY_3, "RAND_INF_COLOSSUS_OASIS_FAIRY_3" }, - { RAND_INF_COLOSSUS_OASIS_FAIRY_4, "RAND_INF_COLOSSUS_OASIS_FAIRY_4" }, - { RAND_INF_COLOSSUS_OASIS_FAIRY_5, "RAND_INF_COLOSSUS_OASIS_FAIRY_5" }, - { RAND_INF_COLOSSUS_OASIS_FAIRY_6, "RAND_INF_COLOSSUS_OASIS_FAIRY_6" }, - { RAND_INF_COLOSSUS_OASIS_FAIRY_7, "RAND_INF_COLOSSUS_OASIS_FAIRY_7" }, - { RAND_INF_COLOSSUS_OASIS_FAIRY_8, "RAND_INF_COLOSSUS_OASIS_FAIRY_8" }, + { RAND_INF_KF_SOUTH_GRASS_WEST_RUPEE, "RAND_INF_KF_SOUTH_GRASS_WEST_RUPEE" }, + { RAND_INF_KF_NORTH_GRASS_WEST_RUPEE, "RAND_INF_KF_NORTH_GRASS_WEST_RUPEE" }, + { RAND_INF_KF_NORTH_GRASS_EAST_RUPEE, "RAND_INF_KF_NORTH_GRASS_EAST_RUPEE" }, + { RAND_INF_KF_SOUTH_GRASS_EAST_RUPEE, "RAND_INF_KF_SOUTH_GRASS_EAST_RUPEE" }, + { RAND_INF_KF_SARIAS_TOP_LEFT_HEART, "RAND_INF_KF_SARIAS_TOP_LEFT_HEART" }, + { RAND_INF_KF_SARIAS_TOP_RIGHT_HEART, "RAND_INF_KF_SARIAS_TOP_RIGHT_HEART" }, + { RAND_INF_KF_SARIAS_BOTTOM_LEFT_HEART, "RAND_INF_KF_SARIAS_BOTTOM_LEFT_HEART" }, + { RAND_INF_KF_SARIAS_BOTTOM_RIGHT_HEART, "RAND_INF_KF_SARIAS_BOTTOM_RIGHT_HEART" }, + { RAND_INF_KF_BEAN_RUPEE_1, "RAND_INF_KF_BEAN_RUPEE_1" }, + { RAND_INF_KF_BEAN_RUPEE_2, "RAND_INF_KF_BEAN_RUPEE_2" }, + { RAND_INF_KF_BEAN_RUPEE_3, "RAND_INF_KF_BEAN_RUPEE_3" }, + { RAND_INF_KF_BEAN_RUPEE_4, "RAND_INF_KF_BEAN_RUPEE_4" }, + { RAND_INF_KF_BEAN_RUPEE_5, "RAND_INF_KF_BEAN_RUPEE_5" }, + { RAND_INF_KF_BEAN_RUPEE_6, "RAND_INF_KF_BEAN_RUPEE_6" }, + { RAND_INF_KF_BEAN_RED_RUPEE, "RAND_INF_KF_BEAN_RED_RUPEE" }, + { RAND_INF_LW_SHORTCUT_RUPEE_1, "RAND_INF_LW_SHORTCUT_RUPEE_1" }, + { RAND_INF_LW_SHORTCUT_RUPEE_2, "RAND_INF_LW_SHORTCUT_RUPEE_2" }, + { RAND_INF_LW_SHORTCUT_RUPEE_3, "RAND_INF_LW_SHORTCUT_RUPEE_3" }, + { RAND_INF_LW_SHORTCUT_RUPEE_4, "RAND_INF_LW_SHORTCUT_RUPEE_4" }, + { RAND_INF_LW_SHORTCUT_RUPEE_5, "RAND_INF_LW_SHORTCUT_RUPEE_5" }, + { RAND_INF_LW_SHORTCUT_RUPEE_6, "RAND_INF_LW_SHORTCUT_RUPEE_6" }, + { RAND_INF_LW_SHORTCUT_RUPEE_7, "RAND_INF_LW_SHORTCUT_RUPEE_7" }, + { RAND_INF_LW_SHORTCUT_RUPEE_8, "RAND_INF_LW_SHORTCUT_RUPEE_8" }, + { RAND_INF_LH_FRONT_RUPEE, "RAND_INF_LH_FRONT_RUPEE" }, + { RAND_INF_LH_MIDDLE_RUPEE, "RAND_INF_LH_MIDDLE_RUPEE" }, + { RAND_INF_LH_BACK_RUPEE, "RAND_INF_LH_BACK_RUPEE" }, + { RAND_INF_GRAVEYARD_DAMPE_RACE_RUPEE_1, "RAND_INF_GRAVEYARD_DAMPE_RACE_RUPEE_1" }, + { RAND_INF_GRAVEYARD_DAMPE_RACE_RUPEE_2, "RAND_INF_GRAVEYARD_DAMPE_RACE_RUPEE_2" }, + { RAND_INF_GRAVEYARD_DAMPE_RACE_RUPEE_3, "RAND_INF_GRAVEYARD_DAMPE_RACE_RUPEE_3" }, + { RAND_INF_GRAVEYARD_DAMPE_RACE_RUPEE_4, "RAND_INF_GRAVEYARD_DAMPE_RACE_RUPEE_4" }, + { RAND_INF_GRAVEYARD_DAMPE_RACE_RUPEE_5, "RAND_INF_GRAVEYARD_DAMPE_RACE_RUPEE_5" }, + { RAND_INF_GRAVEYARD_DAMPE_RACE_RUPEE_6, "RAND_INF_GRAVEYARD_DAMPE_RACE_RUPEE_6" }, + { RAND_INF_GRAVEYARD_DAMPE_RACE_RUPEE_7, "RAND_INF_GRAVEYARD_DAMPE_RACE_RUPEE_7" }, + { RAND_INF_GRAVEYARD_DAMPE_RACE_RUPEE_8, "RAND_INF_GRAVEYARD_DAMPE_RACE_RUPEE_8" }, + { RAND_INF_GV_OCTOROK_GROTTO_FRONT_LEFT_BLUE_RUPEE, "RAND_INF_GV_OCTOROK_GROTTO_FRONT_LEFT_BLUE_RUPEE" }, + { RAND_INF_GV_OCTOROK_GROTTO_BACK_BLUE_RUPEE, "RAND_INF_GV_OCTOROK_GROTTO_BACK_BLUE_RUPEE" }, + { RAND_INF_GV_OCTOROK_GROTTO_FRONT_RIGHT_BLUE_RUPEE, "RAND_INF_GV_OCTOROK_GROTTO_FRONT_RIGHT_BLUE_RUPEE" }, + { RAND_INF_GV_OCTOROK_GROTTO_FRONT_LEFT_GREEN_RUPEE, "RAND_INF_GV_OCTOROK_GROTTO_FRONT_LEFT_GREEN_RUPEE" }, + { RAND_INF_GV_OCTOROK_GROTTO_FRONT_RIGHT_GREEN_RUPEE, "RAND_INF_GV_OCTOROK_GROTTO_FRONT_RIGHT_GREEN_RUPEE" }, + { RAND_INF_GV_OCTOROK_GROTTO_BACK_LEFT_GREEN_RUPEE, "RAND_INF_GV_OCTOROK_GROTTO_BACK_LEFT_GREEN_RUPEE" }, + { RAND_INF_GV_OCTOROK_GROTTO_BACK_RIGHT_GREEN_RUPEE, "RAND_INF_GV_OCTOROK_GROTTO_BACK_RIGHT_GREEN_RUPEE" }, + { RAND_INF_GV_OCTOROK_GROTTO_RED_RUPEE, "RAND_INF_GV_OCTOROK_GROTTO_RED_RUPEE" }, + { RAND_INF_DMT_BLUE_RUPEE, "RAND_INF_DMT_BLUE_RUPEE" }, + { RAND_INF_DMT_COW_GROTTO_LEFT_HEART, "RAND_INF_DMT_COW_GROTTO_LEFT_HEART" }, + { RAND_INF_DMT_COW_GROTTO_MIDDLE_LEFT_HEART, "RAND_INF_DMT_COW_GROTTO_MIDDLE_LEFT_HEART" }, + { RAND_INF_DMT_COW_GROTTO_MIDDLE_RIGHT_HEART, "RAND_INF_DMT_COW_GROTTO_MIDDLE_RIGHT_HEART" }, + { RAND_INF_DMT_COW_GROTTO_RIGHT_HEART, "RAND_INF_DMT_COW_GROTTO_RIGHT_HEART" }, + { RAND_INF_DMT_COW_GROTTO_RUPEE_1, "RAND_INF_DMT_COW_GROTTO_RUPEE_1" }, + { RAND_INF_DMT_COW_GROTTO_RUPEE_2, "RAND_INF_DMT_COW_GROTTO_RUPEE_2" }, + { RAND_INF_DMT_COW_GROTTO_RUPEE_3, "RAND_INF_DMT_COW_GROTTO_RUPEE_3" }, + { RAND_INF_DMT_COW_GROTTO_RUPEE_4, "RAND_INF_DMT_COW_GROTTO_RUPEE_4" }, + { RAND_INF_DMT_COW_GROTTO_RUPEE_5, "RAND_INF_DMT_COW_GROTTO_RUPEE_5" }, + { RAND_INF_DMT_COW_GROTTO_RUPEE_6, "RAND_INF_DMT_COW_GROTTO_RUPEE_6" }, + { RAND_INF_DMT_COW_GROTTO_RED_RUPEE, "RAND_INF_DMT_COW_GROTTO_RED_RUPEE" }, + { RAND_INF_DMC_NEAR_PLATFORM_RED_RUPEE, "RAND_INF_DMC_NEAR_PLATFORM_RED_RUPEE" }, + { RAND_INF_DMC_MIDDLE_PLATFORM_RED_RUPEE, "RAND_INF_DMC_MIDDLE_PLATFORM_RED_RUPEE" }, + { RAND_INF_DMC_MIDDLE_PLATFORM_BLUE_RUPEE_1, "RAND_INF_DMC_MIDDLE_PLATFORM_BLUE_RUPEE_1" }, + { RAND_INF_DMC_MIDDLE_PLATFORM_BLUE_RUPEE_2, "RAND_INF_DMC_MIDDLE_PLATFORM_BLUE_RUPEE_2" }, + { RAND_INF_DMC_MIDDLE_PLATFORM_BLUE_RUPEE_3, "RAND_INF_DMC_MIDDLE_PLATFORM_BLUE_RUPEE_3" }, + { RAND_INF_DMC_MIDDLE_PLATFORM_BLUE_RUPEE_4, "RAND_INF_DMC_MIDDLE_PLATFORM_BLUE_RUPEE_4" }, + { RAND_INF_DMC_MIDDLE_PLATFORM_BLUE_RUPEE_5, "RAND_INF_DMC_MIDDLE_PLATFORM_BLUE_RUPEE_5" }, + { RAND_INF_DMC_MIDDLE_PLATFORM_BLUE_RUPEE_6, "RAND_INF_DMC_MIDDLE_PLATFORM_BLUE_RUPEE_6" }, + { RAND_INF_DMC_DISTANT_PLATFORM_RUPEE_1, "RAND_INF_DMC_DISTANT_PLATFORM_RUPEE_1" }, + { RAND_INF_DMC_DISTANT_PLATFORM_RUPEE_2, "RAND_INF_DMC_DISTANT_PLATFORM_RUPEE_2" }, + { RAND_INF_DMC_DISTANT_PLATFORM_RUPEE_3, "RAND_INF_DMC_DISTANT_PLATFORM_RUPEE_3" }, + { RAND_INF_DMC_DISTANT_PLATFORM_RUPEE_4, "RAND_INF_DMC_DISTANT_PLATFORM_RUPEE_4" }, + { RAND_INF_DMC_DISTANT_PLATFORM_RUPEE_5, "RAND_INF_DMC_DISTANT_PLATFORM_RUPEE_5" }, + { RAND_INF_DMC_DISTANT_PLATFORM_RUPEE_6, "RAND_INF_DMC_DISTANT_PLATFORM_RUPEE_6" }, + { RAND_INF_DMC_DISTANT_PLATFORM_RED_RUPEE, "RAND_INF_DMC_DISTANT_PLATFORM_RED_RUPEE" }, + { RAND_INF_ZR_BENEATH_WATERFALL_LEFT_RUPEE, "RAND_INF_ZR_BENEATH_WATERFALL_LEFT_RUPEE" }, + { RAND_INF_ZR_BENEATH_WATERFALL_MIDDLE_LEFT_RUPEE, "RAND_INF_ZR_BENEATH_WATERFALL_MIDDLE_LEFT_RUPEE" }, + { RAND_INF_ZR_BENEATH_WATERFALL_MIDDLE_RIGHT_RUPEE, "RAND_INF_ZR_BENEATH_WATERFALL_MIDDLE_RIGHT_RUPEE" }, + { RAND_INF_ZR_BENEATH_WATERFALL_RIGHT_RUPEE, "RAND_INF_ZR_BENEATH_WATERFALL_RIGHT_RUPEE" }, + { RAND_INF_ZF_BOTTOM_NORTH_INNER_RUPEE, "RAND_INF_ZF_BOTTOM_NORTH_INNER_RUPEE" }, + { RAND_INF_ZF_BOTTOM_NORTHEAST_INNER_RUPEE, "RAND_INF_ZF_BOTTOM_NORTHEAST_INNER_RUPEE" }, + { RAND_INF_ZF_BOTTOM_SOUTHEAST_INNER_RUPEE, "RAND_INF_ZF_BOTTOM_SOUTHEAST_INNER_RUPEE" }, + { RAND_INF_ZF_BOTTOM_SOUTH_INNER_RUPEE, "RAND_INF_ZF_BOTTOM_SOUTH_INNER_RUPEE" }, + { RAND_INF_ZF_BOTTOM_SOUTHWEST_INNER_RUPEE, "RAND_INF_ZF_BOTTOM_SOUTHWEST_INNER_RUPEE" }, + { RAND_INF_ZF_BOTTOM_NORTHWEST_INNER_RUPEE, "RAND_INF_ZF_BOTTOM_NORTHWEST_INNER_RUPEE" }, + { RAND_INF_ZF_BOTTOM_NORTH_MIDDLE_RUPEE, "RAND_INF_ZF_BOTTOM_NORTH_MIDDLE_RUPEE" }, + { RAND_INF_ZF_BOTTOM_NORTHEAST_MIDDLE_RUPEE, "RAND_INF_ZF_BOTTOM_NORTHEAST_MIDDLE_RUPEE" }, + { RAND_INF_ZF_BOTTOM_SOUTHEAST_MIDDLE_RUPEE, "RAND_INF_ZF_BOTTOM_SOUTHEAST_MIDDLE_RUPEE" }, + { RAND_INF_ZF_BOTTOM_SOUTH_MIDDLE_RUPEE, "RAND_INF_ZF_BOTTOM_SOUTH_MIDDLE_RUPEE" }, + { RAND_INF_ZF_BOTTOM_SOUTHWEST_MIDDLE_RUPEE, "RAND_INF_ZF_BOTTOM_SOUTHWEST_MIDDLE_RUPEE" }, + { RAND_INF_ZF_BOTTOM_NORTHWEST_MIDDLE_RUPEE, "RAND_INF_ZF_BOTTOM_NORTHWEST_MIDDLE_RUPEE" }, + { RAND_INF_ZF_BOTTOM_NORTH_OUTER_RUPEE, "RAND_INF_ZF_BOTTOM_NORTH_OUTER_RUPEE" }, + { RAND_INF_ZF_BOTTOM_NORTHEAST_OUTER_RUPEE, "RAND_INF_ZF_BOTTOM_NORTHEAST_OUTER_RUPEE" }, + { RAND_INF_ZF_BOTTOM_SOUTHEAST_OUTER_RUPEE, "RAND_INF_ZF_BOTTOM_SOUTHEAST_OUTER_RUPEE" }, + { RAND_INF_ZF_BOTTOM_SOUTH_OUTER_RUPEE, "RAND_INF_ZF_BOTTOM_SOUTH_OUTER_RUPEE" }, + { RAND_INF_ZF_BOTTOM_SOUTHWEST_OUTER_RUPEE, "RAND_INF_ZF_BOTTOM_SOUTHWEST_OUTER_RUPEE" }, + { RAND_INF_ZF_BOTTOM_NORTHWEST_OUTER_RUPEE, "RAND_INF_ZF_BOTTOM_NORTHWEST_OUTER_RUPEE" }, + { RAND_INF_DEKU_TREE_LOBBY_LOWER_HEART, "RAND_INF_DEKU_TREE_LOBBY_LOWER_HEART" }, + { RAND_INF_DEKU_TREE_LOBBY_UPPER_HEART, "RAND_INF_DEKU_TREE_LOBBY_UPPER_HEART" }, + { RAND_INF_DEKU_TREE_BEFORE_BOSS_LEFT_HEART, "RAND_INF_DEKU_TREE_BEFORE_BOSS_LEFT_HEART" }, + { RAND_INF_DEKU_TREE_BEFORE_BOSS_MIDDLE_HEART, "RAND_INF_DEKU_TREE_BEFORE_BOSS_MIDDLE_HEART" }, + { RAND_INF_DEKU_TREE_BEFORE_BOSS_RIGHT_HEART, "RAND_INF_DEKU_TREE_BEFORE_BOSS_RIGHT_HEART" }, + { RAND_INF_DODONGOS_CAVERN_BLADE_ROOM_HEART, "RAND_INF_DODONGOS_CAVERN_BLADE_ROOM_HEART" }, + { RAND_INF_DODONGOS_CAVERN_UPPER_LIZALFOS_LEFT_HEART, "RAND_INF_DODONGOS_CAVERN_UPPER_LIZALFOS_LEFT_HEART" }, + { RAND_INF_DODONGOS_CAVERN_UPPER_LIZALFOS_RIGHT_HEART, + "RAND_INF_DODONGOS_CAVERN_UPPER_LIZALFOS_RIGHT_HEART" }, + { RAND_INF_FOREST_TEMPLE_COURTYARD_RIGHT_HEART, "RAND_INF_FOREST_TEMPLE_COURTYARD_RIGHT_HEART" }, + { RAND_INF_FOREST_TEMPLE_COURTYARD_LEFT_HEART, "RAND_INF_FOREST_TEMPLE_COURTYARD_LEFT_HEART" }, + { RAND_INF_FOREST_TEMPLE_WELL_WEST_HEART, "RAND_INF_FOREST_TEMPLE_WELL_WEST_HEART" }, + { RAND_INF_FOREST_TEMPLE_WELL_EAST_HEART, "RAND_INF_FOREST_TEMPLE_WELL_EAST_HEART" }, + { RAND_INF_FIRE_TEMPLE_FIRE_PILLAR_LEFT_HEART, "RAND_INF_FIRE_TEMPLE_FIRE_PILLAR_LEFT_HEART" }, + { RAND_INF_FIRE_TEMPLE_FIRE_PILLAR_RIGHT_HEART, "RAND_INF_FIRE_TEMPLE_FIRE_PILLAR_RIGHT_HEART" }, + { RAND_INF_FIRE_TEMPLE_FIRE_PILLAR_BACK_HEART, "RAND_INF_FIRE_TEMPLE_FIRE_PILLAR_BACK_HEART" }, + { RAND_INF_FIRE_TEMPLE_EAST_CENTRAL_LEFT_HEART, "RAND_INF_FIRE_TEMPLE_EAST_CENTRAL_LEFT_HEART" }, + { RAND_INF_FIRE_TEMPLE_EAST_CENTRAL_RIGHT_HEART, "RAND_INF_FIRE_TEMPLE_EAST_CENTRAL_RIGHT_HEART" }, + { RAND_INF_FIRE_TEMPLE_EAST_CENTRAL_MIDDLE_HEART, "RAND_INF_FIRE_TEMPLE_EAST_CENTRAL_MIDDLE_HEART" }, + { RAND_INF_FIRE_TEMPLE_FIRE_WALL_EAST_HEART, "RAND_INF_FIRE_TEMPLE_FIRE_WALL_EAST_HEART" }, + { RAND_INF_FIRE_TEMPLE_FIRE_WALL_WEST_HEART, "RAND_INF_FIRE_TEMPLE_FIRE_WALL_WEST_HEART" }, + { RAND_INF_FIRE_TEMPLE_FIRE_WALL_EXIT_HEART, "RAND_INF_FIRE_TEMPLE_FIRE_WALL_EXIT_HEART" }, + { RAND_INF_WATER_TEMPLE_RIVER_HEART_1, "RAND_INF_WATER_TEMPLE_RIVER_HEART_1" }, + { RAND_INF_WATER_TEMPLE_RIVER_HEART_2, "RAND_INF_WATER_TEMPLE_RIVER_HEART_2" }, + { RAND_INF_WATER_TEMPLE_RIVER_HEART_3, "RAND_INF_WATER_TEMPLE_RIVER_HEART_3" }, + { RAND_INF_WATER_TEMPLE_RIVER_HEART_4, "RAND_INF_WATER_TEMPLE_RIVER_HEART_4" }, + { RAND_INF_SHADOW_TEMPLE_INVISIBLE_BLADES_LEFT_HEART, "RAND_INF_SHADOW_TEMPLE_INVISIBLE_BLADES_LEFT_HEART" }, + { RAND_INF_SHADOW_TEMPLE_INVISIBLE_BLADES_RIGHT_HEART, + "RAND_INF_SHADOW_TEMPLE_INVISIBLE_BLADES_RIGHT_HEART" }, + { RAND_INF_SHADOW_TEMPLE_SCARECROW_NORTH_HEART, "RAND_INF_SHADOW_TEMPLE_SCARECROW_NORTH_HEART" }, + { RAND_INF_SHADOW_TEMPLE_SCARECROW_SOUTH_HEART, "RAND_INF_SHADOW_TEMPLE_SCARECROW_SOUTH_HEART" }, + { RAND_INF_SHADOW_TEMPLE_AFTER_SHIP_UPPER_LEFT_HEART, "RAND_INF_SHADOW_TEMPLE_AFTER_SHIP_UPPER_LEFT_HEART" }, + { RAND_INF_SHADOW_TEMPLE_AFTER_SHIP_UPPER_RIGHT_HEART, + "RAND_INF_SHADOW_TEMPLE_AFTER_SHIP_UPPER_RIGHT_HEART" }, + { RAND_INF_SHADOW_TEMPLE_AFTER_SHIP_LOWER_HEART, "RAND_INF_SHADOW_TEMPLE_AFTER_SHIP_LOWER_HEART" }, + { RAND_INF_ICE_CAVERN_LOBBY_RUPEE, "RAND_INF_ICE_CAVERN_LOBBY_RUPEE" }, + { RAND_INF_ICE_CAVERN_MAP_ROOM_LEFT_HEART, "RAND_INF_ICE_CAVERN_MAP_ROOM_LEFT_HEART" }, + { RAND_INF_ICE_CAVERN_MAP_ROOM_MIDDLE_HEART, "RAND_INF_ICE_CAVERN_MAP_ROOM_MIDDLE_HEART" }, + { RAND_INF_ICE_CAVERN_MAP_ROOM_RIGHT_HEART, "RAND_INF_ICE_CAVERN_MAP_ROOM_RIGHT_HEART" }, + { RAND_INF_ICE_CAVERN_SLIDING_BLOCK_RUPEE_1, "RAND_INF_ICE_CAVERN_SLIDING_BLOCK_RUPEE_1" }, + { RAND_INF_ICE_CAVERN_SLIDING_BLOCK_RUPEE_2, "RAND_INF_ICE_CAVERN_SLIDING_BLOCK_RUPEE_2" }, + { RAND_INF_ICE_CAVERN_SLIDING_BLOCK_RUPEE_3, "RAND_INF_ICE_CAVERN_SLIDING_BLOCK_RUPEE_3" }, + { RAND_INF_BOTTOM_OF_THE_WELL_COFFIN_ROOM_MIDDLE_RIGHT_HEART, + "RAND_INF_BOTTOM_OF_THE_WELL_COFFIN_ROOM_MIDDLE_RIGHT_HEART" }, + { RAND_INF_GERUDO_TRAINING_GROUND_BEAMOS_SOUTH_HEART, "RAND_INF_GERUDO_TRAINING_GROUND_BEAMOS_SOUTH_HEART" }, + { RAND_INF_GERUDO_TRAINING_GROUND_BEAMOS_EAST_HEART, "RAND_INF_GERUDO_TRAINING_GROUND_BEAMOS_EAST_HEART" }, + { RAND_INF_GANONS_CASTLE_SHADOW_TRIAL_HEART_1, "RAND_INF_GANONS_CASTLE_SHADOW_TRIAL_HEART_1" }, + { RAND_INF_GANONS_CASTLE_SHADOW_TRIAL_HEART_2, "RAND_INF_GANONS_CASTLE_SHADOW_TRIAL_HEART_2" }, + { RAND_INF_GANONS_CASTLE_SHADOW_TRIAL_HEART_3, "RAND_INF_GANONS_CASTLE_SHADOW_TRIAL_HEART_3" }, + { RAND_INF_GANONS_CASTLE_FIRE_TRIAL_HEART, "RAND_INF_GANONS_CASTLE_FIRE_TRIAL_HEART" }, + { RAND_INF_GANONS_CASTLE_SPIRIT_TRIAL_HEART, "RAND_INF_GANONS_CASTLE_SPIRIT_TRIAL_HEART" }, + { RAND_INF_DEKU_TREE_MQ_COMPASS_ROOM_HEART, "RAND_INF_DEKU_TREE_MQ_COMPASS_ROOM_HEART" }, + { RAND_INF_DEKU_TREE_MQ_DEKU_BABA_HEART, "RAND_INF_DEKU_TREE_MQ_DEKU_BABA_HEART" }, + { RAND_INF_DEKU_TREE_MQ_LOBBY_HEART, "RAND_INF_DEKU_TREE_MQ_LOBBY_HEART" }, + { RAND_INF_DEKU_TREE_MQ_SLINGSHOT_ROOM_HEART, "RAND_INF_DEKU_TREE_MQ_SLINGSHOT_ROOM_HEART" }, + { RAND_INF_DEKU_TREE_MQ_BEFORE_BOSS_LEFT_HEART, "RAND_INF_DEKU_TREE_MQ_BEFORE_BOSS_LEFT_HEART" }, + { RAND_INF_DEKU_TREE_MQ_BEFORE_BOSS_MIDDLE_HEART, "RAND_INF_DEKU_TREE_MQ_BEFORE_BOSS_MIDDLE_HEART" }, + { RAND_INF_DEKU_TREE_MQ_BEFORE_BOSS_RIGHT_HEART, "RAND_INF_DEKU_TREE_MQ_BEFORE_BOSS_RIGHT_HEART" }, + { RAND_INF_DODONGOS_CAVERN_MQ_TORCH_PUZZLE_ROOM_HEART, + "RAND_INF_DODONGOS_CAVERN_MQ_TORCH_PUZZLE_ROOM_HEART" }, + { RAND_INF_JABU_JABUS_BELLY_MQ_LIFT_HEART_1, "RAND_INF_JABU_JABUS_BELLY_MQ_LIFT_HEART_1" }, + { RAND_INF_JABU_JABUS_BELLY_MQ_LIFT_HEART_2, "RAND_INF_JABU_JABUS_BELLY_MQ_LIFT_HEART_2" }, + { RAND_INF_FOREST_TEMPLE_MQ_COURTYARD_RIGHT_HEART, "RAND_INF_FOREST_TEMPLE_MQ_COURTYARD_RIGHT_HEART" }, + { RAND_INF_FOREST_TEMPLE_MQ_COURTYARD_MIDDLE_HEART, "RAND_INF_FOREST_TEMPLE_MQ_COURTYARD_MIDDLE_HEART" }, + { RAND_INF_FOREST_TEMPLE_MQ_COURTYARD_LEFT_HEART, "RAND_INF_FOREST_TEMPLE_MQ_COURTYARD_LEFT_HEART" }, + { RAND_INF_FOREST_TEMPLE_WELL_MQ_WEST_HEART, "RAND_INF_FOREST_TEMPLE_WELL_MQ_WEST_HEART" }, + { RAND_INF_FOREST_TEMPLE_WELL_MQ_MIDDLE_HEART, "RAND_INF_FOREST_TEMPLE_WELL_MQ_MIDDLE_HEART" }, + { RAND_INF_FOREST_TEMPLE_WELL_MQ_EAST_HEART, "RAND_INF_FOREST_TEMPLE_WELL_MQ_EAST_HEART" }, + { RAND_INF_FIRE_TEMPLE_MQ_FIRE_PILLAR_LEFT_HEART, "RAND_INF_FIRE_TEMPLE_MQ_FIRE_PILLAR_LEFT_HEART" }, + { RAND_INF_FIRE_TEMPLE_MQ_FIRE_PILLAR_RIGHT_HEART, "RAND_INF_FIRE_TEMPLE_MQ_FIRE_PILLAR_RIGHT_HEART" }, + { RAND_INF_FIRE_TEMPLE_MQ_FIRE_PILLAR_LOWER_HEART, "RAND_INF_FIRE_TEMPLE_MQ_FIRE_PILLAR_LOWER_HEART" }, + { RAND_INF_SHADOW_TEMPLE_MQ_INVISIBLE_BLADES_LEFT_HEART, + "RAND_INF_SHADOW_TEMPLE_MQ_INVISIBLE_BLADES_LEFT_HEART" }, + { RAND_INF_SHADOW_TEMPLE_MQ_INVISIBLE_BLADES_RIGHT_HEART, + "RAND_INF_SHADOW_TEMPLE_MQ_INVISIBLE_BLADES_RIGHT_HEART" }, + { RAND_INF_SHADOW_TEMPLE_MQ_SCARECROW_NORTH_HEART, "RAND_INF_SHADOW_TEMPLE_MQ_SCARECROW_NORTH_HEART" }, + { RAND_INF_SHADOW_TEMPLE_MQ_SCARECROW_SOUTH_HEART, "RAND_INF_SHADOW_TEMPLE_MQ_SCARECROW_SOUTH_HEART" }, + { RAND_INF_SHADOW_TEMPLE_MQ_AFTER_SHIP_UPPER_LEFT_HEART, + "RAND_INF_SHADOW_TEMPLE_MQ_AFTER_SHIP_UPPER_LEFT_HEART" }, + { RAND_INF_SHADOW_TEMPLE_MQ_AFTER_SHIP_UPPER_RIGHT_HEART, + "RAND_INF_SHADOW_TEMPLE_MQ_AFTER_SHIP_UPPER_RIGHT_HEART" }, + { RAND_INF_SHADOW_TEMPLE_MQ_AFTER_SHIP_LOWER_HEART, "RAND_INF_SHADOW_TEMPLE_MQ_AFTER_SHIP_LOWER_HEART" }, + { RAND_INF_BOTTOM_OF_THE_WELL_MQ_COFFIN_ROOM_FRONT_RIGHT_HEART, + "RAND_INF_BOTTOM_OF_THE_WELL_MQ_COFFIN_ROOM_FRONT_RIGHT_HEART" }, + { RAND_INF_BOTTOM_OF_THE_WELL_MQ_BOMB_LEFT_HEART, "RAND_INF_BOTTOM_OF_THE_WELL_MQ_BOMB_LEFT_HEART" }, + { RAND_INF_BOTTOM_OF_THE_WELL_MQ_BOMB_RIGHT_HEART, "RAND_INF_BOTTOM_OF_THE_WELL_MQ_BOMB_RIGHT_HEART" }, + { RAND_INF_BOTTOM_OF_THE_WELL_MQ_COFFIN_ROOM_MIDDLE_LEFT_HEART, + "RAND_INF_BOTTOM_OF_THE_WELL_MQ_COFFIN_ROOM_MIDDLE_LEFT_HEART" }, + { RAND_INF_BOTTOM_OF_THE_WELL_MQ_BASEMENT_HALLWAY_FRONT_HEART, + "RAND_INF_BOTTOM_OF_THE_WELL_MQ_BASEMENT_HALLWAY_FRONT_HEART" }, + { RAND_INF_BOTTOM_OF_THE_WELL_MQ_BASEMENT_HALLWAY_LEFT_HEART, + "RAND_INF_BOTTOM_OF_THE_WELL_MQ_BASEMENT_HALLWAY_LEFT_HEART" }, + { RAND_INF_BOTTOM_OF_THE_WELL_MQ_BASEMENT_HALLWAY_RIGHT_HEART, + "RAND_INF_BOTTOM_OF_THE_WELL_MQ_BASEMENT_HALLWAY_RIGHT_HEART" }, + { RAND_INF_GANONS_CASTLE_MQ_WATER_TRIAL_HEART, "RAND_INF_GANONS_CASTLE_MQ_WATER_TRIAL_HEART" }, + { RAND_INF_GANONS_CASTLE_MQ_LIGHT_TRIAL_RIGHT_HEART, "RAND_INF_GANONS_CASTLE_MQ_LIGHT_TRIAL_RIGHT_HEART" }, + { RAND_INF_GANONS_CASTLE_MQ_LIGHT_TRIAL_LEFT_HEART, "RAND_INF_GANONS_CASTLE_MQ_LIGHT_TRIAL_LEFT_HEART" }, - { RAND_INF_ZR_BEAN_SPROUT_FAIRY_1, "RAND_INF_ZR_BEAN_SPROUT_FAIRY_1" }, - { RAND_INF_ZR_BEAN_SPROUT_FAIRY_2, "RAND_INF_ZR_BEAN_SPROUT_FAIRY_2" }, - { RAND_INF_ZR_BEAN_SPROUT_FAIRY_3, "RAND_INF_ZR_BEAN_SPROUT_FAIRY_3" }, - { RAND_INF_KF_BEAN_SPROUT_FAIRY_1, "RAND_INF_KF_BEAN_SPROUT_FAIRY_1" }, - { RAND_INF_KF_BEAN_SPROUT_FAIRY_2, "RAND_INF_KF_BEAN_SPROUT_FAIRY_2" }, - { RAND_INF_KF_BEAN_SPROUT_FAIRY_3, "RAND_INF_KF_BEAN_SPROUT_FAIRY_3" }, - { RAND_INF_LW_BEAN_SPROUT_NEAR_BRIDGE_FAIRY_1, "RAND_INF_LW_BEAN_SPROUT_NEAR_BRIDGE_FAIRY_1" }, - { RAND_INF_LW_BEAN_SPROUT_NEAR_BRIDGE_FAIRY_2, "RAND_INF_LW_BEAN_SPROUT_NEAR_BRIDGE_FAIRY_2" }, - { RAND_INF_LW_BEAN_SPROUT_NEAR_BRIDGE_FAIRY_3, "RAND_INF_LW_BEAN_SPROUT_NEAR_BRIDGE_FAIRY_3" }, - { RAND_INF_LW_BEAN_SPROUT_NEAR_THEATER_FAIRY_1, "RAND_INF_LW_BEAN_SPROUT_NEAR_THEATER_FAIRY_1" }, - { RAND_INF_LW_BEAN_SPROUT_NEAR_THEATER_FAIRY_2, "RAND_INF_LW_BEAN_SPROUT_NEAR_THEATER_FAIRY_2" }, - { RAND_INF_LW_BEAN_SPROUT_NEAR_THEATER_FAIRY_3, "RAND_INF_LW_BEAN_SPROUT_NEAR_THEATER_FAIRY_3" }, - { RAND_INF_LH_BEAN_SPROUT_FAIRY_1, "RAND_INF_LH_BEAN_SPROUT_FAIRY_1" }, - { RAND_INF_LH_BEAN_SPROUT_FAIRY_2, "RAND_INF_LH_BEAN_SPROUT_FAIRY_2" }, - { RAND_INF_LH_BEAN_SPROUT_FAIRY_3, "RAND_INF_LH_BEAN_SPROUT_FAIRY_3" }, - { RAND_INF_GV_BEAN_SPROUT_FAIRY_1, "RAND_INF_GV_BEAN_SPROUT_FAIRY_1" }, - { RAND_INF_GV_BEAN_SPROUT_FAIRY_2, "RAND_INF_GV_BEAN_SPROUT_FAIRY_2" }, - { RAND_INF_GV_BEAN_SPROUT_FAIRY_3, "RAND_INF_GV_BEAN_SPROUT_FAIRY_3" }, - { RAND_INF_COLOSSUS_BEAN_SPROUT_FAIRY_1, "RAND_INF_COLOSSUS_BEAN_SPROUT_FAIRY_1" }, - { RAND_INF_COLOSSUS_BEAN_SPROUT_FAIRY_2, "RAND_INF_COLOSSUS_BEAN_SPROUT_FAIRY_2" }, - { RAND_INF_COLOSSUS_BEAN_SPROUT_FAIRY_3, "RAND_INF_COLOSSUS_BEAN_SPROUT_FAIRY_3" }, - { RAND_INF_GRAVEYARD_BEAN_SPROUT_FAIRY_1, "RAND_INF_GRAVEYARD_BEAN_SPROUT_FAIRY_1" }, - { RAND_INF_GRAVEYARD_BEAN_SPROUT_FAIRY_2, "RAND_INF_GRAVEYARD_BEAN_SPROUT_FAIRY_2" }, - { RAND_INF_GRAVEYARD_BEAN_SPROUT_FAIRY_3, "RAND_INF_GRAVEYARD_BEAN_SPROUT_FAIRY_3" }, - { RAND_INF_DMC_BEAN_SPROUT_FAIRY_1, "RAND_INF_DMC_BEAN_SPROUT_FAIRY_1" }, - { RAND_INF_DMC_BEAN_SPROUT_FAIRY_2, "RAND_INF_DMC_BEAN_SPROUT_FAIRY_2" }, - { RAND_INF_DMC_BEAN_SPROUT_FAIRY_3, "RAND_INF_DMC_BEAN_SPROUT_FAIRY_3" }, - { RAND_INF_DMT_BEAN_SPROUT_FAIRY_1, "RAND_INF_DMT_BEAN_SPROUT_FAIRY_1" }, - { RAND_INF_DMT_BEAN_SPROUT_FAIRY_2, "RAND_INF_DMT_BEAN_SPROUT_FAIRY_2" }, - { RAND_INF_DMT_BEAN_SPROUT_FAIRY_3, "RAND_INF_DMT_BEAN_SPROUT_FAIRY_3" }, + { RAND_INF_SFM_FAIRY_GROTTO_FAIRY_1, "RAND_INF_SFM_FAIRY_GROTTO_FAIRY_1" }, + { RAND_INF_SFM_FAIRY_GROTTO_FAIRY_2, "RAND_INF_SFM_FAIRY_GROTTO_FAIRY_2" }, + { RAND_INF_SFM_FAIRY_GROTTO_FAIRY_3, "RAND_INF_SFM_FAIRY_GROTTO_FAIRY_3" }, + { RAND_INF_SFM_FAIRY_GROTTO_FAIRY_4, "RAND_INF_SFM_FAIRY_GROTTO_FAIRY_4" }, + { RAND_INF_SFM_FAIRY_GROTTO_FAIRY_5, "RAND_INF_SFM_FAIRY_GROTTO_FAIRY_5" }, + { RAND_INF_SFM_FAIRY_GROTTO_FAIRY_6, "RAND_INF_SFM_FAIRY_GROTTO_FAIRY_6" }, + { RAND_INF_SFM_FAIRY_GROTTO_FAIRY_7, "RAND_INF_SFM_FAIRY_GROTTO_FAIRY_7" }, + { RAND_INF_SFM_FAIRY_GROTTO_FAIRY_8, "RAND_INF_SFM_FAIRY_GROTTO_FAIRY_8" }, + { RAND_INF_ZR_FAIRY_GROTTO_FAIRY_1, "RAND_INF_ZR_FAIRY_GROTTO_FAIRY_1" }, + { RAND_INF_ZR_FAIRY_GROTTO_FAIRY_2, "RAND_INF_ZR_FAIRY_GROTTO_FAIRY_2" }, + { RAND_INF_ZR_FAIRY_GROTTO_FAIRY_3, "RAND_INF_ZR_FAIRY_GROTTO_FAIRY_3" }, + { RAND_INF_ZR_FAIRY_GROTTO_FAIRY_4, "RAND_INF_ZR_FAIRY_GROTTO_FAIRY_4" }, + { RAND_INF_ZR_FAIRY_GROTTO_FAIRY_5, "RAND_INF_ZR_FAIRY_GROTTO_FAIRY_5" }, + { RAND_INF_ZR_FAIRY_GROTTO_FAIRY_6, "RAND_INF_ZR_FAIRY_GROTTO_FAIRY_6" }, + { RAND_INF_ZR_FAIRY_GROTTO_FAIRY_7, "RAND_INF_ZR_FAIRY_GROTTO_FAIRY_7" }, + { RAND_INF_ZR_FAIRY_GROTTO_FAIRY_8, "RAND_INF_ZR_FAIRY_GROTTO_FAIRY_8" }, + { RAND_INF_HF_FAIRY_GROTTO_FAIRY_1, "RAND_INF_HF_FAIRY_GROTTO_FAIRY_1" }, + { RAND_INF_HF_FAIRY_GROTTO_FAIRY_2, "RAND_INF_HF_FAIRY_GROTTO_FAIRY_2" }, + { RAND_INF_HF_FAIRY_GROTTO_FAIRY_3, "RAND_INF_HF_FAIRY_GROTTO_FAIRY_3" }, + { RAND_INF_HF_FAIRY_GROTTO_FAIRY_4, "RAND_INF_HF_FAIRY_GROTTO_FAIRY_4" }, + { RAND_INF_HF_FAIRY_GROTTO_FAIRY_5, "RAND_INF_HF_FAIRY_GROTTO_FAIRY_5" }, + { RAND_INF_HF_FAIRY_GROTTO_FAIRY_6, "RAND_INF_HF_FAIRY_GROTTO_FAIRY_6" }, + { RAND_INF_HF_FAIRY_GROTTO_FAIRY_7, "RAND_INF_HF_FAIRY_GROTTO_FAIRY_7" }, + { RAND_INF_HF_FAIRY_GROTTO_FAIRY_8, "RAND_INF_HF_FAIRY_GROTTO_FAIRY_8" }, + { RAND_INF_ZD_FAIRY_GROTTO_FAIRY_1, "RAND_INF_ZD_FAIRY_GROTTO_FAIRY_1" }, + { RAND_INF_ZD_FAIRY_GROTTO_FAIRY_2, "RAND_INF_ZD_FAIRY_GROTTO_FAIRY_2" }, + { RAND_INF_ZD_FAIRY_GROTTO_FAIRY_3, "RAND_INF_ZD_FAIRY_GROTTO_FAIRY_3" }, + { RAND_INF_ZD_FAIRY_GROTTO_FAIRY_4, "RAND_INF_ZD_FAIRY_GROTTO_FAIRY_4" }, + { RAND_INF_ZD_FAIRY_GROTTO_FAIRY_5, "RAND_INF_ZD_FAIRY_GROTTO_FAIRY_5" }, + { RAND_INF_ZD_FAIRY_GROTTO_FAIRY_6, "RAND_INF_ZD_FAIRY_GROTTO_FAIRY_6" }, + { RAND_INF_ZD_FAIRY_GROTTO_FAIRY_7, "RAND_INF_ZD_FAIRY_GROTTO_FAIRY_7" }, + { RAND_INF_ZD_FAIRY_GROTTO_FAIRY_8, "RAND_INF_ZD_FAIRY_GROTTO_FAIRY_8" }, + { RAND_INF_GF_FAIRY_GROTTO_FAIRY_1, "RAND_INF_GF_FAIRY_GROTTO_FAIRY_1" }, + { RAND_INF_GF_FAIRY_GROTTO_FAIRY_2, "RAND_INF_GF_FAIRY_GROTTO_FAIRY_2" }, + { RAND_INF_GF_FAIRY_GROTTO_FAIRY_3, "RAND_INF_GF_FAIRY_GROTTO_FAIRY_3" }, + { RAND_INF_GF_FAIRY_GROTTO_FAIRY_4, "RAND_INF_GF_FAIRY_GROTTO_FAIRY_4" }, + { RAND_INF_GF_FAIRY_GROTTO_FAIRY_5, "RAND_INF_GF_FAIRY_GROTTO_FAIRY_5" }, + { RAND_INF_GF_FAIRY_GROTTO_FAIRY_6, "RAND_INF_GF_FAIRY_GROTTO_FAIRY_6" }, + { RAND_INF_GF_FAIRY_GROTTO_FAIRY_7, "RAND_INF_GF_FAIRY_GROTTO_FAIRY_7" }, + { RAND_INF_GF_FAIRY_GROTTO_FAIRY_8, "RAND_INF_GF_FAIRY_GROTTO_FAIRY_8" }, + { RAND_INF_GRAVEYARD_SHIELD_GRAVE_FAIRY_1, "RAND_INF_GRAVEYARD_SHIELD_GRAVE_FAIRY_1" }, + { RAND_INF_GRAVEYARD_SHIELD_GRAVE_FAIRY_2, "RAND_INF_GRAVEYARD_SHIELD_GRAVE_FAIRY_2" }, + { RAND_INF_GRAVEYARD_SHIELD_GRAVE_FAIRY_3, "RAND_INF_GRAVEYARD_SHIELD_GRAVE_FAIRY_3" }, + { RAND_INF_GRAVEYARD_SHIELD_GRAVE_FAIRY_4, "RAND_INF_GRAVEYARD_SHIELD_GRAVE_FAIRY_4" }, + { RAND_INF_GRAVEYARD_SHIELD_GRAVE_FAIRY_5, "RAND_INF_GRAVEYARD_SHIELD_GRAVE_FAIRY_5" }, + { RAND_INF_GRAVEYARD_SHIELD_GRAVE_FAIRY_6, "RAND_INF_GRAVEYARD_SHIELD_GRAVE_FAIRY_6" }, + { RAND_INF_GRAVEYARD_SHIELD_GRAVE_FAIRY_7, "RAND_INF_GRAVEYARD_SHIELD_GRAVE_FAIRY_7" }, + { RAND_INF_GRAVEYARD_SHIELD_GRAVE_FAIRY_8, "RAND_INF_GRAVEYARD_SHIELD_GRAVE_FAIRY_8" }, + { RAND_INF_GANONS_CASTLE_SCRUBS_FAIRY_1, "RAND_INF_GANONS_CASTLE_SCRUBS_FAIRY_1" }, + { RAND_INF_GANONS_CASTLE_SCRUBS_FAIRY_2, "RAND_INF_GANONS_CASTLE_SCRUBS_FAIRY_2" }, + { RAND_INF_GANONS_CASTLE_SCRUBS_FAIRY_3, "RAND_INF_GANONS_CASTLE_SCRUBS_FAIRY_3" }, + { RAND_INF_GANONS_CASTLE_SCRUBS_FAIRY_4, "RAND_INF_GANONS_CASTLE_SCRUBS_FAIRY_4" }, + { RAND_INF_GANONS_CASTLE_SCRUBS_FAIRY_5, "RAND_INF_GANONS_CASTLE_SCRUBS_FAIRY_5" }, + { RAND_INF_GANONS_CASTLE_SCRUBS_FAIRY_6, "RAND_INF_GANONS_CASTLE_SCRUBS_FAIRY_6" }, + { RAND_INF_GANONS_CASTLE_SCRUBS_FAIRY_7, "RAND_INF_GANONS_CASTLE_SCRUBS_FAIRY_7" }, + { RAND_INF_GANONS_CASTLE_SCRUBS_FAIRY_8, "RAND_INF_GANONS_CASTLE_SCRUBS_FAIRY_8" }, + { RAND_INF_GANONS_CASTLE_MQ_SCRUBS_FAIRY_1, "RAND_INF_GANONS_CASTLE_MQ_SCRUBS_FAIRY_1" }, + { RAND_INF_GANONS_CASTLE_MQ_SCRUBS_FAIRY_2, "RAND_INF_GANONS_CASTLE_MQ_SCRUBS_FAIRY_2" }, + { RAND_INF_GANONS_CASTLE_MQ_SCRUBS_FAIRY_3, "RAND_INF_GANONS_CASTLE_MQ_SCRUBS_FAIRY_3" }, + { RAND_INF_GANONS_CASTLE_MQ_SCRUBS_FAIRY_4, "RAND_INF_GANONS_CASTLE_MQ_SCRUBS_FAIRY_4" }, + { RAND_INF_GANONS_CASTLE_MQ_SCRUBS_FAIRY_5, "RAND_INF_GANONS_CASTLE_MQ_SCRUBS_FAIRY_5" }, + { RAND_INF_GANONS_CASTLE_MQ_SCRUBS_FAIRY_6, "RAND_INF_GANONS_CASTLE_MQ_SCRUBS_FAIRY_6" }, + { RAND_INF_GANONS_CASTLE_MQ_SCRUBS_FAIRY_7, "RAND_INF_GANONS_CASTLE_MQ_SCRUBS_FAIRY_7" }, + { RAND_INF_GANONS_CASTLE_MQ_SCRUBS_FAIRY_8, "RAND_INF_GANONS_CASTLE_MQ_SCRUBS_FAIRY_8" }, + { RAND_INF_COLOSSUS_OASIS_FAIRY_1, "RAND_INF_COLOSSUS_OASIS_FAIRY_1" }, + { RAND_INF_COLOSSUS_OASIS_FAIRY_2, "RAND_INF_COLOSSUS_OASIS_FAIRY_2" }, + { RAND_INF_COLOSSUS_OASIS_FAIRY_3, "RAND_INF_COLOSSUS_OASIS_FAIRY_3" }, + { RAND_INF_COLOSSUS_OASIS_FAIRY_4, "RAND_INF_COLOSSUS_OASIS_FAIRY_4" }, + { RAND_INF_COLOSSUS_OASIS_FAIRY_5, "RAND_INF_COLOSSUS_OASIS_FAIRY_5" }, + { RAND_INF_COLOSSUS_OASIS_FAIRY_6, "RAND_INF_COLOSSUS_OASIS_FAIRY_6" }, + { RAND_INF_COLOSSUS_OASIS_FAIRY_7, "RAND_INF_COLOSSUS_OASIS_FAIRY_7" }, + { RAND_INF_COLOSSUS_OASIS_FAIRY_8, "RAND_INF_COLOSSUS_OASIS_FAIRY_8" }, - { RAND_INF_TOT_LEFTMOST_GOSSIP_STONE_FAIRY, "RAND_INF_TOT_LEFTMOST_GOSSIP_STONE_FAIRY" }, - { RAND_INF_TOT_LEFTMOST_GOSSIP_STONE_FAIRY_BIG, "RAND_INF_TOT_LEFTMOST_GOSSIP_STONE_FAIRY_BIG" }, - { RAND_INF_TOT_LEFT_CENTER_GOSSIP_STONE_FAIRY, "RAND_INF_TOT_LEFT_CENTER_GOSSIP_STONE_FAIRY" }, - { RAND_INF_TOT_LEFT_CENTER_GOSSIP_STONE_FAIRY_BIG, "RAND_INF_TOT_LEFT_CENTER_GOSSIP_STONE_FAIRY_BIG" }, - { RAND_INF_TOT_RIGHT_CENTER_GOSSIP_STONE_FAIRY, "RAND_INF_TOT_RIGHT_CENTER_GOSSIP_STONE_FAIRY" }, - { RAND_INF_TOT_RIGHT_CENTER_GOSSIP_STONE_FAIRY_BIG, "RAND_INF_TOT_RIGHT_CENTER_GOSSIP_STONE_FAIRY_BIG" }, - { RAND_INF_TOT_RIGHTMOST_GOSSIP_STONE_FAIRY, "RAND_INF_TOT_RIGHTMOST_GOSSIP_STONE_FAIRY" }, - { RAND_INF_TOT_RIGHTMOST_GOSSIP_STONE_FAIRY_BIG, "RAND_INF_TOT_RIGHTMOST_GOSSIP_STONE_FAIRY_BIG" }, - { RAND_INF_DMC_GOSSIP_STONE_FAIRY, "RAND_INF_DMC_GOSSIP_STONE_FAIRY" }, - { RAND_INF_DMC_GOSSIP_STONE_FAIRY_BIG, "RAND_INF_DMC_GOSSIP_STONE_FAIRY_BIG" }, - { RAND_INF_DMT_GOSSIP_STONE_FAIRY, "RAND_INF_DMT_GOSSIP_STONE_FAIRY" }, - { RAND_INF_DMT_GOSSIP_STONE_FAIRY_BIG, "RAND_INF_DMT_GOSSIP_STONE_FAIRY_BIG" }, - { RAND_INF_COLOSSUS_GOSSIP_STONE_FAIRY, "RAND_INF_COLOSSUS_GOSSIP_STONE_FAIRY" }, - { RAND_INF_COLOSSUS_GOSSIP_STONE_FAIRY_BIG, "RAND_INF_COLOSSUS_GOSSIP_STONE_FAIRY_BIG" }, - { RAND_INF_DODONGOS_CAVERN_GOSSIP_STONE_FAIRY, "RAND_INF_DODONGOS_CAVERN_GOSSIP_STONE_FAIRY" }, - { RAND_INF_DODONGOS_CAVERN_GOSSIP_STONE_FAIRY_BIG, "RAND_INF_DODONGOS_CAVERN_GOSSIP_STONE_FAIRY_BIG" }, - { RAND_INF_DODONGOS_CAVERN_MQ_GOSSIP_STONE_FAIRY, "RAND_INF_DODONGOS_CAVERN_MQ_GOSSIP_STONE_FAIRY" }, - { RAND_INF_DODONGOS_CAVERN_MQ_GOSSIP_STONE_FAIRY_BIG, "RAND_INF_DODONGOS_CAVERN_MQ_GOSSIP_STONE_FAIRY_BIG" }, - { RAND_INF_GV_GOSSIP_STONE_FAIRY, "RAND_INF_GV_GOSSIP_STONE_FAIRY" }, - { RAND_INF_GV_GOSSIP_STONE_FAIRY_BIG, "RAND_INF_GV_GOSSIP_STONE_FAIRY_BIG" }, - { RAND_INF_GC_MAZE_GOSSIP_STONE_FAIRY, "RAND_INF_GC_MAZE_GOSSIP_STONE_FAIRY" }, - { RAND_INF_GC_MAZE_GOSSIP_STONE_FAIRY_BIG, "RAND_INF_GC_MAZE_GOSSIP_STONE_FAIRY_BIG" }, - { RAND_INF_GC_MEDIGORON_GOSSIP_STONE_FAIRY, "RAND_INF_GC_MEDIGORON_GOSSIP_STONE_FAIRY" }, - { RAND_INF_GC_MEDIGORON_GOSSIP_STONE_FAIRY_BIG, "RAND_INF_GC_MEDIGORON_GOSSIP_STONE_FAIRY_BIG" }, - { RAND_INF_GRAVEYARD_GOSSIP_STONE_FAIRY, "RAND_INF_GRAVEYARD_GOSSIP_STONE_FAIRY" }, - { RAND_INF_GRAVEYARD_GOSSIP_STONE_FAIRY_BIG, "RAND_INF_GRAVEYARD_GOSSIP_STONE_FAIRY_BIG" }, - { RAND_INF_HC_MALON_GOSSIP_STONE_FAIRY, "RAND_INF_HC_MALON_GOSSIP_STONE_FAIRY" }, - { RAND_INF_HC_MALON_GOSSIP_STONE_FAIRY_BIG, "RAND_INF_HC_MALON_GOSSIP_STONE_FAIRY_BIG" }, - { RAND_INF_HC_ROCK_WALL_GOSSIP_STONE_FAIRY, "RAND_INF_HC_ROCK_WALL_GOSSIP_STONE_FAIRY" }, - { RAND_INF_HC_ROCK_WALL_GOSSIP_STONE_FAIRY_BIG, "RAND_INF_HC_ROCK_WALL_GOSSIP_STONE_FAIRY_BIG" }, - { RAND_INF_HC_STORMS_GROTTO_GOSSIP_STONE_FAIRY, "RAND_INF_HC_STORMS_GROTTO_GOSSIP_STONE_FAIRY" }, - { RAND_INF_HC_STORMS_GROTTO_GOSSIP_STONE_FAIRY_BIG, "RAND_INF_HC_STORMS_GROTTO_GOSSIP_STONE_FAIRY_BIG" }, - { RAND_INF_KF_DEKU_TREE_LEFT_GOSSIP_STONE_FAIRY, "RAND_INF_KF_DEKU_TREE_LEFT_GOSSIP_STONE_FAIRY" }, - { RAND_INF_KF_DEKU_TREE_LEFT_GOSSIP_STONE_FAIRY_BIG, "RAND_INF_KF_DEKU_TREE_LEFT_GOSSIP_STONE_FAIRY_BIG" }, - { RAND_INF_KF_DEKU_TREE_RIGHT_GOSSIP_STONE_FAIRY, "RAND_INF_KF_DEKU_TREE_RIGHT_GOSSIP_STONE_FAIRY" }, - { RAND_INF_KF_DEKU_TREE_RIGHT_GOSSIP_STONE_FAIRY_BIG, "RAND_INF_KF_DEKU_TREE_RIGHT_GOSSIP_STONE_FAIRY_BIG" }, - { RAND_INF_KF_GOSSIP_STONE_FAIRY, "RAND_INF_KF_GOSSIP_STONE_FAIRY" }, - { RAND_INF_KF_GOSSIP_STONE_FAIRY_BIG, "RAND_INF_KF_GOSSIP_STONE_FAIRY_BIG" }, - { RAND_INF_KF_STORMS_GROTTO_GOSSIP_STONE_FAIRY, "RAND_INF_KF_STORMS_GROTTO_GOSSIP_STONE_FAIRY" }, - { RAND_INF_KF_STORMS_GROTTO_GOSSIP_STONE_FAIRY_BIG, "RAND_INF_KF_STORMS_GROTTO_GOSSIP_STONE_FAIRY_BIG" }, - { RAND_INF_LH_LAB_GOSSIP_STONE_FAIRY, "RAND_INF_LH_LAB_GOSSIP_STONE_FAIRY" }, - { RAND_INF_LH_LAB_GOSSIP_STONE_FAIRY_BIG, "RAND_INF_LH_LAB_GOSSIP_STONE_FAIRY_BIG" }, - { RAND_INF_LH_SOUTHEAST_GOSSIP_STONE_FAIRY, "RAND_INF_LH_SOUTHEAST_GOSSIP_STONE_FAIRY" }, - { RAND_INF_LH_SOUTHEAST_GOSSIP_STONE_FAIRY_BIG, "RAND_INF_LH_SOUTHEAST_GOSSIP_STONE_FAIRY_BIG" }, - { RAND_INF_LH_SOUTHWEST_GOSSIP_STONE_FAIRY, "RAND_INF_LH_SOUTHWEST_GOSSIP_STONE_FAIRY" }, - { RAND_INF_LH_SOUTHWEST_GOSSIP_STONE_FAIRY_BIG, "RAND_INF_LH_SOUTHWEST_GOSSIP_STONE_FAIRY_BIG" }, - { RAND_INF_LW_GOSSIP_STONE_FAIRY, "RAND_INF_LW_GOSSIP_STONE_FAIRY" }, - { RAND_INF_LW_GOSSIP_STONE_FAIRY_BIG, "RAND_INF_LW_GOSSIP_STONE_FAIRY_BIG" }, - { RAND_INF_SFM_MAZE_LOWER_GOSSIP_STONE_FAIRY, "RAND_INF_SFM_MAZE_LOWER_GOSSIP_STONE_FAIRY" }, - { RAND_INF_SFM_MAZE_LOWER_GOSSIP_STONE_FAIRY_BIG, "RAND_INF_SFM_MAZE_LOWER_GOSSIP_STONE_FAIRY_BIG" }, - { RAND_INF_SFM_MAZE_UPPER_GOSSIP_STONE_FAIRY, "RAND_INF_SFM_MAZE_UPPER_GOSSIP_STONE_FAIRY" }, - { RAND_INF_SFM_MAZE_UPPER_GOSSIP_STONE_FAIRY_BIG, "RAND_INF_SFM_MAZE_UPPER_GOSSIP_STONE_FAIRY_BIG" }, - { RAND_INF_SFM_SARIA_GOSSIP_STONE_FAIRY, "RAND_INF_SFM_SARIA_GOSSIP_STONE_FAIRY" }, - { RAND_INF_SFM_SARIA_GOSSIP_STONE_FAIRY_BIG, "RAND_INF_SFM_SARIA_GOSSIP_STONE_FAIRY_BIG" }, - { RAND_INF_ZD_GOSSIP_STONE_FAIRY, "RAND_INF_ZD_GOSSIP_STONE_FAIRY" }, - { RAND_INF_ZD_GOSSIP_STONE_FAIRY_BIG, "RAND_INF_ZD_GOSSIP_STONE_FAIRY_BIG" }, - { RAND_INF_ZF_FAIRY_GOSSIP_STONE_FAIRY, "RAND_INF_ZF_FAIRY_GOSSIP_STONE_FAIRY" }, - { RAND_INF_ZF_FAIRY_GOSSIP_STONE_FAIRY_BIG, "RAND_INF_ZF_FAIRY_GOSSIP_STONE_FAIRY_BIG" }, - { RAND_INF_ZF_JABU_GOSSIP_STONE_FAIRY, "RAND_INF_ZF_JABU_GOSSIP_STONE_FAIRY" }, - { RAND_INF_ZF_JABU_GOSSIP_STONE_FAIRY_BIG, "RAND_INF_ZF_JABU_GOSSIP_STONE_FAIRY_BIG" }, - { RAND_INF_ZR_NEAR_GROTTOS_GOSSIP_STONE_FAIRY, "RAND_INF_ZR_NEAR_GROTTOS_GOSSIP_STONE_FAIRY" }, - { RAND_INF_ZR_NEAR_GROTTOS_GOSSIP_STONE_FAIRY_BIG, "RAND_INF_ZR_NEAR_GROTTOS_GOSSIP_STONE_FAIRY_BIG" }, - { RAND_INF_ZR_NEAR_DOMAIN_GOSSIP_STONE_FAIRY, "RAND_INF_ZR_NEAR_DOMAIN_GOSSIP_STONE_FAIRY" }, - { RAND_INF_ZR_NEAR_DOMAIN_GOSSIP_STONE_FAIRY_BIG, "RAND_INF_ZR_NEAR_DOMAIN_GOSSIP_STONE_FAIRY_BIG" }, - { RAND_INF_HF_COW_GROTTO_GOSSIP_STONE_FAIRY, "RAND_INF_HF_COW_GROTTO_GOSSIP_STONE_FAIRY" }, - { RAND_INF_HF_COW_GROTTO_GOSSIP_STONE_FAIRY_BIG, "RAND_INF_HF_COW_GROTTO_GOSSIP_STONE_FAIRY_BIG" }, - { RAND_INF_HF_NEAR_MARKET_GROTTO_GOSSIP_STONE_FAIRY, "RAND_INF_HF_NEAR_MARKET_GROTTO_GOSSIP_STONE_FAIRY" }, - { RAND_INF_HF_NEAR_MARKET_GROTTO_GOSSIP_STONE_FAIRY_BIG, "RAND_INF_HF_NEAR_MARKET_GROTTO_GOSSIP_STONE_FAIRY_BIG" }, - { RAND_INF_HF_SOUTHEAST_GROTTO_GOSSIP_STONE_FAIRY, "RAND_INF_HF_SOUTHEAST_GROTTO_GOSSIP_STONE_FAIRY" }, - { RAND_INF_HF_SOUTHEAST_GROTTO_GOSSIP_STONE_FAIRY_BIG, "RAND_INF_HF_SOUTHEAST_GROTTO_GOSSIP_STONE_FAIRY_BIG" }, - { RAND_INF_HF_OPEN_GROTTO_GOSSIP_STONE_FAIRY, "RAND_INF_HF_OPEN_GROTTO_GOSSIP_STONE_FAIRY" }, - { RAND_INF_HF_OPEN_GROTTO_GOSSIP_STONE_FAIRY_BIG, "RAND_INF_HF_OPEN_GROTTO_GOSSIP_STONE_FAIRY_BIG" }, - { RAND_INF_KAK_OPEN_GROTTO_GOSSIP_STONE_FAIRY, "RAND_INF_KAK_OPEN_GROTTO_GOSSIP_STONE_FAIRY" }, - { RAND_INF_KAK_OPEN_GROTTO_GOSSIP_STONE_FAIRY_BIG, "RAND_INF_KAK_OPEN_GROTTO_GOSSIP_STONE_FAIRY_BIG" }, - { RAND_INF_ZR_OPEN_GROTTO_GOSSIP_STONE_FAIRY, "RAND_INF_ZR_OPEN_GROTTO_GOSSIP_STONE_FAIRY" }, - { RAND_INF_ZR_OPEN_GROTTO_GOSSIP_STONE_FAIRY_BIG, "RAND_INF_ZR_OPEN_GROTTO_GOSSIP_STONE_FAIRY_BIG" }, - { RAND_INF_LW_NEAR_SHORTCUTS_GROTTO_GOSSIP_STONE_FAIRY, "RAND_INF_LW_NEAR_SHORTCUTS_GROTTO_GOSSIP_STONE_FAIRY" }, - { RAND_INF_LW_NEAR_SHORTCUTS_GROTTO_GOSSIP_STONE_FAIRY_BIG, "RAND_INF_LW_NEAR_SHORTCUTS_GROTTO_GOSSIP_STONE_FAIRY_BIG" }, - { RAND_INF_DMT_STORMS_GROTTO_GOSSIP_STONE_FAIRY, "RAND_INF_DMT_STORMS_GROTTO_GOSSIP_STONE_FAIRY" }, - { RAND_INF_DMT_STORMS_GROTTO_GOSSIP_STONE_FAIRY_BIG, "RAND_INF_DMT_STORMS_GROTTO_GOSSIP_STONE_FAIRY_BIG" }, - { RAND_INF_DMC_UPPER_GROTTO_GOSSIP_STONE_FAIRY, "RAND_INF_DMC_UPPER_GROTTO_GOSSIP_STONE_FAIRY" }, - { RAND_INF_DMC_UPPER_GROTTO_GOSSIP_STONE_FAIRY_BIG, "RAND_INF_DMC_UPPER_GROTTO_GOSSIP_STONE_FAIRY_BIG" }, - - { RAND_INF_LH_ISLAND_SUN_FAIRY, "RAND_INF_LH_ISLAND_SUN_FAIRY" }, - { RAND_INF_HF_POND_STORMS_FAIRY, "RAND_INF_HF_POND_STORMS_FAIRY" }, - { RAND_INF_DMT_FLAG_SUN_FAIRY, "RAND_INF_DMT_FLAG_SUN_FAIRY" }, - { RAND_INF_LW_SHORTCUT_STORMS_FAIRY, "RAND_INF_LW_SHORTCUT_STORMS_FAIRY" }, - { RAND_INF_GF_KITCHEN_SUN_FAIRY, "RAND_INF_GF_KITCHEN_SUN_FAIRY" }, - { RAND_INF_SPIRIT_TEMPLE_BOULDER_ROOM_SUN_FAIRY, "RAND_INF_SPIRIT_TEMPLE_BOULDER_ROOM_SUN_FAIRY" }, - { RAND_INF_SPIRIT_TEMPLE_ARMOS_ROOM_SUN_FAIRY, "RAND_INF_SPIRIT_TEMPLE_ARMOS_ROOM_SUN_FAIRY" }, - { RAND_INF_SHADOW_TEMPLE_BEAMOS_STORM_FAIRY, "RAND_INF_SHADOW_TEMPLE_BEAMOS_STORM_FAIRY" }, - { RAND_INF_SHADOW_TEMPLE_PIT_STORM_FAIRY, "RAND_INF_SHADOW_TEMPLE_PIT_STORM_FAIRY" }, - { RAND_INF_SHADOW_TEMPLE_WIND_HINT_SUN_FAIRY, "RAND_INF_SHADOW_TEMPLE_WIND_HINT_SUN_FAIRY" }, - { RAND_INF_BOTTOM_OF_THE_WELL_BASEMENT_SUN_FAIRY, "RAND_INF_BOTTOM_OF_THE_WELL_BASEMENT_SUN_FAIRY" }, - { RAND_INF_ICE_CAVERN_ENTRANCE_STORMS_FAIRY, "RAND_INF_ICE_CAVERN_ENTRANCE_STORMS_FAIRY" }, - { RAND_INF_GERUDO_TRAINING_GROUND_ENTRANCE_STORMS_FAIRY, "RAND_INF_GERUDO_TRAINING_GROUND_ENTRANCE_STORMS_FAIRY" }, - { RAND_INF_GANONS_CASTLE_SPIRIT_TRIAL_SUN_FAIRY, "RAND_INF_GANONS_CASTLE_SPIRIT_TRIAL_SUN_FAIRY" }, - { RAND_INF_FIRE_TEMPLE_MQ_LOOP_STALFOS_SUN_FAIRY, "RAND_INF_FIRE_TEMPLE_MQ_LOOP_STALFOS_SUN_FAIRY" }, - { RAND_INF_FIRE_TEMPLE_MQ_LOOP_KNUCKLE_SUN_FAIRY, "RAND_INF_FIRE_TEMPLE_MQ_LOOP_KNUCKLE_SUN_FAIRY" }, - { RAND_INF_WATER_TEMPLE_MQ_DARK_LINK_PILAR_SUN_FAIRY, "RAND_INF_WATER_TEMPLE_MQ_DARK_LINK_PILAR_SUN_FAIRY" }, - { RAND_INF_WATER_TEMPLE_MQ_DARK_LINK_LEFT_STORM_FAIRY, "RAND_INF_WATER_TEMPLE_MQ_DARK_LINK_LEFT_STORM_FAIRY" }, - { RAND_INF_WATER_TEMPLE_MQ_DARK_LINK_RIGHT_SUN_FAIRY, "RAND_INF_WATER_TEMPLE_MQ_DARK_LINK_RIGHT_SUN_FAIRY" }, - { RAND_INF_SPIRIT_TEMPLE_MQ_DINALFOS_ROOM_SUN_FAIRY, "RAND_INF_SPIRIT_TEMPLE_MQ_DINALFOS_ROOM_SUN_FAIRY" }, - { RAND_INF_SHADOW_TEMPLE_MQ_BEAMOS_STORM_FAIRY, "RAND_INF_SHADOW_TEMPLE_MQ_BEAMOS_STORM_FAIRY" }, - { RAND_INF_SHADOW_TEMPLE_MQ_PIT_STORM_FAIRY, "RAND_INF_SHADOW_TEMPLE_MQ_PIT_STORM_FAIRY" }, - { RAND_INF_SHADOW_TEMPLE_MQ_WIND_HINT_SUN_FAIRY, "RAND_INF_SHADOW_TEMPLE_MQ_WIND_HINT_SUN_FAIRY" }, - { RAND_INF_BOTTOM_OF_THE_WELL_MQ_CELL_SUN_FAIRY, "RAND_INF_BOTTOM_OF_THE_WELL_MQ_CELL_SUN_FAIRY" }, - { RAND_INF_BOTTOM_OF_THE_WELL_MQ_BASEMENT_SUN_FAIRY, "RAND_INF_BOTTOM_OF_THE_WELL_MQ_BASEMENT_SUN_FAIRY" }, + { RAND_INF_ZR_BEAN_SPROUT_FAIRY_1, "RAND_INF_ZR_BEAN_SPROUT_FAIRY_1" }, + { RAND_INF_ZR_BEAN_SPROUT_FAIRY_2, "RAND_INF_ZR_BEAN_SPROUT_FAIRY_2" }, + { RAND_INF_ZR_BEAN_SPROUT_FAIRY_3, "RAND_INF_ZR_BEAN_SPROUT_FAIRY_3" }, + { RAND_INF_KF_BEAN_SPROUT_FAIRY_1, "RAND_INF_KF_BEAN_SPROUT_FAIRY_1" }, + { RAND_INF_KF_BEAN_SPROUT_FAIRY_2, "RAND_INF_KF_BEAN_SPROUT_FAIRY_2" }, + { RAND_INF_KF_BEAN_SPROUT_FAIRY_3, "RAND_INF_KF_BEAN_SPROUT_FAIRY_3" }, + { RAND_INF_LW_BEAN_SPROUT_NEAR_BRIDGE_FAIRY_1, "RAND_INF_LW_BEAN_SPROUT_NEAR_BRIDGE_FAIRY_1" }, + { RAND_INF_LW_BEAN_SPROUT_NEAR_BRIDGE_FAIRY_2, "RAND_INF_LW_BEAN_SPROUT_NEAR_BRIDGE_FAIRY_2" }, + { RAND_INF_LW_BEAN_SPROUT_NEAR_BRIDGE_FAIRY_3, "RAND_INF_LW_BEAN_SPROUT_NEAR_BRIDGE_FAIRY_3" }, + { RAND_INF_LW_BEAN_SPROUT_NEAR_THEATER_FAIRY_1, "RAND_INF_LW_BEAN_SPROUT_NEAR_THEATER_FAIRY_1" }, + { RAND_INF_LW_BEAN_SPROUT_NEAR_THEATER_FAIRY_2, "RAND_INF_LW_BEAN_SPROUT_NEAR_THEATER_FAIRY_2" }, + { RAND_INF_LW_BEAN_SPROUT_NEAR_THEATER_FAIRY_3, "RAND_INF_LW_BEAN_SPROUT_NEAR_THEATER_FAIRY_3" }, + { RAND_INF_LH_BEAN_SPROUT_FAIRY_1, "RAND_INF_LH_BEAN_SPROUT_FAIRY_1" }, + { RAND_INF_LH_BEAN_SPROUT_FAIRY_2, "RAND_INF_LH_BEAN_SPROUT_FAIRY_2" }, + { RAND_INF_LH_BEAN_SPROUT_FAIRY_3, "RAND_INF_LH_BEAN_SPROUT_FAIRY_3" }, + { RAND_INF_GV_BEAN_SPROUT_FAIRY_1, "RAND_INF_GV_BEAN_SPROUT_FAIRY_1" }, + { RAND_INF_GV_BEAN_SPROUT_FAIRY_2, "RAND_INF_GV_BEAN_SPROUT_FAIRY_2" }, + { RAND_INF_GV_BEAN_SPROUT_FAIRY_3, "RAND_INF_GV_BEAN_SPROUT_FAIRY_3" }, + { RAND_INF_COLOSSUS_BEAN_SPROUT_FAIRY_1, "RAND_INF_COLOSSUS_BEAN_SPROUT_FAIRY_1" }, + { RAND_INF_COLOSSUS_BEAN_SPROUT_FAIRY_2, "RAND_INF_COLOSSUS_BEAN_SPROUT_FAIRY_2" }, + { RAND_INF_COLOSSUS_BEAN_SPROUT_FAIRY_3, "RAND_INF_COLOSSUS_BEAN_SPROUT_FAIRY_3" }, + { RAND_INF_GRAVEYARD_BEAN_SPROUT_FAIRY_1, "RAND_INF_GRAVEYARD_BEAN_SPROUT_FAIRY_1" }, + { RAND_INF_GRAVEYARD_BEAN_SPROUT_FAIRY_2, "RAND_INF_GRAVEYARD_BEAN_SPROUT_FAIRY_2" }, + { RAND_INF_GRAVEYARD_BEAN_SPROUT_FAIRY_3, "RAND_INF_GRAVEYARD_BEAN_SPROUT_FAIRY_3" }, + { RAND_INF_DMC_BEAN_SPROUT_FAIRY_1, "RAND_INF_DMC_BEAN_SPROUT_FAIRY_1" }, + { RAND_INF_DMC_BEAN_SPROUT_FAIRY_2, "RAND_INF_DMC_BEAN_SPROUT_FAIRY_2" }, + { RAND_INF_DMC_BEAN_SPROUT_FAIRY_3, "RAND_INF_DMC_BEAN_SPROUT_FAIRY_3" }, + { RAND_INF_DMT_BEAN_SPROUT_FAIRY_1, "RAND_INF_DMT_BEAN_SPROUT_FAIRY_1" }, + { RAND_INF_DMT_BEAN_SPROUT_FAIRY_2, "RAND_INF_DMT_BEAN_SPROUT_FAIRY_2" }, + { RAND_INF_DMT_BEAN_SPROUT_FAIRY_3, "RAND_INF_DMT_BEAN_SPROUT_FAIRY_3" }, - { RAND_INF_GUARD_HOUSE_UNLOCKED, "RAND_INF_GUARD_HOUSE_UNLOCKED" }, - { RAND_INF_GUARD_HOUSE_KEY_OBTAINED, "RAND_INF_GUARD_HOUSE_KEY_OBTAINED" }, - { RAND_INF_MARKET_BAZAAR_UNLOCKED, "RAND_INF_MARKET_BAZAAR_UNLOCKED" }, - { RAND_INF_MARKET_BAZAAR_KEY_OBTAINED, "RAND_INF_MARKET_BAZAAR_KEY_OBTAINED" }, - { RAND_INF_MARKET_POTION_SHOP_UNLOCKED, "RAND_INF_MARKET_POTION_SHOP_UNLOCKED" }, - { RAND_INF_MARKET_POTION_SHOP_KEY_OBTAINED, "RAND_INF_MARKET_POTION_SHOP_KEY_OBTAINED" }, - { RAND_INF_MASK_SHOP_UNLOCKED, "RAND_INF_MASK_SHOP_UNLOCKED" }, - { RAND_INF_MASK_SHOP_KEY_OBTAINED, "RAND_INF_MASK_SHOP_KEY_OBTAINED" }, - { RAND_INF_MARKET_SHOOTING_GALLERY_UNLOCKED, "RAND_INF_MARKET_SHOOTING_GALLERY_UNLOCKED" }, - { RAND_INF_MARKET_SHOOTING_GALLERY_KEY_OBTAINED, "RAND_INF_MARKET_SHOOTING_GALLERY_KEY_OBTAINED" }, - { RAND_INF_BOMBCHU_BOWLING_UNLOCKED, "RAND_INF_BOMBCHU_BOWLING_UNLOCKED" }, - { RAND_INF_BOMBCHU_BOWLING_KEY_OBTAINED, "RAND_INF_BOMBCHU_BOWLING_KEY_OBTAINED" }, - { RAND_INF_TREASURE_CHEST_GAME_BUILDING_UNLOCKED, "RAND_INF_TREASURE_CHEST_GAME_BUILDING_UNLOCKED" }, - { RAND_INF_TREASURE_CHEST_GAME_BUILDING_KEY_OBTAINED, "RAND_INF_TREASURE_CHEST_GAME_BUILDING_KEY_OBTAINED" }, - { RAND_INF_BOMBCHU_SHOP_UNLOCKED, "RAND_INF_BOMBCHU_SHOP_UNLOCKED" }, - { RAND_INF_BOMBCHU_SHOP_KEY_OBTAINED, "RAND_INF_BOMBCHU_SHOP_KEY_OBTAINED" }, - { RAND_INF_RICHARDS_HOUSE_UNLOCKED, "RAND_INF_RICHARDS_HOUSE_UNLOCKED" }, - { RAND_INF_RICHARDS_HOUSE_KEY_OBTAINED, "RAND_INF_RICHARDS_HOUSE_KEY_OBTAINED" }, - { RAND_INF_ALLEY_HOUSE_UNLOCKED, "RAND_INF_ALLEY_HOUSE_UNLOCKED" }, - { RAND_INF_ALLEY_HOUSE_KEY_OBTAINED, "RAND_INF_ALLEY_HOUSE_KEY_OBTAINED" }, - { RAND_INF_KAK_BAZAAR_UNLOCKED, "RAND_INF_KAK_BAZAAR_UNLOCKED" }, - { RAND_INF_KAK_BAZAAR_KEY_OBTAINED, "RAND_INF_KAK_BAZAAR_KEY_OBTAINED" }, - { RAND_INF_KAK_POTION_SHOP_UNLOCKED, "RAND_INF_KAK_POTION_SHOP_UNLOCKED" }, - { RAND_INF_KAK_POTION_SHOP_KEY_OBTAINED, "RAND_INF_KAK_POTION_SHOP_KEY_OBTAINED" }, - { RAND_INF_BOSS_HOUSE_UNLOCKED, "RAND_INF_BOSS_HOUSE_UNLOCKED" }, - { RAND_INF_BOSS_HOUSE_KEY_OBTAINED, "RAND_INF_BOSS_HOUSE_KEY_OBTAINED" }, - { RAND_INF_GRANNYS_POTION_SHOP_UNLOCKED, "RAND_INF_GRANNYS_POTION_SHOP_UNLOCKED" }, - { RAND_INF_GRANNYS_POTION_SHOP_KEY_OBTAINED, "RAND_INF_GRANNYS_POTION_SHOP_KEY_OBTAINED" }, - { RAND_INF_SKULLTULA_HOUSE_UNLOCKED, "RAND_INF_SKULLTULA_HOUSE_UNLOCKED" }, - { RAND_INF_SKULLTULA_HOUSE_KEY_OBTAINED, "RAND_INF_SKULLTULA_HOUSE_KEY_OBTAINED" }, - { RAND_INF_IMPAS_HOUSE_UNLOCKED, "RAND_INF_IMPAS_HOUSE_UNLOCKED" }, - { RAND_INF_IMPAS_HOUSE_KEY_OBTAINED, "RAND_INF_IMPAS_HOUSE_KEY_OBTAINED" }, - { RAND_INF_WINDMILL_UNLOCKED, "RAND_INF_WINDMILL_UNLOCKED" }, - { RAND_INF_WINDMILL_KEY_OBTAINED, "RAND_INF_WINDMILL_KEY_OBTAINED" }, - { RAND_INF_KAK_SHOOTING_GALLERY_UNLOCKED, "RAND_INF_KAK_SHOOTING_GALLERY_UNLOCKED" }, - { RAND_INF_KAK_SHOOTING_GALLERY_KEY_OBTAINED, "RAND_INF_KAK_SHOOTING_GALLERY_KEY_OBTAINED" }, - { RAND_INF_DAMPES_HUT_UNLOCKED, "RAND_INF_DAMPES_HUT_UNLOCKED" }, - { RAND_INF_DAMPES_HUT_KEY_OBTAINED, "RAND_INF_DAMPES_HUT_KEY_OBTAINED" }, - { RAND_INF_TALONS_HOUSE_UNLOCKED, "RAND_INF_TALONS_HOUSE_UNLOCKED" }, - { RAND_INF_TALONS_HOUSE_KEY_OBTAINED, "RAND_INF_TALONS_HOUSE_KEY_OBTAINED" }, - { RAND_INF_STABLES_UNLOCKED, "RAND_INF_STABLES_UNLOCKED" }, - { RAND_INF_STABLES_KEY_OBTAINED, "RAND_INF_STABLES_KEY_OBTAINED" }, - { RAND_INF_BACK_TOWER_UNLOCKED, "RAND_INF_BACK_TOWER_UNLOCKED" }, - { RAND_INF_BACK_TOWER_KEY_OBTAINED, "RAND_INF_BACK_TOWER_KEY_OBTAINED" }, - { RAND_INF_HYLIA_LAB_UNLOCKED, "RAND_INF_HYLIA_LAB_UNLOCKED" }, - { RAND_INF_HYLIA_LAB_KEY_OBTAINED, "RAND_INF_HYLIA_LAB_KEY_OBTAINED" }, - { RAND_INF_FISHING_HOLE_UNLOCKED, "RAND_INF_FISHING_HOLE_UNLOCKED" }, - { RAND_INF_FISHING_HOLE_KEY_OBTAINED, "RAND_INF_FISHING_HOLE_KEY_OBTAINED" }, + { RAND_INF_TOT_LEFTMOST_GOSSIP_STONE_FAIRY, "RAND_INF_TOT_LEFTMOST_GOSSIP_STONE_FAIRY" }, + { RAND_INF_TOT_LEFTMOST_GOSSIP_STONE_FAIRY_BIG, "RAND_INF_TOT_LEFTMOST_GOSSIP_STONE_FAIRY_BIG" }, + { RAND_INF_TOT_LEFT_CENTER_GOSSIP_STONE_FAIRY, "RAND_INF_TOT_LEFT_CENTER_GOSSIP_STONE_FAIRY" }, + { RAND_INF_TOT_LEFT_CENTER_GOSSIP_STONE_FAIRY_BIG, "RAND_INF_TOT_LEFT_CENTER_GOSSIP_STONE_FAIRY_BIG" }, + { RAND_INF_TOT_RIGHT_CENTER_GOSSIP_STONE_FAIRY, "RAND_INF_TOT_RIGHT_CENTER_GOSSIP_STONE_FAIRY" }, + { RAND_INF_TOT_RIGHT_CENTER_GOSSIP_STONE_FAIRY_BIG, "RAND_INF_TOT_RIGHT_CENTER_GOSSIP_STONE_FAIRY_BIG" }, + { RAND_INF_TOT_RIGHTMOST_GOSSIP_STONE_FAIRY, "RAND_INF_TOT_RIGHTMOST_GOSSIP_STONE_FAIRY" }, + { RAND_INF_TOT_RIGHTMOST_GOSSIP_STONE_FAIRY_BIG, "RAND_INF_TOT_RIGHTMOST_GOSSIP_STONE_FAIRY_BIG" }, + { RAND_INF_DMC_GOSSIP_STONE_FAIRY, "RAND_INF_DMC_GOSSIP_STONE_FAIRY" }, + { RAND_INF_DMC_GOSSIP_STONE_FAIRY_BIG, "RAND_INF_DMC_GOSSIP_STONE_FAIRY_BIG" }, + { RAND_INF_DMT_GOSSIP_STONE_FAIRY, "RAND_INF_DMT_GOSSIP_STONE_FAIRY" }, + { RAND_INF_DMT_GOSSIP_STONE_FAIRY_BIG, "RAND_INF_DMT_GOSSIP_STONE_FAIRY_BIG" }, + { RAND_INF_COLOSSUS_GOSSIP_STONE_FAIRY, "RAND_INF_COLOSSUS_GOSSIP_STONE_FAIRY" }, + { RAND_INF_COLOSSUS_GOSSIP_STONE_FAIRY_BIG, "RAND_INF_COLOSSUS_GOSSIP_STONE_FAIRY_BIG" }, + { RAND_INF_DODONGOS_CAVERN_GOSSIP_STONE_FAIRY, "RAND_INF_DODONGOS_CAVERN_GOSSIP_STONE_FAIRY" }, + { RAND_INF_DODONGOS_CAVERN_GOSSIP_STONE_FAIRY_BIG, "RAND_INF_DODONGOS_CAVERN_GOSSIP_STONE_FAIRY_BIG" }, + { RAND_INF_DODONGOS_CAVERN_MQ_GOSSIP_STONE_FAIRY, "RAND_INF_DODONGOS_CAVERN_MQ_GOSSIP_STONE_FAIRY" }, + { RAND_INF_DODONGOS_CAVERN_MQ_GOSSIP_STONE_FAIRY_BIG, "RAND_INF_DODONGOS_CAVERN_MQ_GOSSIP_STONE_FAIRY_BIG" }, + { RAND_INF_GV_GOSSIP_STONE_FAIRY, "RAND_INF_GV_GOSSIP_STONE_FAIRY" }, + { RAND_INF_GV_GOSSIP_STONE_FAIRY_BIG, "RAND_INF_GV_GOSSIP_STONE_FAIRY_BIG" }, + { RAND_INF_GC_MAZE_GOSSIP_STONE_FAIRY, "RAND_INF_GC_MAZE_GOSSIP_STONE_FAIRY" }, + { RAND_INF_GC_MAZE_GOSSIP_STONE_FAIRY_BIG, "RAND_INF_GC_MAZE_GOSSIP_STONE_FAIRY_BIG" }, + { RAND_INF_GC_MEDIGORON_GOSSIP_STONE_FAIRY, "RAND_INF_GC_MEDIGORON_GOSSIP_STONE_FAIRY" }, + { RAND_INF_GC_MEDIGORON_GOSSIP_STONE_FAIRY_BIG, "RAND_INF_GC_MEDIGORON_GOSSIP_STONE_FAIRY_BIG" }, + { RAND_INF_GRAVEYARD_GOSSIP_STONE_FAIRY, "RAND_INF_GRAVEYARD_GOSSIP_STONE_FAIRY" }, + { RAND_INF_GRAVEYARD_GOSSIP_STONE_FAIRY_BIG, "RAND_INF_GRAVEYARD_GOSSIP_STONE_FAIRY_BIG" }, + { RAND_INF_HC_MALON_GOSSIP_STONE_FAIRY, "RAND_INF_HC_MALON_GOSSIP_STONE_FAIRY" }, + { RAND_INF_HC_MALON_GOSSIP_STONE_FAIRY_BIG, "RAND_INF_HC_MALON_GOSSIP_STONE_FAIRY_BIG" }, + { RAND_INF_HC_ROCK_WALL_GOSSIP_STONE_FAIRY, "RAND_INF_HC_ROCK_WALL_GOSSIP_STONE_FAIRY" }, + { RAND_INF_HC_ROCK_WALL_GOSSIP_STONE_FAIRY_BIG, "RAND_INF_HC_ROCK_WALL_GOSSIP_STONE_FAIRY_BIG" }, + { RAND_INF_HC_STORMS_GROTTO_GOSSIP_STONE_FAIRY, "RAND_INF_HC_STORMS_GROTTO_GOSSIP_STONE_FAIRY" }, + { RAND_INF_HC_STORMS_GROTTO_GOSSIP_STONE_FAIRY_BIG, "RAND_INF_HC_STORMS_GROTTO_GOSSIP_STONE_FAIRY_BIG" }, + { RAND_INF_KF_DEKU_TREE_LEFT_GOSSIP_STONE_FAIRY, "RAND_INF_KF_DEKU_TREE_LEFT_GOSSIP_STONE_FAIRY" }, + { RAND_INF_KF_DEKU_TREE_LEFT_GOSSIP_STONE_FAIRY_BIG, "RAND_INF_KF_DEKU_TREE_LEFT_GOSSIP_STONE_FAIRY_BIG" }, + { RAND_INF_KF_DEKU_TREE_RIGHT_GOSSIP_STONE_FAIRY, "RAND_INF_KF_DEKU_TREE_RIGHT_GOSSIP_STONE_FAIRY" }, + { RAND_INF_KF_DEKU_TREE_RIGHT_GOSSIP_STONE_FAIRY_BIG, "RAND_INF_KF_DEKU_TREE_RIGHT_GOSSIP_STONE_FAIRY_BIG" }, + { RAND_INF_KF_GOSSIP_STONE_FAIRY, "RAND_INF_KF_GOSSIP_STONE_FAIRY" }, + { RAND_INF_KF_GOSSIP_STONE_FAIRY_BIG, "RAND_INF_KF_GOSSIP_STONE_FAIRY_BIG" }, + { RAND_INF_KF_STORMS_GROTTO_GOSSIP_STONE_FAIRY, "RAND_INF_KF_STORMS_GROTTO_GOSSIP_STONE_FAIRY" }, + { RAND_INF_KF_STORMS_GROTTO_GOSSIP_STONE_FAIRY_BIG, "RAND_INF_KF_STORMS_GROTTO_GOSSIP_STONE_FAIRY_BIG" }, + { RAND_INF_LH_LAB_GOSSIP_STONE_FAIRY, "RAND_INF_LH_LAB_GOSSIP_STONE_FAIRY" }, + { RAND_INF_LH_LAB_GOSSIP_STONE_FAIRY_BIG, "RAND_INF_LH_LAB_GOSSIP_STONE_FAIRY_BIG" }, + { RAND_INF_LH_SOUTHEAST_GOSSIP_STONE_FAIRY, "RAND_INF_LH_SOUTHEAST_GOSSIP_STONE_FAIRY" }, + { RAND_INF_LH_SOUTHEAST_GOSSIP_STONE_FAIRY_BIG, "RAND_INF_LH_SOUTHEAST_GOSSIP_STONE_FAIRY_BIG" }, + { RAND_INF_LH_SOUTHWEST_GOSSIP_STONE_FAIRY, "RAND_INF_LH_SOUTHWEST_GOSSIP_STONE_FAIRY" }, + { RAND_INF_LH_SOUTHWEST_GOSSIP_STONE_FAIRY_BIG, "RAND_INF_LH_SOUTHWEST_GOSSIP_STONE_FAIRY_BIG" }, + { RAND_INF_LW_GOSSIP_STONE_FAIRY, "RAND_INF_LW_GOSSIP_STONE_FAIRY" }, + { RAND_INF_LW_GOSSIP_STONE_FAIRY_BIG, "RAND_INF_LW_GOSSIP_STONE_FAIRY_BIG" }, + { RAND_INF_SFM_MAZE_LOWER_GOSSIP_STONE_FAIRY, "RAND_INF_SFM_MAZE_LOWER_GOSSIP_STONE_FAIRY" }, + { RAND_INF_SFM_MAZE_LOWER_GOSSIP_STONE_FAIRY_BIG, "RAND_INF_SFM_MAZE_LOWER_GOSSIP_STONE_FAIRY_BIG" }, + { RAND_INF_SFM_MAZE_UPPER_GOSSIP_STONE_FAIRY, "RAND_INF_SFM_MAZE_UPPER_GOSSIP_STONE_FAIRY" }, + { RAND_INF_SFM_MAZE_UPPER_GOSSIP_STONE_FAIRY_BIG, "RAND_INF_SFM_MAZE_UPPER_GOSSIP_STONE_FAIRY_BIG" }, + { RAND_INF_SFM_SARIA_GOSSIP_STONE_FAIRY, "RAND_INF_SFM_SARIA_GOSSIP_STONE_FAIRY" }, + { RAND_INF_SFM_SARIA_GOSSIP_STONE_FAIRY_BIG, "RAND_INF_SFM_SARIA_GOSSIP_STONE_FAIRY_BIG" }, + { RAND_INF_ZD_GOSSIP_STONE_FAIRY, "RAND_INF_ZD_GOSSIP_STONE_FAIRY" }, + { RAND_INF_ZD_GOSSIP_STONE_FAIRY_BIG, "RAND_INF_ZD_GOSSIP_STONE_FAIRY_BIG" }, + { RAND_INF_ZF_FAIRY_GOSSIP_STONE_FAIRY, "RAND_INF_ZF_FAIRY_GOSSIP_STONE_FAIRY" }, + { RAND_INF_ZF_FAIRY_GOSSIP_STONE_FAIRY_BIG, "RAND_INF_ZF_FAIRY_GOSSIP_STONE_FAIRY_BIG" }, + { RAND_INF_ZF_JABU_GOSSIP_STONE_FAIRY, "RAND_INF_ZF_JABU_GOSSIP_STONE_FAIRY" }, + { RAND_INF_ZF_JABU_GOSSIP_STONE_FAIRY_BIG, "RAND_INF_ZF_JABU_GOSSIP_STONE_FAIRY_BIG" }, + { RAND_INF_ZR_NEAR_GROTTOS_GOSSIP_STONE_FAIRY, "RAND_INF_ZR_NEAR_GROTTOS_GOSSIP_STONE_FAIRY" }, + { RAND_INF_ZR_NEAR_GROTTOS_GOSSIP_STONE_FAIRY_BIG, "RAND_INF_ZR_NEAR_GROTTOS_GOSSIP_STONE_FAIRY_BIG" }, + { RAND_INF_ZR_NEAR_DOMAIN_GOSSIP_STONE_FAIRY, "RAND_INF_ZR_NEAR_DOMAIN_GOSSIP_STONE_FAIRY" }, + { RAND_INF_ZR_NEAR_DOMAIN_GOSSIP_STONE_FAIRY_BIG, "RAND_INF_ZR_NEAR_DOMAIN_GOSSIP_STONE_FAIRY_BIG" }, + { RAND_INF_HF_COW_GROTTO_GOSSIP_STONE_FAIRY, "RAND_INF_HF_COW_GROTTO_GOSSIP_STONE_FAIRY" }, + { RAND_INF_HF_COW_GROTTO_GOSSIP_STONE_FAIRY_BIG, "RAND_INF_HF_COW_GROTTO_GOSSIP_STONE_FAIRY_BIG" }, + { RAND_INF_HF_NEAR_MARKET_GROTTO_GOSSIP_STONE_FAIRY, "RAND_INF_HF_NEAR_MARKET_GROTTO_GOSSIP_STONE_FAIRY" }, + { RAND_INF_HF_NEAR_MARKET_GROTTO_GOSSIP_STONE_FAIRY_BIG, + "RAND_INF_HF_NEAR_MARKET_GROTTO_GOSSIP_STONE_FAIRY_BIG" }, + { RAND_INF_HF_SOUTHEAST_GROTTO_GOSSIP_STONE_FAIRY, "RAND_INF_HF_SOUTHEAST_GROTTO_GOSSIP_STONE_FAIRY" }, + { RAND_INF_HF_SOUTHEAST_GROTTO_GOSSIP_STONE_FAIRY_BIG, + "RAND_INF_HF_SOUTHEAST_GROTTO_GOSSIP_STONE_FAIRY_BIG" }, + { RAND_INF_HF_OPEN_GROTTO_GOSSIP_STONE_FAIRY, "RAND_INF_HF_OPEN_GROTTO_GOSSIP_STONE_FAIRY" }, + { RAND_INF_HF_OPEN_GROTTO_GOSSIP_STONE_FAIRY_BIG, "RAND_INF_HF_OPEN_GROTTO_GOSSIP_STONE_FAIRY_BIG" }, + { RAND_INF_KAK_OPEN_GROTTO_GOSSIP_STONE_FAIRY, "RAND_INF_KAK_OPEN_GROTTO_GOSSIP_STONE_FAIRY" }, + { RAND_INF_KAK_OPEN_GROTTO_GOSSIP_STONE_FAIRY_BIG, "RAND_INF_KAK_OPEN_GROTTO_GOSSIP_STONE_FAIRY_BIG" }, + { RAND_INF_ZR_OPEN_GROTTO_GOSSIP_STONE_FAIRY, "RAND_INF_ZR_OPEN_GROTTO_GOSSIP_STONE_FAIRY" }, + { RAND_INF_ZR_OPEN_GROTTO_GOSSIP_STONE_FAIRY_BIG, "RAND_INF_ZR_OPEN_GROTTO_GOSSIP_STONE_FAIRY_BIG" }, + { RAND_INF_LW_NEAR_SHORTCUTS_GROTTO_GOSSIP_STONE_FAIRY, + "RAND_INF_LW_NEAR_SHORTCUTS_GROTTO_GOSSIP_STONE_FAIRY" }, + { RAND_INF_LW_NEAR_SHORTCUTS_GROTTO_GOSSIP_STONE_FAIRY_BIG, + "RAND_INF_LW_NEAR_SHORTCUTS_GROTTO_GOSSIP_STONE_FAIRY_BIG" }, + { RAND_INF_DMT_STORMS_GROTTO_GOSSIP_STONE_FAIRY, "RAND_INF_DMT_STORMS_GROTTO_GOSSIP_STONE_FAIRY" }, + { RAND_INF_DMT_STORMS_GROTTO_GOSSIP_STONE_FAIRY_BIG, "RAND_INF_DMT_STORMS_GROTTO_GOSSIP_STONE_FAIRY_BIG" }, + { RAND_INF_DMC_UPPER_GROTTO_GOSSIP_STONE_FAIRY, "RAND_INF_DMC_UPPER_GROTTO_GOSSIP_STONE_FAIRY" }, + { RAND_INF_DMC_UPPER_GROTTO_GOSSIP_STONE_FAIRY_BIG, "RAND_INF_DMC_UPPER_GROTTO_GOSSIP_STONE_FAIRY_BIG" }, - { RAND_INF_CHILD_TRADES_HAS_WEIRD_EGG, "RAND_INF_CHILD_TRADES_HAS_WEIRD_EGG" }, - { RAND_INF_CHILD_TRADES_HAS_CHICKEN, "RAND_INF_CHILD_TRADES_HAS_CHICKEN" }, - { RAND_INF_CHILD_TRADES_HAS_LETTER_ZELDA, "RAND_INF_CHILD_TRADES_HAS_LETTER_ZELDA" }, - { RAND_INF_CHILD_TRADES_HAS_MASK_KEATON, "RAND_INF_CHILD_TRADES_HAS_MASK_KEATON" }, - { RAND_INF_CHILD_TRADES_HAS_MASK_SKULL, "RAND_INF_CHILD_TRADES_HAS_MASK_SKULL" }, - { RAND_INF_CHILD_TRADES_HAS_MASK_SPOOKY, "RAND_INF_CHILD_TRADES_HAS_MASK_SPOOKY" }, - { RAND_INF_CHILD_TRADES_HAS_MASK_BUNNY, "RAND_INF_CHILD_TRADES_HAS_MASK_BUNNY" }, - { RAND_INF_CHILD_TRADES_HAS_MASK_GORON, "RAND_INF_CHILD_TRADES_HAS_MASK_GORON" }, - { RAND_INF_CHILD_TRADES_HAS_MASK_ZORA, "RAND_INF_CHILD_TRADES_HAS_MASK_ZORA" }, - { RAND_INF_CHILD_TRADES_HAS_MASK_GERUDO, "RAND_INF_CHILD_TRADES_HAS_MASK_GERUDO" }, - { RAND_INF_CHILD_TRADES_HAS_MASK_TRUTH, "RAND_INF_CHILD_TRADES_HAS_MASK_TRUTH" }, + { RAND_INF_LH_ISLAND_SUN_FAIRY, "RAND_INF_LH_ISLAND_SUN_FAIRY" }, + { RAND_INF_HF_POND_STORMS_FAIRY, "RAND_INF_HF_POND_STORMS_FAIRY" }, + { RAND_INF_DMT_FLAG_SUN_FAIRY, "RAND_INF_DMT_FLAG_SUN_FAIRY" }, + { RAND_INF_LW_SHORTCUT_STORMS_FAIRY, "RAND_INF_LW_SHORTCUT_STORMS_FAIRY" }, + { RAND_INF_GF_KITCHEN_SUN_FAIRY, "RAND_INF_GF_KITCHEN_SUN_FAIRY" }, + { RAND_INF_SPIRIT_TEMPLE_BOULDER_ROOM_SUN_FAIRY, "RAND_INF_SPIRIT_TEMPLE_BOULDER_ROOM_SUN_FAIRY" }, + { RAND_INF_SPIRIT_TEMPLE_ARMOS_ROOM_SUN_FAIRY, "RAND_INF_SPIRIT_TEMPLE_ARMOS_ROOM_SUN_FAIRY" }, + { RAND_INF_SHADOW_TEMPLE_BEAMOS_STORM_FAIRY, "RAND_INF_SHADOW_TEMPLE_BEAMOS_STORM_FAIRY" }, + { RAND_INF_SHADOW_TEMPLE_PIT_STORM_FAIRY, "RAND_INF_SHADOW_TEMPLE_PIT_STORM_FAIRY" }, + { RAND_INF_SHADOW_TEMPLE_WIND_HINT_SUN_FAIRY, "RAND_INF_SHADOW_TEMPLE_WIND_HINT_SUN_FAIRY" }, + { RAND_INF_BOTTOM_OF_THE_WELL_BASEMENT_SUN_FAIRY, "RAND_INF_BOTTOM_OF_THE_WELL_BASEMENT_SUN_FAIRY" }, + { RAND_INF_ICE_CAVERN_ENTRANCE_STORMS_FAIRY, "RAND_INF_ICE_CAVERN_ENTRANCE_STORMS_FAIRY" }, + { RAND_INF_GERUDO_TRAINING_GROUND_ENTRANCE_STORMS_FAIRY, + "RAND_INF_GERUDO_TRAINING_GROUND_ENTRANCE_STORMS_FAIRY" }, + { RAND_INF_GANONS_CASTLE_SPIRIT_TRIAL_SUN_FAIRY, "RAND_INF_GANONS_CASTLE_SPIRIT_TRIAL_SUN_FAIRY" }, + { RAND_INF_FIRE_TEMPLE_MQ_LOOP_STALFOS_SUN_FAIRY, "RAND_INF_FIRE_TEMPLE_MQ_LOOP_STALFOS_SUN_FAIRY" }, + { RAND_INF_FIRE_TEMPLE_MQ_LOOP_KNUCKLE_SUN_FAIRY, "RAND_INF_FIRE_TEMPLE_MQ_LOOP_KNUCKLE_SUN_FAIRY" }, + { RAND_INF_WATER_TEMPLE_MQ_DARK_LINK_PILAR_SUN_FAIRY, "RAND_INF_WATER_TEMPLE_MQ_DARK_LINK_PILAR_SUN_FAIRY" }, + { RAND_INF_WATER_TEMPLE_MQ_DARK_LINK_LEFT_STORM_FAIRY, + "RAND_INF_WATER_TEMPLE_MQ_DARK_LINK_LEFT_STORM_FAIRY" }, + { RAND_INF_WATER_TEMPLE_MQ_DARK_LINK_RIGHT_SUN_FAIRY, "RAND_INF_WATER_TEMPLE_MQ_DARK_LINK_RIGHT_SUN_FAIRY" }, + { RAND_INF_SPIRIT_TEMPLE_MQ_DINALFOS_ROOM_SUN_FAIRY, "RAND_INF_SPIRIT_TEMPLE_MQ_DINALFOS_ROOM_SUN_FAIRY" }, + { RAND_INF_SHADOW_TEMPLE_MQ_BEAMOS_STORM_FAIRY, "RAND_INF_SHADOW_TEMPLE_MQ_BEAMOS_STORM_FAIRY" }, + { RAND_INF_SHADOW_TEMPLE_MQ_PIT_STORM_FAIRY, "RAND_INF_SHADOW_TEMPLE_MQ_PIT_STORM_FAIRY" }, + { RAND_INF_SHADOW_TEMPLE_MQ_WIND_HINT_SUN_FAIRY, "RAND_INF_SHADOW_TEMPLE_MQ_WIND_HINT_SUN_FAIRY" }, + { RAND_INF_BOTTOM_OF_THE_WELL_MQ_CELL_SUN_FAIRY, "RAND_INF_BOTTOM_OF_THE_WELL_MQ_CELL_SUN_FAIRY" }, + { RAND_INF_BOTTOM_OF_THE_WELL_MQ_BASEMENT_SUN_FAIRY, "RAND_INF_BOTTOM_OF_THE_WELL_MQ_BASEMENT_SUN_FAIRY" }, - { RAND_INF_ADULT_TRADES_HAS_POCKET_EGG, "RAND_INF_ADULT_TRADES_HAS_POCKET_EGG" }, - { RAND_INF_ADULT_TRADES_HAS_POCKET_CUCCO, "RAND_INF_ADULT_TRADES_HAS_POCKET_CUCCO" }, - { RAND_INF_ADULT_TRADES_HAS_COJIRO, "RAND_INF_ADULT_TRADES_HAS_COJIRO" }, - { RAND_INF_ADULT_TRADES_HAS_ODD_MUSHROOM, "RAND_INF_ADULT_TRADES_HAS_ODD_MUSHROOM" }, - { RAND_INF_ADULT_TRADES_HAS_ODD_POTION, "RAND_INF_ADULT_TRADES_HAS_ODD_POTION" }, - { RAND_INF_ADULT_TRADES_HAS_SAW, "RAND_INF_ADULT_TRADES_HAS_SAW" }, - { RAND_INF_ADULT_TRADES_HAS_SWORD_BROKEN, "RAND_INF_ADULT_TRADES_HAS_SWORD_BROKEN" }, - { RAND_INF_ADULT_TRADES_HAS_PRESCRIPTION, "RAND_INF_ADULT_TRADES_HAS_PRESCRIPTION" }, - { RAND_INF_ADULT_TRADES_HAS_FROG, "RAND_INF_ADULT_TRADES_HAS_FROG" }, - { RAND_INF_ADULT_TRADES_HAS_EYEDROPS, "RAND_INF_ADULT_TRADES_HAS_EYEDROPS" }, - { RAND_INF_ADULT_TRADES_HAS_CLAIM_CHECK, "RAND_INF_ADULT_TRADES_HAS_CLAIM_CHECK" }, - } }, + { RAND_INF_GUARD_HOUSE_UNLOCKED, "RAND_INF_GUARD_HOUSE_UNLOCKED" }, + { RAND_INF_GUARD_HOUSE_KEY_OBTAINED, "RAND_INF_GUARD_HOUSE_KEY_OBTAINED" }, + { RAND_INF_MARKET_BAZAAR_UNLOCKED, "RAND_INF_MARKET_BAZAAR_UNLOCKED" }, + { RAND_INF_MARKET_BAZAAR_KEY_OBTAINED, "RAND_INF_MARKET_BAZAAR_KEY_OBTAINED" }, + { RAND_INF_MARKET_POTION_SHOP_UNLOCKED, "RAND_INF_MARKET_POTION_SHOP_UNLOCKED" }, + { RAND_INF_MARKET_POTION_SHOP_KEY_OBTAINED, "RAND_INF_MARKET_POTION_SHOP_KEY_OBTAINED" }, + { RAND_INF_MASK_SHOP_UNLOCKED, "RAND_INF_MASK_SHOP_UNLOCKED" }, + { RAND_INF_MASK_SHOP_KEY_OBTAINED, "RAND_INF_MASK_SHOP_KEY_OBTAINED" }, + { RAND_INF_MARKET_SHOOTING_GALLERY_UNLOCKED, "RAND_INF_MARKET_SHOOTING_GALLERY_UNLOCKED" }, + { RAND_INF_MARKET_SHOOTING_GALLERY_KEY_OBTAINED, "RAND_INF_MARKET_SHOOTING_GALLERY_KEY_OBTAINED" }, + { RAND_INF_BOMBCHU_BOWLING_UNLOCKED, "RAND_INF_BOMBCHU_BOWLING_UNLOCKED" }, + { RAND_INF_BOMBCHU_BOWLING_KEY_OBTAINED, "RAND_INF_BOMBCHU_BOWLING_KEY_OBTAINED" }, + { RAND_INF_TREASURE_CHEST_GAME_BUILDING_UNLOCKED, "RAND_INF_TREASURE_CHEST_GAME_BUILDING_UNLOCKED" }, + { RAND_INF_TREASURE_CHEST_GAME_BUILDING_KEY_OBTAINED, "RAND_INF_TREASURE_CHEST_GAME_BUILDING_KEY_OBTAINED" }, + { RAND_INF_BOMBCHU_SHOP_UNLOCKED, "RAND_INF_BOMBCHU_SHOP_UNLOCKED" }, + { RAND_INF_BOMBCHU_SHOP_KEY_OBTAINED, "RAND_INF_BOMBCHU_SHOP_KEY_OBTAINED" }, + { RAND_INF_RICHARDS_HOUSE_UNLOCKED, "RAND_INF_RICHARDS_HOUSE_UNLOCKED" }, + { RAND_INF_RICHARDS_HOUSE_KEY_OBTAINED, "RAND_INF_RICHARDS_HOUSE_KEY_OBTAINED" }, + { RAND_INF_ALLEY_HOUSE_UNLOCKED, "RAND_INF_ALLEY_HOUSE_UNLOCKED" }, + { RAND_INF_ALLEY_HOUSE_KEY_OBTAINED, "RAND_INF_ALLEY_HOUSE_KEY_OBTAINED" }, + { RAND_INF_KAK_BAZAAR_UNLOCKED, "RAND_INF_KAK_BAZAAR_UNLOCKED" }, + { RAND_INF_KAK_BAZAAR_KEY_OBTAINED, "RAND_INF_KAK_BAZAAR_KEY_OBTAINED" }, + { RAND_INF_KAK_POTION_SHOP_UNLOCKED, "RAND_INF_KAK_POTION_SHOP_UNLOCKED" }, + { RAND_INF_KAK_POTION_SHOP_KEY_OBTAINED, "RAND_INF_KAK_POTION_SHOP_KEY_OBTAINED" }, + { RAND_INF_BOSS_HOUSE_UNLOCKED, "RAND_INF_BOSS_HOUSE_UNLOCKED" }, + { RAND_INF_BOSS_HOUSE_KEY_OBTAINED, "RAND_INF_BOSS_HOUSE_KEY_OBTAINED" }, + { RAND_INF_GRANNYS_POTION_SHOP_UNLOCKED, "RAND_INF_GRANNYS_POTION_SHOP_UNLOCKED" }, + { RAND_INF_GRANNYS_POTION_SHOP_KEY_OBTAINED, "RAND_INF_GRANNYS_POTION_SHOP_KEY_OBTAINED" }, + { RAND_INF_SKULLTULA_HOUSE_UNLOCKED, "RAND_INF_SKULLTULA_HOUSE_UNLOCKED" }, + { RAND_INF_SKULLTULA_HOUSE_KEY_OBTAINED, "RAND_INF_SKULLTULA_HOUSE_KEY_OBTAINED" }, + { RAND_INF_IMPAS_HOUSE_UNLOCKED, "RAND_INF_IMPAS_HOUSE_UNLOCKED" }, + { RAND_INF_IMPAS_HOUSE_KEY_OBTAINED, "RAND_INF_IMPAS_HOUSE_KEY_OBTAINED" }, + { RAND_INF_WINDMILL_UNLOCKED, "RAND_INF_WINDMILL_UNLOCKED" }, + { RAND_INF_WINDMILL_KEY_OBTAINED, "RAND_INF_WINDMILL_KEY_OBTAINED" }, + { RAND_INF_KAK_SHOOTING_GALLERY_UNLOCKED, "RAND_INF_KAK_SHOOTING_GALLERY_UNLOCKED" }, + { RAND_INF_KAK_SHOOTING_GALLERY_KEY_OBTAINED, "RAND_INF_KAK_SHOOTING_GALLERY_KEY_OBTAINED" }, + { RAND_INF_DAMPES_HUT_UNLOCKED, "RAND_INF_DAMPES_HUT_UNLOCKED" }, + { RAND_INF_DAMPES_HUT_KEY_OBTAINED, "RAND_INF_DAMPES_HUT_KEY_OBTAINED" }, + { RAND_INF_TALONS_HOUSE_UNLOCKED, "RAND_INF_TALONS_HOUSE_UNLOCKED" }, + { RAND_INF_TALONS_HOUSE_KEY_OBTAINED, "RAND_INF_TALONS_HOUSE_KEY_OBTAINED" }, + { RAND_INF_STABLES_UNLOCKED, "RAND_INF_STABLES_UNLOCKED" }, + { RAND_INF_STABLES_KEY_OBTAINED, "RAND_INF_STABLES_KEY_OBTAINED" }, + { RAND_INF_BACK_TOWER_UNLOCKED, "RAND_INF_BACK_TOWER_UNLOCKED" }, + { RAND_INF_BACK_TOWER_KEY_OBTAINED, "RAND_INF_BACK_TOWER_KEY_OBTAINED" }, + { RAND_INF_HYLIA_LAB_UNLOCKED, "RAND_INF_HYLIA_LAB_UNLOCKED" }, + { RAND_INF_HYLIA_LAB_KEY_OBTAINED, "RAND_INF_HYLIA_LAB_KEY_OBTAINED" }, + { RAND_INF_FISHING_HOLE_UNLOCKED, "RAND_INF_FISHING_HOLE_UNLOCKED" }, + { RAND_INF_FISHING_HOLE_KEY_OBTAINED, "RAND_INF_FISHING_HOLE_KEY_OBTAINED" }, + + { RAND_INF_CHILD_TRADES_HAS_WEIRD_EGG, "RAND_INF_CHILD_TRADES_HAS_WEIRD_EGG" }, + { RAND_INF_CHILD_TRADES_HAS_CHICKEN, "RAND_INF_CHILD_TRADES_HAS_CHICKEN" }, + { RAND_INF_CHILD_TRADES_HAS_LETTER_ZELDA, "RAND_INF_CHILD_TRADES_HAS_LETTER_ZELDA" }, + { RAND_INF_CHILD_TRADES_HAS_MASK_KEATON, "RAND_INF_CHILD_TRADES_HAS_MASK_KEATON" }, + { RAND_INF_CHILD_TRADES_HAS_MASK_SKULL, "RAND_INF_CHILD_TRADES_HAS_MASK_SKULL" }, + { RAND_INF_CHILD_TRADES_HAS_MASK_SPOOKY, "RAND_INF_CHILD_TRADES_HAS_MASK_SPOOKY" }, + { RAND_INF_CHILD_TRADES_HAS_MASK_BUNNY, "RAND_INF_CHILD_TRADES_HAS_MASK_BUNNY" }, + { RAND_INF_CHILD_TRADES_HAS_MASK_GORON, "RAND_INF_CHILD_TRADES_HAS_MASK_GORON" }, + { RAND_INF_CHILD_TRADES_HAS_MASK_ZORA, "RAND_INF_CHILD_TRADES_HAS_MASK_ZORA" }, + { RAND_INF_CHILD_TRADES_HAS_MASK_GERUDO, "RAND_INF_CHILD_TRADES_HAS_MASK_GERUDO" }, + { RAND_INF_CHILD_TRADES_HAS_MASK_TRUTH, "RAND_INF_CHILD_TRADES_HAS_MASK_TRUTH" }, + + { RAND_INF_ADULT_TRADES_HAS_POCKET_EGG, "RAND_INF_ADULT_TRADES_HAS_POCKET_EGG" }, + { RAND_INF_ADULT_TRADES_HAS_POCKET_CUCCO, "RAND_INF_ADULT_TRADES_HAS_POCKET_CUCCO" }, + { RAND_INF_ADULT_TRADES_HAS_COJIRO, "RAND_INF_ADULT_TRADES_HAS_COJIRO" }, + { RAND_INF_ADULT_TRADES_HAS_ODD_MUSHROOM, "RAND_INF_ADULT_TRADES_HAS_ODD_MUSHROOM" }, + { RAND_INF_ADULT_TRADES_HAS_ODD_POTION, "RAND_INF_ADULT_TRADES_HAS_ODD_POTION" }, + { RAND_INF_ADULT_TRADES_HAS_SAW, "RAND_INF_ADULT_TRADES_HAS_SAW" }, + { RAND_INF_ADULT_TRADES_HAS_SWORD_BROKEN, "RAND_INF_ADULT_TRADES_HAS_SWORD_BROKEN" }, + { RAND_INF_ADULT_TRADES_HAS_PRESCRIPTION, "RAND_INF_ADULT_TRADES_HAS_PRESCRIPTION" }, + { RAND_INF_ADULT_TRADES_HAS_FROG, "RAND_INF_ADULT_TRADES_HAS_FROG" }, + { RAND_INF_ADULT_TRADES_HAS_EYEDROPS, "RAND_INF_ADULT_TRADES_HAS_EYEDROPS" }, + { RAND_INF_ADULT_TRADES_HAS_CLAIM_CHECK, "RAND_INF_ADULT_TRADES_HAS_CLAIM_CHECK" }, + } }, }; const std::vector state1 = { @@ -1661,7 +1720,7 @@ const std::vector state1 = { "In Water", "In Item Cutscene", "In Cutscene", - "30", //Unknown + "30", // Unknown "Floor collision disabled", }; @@ -1717,5 +1776,5 @@ class SaveEditorWindow : public Ship::GuiWindow { void InitElement() override; void DrawElement() override; - void UpdateElement() override {}; + void UpdateElement() override{}; }; diff --git a/soh/soh/Enhancements/debugger/dlViewer.cpp b/soh/soh/Enhancements/debugger/dlViewer.cpp index 27833058a..7cedcdf26 100644 --- a/soh/soh/Enhancements/debugger/dlViewer.cpp +++ b/soh/soh/Enhancements/debugger/dlViewer.cpp @@ -66,7 +66,8 @@ std::map cmdMap = { }; void PerformDisplayListSearch() { - auto result = Ship::Context::GetInstance()->GetResourceManager()->GetArchiveManager()->ListFiles("*" + std::string(searchString) + "*DL*"); + auto result = Ship::Context::GetInstance()->GetResourceManager()->GetArchiveManager()->ListFiles( + "*" + std::string(searchString) + "*DL*"); displayListSearchResults.clear(); @@ -79,15 +80,12 @@ void PerformDisplayListSearch() { } // Sort the final list - std::sort(displayListSearchResults.begin(), displayListSearchResults.end(), [](const std::string& a, const std::string& b) { - return std::lexicographical_compare( - a.begin(), a.end(), - b.begin(), b.end(), - [](char c1, char c2) { - return std::tolower(c1) < std::tolower(c2); - } - ); - }); + std::sort(displayListSearchResults.begin(), displayListSearchResults.end(), + [](const std::string& a, const std::string& b) { + return std::lexicographical_compare(a.begin(), a.end(), b.begin(), b.end(), [](char c1, char c2) { + return std::tolower(c1) < std::tolower(c2); + }); + }); } void DLViewerWindow::DrawElement() { @@ -128,7 +126,8 @@ void DLViewerWindow::DrawElement() { } try { - auto res = std::static_pointer_cast(Ship::Context::GetInstance()->GetResourceManager()->LoadResource(activeDisplayList)); + auto res = std::static_pointer_cast( + Ship::Context::GetInstance()->GetResourceManager()->LoadResource(activeDisplayList)); if (res->GetInitData()->Type != static_cast(Fast::ResourceType::DisplayList)) { ImGui::Text("Resource type is not a Display List. Please choose another."); @@ -141,7 +140,8 @@ void DLViewerWindow::DrawElement() { std::string id = "##CMD" + std::to_string(i); Gfx* gfx = (Gfx*)&res->Instructions[i]; int cmd = gfx->words.w0 >> 24; - if (cmdMap.find(cmd) == cmdMap.end()) continue; + if (cmdMap.find(cmd) == cmdMap.end()) + continue; std::string cmdLabel = cmdMap.at(cmd); @@ -199,14 +199,13 @@ void DLViewerWindow::DrawElement() { } ImGui::PopItemWidth(); } - if (cmd == G_RDPPIPESYNC) { - } + if (cmd == G_RDPPIPESYNC) {} if (cmd == G_SETGRAYSCALE) { bool* state = (bool*)&gfx->words.w1; ImGui::SameLine(); UIWidgets::PushStyleCheckbox(THEME_COLOR); if (ImGui::Checkbox(("state" + id).c_str(), state)) { - // + // } UIWidgets::PopStyleCheckbox(); } @@ -304,8 +303,7 @@ void DLViewerWindow::DrawElement() { ImGui::SameLine(); ImGui::Text("Vertex Name: %s", fileName); } - if (cmd == G_DL) { - } + if (cmd == G_DL) {} if (cmd == G_DL_OTR_HASH) { gfx++; uint64_t hash = ((uint64_t)gfx->words.w0 << 32) + (uint64_t)gfx->words.w1; @@ -320,8 +318,8 @@ void DLViewerWindow::DrawElement() { } // Skip second half of instructions that are over 128-bit wide - if (cmd == G_SETTIMG_OTR_HASH || cmd == G_DL_OTR_HASH || cmd == G_VTX_OTR_HASH || - cmd == G_BRANCH_Z_OTR || cmd == G_MARKER || cmd == G_MTX_OTR) { + if (cmd == G_SETTIMG_OTR_HASH || cmd == G_DL_OTR_HASH || cmd == G_VTX_OTR_HASH || cmd == G_BRANCH_Z_OTR || + cmd == G_MARKER || cmd == G_MTX_OTR) { i++; ImGui::Text("%lu - Reserved - Second half of %s", i, cmdLabel.c_str()); } diff --git a/soh/soh/Enhancements/debugger/dlViewer.h b/soh/soh/Enhancements/debugger/dlViewer.h index 9d2785456..3655c8964 100644 --- a/soh/soh/Enhancements/debugger/dlViewer.h +++ b/soh/soh/Enhancements/debugger/dlViewer.h @@ -8,5 +8,5 @@ class DLViewerWindow : public Ship::GuiWindow { void InitElement() override; void DrawElement() override; - void UpdateElement() override {}; + void UpdateElement() override{}; }; diff --git a/soh/soh/Enhancements/debugger/hookDebugger.h b/soh/soh/Enhancements/debugger/hookDebugger.h index ae6f5113f..4d5c776db 100644 --- a/soh/soh/Enhancements/debugger/hookDebugger.h +++ b/soh/soh/Enhancements/debugger/hookDebugger.h @@ -6,5 +6,5 @@ class HookDebuggerWindow : public Ship::GuiWindow { void InitElement() override; void DrawElement() override; - void UpdateElement() override {}; + void UpdateElement() override{}; }; diff --git a/soh/soh/Enhancements/debugger/performanceTimer.cpp b/soh/soh/Enhancements/debugger/performanceTimer.cpp index 54e1cb983..43999e7bc 100644 --- a/soh/soh/Enhancements/debugger/performanceTimer.cpp +++ b/soh/soh/Enhancements/debugger/performanceTimer.cpp @@ -1,14 +1,14 @@ #include "performanceTimer.h" -void StartPerformanceTimer(TimerID timer){ +void StartPerformanceTimer(TimerID timer) { timeStarted[timer] = std::chrono::high_resolution_clock::now(); } -void StopPerformanceTimer(TimerID timer){ +void StopPerformanceTimer(TimerID timer) { totalTimes[timer] += (std::chrono::high_resolution_clock::now() - timeStarted[timer]); } -std::chrono::duration GetPerformanceTimer(TimerID timer){ +std::chrono::duration GetPerformanceTimer(TimerID timer) { return totalTimes[timer]; } @@ -16,6 +16,6 @@ void ResetPerformanceTimer(TimerID timer) { totalTimes[timer] = {}; } -void ResetPerformanceTimers(){ +void ResetPerformanceTimers() { totalTimes = {}; } \ No newline at end of file diff --git a/soh/soh/Enhancements/debugger/performanceTimer.h b/soh/soh/Enhancements/debugger/performanceTimer.h index b94ab5f6d..6bff229a3 100644 --- a/soh/soh/Enhancements/debugger/performanceTimer.h +++ b/soh/soh/Enhancements/debugger/performanceTimer.h @@ -5,28 +5,28 @@ #include typedef enum { - PT_WHOLE_SEED, - PT_LOGIC_RESET, - PT_REGION_RESET, - PT_SPOILER_LOG, - PT_ENTRANCE_SHUFFLE, - PT_SHOPSANITY, - PT_OWN_DUNGEON, - PT_LIMITED_CHECKS, - PT_ADVANCEMENT_ITEMS, - PT_REMAINING_ITEMS, - PT_PLAYTHROUGH_GENERATION, - PT_PARE_DOWN_PLAYTHROUGH, - PT_WOTH, - PT_FOOLISH, - PT_OVERRIDES, - PT_HINTS, - PT_EVENT_ACCESS, - PT_TOD_ACCESS, - PT_ENTRANCE_LOGIC, - PT_LOCATION_LOGIC, - PT_RECALCULATE_AVAILABLE_CHECKS, - PT_MAX + PT_WHOLE_SEED, + PT_LOGIC_RESET, + PT_REGION_RESET, + PT_SPOILER_LOG, + PT_ENTRANCE_SHUFFLE, + PT_SHOPSANITY, + PT_OWN_DUNGEON, + PT_LIMITED_CHECKS, + PT_ADVANCEMENT_ITEMS, + PT_REMAINING_ITEMS, + PT_PLAYTHROUGH_GENERATION, + PT_PARE_DOWN_PLAYTHROUGH, + PT_WOTH, + PT_FOOLISH, + PT_OVERRIDES, + PT_HINTS, + PT_EVENT_ACCESS, + PT_TOD_ACCESS, + PT_ENTRANCE_LOGIC, + PT_LOCATION_LOGIC, + PT_RECALCULATE_AVAILABLE_CHECKS, + PT_MAX } TimerID; void StartPerformanceTimer(TimerID timer); @@ -36,4 +36,3 @@ void ResetPerformanceTimer(TimerID timer); void ResetPerformanceTimers(); static std::array, PT_MAX> totalTimes = {}; static std::array timeStarted = {}; - diff --git a/soh/soh/Enhancements/debugger/valueViewer.cpp b/soh/soh/Enhancements/debugger/valueViewer.cpp index c0ac04739..1ea117444 100644 --- a/soh/soh/Enhancements/debugger/valueViewer.cpp +++ b/soh/soh/Enhancements/debugger/valueViewer.cpp @@ -77,27 +77,35 @@ std::vector valueTable = { extern "C" void ValueViewer_Draw(GfxPrint* printer) { for (int i = 0; i < valueTable.size(); i++) { ValueTableElement& element = valueTable[i]; - if (!element.isActive || !element.isPrinted || (gPlayState == NULL && element.requiresPlayState)) continue; - GfxPrint_SetColor(printer, element.color.x * 255, element.color.y * 255, element.color.z * 255, element.color.w * 255); + if (!element.isActive || !element.isPrinted || (gPlayState == NULL && element.requiresPlayState)) + continue; + GfxPrint_SetColor(printer, element.color.x * 255, element.color.y * 255, element.color.z * 255, + element.color.w * 255); GfxPrint_SetPos(printer, element.x, element.y); switch (element.type) { case TYPE_S8: - GfxPrint_Printf(printer, (element.typeFormat ? "%s0x%x" : "%s%d"), element.prefix.c_str(), *(s8*)element.valueFn()); + GfxPrint_Printf(printer, (element.typeFormat ? "%s0x%x" : "%s%d"), element.prefix.c_str(), + *(s8*)element.valueFn()); break; case TYPE_U8: - GfxPrint_Printf(printer, (element.typeFormat ? "%s0x%x" : "%s%u"), element.prefix.c_str(), *(u8*)element.valueFn()); + GfxPrint_Printf(printer, (element.typeFormat ? "%s0x%x" : "%s%u"), element.prefix.c_str(), + *(u8*)element.valueFn()); break; case TYPE_S16: - GfxPrint_Printf(printer, (element.typeFormat ? "%s0x%x" : "%s%d"), element.prefix.c_str(), *(s16*)element.valueFn()); + GfxPrint_Printf(printer, (element.typeFormat ? "%s0x%x" : "%s%d"), element.prefix.c_str(), + *(s16*)element.valueFn()); break; case TYPE_U16: - GfxPrint_Printf(printer, (element.typeFormat ? "%s0x%x" : "%s%u"), element.prefix.c_str(), *(u16*)element.valueFn()); + GfxPrint_Printf(printer, (element.typeFormat ? "%s0x%x" : "%s%u"), element.prefix.c_str(), + *(u16*)element.valueFn()); break; case TYPE_S32: - GfxPrint_Printf(printer, (element.typeFormat ? "%s0x%x" : "%s%d"), element.prefix.c_str(), *(s32*)element.valueFn()); + GfxPrint_Printf(printer, (element.typeFormat ? "%s0x%x" : "%s%d"), element.prefix.c_str(), + *(s32*)element.valueFn()); break; case TYPE_U32: - GfxPrint_Printf(printer, (element.typeFormat ? "%s0x%x" : "%s%u"), element.prefix.c_str(), *(u32*)element.valueFn()); + GfxPrint_Printf(printer, (element.typeFormat ? "%s0x%x" : "%s%u"), element.prefix.c_str(), + *(u32*)element.valueFn()); break; case TYPE_CHAR: GfxPrint_Printf(printer, "%s%c", element.prefix.c_str(), *(char*)element.valueFn()); @@ -106,7 +114,8 @@ extern "C" void ValueViewer_Draw(GfxPrint* printer) { GfxPrint_Printf(printer, "%s%s", element.prefix.c_str(), (char*)element.valueFn()); break; case TYPE_FLOAT: - GfxPrint_Printf(printer, (element.typeFormat ? "%s%4.1f" : "%s%f"), element.prefix.c_str(), *(float*)element.valueFn()); + GfxPrint_Printf(printer, (element.typeFormat ? "%s%4.1f" : "%s%f"), element.prefix.c_str(), + *(float*)element.valueFn()); break; } } @@ -149,17 +158,16 @@ void ValueViewerWindow::DrawElement() { ImGui::BeginGroup(); static int selectedElement = -1; - std::string selectedElementText = (selectedElement == -1) ? "Select a value" : ( - std::string(valueTable[selectedElement].name) + " (" + std::string(valueTable[selectedElement].path) + ")" - ); + std::string selectedElementText = (selectedElement == -1) ? "Select a value" + : (std::string(valueTable[selectedElement].name) + " (" + + std::string(valueTable[selectedElement].path) + ")"); UIWidgets::PushStyleCombobox(THEME_COLOR); if (ImGui::BeginCombo("##valueViewerElement", selectedElementText.c_str())) { for (int i = 0; i < valueTable.size(); i++) { - if (valueTable[i].isActive) continue; + if (valueTable[i].isActive) + continue; bool isSelected = (selectedElement == i); - std::string elementText = ( - std::string(valueTable[i].name) + " (" + std::string(valueTable[i].path) + ")" - ); + std::string elementText = (std::string(valueTable[i].name) + " (" + std::string(valueTable[i].path) + ")"); if (ImGui::Selectable(elementText.c_str(), isSelected)) { selectedElement = i; } @@ -181,7 +189,8 @@ void ValueViewerWindow::DrawElement() { for (int i = 0; i < valueTable.size(); i++) { ValueTableElement& element = valueTable[i]; - if (!element.isActive || (gPlayState == NULL && element.requiresPlayState)) continue; + if (!element.isActive || (gPlayState == NULL && element.requiresPlayState)) + continue; UIWidgets::PushStyleButton(THEME_COLOR); UIWidgets::PushStyleCheckbox(THEME_COLOR); ImGui::AlignTextToFramePadding(); @@ -249,7 +258,8 @@ void ValueViewerWindow::DrawElement() { } UIWidgets::PopStyleInput(); ImGui::SameLine(); - ImGui::ColorEdit3(("##color" + std::string(element.name)).c_str(), (float*)&element.color, ImGuiColorEditFlags_NoInputs | ImGuiColorEditFlags_NoLabel); + ImGui::ColorEdit3(("##color" + std::string(element.name)).c_str(), (float*)&element.color, + ImGuiColorEditFlags_NoInputs | ImGuiColorEditFlags_NoLabel); ImGui::SameLine(); UIWidgets::PushStyleCheckbox(THEME_COLOR); if (ImGui::Button(("Position##" + std::string(element.name)).c_str())) { diff --git a/soh/soh/Enhancements/debugger/valueViewer.h b/soh/soh/Enhancements/debugger/valueViewer.h index e93491fa5..c5e51a126 100644 --- a/soh/soh/Enhancements/debugger/valueViewer.h +++ b/soh/soh/Enhancements/debugger/valueViewer.h @@ -39,7 +39,7 @@ class ValueViewerWindow : public Ship::GuiWindow { void InitElement() override; void DrawElement() override; - void UpdateElement() override {}; + void UpdateElement() override{}; }; #endif diff --git a/soh/soh/Enhancements/enemyrandomizer.cpp b/soh/soh/Enhancements/enemyrandomizer.cpp index 42bd8d042..611131584 100644 --- a/soh/soh/Enhancements/enemyrandomizer.cpp +++ b/soh/soh/Enhancements/enemyrandomizer.cpp @@ -42,18 +42,54 @@ const char* enemyCVarList[] = { }; const char* enemyNameList[] = { - "Armos", "Arwing", "Baby Dodongo", "Bari", - "Beamos", "Big Skulltula", "Stalchild (Big)", "Biri", - "Iron Knuckle (Black)", "Blue Tektite", "Bubble", "Club Moblin", - "Dark Link", "Dinolfos", "Dodongo", "Fire Keese", - "Floor Tile", "Floormaster", "Flying Peahat", "Flying Pot", - "Freezard", "Gibdo", "Gohma Larva", "Guay", - "Ice Keese", "Invisible Skulltula", "Keese", "Large Deku Baba", - "Like-Like", "Lizalfos", "Mad Scrub", "Wolfos (Normal)", - "Peahat Larva", "Redead", "Red Tektite", "Shabom", - "Shell Blade", "Skulltula", "Small Deku Baba", "Stalchild (Small)", - "Spike", "Stalfos", "Stinger", "Tailpasaran", - "Torch Slug", "Wallmaster", "Iron Knuckle (White)", "Wolfos (White)", + "Armos", + "Arwing", + "Baby Dodongo", + "Bari", + "Beamos", + "Big Skulltula", + "Stalchild (Big)", + "Biri", + "Iron Knuckle (Black)", + "Blue Tektite", + "Bubble", + "Club Moblin", + "Dark Link", + "Dinolfos", + "Dodongo", + "Fire Keese", + "Floor Tile", + "Floormaster", + "Flying Peahat", + "Flying Pot", + "Freezard", + "Gibdo", + "Gohma Larva", + "Guay", + "Ice Keese", + "Invisible Skulltula", + "Keese", + "Large Deku Baba", + "Like-Like", + "Lizalfos", + "Mad Scrub", + "Wolfos (Normal)", + "Peahat Larva", + "Redead", + "Red Tektite", + "Shabom", + "Shell Blade", + "Skulltula", + "Small Deku Baba", + "Stalchild (Small)", + "Spike", + "Stalfos", + "Stinger", + "Tailpasaran", + "Torch Slug", + "Wallmaster", + "Iron Knuckle (White)", + "Wolfos (White)", "Withered Deku Baba", }; @@ -111,43 +147,45 @@ static EnemyEntry randomizedEnemySpawnTable[RANDOMIZED_ENEMY_SPAWN_TABLE_SIZE] = // Doesn't work {ACTOR_EN_POH, 0}, // Poe (Seems to rely on other objects?) // Doesn't work {ACTOR_EN_POH, 2}, // Poe (composer Sharp) (Seems to rely on other objects?) // Doesn't work {ACTOR_EN_POH, 3}, // Poe (composer Flat) (Seems to rely on other objects?) - // Doesn't work {ACTOR_EN_OKUTA, 0}, // Octorok (actor directly uses water box collision to handle hiding/popping up) - // Doesn't work {ACTOR_EN_REEBA, 0}, // Leever (reliant on surface and also normally used in tandem with a leever spawner, kills itself too quickly otherwise) - // Kinda doesn't work { ACTOR_EN_FD, 0 }, // Flare Dancer (jumps out of bounds a lot, and possible cause of crashes because of spawning a ton of flame actors) + // Doesn't work {ACTOR_EN_OKUTA, 0}, // Octorok (actor directly uses water box collision to handle hiding/popping + // up) Doesn't work {ACTOR_EN_REEBA, 0}, // Leever (reliant on surface and also normally used in tandem with a + // leever spawner, kills itself too quickly otherwise) Kinda doesn't work { ACTOR_EN_FD, 0 }, // Flare Dancer (jumps + // out of bounds a lot, and possible cause of crashes because of spawning a ton of flame actors) }; static int enemiesToRandomize[] = { - ACTOR_EN_FIREFLY, // Keese (including fire/ice) - ACTOR_EN_TEST, // Stalfos - ACTOR_EN_TITE, // Tektite - ACTOR_EN_POH, // Poe (normal, blue rupee, composers) - ACTOR_EN_OKUTA, // Octorok - ACTOR_EN_WALLMAS, // Wallmaster - ACTOR_EN_DODONGO, // Dodongo + ACTOR_EN_FIREFLY, // Keese (including fire/ice) + ACTOR_EN_TEST, // Stalfos + ACTOR_EN_TITE, // Tektite + ACTOR_EN_POH, // Poe (normal, blue rupee, composers) + ACTOR_EN_OKUTA, // Octorok + ACTOR_EN_WALLMAS, // Wallmaster + ACTOR_EN_DODONGO, // Dodongo // ACTOR_EN_REEBA, // Leever (reliant on spawner (z_e_encount1.c) - ACTOR_EN_PEEHAT, // Flying Peahat, big one spawning larva, larva - ACTOR_EN_ZF, // Lizalfos, Dinolfos - ACTOR_EN_GOMA, // Gohma Larva (normal, eggs, gohma eggs) - ACTOR_EN_BUBBLE, // Shabom (bubble) - ACTOR_EN_DODOJR, // Baby Dodongo - ACTOR_EN_TORCH2, // Dark Link - ACTOR_EN_BILI, // Biri (small jellyfish) - ACTOR_EN_TP, // Electric Tailpasaran - ACTOR_EN_ST, // Skulltula (normal, big, invisible) - ACTOR_EN_BW, // Torch Slug - ACTOR_EN_EIYER, // Stinger (land) - ACTOR_EN_MB, // Moblins (Club, spear) - ACTOR_EN_DEKUBABA, // Deku Baba (small, large) - ACTOR_EN_AM, // Armos (enemy variant) - ACTOR_EN_DEKUNUTS, // Mad Scrub (single attack, triple attack) - ACTOR_EN_VALI, // Bari (big jellyfish) (spawns very high up) - ACTOR_EN_BB, // Bubble (flying skull enemy) (all colors) - ACTOR_EN_YUKABYUN, // Flying Floor Tile - ACTOR_EN_VM, // Beamos - ACTOR_EN_FLOORMAS, // Floormaster - ACTOR_EN_RD, // Redead, Gibdo - ACTOR_EN_SW, // Skullwalltula - // ACTOR_EN_FD, // Flare Dancer (can be randomized, but not randomized to, so keeping it in vanilla locations means it at least shows up in the game) + ACTOR_EN_PEEHAT, // Flying Peahat, big one spawning larva, larva + ACTOR_EN_ZF, // Lizalfos, Dinolfos + ACTOR_EN_GOMA, // Gohma Larva (normal, eggs, gohma eggs) + ACTOR_EN_BUBBLE, // Shabom (bubble) + ACTOR_EN_DODOJR, // Baby Dodongo + ACTOR_EN_TORCH2, // Dark Link + ACTOR_EN_BILI, // Biri (small jellyfish) + ACTOR_EN_TP, // Electric Tailpasaran + ACTOR_EN_ST, // Skulltula (normal, big, invisible) + ACTOR_EN_BW, // Torch Slug + ACTOR_EN_EIYER, // Stinger (land) + ACTOR_EN_MB, // Moblins (Club, spear) + ACTOR_EN_DEKUBABA, // Deku Baba (small, large) + ACTOR_EN_AM, // Armos (enemy variant) + ACTOR_EN_DEKUNUTS, // Mad Scrub (single attack, triple attack) + ACTOR_EN_VALI, // Bari (big jellyfish) (spawns very high up) + ACTOR_EN_BB, // Bubble (flying skull enemy) (all colors) + ACTOR_EN_YUKABYUN, // Flying Floor Tile + ACTOR_EN_VM, // Beamos + ACTOR_EN_FLOORMAS, // Floormaster + ACTOR_EN_RD, // Redead, Gibdo + ACTOR_EN_SW, // Skullwalltula + // ACTOR_EN_FD, // Flare Dancer (can be randomized, but not randomized to, so keeping it in vanilla locations + // means it at least shows up in the game) ACTOR_EN_SB, // Shell Blade ACTOR_EN_KAREBABA, // Withered Deku Baba ACTOR_EN_RR, // Like-Like @@ -162,8 +200,8 @@ static int enemiesToRandomize[] = { ACTOR_EN_CROW, // Guay }; -extern "C" uint8_t GetRandomizedEnemy(PlayState* play, int16_t *actorId, f32 *posX, f32 *posY, f32 *posZ, int16_t *rotX, - int16_t *rotY, int16_t *rotZ, int16_t *params) { +extern "C" uint8_t GetRandomizedEnemy(PlayState* play, int16_t* actorId, f32* posX, f32* posY, f32* posZ, int16_t* rotX, + int16_t* rotY, int16_t* rotZ, int16_t* params) { uint32_t isMQ = ResourceMgr_IsSceneMasterQuest(play->sceneNum); @@ -171,7 +209,8 @@ extern "C" uint8_t GetRandomizedEnemy(PlayState* play, int16_t *actorId, f32 *po // This should probably be handled on OTR generation in the future when object dependency is fully removed. // Remove bats and Skulltulas from graveyard. // Remove Octorok in Lost Woods. - if (((*actorId == ACTOR_EN_FIREFLY || (*actorId == ACTOR_EN_SW && *params == 0)) && play->sceneNum == SCENE_GRAVEYARD) || + if (((*actorId == ACTOR_EN_FIREFLY || (*actorId == ACTOR_EN_SW && *params == 0)) && + play->sceneNum == SCENE_GRAVEYARD) || (*actorId == ACTOR_EN_OKUTA && play->sceneNum == SCENE_LOST_WOODS)) { return 0; } @@ -229,7 +268,8 @@ extern "C" uint8_t GetRandomizedEnemy(PlayState* play, int16_t *actorId, f32 *po } // Get randomized enemy ID and parameter. - uint32_t seed = play->sceneNum + *actorId + (int)*posX + (int)*posY + (int)*posZ + *rotX + *rotY + *rotZ + *params; + uint32_t seed = + play->sceneNum + *actorId + (int)*posX + (int)*posY + (int)*posZ + *rotX + *rotY + *rotZ + *params; EnemyEntry randomEnemy = GetRandomizedEnemyEntry(seed); int8_t timesRandomized = 1; @@ -305,7 +345,8 @@ EnemyEntry GetRandomizedEnemyEntry(uint32_t seed) { GetSelectedEnemies(); } if (CVarGetInteger(CVAR_ENHANCEMENT("RandomizedEnemies"), ENEMY_RANDOMIZER_OFF) == ENEMY_RANDOMIZER_RANDOM_SEEDED) { - uint32_t finalSeed = seed + (IS_RANDO ? Rando::Context::GetInstance()->GetSeed() : gSaveContext.ship.stats.fileCreatedAt); + uint32_t finalSeed = + seed + (IS_RANDO ? Rando::Context::GetInstance()->GetSeed() : gSaveContext.ship.stats.fileCreatedAt); Random_Init(finalSeed); uint32_t randomNumber = Random(0, RANDOMIZED_ENEMY_SPAWN_TABLE_SIZE); return selectedEnemyList[randomNumber]; @@ -357,17 +398,19 @@ bool IsEnemyFoundToRandomize(int16_t sceneNum, int8_t roomNum, int16_t actorId, // Don't randomize the Wolfos in SFM because it's needed to open the gate. case ACTOR_EN_WF: return (params != 7936); - // Don't randomize the Stalfos in Forest Temple because other enemies fall through the hole and don't trigger the platform. - // Don't randomize the Stalfos spawning on the boat in Shadow Temple, as randomizing them places the new enemies - // down in the river. + // Don't randomize the Stalfos in Forest Temple because other enemies fall through the hole and don't + // trigger the platform. Don't randomize the Stalfos spawning on the boat in Shadow Temple, as + // randomizing them places the new enemies down in the river. case ACTOR_EN_TEST: return (params != 1 && !(sceneNum == SCENE_SHADOW_TEMPLE && roomNum == 21)); // Only randomize the enemy variant of Armos Statue. - // Leave one Armos unrandomized in the Spirit Temple room where an armos is needed to push down a button. + // Leave one Armos unrandomized in the Spirit Temple room where an armos is needed to push down a + // button. case ACTOR_EN_AM: return ((params == -1 || params == 255) && !(sceneNum == SCENE_SPIRIT_TEMPLE && posX == 2141)); - // Don't randomize Shell Blades and Spikes in the underwater portion in Water Temple as it's impossible to kill - // most other enemies underwater with just hookshot and they're required to be killed for a grate to open. + // Don't randomize Shell Blades and Spikes in the underwater portion in Water Temple as it's impossible + // to kill most other enemies underwater with just hookshot and they're required to be killed for a + // grate to open. case ACTOR_EN_SB: case ACTOR_EN_NY: return (!(!isMQ && sceneNum == SCENE_WATER_TEMPLE && roomNum == 2)); @@ -403,7 +446,8 @@ bool IsEnemyAllowedToSpawn(int16_t sceneNum, int8_t roomNum, EnemyEntry enemy) { // Deku Tree case SCENE_DEKU_TREE: return (!(!isMQ && enemiesToExcludeClearRooms && (roomNum == 1 || roomNum == 9)) && - !(isMQ && enemiesToExcludeClearRooms && (roomNum == 4 || roomNum == 6 || roomNum == 9 || roomNum == 10))); + !(isMQ && enemiesToExcludeClearRooms && + (roomNum == 4 || roomNum == 6 || roomNum == 9 || roomNum == 10))); // Dodongo's Cavern case SCENE_DODONGOS_CAVERN: return (!(!isMQ && enemiesToExcludeClearRooms && roomNum == 15) && @@ -415,8 +459,10 @@ bool IsEnemyAllowedToSpawn(int16_t sceneNum, int8_t roomNum, EnemyEntry enemy) { !(isMQ && enemiesToExcludeClearRooms && (roomNum == 11 || roomNum == 14))); // Forest Temple case SCENE_FOREST_TEMPLE: - return (!(!isMQ && enemiesToExcludeClearRooms && (roomNum == 6 || roomNum == 10 || roomNum == 18 || roomNum == 21)) && - !(isMQ && enemiesToExcludeClearRooms && (roomNum == 5 || roomNum == 6 || roomNum == 18 || roomNum == 21))); + return (!(!isMQ && enemiesToExcludeClearRooms && + (roomNum == 6 || roomNum == 10 || roomNum == 18 || roomNum == 21)) && + !(isMQ && enemiesToExcludeClearRooms && + (roomNum == 5 || roomNum == 6 || roomNum == 18 || roomNum == 21))); // Fire Temple case SCENE_FIRE_TEMPLE: return (!(!isMQ && enemiesToExcludeClearRooms && roomNum == 15) && @@ -427,23 +473,31 @@ bool IsEnemyAllowedToSpawn(int16_t sceneNum, int8_t roomNum, EnemyEntry enemy) { !(isMQ && enemiesToExcludeClearRooms && (roomNum == 13 || roomNum == 18))); // Spirit Temple case SCENE_SPIRIT_TEMPLE: - return (!(!isMQ && enemiesToExcludeClearRooms && (roomNum == 1 || roomNum == 10 || roomNum == 17 || roomNum == 20)) && - !(isMQ && enemiesToExcludeClearRooms && (roomNum == 1 || roomNum == 2 || roomNum == 4 || roomNum == 10 || roomNum == 15 || roomNum == 19 || roomNum == 20))); + return (!(!isMQ && enemiesToExcludeClearRooms && + (roomNum == 1 || roomNum == 10 || roomNum == 17 || roomNum == 20)) && + !(isMQ && enemiesToExcludeClearRooms && + (roomNum == 1 || roomNum == 2 || roomNum == 4 || roomNum == 10 || roomNum == 15 || + roomNum == 19 || roomNum == 20))); // Shadow Temple case SCENE_SHADOW_TEMPLE: - return (!(!isMQ && enemiesToExcludeClearRooms && - (roomNum == 1 || roomNum == 7 || roomNum == 11 || roomNum == 14 || roomNum == 16 || roomNum == 17 || roomNum == 19 || roomNum == 20)) && - !(isMQ && enemiesToExcludeClearRooms && (roomNum == 1 || roomNum == 6 || roomNum == 7 || roomNum == 11 || roomNum == 14 || roomNum == 20))); + return ( + !(!isMQ && enemiesToExcludeClearRooms && + (roomNum == 1 || roomNum == 7 || roomNum == 11 || roomNum == 14 || roomNum == 16 || roomNum == 17 || + roomNum == 19 || roomNum == 20)) && + !(isMQ && enemiesToExcludeClearRooms && + (roomNum == 1 || roomNum == 6 || roomNum == 7 || roomNum == 11 || roomNum == 14 || roomNum == 20))); // Ganon's Castle Trials case SCENE_INSIDE_GANONS_CASTLE: return (!(!isMQ && enemiesToExcludeClearRooms && (roomNum == 2 || roomNum == 5 || roomNum == 9)) && - !(isMQ && enemiesToExcludeClearRooms && (roomNum == 0 || roomNum == 2 || roomNum == 5 || roomNum == 9))); + !(isMQ && enemiesToExcludeClearRooms && + (roomNum == 0 || roomNum == 2 || roomNum == 5 || roomNum == 9))); // Ice Caverns case SCENE_ICE_CAVERN: return (!(!isMQ && enemiesToExcludeClearRooms && (roomNum == 1 || roomNum == 7)) && !(isMQ && enemiesToExcludeClearRooms && (roomNum == 3 || roomNum == 7))); // Bottom of the Well - // Exclude Dark Link from room with holes in the floor because it can pull you in a like-like making the player fall down. + // Exclude Dark Link from room with holes in the floor because it can pull you in a like-like making the player + // fall down. case SCENE_BOTTOM_OF_THE_WELL: return (!(!isMQ && enemy.id == ACTOR_EN_TORCH2 && roomNum == 3)); // Don't allow Dark Link in areas with lava void out zones as it voids out the player as well. @@ -452,18 +506,21 @@ bool IsEnemyAllowedToSpawn(int16_t sceneNum, int8_t roomNum, EnemyEntry enemy) { return (!(enemy.id == ACTOR_EN_TORCH2 && roomNum == 6) && !(!isMQ && enemiesToExcludeTimedRooms && (roomNum == 1 || roomNum == 7)) && !(!isMQ && enemiesToExcludeClearRooms && (roomNum == 3 || roomNum == 5 || roomNum == 10)) && - !(isMQ && enemiesToExcludeTimedRooms && (roomNum == 1 || roomNum == 3 || roomNum == 5 || roomNum == 7)) && + !(isMQ && enemiesToExcludeTimedRooms && + (roomNum == 1 || roomNum == 3 || roomNum == 5 || roomNum == 7)) && !(isMQ && enemiesToExcludeClearRooms && roomNum == 10)); // Don't allow certain enemies in Ganon's Tower because they would spawn up on the ceiling, // becoming impossible to kill. // Ganon's Tower. case SCENE_GANONS_TOWER: - return (!(enemiesToExcludeClearRooms || enemy.id == ACTOR_EN_VALI || (enemy.id == ACTOR_EN_ZF && enemy.params == -1))); + return (!(enemiesToExcludeClearRooms || enemy.id == ACTOR_EN_VALI || + (enemy.id == ACTOR_EN_ZF && enemy.params == -1))); // Ganon's Tower Escape. case SCENE_GANONS_TOWER_COLLAPSE_INTERIOR: return (!((enemiesToExcludeTimedRooms || (enemy.id == ACTOR_EN_ZF && enemy.params == -1)) && roomNum == 1)); - // Don't allow big Stalchildren, big Peahats and the large Bari (jellyfish) during the Gohma fight because they can clip into Gohma - // and it crashes the game. Likely because Gohma on the ceiling can't handle collision with other enemies. + // Don't allow big Stalchildren, big Peahats and the large Bari (jellyfish) during the Gohma fight because they + // can clip into Gohma and it crashes the game. Likely because Gohma on the ceiling can't handle collision with + // other enemies. case SCENE_DEKU_TREE_BOSS: return (!enemiesToExcludeTimedRooms && !(enemy.id == ACTOR_EN_SKB && enemy.params == 20) && !(enemy.id == ACTOR_EN_PEEHAT && enemy.params == -1)); diff --git a/soh/soh/Enhancements/enemyrandomizer.h b/soh/soh/Enhancements/enemyrandomizer.h index f819de9bf..4c4fd5576 100644 --- a/soh/soh/Enhancements/enemyrandomizer.h +++ b/soh/soh/Enhancements/enemyrandomizer.h @@ -18,5 +18,6 @@ extern const char* enemyNameList[]; extern void GetSelectedEnemies(); #ifndef __cplusplus -uint8_t GetRandomizedEnemy(PlayState* play, int16_t *actorId, f32 *posX, f32 *posY, f32 *posZ, int16_t *rotX, int16_t *rotY, int16_t *rotZ, int16_t *params); +uint8_t GetRandomizedEnemy(PlayState* play, int16_t* actorId, f32* posX, f32* posY, f32* posZ, int16_t* rotX, + int16_t* rotY, int16_t* rotZ, int16_t* params); #endif diff --git a/soh/soh/Enhancements/game-interactor/GameInteractionEffect.cpp b/soh/soh/Enhancements/game-interactor/GameInteractionEffect.cpp index 913496159..95455926b 100644 --- a/soh/soh/Enhancements/game-interactor/GameInteractionEffect.cpp +++ b/soh/soh/Enhancements/game-interactor/GameInteractionEffect.cpp @@ -47,621 +47,617 @@ GameInteractionEffectQueryResult RemovableGameInteractionEffect::Remove() { namespace GameInteractionEffect { - // MARK: - Flags - GameInteractionEffectQueryResult SetSceneFlag::CanBeApplied() { - if (!GameInteractor::IsSaveLoaded()) { - return GameInteractionEffectQueryResult::TemporarilyNotPossible; - } +// MARK: - Flags +GameInteractionEffectQueryResult SetSceneFlag::CanBeApplied() { + if (!GameInteractor::IsSaveLoaded()) { + return GameInteractionEffectQueryResult::TemporarilyNotPossible; + } + return GameInteractionEffectQueryResult::Possible; +} + +void SetSceneFlag::_Apply() { + GameInteractor::RawAction::SetSceneFlag(parameters[0], parameters[1], parameters[2]); +} + +GameInteractionEffectQueryResult UnsetSceneFlag::CanBeApplied() { + if (!GameInteractor::IsSaveLoaded()) { + return GameInteractionEffectQueryResult::TemporarilyNotPossible; + } + + return GameInteractionEffectQueryResult::Possible; +} + +void UnsetSceneFlag::_Apply() { + GameInteractor::RawAction::UnsetSceneFlag(parameters[0], parameters[1], parameters[2]); +} + +GameInteractionEffectQueryResult SetFlag::CanBeApplied() { + if (!GameInteractor::IsSaveLoaded()) { + return GameInteractionEffectQueryResult::TemporarilyNotPossible; + } + + return GameInteractionEffectQueryResult::Possible; +} + +void SetFlag::_Apply() { + GameInteractor::RawAction::SetFlag(parameters[0], parameters[1]); +} + +GameInteractionEffectQueryResult UnsetFlag::CanBeApplied() { + if (!GameInteractor::IsSaveLoaded()) { + return GameInteractionEffectQueryResult::TemporarilyNotPossible; + } + + return GameInteractionEffectQueryResult::Possible; +} + +void UnsetFlag::_Apply() { + GameInteractor::RawAction::UnsetFlag(parameters[0], parameters[1]); +} + +// MARK: - ModifyHeartContainers +GameInteractionEffectQueryResult ModifyHeartContainers::CanBeApplied() { + if (!GameInteractor::IsSaveLoaded()) { + return GameInteractionEffectQueryResult::TemporarilyNotPossible; + } else if ((parameters[0] > 0 && (gSaveContext.healthCapacity + (parameters[0] * 0x10) > 0x140)) || + (parameters[0] < 0 && (gSaveContext.healthCapacity + (parameters[0] * 0x10) < 0x10))) { + return GameInteractionEffectQueryResult::NotPossible; + } + + return GameInteractionEffectQueryResult::Possible; +} + +void ModifyHeartContainers::_Apply() { + GameInteractor::RawAction::AddOrRemoveHealthContainers(parameters[0]); +} + +// MARK: - FillMagic +GameInteractionEffectQueryResult FillMagic::CanBeApplied() { + if (!GameInteractor::IsSaveLoaded()) { + return GameInteractionEffectQueryResult::TemporarilyNotPossible; + } else if (!gSaveContext.isMagicAcquired || gSaveContext.magic >= ((gSaveContext.isDoubleMagicAcquired + 1) * 48)) { + return GameInteractionEffectQueryResult::NotPossible; + } else { return GameInteractionEffectQueryResult::Possible; } - - void SetSceneFlag::_Apply() { - GameInteractor::RawAction::SetSceneFlag(parameters[0], parameters[1], parameters[2]); - } - - GameInteractionEffectQueryResult UnsetSceneFlag::CanBeApplied() { - if (!GameInteractor::IsSaveLoaded()) { - return GameInteractionEffectQueryResult::TemporarilyNotPossible; - } - - return GameInteractionEffectQueryResult::Possible; - } - - void UnsetSceneFlag::_Apply() { - GameInteractor::RawAction::UnsetSceneFlag(parameters[0], parameters[1], parameters[2]); - } - - GameInteractionEffectQueryResult SetFlag::CanBeApplied() { - if (!GameInteractor::IsSaveLoaded()) { - return GameInteractionEffectQueryResult::TemporarilyNotPossible; - } - - return GameInteractionEffectQueryResult::Possible; - } - - void SetFlag::_Apply() { - GameInteractor::RawAction::SetFlag(parameters[0], parameters[1]); - } - - GameInteractionEffectQueryResult UnsetFlag::CanBeApplied() { - if (!GameInteractor::IsSaveLoaded()) { - return GameInteractionEffectQueryResult::TemporarilyNotPossible; - } - - return GameInteractionEffectQueryResult::Possible; - } - - void UnsetFlag::_Apply() { - GameInteractor::RawAction::UnsetFlag(parameters[0], parameters[1]); - } - - // MARK: - ModifyHeartContainers - GameInteractionEffectQueryResult ModifyHeartContainers::CanBeApplied() { - if (!GameInteractor::IsSaveLoaded()) { - return GameInteractionEffectQueryResult::TemporarilyNotPossible; - } else if ( - (parameters[0] > 0 && (gSaveContext.healthCapacity + (parameters[0] * 0x10) > 0x140)) || - (parameters[0] < 0 && (gSaveContext.healthCapacity + (parameters[0] * 0x10) < 0x10)) - ) { - return GameInteractionEffectQueryResult::NotPossible; - } - - return GameInteractionEffectQueryResult::Possible; - } - - void ModifyHeartContainers::_Apply() { - GameInteractor::RawAction::AddOrRemoveHealthContainers(parameters[0]); - } - - // MARK: - FillMagic - GameInteractionEffectQueryResult FillMagic::CanBeApplied() { - if (!GameInteractor::IsSaveLoaded()) { - return GameInteractionEffectQueryResult::TemporarilyNotPossible; - } else if (!gSaveContext.isMagicAcquired || gSaveContext.magic >= ((gSaveContext.isDoubleMagicAcquired + 1) * 48)) { - return GameInteractionEffectQueryResult::NotPossible; - } else { - return GameInteractionEffectQueryResult::Possible; - } - } - void FillMagic::_Apply() { - GameInteractor::RawAction::AddOrRemoveMagic(96); - } - - // MARK: - EmptyMagic - GameInteractionEffectQueryResult EmptyMagic::CanBeApplied() { - if (!GameInteractor::IsSaveLoaded()) { - return GameInteractionEffectQueryResult::TemporarilyNotPossible; - } else if (!gSaveContext.isMagicAcquired || gSaveContext.magic <= 0) { - return GameInteractionEffectQueryResult::NotPossible; - } else { - return GameInteractionEffectQueryResult::Possible; - } - } - void EmptyMagic::_Apply() { - GameInteractor::RawAction::AddOrRemoveMagic(-96); - } - - // MARK: - ModifyRupees - GameInteractionEffectQueryResult ModifyRupees::CanBeApplied() { - if (!GameInteractor::IsSaveLoaded()) { - return GameInteractionEffectQueryResult::TemporarilyNotPossible; - } else if ( - (parameters[0] < 0 && gSaveContext.rupees <= 0) || - (parameters[0] > 0 && gSaveContext.rupees >= CUR_CAPACITY(UPG_WALLET)) - ) { - return GameInteractionEffectQueryResult::NotPossible; - } else { - return GameInteractionEffectQueryResult::Possible; - } - } - void ModifyRupees::_Apply() { - Rupees_ChangeBy(parameters[0]); - } - - // MARK: - NoUI - GameInteractionEffectQueryResult NoUI::CanBeApplied() { - if (!GameInteractor::IsSaveLoaded() || GameInteractor::IsGameplayPaused()) { - return GameInteractionEffectQueryResult::TemporarilyNotPossible; - } else { - return GameInteractionEffectQueryResult::Possible; - } - } - void NoUI::_Apply() { - GameInteractor::State::NoUIActive = 1; - } - void NoUI::_Remove() { - GameInteractor::State::NoUIActive = 0; - } - - // MARK: - ModifyGravity - GameInteractionEffectQueryResult ModifyGravity::CanBeApplied() { - if (!GameInteractor::IsSaveLoaded() || GameInteractor::IsGameplayPaused()) { - return GameInteractionEffectQueryResult::TemporarilyNotPossible; - } else { - return GameInteractionEffectQueryResult::Possible; - } - } - void ModifyGravity::_Apply() { - GameInteractor::State::GravityLevel = (GIGravityLevel)parameters[0]; - } - void ModifyGravity::_Remove() { - GameInteractor::State::GravityLevel = GI_GRAVITY_LEVEL_NORMAL; - } - - // MARK: - ModifyHealth - GameInteractionEffectQueryResult ModifyHealth::CanBeApplied() { - if (!GameInteractor::IsSaveLoaded()) { - return GameInteractionEffectQueryResult::TemporarilyNotPossible; - } else if ( - (parameters[0] > 0 && gSaveContext.health == gSaveContext.healthCapacity) - || (parameters[0] < 0 && (gSaveContext.health + (16 * parameters[0]) <= 0)) - ) { - return GameInteractionEffectQueryResult::NotPossible; - } - - return GameInteractionEffectQueryResult::Possible; - } - void ModifyHealth::_Apply() { - GameInteractor::RawAction::HealOrDamagePlayer(parameters[0]); - } - - // MARK: - SetPlayerHealth - GameInteractionEffectQueryResult SetPlayerHealth::CanBeApplied() { - Player* player = GET_PLAYER(gPlayState); - if (!GameInteractor::IsSaveLoaded() || GameInteractor::IsGameplayPaused()) { - return GameInteractionEffectQueryResult::TemporarilyNotPossible; - } else { - return GameInteractionEffectQueryResult::Possible; - } - } - void SetPlayerHealth::_Apply() { - GameInteractor::RawAction::SetPlayerHealth(parameters[0]); - } - - // MARK: - FreezePlayer - GameInteractionEffectQueryResult FreezePlayer::CanBeApplied() { - Player* player = GET_PLAYER(gPlayState); - if (!GameInteractor::IsSaveLoaded() || GameInteractor::IsGameplayPaused() || !PlayerGrounded(player)) { - return GameInteractionEffectQueryResult::TemporarilyNotPossible; - } else { - return GameInteractionEffectQueryResult::Possible; - } - } - void FreezePlayer::_Apply() { - GameInteractor::RawAction::FreezePlayer(); - } - - // MARK: - BurnPlayer - GameInteractionEffectQueryResult BurnPlayer::CanBeApplied() { - Player* player = GET_PLAYER(gPlayState); - if (!GameInteractor::IsSaveLoaded() || GameInteractor::IsGameplayPaused() || !PlayerGrounded(player)) { - return GameInteractionEffectQueryResult::TemporarilyNotPossible; - } else { - return GameInteractionEffectQueryResult::Possible; - } - } - void BurnPlayer::_Apply() { - GameInteractor::RawAction::BurnPlayer(); - } - - // MARK: - ElectrocutePlayer - GameInteractionEffectQueryResult ElectrocutePlayer::CanBeApplied() { - Player* player = GET_PLAYER(gPlayState); - if (!GameInteractor::IsSaveLoaded() || GameInteractor::IsGameplayPaused() || !PlayerGrounded(player)) { - return GameInteractionEffectQueryResult::TemporarilyNotPossible; - } else { - return GameInteractionEffectQueryResult::Possible; - } - } - void ElectrocutePlayer::_Apply() { - GameInteractor::RawAction::ElectrocutePlayer(); - } - - // MARK: - KnockbackPlayer - GameInteractionEffectQueryResult KnockbackPlayer::CanBeApplied() { - Player* player = GET_PLAYER(gPlayState); - if (!GameInteractor::IsSaveLoaded() || GameInteractor::IsGameplayPaused() || player->stateFlags2 & PLAYER_STATE2_CRAWLING) { - return GameInteractionEffectQueryResult::TemporarilyNotPossible; - } else { - return GameInteractionEffectQueryResult::Possible; - } - } - void KnockbackPlayer::_Apply() { - GameInteractor::RawAction::KnockbackPlayer(parameters[0]); - } - - // MARK: - ModifyLinkSize - GameInteractionEffectQueryResult ModifyLinkSize::CanBeApplied() { - if (!GameInteractor::IsSaveLoaded() || GameInteractor::IsGameplayPaused()) { - return GameInteractionEffectQueryResult::TemporarilyNotPossible; - } else { - return GameInteractionEffectQueryResult::Possible; - } - } - void ModifyLinkSize::_Apply() { - GameInteractor::State::LinkSize = (GILinkSize)parameters[0]; - } - void ModifyLinkSize::_Remove() { - GameInteractor::State::LinkSize = GI_LINK_SIZE_RESET; - } - - // MARK: - InvisibleLink - GameInteractionEffectQueryResult InvisibleLink::CanBeApplied() { - if (!GameInteractor::IsSaveLoaded() || GameInteractor::IsGameplayPaused()) { - return GameInteractionEffectQueryResult::TemporarilyNotPossible; - } else { - return GameInteractionEffectQueryResult::Possible; - } - } - void InvisibleLink::_Apply() { - GameInteractor::RawAction::SetLinkInvisibility(true); - } - void InvisibleLink::_Remove() { - GameInteractor::RawAction::SetLinkInvisibility(false); - } - - // MARK: - PacifistMode - GameInteractionEffectQueryResult PacifistMode::CanBeApplied() { - if (!GameInteractor::IsSaveLoaded() || GameInteractor::IsGameplayPaused()) { - return GameInteractionEffectQueryResult::TemporarilyNotPossible; - } else { - return GameInteractionEffectQueryResult::Possible; - } - } - void PacifistMode::_Apply() { - GameInteractor::State::SetPacifistMode(true); - } - void PacifistMode::_Remove() { - GameInteractor::State::SetPacifistMode(false); - } - - // MARK: - DisableZTargeting - GameInteractionEffectQueryResult DisableZTargeting::CanBeApplied() { - if (!GameInteractor::IsSaveLoaded() || GameInteractor::IsGameplayPaused()) { - return GameInteractionEffectQueryResult::TemporarilyNotPossible; - } else { - return GameInteractionEffectQueryResult::Possible; - } - } - void DisableZTargeting::_Apply() { - GameInteractor::State::DisableZTargetingActive = 1; - } - void DisableZTargeting::_Remove() { - GameInteractor::State::DisableZTargetingActive = 0; - } - - // MARK: - WeatherRainstorm - GameInteractionEffectQueryResult WeatherRainstorm::CanBeApplied() { - if (!GameInteractor::IsSaveLoaded() || GameInteractor::IsGameplayPaused()) { - return GameInteractionEffectQueryResult::TemporarilyNotPossible; - } else { - return GameInteractionEffectQueryResult::Possible; - } - } - void WeatherRainstorm::_Apply() { - GameInteractor::RawAction::SetWeatherStorm(true); - } - void WeatherRainstorm::_Remove() { - GameInteractor::RawAction::SetWeatherStorm(false); - } - - // MARK: - ReverseControls - GameInteractionEffectQueryResult ReverseControls::CanBeApplied() { - if (!GameInteractor::IsSaveLoaded()) { - return GameInteractionEffectQueryResult::TemporarilyNotPossible; - } else { - return GameInteractionEffectQueryResult::Possible; - } - } - void ReverseControls::_Apply() { - GameInteractor::State::ReverseControlsActive = 1; - } - void ReverseControls::_Remove() { - GameInteractor::State::ReverseControlsActive = 0; - } - - // MARK: - ForceEquipBoots - GameInteractionEffectQueryResult ForceEquipBoots::CanBeApplied() { - if (!GameInteractor::IsSaveLoaded() || GameInteractor::IsGameplayPaused()) { - return GameInteractionEffectQueryResult::TemporarilyNotPossible; - } else { - return GameInteractionEffectQueryResult::Possible; - } - } - void ForceEquipBoots::_Apply() { - GameInteractor::RawAction::ForceEquipBoots(parameters[0]); - } - void ForceEquipBoots::_Remove() { - GameInteractor::RawAction::ForceEquipBoots(EQUIP_VALUE_BOOTS_KOKIRI); - } - - // MARK: - ModifyRunSpeedModifier - GameInteractionEffectQueryResult ModifyRunSpeedModifier::CanBeApplied() { - if (!GameInteractor::IsSaveLoaded() || GameInteractor::IsGameplayPaused()) { - return GameInteractionEffectQueryResult::TemporarilyNotPossible; - } else { - return GameInteractionEffectQueryResult::Possible; - } - } - void ModifyRunSpeedModifier::_Apply() { - GameInteractor::State::RunSpeedModifier = parameters[0]; - } - void ModifyRunSpeedModifier::_Remove() { - GameInteractor::State::RunSpeedModifier = 0; - } - - // MARK: - OneHitKO - GameInteractionEffectQueryResult OneHitKO::CanBeApplied() { - if (!GameInteractor::IsSaveLoaded() || GameInteractor::IsGameplayPaused()) { - return GameInteractionEffectQueryResult::TemporarilyNotPossible; - } else { - return GameInteractionEffectQueryResult::Possible; - } - } - void OneHitKO::_Apply() { - GameInteractor::State::OneHitKOActive = 1; - } - void OneHitKO::_Remove() { - GameInteractor::State::OneHitKOActive = 0; - } - - // MARK: - ModifyDefenseModifier - GameInteractionEffectQueryResult ModifyDefenseModifier::CanBeApplied() { - if (!GameInteractor::IsSaveLoaded() || GameInteractor::IsGameplayPaused()) { - return GameInteractionEffectQueryResult::TemporarilyNotPossible; - } else { - return GameInteractionEffectQueryResult::Possible; - } - } - void ModifyDefenseModifier::_Apply() { - GameInteractor::State::DefenseModifier = parameters[0]; - } - void ModifyDefenseModifier::_Remove() { - GameInteractor::State::DefenseModifier = 0; - } - - // MARK: - GiveOrTakeShield - GameInteractionEffectQueryResult GiveOrTakeShield::CanBeApplied() { - if (!GameInteractor::IsSaveLoaded() || GameInteractor::IsGameplayPaused()) { - return GameInteractionEffectQueryResult::TemporarilyNotPossible; - } else if ((parameters[0] > 0 && ((gBitFlags[parameters[0] - ITEM_SHIELD_DEKU] << gEquipShifts[EQUIP_TYPE_SHIELD]) & - gSaveContext.inventory.equipment)) || - (parameters[0] < 0 && !((gBitFlags[(parameters[0] * -1) - ITEM_SHIELD_DEKU] << gEquipShifts[EQUIP_TYPE_SHIELD]) & - gSaveContext.inventory.equipment))) { - return GameInteractionEffectQueryResult::NotPossible; - } else { - return GameInteractionEffectQueryResult::Possible; - } - } - void GiveOrTakeShield::_Apply() { - GameInteractor::RawAction::GiveOrTakeShield(parameters[0]); - } - - // MARK: - TeleportPlayer - GameInteractionEffectQueryResult TeleportPlayer::CanBeApplied() { - if (!GameInteractor::IsSaveLoaded() || GameInteractor::IsGameplayPaused()) { - return GameInteractionEffectQueryResult::TemporarilyNotPossible; - } else { - return GameInteractionEffectQueryResult::Possible; - } - } - void TeleportPlayer::_Apply() { - GameInteractor::RawAction::TeleportPlayer(parameters[0]); - } - - // MARK: - ClearAssignedButtons - GameInteractionEffectQueryResult ClearAssignedButtons::CanBeApplied() { - if (!GameInteractor::IsSaveLoaded()) { - return GameInteractionEffectQueryResult::TemporarilyNotPossible; - } else { - return GameInteractionEffectQueryResult::Possible; - } - } - void ClearAssignedButtons::_Apply() { - GameInteractor::RawAction::ClearAssignedButtons(parameters[0]); - } - - // MARK: - SetTimeOfDay - GameInteractionEffectQueryResult SetTimeOfDay::CanBeApplied() { - if (!GameInteractor::IsSaveLoaded()) { - return GameInteractionEffectQueryResult::TemporarilyNotPossible; - } else { - return GameInteractionEffectQueryResult::Possible; - } - } - void SetTimeOfDay::_Apply() { - GameInteractor::RawAction::SetTimeOfDay(parameters[0]); - } - - // MARK: - SetCollisionViewer - GameInteractionEffectQueryResult SetCollisionViewer::CanBeApplied() { - if (!GameInteractor::IsSaveLoaded() || GameInteractor::IsGameplayPaused()) { - return GameInteractionEffectQueryResult::TemporarilyNotPossible; - } else { - return GameInteractionEffectQueryResult::Possible; - } - } - void SetCollisionViewer::_Apply() { - GameInteractor::RawAction::SetCollisionViewer(true); - } - void SetCollisionViewer::_Remove() { - GameInteractor::RawAction::SetCollisionViewer(false); - } - - // MARK: - SetCosmeticsColor - GameInteractionEffectQueryResult SetCosmeticsColor::CanBeApplied() { - if (!GameInteractor::IsSaveLoaded()) { - return GameInteractionEffectQueryResult::TemporarilyNotPossible; - } else { - return GameInteractionEffectQueryResult::Possible; - } - } - void SetCosmeticsColor::_Apply() { - GameInteractor::RawAction::SetCosmeticsColor(parameters[0], parameters[1]); - } - - // MARK: - RandomizeCosmetics - GameInteractionEffectQueryResult RandomizeCosmetics::CanBeApplied() { - if (!GameInteractor::IsSaveLoaded()) { - return GameInteractionEffectQueryResult::TemporarilyNotPossible; - } else { - return GameInteractionEffectQueryResult::Possible; - } - } - void RandomizeCosmetics::_Apply() { - GameInteractor::RawAction::RandomizeCosmeticsColors(true); - } - - // MARK: - PressButton - GameInteractionEffectQueryResult PressButton::CanBeApplied() { - if (!GameInteractor::IsSaveLoaded()) { - return GameInteractionEffectQueryResult::TemporarilyNotPossible; - } else { - return GameInteractionEffectQueryResult::Possible; - } - } - void PressButton::_Apply() { - GameInteractor::RawAction::EmulateButtonPress(parameters[0]); - } - - // MARK: - PressRandomButton - GameInteractionEffectQueryResult PressRandomButton::CanBeApplied() { - if (!GameInteractor::IsSaveLoaded()) { - return GameInteractionEffectQueryResult::TemporarilyNotPossible; - } else { - return GameInteractionEffectQueryResult::Possible; - } - } - void PressRandomButton::_Apply() { - GameInteractor::RawAction::EmulateRandomButtonPress(parameters[0]); - } - - // MARK: - AddOrTakeAmmo - GameInteractionEffectQueryResult AddOrTakeAmmo::CanBeApplied() { - if (!GameInteractor::IsSaveLoaded()) { - return GameInteractionEffectQueryResult::TemporarilyNotPossible; - } else if (!GameInteractor::CanAddOrTakeAmmo(parameters[0], parameters[1])) { - return GameInteractionEffectQueryResult::NotPossible; - } else { - return GameInteractionEffectQueryResult::Possible; - } - } - void AddOrTakeAmmo::_Apply() { - GameInteractor::RawAction::AddOrTakeAmmo(parameters[0], parameters[1]); - } - - // MARK: - RandomBombFuseTimer - GameInteractionEffectQueryResult RandomBombFuseTimer::CanBeApplied() { - if (!GameInteractor::IsSaveLoaded() || GameInteractor::IsGameplayPaused()) { - return GameInteractionEffectQueryResult::TemporarilyNotPossible; - } else { - return GameInteractionEffectQueryResult::Possible; - } - } - void RandomBombFuseTimer::_Apply() { - GameInteractor::State::RandomBombFuseTimerActive = 1; - } - void RandomBombFuseTimer::_Remove() { - GameInteractor::State::RandomBombFuseTimerActive = 0; - } - - // MARK: - DisableLedgeGrabs - GameInteractionEffectQueryResult DisableLedgeGrabs::CanBeApplied() { - if (!GameInteractor::IsSaveLoaded() || GameInteractor::IsGameplayPaused()) { - return GameInteractionEffectQueryResult::TemporarilyNotPossible; - } else { - return GameInteractionEffectQueryResult::Possible; - } - } - void DisableLedgeGrabs::_Apply() { - GameInteractor::State::DisableLedgeGrabsActive = 1; - } - void DisableLedgeGrabs::_Remove() { - GameInteractor::State::DisableLedgeGrabsActive = 0; - } - - // MARK: - RandomWind - GameInteractionEffectQueryResult RandomWind::CanBeApplied() { - if (!GameInteractor::IsSaveLoaded() || GameInteractor::IsGameplayPaused()) { - return GameInteractionEffectQueryResult::TemporarilyNotPossible; - } else { - return GameInteractionEffectQueryResult::Possible; - } - } - void RandomWind::_Apply() { - GameInteractor::RawAction::SetRandomWind(true); - } - void RandomWind::_Remove() { - GameInteractor::RawAction::SetRandomWind(false); - } - - // MARK: - RandomBonks - GameInteractionEffectQueryResult RandomBonks::CanBeApplied() { - if (!GameInteractor::IsSaveLoaded() || GameInteractor::IsGameplayPaused()) { - return GameInteractionEffectQueryResult::TemporarilyNotPossible; - } else { - return GameInteractionEffectQueryResult::Possible; - } - } - void RandomBonks::_Apply() { - GameInteractor::State::RandomBonksActive = 1; - } - void RandomBonks::_Remove() { - GameInteractor::State::RandomBonksActive = 0; - } - - // MARK: - PlayerInvincibility - GameInteractionEffectQueryResult PlayerInvincibility::CanBeApplied() { - if (!GameInteractor::IsSaveLoaded() || GameInteractor::IsGameplayPaused()) { - return GameInteractionEffectQueryResult::TemporarilyNotPossible; - } else { - return GameInteractionEffectQueryResult::Possible; - } - } - void PlayerInvincibility::_Apply() { - GameInteractor::RawAction::SetPlayerInvincibility(true); - } - void PlayerInvincibility::_Remove() { - GameInteractor::RawAction::SetPlayerInvincibility(false); - } - - // MARK: - SlipperyFloor - GameInteractionEffectQueryResult SlipperyFloor::CanBeApplied() { - if (!GameInteractor::IsSaveLoaded() || GameInteractor::IsGameplayPaused()) { - return GameInteractionEffectQueryResult::TemporarilyNotPossible; - } else { - return GameInteractionEffectQueryResult::Possible; - } - } - void SlipperyFloor::_Apply() { - GameInteractor::State::SlipperyFloorActive = 1; - } - void SlipperyFloor::_Remove() { - GameInteractor::State::SlipperyFloorActive = 0; - } - - // MARK: - SpawnEnemyWithOffset - GameInteractionEffectQueryResult SpawnEnemyWithOffset::CanBeApplied() { - if (!GameInteractor::IsSaveLoaded()) { - return GameInteractionEffectQueryResult::TemporarilyNotPossible; - } - return GameInteractor::RawAction::SpawnEnemyWithOffset(parameters[0], parameters[1]); - } - - void SpawnEnemyWithOffset::_Apply() { - GameInteractor::RawAction::SpawnEnemyWithOffset(parameters[0], parameters[1]); - } - - // MARK: - SpawnActor - GameInteractionEffectQueryResult SpawnActor::CanBeApplied() { - if (!GameInteractor::IsSaveLoaded()) { - return GameInteractionEffectQueryResult::TemporarilyNotPossible; - } - return GameInteractor::RawAction::SpawnActor(parameters[0], parameters[1]); - } - - void SpawnActor::_Apply() { - GameInteractor::RawAction::SpawnActor(parameters[0], parameters[1]); - } } +void FillMagic::_Apply() { + GameInteractor::RawAction::AddOrRemoveMagic(96); +} + +// MARK: - EmptyMagic +GameInteractionEffectQueryResult EmptyMagic::CanBeApplied() { + if (!GameInteractor::IsSaveLoaded()) { + return GameInteractionEffectQueryResult::TemporarilyNotPossible; + } else if (!gSaveContext.isMagicAcquired || gSaveContext.magic <= 0) { + return GameInteractionEffectQueryResult::NotPossible; + } else { + return GameInteractionEffectQueryResult::Possible; + } +} +void EmptyMagic::_Apply() { + GameInteractor::RawAction::AddOrRemoveMagic(-96); +} + +// MARK: - ModifyRupees +GameInteractionEffectQueryResult ModifyRupees::CanBeApplied() { + if (!GameInteractor::IsSaveLoaded()) { + return GameInteractionEffectQueryResult::TemporarilyNotPossible; + } else if ((parameters[0] < 0 && gSaveContext.rupees <= 0) || + (parameters[0] > 0 && gSaveContext.rupees >= CUR_CAPACITY(UPG_WALLET))) { + return GameInteractionEffectQueryResult::NotPossible; + } else { + return GameInteractionEffectQueryResult::Possible; + } +} +void ModifyRupees::_Apply() { + Rupees_ChangeBy(parameters[0]); +} + +// MARK: - NoUI +GameInteractionEffectQueryResult NoUI::CanBeApplied() { + if (!GameInteractor::IsSaveLoaded() || GameInteractor::IsGameplayPaused()) { + return GameInteractionEffectQueryResult::TemporarilyNotPossible; + } else { + return GameInteractionEffectQueryResult::Possible; + } +} +void NoUI::_Apply() { + GameInteractor::State::NoUIActive = 1; +} +void NoUI::_Remove() { + GameInteractor::State::NoUIActive = 0; +} + +// MARK: - ModifyGravity +GameInteractionEffectQueryResult ModifyGravity::CanBeApplied() { + if (!GameInteractor::IsSaveLoaded() || GameInteractor::IsGameplayPaused()) { + return GameInteractionEffectQueryResult::TemporarilyNotPossible; + } else { + return GameInteractionEffectQueryResult::Possible; + } +} +void ModifyGravity::_Apply() { + GameInteractor::State::GravityLevel = (GIGravityLevel)parameters[0]; +} +void ModifyGravity::_Remove() { + GameInteractor::State::GravityLevel = GI_GRAVITY_LEVEL_NORMAL; +} + +// MARK: - ModifyHealth +GameInteractionEffectQueryResult ModifyHealth::CanBeApplied() { + if (!GameInteractor::IsSaveLoaded()) { + return GameInteractionEffectQueryResult::TemporarilyNotPossible; + } else if ((parameters[0] > 0 && gSaveContext.health == gSaveContext.healthCapacity) || + (parameters[0] < 0 && (gSaveContext.health + (16 * parameters[0]) <= 0))) { + return GameInteractionEffectQueryResult::NotPossible; + } + + return GameInteractionEffectQueryResult::Possible; +} +void ModifyHealth::_Apply() { + GameInteractor::RawAction::HealOrDamagePlayer(parameters[0]); +} + +// MARK: - SetPlayerHealth +GameInteractionEffectQueryResult SetPlayerHealth::CanBeApplied() { + Player* player = GET_PLAYER(gPlayState); + if (!GameInteractor::IsSaveLoaded() || GameInteractor::IsGameplayPaused()) { + return GameInteractionEffectQueryResult::TemporarilyNotPossible; + } else { + return GameInteractionEffectQueryResult::Possible; + } +} +void SetPlayerHealth::_Apply() { + GameInteractor::RawAction::SetPlayerHealth(parameters[0]); +} + +// MARK: - FreezePlayer +GameInteractionEffectQueryResult FreezePlayer::CanBeApplied() { + Player* player = GET_PLAYER(gPlayState); + if (!GameInteractor::IsSaveLoaded() || GameInteractor::IsGameplayPaused() || !PlayerGrounded(player)) { + return GameInteractionEffectQueryResult::TemporarilyNotPossible; + } else { + return GameInteractionEffectQueryResult::Possible; + } +} +void FreezePlayer::_Apply() { + GameInteractor::RawAction::FreezePlayer(); +} + +// MARK: - BurnPlayer +GameInteractionEffectQueryResult BurnPlayer::CanBeApplied() { + Player* player = GET_PLAYER(gPlayState); + if (!GameInteractor::IsSaveLoaded() || GameInteractor::IsGameplayPaused() || !PlayerGrounded(player)) { + return GameInteractionEffectQueryResult::TemporarilyNotPossible; + } else { + return GameInteractionEffectQueryResult::Possible; + } +} +void BurnPlayer::_Apply() { + GameInteractor::RawAction::BurnPlayer(); +} + +// MARK: - ElectrocutePlayer +GameInteractionEffectQueryResult ElectrocutePlayer::CanBeApplied() { + Player* player = GET_PLAYER(gPlayState); + if (!GameInteractor::IsSaveLoaded() || GameInteractor::IsGameplayPaused() || !PlayerGrounded(player)) { + return GameInteractionEffectQueryResult::TemporarilyNotPossible; + } else { + return GameInteractionEffectQueryResult::Possible; + } +} +void ElectrocutePlayer::_Apply() { + GameInteractor::RawAction::ElectrocutePlayer(); +} + +// MARK: - KnockbackPlayer +GameInteractionEffectQueryResult KnockbackPlayer::CanBeApplied() { + Player* player = GET_PLAYER(gPlayState); + if (!GameInteractor::IsSaveLoaded() || GameInteractor::IsGameplayPaused() || + player->stateFlags2 & PLAYER_STATE2_CRAWLING) { + return GameInteractionEffectQueryResult::TemporarilyNotPossible; + } else { + return GameInteractionEffectQueryResult::Possible; + } +} +void KnockbackPlayer::_Apply() { + GameInteractor::RawAction::KnockbackPlayer(parameters[0]); +} + +// MARK: - ModifyLinkSize +GameInteractionEffectQueryResult ModifyLinkSize::CanBeApplied() { + if (!GameInteractor::IsSaveLoaded() || GameInteractor::IsGameplayPaused()) { + return GameInteractionEffectQueryResult::TemporarilyNotPossible; + } else { + return GameInteractionEffectQueryResult::Possible; + } +} +void ModifyLinkSize::_Apply() { + GameInteractor::State::LinkSize = (GILinkSize)parameters[0]; +} +void ModifyLinkSize::_Remove() { + GameInteractor::State::LinkSize = GI_LINK_SIZE_RESET; +} + +// MARK: - InvisibleLink +GameInteractionEffectQueryResult InvisibleLink::CanBeApplied() { + if (!GameInteractor::IsSaveLoaded() || GameInteractor::IsGameplayPaused()) { + return GameInteractionEffectQueryResult::TemporarilyNotPossible; + } else { + return GameInteractionEffectQueryResult::Possible; + } +} +void InvisibleLink::_Apply() { + GameInteractor::RawAction::SetLinkInvisibility(true); +} +void InvisibleLink::_Remove() { + GameInteractor::RawAction::SetLinkInvisibility(false); +} + +// MARK: - PacifistMode +GameInteractionEffectQueryResult PacifistMode::CanBeApplied() { + if (!GameInteractor::IsSaveLoaded() || GameInteractor::IsGameplayPaused()) { + return GameInteractionEffectQueryResult::TemporarilyNotPossible; + } else { + return GameInteractionEffectQueryResult::Possible; + } +} +void PacifistMode::_Apply() { + GameInteractor::State::SetPacifistMode(true); +} +void PacifistMode::_Remove() { + GameInteractor::State::SetPacifistMode(false); +} + +// MARK: - DisableZTargeting +GameInteractionEffectQueryResult DisableZTargeting::CanBeApplied() { + if (!GameInteractor::IsSaveLoaded() || GameInteractor::IsGameplayPaused()) { + return GameInteractionEffectQueryResult::TemporarilyNotPossible; + } else { + return GameInteractionEffectQueryResult::Possible; + } +} +void DisableZTargeting::_Apply() { + GameInteractor::State::DisableZTargetingActive = 1; +} +void DisableZTargeting::_Remove() { + GameInteractor::State::DisableZTargetingActive = 0; +} + +// MARK: - WeatherRainstorm +GameInteractionEffectQueryResult WeatherRainstorm::CanBeApplied() { + if (!GameInteractor::IsSaveLoaded() || GameInteractor::IsGameplayPaused()) { + return GameInteractionEffectQueryResult::TemporarilyNotPossible; + } else { + return GameInteractionEffectQueryResult::Possible; + } +} +void WeatherRainstorm::_Apply() { + GameInteractor::RawAction::SetWeatherStorm(true); +} +void WeatherRainstorm::_Remove() { + GameInteractor::RawAction::SetWeatherStorm(false); +} + +// MARK: - ReverseControls +GameInteractionEffectQueryResult ReverseControls::CanBeApplied() { + if (!GameInteractor::IsSaveLoaded()) { + return GameInteractionEffectQueryResult::TemporarilyNotPossible; + } else { + return GameInteractionEffectQueryResult::Possible; + } +} +void ReverseControls::_Apply() { + GameInteractor::State::ReverseControlsActive = 1; +} +void ReverseControls::_Remove() { + GameInteractor::State::ReverseControlsActive = 0; +} + +// MARK: - ForceEquipBoots +GameInteractionEffectQueryResult ForceEquipBoots::CanBeApplied() { + if (!GameInteractor::IsSaveLoaded() || GameInteractor::IsGameplayPaused()) { + return GameInteractionEffectQueryResult::TemporarilyNotPossible; + } else { + return GameInteractionEffectQueryResult::Possible; + } +} +void ForceEquipBoots::_Apply() { + GameInteractor::RawAction::ForceEquipBoots(parameters[0]); +} +void ForceEquipBoots::_Remove() { + GameInteractor::RawAction::ForceEquipBoots(EQUIP_VALUE_BOOTS_KOKIRI); +} + +// MARK: - ModifyRunSpeedModifier +GameInteractionEffectQueryResult ModifyRunSpeedModifier::CanBeApplied() { + if (!GameInteractor::IsSaveLoaded() || GameInteractor::IsGameplayPaused()) { + return GameInteractionEffectQueryResult::TemporarilyNotPossible; + } else { + return GameInteractionEffectQueryResult::Possible; + } +} +void ModifyRunSpeedModifier::_Apply() { + GameInteractor::State::RunSpeedModifier = parameters[0]; +} +void ModifyRunSpeedModifier::_Remove() { + GameInteractor::State::RunSpeedModifier = 0; +} + +// MARK: - OneHitKO +GameInteractionEffectQueryResult OneHitKO::CanBeApplied() { + if (!GameInteractor::IsSaveLoaded() || GameInteractor::IsGameplayPaused()) { + return GameInteractionEffectQueryResult::TemporarilyNotPossible; + } else { + return GameInteractionEffectQueryResult::Possible; + } +} +void OneHitKO::_Apply() { + GameInteractor::State::OneHitKOActive = 1; +} +void OneHitKO::_Remove() { + GameInteractor::State::OneHitKOActive = 0; +} + +// MARK: - ModifyDefenseModifier +GameInteractionEffectQueryResult ModifyDefenseModifier::CanBeApplied() { + if (!GameInteractor::IsSaveLoaded() || GameInteractor::IsGameplayPaused()) { + return GameInteractionEffectQueryResult::TemporarilyNotPossible; + } else { + return GameInteractionEffectQueryResult::Possible; + } +} +void ModifyDefenseModifier::_Apply() { + GameInteractor::State::DefenseModifier = parameters[0]; +} +void ModifyDefenseModifier::_Remove() { + GameInteractor::State::DefenseModifier = 0; +} + +// MARK: - GiveOrTakeShield +GameInteractionEffectQueryResult GiveOrTakeShield::CanBeApplied() { + if (!GameInteractor::IsSaveLoaded() || GameInteractor::IsGameplayPaused()) { + return GameInteractionEffectQueryResult::TemporarilyNotPossible; + } else if ((parameters[0] > 0 && ((gBitFlags[parameters[0] - ITEM_SHIELD_DEKU] << gEquipShifts[EQUIP_TYPE_SHIELD]) & + gSaveContext.inventory.equipment)) || + (parameters[0] < 0 && + !((gBitFlags[(parameters[0] * -1) - ITEM_SHIELD_DEKU] << gEquipShifts[EQUIP_TYPE_SHIELD]) & + gSaveContext.inventory.equipment))) { + return GameInteractionEffectQueryResult::NotPossible; + } else { + return GameInteractionEffectQueryResult::Possible; + } +} +void GiveOrTakeShield::_Apply() { + GameInteractor::RawAction::GiveOrTakeShield(parameters[0]); +} + +// MARK: - TeleportPlayer +GameInteractionEffectQueryResult TeleportPlayer::CanBeApplied() { + if (!GameInteractor::IsSaveLoaded() || GameInteractor::IsGameplayPaused()) { + return GameInteractionEffectQueryResult::TemporarilyNotPossible; + } else { + return GameInteractionEffectQueryResult::Possible; + } +} +void TeleportPlayer::_Apply() { + GameInteractor::RawAction::TeleportPlayer(parameters[0]); +} + +// MARK: - ClearAssignedButtons +GameInteractionEffectQueryResult ClearAssignedButtons::CanBeApplied() { + if (!GameInteractor::IsSaveLoaded()) { + return GameInteractionEffectQueryResult::TemporarilyNotPossible; + } else { + return GameInteractionEffectQueryResult::Possible; + } +} +void ClearAssignedButtons::_Apply() { + GameInteractor::RawAction::ClearAssignedButtons(parameters[0]); +} + +// MARK: - SetTimeOfDay +GameInteractionEffectQueryResult SetTimeOfDay::CanBeApplied() { + if (!GameInteractor::IsSaveLoaded()) { + return GameInteractionEffectQueryResult::TemporarilyNotPossible; + } else { + return GameInteractionEffectQueryResult::Possible; + } +} +void SetTimeOfDay::_Apply() { + GameInteractor::RawAction::SetTimeOfDay(parameters[0]); +} + +// MARK: - SetCollisionViewer +GameInteractionEffectQueryResult SetCollisionViewer::CanBeApplied() { + if (!GameInteractor::IsSaveLoaded() || GameInteractor::IsGameplayPaused()) { + return GameInteractionEffectQueryResult::TemporarilyNotPossible; + } else { + return GameInteractionEffectQueryResult::Possible; + } +} +void SetCollisionViewer::_Apply() { + GameInteractor::RawAction::SetCollisionViewer(true); +} +void SetCollisionViewer::_Remove() { + GameInteractor::RawAction::SetCollisionViewer(false); +} + +// MARK: - SetCosmeticsColor +GameInteractionEffectQueryResult SetCosmeticsColor::CanBeApplied() { + if (!GameInteractor::IsSaveLoaded()) { + return GameInteractionEffectQueryResult::TemporarilyNotPossible; + } else { + return GameInteractionEffectQueryResult::Possible; + } +} +void SetCosmeticsColor::_Apply() { + GameInteractor::RawAction::SetCosmeticsColor(parameters[0], parameters[1]); +} + +// MARK: - RandomizeCosmetics +GameInteractionEffectQueryResult RandomizeCosmetics::CanBeApplied() { + if (!GameInteractor::IsSaveLoaded()) { + return GameInteractionEffectQueryResult::TemporarilyNotPossible; + } else { + return GameInteractionEffectQueryResult::Possible; + } +} +void RandomizeCosmetics::_Apply() { + GameInteractor::RawAction::RandomizeCosmeticsColors(true); +} + +// MARK: - PressButton +GameInteractionEffectQueryResult PressButton::CanBeApplied() { + if (!GameInteractor::IsSaveLoaded()) { + return GameInteractionEffectQueryResult::TemporarilyNotPossible; + } else { + return GameInteractionEffectQueryResult::Possible; + } +} +void PressButton::_Apply() { + GameInteractor::RawAction::EmulateButtonPress(parameters[0]); +} + +// MARK: - PressRandomButton +GameInteractionEffectQueryResult PressRandomButton::CanBeApplied() { + if (!GameInteractor::IsSaveLoaded()) { + return GameInteractionEffectQueryResult::TemporarilyNotPossible; + } else { + return GameInteractionEffectQueryResult::Possible; + } +} +void PressRandomButton::_Apply() { + GameInteractor::RawAction::EmulateRandomButtonPress(parameters[0]); +} + +// MARK: - AddOrTakeAmmo +GameInteractionEffectQueryResult AddOrTakeAmmo::CanBeApplied() { + if (!GameInteractor::IsSaveLoaded()) { + return GameInteractionEffectQueryResult::TemporarilyNotPossible; + } else if (!GameInteractor::CanAddOrTakeAmmo(parameters[0], parameters[1])) { + return GameInteractionEffectQueryResult::NotPossible; + } else { + return GameInteractionEffectQueryResult::Possible; + } +} +void AddOrTakeAmmo::_Apply() { + GameInteractor::RawAction::AddOrTakeAmmo(parameters[0], parameters[1]); +} + +// MARK: - RandomBombFuseTimer +GameInteractionEffectQueryResult RandomBombFuseTimer::CanBeApplied() { + if (!GameInteractor::IsSaveLoaded() || GameInteractor::IsGameplayPaused()) { + return GameInteractionEffectQueryResult::TemporarilyNotPossible; + } else { + return GameInteractionEffectQueryResult::Possible; + } +} +void RandomBombFuseTimer::_Apply() { + GameInteractor::State::RandomBombFuseTimerActive = 1; +} +void RandomBombFuseTimer::_Remove() { + GameInteractor::State::RandomBombFuseTimerActive = 0; +} + +// MARK: - DisableLedgeGrabs +GameInteractionEffectQueryResult DisableLedgeGrabs::CanBeApplied() { + if (!GameInteractor::IsSaveLoaded() || GameInteractor::IsGameplayPaused()) { + return GameInteractionEffectQueryResult::TemporarilyNotPossible; + } else { + return GameInteractionEffectQueryResult::Possible; + } +} +void DisableLedgeGrabs::_Apply() { + GameInteractor::State::DisableLedgeGrabsActive = 1; +} +void DisableLedgeGrabs::_Remove() { + GameInteractor::State::DisableLedgeGrabsActive = 0; +} + +// MARK: - RandomWind +GameInteractionEffectQueryResult RandomWind::CanBeApplied() { + if (!GameInteractor::IsSaveLoaded() || GameInteractor::IsGameplayPaused()) { + return GameInteractionEffectQueryResult::TemporarilyNotPossible; + } else { + return GameInteractionEffectQueryResult::Possible; + } +} +void RandomWind::_Apply() { + GameInteractor::RawAction::SetRandomWind(true); +} +void RandomWind::_Remove() { + GameInteractor::RawAction::SetRandomWind(false); +} + +// MARK: - RandomBonks +GameInteractionEffectQueryResult RandomBonks::CanBeApplied() { + if (!GameInteractor::IsSaveLoaded() || GameInteractor::IsGameplayPaused()) { + return GameInteractionEffectQueryResult::TemporarilyNotPossible; + } else { + return GameInteractionEffectQueryResult::Possible; + } +} +void RandomBonks::_Apply() { + GameInteractor::State::RandomBonksActive = 1; +} +void RandomBonks::_Remove() { + GameInteractor::State::RandomBonksActive = 0; +} + +// MARK: - PlayerInvincibility +GameInteractionEffectQueryResult PlayerInvincibility::CanBeApplied() { + if (!GameInteractor::IsSaveLoaded() || GameInteractor::IsGameplayPaused()) { + return GameInteractionEffectQueryResult::TemporarilyNotPossible; + } else { + return GameInteractionEffectQueryResult::Possible; + } +} +void PlayerInvincibility::_Apply() { + GameInteractor::RawAction::SetPlayerInvincibility(true); +} +void PlayerInvincibility::_Remove() { + GameInteractor::RawAction::SetPlayerInvincibility(false); +} + +// MARK: - SlipperyFloor +GameInteractionEffectQueryResult SlipperyFloor::CanBeApplied() { + if (!GameInteractor::IsSaveLoaded() || GameInteractor::IsGameplayPaused()) { + return GameInteractionEffectQueryResult::TemporarilyNotPossible; + } else { + return GameInteractionEffectQueryResult::Possible; + } +} +void SlipperyFloor::_Apply() { + GameInteractor::State::SlipperyFloorActive = 1; +} +void SlipperyFloor::_Remove() { + GameInteractor::State::SlipperyFloorActive = 0; +} + +// MARK: - SpawnEnemyWithOffset +GameInteractionEffectQueryResult SpawnEnemyWithOffset::CanBeApplied() { + if (!GameInteractor::IsSaveLoaded()) { + return GameInteractionEffectQueryResult::TemporarilyNotPossible; + } + return GameInteractor::RawAction::SpawnEnemyWithOffset(parameters[0], parameters[1]); +} + +void SpawnEnemyWithOffset::_Apply() { + GameInteractor::RawAction::SpawnEnemyWithOffset(parameters[0], parameters[1]); +} + +// MARK: - SpawnActor +GameInteractionEffectQueryResult SpawnActor::CanBeApplied() { + if (!GameInteractor::IsSaveLoaded()) { + return GameInteractionEffectQueryResult::TemporarilyNotPossible; + } + return GameInteractor::RawAction::SpawnActor(parameters[0], parameters[1]); +} + +void SpawnActor::_Apply() { + GameInteractor::RawAction::SpawnActor(parameters[0], parameters[1]); +} +} // namespace GameInteractionEffect diff --git a/soh/soh/Enhancements/game-interactor/GameInteractionEffect.h b/soh/soh/Enhancements/game-interactor/GameInteractionEffect.h index 2a29022d5..72eb101b0 100644 --- a/soh/soh/Enhancements/game-interactor/GameInteractionEffect.h +++ b/soh/soh/Enhancements/game-interactor/GameInteractionEffect.h @@ -6,271 +6,269 @@ #include #ifdef __cplusplus -enum GameInteractionEffectQueryResult { - Possible = 0x00, - TemporarilyNotPossible = 0x01, - NotPossible = 0xFF -}; +enum GameInteractionEffectQueryResult { Possible = 0x00, TemporarilyNotPossible = 0x01, NotPossible = 0xFF }; class GameInteractionEffectBase { -public: + public: virtual GameInteractionEffectQueryResult CanBeApplied() = 0; GameInteractionEffectQueryResult Apply(); -protected: + + protected: virtual void _Apply() = 0; }; -class RemovableGameInteractionEffect: public GameInteractionEffectBase { -public: +class RemovableGameInteractionEffect : public GameInteractionEffectBase { + public: virtual GameInteractionEffectQueryResult CanBeRemoved(); GameInteractionEffectQueryResult Remove(); -protected: - virtual void _Remove() {}; + + protected: + virtual void _Remove(){}; }; class ParameterizedGameInteractionEffect { -public: + public: int32_t parameters[3]; }; namespace GameInteractionEffect { - class SetSceneFlag: public GameInteractionEffectBase, public ParameterizedGameInteractionEffect { - GameInteractionEffectQueryResult CanBeApplied() override; - void _Apply() override; - }; +class SetSceneFlag : public GameInteractionEffectBase, public ParameterizedGameInteractionEffect { + GameInteractionEffectQueryResult CanBeApplied() override; + void _Apply() override; +}; - class UnsetSceneFlag: public GameInteractionEffectBase, public ParameterizedGameInteractionEffect { - GameInteractionEffectQueryResult CanBeApplied() override; - void _Apply() override; - }; +class UnsetSceneFlag : public GameInteractionEffectBase, public ParameterizedGameInteractionEffect { + GameInteractionEffectQueryResult CanBeApplied() override; + void _Apply() override; +}; - class SetFlag: public GameInteractionEffectBase, public ParameterizedGameInteractionEffect { - GameInteractionEffectQueryResult CanBeApplied() override; - void _Apply() override; - }; +class SetFlag : public GameInteractionEffectBase, public ParameterizedGameInteractionEffect { + GameInteractionEffectQueryResult CanBeApplied() override; + void _Apply() override; +}; - class UnsetFlag: public GameInteractionEffectBase, public ParameterizedGameInteractionEffect { - GameInteractionEffectQueryResult CanBeApplied() override; - void _Apply() override; - }; +class UnsetFlag : public GameInteractionEffectBase, public ParameterizedGameInteractionEffect { + GameInteractionEffectQueryResult CanBeApplied() override; + void _Apply() override; +}; - class ModifyHeartContainers: public GameInteractionEffectBase, public ParameterizedGameInteractionEffect { - GameInteractionEffectQueryResult CanBeApplied() override; - void _Apply() override; - }; +class ModifyHeartContainers : public GameInteractionEffectBase, public ParameterizedGameInteractionEffect { + GameInteractionEffectQueryResult CanBeApplied() override; + void _Apply() override; +}; - class FillMagic: public GameInteractionEffectBase { - GameInteractionEffectQueryResult CanBeApplied() override; - void _Apply() override; - }; +class FillMagic : public GameInteractionEffectBase { + GameInteractionEffectQueryResult CanBeApplied() override; + void _Apply() override; +}; - class EmptyMagic: public GameInteractionEffectBase { - GameInteractionEffectQueryResult CanBeApplied() override; - void _Apply() override; - }; +class EmptyMagic : public GameInteractionEffectBase { + GameInteractionEffectQueryResult CanBeApplied() override; + void _Apply() override; +}; - class ModifyRupees: public GameInteractionEffectBase, public ParameterizedGameInteractionEffect { - GameInteractionEffectQueryResult CanBeApplied() override; - void _Apply() override; - }; +class ModifyRupees : public GameInteractionEffectBase, public ParameterizedGameInteractionEffect { + GameInteractionEffectQueryResult CanBeApplied() override; + void _Apply() override; +}; - class NoUI: public RemovableGameInteractionEffect { - GameInteractionEffectQueryResult CanBeApplied() override; - void _Apply() override; - void _Remove() override; - }; +class NoUI : public RemovableGameInteractionEffect { + GameInteractionEffectQueryResult CanBeApplied() override; + void _Apply() override; + void _Remove() override; +}; - class ModifyGravity: public RemovableGameInteractionEffect, public ParameterizedGameInteractionEffect { - GameInteractionEffectQueryResult CanBeApplied() override; - void _Apply() override; - void _Remove() override; - }; +class ModifyGravity : public RemovableGameInteractionEffect, public ParameterizedGameInteractionEffect { + GameInteractionEffectQueryResult CanBeApplied() override; + void _Apply() override; + void _Remove() override; +}; - class ModifyHealth: public GameInteractionEffectBase, public ParameterizedGameInteractionEffect { - GameInteractionEffectQueryResult CanBeApplied() override; - void _Apply() override; - }; +class ModifyHealth : public GameInteractionEffectBase, public ParameterizedGameInteractionEffect { + GameInteractionEffectQueryResult CanBeApplied() override; + void _Apply() override; +}; - class SetPlayerHealth: public GameInteractionEffectBase, public ParameterizedGameInteractionEffect { - GameInteractionEffectQueryResult CanBeApplied() override; - void _Apply() override; - }; +class SetPlayerHealth : public GameInteractionEffectBase, public ParameterizedGameInteractionEffect { + GameInteractionEffectQueryResult CanBeApplied() override; + void _Apply() override; +}; - class FreezePlayer: public GameInteractionEffectBase { - GameInteractionEffectQueryResult CanBeApplied() override; - void _Apply() override; - }; +class FreezePlayer : public GameInteractionEffectBase { + GameInteractionEffectQueryResult CanBeApplied() override; + void _Apply() override; +}; - class BurnPlayer: public GameInteractionEffectBase { - GameInteractionEffectQueryResult CanBeApplied() override; - void _Apply() override; - }; +class BurnPlayer : public GameInteractionEffectBase { + GameInteractionEffectQueryResult CanBeApplied() override; + void _Apply() override; +}; - class ElectrocutePlayer: public GameInteractionEffectBase { - GameInteractionEffectQueryResult CanBeApplied() override; - void _Apply() override; - }; +class ElectrocutePlayer : public GameInteractionEffectBase { + GameInteractionEffectQueryResult CanBeApplied() override; + void _Apply() override; +}; - class KnockbackPlayer: public GameInteractionEffectBase, public ParameterizedGameInteractionEffect { - GameInteractionEffectQueryResult CanBeApplied() override; - void _Apply() override; - }; +class KnockbackPlayer : public GameInteractionEffectBase, public ParameterizedGameInteractionEffect { + GameInteractionEffectQueryResult CanBeApplied() override; + void _Apply() override; +}; - class ModifyLinkSize: public RemovableGameInteractionEffect, public ParameterizedGameInteractionEffect { - GameInteractionEffectQueryResult CanBeApplied() override; - void _Apply() override; - void _Remove() override; - }; +class ModifyLinkSize : public RemovableGameInteractionEffect, public ParameterizedGameInteractionEffect { + GameInteractionEffectQueryResult CanBeApplied() override; + void _Apply() override; + void _Remove() override; +}; - class InvisibleLink : public RemovableGameInteractionEffect, public ParameterizedGameInteractionEffect { - GameInteractionEffectQueryResult CanBeApplied() override; - void _Apply() override; - void _Remove() override; - }; +class InvisibleLink : public RemovableGameInteractionEffect, public ParameterizedGameInteractionEffect { + GameInteractionEffectQueryResult CanBeApplied() override; + void _Apply() override; + void _Remove() override; +}; - class PacifistMode : public RemovableGameInteractionEffect { - GameInteractionEffectQueryResult CanBeApplied() override; - void _Apply() override; - void _Remove() override; - }; +class PacifistMode : public RemovableGameInteractionEffect { + GameInteractionEffectQueryResult CanBeApplied() override; + void _Apply() override; + void _Remove() override; +}; - class DisableZTargeting: public RemovableGameInteractionEffect, public ParameterizedGameInteractionEffect { - GameInteractionEffectQueryResult CanBeApplied() override; - void _Apply() override; - void _Remove() override; - }; +class DisableZTargeting : public RemovableGameInteractionEffect, public ParameterizedGameInteractionEffect { + GameInteractionEffectQueryResult CanBeApplied() override; + void _Apply() override; + void _Remove() override; +}; - class WeatherRainstorm: public RemovableGameInteractionEffect { - GameInteractionEffectQueryResult CanBeApplied() override; - void _Apply() override; - void _Remove() override; - }; +class WeatherRainstorm : public RemovableGameInteractionEffect { + GameInteractionEffectQueryResult CanBeApplied() override; + void _Apply() override; + void _Remove() override; +}; - class ReverseControls: public RemovableGameInteractionEffect { - GameInteractionEffectQueryResult CanBeApplied() override; - void _Apply() override; - void _Remove() override; - }; +class ReverseControls : public RemovableGameInteractionEffect { + GameInteractionEffectQueryResult CanBeApplied() override; + void _Apply() override; + void _Remove() override; +}; - class ForceEquipBoots: public RemovableGameInteractionEffect, public ParameterizedGameInteractionEffect { - GameInteractionEffectQueryResult CanBeApplied() override; - void _Apply() override; - void _Remove() override; - }; +class ForceEquipBoots : public RemovableGameInteractionEffect, public ParameterizedGameInteractionEffect { + GameInteractionEffectQueryResult CanBeApplied() override; + void _Apply() override; + void _Remove() override; +}; - class ModifyRunSpeedModifier: public RemovableGameInteractionEffect, public ParameterizedGameInteractionEffect { - GameInteractionEffectQueryResult CanBeApplied() override; - void _Apply() override; - void _Remove() override; - }; +class ModifyRunSpeedModifier : public RemovableGameInteractionEffect, public ParameterizedGameInteractionEffect { + GameInteractionEffectQueryResult CanBeApplied() override; + void _Apply() override; + void _Remove() override; +}; - class OneHitKO : public RemovableGameInteractionEffect { - GameInteractionEffectQueryResult CanBeApplied() override; - void _Apply() override; - void _Remove() override; - }; +class OneHitKO : public RemovableGameInteractionEffect { + GameInteractionEffectQueryResult CanBeApplied() override; + void _Apply() override; + void _Remove() override; +}; - class ModifyDefenseModifier: public RemovableGameInteractionEffect, public ParameterizedGameInteractionEffect { - GameInteractionEffectQueryResult CanBeApplied() override; - void _Apply() override; - void _Remove() override; - }; +class ModifyDefenseModifier : public RemovableGameInteractionEffect, public ParameterizedGameInteractionEffect { + GameInteractionEffectQueryResult CanBeApplied() override; + void _Apply() override; + void _Remove() override; +}; - class GiveOrTakeShield: public GameInteractionEffectBase, public ParameterizedGameInteractionEffect { - GameInteractionEffectQueryResult CanBeApplied() override; - void _Apply() override; - }; +class GiveOrTakeShield : public GameInteractionEffectBase, public ParameterizedGameInteractionEffect { + GameInteractionEffectQueryResult CanBeApplied() override; + void _Apply() override; +}; - class TeleportPlayer: public GameInteractionEffectBase, public ParameterizedGameInteractionEffect { - GameInteractionEffectQueryResult CanBeApplied() override; - void _Apply() override; - }; +class TeleportPlayer : public GameInteractionEffectBase, public ParameterizedGameInteractionEffect { + GameInteractionEffectQueryResult CanBeApplied() override; + void _Apply() override; +}; - class ClearAssignedButtons: public GameInteractionEffectBase, public ParameterizedGameInteractionEffect { - GameInteractionEffectQueryResult CanBeApplied() override; - void _Apply() override; - }; +class ClearAssignedButtons : public GameInteractionEffectBase, public ParameterizedGameInteractionEffect { + GameInteractionEffectQueryResult CanBeApplied() override; + void _Apply() override; +}; - class SetTimeOfDay: public GameInteractionEffectBase, public ParameterizedGameInteractionEffect { - GameInteractionEffectQueryResult CanBeApplied() override; - void _Apply() override; - }; +class SetTimeOfDay : public GameInteractionEffectBase, public ParameterizedGameInteractionEffect { + GameInteractionEffectQueryResult CanBeApplied() override; + void _Apply() override; +}; - class SetCollisionViewer: public RemovableGameInteractionEffect { - GameInteractionEffectQueryResult CanBeApplied() override; - void _Apply() override; - void _Remove() override; - }; +class SetCollisionViewer : public RemovableGameInteractionEffect { + GameInteractionEffectQueryResult CanBeApplied() override; + void _Apply() override; + void _Remove() override; +}; - class SetCosmeticsColor: public GameInteractionEffectBase, public ParameterizedGameInteractionEffect { - GameInteractionEffectQueryResult CanBeApplied() override; - void _Apply() override; - }; +class SetCosmeticsColor : public GameInteractionEffectBase, public ParameterizedGameInteractionEffect { + GameInteractionEffectQueryResult CanBeApplied() override; + void _Apply() override; +}; - class RandomizeCosmetics: public GameInteractionEffectBase { - GameInteractionEffectQueryResult CanBeApplied() override; - void _Apply() override; - }; +class RandomizeCosmetics : public GameInteractionEffectBase { + GameInteractionEffectQueryResult CanBeApplied() override; + void _Apply() override; +}; - class PressButton: public GameInteractionEffectBase, public ParameterizedGameInteractionEffect { - GameInteractionEffectQueryResult CanBeApplied() override; - void _Apply() override; - }; +class PressButton : public GameInteractionEffectBase, public ParameterizedGameInteractionEffect { + GameInteractionEffectQueryResult CanBeApplied() override; + void _Apply() override; +}; - class PressRandomButton: public RemovableGameInteractionEffect, public ParameterizedGameInteractionEffect { - GameInteractionEffectQueryResult CanBeApplied() override; - void _Apply() override; - }; +class PressRandomButton : public RemovableGameInteractionEffect, public ParameterizedGameInteractionEffect { + GameInteractionEffectQueryResult CanBeApplied() override; + void _Apply() override; +}; - class AddOrTakeAmmo: public GameInteractionEffectBase, public ParameterizedGameInteractionEffect { - GameInteractionEffectQueryResult CanBeApplied() override; - void _Apply() override; - }; +class AddOrTakeAmmo : public GameInteractionEffectBase, public ParameterizedGameInteractionEffect { + GameInteractionEffectQueryResult CanBeApplied() override; + void _Apply() override; +}; - class RandomBombFuseTimer: public RemovableGameInteractionEffect { - GameInteractionEffectQueryResult CanBeApplied() override; - void _Apply() override; - void _Remove() override; - }; +class RandomBombFuseTimer : public RemovableGameInteractionEffect { + GameInteractionEffectQueryResult CanBeApplied() override; + void _Apply() override; + void _Remove() override; +}; - class DisableLedgeGrabs: public RemovableGameInteractionEffect { - GameInteractionEffectQueryResult CanBeApplied() override; - void _Apply() override; - void _Remove() override; - }; +class DisableLedgeGrabs : public RemovableGameInteractionEffect { + GameInteractionEffectQueryResult CanBeApplied() override; + void _Apply() override; + void _Remove() override; +}; - class RandomWind: public RemovableGameInteractionEffect { - GameInteractionEffectQueryResult CanBeApplied() override; - void _Apply() override; - void _Remove() override; - }; +class RandomWind : public RemovableGameInteractionEffect { + GameInteractionEffectQueryResult CanBeApplied() override; + void _Apply() override; + void _Remove() override; +}; - class RandomBonks: public RemovableGameInteractionEffect { - GameInteractionEffectQueryResult CanBeApplied() override; - void _Apply() override; - void _Remove() override; - }; +class RandomBonks : public RemovableGameInteractionEffect { + GameInteractionEffectQueryResult CanBeApplied() override; + void _Apply() override; + void _Remove() override; +}; - class PlayerInvincibility: public RemovableGameInteractionEffect { - GameInteractionEffectQueryResult CanBeApplied() override; - void _Apply() override; - void _Remove() override; - }; +class PlayerInvincibility : public RemovableGameInteractionEffect { + GameInteractionEffectQueryResult CanBeApplied() override; + void _Apply() override; + void _Remove() override; +}; - class SlipperyFloor: public RemovableGameInteractionEffect { - GameInteractionEffectQueryResult CanBeApplied() override; - void _Apply() override; - void _Remove() override; - }; - class SpawnEnemyWithOffset: public GameInteractionEffectBase, public ParameterizedGameInteractionEffect { - GameInteractionEffectQueryResult CanBeApplied() override; - void _Apply() override; - }; - class SpawnActor: public GameInteractionEffectBase, public ParameterizedGameInteractionEffect { - GameInteractionEffectQueryResult CanBeApplied() override; - void _Apply() override; - }; -} +class SlipperyFloor : public RemovableGameInteractionEffect { + GameInteractionEffectQueryResult CanBeApplied() override; + void _Apply() override; + void _Remove() override; +}; +class SpawnEnemyWithOffset : public GameInteractionEffectBase, public ParameterizedGameInteractionEffect { + GameInteractionEffectQueryResult CanBeApplied() override; + void _Apply() override; +}; +class SpawnActor : public GameInteractionEffectBase, public ParameterizedGameInteractionEffect { + GameInteractionEffectQueryResult CanBeApplied() override; + void _Apply() override; +}; +} // namespace GameInteractionEffect #endif /* __cplusplus */ #endif /* GameInteractionEffect_h */ diff --git a/soh/soh/Enhancements/game-interactor/GameInteractor.cpp b/soh/soh/Enhancements/game-interactor/GameInteractor.cpp index dbb4782fd..fb3db74df 100644 --- a/soh/soh/Enhancements/game-interactor/GameInteractor.cpp +++ b/soh/soh/Enhancements/game-interactor/GameInteractor.cpp @@ -1,4 +1,4 @@ -/* +/* GameInteractor is meant to be used for interacting with the game (yup...). It exposes functions that directly modify, add or remove game related elements. @@ -54,7 +54,10 @@ bool GameInteractor::IsSaveLoaded(bool allowDbgSave) { bool GameInteractor::IsGameplayPaused() { Player* player = GET_PLAYER(gPlayState); - return (Player_InBlockingCsMode(gPlayState, player) || gPlayState->pauseCtx.state != 0 || gPlayState->msgCtx.msgMode != 0) ? true : false; + return (Player_InBlockingCsMode(gPlayState, player) || gPlayState->pauseCtx.state != 0 || + gPlayState->msgCtx.msgMode != 0) + ? true + : false; } bool GameInteractor::CanSpawnActor() { diff --git a/soh/soh/Enhancements/game-interactor/GameInteractor_HookTable.h b/soh/soh/Enhancements/game-interactor/GameInteractor_HookTable.h index 59d511941..44d0e643a 100644 --- a/soh/soh/Enhancements/game-interactor/GameInteractor_HookTable.h +++ b/soh/soh/Enhancements/game-interactor/GameInteractor_HookTable.h @@ -34,9 +34,9 @@ DEFINE_HOOK(OnPlayerBonk, ()); DEFINE_HOOK(OnPlayerHealthChange, (int16_t amount)); DEFINE_HOOK(OnPlayerBottleUpdate, (int16_t contents)); DEFINE_HOOK(OnPlayerHoldUpShield, ()); -DEFINE_HOOK(OnPlayerFirstPersonControl, (Player* player)); +DEFINE_HOOK(OnPlayerFirstPersonControl, (Player * player)); DEFINE_HOOK(OnPlayerProcessStick, ()); -DEFINE_HOOK(OnPlayerShieldControl, (float_t* sp50, float_t* sp54)); +DEFINE_HOOK(OnPlayerShieldControl, (float_t * sp50, float_t* sp54)); DEFINE_HOOK(OnPlayDestroy, ()); DEFINE_HOOK(OnPlayDrawEnd, ()); DEFINE_HOOK(OnVanillaBehavior, (GIVanillaBehavior flag, bool* result, va_list originalArgs)); diff --git a/soh/soh/Enhancements/game-interactor/GameInteractor_Hooks.cpp b/soh/soh/Enhancements/game-interactor/GameInteractor_Hooks.cpp index 40c47e9a9..9231da843 100644 --- a/soh/soh/Enhancements/game-interactor/GameInteractor_Hooks.cpp +++ b/soh/soh/Enhancements/game-interactor/GameInteractor_Hooks.cpp @@ -126,7 +126,7 @@ void GameInteractor_ExecuteOnBossDefeat(void* actor) { GameInteractor::Instance->ExecuteHooksForFilter(actor); } -void GameInteractor_ExecuteOnTimestamp (u8 item) { +void GameInteractor_ExecuteOnTimestamp(u8 item) { GameInteractor::Instance->ExecuteHooks(item); } @@ -266,7 +266,8 @@ void GameInteractor_ExecuteOnUpdateFileQuestSelection(uint8_t questIndex) { } void GameInteractor_ExecuteOnUpdateFileBossRushOptionSelection(uint8_t optionIndex, uint8_t optionValue) { - GameInteractor::Instance->ExecuteHooks(optionIndex, optionValue); + GameInteractor::Instance->ExecuteHooks(optionIndex, + optionValue); } void GameInteractor_ExecuteOnUpdateFileNameSelection(int16_t charCode) { @@ -285,7 +286,7 @@ void GameInteractor_RegisterOnAssetAltChange(void (*fn)(void)) { GameInteractor::Instance->RegisterGameHook(fn); } -//MARK: Pause Menu +// MARK: Pause Menu void GameInteractor_ExecuteOnKaleidoUpdate() { GameInteractor::Instance->ExecuteHooks(); diff --git a/soh/soh/Enhancements/game-interactor/GameInteractor_Hooks.h b/soh/soh/Enhancements/game-interactor/GameInteractor_Hooks.h index 10ab3a877..33c8d2681 100644 --- a/soh/soh/Enhancements/game-interactor/GameInteractor_Hooks.h +++ b/soh/soh/Enhancements/game-interactor/GameInteractor_Hooks.h @@ -31,7 +31,7 @@ void GameInteractor_ExecuteOnActorUpdate(void* actor); void GameInteractor_ExecuteOnActorKill(void* actor); void GameInteractor_ExecuteOnEnemyDefeat(void* actor); void GameInteractor_ExecuteOnBossDefeat(void* actor); -void GameInteractor_ExecuteOnTimestamp (u8 item); +void GameInteractor_ExecuteOnTimestamp(u8 item); void GameInteractor_ExecuteOnPlayerBonk(); void GameInteractor_ExecuteOnPlayerHealthChange(int16_t amount); void GameInteractor_ExecuteOnPlayerBottleUpdate(int16_t contents); @@ -76,7 +76,7 @@ void GameInteractor_ExecuteOnSetGameLanguage(); // MARK: - System void GameInteractor_RegisterOnAssetAltChange(void (*fn)(void)); -//Mark: - Pause Menu +// Mark: - Pause Menu void GameInteractor_ExecuteOnKaleidoUpdate(); #ifdef __cplusplus diff --git a/soh/soh/Enhancements/game-interactor/GameInteractor_RawAction.cpp b/soh/soh/Enhancements/game-interactor/GameInteractor_RawAction.cpp index 1db2f1e33..ac99859b5 100644 --- a/soh/soh/Enhancements/game-interactor/GameInteractor_RawAction.cpp +++ b/soh/soh/Enhancements/game-interactor/GameInteractor_RawAction.cpp @@ -143,11 +143,13 @@ void GameInteractor::RawAction::SetSceneFlag(int16_t sceneNum, int16_t flagType, } break; case FlagType::FLAG_SCENE_CLEAR: - if (sceneNum == gPlayState->sceneNum) gPlayState->actorCtx.flags.clear |= (1 << flag); + if (sceneNum == gPlayState->sceneNum) + gPlayState->actorCtx.flags.clear |= (1 << flag); gSaveContext.sceneFlags[sceneNum].clear |= (1 << flag); break; case FlagType::FLAG_SCENE_TREASURE: - if (sceneNum == gPlayState->sceneNum) gPlayState->actorCtx.flags.chest |= (1 << flag); + if (sceneNum == gPlayState->sceneNum) + gPlayState->actorCtx.flags.chest |= (1 << flag); gSaveContext.sceneFlags[sceneNum].chest |= (1 << flag); break; case FlagType::FLAG_SCENE_COLLECTIBLE: @@ -182,11 +184,13 @@ void GameInteractor::RawAction::UnsetSceneFlag(int16_t sceneNum, int16_t flagTyp } break; case FlagType::FLAG_SCENE_CLEAR: - if (sceneNum == gPlayState->sceneNum) gPlayState->actorCtx.flags.clear &= ~(1 << flag); + if (sceneNum == gPlayState->sceneNum) + gPlayState->actorCtx.flags.clear &= ~(1 << flag); gSaveContext.sceneFlags[sceneNum].clear &= ~(1 << flag); break; case FlagType::FLAG_SCENE_TREASURE: - if (sceneNum == gPlayState->sceneNum) gPlayState->actorCtx.flags.chest &= ~(1 << flag); + if (sceneNum == gPlayState->sceneNum) + gPlayState->actorCtx.flags.chest &= ~(1 << flag); gSaveContext.sceneFlags[sceneNum].chest &= ~(1 << flag); break; case FlagType::FLAG_SCENE_COLLECTIBLE: @@ -337,7 +341,7 @@ void GameInteractor::RawAction::UpdateActor(void* refActor) { // Update actor again outside of their normal update cycle. Actor* actor = static_cast(refActor); - + // Sometimes the actor is destroyed in the previous Update, so check if the update function still exists. if (actor->update != NULL) { // Fix for enemies sometimes taking a "fake" hit, where their invincibility timer is @@ -355,7 +359,8 @@ void GameInteractor::RawAction::UpdateActor(void* refActor) { } void GameInteractor::RawAction::TeleportPlayer(int32_t nextEntrance) { - Audio_PlaySoundGeneral(NA_SE_EN_GANON_LAUGH, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb); + Audio_PlaySoundGeneral(NA_SE_EN_GANON_LAUGH, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, + &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb); gPlayState->nextEntranceIndex = nextEntrance; gPlayState->transitionTrigger = TRANS_TRIGGER_START; gPlayState->transitionType = TRANS_TYPE_FADE_BLACK; @@ -386,7 +391,7 @@ void GameInteractor::RawAction::SetTimeOfDay(uint32_t time) { void GameInteractor::RawAction::SetCollisionViewer(bool active) { CVarSetInteger(CVAR_DEVELOPER_TOOLS("ColViewer.Enabled"), active); CVarSetInteger(CVAR_DEVELOPER_TOOLS("ColViewer.Decal"), active); - + if (active) { CVarSetInteger(CVAR_DEVELOPER_TOOLS("ColViewer.Scene"), COLVIEW_TRANSPARENT); CVarSetInteger(CVAR_DEVELOPER_TOOLS("ColViewer.BGActors"), COLVIEW_TRANSPARENT); @@ -406,8 +411,8 @@ void GameInteractor::RawAction::SetCosmeticsColor(uint8_t cosmeticCategory, uint newColor.g = 255; newColor.b = 255; newColor.a = 255; - - switch (colorValue) { + + switch (colorValue) { case GI_COLOR_RED: newColor.r = 200; newColor.g = 30; @@ -457,7 +462,7 @@ void GameInteractor::RawAction::SetCosmeticsColor(uint8_t cosmeticCategory, uint break; } - switch (cosmeticCategory) { + switch (cosmeticCategory) { case GI_COSMETICS_TUNICS: CVarSetColor(CVAR_COSMETIC("Link.KokiriTunic.Value"), newColor); CVarSetInteger(CVAR_COSMETIC("Link.KokiriTunic.Changed"), 1); @@ -495,19 +500,13 @@ void GameInteractor::RawAction::SetCosmeticsColor(uint8_t cosmeticCategory, uint } void GameInteractor::RawAction::RandomizeCosmeticsColors(bool excludeBiddingWarColors) { - const char* cvarsToLock[12] = { - CVAR_COSMETIC("Link.KokiriTunic.Locked"), - CVAR_COSMETIC("Link.GoronTunic.Locked"), - CVAR_COSMETIC("Link.ZoraTunic.Locked"), - CVAR_COSMETIC("Navi.EnemyPrimary.Locked"), - CVAR_COSMETIC("Navi.EnemySecondary.Locked"), - CVAR_COSMETIC("Navi.IdlePrimary.Locked"), - CVAR_COSMETIC("Navi.IdleSecondary.Locked"), - CVAR_COSMETIC("Navi.NPCPrimary.Locked"), - CVAR_COSMETIC("Navi.NPCSecondary.Locked"), - CVAR_COSMETIC("Navi.PropsPrimary.Locked"), - CVAR_COSMETIC("Navi.PropsSecondary.Locked"), - CVAR_COSMETIC("Link.Hair.Locked") + const char* cvarsToLock[12] = { + CVAR_COSMETIC("Link.KokiriTunic.Locked"), CVAR_COSMETIC("Link.GoronTunic.Locked"), + CVAR_COSMETIC("Link.ZoraTunic.Locked"), CVAR_COSMETIC("Navi.EnemyPrimary.Locked"), + CVAR_COSMETIC("Navi.EnemySecondary.Locked"), CVAR_COSMETIC("Navi.IdlePrimary.Locked"), + CVAR_COSMETIC("Navi.IdleSecondary.Locked"), CVAR_COSMETIC("Navi.NPCPrimary.Locked"), + CVAR_COSMETIC("Navi.NPCSecondary.Locked"), CVAR_COSMETIC("Navi.PropsPrimary.Locked"), + CVAR_COSMETIC("Navi.PropsSecondary.Locked"), CVAR_COSMETIC("Link.Hair.Locked") }; if (excludeBiddingWarColors) { @@ -533,7 +532,7 @@ void GameInteractor::RawAction::EmulateRandomButtonPress(uint32_t chancePercenta uint32_t emulatedButton; uint32_t randomNumber = rand(); uint32_t possibleButtons[14] = { BTN_CRIGHT, BTN_CLEFT, BTN_CDOWN, BTN_CUP, BTN_R, BTN_L, BTN_DRIGHT, - BTN_DLEFT, BTN_DDOWN, BTN_DUP, BTN_START, BTN_Z, BTN_B, BTN_A }; + BTN_DLEFT, BTN_DDOWN, BTN_DUP, BTN_START, BTN_Z, BTN_B, BTN_A }; emulatedButton = possibleButtons[randomNumber % 14]; @@ -575,12 +574,14 @@ void GameInteractor::RawAction::SetPlayerInvincibility(bool active) { /// Clears the cutscene pointer to a value safe for wrong warps. void GameInteractor::RawAction::ClearCutscenePointer() { - if (!gPlayState) return; - static uint32_t null_cs[] = {0, 0}; + if (!gPlayState) + return; + static uint32_t null_cs[] = { 0, 0 }; gPlayState->csCtx.segment = &null_cs; } -GameInteractionEffectQueryResult GameInteractor::RawAction::SpawnEnemyWithOffset(uint32_t enemyId, int32_t enemyParams) { +GameInteractionEffectQueryResult GameInteractor::RawAction::SpawnEnemyWithOffset(uint32_t enemyId, + int32_t enemyParams) { if (!GameInteractor::CanSpawnActor()) { return GameInteractionEffectQueryResult::TemporarilyNotPossible; @@ -608,8 +609,9 @@ GameInteractionEffectQueryResult GameInteractor::RawAction::SpawnEnemyWithOffset // Don't allow Arwings in certain areas because they cause issues. // Locations: King dodongo room, Morpha room, Twinrova room, Ganondorf room, Fishing pond, Ganon's room // TODO: Swap this to disabling the option in CC options menu instead. - if (sceneNum == SCENE_DODONGOS_CAVERN_BOSS || sceneNum == SCENE_WATER_TEMPLE_BOSS || sceneNum == SCENE_SPIRIT_TEMPLE_BOSS || - sceneNum == SCENE_GANONDORF_BOSS || sceneNum == SCENE_FISHING_POND || sceneNum == SCENE_GANON_BOSS) { + if (sceneNum == SCENE_DODONGOS_CAVERN_BOSS || sceneNum == SCENE_WATER_TEMPLE_BOSS || + sceneNum == SCENE_SPIRIT_TEMPLE_BOSS || sceneNum == SCENE_GANONDORF_BOSS || + sceneNum == SCENE_FISHING_POND || sceneNum == SCENE_GANON_BOSS) { return GameInteractionEffectQueryResult::NotPossible; } } @@ -649,13 +651,15 @@ GameInteractionEffectQueryResult GameInteractor::RawAction::SpawnEnemyWithOffset pos.x += 10; pos.y += 10; pos.z += 10; - if (Actor_Spawn(&gPlayState->actorCtx, gPlayState, enemyId, pos.x, pos.y, pos.z, 0, 0, 0, enemyParams, 0) == NULL) { + if (Actor_Spawn(&gPlayState->actorCtx, gPlayState, enemyId, pos.x, pos.y, pos.z, 0, 0, 0, enemyParams, 0) == + NULL) { return GameInteractionEffectQueryResult::TemporarilyNotPossible; } } return GameInteractionEffectQueryResult::Possible; } else { - if (Actor_Spawn(&gPlayState->actorCtx, gPlayState, enemyId, pos.x, pos.y, pos.z, 0, 0, 0, enemyParams, 0) != NULL) { + if (Actor_Spawn(&gPlayState->actorCtx, gPlayState, enemyId, pos.x, pos.y, pos.z, 0, 0, 0, enemyParams, 0) != + NULL) { return GameInteractionEffectQueryResult::Possible; } } @@ -673,8 +677,9 @@ GameInteractionEffectQueryResult GameInteractor::RawAction::SpawnActor(uint32_t if (actorId == ACTOR_EN_NIW) { // Spawn Cucco and make it angry - EnNiw* cucco = (EnNiw*)Actor_Spawn(&gPlayState->actorCtx, gPlayState, actorId, player->actor.world.pos.x, - player->actor.world.pos.y + 2200, player->actor.world.pos.z, 0, 0, 0, actorParams, 0); + EnNiw* cucco = + (EnNiw*)Actor_Spawn(&gPlayState->actorCtx, gPlayState, actorId, player->actor.world.pos.x, + player->actor.world.pos.y + 2200, player->actor.world.pos.z, 0, 0, 0, actorParams, 0); if (cucco == NULL) { return GameInteractionEffectQueryResult::TemporarilyNotPossible; } @@ -683,8 +688,9 @@ GameInteractionEffectQueryResult GameInteractor::RawAction::SpawnActor(uint32_t return GameInteractionEffectQueryResult::Possible; } else if (actorId == ACTOR_EN_BOM) { // Spawn a bomb, make it explode instantly when params is set to 1 to emulate spawning an explosion - EnBom* bomb = (EnBom*)Actor_Spawn(&gPlayState->actorCtx, gPlayState, ACTOR_EN_BOM, player->actor.world.pos.x, - player->actor.world.pos.y + 30, player->actor.world.pos.z, 0, 0, 0, BOMB_BODY, true); + EnBom* bomb = + (EnBom*)Actor_Spawn(&gPlayState->actorCtx, gPlayState, ACTOR_EN_BOM, player->actor.world.pos.x, + player->actor.world.pos.y + 30, player->actor.world.pos.z, 0, 0, 0, BOMB_BODY, true); if (bomb == NULL) { return GameInteractionEffectQueryResult::TemporarilyNotPossible; @@ -704,5 +710,4 @@ GameInteractionEffectQueryResult GameInteractor::RawAction::SpawnActor(uint32_t } return GameInteractionEffectQueryResult::TemporarilyNotPossible; - } diff --git a/soh/soh/Enhancements/game-interactor/vanilla-behavior/GIVanillaBehavior.h b/soh/soh/Enhancements/game-interactor/vanilla-behavior/GIVanillaBehavior.h index 078d645b5..1c516fc6e 100644 --- a/soh/soh/Enhancements/game-interactor/vanilla-behavior/GIVanillaBehavior.h +++ b/soh/soh/Enhancements/game-interactor/vanilla-behavior/GIVanillaBehavior.h @@ -136,7 +136,8 @@ typedef enum { // #### `result` // ```c - // !Flags_GetEventChkInf(EVENTCHKINF_LEARNED_PRELUDE_OF_LIGHT) && Flags_GetEventChkInf(EVENTCHKINF_USED_FOREST_TEMPLE_BLUE_WARP) + // !Flags_GetEventChkInf(EVENTCHKINF_LEARNED_PRELUDE_OF_LIGHT) && + // Flags_GetEventChkInf(EVENTCHKINF_USED_FOREST_TEMPLE_BLUE_WARP) // ``` // #### `args` // - None @@ -163,7 +164,8 @@ typedef enum { // #### `result` // ```c - // CHECK_OWNED_EQUIP(EQUIP_TYPE_BOOTS, EQUIP_INV_BOOTS_IRON) && !Flags_GetEventChkInf(EVENTCHKINF_LEARNED_SERENADE_OF_WATER) + // CHECK_OWNED_EQUIP(EQUIP_TYPE_BOOTS, EQUIP_INV_BOOTS_IRON) && + // !Flags_GetEventChkInf(EVENTCHKINF_LEARNED_SERENADE_OF_WATER) // ``` // #### `args` // - None @@ -275,7 +277,7 @@ typedef enum { // #### `args` // - `*EnDoor` VB_CONSUME_SMALL_KEY, - + // #### `result` // ```c // itemDropped >= 0 && itemDropped < 0x1A @@ -302,7 +304,8 @@ typedef enum { // #### `result` // ```c - // gSaveContext.dayTime <= 0xC000 || gSaveContext.dayTime >= 0xE000 || LINK_IS_ADULT || play->sceneNum != SCENE_GRAVEYARD + // gSaveContext.dayTime <= 0xC000 || gSaveContext.dayTime >= 0xE000 || LINK_IS_ADULT || play->sceneNum != + // SCENE_GRAVEYARD // ``` // #### `args` // - `*EnTk` @@ -371,7 +374,8 @@ typedef enum { // #### `result` // ```c - // play->sceneNum == SCENE_LINKS_HOUSE && (!LINK_IS_ADULT || !Flags_GetEventChkInf(EVENTCHKINF_WON_COW_IN_MALONS_RACE) + // play->sceneNum == SCENE_LINKS_HOUSE && (!LINK_IS_ADULT || + // !Flags_GetEventChkInf(EVENTCHKINF_WON_COW_IN_MALONS_RACE) // ``` // #### `args` // - `*EnCow` @@ -1322,7 +1326,8 @@ typedef enum { // Close enough & various cutscene checks // ```c // (func_80AEC5FC(this, play)) && (!Play_InCsMode(play)) && - // (!(player->stateFlags1 & (PLAYER_STATE1_HANGING_OFF_LEDGE | PLAYER_STATE1_CLIMBING_LEDGE | PLAYER_STATE1_CLIMBING_LADDER))) && + // (!(player->stateFlags1 & (PLAYER_STATE1_HANGING_OFF_LEDGE | PLAYER_STATE1_CLIMBING_LEDGE | + // PLAYER_STATE1_CLIMBING_LADDER))) && // (player->actor.bgCheckFlags & 1) // ``` // #### `args` @@ -1676,7 +1681,8 @@ typedef enum { // #### `result` // ```c - // (!CHECK_OWNED_EQUIP(EQUIP_TYPE_BOOTS, EQUIP_INV_BOOTS_IRON) && !Flags_GetEventChkInf(EVENTCHKINF_LEARNED_SERENADE_OF_WATER)) && LINK_IS_ADULT + // (!CHECK_OWNED_EQUIP(EQUIP_TYPE_BOOTS, EQUIP_INV_BOOTS_IRON) && + // !Flags_GetEventChkInf(EVENTCHKINF_LEARNED_SERENADE_OF_WATER)) && LINK_IS_ADULT // ``` // #### `args` // - None diff --git a/soh/soh/Enhancements/gameconsole.c b/soh/soh/Enhancements/gameconsole.c index da0c7cf97..6992b7fb4 100644 --- a/soh/soh/Enhancements/gameconsole.c +++ b/soh/soh/Enhancements/gameconsole.c @@ -17,4 +17,5 @@ extern PlayState* gPlayState; -void GameConsole_Init() {} \ No newline at end of file +void GameConsole_Init() { +} \ No newline at end of file diff --git a/soh/soh/Enhancements/gameconsole.h b/soh/soh/Enhancements/gameconsole.h index e9a3634a1..0952baf08 100644 --- a/soh/soh/Enhancements/gameconsole.h +++ b/soh/soh/Enhancements/gameconsole.h @@ -8,22 +8,19 @@ #define MAX_CVARS 2048 #ifdef __cplusplus -extern "C" -{ +extern "C" { #endif -typedef enum -{ +typedef enum { CONSOLECOMMAND_RESULT_SUCCESS, CONSOLECOMMAND_RESULT_INVALIDARGS, CONSOLECOMMAND_RESULT_INVALIDCOMMAND, CONSOLECOMMAND_RESULT_FAILURE } ConsoleCommandResult; -typedef ConsoleCommandResult(*ConsoleCommandFunc)(char** argv, s32 argc); // Returns the number of arguments it read +typedef ConsoleCommandResult (*ConsoleCommandFunc)(char** argv, s32 argc); // Returns the number of arguments it read -typedef struct ConsoleCommand -{ +typedef struct ConsoleCommand { char* name; ConsoleCommandFunc func; char* description; diff --git a/soh/soh/Enhancements/gameplaystats.cpp b/soh/soh/Enhancements/gameplaystats.cpp index 347bfe982..ca360543f 100644 --- a/soh/soh/Enhancements/gameplaystats.cpp +++ b/soh/soh/Enhancements/gameplaystats.cpp @@ -124,7 +124,7 @@ const char* const sceneMappings[] = { "Goron City", "Lon Lon Ranch", "Outside Ganon's Castle", - //Debug Rooms + // Debug Rooms "Test Map", "Test Room", "Depth Test", @@ -230,15 +230,15 @@ const char* const countMappings[] = { "Start:", }; -#define COLOR_WHITE ImVec4(1.00f, 1.00f, 1.00f, 1.00f) -#define COLOR_RED ImVec4(1.00f, 0.00f, 0.00f, 1.00f) -#define COLOR_GREEN ImVec4(0.10f, 1.00f, 0.10f, 1.00f) -#define COLOR_BLUE ImVec4(0.00f, 0.33f, 1.00f, 1.00f) -#define COLOR_PURPLE ImVec4(0.54f, 0.19f, 0.89f, 1.00f) -#define COLOR_YELLOW ImVec4(1.00f, 1.00f, 0.00f, 1.00f) -#define COLOR_ORANGE ImVec4(1.00f, 0.67f, 0.11f, 1.00f) +#define COLOR_WHITE ImVec4(1.00f, 1.00f, 1.00f, 1.00f) +#define COLOR_RED ImVec4(1.00f, 0.00f, 0.00f, 1.00f) +#define COLOR_GREEN ImVec4(0.10f, 1.00f, 0.10f, 1.00f) +#define COLOR_BLUE ImVec4(0.00f, 0.33f, 1.00f, 1.00f) +#define COLOR_PURPLE ImVec4(0.54f, 0.19f, 0.89f, 1.00f) +#define COLOR_YELLOW ImVec4(1.00f, 1.00f, 0.00f, 1.00f) +#define COLOR_ORANGE ImVec4(1.00f, 0.67f, 0.11f, 1.00f) #define COLOR_LIGHT_BLUE ImVec4(0.00f, 0.88f, 1.00f, 1.00f) -#define COLOR_GREY ImVec4(0.78f, 0.78f, 0.78f, 1.00f) +#define COLOR_GREY ImVec4(0.78f, 0.78f, 0.78f, 1.00f) char itemTimestampDisplayName[TIMESTAMP_MAX][21] = { "" }; ImVec4 itemTimestampDisplayColor[TIMESTAMP_MAX]; @@ -248,14 +248,14 @@ typedef struct { u32 time; ImVec4 color; bool isRoom; -}TimestampInfo; +} TimestampInfo; // Timestamps are an array of structs, each with a name, time, and color // Names and colors are set up at the bottom of this file. // Times are stored in gSaveContext.ship.stats.itemTimestamp. TimestampInfo itemTimestampDisplay[TIMESTAMP_MAX]; TimestampInfo sceneTimestampDisplay[8191]; -//std::vector sceneTimestampDisplay; +// std::vector sceneTimestampDisplay; std::string formatTimestampGameplayStat(uint32_t value) { uint32_t sec = value / 10; @@ -302,37 +302,38 @@ void LoadStatsVersion1() { SaveManager::Instance->LoadData("fileCreatedAt", gSaveContext.ship.stats.fileCreatedAt); SaveManager::Instance->LoadData("playTimer", gSaveContext.ship.stats.playTimer); SaveManager::Instance->LoadData("pauseTimer", gSaveContext.ship.stats.pauseTimer); - SaveManager::Instance->LoadArray("itemTimestamps", ARRAY_COUNT(gSaveContext.ship.stats.itemTimestamp), [](size_t i) { - SaveManager::Instance->LoadData("", gSaveContext.ship.stats.itemTimestamp[i]); - }); - SaveManager::Instance->LoadArray("sceneTimestamps", ARRAY_COUNT(gSaveContext.ship.stats.sceneTimestamps), [&](size_t i) { - SaveManager::Instance->LoadStruct("", [&]() { - int scene, room, sceneTime, roomTime, isRoom; - SaveManager::Instance->LoadData("scene", scene); - SaveManager::Instance->LoadData("room", room); - SaveManager::Instance->LoadData("sceneTime", sceneTime); - SaveManager::Instance->LoadData("roomTime", roomTime); - SaveManager::Instance->LoadData("isRoom", isRoom); - if (scene == 0 && room == 0 && sceneTime == 0 && roomTime == 0 && isRoom == 0) { - return; - } - gSaveContext.ship.stats.sceneTimestamps[i].scene = scene; - gSaveContext.ship.stats.sceneTimestamps[i].room = room; - gSaveContext.ship.stats.sceneTimestamps[i].sceneTime = sceneTime; - gSaveContext.ship.stats.sceneTimestamps[i].roomTime = roomTime; - gSaveContext.ship.stats.sceneTimestamps[i].isRoom = isRoom; + SaveManager::Instance->LoadArray( + "itemTimestamps", ARRAY_COUNT(gSaveContext.ship.stats.itemTimestamp), + [](size_t i) { SaveManager::Instance->LoadData("", gSaveContext.ship.stats.itemTimestamp[i]); }); + SaveManager::Instance->LoadArray( + "sceneTimestamps", ARRAY_COUNT(gSaveContext.ship.stats.sceneTimestamps), [&](size_t i) { + SaveManager::Instance->LoadStruct("", [&]() { + int scene, room, sceneTime, roomTime, isRoom; + SaveManager::Instance->LoadData("scene", scene); + SaveManager::Instance->LoadData("room", room); + SaveManager::Instance->LoadData("sceneTime", sceneTime); + SaveManager::Instance->LoadData("roomTime", roomTime); + SaveManager::Instance->LoadData("isRoom", isRoom); + if (scene == 0 && room == 0 && sceneTime == 0 && roomTime == 0 && isRoom == 0) { + return; + } + gSaveContext.ship.stats.sceneTimestamps[i].scene = scene; + gSaveContext.ship.stats.sceneTimestamps[i].room = room; + gSaveContext.ship.stats.sceneTimestamps[i].sceneTime = sceneTime; + gSaveContext.ship.stats.sceneTimestamps[i].roomTime = roomTime; + gSaveContext.ship.stats.sceneTimestamps[i].isRoom = isRoom; + }); }); - }); SaveManager::Instance->LoadData("tsIdx", gSaveContext.ship.stats.tsIdx); SaveManager::Instance->LoadArray("counts", ARRAY_COUNT(gSaveContext.ship.stats.count), [](size_t i) { SaveManager::Instance->LoadData("", gSaveContext.ship.stats.count[i]); }); - SaveManager::Instance->LoadArray("scenesDiscovered", ARRAY_COUNT(gSaveContext.ship.stats.scenesDiscovered), [](size_t i) { - SaveManager::Instance->LoadData("", gSaveContext.ship.stats.scenesDiscovered[i]); - }); - SaveManager::Instance->LoadArray("entrancesDiscovered", ARRAY_COUNT(gSaveContext.ship.stats.entrancesDiscovered), [](size_t i) { - SaveManager::Instance->LoadData("", gSaveContext.ship.stats.entrancesDiscovered[i]); - }); + SaveManager::Instance->LoadArray( + "scenesDiscovered", ARRAY_COUNT(gSaveContext.ship.stats.scenesDiscovered), + [](size_t i) { SaveManager::Instance->LoadData("", gSaveContext.ship.stats.scenesDiscovered[i]); }); + SaveManager::Instance->LoadArray( + "entrancesDiscovered", ARRAY_COUNT(gSaveContext.ship.stats.entrancesDiscovered), + [](size_t i) { SaveManager::Instance->LoadData("", gSaveContext.ship.stats.entrancesDiscovered[i]); }); } void SaveStats(SaveContext* saveContext, int sectionID, bool fullSave) { @@ -350,30 +351,32 @@ void SaveStats(SaveContext* saveContext, int sectionID, bool fullSave) { SaveManager::Instance->SaveData("fileCreatedAt", saveContext->ship.stats.fileCreatedAt); SaveManager::Instance->SaveData("playTimer", saveContext->ship.stats.playTimer); SaveManager::Instance->SaveData("pauseTimer", saveContext->ship.stats.pauseTimer); - SaveManager::Instance->SaveArray("itemTimestamps", ARRAY_COUNT(saveContext->ship.stats.itemTimestamp), [&](size_t i) { - SaveManager::Instance->SaveData("", saveContext->ship.stats.itemTimestamp[i]); - }); - SaveManager::Instance->SaveArray("sceneTimestamps", ARRAY_COUNT(saveContext->ship.stats.sceneTimestamps), [&](size_t i) { - if (saveContext->ship.stats.sceneTimestamps[i].scene != 254 && saveContext->ship.stats.sceneTimestamps[i].room != 254) { - SaveManager::Instance->SaveStruct("", [&]() { - SaveManager::Instance->SaveData("scene", saveContext->ship.stats.sceneTimestamps[i].scene); - SaveManager::Instance->SaveData("room", saveContext->ship.stats.sceneTimestamps[i].room); - SaveManager::Instance->SaveData("sceneTime", saveContext->ship.stats.sceneTimestamps[i].sceneTime); - SaveManager::Instance->SaveData("roomTime", saveContext->ship.stats.sceneTimestamps[i].roomTime); - SaveManager::Instance->SaveData("isRoom", saveContext->ship.stats.sceneTimestamps[i].isRoom); - }); - } - }); + SaveManager::Instance->SaveArray( + "itemTimestamps", ARRAY_COUNT(saveContext->ship.stats.itemTimestamp), + [&](size_t i) { SaveManager::Instance->SaveData("", saveContext->ship.stats.itemTimestamp[i]); }); + SaveManager::Instance->SaveArray( + "sceneTimestamps", ARRAY_COUNT(saveContext->ship.stats.sceneTimestamps), [&](size_t i) { + if (saveContext->ship.stats.sceneTimestamps[i].scene != 254 && + saveContext->ship.stats.sceneTimestamps[i].room != 254) { + SaveManager::Instance->SaveStruct("", [&]() { + SaveManager::Instance->SaveData("scene", saveContext->ship.stats.sceneTimestamps[i].scene); + SaveManager::Instance->SaveData("room", saveContext->ship.stats.sceneTimestamps[i].room); + SaveManager::Instance->SaveData("sceneTime", saveContext->ship.stats.sceneTimestamps[i].sceneTime); + SaveManager::Instance->SaveData("roomTime", saveContext->ship.stats.sceneTimestamps[i].roomTime); + SaveManager::Instance->SaveData("isRoom", saveContext->ship.stats.sceneTimestamps[i].isRoom); + }); + } + }); SaveManager::Instance->SaveData("tsIdx", saveContext->ship.stats.tsIdx); SaveManager::Instance->SaveArray("counts", ARRAY_COUNT(saveContext->ship.stats.count), [&](size_t i) { SaveManager::Instance->SaveData("", saveContext->ship.stats.count[i]); }); - SaveManager::Instance->SaveArray("scenesDiscovered", ARRAY_COUNT(saveContext->ship.stats.scenesDiscovered), [&](size_t i) { - SaveManager::Instance->SaveData("", saveContext->ship.stats.scenesDiscovered[i]); - }); - SaveManager::Instance->SaveArray("entrancesDiscovered", ARRAY_COUNT(saveContext->ship.stats.entrancesDiscovered), [&](size_t i) { - SaveManager::Instance->SaveData("", saveContext->ship.stats.entrancesDiscovered[i]); - }); + SaveManager::Instance->SaveArray( + "scenesDiscovered", ARRAY_COUNT(saveContext->ship.stats.scenesDiscovered), + [&](size_t i) { SaveManager::Instance->SaveData("", saveContext->ship.stats.scenesDiscovered[i]); }); + SaveManager::Instance->SaveArray( + "entrancesDiscovered", ARRAY_COUNT(saveContext->ship.stats.entrancesDiscovered), + [&](size_t i) { SaveManager::Instance->SaveData("", saveContext->ship.stats.entrancesDiscovered[i]); }); } void GameplayStatsRow(const char* label, const std::string& value, ImVec4 color = COLOR_WHITE, @@ -394,7 +397,7 @@ bool compareTimestampInfoByTime(const TimestampInfo& a, const TimestampInfo& b) return CVarGetInteger(CVAR_GAMEPLAY_STATS("ReverseTimestamps"), 0) ? a.time > b.time : a.time < b.time; } -const char* ResolveSceneID(int sceneID, int roomID){ +const char* ResolveSceneID(int sceneID, int roomID) { if (sceneID == SCENE_GROTTOS) { switch (roomID) { case 0: @@ -427,7 +430,7 @@ const char* ResolveSceneID(int sceneID, int roomID){ return "Big Skulltula Grotto"; }; } else if (sceneID == SCENE_WINDMILL_AND_DAMPES_GRAVE) { - //Only the last room of Dampe's Grave (rm 6) is considered the windmill. + // Only the last room of Dampe's Grave (rm 6) is considered the windmill. return roomID == 6 ? "Windmill" : "Dampe's Grave"; } else if (sceneID < SCENE_ID_MAX) { return sceneMappings[sceneID]; @@ -440,7 +443,7 @@ void DrawGameplayStatsHeader() { ImGui::PushStyleVar(ImGuiStyleVar_CellPadding, { 4.0f, 4.0f }); ImGui::BeginTable("gameplayStatsHeader", 1, ImGuiTableFlags_BordersOuter); ImGui::TableSetupColumn("stat", ImGuiTableColumnFlags_WidthStretch); - //if tag is empty (not a release build) + // if tag is empty (not a release build) if (gGitCommitTag[0] == 0) { GameplayStatsRow("Git Branch:", (char*)gGitBranch); GameplayStatsRow("Git Commit Hash:", (char*)gGitCommitHash); @@ -448,21 +451,30 @@ void DrawGameplayStatsHeader() { GameplayStatsRow("Build Version:", (char*)gBuildVersion); } if (gSaveContext.ship.stats.rtaTiming) { - GameplayStatsRow("Total Time (RTA):", formatTimestampGameplayStat(GAMEPLAYSTAT_TOTAL_TIME), gSaveContext.ship.stats.gameComplete ? COLOR_GREEN : COLOR_WHITE); + GameplayStatsRow("Total Time (RTA):", formatTimestampGameplayStat(GAMEPLAYSTAT_TOTAL_TIME), + gSaveContext.ship.stats.gameComplete ? COLOR_GREEN : COLOR_WHITE); } else { - GameplayStatsRow("Total Game Time:", formatTimestampGameplayStat(GAMEPLAYSTAT_TOTAL_TIME), gSaveContext.ship.stats.gameComplete ? COLOR_GREEN : COLOR_WHITE); + GameplayStatsRow("Total Game Time:", formatTimestampGameplayStat(GAMEPLAYSTAT_TOTAL_TIME), + gSaveContext.ship.stats.gameComplete ? COLOR_GREEN : COLOR_WHITE); } if (CVarGetInteger(CVAR_GAMEPLAY_STATS("ShowAdditionalTimers"), 0)) { // !Only display total game time - GameplayStatsRow("Gameplay Time:", formatTimestampGameplayStat(gSaveContext.ship.stats.playTimer / 2), COLOR_GREY); - GameplayStatsRow("Pause Menu Time:", formatTimestampGameplayStat(gSaveContext.ship.stats.pauseTimer / 3), COLOR_GREY); - GameplayStatsRow("Time in scene:", formatTimestampGameplayStat(gSaveContext.ship.stats.sceneTimer / 2), COLOR_LIGHT_BLUE); - GameplayStatsRow("Time in room:", formatTimestampGameplayStat(gSaveContext.ship.stats.roomTimer / 2), COLOR_LIGHT_BLUE); + GameplayStatsRow("Gameplay Time:", formatTimestampGameplayStat(gSaveContext.ship.stats.playTimer / 2), + COLOR_GREY); + GameplayStatsRow("Pause Menu Time:", formatTimestampGameplayStat(gSaveContext.ship.stats.pauseTimer / 3), + COLOR_GREY); + GameplayStatsRow("Time in scene:", formatTimestampGameplayStat(gSaveContext.ship.stats.sceneTimer / 2), + COLOR_LIGHT_BLUE); + GameplayStatsRow("Time in room:", formatTimestampGameplayStat(gSaveContext.ship.stats.roomTimer / 2), + COLOR_LIGHT_BLUE); } if (gPlayState != NULL && CVarGetInteger(CVAR_GAMEPLAY_STATS("ShowDebugInfo"), 0)) { // && display debug info GameplayStatsRow("play->sceneNum:", formatHexGameplayStat(gPlayState->sceneNum), COLOR_YELLOW); - GameplayStatsRow("gSaveContext.entranceIndex:", formatHexGameplayStat(gSaveContext.entranceIndex), COLOR_YELLOW); - GameplayStatsRow("gSaveContext.cutsceneIndex:", formatHexOnlyGameplayStat(gSaveContext.cutsceneIndex), COLOR_YELLOW); - GameplayStatsRow("play->roomCtx.curRoom.num:", formatIntGameplayStat(gPlayState->roomCtx.curRoom.num), COLOR_YELLOW); + GameplayStatsRow("gSaveContext.entranceIndex:", formatHexGameplayStat(gSaveContext.entranceIndex), + COLOR_YELLOW); + GameplayStatsRow("gSaveContext.cutsceneIndex:", formatHexOnlyGameplayStat(gSaveContext.cutsceneIndex), + COLOR_YELLOW); + GameplayStatsRow("play->roomCtx.curRoom.num:", formatIntGameplayStat(gPlayState->roomCtx.curRoom.num), + COLOR_YELLOW); } ImGui::EndTable(); ImGui::PopStyleVar(1); @@ -484,12 +496,12 @@ void DrawGameplayStatsTimestampsTab() { for (int i = 0; i < TIMESTAMP_MAX; i++) { // To be shown, the entry must have a non-zero time and a string for its display name if (itemTimestampDisplay[i].time > 0 && strnlen(itemTimestampDisplay[i].name, 21) > 1) { - GameplayStatsRow(itemTimestampDisplay[i].name, formatTimestampGameplayStat(itemTimestampDisplay[i].time), itemTimestampDisplay[i].color); + GameplayStatsRow(itemTimestampDisplay[i].name, formatTimestampGameplayStat(itemTimestampDisplay[i].time), + itemTimestampDisplay[i].color); } } ImGui::EndTable(); ImGui::PopStyleVar(1); - } void DrawGameplayStatsCountsTab() { @@ -520,7 +532,8 @@ void DrawGameplayStatsCountsTab() { ImGui::TableSetupColumn("stat", ImGuiTableColumnFlags_WidthStretch); GameplayStatsRow("Enemies Defeated:", formatIntGameplayStat(enemiesDefeated)); if (enemiesDefeated > 0) { - ImGui::TableNextRow(); ImGui::TableNextColumn(); + ImGui::TableNextRow(); + ImGui::TableNextColumn(); if (ImGui::TreeNodeEx("Enemy Details...", ImGuiTreeNodeFlags_NoTreePushOnOpen)) { for (int i = COUNT_ENEMIES_DEFEATED_ANUBIS; i <= COUNT_ENEMIES_DEFEATED_WOLFOS; i++) { if (i == COUNT_ENEMIES_DEFEATED_FLOORMASTER) { @@ -537,7 +550,8 @@ void DrawGameplayStatsCountsTab() { GameplayStatsRow("Chests Opened:", formatIntGameplayStat(gSaveContext.ship.stats.count[COUNT_CHESTS_OPENED])); GameplayStatsRow("Ammo Used:", formatIntGameplayStat(ammoUsed)); if (ammoUsed > 0) { - ImGui::TableNextRow(); ImGui::TableNextColumn(); + ImGui::TableNextRow(); + ImGui::TableNextColumn(); if (ImGui::TreeNodeEx("Ammo Details...", ImGuiTreeNodeFlags_NoTreePushOnOpen)) { for (int i = COUNT_AMMO_USED_STICK; i <= COUNT_AMMO_USED_BEAN; i++) { GameplayStatsRow(countMappings[i], formatIntGameplayStat(gSaveContext.ship.stats.count[i])); @@ -548,8 +562,10 @@ void DrawGameplayStatsCountsTab() { GameplayStatsRow("Sword Swings:", formatIntGameplayStat(gSaveContext.ship.stats.count[COUNT_SWORD_SWINGS])); GameplayStatsRow("Steps Taken:", formatIntGameplayStat(gSaveContext.ship.stats.count[COUNT_STEPS])); // If using MM Bunny Hood enhancement, show how long it's been equipped (not counting pause time) - if (CVarGetInteger(CVAR_ENHANCEMENT("MMBunnyHood"), BUNNY_HOOD_VANILLA) != BUNNY_HOOD_VANILLA || gSaveContext.ship.stats.count[COUNT_TIME_BUNNY_HOOD] > 0) { - GameplayStatsRow("Bunny Hood Time:", formatTimestampGameplayStat(gSaveContext.ship.stats.count[COUNT_TIME_BUNNY_HOOD] / 2)); + if (CVarGetInteger(CVAR_ENHANCEMENT("MMBunnyHood"), BUNNY_HOOD_VANILLA) != BUNNY_HOOD_VANILLA || + gSaveContext.ship.stats.count[COUNT_TIME_BUNNY_HOOD] > 0) { + GameplayStatsRow("Bunny Hood Time:", + formatTimestampGameplayStat(gSaveContext.ship.stats.count[COUNT_TIME_BUNNY_HOOD] / 2)); } GameplayStatsRow("Rolls:", formatIntGameplayStat(gSaveContext.ship.stats.count[COUNT_ROLLS])); GameplayStatsRow("Bonks:", formatIntGameplayStat(gSaveContext.ship.stats.count[COUNT_BONKS])); @@ -561,7 +577,8 @@ void DrawGameplayStatsCountsTab() { GameplayStatsRow("Bushes Cut:", formatIntGameplayStat(gSaveContext.ship.stats.count[COUNT_BUSHES_CUT])); GameplayStatsRow("Buttons Pressed:", formatIntGameplayStat(buttonPresses)); if (buttonPresses > 0) { - ImGui::TableNextRow(); ImGui::TableNextColumn(); + ImGui::TableNextRow(); + ImGui::TableNextColumn(); if (ImGui::TreeNodeEx("Buttons...", ImGuiTreeNodeFlags_NoTreePushOnOpen)) { for (int i = COUNT_BUTTON_PRESSES_A; i <= COUNT_BUTTON_PRESSES_START; i++) { GameplayStatsRow(countMappings[i], formatIntGameplayStat(gSaveContext.ship.stats.count[i])); @@ -574,16 +591,19 @@ void DrawGameplayStatsCountsTab() { void DrawGameplayStatsBreakdownTab() { for (int i = 0; i < gSaveContext.ship.stats.tsIdx; i++) { - std::string sceneName = ResolveSceneID(gSaveContext.ship.stats.sceneTimestamps[i].scene, gSaveContext.ship.stats.sceneTimestamps[i].room); + std::string sceneName = ResolveSceneID(gSaveContext.ship.stats.sceneTimestamps[i].scene, + gSaveContext.ship.stats.sceneTimestamps[i].room); std::string name; - if (CVarGetInteger(CVAR_GAMEPLAY_STATS("RoomBreakdown"), 0) && gSaveContext.ship.stats.sceneTimestamps[i].scene != SCENE_GROTTOS) { + if (CVarGetInteger(CVAR_GAMEPLAY_STATS("RoomBreakdown"), 0) && + gSaveContext.ship.stats.sceneTimestamps[i].scene != SCENE_GROTTOS) { name = fmt::format("{:s} Room {:d}", sceneName, gSaveContext.ship.stats.sceneTimestamps[i].room); } else { name = sceneName; } strcpy(sceneTimestampDisplay[i].name, name.c_str()); - sceneTimestampDisplay[i].time = CVarGetInteger(CVAR_GAMEPLAY_STATS("RoomBreakdown"), 0) ? - gSaveContext.ship.stats.sceneTimestamps[i].roomTime : gSaveContext.ship.stats.sceneTimestamps[i].sceneTime; + sceneTimestampDisplay[i].time = CVarGetInteger(CVAR_GAMEPLAY_STATS("RoomBreakdown"), 0) + ? gSaveContext.ship.stats.sceneTimestamps[i].roomTime + : gSaveContext.ship.stats.sceneTimestamps[i].sceneTime; sceneTimestampDisplay[i].color = COLOR_GREY; sceneTimestampDisplay[i].isRoom = gSaveContext.ship.stats.sceneTimestamps[i].isRoom; } @@ -600,7 +620,9 @@ void DrawGameplayStatsBreakdownTab() { } std::string toPass; if (CVarGetInteger(CVAR_GAMEPLAY_STATS("RoomBreakdown"), 0) && gSaveContext.ship.stats.sceneNum != SCENE_GROTTOS) { - toPass = fmt::format("{:s} Room {:d}", ResolveSceneID(gSaveContext.ship.stats.sceneNum, gSaveContext.ship.stats.roomNum), gSaveContext.ship.stats.roomNum); + toPass = fmt::format("{:s} Room {:d}", + ResolveSceneID(gSaveContext.ship.stats.sceneNum, gSaveContext.ship.stats.roomNum), + gSaveContext.ship.stats.roomNum); } else { toPass = ResolveSceneID(gSaveContext.ship.stats.sceneNum, gSaveContext.ship.stats.roomNum); } @@ -611,27 +633,27 @@ void DrawGameplayStatsBreakdownTab() { void DrawGameplayStatsOptionsTab() { UIWidgets::CVarCheckbox("Show in-game total timer", CVAR_GAMEPLAY_STATS("ShowIngameTimer"), - UIWidgets::CheckboxOptions() - .Tooltip("Keep track of the timer as an in-game HUD element. The position of the " - "timer can be changed in the Cosmetics Editor.") - .Color(THEME_COLOR)); + UIWidgets::CheckboxOptions() + .Tooltip("Keep track of the timer as an in-game HUD element. The position of the " + "timer can be changed in the Cosmetics Editor.") + .Color(THEME_COLOR)); UIWidgets::CVarCheckbox("Show latest timestamps on top", CVAR_GAMEPLAY_STATS("ReverseTimestamps"), - UIWidgets::CheckboxOptions().Color(THEME_COLOR)); + UIWidgets::CheckboxOptions().Color(THEME_COLOR)); UIWidgets::CVarCheckbox("Room Breakdown", CVAR_GAMEPLAY_STATS("RoomBreakdown"), - UIWidgets::CheckboxOptions() - .Tooltip("Allows a more in-depth perspective of time spent in a certain map.") - .Color(THEME_COLOR)); + UIWidgets::CheckboxOptions() + .Tooltip("Allows a more in-depth perspective of time spent in a certain map.") + .Color(THEME_COLOR)); UIWidgets::CVarCheckbox("RTA Timing on new files", CVAR_GAMEPLAY_STATS("RTATiming"), - UIWidgets::CheckboxOptions() - .Tooltip("Timestamps are relative to starting timestamp rather than in game time, " - "usually necessary for races/speedruns.\n\n" - "Starting timestamp is on first non-C-up input after intro cutscene.\n\n" - "NOTE: THIS NEEDS TO BE SET BEFORE CREATING A FILE TO TAKE EFFECT") - .Color(THEME_COLOR)); + UIWidgets::CheckboxOptions() + .Tooltip("Timestamps are relative to starting timestamp rather than in game time, " + "usually necessary for races/speedruns.\n\n" + "Starting timestamp is on first non-C-up input after intro cutscene.\n\n" + "NOTE: THIS NEEDS TO BE SET BEFORE CREATING A FILE TO TAKE EFFECT") + .Color(THEME_COLOR)); UIWidgets::CVarCheckbox("Show additional detail timers", CVAR_GAMEPLAY_STATS("ShowAdditionalTimers"), - UIWidgets::CheckboxOptions().Color(THEME_COLOR)); + UIWidgets::CheckboxOptions().Color(THEME_COLOR)); UIWidgets::CVarCheckbox("Show Debug Info", CVAR_GAMEPLAY_STATS("ShowDebugInfo"), - UIWidgets::CheckboxOptions().Color(THEME_COLOR)); + UIWidgets::CheckboxOptions().Color(THEME_COLOR)); } void GameplayStatsWindow::DrawElement() { @@ -693,7 +715,8 @@ void InitStats(bool isDebug) { for (int scenesIdx = 0; scenesIdx < ARRAY_COUNT(gSaveContext.ship.stats.scenesDiscovered); scenesIdx++) { gSaveContext.ship.stats.scenesDiscovered[scenesIdx] = 0; } - for (int entrancesIdx = 0; entrancesIdx < ARRAY_COUNT(gSaveContext.ship.stats.entrancesDiscovered); entrancesIdx++) { + for (int entrancesIdx = 0; entrancesIdx < ARRAY_COUNT(gSaveContext.ship.stats.entrancesDiscovered); + entrancesIdx++) { gSaveContext.ship.stats.entrancesDiscovered[entrancesIdx] = 0; } diff --git a/soh/soh/Enhancements/gameplaystats.h b/soh/soh/Enhancements/gameplaystats.h index b4d140f1f..1f89cb3a4 100644 --- a/soh/soh/Enhancements/gameplaystats.h +++ b/soh/soh/Enhancements/gameplaystats.h @@ -6,30 +6,32 @@ #ifdef __cplusplus extern "C" { #endif - uint64_t GetUnixTimestamp(void); - char* GameplayStats_GetCurrentTime(); +uint64_t GetUnixTimestamp(void); +char* GameplayStats_GetCurrentTime(); #ifdef __cplusplus }; #endif // When using RTA timing - // get the diff since the save was created, - // unless the game is complete in which we use the defeated ganon timestamp +// get the diff since the save was created, +// unless the game is complete in which we use the defeated ganon timestamp // When not using RTA timing - // Total gameplay time is tracked in tenths of seconds - // I.E. game time counts frames at 20fps/2, pause time counts frames at 30fps/3 - // Frame counts in z_play.c and z_kaleido_scope_call.c -#define GAMEPLAYSTAT_TOTAL_TIME (gSaveContext.ship.stats.rtaTiming ?\ - (!gSaveContext.ship.stats.gameComplete ?\ - (!gSaveContext.ship.stats.fileCreatedAt ? 0 : ((GetUnixTimestamp() - gSaveContext.ship.stats.fileCreatedAt) / 100)) :\ - (gSaveContext.ship.stats.itemTimestamp[TIMESTAMP_DEFEAT_GANON] \ +// Total gameplay time is tracked in tenths of seconds +// I.E. game time counts frames at 20fps/2, pause time counts frames at 30fps/3 +// Frame counts in z_play.c and z_kaleido_scope_call.c +#define GAMEPLAYSTAT_TOTAL_TIME \ + (gSaveContext.ship.stats.rtaTiming \ + ? (!gSaveContext.ship.stats.gameComplete \ + ? (!gSaveContext.ship.stats.fileCreatedAt \ + ? 0 \ + : ((GetUnixTimestamp() - gSaveContext.ship.stats.fileCreatedAt) / 100)) \ + : (gSaveContext.ship.stats.itemTimestamp[TIMESTAMP_DEFEAT_GANON] \ ? gSaveContext.ship.stats.itemTimestamp[TIMESTAMP_DEFEAT_GANON] \ : gSaveContext.ship.stats.itemTimestamp[TIMESTAMP_TRIFORCE_COMPLETED])) \ - :\ - (gSaveContext.ship.stats.playTimer / 2 + gSaveContext.ship.stats.pauseTimer / 3)) -#define CURRENT_MODE_TIMER (CVarGetInteger(CVAR_GAMEPLAY_STATS("RoomBreakdown"), 0) ?\ - gSaveContext.ship.stats.roomTimer :\ - gSaveContext.ship.stats.sceneTimer) + : (gSaveContext.ship.stats.playTimer / 2 + gSaveContext.ship.stats.pauseTimer / 3)) +#define CURRENT_MODE_TIMER \ + (CVarGetInteger(CVAR_GAMEPLAY_STATS("RoomBreakdown"), 0) ? gSaveContext.ship.stats.roomTimer \ + : gSaveContext.ship.stats.sceneTimer) void InitStatTracker(); @@ -37,22 +39,22 @@ typedef enum { // 0x00 to 0x9B (0 to 155) used for getting items, // piggybacked off enum "ItemID" in z64item.h - /* 0xA0 */ TIMESTAMP_DEFEAT_GOHMA = 0xA0, // z_boss_goma.c - /* 0xA1 */ TIMESTAMP_DEFEAT_KING_DODONGO, // z_boss_dodongo.c - /* 0xA2 */ TIMESTAMP_DEFEAT_BARINADE, // z_boss_va.c - /* 0xA3 */ TIMESTAMP_DEFEAT_PHANTOM_GANON, // z_boss_ganondrof.c - /* 0xA4 */ TIMESTAMP_DEFEAT_VOLVAGIA, // z_boss_fd2.c - /* 0xA5 */ TIMESTAMP_DEFEAT_MORPHA, // z_boss_mo.c - /* 0xA6 */ TIMESTAMP_DEFEAT_BONGO_BONGO, // z_boss_sst.c - /* 0xA7 */ TIMESTAMP_DEFEAT_TWINROVA, // z_boss_tw.c - /* 0xA8 */ TIMESTAMP_DEFEAT_GANONDORF, // z_boss_ganon.c - /* 0xA9 */ TIMESTAMP_DEFEAT_GANON, // z_boss_ganon2.c - /* 0xA9 */ TIMESTAMP_BOSSRUSH_FINISH, // z_boss_ganon2.c - /* 0xAA */ TIMESTAMP_FOUND_GREG, // z_parameter.c - /* 0xAA */ TIMESTAMP_TRIFORCE_COMPLETED, // z_parameter.c + /* 0xA0 */ TIMESTAMP_DEFEAT_GOHMA = 0xA0, // z_boss_goma.c + /* 0xA1 */ TIMESTAMP_DEFEAT_KING_DODONGO, // z_boss_dodongo.c + /* 0xA2 */ TIMESTAMP_DEFEAT_BARINADE, // z_boss_va.c + /* 0xA3 */ TIMESTAMP_DEFEAT_PHANTOM_GANON, // z_boss_ganondrof.c + /* 0xA4 */ TIMESTAMP_DEFEAT_VOLVAGIA, // z_boss_fd2.c + /* 0xA5 */ TIMESTAMP_DEFEAT_MORPHA, // z_boss_mo.c + /* 0xA6 */ TIMESTAMP_DEFEAT_BONGO_BONGO, // z_boss_sst.c + /* 0xA7 */ TIMESTAMP_DEFEAT_TWINROVA, // z_boss_tw.c + /* 0xA8 */ TIMESTAMP_DEFEAT_GANONDORF, // z_boss_ganon.c + /* 0xA9 */ TIMESTAMP_DEFEAT_GANON, // z_boss_ganon2.c + /* 0xA9 */ TIMESTAMP_BOSSRUSH_FINISH, // z_boss_ganon2.c + /* 0xAA */ TIMESTAMP_FOUND_GREG, // z_parameter.c + /* 0xAA */ TIMESTAMP_TRIFORCE_COMPLETED, // z_parameter.c /* 0xAB */ TIMESTAMP_MAX -}GameplayStatTimestamp; +} GameplayStatTimestamp; typedef enum { // Enemies defeated diff --git a/soh/soh/Enhancements/gameplaystatswindow.h b/soh/soh/Enhancements/gameplaystatswindow.h index 446cc1ef4..16cf94e53 100644 --- a/soh/soh/Enhancements/gameplaystatswindow.h +++ b/soh/soh/Enhancements/gameplaystatswindow.h @@ -6,5 +6,5 @@ class GameplayStatsWindow : public Ship::GuiWindow { void InitElement() override; void DrawElement() override; - void UpdateElement() override {}; + void UpdateElement() override{}; }; \ No newline at end of file diff --git a/soh/soh/Enhancements/item-tables/ItemTableManager.h b/soh/soh/Enhancements/item-tables/ItemTableManager.h index e20632f38..8420e6897 100644 --- a/soh/soh/Enhancements/item-tables/ItemTableManager.h +++ b/soh/soh/Enhancements/item-tables/ItemTableManager.h @@ -8,16 +8,16 @@ typedef std::unordered_map ItemTable; class ItemTableManager { public: - static ItemTableManager* Instance; - ItemTableManager(); - ~ItemTableManager(); - bool AddItemTable(uint16_t tableID); - bool AddItemEntry(uint16_t tableID, uint16_t getItemID, GetItemEntry getItemEntry); - GetItemEntry RetrieveItemEntry(uint16_t tableID, uint16_t getItemID); - bool ClearItemTable(uint16_t tableID); + static ItemTableManager* Instance; + ItemTableManager(); + ~ItemTableManager(); + bool AddItemTable(uint16_t tableID); + bool AddItemEntry(uint16_t tableID, uint16_t getItemID, GetItemEntry getItemEntry); + GetItemEntry RetrieveItemEntry(uint16_t tableID, uint16_t getItemID); + bool ClearItemTable(uint16_t tableID); private: - std::unordered_map itemTables; + std::unordered_map itemTables; - ItemTable* RetrieveItemTable(uint16_t tableID); + ItemTable* RetrieveItemTable(uint16_t tableID); }; diff --git a/soh/soh/Enhancements/item-tables/ItemTableTypes.h b/soh/soh/Enhancements/item-tables/ItemTableTypes.h index d9d742717..df59d6770 100644 --- a/soh/soh/Enhancements/item-tables/ItemTableTypes.h +++ b/soh/soh/Enhancements/item-tables/ItemTableTypes.h @@ -29,11 +29,18 @@ typedef enum GetItemCategory { /* 0x05 */ ITEM_CATEGORY_MAJOR, } GetItemCategory; -#define GET_ITEM(itemId, objectId, drawId, textId, field, chestAnim, itemCategory, modIndex, getItemId) \ - { itemId, field, (int16_t)((chestAnim != CHEST_ANIM_SHORT ? 1 : -1) * (drawId + 1)), textId, objectId, modIndex, modIndex, getItemId, drawId, true, ITEM_FROM_NPC, itemCategory, itemId, modIndex, NULL } +#define GET_ITEM(itemId, objectId, drawId, textId, field, chestAnim, itemCategory, modIndex, getItemId) \ + { \ + itemId, field, (int16_t)((chestAnim != CHEST_ANIM_SHORT ? 1 : -1) * (drawId + 1)), textId, objectId, modIndex, \ + modIndex, getItemId, drawId, true, ITEM_FROM_NPC, itemCategory, itemId, modIndex, NULL \ + } -#define GET_ITEM_CUSTOM_TABLE(itemId, objectId, drawId, textId, field, chestAnim, itemCategory, modIndex, tableId, getItemId) \ - { itemId, field, (int16_t)((chestAnim != CHEST_ANIM_SHORT ? 1 : -1) * (drawId + 1)), textId, objectId, modIndex, tableId, getItemId, drawId, true, ITEM_FROM_NPC, itemCategory, itemId, modIndex, NULL } +#define GET_ITEM_CUSTOM_TABLE(itemId, objectId, drawId, textId, field, chestAnim, itemCategory, modIndex, tableId, \ + getItemId) \ + { \ + itemId, field, (int16_t)((chestAnim != CHEST_ANIM_SHORT ? 1 : -1) * (drawId + 1)), textId, objectId, modIndex, \ + tableId, getItemId, drawId, true, ITEM_FROM_NPC, itemCategory, itemId, modIndex, NULL \ + } #define GET_ITEM_NONE \ { ITEM_NONE, 0, 0, 0, 0, 0, 0, 0, 0, false, ITEM_FROM_NPC, ITEM_CATEGORY_JUNK, ITEM_NONE, 0, NULL } @@ -50,13 +57,16 @@ typedef struct GetItemEntry { /* 0x03 */ uint16_t textId; /* 0x04 */ uint16_t objectId; /* 0x06 */ uint16_t modIndex; // Primarily used for determining whether to use Item_Give or Randomizer_Item_Give - /* 0x07 */ uint16_t tableId; // GetItemEntry table this entry is in (usually the same as modIndex, but not always) + /* 0x07 */ uint16_t tableId; // GetItemEntry table this entry is in (usually the same as modIndex, but not always) /* 0x08 */ int16_t getItemId; /* 0x0A */ uint16_t gid; // Stores the GID value unmodified for future reference. - /* 0x0C */ uint16_t collectable; // determines whether the item can be collected on the overworld. Will be true in most cases. + /* 0x0C */ uint16_t + collectable; // determines whether the item can be collected on the overworld. Will be true in most cases. /* 0x0E */ GetItemFrom getItemFrom; /* 0x0F */ GetItemCategory getItemCategory; // Primarily made and used for chest size/texture matches contents - /* 0x10 */ uint16_t drawItemId; // Will be a copy of itemId unless the item is an ice trap. Needed for particles to function on ice traps. - /* 0x11 */ uint16_t drawModIndex; // Will be a copy of modIndex unless the item is an ice trap. Needed for particles to function on ice traps. + /* 0x10 */ uint16_t drawItemId; // Will be a copy of itemId unless the item is an ice trap. Needed for particles to + // function on ice traps. + /* 0x11 */ uint16_t drawModIndex; // Will be a copy of modIndex unless the item is an ice trap. Needed for particles + // to function on ice traps. CustomDrawFunc drawFunc; } GetItemEntry; // size = 0x11 diff --git a/soh/soh/Enhancements/kaleido.cpp b/soh/soh/Enhancements/kaleido.cpp index 449d1612d..eef19b495 100644 --- a/soh/soh/Enhancements/kaleido.cpp +++ b/soh/soh/Enhancements/kaleido.cpp @@ -27,429 +27,423 @@ void KaleidoScope_MoveCursorToSpecialPos(PlayState* play, u16 specialPos); namespace Rando { - void KaleidoEntryIcon::LoadIconTex(std::vector* mEntryDl) { - if (mIconFormat == G_IM_FMT_IA) { - if (mIconSize == G_IM_SIZ_8b) { - Gfx iconTexture[] = { gsDPLoadTextureBlock(mIconResourceName, G_IM_FMT_IA, G_IM_SIZ_8b, mIconWidth, mIconHeight, 0, - G_TX_NOMIRROR | G_TX_WRAP, G_TX_NOMIRROR | G_TX_WRAP, G_TX_NOMASK, G_TX_NOMASK, - G_TX_NOLOD, G_TX_NOLOD) }; - mEntryDl->insert(mEntryDl->end(), std::begin(iconTexture), std::end(iconTexture)); - } - } else if (mIconFormat == G_IM_FMT_RGBA) { - if (mIconSize == G_IM_SIZ_32b) { - Gfx iconTexture[] = { gsDPLoadTextureBlock(mIconResourceName, G_IM_FMT_RGBA, G_IM_SIZ_32b, mIconWidth, mIconHeight, 0, - G_TX_NOMIRROR | G_TX_WRAP, G_TX_NOMIRROR | G_TX_WRAP, G_TX_NOMASK, G_TX_NOMASK, - G_TX_NOLOD, G_TX_NOLOD) }; - mEntryDl->insert(mEntryDl->end(), std::begin(iconTexture), std::end(iconTexture)); - } +void KaleidoEntryIcon::LoadIconTex(std::vector* mEntryDl) { + if (mIconFormat == G_IM_FMT_IA) { + if (mIconSize == G_IM_SIZ_8b) { + Gfx iconTexture[] = { gsDPLoadTextureBlock( + mIconResourceName, G_IM_FMT_IA, G_IM_SIZ_8b, mIconWidth, mIconHeight, 0, G_TX_NOMIRROR | G_TX_WRAP, + G_TX_NOMIRROR | G_TX_WRAP, G_TX_NOMASK, G_TX_NOMASK, G_TX_NOLOD, G_TX_NOLOD) }; + mEntryDl->insert(mEntryDl->end(), std::begin(iconTexture), std::end(iconTexture)); + } + } else if (mIconFormat == G_IM_FMT_RGBA) { + if (mIconSize == G_IM_SIZ_32b) { + Gfx iconTexture[] = { gsDPLoadTextureBlock( + mIconResourceName, G_IM_FMT_RGBA, G_IM_SIZ_32b, mIconWidth, mIconHeight, 0, G_TX_NOMIRROR | G_TX_WRAP, + G_TX_NOMIRROR | G_TX_WRAP, G_TX_NOMASK, G_TX_NOMASK, G_TX_NOLOD, G_TX_NOLOD) }; + mEntryDl->insert(mEntryDl->end(), std::begin(iconTexture), std::end(iconTexture)); } } +} - KaleidoEntry::KaleidoEntry(int16_t x, int16_t y, std::string text) : mX(x), mY(y), mText(std::move(text)) { - mHeight = 0; - mWidth = 0; - vtx = nullptr; +KaleidoEntry::KaleidoEntry(int16_t x, int16_t y, std::string text) : mX(x), mY(y), mText(std::move(text)) { + mHeight = 0; + mWidth = 0; + vtx = nullptr; +} + +void KaleidoEntry::SetYOffset(int yOffset) { + mY = yOffset; +} + +void KaleidoEntryIcon::Draw(PlayState* play, std::vector* mEntryDl) { + if (vtx == nullptr) { + return; + } + size_t numChar = mText.length(); + if (numChar == 0) { + return; } - void KaleidoEntry::SetYOffset(int yOffset) { - mY = yOffset; + Color_RGBA8 textColor = { 255, 255, 255, 255 }; + if (mAchieved) { + textColor = { 0x98, 0xFF, 0x44, 255 }; } - void KaleidoEntryIcon::Draw(PlayState* play, std::vector* mEntryDl) { - if (vtx == nullptr) { - return; - } - size_t numChar = mText.length(); - if (numChar == 0) { - return; - } + Matrix_Translate(mX, mY, 0.0f, MTXMODE_APPLY); - Color_RGBA8 textColor = { 255, 255, 255, 255 }; - if (mAchieved) { - textColor = { 0x98, 0xFF, 0x44, 255 }; - } + mEntryDl->push_back(gsSPMatrix(Matrix_NewMtx(play->state.gfxCtx, (char*)__FILE__, __LINE__), + G_MTX_PUSH | G_MTX_LOAD | G_MTX_MODELVIEW)); - Matrix_Translate(mX, mY, 0.0f, MTXMODE_APPLY); - - mEntryDl->push_back(gsSPMatrix(Matrix_NewMtx(play->state.gfxCtx, (char*)__FILE__, __LINE__), G_MTX_PUSH | G_MTX_LOAD | G_MTX_MODELVIEW)); - - // icon - if (!mAchieved) { - mEntryDl->push_back(gsDPSetGrayscaleColor(109, 109, 109, 255)); - mEntryDl->push_back(gsSPGrayscale(true)); - } - mEntryDl->push_back(gsDPSetPrimColor(0, 0, mIconColor.r, mIconColor.g, mIconColor.b, mIconColor.a)); - mEntryDl->push_back(gsSPVertex(vtx, 4, 0)); - LoadIconTex(mEntryDl); - mEntryDl->push_back(gsSP1Quadrangle(0, 2, 3, 1, 0)); - mEntryDl->push_back(gsSPGrayscale(false)); - - // text - mEntryDl->push_back(gsDPSetPrimColor(0, 0, textColor.r, textColor.g, textColor.b, textColor.a)); - for (size_t i = 0, vtxGroup = 0; i < numChar; i++) { - // A maximum of 64 Vtx can be loaded at once by gSPVertex, or basically 16 characters - // handle loading groups of 16 chars at a time until there are no more left to load. - // By this point 4 vertices have already been loaded for the preceding icon. - if (i % 16 == 0) { - size_t numVtxToLoad = std::min(numChar - i, 16) * 4; - mEntryDl->push_back(gsSPVertex(&vtx[4 + (vtxGroup * 16 * 4)], numVtxToLoad, 0)); - vtxGroup++; - } - - auto texture = reinterpret_cast(Ship_GetCharFontTexture(mText[i])); - auto vertexStart = static_cast(4 * (i % 16)); - - Gfx charTexture[] = { gsDPLoadTextureBlock_4b( - texture, G_IM_FMT_I, FONT_CHAR_TEX_WIDTH, FONT_CHAR_TEX_HEIGHT, 0, G_TX_NOMIRROR | G_TX_CLAMP, - G_TX_NOMIRROR | G_TX_CLAMP, G_TX_NOMASK, G_TX_NOMASK, G_TX_NOLOD, G_TX_NOLOD) }; - mEntryDl->insert(mEntryDl->end(), std::begin(charTexture), std::end(charTexture)); - mEntryDl->push_back(gsSP1Quadrangle(vertexStart, vertexStart + 2, vertexStart + 3, vertexStart + 1, 0)); - } - mEntryDl->push_back(gsSPPopMatrix(G_MTX_MODELVIEW)); + // icon + if (!mAchieved) { + mEntryDl->push_back(gsDPSetGrayscaleColor(109, 109, 109, 255)); + mEntryDl->push_back(gsSPGrayscale(true)); } + mEntryDl->push_back(gsDPSetPrimColor(0, 0, mIconColor.r, mIconColor.g, mIconColor.b, mIconColor.a)); + mEntryDl->push_back(gsSPVertex(vtx, 4, 0)); + LoadIconTex(mEntryDl); + mEntryDl->push_back(gsSP1Quadrangle(0, 2, 3, 1, 0)); + mEntryDl->push_back(gsSPGrayscale(false)); - Kaleido::Kaleido() { - const auto ctx = Rando::Context::GetInstance(); - int yOffset = 2; - mEntries.push_back(std::make_shared(gRupeeCounterIconTex, G_IM_FMT_IA, G_IM_SIZ_8b, 16, 16, - Color_RGBA8{ 0xC8, 0xFF, 0x64, 255 }, FlagType::FLAG_RANDOMIZER_INF, - static_cast(RAND_INF_GREG_FOUND), 0, yOffset, "Greg")); + // text + mEntryDl->push_back(gsDPSetPrimColor(0, 0, textColor.r, textColor.g, textColor.b, textColor.a)); + for (size_t i = 0, vtxGroup = 0; i < numChar; i++) { + // A maximum of 64 Vtx can be loaded at once by gSPVertex, or basically 16 characters + // handle loading groups of 16 chars at a time until there are no more left to load. + // By this point 4 vertices have already been loaded for the preceding icon. + if (i % 16 == 0) { + size_t numVtxToLoad = std::min(numChar - i, 16) * 4; + mEntryDl->push_back(gsSPVertex(&vtx[4 + (vtxGroup * 16 * 4)], numVtxToLoad, 0)); + vtxGroup++; + } + + auto texture = reinterpret_cast(Ship_GetCharFontTexture(mText[i])); + auto vertexStart = static_cast(4 * (i % 16)); + + Gfx charTexture[] = { gsDPLoadTextureBlock_4b(texture, G_IM_FMT_I, FONT_CHAR_TEX_WIDTH, FONT_CHAR_TEX_HEIGHT, 0, + G_TX_NOMIRROR | G_TX_CLAMP, G_TX_NOMIRROR | G_TX_CLAMP, + G_TX_NOMASK, G_TX_NOMASK, G_TX_NOLOD, G_TX_NOLOD) }; + mEntryDl->insert(mEntryDl->end(), std::begin(charTexture), std::end(charTexture)); + mEntryDl->push_back(gsSP1Quadrangle(vertexStart, vertexStart + 2, vertexStart + 3, vertexStart + 1, 0)); + } + mEntryDl->push_back(gsSPPopMatrix(G_MTX_MODELVIEW)); +} + +Kaleido::Kaleido() { + const auto ctx = Rando::Context::GetInstance(); + int yOffset = 2; + mEntries.push_back(std::make_shared( + gRupeeCounterIconTex, G_IM_FMT_IA, G_IM_SIZ_8b, 16, 16, Color_RGBA8{ 0xC8, 0xFF, 0x64, 255 }, + FlagType::FLAG_RANDOMIZER_INF, static_cast(RAND_INF_GREG_FOUND), 0, yOffset, "Greg")); + yOffset += 18; + if (ctx->GetOption(RSK_TRIFORCE_HUNT)) { + mEntries.push_back(std::make_shared( + gTriforcePieceTex, G_IM_FMT_RGBA, G_IM_SIZ_32b, 32, 32, Color_RGBA8{ 255, 255, 255, 255 }, 0, yOffset, + reinterpret_cast(&gSaveContext.ship.quest.data.randomizer.triforcePiecesCollected), + ctx->GetOption(RSK_TRIFORCE_HUNT_PIECES_REQUIRED).Get() + 1, + ctx->GetOption(RSK_TRIFORCE_HUNT_PIECES_TOTAL).Get() + 1)); yOffset += 18; - if (ctx->GetOption(RSK_TRIFORCE_HUNT)) { - mEntries.push_back( - std::make_shared( - gTriforcePieceTex, G_IM_FMT_RGBA, G_IM_SIZ_32b, 32, 32, Color_RGBA8{ 255,255,255,255 }, 0, - yOffset, reinterpret_cast(&gSaveContext.ship.quest.data.randomizer.triforcePiecesCollected), - ctx->GetOption(RSK_TRIFORCE_HUNT_PIECES_REQUIRED).Get() + 1, - ctx->GetOption(RSK_TRIFORCE_HUNT_PIECES_TOTAL).Get() + 1)); - yOffset += 18; - } - if (ctx->GetOption(RSK_SHUFFLE_OCARINA_BUTTONS)) { - mEntries.push_back(std::make_shared(0, yOffset)); - yOffset += 18; - } - if (ctx->GetOption(RSK_SHUFFLE_BOSS_SOULS).IsNot(RO_BOSS_SOULS_OFF)) { - static const char* bossSoulNames[] = { - "Gohma's Soul", - "King Dodongo's Soul", - "Barinade's Soul", - "Phantom Ganon's Soul", - "Volvagia's Soul", - "Morpha's Soul", - "Bongo Bongo's Soul", - "Twinrova's Soul", - }; - for (int i = RAND_INF_GOHMA_SOUL; i < RAND_INF_GANON_SOUL; i++) { - mEntries.push_back( - std::make_shared( - gBossSoulTex, G_IM_FMT_RGBA, G_IM_SIZ_32b, 32, 32, Color_RGBA8{ 255, 255, 255, 255 }, - FlagType::FLAG_RANDOMIZER_INF, i, 0, yOffset, bossSoulNames[i - RAND_INF_GOHMA_SOUL] - ) - ); - yOffset += 18; - } - } - if (ctx->GetOption(RSK_SHUFFLE_BOSS_SOULS).Is(RO_BOSS_SOULS_ON_PLUS_GANON)) { - mEntries.push_back( - std::make_shared( - gBossSoulTex, G_IM_FMT_RGBA, G_IM_SIZ_32b, 32, 32, Color_RGBA8{ 255, 255, 255, 255 }, - FlagType::FLAG_RANDOMIZER_INF, RAND_INF_GANON_SOUL, 0, yOffset, "Ganon's Soul" - ) - ); + } + if (ctx->GetOption(RSK_SHUFFLE_OCARINA_BUTTONS)) { + mEntries.push_back(std::make_shared(0, yOffset)); + yOffset += 18; + } + if (ctx->GetOption(RSK_SHUFFLE_BOSS_SOULS).IsNot(RO_BOSS_SOULS_OFF)) { + static const char* bossSoulNames[] = { + "Gohma's Soul", "King Dodongo's Soul", "Barinade's Soul", "Phantom Ganon's Soul", + "Volvagia's Soul", "Morpha's Soul", "Bongo Bongo's Soul", "Twinrova's Soul", + }; + for (int i = RAND_INF_GOHMA_SOUL; i < RAND_INF_GANON_SOUL; i++) { + mEntries.push_back(std::make_shared( + gBossSoulTex, G_IM_FMT_RGBA, G_IM_SIZ_32b, 32, 32, Color_RGBA8{ 255, 255, 255, 255 }, + FlagType::FLAG_RANDOMIZER_INF, i, 0, yOffset, bossSoulNames[i - RAND_INF_GOHMA_SOUL])); yOffset += 18; } } - - extern "C" { - void FrameInterpolation_RecordCloseChild(void); - void FrameInterpolation_RecordOpenChild(const void* a, int b); + if (ctx->GetOption(RSK_SHUFFLE_BOSS_SOULS).Is(RO_BOSS_SOULS_ON_PLUS_GANON)) { + mEntries.push_back(std::make_shared( + gBossSoulTex, G_IM_FMT_RGBA, G_IM_SIZ_32b, 32, 32, Color_RGBA8{ 255, 255, 255, 255 }, + FlagType::FLAG_RANDOMIZER_INF, RAND_INF_GANON_SOUL, 0, yOffset, "Ganon's Soul")); + yOffset += 18; } +} - void Kaleido::Draw(PlayState* play) { - if (play == nullptr || mEntries.empty()) { - return; - } - PauseContext* pauseCtx = &play->pauseCtx; - Input* input = &play->state.input[0]; - mEntryDl.clear(); - OPEN_DISPS(play->state.gfxCtx); - mEntryDl.push_back(gsDPPipeSync()); - Gfx_SetupDL_42Opa(play->state.gfxCtx); - mEntryDl.push_back(gsDPSetCombineMode(G_CC_MODULATEIA_PRIM, G_CC_MODULATEIA_PRIM)); +extern "C" { +void FrameInterpolation_RecordCloseChild(void); +void FrameInterpolation_RecordOpenChild(const void* a, int b); +} - // Move the matrix origin to the top-left corner of the kaleido page - Matrix_Translate(-108.f, 58.f, 0.0f, MTXMODE_APPLY); - // Invert the matrix to render vertices with positive going down - Matrix_Scale(1.0f, -1.0f, 1.0f, MTXMODE_APPLY); - // The scrolling logic is in here because the built in kaleido input throttling happens - // in its Draw functions, which get called after their update functions. I hate it but fixing - // it would be a much larger Kaleido change. - bool shouldScroll = false; - bool dpad = CVarGetInteger(CVAR_SETTING("DPadOnPause"), 0); - if (((pauseCtx->unk_1E4 == 0) || (pauseCtx->unk_1E4 == 5) || (pauseCtx->unk_1E4 == 8)) && - (pauseCtx->pageIndex == PAUSE_QUEST)) { - if (!((pauseCtx->state != 6) || ((pauseCtx->stickRelX == 0) && (pauseCtx->stickRelY == 0)))) { - if (pauseCtx->cursorSpecialPos == 0) { - if ((pauseCtx->stickRelY > 30) || (dpad && CHECK_BTN_ALL(input->press.button, BTN_DUP))) { - if (mTopIndex > 0) { - mTopIndex--; - shouldScroll = true; - } - } else if ((pauseCtx->stickRelY < -30) || (dpad && CHECK_BTN_ALL(input->press.button, BTN_DDOWN))) { - if (mTopIndex + mNumVisible < mEntries.size()) { - mTopIndex++; - shouldScroll = true; - } +void Kaleido::Draw(PlayState* play) { + if (play == nullptr || mEntries.empty()) { + return; + } + PauseContext* pauseCtx = &play->pauseCtx; + Input* input = &play->state.input[0]; + mEntryDl.clear(); + OPEN_DISPS(play->state.gfxCtx); + mEntryDl.push_back(gsDPPipeSync()); + Gfx_SetupDL_42Opa(play->state.gfxCtx); + mEntryDl.push_back(gsDPSetCombineMode(G_CC_MODULATEIA_PRIM, G_CC_MODULATEIA_PRIM)); + + // Move the matrix origin to the top-left corner of the kaleido page + Matrix_Translate(-108.f, 58.f, 0.0f, MTXMODE_APPLY); + // Invert the matrix to render vertices with positive going down + Matrix_Scale(1.0f, -1.0f, 1.0f, MTXMODE_APPLY); + // The scrolling logic is in here because the built in kaleido input throttling happens + // in its Draw functions, which get called after their update functions. I hate it but fixing + // it would be a much larger Kaleido change. + bool shouldScroll = false; + bool dpad = CVarGetInteger(CVAR_SETTING("DPadOnPause"), 0); + if (((pauseCtx->unk_1E4 == 0) || (pauseCtx->unk_1E4 == 5) || (pauseCtx->unk_1E4 == 8)) && + (pauseCtx->pageIndex == PAUSE_QUEST)) { + if (!((pauseCtx->state != 6) || ((pauseCtx->stickRelX == 0) && (pauseCtx->stickRelY == 0)))) { + if (pauseCtx->cursorSpecialPos == 0) { + if ((pauseCtx->stickRelY > 30) || (dpad && CHECK_BTN_ALL(input->press.button, BTN_DUP))) { + if (mTopIndex > 0) { + mTopIndex--; + shouldScroll = true; } - if ((pauseCtx->stickRelX < -30) || (dpad && CHECK_BTN_ALL(input->press.button, BTN_DLEFT))) { - KaleidoScope_MoveCursorToSpecialPos(play, PAUSE_CURSOR_PAGE_LEFT); - pauseCtx->unk_1E4 = 0; - } else if ((pauseCtx->stickRelX > 30) || (dpad && CHECK_BTN_ALL(input->press.button, BTN_DRIGHT))) { - KaleidoScope_MoveCursorToSpecialPos(play, PAUSE_CURSOR_PAGE_RIGHT); - pauseCtx->unk_1E4 = 0; - } - } else if (pauseCtx->cursorSpecialPos == PAUSE_CURSOR_PAGE_LEFT) { - if ((pauseCtx->stickRelX > 30) || (dpad && CHECK_BTN_ALL(input->press.button, BTN_DRIGHT))) { - pauseCtx->cursorSpecialPos = 0; - Audio_PlaySoundGeneral(NA_SE_SY_CURSOR, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb); - } - } else if (pauseCtx->cursorSpecialPos == PAUSE_CURSOR_PAGE_RIGHT) { - if ((pauseCtx->stickRelX < -30) || (dpad && CHECK_BTN_ALL(input->press.button, BTN_DLEFT))) { - pauseCtx->cursorSpecialPos = 0; - Audio_PlaySoundGeneral(NA_SE_SY_CURSOR, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb); + } else if ((pauseCtx->stickRelY < -30) || (dpad && CHECK_BTN_ALL(input->press.button, BTN_DDOWN))) { + if (mTopIndex + mNumVisible < mEntries.size()) { + mTopIndex++; + shouldScroll = true; } } - } else if (pauseCtx->cursorSpecialPos != 0 && pauseCtx->state == 7) { - pauseCtx->cursorSpecialPos = 0; + if ((pauseCtx->stickRelX < -30) || (dpad && CHECK_BTN_ALL(input->press.button, BTN_DLEFT))) { + KaleidoScope_MoveCursorToSpecialPos(play, PAUSE_CURSOR_PAGE_LEFT); + pauseCtx->unk_1E4 = 0; + } else if ((pauseCtx->stickRelX > 30) || (dpad && CHECK_BTN_ALL(input->press.button, BTN_DRIGHT))) { + KaleidoScope_MoveCursorToSpecialPos(play, PAUSE_CURSOR_PAGE_RIGHT); + pauseCtx->unk_1E4 = 0; + } + } else if (pauseCtx->cursorSpecialPos == PAUSE_CURSOR_PAGE_LEFT) { + if ((pauseCtx->stickRelX > 30) || (dpad && CHECK_BTN_ALL(input->press.button, BTN_DRIGHT))) { + pauseCtx->cursorSpecialPos = 0; + Audio_PlaySoundGeneral(NA_SE_SY_CURSOR, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, + &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb); + } + } else if (pauseCtx->cursorSpecialPos == PAUSE_CURSOR_PAGE_RIGHT) { + if ((pauseCtx->stickRelX < -30) || (dpad && CHECK_BTN_ALL(input->press.button, BTN_DLEFT))) { + pauseCtx->cursorSpecialPos = 0; + Audio_PlaySoundGeneral(NA_SE_SY_CURSOR, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, + &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb); + } } - } - int yOffset = 2; - for (int i = mTopIndex; i < (mTopIndex + mNumVisible) && i < mEntries.size(); i++) { - auto& entry = mEntries[i]; - if (shouldScroll) { - entry->SetYOffset(yOffset); - yOffset += 18; - Audio_PlaySoundGeneral(NA_SE_SY_CURSOR, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb); - } - Matrix_Push(); - entry->Draw(play, &mEntryDl); - Matrix_Pop(); - } - - mEntryDl.push_back(gsSPEndDisplayList()); - gSPDisplayList(POLY_OPA_DISP++, mEntryDl.data()); - CLOSE_DISPS(play->state.gfxCtx); - } - - void Kaleido::Update(PlayState *play) { - for(int i = mTopIndex; i < (mTopIndex + mNumVisible) && i < mEntries.size(); i++) { - const auto& entry = mEntries[i]; - entry->Update(play); + } else if (pauseCtx->cursorSpecialPos != 0 && pauseCtx->state == 7) { + pauseCtx->cursorSpecialPos = 0; } } - - extern "C" void RandoKaleido_DrawMiscCollectibles(PlayState* play) { - OTRGlobals::Instance->gRandoContext->GetKaleido()->Draw(play); - } - - extern "C" void RandoKaleido_UpdateMiscCollectibles(int16_t inDungeonScene) { - PauseContext* pauseCtx = &gPlayState->pauseCtx; - if (pauseCtx->randoQuestMode && pauseCtx->pageIndex == PAUSE_QUEST) { - OTRGlobals::Instance->gRandoContext->GetKaleido()->Update(gPlayState); + int yOffset = 2; + for (int i = mTopIndex; i < (mTopIndex + mNumVisible) && i < mEntries.size(); i++) { + auto& entry = mEntries[i]; + if (shouldScroll) { + entry->SetYOffset(yOffset); + yOffset += 18; + Audio_PlaySoundGeneral(NA_SE_SY_CURSOR, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, + &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb); } + Matrix_Push(); + entry->Draw(play, &mEntryDl); + Matrix_Pop(); } - KaleidoEntryIconFlag::KaleidoEntryIconFlag(const char *iconResourceName, int iconFormat, int iconSize, int iconWidth, - int iconHeight, Color_RGBA8 iconColor, FlagType flagType, int flag, - int16_t x, int16_t y, std::string name) : - mFlagType(flagType), mFlag(flag), - KaleidoEntryIcon(iconResourceName, iconFormat, iconSize, iconWidth, iconHeight, iconColor, x, y, std::move(name)) { - BuildVertices(); - } + mEntryDl.push_back(gsSPEndDisplayList()); + gSPDisplayList(POLY_OPA_DISP++, mEntryDl.data()); + CLOSE_DISPS(play->state.gfxCtx); +} - void KaleidoEntryIconFlag::Update(PlayState* play) { - mAchieved = GameInteractor::RawAction::CheckFlag(mFlagType, static_cast(mFlag)); +void Kaleido::Update(PlayState* play) { + for (int i = mTopIndex; i < (mTopIndex + mNumVisible) && i < mEntries.size(); i++) { + const auto& entry = mEntries[i]; + entry->Update(play); } +} - KaleidoEntryIconCountRequired::KaleidoEntryIconCountRequired(const char *iconResourceName, int iconFormat, - int iconSize, int iconWidth, int iconHeight, Color_RGBA8 iconColor, int16_t x, int16_t y, int* watch, - int required, int total) : mWatch(watch), mRequired(required), mTotal(total), - KaleidoEntryIcon(iconResourceName, iconFormat, iconSize, iconWidth, iconHeight, iconColor, x, y) { +extern "C" void RandoKaleido_DrawMiscCollectibles(PlayState* play) { + OTRGlobals::Instance->gRandoContext->GetKaleido()->Draw(play); +} + +extern "C" void RandoKaleido_UpdateMiscCollectibles(int16_t inDungeonScene) { + PauseContext* pauseCtx = &gPlayState->pauseCtx; + if (pauseCtx->randoQuestMode && pauseCtx->pageIndex == PAUSE_QUEST) { + OTRGlobals::Instance->gRandoContext->GetKaleido()->Update(gPlayState); + } +} + +KaleidoEntryIconFlag::KaleidoEntryIconFlag(const char* iconResourceName, int iconFormat, int iconSize, int iconWidth, + int iconHeight, Color_RGBA8 iconColor, FlagType flagType, int flag, + int16_t x, int16_t y, std::string name) + : mFlagType(flagType), mFlag(flag), KaleidoEntryIcon(iconResourceName, iconFormat, iconSize, iconWidth, iconHeight, + iconColor, x, y, std::move(name)) { + BuildVertices(); +} + +void KaleidoEntryIconFlag::Update(PlayState* play) { + mAchieved = GameInteractor::RawAction::CheckFlag(mFlagType, static_cast(mFlag)); +} + +KaleidoEntryIconCountRequired::KaleidoEntryIconCountRequired(const char* iconResourceName, int iconFormat, int iconSize, + int iconWidth, int iconHeight, Color_RGBA8 iconColor, + int16_t x, int16_t y, int* watch, int required, int total) + : mWatch(watch), mRequired(required), mTotal(total), + KaleidoEntryIcon(iconResourceName, iconFormat, iconSize, iconWidth, iconHeight, iconColor, x, y) { + mCount = *mWatch; + BuildText(); + BuildVertices(); +} + +void KaleidoEntryIconCountRequired::BuildText() { + std::ostringstream totals; + totals << mCount; + if (mRequired != 0 && mCount < mRequired) { + totals << '/' << mRequired; + } + if (mTotal >= mRequired && mCount >= mRequired) { + totals << '/' << mTotal; + } + mText = totals.str(); +} + +void KaleidoEntryIcon::BuildVertices() { + int offsetY = 0; + int offsetX = 0; + // 4 vertices per character, plus one for the preceding icon. + Vtx* vertices = (Vtx*)calloc(sizeof(Vtx[4]), mText.length() + 1); + // Vertex for the preceding icon. + Ship_CreateQuadVertexGroup(vertices, offsetX, offsetY, mIconWidth, mIconHeight, 0); + offsetX += 18; + for (size_t i = 0; i < mText.length(); i++) { + int charWidth = static_cast(Ship_GetCharFontWidth(mText[i])); + Ship_CreateQuadVertexGroup(&(vertices)[(i + 1) * 4], offsetX, offsetY, charWidth, 16, 0); + offsetX += charWidth; + } + offsetY += FONT_CHAR_TEX_HEIGHT; + mWidth = static_cast(offsetX); + mHeight = static_cast(offsetY); + + vertices[1].v.ob[0] = 16; + vertices[2].v.ob[1] = 16; + vertices[3].v.ob[0] = 16; + vertices[3].v.ob[1] = 16; + vtx = vertices; +} + +KaleidoEntryIcon::KaleidoEntryIcon(const char* iconResourceName, int iconFormat, int iconSize, int iconWidth, + int iconHeight, Color_RGBA8 iconColor, int16_t x, int16_t y, std::string text) + : mIconResourceName(iconResourceName), mIconFormat(iconFormat), mIconSize(iconSize), mIconWidth(iconWidth), + mIconHeight(iconHeight), mIconColor(iconColor), KaleidoEntry(x, y, std::move(text)) { +} + +void KaleidoEntryIcon::RebuildVertices() { + free(vtx); + vtx = nullptr; + BuildVertices(); +} + +void KaleidoEntryIconCountRequired::Update(PlayState* play) { + if (mCount != *mWatch) { mCount = *mWatch; BuildText(); - BuildVertices(); + RebuildVertices(); + mAchieved = mCount >= mRequired; } +} - void KaleidoEntryIconCountRequired::BuildText() { - std::ostringstream totals; - totals << mCount; - if (mRequired != 0 && mCount < mRequired) { - totals << '/' << mRequired; - } - if (mTotal >= mRequired && mCount >= mRequired) { - totals << '/' << mTotal; - } - mText = totals.str(); +KaleidoEntryOcarinaButtons::KaleidoEntryOcarinaButtons(int16_t x, int16_t y) + : KaleidoEntryIcon(gItemIconOcarinaOfTimeTex, G_IM_FMT_RGBA, G_IM_SIZ_32b, 32, 32, + Color_RGBA8{ 255, 255, 255, 255 }, x, y, "\x9F\xA5\xA6\xA7\xA8") { + CalculateColors(); + BuildVertices(); +} + +void KaleidoEntryOcarinaButtons::CalculateColors() { + Color_RGB8 aButtonColor = { 80, 150, 255 }; + if (CVarGetInteger(CVAR_COSMETIC("HUD.AButton.Changed"), 0)) { + aButtonColor = CVarGetColor24(CVAR_COSMETIC("HUD.AButton.Value"), aButtonColor); + } else if (CVarGetInteger(CVAR_COSMETIC("DefaultColorScheme"), COLORSCHEME_N64) == COLORSCHEME_GAMECUBE) { + aButtonColor = { 80, 255, 150 }; } - - void KaleidoEntryIcon::BuildVertices() { - int offsetY = 0; - int offsetX = 0; - // 4 vertices per character, plus one for the preceding icon. - Vtx* vertices = (Vtx*)calloc(sizeof(Vtx[4]), mText.length() + 1); - // Vertex for the preceding icon. - Ship_CreateQuadVertexGroup(vertices, offsetX, offsetY, mIconWidth, mIconHeight, 0); - offsetX += 18; - for (size_t i = 0; i < mText.length(); i++) { - int charWidth = static_cast(Ship_GetCharFontWidth(mText[i])); - Ship_CreateQuadVertexGroup(&(vertices)[(i + 1) * 4], offsetX, offsetY, charWidth, 16, 0); - offsetX += charWidth; - } - offsetY += FONT_CHAR_TEX_HEIGHT; - mWidth = static_cast(offsetX); - mHeight = static_cast(offsetY); - - vertices[1].v.ob[0] = 16; - vertices[2].v.ob[1] = 16; - vertices[3].v.ob[0] = 16; - vertices[3].v.ob[1] = 16; - vtx = vertices; + mButtonColors[0] = { aButtonColor.r, aButtonColor.g, aButtonColor.b, 255 }; + Color_RGB8 cButtonsColor = { 255, 255, 50 }; + Color_RGB8 cUpButtonColor = cButtonsColor; + Color_RGB8 cDownButtonColor = cButtonsColor; + Color_RGB8 cLeftButtonColor = cButtonsColor; + Color_RGB8 cRightButtonColor = cButtonsColor; + if (CVarGetInteger(CVAR_COSMETIC("HUD.CButtons.Changed"), 0)) { + cUpButtonColor = CVarGetColor24(CVAR_COSMETIC("HUD.CButtons.Value"), cButtonsColor); + cDownButtonColor = CVarGetColor24(CVAR_COSMETIC("HUD.CButtons.Value"), cButtonsColor); + cLeftButtonColor = CVarGetColor24(CVAR_COSMETIC("HUD.CButtons.Value"), cButtonsColor); + cRightButtonColor = CVarGetColor24(CVAR_COSMETIC("HUD.CButtons.Value"), cButtonsColor); } - - KaleidoEntryIcon::KaleidoEntryIcon(const char *iconResourceName, int iconFormat, int iconSize, int iconWidth, - int iconHeight, Color_RGBA8 iconColor, int16_t x, int16_t y, std::string text) - : mIconResourceName(iconResourceName), mIconFormat(iconFormat), mIconSize(iconSize), - mIconWidth(iconWidth), mIconHeight(iconHeight), mIconColor(iconColor), - KaleidoEntry(x, y, std::move(text)) {} - - void KaleidoEntryIcon::RebuildVertices() { - free(vtx); - vtx = nullptr; - BuildVertices(); + if (CVarGetInteger(CVAR_COSMETIC("HUD.CUpButton.Changed"), 0)) { + cUpButtonColor = CVarGetColor24(CVAR_COSMETIC("HUD.CUpButton.Value"), cUpButtonColor); } - - void KaleidoEntryIconCountRequired::Update(PlayState *play) { - if (mCount != *mWatch) { - mCount = *mWatch; - BuildText(); - RebuildVertices(); - mAchieved = mCount >= mRequired; - } - + if (CVarGetInteger(CVAR_COSMETIC("HUD.CDownButton.Changed"), 0)) { + cDownButtonColor = CVarGetColor24(CVAR_COSMETIC("HUD.CDownButton.Value"), cDownButtonColor); } - - KaleidoEntryOcarinaButtons::KaleidoEntryOcarinaButtons(int16_t x, int16_t y) : - KaleidoEntryIcon(gItemIconOcarinaOfTimeTex, G_IM_FMT_RGBA, G_IM_SIZ_32b, 32, 32, - Color_RGBA8{ 255, 255, 255, 255 }, x, y, "\x9F\xA5\xA6\xA7\xA8") { - CalculateColors(); - BuildVertices(); + if (CVarGetInteger(CVAR_COSMETIC("HUD.CLeftButton.Changed"), 0)) { + cLeftButtonColor = CVarGetColor24(CVAR_COSMETIC("HUD.CLeftButton.Value"), cLeftButtonColor); } - - void KaleidoEntryOcarinaButtons::CalculateColors() { - Color_RGB8 aButtonColor = { 80, 150, 255 }; - if (CVarGetInteger(CVAR_COSMETIC("HUD.AButton.Changed"), 0)) { - aButtonColor = CVarGetColor24(CVAR_COSMETIC("HUD.AButton.Value"), aButtonColor); - } else if (CVarGetInteger(CVAR_COSMETIC("DefaultColorScheme"), COLORSCHEME_N64) == COLORSCHEME_GAMECUBE) { - aButtonColor = { 80, 255, 150}; - } - mButtonColors[0] = { aButtonColor.r, aButtonColor.g, aButtonColor.b, 255 }; - Color_RGB8 cButtonsColor = { 255, 255, 50 }; - Color_RGB8 cUpButtonColor = cButtonsColor; - Color_RGB8 cDownButtonColor = cButtonsColor; - Color_RGB8 cLeftButtonColor = cButtonsColor; - Color_RGB8 cRightButtonColor = cButtonsColor; - if (CVarGetInteger(CVAR_COSMETIC("HUD.CButtons.Changed"), 0)) { - cUpButtonColor = CVarGetColor24(CVAR_COSMETIC("HUD.CButtons.Value"), cButtonsColor); - cDownButtonColor = CVarGetColor24(CVAR_COSMETIC("HUD.CButtons.Value"), cButtonsColor); - cLeftButtonColor = CVarGetColor24(CVAR_COSMETIC("HUD.CButtons.Value"), cButtonsColor); - cRightButtonColor = CVarGetColor24(CVAR_COSMETIC("HUD.CButtons.Value"), cButtonsColor); - } - if (CVarGetInteger(CVAR_COSMETIC("HUD.CUpButton.Changed"), 0)) { - cUpButtonColor = CVarGetColor24(CVAR_COSMETIC("HUD.CUpButton.Value"), cUpButtonColor); - } - if (CVarGetInteger(CVAR_COSMETIC("HUD.CDownButton.Changed"), 0)) { - cDownButtonColor = CVarGetColor24(CVAR_COSMETIC("HUD.CDownButton.Value"), cDownButtonColor); - } - if (CVarGetInteger(CVAR_COSMETIC("HUD.CLeftButton.Changed"), 0)) { - cLeftButtonColor = CVarGetColor24(CVAR_COSMETIC("HUD.CLeftButton.Value"), cLeftButtonColor); - } - if (CVarGetInteger(CVAR_COSMETIC("HUD.CRightButton.Changed"), 0)) { - cRightButtonColor = CVarGetColor24(CVAR_COSMETIC("HUD.CRightButton.Value"), cRightButtonColor); - } - mButtonColors[1] = { cUpButtonColor.r, cUpButtonColor.g, cUpButtonColor.b, 255 }; - mButtonColors[2] = { cDownButtonColor.r, cDownButtonColor.g, cDownButtonColor.b, 255 }; - mButtonColors[3] = { cLeftButtonColor.r, cLeftButtonColor.g, cLeftButtonColor.b, 255 }; - mButtonColors[4] = { cRightButtonColor.r, cRightButtonColor.g, cRightButtonColor.b, 255 }; + if (CVarGetInteger(CVAR_COSMETIC("HUD.CRightButton.Changed"), 0)) { + cRightButtonColor = CVarGetColor24(CVAR_COSMETIC("HUD.CRightButton.Value"), cRightButtonColor); } + mButtonColors[1] = { cUpButtonColor.r, cUpButtonColor.g, cUpButtonColor.b, 255 }; + mButtonColors[2] = { cDownButtonColor.r, cDownButtonColor.g, cDownButtonColor.b, 255 }; + mButtonColors[3] = { cLeftButtonColor.r, cLeftButtonColor.g, cLeftButtonColor.b, 255 }; + mButtonColors[4] = { cRightButtonColor.r, cRightButtonColor.g, cRightButtonColor.b, 255 }; +} - void KaleidoEntryOcarinaButtons::Update(PlayState *play) { - mButtonCollected[0] = GameInteractor::RawAction::CheckFlag(FLAG_RANDOMIZER_INF, RAND_INF_HAS_OCARINA_A) > 0; - mButtonCollected[1] = GameInteractor::RawAction::CheckFlag(FLAG_RANDOMIZER_INF, RAND_INF_HAS_OCARINA_C_UP) > 0; - mButtonCollected[2] = GameInteractor::RawAction::CheckFlag(FLAG_RANDOMIZER_INF, RAND_INF_HAS_OCARINA_C_DOWN) > 0; - mButtonCollected[3] = GameInteractor::RawAction::CheckFlag(FLAG_RANDOMIZER_INF, RAND_INF_HAS_OCARINA_C_LEFT) > 0; - mButtonCollected[4] = GameInteractor::RawAction::CheckFlag(FLAG_RANDOMIZER_INF, RAND_INF_HAS_OCARINA_C_RIGHT) > 0; - CalculateColors(); - mAchieved = false; - for (int i = 0; i < mButtonCollected.size(); i++) { - if (!mButtonCollected[i]) { - mButtonColors[i] = Color_RGBA8{ 109, 109, 109, 255 }; - } else { - mAchieved = true; - } +void KaleidoEntryOcarinaButtons::Update(PlayState* play) { + mButtonCollected[0] = GameInteractor::RawAction::CheckFlag(FLAG_RANDOMIZER_INF, RAND_INF_HAS_OCARINA_A) > 0; + mButtonCollected[1] = GameInteractor::RawAction::CheckFlag(FLAG_RANDOMIZER_INF, RAND_INF_HAS_OCARINA_C_UP) > 0; + mButtonCollected[2] = GameInteractor::RawAction::CheckFlag(FLAG_RANDOMIZER_INF, RAND_INF_HAS_OCARINA_C_DOWN) > 0; + mButtonCollected[3] = GameInteractor::RawAction::CheckFlag(FLAG_RANDOMIZER_INF, RAND_INF_HAS_OCARINA_C_LEFT) > 0; + mButtonCollected[4] = GameInteractor::RawAction::CheckFlag(FLAG_RANDOMIZER_INF, RAND_INF_HAS_OCARINA_C_RIGHT) > 0; + CalculateColors(); + mAchieved = false; + for (int i = 0; i < mButtonCollected.size(); i++) { + if (!mButtonCollected[i]) { + mButtonColors[i] = Color_RGBA8{ 109, 109, 109, 255 }; + } else { + mAchieved = true; } } +} - void KaleidoEntryOcarinaButtons::Draw(PlayState *play, std::vector* mEntryDl) { - if (vtx == nullptr) { - return; - } - size_t numChar = mText.length(); - if (numChar == 0) { - return; - } - - Matrix_Translate(mX, mY, 0.0f, MTXMODE_APPLY); -// Matrix_Scale(0.75f, 0.75f, 0.75f, MTXMODE_APPLY); - - mEntryDl->push_back(gsSPMatrix(Matrix_NewMtx(play->state.gfxCtx, (char*)__FILE__, __LINE__), G_MTX_PUSH | G_MTX_LOAD | G_MTX_MODELVIEW)); - - // icon - if (!mAchieved) { - mEntryDl->push_back(gsDPSetGrayscaleColor(109, 109, 109, 255)); - mEntryDl->push_back(gsSPGrayscale(true)); - } - mEntryDl->push_back(gsDPSetPrimColor(0, 0, mIconColor.r, mIconColor.g, mIconColor.b, mIconColor.a)); - mEntryDl->push_back(gsSPVertex(vtx, 4, 0)); - LoadIconTex(mEntryDl); - mEntryDl->push_back(gsSP1Quadrangle(0, 2, 3, 1, 0)); - mEntryDl->push_back(gsSPGrayscale(false)); - - // text - for (size_t i = 0, vtxGroup = 0; i < numChar; i++) { - mEntryDl->push_back(gsDPSetPrimColor(0, 0, mButtonColors[i].r, mButtonColors[i].g, mButtonColors[i].b, mButtonColors[i].a)); - - // A maximum of 64 Vtx can be loaded at once by gSPVertex, or basically 16 characters - // handle loading groups of 16 chars at a time until there are no more left to load. - // By this point 4 vertices have already been loaded for the preceding icon. - if (i % 16 == 0) { - size_t numVtxToLoad = std::min(numChar - i, 16) * 4; - mEntryDl->push_back(gsSPVertex(&vtx[4 + (vtxGroup * 16 * 4)], numVtxToLoad, 0)); - vtxGroup++; - } - - auto texture = reinterpret_cast(Ship_GetCharFontTexture(mText[i])); - auto vertexStart = static_cast(4 * (i % 16)); - - Gfx charTexture[] = { gsDPLoadTextureBlock_4b( - texture, G_IM_FMT_I, FONT_CHAR_TEX_WIDTH, FONT_CHAR_TEX_HEIGHT, 0, G_TX_NOMIRROR | G_TX_CLAMP, - G_TX_NOMIRROR | G_TX_CLAMP, G_TX_NOMASK, G_TX_NOMASK, G_TX_NOLOD, G_TX_NOLOD) }; - mEntryDl->insert(mEntryDl->end(), std::begin(charTexture), std::end(charTexture)); - mEntryDl->push_back(gsSP1Quadrangle(vertexStart, vertexStart + 2, vertexStart + 3, vertexStart + 1, 0)); - } - mEntryDl->push_back(gsSPPopMatrix(G_MTX_MODELVIEW)); +void KaleidoEntryOcarinaButtons::Draw(PlayState* play, std::vector* mEntryDl) { + if (vtx == nullptr) { + return; } -} // Rando + size_t numChar = mText.length(); + if (numChar == 0) { + return; + } + + Matrix_Translate(mX, mY, 0.0f, MTXMODE_APPLY); + // Matrix_Scale(0.75f, 0.75f, 0.75f, MTXMODE_APPLY); + + mEntryDl->push_back(gsSPMatrix(Matrix_NewMtx(play->state.gfxCtx, (char*)__FILE__, __LINE__), + G_MTX_PUSH | G_MTX_LOAD | G_MTX_MODELVIEW)); + + // icon + if (!mAchieved) { + mEntryDl->push_back(gsDPSetGrayscaleColor(109, 109, 109, 255)); + mEntryDl->push_back(gsSPGrayscale(true)); + } + mEntryDl->push_back(gsDPSetPrimColor(0, 0, mIconColor.r, mIconColor.g, mIconColor.b, mIconColor.a)); + mEntryDl->push_back(gsSPVertex(vtx, 4, 0)); + LoadIconTex(mEntryDl); + mEntryDl->push_back(gsSP1Quadrangle(0, 2, 3, 1, 0)); + mEntryDl->push_back(gsSPGrayscale(false)); + + // text + for (size_t i = 0, vtxGroup = 0; i < numChar; i++) { + mEntryDl->push_back( + gsDPSetPrimColor(0, 0, mButtonColors[i].r, mButtonColors[i].g, mButtonColors[i].b, mButtonColors[i].a)); + + // A maximum of 64 Vtx can be loaded at once by gSPVertex, or basically 16 characters + // handle loading groups of 16 chars at a time until there are no more left to load. + // By this point 4 vertices have already been loaded for the preceding icon. + if (i % 16 == 0) { + size_t numVtxToLoad = std::min(numChar - i, 16) * 4; + mEntryDl->push_back(gsSPVertex(&vtx[4 + (vtxGroup * 16 * 4)], numVtxToLoad, 0)); + vtxGroup++; + } + + auto texture = reinterpret_cast(Ship_GetCharFontTexture(mText[i])); + auto vertexStart = static_cast(4 * (i % 16)); + + Gfx charTexture[] = { gsDPLoadTextureBlock_4b(texture, G_IM_FMT_I, FONT_CHAR_TEX_WIDTH, FONT_CHAR_TEX_HEIGHT, 0, + G_TX_NOMIRROR | G_TX_CLAMP, G_TX_NOMIRROR | G_TX_CLAMP, + G_TX_NOMASK, G_TX_NOMASK, G_TX_NOLOD, G_TX_NOLOD) }; + mEntryDl->insert(mEntryDl->end(), std::begin(charTexture), std::end(charTexture)); + mEntryDl->push_back(gsSP1Quadrangle(vertexStart, vertexStart + 2, vertexStart + 3, vertexStart + 1, 0)); + } + mEntryDl->push_back(gsSPPopMatrix(G_MTX_MODELVIEW)); +} +} // namespace Rando void RandoKaleido_RegisterHooks() { - GameInteractor::Instance->RegisterGameHook(RandoKaleido_UpdateMiscCollectibles); + GameInteractor::Instance->RegisterGameHook( + RandoKaleido_UpdateMiscCollectibles); } diff --git a/soh/soh/Enhancements/kaleido.h b/soh/soh/Enhancements/kaleido.h index db86a817e..7776afb66 100644 --- a/soh/soh/Enhancements/kaleido.h +++ b/soh/soh/Enhancements/kaleido.h @@ -2,7 +2,6 @@ #define KALEIDO_H #include - #ifdef __cplusplus #include #include @@ -18,7 +17,7 @@ namespace Rando { * subclasses to declare their Draw and Update functions. */ class KaleidoEntry { -public: + public: /** * @brief Constructor for Base KaleidoEntry class. Sets the position and * initial value of the line of text. @@ -31,7 +30,8 @@ public: virtual void Draw(PlayState* play, std::vector* mEntryDl) = 0; virtual void Update(PlayState* play) = 0; void SetYOffset(int yOffset); -protected: + + protected: int16_t mX; int16_t mY; int16_t mHeight; @@ -39,7 +39,6 @@ protected: Vtx* vtx; std::string mText; bool mAchieved = false; - }; /** @@ -47,7 +46,7 @@ protected: * that wish to render an Icon at the start of their line. */ class KaleidoEntryIcon : public KaleidoEntry { -public: + public: /** * @param iconResourceName resource name of the icon to draw * @param iconFormat flag representing the format of the icon (i.e. G_IM_FMT_IA) @@ -63,7 +62,8 @@ public: Color_RGBA8 iconColor, int16_t x, int16_t y, std::string text = ""); void Draw(PlayState* play, std::vector* mEntryDl) override; void RebuildVertices(); -protected: + + protected: const char* mIconResourceName; int mIconFormat; int mIconSize; @@ -80,7 +80,7 @@ protected: * that is either colored in or Grayscale according to a flag */ class KaleidoEntryIconFlag : public KaleidoEntryIcon { -public : + public: /** * @param iconResourceName resource name of the icon to draw * @param iconFormat flag representing the format of the icon (i.e. G_IM_FMT_IA) @@ -98,7 +98,8 @@ public : Color_RGBA8 iconColor, FlagType flagType, int flag, int16_t x, int16_t y, std::string name = ""); void Update(PlayState* play) override; -private: + + private: FlagType mFlagType; int mFlag; }; @@ -109,7 +110,7 @@ private: * render the count and not show progress towards a required amount or a total. */ class KaleidoEntryIconCountRequired : public KaleidoEntryIcon { -public: + public: /** * @param iconResourceName resource name of the icon to draw * @param iconFormat flag representing the format of the icon (i.e. G_IM_FMT_IA) @@ -126,10 +127,12 @@ public: * @param required The amount of this collectible required to beat the seed. Set to 0 to not render. * @param total The amount of this collectible available in the seed. Set to 0 to not render. */ - KaleidoEntryIconCountRequired(const char* iconResourceName, int iconFormat, int iconSize, int iconWidth, int iconHeight, - Color_RGBA8 iconColor, int16_t x, int16_t y, int* watch, int required = 0, int total = 0); + KaleidoEntryIconCountRequired(const char* iconResourceName, int iconFormat, int iconSize, int iconWidth, + int iconHeight, Color_RGBA8 iconColor, int16_t x, int16_t y, int* watch, + int required = 0, int total = 0); void Update(PlayState* play) override; -private: + + private: int* mWatch; int mRequired; int mTotal; @@ -139,11 +142,12 @@ private: }; class KaleidoEntryOcarinaButtons : public KaleidoEntryIcon { -public: + public: KaleidoEntryOcarinaButtons(int16_t x, int16_t y); void Update(PlayState* play) override; void Draw(PlayState* play, std::vector* mEntryDl) override; -private: + + private: void CalculateColors(); std::array mButtonColors = {}; @@ -151,17 +155,18 @@ private: }; class Kaleido { -public: + public: Kaleido(); void Draw(PlayState* play); void Update(PlayState* play); -private: + + private: std::vector> mEntries; std::vector mEntryDl; int mTopIndex = 0; int mNumVisible = 7; }; -} // Rando +} // namespace Rando extern "C" { #endif @@ -172,5 +177,4 @@ void RandoKaleido_UpdateMiscCollectibles(int16_t inDungeonScene); #endif void RandoKaleido_RegisterHooks(); - -#endif //KALEIDO_H +#endif // KALEIDO_H diff --git a/soh/soh/Enhancements/mods.cpp b/soh/soh/Enhancements/mods.cpp index b208d2598..2c357fd34 100644 --- a/soh/soh/Enhancements/mods.cpp +++ b/soh/soh/Enhancements/mods.cpp @@ -66,7 +66,8 @@ static const ALIGN_ASSET(2) char tokinoma_room_0DL_007FD0[] = dtokinoma_room_0DL /// Switches Link's age and respawns him at the last entrance he entered. void SwitchAge() { - if (gPlayState == NULL) return; + if (gPlayState == NULL) + return; Player* player = GET_PLAYER(gPlayState); @@ -114,14 +115,16 @@ void RegisterOcarinaTimeTravel() { } Actor* player = &GET_PLAYER(gPlayState)->actor; - Actor* nearbyTimeBlockEmpty = Actor_FindNearby(gPlayState, player, ACTOR_OBJ_WARP2BLOCK, ACTORCAT_ITEMACTION, 300.0f); + Actor* nearbyTimeBlockEmpty = + Actor_FindNearby(gPlayState, player, ACTOR_OBJ_WARP2BLOCK, ACTORCAT_ITEMACTION, 300.0f); Actor* nearbyTimeBlock = Actor_FindNearby(gPlayState, player, ACTOR_OBJ_TIMEBLOCK, ACTORCAT_ITEMACTION, 300.0f); Actor* nearbyOcarinaSpot = Actor_FindNearby(gPlayState, player, ACTOR_EN_OKARINA_TAG, ACTORCAT_PROP, 120.0f); Actor* nearbyDoorOfTime = Actor_FindNearby(gPlayState, player, ACTOR_DOOR_TOKI, ACTORCAT_BG, 500.0f); Actor* nearbyFrogs = Actor_FindNearby(gPlayState, player, ACTOR_EN_FR, ACTORCAT_NPC, 300.0f); Actor* nearbyGossipStone = Actor_FindNearby(gPlayState, player, ACTOR_EN_GS, ACTORCAT_NPC, 300.0f); bool justPlayedSoT = gPlayState->msgCtx.lastPlayedSong == OCARINA_SONG_TIME; - bool notNearAnySource = !nearbyTimeBlockEmpty && !nearbyTimeBlock && !nearbyOcarinaSpot && !nearbyDoorOfTime && !nearbyFrogs && !nearbyGossipStone; + bool notNearAnySource = !nearbyTimeBlockEmpty && !nearbyTimeBlock && !nearbyOcarinaSpot && !nearbyDoorOfTime && + !nearbyFrogs && !nearbyGossipStone; bool hasOcarinaOfTime = (INV_CONTENT(ITEM_OCARINA_TIME) == ITEM_OCARINA_TIME); bool doesntNeedOcarinaOfTime = CVarGetInteger(CVAR_ENHANCEMENT("TimeTravel"), 0) == 2; bool hasMasterSword = CHECK_OWNED_EQUIP(EQUIP_TYPE_SWORD, EQUIP_INV_SWORD_MASTER); @@ -137,11 +140,11 @@ void RegisterRupeeDash() { if (!CVarGetInteger(CVAR_ENHANCEMENT("RupeeDash"), 0)) { return; } - + // Initialize Timer static uint16_t rupeeDashTimer = 0; uint16_t rdmTime = CVarGetInteger(CVAR_ENHANCEMENT("RupeeDashInterval"), 5) * 20; - + // Did time change by DashInterval? if (rupeeDashTimer >= rdmTime) { rupeeDashTimer = 0; @@ -165,10 +168,10 @@ void RegisterShadowTag() { if (!CVarGetInteger(CVAR_ENHANCEMENT("ShadowTag"), 0)) { return; } - if (gPlayState->sceneNum == SCENE_FOREST_TEMPLE && // Forest Temple Scene - gPlayState->roomCtx.curRoom.num == 16 || // Green Poe Room - gPlayState->roomCtx.curRoom.num == 13 || // Blue Poe Room - gPlayState->roomCtx.curRoom.num == 12) { // Red Poe Room + if (gPlayState->sceneNum == SCENE_FOREST_TEMPLE && // Forest Temple Scene + gPlayState->roomCtx.curRoom.num == 16 || // Green Poe Room + gPlayState->roomCtx.curRoom.num == 13 || // Blue Poe Room + gPlayState->roomCtx.curRoom.num == 12) { // Red Poe Room return; } else { if (shouldSpawn && (delayTimer <= 0)) { @@ -191,13 +194,14 @@ void RegisterShadowTag() { static bool hasAffectedHealth = false; void UpdatePermanentHeartLossState() { - if (!GameInteractor::IsSaveLoaded()) return; + if (!GameInteractor::IsSaveLoaded()) + return; if (!CVarGetInteger(CVAR_ENHANCEMENT("PermanentHeartLoss"), 0) && hasAffectedHealth) { uint8_t heartContainers = gSaveContext.ship.stats.heartContainers; // each worth 16 health uint8_t heartPieces = gSaveContext.ship.stats.heartPieces; // each worth 4 health, but only in groups of 4 - uint8_t startingHealth = 16 * (IS_RANDO ? (OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_STARTING_HEARTS) + 1) : 3); - + uint8_t startingHealth = + 16 * (IS_RANDO ? (OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_STARTING_HEARTS) + 1) : 3); uint8_t newCapacity = startingHealth + (heartContainers * 16) + ((heartPieces - (heartPieces % 4)) * 4); gSaveContext.healthCapacity = MAX(newCapacity, gSaveContext.healthCapacity); @@ -213,7 +217,8 @@ void RegisterPermanentHeartLoss() { }); GameInteractor::Instance->RegisterGameHook([]() { - if (!CVarGetInteger(CVAR_ENHANCEMENT("PermanentHeartLoss"), 0) || !GameInteractor::IsSaveLoaded()) return; + if (!CVarGetInteger(CVAR_ENHANCEMENT("PermanentHeartLoss"), 0) || !GameInteractor::IsSaveLoaded()) + return; if (gSaveContext.healthCapacity > 16 && gSaveContext.healthCapacity - gSaveContext.health >= 16) { gSaveContext.healthCapacity -= 16; @@ -225,12 +230,16 @@ void RegisterPermanentHeartLoss() { void RegisterDeleteFileOnDeath() { GameInteractor::Instance->RegisterGameHook([]() { - if (!CVarGetInteger(CVAR_ENHANCEMENT("DeleteFileOnDeath"), 0) || !GameInteractor::IsSaveLoaded() || gPlayState == NULL) return; + if (!CVarGetInteger(CVAR_ENHANCEMENT("DeleteFileOnDeath"), 0) || !GameInteractor::IsSaveLoaded() || + gPlayState == NULL) + return; if (gPlayState->gameOverCtx.state == GAMEOVER_DEATH_MENU && gPlayState->pauseCtx.state == 9) { SaveManager::Instance->DeleteZeldaFile(gSaveContext.fileNum); hasAffectedHealth = false; - std::reinterpret_pointer_cast(Ship::Context::GetInstance()->GetWindow()->GetGui()->GetGuiWindow("Console"))->Dispatch("reset"); + std::reinterpret_pointer_cast( + Ship::Context::GetInstance()->GetWindow()->GetGui()->GetGuiWindow("Console")) + ->Dispatch("reset"); } }); } @@ -258,7 +267,10 @@ void RegisterDaytimeGoldSkultullas() { // ZF { SCENE_ZORAS_FOUNTAIN, 0, true, { { ACTOR_EN_SW, { -1891, 187, 1911 }, { 16384, 18022, 0 }, -19964 } } }, // GF - { SCENE_GERUDOS_FORTRESS, 0, false, { { ACTOR_EN_SW, { 1598, 999, -2008 }, { 16384, -16384, 0 }, -19198 } } }, + { SCENE_GERUDOS_FORTRESS, + 0, + false, + { { ACTOR_EN_SW, { 1598, 999, -2008 }, { 16384, -16384, 0 }, -19198 } } }, { SCENE_GERUDOS_FORTRESS, 1, false, { { ACTOR_EN_SW, { 3377, 1734, -4935 }, { 16384, 0, 0 }, -19199 } } }, // Kak { SCENE_KAKARIKO_VILLAGE, 0, false, { { ACTOR_EN_SW, { -18, 540, 1800 }, { 0, -32768, 0 }, -20160 } } }, @@ -293,7 +305,8 @@ void RegisterDaytimeGoldSkultullas() { bool IsHyperBossesActive() { return CVarGetInteger(CVAR_ENHANCEMENT("HyperBosses"), 0) || - (IS_BOSS_RUSH && gSaveContext.ship.quest.data.bossRush.options[BR_OPTIONS_HYPERBOSSES] == BR_CHOICE_HYPERBOSSES_YES); + (IS_BOSS_RUSH && + gSaveContext.ship.quest.data.bossRush.options[BR_OPTIONS_HYPERBOSSES] == BR_CHOICE_HYPERBOSSES_YES); } void UpdateHyperBossesState() { @@ -304,53 +317,53 @@ void UpdateHyperBossesState() { } if (IsHyperBossesActive()) { - actorUpdateHookId = GameInteractor::Instance->RegisterGameHook([](void* refActor) { - // Run the update function a second time to make bosses move and act twice as fast. + actorUpdateHookId = + GameInteractor::Instance->RegisterGameHook([](void* refActor) { + // Run the update function a second time to make bosses move and act twice as fast. - Player* player = GET_PLAYER(gPlayState); - Actor* actor = static_cast(refActor); + Player* player = GET_PLAYER(gPlayState); + Actor* actor = static_cast(refActor); - uint8_t isBossActor = - actor->id == ACTOR_BOSS_GOMA || // Gohma - actor->id == ACTOR_BOSS_DODONGO || // King Dodongo - actor->id == ACTOR_EN_BDFIRE || // King Dodongo Fire Breath - actor->id == ACTOR_BOSS_VA || // Barinade - actor->id == ACTOR_BOSS_GANONDROF || // Phantom Ganon - actor->id == ACTOR_EN_FHG_FIRE || // Phantom Ganon/Ganondorf Energy Ball/Thunder - actor->id == ACTOR_EN_FHG || // Phantom Ganon's Horse - actor->id == ACTOR_BOSS_FD || actor->id == ACTOR_BOSS_FD2 || // Volvagia (grounded/flying) - actor->id == ACTOR_EN_VB_BALL || // Volvagia Rocks - actor->id == ACTOR_BOSS_MO || // Morpha - actor->id == ACTOR_BOSS_SST || // Bongo Bongo - actor->id == ACTOR_BOSS_TW || // Twinrova - actor->id == ACTOR_BOSS_GANON || // Ganondorf - actor->id == ACTOR_BOSS_GANON2; // Ganon + uint8_t isBossActor = actor->id == ACTOR_BOSS_GOMA || // Gohma + actor->id == ACTOR_BOSS_DODONGO || // King Dodongo + actor->id == ACTOR_EN_BDFIRE || // King Dodongo Fire Breath + actor->id == ACTOR_BOSS_VA || // Barinade + actor->id == ACTOR_BOSS_GANONDROF || // Phantom Ganon + actor->id == ACTOR_EN_FHG_FIRE || // Phantom Ganon/Ganondorf Energy Ball/Thunder + actor->id == ACTOR_EN_FHG || // Phantom Ganon's Horse + actor->id == ACTOR_BOSS_FD || + actor->id == ACTOR_BOSS_FD2 || // Volvagia (grounded/flying) + actor->id == ACTOR_EN_VB_BALL || // Volvagia Rocks + actor->id == ACTOR_BOSS_MO || // Morpha + actor->id == ACTOR_BOSS_SST || // Bongo Bongo + actor->id == ACTOR_BOSS_TW || // Twinrova + actor->id == ACTOR_BOSS_GANON || // Ganondorf + actor->id == ACTOR_BOSS_GANON2; // Ganon - // Don't apply during cutscenes because it causes weird behaviour and/or crashes on some bosses. - if (IsHyperBossesActive() && isBossActor && !Player_InBlockingCsMode(gPlayState, player)) { - // Barinade needs to be updated in sequence to avoid unintended behaviour. - if (actor->id == ACTOR_BOSS_VA) { - // params -1 is BOSSVA_BODY - if (actor->params == -1) { - Actor* actorList = gPlayState->actorCtx.actorLists[ACTORCAT_BOSS].head; - while (actorList != NULL) { - GameInteractor::RawAction::UpdateActor(actorList); - actorList = actorList->next; + // Don't apply during cutscenes because it causes weird behaviour and/or crashes on some bosses. + if (IsHyperBossesActive() && isBossActor && !Player_InBlockingCsMode(gPlayState, player)) { + // Barinade needs to be updated in sequence to avoid unintended behaviour. + if (actor->id == ACTOR_BOSS_VA) { + // params -1 is BOSSVA_BODY + if (actor->params == -1) { + Actor* actorList = gPlayState->actorCtx.actorLists[ACTORCAT_BOSS].head; + while (actorList != NULL) { + GameInteractor::RawAction::UpdateActor(actorList); + actorList = actorList->next; + } } + } else { + GameInteractor::RawAction::UpdateActor(actor); } - } else { - GameInteractor::RawAction::UpdateActor(actor); } - } - }); + }); } } void RegisterHyperBosses() { UpdateHyperBossesState(); - GameInteractor::Instance->RegisterGameHook([](int16_t fileNum) { - UpdateHyperBossesState(); - }); + GameInteractor::Instance->RegisterGameHook( + [](int16_t fileNum) { UpdateHyperBossesState(); }); } void UpdateHyperEnemiesState() { @@ -361,22 +374,23 @@ void UpdateHyperEnemiesState() { } if (CVarGetInteger(CVAR_ENHANCEMENT("HyperEnemies"), 0)) { - actorUpdateHookId = GameInteractor::Instance->RegisterGameHook([](void* refActor) { - // Run the update function a second time to make enemies and minibosses move and act twice as fast. + actorUpdateHookId = + GameInteractor::Instance->RegisterGameHook([](void* refActor) { + // Run the update function a second time to make enemies and minibosses move and act twice as fast. - Player* player = GET_PLAYER(gPlayState); - Actor* actor = static_cast(refActor); + Player* player = GET_PLAYER(gPlayState); + Actor* actor = static_cast(refActor); - // Some enemies are not in the ACTORCAT_ENEMY category, and some are that aren't really enemies. - bool isEnemy = actor->category == ACTORCAT_ENEMY || actor->id == ACTOR_EN_TORCH2; - bool isExcludedEnemy = actor->id == ACTOR_EN_FIRE_ROCK || actor->id == ACTOR_EN_ENCOUNT2; + // Some enemies are not in the ACTORCAT_ENEMY category, and some are that aren't really enemies. + bool isEnemy = actor->category == ACTORCAT_ENEMY || actor->id == ACTOR_EN_TORCH2; + bool isExcludedEnemy = actor->id == ACTOR_EN_FIRE_ROCK || actor->id == ACTOR_EN_ENCOUNT2; - // Don't apply during cutscenes because it causes weird behaviour and/or crashes on some cutscenes. - if (CVarGetInteger(CVAR_ENHANCEMENT("HyperEnemies"), 0) && isEnemy && !isExcludedEnemy && - !Player_InBlockingCsMode(gPlayState, player)) { - GameInteractor::RawAction::UpdateActor(actor); - } - }); + // Don't apply during cutscenes because it causes weird behaviour and/or crashes on some cutscenes. + if (CVarGetInteger(CVAR_ENHANCEMENT("HyperEnemies"), 0) && isEnemy && !isExcludedEnemy && + !Player_InBlockingCsMode(gPlayState, player)) { + GameInteractor::RawAction::UpdateActor(actor); + } + }); } } @@ -415,7 +429,7 @@ void RegisterBonkDamage() { default: break; } - + Health_ChangeBy(gPlayState, -bonkDamage); // Set invincibility to make Link flash red as a visual damage indicator. Player* player = GET_PLAYER(gPlayState); @@ -428,7 +442,8 @@ void UpdateDirtPathFixState(int32_t sceneNum) { case SCENE_HYRULE_FIELD: case SCENE_KOKIRI_FOREST: case SCENE_HYRULE_CASTLE: - CVarSetInteger(CVAR_Z_FIGHTING_MODE, CVarGetInteger(CVAR_ENHANCEMENT("SceneSpecificDirtPathFix"), ZFIGHT_FIX_DISABLED)); + CVarSetInteger(CVAR_Z_FIGHTING_MODE, + CVarGetInteger(CVAR_ENHANCEMENT("SceneSpecificDirtPathFix"), ZFIGHT_FIX_DISABLED)); return; default: CVarClear(CVAR_Z_FIGHTING_MODE); @@ -436,9 +451,8 @@ void UpdateDirtPathFixState(int32_t sceneNum) { } void RegisterMenuPathFix() { - GameInteractor::Instance->RegisterGameHook([](int32_t sceneNum) { - UpdateDirtPathFixState(sceneNum); - }); + GameInteractor::Instance->RegisterGameHook( + [](int32_t sceneNum) { UpdateDirtPathFixState(sceneNum); }); } void UpdateMirrorModeState(int32_t sceneNum) { @@ -446,27 +460,28 @@ void UpdateMirrorModeState(int32_t sceneNum) { bool nextMirroredWorld = false; int16_t mirroredMode = CVarGetInteger(CVAR_ENHANCEMENT("MirroredWorldMode"), MIRRORED_WORLD_OFF); - int16_t inDungeon = (sceneNum >= SCENE_DEKU_TREE && sceneNum <= SCENE_INSIDE_GANONS_CASTLE_COLLAPSE && sceneNum != SCENE_THIEVES_HIDEOUT) || + int16_t inDungeon = (sceneNum >= SCENE_DEKU_TREE && sceneNum <= SCENE_INSIDE_GANONS_CASTLE_COLLAPSE && + sceneNum != SCENE_THIEVES_HIDEOUT) || (sceneNum >= SCENE_DEKU_TREE_BOSS && sceneNum <= SCENE_GANONS_TOWER_COLLAPSE_EXTERIOR) || (sceneNum == SCENE_GANON_BOSS); if (mirroredMode == MIRRORED_WORLD_RANDOM_SEEDED || mirroredMode == MIRRORED_WORLD_DUNGEONS_RANDOM_SEEDED) { - uint32_t seed = sceneNum + (IS_RANDO ? Rando::Context::GetInstance()->GetSeed() - : gSaveContext.ship.stats.fileCreatedAt); + uint32_t seed = + sceneNum + (IS_RANDO ? Rando::Context::GetInstance()->GetSeed() : gSaveContext.ship.stats.fileCreatedAt); Random_Init(seed); } bool randomMirror = Random(0, 2) == 1; - if ( - mirroredMode == MIRRORED_WORLD_ALWAYS || + if (mirroredMode == MIRRORED_WORLD_ALWAYS || ((mirroredMode == MIRRORED_WORLD_RANDOM || mirroredMode == MIRRORED_WORLD_RANDOM_SEEDED) && randomMirror) || // Dungeon modes - (inDungeon && (mirroredMode == MIRRORED_WORLD_DUNGEONS_ALL || - (mirroredMode == MIRRORED_WORLD_DUNGEONS_VANILLA && !ResourceMgr_IsSceneMasterQuest(sceneNum)) || - (mirroredMode == MIRRORED_WORLD_DUNGEONS_MQ && ResourceMgr_IsSceneMasterQuest(sceneNum)) || - ((mirroredMode == MIRRORED_WORLD_DUNGEONS_RANDOM || mirroredMode == MIRRORED_WORLD_DUNGEONS_RANDOM_SEEDED) && randomMirror))) - ) { + (inDungeon && + (mirroredMode == MIRRORED_WORLD_DUNGEONS_ALL || + (mirroredMode == MIRRORED_WORLD_DUNGEONS_VANILLA && !ResourceMgr_IsSceneMasterQuest(sceneNum)) || + (mirroredMode == MIRRORED_WORLD_DUNGEONS_MQ && ResourceMgr_IsSceneMasterQuest(sceneNum)) || + ((mirroredMode == MIRRORED_WORLD_DUNGEONS_RANDOM || mirroredMode == MIRRORED_WORLD_DUNGEONS_RANDOM_SEEDED) && + randomMirror)))) { nextMirroredWorld = true; CVarSetInteger(CVAR_ENHANCEMENT("MirroredWorld"), 1); } else { @@ -481,25 +496,33 @@ void UpdateMirrorModeState(int32_t sceneNum) { } void RegisterMirrorModeHandler() { - GameInteractor::Instance->RegisterGameHook([](int32_t sceneNum) { - UpdateMirrorModeState(sceneNum); - }); + GameInteractor::Instance->RegisterGameHook( + [](int32_t sceneNum) { UpdateMirrorModeState(sceneNum); }); } void UpdatePatchHand() { if ((CVarGetInteger(CVAR_ENHANCEMENT("EquipmentAlwaysVisible"), 0)) && LINK_IS_CHILD) { - ResourceMgr_PatchGfxByName(gLinkAdultLeftHandHoldingHammerNearDL, "childHammer1", 92, gsSPDisplayListOTRFilePath(gLinkChildLeftFistNearDL)); + ResourceMgr_PatchGfxByName(gLinkAdultLeftHandHoldingHammerNearDL, "childHammer1", 92, + gsSPDisplayListOTRFilePath(gLinkChildLeftFistNearDL)); ResourceMgr_PatchGfxByName(gLinkAdultLeftHandHoldingHammerNearDL, "childHammer2", 93, gsSPEndDisplayList()); - ResourceMgr_PatchGfxByName(gLinkAdultRightHandHoldingHookshotNearDL, "childHookshot1", 84, gsSPDisplayListOTRFilePath(gLinkChildRightHandClosedNearDL)); - ResourceMgr_PatchGfxByName(gLinkAdultRightHandHoldingHookshotNearDL, "childHookshot2", 85, gsSPEndDisplayList()); - ResourceMgr_PatchGfxByName(gLinkAdultRightHandHoldingBowNearDL, "childBow1", 51, gsSPDisplayListOTRFilePath(gLinkChildRightHandClosedNearDL)); + ResourceMgr_PatchGfxByName(gLinkAdultRightHandHoldingHookshotNearDL, "childHookshot1", 84, + gsSPDisplayListOTRFilePath(gLinkChildRightHandClosedNearDL)); + ResourceMgr_PatchGfxByName(gLinkAdultRightHandHoldingHookshotNearDL, "childHookshot2", 85, + gsSPEndDisplayList()); + ResourceMgr_PatchGfxByName(gLinkAdultRightHandHoldingBowNearDL, "childBow1", 51, + gsSPDisplayListOTRFilePath(gLinkChildRightHandClosedNearDL)); ResourceMgr_PatchGfxByName(gLinkAdultRightHandHoldingBowNearDL, "childBow2", 52, gsSPEndDisplayList()); - ResourceMgr_PatchGfxByName(gLinkAdultLeftHandHoldingMasterSwordNearDL, "childMasterSword1", 104, gsSPDisplayListOTRFilePath(gLinkChildLeftFistNearDL)); - ResourceMgr_PatchGfxByName(gLinkAdultLeftHandHoldingMasterSwordNearDL, "childMasterSword2", 105, gsSPEndDisplayList()); - ResourceMgr_PatchGfxByName(gLinkAdultLeftHandHoldingBgsNearDL, "childBiggoronSword1", 79, gsSPDisplayListOTRFilePath(gLinkChildLeftFistNearDL)); + ResourceMgr_PatchGfxByName(gLinkAdultLeftHandHoldingMasterSwordNearDL, "childMasterSword1", 104, + gsSPDisplayListOTRFilePath(gLinkChildLeftFistNearDL)); + ResourceMgr_PatchGfxByName(gLinkAdultLeftHandHoldingMasterSwordNearDL, "childMasterSword2", 105, + gsSPEndDisplayList()); + ResourceMgr_PatchGfxByName(gLinkAdultLeftHandHoldingBgsNearDL, "childBiggoronSword1", 79, + gsSPDisplayListOTRFilePath(gLinkChildLeftFistNearDL)); ResourceMgr_PatchGfxByName(gLinkAdultLeftHandHoldingBgsNearDL, "childBiggoronSword2", 80, gsSPEndDisplayList()); - ResourceMgr_PatchGfxByName(gLinkAdultHandHoldingBrokenGiantsKnifeDL, "childBrokenGiantsKnife1", 76, gsSPDisplayListOTRFilePath(gLinkChildLeftFistNearDL)); - ResourceMgr_PatchGfxByName(gLinkAdultHandHoldingBrokenGiantsKnifeDL, "childBrokenGiantsKnife2", 77, gsSPEndDisplayList()); + ResourceMgr_PatchGfxByName(gLinkAdultHandHoldingBrokenGiantsKnifeDL, "childBrokenGiantsKnife1", 76, + gsSPDisplayListOTRFilePath(gLinkChildLeftFistNearDL)); + ResourceMgr_PatchGfxByName(gLinkAdultHandHoldingBrokenGiantsKnifeDL, "childBrokenGiantsKnife2", 77, + gsSPEndDisplayList()); } else { ResourceMgr_UnpatchGfxByName(gLinkAdultLeftHandHoldingHammerNearDL, "childHammer1"); @@ -514,12 +537,16 @@ void UpdatePatchHand() { ResourceMgr_UnpatchGfxByName(gLinkAdultLeftHandHoldingBgsNearDL, "childBiggoronSword2"); ResourceMgr_UnpatchGfxByName(gLinkAdultHandHoldingBrokenGiantsKnifeDL, "childBrokenGiantsKnife1"); ResourceMgr_UnpatchGfxByName(gLinkAdultHandHoldingBrokenGiantsKnifeDL, "childBrokenGiantsKnife2"); - } + } if ((CVarGetInteger(CVAR_ENHANCEMENT("EquipmentAlwaysVisible"), 0)) && LINK_IS_ADULT) { - ResourceMgr_PatchGfxByName(gLinkChildLeftFistAndKokiriSwordNearDL, "adultKokiriSword", 13, gsSPDisplayListOTRFilePath(gLinkAdultLeftHandClosedNearDL)); - ResourceMgr_PatchGfxByName(gLinkChildRightHandHoldingSlingshotNearDL, "adultSlingshot", 13, gsSPDisplayListOTRFilePath(gLinkAdultRightHandClosedNearDL)); - ResourceMgr_PatchGfxByName(gLinkChildLeftFistAndBoomerangNearDL, "adultBoomerang", 50, gsSPDisplayListOTRFilePath(gLinkAdultLeftHandClosedNearDL)); - ResourceMgr_PatchGfxByName(gLinkChildRightFistAndDekuShieldNearDL, "adultDekuShield", 49, gsSPDisplayListOTRFilePath(gLinkAdultRightHandClosedNearDL)); + ResourceMgr_PatchGfxByName(gLinkChildLeftFistAndKokiriSwordNearDL, "adultKokiriSword", 13, + gsSPDisplayListOTRFilePath(gLinkAdultLeftHandClosedNearDL)); + ResourceMgr_PatchGfxByName(gLinkChildRightHandHoldingSlingshotNearDL, "adultSlingshot", 13, + gsSPDisplayListOTRFilePath(gLinkAdultRightHandClosedNearDL)); + ResourceMgr_PatchGfxByName(gLinkChildLeftFistAndBoomerangNearDL, "adultBoomerang", 50, + gsSPDisplayListOTRFilePath(gLinkAdultLeftHandClosedNearDL)); + ResourceMgr_PatchGfxByName(gLinkChildRightFistAndDekuShieldNearDL, "adultDekuShield", 49, + gsSPDisplayListOTRFilePath(gLinkAdultRightHandClosedNearDL)); } else { ResourceMgr_UnpatchGfxByName(gLinkChildLeftFistAndKokiriSwordNearDL, "adultKokiriSword"); ResourceMgr_UnpatchGfxByName(gLinkChildRightHandHoldingSlingshotNearDL, "adultSlingshot"); @@ -527,7 +554,8 @@ void UpdatePatchHand() { ResourceMgr_UnpatchGfxByName(gLinkChildRightFistAndDekuShieldNearDL, "adultDekuShield"); } if (CVarGetInteger("gEnhancements.FixHammerHand", 0) && LINK_IS_ADULT) { - ResourceMgr_PatchGfxByName(gLinkAdultLeftHandHoldingHammerNearDL, "hammerHand1", 92, gsSPDisplayListOTRFilePath(gLinkAdultLeftHandClosedNearDL)); + ResourceMgr_PatchGfxByName(gLinkAdultLeftHandHoldingHammerNearDL, "hammerHand1", 92, + gsSPDisplayListOTRFilePath(gLinkAdultLeftHandClosedNearDL)); ResourceMgr_PatchGfxByName(gLinkAdultLeftHandHoldingHammerNearDL, "hammerHand2", 93, gsSPEndDisplayList()); } else { ResourceMgr_UnpatchGfxByName(gLinkAdultLeftHandHoldingHammerNearDL, "hammerHand1"); @@ -536,62 +564,61 @@ void UpdatePatchHand() { } void RegisterPatchHandHandler() { - GameInteractor::Instance->RegisterGameHook([](int32_t sceneNum) { - UpdatePatchHand(); - }); + GameInteractor::Instance->RegisterGameHook( + [](int32_t sceneNum) { UpdatePatchHand(); }); } void RegisterResetNaviTimer() { GameInteractor::Instance->RegisterGameHook([](int32_t sceneNum) { - if (CVarGetInteger(CVAR_ENHANCEMENT("ResetNaviTimer"), 0)) { - gSaveContext.naviTimer = 0; - } - }); + if (CVarGetInteger(CVAR_ENHANCEMENT("ResetNaviTimer"), 0)) { + gSaveContext.naviTimer = 0; + } + }); } -//this map is used for enemies that can be uniquely identified by their id -//and that are always counted -//enemies that can't be uniquely identified by their id -//or only sometimes count (like ACTOR_EN_TP) -//have to be manually handled in RegisterEnemyDefeatCounts +// this map is used for enemies that can be uniquely identified by their id +// and that are always counted +// enemies that can't be uniquely identified by their id +// or only sometimes count (like ACTOR_EN_TP) +// have to be manually handled in RegisterEnemyDefeatCounts static std::unordered_map uniqueEnemyIdToStatCount = { - { ACTOR_EN_ANUBICE, COUNT_ENEMIES_DEFEATED_ANUBIS }, - { ACTOR_EN_AM, COUNT_ENEMIES_DEFEATED_ARMOS }, - { ACTOR_EN_CLEAR_TAG, COUNT_ENEMIES_DEFEATED_ARWING }, - { ACTOR_EN_VALI, COUNT_ENEMIES_DEFEATED_BARI }, - { ACTOR_EN_VM, COUNT_ENEMIES_DEFEATED_BEAMOS }, - { ACTOR_EN_BIGOKUTA, COUNT_ENEMIES_DEFEATED_BIG_OCTO }, - { ACTOR_EN_BILI, COUNT_ENEMIES_DEFEATED_BIRI }, - { ACTOR_EN_DNS, COUNT_ENEMIES_DEFEATED_BUSINESS_SCRUB }, - { ACTOR_EN_TORCH, COUNT_ENEMIES_DEFEATED_DARK_LINK }, - { ACTOR_EN_DH, COUNT_ENEMIES_DEFEATED_DEAD_HAND }, - { ACTOR_EN_HINTNUTS, COUNT_ENEMIES_DEFEATED_DEKU_SCRUB }, - { ACTOR_EN_DODONGO, COUNT_ENEMIES_DEFEATED_DODONGO }, - { ACTOR_EN_DODOJR, COUNT_ENEMIES_DEFEATED_DODONGO_BABY }, - { ACTOR_DOOR_KILLER, COUNT_ENEMIES_DEFEATED_DOOR_TRAP }, - { ACTOR_EN_FD, COUNT_ENEMIES_DEFEATED_FLARE_DANCER }, - { ACTOR_EN_FLOORMAS, COUNT_ENEMIES_DEFEATED_FLOORMASTER }, - { ACTOR_EN_TUBO_TRAP, COUNT_ENEMIES_DEFEATED_FLYING_POT }, - { ACTOR_EN_YUKABYUN, COUNT_ENEMIES_DEFEATED_FLOOR_TILE }, - { ACTOR_EN_FZ, COUNT_ENEMIES_DEFEATED_FREEZARD }, - { ACTOR_EN_GELDB, COUNT_ENEMIES_DEFEATED_GERUDO_THIEF }, - { ACTOR_EN_GOMA, COUNT_ENEMIES_DEFEATED_GOHMA_LARVA }, - { ACTOR_EN_CROW, COUNT_ENEMIES_DEFEATED_GUAY }, - { ACTOR_EN_RR, COUNT_ENEMIES_DEFEATED_LIKE_LIKE }, - { ACTOR_EN_DEKUNUTS, COUNT_ENEMIES_DEFEATED_MAD_SCRUB }, - { ACTOR_EN_OKUTA, COUNT_ENEMIES_DEFEATED_OCTOROK }, - { ACTOR_EN_BA, COUNT_ENEMIES_DEFEATED_PARASITIC_TENTACLE }, + { ACTOR_EN_ANUBICE, COUNT_ENEMIES_DEFEATED_ANUBIS }, + { ACTOR_EN_AM, COUNT_ENEMIES_DEFEATED_ARMOS }, + { ACTOR_EN_CLEAR_TAG, COUNT_ENEMIES_DEFEATED_ARWING }, + { ACTOR_EN_VALI, COUNT_ENEMIES_DEFEATED_BARI }, + { ACTOR_EN_VM, COUNT_ENEMIES_DEFEATED_BEAMOS }, + { ACTOR_EN_BIGOKUTA, COUNT_ENEMIES_DEFEATED_BIG_OCTO }, + { ACTOR_EN_BILI, COUNT_ENEMIES_DEFEATED_BIRI }, + { ACTOR_EN_DNS, COUNT_ENEMIES_DEFEATED_BUSINESS_SCRUB }, + { ACTOR_EN_TORCH, COUNT_ENEMIES_DEFEATED_DARK_LINK }, + { ACTOR_EN_DH, COUNT_ENEMIES_DEFEATED_DEAD_HAND }, + { ACTOR_EN_HINTNUTS, COUNT_ENEMIES_DEFEATED_DEKU_SCRUB }, + { ACTOR_EN_DODONGO, COUNT_ENEMIES_DEFEATED_DODONGO }, + { ACTOR_EN_DODOJR, COUNT_ENEMIES_DEFEATED_DODONGO_BABY }, + { ACTOR_DOOR_KILLER, COUNT_ENEMIES_DEFEATED_DOOR_TRAP }, + { ACTOR_EN_FD, COUNT_ENEMIES_DEFEATED_FLARE_DANCER }, + { ACTOR_EN_FLOORMAS, COUNT_ENEMIES_DEFEATED_FLOORMASTER }, + { ACTOR_EN_TUBO_TRAP, COUNT_ENEMIES_DEFEATED_FLYING_POT }, + { ACTOR_EN_YUKABYUN, COUNT_ENEMIES_DEFEATED_FLOOR_TILE }, + { ACTOR_EN_FZ, COUNT_ENEMIES_DEFEATED_FREEZARD }, + { ACTOR_EN_GELDB, COUNT_ENEMIES_DEFEATED_GERUDO_THIEF }, + { ACTOR_EN_GOMA, COUNT_ENEMIES_DEFEATED_GOHMA_LARVA }, + { ACTOR_EN_CROW, COUNT_ENEMIES_DEFEATED_GUAY }, + { ACTOR_EN_RR, COUNT_ENEMIES_DEFEATED_LIKE_LIKE }, + { ACTOR_EN_DEKUNUTS, COUNT_ENEMIES_DEFEATED_MAD_SCRUB }, + { ACTOR_EN_OKUTA, COUNT_ENEMIES_DEFEATED_OCTOROK }, + { ACTOR_EN_BA, COUNT_ENEMIES_DEFEATED_PARASITIC_TENTACLE }, { ACTOR_EN_PO_SISTERS, COUNT_ENEMIES_DEFEATED_POE_SISTERS }, - { ACTOR_EN_BUBBLE, COUNT_ENEMIES_DEFEATED_SHABOM }, - { ACTOR_EN_SB, COUNT_ENEMIES_DEFEATED_SHELLBLADE }, - { ACTOR_EN_SKJ, COUNT_ENEMIES_DEFEATED_SKULL_KID }, - { ACTOR_EN_NY, COUNT_ENEMIES_DEFEATED_SPIKE }, - { ACTOR_EN_SKB, COUNT_ENEMIES_DEFEATED_STALCHILD }, - { ACTOR_EN_TEST, COUNT_ENEMIES_DEFEATED_STALFOS }, - { ACTOR_EN_WEIYER, COUNT_ENEMIES_DEFEATED_STINGER }, - { ACTOR_EN_BW, COUNT_ENEMIES_DEFEATED_TORCH_SLUG }, - { ACTOR_EN_WALLMAS, COUNT_ENEMIES_DEFEATED_WALLMASTER }, - { ACTOR_EN_KAREBABA, COUNT_ENEMIES_DEFEATED_WITHERED_DEKU_BABA }, + { ACTOR_EN_BUBBLE, COUNT_ENEMIES_DEFEATED_SHABOM }, + { ACTOR_EN_SB, COUNT_ENEMIES_DEFEATED_SHELLBLADE }, + { ACTOR_EN_SKJ, COUNT_ENEMIES_DEFEATED_SKULL_KID }, + { ACTOR_EN_NY, COUNT_ENEMIES_DEFEATED_SPIKE }, + { ACTOR_EN_SKB, COUNT_ENEMIES_DEFEATED_STALCHILD }, + { ACTOR_EN_TEST, COUNT_ENEMIES_DEFEATED_STALFOS }, + { ACTOR_EN_WEIYER, COUNT_ENEMIES_DEFEATED_STINGER }, + { ACTOR_EN_BW, COUNT_ENEMIES_DEFEATED_TORCH_SLUG }, + { ACTOR_EN_WALLMAS, COUNT_ENEMIES_DEFEATED_WALLMASTER }, + { ACTOR_EN_KAREBABA, COUNT_ENEMIES_DEFEATED_WITHERED_DEKU_BABA }, }; void RegisterEnemyDefeatCounts() { @@ -655,16 +682,14 @@ void RegisterEnemyDefeatCounts() { } break; - case ACTOR_EN_REEBA: - { - EnReeba* reeba = (EnReeba*)actor; - if (reeba->isBig) { - gSaveContext.ship.stats.count[COUNT_ENEMIES_DEFEATED_LEEVER_BIG]++; - } else { - gSaveContext.ship.stats.count[COUNT_ENEMIES_DEFEATED_LEEVER]++; - } + case ACTOR_EN_REEBA: { + EnReeba* reeba = (EnReeba*)actor; + if (reeba->isBig) { + gSaveContext.ship.stats.count[COUNT_ENEMIES_DEFEATED_LEEVER_BIG]++; + } else { + gSaveContext.ship.stats.count[COUNT_ENEMIES_DEFEATED_LEEVER]++; } - break; + } break; case ACTOR_EN_MB: if (actor->params == 0) { @@ -781,26 +806,25 @@ void RegisterBossDefeatTimestamps() { } void UpdateHurtContainerModeState(bool newState) { - static bool hurtEnabled = false; - if (hurtEnabled == newState) { - return; - } + static bool hurtEnabled = false; + if (hurtEnabled == newState) { + return; + } - hurtEnabled = newState; - uint16_t getHeartPieces = gSaveContext.ship.stats.heartPieces / 4; - uint16_t getHeartContainers = gSaveContext.ship.stats.heartContainers; + hurtEnabled = newState; + uint16_t getHeartPieces = gSaveContext.ship.stats.heartPieces / 4; + uint16_t getHeartContainers = gSaveContext.ship.stats.heartContainers; - if (hurtEnabled) { - gSaveContext.healthCapacity = 320 - ((getHeartPieces + getHeartContainers) * 16); - } else { - gSaveContext.healthCapacity = 48 + ((getHeartPieces + getHeartContainers) * 16); - } + if (hurtEnabled) { + gSaveContext.healthCapacity = 320 - ((getHeartPieces + getHeartContainers) * 16); + } else { + gSaveContext.healthCapacity = 48 + ((getHeartPieces + getHeartContainers) * 16); + } } void RegisterHurtContainerModeHandler() { - GameInteractor::Instance->RegisterGameHook([](int32_t fileNum) { - UpdateHurtContainerModeState(CVarGetInteger(CVAR_ENHANCEMENT("HurtContainer"), 0)); - }); + GameInteractor::Instance->RegisterGameHook( + [](int32_t fileNum) { UpdateHurtContainerModeState(CVarGetInteger(CVAR_ENHANCEMENT("HurtContainer"), 0)); }); } void RegisterRandomizedEnemySizes() { @@ -820,7 +844,8 @@ void RegisterRandomizedEnemySizes() { actor->id == ACTOR_BOSS_FD2 || actor->id == ACTOR_EN_DH; // Only apply to enemies and bosses. - if (!CVarGetInteger(CVAR_ENHANCEMENT("RandomizedEnemySizes"), 0) || (actor->category != ACTORCAT_ENEMY && actor->category != ACTORCAT_BOSS) || excludedEnemy) { + if (!CVarGetInteger(CVAR_ENHANCEMENT("RandomizedEnemySizes"), 0) || + (actor->category != ACTORCAT_ENEMY && actor->category != ACTORCAT_BOSS) || excludedEnemy) { return; } @@ -860,7 +885,8 @@ void RegisterOpenAllHours() { GameInteractor::Instance->RegisterGameHook([](void* refActor) { Actor* actor = static_cast(refActor); - if (CVarGetInteger(CVAR_ENHANCEMENT("OpenAllHours"), 0) && (actor->id == ACTOR_EN_DOOR) && (!IS_RANDO || !OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_LOCK_OVERWORLD_DOORS))) { + if (CVarGetInteger(CVAR_ENHANCEMENT("OpenAllHours"), 0) && (actor->id == ACTOR_EN_DOOR) && + (!IS_RANDO || !OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_LOCK_OVERWORLD_DOORS))) { switch (actor->params) { case 4753: // Night Market Bazaar case 1678: // Night Potion Shop @@ -892,47 +918,65 @@ void PatchToTMedallions() { ResourceMgr_PatchGfxByName(tokinoma_room_0DL_007FD0, "ToTMedallions_2_StartGrayscale", 7, gsSPGrayscale(true)); if (CHECK_QUEST_ITEM(QUEST_MEDALLION_WATER)) { - ResourceMgr_PatchGfxByName(tokinoma_room_0DL_007A70, "ToTMedallions_MakeBlue", 16, gsDPSetGrayscaleColor(0, 161, 255, 255)); + ResourceMgr_PatchGfxByName(tokinoma_room_0DL_007A70, "ToTMedallions_MakeBlue", 16, + gsDPSetGrayscaleColor(0, 161, 255, 255)); } else { - ResourceMgr_PatchGfxByName(tokinoma_room_0DL_007A70, "ToTMedallions_MakeBlue", 16, gsDPSetGrayscaleColor(255, 255, 255, 255)); + ResourceMgr_PatchGfxByName(tokinoma_room_0DL_007A70, "ToTMedallions_MakeBlue", 16, + gsDPSetGrayscaleColor(255, 255, 255, 255)); } if (CHECK_QUEST_ITEM(QUEST_MEDALLION_SPIRIT)) { - ResourceMgr_PatchGfxByName(tokinoma_room_0DL_007A70, "ToTMedallions_MakeOrange", 45, gsDPSetGrayscaleColor(255, 135, 0, 255)); + ResourceMgr_PatchGfxByName(tokinoma_room_0DL_007A70, "ToTMedallions_MakeOrange", 45, + gsDPSetGrayscaleColor(255, 135, 0, 255)); } else { - ResourceMgr_PatchGfxByName(tokinoma_room_0DL_007A70, "ToTMedallions_MakeOrange", 45, gsDPSetGrayscaleColor(255, 255, 255, 255)); + ResourceMgr_PatchGfxByName(tokinoma_room_0DL_007A70, "ToTMedallions_MakeOrange", 45, + gsDPSetGrayscaleColor(255, 255, 255, 255)); } if (CHECK_QUEST_ITEM(QUEST_MEDALLION_LIGHT)) { - ResourceMgr_PatchGfxByName(tokinoma_room_0DL_007A70, "ToTMedallions_MakeYellow", 69, gsDPSetGrayscaleColor(255, 255, 0, 255)); - ResourceMgr_PatchGfxByName(tokinoma_room_0DL_007FD0, "ToTMedallions_2_MakeYellow", 16, gsDPSetGrayscaleColor(255, 255, 0, 255)); + ResourceMgr_PatchGfxByName(tokinoma_room_0DL_007A70, "ToTMedallions_MakeYellow", 69, + gsDPSetGrayscaleColor(255, 255, 0, 255)); + ResourceMgr_PatchGfxByName(tokinoma_room_0DL_007FD0, "ToTMedallions_2_MakeYellow", 16, + gsDPSetGrayscaleColor(255, 255, 0, 255)); } else { - ResourceMgr_PatchGfxByName(tokinoma_room_0DL_007A70, "ToTMedallions_MakeYellow", 69, gsDPSetGrayscaleColor(255, 255, 255, 255)); - ResourceMgr_PatchGfxByName(tokinoma_room_0DL_007FD0, "ToTMedallions_2_MakeYellow", 16, gsDPSetGrayscaleColor(255, 255, 255, 255)); + ResourceMgr_PatchGfxByName(tokinoma_room_0DL_007A70, "ToTMedallions_MakeYellow", 69, + gsDPSetGrayscaleColor(255, 255, 255, 255)); + ResourceMgr_PatchGfxByName(tokinoma_room_0DL_007FD0, "ToTMedallions_2_MakeYellow", 16, + gsDPSetGrayscaleColor(255, 255, 255, 255)); } if (CHECK_QUEST_ITEM(QUEST_MEDALLION_FOREST)) { - ResourceMgr_PatchGfxByName(tokinoma_room_0DL_007A70, "ToTMedallions_MakeGreen", 94, gsDPSetGrayscaleColor(0, 255, 0, 255)); + ResourceMgr_PatchGfxByName(tokinoma_room_0DL_007A70, "ToTMedallions_MakeGreen", 94, + gsDPSetGrayscaleColor(0, 255, 0, 255)); } else { - ResourceMgr_PatchGfxByName(tokinoma_room_0DL_007A70, "ToTMedallions_MakeGreen", 94, gsDPSetGrayscaleColor(255, 255, 255, 255)); + ResourceMgr_PatchGfxByName(tokinoma_room_0DL_007A70, "ToTMedallions_MakeGreen", 94, + gsDPSetGrayscaleColor(255, 255, 255, 255)); } if (CHECK_QUEST_ITEM(QUEST_MEDALLION_FIRE)) { - ResourceMgr_PatchGfxByName(tokinoma_room_0DL_007A70, "ToTMedallions_MakeRed", 118, gsDPSetGrayscaleColor(255, 0, 0, 255)); + ResourceMgr_PatchGfxByName(tokinoma_room_0DL_007A70, "ToTMedallions_MakeRed", 118, + gsDPSetGrayscaleColor(255, 0, 0, 255)); } else { - ResourceMgr_PatchGfxByName(tokinoma_room_0DL_007A70, "ToTMedallions_MakeRed", 118, gsDPSetGrayscaleColor(255, 255, 255, 255)); + ResourceMgr_PatchGfxByName(tokinoma_room_0DL_007A70, "ToTMedallions_MakeRed", 118, + gsDPSetGrayscaleColor(255, 255, 255, 255)); } if (CHECK_QUEST_ITEM(QUEST_MEDALLION_SHADOW)) { - ResourceMgr_PatchGfxByName(tokinoma_room_0DL_007A70, "ToTMedallions_MakePurple", 142, gsDPSetGrayscaleColor(212, 0, 255, 255)); - ResourceMgr_PatchGfxByName(tokinoma_room_0DL_007FD0, "ToTMedallions_2_MakePurple", 27, gsDPSetGrayscaleColor(212, 0, 255, 255)); + ResourceMgr_PatchGfxByName(tokinoma_room_0DL_007A70, "ToTMedallions_MakePurple", 142, + gsDPSetGrayscaleColor(212, 0, 255, 255)); + ResourceMgr_PatchGfxByName(tokinoma_room_0DL_007FD0, "ToTMedallions_2_MakePurple", 27, + gsDPSetGrayscaleColor(212, 0, 255, 255)); } else { - ResourceMgr_PatchGfxByName(tokinoma_room_0DL_007A70, "ToTMedallions_MakePurple", 142, gsDPSetGrayscaleColor(255, 255, 255, 255)); - ResourceMgr_PatchGfxByName(tokinoma_room_0DL_007FD0, "ToTMedallions_2_MakePurple", 27, gsDPSetGrayscaleColor(255, 255, 255, 255)); + ResourceMgr_PatchGfxByName(tokinoma_room_0DL_007A70, "ToTMedallions_MakePurple", 142, + gsDPSetGrayscaleColor(255, 255, 255, 255)); + ResourceMgr_PatchGfxByName(tokinoma_room_0DL_007FD0, "ToTMedallions_2_MakePurple", 27, + gsDPSetGrayscaleColor(255, 255, 255, 255)); } - ResourceMgr_PatchGfxByName(tokinoma_room_0DL_007A70, "ToTMedallions_EndGrayscaleAndEndDlist", 160, gsSPBranchListOTRFilePath(gEndGrayscaleAndEndDlistDL)); - ResourceMgr_PatchGfxByName(tokinoma_room_0DL_007FD0, "ToTMedallions_2_EndGrayscaleAndEndDlist", 51, gsSPBranchListOTRFilePath(gEndGrayscaleAndEndDlistDL)); + ResourceMgr_PatchGfxByName(tokinoma_room_0DL_007A70, "ToTMedallions_EndGrayscaleAndEndDlist", 160, + gsSPBranchListOTRFilePath(gEndGrayscaleAndEndDlistDL)); + ResourceMgr_PatchGfxByName(tokinoma_room_0DL_007FD0, "ToTMedallions_2_EndGrayscaleAndEndDlist", 51, + gsSPBranchListOTRFilePath(gEndGrayscaleAndEndDlistDL)); } else { // Unpatch everything ResourceMgr_UnpatchGfxByName(tokinoma_room_0DL_007A70, "ToTMedallions_StartGrayscale"); @@ -953,7 +997,8 @@ void PatchToTMedallions() { void RegisterToTMedallions() { GameInteractor::Instance->RegisterGameHook([](GetItemEntry _unused) { - if (!CVarGetInteger(CVAR_ENHANCEMENT("ToTMedallionsColors"), 0) || !gPlayState || gPlayState->sceneNum != SCENE_TEMPLE_OF_TIME) { + if (!CVarGetInteger(CVAR_ENHANCEMENT("ToTMedallionsColors"), 0) || !gPlayState || + gPlayState->sceneNum != SCENE_TEMPLE_OF_TIME) { return; } PatchToTMedallions(); @@ -966,7 +1011,6 @@ void RegisterToTMedallions() { }); } - void RegisterFloorSwitchesHook() { GameInteractor::Instance->RegisterGameHook([](void* refActor) { Actor* actor = static_cast(refActor); @@ -991,10 +1035,10 @@ void RegisterPauseMenuHooks() { return; } if (!pauseWarpHooksRegistered) { - GameInteractor::Instance->RegisterGameHook([]() {PauseWarp_HandleSelection();}); - GameInteractor::Instance->RegisterGameHook([]() { - PauseWarp_Execute(); - }); + GameInteractor::Instance->RegisterGameHook( + []() { PauseWarp_HandleSelection(); }); + GameInteractor::Instance->RegisterGameHook( + []() { PauseWarp_Execute(); }); pauseWarpHooksRegistered = true; } }); @@ -1004,7 +1048,6 @@ void RegisterCustomSkeletons() { static int8_t previousTunic = -1; GameInteractor::Instance->RegisterGameHook([]() { - if (!GameInteractor::IsSaveLoaded() || gPlayState == NULL) { return; } diff --git a/soh/soh/Enhancements/nametag.cpp b/soh/soh/Enhancements/nametag.cpp index 131f9b724..253c0980b 100644 --- a/soh/soh/Enhancements/nametag.cpp +++ b/soh/soh/Enhancements/nametag.cpp @@ -19,15 +19,15 @@ extern PlayState* gPlayState; typedef struct { Actor* actor; - std::string text; // Original text + std::string text; // Original text std::string processedText; // Text filtered for supported font textures - const char* tag; // Tag identifier - Color_RGBA8 textColor; // Text color override. Global color is used if alpha is 0 - int16_t height; // Textbox height - int16_t width; // Textbox width - int16_t yOffset; // Addition Y offset - Mtx* mtx; // Allocated Mtx for rendering - Vtx* vtx; // Allocated Vtx for rendering + const char* tag; // Tag identifier + Color_RGBA8 textColor; // Text color override. Global color is used if alpha is 0 + int16_t height; // Textbox height + int16_t width; // Textbox width + int16_t yOffset; // Addition Y offset + Mtx* mtx; // Allocated Mtx for rendering + Vtx* vtx; // Allocated Vtx for rendering } NameTag; static std::vector nameTags; @@ -69,7 +69,7 @@ void DrawNameTag(PlayState* play, const NameTag* nameTag) { return; } - Color_RGBA8 textboxColor = { 0, 0, 0, 80}; + Color_RGBA8 textboxColor = { 0, 0, 0, 80 }; Color_RGBA8 textColor = { 255, 255, 255, 255 }; if (CVarGetInteger(CVAR_COSMETIC("HUD.NameTagActorBackground.Changed"), 0)) { @@ -130,9 +130,9 @@ void DrawNameTag(PlayState* play, const NameTag* nameTag) { int16_t vertexStart = 4 * (i % 16); // Multi-instruction macro, need to insert all to the dl buffer - Gfx charTexture[] = { gsDPLoadTextureBlock_4b( - texture, G_IM_FMT_I, FONT_CHAR_TEX_WIDTH, FONT_CHAR_TEX_HEIGHT, 0, G_TX_NOMIRROR | G_TX_CLAMP, - G_TX_NOMIRROR | G_TX_CLAMP, G_TX_NOMASK, G_TX_NOMASK, G_TX_NOLOD, G_TX_NOLOD) }; + Gfx charTexture[] = { gsDPLoadTextureBlock_4b(texture, G_IM_FMT_I, FONT_CHAR_TEX_WIDTH, FONT_CHAR_TEX_HEIGHT, 0, + G_TX_NOMIRROR | G_TX_CLAMP, G_TX_NOMIRROR | G_TX_CLAMP, + G_TX_NOMASK, G_TX_NOMASK, G_TX_NOLOD, G_TX_NOLOD) }; nameTagDl.insert(nameTagDl.end(), std::begin(charTexture), std::end(charTexture)); nameTagDl.push_back(gsSP1Quadrangle(vertexStart, vertexStart + 2, vertexStart + 3, vertexStart + 1, 0)); @@ -195,11 +195,14 @@ extern "C" void NameTag_RegisterForActorWithOptions(Actor* actor, const char* te std::string processedText = std::string(Interface_ReplaceSpecialCharacters((char*)text)); // Strip out unsupported characters - processedText.erase(std::remove_if(processedText.begin(), processedText.end(), [](const char& c) { - // 172 is max supported texture for the in-game font system, - // and filter anything less than a space but not the newline or nul characters - return (unsigned char)c > 172 || (c < ' ' && c != '\n' && c != '\0'); - }), processedText.end()); + processedText.erase(std::remove_if(processedText.begin(), processedText.end(), + [](const char& c) { + // 172 is max supported texture for the in-game font system, + // and filter anything less than a space but not the newline or nul + // characters + return (unsigned char)c > 172 || (c < ' ' && c != '\n' && c != '\0'); + }), + processedText.end()); int16_t numChar = processedText.length(); int16_t numLines = 1; diff --git a/soh/soh/Enhancements/nametag.h b/soh/soh/Enhancements/nametag.h index 9fd26643e..98b83f7cc 100644 --- a/soh/soh/Enhancements/nametag.h +++ b/soh/soh/Enhancements/nametag.h @@ -3,8 +3,8 @@ #include typedef struct { - const char* tag; // Tag identifier to filter/remove multiple tags - int16_t yOffset; // Additional Y offset to apply for the name tag + const char* tag; // Tag identifier to filter/remove multiple tags + int16_t yOffset; // Additional Y offset to apply for the name tag Color_RGBA8 textColor; // Text color override. Global color is used if alpha is 0 } NameTagOptions; diff --git a/soh/soh/Enhancements/pausewarp.c b/soh/soh/Enhancements/pausewarp.c index 4934f6050..10f7e4e39 100644 --- a/soh/soh/Enhancements/pausewarp.c +++ b/soh/soh/Enhancements/pausewarp.c @@ -4,49 +4,37 @@ #include "game-interactor/GameInteractor.h" #include "soh/OTRGlobals.h" -static const int songMessageMap[] = { - TEXT_WARP_MINUET_OF_FOREST, - TEXT_WARP_BOLERO_OF_FIRE, - TEXT_WARP_SERENADE_OF_WATER, - TEXT_WARP_REQUIEM_OF_SPIRIT, - TEXT_WARP_NOCTURNE_OF_SHADOW, - TEXT_WARP_PRELUDE_OF_LIGHT, +static const int songMessageMap[] = { + TEXT_WARP_MINUET_OF_FOREST, TEXT_WARP_BOLERO_OF_FIRE, TEXT_WARP_SERENADE_OF_WATER, + TEXT_WARP_REQUIEM_OF_SPIRIT, TEXT_WARP_NOCTURNE_OF_SHADOW, TEXT_WARP_PRELUDE_OF_LIGHT, }; static const int ocarinaSongMap[] = { - OCARINA_SONG_MINUET, - OCARINA_SONG_BOLERO, - OCARINA_SONG_SERENADE, - OCARINA_SONG_REQUIEM, - OCARINA_SONG_NOCTURNE, - OCARINA_SONG_PRELUDE, + OCARINA_SONG_MINUET, OCARINA_SONG_BOLERO, OCARINA_SONG_SERENADE, + OCARINA_SONG_REQUIEM, OCARINA_SONG_NOCTURNE, OCARINA_SONG_PRELUDE, }; static const int entranceIndexMap[] = { - ENTR_SACRED_FOREST_MEADOW_WARP_PAD, // Minuet + ENTR_SACRED_FOREST_MEADOW_WARP_PAD, // Minuet ENTR_DEATH_MOUNTAIN_CRATER_WARP_PAD, // Bolero - ENTR_LAKE_HYLIA_WARP_PAD, // Serenade - ENTR_DESERT_COLOSSUS_WARP_PAD, // Requiem - ENTR_GRAVEYARD_WARP_PAD, // Nocturne - ENTR_TEMPLE_OF_TIME_WARP_PAD, // Prelude + ENTR_LAKE_HYLIA_WARP_PAD, // Serenade + ENTR_DESERT_COLOSSUS_WARP_PAD, // Requiem + ENTR_GRAVEYARD_WARP_PAD, // Nocturne + ENTR_TEMPLE_OF_TIME_WARP_PAD, // Prelude }; -static const int songAudioMap[] = { - NA_BGM_OCA_MINUET, - NA_BGM_OCA_BOLERO, - NA_BGM_OCA_SERENADE, - NA_BGM_OCA_REQUIEM, - NA_BGM_OCA_NOCTURNE, - NA_BGM_OCA_LIGHT, +static const int songAudioMap[] = { + NA_BGM_OCA_MINUET, NA_BGM_OCA_BOLERO, NA_BGM_OCA_SERENADE, + NA_BGM_OCA_REQUIEM, NA_BGM_OCA_NOCTURNE, NA_BGM_OCA_LIGHT, }; -static bool isWarpActive = false; +static bool isWarpActive = false; void PauseWarp_Execute() { if (!isWarpActive || gPlayState->msgCtx.msgMode != MSGMODE_NONE) { return; } - isWarpActive = false; + isWarpActive = false; GET_PLAYER(gPlayState)->stateFlags1 &= ~PLAYER_STATE1_IN_CUTSCENE; if (gPlayState->msgCtx.choiceIndex != 0) { return; @@ -88,41 +76,42 @@ void PauseWarp_HandleSelection() { int song = gPlayState->pauseCtx.cursorPoint[PAUSE_QUEST]; if (aButtonPressed && CHECK_QUEST_ITEM(song) && song >= QUEST_SONG_MINUET && song <= QUEST_SONG_PRELUDE && gPlayState->pauseCtx.pageIndex == PAUSE_QUEST && gPlayState->pauseCtx.state == 6) { - if (gSaveContext.ship.quest.id == QUEST_RANDOMIZER && Randomizer_GetSettingValue(RSK_SHUFFLE_OCARINA_BUTTONS)) { + if (gSaveContext.ship.quest.id == QUEST_RANDOMIZER && + Randomizer_GetSettingValue(RSK_SHUFFLE_OCARINA_BUTTONS)) { bool canplay = false; switch (song) { case QUEST_SONG_MINUET: canplay = Flags_GetRandomizerInf(RAND_INF_HAS_OCARINA_A) && - Flags_GetRandomizerInf(RAND_INF_HAS_OCARINA_C_LEFT) && - Flags_GetRandomizerInf(RAND_INF_HAS_OCARINA_C_RIGHT) && - Flags_GetRandomizerInf(RAND_INF_HAS_OCARINA_C_UP); + Flags_GetRandomizerInf(RAND_INF_HAS_OCARINA_C_LEFT) && + Flags_GetRandomizerInf(RAND_INF_HAS_OCARINA_C_RIGHT) && + Flags_GetRandomizerInf(RAND_INF_HAS_OCARINA_C_UP); break; case QUEST_SONG_BOLERO: canplay = Flags_GetRandomizerInf(RAND_INF_HAS_OCARINA_A) && - Flags_GetRandomizerInf(RAND_INF_HAS_OCARINA_C_RIGHT) && - Flags_GetRandomizerInf(RAND_INF_HAS_OCARINA_C_DOWN); + Flags_GetRandomizerInf(RAND_INF_HAS_OCARINA_C_RIGHT) && + Flags_GetRandomizerInf(RAND_INF_HAS_OCARINA_C_DOWN); break; case QUEST_SONG_SERENADE: canplay = Flags_GetRandomizerInf(RAND_INF_HAS_OCARINA_A) && - Flags_GetRandomizerInf(RAND_INF_HAS_OCARINA_C_LEFT) && - Flags_GetRandomizerInf(RAND_INF_HAS_OCARINA_C_RIGHT) && - Flags_GetRandomizerInf(RAND_INF_HAS_OCARINA_C_DOWN); + Flags_GetRandomizerInf(RAND_INF_HAS_OCARINA_C_LEFT) && + Flags_GetRandomizerInf(RAND_INF_HAS_OCARINA_C_RIGHT) && + Flags_GetRandomizerInf(RAND_INF_HAS_OCARINA_C_DOWN); break; case QUEST_SONG_REQUIEM: canplay = Flags_GetRandomizerInf(RAND_INF_HAS_OCARINA_A) && - Flags_GetRandomizerInf(RAND_INF_HAS_OCARINA_C_RIGHT) && - Flags_GetRandomizerInf(RAND_INF_HAS_OCARINA_C_DOWN); + Flags_GetRandomizerInf(RAND_INF_HAS_OCARINA_C_RIGHT) && + Flags_GetRandomizerInf(RAND_INF_HAS_OCARINA_C_DOWN); break; case QUEST_SONG_NOCTURNE: canplay = Flags_GetRandomizerInf(RAND_INF_HAS_OCARINA_A) && - Flags_GetRandomizerInf(RAND_INF_HAS_OCARINA_C_LEFT) && - Flags_GetRandomizerInf(RAND_INF_HAS_OCARINA_C_RIGHT) && - Flags_GetRandomizerInf(RAND_INF_HAS_OCARINA_C_DOWN); + Flags_GetRandomizerInf(RAND_INF_HAS_OCARINA_C_LEFT) && + Flags_GetRandomizerInf(RAND_INF_HAS_OCARINA_C_RIGHT) && + Flags_GetRandomizerInf(RAND_INF_HAS_OCARINA_C_DOWN); break; case QUEST_SONG_PRELUDE: canplay = Flags_GetRandomizerInf(RAND_INF_HAS_OCARINA_C_LEFT) && - Flags_GetRandomizerInf(RAND_INF_HAS_OCARINA_C_RIGHT) && - Flags_GetRandomizerInf(RAND_INF_HAS_OCARINA_C_UP); + Flags_GetRandomizerInf(RAND_INF_HAS_OCARINA_C_RIGHT) && + Flags_GetRandomizerInf(RAND_INF_HAS_OCARINA_C_UP); break; } if (!canplay) { diff --git a/soh/soh/Enhancements/randomizer/3drando/custom_messages.cpp b/soh/soh/Enhancements/randomizer/3drando/custom_messages.cpp index fcab083b4..cec16a468 100644 --- a/soh/soh/Enhancements/randomizer/3drando/custom_messages.cpp +++ b/soh/soh/Enhancements/randomizer/3drando/custom_messages.cpp @@ -5,40 +5,76 @@ namespace CustomMessages { using namespace std::literals::string_literals; - std::string MESSAGE_END() { return "\x7F\x00"s; } - std::string WAIT_FOR_INPUT() { return "\x7F\x01"s; } - std::string HORIZONTAL_SPACE(uint8_t x) { - return "\x7F\x02"s + char(x); - } - std::string GO_TO(uint16_t x) { - return "\x7F\x03"s + char(x >> 8) + char(x & 0x00FF); - } - std::string INSTANT_TEXT_ON() { return "\x7F\x04"s; } - std::string INSTANT_TEXT_OFF() { return "\x7F\x05"s; } - std::string SHOP_MESSAGE_BOX() { return "\x7F\x06\x00"s; } - std::string EVENT_TRIGGER() { return "\x7F\x07"s; } - std::string DELAY_FRAMES(uint8_t x) { - return "\x7F\x08"s + char(x); - } - std::string CLOSE_AFTER(uint8_t x) { - return "\x7F\x0A"s + char(x); - } - std::string PLAYER_NAME() { return "\x7F\x0B"s; } - std::string PLAY_OCARINA() { return "\x7F\x0C"s; } - std::string ITEM_OBTAINED(uint8_t x) { - return "\x7F\x0F"s + char(x); - } - std::string SET_SPEED(uint8_t x) { - return "\x7F\x10"s + char(x); - } - std::string SKULLTULAS_DESTROYED() { return "\x7F\x15"s; } - std::string CURRENT_TIME() { return "\x7F\x17"s; } - std::string UNSKIPPABLE() { return "\x7F\x19"s; } - std::string TWO_WAY_CHOICE() { return "\x1B"s; } - std::string NEWLINE() { return "\x7F\x1C"s; } - std::string COLOR(std::string x) { return "\x7F\x1D"s + x; } - std::string CENTER_TEXT() { return "\x7F\x1E"s; } - std::string IF_NOT_MQ() { return "\x7F\x29"s; } - std::string MQ_ELSE() { return "\x7F\x2A"s; } - std::string MQ_END() { return "\x7F\x2B"s; } +std::string MESSAGE_END() { + return "\x7F\x00"s; } +std::string WAIT_FOR_INPUT() { + return "\x7F\x01"s; +} +std::string HORIZONTAL_SPACE(uint8_t x) { + return "\x7F\x02"s + char(x); +} +std::string GO_TO(uint16_t x) { + return "\x7F\x03"s + char(x >> 8) + char(x & 0x00FF); +} +std::string INSTANT_TEXT_ON() { + return "\x7F\x04"s; +} +std::string INSTANT_TEXT_OFF() { + return "\x7F\x05"s; +} +std::string SHOP_MESSAGE_BOX() { + return "\x7F\x06\x00"s; +} +std::string EVENT_TRIGGER() { + return "\x7F\x07"s; +} +std::string DELAY_FRAMES(uint8_t x) { + return "\x7F\x08"s + char(x); +} +std::string CLOSE_AFTER(uint8_t x) { + return "\x7F\x0A"s + char(x); +} +std::string PLAYER_NAME() { + return "\x7F\x0B"s; +} +std::string PLAY_OCARINA() { + return "\x7F\x0C"s; +} +std::string ITEM_OBTAINED(uint8_t x) { + return "\x7F\x0F"s + char(x); +} +std::string SET_SPEED(uint8_t x) { + return "\x7F\x10"s + char(x); +} +std::string SKULLTULAS_DESTROYED() { + return "\x7F\x15"s; +} +std::string CURRENT_TIME() { + return "\x7F\x17"s; +} +std::string UNSKIPPABLE() { + return "\x7F\x19"s; +} +std::string TWO_WAY_CHOICE() { + return "\x1B"s; +} +std::string NEWLINE() { + return "\x7F\x1C"s; +} +std::string COLOR(std::string x) { + return "\x7F\x1D"s + x; +} +std::string CENTER_TEXT() { + return "\x7F\x1E"s; +} +std::string IF_NOT_MQ() { + return "\x7F\x29"s; +} +std::string MQ_ELSE() { + return "\x7F\x2A"s; +} +std::string MQ_END() { + return "\x7F\x2B"s; +} +} // namespace CustomMessages diff --git a/soh/soh/Enhancements/randomizer/3drando/fill.cpp b/soh/soh/Enhancements/randomizer/3drando/fill.cpp index 356bc507b..e5e22ad1d 100644 --- a/soh/soh/Enhancements/randomizer/3drando/fill.cpp +++ b/soh/soh/Enhancements/randomizer/3drando/fill.cpp @@ -20,270 +20,287 @@ using namespace Rando; - static bool placementFailure = false; +PriceSettingsStruct shopsanityPrices = { + RSK_SHOPSANITY_PRICES, + RSK_SHOPSANITY_PRICES_FIXED_PRICE, + RSK_SHOPSANITY_PRICES_RANGE_1, + RSK_SHOPSANITY_PRICES_RANGE_2, + RSK_SHOPSANITY_PRICES_NO_WALLET_WEIGHT, + RSK_SHOPSANITY_PRICES_CHILD_WALLET_WEIGHT, + RSK_SHOPSANITY_PRICES_ADULT_WALLET_WEIGHT, + RSK_SHOPSANITY_PRICES_GIANT_WALLET_WEIGHT, + RSK_SHOPSANITY_PRICES_TYCOON_WALLET_WEIGHT, + RSK_SHOPSANITY_PRICES_AFFORDABLE, +}; -PriceSettingsStruct shopsanityPrices = {RSK_SHOPSANITY_PRICES, - RSK_SHOPSANITY_PRICES_FIXED_PRICE, - RSK_SHOPSANITY_PRICES_RANGE_1, - RSK_SHOPSANITY_PRICES_RANGE_2, - RSK_SHOPSANITY_PRICES_NO_WALLET_WEIGHT, - RSK_SHOPSANITY_PRICES_CHILD_WALLET_WEIGHT, - RSK_SHOPSANITY_PRICES_ADULT_WALLET_WEIGHT, - RSK_SHOPSANITY_PRICES_GIANT_WALLET_WEIGHT, - RSK_SHOPSANITY_PRICES_TYCOON_WALLET_WEIGHT, - RSK_SHOPSANITY_PRICES_AFFORDABLE, }; - -PriceSettingsStruct scrubPrices = {RSK_SCRUBS_PRICES, - RSK_SCRUBS_PRICES_FIXED_PRICE, - RSK_SCRUBS_PRICES_RANGE_1, - RSK_SCRUBS_PRICES_RANGE_2, - RSK_SCRUBS_PRICES_NO_WALLET_WEIGHT, - RSK_SCRUBS_PRICES_CHILD_WALLET_WEIGHT, - RSK_SCRUBS_PRICES_ADULT_WALLET_WEIGHT, - RSK_SCRUBS_PRICES_GIANT_WALLET_WEIGHT, - RSK_SCRUBS_PRICES_TYCOON_WALLET_WEIGHT, - RSK_SCRUBS_PRICES_AFFORDABLE, }; +PriceSettingsStruct scrubPrices = { + RSK_SCRUBS_PRICES, + RSK_SCRUBS_PRICES_FIXED_PRICE, + RSK_SCRUBS_PRICES_RANGE_1, + RSK_SCRUBS_PRICES_RANGE_2, + RSK_SCRUBS_PRICES_NO_WALLET_WEIGHT, + RSK_SCRUBS_PRICES_CHILD_WALLET_WEIGHT, + RSK_SCRUBS_PRICES_ADULT_WALLET_WEIGHT, + RSK_SCRUBS_PRICES_GIANT_WALLET_WEIGHT, + RSK_SCRUBS_PRICES_TYCOON_WALLET_WEIGHT, + RSK_SCRUBS_PRICES_AFFORDABLE, +}; -PriceSettingsStruct merchantPrices = {RSK_MERCHANT_PRICES, - RSK_MERCHANT_PRICES_FIXED_PRICE, - RSK_MERCHANT_PRICES_RANGE_1, - RSK_MERCHANT_PRICES_RANGE_2, - RSK_MERCHANT_PRICES_NO_WALLET_WEIGHT, - RSK_MERCHANT_PRICES_CHILD_WALLET_WEIGHT, - RSK_MERCHANT_PRICES_ADULT_WALLET_WEIGHT, - RSK_MERCHANT_PRICES_GIANT_WALLET_WEIGHT, - RSK_MERCHANT_PRICES_TYCOON_WALLET_WEIGHT, - RSK_MERCHANT_PRICES_AFFORDABLE, }; +PriceSettingsStruct merchantPrices = { + RSK_MERCHANT_PRICES, + RSK_MERCHANT_PRICES_FIXED_PRICE, + RSK_MERCHANT_PRICES_RANGE_1, + RSK_MERCHANT_PRICES_RANGE_2, + RSK_MERCHANT_PRICES_NO_WALLET_WEIGHT, + RSK_MERCHANT_PRICES_CHILD_WALLET_WEIGHT, + RSK_MERCHANT_PRICES_ADULT_WALLET_WEIGHT, + RSK_MERCHANT_PRICES_GIANT_WALLET_WEIGHT, + RSK_MERCHANT_PRICES_TYCOON_WALLET_WEIGHT, + RSK_MERCHANT_PRICES_AFFORDABLE, +}; static void RemoveStartingItemsFromPool() { - for (RandomizerGet startingItem : StartingInventory) { - for (size_t i = 0; i < ItemPool.size(); i++) { - if (startingItem == RG_BIGGORON_SWORD) { - if (ItemPool[i] == RG_GIANTS_KNIFE || ItemPool[i] == RG_BIGGORON_SWORD) { - ItemPool[i] = GetJunkItem(); + for (RandomizerGet startingItem : StartingInventory) { + for (size_t i = 0; i < ItemPool.size(); i++) { + if (startingItem == RG_BIGGORON_SWORD) { + if (ItemPool[i] == RG_GIANTS_KNIFE || ItemPool[i] == RG_BIGGORON_SWORD) { + ItemPool[i] = GetJunkItem(); + } + continue; + } else if (startingItem == ItemPool[i] || (Rando::StaticData::RetrieveItem(startingItem).IsBottleItem() && + Rando::StaticData::RetrieveItem(ItemPool[i]).IsBottleItem())) { + if (AdditionalHeartContainers > 0 && + (startingItem == RG_PIECE_OF_HEART || startingItem == RG_TREASURE_GAME_HEART)) { + ItemPool[i] = RG_HEART_CONTAINER; + AdditionalHeartContainers--; + } else { + ItemPool[i] = GetJunkItem(); + } + break; + } } - continue; - } else if (startingItem == ItemPool[i] || (Rando::StaticData::RetrieveItem(startingItem).IsBottleItem() && - Rando::StaticData::RetrieveItem(ItemPool[i]).IsBottleItem())) { - if (AdditionalHeartContainers > 0 && - (startingItem == RG_PIECE_OF_HEART || startingItem == RG_TREASURE_GAME_HEART)) { - ItemPool[i] = RG_HEART_CONTAINER; - AdditionalHeartContainers--; - } else { - ItemPool[i] = GetJunkItem(); - } - break; - } } - } } -static void PropagateTimeTravel(GetAccessibleLocationsStruct& gals, RandomizerGet ignore = RG_NONE, - bool stopOnBeatable = false, bool addToPlaythrough = false){ - //special check for temple of time - if(gals.haveTimeAccess && gals.foundTempleOfTime && gals.validatedStartingRegion){ - if (!RegionTable(RR_ROOT)->Adult() && RegionTable(RR_TOT_BEYOND_DOOR_OF_TIME)->Child()) { //RANDOTODO: sphere weirdness, other age locations not propagated in this sphere - RegionTable(RR_ROOT)->adultDay = RegionTable(RR_TOT_BEYOND_DOOR_OF_TIME)->childDay; - RegionTable(RR_ROOT)->adultNight = RegionTable(RR_TOT_BEYOND_DOOR_OF_TIME)->childNight; - ProcessRegion(RegionTable(RR_ROOT), gals, ignore, stopOnBeatable, addToPlaythrough); - } else if (!RegionTable(RR_ROOT)->Child() && RegionTable(RR_TOT_BEYOND_DOOR_OF_TIME)->Adult()){ - RegionTable(RR_ROOT)->childDay = RegionTable(RR_TOT_BEYOND_DOOR_OF_TIME)->adultDay; - RegionTable(RR_ROOT)->childNight = RegionTable(RR_TOT_BEYOND_DOOR_OF_TIME)->adultNight; - ProcessRegion(RegionTable(RR_ROOT), gals, ignore, stopOnBeatable, addToPlaythrough); +static void PropagateTimeTravel(GetAccessibleLocationsStruct& gals, RandomizerGet ignore = RG_NONE, + bool stopOnBeatable = false, bool addToPlaythrough = false) { + // special check for temple of time + if (gals.haveTimeAccess && gals.foundTempleOfTime && gals.validatedStartingRegion) { + if (!RegionTable(RR_ROOT)->Adult() && + RegionTable(RR_TOT_BEYOND_DOOR_OF_TIME) + ->Child()) { // RANDOTODO: sphere weirdness, other age locations not propagated in this sphere + RegionTable(RR_ROOT)->adultDay = RegionTable(RR_TOT_BEYOND_DOOR_OF_TIME)->childDay; + RegionTable(RR_ROOT)->adultNight = RegionTable(RR_TOT_BEYOND_DOOR_OF_TIME)->childNight; + ProcessRegion(RegionTable(RR_ROOT), gals, ignore, stopOnBeatable, addToPlaythrough); + } else if (!RegionTable(RR_ROOT)->Child() && RegionTable(RR_TOT_BEYOND_DOOR_OF_TIME)->Adult()) { + RegionTable(RR_ROOT)->childDay = RegionTable(RR_TOT_BEYOND_DOOR_OF_TIME)->adultDay; + RegionTable(RR_ROOT)->childNight = RegionTable(RR_TOT_BEYOND_DOOR_OF_TIME)->adultNight; + ProcessRegion(RegionTable(RR_ROOT), gals, ignore, stopOnBeatable, addToPlaythrough); + } } - } } -//This function will propagate Time of Day access through the entrance +// This function will propagate Time of Day access through the entrance static bool UpdateToDAccess(Entrance* entrance, Region* connection) { - StartPerformanceTimer(PT_TOD_ACCESS); + StartPerformanceTimer(PT_TOD_ACCESS); - bool ageTimePropogated = false; - Region* parent = entrance->GetParentRegion(); + bool ageTimePropogated = false; + Region* parent = entrance->GetParentRegion(); - if (!connection->childDay && parent->childDay && entrance->CheckConditionAtAgeTime(logic->IsChild, logic->AtDay)) { - connection->childDay = true; - ageTimePropogated = true; - } - if (!connection->childNight && parent->childNight && entrance->CheckConditionAtAgeTime(logic->IsChild, logic->AtNight)) { - connection->childNight = true; - ageTimePropogated = true; - } - if (!connection->adultDay && parent->adultDay && entrance->CheckConditionAtAgeTime(logic->IsAdult, logic->AtDay)) { - connection->adultDay = true; - ageTimePropogated = true; - } - if (!connection->adultNight && parent->adultNight && entrance->CheckConditionAtAgeTime(logic->IsAdult, logic->AtNight)) { - connection->adultNight = true; - ageTimePropogated = true; - } + if (!connection->childDay && parent->childDay && entrance->CheckConditionAtAgeTime(logic->IsChild, logic->AtDay)) { + connection->childDay = true; + ageTimePropogated = true; + } + if (!connection->childNight && parent->childNight && + entrance->CheckConditionAtAgeTime(logic->IsChild, logic->AtNight)) { + connection->childNight = true; + ageTimePropogated = true; + } + if (!connection->adultDay && parent->adultDay && entrance->CheckConditionAtAgeTime(logic->IsAdult, logic->AtDay)) { + connection->adultDay = true; + ageTimePropogated = true; + } + if (!connection->adultNight && parent->adultNight && + entrance->CheckConditionAtAgeTime(logic->IsAdult, logic->AtNight)) { + connection->adultNight = true; + ageTimePropogated = true; + } - StopPerformanceTimer(PT_TOD_ACCESS); - return ageTimePropogated; + StopPerformanceTimer(PT_TOD_ACCESS); + return ageTimePropogated; } // Check if key locations in the overworld are accessable static void ValidateOtherEntrance(GetAccessibleLocationsStruct& gals) { - auto ctx = Rando::Context::GetInstance(); - // Condition for validating Temple of Time Access - if (!gals.foundTempleOfTime && ((ctx->GetOption(RSK_SELECTED_STARTING_AGE).Is(RO_AGE_CHILD) && RegionTable(RR_TEMPLE_OF_TIME)->Adult()) || - (ctx->GetOption(RSK_SELECTED_STARTING_AGE).Is(RO_AGE_ADULT) && RegionTable(RR_TEMPLE_OF_TIME)->Child()))) { - gals.foundTempleOfTime = true; - } - // Condition for validating a valid starting region - if (!gals.validatedStartingRegion) { - bool childAccess = ctx->GetOption(RSK_SELECTED_STARTING_AGE).Is(RO_AGE_CHILD) || RegionTable(RR_TOT_BEYOND_DOOR_OF_TIME)->Child(); - bool adultAccess = ctx->GetOption(RSK_SELECTED_STARTING_AGE).Is(RO_AGE_ADULT) || RegionTable(RR_TOT_BEYOND_DOOR_OF_TIME)->Adult(); - - Region* kokiri = RegionTable(RR_KOKIRI_FOREST); - Region* kakariko = RegionTable(RR_KAKARIKO_VILLAGE); - - if ((childAccess && (kokiri->Child() || kakariko->Child())) ||// RANDOTODO when proper ammo logic is done, this could probably be made optional - (adultAccess && (kokiri->Adult() || kakariko->Adult()))) { - gals.validatedStartingRegion = true; - ApplyStartingInventory(); // RANDOTODO when proper ammo logic is done, this could be moved to the start + auto ctx = Rando::Context::GetInstance(); + // Condition for validating Temple of Time Access + if (!gals.foundTempleOfTime && + ((ctx->GetOption(RSK_SELECTED_STARTING_AGE).Is(RO_AGE_CHILD) && RegionTable(RR_TEMPLE_OF_TIME)->Adult()) || + (ctx->GetOption(RSK_SELECTED_STARTING_AGE).Is(RO_AGE_ADULT) && RegionTable(RR_TEMPLE_OF_TIME)->Child()))) { + gals.foundTempleOfTime = true; + } + // Condition for validating a valid starting region + if (!gals.validatedStartingRegion) { + bool childAccess = ctx->GetOption(RSK_SELECTED_STARTING_AGE).Is(RO_AGE_CHILD) || + RegionTable(RR_TOT_BEYOND_DOOR_OF_TIME)->Child(); + bool adultAccess = ctx->GetOption(RSK_SELECTED_STARTING_AGE).Is(RO_AGE_ADULT) || + RegionTable(RR_TOT_BEYOND_DOOR_OF_TIME)->Adult(); + + Region* kokiri = RegionTable(RR_KOKIRI_FOREST); + Region* kakariko = RegionTable(RR_KAKARIKO_VILLAGE); + + if ((childAccess && + (kokiri->Child() || + kakariko->Child())) || // RANDOTODO when proper ammo logic is done, this could probably be made optional + (adultAccess && (kokiri->Adult() || kakariko->Adult()))) { + gals.validatedStartingRegion = true; + ApplyStartingInventory(); // RANDOTODO when proper ammo logic is done, this could be moved to the start + } + } + // If we are not shuffling the guard house, add the key so we can properly check for poe merchant access + if (gals.validatedStartingRegion && gals.foundTempleOfTime && + !ctx->GetOption(RSK_SHUFFLE_INTERIOR_ENTRANCES).Is(RO_INTERIOR_ENTRANCE_SHUFFLE_ALL)) { + Rando::StaticData::RetrieveItem(RG_GUARD_HOUSE_KEY).ApplyEffect(); } - } - //If we are not shuffling the guard house, add the key so we can properly check for poe merchant access - if (gals.validatedStartingRegion && gals.foundTempleOfTime && !ctx->GetOption(RSK_SHUFFLE_INTERIOR_ENTRANCES).Is(RO_INTERIOR_ENTRANCE_SHUFFLE_ALL)){ - Rando::StaticData::RetrieveItem(RG_GUARD_HOUSE_KEY).ApplyEffect(); - } } // Apply all items that are necessary for checking all location access -static void ApplyAllAdvancmentItems(){ - std::vector itemsToPlace = - FilterFromPool(ItemPool, [](const auto i) { return Rando::StaticData::RetrieveItem(i).IsAdvancement(); }); - for (RandomizerGet unplacedItem : itemsToPlace) { - Rando::StaticData::RetrieveItem(unplacedItem).ApplyEffect(); - } +static void ApplyAllAdvancmentItems() { + std::vector itemsToPlace = + FilterFromPool(ItemPool, [](const auto i) { return Rando::StaticData::RetrieveItem(i).IsAdvancement(); }); + for (RandomizerGet unplacedItem : itemsToPlace) { + Rando::StaticData::RetrieveItem(unplacedItem).ApplyEffect(); + } } // Check if everything in an entrance rando seed that needs to be avalible without items, is, // and if so allow obtaining items in logic -static void ValidateSphereZero(GetAccessibleLocationsStruct& gals){ - auto ctx = Rando::Context::GetInstance(); - // Condition for verifying everything required for sphere 0, expanding search to all locations - if ((!logic->AreCheckingBigPoes || logic->CanEmptyBigPoes) && gals.validatedStartingRegion && gals.foundTempleOfTime && gals.haveTimeAccess) { - //stop checking for big poes - logic->AreCheckingBigPoes = false; - // Apply all items that are necessary for checking all location access - ApplyAllAdvancmentItems(); - // Reset access as the non-starting age - if (ctx->GetOption(RSK_SELECTED_STARTING_AGE).Is(RO_AGE_CHILD)) { - for (RandomizerRegion regionKey : gals.regionPool) { - RegionTable(regionKey)->adultDay = false; - RegionTable(regionKey)->adultNight = false; - } - } else { - for (RandomizerRegion regionKey : gals.regionPool) { - RegionTable(regionKey)->childDay = false; - RegionTable(regionKey)->childNight = false; - } +static void ValidateSphereZero(GetAccessibleLocationsStruct& gals) { + auto ctx = Rando::Context::GetInstance(); + // Condition for verifying everything required for sphere 0, expanding search to all locations + if ((!logic->AreCheckingBigPoes || logic->CanEmptyBigPoes) && gals.validatedStartingRegion && + gals.foundTempleOfTime && gals.haveTimeAccess) { + // stop checking for big poes + logic->AreCheckingBigPoes = false; + // Apply all items that are necessary for checking all location access + ApplyAllAdvancmentItems(); + // Reset access as the non-starting age + if (ctx->GetOption(RSK_SELECTED_STARTING_AGE).Is(RO_AGE_CHILD)) { + for (RandomizerRegion regionKey : gals.regionPool) { + RegionTable(regionKey)->adultDay = false; + RegionTable(regionKey)->adultNight = false; + } + } else { + for (RandomizerRegion regionKey : gals.regionPool) { + RegionTable(regionKey)->childDay = false; + RegionTable(regionKey)->childNight = false; + } + } + // RANDOTODO do we want to keep the region pool after this reset? + // It's a lot of potential looping over regions we have no access to + gals.sphereZeroComplete = true; } - //RANDOTODO do we want to keep the region pool after this reset? - //It's a lot of potential looping over regions we have no access to - gals.sphereZeroComplete = true; - } } -//This function handles each possible exit -void ProcessExits(Region* region, GetAccessibleLocationsStruct& gals, RandomizerGet ignore = RG_NONE, - bool stopOnBeatable = false, bool addToPlaythrough = false){ - auto ctx = Rando::Context::GetInstance(); - for (auto& exit : region->exits) { - Region* exitRegion = exit.GetConnectedRegion(); - //Update Time of Day Access for the exit - if (UpdateToDAccess(&exit, exitRegion)) { - gals.logicUpdated = true; - if (!gals.sphereZeroComplete){ - if (!gals.foundTempleOfTime || !gals.validatedStartingRegion){ - ValidateOtherEntrance(gals); +// This function handles each possible exit +void ProcessExits(Region* region, GetAccessibleLocationsStruct& gals, RandomizerGet ignore = RG_NONE, + bool stopOnBeatable = false, bool addToPlaythrough = false) { + auto ctx = Rando::Context::GetInstance(); + for (auto& exit : region->exits) { + Region* exitRegion = exit.GetConnectedRegion(); + // Update Time of Day Access for the exit + if (UpdateToDAccess(&exit, exitRegion)) { + gals.logicUpdated = true; + if (!gals.sphereZeroComplete) { + if (!gals.foundTempleOfTime || !gals.validatedStartingRegion) { + ValidateOtherEntrance(gals); + } + ValidateSphereZero(gals); + } + // process the region we just expanded to, to reduce looping + ProcessRegion(exitRegion, gals, ignore, stopOnBeatable, addToPlaythrough); } - ValidateSphereZero(gals); - } - //process the region we just expanded to, to reduce looping - ProcessRegion(exitRegion, gals, ignore, stopOnBeatable, addToPlaythrough); - } - //If the exit is accessible and hasn't been added yet, add it to the pool - //RANDOTODO do we want to add the region after the loop now, considering we - //are processing the new region immediately. Maybe a reverse for loop in ProcessRegion? - if (!exitRegion->addedToPool && exit.ConditionsMet()) { - exitRegion->addedToPool = true; - gals.regionPool.push_back(exit.GetConnectedRegionKey()); - } - - if (addToPlaythrough){ - // RANDOTODO Should this match the regular spheres? - // Add shuffled entrances to the entrance playthrough - // Include bluewarps when unshuffled but dungeon or boss shuffle is on - if((exit.IsShuffled() || (exit.GetType() == Rando::EntranceType::BlueWarp && - (ctx->GetOption(RSK_SHUFFLE_DUNGEON_ENTRANCES) || ctx->GetOption(RSK_SHUFFLE_BOSS_ENTRANCES)))) && - !exit.IsAddedToPool() && !ctx->GetEntranceShuffler()->HasNoRandomEntrances()) { - gals.entranceSphere.push_back(&exit); - exit.AddToPool(); - // Don't list a two-way coupled entrance from both directions - if (exit.GetReverse() != nullptr && exit.GetReplacement()->GetReverse() != nullptr && !exit.IsDecoupled()) { - exit.GetReplacement()->GetReverse()->AddToPool(); + // If the exit is accessible and hasn't been added yet, add it to the pool + // RANDOTODO do we want to add the region after the loop now, considering we + // are processing the new region immediately. Maybe a reverse for loop in ProcessRegion? + if (!exitRegion->addedToPool && exit.ConditionsMet()) { + exitRegion->addedToPool = true; + gals.regionPool.push_back(exit.GetConnectedRegionKey()); + } + + if (addToPlaythrough) { + // RANDOTODO Should this match the regular spheres? + // Add shuffled entrances to the entrance playthrough + // Include bluewarps when unshuffled but dungeon or boss shuffle is on + if ((exit.IsShuffled() || + (exit.GetType() == Rando::EntranceType::BlueWarp && + (ctx->GetOption(RSK_SHUFFLE_DUNGEON_ENTRANCES) || ctx->GetOption(RSK_SHUFFLE_BOSS_ENTRANCES)))) && + !exit.IsAddedToPool() && !ctx->GetEntranceShuffler()->HasNoRandomEntrances()) { + gals.entranceSphere.push_back(&exit); + exit.AddToPool(); + // Don't list a two-way coupled entrance from both directions + if (exit.GetReverse() != nullptr && exit.GetReplacement()->GetReverse() != nullptr && + !exit.IsDecoupled()) { + exit.GetReplacement()->GetReverse()->AddToPool(); + } + } } - } } - } } - -//Get the max number of tokens that can possibly be useful +// Get the max number of tokens that can possibly be useful static int GetMaxGSCount() { - auto ctx = Rando::Context::GetInstance(); - //If bridge or LACS is set to tokens, get how many are required - int maxBridge = 0; - int maxLACS = 0; - if (ctx->GetOption(RSK_RAINBOW_BRIDGE).Is(RO_BRIDGE_TOKENS)) { - maxBridge = ctx->GetOption(RSK_RAINBOW_BRIDGE_TOKEN_COUNT).Get(); - } - if (ctx->GetOption(RSK_GANONS_BOSS_KEY).Is(RO_GANON_BOSS_KEY_LACS_TOKENS)) { - maxLACS = ctx->GetOption(RSK_LACS_TOKEN_COUNT).Get(); - } - maxBridge = std::max(maxBridge, maxLACS); - //Get the max amount of GS which could be useful from token reward locations - int maxUseful = 0; - //If the highest advancement item is a token, we know it is useless since it won't lead to an otherwise useful item - if (ctx->GetItemLocation(RC_KAK_100_GOLD_SKULLTULA_REWARD)->GetPlacedItem().IsAdvancement() && ctx->GetItemLocation(RC_KAK_100_GOLD_SKULLTULA_REWARD)->GetPlacedItem().GetItemType() != ITEMTYPE_TOKEN) { - maxUseful = 100; - } else if (ctx->GetItemLocation(RC_KAK_50_GOLD_SKULLTULA_REWARD)->GetPlacedItem().IsAdvancement() && - ctx->GetItemLocation(RC_KAK_50_GOLD_SKULLTULA_REWARD)->GetPlacedItem().GetItemType() != ITEMTYPE_TOKEN) { - maxUseful = 50; - } else if (ctx->GetItemLocation(RC_KAK_40_GOLD_SKULLTULA_REWARD)->GetPlacedItem().IsAdvancement() && - ctx->GetItemLocation(RC_KAK_40_GOLD_SKULLTULA_REWARD)->GetPlacedItem().GetItemType() != ITEMTYPE_TOKEN) { - maxUseful = 40; - } else if (ctx->GetItemLocation(RC_KAK_30_GOLD_SKULLTULA_REWARD)->GetPlacedItem().IsAdvancement() && - ctx->GetItemLocation(RC_KAK_30_GOLD_SKULLTULA_REWARD)->GetPlacedItem().GetItemType() != ITEMTYPE_TOKEN) { - maxUseful = 30; - } else if (ctx->GetItemLocation(RC_KAK_20_GOLD_SKULLTULA_REWARD)->GetPlacedItem().IsAdvancement() && - ctx->GetItemLocation(RC_KAK_20_GOLD_SKULLTULA_REWARD)->GetPlacedItem().GetItemType() != ITEMTYPE_TOKEN) { - maxUseful = 20; - } else if (ctx->GetItemLocation(RC_KAK_10_GOLD_SKULLTULA_REWARD)->GetPlacedItem().IsAdvancement() && - ctx->GetItemLocation(RC_KAK_10_GOLD_SKULLTULA_REWARD)->GetPlacedItem().GetItemType() != ITEMTYPE_TOKEN) { - maxUseful = 10; - } - //Return max of the two possible reasons tokens could be important, minus the tokens in the starting inventory - return std::max(maxUseful, maxBridge) - ctx->GetOption(RSK_STARTING_SKULLTULA_TOKEN).Get(); + auto ctx = Rando::Context::GetInstance(); + // If bridge or LACS is set to tokens, get how many are required + int maxBridge = 0; + int maxLACS = 0; + if (ctx->GetOption(RSK_RAINBOW_BRIDGE).Is(RO_BRIDGE_TOKENS)) { + maxBridge = ctx->GetOption(RSK_RAINBOW_BRIDGE_TOKEN_COUNT).Get(); + } + if (ctx->GetOption(RSK_GANONS_BOSS_KEY).Is(RO_GANON_BOSS_KEY_LACS_TOKENS)) { + maxLACS = ctx->GetOption(RSK_LACS_TOKEN_COUNT).Get(); + } + maxBridge = std::max(maxBridge, maxLACS); + // Get the max amount of GS which could be useful from token reward locations + int maxUseful = 0; + // If the highest advancement item is a token, we know it is useless since it won't lead to an otherwise useful item + if (ctx->GetItemLocation(RC_KAK_100_GOLD_SKULLTULA_REWARD)->GetPlacedItem().IsAdvancement() && + ctx->GetItemLocation(RC_KAK_100_GOLD_SKULLTULA_REWARD)->GetPlacedItem().GetItemType() != ITEMTYPE_TOKEN) { + maxUseful = 100; + } else if (ctx->GetItemLocation(RC_KAK_50_GOLD_SKULLTULA_REWARD)->GetPlacedItem().IsAdvancement() && + ctx->GetItemLocation(RC_KAK_50_GOLD_SKULLTULA_REWARD)->GetPlacedItem().GetItemType() != ITEMTYPE_TOKEN) { + maxUseful = 50; + } else if (ctx->GetItemLocation(RC_KAK_40_GOLD_SKULLTULA_REWARD)->GetPlacedItem().IsAdvancement() && + ctx->GetItemLocation(RC_KAK_40_GOLD_SKULLTULA_REWARD)->GetPlacedItem().GetItemType() != ITEMTYPE_TOKEN) { + maxUseful = 40; + } else if (ctx->GetItemLocation(RC_KAK_30_GOLD_SKULLTULA_REWARD)->GetPlacedItem().IsAdvancement() && + ctx->GetItemLocation(RC_KAK_30_GOLD_SKULLTULA_REWARD)->GetPlacedItem().GetItemType() != ITEMTYPE_TOKEN) { + maxUseful = 30; + } else if (ctx->GetItemLocation(RC_KAK_20_GOLD_SKULLTULA_REWARD)->GetPlacedItem().IsAdvancement() && + ctx->GetItemLocation(RC_KAK_20_GOLD_SKULLTULA_REWARD)->GetPlacedItem().GetItemType() != ITEMTYPE_TOKEN) { + maxUseful = 20; + } else if (ctx->GetItemLocation(RC_KAK_10_GOLD_SKULLTULA_REWARD)->GetPlacedItem().IsAdvancement() && + ctx->GetItemLocation(RC_KAK_10_GOLD_SKULLTULA_REWARD)->GetPlacedItem().GetItemType() != ITEMTYPE_TOKEN) { + maxUseful = 10; + } + // Return max of the two possible reasons tokens could be important, minus the tokens in the starting inventory + return std::max(maxUseful, maxBridge) - ctx->GetOption(RSK_STARTING_SKULLTULA_TOKEN).Get(); } std::string GetShopItemBaseName(std::string itemName) { - std::string baseName = itemName.erase(0, 4); //Delete "Buy " - //Delete amount, if present (so when it looks like Buy Deku Nut (10) remove the (10)) - if (baseName.find("(") != std::string::npos) { - baseName = baseName.erase(baseName.find("(")); - } - //Do the same for [] (only applies to red potions, other things with [] also have a ()) - if (baseName.find("[") != std::string::npos) { - baseName = baseName.erase(baseName.find("[")); - } - return baseName; + std::string baseName = itemName.erase(0, 4); // Delete "Buy " + // Delete amount, if present (so when it looks like Buy Deku Nut (10) remove the (10)) + if (baseName.find("(") != std::string::npos) { + baseName = baseName.erase(baseName.find("(")); + } + // Do the same for [] (only applies to red potions, other things with [] also have a ()) + if (baseName.find("[") != std::string::npos) { + baseName = baseName.erase(baseName.find("[")); + } + return baseName; } std::vector GetEmptyLocations(std::vector targetLocations) { @@ -300,501 +317,512 @@ std::vector GetAllEmptyLocations() { }); } -bool IsBombchus(RandomizerGet item, bool includeShops = false){ - return (item >= RG_BOMBCHU_5 && item <= RG_BOMBCHU_20) || item == RG_PROGRESSIVE_BOMBCHUS || - (includeShops && (item == RG_BUY_BOMBCHUS_10 || item == RG_BUY_BOMBCHUS_20)); +bool IsBombchus(RandomizerGet item, bool includeShops = false) { + return (item >= RG_BOMBCHU_5 && item <= RG_BOMBCHU_20) || item == RG_PROGRESSIVE_BOMBCHUS || + (includeShops && (item == RG_BUY_BOMBCHUS_10 || item == RG_BUY_BOMBCHUS_20)); } -bool IsBeatableWithout(RandomizerCheck excludedCheck, bool replaceItem, RandomizerGet ignore = RG_NONE){ //RANDOTODO make excludCheck an ItemLocation - auto ctx = Rando::Context::GetInstance(); - RandomizerGet copy = ctx->GetItemLocation(excludedCheck)->GetPlacedRandomizerGet(); //Copy out item - ctx->GetItemLocation(excludedCheck)->SetPlacedItem(RG_NONE); //Write in empty item - ctx->playthroughBeatable = false; - logic->Reset(); - CheckBeatable(ignore); - if (replaceItem){ - ctx->GetItemLocation(excludedCheck)->SetPlacedItem(copy); //Immediately put item back - } - return ctx->playthroughBeatable; +bool IsBeatableWithout(RandomizerCheck excludedCheck, bool replaceItem, + RandomizerGet ignore = RG_NONE) { // RANDOTODO make excludCheck an ItemLocation + auto ctx = Rando::Context::GetInstance(); + RandomizerGet copy = ctx->GetItemLocation(excludedCheck)->GetPlacedRandomizerGet(); // Copy out item + ctx->GetItemLocation(excludedCheck)->SetPlacedItem(RG_NONE); // Write in empty item + ctx->playthroughBeatable = false; + logic->Reset(); + CheckBeatable(ignore); + if (replaceItem) { + ctx->GetItemLocation(excludedCheck)->SetPlacedItem(copy); // Immediately put item back + } + return ctx->playthroughBeatable; } // Reset non-Logic-class logic, and optionally apply the initial inventory -void ResetLogic(std::shared_ptr& ctx, GetAccessibleLocationsStruct& gals, bool applyInventory = false){ - gals.timePassChildDay = true; - gals.timePassChildNight = true; - gals.timePassAdultDay = true; - gals.timePassAdultNight = true; - gals.haveTimeAccess = true; - gals.foundTempleOfTime = true; - gals.validatedStartingRegion = true; - gals.sphereZeroComplete = true; - if (applyInventory){ - ApplyStartingInventory(); - } - Regions::AccessReset(); - ctx->LocationReset(); -} - -//Generate the playthrough, so we want to add advancement items, unless we know to ignore them -void AddToPlaythrough(LocationAccess& locPair, GetAccessibleLocationsStruct& gals){ - auto ctx = Rando::Context::GetInstance(); - RandomizerCheck loc = locPair.GetLocation(); - Rando::ItemLocation* location = ctx->GetItemLocation(loc); - RandomizerGet locItem = location->GetPlacedRandomizerGet(); - //Item is an advancement item, figure out if it should be added to this sphere - if (!ctx->playthroughBeatable && location->GetPlacedItem().IsAdvancement()) { - ItemType type = location->GetPlacedItem().GetItemType(); - - //Decide whether to exclude this location - //This preprocessing is done to reduce the amount of searches performed in PareDownPlaythrough - //Want to exclude: - //1) Tokens after the last potentially useful one (the last one that gives an advancement item or last for token bridge) - //2) Buy items of the same type, after the first (So only see Buy Deku Nut of any amount once) - bool exclude = true; - //Exclude tokens after the last possibly useful one - if (type == ITEMTYPE_TOKEN && gals.gsCount < gals.maxGsCount) { - gals.gsCount++; - exclude = false; +void ResetLogic(std::shared_ptr& ctx, GetAccessibleLocationsStruct& gals, bool applyInventory = false) { + gals.timePassChildDay = true; + gals.timePassChildNight = true; + gals.timePassAdultDay = true; + gals.timePassAdultNight = true; + gals.haveTimeAccess = true; + gals.foundTempleOfTime = true; + gals.validatedStartingRegion = true; + gals.sphereZeroComplete = true; + if (applyInventory) { + ApplyStartingInventory(); } - //Handle buy items - //If ammo drops are off, don't do this step, since buyable ammo becomes logically important - // TODO: Reimplement Ammo Drops setting - else if (/*AmmoDrops.IsNot(AMMODROPS_NONE) &&*/ type == ITEMTYPE_SHOP) { - //Only check each buy item once - auto buyItem = location->GetPlacedItem().GetLogicVal(); - //Buy item not in list to ignore, add it to list and write to playthrough - if (std::find(gals.buyIgnores.begin(), gals.buyIgnores.end(), buyItem) == gals.buyIgnores.end()) { - exclude = false; - gals.buyIgnores.push_back(buyItem); - } - } - //Add all other advancement items - else if (type != ITEMTYPE_TOKEN && (/*AmmoDrops.Is(AMMODROPS_NONE) ||*/ type != ITEMTYPE_SHOP)) { - exclude = false; - } - //Has not been excluded, add to playthrough - if (!exclude) { - gals.itemSphere.push_back(loc); - } - } - //Triforce has been found, seed is beatable, nothing else in this or future spheres matters - else if (location->GetPlacedRandomizerGet() == RG_TRIFORCE) { - gals.itemSphere.clear(); - gals.itemSphere.push_back(loc); - ctx->playthroughBeatable = true; - } + Regions::AccessReset(); + ctx->LocationReset(); } -void ApplyOrStoreItem(Rando::ItemLocation* loc, GetAccessibleLocationsStruct& gals, bool addToPlaythrough){ - if (addToPlaythrough){ - gals.newItemLocations.push_back(loc); - } else { - loc->ApplyPlacedItemEffect(); - } - gals.logicUpdated = true; +// Generate the playthrough, so we want to add advancement items, unless we know to ignore them +void AddToPlaythrough(LocationAccess& locPair, GetAccessibleLocationsStruct& gals) { + auto ctx = Rando::Context::GetInstance(); + RandomizerCheck loc = locPair.GetLocation(); + Rando::ItemLocation* location = ctx->GetItemLocation(loc); + RandomizerGet locItem = location->GetPlacedRandomizerGet(); + // Item is an advancement item, figure out if it should be added to this sphere + if (!ctx->playthroughBeatable && location->GetPlacedItem().IsAdvancement()) { + ItemType type = location->GetPlacedItem().GetItemType(); + + // Decide whether to exclude this location + // This preprocessing is done to reduce the amount of searches performed in PareDownPlaythrough + // Want to exclude: + // 1) Tokens after the last potentially useful one (the last one that gives an advancement item or last for + // token bridge) 2) Buy items of the same type, after the first (So only see Buy Deku Nut of any amount once) + bool exclude = true; + // Exclude tokens after the last possibly useful one + if (type == ITEMTYPE_TOKEN && gals.gsCount < gals.maxGsCount) { + gals.gsCount++; + exclude = false; + } + // Handle buy items + // If ammo drops are off, don't do this step, since buyable ammo becomes logically important + // TODO: Reimplement Ammo Drops setting + else if (/*AmmoDrops.IsNot(AMMODROPS_NONE) &&*/ type == ITEMTYPE_SHOP) { + // Only check each buy item once + auto buyItem = location->GetPlacedItem().GetLogicVal(); + // Buy item not in list to ignore, add it to list and write to playthrough + if (std::find(gals.buyIgnores.begin(), gals.buyIgnores.end(), buyItem) == gals.buyIgnores.end()) { + exclude = false; + gals.buyIgnores.push_back(buyItem); + } + } + // Add all other advancement items + else if (type != ITEMTYPE_TOKEN && (/*AmmoDrops.Is(AMMODROPS_NONE) ||*/ type != ITEMTYPE_SHOP)) { + exclude = false; + } + // Has not been excluded, add to playthrough + if (!exclude) { + gals.itemSphere.push_back(loc); + } + } + // Triforce has been found, seed is beatable, nothing else in this or future spheres matters + else if (location->GetPlacedRandomizerGet() == RG_TRIFORCE) { + gals.itemSphere.clear(); + gals.itemSphere.push_back(loc); + ctx->playthroughBeatable = true; + } +} + +void ApplyOrStoreItem(Rando::ItemLocation* loc, GetAccessibleLocationsStruct& gals, bool addToPlaythrough) { + if (addToPlaythrough) { + gals.newItemLocations.push_back(loc); + } else { + loc->ApplyPlacedItemEffect(); + } + gals.logicUpdated = true; } // Adds the contents of a location to the current progression and optionally playthrough -bool AddCheckToLogic(LocationAccess& locPair, GetAccessibleLocationsStruct& gals, RandomizerGet ignore, bool stopOnBeatable, Region* parentRegion, bool addToPlaythrough=false){ - auto ctx = Rando::Context::GetInstance(); - StartPerformanceTimer(PT_LOCATION_LOGIC); - RandomizerCheck loc = locPair.GetLocation(); - Rando::ItemLocation* location = ctx->GetItemLocation(loc); - RandomizerGet locItem = location->GetPlacedRandomizerGet(); +bool AddCheckToLogic(LocationAccess& locPair, GetAccessibleLocationsStruct& gals, RandomizerGet ignore, + bool stopOnBeatable, Region* parentRegion, bool addToPlaythrough = false) { + auto ctx = Rando::Context::GetInstance(); + StartPerformanceTimer(PT_LOCATION_LOGIC); + RandomizerCheck loc = locPair.GetLocation(); + Rando::ItemLocation* location = ctx->GetItemLocation(loc); + RandomizerGet locItem = location->GetPlacedRandomizerGet(); - if (!location->IsAddedToPool() && locPair.ConditionsMet(parentRegion, gals.calculatingAvailableChecks)) { - if (gals.calculatingAvailableChecks) { - gals.accessibleLocations.push_back(loc); - StopPerformanceTimer(PT_LOCATION_LOGIC); - return false; - } + if (!location->IsAddedToPool() && locPair.ConditionsMet(parentRegion, gals.calculatingAvailableChecks)) { + if (gals.calculatingAvailableChecks) { + gals.accessibleLocations.push_back(loc); + StopPerformanceTimer(PT_LOCATION_LOGIC); + return false; + } - location->AddToPool(); + location->AddToPool(); - if (locItem == RG_NONE) { - gals.accessibleLocations.push_back(loc); //Empty location, consider for placement - } else { - //If ignore has a value, we want to check if the item location should be considered or not - //This is necessary due to the below preprocessing for playthrough generation - if (ignore != RG_NONE) { - ItemType type = location->GetPlacedItem().GetItemType(); - //If we want to ignore tokens, only add if not a token - if (ignore == RG_GOLD_SKULLTULA_TOKEN && type != ITEMTYPE_TOKEN) { - ApplyOrStoreItem(location, gals, addToPlaythrough); + if (locItem == RG_NONE) { + gals.accessibleLocations.push_back(loc); // Empty location, consider for placement + } else { + // If ignore has a value, we want to check if the item location should be considered or not + // This is necessary due to the below preprocessing for playthrough generation + if (ignore != RG_NONE) { + ItemType type = location->GetPlacedItem().GetItemType(); + // If we want to ignore tokens, only add if not a token + if (ignore == RG_GOLD_SKULLTULA_TOKEN && type != ITEMTYPE_TOKEN) { + ApplyOrStoreItem(location, gals, addToPlaythrough); + } + // If we want to ignore bombchus, only add if bombchu is not in the name + else if (IsBombchus(ignore) && IsBombchus(locItem, true)) { + ApplyOrStoreItem(location, gals, addToPlaythrough); + } + // We want to ignore a specific Buy item. Buy items with different RandomizerGets are recognised by a + // shared GetLogicVal + else if (ignore != RG_GOLD_SKULLTULA_TOKEN && IsBombchus(ignore)) { + if ((type == ITEMTYPE_SHOP && Rando::StaticData::GetItemTable()[ignore].GetLogicVal() != + location->GetPlacedItem().GetLogicVal()) || + type != ITEMTYPE_SHOP) { + ApplyOrStoreItem(location, gals, addToPlaythrough); + } + } + } + // If it doesn't, we can just add the location + else { + ApplyOrStoreItem(location, gals, + addToPlaythrough); // Add item to cache to be considered in logic next iteration + } } - //If we want to ignore bombchus, only add if bombchu is not in the name - else if (IsBombchus(ignore) && IsBombchus(locItem, true)) { - ApplyOrStoreItem(location, gals, addToPlaythrough); + if (addToPlaythrough) { + AddToPlaythrough(locPair, gals); } - //We want to ignore a specific Buy item. Buy items with different RandomizerGets are recognised by a shared GetLogicVal - else if (ignore != RG_GOLD_SKULLTULA_TOKEN && IsBombchus(ignore)) { - if ((type == ITEMTYPE_SHOP && Rando::StaticData::GetItemTable()[ignore].GetLogicVal() != location->GetPlacedItem().GetLogicVal()) || type != ITEMTYPE_SHOP) { - ApplyOrStoreItem(location, gals, addToPlaythrough); - } + // All we care about is if the game is beatable, used to pare down playthrough + if (location->GetPlacedRandomizerGet() == RG_TRIFORCE && stopOnBeatable) { + StopPerformanceTimer(PT_LOCATION_LOGIC); + return true; // Return early for efficiency } - } - //If it doesn't, we can just add the location - else { - ApplyOrStoreItem(location, gals, addToPlaythrough); //Add item to cache to be considered in logic next iteration - } } - if (addToPlaythrough){ - AddToPlaythrough(locPair, gals); - } - //All we care about is if the game is beatable, used to pare down playthrough - if (location->GetPlacedRandomizerGet() == RG_TRIFORCE && stopOnBeatable) { - StopPerformanceTimer(PT_LOCATION_LOGIC); - return true; //Return early for efficiency - } - } - StopPerformanceTimer(PT_LOCATION_LOGIC); - return false; + StopPerformanceTimer(PT_LOCATION_LOGIC); + return false; } -void ProcessRegion(Region* region, GetAccessibleLocationsStruct& gals, RandomizerGet ignore, - bool stopOnBeatable, bool addToPlaythrough){ - - if (gals.haveTimeAccess) { - region->ApplyTimePass(); - } else { - // If we're checking for TimePass access do that for each region as it's being updated. - // TimePass Access is satisfied when every AgeTime can reach a region with TimePass - // without the aid of TimePass. During this mode, TimePass won't update ToD access - // in any region. - //RANDOTODO can probably be removed after a ToD rework that accounts for having Dampe time access - if (region->timePass) { - if (region->childDay) { - gals.timePassChildDay = true; - } - if (region->childNight) { - gals.timePassChildNight = true; - } - if (region->adultDay) { - gals.timePassAdultDay = true; - } - if (region->adultNight) { - gals.timePassAdultNight = true; - } - } - // Condition for validating that all startring AgeTimes have timepass access - if (gals.timePassChildDay && gals.timePassChildNight && - gals.timePassAdultDay && gals.timePassAdultNight) { - gals.haveTimeAccess = true; - region->ApplyTimePass(); - } - } +void ProcessRegion(Region* region, GetAccessibleLocationsStruct& gals, RandomizerGet ignore, bool stopOnBeatable, + bool addToPlaythrough) { - if (region->UpdateEvents()){ - gals.logicUpdated = true; - //if we are working in spheres, reset the sphere on an event being enabled to avoid sphere skipping - if (addToPlaythrough){ - gals.resetSphere = true; + if (gals.haveTimeAccess) { + region->ApplyTimePass(); + } else { + // If we're checking for TimePass access do that for each region as it's being updated. + // TimePass Access is satisfied when every AgeTime can reach a region with TimePass + // without the aid of TimePass. During this mode, TimePass won't update ToD access + // in any region. + // RANDOTODO can probably be removed after a ToD rework that accounts for having Dampe time access + if (region->timePass) { + if (region->childDay) { + gals.timePassChildDay = true; + } + if (region->childNight) { + gals.timePassChildNight = true; + } + if (region->adultDay) { + gals.timePassAdultDay = true; + } + if (region->adultNight) { + gals.timePassAdultNight = true; + } + } + // Condition for validating that all startring AgeTimes have timepass access + if (gals.timePassChildDay && gals.timePassChildNight && gals.timePassAdultDay && gals.timePassAdultNight) { + gals.haveTimeAccess = true; + region->ApplyTimePass(); + } } - } - - ProcessExits(region, gals, ignore, stopOnBeatable, addToPlaythrough); - - PropagateTimeTravel(gals, ignore, stopOnBeatable, addToPlaythrough); - for (size_t k = 0; k < region->locations.size(); k++) { - if(AddCheckToLogic(region->locations[k], gals, ignore, stopOnBeatable, region, addToPlaythrough)){ - Rando::Context::GetInstance()->playthroughBeatable = true; - return; + + if (region->UpdateEvents()) { + gals.logicUpdated = true; + // if we are working in spheres, reset the sphere on an event being enabled to avoid sphere skipping + if (addToPlaythrough) { + gals.resetSphere = true; + } + } + + ProcessExits(region, gals, ignore, stopOnBeatable, addToPlaythrough); + + PropagateTimeTravel(gals, ignore, stopOnBeatable, addToPlaythrough); + for (size_t k = 0; k < region->locations.size(); k++) { + if (AddCheckToLogic(region->locations[k], gals, ignore, stopOnBeatable, region, addToPlaythrough)) { + Rando::Context::GetInstance()->playthroughBeatable = true; + return; + } } - } } // Return any of the targetLocations that are accessible in logic -std::vector ReachabilitySearch(const std::vector& targetLocations, RandomizerGet ignore /* = RG_NONE*/, bool calculatingAvailableChecks /* = false */) { - auto ctx = Rando::Context::GetInstance(); - GetAccessibleLocationsStruct gals(0); - gals.calculatingAvailableChecks = calculatingAvailableChecks; - ResetLogic(ctx, gals, !calculatingAvailableChecks); - do { - gals.InitLoop(); - for (size_t i = 0; i < gals.regionPool.size(); i++) { - ProcessRegion(RegionTable(gals.regionPool[i]), gals, ignore); - } - } while (gals.logicUpdated); - erase_if(gals.accessibleLocations, [&targetLocations, ctx, calculatingAvailableChecks](RandomizerCheck loc) { - if (ctx->GetItemLocation(loc)->GetPlacedRandomizerGet() != RG_NONE && !calculatingAvailableChecks) { - return false; - } - for (RandomizerCheck allowedLocation : targetLocations) { - if (loc == allowedLocation) { - return false; - } - } - return true; - }); - return gals.accessibleLocations; +std::vector ReachabilitySearch(const std::vector& targetLocations, + RandomizerGet ignore /* = RG_NONE*/, + bool calculatingAvailableChecks /* = false */) { + auto ctx = Rando::Context::GetInstance(); + GetAccessibleLocationsStruct gals(0); + gals.calculatingAvailableChecks = calculatingAvailableChecks; + ResetLogic(ctx, gals, !calculatingAvailableChecks); + do { + gals.InitLoop(); + for (size_t i = 0; i < gals.regionPool.size(); i++) { + ProcessRegion(RegionTable(gals.regionPool[i]), gals, ignore); + } + } while (gals.logicUpdated); + erase_if(gals.accessibleLocations, [&targetLocations, ctx, calculatingAvailableChecks](RandomizerCheck loc) { + if (ctx->GetItemLocation(loc)->GetPlacedRandomizerGet() != RG_NONE && !calculatingAvailableChecks) { + return false; + } + for (RandomizerCheck allowedLocation : targetLocations) { + if (loc == allowedLocation) { + return false; + } + } + return true; + }); + return gals.accessibleLocations; } // Create the playthrough for the seed void GeneratePlaythrough() { - auto ctx = Rando::Context::GetInstance(); - ctx->playthroughBeatable = false; - logic->Reset(); - GetAccessibleLocationsStruct gals(GetMaxGSCount()); - ResetLogic(ctx, gals, true); - do { - gals.InitLoop(); - for (size_t i = 0; i < gals.regionPool.size(); i++) { - ProcessRegion(RegionTable(gals.regionPool[i]), gals, RG_NONE, false, true); - if (gals.resetSphere){ - gals.resetSphere = false; - i = -1; - } - } - if (gals.itemSphere.size() > 0) { - ctx->playthroughLocations.push_back(gals.itemSphere); - } - if (gals.entranceSphere.size() > 0 && !ctx->GetEntranceShuffler()->HasNoRandomEntrances()) { - ctx->GetEntranceShuffler()->playthroughEntrances.push_back(gals.entranceSphere); - } - } while (gals.logicUpdated); + auto ctx = Rando::Context::GetInstance(); + ctx->playthroughBeatable = false; + logic->Reset(); + GetAccessibleLocationsStruct gals(GetMaxGSCount()); + ResetLogic(ctx, gals, true); + do { + gals.InitLoop(); + for (size_t i = 0; i < gals.regionPool.size(); i++) { + ProcessRegion(RegionTable(gals.regionPool[i]), gals, RG_NONE, false, true); + if (gals.resetSphere) { + gals.resetSphere = false; + i = -1; + } + } + if (gals.itemSphere.size() > 0) { + ctx->playthroughLocations.push_back(gals.itemSphere); + } + if (gals.entranceSphere.size() > 0 && !ctx->GetEntranceShuffler()->HasNoRandomEntrances()) { + ctx->GetEntranceShuffler()->playthroughEntrances.push_back(gals.entranceSphere); + } + } while (gals.logicUpdated); } // return if the seed is currently beatable or not bool CheckBeatable(RandomizerGet ignore /* = RG_NONE*/) { - auto ctx = Rando::Context::GetInstance(); - GetAccessibleLocationsStruct gals(0); - ResetLogic(ctx, gals, true); - do { - gals.InitLoop(); - for (size_t i = 0; i < gals.regionPool.size(); i++) { - ProcessRegion(RegionTable(gals.regionPool[i]), gals, ignore, true); - if (ctx->playthroughBeatable == true){ - return true; - } - } - } while (gals.logicUpdated); - return false; + auto ctx = Rando::Context::GetInstance(); + GetAccessibleLocationsStruct gals(0); + ResetLogic(ctx, gals, true); + do { + gals.InitLoop(); + for (size_t i = 0; i < gals.regionPool.size(); i++) { + ProcessRegion(RegionTable(gals.regionPool[i]), gals, ignore, true); + if (ctx->playthroughBeatable == true) { + return true; + } + } + } while (gals.logicUpdated); + return false; } // Check if the currently randomised set of entrances is a valid game map. void ValidateEntrances(bool checkPoeCollectorAccess, bool checkOtherEntranceAccess) { - auto ctx = Rando::Context::GetInstance(); - GetAccessibleLocationsStruct gals(0); - ResetLogic(ctx, gals, !checkOtherEntranceAccess); + auto ctx = Rando::Context::GetInstance(); + GetAccessibleLocationsStruct gals(0); + ResetLogic(ctx, gals, !checkOtherEntranceAccess); - ctx->allLocationsReachable = false; - if (checkPoeCollectorAccess){ - logic->AreCheckingBigPoes = true; - } - - if (checkOtherEntranceAccess){ - gals.foundTempleOfTime = false; - gals.validatedStartingRegion = false; - //Variables for Time Pass access - gals.timePassChildDay = false; - gals.timePassChildNight = false; - gals.timePassAdultDay = false; - gals.timePassAdultNight = false; - gals.haveTimeAccess = false; - gals.sphereZeroComplete = false; - RegionTable(RR_ROOT)->childNight = true; - RegionTable(RR_ROOT)->adultNight = true; - RegionTable(RR_ROOT)->childDay = true; - RegionTable(RR_ROOT)->adultDay = true; - } else if (checkPoeCollectorAccess){ - //If we are not shuffling the guard house, add the key so we can properly check for poe merchant access - if (!ctx->GetOption(RSK_SHUFFLE_INTERIOR_ENTRANCES).Is(RO_INTERIOR_ENTRANCE_SHUFFLE_ALL)){ - Rando::StaticData::RetrieveItem(RG_GUARD_HOUSE_KEY).ApplyEffect(); + ctx->allLocationsReachable = false; + if (checkPoeCollectorAccess) { + logic->AreCheckingBigPoes = true; } - } else { - ApplyAllAdvancmentItems(); - } - do { - gals.InitLoop(); - for (size_t i = 0; i < gals.regionPool.size(); i++) { - ProcessRegion(RegionTable(gals.regionPool[i]), gals); - } - } while (gals.logicUpdated); - if (gals.sphereZeroComplete) { - ctx->allLocationsReachable = true; - //RANDOTODO a size check here before getting the exact fails would be a minor optimization - //and a full list of location failures would be useful for logging when it does fail - for (const RandomizerCheck loc : ctx->allLocations) { - if (!ctx->GetItemLocation(loc)->IsAddedToPool()) { - ctx->allLocationsReachable = false; - auto message = "Location " + - Rando::StaticData::GetLocation(ctx->GetItemLocation(loc)->GetRandomizerCheck())->GetName() + - " not reachable\n"; - LUSLOG_DEBUG("%s", message.c_str()); - #ifndef ENABLE_DEBUG - break; - #endif - } - } - } -} - -void LookForExternalArea(Region* currentRegion, std::set &alreadyChecked, std::set &areas, bool LowPriorityMode=false){ - for (const auto& entrance : currentRegion->entrances) { - //if the region is arealess and hasn't already been checked, recursivly check what connects to it - //if this entrance does not pass areas, only process it if we are in low priority mode - if ((LowPriorityMode || entrance->DoesSpreadAreas()) && !alreadyChecked.contains(entrance->GetParentRegion())){ - std::set otherAreas = entrance->GetParentRegion()->GetAllAreas(); - if (otherAreas.size() == 0) { - alreadyChecked.insert(entrance->GetParentRegion()); - LookForExternalArea(entrance->GetParentRegion(), alreadyChecked, areas, LowPriorityMode); - //If we find a valid area we should add it. - //If it's Links Pocket or RA_NONE, do not propagate those, they are not real areas. - //This check is likely to fail if a region somehow is both in Link's Pocket and elsewhere, but this should never happen - } else if (*otherAreas.begin() > RA_LINKS_POCKET){ - areas.merge(otherAreas); - } - } - } -} - -void SetAreas(){ - auto ctx = Rando::Context::GetInstance(); -//RANDOTODO give entrances an enum like RandomizerCheck, the give them all areas here, -//then use those areas to not need to recursivly find ItemLocation areas when an identifying entrance's area - for (int regionType = 0; regionType < RR_MARKER_AREAS_END; regionType++) { - Region* region = &areaTable[regionType]; - std::set areas = region->GetAllAreas(); - std::set regionsToSet = {region}; - if (areas.empty()) { - LookForExternalArea(region, regionsToSet, areas); - //If we found nothing, try again in low priority mode to try every entrance - if (areas.empty()) { - LookForExternalArea(region, regionsToSet, areas, true); - //If we still found nothing, we're disconnected, use RA_NONE to represent that - if (areas.empty()){ - areas.insert(RA_NONE); + if (checkOtherEntranceAccess) { + gals.foundTempleOfTime = false; + gals.validatedStartingRegion = false; + // Variables for Time Pass access + gals.timePassChildDay = false; + gals.timePassChildNight = false; + gals.timePassAdultDay = false; + gals.timePassAdultNight = false; + gals.haveTimeAccess = false; + gals.sphereZeroComplete = false; + RegionTable(RR_ROOT)->childNight = true; + RegionTable(RR_ROOT)->adultNight = true; + RegionTable(RR_ROOT)->childDay = true; + RegionTable(RR_ROOT)->adultDay = true; + } else if (checkPoeCollectorAccess) { + // If we are not shuffling the guard house, add the key so we can properly check for poe merchant access + if (!ctx->GetOption(RSK_SHUFFLE_INTERIOR_ENTRANCES).Is(RO_INTERIOR_ENTRANCE_SHUFFLE_ALL)) { + Rando::StaticData::RetrieveItem(RG_GUARD_HOUSE_KEY).ApplyEffect(); } - } + } else { + ApplyAllAdvancmentItems(); } - for (auto regionToSet : regionsToSet) { - regionToSet->ReplaceAreas(areas); - for (auto& loc : regionToSet->locations){ - ctx->GetItemLocation(loc.GetLocation())->MergeAreas(areas); - } + + do { + gals.InitLoop(); + for (size_t i = 0; i < gals.regionPool.size(); i++) { + ProcessRegion(RegionTable(gals.regionPool[i]), gals); + } + } while (gals.logicUpdated); + if (gals.sphereZeroComplete) { + ctx->allLocationsReachable = true; + // RANDOTODO a size check here before getting the exact fails would be a minor optimization + // and a full list of location failures would be useful for logging when it does fail + for (const RandomizerCheck loc : ctx->allLocations) { + if (!ctx->GetItemLocation(loc)->IsAddedToPool()) { + ctx->allLocationsReachable = false; + auto message = + "Location " + + Rando::StaticData::GetLocation(ctx->GetItemLocation(loc)->GetRandomizerCheck())->GetName() + + " not reachable\n"; + LUSLOG_DEBUG("%s", message.c_str()); +#ifndef ENABLE_DEBUG + break; +#endif + } + } } - } } -//Remove unnecessary items from playthrough by removing their location, and checking if game is still beatable -//To reduce searches, some preprocessing is done in playthrough generation to avoid adding obviously unnecessary items +void LookForExternalArea(Region* currentRegion, std::set& alreadyChecked, std::set& areas, + bool LowPriorityMode = false) { + for (const auto& entrance : currentRegion->entrances) { + // if the region is arealess and hasn't already been checked, recursivly check what connects to it + // if this entrance does not pass areas, only process it if we are in low priority mode + if ((LowPriorityMode || entrance->DoesSpreadAreas()) && !alreadyChecked.contains(entrance->GetParentRegion())) { + std::set otherAreas = entrance->GetParentRegion()->GetAllAreas(); + if (otherAreas.size() == 0) { + alreadyChecked.insert(entrance->GetParentRegion()); + LookForExternalArea(entrance->GetParentRegion(), alreadyChecked, areas, LowPriorityMode); + // If we find a valid area we should add it. + // If it's Links Pocket or RA_NONE, do not propagate those, they are not real areas. + // This check is likely to fail if a region somehow is both in Link's Pocket and elsewhere, but this + // should never happen + } else if (*otherAreas.begin() > RA_LINKS_POCKET) { + areas.merge(otherAreas); + } + } + } +} + +void SetAreas() { + auto ctx = Rando::Context::GetInstance(); + // RANDOTODO give entrances an enum like RandomizerCheck, the give them all areas here, + // then use those areas to not need to recursivly find ItemLocation areas when an identifying entrance's area + for (int regionType = 0; regionType < RR_MARKER_AREAS_END; regionType++) { + Region* region = &areaTable[regionType]; + std::set areas = region->GetAllAreas(); + std::set regionsToSet = { region }; + if (areas.empty()) { + LookForExternalArea(region, regionsToSet, areas); + // If we found nothing, try again in low priority mode to try every entrance + if (areas.empty()) { + LookForExternalArea(region, regionsToSet, areas, true); + // If we still found nothing, we're disconnected, use RA_NONE to represent that + if (areas.empty()) { + areas.insert(RA_NONE); + } + } + } + for (auto regionToSet : regionsToSet) { + regionToSet->ReplaceAreas(areas); + for (auto& loc : regionToSet->locations) { + ctx->GetItemLocation(loc.GetLocation())->MergeAreas(areas); + } + } + } +} + +// Remove unnecessary items from playthrough by removing their location, and checking if game is still beatable +// To reduce searches, some preprocessing is done in playthrough generation to avoid adding obviously unnecessary items static void PareDownPlaythrough() { - auto ctx = Rando::Context::GetInstance(); - std::vector toAddBackItem; - //Start at sphere before Ganon's and count down - for (int i = ctx->playthroughLocations.size() - 2; i >= 0; i--) { - //Check each item location in sphere - std::vector erasableIndices; - std::vector sphere = ctx->playthroughLocations.at(i); - for (int j = sphere.size() - 1; j >= 0; j--) { - RandomizerCheck loc = sphere.at(j); - RandomizerGet locGet = ctx->GetItemLocation(loc)->GetPlacedRandomizerGet(); //Copy out item + auto ctx = Rando::Context::GetInstance(); + std::vector toAddBackItem; + // Start at sphere before Ganon's and count down + for (int i = ctx->playthroughLocations.size() - 2; i >= 0; i--) { + // Check each item location in sphere + std::vector erasableIndices; + std::vector sphere = ctx->playthroughLocations.at(i); + for (int j = sphere.size() - 1; j >= 0; j--) { + RandomizerCheck loc = sphere.at(j); + RandomizerGet locGet = ctx->GetItemLocation(loc)->GetPlacedRandomizerGet(); // Copy out item - RandomizerGet ignore = RG_NONE; - if (locGet == RG_GOLD_SKULLTULA_TOKEN || IsBombchus(locGet, true) - || Rando::StaticData::RetrieveItem(locGet).GetItemType() == ITEMTYPE_SHOP) { - ignore = locGet; - } + RandomizerGet ignore = RG_NONE; + if (locGet == RG_GOLD_SKULLTULA_TOKEN || IsBombchus(locGet, true) || + Rando::StaticData::RetrieveItem(locGet).GetItemType() == ITEMTYPE_SHOP) { + ignore = locGet; + } - //Playthrough is still beatable without this item, therefore it can be removed from playthrough section. - if (IsBeatableWithout(loc, false, ignore)) { - ctx->playthroughLocations[i].erase(ctx->playthroughLocations[i].begin() + j); - ctx->GetItemLocation(loc)->SetDelayedItem(locGet); //Game is still beatable, don't add back until later - toAddBackItem.push_back(loc); - } - else { - ctx->GetItemLocation(loc)->SetPlacedItem(locGet); //Immediately put item back so game is beatable again - } + // Playthrough is still beatable without this item, therefore it can be removed from playthrough section. + if (IsBeatableWithout(loc, false, ignore)) { + ctx->playthroughLocations[i].erase(ctx->playthroughLocations[i].begin() + j); + ctx->GetItemLocation(loc)->SetDelayedItem(locGet); // Game is still beatable, don't add back until later + toAddBackItem.push_back(loc); + } else { + ctx->GetItemLocation(loc)->SetPlacedItem(locGet); // Immediately put item back so game is beatable again + } + } } - } - //Some spheres may now be empty, remove these - for (int i = ctx->playthroughLocations.size() - 2; i >= 0; i--) { - if (ctx->playthroughLocations.at(i).size() == 0) { - ctx->playthroughLocations.erase(ctx->playthroughLocations.begin() + i); + // Some spheres may now be empty, remove these + for (int i = ctx->playthroughLocations.size() - 2; i >= 0; i--) { + if (ctx->playthroughLocations.at(i).size() == 0) { + ctx->playthroughLocations.erase(ctx->playthroughLocations.begin() + i); + } } - } - //Now we can add back items which were removed previously - for (RandomizerCheck loc : toAddBackItem) { - ctx->GetItemLocation(loc)->SaveDelayedItem(); - } + // Now we can add back items which were removed previously + for (RandomizerCheck loc : toAddBackItem) { + ctx->GetItemLocation(loc)->SaveDelayedItem(); + } } -//Very similar to PareDownPlaythrough except it sets WotH candidacy of Way of the Hero items -//Way of the Hero items are more specific than playthrough items in that they are items which *must* -// be obtained to logically be able to complete the seed, rather than playthrough items which -// are just possible items you *can* collect to complete the seed. +// Very similar to PareDownPlaythrough except it sets WotH candidacy of Way of the Hero items +// Way of the Hero items are more specific than playthrough items in that they are items which *must* +// be obtained to logically be able to complete the seed, rather than playthrough items which +// are just possible items you *can* collect to complete the seed. static void CalculateWotH() { - auto ctx = Rando::Context::GetInstance(); - //size - 1 so Triforce is not counted - for (size_t i = 0; i < ctx->playthroughLocations.size() - 1; i++) { - for (size_t j = 0; j < ctx->playthroughLocations[i].size(); j++) { - //If removing this item and no other item caused the game to become unbeatable, then it is strictly necessary, - //so add it unless it is in Links Pocket or an isolated place. - auto itemLoc = ctx->GetItemLocation(ctx->playthroughLocations[i][j]); - if (itemLoc->IsHintable() && itemLoc->GetFirstArea() > RA_LINKS_POCKET && - !(IsBeatableWithout(ctx->playthroughLocations[i][j], true))) { - itemLoc->SetWothCandidate(); - } + auto ctx = Rando::Context::GetInstance(); + // size - 1 so Triforce is not counted + for (size_t i = 0; i < ctx->playthroughLocations.size() - 1; i++) { + for (size_t j = 0; j < ctx->playthroughLocations[i].size(); j++) { + // If removing this item and no other item caused the game to become unbeatable, then it is strictly + // necessary, so add it unless it is in Links Pocket or an isolated place. + auto itemLoc = ctx->GetItemLocation(ctx->playthroughLocations[i][j]); + if (itemLoc->IsHintable() && itemLoc->GetFirstArea() > RA_LINKS_POCKET && + !(IsBeatableWithout(ctx->playthroughLocations[i][j], true))) { + itemLoc->SetWothCandidate(); + } + } } - } - ctx->playthroughBeatable = true; - logic->Reset(); - ReachabilitySearch(ctx->allLocations); + ctx->playthroughBeatable = true; + logic->Reset(); + ReachabilitySearch(ctx->allLocations); } -static bool FindIfBarren(Rando::ItemLocation* itemLoc, std::array NotBarren){ - std::set locAreas = itemLoc->GetAreas(); - for (auto locArea: locAreas){ - if (NotBarren[locArea]){ - return false; - } - } - return true; -} - -//Calculate barren locations and assign Barren Candidacy to all locations inside those areas -static void CalculateBarren() { - auto ctx = Rando::Context::GetInstance(); - std::array NotBarren = {}; //I would invert this but the "initialise all as true" syntax wasn't working - //Isolated Areas and Link's Pocket are never Hinted Barren - NotBarren[RA_NONE] = true; - NotBarren[RA_LINKS_POCKET] = true; - - for (RandomizerCheck loc : ctx->allLocations) { - Rando::ItemLocation* itemLoc = ctx->GetItemLocation(loc); +static bool FindIfBarren(Rando::ItemLocation* itemLoc, std::array NotBarren) { std::set locAreas = itemLoc->GetAreas(); - for (auto locArea: locAreas){ - // If a location has a major item or is a way of the hero location, it is not barren - if (NotBarren[locArea] == false && (itemLoc->GetPlacedItem().IsMajorItem() || itemLoc->IsWothCandidate())) { - NotBarren[locArea] = true; - } + for (auto locArea : locAreas) { + if (NotBarren[locArea]) { + return false; + } } - } - - for (RandomizerCheck loc : ctx->allLocations) { - Rando::ItemLocation* itemLoc = ctx->GetItemLocation(loc); - if (FindIfBarren(itemLoc, NotBarren)){ - itemLoc->SetBarrenCandidate(); - } - } + return true; } -//Will place things completely randomly, no logic checks are performed -static void FastFill(std::vector items, std::vector locations, bool endOnItemsEmpty = false) { - auto ctx = Rando::Context::GetInstance(); - //Loop until locations are empty, or also end if items are empty and the parameters specify to end then - while (!locations.empty() && (!endOnItemsEmpty || !items.empty())) { - if (items.empty() && !endOnItemsEmpty) { - items.push_back(GetJunkItem()); +// Calculate barren locations and assign Barren Candidacy to all locations inside those areas +static void CalculateBarren() { + auto ctx = Rando::Context::GetInstance(); + std::array + NotBarren = {}; // I would invert this but the "initialise all as true" syntax wasn't working + // Isolated Areas and Link's Pocket are never Hinted Barren + NotBarren[RA_NONE] = true; + NotBarren[RA_LINKS_POCKET] = true; + + for (RandomizerCheck loc : ctx->allLocations) { + Rando::ItemLocation* itemLoc = ctx->GetItemLocation(loc); + std::set locAreas = itemLoc->GetAreas(); + for (auto locArea : locAreas) { + // If a location has a major item or is a way of the hero location, it is not barren + if (NotBarren[locArea] == false && (itemLoc->GetPlacedItem().IsMajorItem() || itemLoc->IsWothCandidate())) { + NotBarren[locArea] = true; + } + } } - RandomizerCheck loc = RandomElement(locations, true); - ctx->GetItemLocation(loc)->SetAsHintable(); - ctx->PlaceItemInLocation(loc, RandomElement(items, true)); - } + for (RandomizerCheck loc : ctx->allLocations) { + Rando::ItemLocation* itemLoc = ctx->GetItemLocation(loc); + if (FindIfBarren(itemLoc, NotBarren)) { + itemLoc->SetBarrenCandidate(); + } + } +} + +// Will place things completely randomly, no logic checks are performed +static void FastFill(std::vector items, std::vector locations, + bool endOnItemsEmpty = false) { + auto ctx = Rando::Context::GetInstance(); + // Loop until locations are empty, or also end if items are empty and the parameters specify to end then + while (!locations.empty() && (!endOnItemsEmpty || !items.empty())) { + if (items.empty() && !endOnItemsEmpty) { + items.push_back(GetJunkItem()); + } + + RandomizerCheck loc = RandomElement(locations, true); + ctx->GetItemLocation(loc)->SetAsHintable(); + ctx->PlaceItemInLocation(loc, RandomElement(items, true)); + } } /* @@ -878,7 +906,7 @@ static void AssumedFill(const std::vector& items, const std::vect // reset any locations that got an item for (RandomizerCheck loc : attemptedLocations) { ctx->GetItemLocation(loc)->SetPlacedItem(RG_NONE); - //itemsPlaced--; + // itemsPlaced--; } attemptedLocations.clear(); @@ -906,7 +934,7 @@ static void AssumedFill(const std::vector& items, const std::vect CheckBeatable(); if (ctx->playthroughBeatable) { SPDLOG_DEBUG("Game beatable, now placing items randomly. " + std::to_string(itemsToPlace.size()) + - " major items remaining.\n\n"); + " major items remaining.\n\n"); FastFill(itemsToPlace, GetEmptyLocations(allowedLocations), true); return; } @@ -915,121 +943,135 @@ static void AssumedFill(const std::vector& items, const std::vect } while (unsuccessfulPlacement); } -//This function will specifically randomize dungeon rewards for the End of Dungeons -//setting, or randomize one dungeon reward to Link's Pocket if that setting is on +// This function will specifically randomize dungeon rewards for the End of Dungeons +// setting, or randomize one dungeon reward to Link's Pocket if that setting is on static void RandomizeDungeonRewards() { - auto ctx = Rando::Context::GetInstance(); - //quest item bit mask of each stone/medallion for the savefile - // static constexpr std::array bitMaskTable = { - // 0x00040000, //Kokiri Emerald - // 0x00080000, //Goron Ruby - // 0x00100000, //Zora Sapphire - // 0x00000001, //Forest Medallion - // 0x00000002, //Fire Medallion - // 0x00000004, //Water Medallion - // 0x00000008, //Spirit Medallion - // 0x00000010, //Shadow Medallion - // 0x00000020, //Light Medallion - // }; - int baseOffset = Rando::StaticData::RetrieveItem(RG_KOKIRI_EMERALD).GetItemID(); + auto ctx = Rando::Context::GetInstance(); + // quest item bit mask of each stone/medallion for the savefile + // static constexpr std::array bitMaskTable = { + // 0x00040000, //Kokiri Emerald + // 0x00080000, //Goron Ruby + // 0x00100000, //Zora Sapphire + // 0x00000001, //Forest Medallion + // 0x00000002, //Fire Medallion + // 0x00000004, //Water Medallion + // 0x00000008, //Spirit Medallion + // 0x00000010, //Shadow Medallion + // 0x00000020, //Light Medallion + // }; + int baseOffset = Rando::StaticData::RetrieveItem(RG_KOKIRI_EMERALD).GetItemID(); - //End of Dungeons includes Link's Pocket - if (ctx->GetOption(RSK_SHUFFLE_DUNGEON_REWARDS).Is(RO_DUNGEON_REWARDS_END_OF_DUNGEON) || ctx->GetOption(RSK_SHUFFLE_DUNGEON_REWARDS).Is(RO_DUNGEON_REWARDS_VANILLA)) { - //get stones and medallions - std::vector rewards = FilterAndEraseFromPool(ItemPool, [](const auto i) {return Rando::StaticData::RetrieveItem(i).GetItemType() == ITEMTYPE_DUNGEONREWARD;}); + // End of Dungeons includes Link's Pocket + if (ctx->GetOption(RSK_SHUFFLE_DUNGEON_REWARDS).Is(RO_DUNGEON_REWARDS_END_OF_DUNGEON) || + ctx->GetOption(RSK_SHUFFLE_DUNGEON_REWARDS).Is(RO_DUNGEON_REWARDS_VANILLA)) { + // get stones and medallions + std::vector rewards = FilterAndEraseFromPool(ItemPool, [](const auto i) { + return Rando::StaticData::RetrieveItem(i).GetItemType() == ITEMTYPE_DUNGEONREWARD; + }); - if (ctx->GetOption(RSK_LOGIC_RULES).Is(RO_LOGIC_VANILLA) || ctx->GetOption(RSK_SHUFFLE_DUNGEON_REWARDS).Is(RO_DUNGEON_REWARDS_VANILLA)) { // Place dungeon rewards in vanilla locations - for (RandomizerCheck loc : Rando::StaticData::dungeonRewardLocations) { - ctx->GetItemLocation(loc)->PlaceVanillaItem(); - } - ctx->GetItemLocation(RC_GIFT_FROM_RAURU)->PlaceVanillaItem(); - } else { // Randomize dungeon rewards with assumed fill - std::vector rewardLocations(Rando::StaticData::dungeonRewardLocations); - // If there are less than 9 dungeon rewards, prioritize actual dungeons for placement - if (rewards.size() < 9) { - ctx->PlaceItemInLocation(RC_LINKS_POCKET, RG_GREEN_RUPEE); - } else { - rewardLocations.push_back(RC_LINKS_POCKET); - } - AssumedFill(rewards, rewardLocations); + if (ctx->GetOption(RSK_LOGIC_RULES).Is(RO_LOGIC_VANILLA) || + ctx->GetOption(RSK_SHUFFLE_DUNGEON_REWARDS) + .Is(RO_DUNGEON_REWARDS_VANILLA)) { // Place dungeon rewards in vanilla locations + for (RandomizerCheck loc : Rando::StaticData::dungeonRewardLocations) { + ctx->GetItemLocation(loc)->PlaceVanillaItem(); + } + ctx->GetItemLocation(RC_GIFT_FROM_RAURU)->PlaceVanillaItem(); + } else { // Randomize dungeon rewards with assumed fill + std::vector rewardLocations(Rando::StaticData::dungeonRewardLocations); + // If there are less than 9 dungeon rewards, prioritize actual dungeons for placement + if (rewards.size() < 9) { + ctx->PlaceItemInLocation(RC_LINKS_POCKET, RG_GREEN_RUPEE); + } else { + rewardLocations.push_back(RC_LINKS_POCKET); + } + AssumedFill(rewards, rewardLocations); + } + } else if (ctx->GetOption(RSK_LINKS_POCKET).Is(RO_LINKS_POCKET_DUNGEON_REWARD)) { + // get 1 stone/medallion + std::vector rewards = FilterFromPool(ItemPool, [](const auto i) { + return Rando::StaticData::RetrieveItem(i).GetItemType() == ITEMTYPE_DUNGEONREWARD; + }); + // If there are no remaining stones/medallions, then Link's pocket won't get one + if (rewards.empty()) { + ctx->PlaceItemInLocation(RC_LINKS_POCKET, RG_GREEN_RUPEE); + return; + } + RandomizerGet startingReward = RandomElement(rewards, true); + + // LinksPocketRewardBitMask = bitMaskTable[Rando::StaticData::RetrieveItem(startingReward).GetItemID() - + // baseOffset]; + ctx->PlaceItemInLocation(RC_LINKS_POCKET, startingReward); + // erase the stone/medallion from the Item Pool + FilterAndEraseFromPool(ItemPool, [startingReward](const RandomizerGet i) { return i == startingReward; }); } - } else if (ctx->GetOption(RSK_LINKS_POCKET).Is(RO_LINKS_POCKET_DUNGEON_REWARD)) { - //get 1 stone/medallion - std::vector rewards = FilterFromPool( - ItemPool, [](const auto i) { return Rando::StaticData::RetrieveItem(i).GetItemType() == ITEMTYPE_DUNGEONREWARD; }); - // If there are no remaining stones/medallions, then Link's pocket won't get one - if (rewards.empty()) { - ctx->PlaceItemInLocation(RC_LINKS_POCKET, RG_GREEN_RUPEE); - return; - } - RandomizerGet startingReward = RandomElement(rewards, true); - - //LinksPocketRewardBitMask = bitMaskTable[Rando::StaticData::RetrieveItem(startingReward).GetItemID() - baseOffset]; - ctx->PlaceItemInLocation(RC_LINKS_POCKET, startingReward); - //erase the stone/medallion from the Item Pool - FilterAndEraseFromPool(ItemPool, [startingReward](const RandomizerGet i) {return i == startingReward;}); - } } -//Fills any locations excluded by the player with junk items so that advancement items -//can't be placed there. +// Fills any locations excluded by the player with junk items so that advancement items +// can't be placed there. static void FillExcludedLocations() { - auto ctx = Rando::Context::GetInstance(); - //Only fill in excluded locations that don't already have something and are forbidden - std::vector excludedLocations = FilterFromPool(ctx->allLocations, [ctx](const auto loc){ - return ctx->GetItemLocation(loc)->IsExcluded(); - }); + auto ctx = Rando::Context::GetInstance(); + // Only fill in excluded locations that don't already have something and are forbidden + std::vector excludedLocations = + FilterFromPool(ctx->allLocations, [ctx](const auto loc) { return ctx->GetItemLocation(loc)->IsExcluded(); }); - for (RandomizerCheck loc : excludedLocations) { - PlaceJunkInExcludedLocation(loc); - } + for (RandomizerCheck loc : excludedLocations) { + PlaceJunkInExcludedLocation(loc); + } } -//Function to handle the Own Dungeon setting +// Function to handle the Own Dungeon setting static void RandomizeOwnDungeon(const Rando::DungeonInfo* dungeon) { - auto ctx = Rando::Context::GetInstance(); - std::vector dungeonItems; + auto ctx = Rando::Context::GetInstance(); + std::vector dungeonItems; - // Search and filter for locations that match the hint region of the dungeon - // This accounts for boss room shuffle so that own dungeon items can be placed - // in the shuffled boss room - std::vector dungeonLocations = FilterFromPool(ctx->allLocations, [dungeon, ctx](const auto loc) { - return ctx->GetItemLocation(loc)->GetAreas().contains(dungeon->GetArea()); - }); + // Search and filter for locations that match the hint region of the dungeon + // This accounts for boss room shuffle so that own dungeon items can be placed + // in the shuffled boss room + std::vector dungeonLocations = FilterFromPool(ctx->allLocations, [dungeon, ctx](const auto loc) { + return ctx->GetItemLocation(loc)->GetAreas().contains(dungeon->GetArea()); + }); - //filter out locations that may be required to have songs placed at them - dungeonLocations = FilterFromPool(dungeonLocations, [ctx](const auto loc) { - if (ctx->GetOption(RSK_SHUFFLE_SONGS).Is(RO_SONG_SHUFFLE_SONG_LOCATIONS)) { - return !(Rando::StaticData::GetLocation(loc)->GetRCType() == RCTYPE_SONG_LOCATION); + // filter out locations that may be required to have songs placed at them + dungeonLocations = FilterFromPool(dungeonLocations, [ctx](const auto loc) { + if (ctx->GetOption(RSK_SHUFFLE_SONGS).Is(RO_SONG_SHUFFLE_SONG_LOCATIONS)) { + return !(Rando::StaticData::GetLocation(loc)->GetRCType() == RCTYPE_SONG_LOCATION); + } + if (ctx->GetOption(RSK_SHUFFLE_SONGS).Is(RO_SONG_SHUFFLE_DUNGEON_REWARDS)) { + return !(Rando::StaticData::GetLocation(loc)->GetRCType() == RCTYPE_BOSS_HEART_OR_OTHER_REWARD || + loc == RC_SHEIK_IN_ICE_CAVERN || loc == RC_SONG_FROM_IMPA); + } + return true; + }); + + // Add specific items that need be randomized within this dungeon + if (ctx->GetOption(RSK_KEYSANITY).Is(RO_DUNGEON_ITEM_LOC_OWN_DUNGEON) && dungeon->GetSmallKey() != RG_NONE) { + std::vector dungeonSmallKeys = + FilterAndEraseFromPool(ItemPool, [dungeon](const RandomizerGet i) { + return (i == dungeon->GetSmallKey()) || (i == dungeon->GetKeyRing()); + }); + AddElementsToPool(dungeonItems, dungeonSmallKeys); } - if (ctx->GetOption(RSK_SHUFFLE_SONGS).Is(RO_SONG_SHUFFLE_DUNGEON_REWARDS)) { - return !(Rando::StaticData::GetLocation(loc)->GetRCType() == RCTYPE_BOSS_HEART_OR_OTHER_REWARD || - loc == RC_SHEIK_IN_ICE_CAVERN || - loc == RC_SONG_FROM_IMPA); - } - return true; - }); - //Add specific items that need be randomized within this dungeon - if (ctx->GetOption(RSK_KEYSANITY).Is(RO_DUNGEON_ITEM_LOC_OWN_DUNGEON) && dungeon->GetSmallKey() != RG_NONE) { - std::vector dungeonSmallKeys = FilterAndEraseFromPool(ItemPool, [dungeon](const RandomizerGet i){ return (i == dungeon->GetSmallKey()) || (i == dungeon->GetKeyRing());}); - AddElementsToPool(dungeonItems, dungeonSmallKeys); - } - - if ((ctx->GetOption(RSK_BOSS_KEYSANITY).Is(RO_DUNGEON_ITEM_LOC_OWN_DUNGEON) && dungeon->GetBossKey() != RG_GANONS_CASTLE_BOSS_KEY) || - (ctx->GetOption(RSK_GANONS_BOSS_KEY).Is(RO_GANON_BOSS_KEY_OWN_DUNGEON) && dungeon->GetBossKey() == RG_GANONS_CASTLE_BOSS_KEY)) { - auto dungeonBossKey = FilterAndEraseFromPool(ItemPool, [dungeon](const RandomizerGet i){ return i == dungeon->GetBossKey();}); + if ((ctx->GetOption(RSK_BOSS_KEYSANITY).Is(RO_DUNGEON_ITEM_LOC_OWN_DUNGEON) && + dungeon->GetBossKey() != RG_GANONS_CASTLE_BOSS_KEY) || + (ctx->GetOption(RSK_GANONS_BOSS_KEY).Is(RO_GANON_BOSS_KEY_OWN_DUNGEON) && + dungeon->GetBossKey() == RG_GANONS_CASTLE_BOSS_KEY)) { + auto dungeonBossKey = + FilterAndEraseFromPool(ItemPool, [dungeon](const RandomizerGet i) { return i == dungeon->GetBossKey(); }); AddElementsToPool(dungeonItems, dungeonBossKey); - } + } - //randomize boss key and small keys together for even distribution - AssumedFill(dungeonItems, dungeonLocations); + // randomize boss key and small keys together for even distribution + AssumedFill(dungeonItems, dungeonLocations); - //randomize map and compass separately since they're not progressive - if (ctx->GetOption(RSK_SHUFFLE_MAPANDCOMPASS).Is(RO_DUNGEON_ITEM_LOC_OWN_DUNGEON) && dungeon->GetMap() != RG_NONE && dungeon->GetCompass() != RG_NONE) { - auto dungeonMapAndCompass = FilterAndEraseFromPool(ItemPool, [dungeon](const RandomizerGet i){ return i == dungeon->GetMap() || i == dungeon->GetCompass();}); - AssumedFill(dungeonMapAndCompass, dungeonLocations); - } + // randomize map and compass separately since they're not progressive + if (ctx->GetOption(RSK_SHUFFLE_MAPANDCOMPASS).Is(RO_DUNGEON_ITEM_LOC_OWN_DUNGEON) && dungeon->GetMap() != RG_NONE && + dungeon->GetCompass() != RG_NONE) { + auto dungeonMapAndCompass = FilterAndEraseFromPool(ItemPool, [dungeon](const RandomizerGet i) { + return i == dungeon->GetMap() || i == dungeon->GetCompass(); + }); + AssumedFill(dungeonMapAndCompass, dungeonLocations); + } } /*Randomize items restricted to a certain set of locations. @@ -1041,353 +1083,373 @@ static void RandomizeOwnDungeon(const Rando::DungeonInfo* dungeon) { will be randomized together if they have the same setting. Maps and Compasses are randomized separately once the dungeon advancement items have all been placed.*/ static void RandomizeDungeonItems() { - auto ctx = Rando::Context::GetInstance(); + auto ctx = Rando::Context::GetInstance(); - //Get Any Dungeon and Overworld group locations - std::vector anyDungeonLocations = Rando::StaticData::GetAllDungeonLocations(); + // Get Any Dungeon and Overworld group locations + std::vector anyDungeonLocations = Rando::StaticData::GetAllDungeonLocations(); - //Create Any Dungeon and Overworld item pools - std::vector anyDungeonItems; - std::vector overworldItems; + // Create Any Dungeon and Overworld item pools + std::vector anyDungeonItems; + std::vector overworldItems; - for (auto dungeon : ctx->GetDungeons()->GetDungeonList()) { - if (ctx->GetOption(RSK_KEYSANITY).Is(RO_DUNGEON_ITEM_LOC_ANY_DUNGEON)) { - auto dungeonKeys = FilterAndEraseFromPool(ItemPool, [dungeon](const RandomizerGet i){return (i == dungeon->GetSmallKey()) || (i == dungeon->GetKeyRing());}); - AddElementsToPool(anyDungeonItems, dungeonKeys); - } else if (ctx->GetOption(RSK_KEYSANITY).Is(RO_DUNGEON_ITEM_LOC_OVERWORLD)) { - auto dungeonKeys = FilterAndEraseFromPool(ItemPool, [dungeon](const RandomizerGet i){return (i == dungeon->GetSmallKey()) || (i == dungeon->GetKeyRing());}); - AddElementsToPool(overworldItems, dungeonKeys); + for (auto dungeon : ctx->GetDungeons()->GetDungeonList()) { + if (ctx->GetOption(RSK_KEYSANITY).Is(RO_DUNGEON_ITEM_LOC_ANY_DUNGEON)) { + auto dungeonKeys = FilterAndEraseFromPool(ItemPool, [dungeon](const RandomizerGet i) { + return (i == dungeon->GetSmallKey()) || (i == dungeon->GetKeyRing()); + }); + AddElementsToPool(anyDungeonItems, dungeonKeys); + } else if (ctx->GetOption(RSK_KEYSANITY).Is(RO_DUNGEON_ITEM_LOC_OVERWORLD)) { + auto dungeonKeys = FilterAndEraseFromPool(ItemPool, [dungeon](const RandomizerGet i) { + return (i == dungeon->GetSmallKey()) || (i == dungeon->GetKeyRing()); + }); + AddElementsToPool(overworldItems, dungeonKeys); + } + + if (ctx->GetOption(RSK_BOSS_KEYSANITY).Is(RO_DUNGEON_ITEM_LOC_ANY_DUNGEON) && + dungeon->GetBossKey() != RG_GANONS_CASTLE_BOSS_KEY) { + auto bossKey = FilterAndEraseFromPool( + ItemPool, [dungeon](const RandomizerGet i) { return i == dungeon->GetBossKey(); }); + AddElementsToPool(anyDungeonItems, bossKey); + } else if (ctx->GetOption(RSK_BOSS_KEYSANITY).Is(RO_DUNGEON_ITEM_LOC_OVERWORLD) && + dungeon->GetBossKey() != RG_GANONS_CASTLE_BOSS_KEY) { + auto bossKey = FilterAndEraseFromPool( + ItemPool, [dungeon](const RandomizerGet i) { return i == dungeon->GetBossKey(); }); + AddElementsToPool(overworldItems, bossKey); + } + + if (ctx->GetOption(RSK_GANONS_BOSS_KEY).Is(RO_GANON_BOSS_KEY_ANY_DUNGEON)) { + auto ganonBossKey = + FilterAndEraseFromPool(ItemPool, [](const auto i) { return i == RG_GANONS_CASTLE_BOSS_KEY; }); + AddElementsToPool(anyDungeonItems, ganonBossKey); + } else if (ctx->GetOption(RSK_GANONS_BOSS_KEY).Is(RO_GANON_BOSS_KEY_OVERWORLD)) { + auto ganonBossKey = + FilterAndEraseFromPool(ItemPool, [](const auto i) { return i == RG_GANONS_CASTLE_BOSS_KEY; }); + AddElementsToPool(overworldItems, ganonBossKey); + } } - if (ctx->GetOption(RSK_BOSS_KEYSANITY).Is(RO_DUNGEON_ITEM_LOC_ANY_DUNGEON) && dungeon->GetBossKey() != RG_GANONS_CASTLE_BOSS_KEY) { - auto bossKey = FilterAndEraseFromPool(ItemPool, [dungeon](const RandomizerGet i){return i == dungeon->GetBossKey();}); - AddElementsToPool(anyDungeonItems, bossKey); - } else if (ctx->GetOption(RSK_BOSS_KEYSANITY).Is(RO_DUNGEON_ITEM_LOC_OVERWORLD) && dungeon->GetBossKey() != RG_GANONS_CASTLE_BOSS_KEY) { - auto bossKey = FilterAndEraseFromPool(ItemPool, [dungeon](const RandomizerGet i){return i == dungeon->GetBossKey();}); - AddElementsToPool(overworldItems, bossKey); + if (ctx->GetOption(RSK_GERUDO_KEYS).Is(RO_GERUDO_KEYS_ANY_DUNGEON)) { + auto gerudoKeys = FilterAndEraseFromPool(ItemPool, [](const auto i) { + return i == RG_GERUDO_FORTRESS_SMALL_KEY || i == RG_GERUDO_FORTRESS_KEY_RING; + }); + AddElementsToPool(anyDungeonItems, gerudoKeys); + } else if (ctx->GetOption(RSK_GERUDO_KEYS).Is(RO_GERUDO_KEYS_OVERWORLD)) { + auto gerudoKeys = FilterAndEraseFromPool(ItemPool, [](const auto i) { + return i == RG_GERUDO_FORTRESS_SMALL_KEY || i == RG_GERUDO_FORTRESS_KEY_RING; + }); + AddElementsToPool(overworldItems, gerudoKeys); } - if (ctx->GetOption(RSK_GANONS_BOSS_KEY).Is(RO_GANON_BOSS_KEY_ANY_DUNGEON)) { - auto ganonBossKey = FilterAndEraseFromPool(ItemPool, [](const auto i){return i == RG_GANONS_CASTLE_BOSS_KEY;}); - AddElementsToPool(anyDungeonItems, ganonBossKey); - } else if (ctx->GetOption(RSK_GANONS_BOSS_KEY).Is(RO_GANON_BOSS_KEY_OVERWORLD)) { - auto ganonBossKey = FilterAndEraseFromPool(ItemPool, [](const auto i) { return i == RG_GANONS_CASTLE_BOSS_KEY; }); - AddElementsToPool(overworldItems, ganonBossKey); + if (ctx->GetOption(RSK_SHUFFLE_DUNGEON_REWARDS).Is(RO_DUNGEON_REWARDS_ANY_DUNGEON)) { + auto rewards = FilterAndEraseFromPool(ItemPool, [](const auto i) { + return Rando::StaticData::RetrieveItem(i).GetItemType() == ITEMTYPE_DUNGEONREWARD; + }); + AddElementsToPool(anyDungeonItems, rewards); + } else if (ctx->GetOption(RSK_SHUFFLE_DUNGEON_REWARDS).Is(RO_DUNGEON_REWARDS_OVERWORLD)) { + auto rewards = FilterAndEraseFromPool(ItemPool, [](const auto i) { + return Rando::StaticData::RetrieveItem(i).GetItemType() == ITEMTYPE_DUNGEONREWARD; + }); + AddElementsToPool(overworldItems, rewards); } - } - if (ctx->GetOption(RSK_GERUDO_KEYS).Is(RO_GERUDO_KEYS_ANY_DUNGEON)) { - auto gerudoKeys = FilterAndEraseFromPool(ItemPool, [](const auto i) { return i == RG_GERUDO_FORTRESS_SMALL_KEY || i == RG_GERUDO_FORTRESS_KEY_RING; }); - AddElementsToPool(anyDungeonItems, gerudoKeys); - } else if (ctx->GetOption(RSK_GERUDO_KEYS).Is(RO_GERUDO_KEYS_OVERWORLD)) { - auto gerudoKeys = FilterAndEraseFromPool(ItemPool, [](const auto i) { return i == RG_GERUDO_FORTRESS_SMALL_KEY || i == RG_GERUDO_FORTRESS_KEY_RING; }); - AddElementsToPool(overworldItems, gerudoKeys); - } + // Randomize Any Dungeon and Overworld pools + AssumedFill(anyDungeonItems, anyDungeonLocations, true); + AssumedFill(overworldItems, ctx->overworldLocations, true); - if (ctx->GetOption(RSK_SHUFFLE_DUNGEON_REWARDS).Is(RO_DUNGEON_REWARDS_ANY_DUNGEON)) { - auto rewards = FilterAndEraseFromPool( - ItemPool, [](const auto i) { return Rando::StaticData::RetrieveItem(i).GetItemType() == ITEMTYPE_DUNGEONREWARD; }); - AddElementsToPool(anyDungeonItems, rewards); - } else if (ctx->GetOption(RSK_SHUFFLE_DUNGEON_REWARDS).Is(RO_DUNGEON_REWARDS_OVERWORLD)) { - auto rewards = FilterAndEraseFromPool( - ItemPool, [](const auto i) { return Rando::StaticData::RetrieveItem(i).GetItemType() == ITEMTYPE_DUNGEONREWARD; }); - AddElementsToPool(overworldItems, rewards); - } - - //Randomize Any Dungeon and Overworld pools - AssumedFill(anyDungeonItems, anyDungeonLocations, true); - AssumedFill(overworldItems, ctx->overworldLocations, true); - - //Randomize maps and compasses after since they're not advancement items - for (auto dungeon : ctx->GetDungeons()->GetDungeonList()) { - if (ctx->GetOption(RSK_SHUFFLE_MAPANDCOMPASS).Is(RO_DUNGEON_ITEM_LOC_ANY_DUNGEON)) { - auto mapAndCompassItems = FilterAndEraseFromPool(ItemPool, [dungeon](const RandomizerGet i){return i == dungeon->GetMap() || i == dungeon->GetCompass();}); - AssumedFill(mapAndCompassItems, anyDungeonLocations, true); - } else if (ctx->GetOption(RSK_SHUFFLE_MAPANDCOMPASS).Is(RO_DUNGEON_ITEM_LOC_OVERWORLD)) { - auto mapAndCompassItems = FilterAndEraseFromPool(ItemPool, [dungeon](const RandomizerGet i){return i == dungeon->GetMap() || i == dungeon->GetCompass();}); - AssumedFill(mapAndCompassItems, ctx->overworldLocations, true); + // Randomize maps and compasses after since they're not advancement items + for (auto dungeon : ctx->GetDungeons()->GetDungeonList()) { + if (ctx->GetOption(RSK_SHUFFLE_MAPANDCOMPASS).Is(RO_DUNGEON_ITEM_LOC_ANY_DUNGEON)) { + auto mapAndCompassItems = FilterAndEraseFromPool(ItemPool, [dungeon](const RandomizerGet i) { + return i == dungeon->GetMap() || i == dungeon->GetCompass(); + }); + AssumedFill(mapAndCompassItems, anyDungeonLocations, true); + } else if (ctx->GetOption(RSK_SHUFFLE_MAPANDCOMPASS).Is(RO_DUNGEON_ITEM_LOC_OVERWORLD)) { + auto mapAndCompassItems = FilterAndEraseFromPool(ItemPool, [dungeon](const RandomizerGet i) { + return i == dungeon->GetMap() || i == dungeon->GetCompass(); + }); + AssumedFill(mapAndCompassItems, ctx->overworldLocations, true); + } } - } } static void RandomizeLinksPocket() { - auto ctx = Rando::Context::GetInstance(); - if (ctx->GetOption(RSK_LINKS_POCKET).Is(RO_LINKS_POCKET_ADVANCEMENT)) { - //Get all the advancement items don't include tokens - std::vector advancementItems = FilterAndEraseFromPool(ItemPool, [](const auto i) { - return Rando::StaticData::RetrieveItem(i).IsAdvancement() && Rando::StaticData::RetrieveItem(i).GetItemType() != ITEMTYPE_TOKEN; - }); - //select a random one - RandomizerGet startingItem = RandomElement(advancementItems, true); - //add the others back - AddElementsToPool(ItemPool, advancementItems); + auto ctx = Rando::Context::GetInstance(); + if (ctx->GetOption(RSK_LINKS_POCKET).Is(RO_LINKS_POCKET_ADVANCEMENT)) { + // Get all the advancement items don't include tokens + std::vector advancementItems = FilterAndEraseFromPool(ItemPool, [](const auto i) { + return Rando::StaticData::RetrieveItem(i).IsAdvancement() && + Rando::StaticData::RetrieveItem(i).GetItemType() != ITEMTYPE_TOKEN; + }); + // select a random one + RandomizerGet startingItem = RandomElement(advancementItems, true); + // add the others back + AddElementsToPool(ItemPool, advancementItems); - ctx->PlaceItemInLocation(RC_LINKS_POCKET, startingItem); - } else if (ctx->GetOption(RSK_LINKS_POCKET).Is(RO_LINKS_POCKET_NOTHING)) { - ctx->PlaceItemInLocation(RC_LINKS_POCKET, RG_GREEN_RUPEE); - } + ctx->PlaceItemInLocation(RC_LINKS_POCKET, startingItem); + } else if (ctx->GetOption(RSK_LINKS_POCKET).Is(RO_LINKS_POCKET_NOTHING)) { + ctx->PlaceItemInLocation(RC_LINKS_POCKET, RG_GREEN_RUPEE); + } } void VanillaFill() { - auto ctx = Rando::Context::GetInstance(); - //Perform minimum needed initialization - RegionTable_Init(); - ctx->GenerateLocationPool(); - GenerateItemPool(); - GenerateStartingInventory(); - //Place vanilla item in each location - RandomizeDungeonRewards(); - for (RandomizerCheck loc : ctx->allLocations) { - ctx->GetItemLocation(loc)->PlaceVanillaItem(); - } - //If necessary, handle ER stuff - if (ctx->GetOption(RSK_SHUFFLE_ENTRANCES)) { - SPDLOG_INFO("Shuffling Entrances..."); - ctx->GetEntranceShuffler()->ShuffleAllEntrances(); - SPDLOG_INFO("Shuffling Entrances Done"); - } - // Populate the playthrough for entrances so they are placed in the spoiler log - GeneratePlaythrough(); - //Finish up - ctx->CreateItemOverrides(); - ctx->GetEntranceShuffler()->CreateEntranceOverrides(); - CreateWarpSongTexts(); + auto ctx = Rando::Context::GetInstance(); + // Perform minimum needed initialization + RegionTable_Init(); + ctx->GenerateLocationPool(); + GenerateItemPool(); + GenerateStartingInventory(); + // Place vanilla item in each location + RandomizeDungeonRewards(); + for (RandomizerCheck loc : ctx->allLocations) { + ctx->GetItemLocation(loc)->PlaceVanillaItem(); + } + // If necessary, handle ER stuff + if (ctx->GetOption(RSK_SHUFFLE_ENTRANCES)) { + SPDLOG_INFO("Shuffling Entrances..."); + ctx->GetEntranceShuffler()->ShuffleAllEntrances(); + SPDLOG_INFO("Shuffling Entrances Done"); + } + // Populate the playthrough for entrances so they are placed in the spoiler log + GeneratePlaythrough(); + // Finish up + ctx->CreateItemOverrides(); + ctx->GetEntranceShuffler()->CreateEntranceOverrides(); + CreateWarpSongTexts(); } void ClearProgress() { } int Fill() { - auto ctx = Rando::Context::GetInstance(); - int retries = 0; - SPDLOG_INFO("Starting seed generation..."); - while(retries < 5) { - SPDLOG_INFO("Attempt {}...", retries + 1); - placementFailure = false; - //showItemProgress = false; - ctx->playthroughLocations.clear(); - ctx->GetEntranceShuffler()->playthroughEntrances.clear(); - RegionTable_Init(); //Reset the world graph to intialize the proper locations - ctx->ItemReset(); //Reset shops incase of shopsanity random - ctx->GenerateLocationPool(); - GenerateItemPool(); - GenerateStartingInventory(); - RemoveStartingItemsFromPool(); - FillExcludedLocations(); + auto ctx = Rando::Context::GetInstance(); + int retries = 0; + SPDLOG_INFO("Starting seed generation..."); + while (retries < 5) { + SPDLOG_INFO("Attempt {}...", retries + 1); + placementFailure = false; + // showItemProgress = false; + ctx->playthroughLocations.clear(); + ctx->GetEntranceShuffler()->playthroughEntrances.clear(); + RegionTable_Init(); // Reset the world graph to intialize the proper locations + ctx->ItemReset(); // Reset shops incase of shopsanity random + ctx->GenerateLocationPool(); + GenerateItemPool(); + GenerateStartingInventory(); + RemoveStartingItemsFromPool(); + FillExcludedLocations(); - //Temporarily add shop items to the ItemPool so that entrance randomization - //can validate the world using deku/hylian shields - StartPerformanceTimer(PT_ENTRANCE_SHUFFLE); - AddElementsToPool(ItemPool, GetMinVanillaShopItems(8)); //assume worst case shopsanity 7 - if (ctx->GetOption(RSK_SHUFFLE_ENTRANCES)) { - SPDLOG_INFO("Shuffling Entrances..."); - if (ctx->GetEntranceShuffler()->ShuffleAllEntrances() == ENTRANCE_SHUFFLE_FAILURE) { + // Temporarily add shop items to the ItemPool so that entrance randomization + // can validate the world using deku/hylian shields + StartPerformanceTimer(PT_ENTRANCE_SHUFFLE); + AddElementsToPool(ItemPool, GetMinVanillaShopItems(8)); // assume worst case shopsanity 7 + if (ctx->GetOption(RSK_SHUFFLE_ENTRANCES)) { + SPDLOG_INFO("Shuffling Entrances..."); + if (ctx->GetEntranceShuffler()->ShuffleAllEntrances() == ENTRANCE_SHUFFLE_FAILURE) { + retries++; + ClearProgress(); + continue; + } + SPDLOG_INFO("Shuffling Entrances Done"); + } + SetAreas(); + // erase temporary shop items + FilterAndEraseFromPool(ItemPool, [](const auto item) { + return Rando::StaticData::RetrieveItem(item).GetItemType() == ITEMTYPE_SHOP; + }); + StopPerformanceTimer(PT_ENTRANCE_SHUFFLE); + + // ctx->showItemProgress = true; + // Place shop items first, since a buy shield is needed to place a dungeon reward on Gohma due to access + + StartPerformanceTimer(PT_SHOPSANITY); + if (ctx->GetOption(RSK_SHOPSANITY).Is(RO_SHOPSANITY_OFF)) { + SPDLOG_INFO("Placing Vanilla Shop Items..."); + PlaceVanillaShopItems(); // Place vanilla shop items in vanilla location + } else { + SPDLOG_INFO("Shuffling Shop Items"); + int total_replaced = 0; + if (ctx->GetOption(RSK_SHOPSANITY).Is(RO_SHOPSANITY_RANDOM) || + ctx->GetOption(RSK_SHOPSANITY_COUNT).IsNot(RO_SHOPSANITY_COUNT_ZERO_ITEMS)) { // Shopsanity 1-7, random + /* + Indices from OoTR. So shopsanity one will overwrite 7, three will overwrite 7, 5, 8, etc. + 8 6 2 4 + 7 5 1 3 + */ + const std::array indices = { 7, 5, 8, 6, 3, 1, 4, 2 }; +// Overwrite appropriate number of shop items +#define LOCATIONS_PER_SHOP 8 + for (size_t i = 0; i < Rando::StaticData::GetShopLocations().size() / LOCATIONS_PER_SHOP; i++) { + int num_to_replace = + GetShopsanityReplaceAmount(); // 1-7 shop items will be overwritten, depending on settings + total_replaced += num_to_replace; + for (int j = 0; j < num_to_replace; j++) { + int itemindex = indices[j]; + RandomizerCheck rc = + Rando::StaticData::GetShopLocations()[i * LOCATIONS_PER_SHOP + itemindex - 1]; + Rando::ItemLocation* itemLoc = ctx->GetItemLocation(rc); + uint16_t shopsanityPrice = GetRandomPrice(Rando::StaticData::GetLocation(rc), shopsanityPrices); + itemLoc->SetCustomPrice(shopsanityPrice); + } + } +#undef LOCATIONS_PER_SHOP + } + // Get all locations and items that don't have a shopsanity price attached + std::vector shopLocations = {}; + // Get as many vanilla shop items as the total number of shop items minus the number of replaced items + // So shopsanity 0 will get all 64 vanilla items, shopsanity 4 will get 32, etc. + std::vector shopItems = GetMinVanillaShopItems(total_replaced); + + for (RandomizerCheck& randomizerCheck : Rando::StaticData::GetShopLocations()) { + if (!(ctx->GetItemLocation(randomizerCheck)->HasCustomPrice())) { + shopLocations.push_back(randomizerCheck); + } + } + // Place the shop items which will still be at shop locations + AssumedFill(shopItems, shopLocations); + } + + // Add prices to scrubs + auto scrubLoc = Rando::StaticData::GetScrubLocations(); + if (ctx->GetOption(RSK_SHUFFLE_SCRUBS).Is(RO_SCRUBS_ALL)) { + for (size_t i = 0; i < scrubLoc.size(); i++) { + ctx->GetItemLocation(scrubLoc[i]) + ->SetCustomPrice(GetRandomPrice(Rando::StaticData::GetLocation(scrubLoc[i]), scrubPrices)); + } + } else { + for (size_t i = 0; i < scrubLoc.size(); i++) { + ctx->GetItemLocation(scrubLoc[i]) + ->SetCustomPrice(Rando::StaticData::GetLocation(scrubLoc[i])->GetVanillaPrice()); + } + } + + // set merchant prices + if (ctx->GetOption(RSK_SHUFFLE_MERCHANTS).Is(RO_SHUFFLE_MERCHANTS_BEANS_ONLY) || + ctx->GetOption(RSK_SHUFFLE_MERCHANTS).Is(RO_SHUFFLE_MERCHANTS_ALL)) { + ctx->GetItemLocation(RC_ZR_MAGIC_BEAN_SALESMAN) + ->SetCustomPrice( + GetRandomPrice(Rando::StaticData::GetLocation(RC_ZR_MAGIC_BEAN_SALESMAN), merchantPrices)); + } else { + ctx->GetItemLocation(RC_ZR_MAGIC_BEAN_SALESMAN) + ->SetCustomPrice(Rando::StaticData::GetLocation(RC_ZR_MAGIC_BEAN_SALESMAN)->GetVanillaPrice()); + } + + auto merchantLoc = Rando::StaticData::GetMerchantLocations(); + + if (ctx->GetOption(RSK_SHUFFLE_MERCHANTS).Is(RO_SHUFFLE_MERCHANTS_ALL_BUT_BEANS) || + ctx->GetOption(RSK_SHUFFLE_MERCHANTS).Is(RO_SHUFFLE_MERCHANTS_ALL)) { + for (size_t i = 0; i < merchantLoc.size(); i++) { + ctx->GetItemLocation(merchantLoc[i]) + ->SetCustomPrice(GetRandomPrice(Rando::StaticData::GetLocation(merchantLoc[i]), merchantPrices)); + } + } else { + for (size_t i = 0; i < merchantLoc.size(); i++) { + ctx->GetItemLocation(merchantLoc[i]) + ->SetCustomPrice(Rando::StaticData::GetLocation(merchantLoc[i])->GetVanillaPrice()); + } + } + StopPerformanceTimer(PT_SHOPSANITY); + + StartPerformanceTimer(PT_OWN_DUNGEON); + // Place dungeon rewards + SPDLOG_INFO("Shuffling and Placing Dungeon Items..."); + RandomizeDungeonRewards(); + + // Place dungeon items restricted to their Own Dungeon + for (auto dungeon : ctx->GetDungeons()->GetDungeonList()) { + RandomizeOwnDungeon(dungeon); + } + StopPerformanceTimer(PT_OWN_DUNGEON); + + StartPerformanceTimer(PT_LIMITED_CHECKS); + // Then Place songs if song shuffle is set to specific locations + if (ctx->GetOption(RSK_SHUFFLE_SONGS).IsNot(RO_SONG_SHUFFLE_ANYWHERE)) { + + // Get each song + std::vector songs = FilterAndEraseFromPool(ItemPool, [](const auto i) { + return Rando::StaticData::RetrieveItem(i).GetItemType() == ITEMTYPE_SONG; + }); + + // Get each song location + std::vector songLocations; + if (ctx->GetOption(RSK_SHUFFLE_SONGS).Is(RO_SONG_SHUFFLE_SONG_LOCATIONS)) { + songLocations = FilterFromPool(ctx->allLocations, [](const auto loc) { + return Rando::StaticData::GetLocation(loc)->GetRCType() == RCTYPE_SONG_LOCATION; + }); + + } else if (ctx->GetOption(RSK_SHUFFLE_SONGS).Is(RO_SONG_SHUFFLE_DUNGEON_REWARDS)) { + songLocations = FilterFromPool(ctx->allLocations, [](const auto loc) { + return Rando::StaticData::GetLocation(loc)->GetRCType() == RCTYPE_BOSS_HEART_OR_OTHER_REWARD || + loc == RC_SHEIK_IN_ICE_CAVERN || loc == RC_SONG_FROM_IMPA; + }); + } + + AssumedFill(songs, songLocations, true); + } + + // Then place dungeon items that are assigned to restrictive location pools + RandomizeDungeonItems(); + SPDLOG_INFO("Dungeon Items Done"); + + // Then place Link's Pocket Item if it has to be an advancement item + RandomizeLinksPocket(); + StopPerformanceTimer(PT_LIMITED_CHECKS); + + StartPerformanceTimer(PT_ADVANCEMENT_ITEMS); + SPDLOG_INFO("Shuffling Advancement Items"); + // Then place the rest of the advancement items + std::vector remainingAdvancementItems = FilterAndEraseFromPool( + ItemPool, [](const auto i) { return Rando::StaticData::RetrieveItem(i).IsAdvancement(); }); + AssumedFill(remainingAdvancementItems, ctx->allLocations, true); + StopPerformanceTimer(PT_ADVANCEMENT_ITEMS); + + StartPerformanceTimer(PT_REMAINING_ITEMS); + // Fast fill for the rest of the pool + SPDLOG_INFO("Shuffling Remaining Items"); + std::vector remainingPool = FilterAndEraseFromPool(ItemPool, [](const auto i) { return true; }); + FastFill(remainingPool, GetAllEmptyLocations(), false); + StopPerformanceTimer(PT_REMAINING_ITEMS); + + StartPerformanceTimer(PT_PLAYTHROUGH_GENERATION); + GeneratePlaythrough(); + StopPerformanceTimer(PT_PLAYTHROUGH_GENERATION); + // Successful placement, produced beatable result + if (ctx->playthroughBeatable && !placementFailure) { + + SPDLOG_INFO("Calculating Playthrough..."); + StartPerformanceTimer(PT_PARE_DOWN_PLAYTHROUGH); + PareDownPlaythrough(); + StopPerformanceTimer(PT_PARE_DOWN_PLAYTHROUGH); + + StartPerformanceTimer(PT_WOTH); + CalculateWotH(); + StopPerformanceTimer(PT_WOTH); + + StartPerformanceTimer(PT_FOOLISH); + CalculateBarren(); + StopPerformanceTimer(PT_FOOLISH); + SPDLOG_INFO("Calculating Playthrough Done"); + + StartPerformanceTimer(PT_OVERRIDES); + ctx->CreateItemOverrides(); + ctx->GetEntranceShuffler()->CreateEntranceOverrides(); + StopPerformanceTimer(PT_OVERRIDES); + + StartPerformanceTimer(PT_HINTS); + CreateAllHints(); + CreateWarpSongTexts(); + StopPerformanceTimer(PT_HINTS); + SPDLOG_DEBUG("Number of retries {}", retries); + return 1; + } + // Unsuccessful placement + if (retries < 4) { + SPDLOG_DEBUG("Failed to generate a beatable seed. Retrying..."); + Regions::ResetAllLocations(); + logic->Reset(); + ClearProgress(); + } retries++; - ClearProgress(); - continue; - } - SPDLOG_INFO("Shuffling Entrances Done"); } - SetAreas(); - //erase temporary shop items - FilterAndEraseFromPool(ItemPool, [](const auto item) { return Rando::StaticData::RetrieveItem(item).GetItemType() == ITEMTYPE_SHOP; }); - StopPerformanceTimer(PT_ENTRANCE_SHUFFLE); - - //ctx->showItemProgress = true; - //Place shop items first, since a buy shield is needed to place a dungeon reward on Gohma due to access - - StartPerformanceTimer(PT_SHOPSANITY); - if (ctx->GetOption(RSK_SHOPSANITY).Is(RO_SHOPSANITY_OFF)) { - SPDLOG_INFO("Placing Vanilla Shop Items..."); - PlaceVanillaShopItems(); //Place vanilla shop items in vanilla location - } else { - SPDLOG_INFO("Shuffling Shop Items"); - int total_replaced = 0; - if (ctx->GetOption(RSK_SHOPSANITY).Is(RO_SHOPSANITY_RANDOM) || ctx->GetOption(RSK_SHOPSANITY_COUNT).IsNot(RO_SHOPSANITY_COUNT_ZERO_ITEMS)) { //Shopsanity 1-7, random - /* - Indices from OoTR. So shopsanity one will overwrite 7, three will overwrite 7, 5, 8, etc. - 8 6 2 4 - 7 5 1 3 - */ - const std::array indices = { 7, 5, 8, 6, 3, 1, 4, 2 }; - //Overwrite appropriate number of shop items - #define LOCATIONS_PER_SHOP 8 - for (size_t i = 0; i < Rando::StaticData::GetShopLocations().size() / LOCATIONS_PER_SHOP; i++) { - int num_to_replace = GetShopsanityReplaceAmount(); //1-7 shop items will be overwritten, depending on settings - total_replaced += num_to_replace; - for (int j = 0; j < num_to_replace; j++) { - int itemindex = indices[j]; - RandomizerCheck rc = Rando::StaticData::GetShopLocations()[i * LOCATIONS_PER_SHOP + itemindex - 1]; - Rando::ItemLocation* itemLoc = ctx->GetItemLocation(rc); - uint16_t shopsanityPrice = GetRandomPrice(Rando::StaticData::GetLocation(rc), shopsanityPrices); - itemLoc->SetCustomPrice(shopsanityPrice); - } - } - #undef LOCATIONS_PER_SHOP - } - //Get all locations and items that don't have a shopsanity price attached - std::vector shopLocations = {}; - //Get as many vanilla shop items as the total number of shop items minus the number of replaced items - //So shopsanity 0 will get all 64 vanilla items, shopsanity 4 will get 32, etc. - std::vector shopItems = GetMinVanillaShopItems(total_replaced); - - for (RandomizerCheck& randomizerCheck : Rando::StaticData::GetShopLocations()) { - if (!(ctx->GetItemLocation(randomizerCheck)->HasCustomPrice())) { - shopLocations.push_back(randomizerCheck); - } - } - //Place the shop items which will still be at shop locations - AssumedFill(shopItems, shopLocations); - } - - //Add prices to scrubs - auto scrubLoc = Rando::StaticData::GetScrubLocations(); - if (ctx->GetOption(RSK_SHUFFLE_SCRUBS).Is(RO_SCRUBS_ALL)) { - for (size_t i = 0; i < scrubLoc.size(); i++) { - ctx->GetItemLocation(scrubLoc[i])->SetCustomPrice( - GetRandomPrice(Rando::StaticData::GetLocation(scrubLoc[i]), scrubPrices) - ); - } - } else { - for (size_t i = 0; i < scrubLoc.size(); i++) { - ctx->GetItemLocation(scrubLoc[i])->SetCustomPrice( - Rando::StaticData::GetLocation(scrubLoc[i])->GetVanillaPrice() - ); - } - } - - //set merchant prices - if (ctx->GetOption(RSK_SHUFFLE_MERCHANTS).Is(RO_SHUFFLE_MERCHANTS_BEANS_ONLY) || - ctx->GetOption(RSK_SHUFFLE_MERCHANTS).Is(RO_SHUFFLE_MERCHANTS_ALL)){ - ctx->GetItemLocation(RC_ZR_MAGIC_BEAN_SALESMAN)->SetCustomPrice( - GetRandomPrice(Rando::StaticData::GetLocation(RC_ZR_MAGIC_BEAN_SALESMAN), merchantPrices) - ); - } else { - ctx->GetItemLocation(RC_ZR_MAGIC_BEAN_SALESMAN)->SetCustomPrice( - Rando::StaticData::GetLocation(RC_ZR_MAGIC_BEAN_SALESMAN)->GetVanillaPrice() - ); - } - - auto merchantLoc = Rando::StaticData::GetMerchantLocations(); - - if (ctx->GetOption(RSK_SHUFFLE_MERCHANTS).Is(RO_SHUFFLE_MERCHANTS_ALL_BUT_BEANS) || - ctx->GetOption(RSK_SHUFFLE_MERCHANTS).Is(RO_SHUFFLE_MERCHANTS_ALL)){ - for (size_t i = 0; i < merchantLoc.size(); i++) { - ctx->GetItemLocation(merchantLoc[i])->SetCustomPrice( - GetRandomPrice(Rando::StaticData::GetLocation(merchantLoc[i]), merchantPrices) - ); - } - } else { - for (size_t i = 0; i < merchantLoc.size(); i++) { - ctx->GetItemLocation(merchantLoc[i])->SetCustomPrice( - Rando::StaticData::GetLocation(merchantLoc[i])->GetVanillaPrice() - ); - } - } - StopPerformanceTimer(PT_SHOPSANITY); - - StartPerformanceTimer(PT_OWN_DUNGEON); - //Place dungeon rewards - SPDLOG_INFO("Shuffling and Placing Dungeon Items..."); - RandomizeDungeonRewards(); - - //Place dungeon items restricted to their Own Dungeon - for (auto dungeon : ctx->GetDungeons()->GetDungeonList()) { - RandomizeOwnDungeon(dungeon); - } - StopPerformanceTimer(PT_OWN_DUNGEON); - - StartPerformanceTimer(PT_LIMITED_CHECKS); - //Then Place songs if song shuffle is set to specific locations - if (ctx->GetOption(RSK_SHUFFLE_SONGS).IsNot(RO_SONG_SHUFFLE_ANYWHERE)) { - - //Get each song - std::vector songs = FilterAndEraseFromPool( - ItemPool, [](const auto i) { return Rando::StaticData::RetrieveItem(i).GetItemType() == ITEMTYPE_SONG; }); - - //Get each song location - std::vector songLocations; - if (ctx->GetOption(RSK_SHUFFLE_SONGS).Is(RO_SONG_SHUFFLE_SONG_LOCATIONS)) { - songLocations = FilterFromPool( - ctx->allLocations, [](const auto loc) { return Rando::StaticData::GetLocation(loc)->GetRCType() == RCTYPE_SONG_LOCATION; }); - - } else if (ctx->GetOption(RSK_SHUFFLE_SONGS).Is(RO_SONG_SHUFFLE_DUNGEON_REWARDS)) { - songLocations = FilterFromPool(ctx->allLocations, [](const auto loc) { - return Rando::StaticData::GetLocation(loc)->GetRCType() == RCTYPE_BOSS_HEART_OR_OTHER_REWARD || - loc == RC_SHEIK_IN_ICE_CAVERN || - loc == RC_SONG_FROM_IMPA; - }); - } - - AssumedFill(songs, songLocations, true); - } - - //Then place dungeon items that are assigned to restrictive location pools - RandomizeDungeonItems(); - SPDLOG_INFO("Dungeon Items Done"); - - //Then place Link's Pocket Item if it has to be an advancement item - RandomizeLinksPocket(); - StopPerformanceTimer(PT_LIMITED_CHECKS); - - - StartPerformanceTimer(PT_ADVANCEMENT_ITEMS); - SPDLOG_INFO("Shuffling Advancement Items"); - //Then place the rest of the advancement items - std::vector remainingAdvancementItems = - FilterAndEraseFromPool(ItemPool, [](const auto i) { return Rando::StaticData::RetrieveItem(i).IsAdvancement(); }); - AssumedFill(remainingAdvancementItems, ctx->allLocations, true); - StopPerformanceTimer(PT_ADVANCEMENT_ITEMS); - - StartPerformanceTimer(PT_REMAINING_ITEMS); - //Fast fill for the rest of the pool - SPDLOG_INFO("Shuffling Remaining Items"); - std::vector remainingPool = FilterAndEraseFromPool(ItemPool, [](const auto i) { return true; }); - FastFill(remainingPool, GetAllEmptyLocations(), false); - StopPerformanceTimer(PT_REMAINING_ITEMS); - - - StartPerformanceTimer(PT_PLAYTHROUGH_GENERATION); - GeneratePlaythrough(); - StopPerformanceTimer(PT_PLAYTHROUGH_GENERATION); - //Successful placement, produced beatable result - if(ctx->playthroughBeatable && !placementFailure) { - - SPDLOG_INFO("Calculating Playthrough..."); - StartPerformanceTimer(PT_PARE_DOWN_PLAYTHROUGH); - PareDownPlaythrough(); - StopPerformanceTimer(PT_PARE_DOWN_PLAYTHROUGH); - - StartPerformanceTimer(PT_WOTH); - CalculateWotH(); - StopPerformanceTimer(PT_WOTH); - - StartPerformanceTimer(PT_FOOLISH); - CalculateBarren(); - StopPerformanceTimer(PT_FOOLISH); - SPDLOG_INFO("Calculating Playthrough Done"); - - StartPerformanceTimer(PT_OVERRIDES); - ctx->CreateItemOverrides(); - ctx->GetEntranceShuffler()->CreateEntranceOverrides(); - StopPerformanceTimer(PT_OVERRIDES); - - StartPerformanceTimer(PT_HINTS); - CreateAllHints(); - CreateWarpSongTexts(); - StopPerformanceTimer(PT_HINTS); - SPDLOG_DEBUG("Number of retries {}", retries); - return 1; - } - //Unsuccessful placement - if(retries < 4) { - SPDLOG_DEBUG("Failed to generate a beatable seed. Retrying..."); - Regions::ResetAllLocations(); - logic->Reset(); - ClearProgress(); - } - retries++; - } - //All retries failed - return -1; + // All retries failed + return -1; } diff --git a/soh/soh/Enhancements/randomizer/3drando/hint_list.cpp b/soh/soh/Enhancements/randomizer/3drando/hint_list.cpp index f0d7742f0..5d880f047 100644 --- a/soh/soh/Enhancements/randomizer/3drando/hint_list.cpp +++ b/soh/soh/Enhancements/randomizer/3drando/hint_list.cpp @@ -2422,4 +2422,4 @@ void StaticData::HintTable_Init() { // clang-format on } -} +} // namespace Rando 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 a54de6b64..1347945ec 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 @@ -2227,4 +2227,4 @@ void StaticData::HintTable_Init_Exclude_Dungeon() { // clang-format on } -} +} // namespace Rando 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 6d5242a5d..11d89d837 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 @@ -2017,4 +2017,4 @@ void StaticData::HintTable_Init_Exclude_Overworld() { // clang-format on } -} +} // namespace Rando 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 9f4a0026a..ba0468849 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 @@ -2173,4 +2173,4 @@ void StaticData::HintTable_Init_Item() { // clang-format on } -} +} // namespace Rando diff --git a/soh/soh/Enhancements/randomizer/3drando/hints.cpp b/soh/soh/Enhancements/randomizer/3drando/hints.cpp index 932b97316..c55145fcd 100644 --- a/soh/soh/Enhancements/randomizer/3drando/hints.cpp +++ b/soh/soh/Enhancements/randomizer/3drando/hints.cpp @@ -13,16 +13,11 @@ #include "../hint.h" #include "../static_data.h" - using namespace Rando; -HintDistributionSetting::HintDistributionSetting(std::string _name, - HintType _type, - uint32_t _weight, - uint8_t _fixed, - uint8_t _copies, - std::function _filter, - uint8_t _dungeonLimit){ +HintDistributionSetting::HintDistributionSetting(std::string _name, HintType _type, uint32_t _weight, uint8_t _fixed, + uint8_t _copies, std::function _filter, + uint8_t _dungeonLimit) { name = _name; type = _type; weight = _weight; @@ -30,10 +25,12 @@ HintDistributionSetting::HintDistributionSetting(std::string _name, copies = _copies; filter = _filter; dungeonLimit = _dungeonLimit; - } +} -HintText::HintText(CustomMessage clearText_, std::vector ambiguousText_, std::vector obscureText_) -: clearText(std::move(clearText_)), ambiguousText(std::move(ambiguousText_)), obscureText(std::move(obscureText_)){} +HintText::HintText(CustomMessage clearText_, std::vector ambiguousText_, + std::vector obscureText_) + : clearText(std::move(clearText_)), ambiguousText(std::move(ambiguousText_)), obscureText(std::move(obscureText_)) { +} const CustomMessage& HintText::GetClear() const { return clearText; @@ -44,7 +41,7 @@ const CustomMessage& HintText::GetObscure() const { } const CustomMessage& HintText::GetObscure(uint8_t selection) const { - if (obscureText.size() > selection){ + if (obscureText.size() > selection) { return obscureText[selection]; } else if (obscureText.size() > 0) { return obscureText[0]; @@ -57,7 +54,7 @@ const CustomMessage& HintText::GetAmbiguous() const { } const CustomMessage& HintText::GetAmbiguous(uint8_t selection) const { - if (ambiguousText.size() > selection){ + if (ambiguousText.size() > selection) { return ambiguousText[selection]; } else if (ambiguousText.size() > 0) { return ambiguousText[0]; @@ -65,11 +62,11 @@ const CustomMessage& HintText::GetAmbiguous(uint8_t selection) const { return clearText; } -uint8_t HintText::GetAmbiguousSize() const{ +uint8_t HintText::GetAmbiguousSize() const { return ambiguousText.size(); } -uint8_t HintText::GetObscureSize() const{ +uint8_t HintText::GetObscureSize() const { return obscureText.size(); } @@ -96,66 +93,65 @@ const CustomMessage HintText::GetMessageCopy() const { } bool HintText::operator==(const HintText& right) const { - return obscureText == right.obscureText && - ambiguousText == right.ambiguousText && - clearText == right.clearText; + return obscureText == right.obscureText && ambiguousText == right.ambiguousText && clearText == right.clearText; } bool HintText::operator!=(const HintText& right) const { return !operator==(right); } -StaticHintInfo::StaticHintInfo(HintType _type, std::vector _hintKeys, RandomizerSettingKey _setting, - std::variant _condition, std::vector _targetChecks, - std::vector _targetItems, std::vector _hintChecks, bool _yourPocket, int _num): - type(_type), hintKeys(_hintKeys), setting(_setting), condition(_condition), targetChecks(_targetChecks), - targetItems(_targetItems), hintChecks(_hintChecks), yourPocket(_yourPocket), num(_num){} +StaticHintInfo::StaticHintInfo(HintType _type, std::vector _hintKeys, + RandomizerSettingKey _setting, std::variant _condition, + std::vector _targetChecks, std::vector _targetItems, + std::vector _hintChecks, bool _yourPocket, int _num) + : type(_type), hintKeys(_hintKeys), setting(_setting), condition(_condition), targetChecks(_targetChecks), + targetItems(_targetItems), hintChecks(_hintChecks), yourPocket(_yourPocket), num(_num) { +} -RandomizerHintTextKey GetRandomJunkHint(){ +RandomizerHintTextKey GetRandomJunkHint() { // Temp code to handle random junk hints now I work in keys instead of a vector of HintText // Will be replaced with a better system once more customisable hint pools are added uint32_t range = RHT_JUNK71 - RHT_JUNK01; return (RandomizerHintTextKey)(Random(0, range) + RHT_JUNK01); } -RandomizerHintTextKey GetRandomGanonJoke(){ - uint32_t range = RHT_GANON_JOKE11 - RHT_GANON_JOKE01; - return (RandomizerHintTextKey)(Random(0, range) + RHT_GANON_JOKE01); +RandomizerHintTextKey GetRandomGanonJoke() { + uint32_t range = RHT_GANON_JOKE11 - RHT_GANON_JOKE01; + return (RandomizerHintTextKey)(Random(0, range) + RHT_GANON_JOKE01); } - -bool FilterWotHLocations(RandomizerCheck loc){ - auto ctx = Rando::Context::GetInstance(); - return ctx->GetItemLocation(loc)->IsWothCandidate(); +bool FilterWotHLocations(RandomizerCheck loc) { + auto ctx = Rando::Context::GetInstance(); + return ctx->GetItemLocation(loc)->IsWothCandidate(); } -bool FilterFoolishLocations(RandomizerCheck loc){ - auto ctx = Rando::Context::GetInstance(); - return ctx->GetItemLocation(loc)->IsFoolishCandidate(); +bool FilterFoolishLocations(RandomizerCheck loc) { + auto ctx = Rando::Context::GetInstance(); + return ctx->GetItemLocation(loc)->IsFoolishCandidate(); } -bool FilterSongLocations(RandomizerCheck loc){ - auto ctx = Rando::Context::GetInstance(); - return Rando::StaticData::GetLocation(loc)->GetRCType() == RCTYPE_SONG_LOCATION; +bool FilterSongLocations(RandomizerCheck loc) { + auto ctx = Rando::Context::GetInstance(); + return Rando::StaticData::GetLocation(loc)->GetRCType() == RCTYPE_SONG_LOCATION; } -bool FilterOverworldLocations(RandomizerCheck loc){ - auto ctx = Rando::Context::GetInstance(); - return Rando::StaticData::GetLocation(loc)->IsOverworld(); +bool FilterOverworldLocations(RandomizerCheck loc) { + auto ctx = Rando::Context::GetInstance(); + return Rando::StaticData::GetLocation(loc)->IsOverworld(); } -bool FilterDungeonLocations(RandomizerCheck loc){ - auto ctx = Rando::Context::GetInstance(); - return Rando::StaticData::GetLocation(loc)->IsDungeon(); +bool FilterDungeonLocations(RandomizerCheck loc) { + auto ctx = Rando::Context::GetInstance(); + return Rando::StaticData::GetLocation(loc)->IsDungeon(); } -bool FilterGoodItems(RandomizerCheck loc){ - auto ctx = Rando::Context::GetInstance(); - return ctx->GetItemLocation(loc)->GetPlacedItem().IsMajorItem(); +bool FilterGoodItems(RandomizerCheck loc) { + auto ctx = Rando::Context::GetInstance(); + return ctx->GetItemLocation(loc)->GetPlacedItem().IsMajorItem(); } -bool NoFilter(RandomizerCheck loc){ - return true; +bool NoFilter(RandomizerCheck loc) { + return true; } const std::array hintSettingTable{{ @@ -225,15 +221,16 @@ uint8_t StonesRequiredBySettings() { stones = ctx->GetOption(RSK_RAINBOW_BRIDGE_STONE_COUNT).Get(); } else if (ctx->GetOption(RSK_RAINBOW_BRIDGE).Is(RO_BRIDGE_DUNGEON_REWARDS)) { stones = ctx->GetOption(RSK_RAINBOW_BRIDGE_REWARD_COUNT).Get() - 6; - } else if ((ctx->GetOption(RSK_RAINBOW_BRIDGE).Is(RO_BRIDGE_DUNGEONS)) && (ctx->GetOption(RSK_SHUFFLE_DUNGEON_REWARDS).Is(RO_DUNGEON_REWARDS_END_OF_DUNGEON))) { + } else if ((ctx->GetOption(RSK_RAINBOW_BRIDGE).Is(RO_BRIDGE_DUNGEONS)) && + (ctx->GetOption(RSK_SHUFFLE_DUNGEON_REWARDS).Is(RO_DUNGEON_REWARDS_END_OF_DUNGEON))) { stones = ctx->GetOption(RSK_RAINBOW_BRIDGE_DUNGEON_COUNT).Get() - 6; } if (ctx->GetOption(RSK_GANONS_BOSS_KEY).Is(RO_GANON_BOSS_KEY_LACS_STONES)) { stones = std::max({ stones, ctx->GetOption(RSK_LACS_STONE_COUNT).Get() }); } else if (ctx->GetOption(RSK_GANONS_BOSS_KEY).Is(RO_GANON_BOSS_KEY_LACS_STONES)) { - stones = std::max({ stones, (uint8_t)(ctx->GetOption(RSK_LACS_REWARD_COUNT).Get() - 6 )}); + stones = std::max({ stones, (uint8_t)(ctx->GetOption(RSK_LACS_REWARD_COUNT).Get() - 6) }); } else if (ctx->GetOption(RSK_GANONS_BOSS_KEY).Is(RO_GANON_BOSS_KEY_LACS_DUNGEONS)) { - stones = std::max({ stones, (uint8_t)(ctx->GetOption(RSK_LACS_DUNGEON_COUNT).Get() - 6 )}); + stones = std::max({ stones, (uint8_t)(ctx->GetOption(RSK_LACS_DUNGEON_COUNT).Get() - 6) }); } return stones; } @@ -245,15 +242,17 @@ uint8_t MedallionsRequiredBySettings() { medallions = ctx->GetOption(RSK_RAINBOW_BRIDGE_MEDALLION_COUNT).Get(); } else if (ctx->GetOption(RSK_RAINBOW_BRIDGE).Is(RO_BRIDGE_DUNGEON_REWARDS)) { medallions = ctx->GetOption(RSK_RAINBOW_BRIDGE_REWARD_COUNT).Get() - 3; - } else if (ctx->GetOption(RSK_RAINBOW_BRIDGE).Is(RO_BRIDGE_DUNGEONS) && ctx->GetOption(RSK_SHUFFLE_DUNGEON_REWARDS).Is(RO_DUNGEON_REWARDS_END_OF_DUNGEON)) { + } else if (ctx->GetOption(RSK_RAINBOW_BRIDGE).Is(RO_BRIDGE_DUNGEONS) && + ctx->GetOption(RSK_SHUFFLE_DUNGEON_REWARDS).Is(RO_DUNGEON_REWARDS_END_OF_DUNGEON)) { medallions = ctx->GetOption(RSK_RAINBOW_BRIDGE_DUNGEON_COUNT).Get() - 3; } if (ctx->GetOption(RSK_GANONS_BOSS_KEY).Is(RO_GANON_BOSS_KEY_LACS_MEDALLIONS)) { medallions = std::max({ medallions, ctx->GetOption(RSK_LACS_MEDALLION_COUNT).Get() }); } else if (ctx->GetOption(RSK_GANONS_BOSS_KEY).Is(RO_GANON_BOSS_KEY_LACS_REWARDS)) { - medallions = std::max({ medallions, (uint8_t)(ctx->GetOption(RSK_LACS_REWARD_COUNT).Get() - 3 )}); - } else if (ctx->GetOption(RSK_GANONS_BOSS_KEY).Is(RO_GANON_BOSS_KEY_LACS_DUNGEONS) && ctx->GetOption(RSK_SHUFFLE_DUNGEON_REWARDS).Is(RO_DUNGEON_REWARDS_END_OF_DUNGEON)) { - medallions = std::max({ medallions, (uint8_t)(ctx->GetOption(RSK_LACS_DUNGEON_COUNT).Get() - 3 )}); + medallions = std::max({ medallions, (uint8_t)(ctx->GetOption(RSK_LACS_REWARD_COUNT).Get() - 3) }); + } else if (ctx->GetOption(RSK_GANONS_BOSS_KEY).Is(RO_GANON_BOSS_KEY_LACS_DUNGEONS) && + ctx->GetOption(RSK_SHUFFLE_DUNGEON_REWARDS).Is(RO_DUNGEON_REWARDS_END_OF_DUNGEON)) { + medallions = std::max({ medallions, (uint8_t)(ctx->GetOption(RSK_LACS_DUNGEON_COUNT).Get() - 3) }); } return medallions; } @@ -271,555 +270,601 @@ uint8_t TokensRequiredBySettings() { } std::vector>> conditionalAlwaysHints = { - std::make_pair(RC_MARKET_10_BIG_POES, []() { + std::make_pair(RC_MARKET_10_BIG_POES, + []() { auto ctx = Rando::Context::GetInstance(); return ctx->GetOption(RSK_BIG_POE_COUNT).Get() >= 3 && !ctx->GetOption(RSK_BIG_POES_HINT); }), // Remember, the option's value being 3 means 4 are required - std::make_pair(RC_DEKU_THEATER_MASK_OF_TRUTH, []() { + std::make_pair(RC_DEKU_THEATER_MASK_OF_TRUTH, + []() { auto ctx = Rando::Context::GetInstance(); return !ctx->GetOption(RSK_MASK_SHOP_HINT) && !ctx->GetOption(RSK_COMPLETE_MASK_QUEST); }), - std::make_pair(RC_SONG_FROM_OCARINA_OF_TIME, []() { - auto ctx = Rando::Context::GetInstance(); - return StonesRequiredBySettings() < 2 && !ctx->GetOption(RSK_OOT_HINT); + std::make_pair(RC_SONG_FROM_OCARINA_OF_TIME, + []() { + auto ctx = Rando::Context::GetInstance(); + return StonesRequiredBySettings() < 2 && !ctx->GetOption(RSK_OOT_HINT); }), std::make_pair(RC_HF_OCARINA_OF_TIME_ITEM, []() { return StonesRequiredBySettings() < 2; }), std::make_pair(RC_SHEIK_IN_KAKARIKO, []() { return MedallionsRequiredBySettings() < 5; }), - std::make_pair(RC_DMT_TRADE_CLAIM_CHECK, []() { + std::make_pair(RC_DMT_TRADE_CLAIM_CHECK, + []() { auto ctx = Rando::Context::GetInstance(); return !ctx->GetOption(RSK_BIGGORON_HINT); }), - std::make_pair(RC_KAK_30_GOLD_SKULLTULA_REWARD, []() { + std::make_pair(RC_KAK_30_GOLD_SKULLTULA_REWARD, + []() { auto ctx = Rando::Context::GetInstance(); return !ctx->GetOption(RSK_KAK_30_SKULLS_HINT) && TokensRequiredBySettings() < 30; }), - std::make_pair(RC_KAK_40_GOLD_SKULLTULA_REWARD, []() { + std::make_pair(RC_KAK_40_GOLD_SKULLTULA_REWARD, + []() { auto ctx = Rando::Context::GetInstance(); return !ctx->GetOption(RSK_KAK_40_SKULLS_HINT) && TokensRequiredBySettings() < 40; }), - std::make_pair(RC_KAK_50_GOLD_SKULLTULA_REWARD, []() { + std::make_pair(RC_KAK_50_GOLD_SKULLTULA_REWARD, + []() { auto ctx = Rando::Context::GetInstance(); return !ctx->GetOption(RSK_KAK_50_SKULLS_HINT) && TokensRequiredBySettings() < 50; }), - std::make_pair(RC_ZR_FROGS_OCARINA_GAME, []() { + std::make_pair(RC_ZR_FROGS_OCARINA_GAME, + []() { auto ctx = Rando::Context::GetInstance(); return !ctx->GetOption(RSK_FROGS_HINT); }), - std::make_pair(RC_KF_LINKS_HOUSE_COW, []() { + std::make_pair(RC_KF_LINKS_HOUSE_COW, + []() { auto ctx = Rando::Context::GetInstance(); return !ctx->GetOption(RSK_MALON_HINT); }), - std::make_pair(RC_KAK_100_GOLD_SKULLTULA_REWARD, []() { + std::make_pair(RC_KAK_100_GOLD_SKULLTULA_REWARD, + []() { auto ctx = Rando::Context::GetInstance(); return !ctx->GetOption(RSK_KAK_100_SKULLS_HINT) && TokensRequiredBySettings() < 100; }), }; static std::vector GetEmptyGossipStones() { - auto emptyGossipStones = GetEmptyLocations(Rando::StaticData::GetGossipStoneLocations()); - return emptyGossipStones; + auto emptyGossipStones = GetEmptyLocations(Rando::StaticData::GetGossipStoneLocations()); + return emptyGossipStones; } static std::vector GetAccessibleGossipStones(const RandomizerCheck hintedLocation = RC_GANON) { - auto ctx = Rando::Context::GetInstance(); - //temporarily remove the hinted location's item, and then perform a - //reachability search for gossip stone locations. - RandomizerGet originalItem = ctx->GetItemLocation(hintedLocation)->GetPlacedRandomizerGet(); - ctx->GetItemLocation(hintedLocation)->SetPlacedItem(RG_NONE); + auto ctx = Rando::Context::GetInstance(); + // temporarily remove the hinted location's item, and then perform a + // reachability search for gossip stone locations. + RandomizerGet originalItem = ctx->GetItemLocation(hintedLocation)->GetPlacedRandomizerGet(); + ctx->GetItemLocation(hintedLocation)->SetPlacedItem(RG_NONE); - ctx->GetLogic()->Reset(); - auto accessibleGossipStones = ReachabilitySearch(Rando::StaticData::GetGossipStoneLocations()); - //Give the item back to the location - ctx->GetItemLocation(hintedLocation)->SetPlacedItem(originalItem); - - return accessibleGossipStones; -} - -bool IsReachableWithout(std::vector locsToCheck, RandomizerCheck excludedCheck, bool resetAfter = true){ - //temporarily remove the hinted location's item, and then perform a - //reachability search for this check RANDOTODO convert excludedCheck to an ItemLocation - auto ctx = Rando::Context::GetInstance(); - RandomizerGet originalItem = ctx->GetItemLocation(excludedCheck)->GetPlacedRandomizerGet(); - ctx->GetItemLocation(excludedCheck)->SetPlacedItem(RG_NONE); - ctx->GetLogic()->Reset(); - const auto rechableWithout = ReachabilitySearch(locsToCheck); - ctx->GetItemLocation(excludedCheck)->SetPlacedItem(originalItem); - if (resetAfter){ - //if resetAfter is on, reset logic we are done ctx->GetLogic()->Reset(); - } - if (rechableWithout.empty()) { - return false; - } - return true; + auto accessibleGossipStones = ReachabilitySearch(Rando::StaticData::GetGossipStoneLocations()); + // Give the item back to the location + ctx->GetItemLocation(hintedLocation)->SetPlacedItem(originalItem); + + return accessibleGossipStones; } -static void SetAllInAreaAsHintAccesible(RandomizerArea area, std::vector locations){ - auto ctx = Rando::Context::GetInstance(); - std::vector locsInArea = FilterFromPool(locations, [area, ctx](const RandomizerCheck loc){ - return ctx->GetItemLocation(loc)->GetAreas().contains(area); - }); - for(RandomizerCheck loc: locsInArea){ - ctx->GetItemLocation(loc)->SetHintAccesible(); - } +bool IsReachableWithout(std::vector locsToCheck, RandomizerCheck excludedCheck, + bool resetAfter = true) { + // temporarily remove the hinted location's item, and then perform a + // reachability search for this check RANDOTODO convert excludedCheck to an ItemLocation + auto ctx = Rando::Context::GetInstance(); + RandomizerGet originalItem = ctx->GetItemLocation(excludedCheck)->GetPlacedRandomizerGet(); + ctx->GetItemLocation(excludedCheck)->SetPlacedItem(RG_NONE); + ctx->GetLogic()->Reset(); + const auto rechableWithout = ReachabilitySearch(locsToCheck); + ctx->GetItemLocation(excludedCheck)->SetPlacedItem(originalItem); + if (resetAfter) { + // if resetAfter is on, reset logic we are done + ctx->GetLogic()->Reset(); + } + if (rechableWithout.empty()) { + return false; + } + return true; } -static void AddGossipStoneHint( const RandomizerCheck gossipStone, - const HintType hintType, - const std::string distributionName, - const std::vector hintKeys, - const std::vector locations, - const std::vector areas, - const std::vector trials) { - auto ctx = Rando::Context::GetInstance(); - ctx->AddHint(StaticData::gossipStoneCheckToHint[gossipStone], Hint(StaticData::gossipStoneCheckToHint[gossipStone], hintType, distributionName, hintKeys, locations, areas, trials)); - ctx->GetItemLocation(gossipStone)->SetPlacedItem(RG_HINT); //RANDOTODO, better gossip stone to location to hint key system +static void SetAllInAreaAsHintAccesible(RandomizerArea area, std::vector locations) { + auto ctx = Rando::Context::GetInstance(); + std::vector locsInArea = FilterFromPool(locations, [area, ctx](const RandomizerCheck loc) { + return ctx->GetItemLocation(loc)->GetAreas().contains(area); + }); + for (RandomizerCheck loc : locsInArea) { + ctx->GetItemLocation(loc)->SetHintAccesible(); + } } -static void AddGossipStoneHintCopies(uint8_t copies, - const HintType hintType, - const std::string distributionName, +static void AddGossipStoneHint(const RandomizerCheck gossipStone, const HintType hintType, + const std::string distributionName, const std::vector hintKeys, + const std::vector locations, const std::vector areas, + const std::vector trials) { + auto ctx = Rando::Context::GetInstance(); + ctx->AddHint(StaticData::gossipStoneCheckToHint[gossipStone], + Hint(StaticData::gossipStoneCheckToHint[gossipStone], hintType, distributionName, hintKeys, locations, + areas, trials)); + ctx->GetItemLocation(gossipStone) + ->SetPlacedItem(RG_HINT); // RANDOTODO, better gossip stone to location to hint key system +} + +static void AddGossipStoneHintCopies(uint8_t copies, const HintType hintType, const std::string distributionName, const std::vector hintKeys = {}, const std::vector locations = {}, const std::vector areas = {}, const std::vector trials = {}, - RandomizerCheck firstStone = RC_UNKNOWN_CHECK){ + RandomizerCheck firstStone = RC_UNKNOWN_CHECK) { - if (firstStone != RC_UNKNOWN_CHECK && copies > 0){ - AddGossipStoneHint(firstStone, hintType, distributionName, hintKeys, locations, areas, trials); - copies -= 1; - } - for(int c=0; c 0) { + AddGossipStoneHint(firstStone, hintType, distributionName, hintKeys, locations, areas, trials); + copies -= 1; + } + for (int c = 0; c < copies; c++) { + // get a random gossip stone + auto gossipStones = GetEmptyGossipStones(); + if (gossipStones.empty()) { + SPDLOG_DEBUG("\tNO GOSSIP STONES TO PLACE HINT\n\n"); + return; + } + auto gossipStone = RandomElement(gossipStones, false); + AddGossipStoneHint(gossipStone, hintType, distributionName, hintKeys, locations, areas, trials); } - auto gossipStone = RandomElement(gossipStones, false); - AddGossipStoneHint(gossipStone, hintType, distributionName, hintKeys, locations, areas, trials); - } } -static bool CreateHint(RandomizerCheck location, uint8_t copies, HintType type, std::string distribution){ - auto ctx = Rando::Context::GetInstance(); +static bool CreateHint(RandomizerCheck location, uint8_t copies, HintType type, std::string distribution) { + auto ctx = Rando::Context::GetInstance(); - //get a gossip stone accessible without the hinted item - std::vector gossipStoneLocations = GetAccessibleGossipStones(location); - if (gossipStoneLocations.empty()) { - SPDLOG_DEBUG("\tNO IN LOGIC GOSSIP STONE\n\n"); - return false; - } - RandomizerCheck gossipStone = RandomElement(gossipStoneLocations); - RandomizerArea area = ctx->GetItemLocation(location)->GetRandomArea(); + // get a gossip stone accessible without the hinted item + std::vector gossipStoneLocations = GetAccessibleGossipStones(location); + if (gossipStoneLocations.empty()) { + SPDLOG_DEBUG("\tNO IN LOGIC GOSSIP STONE\n\n"); + return false; + } + RandomizerCheck gossipStone = RandomElement(gossipStoneLocations); + RandomizerArea area = ctx->GetItemLocation(location)->GetRandomArea(); - //Set that hints are accesible - ctx->GetItemLocation(location)->SetHintAccesible(); - if (type == HINT_TYPE_FOOLISH){ - SetAllInAreaAsHintAccesible(area, ctx->allLocations); - } + // Set that hints are accesible + ctx->GetItemLocation(location)->SetHintAccesible(); + if (type == HINT_TYPE_FOOLISH) { + SetAllInAreaAsHintAccesible(area, ctx->allLocations); + } - AddGossipStoneHintCopies(copies, type, distribution, {}, {location}, {area}, {}, gossipStone); - return true; + AddGossipStoneHintCopies(copies, type, distribution, {}, { location }, { area }, {}, gossipStone); + return true; } +static RandomizerCheck CreateRandomHint(std::vector& possibleHintLocations, uint8_t copies, + HintType type, std::string distributionName) { + auto ctx = Rando::Context::GetInstance(); -static RandomizerCheck CreateRandomHint(std::vector& possibleHintLocations, - uint8_t copies, - HintType type, - std::string distributionName) { - auto ctx = Rando::Context::GetInstance(); - - //return if there aren't any hintable locations or gossip stones available - if (GetEmptyGossipStones().size() < copies) { - SPDLOG_DEBUG("\tNOT ENOUGH GOSSIP STONES TO PLACE HINTS\n\n"); - return RC_UNKNOWN_CHECK; - } - - RandomizerCheck hintedLocation; - bool placed = false; - while (!placed){ - if (possibleHintLocations.empty()) { - SPDLOG_DEBUG("\tNO LOCATIONS TO HINT\n\n"); - return RC_UNKNOWN_CHECK; + // return if there aren't any hintable locations or gossip stones available + if (GetEmptyGossipStones().size() < copies) { + SPDLOG_DEBUG("\tNOT ENOUGH GOSSIP STONES TO PLACE HINTS\n\n"); + return RC_UNKNOWN_CHECK; } - hintedLocation = RandomElement(possibleHintLocations, true); //removing the location to avoid it being hinted again on fail - - SPDLOG_DEBUG("\tLocation: "); - SPDLOG_DEBUG(Rando::StaticData::GetLocation(hintedLocation)->GetName()); - SPDLOG_DEBUG("\n"); - SPDLOG_DEBUG("\tItem: "); - SPDLOG_DEBUG(ctx->GetItemLocation(hintedLocation)->GetPlacedItemName().GetEnglish()); - SPDLOG_DEBUG("\n"); + RandomizerCheck hintedLocation; + bool placed = false; + while (!placed) { + if (possibleHintLocations.empty()) { + SPDLOG_DEBUG("\tNO LOCATIONS TO HINT\n\n"); + return RC_UNKNOWN_CHECK; + } + hintedLocation = + RandomElement(possibleHintLocations, true); // removing the location to avoid it being hinted again on fail - placed = CreateHint(hintedLocation, copies, type, distributionName); - } - return hintedLocation; + SPDLOG_DEBUG("\tLocation: "); + SPDLOG_DEBUG(Rando::StaticData::GetLocation(hintedLocation)->GetName()); + SPDLOG_DEBUG("\n"); + + SPDLOG_DEBUG("\tItem: "); + SPDLOG_DEBUG(ctx->GetItemLocation(hintedLocation)->GetPlacedItemName().GetEnglish()); + SPDLOG_DEBUG("\n"); + + placed = CreateHint(hintedLocation, copies, type, distributionName); + } + return hintedLocation; } static std::vector FilterHintability(std::vector& locations, - std::function extraFilter = NoFilter){ - auto ctx = Rando::Context::GetInstance(); - return FilterFromPool(locations, [extraFilter, ctx](const RandomizerCheck loc) { - return ctx->GetItemLocation(loc)->IsHintable() && !(ctx->GetItemLocation(loc)->IsAHintAccessible()) - && extraFilter(loc); - }); + std::function extraFilter = NoFilter) { + auto ctx = Rando::Context::GetInstance(); + return FilterFromPool(locations, [extraFilter, ctx](const RandomizerCheck loc) { + return ctx->GetItemLocation(loc)->IsHintable() && !(ctx->GetItemLocation(loc)->IsAHintAccessible()) && + extraFilter(loc); + }); } static void CreateJunkHints(uint8_t numHints) { - for(uint8_t c = 0; c < numHints; c++){ - //duplicate junk hints are possible for now - AddGossipStoneHintCopies(1, HINT_TYPE_HINT_KEY, "Junk", {GetRandomJunkHint()}); - } + for (uint8_t c = 0; c < numHints; c++) { + // duplicate junk hints are possible for now + AddGossipStoneHintCopies(1, HINT_TYPE_HINT_KEY, "Junk", { GetRandomJunkHint() }); + } } static void CreateTrialHints(uint8_t copies) { - if (copies > 0) { - auto ctx = Rando::Context::GetInstance(); - if (ctx->GetOption(RSK_TRIAL_COUNT).Is(6)) {//six trials - AddGossipStoneHintCopies(copies, HINT_TYPE_HINT_KEY, "Trial", {RHT_SIX_TRIALS}); - } else if (ctx->GetOption(RSK_TRIAL_COUNT).Is(0)) {//zero trials - AddGossipStoneHintCopies(copies, HINT_TYPE_HINT_KEY, "Trial", {RHT_ZERO_TRIALS}); - } else { - std::vector trials = ctx->GetTrials()->GetTrialList(); //there's probably a way to remove this assignment - if (ctx->GetOption(RSK_TRIAL_COUNT).Get() >= 4) {//4 or 5 required trials, get skipped trials - trials = FilterFromPool(trials, [](TrialInfo* trial){return trial->IsSkipped();}); - } else {//1 to 3 trials, get requried trials - auto requiredTrials = FilterFromPool(trials, [](TrialInfo* trial){return trial->IsRequired();}); - } - for (auto& trial : trials) {//create a hint for each hinted trial - AddGossipStoneHintCopies(copies, HINT_TYPE_TRIAL, "Trial", {}, {}, {}, {trial->GetTrialKey()}); - } + if (copies > 0) { + auto ctx = Rando::Context::GetInstance(); + if (ctx->GetOption(RSK_TRIAL_COUNT).Is(6)) { // six trials + AddGossipStoneHintCopies(copies, HINT_TYPE_HINT_KEY, "Trial", { RHT_SIX_TRIALS }); + } else if (ctx->GetOption(RSK_TRIAL_COUNT).Is(0)) { // zero trials + AddGossipStoneHintCopies(copies, HINT_TYPE_HINT_KEY, "Trial", { RHT_ZERO_TRIALS }); + } else { + std::vector trials = + ctx->GetTrials()->GetTrialList(); // there's probably a way to remove this assignment + if (ctx->GetOption(RSK_TRIAL_COUNT).Get() >= 4) { // 4 or 5 required trials, get skipped trials + trials = FilterFromPool(trials, [](TrialInfo* trial) { return trial->IsSkipped(); }); + } else { // 1 to 3 trials, get requried trials + auto requiredTrials = FilterFromPool(trials, [](TrialInfo* trial) { return trial->IsRequired(); }); + } + for (auto& trial : trials) { // create a hint for each hinted trial + AddGossipStoneHintCopies(copies, HINT_TYPE_TRIAL, "Trial", {}, {}, {}, { trial->GetTrialKey() }); + } + } } - } } void CreateWarpSongTexts() { - auto ctx = Rando::Context::GetInstance(); - if (ctx->GetOption(RSK_WARP_SONG_HINTS)){ - auto warpSongEntrances = GetShuffleableEntrances(EntranceType::WarpSong, false); - for (auto entrance : warpSongEntrances) { - //RANDOTODO make random - RandomizerArea destination = entrance->GetConnectedRegion()->GetFirstArea(); - switch (entrance->GetIndex()) { - case 0x0600: // minuet RANDOTODO make into entrance hints when they are added - ctx->AddHint(RH_MINUET_WARP_LOC, Hint(RH_MINUET_WARP_LOC, HINT_TYPE_AREA, "", {RHT_WARP_SONG}, {}, {destination})); - break; - case 0x04F6: // bolero - ctx->AddHint(RH_BOLERO_WARP_LOC, Hint(RH_BOLERO_WARP_LOC, HINT_TYPE_AREA, "", {RHT_WARP_SONG}, {}, {destination})); - break; - case 0x0604: // serenade - ctx->AddHint(RH_SERENADE_WARP_LOC, Hint(RH_SERENADE_WARP_LOC, HINT_TYPE_AREA, "", {RHT_WARP_SONG}, {}, {destination})); - break; - case 0x01F1: // requiem - ctx->AddHint(RH_REQUIEM_WARP_LOC, Hint(RH_REQUIEM_WARP_LOC, HINT_TYPE_AREA, "", {RHT_WARP_SONG}, {}, {destination})); - break; - case 0x0568: // nocturne - ctx->AddHint(RH_NOCTURNE_WARP_LOC, Hint(RH_NOCTURNE_WARP_LOC, HINT_TYPE_AREA, "", {RHT_WARP_SONG}, {}, {destination})); - break; - case 0x05F4: // prelude - ctx->AddHint(RH_PRELUDE_WARP_LOC, Hint(RH_PRELUDE_WARP_LOC, HINT_TYPE_AREA, "", {RHT_WARP_SONG}, {}, {destination})); - break; - default: - break; - } - } - } -} - -int32_t getRandomWeight(int32_t totalWeight){ - if (totalWeight <= 1){ - return 1; - } - return Random(1,totalWeight); -} - -static void DistributeHints(std::vector& selected, size_t stoneCount, std::vector distTable, uint8_t junkWieght, bool addFixed = true){ - int32_t totalWeight = junkWieght; //Start with our Junk Weight, the natural chance of a junk hint - - for (size_t c=0; c < distTable.size(); c++){ //Gather the weights of each distribution and, if it's the first pass, apply fixed hints - totalWeight += distTable[c].weight; //Note that PlaceHints will set weights of distributions to zero if it can't place anything from them - if (addFixed){ - selected[c] += distTable[c].fixed; - stoneCount -= distTable[c].fixed * distTable[c].copies; - } - } - int32_t currentWeight = getRandomWeight(totalWeight); //Initialise with the first random weight from 1 to the total. - while(stoneCount > 0 && totalWeight > 0){//Loop until we run out of stones or have no TotalWeight. 0 totalWeight means junkWeight is 0 - //and that all weights have been 0'd out for another reason, and skips to placing all junk hints - for (size_t distribution = 0; distribution < distTable.size(); distribution++){ - currentWeight -= distTable[distribution].weight; //go over each distribution, subtracting the weight each time. Once we reach zero or less, - if (currentWeight <= 0){ //tell the system to make 1 of that hint, unless not enough stones remain - if (stoneCount >= distTable[distribution].copies && distTable[distribution].copies > 0){ - selected[distribution] += 1; //if we have enough stones, and copies are not zero, assign 1 to this hint type, remove the stones, and break - stoneCount -= distTable[distribution].copies; - break; //This leaves the whole for loop - } else { //If we don't have the stones, or copies is 0 despite there being the wieght to trigger a hit, temporerally set wieght to zero - totalWeight -= distTable[distribution].weight; //Unlike PlaceHint, distTable is passed by value here, making this temporary - distTable[distribution].weight = 0; //this is so we can still roll this hint type if more stones free up later - break; + auto ctx = Rando::Context::GetInstance(); + if (ctx->GetOption(RSK_WARP_SONG_HINTS)) { + auto warpSongEntrances = GetShuffleableEntrances(EntranceType::WarpSong, false); + for (auto entrance : warpSongEntrances) { + // RANDOTODO make random + RandomizerArea destination = entrance->GetConnectedRegion()->GetFirstArea(); + switch (entrance->GetIndex()) { + case 0x0600: // minuet RANDOTODO make into entrance hints when they are added + ctx->AddHint(RH_MINUET_WARP_LOC, + Hint(RH_MINUET_WARP_LOC, HINT_TYPE_AREA, "", { RHT_WARP_SONG }, {}, { destination })); + break; + case 0x04F6: // bolero + ctx->AddHint(RH_BOLERO_WARP_LOC, + Hint(RH_BOLERO_WARP_LOC, HINT_TYPE_AREA, "", { RHT_WARP_SONG }, {}, { destination })); + break; + case 0x0604: // serenade + ctx->AddHint(RH_SERENADE_WARP_LOC, Hint(RH_SERENADE_WARP_LOC, HINT_TYPE_AREA, "", { RHT_WARP_SONG }, + {}, { destination })); + break; + case 0x01F1: // requiem + ctx->AddHint(RH_REQUIEM_WARP_LOC, + Hint(RH_REQUIEM_WARP_LOC, HINT_TYPE_AREA, "", { RHT_WARP_SONG }, {}, { destination })); + break; + case 0x0568: // nocturne + ctx->AddHint(RH_NOCTURNE_WARP_LOC, Hint(RH_NOCTURNE_WARP_LOC, HINT_TYPE_AREA, "", { RHT_WARP_SONG }, + {}, { destination })); + break; + case 0x05F4: // prelude + ctx->AddHint(RH_PRELUDE_WARP_LOC, + Hint(RH_PRELUDE_WARP_LOC, HINT_TYPE_AREA, "", { RHT_WARP_SONG }, {}, { destination })); + break; + default: + break; + } } - } } - //if there's still weight then it's junk, as the leftover weight is junkWeight - if (currentWeight > 0){ //zero TotalWeight breaks the while loop and hits the fallback, so skipping this is fine in that case - selected[selected.size()-1] += 1; - stoneCount -= 1; - } - currentWeight = getRandomWeight(totalWeight); - } - //if stones are left, assign junk to every remaining stone as a fallback. - if (stoneCount > 0){ - selected[selected.size()-1] += stoneCount; - } } -uint8_t PlaceHints(std::vector& selectedHints, std::vector& distTable){ - auto ctx = Rando::Context::GetInstance(); - uint8_t curSlot = 0; - for (HintDistributionSetting distribution : distTable){ - std::vector hintTypePool = FilterHintability(ctx->allLocations, distribution.filter); - for (uint8_t numHint = 0; numHint < selectedHints[curSlot]; numHint++){ - hintTypePool = FilterHintability(hintTypePool); - SPDLOG_DEBUG("Attempting to make hint of type: " + StaticData::hintTypeNames[distribution.type].GetEnglish(MF_CLEAN) + "\n"); - RandomizerCheck hintedLocation = RC_UNKNOWN_CHECK; - - hintedLocation = CreateRandomHint(hintTypePool, distribution.copies, distribution.type, distribution.name); - - if (hintedLocation == RC_UNKNOWN_CHECK){ //if hint failed to place, remove all wieght and copies then return the number of stones to redistribute - uint8_t hintsToRemove = (selectedHints[curSlot] - numHint) * distribution.copies; - selectedHints[curSlot] = 0; //as distTable is passed by refernce here, these changes stick for the rest of this seed generation - distTable[curSlot].copies = 0;//and prevent future distribution from choosing this slot - distTable[curSlot].weight = 0; - return hintsToRemove; - } - if(Rando::StaticData::GetLocation(hintedLocation)->IsDungeon()){ - distribution.dungeonLimit -= 1; - if (distribution.dungeonLimit == 0){ - FilterFromPool(hintTypePool, FilterOverworldLocations); - } - } +int32_t getRandomWeight(int32_t totalWeight) { + if (totalWeight <= 1) { + return 1; } - selectedHints[curSlot] = 0; - curSlot += 1; - } - CreateJunkHints(selectedHints[selectedHints.size() - 1]); - return 0; + return Random(1, totalWeight); +} + +static void DistributeHints(std::vector& selected, size_t stoneCount, + std::vector distTable, uint8_t junkWieght, bool addFixed = true) { + int32_t totalWeight = junkWieght; // Start with our Junk Weight, the natural chance of a junk hint + + for (size_t c = 0; c < distTable.size(); + c++) { // Gather the weights of each distribution and, if it's the first pass, apply fixed hints + totalWeight += distTable[c].weight; // Note that PlaceHints will set weights of distributions to zero if it + // can't place anything from them + if (addFixed) { + selected[c] += distTable[c].fixed; + stoneCount -= distTable[c].fixed * distTable[c].copies; + } + } + int32_t currentWeight = getRandomWeight(totalWeight); // Initialise with the first random weight from 1 to the + // total. + while (stoneCount > 0 && + totalWeight > + 0) { // Loop until we run out of stones or have no TotalWeight. 0 totalWeight means junkWeight is 0 + // and that all weights have been 0'd out for another reason, and skips to placing all junk hints + for (size_t distribution = 0; distribution < distTable.size(); distribution++) { + currentWeight -= + distTable[distribution] + .weight; // go over each distribution, subtracting the weight each time. Once we reach zero or less, + if (currentWeight <= 0) { // tell the system to make 1 of that hint, unless not enough stones remain + if (stoneCount >= distTable[distribution].copies && distTable[distribution].copies > 0) { + selected[distribution] += 1; // if we have enough stones, and copies are not zero, assign 1 to this + // hint type, remove the stones, and break + stoneCount -= distTable[distribution].copies; + break; // This leaves the whole for loop + } else { // If we don't have the stones, or copies is 0 despite there being the wieght to trigger a hit, + // temporerally set wieght to zero + totalWeight -= + distTable[distribution] + .weight; // Unlike PlaceHint, distTable is passed by value here, making this temporary + distTable[distribution].weight = + 0; // this is so we can still roll this hint type if more stones free up later + break; + } + } + } + // if there's still weight then it's junk, as the leftover weight is junkWeight + if (currentWeight > + 0) { // zero TotalWeight breaks the while loop and hits the fallback, so skipping this is fine in that case + selected[selected.size() - 1] += 1; + stoneCount -= 1; + } + currentWeight = getRandomWeight(totalWeight); + } + // if stones are left, assign junk to every remaining stone as a fallback. + if (stoneCount > 0) { + selected[selected.size() - 1] += stoneCount; + } +} + +uint8_t PlaceHints(std::vector& selectedHints, std::vector& distTable) { + auto ctx = Rando::Context::GetInstance(); + uint8_t curSlot = 0; + for (HintDistributionSetting distribution : distTable) { + std::vector hintTypePool = FilterHintability(ctx->allLocations, distribution.filter); + for (uint8_t numHint = 0; numHint < selectedHints[curSlot]; numHint++) { + hintTypePool = FilterHintability(hintTypePool); + SPDLOG_DEBUG("Attempting to make hint of type: " + + StaticData::hintTypeNames[distribution.type].GetEnglish(MF_CLEAN) + "\n"); + RandomizerCheck hintedLocation = RC_UNKNOWN_CHECK; + + hintedLocation = CreateRandomHint(hintTypePool, distribution.copies, distribution.type, distribution.name); + + if (hintedLocation == RC_UNKNOWN_CHECK) { // if hint failed to place, remove all wieght and copies then + // return the number of stones to redistribute + uint8_t hintsToRemove = (selectedHints[curSlot] - numHint) * distribution.copies; + selectedHints[curSlot] = 0; // as distTable is passed by refernce here, these changes stick for the rest + // of this seed generation + distTable[curSlot].copies = 0; // and prevent future distribution from choosing this slot + distTable[curSlot].weight = 0; + return hintsToRemove; + } + if (Rando::StaticData::GetLocation(hintedLocation)->IsDungeon()) { + distribution.dungeonLimit -= 1; + if (distribution.dungeonLimit == 0) { + FilterFromPool(hintTypePool, FilterOverworldLocations); + } + } + } + selectedHints[curSlot] = 0; + curSlot += 1; + } + CreateJunkHints(selectedHints[selectedHints.size() - 1]); + return 0; } void CreateStoneHints() { - auto ctx = Rando::Context::GetInstance(); - SPDLOG_DEBUG("\nNOW CREATING HINTS\n"); - const HintSetting& hintSetting = hintSettingTable[ctx->GetOption(RSK_HINT_DISTRIBUTION).Get()]; - std::vector distTable = hintSetting.distTable; + auto ctx = Rando::Context::GetInstance(); + SPDLOG_DEBUG("\nNOW CREATING HINTS\n"); + const HintSetting& hintSetting = hintSettingTable[ctx->GetOption(RSK_HINT_DISTRIBUTION).Get()]; + std::vector distTable = hintSetting.distTable; - // Apply impa's song exclusions when zelda is skipped - if(ctx->GetOption(RSK_SKIP_CHILD_ZELDA)){ - ctx->GetItemLocation(RC_SONG_FROM_IMPA)->SetHintAccesible(); - } - - // Add 'always' location hints - std::vector alwaysHintLocations = {}; - if (hintSetting.alwaysCopies > 0) { - if (ctx->GetOption(RSK_RAINBOW_BRIDGE).Is(RO_BRIDGE_GREG)){ - // If we have Rainbow Bridge set to Greg and the greg hint isn't useful, add a hint for where Greg is - // Do we really need this with the greg hint? - auto gregLocations = FilterFromPool(ctx->allLocations, [ctx](const RandomizerCheck loc) { - return ( - (ctx->GetItemLocation(loc)->GetPlacedRandomizerGet() == RG_GREG_RUPEE)) && - ctx->GetItemLocation(loc)->IsHintable() && - !(ctx->GetOption(RSK_GREG_HINT) && (IsReachableWithout({RC_GREG_HINT}, loc, true))); - }); - if (gregLocations.size() > 0){ - alwaysHintLocations.push_back(gregLocations[0]); - } + // Apply impa's song exclusions when zelda is skipped + if (ctx->GetOption(RSK_SKIP_CHILD_ZELDA)) { + ctx->GetItemLocation(RC_SONG_FROM_IMPA)->SetHintAccesible(); } - for (auto& hint : conditionalAlwaysHints) { - RandomizerCheck loc = hint.first; - if (hint.second() && ctx->GetItemLocation(loc)->IsHintable()) { - alwaysHintLocations.push_back(loc); + // Add 'always' location hints + std::vector alwaysHintLocations = {}; + if (hintSetting.alwaysCopies > 0) { + if (ctx->GetOption(RSK_RAINBOW_BRIDGE).Is(RO_BRIDGE_GREG)) { + // If we have Rainbow Bridge set to Greg and the greg hint isn't useful, add a hint for where Greg is + // Do we really need this with the greg hint? + auto gregLocations = FilterFromPool(ctx->allLocations, [ctx](const RandomizerCheck loc) { + return ((ctx->GetItemLocation(loc)->GetPlacedRandomizerGet() == RG_GREG_RUPEE)) && + ctx->GetItemLocation(loc)->IsHintable() && + !(ctx->GetOption(RSK_GREG_HINT) && (IsReachableWithout({ RC_GREG_HINT }, loc, true))); + }); + if (gregLocations.size() > 0) { + alwaysHintLocations.push_back(gregLocations[0]); + } + } + + for (auto& hint : conditionalAlwaysHints) { + RandomizerCheck loc = hint.first; + if (hint.second() && ctx->GetItemLocation(loc)->IsHintable()) { + alwaysHintLocations.push_back(loc); + } + } + + for (RandomizerCheck location : alwaysHintLocations) { + CreateHint(location, hintSetting.alwaysCopies, HINT_TYPE_ITEM, "Always"); } } - for (RandomizerCheck location : alwaysHintLocations) { - CreateHint(location, hintSetting.alwaysCopies, HINT_TYPE_ITEM, "Always"); + // Add 'trial' location hints + if (ctx->GetOption(RSK_GANONS_TRIALS).IsNot(RO_GANONS_TRIALS_SKIP)) { + CreateTrialHints(hintSetting.trialCopies); } - } - //Add 'trial' location hints - if (ctx->GetOption(RSK_GANONS_TRIALS).IsNot(RO_GANONS_TRIALS_SKIP)) { - CreateTrialHints(hintSetting.trialCopies); - } - - size_t totalStones = GetEmptyGossipStones().size(); - std::vector selectedHints = {}; - for (size_t c=0; c < distTable.size(); c++){ + size_t totalStones = GetEmptyGossipStones().size(); + std::vector selectedHints = {}; + for (size_t c = 0; c < distTable.size(); c++) { + selectedHints.push_back(0); + } selectedHints.push_back(0); - } - selectedHints.push_back(0); - DistributeHints(selectedHints, totalStones, distTable, hintSetting.junkWeight); - - while(totalStones != 0){ - totalStones = PlaceHints(selectedHints, distTable); - if (totalStones != 0){ - DistributeHints(selectedHints, totalStones, distTable, hintSetting.junkWeight, false); - } - } + DistributeHints(selectedHints, totalStones, distTable, hintSetting.junkWeight); - //Getting gossip stone locations temporarily sets one location to not be reachable. - //Call the function one last time to get rid of false positives on locations not - //being reachable. - ReachabilitySearch({}); + while (totalStones != 0) { + totalStones = PlaceHints(selectedHints, distTable); + if (totalStones != 0) { + DistributeHints(selectedHints, totalStones, distTable, hintSetting.junkWeight, false); + } + } + + // Getting gossip stone locations temporarily sets one location to not be reachable. + // Call the function one last time to get rid of false positives on locations not + // being reachable. + ReachabilitySearch({}); } -std::vector FindItemsAndMarkHinted(std::vector items, std::vector hintChecks){ - std::vector locations = {}; - auto ctx = Rando::Context::GetInstance(); - for (size_t c = 0; c < items.size(); c++){ - std::vector found = FilterFromPool(ctx->allLocations, [items, ctx, c](const RandomizerCheck loc) { - return ctx->GetItemLocation(loc)->GetPlacedRandomizerGet() == items[c];}); - if (found.size() > 0){ - locations.push_back(found[0]); - //RANDOTODO make the called functions of this always return true if empty hintChecks are provided - if (!ctx->GetItemLocation(found[0])->IsAHintAccessible() && (hintChecks.size() == 0 || IsReachableWithout(hintChecks, found[0],true))){ - ctx->GetItemLocation(found[0])->SetHintAccesible(); - } - } else { - locations.push_back(RC_UNKNOWN_CHECK); +std::vector FindItemsAndMarkHinted(std::vector items, + std::vector hintChecks) { + std::vector locations = {}; + auto ctx = Rando::Context::GetInstance(); + for (size_t c = 0; c < items.size(); c++) { + std::vector found = + FilterFromPool(ctx->allLocations, [items, ctx, c](const RandomizerCheck loc) { + return ctx->GetItemLocation(loc)->GetPlacedRandomizerGet() == items[c]; + }); + if (found.size() > 0) { + locations.push_back(found[0]); + // RANDOTODO make the called functions of this always return true if empty hintChecks are provided + if (!ctx->GetItemLocation(found[0])->IsAHintAccessible() && + (hintChecks.size() == 0 || IsReachableWithout(hintChecks, found[0], true))) { + ctx->GetItemLocation(found[0])->SetHintAccesible(); + } + } else { + locations.push_back(RC_UNKNOWN_CHECK); + } } - } - return locations; + return locations; } void CreateChildAltarHint() { - auto ctx = Rando::Context::GetInstance(); - if (!ctx->GetHint(RH_ALTAR_CHILD)->IsEnabled() && ctx->GetOption(RSK_TOT_ALTAR_HINT)){ - std::vector stoneLocs = {}; - //force marking the rewards as hinted if they are at the end of dungeons as they can be inferred - if (ctx->GetOption(RSK_SHUFFLE_DUNGEON_REWARDS).Is(RO_DUNGEON_REWARDS_END_OF_DUNGEON) || ctx->GetOption(RSK_SHUFFLE_DUNGEON_REWARDS).Is(RO_DUNGEON_REWARDS_VANILLA)) { - stoneLocs = FindItemsAndMarkHinted({RG_KOKIRI_EMERALD, RG_GORON_RUBY, RG_ZORA_SAPPHIRE}, {}); - } else { - stoneLocs = FindItemsAndMarkHinted({RG_KOKIRI_EMERALD, RG_GORON_RUBY, RG_ZORA_SAPPHIRE}, {RC_ALTAR_HINT_CHILD}); + auto ctx = Rando::Context::GetInstance(); + if (!ctx->GetHint(RH_ALTAR_CHILD)->IsEnabled() && ctx->GetOption(RSK_TOT_ALTAR_HINT)) { + std::vector stoneLocs = {}; + // force marking the rewards as hinted if they are at the end of dungeons as they can be inferred + if (ctx->GetOption(RSK_SHUFFLE_DUNGEON_REWARDS).Is(RO_DUNGEON_REWARDS_END_OF_DUNGEON) || + ctx->GetOption(RSK_SHUFFLE_DUNGEON_REWARDS).Is(RO_DUNGEON_REWARDS_VANILLA)) { + stoneLocs = FindItemsAndMarkHinted({ RG_KOKIRI_EMERALD, RG_GORON_RUBY, RG_ZORA_SAPPHIRE }, {}); + } else { + stoneLocs = + FindItemsAndMarkHinted({ RG_KOKIRI_EMERALD, RG_GORON_RUBY, RG_ZORA_SAPPHIRE }, { RC_ALTAR_HINT_CHILD }); + } + std::vector stoneAreas = {}; + for (auto loc : stoneLocs) { + if (loc != RC_UNKNOWN_CHECK) { + stoneAreas.push_back(ctx->GetItemLocation(loc)->GetRandomArea()); + } + } + ctx->AddHint(RH_ALTAR_CHILD, Hint(RH_ALTAR_CHILD, HINT_TYPE_ALTAR_CHILD, {}, stoneLocs, stoneAreas)); } - std::vector stoneAreas = {}; - for (auto loc : stoneLocs){ - if (loc != RC_UNKNOWN_CHECK) { - stoneAreas.push_back(ctx->GetItemLocation(loc)->GetRandomArea()); - } - } - ctx->AddHint(RH_ALTAR_CHILD, Hint(RH_ALTAR_CHILD, HINT_TYPE_ALTAR_CHILD, {}, stoneLocs, stoneAreas)); - } } void CreateAdultAltarHint() { - auto ctx = Rando::Context::GetInstance(); - if (!ctx->GetHint(RH_ALTAR_ADULT)->IsEnabled()){ - std::vector medallionLocs = {}; - if (ctx->GetOption(RSK_TOT_ALTAR_HINT)) { - //force marking the rewards as hinted if they are at the end of dungeons as they can be inferred - if (ctx->GetOption(RSK_SHUFFLE_DUNGEON_REWARDS).Is(RO_DUNGEON_REWARDS_END_OF_DUNGEON) || ctx->GetOption(RSK_SHUFFLE_DUNGEON_REWARDS).Is(RO_DUNGEON_REWARDS_VANILLA)) { - medallionLocs = FindItemsAndMarkHinted({RG_LIGHT_MEDALLION, RG_FOREST_MEDALLION, RG_FIRE_MEDALLION, RG_WATER_MEDALLION, RG_SPIRIT_MEDALLION, RG_SHADOW_MEDALLION}, - {}); - } else { - medallionLocs = FindItemsAndMarkHinted({RG_LIGHT_MEDALLION, RG_FOREST_MEDALLION, RG_FIRE_MEDALLION, RG_WATER_MEDALLION, RG_SPIRIT_MEDALLION, RG_SHADOW_MEDALLION}, - {RC_ALTAR_HINT_ADULT}); - } + auto ctx = Rando::Context::GetInstance(); + if (!ctx->GetHint(RH_ALTAR_ADULT)->IsEnabled()) { + std::vector medallionLocs = {}; + if (ctx->GetOption(RSK_TOT_ALTAR_HINT)) { + // force marking the rewards as hinted if they are at the end of dungeons as they can be inferred + if (ctx->GetOption(RSK_SHUFFLE_DUNGEON_REWARDS).Is(RO_DUNGEON_REWARDS_END_OF_DUNGEON) || + ctx->GetOption(RSK_SHUFFLE_DUNGEON_REWARDS).Is(RO_DUNGEON_REWARDS_VANILLA)) { + medallionLocs = FindItemsAndMarkHinted({ RG_LIGHT_MEDALLION, RG_FOREST_MEDALLION, RG_FIRE_MEDALLION, + RG_WATER_MEDALLION, RG_SPIRIT_MEDALLION, RG_SHADOW_MEDALLION }, + {}); + } else { + medallionLocs = FindItemsAndMarkHinted({ RG_LIGHT_MEDALLION, RG_FOREST_MEDALLION, RG_FIRE_MEDALLION, + RG_WATER_MEDALLION, RG_SPIRIT_MEDALLION, RG_SHADOW_MEDALLION }, + { RC_ALTAR_HINT_ADULT }); + } + } + std::vector medallionAreas = {}; + for (auto loc : medallionLocs) { + if (loc != RC_UNKNOWN_CHECK) { + medallionAreas.push_back(ctx->GetItemLocation(loc)->GetRandomArea()); + } + } + ctx->AddHint(RH_ALTAR_ADULT, Hint(RH_ALTAR_ADULT, HINT_TYPE_ALTAR_ADULT, {}, medallionLocs, medallionAreas)); } - std::vector medallionAreas = {}; - for (auto loc : medallionLocs){ - if (loc != RC_UNKNOWN_CHECK) { - medallionAreas.push_back(ctx->GetItemLocation(loc)->GetRandomArea()); - } - } - ctx->AddHint(RH_ALTAR_ADULT, Hint(RH_ALTAR_ADULT, HINT_TYPE_ALTAR_ADULT, {}, medallionLocs, medallionAreas)); - } } -void CreateStaticHintFromData(RandomizerHint hint, StaticHintInfo staticData){ - auto ctx = Rando::Context::GetInstance(); - if (!ctx->GetHint(hint)->IsEnabled()){ - OptionValue& option = ctx->GetOption(staticData.setting); - if ((std::holds_alternative(staticData.condition) && option.Is(std::get(staticData.condition))) || - (std::holds_alternative(staticData.condition) && option.Is(std::get(staticData.condition)))){ +void CreateStaticHintFromData(RandomizerHint hint, StaticHintInfo staticData) { + auto ctx = Rando::Context::GetInstance(); + if (!ctx->GetHint(hint)->IsEnabled()) { + OptionValue& option = ctx->GetOption(staticData.setting); + if ((std::holds_alternative(staticData.condition) && option.Is(std::get(staticData.condition))) || + (std::holds_alternative(staticData.condition) && + option.Is(std::get(staticData.condition)))) { - std::vector locations = {}; - if (staticData.targetItems.size() > 0){ - locations = FindItemsAndMarkHinted(staticData.targetItems, staticData.hintChecks); - } else { - for(auto check: staticData.targetChecks){ - locations.push_back(check); + std::vector locations = {}; + if (staticData.targetItems.size() > 0) { + locations = FindItemsAndMarkHinted(staticData.targetItems, staticData.hintChecks); + } else { + for (auto check : staticData.targetChecks) { + locations.push_back(check); + } + } + std::vector areas = {}; + for (auto loc : locations) { + ctx->GetItemLocation(loc)->SetHintAccesible(); + if (ctx->GetItemLocation(loc)->GetAreas().empty()) { + // If we get to here then it means a location got through with no area assignment, which means + // something went wrong elsewhere. + SPDLOG_DEBUG("Attempted to hint location with no areas: "); + SPDLOG_DEBUG(Rando::StaticData::GetLocation(loc)->GetName()); + // assert(false); + areas.push_back(RA_NONE); + } else { + areas.push_back(ctx->GetItemLocation(loc)->GetRandomArea()); + } + } + // hintKeys are defaulted to in the hint object and do not need to be specified + ctx->AddHint(hint, + Hint(hint, staticData.type, {}, locations, areas, {}, staticData.yourPocket, staticData.num)); } - } - std::vector areas = {}; - for (auto loc : locations){ - ctx->GetItemLocation(loc)->SetHintAccesible(); - if (ctx->GetItemLocation(loc)->GetAreas().empty()){ - //If we get to here then it means a location got through with no area assignment, which means something went wrong elsewhere. - SPDLOG_DEBUG("Attempted to hint location with no areas: "); - SPDLOG_DEBUG(Rando::StaticData::GetLocation(loc)->GetName()); - //assert(false); - areas.push_back(RA_NONE); - } else { - areas.push_back(ctx->GetItemLocation(loc)->GetRandomArea()); - } - } - //hintKeys are defaulted to in the hint object and do not need to be specified - ctx->AddHint(hint, Hint(hint, staticData.type, {}, locations, areas, {}, staticData.yourPocket, staticData.num)); } - } } void CreateStaticItemHint(RandomizerHint hintKey, std::vector hintTextKeys, - std::vector items, std::vector hintChecks, bool yourPocket = false) { - //RANDOTODO choose area in case there are multiple - auto ctx = Rando::Context::GetInstance(); - std::vector locations = FindItemsAndMarkHinted(items, hintChecks); - std::vector areas = {}; - for (auto loc : locations){ - areas.push_back(ctx->GetItemLocation(loc)->GetRandomArea()); - } - ctx->AddHint(hintKey, Hint(hintKey, HINT_TYPE_AREA, hintTextKeys, locations, areas, {}, yourPocket)); -} - -void CreateGanondorfJoke(){ - auto ctx = Rando::Context::GetInstance(); - if (!ctx->GetHint(RH_GANONDORF_JOKE)->IsEnabled()){ - ctx->AddHint(RH_GANONDORF_JOKE, Hint(RH_GANONDORF_JOKE, HINT_TYPE_HINT_KEY, {GetRandomGanonJoke()})); - } -} - -void CreateGanondorfHint(){ - auto ctx = Rando::Context::GetInstance(); - if (ctx->GetOption(RSK_GANONDORF_HINT) && !ctx->GetHint(RH_GANONDORF_HINT)->IsEnabled()){ - if (ctx->GetOption(RSK_SHUFFLE_MASTER_SWORD)) { - CreateStaticItemHint(RH_GANONDORF_HINT, {RHT_GANONDORF_HINT_LA_ONLY, RHT_GANONDORF_HINT_MS_ONLY, RHT_GANONDORF_HINT_LA_AND_MS}, - {RG_LIGHT_ARROWS, RG_MASTER_SWORD}, {RC_GANONDORF_HINT}, true); - } else { - CreateStaticItemHint(RH_GANONDORF_HINT, {RHT_GANONDORF_HINT_LA_ONLY}, {RG_LIGHT_ARROWS}, {RC_GANONDORF_HINT}, true); + std::vector items, std::vector hintChecks, + bool yourPocket = false) { + // RANDOTODO choose area in case there are multiple + auto ctx = Rando::Context::GetInstance(); + std::vector locations = FindItemsAndMarkHinted(items, hintChecks); + std::vector areas = {}; + for (auto loc : locations) { + areas.push_back(ctx->GetItemLocation(loc)->GetRandomArea()); } - } + ctx->AddHint(hintKey, Hint(hintKey, HINT_TYPE_AREA, hintTextKeys, locations, areas, {}, yourPocket)); } -void CreateStaticHints(){ - CreateChildAltarHint(); - CreateAdultAltarHint(); - CreateGanondorfJoke(); - CreateGanondorfHint(); - for (auto[hint, staticData] : StaticData::staticHintInfoMap){ - CreateStaticHintFromData(hint, staticData); - } +void CreateGanondorfJoke() { + auto ctx = Rando::Context::GetInstance(); + if (!ctx->GetHint(RH_GANONDORF_JOKE)->IsEnabled()) { + ctx->AddHint(RH_GANONDORF_JOKE, Hint(RH_GANONDORF_JOKE, HINT_TYPE_HINT_KEY, { GetRandomGanonJoke() })); + } } -void CreateAllHints(){ - auto ctx = Rando::Context::GetInstance(); - - CreateStaticHints(); - - if (ctx->GetOption(RSK_GOSSIP_STONE_HINTS).IsNot(RO_GOSSIP_STONES_NONE)) { - SPDLOG_INFO("Creating Hints..."); - CreateStoneHints(); - SPDLOG_INFO("Creating Hints Done"); - } +void CreateGanondorfHint() { + auto ctx = Rando::Context::GetInstance(); + if (ctx->GetOption(RSK_GANONDORF_HINT) && !ctx->GetHint(RH_GANONDORF_HINT)->IsEnabled()) { + if (ctx->GetOption(RSK_SHUFFLE_MASTER_SWORD)) { + CreateStaticItemHint( + RH_GANONDORF_HINT, + { RHT_GANONDORF_HINT_LA_ONLY, RHT_GANONDORF_HINT_MS_ONLY, RHT_GANONDORF_HINT_LA_AND_MS }, + { RG_LIGHT_ARROWS, RG_MASTER_SWORD }, { RC_GANONDORF_HINT }, true); + } else { + CreateStaticItemHint(RH_GANONDORF_HINT, { RHT_GANONDORF_HINT_LA_ONLY }, { RG_LIGHT_ARROWS }, + { RC_GANONDORF_HINT }, true); + } + } +} + +void CreateStaticHints() { + CreateChildAltarHint(); + CreateAdultAltarHint(); + CreateGanondorfJoke(); + CreateGanondorfHint(); + for (auto [hint, staticData] : StaticData::staticHintInfoMap) { + CreateStaticHintFromData(hint, staticData); + } +} + +void CreateAllHints() { + auto ctx = Rando::Context::GetInstance(); + + CreateStaticHints(); + + if (ctx->GetOption(RSK_GOSSIP_STONE_HINTS).IsNot(RO_GOSSIP_STONES_NONE)) { + SPDLOG_INFO("Creating Hints..."); + CreateStoneHints(); + SPDLOG_INFO("Creating Hints Done"); + } } diff --git a/soh/soh/Enhancements/randomizer/3drando/item_pool.cpp b/soh/soh/Enhancements/randomizer/3drando/item_pool.cpp index 9b1fd2bf0..a04a7d65c 100644 --- a/soh/soh/Enhancements/randomizer/3drando/item_pool.cpp +++ b/soh/soh/Enhancements/randomizer/3drando/item_pool.cpp @@ -13,1358 +13,1254 @@ std::vector ItemPool = {}; std::vector PendingJunkPool = {}; const std::array dungeonRewards = { - RG_KOKIRI_EMERALD, - RG_GORON_RUBY, - RG_ZORA_SAPPHIRE, - RG_FOREST_MEDALLION, - RG_FIRE_MEDALLION, - RG_WATER_MEDALLION, - RG_SPIRIT_MEDALLION, - RG_SHADOW_MEDALLION, - RG_LIGHT_MEDALLION, + RG_KOKIRI_EMERALD, RG_GORON_RUBY, RG_ZORA_SAPPHIRE, RG_FOREST_MEDALLION, RG_FIRE_MEDALLION, + RG_WATER_MEDALLION, RG_SPIRIT_MEDALLION, RG_SHADOW_MEDALLION, RG_LIGHT_MEDALLION, }; const std::array JunkPoolItems = { - RG_BOMBS_5, - RG_BOMBS_10, - RG_BOMBS_20, - RG_DEKU_NUTS_5, - RG_DEKU_STICK_1, - RG_DEKU_SEEDS_30, - RG_RECOVERY_HEART, - RG_ARROWS_5, - RG_ARROWS_10, - RG_ARROWS_30, - RG_BLUE_RUPEE, - RG_RED_RUPEE, - RG_PURPLE_RUPEE, - RG_HUGE_RUPEE, - RG_DEKU_NUTS_10, - RG_ICE_TRAP, + RG_BOMBS_5, RG_BOMBS_10, RG_BOMBS_20, RG_DEKU_NUTS_5, RG_DEKU_STICK_1, RG_DEKU_SEEDS_30, + RG_RECOVERY_HEART, RG_ARROWS_5, RG_ARROWS_10, RG_ARROWS_30, RG_BLUE_RUPEE, RG_RED_RUPEE, + RG_PURPLE_RUPEE, RG_HUGE_RUPEE, RG_DEKU_NUTS_10, RG_ICE_TRAP, }; const std::array alwaysItems = { - RG_BIGGORON_SWORD, - RG_BOOMERANG, - RG_LENS_OF_TRUTH, - RG_MEGATON_HAMMER, - RG_IRON_BOOTS, - RG_GORON_TUNIC, - RG_ZORA_TUNIC, - RG_HOVER_BOOTS, - RG_MIRROR_SHIELD, - RG_STONE_OF_AGONY, - RG_FIRE_ARROWS, - RG_ICE_ARROWS, - RG_LIGHT_ARROWS, - RG_DINS_FIRE, - RG_FARORES_WIND, - RG_NAYRUS_LOVE, - RG_GREG_RUPEE, - RG_PROGRESSIVE_HOOKSHOT, //2 progressive hookshots - RG_PROGRESSIVE_HOOKSHOT, - RG_DEKU_SHIELD, - RG_HYLIAN_SHIELD, - RG_PROGRESSIVE_STRENGTH, //3 progressive strength upgrades - RG_PROGRESSIVE_STRENGTH, - RG_PROGRESSIVE_STRENGTH, - RG_PROGRESSIVE_SCALE, //2 progressive scales - RG_PROGRESSIVE_SCALE, - RG_PROGRESSIVE_BOW, //3 progressive Bows - RG_PROGRESSIVE_BOW, - RG_PROGRESSIVE_BOW, - RG_PROGRESSIVE_SLINGSHOT, //3 progressive bullet bags - RG_PROGRESSIVE_SLINGSHOT, - RG_PROGRESSIVE_SLINGSHOT, - RG_PROGRESSIVE_BOMB_BAG, //3 progressive bomb bags - RG_PROGRESSIVE_BOMB_BAG, - RG_PROGRESSIVE_BOMB_BAG, - RG_PROGRESSIVE_WALLET, //2 progressive wallets - RG_PROGRESSIVE_WALLET, - RG_PROGRESSIVE_MAGIC_METER, //2 progressive magic meters - RG_PROGRESSIVE_MAGIC_METER, - RG_DOUBLE_DEFENSE, - RG_PROGRESSIVE_STICK_UPGRADE, //2 stick upgrades - RG_PROGRESSIVE_STICK_UPGRADE, - RG_PROGRESSIVE_NUT_UPGRADE, //2 nut upgrades - RG_PROGRESSIVE_NUT_UPGRADE, - RG_RECOVERY_HEART, //6 recovery hearts - RG_RECOVERY_HEART, - RG_RECOVERY_HEART, - RG_RECOVERY_HEART, - RG_RECOVERY_HEART, - RG_RECOVERY_HEART, - RG_BOMBS_5, //2 - RG_BOMBS_5, - RG_BOMBS_10, - RG_BOMBS_20, - RG_ARROWS_5, - RG_ARROWS_10, //5 - RG_ARROWS_10, - RG_ARROWS_10, - RG_TREASURE_GAME_HEART, -}; -const std::array easyItems = { - RG_BIGGORON_SWORD, - RG_KOKIRI_SWORD, - RG_MASTER_SWORD, - RG_BOOMERANG, - RG_LENS_OF_TRUTH, - RG_MEGATON_HAMMER, - RG_IRON_BOOTS, - RG_GORON_TUNIC, - RG_ZORA_TUNIC, - RG_HOVER_BOOTS, - RG_MIRROR_SHIELD, - RG_FIRE_ARROWS, - RG_LIGHT_ARROWS, - RG_DINS_FIRE, - RG_PROGRESSIVE_HOOKSHOT, - RG_PROGRESSIVE_STRENGTH, - RG_PROGRESSIVE_SCALE, - RG_PROGRESSIVE_WALLET, - RG_PROGRESSIVE_MAGIC_METER, - RG_PROGRESSIVE_STICK_UPGRADE, - RG_PROGRESSIVE_NUT_UPGRADE, - RG_PROGRESSIVE_BOW, - RG_PROGRESSIVE_SLINGSHOT, - RG_PROGRESSIVE_BOMB_BAG, - RG_DOUBLE_DEFENSE, - RG_HEART_CONTAINER, //16 Heart Containers - RG_HEART_CONTAINER, - RG_HEART_CONTAINER, - RG_HEART_CONTAINER, - RG_HEART_CONTAINER, - RG_HEART_CONTAINER, - RG_HEART_CONTAINER, - RG_HEART_CONTAINER, - RG_HEART_CONTAINER, - RG_HEART_CONTAINER, - RG_HEART_CONTAINER, - RG_HEART_CONTAINER, - RG_HEART_CONTAINER, - RG_HEART_CONTAINER, - RG_HEART_CONTAINER, - RG_HEART_CONTAINER, - RG_PIECE_OF_HEART, //3 heart pieces - RG_PIECE_OF_HEART, - RG_PIECE_OF_HEART, -}; -const std::array normalItems = { - // 35 pieces of heart - RG_PIECE_OF_HEART, - RG_PIECE_OF_HEART, - RG_PIECE_OF_HEART, - RG_PIECE_OF_HEART, - RG_PIECE_OF_HEART, - RG_PIECE_OF_HEART, - RG_PIECE_OF_HEART, - RG_PIECE_OF_HEART, - RG_PIECE_OF_HEART, - RG_PIECE_OF_HEART, - RG_PIECE_OF_HEART, - RG_PIECE_OF_HEART, - RG_PIECE_OF_HEART, - RG_PIECE_OF_HEART, - RG_PIECE_OF_HEART, - RG_PIECE_OF_HEART, - RG_PIECE_OF_HEART, - RG_PIECE_OF_HEART, - RG_PIECE_OF_HEART, - RG_PIECE_OF_HEART, - RG_PIECE_OF_HEART, - RG_PIECE_OF_HEART, - RG_PIECE_OF_HEART, - RG_PIECE_OF_HEART, - RG_PIECE_OF_HEART, - RG_PIECE_OF_HEART, - RG_PIECE_OF_HEART, - RG_PIECE_OF_HEART, - RG_PIECE_OF_HEART, - RG_PIECE_OF_HEART, - RG_PIECE_OF_HEART, - RG_PIECE_OF_HEART, - RG_PIECE_OF_HEART, - RG_PIECE_OF_HEART, - RG_PIECE_OF_HEART, - // 8 heart containers - RG_HEART_CONTAINER, - RG_HEART_CONTAINER, - RG_HEART_CONTAINER, - RG_HEART_CONTAINER, - RG_HEART_CONTAINER, - RG_HEART_CONTAINER, - RG_HEART_CONTAINER, - RG_HEART_CONTAINER, -}; -const std::array DT_Vanilla = { - RG_RECOVERY_HEART, - RG_RECOVERY_HEART, -}; -const std::array DT_MQ = { - RG_DEKU_SHIELD, - RG_DEKU_SHIELD, - RG_PURPLE_RUPEE, -}; -const std::array DC_Vanilla = { - RG_RED_RUPEE, -}; -const std::array DC_MQ = { - RG_HYLIAN_SHIELD, - RG_BLUE_RUPEE, -}; -const std::array JB_MQ = { - RG_DEKU_NUTS_5, - RG_DEKU_NUTS_5, - RG_DEKU_NUTS_5, - RG_DEKU_NUTS_5, - RG_RECOVERY_HEART, - RG_DEKU_SHIELD, - RG_DEKU_STICK_1, -}; -const std::array FoT_Vanilla = { - RG_RECOVERY_HEART, - RG_ARROWS_10, - RG_ARROWS_30, -}; -const std::array FoT_MQ = { - RG_ARROWS_5, -}; -const std::array FiT_Vanilla = { - RG_HUGE_RUPEE, -}; -const std::array FiT_MQ = { - RG_BOMBS_20, - RG_HYLIAN_SHIELD, -}; -const std::array SpT_Vanilla = { - RG_DEKU_SHIELD, - RG_DEKU_SHIELD, - RG_RECOVERY_HEART, - RG_BOMBS_20, -}; -const std::array SpT_MQ = { - RG_PURPLE_RUPEE, - RG_PURPLE_RUPEE, - RG_ARROWS_30, -}; -const std::array ShT_Vanilla = { - RG_ARROWS_30, -}; -const std::array ShT_MQ = { - RG_ARROWS_5, - RG_ARROWS_5, - RG_RED_RUPEE, -}; -const std::array BW_Vanilla = { - RG_RECOVERY_HEART, - RG_BOMBS_10, - RG_HUGE_RUPEE, - RG_DEKU_NUTS_5, - RG_DEKU_NUTS_10, - RG_DEKU_SHIELD, - RG_HYLIAN_SHIELD, -}; -const std::array GTG_Vanilla = { - RG_ARROWS_30, - RG_ARROWS_30, - RG_ARROWS_30, - RG_HUGE_RUPEE, -}; -const std::array GTG_MQ = { - RG_TREASURE_GAME_GREEN_RUPEE, - RG_TREASURE_GAME_GREEN_RUPEE, - RG_ARROWS_10, - RG_GREEN_RUPEE, - RG_PURPLE_RUPEE, -}; -const std::array GC_Vanilla = { - RG_BLUE_RUPEE, - RG_BLUE_RUPEE, - RG_BLUE_RUPEE, - RG_ARROWS_30, -}; -const std::array GC_MQ = { - RG_ARROWS_10, - RG_ARROWS_10, - RG_BOMBS_5, - RG_RED_RUPEE, - RG_RECOVERY_HEART, -}; -const std::array normalBottles = { - RG_EMPTY_BOTTLE, - RG_BOTTLE_WITH_MILK, - RG_BOTTLE_WITH_RED_POTION, - RG_BOTTLE_WITH_GREEN_POTION, - RG_BOTTLE_WITH_BLUE_POTION, - RG_BOTTLE_WITH_FAIRY, - RG_BOTTLE_WITH_FISH, - RG_BOTTLE_WITH_BUGS, - RG_BOTTLE_WITH_POE, - RG_BOTTLE_WITH_BIG_POE, - RG_BOTTLE_WITH_BLUE_FIRE, -}; -const std::array normalRupees = { - RG_BLUE_RUPEE, - RG_BLUE_RUPEE, - RG_BLUE_RUPEE, - RG_BLUE_RUPEE, - RG_BLUE_RUPEE, - RG_BLUE_RUPEE, - RG_BLUE_RUPEE, - RG_BLUE_RUPEE, - RG_BLUE_RUPEE, - RG_BLUE_RUPEE, - RG_BLUE_RUPEE, - RG_BLUE_RUPEE, - RG_BLUE_RUPEE, - RG_RED_RUPEE, - RG_RED_RUPEE, - RG_RED_RUPEE, - RG_RED_RUPEE, - RG_RED_RUPEE, - RG_PURPLE_RUPEE, - RG_PURPLE_RUPEE, - RG_PURPLE_RUPEE, - RG_PURPLE_RUPEE, - RG_PURPLE_RUPEE, - RG_PURPLE_RUPEE, - RG_PURPLE_RUPEE, - RG_HUGE_RUPEE, - RG_HUGE_RUPEE, - RG_HUGE_RUPEE, -}; -const std::array shopsanityRupees = { - RG_BLUE_RUPEE, - RG_BLUE_RUPEE, - RG_RED_RUPEE, - RG_RED_RUPEE, - RG_RED_RUPEE, - RG_RED_RUPEE, - RG_RED_RUPEE, - RG_RED_RUPEE, - RG_RED_RUPEE, - RG_RED_RUPEE, - RG_RED_RUPEE, - RG_RED_RUPEE, - RG_PURPLE_RUPEE, - RG_PURPLE_RUPEE, - RG_PURPLE_RUPEE, - RG_PURPLE_RUPEE, - RG_PURPLE_RUPEE, - RG_PURPLE_RUPEE, - RG_PURPLE_RUPEE, - RG_PURPLE_RUPEE, - RG_PURPLE_RUPEE, - RG_PURPLE_RUPEE, - RG_HUGE_RUPEE, - RG_HUGE_RUPEE, - RG_HUGE_RUPEE, - RG_HUGE_RUPEE, - RG_HUGE_RUPEE, - RG_HUGE_RUPEE, -}; -const std::array dekuScrubItems = { - RG_DEKU_NUTS_5, - RG_DEKU_NUTS_5, - RG_DEKU_NUTS_5, - RG_DEKU_NUTS_5, - RG_DEKU_NUTS_5, - RG_DEKU_STICK_1, - RG_BOMBS_5, - RG_BOMBS_5, - RG_BOMBS_5, - RG_BOMBS_5, - RG_BOMBS_5, - RG_RECOVERY_HEART, - RG_RECOVERY_HEART, - RG_RECOVERY_HEART, - RG_RECOVERY_HEART, - RG_BLUE_RUPEE, - RG_BLUE_RUPEE, - RG_BLUE_RUPEE, - RG_BLUE_RUPEE, -}; -const std::array songList = { - RG_ZELDAS_LULLABY, - RG_EPONAS_SONG, - RG_SUNS_SONG, - RG_SARIAS_SONG, - RG_SONG_OF_TIME, - RG_SONG_OF_STORMS, - RG_MINUET_OF_FOREST, - RG_PRELUDE_OF_LIGHT, - RG_BOLERO_OF_FIRE, - RG_SERENADE_OF_WATER, - RG_NOCTURNE_OF_SHADOW, - RG_REQUIEM_OF_SPIRIT, -}; -const std::array tradeItems = { - RG_POCKET_EGG, - //RG_POCKET_CUCCO, - RG_COJIRO, - RG_ODD_MUSHROOM, - RG_POACHERS_SAW, - RG_BROKEN_SWORD, - RG_PRESCRIPTION, - RG_EYEBALL_FROG, - RG_EYEDROPS, - RG_CLAIM_CHECK, -}; - -void AddItemToPool(std::vector& pool, RandomizerGet item, size_t count /*= 1*/) { - pool.insert(pool.end(), count, item); -} - -template -static void AddItemsToPool(std::vector& toPool, const FromPool& fromPool) { - AddElementsToPool(toPool, fromPool); -} - -static void AddItemToMainPool(const RandomizerGet item, size_t count = 1) { - ItemPool.insert(ItemPool.end(), count, item); -} - -static void AddRandomBottle(std::vector& bottlePool) { - AddItemToMainPool(RandomElement(bottlePool, true)); -} - -RandomizerGet GetJunkItem() { - auto ctx = Rando::Context::GetInstance(); - if (ctx->GetOption(RSK_ICE_TRAPS).Is(RO_ICE_TRAPS_MAYHEM) || ctx->GetOption(RSK_ICE_TRAPS).Is(RO_ICE_TRAPS_ONSLAUGHT)) { - return RG_ICE_TRAP; - } else if (ctx->GetOption(RSK_ICE_TRAPS).Is(RO_ICE_TRAPS_EXTRA)) { - return RandomElement(JunkPoolItems); - } - //Ice Trap is the last item in JunkPoolItems, so subtract 1 to never hit that index - uint8_t idx = Random(0, JunkPoolItems.size() - 1); - return JunkPoolItems[idx]; -} - -static RandomizerGet GetPendingJunkItem() { - if (PendingJunkPool.empty()) { - return GetJunkItem(); - } - - return RandomElement(PendingJunkPool, true); -} - -//Replace junk items in the pool with pending junk -static void ReplaceMaxItem(const RandomizerGet itemToReplace, int max) { - int itemCount = 0; - for (size_t i = 0; i < ItemPool.size(); i++) { - if (ItemPool[i] == itemToReplace) { - if (itemCount >= max) { - ItemPool[i] = RG_NONE; - } - itemCount++; - } - } -} - -void PlaceJunkInExcludedLocation(const RandomizerCheck il) { - //place a non-advancement item in this location - auto ctx = Rando::Context::GetInstance(); - for (size_t i = 0; i < ItemPool.size(); i++) { - if (!Rando::StaticData::RetrieveItem(ItemPool[i]).IsAdvancement()) { - ctx->PlaceItemInLocation(il, ItemPool[i]); - ItemPool.erase(ItemPool.begin() + i); - return; - } - } - SPDLOG_ERROR("ERROR: No Junk to Place!!!"); -} - -static void PlaceVanillaMapsAndCompasses() { - auto ctx = Rando::Context::GetInstance(); - for (auto dungeon : ctx->GetDungeons()->GetDungeonList()) { - dungeon->PlaceVanillaMap(); - dungeon->PlaceVanillaCompass(); - } -} - -static void PlaceVanillaSmallKeys() { - auto ctx = Rando::Context::GetInstance(); - for (auto dungeon : ctx->GetDungeons()->GetDungeonList()) { - dungeon->PlaceVanillaSmallKeys(); - } -} - -static void PlaceVanillaBossKeys() { - auto ctx = Rando::Context::GetInstance(); - for (auto dungeon : ctx->GetDungeons()->GetDungeonList()) { - dungeon->PlaceVanillaBossKey(); - } -} - -static void PlaceItemsForType(RandomizerCheckType rctype, bool overworldActive, bool dungeonActive) { - if (!(overworldActive || dungeonActive)) { - return; - } - for (RandomizerCheck rc : ctx->GetLocations(ctx->allLocations, rctype)) { - auto loc = Rando::StaticData::GetLocation(rc); - - // If item is in the overworld and shuffled, add its item to the pool - if (loc->IsOverworld()) { - if (overworldActive) { - AddItemToMainPool(loc->GetVanillaItem()); - } - } else { - if (dungeonActive) { - // If the same in MQ and vanilla, add. - RandomizerCheckQuest currentQuest = loc->GetQuest(); - if (currentQuest == RCQUEST_BOTH) { - AddItemToMainPool(loc->GetVanillaItem()); - } else { - // Check if current item's dungeon is vanilla or MQ, and only add if quest corresponds to it. - SceneID itemScene = loc->GetScene(); - - if (itemScene >= SCENE_DEKU_TREE && itemScene <= SCENE_GERUDO_TRAINING_GROUND) { - bool isMQ = ctx->GetDungeon(itemScene)->IsMQ(); - - if ((isMQ && currentQuest == RCQUEST_MQ) || (!isMQ && currentQuest == RCQUEST_VANILLA)) { - AddItemToMainPool(loc->GetVanillaItem()); - } - } - } - } - } - } -} - -static void SetScarceItemPool() { - ReplaceMaxItem(RG_PROGRESSIVE_BOMBCHUS, 3); - ReplaceMaxItem(RG_BOMBCHU_5, 1); - ReplaceMaxItem(RG_BOMBCHU_10, 2); - ReplaceMaxItem(RG_BOMBCHU_20, 0); - ReplaceMaxItem(RG_PROGRESSIVE_MAGIC_METER, 1); - ReplaceMaxItem(RG_DOUBLE_DEFENSE, 0); - ReplaceMaxItem(RG_PROGRESSIVE_STICK_UPGRADE, ctx->GetOption(RSK_SHUFFLE_DEKU_STICK_BAG) ? 2 : 1); - ReplaceMaxItem(RG_PROGRESSIVE_NUT_UPGRADE, ctx->GetOption(RSK_SHUFFLE_DEKU_NUT_BAG) ? 2 : 1); - ReplaceMaxItem(RG_PROGRESSIVE_BOW, 2); - ReplaceMaxItem(RG_PROGRESSIVE_SLINGSHOT, 2); - ReplaceMaxItem(RG_PROGRESSIVE_BOMB_BAG, 2); - ReplaceMaxItem(RG_HEART_CONTAINER, 0); -} - -static void SetMinimalItemPool() { - auto ctx = Rando::Context::GetInstance(); - ReplaceMaxItem(RG_PROGRESSIVE_BOMBCHUS, 1); - ReplaceMaxItem(RG_BOMBCHU_5, 1); - ReplaceMaxItem(RG_BOMBCHU_10, 0); - ReplaceMaxItem(RG_BOMBCHU_20, 0); - ReplaceMaxItem(RG_NAYRUS_LOVE, 0); - ReplaceMaxItem(RG_PROGRESSIVE_MAGIC_METER, 1); - ReplaceMaxItem(RG_DOUBLE_DEFENSE, 0); - ReplaceMaxItem(RG_PROGRESSIVE_STICK_UPGRADE, ctx->GetOption(RSK_SHUFFLE_DEKU_STICK_BAG) ? 1 : 0); - ReplaceMaxItem(RG_PROGRESSIVE_NUT_UPGRADE, ctx->GetOption(RSK_SHUFFLE_DEKU_NUT_BAG) ? 1 : 0); - ReplaceMaxItem(RG_PROGRESSIVE_BOW, 1); - ReplaceMaxItem(RG_PROGRESSIVE_SLINGSHOT, 1); - ReplaceMaxItem(RG_PROGRESSIVE_BOMB_BAG, 1); - ReplaceMaxItem(RG_PIECE_OF_HEART, 0); - // Need an extra heart container when starting with 1 heart to be able to reach 3 hearts - ReplaceMaxItem(RG_HEART_CONTAINER, (ctx->GetOption(RSK_STARTING_HEARTS).Get() == 18)? 1 : 0); -} - -void GenerateItemPool() { - //RANDOTODO proper removal of items not in pool or logically relevant instead of dummy checks. - auto ctx = Rando::Context::GetInstance(); - ItemPool.clear(); - PendingJunkPool.clear(); - - //Initialize ice trap models to always major items - ctx->possibleIceTrapModels = { - RG_MIRROR_SHIELD, + RG_BIGGORON_SWORD, RG_BOOMERANG, RG_LENS_OF_TRUTH, RG_MEGATON_HAMMER, RG_IRON_BOOTS, + RG_GORON_TUNIC, + RG_ZORA_TUNIC, RG_HOVER_BOOTS, + RG_MIRROR_SHIELD, RG_STONE_OF_AGONY, - RG_DINS_FIRE, - RG_FARORES_WIND, - RG_NAYRUS_LOVE, RG_FIRE_ARROWS, RG_ICE_ARROWS, RG_LIGHT_ARROWS, + RG_DINS_FIRE, + RG_FARORES_WIND, + RG_NAYRUS_LOVE, + RG_GREG_RUPEE, + RG_PROGRESSIVE_HOOKSHOT, // 2 progressive hookshots + RG_PROGRESSIVE_HOOKSHOT, + RG_DEKU_SHIELD, + RG_HYLIAN_SHIELD, + RG_PROGRESSIVE_STRENGTH, // 3 progressive strength upgrades + RG_PROGRESSIVE_STRENGTH, + RG_PROGRESSIVE_STRENGTH, + RG_PROGRESSIVE_SCALE, // 2 progressive scales + RG_PROGRESSIVE_SCALE, + RG_PROGRESSIVE_BOW, // 3 progressive Bows + RG_PROGRESSIVE_BOW, + RG_PROGRESSIVE_BOW, + RG_PROGRESSIVE_SLINGSHOT, // 3 progressive bullet bags + RG_PROGRESSIVE_SLINGSHOT, + RG_PROGRESSIVE_SLINGSHOT, + RG_PROGRESSIVE_BOMB_BAG, // 3 progressive bomb bags + RG_PROGRESSIVE_BOMB_BAG, + RG_PROGRESSIVE_BOMB_BAG, + RG_PROGRESSIVE_WALLET, // 2 progressive wallets + RG_PROGRESSIVE_WALLET, + RG_PROGRESSIVE_MAGIC_METER, // 2 progressive magic meters + RG_PROGRESSIVE_MAGIC_METER, RG_DOUBLE_DEFENSE, - RG_CLAIM_CHECK, + RG_PROGRESSIVE_STICK_UPGRADE, // 2 stick upgrades + RG_PROGRESSIVE_STICK_UPGRADE, + RG_PROGRESSIVE_NUT_UPGRADE, // 2 nut upgrades + RG_PROGRESSIVE_NUT_UPGRADE, + RG_RECOVERY_HEART, // 6 recovery hearts + RG_RECOVERY_HEART, + RG_RECOVERY_HEART, + RG_RECOVERY_HEART, + RG_RECOVERY_HEART, + RG_RECOVERY_HEART, + RG_BOMBS_5, // 2 + RG_BOMBS_5, + RG_BOMBS_10, + RG_BOMBS_20, + RG_ARROWS_5, + RG_ARROWS_10, // 5 + RG_ARROWS_10, + RG_ARROWS_10, + RG_TREASURE_GAME_HEART, +}; +const std::array easyItems = { + RG_BIGGORON_SWORD, + RG_KOKIRI_SWORD, + RG_MASTER_SWORD, + RG_BOOMERANG, + RG_LENS_OF_TRUTH, + RG_MEGATON_HAMMER, + RG_IRON_BOOTS, + RG_GORON_TUNIC, + RG_ZORA_TUNIC, + RG_HOVER_BOOTS, + RG_MIRROR_SHIELD, + RG_FIRE_ARROWS, + RG_LIGHT_ARROWS, + RG_DINS_FIRE, RG_PROGRESSIVE_HOOKSHOT, RG_PROGRESSIVE_STRENGTH, - RG_PROGRESSIVE_BOMB_BAG, + RG_PROGRESSIVE_SCALE, + RG_PROGRESSIVE_WALLET, + RG_PROGRESSIVE_MAGIC_METER, + RG_PROGRESSIVE_STICK_UPGRADE, + RG_PROGRESSIVE_NUT_UPGRADE, RG_PROGRESSIVE_BOW, RG_PROGRESSIVE_SLINGSHOT, - RG_PROGRESSIVE_WALLET, - RG_PROGRESSIVE_SCALE, - RG_PROGRESSIVE_MAGIC_METER, - }; - //Check song shuffle and dungeon reward shuffle just for ice traps - if (ctx->GetOption(RSK_SHUFFLE_SONGS).Is(RO_SONG_SHUFFLE_ANYWHERE)) { - //Push item ids for songs - ctx->possibleIceTrapModels.push_back(RG_ZELDAS_LULLABY); - ctx->possibleIceTrapModels.push_back(RG_EPONAS_SONG); - ctx->possibleIceTrapModels.push_back(RG_SARIAS_SONG); - ctx->possibleIceTrapModels.push_back(RG_SUNS_SONG); - ctx->possibleIceTrapModels.push_back(RG_SONG_OF_TIME); - ctx->possibleIceTrapModels.push_back(RG_SONG_OF_STORMS); - ctx->possibleIceTrapModels.push_back(RG_MINUET_OF_FOREST); - ctx->possibleIceTrapModels.push_back(RG_BOLERO_OF_FIRE); - ctx->possibleIceTrapModels.push_back(RG_SERENADE_OF_WATER); - ctx->possibleIceTrapModels.push_back(RG_REQUIEM_OF_SPIRIT); - ctx->possibleIceTrapModels.push_back(RG_NOCTURNE_OF_SHADOW); - ctx->possibleIceTrapModels.push_back(RG_PRELUDE_OF_LIGHT); - } - if (ctx->GetOption(RSK_SHUFFLE_DUNGEON_REWARDS).Is(RO_DUNGEON_REWARDS_ANYWHERE)) { - //Push item ids for dungeon rewards - ctx->possibleIceTrapModels.push_back(RG_KOKIRI_EMERALD); - ctx->possibleIceTrapModels.push_back(RG_GORON_RUBY); - ctx->possibleIceTrapModels.push_back(RG_ZORA_SAPPHIRE); - ctx->possibleIceTrapModels.push_back(RG_FOREST_MEDALLION); - ctx->possibleIceTrapModels.push_back(RG_FIRE_MEDALLION); - ctx->possibleIceTrapModels.push_back(RG_WATER_MEDALLION); - ctx->possibleIceTrapModels.push_back(RG_SPIRIT_MEDALLION); - ctx->possibleIceTrapModels.push_back(RG_SHADOW_MEDALLION); - ctx->possibleIceTrapModels.push_back(RG_LIGHT_MEDALLION); - } + RG_PROGRESSIVE_BOMB_BAG, + RG_DOUBLE_DEFENSE, + RG_HEART_CONTAINER, // 16 Heart Containers + RG_HEART_CONTAINER, + RG_HEART_CONTAINER, + RG_HEART_CONTAINER, + RG_HEART_CONTAINER, + RG_HEART_CONTAINER, + RG_HEART_CONTAINER, + RG_HEART_CONTAINER, + RG_HEART_CONTAINER, + RG_HEART_CONTAINER, + RG_HEART_CONTAINER, + RG_HEART_CONTAINER, + RG_HEART_CONTAINER, + RG_HEART_CONTAINER, + RG_HEART_CONTAINER, + RG_HEART_CONTAINER, + RG_PIECE_OF_HEART, // 3 heart pieces + RG_PIECE_OF_HEART, + RG_PIECE_OF_HEART, +}; +const std::array normalItems = { + // 35 pieces of heart + RG_PIECE_OF_HEART, + RG_PIECE_OF_HEART, + RG_PIECE_OF_HEART, + RG_PIECE_OF_HEART, + RG_PIECE_OF_HEART, + RG_PIECE_OF_HEART, + RG_PIECE_OF_HEART, + RG_PIECE_OF_HEART, + RG_PIECE_OF_HEART, + RG_PIECE_OF_HEART, + RG_PIECE_OF_HEART, + RG_PIECE_OF_HEART, + RG_PIECE_OF_HEART, + RG_PIECE_OF_HEART, + RG_PIECE_OF_HEART, + RG_PIECE_OF_HEART, + RG_PIECE_OF_HEART, + RG_PIECE_OF_HEART, + RG_PIECE_OF_HEART, + RG_PIECE_OF_HEART, + RG_PIECE_OF_HEART, + RG_PIECE_OF_HEART, + RG_PIECE_OF_HEART, + RG_PIECE_OF_HEART, + RG_PIECE_OF_HEART, + RG_PIECE_OF_HEART, + RG_PIECE_OF_HEART, + RG_PIECE_OF_HEART, + RG_PIECE_OF_HEART, + RG_PIECE_OF_HEART, + RG_PIECE_OF_HEART, + RG_PIECE_OF_HEART, + RG_PIECE_OF_HEART, + RG_PIECE_OF_HEART, + RG_PIECE_OF_HEART, + // 8 heart containers + RG_HEART_CONTAINER, + RG_HEART_CONTAINER, + RG_HEART_CONTAINER, + RG_HEART_CONTAINER, + RG_HEART_CONTAINER, + RG_HEART_CONTAINER, + RG_HEART_CONTAINER, + RG_HEART_CONTAINER, +}; +const std::array DT_Vanilla = { + RG_RECOVERY_HEART, + RG_RECOVERY_HEART, +}; +const std::array DT_MQ = { + RG_DEKU_SHIELD, + RG_DEKU_SHIELD, + RG_PURPLE_RUPEE, +}; +const std::array DC_Vanilla = { + RG_RED_RUPEE, +}; +const std::array DC_MQ = { + RG_HYLIAN_SHIELD, + RG_BLUE_RUPEE, +}; +const std::array JB_MQ = { + RG_DEKU_NUTS_5, RG_DEKU_NUTS_5, RG_DEKU_NUTS_5, RG_DEKU_NUTS_5, RG_RECOVERY_HEART, RG_DEKU_SHIELD, RG_DEKU_STICK_1, +}; +const std::array FoT_Vanilla = { + RG_RECOVERY_HEART, + RG_ARROWS_10, + RG_ARROWS_30, +}; +const std::array FoT_MQ = { + RG_ARROWS_5, +}; +const std::array FiT_Vanilla = { + RG_HUGE_RUPEE, +}; +const std::array FiT_MQ = { + RG_BOMBS_20, + RG_HYLIAN_SHIELD, +}; +const std::array SpT_Vanilla = { + RG_DEKU_SHIELD, + RG_DEKU_SHIELD, + RG_RECOVERY_HEART, + RG_BOMBS_20, +}; +const std::array SpT_MQ = { + RG_PURPLE_RUPEE, + RG_PURPLE_RUPEE, + RG_ARROWS_30, +}; +const std::array ShT_Vanilla = { + RG_ARROWS_30, +}; +const std::array ShT_MQ = { + RG_ARROWS_5, + RG_ARROWS_5, + RG_RED_RUPEE, +}; +const std::array BW_Vanilla = { + RG_RECOVERY_HEART, RG_BOMBS_10, RG_HUGE_RUPEE, RG_DEKU_NUTS_5, RG_DEKU_NUTS_10, RG_DEKU_SHIELD, RG_HYLIAN_SHIELD, +}; +const std::array GTG_Vanilla = { + RG_ARROWS_30, + RG_ARROWS_30, + RG_ARROWS_30, + RG_HUGE_RUPEE, +}; +const std::array GTG_MQ = { + RG_TREASURE_GAME_GREEN_RUPEE, RG_TREASURE_GAME_GREEN_RUPEE, RG_ARROWS_10, RG_GREEN_RUPEE, RG_PURPLE_RUPEE, +}; +const std::array GC_Vanilla = { + RG_BLUE_RUPEE, + RG_BLUE_RUPEE, + RG_BLUE_RUPEE, + RG_ARROWS_30, +}; +const std::array GC_MQ = { + RG_ARROWS_10, RG_ARROWS_10, RG_BOMBS_5, RG_RED_RUPEE, RG_RECOVERY_HEART, +}; +const std::array normalBottles = { + RG_EMPTY_BOTTLE, + RG_BOTTLE_WITH_MILK, + RG_BOTTLE_WITH_RED_POTION, + RG_BOTTLE_WITH_GREEN_POTION, + RG_BOTTLE_WITH_BLUE_POTION, + RG_BOTTLE_WITH_FAIRY, + RG_BOTTLE_WITH_FISH, + RG_BOTTLE_WITH_BUGS, + RG_BOTTLE_WITH_POE, + RG_BOTTLE_WITH_BIG_POE, + RG_BOTTLE_WITH_BLUE_FIRE, +}; +const std::array normalRupees = { + RG_BLUE_RUPEE, RG_BLUE_RUPEE, RG_BLUE_RUPEE, RG_BLUE_RUPEE, RG_BLUE_RUPEE, RG_BLUE_RUPEE, + RG_BLUE_RUPEE, RG_BLUE_RUPEE, RG_BLUE_RUPEE, RG_BLUE_RUPEE, RG_BLUE_RUPEE, RG_BLUE_RUPEE, + RG_BLUE_RUPEE, RG_RED_RUPEE, RG_RED_RUPEE, RG_RED_RUPEE, RG_RED_RUPEE, RG_RED_RUPEE, + RG_PURPLE_RUPEE, RG_PURPLE_RUPEE, RG_PURPLE_RUPEE, RG_PURPLE_RUPEE, RG_PURPLE_RUPEE, RG_PURPLE_RUPEE, + RG_PURPLE_RUPEE, RG_HUGE_RUPEE, RG_HUGE_RUPEE, RG_HUGE_RUPEE, +}; +const std::array shopsanityRupees = { + RG_BLUE_RUPEE, RG_BLUE_RUPEE, RG_RED_RUPEE, RG_RED_RUPEE, RG_RED_RUPEE, RG_RED_RUPEE, + RG_RED_RUPEE, RG_RED_RUPEE, RG_RED_RUPEE, RG_RED_RUPEE, RG_RED_RUPEE, RG_RED_RUPEE, + RG_PURPLE_RUPEE, RG_PURPLE_RUPEE, RG_PURPLE_RUPEE, RG_PURPLE_RUPEE, RG_PURPLE_RUPEE, RG_PURPLE_RUPEE, + RG_PURPLE_RUPEE, RG_PURPLE_RUPEE, RG_PURPLE_RUPEE, RG_PURPLE_RUPEE, RG_HUGE_RUPEE, RG_HUGE_RUPEE, + RG_HUGE_RUPEE, RG_HUGE_RUPEE, RG_HUGE_RUPEE, RG_HUGE_RUPEE, +}; +const std::array dekuScrubItems = { + RG_DEKU_NUTS_5, RG_DEKU_NUTS_5, RG_DEKU_NUTS_5, RG_DEKU_NUTS_5, RG_DEKU_NUTS_5, + RG_DEKU_STICK_1, RG_BOMBS_5, RG_BOMBS_5, RG_BOMBS_5, RG_BOMBS_5, + RG_BOMBS_5, RG_RECOVERY_HEART, RG_RECOVERY_HEART, RG_RECOVERY_HEART, RG_RECOVERY_HEART, + RG_BLUE_RUPEE, RG_BLUE_RUPEE, RG_BLUE_RUPEE, RG_BLUE_RUPEE, +}; +const std::array songList = { + RG_ZELDAS_LULLABY, RG_EPONAS_SONG, RG_SUNS_SONG, RG_SARIAS_SONG, + RG_SONG_OF_TIME, RG_SONG_OF_STORMS, RG_MINUET_OF_FOREST, RG_PRELUDE_OF_LIGHT, + RG_BOLERO_OF_FIRE, RG_SERENADE_OF_WATER, RG_NOCTURNE_OF_SHADOW, RG_REQUIEM_OF_SPIRIT, +}; +const std::array tradeItems = { + RG_POCKET_EGG, + // RG_POCKET_CUCCO, + RG_COJIRO, + RG_ODD_MUSHROOM, + RG_POACHERS_SAW, + RG_BROKEN_SWORD, + RG_PRESCRIPTION, + RG_EYEBALL_FROG, + RG_EYEDROPS, + RG_CLAIM_CHECK, +}; - if (ctx->GetOption(RSK_TRIFORCE_HUNT)) { - ctx->possibleIceTrapModels.push_back(RG_TRIFORCE_PIECE); - AddItemToMainPool(RG_TRIFORCE_PIECE, (ctx->GetOption(RSK_TRIFORCE_HUNT_PIECES_TOTAL).Get() + 1)); - ctx->PlaceItemInLocation(RC_TRIFORCE_COMPLETED, RG_TRIFORCE); // Win condition - ctx->PlaceItemInLocation(RC_GANON, GetJunkItem(), false, true); - } else { - ctx->PlaceItemInLocation(RC_GANON, RG_TRIFORCE); // Win condition - } +void AddItemToPool(std::vector& pool, RandomizerGet item, size_t count /*= 1*/) { + pool.insert(pool.end(), count, item); +} - //Fixed item locations - ctx->PlaceItemInLocation(RC_HC_ZELDAS_LETTER, RG_ZELDAS_LETTER); +template static void AddItemsToPool(std::vector& toPool, const FromPool& fromPool) { + AddElementsToPool(toPool, fromPool); +} - if (ctx->GetOption(RSK_SHUFFLE_KOKIRI_SWORD)) { - AddItemToMainPool(RG_KOKIRI_SWORD); - ctx->possibleIceTrapModels.push_back(RG_KOKIRI_SWORD); - } else { - if (!ctx->GetOption(RSK_STARTING_KOKIRI_SWORD)) { - ctx->PlaceItemInLocation(RC_KF_KOKIRI_SWORD_CHEST, RG_KOKIRI_SWORD, false, true); - } - } +static void AddItemToMainPool(const RandomizerGet item, size_t count = 1) { + ItemPool.insert(ItemPool.end(), count, item); +} - if (ctx->GetOption(RSK_SHUFFLE_MASTER_SWORD)) { - AddItemToMainPool(RG_MASTER_SWORD); - ctx->possibleIceTrapModels.push_back(RG_MASTER_SWORD); - } else { - if (!ctx->GetOption(RSK_STARTING_MASTER_SWORD)) { - ctx->PlaceItemInLocation(RC_TOT_MASTER_SWORD, RG_MASTER_SWORD, false, true); - } - } +static void AddRandomBottle(std::vector& bottlePool) { + AddItemToMainPool(RandomElement(bottlePool, true)); +} - if (ctx->GetOption(RSK_SHUFFLE_WEIRD_EGG)) { - AddItemToMainPool(RG_WEIRD_EGG); - ctx->possibleIceTrapModels.push_back(RG_WEIRD_EGG); - } else { - ctx->PlaceItemInLocation(RC_HC_MALON_EGG, RG_WEIRD_EGG, false, true); - } - - if (ctx->GetOption(RSK_SHUFFLE_OCARINA)) { - AddItemToMainPool(RG_PROGRESSIVE_OCARINA, 2); - if (ctx->GetOption(RSK_ITEM_POOL).Is(RO_ITEM_POOL_PLENTIFUL)) { - AddItemToPool(PendingJunkPool, RG_PROGRESSIVE_OCARINA); +RandomizerGet GetJunkItem() { + auto ctx = Rando::Context::GetInstance(); + if (ctx->GetOption(RSK_ICE_TRAPS).Is(RO_ICE_TRAPS_MAYHEM) || + ctx->GetOption(RSK_ICE_TRAPS).Is(RO_ICE_TRAPS_ONSLAUGHT)) { + return RG_ICE_TRAP; + } else if (ctx->GetOption(RSK_ICE_TRAPS).Is(RO_ICE_TRAPS_EXTRA)) { + return RandomElement(JunkPoolItems); } - ctx->possibleIceTrapModels.push_back(RG_PROGRESSIVE_OCARINA); - } else { - if (ctx->GetOption(RSK_STARTING_OCARINA).Is(RO_STARTING_OCARINA_OFF)) { - ctx->PlaceItemInLocation(RC_LW_GIFT_FROM_SARIA, RG_PROGRESSIVE_OCARINA, false, true); - ctx->PlaceItemInLocation(RC_HF_OCARINA_OF_TIME_ITEM, RG_PROGRESSIVE_OCARINA, false, true); - } else { - if (ctx->GetOption(RSK_STARTING_OCARINA).IsNot(RO_STARTING_OCARINA_TIME)) { - ctx->PlaceItemInLocation(RC_HF_OCARINA_OF_TIME_ITEM, RG_PROGRESSIVE_OCARINA, false, true); - } - } - } + // Ice Trap is the last item in JunkPoolItems, so subtract 1 to never hit that index + uint8_t idx = Random(0, JunkPoolItems.size() - 1); + return JunkPoolItems[idx]; +} - if (ctx->GetOption(RSK_SHUFFLE_OCARINA_BUTTONS)) { - AddItemToMainPool(RG_OCARINA_A_BUTTON); - AddItemToMainPool(RG_OCARINA_C_UP_BUTTON); - AddItemToMainPool(RG_OCARINA_C_DOWN_BUTTON); - AddItemToMainPool(RG_OCARINA_C_LEFT_BUTTON); - AddItemToMainPool(RG_OCARINA_C_RIGHT_BUTTON); +static RandomizerGet GetPendingJunkItem() { + if (PendingJunkPool.empty()) { + return GetJunkItem(); + } - ctx->possibleIceTrapModels.push_back(RG_OCARINA_A_BUTTON); - ctx->possibleIceTrapModels.push_back(RG_OCARINA_C_UP_BUTTON); - ctx->possibleIceTrapModels.push_back(RG_OCARINA_C_DOWN_BUTTON); - ctx->possibleIceTrapModels.push_back(RG_OCARINA_C_LEFT_BUTTON); - ctx->possibleIceTrapModels.push_back(RG_OCARINA_C_RIGHT_BUTTON); - } + return RandomElement(PendingJunkPool, true); +} - if (ctx->GetOption(RSK_SKELETON_KEY)) { - AddItemToMainPool(RG_SKELETON_KEY); - } - - if (ctx->GetOption(RSK_SHUFFLE_SWIM)) { - AddItemToMainPool(RG_PROGRESSIVE_SCALE); - } - - if (ctx->GetOption(RSK_SHUFFLE_BEEHIVES)) { - //32 total beehive locations - AddItemToPool(PendingJunkPool, RG_RED_RUPEE, 23); - AddItemToPool(PendingJunkPool, RG_BLUE_RUPEE, 9); - } - - // Shuffle Pots - bool overworldPotsActive = ctx->GetOption(RSK_SHUFFLE_POTS).Is(RO_SHUFFLE_POTS_OVERWORLD) || - ctx->GetOption(RSK_SHUFFLE_POTS).Is(RO_SHUFFLE_POTS_ALL); - bool dungeonPotsActive = ctx->GetOption(RSK_SHUFFLE_POTS).Is(RO_SHUFFLE_POTS_DUNGEONS) || - ctx->GetOption(RSK_SHUFFLE_POTS).Is(RO_SHUFFLE_POTS_ALL); - PlaceItemsForType(RCTYPE_POT, overworldPotsActive, dungeonPotsActive); - - // Shuffle Crates - bool overworldCratesActive = ctx->GetOption(RSK_SHUFFLE_CRATES).Is(RO_SHUFFLE_CRATES_OVERWORLD) || - ctx->GetOption(RSK_SHUFFLE_CRATES).Is(RO_SHUFFLE_CRATES_ALL); - bool overworldNLCratesActive = ctx->GetOption(RSK_LOGIC_RULES).Is(RO_LOGIC_NO_LOGIC) && - (ctx->GetOption(RSK_SHUFFLE_CRATES).Is(RO_SHUFFLE_CRATES_OVERWORLD) || - ctx->GetOption(RSK_SHUFFLE_CRATES).Is(RO_SHUFFLE_CRATES_ALL)); - bool dungeonCratesActive = ctx->GetOption(RSK_SHUFFLE_CRATES).Is(RO_SHUFFLE_CRATES_DUNGEONS) || - ctx->GetOption(RSK_SHUFFLE_CRATES).Is(RO_SHUFFLE_CRATES_ALL); - PlaceItemsForType(RCTYPE_CRATE, overworldCratesActive, dungeonCratesActive); - PlaceItemsForType(RCTYPE_NLCRATE, overworldNLCratesActive, dungeonCratesActive); - PlaceItemsForType(RCTYPE_SMALL_CRATE, overworldCratesActive, dungeonCratesActive); - - auto fsMode = ctx->GetOption(RSK_FISHSANITY); - if (fsMode.IsNot(RO_FISHSANITY_OFF)) { - if (fsMode.Is(RO_FISHSANITY_POND) || fsMode.Is(RO_FISHSANITY_BOTH)) { - // 17 max child pond fish - uint8_t pondCt = ctx->GetOption(RSK_FISHSANITY_POND_COUNT).Get(); - for (uint8_t i = 0; i < pondCt; i++) { - AddItemToMainPool(GetJunkItem()); - } - - if (ctx->GetOption(RSK_FISHSANITY_AGE_SPLIT)) { - // 16 max adult pond fish, have to reduce to 16 if every fish is enabled - if (pondCt > 16) - pondCt = 16; - for (uint8_t i = 0; i < pondCt; i++) { - AddItemToMainPool(GetJunkItem()); +// Replace junk items in the pool with pending junk +static void ReplaceMaxItem(const RandomizerGet itemToReplace, int max) { + int itemCount = 0; + for (size_t i = 0; i < ItemPool.size(); i++) { + if (ItemPool[i] == itemToReplace) { + if (itemCount >= max) { + ItemPool[i] = RG_NONE; + } + itemCount++; } - } - } - // 9 grotto fish, 5 zora's domain fish - if (fsMode.Is(RO_FISHSANITY_OVERWORLD) || fsMode.Is(RO_FISHSANITY_BOTH)) { - for (uint8_t i = 0; i < Rando::StaticData::GetOverworldFishLocations().size(); i++) - AddItemToMainPool(GetJunkItem()); } +} - if (fsMode.Is(RO_FISHSANITY_HYRULE_LOACH)) { - AddItemToMainPool(RG_PURPLE_RUPEE); - } else { - ctx->PlaceItemInLocation(RC_LH_HYRULE_LOACH, RG_PURPLE_RUPEE, false, true); - } - } - - if (ctx->GetOption(RSK_SHUFFLE_FISHING_POLE)) { - AddItemToMainPool(RG_FISHING_POLE); - ctx->possibleIceTrapModels.push_back(RG_FISHING_POLE); - } - - if (ctx->GetOption(RSK_INFINITE_UPGRADES).Is(RO_INF_UPGRADES_PROGRESSIVE)) { - AddItemToMainPool(RG_PROGRESSIVE_BOMB_BAG); - AddItemToMainPool(RG_PROGRESSIVE_BOW); - AddItemToMainPool(RG_PROGRESSIVE_NUT_UPGRADE); - AddItemToMainPool(RG_PROGRESSIVE_SLINGSHOT); - AddItemToMainPool(RG_PROGRESSIVE_STICK_UPGRADE); - AddItemToMainPool(RG_PROGRESSIVE_MAGIC_METER); - AddItemToMainPool(RG_PROGRESSIVE_WALLET); - } - - if (ctx->GetOption(RSK_SHUFFLE_MERCHANTS).Is(RO_SHUFFLE_MERCHANTS_BEANS_ONLY) || - ctx->GetOption(RSK_SHUFFLE_MERCHANTS).Is(RO_SHUFFLE_MERCHANTS_ALL)) { - AddItemToMainPool(RG_MAGIC_BEAN_PACK); - if (ctx->GetOption(RSK_ITEM_POOL).Is(RO_ITEM_POOL_PLENTIFUL)) { - AddItemToPool(PendingJunkPool, RG_MAGIC_BEAN_PACK); - } - ctx->possibleIceTrapModels.push_back(RG_MAGIC_BEAN_PACK); - } else { - ctx->PlaceItemInLocation(RC_ZR_MAGIC_BEAN_SALESMAN, RG_MAGIC_BEAN, false, true); - } - - if (ctx->GetOption(RSK_SHUFFLE_MERCHANTS).Is(RO_SHUFFLE_MERCHANTS_ALL_BUT_BEANS) || - ctx->GetOption(RSK_SHUFFLE_MERCHANTS).Is(RO_SHUFFLE_MERCHANTS_ALL)) { - if (/*!ProgressiveGoronSword TODO: Implement Progressive Goron Sword*/true) { - AddItemToMainPool(RG_GIANTS_KNIFE); - } - if (ctx->GetOption(RSK_BOMBCHU_BAG)) { - AddItemToMainPool(RG_PROGRESSIVE_BOMBCHUS); - } else { - AddItemToMainPool(RG_BOMBCHU_10); - } - } else { - ctx->PlaceItemInLocation(RC_KAK_GRANNYS_SHOP, RG_BLUE_POTION_REFILL, false, true); - ctx->PlaceItemInLocation(RC_GC_MEDIGORON, RG_GIANTS_KNIFE, false, true); - ctx->PlaceItemInLocation(RC_WASTELAND_BOMBCHU_SALESMAN, RG_BOMBCHU_10, false, true); - } - - if (ctx->GetOption(RSK_SHUFFLE_FROG_SONG_RUPEES)) { - AddItemToMainPool(RG_PURPLE_RUPEE, 5); - } else { - ctx->PlaceItemInLocation(RC_ZR_FROGS_ZELDAS_LULLABY, RG_PURPLE_RUPEE, false, true); - ctx->PlaceItemInLocation(RC_ZR_FROGS_EPONAS_SONG, RG_PURPLE_RUPEE, false, true); - ctx->PlaceItemInLocation(RC_ZR_FROGS_SARIAS_SONG, RG_PURPLE_RUPEE, false, true); - ctx->PlaceItemInLocation(RC_ZR_FROGS_SUNS_SONG, RG_PURPLE_RUPEE, false, true); - ctx->PlaceItemInLocation(RC_ZR_FROGS_SONG_OF_TIME, RG_PURPLE_RUPEE, false, true); - } - - if (ctx->GetOption(RSK_SHUFFLE_ADULT_TRADE)) { - AddItemToMainPool(RG_POCKET_EGG); - AddItemToMainPool(RG_COJIRO); - AddItemToMainPool(RG_ODD_MUSHROOM); - AddItemToMainPool(RG_ODD_POTION); - AddItemToMainPool(RG_POACHERS_SAW); - AddItemToMainPool(RG_BROKEN_SWORD); - AddItemToMainPool(RG_PRESCRIPTION); - AddItemToMainPool(RG_EYEBALL_FROG); - AddItemToMainPool(RG_EYEDROPS); - } - AddItemToMainPool(RG_CLAIM_CHECK); - - if (ctx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME).Is(RO_CHEST_GAME_SINGLE_KEYS)) { - AddItemToMainPool(RG_TREASURE_GAME_SMALL_KEY, 6); // 6 individual keys - } else if (ctx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME).Is(RO_CHEST_GAME_PACK)) { - AddItemToMainPool(RG_TREASURE_GAME_SMALL_KEY); // 1 key which will behave as a pack of 6 - } - - if (ctx->GetOption(RSK_SHUFFLE_TOKENS).Is(RO_TOKENSANITY_OFF)) { - for (RandomizerCheck loc : ctx->GetLocations(ctx->allLocations, RCTYPE_SKULL_TOKEN)) { - ctx->PlaceItemInLocation(loc, RG_GOLD_SKULLTULA_TOKEN, false, true); - } - } else if (ctx->GetOption(RSK_SHUFFLE_TOKENS).Is(RO_TOKENSANITY_DUNGEONS)) { - for (RandomizerCheck loc : ctx->GetLocations(ctx->allLocations, RCTYPE_SKULL_TOKEN)) { - if (Rando::StaticData::GetLocation(loc)->IsOverworld()) { - ctx->PlaceItemInLocation((RandomizerCheck)loc, RG_GOLD_SKULLTULA_TOKEN, false, true); - } else { - AddItemToMainPool(RG_GOLD_SKULLTULA_TOKEN); - } - } - } else if (ctx->GetOption(RSK_SHUFFLE_TOKENS).Is(RO_TOKENSANITY_OVERWORLD)) { - for (RandomizerCheck loc : ctx->GetLocations(ctx->allLocations, RCTYPE_SKULL_TOKEN)) { - if (Rando::StaticData::GetLocation(loc)->IsDungeon()) { - ctx->PlaceItemInLocation((RandomizerCheck)loc, RG_GOLD_SKULLTULA_TOKEN, false, true); - } else { - AddItemToMainPool(RG_GOLD_SKULLTULA_TOKEN); - } - } - } else { - AddItemToMainPool(RG_GOLD_SKULLTULA_TOKEN, 100); - } - - if (ctx->GetOption(RSK_SHUFFLE_100_GS_REWARD)) { - if (ctx->GetOption(RSK_SHUFFLE_TOKENS).IsNot(RO_TOKENSANITY_OFF) && ctx->GetOption(RSK_ITEM_POOL).Is(RO_ITEM_POOL_PLENTIFUL)) { - AddItemToPool(PendingJunkPool, RG_GOLD_SKULLTULA_TOKEN, 10); - } - AddItemToMainPool(RG_HUGE_RUPEE); - } else { - ctx->PlaceItemInLocation(RC_KAK_100_GOLD_SKULLTULA_REWARD, RG_HUGE_RUPEE, false, true); - } - - if (ctx->GetOption(RSK_SHUFFLE_BOSS_SOULS)) { - AddItemToMainPool(RG_GOHMA_SOUL); - AddItemToMainPool(RG_KING_DODONGO_SOUL); - AddItemToMainPool(RG_BARINADE_SOUL); - AddItemToMainPool(RG_PHANTOM_GANON_SOUL); - AddItemToMainPool(RG_VOLVAGIA_SOUL); - AddItemToMainPool(RG_MORPHA_SOUL); - AddItemToMainPool(RG_BONGO_BONGO_SOUL); - AddItemToMainPool(RG_TWINROVA_SOUL); - - ctx->possibleIceTrapModels.push_back(RG_GOHMA_SOUL); - ctx->possibleIceTrapModels.push_back(RG_KING_DODONGO_SOUL); - ctx->possibleIceTrapModels.push_back(RG_BARINADE_SOUL); - ctx->possibleIceTrapModels.push_back(RG_PHANTOM_GANON_SOUL); - ctx->possibleIceTrapModels.push_back(RG_VOLVAGIA_SOUL); - ctx->possibleIceTrapModels.push_back(RG_MORPHA_SOUL); - ctx->possibleIceTrapModels.push_back(RG_BONGO_BONGO_SOUL); - ctx->possibleIceTrapModels.push_back(RG_TWINROVA_SOUL); - if (ctx->GetOption(RSK_SHUFFLE_BOSS_SOULS).Is(RO_BOSS_SOULS_ON_PLUS_GANON)) { - AddItemToMainPool(RG_GANON_SOUL); - ctx->possibleIceTrapModels.push_back(RG_GANON_SOUL); - } - } - - if (ctx->GetOption(RSK_SHUFFLE_CHILD_WALLET)) { - AddItemToMainPool(RG_PROGRESSIVE_WALLET); - } - - if (ctx->GetOption(RSK_INCLUDE_TYCOON_WALLET)) { - AddItemToMainPool(RG_PROGRESSIVE_WALLET); - } - - if (ctx->GetOption(RSK_SHUFFLE_DEKU_STICK_BAG)) { - AddItemToMainPool(RG_PROGRESSIVE_STICK_UPGRADE); - } - - if (ctx->GetOption(RSK_SHUFFLE_DEKU_NUT_BAG)) { - AddItemToMainPool(RG_PROGRESSIVE_NUT_UPGRADE); - } - - if (ctx->GetOption(RSK_BOMBCHU_BAG)) { - AddItemToMainPool(RG_PROGRESSIVE_BOMBCHUS, 5); - } else { - AddItemToMainPool(RG_BOMBCHU_5); - AddItemToMainPool(RG_BOMBCHU_10, 3); - AddItemToMainPool(RG_BOMBCHU_20); - } - - //Ice Traps - AddItemToMainPool(RG_ICE_TRAP); - if (ctx->GetDungeon(Rando::GERUDO_TRAINING_GROUND)->IsVanilla()) { - AddItemToMainPool(RG_ICE_TRAP); - } - if (ctx->GetDungeon(Rando::GANONS_CASTLE)->IsVanilla()) { - AddItemToMainPool(RG_ICE_TRAP, 4); - } - - //Gerudo Fortress - if (ctx->GetOption(RSK_GERUDO_FORTRESS).Is(RO_GF_CARPENTERS_FREE)) { - ctx->PlaceItemInLocation(RC_GF_NORTH_F1_CARPENTER, RG_RECOVERY_HEART, false, true); - ctx->PlaceItemInLocation(RC_GF_NORTH_F2_CARPENTER, RG_RECOVERY_HEART, false, true); - ctx->PlaceItemInLocation(RC_GF_SOUTH_F1_CARPENTER, RG_RECOVERY_HEART, false, true); - ctx->PlaceItemInLocation(RC_GF_SOUTH_F2_CARPENTER, RG_RECOVERY_HEART, false, true); - } else if (ctx->GetOption(RSK_GERUDO_KEYS).IsNot(RO_GERUDO_KEYS_VANILLA)) { - if (ctx->GetOption(RSK_GERUDO_FORTRESS).Is(RO_GF_CARPENTERS_FAST)) { - AddItemToMainPool(RG_GERUDO_FORTRESS_SMALL_KEY); - ctx->PlaceItemInLocation(RC_GF_NORTH_F2_CARPENTER, RG_RECOVERY_HEART, false, true); - ctx->PlaceItemInLocation(RC_GF_SOUTH_F1_CARPENTER, RG_RECOVERY_HEART, false, true); - ctx->PlaceItemInLocation(RC_GF_SOUTH_F2_CARPENTER, RG_RECOVERY_HEART, false, true); - } else { - //Only add key ring if 4 Fortress keys necessary - if (ctx->GetOption(RSK_KEYRINGS_GERUDO_FORTRESS) && ctx->GetOption(RSK_KEYRINGS)) { - AddItemToMainPool(RG_GERUDO_FORTRESS_KEY_RING); - //Add junk to make up for missing keys - for (uint8_t i = 0; i < 3; i++) { - AddItemToMainPool(GetJunkItem()); +void PlaceJunkInExcludedLocation(const RandomizerCheck il) { + // place a non-advancement item in this location + auto ctx = Rando::Context::GetInstance(); + for (size_t i = 0; i < ItemPool.size(); i++) { + if (!Rando::StaticData::RetrieveItem(ItemPool[i]).IsAdvancement()) { + ctx->PlaceItemInLocation(il, ItemPool[i]); + ItemPool.erase(ItemPool.begin() + i); + return; } - } else { - AddItemToMainPool(RG_GERUDO_FORTRESS_SMALL_KEY, 4); - } } - if (ctx->GetOption(RSK_ITEM_POOL).Is(RO_ITEM_POOL_PLENTIFUL)) { - if (ctx->GetOption(RSK_KEYRINGS_GERUDO_FORTRESS) && ctx->GetOption(RSK_GERUDO_FORTRESS).Is(RO_GF_CARPENTERS_NORMAL) && ctx->GetOption(RSK_KEYRINGS) ) { - AddItemToPool(PendingJunkPool, RG_GERUDO_FORTRESS_KEY_RING); - } else { - AddItemToPool(PendingJunkPool, RG_GERUDO_FORTRESS_SMALL_KEY); - } - } - } else { - if (ctx->GetOption(RSK_GERUDO_FORTRESS).Is(RO_GF_CARPENTERS_FAST)) { - ctx->PlaceItemInLocation(RC_GF_NORTH_F1_CARPENTER, RG_GERUDO_FORTRESS_SMALL_KEY, false, true); - ctx->PlaceItemInLocation(RC_GF_NORTH_F2_CARPENTER, RG_RECOVERY_HEART, false, true); - ctx->PlaceItemInLocation(RC_GF_SOUTH_F1_CARPENTER, RG_RECOVERY_HEART, false, true); - ctx->PlaceItemInLocation(RC_GF_SOUTH_F2_CARPENTER, RG_RECOVERY_HEART, false, true); - } else { - ctx->PlaceItemInLocation(RC_GF_NORTH_F1_CARPENTER, RG_GERUDO_FORTRESS_SMALL_KEY, false, true); - ctx->PlaceItemInLocation(RC_GF_NORTH_F2_CARPENTER, RG_GERUDO_FORTRESS_SMALL_KEY, false, true); - ctx->PlaceItemInLocation(RC_GF_SOUTH_F1_CARPENTER, RG_GERUDO_FORTRESS_SMALL_KEY, false, true); - ctx->PlaceItemInLocation(RC_GF_SOUTH_F2_CARPENTER, RG_GERUDO_FORTRESS_SMALL_KEY, false, true); - } - } + SPDLOG_ERROR("ERROR: No Junk to Place!!!"); +} - //Gerudo Membership Card - if (ctx->GetOption(RSK_SHUFFLE_GERUDO_MEMBERSHIP_CARD) && ctx->GetOption(RSK_GERUDO_FORTRESS).IsNot(RO_GF_CARPENTERS_FREE)) { - AddItemToMainPool(RG_GERUDO_MEMBERSHIP_CARD); - ctx->possibleIceTrapModels.push_back(RG_GERUDO_MEMBERSHIP_CARD); - } else if (ctx->GetOption(RSK_SHUFFLE_GERUDO_MEMBERSHIP_CARD)) { - AddItemToPool(PendingJunkPool, RG_GERUDO_MEMBERSHIP_CARD); - ctx->PlaceItemInLocation(RC_GF_GERUDO_MEMBERSHIP_CARD, RG_ICE_TRAP, false, true); - } else { - ctx->PlaceItemInLocation(RC_GF_GERUDO_MEMBERSHIP_CARD, RG_GERUDO_MEMBERSHIP_CARD, false, true); - } - - //Keys - - //For key rings, need to add as many junk items as "missing" keys - if (ctx->GetOption(RSK_KEYRINGS).IsNot(RO_KEYRINGS_OFF)) { - uint8_t ringJunkAmt = 0; +static void PlaceVanillaMapsAndCompasses() { + auto ctx = Rando::Context::GetInstance(); for (auto dungeon : ctx->GetDungeons()->GetDungeonList()) { - if (dungeon->HasKeyRing()) { - ringJunkAmt += dungeon->GetSmallKeyCount() - 1; - } + dungeon->PlaceVanillaMap(); + dungeon->PlaceVanillaCompass(); } - for (uint8_t i = 0; i < ringJunkAmt; i++) { - AddItemToMainPool(GetJunkItem()); - } - } +} - if (ctx->GetOption(RSK_ITEM_POOL).Is(RO_ITEM_POOL_PLENTIFUL)) { - if (ctx->GetOption(RSK_SHUFFLE_GERUDO_MEMBERSHIP_CARD)) { - AddItemToPool(PendingJunkPool, RG_GERUDO_MEMBERSHIP_CARD); +static void PlaceVanillaSmallKeys() { + auto ctx = Rando::Context::GetInstance(); + for (auto dungeon : ctx->GetDungeons()->GetDungeonList()) { + dungeon->PlaceVanillaSmallKeys(); + } +} + +static void PlaceVanillaBossKeys() { + auto ctx = Rando::Context::GetInstance(); + for (auto dungeon : ctx->GetDungeons()->GetDungeonList()) { + dungeon->PlaceVanillaBossKey(); + } +} + +static void PlaceItemsForType(RandomizerCheckType rctype, bool overworldActive, bool dungeonActive) { + if (!(overworldActive || dungeonActive)) { + return; + } + for (RandomizerCheck rc : ctx->GetLocations(ctx->allLocations, rctype)) { + auto loc = Rando::StaticData::GetLocation(rc); + + // If item is in the overworld and shuffled, add its item to the pool + if (loc->IsOverworld()) { + if (overworldActive) { + AddItemToMainPool(loc->GetVanillaItem()); + } + } else { + if (dungeonActive) { + // If the same in MQ and vanilla, add. + RandomizerCheckQuest currentQuest = loc->GetQuest(); + if (currentQuest == RCQUEST_BOTH) { + AddItemToMainPool(loc->GetVanillaItem()); + } else { + // Check if current item's dungeon is vanilla or MQ, and only add if quest corresponds to it. + SceneID itemScene = loc->GetScene(); + + if (itemScene >= SCENE_DEKU_TREE && itemScene <= SCENE_GERUDO_TRAINING_GROUND) { + bool isMQ = ctx->GetDungeon(itemScene)->IsMQ(); + + if ((isMQ && currentQuest == RCQUEST_MQ) || (!isMQ && currentQuest == RCQUEST_VANILLA)) { + AddItemToMainPool(loc->GetVanillaItem()); + } + } + } + } + } + } +} + +static void SetScarceItemPool() { + ReplaceMaxItem(RG_PROGRESSIVE_BOMBCHUS, 3); + ReplaceMaxItem(RG_BOMBCHU_5, 1); + ReplaceMaxItem(RG_BOMBCHU_10, 2); + ReplaceMaxItem(RG_BOMBCHU_20, 0); + ReplaceMaxItem(RG_PROGRESSIVE_MAGIC_METER, 1); + ReplaceMaxItem(RG_DOUBLE_DEFENSE, 0); + ReplaceMaxItem(RG_PROGRESSIVE_STICK_UPGRADE, ctx->GetOption(RSK_SHUFFLE_DEKU_STICK_BAG) ? 2 : 1); + ReplaceMaxItem(RG_PROGRESSIVE_NUT_UPGRADE, ctx->GetOption(RSK_SHUFFLE_DEKU_NUT_BAG) ? 2 : 1); + ReplaceMaxItem(RG_PROGRESSIVE_BOW, 2); + ReplaceMaxItem(RG_PROGRESSIVE_SLINGSHOT, 2); + ReplaceMaxItem(RG_PROGRESSIVE_BOMB_BAG, 2); + ReplaceMaxItem(RG_HEART_CONTAINER, 0); +} + +static void SetMinimalItemPool() { + auto ctx = Rando::Context::GetInstance(); + ReplaceMaxItem(RG_PROGRESSIVE_BOMBCHUS, 1); + ReplaceMaxItem(RG_BOMBCHU_5, 1); + ReplaceMaxItem(RG_BOMBCHU_10, 0); + ReplaceMaxItem(RG_BOMBCHU_20, 0); + ReplaceMaxItem(RG_NAYRUS_LOVE, 0); + ReplaceMaxItem(RG_PROGRESSIVE_MAGIC_METER, 1); + ReplaceMaxItem(RG_DOUBLE_DEFENSE, 0); + ReplaceMaxItem(RG_PROGRESSIVE_STICK_UPGRADE, ctx->GetOption(RSK_SHUFFLE_DEKU_STICK_BAG) ? 1 : 0); + ReplaceMaxItem(RG_PROGRESSIVE_NUT_UPGRADE, ctx->GetOption(RSK_SHUFFLE_DEKU_NUT_BAG) ? 1 : 0); + ReplaceMaxItem(RG_PROGRESSIVE_BOW, 1); + ReplaceMaxItem(RG_PROGRESSIVE_SLINGSHOT, 1); + ReplaceMaxItem(RG_PROGRESSIVE_BOMB_BAG, 1); + ReplaceMaxItem(RG_PIECE_OF_HEART, 0); + // Need an extra heart container when starting with 1 heart to be able to reach 3 hearts + ReplaceMaxItem(RG_HEART_CONTAINER, (ctx->GetOption(RSK_STARTING_HEARTS).Get() == 18) ? 1 : 0); +} + +void GenerateItemPool() { + // RANDOTODO proper removal of items not in pool or logically relevant instead of dummy checks. + auto ctx = Rando::Context::GetInstance(); + ItemPool.clear(); + PendingJunkPool.clear(); + + // Initialize ice trap models to always major items + ctx->possibleIceTrapModels = { + RG_MIRROR_SHIELD, + RG_BOOMERANG, + RG_LENS_OF_TRUTH, + RG_MEGATON_HAMMER, + RG_IRON_BOOTS, + RG_HOVER_BOOTS, + RG_STONE_OF_AGONY, + RG_DINS_FIRE, + RG_FARORES_WIND, + RG_NAYRUS_LOVE, + RG_FIRE_ARROWS, + RG_ICE_ARROWS, + RG_LIGHT_ARROWS, + RG_DOUBLE_DEFENSE, + RG_CLAIM_CHECK, + RG_PROGRESSIVE_HOOKSHOT, + RG_PROGRESSIVE_STRENGTH, + RG_PROGRESSIVE_BOMB_BAG, + RG_PROGRESSIVE_BOW, + RG_PROGRESSIVE_SLINGSHOT, + RG_PROGRESSIVE_WALLET, + RG_PROGRESSIVE_SCALE, + RG_PROGRESSIVE_MAGIC_METER, + }; + // Check song shuffle and dungeon reward shuffle just for ice traps + if (ctx->GetOption(RSK_SHUFFLE_SONGS).Is(RO_SONG_SHUFFLE_ANYWHERE)) { + // Push item ids for songs + ctx->possibleIceTrapModels.push_back(RG_ZELDAS_LULLABY); + ctx->possibleIceTrapModels.push_back(RG_EPONAS_SONG); + ctx->possibleIceTrapModels.push_back(RG_SARIAS_SONG); + ctx->possibleIceTrapModels.push_back(RG_SUNS_SONG); + ctx->possibleIceTrapModels.push_back(RG_SONG_OF_TIME); + ctx->possibleIceTrapModels.push_back(RG_SONG_OF_STORMS); + ctx->possibleIceTrapModels.push_back(RG_MINUET_OF_FOREST); + ctx->possibleIceTrapModels.push_back(RG_BOLERO_OF_FIRE); + ctx->possibleIceTrapModels.push_back(RG_SERENADE_OF_WATER); + ctx->possibleIceTrapModels.push_back(RG_REQUIEM_OF_SPIRIT); + ctx->possibleIceTrapModels.push_back(RG_NOCTURNE_OF_SHADOW); + ctx->possibleIceTrapModels.push_back(RG_PRELUDE_OF_LIGHT); + } + if (ctx->GetOption(RSK_SHUFFLE_DUNGEON_REWARDS).Is(RO_DUNGEON_REWARDS_ANYWHERE)) { + // Push item ids for dungeon rewards + ctx->possibleIceTrapModels.push_back(RG_KOKIRI_EMERALD); + ctx->possibleIceTrapModels.push_back(RG_GORON_RUBY); + ctx->possibleIceTrapModels.push_back(RG_ZORA_SAPPHIRE); + ctx->possibleIceTrapModels.push_back(RG_FOREST_MEDALLION); + ctx->possibleIceTrapModels.push_back(RG_FIRE_MEDALLION); + ctx->possibleIceTrapModels.push_back(RG_WATER_MEDALLION); + ctx->possibleIceTrapModels.push_back(RG_SPIRIT_MEDALLION); + ctx->possibleIceTrapModels.push_back(RG_SHADOW_MEDALLION); + ctx->possibleIceTrapModels.push_back(RG_LIGHT_MEDALLION); + } + + if (ctx->GetOption(RSK_TRIFORCE_HUNT)) { + ctx->possibleIceTrapModels.push_back(RG_TRIFORCE_PIECE); + AddItemToMainPool(RG_TRIFORCE_PIECE, (ctx->GetOption(RSK_TRIFORCE_HUNT_PIECES_TOTAL).Get() + 1)); + ctx->PlaceItemInLocation(RC_TRIFORCE_COMPLETED, RG_TRIFORCE); // Win condition + ctx->PlaceItemInLocation(RC_GANON, GetJunkItem(), false, true); + } else { + ctx->PlaceItemInLocation(RC_GANON, RG_TRIFORCE); // Win condition + } + + // Fixed item locations + ctx->PlaceItemInLocation(RC_HC_ZELDAS_LETTER, RG_ZELDAS_LETTER); + + if (ctx->GetOption(RSK_SHUFFLE_KOKIRI_SWORD)) { + AddItemToMainPool(RG_KOKIRI_SWORD); + ctx->possibleIceTrapModels.push_back(RG_KOKIRI_SWORD); + } else { + if (!ctx->GetOption(RSK_STARTING_KOKIRI_SWORD)) { + ctx->PlaceItemInLocation(RC_KF_KOKIRI_SWORD_CHEST, RG_KOKIRI_SWORD, false, true); + } + } + + if (ctx->GetOption(RSK_SHUFFLE_MASTER_SWORD)) { + AddItemToMainPool(RG_MASTER_SWORD); + ctx->possibleIceTrapModels.push_back(RG_MASTER_SWORD); + } else { + if (!ctx->GetOption(RSK_STARTING_MASTER_SWORD)) { + ctx->PlaceItemInLocation(RC_TOT_MASTER_SWORD, RG_MASTER_SWORD, false, true); + } + } + + if (ctx->GetOption(RSK_SHUFFLE_WEIRD_EGG)) { + AddItemToMainPool(RG_WEIRD_EGG); + ctx->possibleIceTrapModels.push_back(RG_WEIRD_EGG); + } else { + ctx->PlaceItemInLocation(RC_HC_MALON_EGG, RG_WEIRD_EGG, false, true); + } + + if (ctx->GetOption(RSK_SHUFFLE_OCARINA)) { + AddItemToMainPool(RG_PROGRESSIVE_OCARINA, 2); + if (ctx->GetOption(RSK_ITEM_POOL).Is(RO_ITEM_POOL_PLENTIFUL)) { + AddItemToPool(PendingJunkPool, RG_PROGRESSIVE_OCARINA); + } + ctx->possibleIceTrapModels.push_back(RG_PROGRESSIVE_OCARINA); + } else { + if (ctx->GetOption(RSK_STARTING_OCARINA).Is(RO_STARTING_OCARINA_OFF)) { + ctx->PlaceItemInLocation(RC_LW_GIFT_FROM_SARIA, RG_PROGRESSIVE_OCARINA, false, true); + ctx->PlaceItemInLocation(RC_HF_OCARINA_OF_TIME_ITEM, RG_PROGRESSIVE_OCARINA, false, true); + } else { + if (ctx->GetOption(RSK_STARTING_OCARINA).IsNot(RO_STARTING_OCARINA_TIME)) { + ctx->PlaceItemInLocation(RC_HF_OCARINA_OF_TIME_ITEM, RG_PROGRESSIVE_OCARINA, false, true); + } + } + } + + if (ctx->GetOption(RSK_SHUFFLE_OCARINA_BUTTONS)) { + AddItemToMainPool(RG_OCARINA_A_BUTTON); + AddItemToMainPool(RG_OCARINA_C_UP_BUTTON); + AddItemToMainPool(RG_OCARINA_C_DOWN_BUTTON); + AddItemToMainPool(RG_OCARINA_C_LEFT_BUTTON); + AddItemToMainPool(RG_OCARINA_C_RIGHT_BUTTON); + + ctx->possibleIceTrapModels.push_back(RG_OCARINA_A_BUTTON); + ctx->possibleIceTrapModels.push_back(RG_OCARINA_C_UP_BUTTON); + ctx->possibleIceTrapModels.push_back(RG_OCARINA_C_DOWN_BUTTON); + ctx->possibleIceTrapModels.push_back(RG_OCARINA_C_LEFT_BUTTON); + ctx->possibleIceTrapModels.push_back(RG_OCARINA_C_RIGHT_BUTTON); + } + + if (ctx->GetOption(RSK_SKELETON_KEY)) { + AddItemToMainPool(RG_SKELETON_KEY); + } + + if (ctx->GetOption(RSK_SHUFFLE_SWIM)) { + AddItemToMainPool(RG_PROGRESSIVE_SCALE); + } + + if (ctx->GetOption(RSK_SHUFFLE_BEEHIVES)) { + // 32 total beehive locations + AddItemToPool(PendingJunkPool, RG_RED_RUPEE, 23); + AddItemToPool(PendingJunkPool, RG_BLUE_RUPEE, 9); + } + + // Shuffle Pots + bool overworldPotsActive = ctx->GetOption(RSK_SHUFFLE_POTS).Is(RO_SHUFFLE_POTS_OVERWORLD) || + ctx->GetOption(RSK_SHUFFLE_POTS).Is(RO_SHUFFLE_POTS_ALL); + bool dungeonPotsActive = ctx->GetOption(RSK_SHUFFLE_POTS).Is(RO_SHUFFLE_POTS_DUNGEONS) || + ctx->GetOption(RSK_SHUFFLE_POTS).Is(RO_SHUFFLE_POTS_ALL); + PlaceItemsForType(RCTYPE_POT, overworldPotsActive, dungeonPotsActive); + + // Shuffle Crates + bool overworldCratesActive = ctx->GetOption(RSK_SHUFFLE_CRATES).Is(RO_SHUFFLE_CRATES_OVERWORLD) || + ctx->GetOption(RSK_SHUFFLE_CRATES).Is(RO_SHUFFLE_CRATES_ALL); + bool overworldNLCratesActive = ctx->GetOption(RSK_LOGIC_RULES).Is(RO_LOGIC_NO_LOGIC) && + (ctx->GetOption(RSK_SHUFFLE_CRATES).Is(RO_SHUFFLE_CRATES_OVERWORLD) || + ctx->GetOption(RSK_SHUFFLE_CRATES).Is(RO_SHUFFLE_CRATES_ALL)); + bool dungeonCratesActive = ctx->GetOption(RSK_SHUFFLE_CRATES).Is(RO_SHUFFLE_CRATES_DUNGEONS) || + ctx->GetOption(RSK_SHUFFLE_CRATES).Is(RO_SHUFFLE_CRATES_ALL); + PlaceItemsForType(RCTYPE_CRATE, overworldCratesActive, dungeonCratesActive); + PlaceItemsForType(RCTYPE_NLCRATE, overworldNLCratesActive, dungeonCratesActive); + PlaceItemsForType(RCTYPE_SMALL_CRATE, overworldCratesActive, dungeonCratesActive); + + auto fsMode = ctx->GetOption(RSK_FISHSANITY); + if (fsMode.IsNot(RO_FISHSANITY_OFF)) { + if (fsMode.Is(RO_FISHSANITY_POND) || fsMode.Is(RO_FISHSANITY_BOTH)) { + // 17 max child pond fish + uint8_t pondCt = ctx->GetOption(RSK_FISHSANITY_POND_COUNT).Get(); + for (uint8_t i = 0; i < pondCt; i++) { + AddItemToMainPool(GetJunkItem()); + } + + if (ctx->GetOption(RSK_FISHSANITY_AGE_SPLIT)) { + // 16 max adult pond fish, have to reduce to 16 if every fish is enabled + if (pondCt > 16) + pondCt = 16; + for (uint8_t i = 0; i < pondCt; i++) { + AddItemToMainPool(GetJunkItem()); + } + } + } + // 9 grotto fish, 5 zora's domain fish + if (fsMode.Is(RO_FISHSANITY_OVERWORLD) || fsMode.Is(RO_FISHSANITY_BOTH)) { + for (uint8_t i = 0; i < Rando::StaticData::GetOverworldFishLocations().size(); i++) + AddItemToMainPool(GetJunkItem()); + } + + if (fsMode.Is(RO_FISHSANITY_HYRULE_LOACH)) { + AddItemToMainPool(RG_PURPLE_RUPEE); + } else { + ctx->PlaceItemInLocation(RC_LH_HYRULE_LOACH, RG_PURPLE_RUPEE, false, true); + } } if (ctx->GetOption(RSK_SHUFFLE_FISHING_POLE)) { - AddItemToPool(PendingJunkPool, RG_FISHING_POLE); + AddItemToMainPool(RG_FISHING_POLE); + ctx->possibleIceTrapModels.push_back(RG_FISHING_POLE); } - //Plentiful small keys - if (ctx->GetOption(RSK_KEYSANITY).Is(RO_DUNGEON_ITEM_LOC_ANYWHERE) || ctx->GetOption(RSK_KEYSANITY).Is(RO_DUNGEON_ITEM_LOC_ANY_DUNGEON) || ctx->GetOption(RSK_KEYSANITY).Is(RO_DUNGEON_ITEM_LOC_OVERWORLD)) { - if (ctx->GetDungeon(Rando::BOTTOM_OF_THE_WELL)->HasKeyRing()) { - AddItemToPool(PendingJunkPool, RG_BOTTOM_OF_THE_WELL_KEY_RING); - } else { - AddItemToPool(PendingJunkPool, RG_BOTTOM_OF_THE_WELL_SMALL_KEY); - } - if (ctx->GetDungeon(Rando::FOREST_TEMPLE)->HasKeyRing()) { - AddItemToPool(PendingJunkPool, RG_FOREST_TEMPLE_KEY_RING); - } else { - AddItemToPool(PendingJunkPool, RG_FOREST_TEMPLE_SMALL_KEY); - } - if (ctx->GetDungeon(Rando::FIRE_TEMPLE)->HasKeyRing()) { - AddItemToPool(PendingJunkPool, RG_FIRE_TEMPLE_KEY_RING); - } else { - AddItemToPool(PendingJunkPool, RG_FIRE_TEMPLE_SMALL_KEY); - } - if (ctx->GetDungeon(Rando::WATER_TEMPLE)->HasKeyRing()) { - AddItemToPool(PendingJunkPool, RG_WATER_TEMPLE_KEY_RING); - } else { - AddItemToPool(PendingJunkPool, RG_WATER_TEMPLE_SMALL_KEY); - } - if (ctx->GetDungeon(Rando::SPIRIT_TEMPLE)->HasKeyRing()) { - AddItemToPool(PendingJunkPool, RG_SPIRIT_TEMPLE_KEY_RING); - } else { - AddItemToPool(PendingJunkPool, RG_SPIRIT_TEMPLE_SMALL_KEY); - } - if (ctx->GetDungeon(Rando::SHADOW_TEMPLE)->HasKeyRing()) { - AddItemToPool(PendingJunkPool, RG_SHADOW_TEMPLE_KEY_RING); - } else { - AddItemToPool(PendingJunkPool, RG_SHADOW_TEMPLE_SMALL_KEY); - } - if (ctx->GetDungeon(Rando::GERUDO_TRAINING_GROUND)->HasKeyRing()) { - AddItemToPool(PendingJunkPool, RG_GERUDO_TRAINING_GROUND_KEY_RING); - } else { - AddItemToPool(PendingJunkPool, RG_GERUDO_TRAINING_GROUND_SMALL_KEY); - } - if (ctx->GetDungeon(Rando::GANONS_CASTLE)->HasKeyRing()) { - AddItemToPool(PendingJunkPool, RG_GANONS_CASTLE_KEY_RING); - } else { - AddItemToPool(PendingJunkPool, RG_GANONS_CASTLE_SMALL_KEY); - } + if (ctx->GetOption(RSK_INFINITE_UPGRADES).Is(RO_INF_UPGRADES_PROGRESSIVE)) { + AddItemToMainPool(RG_PROGRESSIVE_BOMB_BAG); + AddItemToMainPool(RG_PROGRESSIVE_BOW); + AddItemToMainPool(RG_PROGRESSIVE_NUT_UPGRADE); + AddItemToMainPool(RG_PROGRESSIVE_SLINGSHOT); + AddItemToMainPool(RG_PROGRESSIVE_STICK_UPGRADE); + AddItemToMainPool(RG_PROGRESSIVE_MAGIC_METER); + AddItemToMainPool(RG_PROGRESSIVE_WALLET); } - if (ctx->GetOption(RSK_BOSS_KEYSANITY).Is(RO_DUNGEON_ITEM_LOC_ANYWHERE) || ctx->GetOption(RSK_BOSS_KEYSANITY).Is(RO_DUNGEON_ITEM_LOC_ANY_DUNGEON) || ctx->GetOption(RSK_BOSS_KEYSANITY).Is(RO_DUNGEON_ITEM_LOC_OVERWORLD)) { - AddItemToPool(PendingJunkPool, RG_FOREST_TEMPLE_BOSS_KEY); - AddItemToPool(PendingJunkPool, RG_FIRE_TEMPLE_BOSS_KEY); - AddItemToPool(PendingJunkPool, RG_WATER_TEMPLE_BOSS_KEY); - AddItemToPool(PendingJunkPool, RG_SPIRIT_TEMPLE_BOSS_KEY); - AddItemToPool(PendingJunkPool, RG_SHADOW_TEMPLE_BOSS_KEY); - } - - if (ctx->GetOption(RSK_GANONS_BOSS_KEY).Is(RO_GANON_BOSS_KEY_ANYWHERE) || ctx->GetOption(RSK_GANONS_BOSS_KEY).Is(RO_GANON_BOSS_KEY_ANY_DUNGEON) || ctx->GetOption(RSK_GANONS_BOSS_KEY).Is(RO_GANON_BOSS_KEY_OVERWORLD)) { - AddItemToPool(PendingJunkPool, RG_GANONS_CASTLE_BOSS_KEY); - } - } - - if (ctx->GetOption(RSK_LOCK_OVERWORLD_DOORS)) { - AddItemToPool(ItemPool, RG_GUARD_HOUSE_KEY); - AddItemToPool(ItemPool, RG_MARKET_BAZAAR_KEY); - AddItemToPool(ItemPool, RG_MARKET_POTION_SHOP_KEY); - AddItemToPool(ItemPool, RG_MASK_SHOP_KEY); - AddItemToPool(ItemPool, RG_MARKET_SHOOTING_GALLERY_KEY); - AddItemToPool(ItemPool, RG_BOMBCHU_BOWLING_KEY); - AddItemToPool(ItemPool, RG_TREASURE_CHEST_GAME_BUILDING_KEY); - AddItemToPool(ItemPool, RG_BOMBCHU_SHOP_KEY); - AddItemToPool(ItemPool, RG_RICHARDS_HOUSE_KEY); - AddItemToPool(ItemPool, RG_ALLEY_HOUSE_KEY); - AddItemToPool(ItemPool, RG_KAK_BAZAAR_KEY); - AddItemToPool(ItemPool, RG_KAK_POTION_SHOP_KEY); - AddItemToPool(ItemPool, RG_BOSS_HOUSE_KEY); - AddItemToPool(ItemPool, RG_GRANNYS_POTION_SHOP_KEY); - AddItemToPool(ItemPool, RG_SKULLTULA_HOUSE_KEY); - AddItemToPool(ItemPool, RG_IMPAS_HOUSE_KEY); - AddItemToPool(ItemPool, RG_WINDMILL_KEY); - AddItemToPool(ItemPool, RG_KAK_SHOOTING_GALLERY_KEY); - AddItemToPool(ItemPool, RG_DAMPES_HUT_KEY); - AddItemToPool(ItemPool, RG_TALONS_HOUSE_KEY); - AddItemToPool(ItemPool, RG_STABLES_KEY); - AddItemToPool(ItemPool, RG_BACK_TOWER_KEY); - AddItemToPool(ItemPool, RG_HYLIA_LAB_KEY); - AddItemToPool(ItemPool, RG_FISHING_HOLE_KEY); - } - - //Shopsanity - if ( - ctx->GetOption(RSK_SHOPSANITY).Is(RO_SHOPSANITY_OFF) || - ( - ctx->GetOption(RSK_SHOPSANITY).Is(RO_SHOPSANITY_SPECIFIC_COUNT) && - ctx->GetOption(RSK_SHOPSANITY_COUNT).Is(RO_SHOPSANITY_COUNT_ZERO_ITEMS) - ) - ) { - AddItemsToPool(ItemPool, normalRupees); - } else { - AddItemsToPool(ItemPool, shopsanityRupees); //Shopsanity gets extra large rupees - } - - // Shuffle Fairies - if (ctx->GetOption(RSK_SHUFFLE_FAIRIES)) { - for (auto rc : Rando::StaticData::GetOverworldFairyLocations()) { - AddItemToMainPool(GetJunkItem()); - } - // 8 extra for Ganon's Castle + 2 Dodongo's Cavern Gossip Stone + 3 Shadow Temple - int extra = 13; - extra += ctx->GetDungeon(Rando::FIRE_TEMPLE)->IsVanilla() ? 0 : 2; - extra += ctx->GetDungeon(Rando::WATER_TEMPLE)->IsVanilla() ? 0 : 3; - extra += ctx->GetDungeon(Rando::SPIRIT_TEMPLE)->IsVanilla() ? 2 : 1; - extra += ctx->GetDungeon(Rando::BOTTOM_OF_THE_WELL)->IsVanilla() ? 1 : 2; - extra += ctx->GetDungeon(Rando::ICE_CAVERN)->IsVanilla() ? 1 : 0; - extra += ctx->GetDungeon(Rando::GERUDO_TRAINING_GROUND)->IsVanilla() ? 1 : 0; - extra += ctx->GetDungeon(Rando::GANONS_CASTLE)->IsVanilla() ? 1 : 0; - for (int i = 0; i < extra; i++) { - AddItemToMainPool(GetJunkItem()); - } - } - - //Scrubsanity - if (ctx->GetOption(RSK_SHUFFLE_SCRUBS).Is(RO_SCRUBS_ALL)) { - //Deku Tree - if (ctx->GetDungeon(Rando::DEKU_TREE)->IsMQ()) { - AddItemToMainPool(RG_DEKU_SHIELD); - } - - //Dodongos Cavern - AddItemToMainPool(RG_DEKU_STICK_1); - AddItemToMainPool(RG_DEKU_SHIELD); - if (ctx->GetDungeon(Rando::DODONGOS_CAVERN)->IsMQ()) { - AddItemToMainPool(RG_RECOVERY_HEART); - } else { - AddItemToMainPool(RG_DEKU_NUTS_5); - } - - //Jabu Jabus Belly - if (ctx->GetDungeon(Rando::JABU_JABUS_BELLY)->IsVanilla()) { - AddItemToMainPool(RG_DEKU_NUTS_5); - } - - //Ganons Castle - AddItemToMainPool(RG_BOMBS_5); - AddItemToMainPool(RG_RECOVERY_HEART); - AddItemToMainPool(RG_BLUE_RUPEE); - if (ctx->GetDungeon(Rando::GANONS_CASTLE)->IsMQ()) { - AddItemToMainPool(RG_DEKU_NUTS_5); - } - - //Overworld Scrubs - AddItemsToPool(ItemPool, dekuScrubItems); - - //Scrubs which sell seeds or arrows sell it based on age, this randomly assigns them - for (uint8_t i = 0; i < 7; i++) { - if (Random(0, 3)) { - AddItemToMainPool(RG_ARROWS_30); - } else { - AddItemToMainPool(RG_DEKU_SEEDS_30); - } - } - } - - bool overworldFreeStandingActive = ctx->GetOption(RSK_SHUFFLE_FREESTANDING).Is(RO_SHUFFLE_FREESTANDING_OVERWORLD) || - ctx->GetOption(RSK_SHUFFLE_FREESTANDING).Is(RO_SHUFFLE_FREESTANDING_ALL); - bool dungeonFreeStandingActive = ctx->GetOption(RSK_SHUFFLE_FREESTANDING).Is(RO_SHUFFLE_FREESTANDING_DUNGEONS) || - ctx->GetOption(RSK_SHUFFLE_FREESTANDING).Is(RO_SHUFFLE_FREESTANDING_ALL); - PlaceItemsForType(RCTYPE_FREESTANDING, overworldFreeStandingActive, dungeonFreeStandingActive); - - AddItemsToPool(ItemPool, alwaysItems); - AddItemsToPool(ItemPool, dungeonRewards); - - //Dungeon pools - if (ctx->GetDungeon(Rando::DEKU_TREE)->IsMQ()) { - AddItemsToPool(ItemPool, DT_MQ); - } else { - AddItemsToPool(ItemPool, DT_Vanilla); - } - if (ctx->GetDungeon(Rando::DODONGOS_CAVERN)->IsMQ()) { - AddItemsToPool(ItemPool, DC_MQ); - } else { - AddItemsToPool(ItemPool, DC_Vanilla); - } - if (ctx->GetDungeon(Rando::JABU_JABUS_BELLY)->IsMQ()) { - AddItemsToPool(ItemPool, JB_MQ); - } - if (ctx->GetDungeon(Rando::FOREST_TEMPLE)->IsMQ()) { - AddItemsToPool(ItemPool, FoT_MQ); - } else { - AddItemsToPool(ItemPool, FoT_Vanilla); - } - if (ctx->GetDungeon(Rando::FIRE_TEMPLE)->IsMQ()) { - AddItemsToPool(ItemPool, FiT_MQ); - } else { - AddItemsToPool(ItemPool, FiT_Vanilla); - } - if (ctx->GetDungeon(Rando::SPIRIT_TEMPLE)->IsMQ()) { - AddItemsToPool(ItemPool, SpT_MQ); - } else { - AddItemsToPool(ItemPool, SpT_Vanilla); - } - if (ctx->GetDungeon(Rando::SHADOW_TEMPLE)->IsMQ()) { - AddItemsToPool(ItemPool, ShT_MQ); - } else { - AddItemsToPool(ItemPool, ShT_Vanilla); - } - if (ctx->GetDungeon(Rando::BOTTOM_OF_THE_WELL)->IsVanilla()) { - AddItemsToPool(ItemPool, BW_Vanilla); - } - if (ctx->GetDungeon(Rando::GERUDO_TRAINING_GROUND)->IsMQ()) { - AddItemsToPool(ItemPool, GTG_MQ); - } else { - AddItemsToPool(ItemPool, GTG_Vanilla); - } - if (ctx->GetDungeon(Rando::GANONS_CASTLE)->IsMQ()) { - AddItemsToPool(ItemPool, GC_MQ); - } else { - AddItemsToPool(ItemPool, GC_Vanilla); - } - - uint8_t rutoBottles = 1; - if (ctx->GetOption(RSK_ZORAS_FOUNTAIN).Is(RO_ZF_OPEN)) { - rutoBottles = 0; - } - - //Add 4 total bottles - uint8_t bottleCount = 4; - std::vector bottles; - bottles.assign(normalBottles.begin(), normalBottles.end()); - ctx->possibleIceTrapModels.push_back( - Rando::StaticData::RetrieveItem(RandomElement(bottles)).GetRandomizerGet()); // Get one random bottle type for ice traps - for (uint8_t i = 0; i < bottleCount; i++) { - if (i >= rutoBottles) { - if ((i == bottleCount - 1) && - (ctx->GetOption(RSK_SHUFFLE_MERCHANTS).Is(RO_SHUFFLE_MERCHANTS_ALL_BUT_BEANS) || - ctx->GetOption(RSK_SHUFFLE_MERCHANTS).Is(RO_SHUFFLE_MERCHANTS_ALL))) { - AddItemToMainPool(RG_BOTTLE_WITH_BLUE_POTION); - } else { - AddRandomBottle(bottles); - } - } else { - AddItemToMainPool(RG_RUTOS_LETTER); - } - } - - //add extra songs only if song shuffle is anywhere - AddItemsToPool(ItemPool, songList); - if (ctx->GetOption(RSK_SHUFFLE_SONGS).Is(RO_SONG_SHUFFLE_ANYWHERE) && ctx->GetOption(RSK_ITEM_POOL).Is(RO_ITEM_POOL_PLENTIFUL)) { - AddItemsToPool(PendingJunkPool, songList); - } - - /*For item pool generation, dungeon items are either placed in their vanilla - | location, or added to the pool now and filtered out later depending on when - | they need to get placed or removed in fill.cpp. These items are kept in the - | pool until removal because the filling algorithm needs to know all of the - | advancement items that haven't been placed yet for placing higher priority - | items like stones/medallions.*/ - - if (ctx->GetOption(RSK_SHUFFLE_MAPANDCOMPASS).Is(RO_DUNGEON_ITEM_LOC_VANILLA)) { - PlaceVanillaMapsAndCompasses(); - } else { - for (auto dungeon : ctx->GetDungeons()->GetDungeonList()) { - if (dungeon->GetMap() != RG_NONE) { - AddItemToMainPool(dungeon->GetMap()); - } - - if (dungeon->GetCompass() != RG_NONE) { - AddItemToMainPool(dungeon->GetCompass()); - } - } - } - - if (ctx->GetOption(RSK_KEYSANITY).Is(RO_DUNGEON_ITEM_LOC_VANILLA)) { - PlaceVanillaSmallKeys(); - } else { - for (auto dungeon : ctx->GetDungeons()->GetDungeonList()) { - if (dungeon->HasKeyRing() && ctx->GetOption(RSK_KEYSANITY).IsNot(RO_DUNGEON_ITEM_LOC_STARTWITH)) { - AddItemToMainPool(dungeon->GetKeyRing()); - } else if (dungeon->GetSmallKeyCount() > 0) { - AddItemToMainPool(dungeon->GetSmallKey(), dungeon->GetSmallKeyCount()); - } - } - } - - if (ctx->GetOption(RSK_BOSS_KEYSANITY).Is(RO_DUNGEON_ITEM_LOC_VANILLA)) { - PlaceVanillaBossKeys(); - } else { - AddItemToMainPool(RG_FOREST_TEMPLE_BOSS_KEY); - AddItemToMainPool(RG_FIRE_TEMPLE_BOSS_KEY); - AddItemToMainPool(RG_WATER_TEMPLE_BOSS_KEY); - AddItemToMainPool(RG_SPIRIT_TEMPLE_BOSS_KEY); - AddItemToMainPool(RG_SHADOW_TEMPLE_BOSS_KEY); - } - - if (!ctx->GetOption(RSK_TRIFORCE_HUNT)) { // Don't add GBK to the pool at all for Triforce Hunt. - if (ctx->GetOption(RSK_GANONS_BOSS_KEY).Is(RO_GANON_BOSS_KEY_KAK_TOKENS)) { - ctx->PlaceItemInLocation(RC_KAK_100_GOLD_SKULLTULA_REWARD, RG_GANONS_CASTLE_BOSS_KEY); - } else if (ctx->GetOption(RSK_GANONS_BOSS_KEY).Get() >= RO_GANON_BOSS_KEY_LACS_VANILLA) { - ctx->PlaceItemInLocation(RC_TOT_LIGHT_ARROWS_CUTSCENE, RG_GANONS_CASTLE_BOSS_KEY); - } else if (ctx->GetOption(RSK_GANONS_BOSS_KEY).Is(RO_GANON_BOSS_KEY_VANILLA)) { - ctx->PlaceItemInLocation(RC_GANONS_TOWER_BOSS_KEY_CHEST, RG_GANONS_CASTLE_BOSS_KEY); - } else { - AddItemToMainPool(RG_GANONS_CASTLE_BOSS_KEY); - } - } - - if (ctx->GetOption(RSK_ITEM_POOL).Is(RO_ITEM_POOL_PLENTIFUL)) { - AddItemsToPool(ItemPool, easyItems); - } else { - AddItemsToPool(ItemPool, normalItems); - } - - if (!ctx->GetOption(RSK_SHUFFLE_KOKIRI_SWORD)) { - ReplaceMaxItem(RG_KOKIRI_SWORD, 0); - } - - if (!ctx->GetOption(RSK_SHUFFLE_MASTER_SWORD)) { - ReplaceMaxItem(RG_MASTER_SWORD, 0); - } - - if (/*ProgressiveGoronSword TODO: Implement Setting*/false) { - ReplaceMaxItem(RG_BIGGORON_SWORD, 0); - AddItemToMainPool(RG_PROGRESSIVE_GORONSWORD, 2); - ctx->possibleIceTrapModels.push_back(RG_PROGRESSIVE_GORONSWORD); - } else { - ctx->possibleIceTrapModels.push_back(RG_BIGGORON_SWORD); - } - - //Replace ice traps with junk from the pending junk pool if necessary - if (ctx->GetOption(RSK_ICE_TRAPS).Is(RO_ICE_TRAPS_OFF)) { - ReplaceMaxItem(RG_ICE_TRAP, 0); - } - //Replace all junk items with ice traps for onslaught mode - else if (ctx->GetOption(RSK_ICE_TRAPS).Is(RO_ICE_TRAPS_ONSLAUGHT)) { - PendingJunkPool.clear(); - for (uint8_t i = 0; i < JunkPoolItems.size() - 3; i++) { // -3 Omits Huge Rupees and Deku Nuts 10 - ReplaceMaxItem(JunkPoolItems[i], 0); - } - } - - if (ctx->GetOption(RSK_ITEM_POOL).Is(RO_ITEM_POOL_SCARCE)) { - SetScarceItemPool(); - } else if (ctx->GetOption(RSK_ITEM_POOL).Is(RO_ITEM_POOL_MINIMAL)) { - SetMinimalItemPool(); - } else if (/*RemoveDoubleDefense TODO: Implement setting*/ false) { - ReplaceMaxItem(RG_DOUBLE_DEFENSE, 0); - } - - std::erase(ItemPool, RG_NONE); - - if (ItemPool.size() < ctx->allLocations.size()) { - Shuffle(PendingJunkPool); - size_t junkNeeded = std::min(PendingJunkPool.size(), ctx->allLocations.size() - ItemPool.size()); - ItemPool.insert(ItemPool.end(), PendingJunkPool.begin(), PendingJunkPool.begin() + junkNeeded); - PendingJunkPool.erase(PendingJunkPool.begin(), PendingJunkPool.begin() + junkNeeded); - } else if (ItemPool.size() > ctx->allLocations.size()) { - // RANDOTODO: all junk should be put in PendingJunkPool so this is never needed - size_t remove = ItemPool.size() - ctx->allLocations.size(); - for (size_t i = 0; remove > 0 && i < ItemPool.size(); i++) { - for (size_t j = 0; j < JunkPoolItems.size(); j++) { - if (ItemPool[i] == JunkPoolItems[j]) { - ItemPool[i] = RG_NONE; - remove--; - break; + if (ctx->GetOption(RSK_SHUFFLE_MERCHANTS).Is(RO_SHUFFLE_MERCHANTS_BEANS_ONLY) || + ctx->GetOption(RSK_SHUFFLE_MERCHANTS).Is(RO_SHUFFLE_MERCHANTS_ALL)) { + AddItemToMainPool(RG_MAGIC_BEAN_PACK); + if (ctx->GetOption(RSK_ITEM_POOL).Is(RO_ITEM_POOL_PLENTIFUL)) { + AddItemToPool(PendingJunkPool, RG_MAGIC_BEAN_PACK); } - } + ctx->possibleIceTrapModels.push_back(RG_MAGIC_BEAN_PACK); + } else { + ctx->PlaceItemInLocation(RC_ZR_MAGIC_BEAN_SALESMAN, RG_MAGIC_BEAN, false, true); } - std::erase(ItemPool, RG_NONE); - } - // RANDOTODO: Ideally this should be checking for equality, but that is not currently the case and has never been - // the case, and isn't even currently the case in the 3drando repo we inherited this from years ago, so it may - // be a large undertaking to fix. - assert(ItemPool.size() <= ctx->allLocations.size() || !"Item Pool larger than Location Pool"); + if (ctx->GetOption(RSK_SHUFFLE_MERCHANTS).Is(RO_SHUFFLE_MERCHANTS_ALL_BUT_BEANS) || + ctx->GetOption(RSK_SHUFFLE_MERCHANTS).Is(RO_SHUFFLE_MERCHANTS_ALL)) { + if (/*!ProgressiveGoronSword TODO: Implement Progressive Goron Sword*/ true) { + AddItemToMainPool(RG_GIANTS_KNIFE); + } + if (ctx->GetOption(RSK_BOMBCHU_BAG)) { + AddItemToMainPool(RG_PROGRESSIVE_BOMBCHUS); + } else { + AddItemToMainPool(RG_BOMBCHU_10); + } + } else { + ctx->PlaceItemInLocation(RC_KAK_GRANNYS_SHOP, RG_BLUE_POTION_REFILL, false, true); + ctx->PlaceItemInLocation(RC_GC_MEDIGORON, RG_GIANTS_KNIFE, false, true); + ctx->PlaceItemInLocation(RC_WASTELAND_BOMBCHU_SALESMAN, RG_BOMBCHU_10, false, true); + } + + if (ctx->GetOption(RSK_SHUFFLE_FROG_SONG_RUPEES)) { + AddItemToMainPool(RG_PURPLE_RUPEE, 5); + } else { + ctx->PlaceItemInLocation(RC_ZR_FROGS_ZELDAS_LULLABY, RG_PURPLE_RUPEE, false, true); + ctx->PlaceItemInLocation(RC_ZR_FROGS_EPONAS_SONG, RG_PURPLE_RUPEE, false, true); + ctx->PlaceItemInLocation(RC_ZR_FROGS_SARIAS_SONG, RG_PURPLE_RUPEE, false, true); + ctx->PlaceItemInLocation(RC_ZR_FROGS_SUNS_SONG, RG_PURPLE_RUPEE, false, true); + ctx->PlaceItemInLocation(RC_ZR_FROGS_SONG_OF_TIME, RG_PURPLE_RUPEE, false, true); + } + + if (ctx->GetOption(RSK_SHUFFLE_ADULT_TRADE)) { + AddItemToMainPool(RG_POCKET_EGG); + AddItemToMainPool(RG_COJIRO); + AddItemToMainPool(RG_ODD_MUSHROOM); + AddItemToMainPool(RG_ODD_POTION); + AddItemToMainPool(RG_POACHERS_SAW); + AddItemToMainPool(RG_BROKEN_SWORD); + AddItemToMainPool(RG_PRESCRIPTION); + AddItemToMainPool(RG_EYEBALL_FROG); + AddItemToMainPool(RG_EYEDROPS); + } + AddItemToMainPool(RG_CLAIM_CHECK); + + if (ctx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME).Is(RO_CHEST_GAME_SINGLE_KEYS)) { + AddItemToMainPool(RG_TREASURE_GAME_SMALL_KEY, 6); // 6 individual keys + } else if (ctx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME).Is(RO_CHEST_GAME_PACK)) { + AddItemToMainPool(RG_TREASURE_GAME_SMALL_KEY); // 1 key which will behave as a pack of 6 + } + + if (ctx->GetOption(RSK_SHUFFLE_TOKENS).Is(RO_TOKENSANITY_OFF)) { + for (RandomizerCheck loc : ctx->GetLocations(ctx->allLocations, RCTYPE_SKULL_TOKEN)) { + ctx->PlaceItemInLocation(loc, RG_GOLD_SKULLTULA_TOKEN, false, true); + } + } else if (ctx->GetOption(RSK_SHUFFLE_TOKENS).Is(RO_TOKENSANITY_DUNGEONS)) { + for (RandomizerCheck loc : ctx->GetLocations(ctx->allLocations, RCTYPE_SKULL_TOKEN)) { + if (Rando::StaticData::GetLocation(loc)->IsOverworld()) { + ctx->PlaceItemInLocation((RandomizerCheck)loc, RG_GOLD_SKULLTULA_TOKEN, false, true); + } else { + AddItemToMainPool(RG_GOLD_SKULLTULA_TOKEN); + } + } + } else if (ctx->GetOption(RSK_SHUFFLE_TOKENS).Is(RO_TOKENSANITY_OVERWORLD)) { + for (RandomizerCheck loc : ctx->GetLocations(ctx->allLocations, RCTYPE_SKULL_TOKEN)) { + if (Rando::StaticData::GetLocation(loc)->IsDungeon()) { + ctx->PlaceItemInLocation((RandomizerCheck)loc, RG_GOLD_SKULLTULA_TOKEN, false, true); + } else { + AddItemToMainPool(RG_GOLD_SKULLTULA_TOKEN); + } + } + } else { + AddItemToMainPool(RG_GOLD_SKULLTULA_TOKEN, 100); + } + + if (ctx->GetOption(RSK_SHUFFLE_100_GS_REWARD)) { + if (ctx->GetOption(RSK_SHUFFLE_TOKENS).IsNot(RO_TOKENSANITY_OFF) && + ctx->GetOption(RSK_ITEM_POOL).Is(RO_ITEM_POOL_PLENTIFUL)) { + AddItemToPool(PendingJunkPool, RG_GOLD_SKULLTULA_TOKEN, 10); + } + AddItemToMainPool(RG_HUGE_RUPEE); + } else { + ctx->PlaceItemInLocation(RC_KAK_100_GOLD_SKULLTULA_REWARD, RG_HUGE_RUPEE, false, true); + } + + if (ctx->GetOption(RSK_SHUFFLE_BOSS_SOULS)) { + AddItemToMainPool(RG_GOHMA_SOUL); + AddItemToMainPool(RG_KING_DODONGO_SOUL); + AddItemToMainPool(RG_BARINADE_SOUL); + AddItemToMainPool(RG_PHANTOM_GANON_SOUL); + AddItemToMainPool(RG_VOLVAGIA_SOUL); + AddItemToMainPool(RG_MORPHA_SOUL); + AddItemToMainPool(RG_BONGO_BONGO_SOUL); + AddItemToMainPool(RG_TWINROVA_SOUL); + + ctx->possibleIceTrapModels.push_back(RG_GOHMA_SOUL); + ctx->possibleIceTrapModels.push_back(RG_KING_DODONGO_SOUL); + ctx->possibleIceTrapModels.push_back(RG_BARINADE_SOUL); + ctx->possibleIceTrapModels.push_back(RG_PHANTOM_GANON_SOUL); + ctx->possibleIceTrapModels.push_back(RG_VOLVAGIA_SOUL); + ctx->possibleIceTrapModels.push_back(RG_MORPHA_SOUL); + ctx->possibleIceTrapModels.push_back(RG_BONGO_BONGO_SOUL); + ctx->possibleIceTrapModels.push_back(RG_TWINROVA_SOUL); + if (ctx->GetOption(RSK_SHUFFLE_BOSS_SOULS).Is(RO_BOSS_SOULS_ON_PLUS_GANON)) { + AddItemToMainPool(RG_GANON_SOUL); + ctx->possibleIceTrapModels.push_back(RG_GANON_SOUL); + } + } + + if (ctx->GetOption(RSK_SHUFFLE_CHILD_WALLET)) { + AddItemToMainPool(RG_PROGRESSIVE_WALLET); + } + + if (ctx->GetOption(RSK_INCLUDE_TYCOON_WALLET)) { + AddItemToMainPool(RG_PROGRESSIVE_WALLET); + } + + if (ctx->GetOption(RSK_SHUFFLE_DEKU_STICK_BAG)) { + AddItemToMainPool(RG_PROGRESSIVE_STICK_UPGRADE); + } + + if (ctx->GetOption(RSK_SHUFFLE_DEKU_NUT_BAG)) { + AddItemToMainPool(RG_PROGRESSIVE_NUT_UPGRADE); + } + + if (ctx->GetOption(RSK_BOMBCHU_BAG)) { + AddItemToMainPool(RG_PROGRESSIVE_BOMBCHUS, 5); + } else { + AddItemToMainPool(RG_BOMBCHU_5); + AddItemToMainPool(RG_BOMBCHU_10, 3); + AddItemToMainPool(RG_BOMBCHU_20); + } + + // Ice Traps + AddItemToMainPool(RG_ICE_TRAP); + if (ctx->GetDungeon(Rando::GERUDO_TRAINING_GROUND)->IsVanilla()) { + AddItemToMainPool(RG_ICE_TRAP); + } + if (ctx->GetDungeon(Rando::GANONS_CASTLE)->IsVanilla()) { + AddItemToMainPool(RG_ICE_TRAP, 4); + } + + // Gerudo Fortress + if (ctx->GetOption(RSK_GERUDO_FORTRESS).Is(RO_GF_CARPENTERS_FREE)) { + ctx->PlaceItemInLocation(RC_GF_NORTH_F1_CARPENTER, RG_RECOVERY_HEART, false, true); + ctx->PlaceItemInLocation(RC_GF_NORTH_F2_CARPENTER, RG_RECOVERY_HEART, false, true); + ctx->PlaceItemInLocation(RC_GF_SOUTH_F1_CARPENTER, RG_RECOVERY_HEART, false, true); + ctx->PlaceItemInLocation(RC_GF_SOUTH_F2_CARPENTER, RG_RECOVERY_HEART, false, true); + } else if (ctx->GetOption(RSK_GERUDO_KEYS).IsNot(RO_GERUDO_KEYS_VANILLA)) { + if (ctx->GetOption(RSK_GERUDO_FORTRESS).Is(RO_GF_CARPENTERS_FAST)) { + AddItemToMainPool(RG_GERUDO_FORTRESS_SMALL_KEY); + ctx->PlaceItemInLocation(RC_GF_NORTH_F2_CARPENTER, RG_RECOVERY_HEART, false, true); + ctx->PlaceItemInLocation(RC_GF_SOUTH_F1_CARPENTER, RG_RECOVERY_HEART, false, true); + ctx->PlaceItemInLocation(RC_GF_SOUTH_F2_CARPENTER, RG_RECOVERY_HEART, false, true); + } else { + // Only add key ring if 4 Fortress keys necessary + if (ctx->GetOption(RSK_KEYRINGS_GERUDO_FORTRESS) && ctx->GetOption(RSK_KEYRINGS)) { + AddItemToMainPool(RG_GERUDO_FORTRESS_KEY_RING); + // Add junk to make up for missing keys + for (uint8_t i = 0; i < 3; i++) { + AddItemToMainPool(GetJunkItem()); + } + } else { + AddItemToMainPool(RG_GERUDO_FORTRESS_SMALL_KEY, 4); + } + } + if (ctx->GetOption(RSK_ITEM_POOL).Is(RO_ITEM_POOL_PLENTIFUL)) { + if (ctx->GetOption(RSK_KEYRINGS_GERUDO_FORTRESS) && + ctx->GetOption(RSK_GERUDO_FORTRESS).Is(RO_GF_CARPENTERS_NORMAL) && ctx->GetOption(RSK_KEYRINGS)) { + AddItemToPool(PendingJunkPool, RG_GERUDO_FORTRESS_KEY_RING); + } else { + AddItemToPool(PendingJunkPool, RG_GERUDO_FORTRESS_SMALL_KEY); + } + } + } else { + if (ctx->GetOption(RSK_GERUDO_FORTRESS).Is(RO_GF_CARPENTERS_FAST)) { + ctx->PlaceItemInLocation(RC_GF_NORTH_F1_CARPENTER, RG_GERUDO_FORTRESS_SMALL_KEY, false, true); + ctx->PlaceItemInLocation(RC_GF_NORTH_F2_CARPENTER, RG_RECOVERY_HEART, false, true); + ctx->PlaceItemInLocation(RC_GF_SOUTH_F1_CARPENTER, RG_RECOVERY_HEART, false, true); + ctx->PlaceItemInLocation(RC_GF_SOUTH_F2_CARPENTER, RG_RECOVERY_HEART, false, true); + } else { + ctx->PlaceItemInLocation(RC_GF_NORTH_F1_CARPENTER, RG_GERUDO_FORTRESS_SMALL_KEY, false, true); + ctx->PlaceItemInLocation(RC_GF_NORTH_F2_CARPENTER, RG_GERUDO_FORTRESS_SMALL_KEY, false, true); + ctx->PlaceItemInLocation(RC_GF_SOUTH_F1_CARPENTER, RG_GERUDO_FORTRESS_SMALL_KEY, false, true); + ctx->PlaceItemInLocation(RC_GF_SOUTH_F2_CARPENTER, RG_GERUDO_FORTRESS_SMALL_KEY, false, true); + } + } + + // Gerudo Membership Card + if (ctx->GetOption(RSK_SHUFFLE_GERUDO_MEMBERSHIP_CARD) && + ctx->GetOption(RSK_GERUDO_FORTRESS).IsNot(RO_GF_CARPENTERS_FREE)) { + AddItemToMainPool(RG_GERUDO_MEMBERSHIP_CARD); + ctx->possibleIceTrapModels.push_back(RG_GERUDO_MEMBERSHIP_CARD); + } else if (ctx->GetOption(RSK_SHUFFLE_GERUDO_MEMBERSHIP_CARD)) { + AddItemToPool(PendingJunkPool, RG_GERUDO_MEMBERSHIP_CARD); + ctx->PlaceItemInLocation(RC_GF_GERUDO_MEMBERSHIP_CARD, RG_ICE_TRAP, false, true); + } else { + ctx->PlaceItemInLocation(RC_GF_GERUDO_MEMBERSHIP_CARD, RG_GERUDO_MEMBERSHIP_CARD, false, true); + } + + // Keys + + // For key rings, need to add as many junk items as "missing" keys + if (ctx->GetOption(RSK_KEYRINGS).IsNot(RO_KEYRINGS_OFF)) { + uint8_t ringJunkAmt = 0; + for (auto dungeon : ctx->GetDungeons()->GetDungeonList()) { + if (dungeon->HasKeyRing()) { + ringJunkAmt += dungeon->GetSmallKeyCount() - 1; + } + } + for (uint8_t i = 0; i < ringJunkAmt; i++) { + AddItemToMainPool(GetJunkItem()); + } + } + + if (ctx->GetOption(RSK_ITEM_POOL).Is(RO_ITEM_POOL_PLENTIFUL)) { + if (ctx->GetOption(RSK_SHUFFLE_GERUDO_MEMBERSHIP_CARD)) { + AddItemToPool(PendingJunkPool, RG_GERUDO_MEMBERSHIP_CARD); + } + + if (ctx->GetOption(RSK_SHUFFLE_FISHING_POLE)) { + AddItemToPool(PendingJunkPool, RG_FISHING_POLE); + } + + // Plentiful small keys + if (ctx->GetOption(RSK_KEYSANITY).Is(RO_DUNGEON_ITEM_LOC_ANYWHERE) || + ctx->GetOption(RSK_KEYSANITY).Is(RO_DUNGEON_ITEM_LOC_ANY_DUNGEON) || + ctx->GetOption(RSK_KEYSANITY).Is(RO_DUNGEON_ITEM_LOC_OVERWORLD)) { + if (ctx->GetDungeon(Rando::BOTTOM_OF_THE_WELL)->HasKeyRing()) { + AddItemToPool(PendingJunkPool, RG_BOTTOM_OF_THE_WELL_KEY_RING); + } else { + AddItemToPool(PendingJunkPool, RG_BOTTOM_OF_THE_WELL_SMALL_KEY); + } + if (ctx->GetDungeon(Rando::FOREST_TEMPLE)->HasKeyRing()) { + AddItemToPool(PendingJunkPool, RG_FOREST_TEMPLE_KEY_RING); + } else { + AddItemToPool(PendingJunkPool, RG_FOREST_TEMPLE_SMALL_KEY); + } + if (ctx->GetDungeon(Rando::FIRE_TEMPLE)->HasKeyRing()) { + AddItemToPool(PendingJunkPool, RG_FIRE_TEMPLE_KEY_RING); + } else { + AddItemToPool(PendingJunkPool, RG_FIRE_TEMPLE_SMALL_KEY); + } + if (ctx->GetDungeon(Rando::WATER_TEMPLE)->HasKeyRing()) { + AddItemToPool(PendingJunkPool, RG_WATER_TEMPLE_KEY_RING); + } else { + AddItemToPool(PendingJunkPool, RG_WATER_TEMPLE_SMALL_KEY); + } + if (ctx->GetDungeon(Rando::SPIRIT_TEMPLE)->HasKeyRing()) { + AddItemToPool(PendingJunkPool, RG_SPIRIT_TEMPLE_KEY_RING); + } else { + AddItemToPool(PendingJunkPool, RG_SPIRIT_TEMPLE_SMALL_KEY); + } + if (ctx->GetDungeon(Rando::SHADOW_TEMPLE)->HasKeyRing()) { + AddItemToPool(PendingJunkPool, RG_SHADOW_TEMPLE_KEY_RING); + } else { + AddItemToPool(PendingJunkPool, RG_SHADOW_TEMPLE_SMALL_KEY); + } + if (ctx->GetDungeon(Rando::GERUDO_TRAINING_GROUND)->HasKeyRing()) { + AddItemToPool(PendingJunkPool, RG_GERUDO_TRAINING_GROUND_KEY_RING); + } else { + AddItemToPool(PendingJunkPool, RG_GERUDO_TRAINING_GROUND_SMALL_KEY); + } + if (ctx->GetDungeon(Rando::GANONS_CASTLE)->HasKeyRing()) { + AddItemToPool(PendingJunkPool, RG_GANONS_CASTLE_KEY_RING); + } else { + AddItemToPool(PendingJunkPool, RG_GANONS_CASTLE_SMALL_KEY); + } + } + + if (ctx->GetOption(RSK_BOSS_KEYSANITY).Is(RO_DUNGEON_ITEM_LOC_ANYWHERE) || + ctx->GetOption(RSK_BOSS_KEYSANITY).Is(RO_DUNGEON_ITEM_LOC_ANY_DUNGEON) || + ctx->GetOption(RSK_BOSS_KEYSANITY).Is(RO_DUNGEON_ITEM_LOC_OVERWORLD)) { + AddItemToPool(PendingJunkPool, RG_FOREST_TEMPLE_BOSS_KEY); + AddItemToPool(PendingJunkPool, RG_FIRE_TEMPLE_BOSS_KEY); + AddItemToPool(PendingJunkPool, RG_WATER_TEMPLE_BOSS_KEY); + AddItemToPool(PendingJunkPool, RG_SPIRIT_TEMPLE_BOSS_KEY); + AddItemToPool(PendingJunkPool, RG_SHADOW_TEMPLE_BOSS_KEY); + } + + if (ctx->GetOption(RSK_GANONS_BOSS_KEY).Is(RO_GANON_BOSS_KEY_ANYWHERE) || + ctx->GetOption(RSK_GANONS_BOSS_KEY).Is(RO_GANON_BOSS_KEY_ANY_DUNGEON) || + ctx->GetOption(RSK_GANONS_BOSS_KEY).Is(RO_GANON_BOSS_KEY_OVERWORLD)) { + AddItemToPool(PendingJunkPool, RG_GANONS_CASTLE_BOSS_KEY); + } + } + + if (ctx->GetOption(RSK_LOCK_OVERWORLD_DOORS)) { + AddItemToPool(ItemPool, RG_GUARD_HOUSE_KEY); + AddItemToPool(ItemPool, RG_MARKET_BAZAAR_KEY); + AddItemToPool(ItemPool, RG_MARKET_POTION_SHOP_KEY); + AddItemToPool(ItemPool, RG_MASK_SHOP_KEY); + AddItemToPool(ItemPool, RG_MARKET_SHOOTING_GALLERY_KEY); + AddItemToPool(ItemPool, RG_BOMBCHU_BOWLING_KEY); + AddItemToPool(ItemPool, RG_TREASURE_CHEST_GAME_BUILDING_KEY); + AddItemToPool(ItemPool, RG_BOMBCHU_SHOP_KEY); + AddItemToPool(ItemPool, RG_RICHARDS_HOUSE_KEY); + AddItemToPool(ItemPool, RG_ALLEY_HOUSE_KEY); + AddItemToPool(ItemPool, RG_KAK_BAZAAR_KEY); + AddItemToPool(ItemPool, RG_KAK_POTION_SHOP_KEY); + AddItemToPool(ItemPool, RG_BOSS_HOUSE_KEY); + AddItemToPool(ItemPool, RG_GRANNYS_POTION_SHOP_KEY); + AddItemToPool(ItemPool, RG_SKULLTULA_HOUSE_KEY); + AddItemToPool(ItemPool, RG_IMPAS_HOUSE_KEY); + AddItemToPool(ItemPool, RG_WINDMILL_KEY); + AddItemToPool(ItemPool, RG_KAK_SHOOTING_GALLERY_KEY); + AddItemToPool(ItemPool, RG_DAMPES_HUT_KEY); + AddItemToPool(ItemPool, RG_TALONS_HOUSE_KEY); + AddItemToPool(ItemPool, RG_STABLES_KEY); + AddItemToPool(ItemPool, RG_BACK_TOWER_KEY); + AddItemToPool(ItemPool, RG_HYLIA_LAB_KEY); + AddItemToPool(ItemPool, RG_FISHING_HOLE_KEY); + } + + // Shopsanity + if (ctx->GetOption(RSK_SHOPSANITY).Is(RO_SHOPSANITY_OFF) || + (ctx->GetOption(RSK_SHOPSANITY).Is(RO_SHOPSANITY_SPECIFIC_COUNT) && + ctx->GetOption(RSK_SHOPSANITY_COUNT).Is(RO_SHOPSANITY_COUNT_ZERO_ITEMS))) { + AddItemsToPool(ItemPool, normalRupees); + } else { + AddItemsToPool(ItemPool, shopsanityRupees); // Shopsanity gets extra large rupees + } + + // Shuffle Fairies + if (ctx->GetOption(RSK_SHUFFLE_FAIRIES)) { + for (auto rc : Rando::StaticData::GetOverworldFairyLocations()) { + AddItemToMainPool(GetJunkItem()); + } + // 8 extra for Ganon's Castle + 2 Dodongo's Cavern Gossip Stone + 3 Shadow Temple + int extra = 13; + extra += ctx->GetDungeon(Rando::FIRE_TEMPLE)->IsVanilla() ? 0 : 2; + extra += ctx->GetDungeon(Rando::WATER_TEMPLE)->IsVanilla() ? 0 : 3; + extra += ctx->GetDungeon(Rando::SPIRIT_TEMPLE)->IsVanilla() ? 2 : 1; + extra += ctx->GetDungeon(Rando::BOTTOM_OF_THE_WELL)->IsVanilla() ? 1 : 2; + extra += ctx->GetDungeon(Rando::ICE_CAVERN)->IsVanilla() ? 1 : 0; + extra += ctx->GetDungeon(Rando::GERUDO_TRAINING_GROUND)->IsVanilla() ? 1 : 0; + extra += ctx->GetDungeon(Rando::GANONS_CASTLE)->IsVanilla() ? 1 : 0; + for (int i = 0; i < extra; i++) { + AddItemToMainPool(GetJunkItem()); + } + } + + // Scrubsanity + if (ctx->GetOption(RSK_SHUFFLE_SCRUBS).Is(RO_SCRUBS_ALL)) { + // Deku Tree + if (ctx->GetDungeon(Rando::DEKU_TREE)->IsMQ()) { + AddItemToMainPool(RG_DEKU_SHIELD); + } + + // Dodongos Cavern + AddItemToMainPool(RG_DEKU_STICK_1); + AddItemToMainPool(RG_DEKU_SHIELD); + if (ctx->GetDungeon(Rando::DODONGOS_CAVERN)->IsMQ()) { + AddItemToMainPool(RG_RECOVERY_HEART); + } else { + AddItemToMainPool(RG_DEKU_NUTS_5); + } + + // Jabu Jabus Belly + if (ctx->GetDungeon(Rando::JABU_JABUS_BELLY)->IsVanilla()) { + AddItemToMainPool(RG_DEKU_NUTS_5); + } + + // Ganons Castle + AddItemToMainPool(RG_BOMBS_5); + AddItemToMainPool(RG_RECOVERY_HEART); + AddItemToMainPool(RG_BLUE_RUPEE); + if (ctx->GetDungeon(Rando::GANONS_CASTLE)->IsMQ()) { + AddItemToMainPool(RG_DEKU_NUTS_5); + } + + // Overworld Scrubs + AddItemsToPool(ItemPool, dekuScrubItems); + + // Scrubs which sell seeds or arrows sell it based on age, this randomly assigns them + for (uint8_t i = 0; i < 7; i++) { + if (Random(0, 3)) { + AddItemToMainPool(RG_ARROWS_30); + } else { + AddItemToMainPool(RG_DEKU_SEEDS_30); + } + } + } + + bool overworldFreeStandingActive = ctx->GetOption(RSK_SHUFFLE_FREESTANDING).Is(RO_SHUFFLE_FREESTANDING_OVERWORLD) || + ctx->GetOption(RSK_SHUFFLE_FREESTANDING).Is(RO_SHUFFLE_FREESTANDING_ALL); + bool dungeonFreeStandingActive = ctx->GetOption(RSK_SHUFFLE_FREESTANDING).Is(RO_SHUFFLE_FREESTANDING_DUNGEONS) || + ctx->GetOption(RSK_SHUFFLE_FREESTANDING).Is(RO_SHUFFLE_FREESTANDING_ALL); + PlaceItemsForType(RCTYPE_FREESTANDING, overworldFreeStandingActive, dungeonFreeStandingActive); + + AddItemsToPool(ItemPool, alwaysItems); + AddItemsToPool(ItemPool, dungeonRewards); + + // Dungeon pools + if (ctx->GetDungeon(Rando::DEKU_TREE)->IsMQ()) { + AddItemsToPool(ItemPool, DT_MQ); + } else { + AddItemsToPool(ItemPool, DT_Vanilla); + } + if (ctx->GetDungeon(Rando::DODONGOS_CAVERN)->IsMQ()) { + AddItemsToPool(ItemPool, DC_MQ); + } else { + AddItemsToPool(ItemPool, DC_Vanilla); + } + if (ctx->GetDungeon(Rando::JABU_JABUS_BELLY)->IsMQ()) { + AddItemsToPool(ItemPool, JB_MQ); + } + if (ctx->GetDungeon(Rando::FOREST_TEMPLE)->IsMQ()) { + AddItemsToPool(ItemPool, FoT_MQ); + } else { + AddItemsToPool(ItemPool, FoT_Vanilla); + } + if (ctx->GetDungeon(Rando::FIRE_TEMPLE)->IsMQ()) { + AddItemsToPool(ItemPool, FiT_MQ); + } else { + AddItemsToPool(ItemPool, FiT_Vanilla); + } + if (ctx->GetDungeon(Rando::SPIRIT_TEMPLE)->IsMQ()) { + AddItemsToPool(ItemPool, SpT_MQ); + } else { + AddItemsToPool(ItemPool, SpT_Vanilla); + } + if (ctx->GetDungeon(Rando::SHADOW_TEMPLE)->IsMQ()) { + AddItemsToPool(ItemPool, ShT_MQ); + } else { + AddItemsToPool(ItemPool, ShT_Vanilla); + } + if (ctx->GetDungeon(Rando::BOTTOM_OF_THE_WELL)->IsVanilla()) { + AddItemsToPool(ItemPool, BW_Vanilla); + } + if (ctx->GetDungeon(Rando::GERUDO_TRAINING_GROUND)->IsMQ()) { + AddItemsToPool(ItemPool, GTG_MQ); + } else { + AddItemsToPool(ItemPool, GTG_Vanilla); + } + if (ctx->GetDungeon(Rando::GANONS_CASTLE)->IsMQ()) { + AddItemsToPool(ItemPool, GC_MQ); + } else { + AddItemsToPool(ItemPool, GC_Vanilla); + } + + uint8_t rutoBottles = 1; + if (ctx->GetOption(RSK_ZORAS_FOUNTAIN).Is(RO_ZF_OPEN)) { + rutoBottles = 0; + } + + // Add 4 total bottles + uint8_t bottleCount = 4; + std::vector bottles; + bottles.assign(normalBottles.begin(), normalBottles.end()); + ctx->possibleIceTrapModels.push_back(Rando::StaticData::RetrieveItem(RandomElement(bottles)) + .GetRandomizerGet()); // Get one random bottle type for ice traps + for (uint8_t i = 0; i < bottleCount; i++) { + if (i >= rutoBottles) { + if ((i == bottleCount - 1) && + (ctx->GetOption(RSK_SHUFFLE_MERCHANTS).Is(RO_SHUFFLE_MERCHANTS_ALL_BUT_BEANS) || + ctx->GetOption(RSK_SHUFFLE_MERCHANTS).Is(RO_SHUFFLE_MERCHANTS_ALL))) { + AddItemToMainPool(RG_BOTTLE_WITH_BLUE_POTION); + } else { + AddRandomBottle(bottles); + } + } else { + AddItemToMainPool(RG_RUTOS_LETTER); + } + } + + // add extra songs only if song shuffle is anywhere + AddItemsToPool(ItemPool, songList); + if (ctx->GetOption(RSK_SHUFFLE_SONGS).Is(RO_SONG_SHUFFLE_ANYWHERE) && + ctx->GetOption(RSK_ITEM_POOL).Is(RO_ITEM_POOL_PLENTIFUL)) { + AddItemsToPool(PendingJunkPool, songList); + } + + /*For item pool generation, dungeon items are either placed in their vanilla + | location, or added to the pool now and filtered out later depending on when + | they need to get placed or removed in fill.cpp. These items are kept in the + | pool until removal because the filling algorithm needs to know all of the + | advancement items that haven't been placed yet for placing higher priority + | items like stones/medallions.*/ + + if (ctx->GetOption(RSK_SHUFFLE_MAPANDCOMPASS).Is(RO_DUNGEON_ITEM_LOC_VANILLA)) { + PlaceVanillaMapsAndCompasses(); + } else { + for (auto dungeon : ctx->GetDungeons()->GetDungeonList()) { + if (dungeon->GetMap() != RG_NONE) { + AddItemToMainPool(dungeon->GetMap()); + } + + if (dungeon->GetCompass() != RG_NONE) { + AddItemToMainPool(dungeon->GetCompass()); + } + } + } + + if (ctx->GetOption(RSK_KEYSANITY).Is(RO_DUNGEON_ITEM_LOC_VANILLA)) { + PlaceVanillaSmallKeys(); + } else { + for (auto dungeon : ctx->GetDungeons()->GetDungeonList()) { + if (dungeon->HasKeyRing() && ctx->GetOption(RSK_KEYSANITY).IsNot(RO_DUNGEON_ITEM_LOC_STARTWITH)) { + AddItemToMainPool(dungeon->GetKeyRing()); + } else if (dungeon->GetSmallKeyCount() > 0) { + AddItemToMainPool(dungeon->GetSmallKey(), dungeon->GetSmallKeyCount()); + } + } + } + + if (ctx->GetOption(RSK_BOSS_KEYSANITY).Is(RO_DUNGEON_ITEM_LOC_VANILLA)) { + PlaceVanillaBossKeys(); + } else { + AddItemToMainPool(RG_FOREST_TEMPLE_BOSS_KEY); + AddItemToMainPool(RG_FIRE_TEMPLE_BOSS_KEY); + AddItemToMainPool(RG_WATER_TEMPLE_BOSS_KEY); + AddItemToMainPool(RG_SPIRIT_TEMPLE_BOSS_KEY); + AddItemToMainPool(RG_SHADOW_TEMPLE_BOSS_KEY); + } + + if (!ctx->GetOption(RSK_TRIFORCE_HUNT)) { // Don't add GBK to the pool at all for Triforce Hunt. + if (ctx->GetOption(RSK_GANONS_BOSS_KEY).Is(RO_GANON_BOSS_KEY_KAK_TOKENS)) { + ctx->PlaceItemInLocation(RC_KAK_100_GOLD_SKULLTULA_REWARD, RG_GANONS_CASTLE_BOSS_KEY); + } else if (ctx->GetOption(RSK_GANONS_BOSS_KEY).Get() >= RO_GANON_BOSS_KEY_LACS_VANILLA) { + ctx->PlaceItemInLocation(RC_TOT_LIGHT_ARROWS_CUTSCENE, RG_GANONS_CASTLE_BOSS_KEY); + } else if (ctx->GetOption(RSK_GANONS_BOSS_KEY).Is(RO_GANON_BOSS_KEY_VANILLA)) { + ctx->PlaceItemInLocation(RC_GANONS_TOWER_BOSS_KEY_CHEST, RG_GANONS_CASTLE_BOSS_KEY); + } else { + AddItemToMainPool(RG_GANONS_CASTLE_BOSS_KEY); + } + } + + if (ctx->GetOption(RSK_ITEM_POOL).Is(RO_ITEM_POOL_PLENTIFUL)) { + AddItemsToPool(ItemPool, easyItems); + } else { + AddItemsToPool(ItemPool, normalItems); + } + + if (!ctx->GetOption(RSK_SHUFFLE_KOKIRI_SWORD)) { + ReplaceMaxItem(RG_KOKIRI_SWORD, 0); + } + + if (!ctx->GetOption(RSK_SHUFFLE_MASTER_SWORD)) { + ReplaceMaxItem(RG_MASTER_SWORD, 0); + } + + if (/*ProgressiveGoronSword TODO: Implement Setting*/ false) { + ReplaceMaxItem(RG_BIGGORON_SWORD, 0); + AddItemToMainPool(RG_PROGRESSIVE_GORONSWORD, 2); + ctx->possibleIceTrapModels.push_back(RG_PROGRESSIVE_GORONSWORD); + } else { + ctx->possibleIceTrapModels.push_back(RG_BIGGORON_SWORD); + } + + // Replace ice traps with junk from the pending junk pool if necessary + if (ctx->GetOption(RSK_ICE_TRAPS).Is(RO_ICE_TRAPS_OFF)) { + ReplaceMaxItem(RG_ICE_TRAP, 0); + } + // Replace all junk items with ice traps for onslaught mode + else if (ctx->GetOption(RSK_ICE_TRAPS).Is(RO_ICE_TRAPS_ONSLAUGHT)) { + PendingJunkPool.clear(); + for (uint8_t i = 0; i < JunkPoolItems.size() - 3; i++) { // -3 Omits Huge Rupees and Deku Nuts 10 + ReplaceMaxItem(JunkPoolItems[i], 0); + } + } + + if (ctx->GetOption(RSK_ITEM_POOL).Is(RO_ITEM_POOL_SCARCE)) { + SetScarceItemPool(); + } else if (ctx->GetOption(RSK_ITEM_POOL).Is(RO_ITEM_POOL_MINIMAL)) { + SetMinimalItemPool(); + } else if (/*RemoveDoubleDefense TODO: Implement setting*/ false) { + ReplaceMaxItem(RG_DOUBLE_DEFENSE, 0); + } + + std::erase(ItemPool, RG_NONE); + + if (ItemPool.size() < ctx->allLocations.size()) { + Shuffle(PendingJunkPool); + size_t junkNeeded = std::min(PendingJunkPool.size(), ctx->allLocations.size() - ItemPool.size()); + ItemPool.insert(ItemPool.end(), PendingJunkPool.begin(), PendingJunkPool.begin() + junkNeeded); + PendingJunkPool.erase(PendingJunkPool.begin(), PendingJunkPool.begin() + junkNeeded); + } else if (ItemPool.size() > ctx->allLocations.size()) { + // RANDOTODO: all junk should be put in PendingJunkPool so this is never needed + size_t remove = ItemPool.size() - ctx->allLocations.size(); + for (size_t i = 0; remove > 0 && i < ItemPool.size(); i++) { + for (size_t j = 0; j < JunkPoolItems.size(); j++) { + if (ItemPool[i] == JunkPoolItems[j]) { + ItemPool[i] = RG_NONE; + remove--; + break; + } + } + } + std::erase(ItemPool, RG_NONE); + } + + // RANDOTODO: Ideally this should be checking for equality, but that is not currently the case and has never been + // the case, and isn't even currently the case in the 3drando repo we inherited this from years ago, so it may + // be a large undertaking to fix. + assert(ItemPool.size() <= ctx->allLocations.size() || !"Item Pool larger than Location Pool"); } diff --git a/soh/soh/Enhancements/randomizer/3drando/menu.cpp b/soh/soh/Enhancements/randomizer/3drando/menu.cpp index 6bcf21af9..831330571 100644 --- a/soh/soh/Enhancements/randomizer/3drando/menu.cpp +++ b/soh/soh/Enhancements/randomizer/3drando/menu.cpp @@ -22,7 +22,7 @@ Rando::Option* currentSetting; } // namespace bool GenerateRandomizer(std::set excludedLocations, std::set enabledTricks, - std::string seedInput) { + std::string seedInput) { const auto ctx = Rando::Context::GetInstance(); ResetPerformanceTimers(); StartPerformanceTimer(PT_WHOLE_SEED); @@ -35,9 +35,7 @@ bool GenerateRandomizer(std::set excludedLocations, std::set excludedLocations, std::set enabledTricks) { +int Playthrough_Init(uint32_t seed, std::set excludedLocations, + std::set enabledTricks) { // initialize the RNG with just the seed incase any settings need to be // resolved to something random Random_Init(seed); @@ -65,7 +66,6 @@ int Playthrough_Init(uint32_t seed, std::set excludedLocations, Random_Init(finalHash); ctx->SetHash(std::to_string(finalHash)); - if (ctx->GetOption(RSK_LOGIC_RULES).Is(RO_LOGIC_VANILLA)) { VanillaFill(); // Just place items in their vanilla locations } else { // Fill locations with logic @@ -78,8 +78,9 @@ int Playthrough_Init(uint32_t seed, std::set excludedLocations, GenerateHash(); if (true) { - //TODO: Handle different types of file output (i.e. Spoiler Log, Plando Template, Patch Files, Race Files, etc.) - // write logs + // TODO: Handle different types of file output (i.e. Spoiler Log, Plando Template, Patch Files, Race Files, + // etc.) + // write logs SPDLOG_INFO("Writing Spoiler Log..."); StartPerformanceTimer(PT_SPOILER_LOG); if (SpoilerLog_Write()) { @@ -97,7 +98,8 @@ int Playthrough_Init(uint32_t seed, std::set excludedLocations, } // used for generating a lot of seeds at once -int Playthrough_Repeat(std::set excludedLocations, std::set enabledTricks, int count /*= 1*/) { +int Playthrough_Repeat(std::set excludedLocations, std::set enabledTricks, + int count /*= 1*/) { SPDLOG_INFO("GENERATING {} SEEDS", count); auto ctx = Rando::Context::GetInstance(); uint32_t repeatedSeed = 0; diff --git a/soh/soh/Enhancements/randomizer/3drando/rando_main.cpp b/soh/soh/Enhancements/randomizer/3drando/rando_main.cpp index d26e89adb..51cfdd535 100644 --- a/soh/soh/Enhancements/randomizer/3drando/rando_main.cpp +++ b/soh/soh/Enhancements/randomizer/3drando/rando_main.cpp @@ -11,7 +11,7 @@ #include "soh/cvar_prefixes.h" void RandoMain::GenerateRando(std::set excludedLocations, std::set enabledTricks, - std::string seedString) { + std::string seedString) { Rando::Context::GetInstance()->SetSeedGenerated(GenerateRandomizer(excludedLocations, enabledTricks, seedString)); diff --git a/soh/soh/Enhancements/randomizer/3drando/random.cpp b/soh/soh/Enhancements/randomizer/3drando/random.cpp index 92cf22b85..f2599da94 100644 --- a/soh/soh/Enhancements/randomizer/3drando/random.cpp +++ b/soh/soh/Enhancements/randomizer/3drando/random.cpp @@ -8,16 +8,16 @@ static bool init = false; static boost::random::mt19937 generator; -//Initialize with seed specified +// Initialize with seed specified void Random_Init(uint32_t seed) { init = true; - generator = boost::random::mt19937{seed}; + generator = boost::random::mt19937{ seed }; } -//Returns a random integer in range [min, max-1] +// Returns a random integer in range [min, max-1] uint32_t Random(int min, int max) { if (!init) { - //No seed given, get a random number from device to seed + // No seed given, get a random number from device to seed #if !defined(__SWITCH__) && !defined(__WIIU__) const auto seed = static_cast(std::random_device{}()); #else @@ -25,11 +25,11 @@ uint32_t Random(int min, int max) { #endif Random_Init(seed); } - boost::random::uniform_int_distribution distribution(min, max-1); + boost::random::uniform_int_distribution distribution(min, max - 1); return distribution(generator); } -//Returns a random floating point number in [0.0, 1.0] +// Returns a random floating point number in [0.0, 1.0] double RandomDouble() { boost::random::uniform_real_distribution distribution(0.0, 1.0); return distribution(generator); diff --git a/soh/soh/Enhancements/randomizer/3drando/shops.cpp b/soh/soh/Enhancements/randomizer/3drando/shops.cpp index 636f9ecd7..8224865ac 100644 --- a/soh/soh/Enhancements/randomizer/3drando/shops.cpp +++ b/soh/soh/Enhancements/randomizer/3drando/shops.cpp @@ -10,143 +10,90 @@ #include #include "z64item.h" -PriceSettingsStruct::PriceSettingsStruct(RandomizerSettingKey _main, - RandomizerSettingKey _fixedPrice, - RandomizerSettingKey _range1, - RandomizerSettingKey _range2, - RandomizerSettingKey _noWallet, - RandomizerSettingKey _childWallet, - RandomizerSettingKey _adultWallet, - RandomizerSettingKey _giantWallet, - RandomizerSettingKey _tycoonWallet, - RandomizerSettingKey _affordable){ - main = _main; - fixedPrice = _fixedPrice; - range1 = _range1; - range2 = _range2; - noWallet = _noWallet; - childWallet = _childWallet; - adultWallet = _adultWallet; - giantWallet= _giantWallet; - tycoonWallet= _tycoonWallet; - affordable= _affordable; +PriceSettingsStruct::PriceSettingsStruct(RandomizerSettingKey _main, RandomizerSettingKey _fixedPrice, + RandomizerSettingKey _range1, RandomizerSettingKey _range2, + RandomizerSettingKey _noWallet, RandomizerSettingKey _childWallet, + RandomizerSettingKey _adultWallet, RandomizerSettingKey _giantWallet, + RandomizerSettingKey _tycoonWallet, RandomizerSettingKey _affordable) { + main = _main; + fixedPrice = _fixedPrice; + range1 = _range1; + range2 = _range2; + noWallet = _noWallet; + childWallet = _childWallet; + adultWallet = _adultWallet; + giantWallet = _giantWallet; + tycoonWallet = _tycoonWallet; + affordable = _affordable; } - static std::array, 0xF1> trickNameTable; // Table of trick names for ice traps -bool initTrickNames = false; //Indicates if trick ice trap names have been initialized yet +bool initTrickNames = false; // Indicates if trick ice trap names have been initialized yet -//Set vanilla shop item locations before potentially shuffling +// Set vanilla shop item locations before potentially shuffling void PlaceVanillaShopItems() { auto ctx = Rando::Context::GetInstance(); - //Loop to place vanilla items in each location + // Loop to place vanilla items in each location for (RandomizerCheck& randomizerCheck : Rando::StaticData::GetShopLocations()) { ctx->GetItemLocation(randomizerCheck)->PlaceVanillaItem(); } } -//These are the vanilla shop items, but in a priority order of importance -//However many shop item slots were cleared, this will return 64 minus that number of vanilla shop items to be placed with assumed fill -//The first 32 items here will always be present in shops -//Shopsanity 4 will only have the first 32, shopsanity 1 will have the first 56, etc. -//Shopsanity random will have anywhere from the first 32 to the first 56, so the order of items after 32 is relevant +// These are the vanilla shop items, but in a priority order of importance +// However many shop item slots were cleared, this will return 64 minus that number of vanilla shop items to be placed +// with assumed fill The first 32 items here will always be present in shops Shopsanity 4 will only have the first 32, +// shopsanity 1 will have the first 56, etc. Shopsanity random will have anywhere from the first 32 to the first 56, so +// the order of items after 32 is relevant std::vector GetMinVanillaShopItems(int total_replaced) { std::vector minShopItems = { - RG_BUY_DEKU_SHIELD, - RG_BUY_HYLIAN_SHIELD, - RG_BUY_GORON_TUNIC, - RG_BUY_ZORA_TUNIC, - RG_BUY_DEKU_NUTS_5, - RG_BUY_BOMBS_20, - RG_BUY_BOMBCHUS_10, - RG_BUY_DEKU_STICK_1, + RG_BUY_DEKU_SHIELD, RG_BUY_HYLIAN_SHIELD, RG_BUY_GORON_TUNIC, RG_BUY_ZORA_TUNIC, RG_BUY_DEKU_NUTS_5, + RG_BUY_BOMBS_20, RG_BUY_BOMBCHUS_10, RG_BUY_DEKU_STICK_1, //^First 8 items: Exist on shopsanity 7 or less - RG_BUY_FAIRYS_SPIRIT, - RG_BUY_DEKU_SEEDS_30, - RG_BUY_ARROWS_10, - RG_BUY_BLUE_FIRE, - RG_BUY_RED_POTION_30, - RG_BUY_GREEN_POTION, - RG_BUY_DEKU_NUTS_10, - RG_BUY_BOMBCHUS_10, + RG_BUY_FAIRYS_SPIRIT, RG_BUY_DEKU_SEEDS_30, RG_BUY_ARROWS_10, RG_BUY_BLUE_FIRE, RG_BUY_RED_POTION_30, + RG_BUY_GREEN_POTION, RG_BUY_DEKU_NUTS_10, RG_BUY_BOMBCHUS_10, //^First 16 items: Exist on shopsanity 6 or less - RG_BUY_BOMBCHUS_10, - RG_BUY_BOMBCHUS_20, - RG_BUY_BOMBS_525, - RG_BUY_BOMBS_535, - RG_BUY_BOMBS_10, - RG_BUY_DEKU_NUTS_5, - RG_BUY_ARROWS_30, - RG_BUY_ARROWS_50, + RG_BUY_BOMBCHUS_10, RG_BUY_BOMBCHUS_20, RG_BUY_BOMBS_525, RG_BUY_BOMBS_535, RG_BUY_BOMBS_10, RG_BUY_DEKU_NUTS_5, + RG_BUY_ARROWS_30, RG_BUY_ARROWS_50, //^First 24 items: Exist on shopsanity 5 or less - RG_BUY_ARROWS_10, - RG_BUY_FAIRYS_SPIRIT, - RG_BUY_BOTTLE_BUG, - RG_BUY_FISH, + RG_BUY_ARROWS_10, RG_BUY_FAIRYS_SPIRIT, RG_BUY_BOTTLE_BUG, RG_BUY_FISH, //^First 28 items from OoTR - RG_BUY_HYLIAN_SHIELD, - RG_BUY_BOTTLE_BUG, - RG_BUY_DEKU_STICK_1, - RG_BUY_DEKU_STICK_1, + RG_BUY_HYLIAN_SHIELD, RG_BUY_BOTTLE_BUG, RG_BUY_DEKU_STICK_1, RG_BUY_DEKU_STICK_1, //^First 32 items: Exist on shopsanity 4 or less - RG_BUY_BLUE_FIRE, - RG_BUY_FISH, - RG_BUY_BOMBCHUS_10, - RG_BUY_DEKU_NUTS_5, - RG_BUY_ARROWS_10, - RG_BUY_BOMBCHUS_20, - RG_BUY_BOMBS_535, - RG_BUY_RED_POTION_30, + RG_BUY_BLUE_FIRE, RG_BUY_FISH, RG_BUY_BOMBCHUS_10, RG_BUY_DEKU_NUTS_5, RG_BUY_ARROWS_10, RG_BUY_BOMBCHUS_20, + RG_BUY_BOMBS_535, RG_BUY_RED_POTION_30, //^First 40 items: Exist on shopsanity 3 or less - RG_BUY_BOMBS_30, - RG_BUY_BOMBCHUS_20, - RG_BUY_DEKU_NUTS_5, - RG_BUY_ARROWS_10, - RG_BUY_DEKU_NUTS_5, - RG_BUY_ARROWS_30, - RG_BUY_RED_POTION_40, - RG_BUY_FISH, + RG_BUY_BOMBS_30, RG_BUY_BOMBCHUS_20, RG_BUY_DEKU_NUTS_5, RG_BUY_ARROWS_10, RG_BUY_DEKU_NUTS_5, RG_BUY_ARROWS_30, + RG_BUY_RED_POTION_40, RG_BUY_FISH, //^First 48 items: Exist on shopsanity 2 or less - RG_BUY_BOMBCHUS_20, - RG_BUY_ARROWS_30, - RG_BUY_RED_POTION_50, - RG_BUY_ARROWS_30, - RG_BUY_DEKU_NUTS_5, - RG_BUY_ARROWS_50, - RG_BUY_ARROWS_50, - RG_BUY_GREEN_POTION, + RG_BUY_BOMBCHUS_20, RG_BUY_ARROWS_30, RG_BUY_RED_POTION_50, RG_BUY_ARROWS_30, RG_BUY_DEKU_NUTS_5, + RG_BUY_ARROWS_50, RG_BUY_ARROWS_50, RG_BUY_GREEN_POTION, //^First 56 items: Exist on shopsanity 1 or less - RG_BUY_POE, - RG_BUY_POE, - RG_BUY_HEART, - RG_BUY_HEART, - RG_BUY_HEART, - RG_BUY_HEART, - RG_BUY_HEART, - RG_BUY_HEART, + RG_BUY_POE, RG_BUY_POE, RG_BUY_HEART, RG_BUY_HEART, RG_BUY_HEART, RG_BUY_HEART, RG_BUY_HEART, RG_BUY_HEART, //^All 64 items: Only exist with shopsanity 0 }; - //Now delete however many items there are to replace + // Now delete however many items there are to replace for (int i = 0; i < total_replaced; i++) { minShopItems.pop_back(); } return minShopItems; } -//This table contains a cumulative probability for each possible shop price based on -// a beta distribution with alpha = 1.5, beta = 2, and the result of the distribution, a float in [0.0, 1.0), -// being mutliplied by 60, casted to an integer, then multiplied by 5 to give a value in range [0, 295] in increments of 5. -// Meaning the first value is the probability of 0, the next value is the probability of 0 plus the probability of 5, etc. -//Probabilities generated using a python script with 1 billion trials, so should hopefully be pretty good -//Average price ~126 +// This table contains a cumulative probability for each possible shop price based on +// a beta distribution with alpha = 1.5, beta = 2, and the result of the distribution, a float in [0.0, 1.0), +// being mutliplied by 60, casted to an integer, then multiplied by 5 to give a value in range [0, 295] in increments +// of 5. Meaning the first value is the probability of 0, the next value is the probability of 0 plus the probability +// of 5, etc. +// Probabilities generated using a python script with 1 billion trials, so should hopefully be pretty good +// Average price ~126 //~38% chance of needing no wallet, ~45% chance of needing 1, ~17% chance of needing 2 -static constexpr std::array ShopPriceProbability= { - 0.005326994, 0.014908518, 0.027114719, 0.041315285, 0.057136304, 0.074325887, 0.092667151, 0.112002061, 0.132198214, 0.153125390, - 0.174696150, 0.196810540, 0.219388148, 0.242361379, 0.265657012, 0.289205134, 0.312970402, 0.336877590, 0.360881110, 0.384932772, - 0.408976198, 0.432982176, 0.456902494, 0.480686053, 0.504313389, 0.527746488, 0.550938554, 0.573856910, 0.596465330, 0.618736235, - 0.640646600, 0.662162782, 0.683240432, 0.703859801, 0.724001242, 0.743631336, 0.762722631, 0.781259986, 0.799198449, 0.816521905, - 0.833208595, 0.849243398, 0.864579161, 0.879211177, 0.893112051, 0.906263928, 0.918639420, 0.930222611, 0.940985829, 0.950914731, - 0.959992180, 0.968187000, 0.975495390, 0.981884488, 0.987344345, 0.991851853, 0.995389113, 0.997937921, 0.999481947, 1.000000000, +static constexpr std::array ShopPriceProbability = { + 0.005326994, 0.014908518, 0.027114719, 0.041315285, 0.057136304, 0.074325887, 0.092667151, 0.112002061, 0.132198214, + 0.153125390, 0.174696150, 0.196810540, 0.219388148, 0.242361379, 0.265657012, 0.289205134, 0.312970402, 0.336877590, + 0.360881110, 0.384932772, 0.408976198, 0.432982176, 0.456902494, 0.480686053, 0.504313389, 0.527746488, 0.550938554, + 0.573856910, 0.596465330, 0.618736235, 0.640646600, 0.662162782, 0.683240432, 0.703859801, 0.724001242, 0.743631336, + 0.762722631, 0.781259986, 0.799198449, 0.816521905, 0.833208595, 0.849243398, 0.864579161, 0.879211177, 0.893112051, + 0.906263928, 0.918639420, 0.930222611, 0.940985829, 0.950914731, 0.959992180, 0.968187000, 0.975495390, 0.981884488, + 0.987344345, 0.991851853, 0.995389113, 0.997937921, 0.999481947, 1.000000000, }; // Generate random number from 5 to wallet max @@ -155,92 +102,94 @@ int GetPriceFromMax(int max) { return Random(1, max) * 5; } -uint16_t GetPriceFromSettings(Rando::Location *loc, PriceSettingsStruct priceSettings) { - auto ctx = Rando::Context::GetInstance(); - switch (ctx->GetOption(priceSettings.main).Get()){ - case RO_PRICE_VANILLA: - return loc->GetVanillaPrice(); - case RO_PRICE_CHEAP_BALANCED: - return GetCheapBalancedPrice(); - case RO_PRICE_BALANCED:{ - double random = RandomDouble(); //Randomly generated probability value - for (size_t i = 0; i < ShopPriceProbability.size(); i++) { - if (random < ShopPriceProbability[i]) { - // The randomly generated value has surpassed the total probability up to this point, so this is the generated price - // i in range [0, 59], output in range [0, 295] in increments of 5 - return i * 5; +uint16_t GetPriceFromSettings(Rando::Location* loc, PriceSettingsStruct priceSettings) { + auto ctx = Rando::Context::GetInstance(); + switch (ctx->GetOption(priceSettings.main).Get()) { + case RO_PRICE_VANILLA: + return loc->GetVanillaPrice(); + case RO_PRICE_CHEAP_BALANCED: + return GetCheapBalancedPrice(); + case RO_PRICE_BALANCED: { + double random = RandomDouble(); // Randomly generated probability value + for (size_t i = 0; i < ShopPriceProbability.size(); i++) { + if (random < ShopPriceProbability[i]) { + // The randomly generated value has surpassed the total probability up to this point, so this is the + // generated price i in range [0, 59], output in range [0, 295] in increments of 5 + return i * 5; + } } - } - return 150; - } - case RO_PRICE_FIXED: - return (uint16_t)ctx->GetOption(priceSettings.fixedPrice).Get() * 5; - case RO_PRICE_RANGE:{ - uint16_t range1 = (uint16_t)ctx->GetOption(priceSettings.range1).Get() * 5; - uint16_t range2 = (uint16_t)ctx->GetOption(priceSettings.range2).Get() * 5; - return range1 < range2 ? Random(range1, range2+1) : Random(range2, range1+1); - } - case RO_PRICE_SET_BY_WALLET:{ - bool isTycoon = ctx->GetOption(RSK_INCLUDE_TYCOON_WALLET).Get(); - uint16_t noWeight = ctx->GetOption(priceSettings.noWallet).Get(); - uint16_t childWeight = ctx->GetOption(priceSettings.childWallet).Get(); - uint16_t adultWeight = ctx->GetOption(priceSettings.adultWallet).Get(); - uint16_t giantWeight = ctx->GetOption(priceSettings.giantWallet).Get(); - uint16_t tycoonWeight = isTycoon ? ctx->GetOption(priceSettings.tycoonWallet).Get() : 0; - uint16_t totalWeight = noWeight + childWeight + adultWeight + giantWeight + tycoonWeight; - if (totalWeight == 0){ //if no weight, return from sane range - return Random(0, 501); - } - int16_t selected = Random(1, totalWeight + 1); - selected = selected - noWeight; - if (selected <= 0){ - return 0; - } - selected = selected - childWeight; - if (selected <= 0){ - return Random(1, 100); - } - selected = selected - adultWeight; - if (selected <= 0){ - return Random(100, 201); - } - selected = selected - giantWeight; - if (selected <= 0){ - return Random(201, 501); - } - return Random(501, 999); - } - } - SPDLOG_ERROR("GetPriceFromSettings has failed to return a price for location {}, assigning a default value.", loc->GetName()); - assert(false); - return 69; //this should never happen, if it does, EASTER EGG that tells us something is wrong + return 150; + } + case RO_PRICE_FIXED: + return (uint16_t)ctx->GetOption(priceSettings.fixedPrice).Get() * 5; + case RO_PRICE_RANGE: { + uint16_t range1 = (uint16_t)ctx->GetOption(priceSettings.range1).Get() * 5; + uint16_t range2 = (uint16_t)ctx->GetOption(priceSettings.range2).Get() * 5; + return range1 < range2 ? Random(range1, range2 + 1) : Random(range2, range1 + 1); + } + case RO_PRICE_SET_BY_WALLET: { + bool isTycoon = ctx->GetOption(RSK_INCLUDE_TYCOON_WALLET).Get(); + uint16_t noWeight = ctx->GetOption(priceSettings.noWallet).Get(); + uint16_t childWeight = ctx->GetOption(priceSettings.childWallet).Get(); + uint16_t adultWeight = ctx->GetOption(priceSettings.adultWallet).Get(); + uint16_t giantWeight = ctx->GetOption(priceSettings.giantWallet).Get(); + uint16_t tycoonWeight = isTycoon ? ctx->GetOption(priceSettings.tycoonWallet).Get() : 0; + uint16_t totalWeight = noWeight + childWeight + adultWeight + giantWeight + tycoonWeight; + if (totalWeight == 0) { // if no weight, return from sane range + return Random(0, 501); + } + int16_t selected = Random(1, totalWeight + 1); + selected = selected - noWeight; + if (selected <= 0) { + return 0; + } + selected = selected - childWeight; + if (selected <= 0) { + return Random(1, 100); + } + selected = selected - adultWeight; + if (selected <= 0) { + return Random(100, 201); + } + selected = selected - giantWeight; + if (selected <= 0) { + return Random(201, 501); + } + return Random(501, 999); + } + } + SPDLOG_ERROR("GetPriceFromSettings has failed to return a price for location {}, assigning a default value.", + loc->GetName()); + assert(false); + return 69; // this should never happen, if it does, EASTER EGG that tells us something is wrong } -uint16_t GetRandomPrice(Rando::Location *loc, PriceSettingsStruct priceSettings) { - uint16_t initialPrice = GetPriceFromSettings(loc, priceSettings); - auto ctx = Rando::Context::GetInstance(); - if (ctx->GetOption(priceSettings.affordable) && !ctx->GetOption(priceSettings.main).Is(RO_PRICE_FIXED)){ - if (initialPrice > 500) { - return 505; - } else if (initialPrice > 200) { - return 205; - } else if (initialPrice > 99) { - return 100; - } else if (initialPrice > 0) { - return 5; - } - return 0; - } else { - return initialPrice; - } +uint16_t GetRandomPrice(Rando::Location* loc, PriceSettingsStruct priceSettings) { + uint16_t initialPrice = GetPriceFromSettings(loc, priceSettings); + auto ctx = Rando::Context::GetInstance(); + if (ctx->GetOption(priceSettings.affordable) && !ctx->GetOption(priceSettings.main).Is(RO_PRICE_FIXED)) { + if (initialPrice > 500) { + return 505; + } else if (initialPrice > 200) { + return 205; + } else if (initialPrice > 99) { + return 100; + } else if (initialPrice > 0) { + return 5; + } + return 0; + } else { + return initialPrice; + } } -//Similar to above, beta distribution with alpha = 1, beta = 2, -// multiplied by 20 instead of 60 to give values in rage [0, 95] in increments of 5 -//Average price ~31 +// Similar to above, beta distribution with alpha = 1, beta = 2, +// multiplied by 20 instead of 60 to give values in rage [0, 95] in increments of 5 +// Average price ~31 static constexpr std::array CheapPriceProbability = { - 0.097500187, 0.190002748, 0.277509301, 0.360018376, 0.437522571, 0.510021715, 0.577520272, 0.640029304, 0.697527584, 0.750024535, - 0.797518749, 0.840011707, 0.877508776, 0.910010904, 0.937504342, 0.960004661, 0.977502132, 0.989998967, 0.997500116, 1.000000000, + 0.097500187, 0.190002748, 0.277509301, 0.360018376, 0.437522571, 0.510021715, 0.577520272, + 0.640029304, 0.697527584, 0.750024535, 0.797518749, 0.840011707, 0.877508776, 0.910010904, + 0.937504342, 0.960004661, 0.977502132, 0.989998967, 0.997500116, 1.000000000, }; uint16_t GetCheapBalancedPrice() { @@ -253,7 +202,7 @@ uint16_t GetCheapBalancedPrice() { return -1; } -//Get 0 to 7, or a random number from 1-7 depending on shopsanity setting +// Get 0 to 7, or a random number from 1-7 depending on shopsanity setting int GetShopsanityReplaceAmount() { auto ctx = Rando::Context::GetInstance(); if (ctx->GetOption(RSK_SHOPSANITY).Is(RO_SHOPSANITY_OFF)) { @@ -276,670 +225,668 @@ int GetShopsanityReplaceAmount() { } else if (ctx->GetOption(RSK_SHOPSANITY_COUNT).Is(RO_SHOPSANITY_COUNT_SEVEN_ITEMS)) { return 7; } else if (ctx->GetOption(RSK_SHOPSANITY_COUNT).Is(RO_SHOPSANITY_COUNT_EIGHT_ITEMS)) { - return 8; //temporarily unreachable due to logic limitations + return 8; // temporarily unreachable due to logic limitations } else { assert(false); return 0; } - } else { //Random, get number in [1, 7] + } else { // Random, get number in [1, 7] return Random(1, 8); } } -//Initialize the table of trick names with an easy, medium, and hard name for each language +// Initialize the table of trick names with an easy, medium, and hard name for each language void InitTrickNames() { trickNameTable[RG_KOKIRI_SWORD] = { - Text{"Korok Sword", "Épée Korok", "Espada Korok"}, - Text{"Hero's Sword", "Épée du Héros", "Espada del héroe"}, - Text{"Razor Sword", "Lame Rasoir", "Espada de esmeril"}, + Text{ "Korok Sword", "Épée Korok", "Espada Korok" }, + Text{ "Hero's Sword", "Épée du Héros", "Espada del héroe" }, + Text{ "Razor Sword", "Lame Rasoir", "Espada de esmeril" }, }; trickNameTable[RG_MASTER_SWORD] = { - Text{"Goddess Sword", "Épée de la déesse", "Espada Divina"}, - Text{"Gilded Sword", "Excalibur", "Espada de los Sabios"}, - Text{"Magical Sword", "Lame dorée", "Fay"}, + Text{ "Goddess Sword", "Épée de la déesse", "Espada Divina" }, + Text{ "Gilded Sword", "Excalibur", "Espada de los Sabios" }, + Text{ "Magical Sword", "Lame dorée", "Fay" }, }; trickNameTable[RG_GIANTS_KNIFE] = { - Text{"Medigoron's Sword", "l'Épée de Medigoron", "La espada de Medigoron"}, - Text{"Razor Sword", "Lame Rasoir", "Espada de esmeril"}, - Text{"Royal Claymore", "Claymore Royale", "Royal Claymore"}, + Text{ "Medigoron's Sword", "l'Épée de Medigoron", "La espada de Medigoron" }, + Text{ "Razor Sword", "Lame Rasoir", "Espada de esmeril" }, + Text{ "Royal Claymore", "Claymore Royale", "Royal Claymore" }, }; trickNameTable[RG_BIGGORON_SWORD] = { - Text{"Power Sword", "Épée de Puissance", "Espada de poder"}, - Text{"Fierce Deity Sword", "Épée du dieu démon", "Espada de la Fiera Deidad"}, - Text{"Tempered Sword", "Épée de Légende Nv.2", "Espada Maestra mejorada"}, - Text{"Biggoron's Knife", "Lame de Grogoron", "Daga de Biggoron"}, + Text{ "Power Sword", "Épée de Puissance", "Espada de poder" }, + Text{ "Fierce Deity Sword", "Épée du dieu démon", "Espada de la Fiera Deidad" }, + Text{ "Tempered Sword", "Épée de Légende Nv.2", "Espada Maestra mejorada" }, + Text{ "Biggoron's Knife", "Lame de Grogoron", "Daga de Biggoron" }, }; trickNameTable[RG_DEKU_SHIELD] = { - Text{"Boko Shield", "Bouclier Boko", "Escudo Boko"}, - Text{"Ordon Shield", "Bouclier de Toal", "Escudo de Ordon"}, - Text{"Wooden Shield", "Bouclier de Bois", "Escudo de madera"}, + Text{ "Boko Shield", "Bouclier Boko", "Escudo Boko" }, + Text{ "Ordon Shield", "Bouclier de Toal", "Escudo de Ordon" }, + Text{ "Wooden Shield", "Bouclier de Bois", "Escudo de madera" }, }; trickNameTable[RG_HYLIAN_SHIELD] = { - Text{"Hyrule Shield", "Bouclier d'Hyrule", "Escudo Hylian"}, - Text{"Goddess Shield", "Bouclier Sacré", "Escudo Divino"}, - Text{"Hero's Shield", "Bouclier du Héros", "Escudo del héroe"}, + Text{ "Hyrule Shield", "Bouclier d'Hyrule", "Escudo Hylian" }, + Text{ "Goddess Shield", "Bouclier Sacré", "Escudo Divino" }, + Text{ "Hero's Shield", "Bouclier du Héros", "Escudo del héroe" }, }; trickNameTable[RG_MIRROR_SHIELD] = { - Text{"Magic Mirror", "Miroir Magique", "Escudo mágico"}, - Text{"Magical Shield", "Bouclier Magique", "Escudo arcano"}, - Text{"Mirror of Twilight", "Miroir des Ombres", "Espejo del Crepúsculo"}, + Text{ "Magic Mirror", "Miroir Magique", "Escudo mágico" }, + Text{ "Magical Shield", "Bouclier Magique", "Escudo arcano" }, + Text{ "Mirror of Twilight", "Miroir des Ombres", "Espejo del Crepúsculo" }, }; trickNameTable[RG_GORON_TUNIC] = { - Text{"Gerudo Top", "Tunique Gerudo", "Pechera gerudo"}, - Text{"Flamebreaker Armor", "Armure de Pierre", " Armadura ignífuga"}, - Text{"Red Mail", "Habits Rouges", "Ropas rojas"}, + Text{ "Gerudo Top", "Tunique Gerudo", "Pechera gerudo" }, + Text{ "Flamebreaker Armor", "Armure de Pierre", " Armadura ignífuga" }, + Text{ "Red Mail", "Habits Rouges", "Ropas rojas" }, }; trickNameTable[RG_ZORA_TUNIC] = { - Text{"Rito Tunic", "Tunique Rito", "Sayo rito"}, - Text{"Mermaid Suit", "Costume de sirène", "Costume de sirène"}, - Text{"Zora Armor", "Armure Zora", "Túnica Zora"}, - Text{"Blue Mail", "Habits Bleus", "Ropas azules"}, + Text{ "Rito Tunic", "Tunique Rito", "Sayo rito" }, + Text{ "Mermaid Suit", "Costume de sirène", "Costume de sirène" }, + Text{ "Zora Armor", "Armure Zora", "Túnica Zora" }, + Text{ "Blue Mail", "Habits Bleus", "Ropas azules" }, }; trickNameTable[RG_IRON_BOOTS] = { - Text{"Iron Hoofs", "Patins de Plomb", "Botas férreas"}, - Text{"Snow Boots", "Bottes de Neige", "Botas de nieve"}, - Text{"Red Boots", "Bottes rouges", "Botas rojas"}, - Text{"Zora Greaves", "Bottes Zora", "Zora Greaves"}, - Text{"Boots of Power", "Bottes de Puissance", "Botas de plomo"}, + Text{ "Iron Hoofs", "Patins de Plomb", "Botas férreas" }, + Text{ "Snow Boots", "Bottes de Neige", "Botas de nieve" }, + Text{ "Red Boots", "Bottes rouges", "Botas rojas" }, + Text{ "Zora Greaves", "Bottes Zora", "Zora Greaves" }, + Text{ "Boots of Power", "Bottes de Puissance", "Botas de plomo" }, }; trickNameTable[RG_HOVER_BOOTS] = { - Text{"Hover Hoofs", "Patins des airs", "Botas flotadoras"}, - Text{"Golden Boots", "Bottes dorées", "Botas de Oro"}, - Text{"Pegasus Boots", "Bottes pégase", "Botas de Pegaso"}, - Text{"Boots of Speed", "Bottes de vitesse", "Botas del desierto"}, + Text{ "Hover Hoofs", "Patins des airs", "Botas flotadoras" }, + Text{ "Golden Boots", "Bottes dorées", "Botas de Oro" }, + Text{ "Pegasus Boots", "Bottes pégase", "Botas de Pegaso" }, + Text{ "Boots of Speed", "Bottes de vitesse", "Botas del desierto" }, }; trickNameTable[RG_WEIRD_EGG] = { - Text{"Poached Egg", "Oeuf à la coque", "Huevo pasado"}, - Text{"Lon Lon Egg", "Oeuf Lon Lon", "Huevo Lon Lon"}, - Text{"Zora Egg", "Oeuf Zora", "Huevo Zora"}, + Text{ "Poached Egg", "Oeuf à la coque", "Huevo pasado" }, + Text{ "Lon Lon Egg", "Oeuf Lon Lon", "Huevo Lon Lon" }, + Text{ "Zora Egg", "Oeuf Zora", "Huevo Zora" }, }; trickNameTable[RG_ZELDAS_LETTER] = { - Text{"Ruto's Letter", "Lettre de Ruto", "Carta de Ruto"}, - Text{"Royal Letter", "Lettre Eoyale", "Carta para Kafei"}, - Text{"Zelda's Business Card", "Carte d'affaires de Zelda", "Carta"}, - Text{"Letter to Kafei", "Lettre pour Kafei", "Carta para Kafei "}, - Text{"Goat's Letter", "Lettre de la Chèvre", "Carta de la Cabra"}, - Text{"Maggie's Letter", "Lettre de Maggy", "Carta de Dolores"}, + Text{ "Ruto's Letter", "Lettre de Ruto", "Carta de Ruto" }, + Text{ "Royal Letter", "Lettre Eoyale", "Carta para Kafei" }, + Text{ "Zelda's Business Card", "Carte d'affaires de Zelda", "Carta" }, + Text{ "Letter to Kafei", "Lettre pour Kafei", "Carta para Kafei " }, + Text{ "Goat's Letter", "Lettre de la Chèvre", "Carta de la Cabra" }, + Text{ "Maggie's Letter", "Lettre de Maggy", "Carta de Dolores" }, }; trickNameTable[RG_BOOMERANG] = { - Text{"Banana", "Banane", "Plátano"}, - Text{"Prank Fetch Toy", "Inséparable Bâtonnet", "Bumerang"}, - Text{"Gale Boomerang", "Boomerang Tornade", "Bumerán tornado"}, - Text{"Magic Boomerang", "Boomerang Magique", "Bumerán mágico"}, + Text{ "Banana", "Banane", "Plátano" }, + Text{ "Prank Fetch Toy", "Inséparable Bâtonnet", "Bumerang" }, + Text{ "Gale Boomerang", "Boomerang Tornade", "Bumerán tornado" }, + Text{ "Magic Boomerang", "Boomerang Magique", "Bumerán mágico" }, }; trickNameTable[RG_LENS_OF_TRUTH] = { - Text{"Sheikah-leidoscope", "Sheikah-léidoscope", "Monóculo de la Verdad"}, - Text{"Sheikah Sensor", "Sonar Sheikah", "Sensor Sheikah"}, - Text{"Crystal of Vision", "Cristal de Vision", "Cristal de Visión"}, - Text{"Magnifying Lens", "Loupe", "Lente Aumentadora"}, + Text{ "Sheikah-leidoscope", "Sheikah-léidoscope", "Monóculo de la Verdad" }, + Text{ "Sheikah Sensor", "Sonar Sheikah", "Sensor Sheikah" }, + Text{ "Crystal of Vision", "Cristal de Vision", "Cristal de Visión" }, + Text{ "Magnifying Lens", "Loupe", "Lente Aumentadora" }, }; trickNameTable[RG_MEGATON_HAMMER] = { - Text{"Goron Gavel", "Masse Perforatrice", "Mazo Goron"}, - Text{"Magic Hammer", "Marteau Magique", "Martillo mágico"}, - Text{"Skull Hammer", "Maillet Ressort", "Martillo de hierro"}, + Text{ "Goron Gavel", "Masse Perforatrice", "Mazo Goron" }, + Text{ "Magic Hammer", "Marteau Magique", "Martillo mágico" }, + Text{ "Skull Hammer", "Maillet Ressort", "Martillo de hierro" }, }; trickNameTable[RG_STONE_OF_AGONY] = { - Text{"Cave Charm", "Charme de grotte", "Amuleto de la cueva"}, - Text{"Stone of Agahnim", "Fragment d'Agahnim", "Piedra de Agahnim"}, - Text{"Shard of Agony", "Fragment de Souffrance", "Piedra de la Agonía"}, - Text{"Pirate's Charm", "Pierre de Pirate", "Amuleto Pirata"}, + Text{ "Cave Charm", "Charme de grotte", "Amuleto de la cueva" }, + Text{ "Stone of Agahnim", "Fragment d'Agahnim", "Piedra de Agahnim" }, + Text{ "Shard of Agony", "Fragment de Souffrance", "Piedra de la Agonía" }, + Text{ "Pirate's Charm", "Pierre de Pirate", "Amuleto Pirata" }, }; trickNameTable[RG_DINS_FIRE] = { - Text{"Eldin's Fire", "Feu d'Eldin", "Fuego de Eldin"}, - Text{"Din's Blaze", "Flamme de Din", "Poder de Din"}, - Text{"Magic Lantern", "Lanterne Magique", "Linterna mágica"}, - Text{"Ether Medallion", "Médaillon d'Éther", "Medallón de Tesoro"}, - Text{"Bombos Medallion", "Médaillon des Flammes", "Medallón del Temblor"}, + Text{ "Eldin's Fire", "Feu d'Eldin", "Fuego de Eldin" }, + Text{ "Din's Blaze", "Flamme de Din", "Poder de Din" }, + Text{ "Magic Lantern", "Lanterne Magique", "Linterna mágica" }, + Text{ "Ether Medallion", "Médaillon d'Éther", "Medallón de Tesoro" }, + Text{ "Bombos Medallion", "Médaillon des Flammes", "Medallón del Temblor" }, }; trickNameTable[RG_FARORES_WIND] = { - Text{"Faron's Wind", "Vent de Firone", "Viento de Farone"}, - Text{"Farore's Windfall", "Zéphyr de Farore", "Valor de Farore"}, - Text{"Tingle Air", "Tingle Air", "Tingle de aire"}, - Text{"Travel Medallion", "Amulette de téléportation", "Medallón Maligno"}, - Text{"Irene's Taxi", "Le taxi d'Aëline", "El taxi de Airín"}, + Text{ "Faron's Wind", "Vent de Firone", "Viento de Farone" }, + Text{ "Farore's Windfall", "Zéphyr de Farore", "Valor de Farore" }, + Text{ "Tingle Air", "Tingle Air", "Tingle de aire" }, + Text{ "Travel Medallion", "Amulette de téléportation", "Medallón Maligno" }, + Text{ "Irene's Taxi", "Le taxi d'Aëline", "El taxi de Airín" }, }; trickNameTable[RG_NAYRUS_LOVE] = { - Text{"Lanayru's Love", "Amour de Lanelle", "Amor de Lanayru"}, - Text{"Nayru's Passion", "Passion de Nayru", "Sabiduría de Nayru"}, - Text{"Tingle Shield", "Bouclier Tingle", "Escudo de hormigueo"}, - Text{"Shield Spell", "Bouclier Magique", "Hechizo de Protección"}, - Text{"Magic Armor", "Armure Magique", "Armadura mágica"}, + Text{ "Lanayru's Love", "Amour de Lanelle", "Amor de Lanayru" }, + Text{ "Nayru's Passion", "Passion de Nayru", "Sabiduría de Nayru" }, + Text{ "Tingle Shield", "Bouclier Tingle", "Escudo de hormigueo" }, + Text{ "Shield Spell", "Bouclier Magique", "Hechizo de Protección" }, + Text{ "Magic Armor", "Armure Magique", "Armadura mágica" }, }; trickNameTable[RG_FIRE_ARROWS] = { - Text{"Fire Rod", "Baguette de feu", "Cetro de fuego"}, - Text{"Bomb Arrow", "Flèche-Bombe", "Flecha bomba"}, - Text{"Red Candle", "Bougie Rouge", "Vela roja"}, + Text{ "Fire Rod", "Baguette de feu", "Cetro de fuego" }, + Text{ "Bomb Arrow", "Flèche-Bombe", "Flecha bomba" }, + Text{ "Red Candle", "Bougie Rouge", "Vela roja" }, }; trickNameTable[RG_ICE_ARROWS] = { - Text{"Ice Rod", "Baguette des Glaces", "Cetro de Hielo"}, - Text{"Ancient Arrow", "Flèche Archéonique", "Flecha ancestral"}, - Text{"Ice Trap Arrow", "Flèche de Piège de Glace", "Cetro de hielo"}, + Text{ "Ice Rod", "Baguette des Glaces", "Cetro de Hielo" }, + Text{ "Ancient Arrow", "Flèche Archéonique", "Flecha ancestral" }, + Text{ "Ice Trap Arrow", "Flèche de Piège de Glace", "Cetro de hielo" }, }; trickNameTable[RG_LIGHT_ARROWS] = { - Text{"Wind Arrow", "Flèche de Vent", "Flecha del Viento"}, - Text{"Wand of Gamelon", "Baguette de Gamelon", "Varita de Gamelón"}, - Text{"Shock Arrow", "Flèches Électriques", "Flecha eléctrica"}, - Text{"Silver Arrow", "Flèches d'Argent", "Flecha de plata"}, + Text{ "Wind Arrow", "Flèche de Vent", "Flecha del Viento" }, + Text{ "Wand of Gamelon", "Baguette de Gamelon", "Varita de Gamelón" }, + Text{ "Shock Arrow", "Flèches Électriques", "Flecha eléctrica" }, + Text{ "Silver Arrow", "Flèches d'Argent", "Flecha de plata" }, }; trickNameTable[RG_GERUDO_MEMBERSHIP_CARD] = { - Text{"Desert Title Deed", "Abonnement Gerudo", "Escritura del desierto"}, - Text{"Sickle Moon Flag", "Drapeau du croissant de lune", "Bandera de la Luna Creciente"}, - Text{"Complimentary ID", "Bon de félicitation", "Cupón especial"}, - Text{"Gerudo's Card", "Carte Goron", "Tóken Gerudo"}, - Text{"Gerudo's Membership Card", "Autographe de Nabooru", "Tarjeta Gerudo"}, + Text{ "Desert Title Deed", "Abonnement Gerudo", "Escritura del desierto" }, + Text{ "Sickle Moon Flag", "Drapeau du croissant de lune", "Bandera de la Luna Creciente" }, + Text{ "Complimentary ID", "Bon de félicitation", "Cupón especial" }, + Text{ "Gerudo's Card", "Carte Goron", "Tóken Gerudo" }, + Text{ "Gerudo's Membership Card", "Autographe de Nabooru", "Tarjeta Gerudo" }, }; trickNameTable[RG_MAGIC_BEAN_PACK] = { - Text{"Funky Bean Pack", "Paquet de Fèves Magiques", "Lote de frijoles mágicos"}, - Text{"Grapple Berries", "Baies de grappin", "Bayas de garfio"}, - Text{"Crenel Bean Pack", "Paquet de Haricots Gonggle", "Lote de alubias mágicas"}, - Text{"Mystical Seed Pack", "Pack de graines mystiques", "Paquete de semillas místicas"}, + Text{ "Funky Bean Pack", "Paquet de Fèves Magiques", "Lote de frijoles mágicos" }, + Text{ "Grapple Berries", "Baies de grappin", "Bayas de garfio" }, + Text{ "Crenel Bean Pack", "Paquet de Haricots Gonggle", "Lote de alubias mágicas" }, + Text{ "Mystical Seed Pack", "Pack de graines mystiques", "Paquete de semillas místicas" }, }; trickNameTable[RG_DOUBLE_DEFENSE] = { - Text{"Diamond Hearts", "Coeurs de Diamant", "Contenedor de diamante"}, - Text{"Double Damage", "Double Souffrance", "Doble daño receptivo"}, - Text{"Quadruple Defence", "Quadruple Défence", "Defensa cuádruple"}, + Text{ "Diamond Hearts", "Coeurs de Diamant", "Contenedor de diamante" }, + Text{ "Double Damage", "Double Souffrance", "Doble daño receptivo" }, + Text{ "Quadruple Defence", "Quadruple Défence", "Defensa cuádruple" }, }; trickNameTable[RG_POCKET_EGG] = { - Text{"Arpagos Egg", "Oeuf d'Arpagos", "Huevo de Arpagos"}, - Text{"Lon Lon Egg", "oeuf Lon Lon", "Huevo Lon Lon"}, - Text{"Zora Egg", "oeuf Zora", "Huevo del Pez Viento"}, + Text{ "Arpagos Egg", "Oeuf d'Arpagos", "Huevo de Arpagos" }, + Text{ "Lon Lon Egg", "oeuf Lon Lon", "Huevo Lon Lon" }, + Text{ "Zora Egg", "oeuf Zora", "Huevo del Pez Viento" }, }; trickNameTable[RG_POCKET_EGG] = { - Text{"D.I.Y. Alarm Clock", "Réveille-matin improvisé", "Alarma emplumada portátil"}, - Text{"Kakariko Cucco", "Cocotte Cocorico", "Cuco de Kakariko"}, - Text{"Hatched Cucco", "Cocotte éclose", "Pollo de bolsillo"}, + Text{ "D.I.Y. Alarm Clock", "Réveille-matin improvisé", "Alarma emplumada portátil" }, + Text{ "Kakariko Cucco", "Cocotte Cocorico", "Cuco de Kakariko" }, + Text{ "Hatched Cucco", "Cocotte éclose", "Pollo de bolsillo" }, }; trickNameTable[RG_COJIRO] = { - Text{"Blucco", "Chair-Qui-Poule", "Cucazul"}, - Text{"Piyoko", "Piyoko", "Piyoko"}, - Text{"Dark Cucco", "Cocotte Sombre", "Cucco oscuro"}, - Text{"Grog's Cucco", "Cocotte de Grog", "Cuco de Grog"}, + Text{ "Blucco", "Chair-Qui-Poule", "Cucazul" }, + Text{ "Piyoko", "Piyoko", "Piyoko" }, + Text{ "Dark Cucco", "Cocotte Sombre", "Cucco oscuro" }, + Text{ "Grog's Cucco", "Cocotte de Grog", "Cuco de Grog" }, }; trickNameTable[RG_ODD_MUSHROOM] = { - Text{"Magic Mushroom", "Champignon magique", "Champiñón mágico"}, - Text{"Endura Shroom", "Champi Vigueur", "Champiñón del bosque"}, - Text{"Sleepy Toadstool", "Crapaud Fatigué", "Seta durmiente"}, - Text{"Mushroom", "Champignon", "Seta"}, + Text{ "Magic Mushroom", "Champignon magique", "Champiñón mágico" }, + Text{ "Endura Shroom", "Champi Vigueur", "Champiñón del bosque" }, + Text{ "Sleepy Toadstool", "Crapaud Fatigué", "Seta durmiente" }, + Text{ "Mushroom", "Champignon", "Seta" }, }; trickNameTable[RG_ODD_POTION] = { - Text{"Odd Medicine", "Élixir suspect", "Poción rara"}, - Text{"Granny's Poultice", "Mixture de Granny", "Medicina de la abuela"}, - Text{"Mushroom Poultice", "Mixture de champignon", "Medicina de champiñones"}, - Text{"Secret Medicine", "Médicament", "Pócima secreta"}, - Text{"Mushroom Spores", "Spores de Champignons", "Esporas de hongos"}, - Text{"Hanyu Spore", "Hanyu Spore", "Espora Hanyu"}, + Text{ "Odd Medicine", "Élixir suspect", "Poción rara" }, + Text{ "Granny's Poultice", "Mixture de Granny", "Medicina de la abuela" }, + Text{ "Mushroom Poultice", "Mixture de champignon", "Medicina de champiñones" }, + Text{ "Secret Medicine", "Médicament", "Pócima secreta" }, + Text{ "Mushroom Spores", "Spores de Champignons", "Esporas de hongos" }, + Text{ "Hanyu Spore", "Hanyu Spore", "Espora Hanyu" }, }; trickNameTable[RG_POACHERS_SAW] = { - Text{"Carpenter's Saw", "Scie du charpentier", "Sierra del carpintero"}, - Text{"Poacher's Sword", "Hache du chasseur", "Espada del capataz"}, - Text{"Ancient Bladesaw", "Longue Épée Archéonique", "Mandoble ancestral"}, - Text{"Woodcutter's Axe", "Hache du Bûcheron", "Hacha de leñador"}, - Text{"Grog's Saw", "Scie de Grog", "Sierra del Cazador Furtivo"}, + Text{ "Carpenter's Saw", "Scie du charpentier", "Sierra del carpintero" }, + Text{ "Poacher's Sword", "Hache du chasseur", "Espada del capataz" }, + Text{ "Ancient Bladesaw", "Longue Épée Archéonique", "Mandoble ancestral" }, + Text{ "Woodcutter's Axe", "Hache du Bûcheron", "Hacha de leñador" }, + Text{ "Grog's Saw", "Scie de Grog", "Sierra del Cazador Furtivo" }, }; trickNameTable[RG_BROKEN_SWORD] = { - Text{"Broken Biggoron's Sword", "Épée brisée de Grogoron", "Espada de Biggoron rota"}, - Text{"Broken Giant's Knife", "Lame des Géants brisée", "Daga gigante rota"}, - Text{"Broken Noble Sword", "Épée noble brisée", "Espada noble rota"}, - Text{"Broken Picori Blade", "Épée Minish brisée", "Espada minish rota"}, - Text{"Decayed Master Sword", "Épée de légende pourrie", "Espada decadente de leyenda"}, + Text{ "Broken Biggoron's Sword", "Épée brisée de Grogoron", "Espada de Biggoron rota" }, + Text{ "Broken Giant's Knife", "Lame des Géants brisée", "Daga gigante rota" }, + Text{ "Broken Noble Sword", "Épée noble brisée", "Espada noble rota" }, + Text{ "Broken Picori Blade", "Épée Minish brisée", "Espada minish rota" }, + Text{ "Decayed Master Sword", "Épée de légende pourrie", "Espada decadente de leyenda" }, }; trickNameTable[RG_PRESCRIPTION] = { - Text{"Biggoron's Prescription", "Ordonnance de Grogoron", "Receta de Biggoron"}, - Text{"Eyedrop Prescription", "Ordonnance de gouttes", "Receta ocular"}, - Text{"Urgent Prescription", "Ordonnance urgente", "Prescripción"}, - Text{"Swordsman's Scroll", "Précis d'escrime", "Esgrimidorium"}, - Text{"Portrait of Oren", "Portrait d'Orlène", "Retrato de Oren"}, - Text{"Letter to King Zora", "Lettre au roi Zora", "Carta al Rey Zora"}, + Text{ "Biggoron's Prescription", "Ordonnance de Grogoron", "Receta de Biggoron" }, + Text{ "Eyedrop Prescription", "Ordonnance de gouttes", "Receta ocular" }, + Text{ "Urgent Prescription", "Ordonnance urgente", "Prescripción" }, + Text{ "Swordsman's Scroll", "Précis d'escrime", "Esgrimidorium" }, + Text{ "Portrait of Oren", "Portrait d'Orlène", "Retrato de Oren" }, + Text{ "Letter to King Zora", "Lettre au roi Zora", "Carta al Rey Zora" }, }; trickNameTable[RG_EYEBALL_FROG] = { - Text{"Don Gero", "Don Gero", "Don Gero"}, - Text{"Hot-Footed Frog", "Grenouille à pieds chauds", "Rana de patas calientes"}, - Text{"Lost Swordsmith", "Forgeron perdu", "Espadachín perdido"}, - Text{"Eyedrop Frog", "Grenouille-qui-louche", "Globo Ocular de Rana"}, + Text{ "Don Gero", "Don Gero", "Don Gero" }, + Text{ "Hot-Footed Frog", "Grenouille à pieds chauds", "Rana de patas calientes" }, + Text{ "Lost Swordsmith", "Forgeron perdu", "Espadachín perdido" }, + Text{ "Eyedrop Frog", "Grenouille-qui-louche", "Globo Ocular de Rana" }, }; trickNameTable[RG_EYEDROPS] = { - Text{"Biggoron's Eyedrops", "Gouttes de Grogoron", "Gotas de Biggoron"}, - Text{"Hyrule's Finest Eyedrops", "Eau du Lac Hylia", "Gotas oculares"}, - Text{"Moon's Tear", "Larme de Lune", "Lágrima de Luna"}, - Text{"Engine Grease", "Graisse moteur", "Grasa del motor"}, - Text{"Zora Perfume", "Parfum Zora", "Perfume Zora"}, + Text{ "Biggoron's Eyedrops", "Gouttes de Grogoron", "Gotas de Biggoron" }, + Text{ "Hyrule's Finest Eyedrops", "Eau du Lac Hylia", "Gotas oculares" }, + Text{ "Moon's Tear", "Larme de Lune", "Lágrima de Luna" }, + Text{ "Engine Grease", "Graisse moteur", "Grasa del motor" }, + Text{ "Zora Perfume", "Parfum Zora", "Perfume Zora" }, }; trickNameTable[RG_CLAIM_CHECK] = { - Text{"Clay Check", "Certificat Grogoron", "Comprobante de Reclamación"}, - Text{"Ancient Tablet", "Stèle ancienne", "Litografía arcana"}, - Text{"Sheikah Slate", "Tablette Sheikah", "Piedra Sheikah"}, - Text{"Cyclone Slate", "Ardoise des tornades", "Pizarra de los Torbellinos"}, + Text{ "Clay Check", "Certificat Grogoron", "Comprobante de Reclamación" }, + Text{ "Ancient Tablet", "Stèle ancienne", "Litografía arcana" }, + Text{ "Sheikah Slate", "Tablette Sheikah", "Piedra Sheikah" }, + Text{ "Cyclone Slate", "Ardoise des tornades", "Pizarra de los Torbellinos" }, }; trickNameTable[RG_GOLD_SKULLTULA_TOKEN] = { - Text{"Skulltula Token", "Bon de Skulltula dorée", "Símbolo de Skulltula"}, - Text{"Golden Skulltula Spirit", "Pièce de Skulltula dorée", "Tóken de Skulltula Dorada"}, - Text{"Gold Walltula Token", "Jeton de Walltula dorée", "Skulltula dorada"}, - Text{"Maiamai", "Ti'gorneau", "Maimai"}, - Text{"Gratitude Crystal", "Cristal de gratitude", "Gema de gratitud"}, - Text{"Korok Seed", "Noix korogu", "Semilla de kolog"}, + Text{ "Skulltula Token", "Bon de Skulltula dorée", "Símbolo de Skulltula" }, + Text{ "Golden Skulltula Spirit", "Pièce de Skulltula dorée", "Tóken de Skulltula Dorada" }, + Text{ "Gold Walltula Token", "Jeton de Walltula dorée", "Skulltula dorada" }, + Text{ "Maiamai", "Ti'gorneau", "Maimai" }, + Text{ "Gratitude Crystal", "Cristal de gratitude", "Gema de gratitud" }, + Text{ "Korok Seed", "Noix korogu", "Semilla de kolog" }, }; trickNameTable[RG_PROGRESSIVE_HOOKSHOT] = { - Text{"Progressive Grappling Hook", "Lance-chaîne (prog.)", "Garra progresiva"}, - Text{"Progressive Clawshot", "Grappin-griffe (prog.)", "Zarpa progresiva"}, - Text{"Progressive Gripshot", "Grappince (prog.)", "Enganchador progresivo"}, - Text{"Progressive Rope", "Corde (prog.)", "Cuerda progresivo"}, + Text{ "Progressive Grappling Hook", "Lance-chaîne (prog.)", "Garra progresiva" }, + Text{ "Progressive Clawshot", "Grappin-griffe (prog.)", "Zarpa progresiva" }, + Text{ "Progressive Gripshot", "Grappince (prog.)", "Enganchador progresivo" }, + Text{ "Progressive Rope", "Corde (prog.)", "Cuerda progresivo" }, }; trickNameTable[RG_PROGRESSIVE_STRENGTH] = { - Text{"Power Glove", "Gant de Puissance (prog.)", "Guanteletes progresivos"}, - Text{"Power Bracelet", "Bracelet de Force (prog.)", "Brasaletes progresivos"}, - Text{"Magic Bracelet", "Bracelet Magique (prog.)", "Manoplas progresivas"}, + Text{ "Power Glove", "Gant de Puissance (prog.)", "Guanteletes progresivos" }, + Text{ "Power Bracelet", "Bracelet de Force (prog.)", "Brasaletes progresivos" }, + Text{ "Magic Bracelet", "Bracelet Magique (prog.)", "Manoplas progresivas" }, }; trickNameTable[RG_PROGRESSIVE_BOMB_BAG] = { - Text{"Progressive Bomb Capacity", "Capacité de bombes (prog.)", "Mayor capacidad de bombas"}, - Text{"Progressive Bomb Pack", "Paquet de bombes (prog.)", "Zurrón de bombas progresivo"}, - Text{"Progressive Bomb Box", "Boîte à bombes (prog.)", "Bolsa de bombas progresiva"}, - Text{"Progressive Blast Mask", "Masque d'Explosion (prog.)", "Máscara explosiva progresiva"}, - Text{"Progressive Powder Kegs", "Baril de Poudre (prog.)", "Barril de polvo progresivo"}, - Text{"Progressive Remote Bombs", "Bombes à distance (prog.)", "Bombas remotas progresivas"}, + Text{ "Progressive Bomb Capacity", "Capacité de bombes (prog.)", "Mayor capacidad de bombas" }, + Text{ "Progressive Bomb Pack", "Paquet de bombes (prog.)", "Zurrón de bombas progresivo" }, + Text{ "Progressive Bomb Box", "Boîte à bombes (prog.)", "Bolsa de bombas progresiva" }, + Text{ "Progressive Blast Mask", "Masque d'Explosion (prog.)", "Máscara explosiva progresiva" }, + Text{ "Progressive Powder Kegs", "Baril de Poudre (prog.)", "Barril de polvo progresivo" }, + Text{ "Progressive Remote Bombs", "Bombes à distance (prog.)", "Bombas remotas progresivas" }, }; trickNameTable[RG_PROGRESSIVE_BOW] = { - Text{"Progressive Arrow Capacity", "Capacité de flèches (prog.)", "Mayor capacidad de flechas"}, - Text{"Progressive Hero's Bow", "Arc du héros (prog.)", "Arco del héroe progresivo"}, - Text{"Progressive Arrow Holder", "Arbalète (prog.)", "Ballesta progresiva"}, - Text{"Progressive Crossbow", "Arbalète (prog.)", "Ballesta progresiva"}, - Text{"Progressive Sacred Bow", "Arc sacré (prog)", "Arco Sagrado Progresivo"}, - Text{"Progressive Lynel Bow", "Arc de Lynel (prog.)", "Arco de centaleón Progresivo"}, + Text{ "Progressive Arrow Capacity", "Capacité de flèches (prog.)", "Mayor capacidad de flechas" }, + Text{ "Progressive Hero's Bow", "Arc du héros (prog.)", "Arco del héroe progresivo" }, + Text{ "Progressive Arrow Holder", "Arbalète (prog.)", "Ballesta progresiva" }, + Text{ "Progressive Crossbow", "Arbalète (prog.)", "Ballesta progresiva" }, + Text{ "Progressive Sacred Bow", "Arc sacré (prog)", "Arco Sagrado Progresivo" }, + Text{ "Progressive Lynel Bow", "Arc de Lynel (prog.)", "Arco de centaleón Progresivo" }, }; trickNameTable[RG_PROGRESSIVE_SLINGSHOT] = { - Text{"Progressive Seed Capacity", "Capacité de graines (prog.)", "Mayor capacidad de semillas"}, - Text{"Progressive Catapult", "Catapulte (prog.)", "Catapulta progresiva"}, - Text{"Progressive Scattershot", "Lance-Pierre rafale (prog.)", "Resortera múltiple progresiva"}, - Text{"Progressive Seed Launcher", "Lanceur de semences (prog.)", "Lanzador de semillas progresivo"}, - Text{"Progressive Seed Satchel", "Sac de graines (prog.)", "Bolsa de semillas progresiva"}, + Text{ "Progressive Seed Capacity", "Capacité de graines (prog.)", "Mayor capacidad de semillas" }, + Text{ "Progressive Catapult", "Catapulte (prog.)", "Catapulta progresiva" }, + Text{ "Progressive Scattershot", "Lance-Pierre rafale (prog.)", "Resortera múltiple progresiva" }, + Text{ "Progressive Seed Launcher", "Lanceur de semences (prog.)", "Lanzador de semillas progresivo" }, + Text{ "Progressive Seed Satchel", "Sac de graines (prog.)", "Bolsa de semillas progresiva" }, }; trickNameTable[RG_PROGRESSIVE_WALLET] = { - Text{"Progressive Rupee Capacity", "Capacité de rubis (prog.)", "Mayor capacidad de rupias"}, - Text{"Progressive Purse", "Sacoche (prog.)", "Cartera de rupias progresiva"}, - Text{"Progressive Rupee Bag", "Sac à rubis (prog.)", "Zurrón de rupias progresivo"}, - Text{"Progressive Rupoor Capacity", "Capacité de Roupir (prog.)", "Capacidad progresiva Rupobre"}, - Text{"Progressive Spoils Bag", "Sac à Butin (prog.)", "Bolsa de trofeos progresiva"}, - Text{"Progressive Ruby Bag", "Capacité du sac Ruby (prog.)", "Bolso Ruby progresivo"}, + Text{ "Progressive Rupee Capacity", "Capacité de rubis (prog.)", "Mayor capacidad de rupias" }, + Text{ "Progressive Purse", "Sacoche (prog.)", "Cartera de rupias progresiva" }, + Text{ "Progressive Rupee Bag", "Sac à rubis (prog.)", "Zurrón de rupias progresivo" }, + Text{ "Progressive Rupoor Capacity", "Capacité de Roupir (prog.)", "Capacidad progresiva Rupobre" }, + Text{ "Progressive Spoils Bag", "Sac à Butin (prog.)", "Bolsa de trofeos progresiva" }, + Text{ "Progressive Ruby Bag", "Capacité du sac Ruby (prog.)", "Bolso Ruby progresivo" }, }; trickNameTable[RG_PROGRESSIVE_SCALE] = { - Text{"Progressive Flippers", "Palmes de Zora (prog.)", "Aletas de zora progresiva"}, - Text{"Progressive Dragon's Scale", "Écaille du dragon d'eau (prog.)", "Escama dragón acuático progresiva"}, - Text{"Progressive Diving Ability", "Plongée (prog.)", "Buceo progresivo"}, - Text{"Progressive Pearl", "Perle (prog.)", "Perla progresiva"}, - Text{"Progressive Scute", "Bulle (prog.)", "Fragmento Zora progresivo"}, + Text{ "Progressive Flippers", "Palmes de Zora (prog.)", "Aletas de zora progresiva" }, + Text{ "Progressive Dragon's Scale", "Écaille du dragon d'eau (prog.)", "Escama dragón acuático progresiva" }, + Text{ "Progressive Diving Ability", "Plongée (prog.)", "Buceo progresivo" }, + Text{ "Progressive Pearl", "Perle (prog.)", "Perla progresiva" }, + Text{ "Progressive Scute", "Bulle (prog.)", "Fragmento Zora progresivo" }, }; trickNameTable[RG_PROGRESSIVE_NUT_UPGRADE] = { - Text{"Progressive Nut Pack", "Paquet de noix (prog.)", "Mayor capacidad de semillas"}, - Text{"Progressive Bait Bag", "Sac à Appâts (prog.)", "Bolsa de cebo progresiva"}, - Text{"Progressive Pear Capacity", "Capacité de poire (prog.)", "Capacidad progresiva de pera"}, - Text{"Progressive Nut Bag", "Sac de noix (prog.)", "Bolsa de nueces progresiva"}, - Text{"Progressive Husk Capacity", "Capacité de noisettes (prog.)", "Mayor capacidad de castañas"}, + Text{ "Progressive Nut Pack", "Paquet de noix (prog.)", "Mayor capacidad de semillas" }, + Text{ "Progressive Bait Bag", "Sac à Appâts (prog.)", "Bolsa de cebo progresiva" }, + Text{ "Progressive Pear Capacity", "Capacité de poire (prog.)", "Capacidad progresiva de pera" }, + Text{ "Progressive Nut Bag", "Sac de noix (prog.)", "Bolsa de nueces progresiva" }, + Text{ "Progressive Husk Capacity", "Capacité de noisettes (prog.)", "Mayor capacidad de castañas" }, }; trickNameTable[RG_PROGRESSIVE_STICK_UPGRADE] = { - Text{"Progressive Stick Bag", "Sac de bâtons (prog.)", "Mayor capacidad de ramas deku"}, - Text{"Progressive Stick Pack", "Paquet de bâtons Mojo (prog.)", "Mayor capacidad de bastones"}, - Text{"Progressive Branch Capacity", "Capacité de la succursale (prog.)", "Capacidad progresiva de la sucursal"}, - Text{"Progressive Rod Capacity", "Capacité de tiges (prog.)", "Mayor capacidad de cetros deku"}, + Text{ "Progressive Stick Bag", "Sac de bâtons (prog.)", "Mayor capacidad de ramas deku" }, + Text{ "Progressive Stick Pack", "Paquet de bâtons Mojo (prog.)", "Mayor capacidad de bastones" }, + Text{ "Progressive Branch Capacity", "Capacité de la succursale (prog.)", + "Capacidad progresiva de la sucursal" }, + Text{ "Progressive Rod Capacity", "Capacité de tiges (prog.)", "Mayor capacidad de cetros deku" }, }; trickNameTable[RG_PROGRESSIVE_BOMBCHUS] = { - Text{"Progressive Bomblings", "Bombinsectes (prog.)", "Bombinsectos progresivos"}, - Text{"Progressive Sentrobe Bombs", "Bombe de Sphérodrone (prog.)", "Bomba de helicobot progresivo"}, - Text{"Progressive Bomb-ombs", "Bombe Soldat (prog.)", "Soldado bomba progresivo"}, - Text{"Progressive Missiles", "Missiles (prog.)", "Misiles progresivos"}, - Text{"Progressive Bombchu Bag", "Sac à Bombchu (prog.)", "Bombachus progresivos"}, + Text{ "Progressive Bomblings", "Bombinsectes (prog.)", "Bombinsectos progresivos" }, + Text{ "Progressive Sentrobe Bombs", "Bombe de Sphérodrone (prog.)", "Bomba de helicobot progresivo" }, + Text{ "Progressive Bomb-ombs", "Bombe Soldat (prog.)", "Soldado bomba progresivo" }, + Text{ "Progressive Missiles", "Missiles (prog.)", "Misiles progresivos" }, + Text{ "Progressive Bombchu Bag", "Sac à Bombchu (prog.)", "Bombachus progresivos" }, }; trickNameTable[RG_PROGRESSIVE_MAGIC_METER] = { - Text{"Progressive Stamina Meter", "Jauge d'endurance (prog.)", "Medidor de vigor progresivo"}, - Text{"Progressive Energy Gauge", "Jauge d'énergie (prog.)", "Medidor de energía progresivo"}, - Text{"Progressive Magic Powder", "Poudre magique (prog.)", "Medidor de carga progresivo"}, + Text{ "Progressive Stamina Meter", "Jauge d'endurance (prog.)", "Medidor de vigor progresivo" }, + Text{ "Progressive Energy Gauge", "Jauge d'énergie (prog.)", "Medidor de energía progresivo" }, + Text{ "Progressive Magic Powder", "Poudre magique (prog.)", "Medidor de carga progresivo" }, }; trickNameTable[RG_PROGRESSIVE_OCARINA] = { - Text{"Progressive Memento", "Souvenir (prog.)", "Silbato progresivo"}, - Text{"Progressive Whistle", "Siffler (prog.)", "Silbido progresivo"}, - Text{"Progressive Flute", "Flûte (prog.)", "Flauta progresiva"}, - Text{"Progressive Recorder", "Harmonica (prog.)", "Armónica progresiva"}, + Text{ "Progressive Memento", "Souvenir (prog.)", "Silbato progresivo" }, + Text{ "Progressive Whistle", "Siffler (prog.)", "Silbido progresivo" }, + Text{ "Progressive Flute", "Flûte (prog.)", "Flauta progresiva" }, + Text{ "Progressive Recorder", "Harmonica (prog.)", "Armónica progresiva" }, }; trickNameTable[RG_PROGRESSIVE_GORONSWORD] = { - Text{"Progressive Titan Blade", "Lame des Titans (prog.)", "Hoja del Titán progresiva"}, - Text{"Progressive Goron Knife", "Lame Goron (prog.)", "Daga Goron progresiva"}, - Text{"Progressive Giant Sword", "Épée géante (prog.)", "Espada gigante progresiva"}, - Text{"Progressive Darknut Sword", "Épée de Darknut (prog.)", "Espada Darknut progresiva"}, - Text{"Progressive Power Sword", "Épée de Puissance (prog.)", "Espada de poder progresiva"}, - Text{"Progressive Big Stabby", "Gros coup de poignard (prog.)", "Gran puñalada progresiva"}, + Text{ "Progressive Titan Blade", "Lame des Titans (prog.)", "Hoja del Titán progresiva" }, + Text{ "Progressive Goron Knife", "Lame Goron (prog.)", "Daga Goron progresiva" }, + Text{ "Progressive Giant Sword", "Épée géante (prog.)", "Espada gigante progresiva" }, + Text{ "Progressive Darknut Sword", "Épée de Darknut (prog.)", "Espada Darknut progresiva" }, + Text{ "Progressive Power Sword", "Épée de Puissance (prog.)", "Espada de poder progresiva" }, + Text{ "Progressive Big Stabby", "Gros coup de poignard (prog.)", "Gran puñalada progresiva" }, }; trickNameTable[RG_EMPTY_BOTTLE] = { - Text{"Empty Canteen", "Cantine vide", "cantimplora vacía"}, - Text{"Vial of Winds", "Fiole de vents", "Vial de Vientos"}, - Text{"Tingle Bottle", "Flacon de Tingle", "Botella de Tingle"}, - Text{"Magic Bottle", "Flacon magique", "Frasco feérico"}, - Text{"Glass Bottle", "Flacon de verre", "Botella de cristal"}, - Text{"Bottle with Water", "Flacon d'eau", "Botella Tingle"}, + Text{ "Empty Canteen", "Cantine vide", "cantimplora vacía" }, + Text{ "Vial of Winds", "Fiole de vents", "Vial de Vientos" }, + Text{ "Tingle Bottle", "Flacon de Tingle", "Botella de Tingle" }, + Text{ "Magic Bottle", "Flacon magique", "Frasco feérico" }, + Text{ "Glass Bottle", "Flacon de verre", "Botella de cristal" }, + Text{ "Bottle with Water", "Flacon d'eau", "Botella Tingle" }, }; trickNameTable[RG_BOTTLE_WITH_MILK] = { - Text{"Bottle with Chateau Romani", "Flacon de cuvée Romani", "Botella de Reserva Romani"}, - Text{"Bottle with Premium Milk", "Flacon avec lait de qualité supérieure", "Biberón con leche Premium"}, - Text{"Bottle with Mystery Milk", "Flacon de lait grand cru", "Botella de leche extra"}, - Text{"Bottle with Fresh Milk", "Flacon de lait frais", "Botella de leche fresca"},}; + Text{ "Bottle with Chateau Romani", "Flacon de cuvée Romani", "Botella de Reserva Romani" }, + Text{ "Bottle with Premium Milk", "Flacon avec lait de qualité supérieure", "Biberón con leche Premium" }, + Text{ "Bottle with Mystery Milk", "Flacon de lait grand cru", "Botella de leche extra" }, + Text{ "Bottle with Fresh Milk", "Flacon de lait frais", "Botella de leche fresca" }, + }; trickNameTable[RG_BOTTLE_WITH_RED_POTION] = { - Text{"Bottle with Red Chu Jelly", "Flacon de gelée Chuchu rouge", "Jugo de Chuchu Rojo"}, - Text{"Bottle with Hibiscus Potion", "Flacon de potion de Hibiscus", "Botella de poción de Hibisco"}, - Text{"Bottle with Medicine of Life", "Flacon d'élixir rouge", "Botella de medicina de la vida"}, - Text{"Bottle with Heart Potion", "Flacon de potion de soin", "Botella de poción de salud"}, + Text{ "Bottle with Red Chu Jelly", "Flacon de gelée Chuchu rouge", "Jugo de Chuchu Rojo" }, + Text{ "Bottle with Hibiscus Potion", "Flacon de potion de Hibiscus", "Botella de poción de Hibisco" }, + Text{ "Bottle with Medicine of Life", "Flacon d'élixir rouge", "Botella de medicina de la vida" }, + Text{ "Bottle with Heart Potion", "Flacon de potion de soin", "Botella de poción de salud" }, }; trickNameTable[RG_BOTTLE_WITH_GREEN_POTION] = { - Text{"Bottle with Green Chu Jelly", "Flacon de gelée Chuchu verte", "Jugo de Chuchu Verde"}, - Text{"Bottle with Lamp Oil", "Flacon de Huile à lanterne", "Botella de Aceite de candil "}, - Text{"Bottle with Medicine of Magic", "Flacon d'élixir vert", "Botella de medicina mágica"}, - Text{"Bottle with Stamina Potion", "Flacon d'Endurol", "Botella de elixir vigorizante"}, + Text{ "Bottle with Green Chu Jelly", "Flacon de gelée Chuchu verte", "Jugo de Chuchu Verde" }, + Text{ "Bottle with Lamp Oil", "Flacon de Huile à lanterne", "Botella de Aceite de candil " }, + Text{ "Bottle with Medicine of Magic", "Flacon d'élixir vert", "Botella de medicina mágica" }, + Text{ "Bottle with Stamina Potion", "Flacon d'Endurol", "Botella de elixir vigorizante" }, }; trickNameTable[RG_BOTTLE_WITH_BLUE_POTION] = { - Text{"Bottle with Blue Chu Jelly", "Flacon de gelée Chuchu bleue", "Jugo de Chuchu Azul"}, - Text{"Bottle with Water of Life", "Flacon d'élixir bleu", "Botella de agua de la vida"}, - Text{"Bottle with Air Potion", "Flacon de potion d'oxygène", "Botella de oxígeno"}, + Text{ "Bottle with Blue Chu Jelly", "Flacon de gelée Chuchu bleue", "Jugo de Chuchu Azul" }, + Text{ "Bottle with Water of Life", "Flacon d'élixir bleu", "Botella de agua de la vida" }, + Text{ "Bottle with Air Potion", "Flacon de potion d'oxygène", "Botella de oxígeno" }, }; trickNameTable[RG_BOTTLE_WITH_FAIRY] = { - Text{"Bottle with Forest Firefly", "Flacon avec une luciole", "Luciérnaga del bosque"}, - Text{"Bottle with Deku Princess", "Flacon avec Deku Princess", "Botella con Deku Princess"}, - Text{"Bottle with Stray Fairy", "Flacon avec une fée perdue", "Hada perdida en una botella"}, + Text{ "Bottle with Forest Firefly", "Flacon avec une luciole", "Luciérnaga del bosque" }, + Text{ "Bottle with Deku Princess", "Flacon avec Deku Princess", "Botella con Deku Princess" }, + Text{ "Bottle with Stray Fairy", "Flacon avec une fée perdue", "Hada perdida en una botella" }, }; trickNameTable[RG_BOTTLE_WITH_FISH] = { - Text{"Bottle with Small Jabu-Jabu", "Flacon avec mini Jabu-Jabu", "Lord Chapu-Chapu embotellado"}, - Text{"Bottle with Reekfish", "Flacon avec Reekfish", "Reekfish embotellada"}, - Text{"Bottle with Hyrule Bass", "Flacon avec perche d'Hyrule", "Locha de Hyrule embotellada"}, - Text{"Bottle with Hyrule Loach", "Flacon avec loche d'Hyrule", "Perca de Términa embotellada"}, + Text{ "Bottle with Small Jabu-Jabu", "Flacon avec mini Jabu-Jabu", "Lord Chapu-Chapu embotellado" }, + Text{ "Bottle with Reekfish", "Flacon avec Reekfish", "Reekfish embotellada" }, + Text{ "Bottle with Hyrule Bass", "Flacon avec perche d'Hyrule", "Locha de Hyrule embotellada" }, + Text{ "Bottle with Hyrule Loach", "Flacon avec loche d'Hyrule", "Perca de Términa embotellada" }, }; trickNameTable[RG_BOTTLE_WITH_BLUE_FIRE] = { - Text{"Bottle with Will-O-Wisp", "Flacon avec feu follet", "Botella de llama azul"}, - Text{"Bottle with Ancient Flame", "Flacon de flamme ancienne", "Botella de fuego ancestral"}, - Text{"Bottle with a Blue Candle", "Flacon avec une bougie bleue", "Botella con una vela azul"}, - Text{"Bottle with Red Ice", "Flacon de Glace Rouge", "Botella de Hielo rojo"}, - Text{"Bottle with Nayru's Flame", "Flacon de flamme de Nayru", "Botella de llamas de Nayru"}, + Text{ "Bottle with Will-O-Wisp", "Flacon avec feu follet", "Botella de llama azul" }, + Text{ "Bottle with Ancient Flame", "Flacon de flamme ancienne", "Botella de fuego ancestral" }, + Text{ "Bottle with a Blue Candle", "Flacon avec une bougie bleue", "Botella con una vela azul" }, + Text{ "Bottle with Red Ice", "Flacon de Glace Rouge", "Botella de Hielo rojo" }, + Text{ "Bottle with Nayru's Flame", "Flacon de flamme de Nayru", "Botella de llamas de Nayru" }, }; trickNameTable[RG_BOTTLE_WITH_BUGS] = { - Text{"Bottle with Baby Tektites", "Flacon de bébé Araknon", "Tektites en una botella"}, - Text{"Bottle with A Beetle", "Flacon avec un scarabée", "Botella con un escarabajo"}, - Text{"Bottle with Lanayru Ants", "Flacon de fourmis de Lanelle", "Celestarabajo embotellado"}, - Text{"Bottle with Insects", "Flacon de bibittes", "Saltabosques embotellados"}, - Text{"Bottle with a Golden Bee", "Flacon avec une abeille dorée", "Botella con una abeja dorada"}, + Text{ "Bottle with Baby Tektites", "Flacon de bébé Araknon", "Tektites en una botella" }, + Text{ "Bottle with A Beetle", "Flacon avec un scarabée", "Botella con un escarabajo" }, + Text{ "Bottle with Lanayru Ants", "Flacon de fourmis de Lanelle", "Celestarabajo embotellado" }, + Text{ "Bottle with Insects", "Flacon de bibittes", "Saltabosques embotellados" }, + Text{ "Bottle with a Golden Bee", "Flacon avec une abeille dorée", "Botella con una abeja dorada" }, }; trickNameTable[RG_BOTTLE_WITH_POE] = { - Text{"Bottle with Ghini", "Flacon avec Ghini", "Ghini en una botella"}, - Text{"Bottle with Reapling", "Flacon avec Âme Damnée", "Reapling en una botella"}, - Text{"Bottle with Imp Poe", "Flacon avec Spectre", "Espectro en una botella"}, - Text{"Bottle with Anti-Fairy", "Flacon avec Tetdoss", "Whisp en una botella"}, + Text{ "Bottle with Ghini", "Flacon avec Ghini", "Ghini en una botella" }, + Text{ "Bottle with Reapling", "Flacon avec Âme Damnée", "Reapling en una botella" }, + Text{ "Bottle with Imp Poe", "Flacon avec Spectre", "Espectro en una botella" }, + Text{ "Bottle with Anti-Fairy", "Flacon avec Tetdoss", "Whisp en una botella" }, }; trickNameTable[RG_RUTOS_LETTER] = { - Text{"Bottle with Maggie's Letter", "Flacon avec lettre de Maggy", "Carta de Dolores"}, - Text{"Bottle with Letter to Kafei", "Flacon avec lettre pour Kafei", "Carta para Kafei"}, - Text{"Bottle with Zelda's Letter", "Flacon avec Lettre de Zelda", "Carta náutica"}, + Text{ "Bottle with Maggie's Letter", "Flacon avec lettre de Maggy", "Carta de Dolores" }, + Text{ "Bottle with Letter to Kafei", "Flacon avec lettre pour Kafei", "Carta para Kafei" }, + Text{ "Bottle with Zelda's Letter", "Flacon avec Lettre de Zelda", "Carta náutica" }, }; trickNameTable[RG_BOTTLE_WITH_BIG_POE] = { - Text{"Bottle with Composer Brother", "Flacon avec un compositeur", "Hermana Poe embotellada"}, - Text{"Bottle with Jalhalla", "Flacon avec Jalhalla", "Yaihalla embotellado"}, - Text{"Bottle with Grim Repoe", "Flacon avec le Faucheur", "Bubble en una botella"}, + Text{ "Bottle with Composer Brother", "Flacon avec un compositeur", "Hermana Poe embotellada" }, + Text{ "Bottle with Jalhalla", "Flacon avec Jalhalla", "Yaihalla embotellado" }, + Text{ "Bottle with Grim Repoe", "Flacon avec le Faucheur", "Bubble en una botella" }, }; trickNameTable[RG_ZELDAS_LULLABY] = { - Text{"Ballad of the Goddess", "Chant de la déesse", "Cántico de la Diosa"}, - Text{"Song of Healing", "Chant de l'apaisement", "Canción de curación"}, - Text{"Song of the Hero", "Chant du héros", "Canción del héroe"}, + Text{ "Ballad of the Goddess", "Chant de la déesse", "Cántico de la Diosa" }, + Text{ "Song of Healing", "Chant de l'apaisement", "Canción de curación" }, + Text{ "Song of the Hero", "Chant du héros", "Canción del héroe" }, }; trickNameTable[RG_EPONAS_SONG] = { - Text{"Song of Birds","Chant des oiseaux","Cantar del ave"}, - Text{"Song of Soaring", "Chant de l'envol", "Canción del viento"}, - Text{"Song of Horse", "Chant du cheval", "Chant du cheval"}, + Text{ "Song of Birds", "Chant des oiseaux", "Cantar del ave" }, + Text{ "Song of Soaring", "Chant de l'envol", "Canción del viento" }, + Text{ "Song of Horse", "Chant du cheval", "Chant du cheval" }, }; trickNameTable[RG_SARIAS_SONG] = { - Text{"Mido's Song", "La chanson de Mido", "La canción de Mido"}, - Text{"Kass' Theme", "Le thème de Kass", "El tema de Kass"}, - Text{"Tune of Echoes", "Chant des Échos ", "Melodía del Eco "}, + Text{ "Mido's Song", "La chanson de Mido", "La canción de Mido" }, + Text{ "Kass' Theme", "Le thème de Kass", "El tema de Kass" }, + Text{ "Tune of Echoes", "Chant des Échos ", "Melodía del Eco " }, }; trickNameTable[RG_SUNS_SONG] = { - Text{"Song of Passing", "Mambo de Manbo", "Melodía del transcurrir"}, - Text{"Command Melody", "Air du marionnettiste", "Cara al Sol"}, - Text{"Moon's Song", "La chanson de Moon", "La canción de la luna"}, + Text{ "Song of Passing", "Mambo de Manbo", "Melodía del transcurrir" }, + Text{ "Command Melody", "Air du marionnettiste", "Cara al Sol" }, + Text{ "Moon's Song", "La chanson de Moon", "La canción de la luna" }, }; trickNameTable[RG_SONG_OF_TIME] = { - Text{"Song of Double Time", "Chant accéléré", "Canción del doble tiempo"}, - Text{"Inverted Song of Time", "Chant du temps inversé", "Canción del tiempo invertida"}, - Text{"Tune of Ages", "Chant du Temps", "Melodía del Tiempo"}, + Text{ "Song of Double Time", "Chant accéléré", "Canción del doble tiempo" }, + Text{ "Inverted Song of Time", "Chant du temps inversé", "Canción del tiempo invertida" }, + Text{ "Tune of Ages", "Chant du Temps", "Melodía del Tiempo" }, }; trickNameTable[RG_SONG_OF_STORMS] = { - Text{"Ballad of Gales", "Requiem de la tornade", "Melodía del Tornado"}, - Text{"Frog's Song of Soul", "Rap des grenouilles", "Canción del alma de la rana"}, - Text{"Wind's Requiem", "Mélodie du vent", "Melodía del Viento"}, + Text{ "Ballad of Gales", "Requiem de la tornade", "Melodía del Tornado" }, + Text{ "Frog's Song of Soul", "Rap des grenouilles", "Canción del alma de la rana" }, + Text{ "Wind's Requiem", "Mélodie du vent", "Melodía del Viento" }, }; trickNameTable[RG_MINUET_OF_FOREST] = { - Text{"Saria's Karaoke", "Karaoké de Saria", "Dueto del bosque"}, - Text{"Sonata of Awakening", "Sonate de l'éveil", "Sonata del despertar"}, - Text{"Wind God's Aria", "Hymne du dieu du vent", "Melodía del Espíritu del Viento"}, + Text{ "Saria's Karaoke", "Karaoké de Saria", "Dueto del bosque" }, + Text{ "Sonata of Awakening", "Sonate de l'éveil", "Sonata del despertar" }, + Text{ "Wind God's Aria", "Hymne du dieu du vent", "Melodía del Espíritu del Viento" }, }; trickNameTable[RG_BOLERO_OF_FIRE] = { - Text{"Darunia's Tango", "Tango de Darunia", "Coro del fuego"}, - Text{"Tune of Currents", "Chants des Flux", "Melodía de las Corrientes"}, - Text{"Goron Lullaby", "Berceuse des Gorons", "Nana goron"}, + Text{ "Darunia's Tango", "Tango de Darunia", "Coro del fuego" }, + Text{ "Tune of Currents", "Chants des Flux", "Melodía de las Corrientes" }, + Text{ "Goron Lullaby", "Berceuse des Gorons", "Nana goron" }, }; trickNameTable[RG_SERENADE_OF_WATER] = { - Text{"Ruto's Blues", "Blues de Ruto", "Sonata del agua"}, - Text{"New Wave Bossa Nova", "Bossa-nova des flots", "Bossanova de las olas"}, - Text{"Manbo's Mambo", "Mambo de Manbo", "Mambo de Manbo"}, + Text{ "Ruto's Blues", "Blues de Ruto", "Sonata del agua" }, + Text{ "New Wave Bossa Nova", "Bossa-nova des flots", "Bossanova de las olas" }, + Text{ "Manbo's Mambo", "Mambo de Manbo", "Mambo de Manbo" }, }; trickNameTable[RG_REQUIEM_OF_SPIRIT] = { - Text{"Nabooru's Reggae", "Reggae de Nabooru", "Reggae del espíritu"}, - Text{"Elegy of Emptiness", "Hymne du vide", "Elegía al vacío"}, - Text{"Earth God's Lyric", "Hymne du dieu de la terre", "Melodía del Espíritu de la Tierra"}, + Text{ "Nabooru's Reggae", "Reggae de Nabooru", "Reggae del espíritu" }, + Text{ "Elegy of Emptiness", "Hymne du vide", "Elegía al vacío" }, + Text{ "Earth God's Lyric", "Hymne du dieu de la terre", "Melodía del Espíritu de la Tierra" }, }; trickNameTable[RG_NOCTURNE_OF_SHADOW] = { - Text{"Impa's Death Metal", "Death métal d'Impa", "Diurno de la sombra"}, - Text{"Oath to Order", "Ode de l'appel", "Oda al orden"}, - Text{"Song of Discovery", "Chant des secrets", "Canto revelador"}, + Text{ "Impa's Death Metal", "Death métal d'Impa", "Diurno de la sombra" }, + Text{ "Oath to Order", "Ode de l'appel", "Oda al orden" }, + Text{ "Song of Discovery", "Chant des secrets", "Canto revelador" }, }; trickNameTable[RG_PRELUDE_OF_LIGHT] = { - Text{"Rauru's Sing-Along", "Chansonnette de Rauru", "Predulio de luz"}, - Text{"Ballad of the Wind Fish", "Ballade sur Poisson-Rêve", "Balada del Piez Viento"}, - Text{"Song of Light", "Chant de la lumière", "Sonidos de la luz"}, + Text{ "Rauru's Sing-Along", "Chansonnette de Rauru", "Predulio de luz" }, + Text{ "Ballad of the Wind Fish", "Ballade sur Poisson-Rêve", "Balada del Piez Viento" }, + Text{ "Song of Light", "Chant de la lumière", "Sonidos de la luz" }, }; trickNameTable[RG_KOKIRI_EMERALD] = { - Text{"Pendant of Courage", "Pendentif du courage", "Colgante del valor"}, - Text{"Farore's Pearl", "Perle de Farore", "Orbe de Farore"}, - Text{"Aquanine", "Smaragdine", "Yerbánida"}, - Text{"Farore's Emerald", "Émeraude de Farore", "Esmeralda de Farore"}, - Text{"Kokiri's Peridot", "Péridot Kokiri", "Ágata de los Kokiri"}, + Text{ "Pendant of Courage", "Pendentif du courage", "Colgante del valor" }, + Text{ "Farore's Pearl", "Perle de Farore", "Orbe de Farore" }, + Text{ "Aquanine", "Smaragdine", "Yerbánida" }, + Text{ "Farore's Emerald", "Émeraude de Farore", "Esmeralda de Farore" }, + Text{ "Kokiri's Peridot", "Péridot Kokiri", "Ágata de los Kokiri" }, }; trickNameTable[RG_GORON_RUBY] = { - Text{"Pendant of Power", "Pendentif de la force", "Colgante del poder"}, - Text{"Din's Pearl", "Perle de Din", "Orbe de Din"}, - Text{"Crimsonine", "Alzanine", "Bermellina"}, - Text{"Din's Ruby", "Rubis de Din", "Rubí de Din"}, - Text{"Goron's Garnet", "Grenat Goron", "Topacio de los Goron"}, + Text{ "Pendant of Power", "Pendentif de la force", "Colgante del poder" }, + Text{ "Din's Pearl", "Perle de Din", "Orbe de Din" }, + Text{ "Crimsonine", "Alzanine", "Bermellina" }, + Text{ "Din's Ruby", "Rubis de Din", "Rubí de Din" }, + Text{ "Goron's Garnet", "Grenat Goron", "Topacio de los Goron" }, }; trickNameTable[RG_ZORA_SAPPHIRE] = { - Text{"Pendant of Wisdom", "Pendentif de la sagesse", "Colgante de la sabiduría"}, - Text{"Nayru's Pearl", "Perle de Nayru", "Orbe de Nayru"}, - Text{"Azurine", "Aquanine", "Azurina"}, - Text{"Nayru's Sapphire", "Saphir de Nayru", "Zafiro de Nayru"}, - Text{"Zora's Aquamarine", "Aquamarine Zora", "Lapislázuli de los Zora"}, + Text{ "Pendant of Wisdom", "Pendentif de la sagesse", "Colgante de la sabiduría" }, + Text{ "Nayru's Pearl", "Perle de Nayru", "Orbe de Nayru" }, + Text{ "Azurine", "Aquanine", "Azurina" }, + Text{ "Nayru's Sapphire", "Saphir de Nayru", "Zafiro de Nayru" }, + Text{ "Zora's Aquamarine", "Aquamarine Zora", "Lapislázuli de los Zora" }, }; trickNameTable[RG_FOREST_MEDALLION] = { - Text{"Wind Medallion", "Médaillon du vent", "Medallón del Viento"}, - Text{"Wind Element", "Elément Vent", "Elemento de aire"}, - Text{"Saria's Medallion", "Médaillon de Saria", "Medallón de Saria"}, - Text{"Sign of Air", "Glyphe de l'air", "Glifo de aire"}, - Text{"Medallion of Forest", "Médaillon du Temple de la Forêt", "Medalla del Bosque"}, + Text{ "Wind Medallion", "Médaillon du vent", "Medallón del Viento" }, + Text{ "Wind Element", "Elément Vent", "Elemento de aire" }, + Text{ "Saria's Medallion", "Médaillon de Saria", "Medallón de Saria" }, + Text{ "Sign of Air", "Glyphe de l'air", "Glifo de aire" }, + Text{ "Medallion of Forest", "Médaillon du Temple de la Forêt", "Medalla del Bosque" }, }; trickNameTable[RG_FIRE_MEDALLION] = { - Text{"Fire Element", "Elément Feu", "Elemento de fuego"}, - Text{"Darunia's Medallion", "Médaillon de Darunia", "Medallón de Darunia"}, - Text{"Sign of Fire", "Glyphe de feu", "Glifo de fuego"}, - Text{"Medallion of Fire", "Médaillon du Temple du Feu", "Medalla del Fuego"}, + Text{ "Fire Element", "Elément Feu", "Elemento de fuego" }, + Text{ "Darunia's Medallion", "Médaillon de Darunia", "Medallón de Darunia" }, + Text{ "Sign of Fire", "Glyphe de feu", "Glifo de fuego" }, + Text{ "Medallion of Fire", "Médaillon du Temple du Feu", "Medalla del Fuego" }, }; trickNameTable[RG_WATER_MEDALLION] = { - Text{"Water Element", "Elément Eau", "Elemento de agua"}, - Text{"Ice Medallion", "Médaillon de glace", "Medallón Helado"}, - Text{"Ruto's Medallion", "Médaillon de Ruto", "Medallón de Ruto"}, - Text{"Sign of Water", "Glyphe de l'eau", "Glifo de agua"}, - Text{"Medallion of Water", "Médaillon du Temple de l'Eau", "Medalla del Agua"}, + Text{ "Water Element", "Elément Eau", "Elemento de agua" }, + Text{ "Ice Medallion", "Médaillon de glace", "Medallón Helado" }, + Text{ "Ruto's Medallion", "Médaillon de Ruto", "Medallón de Ruto" }, + Text{ "Sign of Water", "Glyphe de l'eau", "Glifo de agua" }, + Text{ "Medallion of Water", "Médaillon du Temple de l'Eau", "Medalla del Agua" }, }; trickNameTable[RG_SPIRIT_MEDALLION] = { - Text{"Earth Element", "Elément Terre", "Elemento de tierra"}, - Text{"Nabooru's Medallion", "Médaillon de Nabooru", "Medallón de Nabooru"}, - Text{"Sign of Earth", "Glyphe de la Terre", "Glifo de la tierra"}, - Text{"Medallion of Spirit", "Médaillon du Temple de l'Esprit", "Medalla del Espíritu"}, + Text{ "Earth Element", "Elément Terre", "Elemento de tierra" }, + Text{ "Nabooru's Medallion", "Médaillon de Nabooru", "Medallón de Nabooru" }, + Text{ "Sign of Earth", "Glyphe de la Terre", "Glifo de la tierra" }, + Text{ "Medallion of Spirit", "Médaillon du Temple de l'Esprit", "Medalla del Espíritu" }, }; trickNameTable[RG_SHADOW_MEDALLION] = { - Text{"Fused Shadow", "Cristal d'ombre", "Sombra Fundida"}, - Text{"Impa's Medallion", "Médaillon d'Impa", "Medallón de Impa"}, - Text{"Sign of Illusion", "Glyphe de l'illusion", "Glifo de ilusión"}, - Text{"Medallion of Shadow", "Médaillon du Temple de l'Ombre", "Medalla de la Sombra"}, + Text{ "Fused Shadow", "Cristal d'ombre", "Sombra Fundida" }, + Text{ "Impa's Medallion", "Médaillon d'Impa", "Medallón de Impa" }, + Text{ "Sign of Illusion", "Glyphe de l'illusion", "Glifo de ilusión" }, + Text{ "Medallion of Shadow", "Médaillon du Temple de l'Ombre", "Medalla de la Sombra" }, }; trickNameTable[RG_LIGHT_MEDALLION] = { - Text{"Compass of Light", "Boussole de lumière", "Brújula de Luz"}, - Text{"Rauru's Medallion", "Médaillon de Rauru", "Medallón de Rauru"}, - Text{"Sign of Destiny", "Glyphe du destin", "Glifo del destino"}, - Text{"Medallion of Light", "Médaillon du temple de lumière", "Medalla de la Luz"}, + Text{ "Compass of Light", "Boussole de lumière", "Brújula de Luz" }, + Text{ "Rauru's Medallion", "Médaillon de Rauru", "Medallón de Rauru" }, + Text{ "Sign of Destiny", "Glyphe du destin", "Glifo del destino" }, + Text{ "Medallion of Light", "Médaillon du temple de lumière", "Medalla de la Luz" }, }; trickNameTable[RG_RECOVERY_HEART] = { - Text{"Love", "Bisou", "Te amo"}, - Text{"Life", "Vie", "vida"}, - Text{"HP", "VP", "VP"}, + Text{ "Love", "Bisou", "Te amo" }, + Text{ "Life", "Vie", "vida" }, + Text{ "HP", "VP", "VP" }, }; trickNameTable[RG_GREEN_RUPEE] = { - Text{"False Greg", "Faux Greg", "Falso Greg"}, - Text{"One Ruby", "Un rubis", "Un rubí"}, - Text{"Rupoor (1)", "Roupir (1)", "Rupobre (1)"}, - Text{"One Rupee", "Un rubis", "Guaraní hyliano"}, - Text{"Rupee (1)", "Rubis (1)", "Peso hyliano"}, + Text{ "False Greg", "Faux Greg", "Falso Greg" }, Text{ "One Ruby", "Un rubis", "Un rubí" }, + Text{ "Rupoor (1)", "Roupir (1)", "Rupobre (1)" }, Text{ "One Rupee", "Un rubis", "Guaraní hyliano" }, + Text{ "Rupee (1)", "Rubis (1)", "Peso hyliano" }, }; trickNameTable[RG_BLUE_RUPEE] = { - Text{"Blupee", "Bleubi", "Azupia"}, - Text{"Five Rubies", "Cinq Rubys", "Cinco rubíes"}, - Text{"Five Rupees", "Cinq rubis", "Bolívar hyliano"}, - Text{"Rupee (5)", "Rubis (5)", "Peso hyliano"}, - Text{"Rupoor (5)", "Roupir (5)", "Rupobre (5)"}, + Text{ "Blupee", "Bleubi", "Azupia" }, + Text{ "Five Rubies", "Cinq Rubys", "Cinco rubíes" }, + Text{ "Five Rupees", "Cinq rubis", "Bolívar hyliano" }, + Text{ "Rupee (5)", "Rubis (5)", "Peso hyliano" }, + Text{ "Rupoor (5)", "Roupir (5)", "Rupobre (5)" }, }; trickNameTable[RG_RED_RUPEE] = { - Text{"Big 20", "Grand 20", "Los 20 grandes"}, - Text{"Twenty Rubies", "vingt rubis", "Veinte rubíes"}, - Text{"Rupoor (20)", "Roupir (20)", "Rupobre (20)"}, - Text{"Twenty Rupees", "Vingt rubis", "Colon hyliano"}, - Text{"Rupee (20)", "Rubis (20)", "Peso hyliano"}, + Text{ "Big 20", "Grand 20", "Los 20 grandes" }, Text{ "Twenty Rubies", "vingt rubis", "Veinte rubíes" }, + Text{ "Rupoor (20)", "Roupir (20)", "Rupobre (20)" }, Text{ "Twenty Rupees", "Vingt rubis", "Colon hyliano" }, + Text{ "Rupee (20)", "Rubis (20)", "Peso hyliano" }, }; trickNameTable[RG_PURPLE_RUPEE] = { - Text{"Purpee", "pourbi", "morupiua"}, - Text{"Fifty Rubies", "cinquante rubis", "Cincuenta rubíes"}, - Text{"Rupoor (50)", "Roupir (50)", "Rupobre (50)"}, - Text{"Fifty Rupees", "Cinquante rubis", "Balboa hyliano"}, - Text{"Rupee (50)", "Rubis (50)", "Peso hyliano"}, + Text{ "Purpee", "pourbi", "morupiua" }, + Text{ "Fifty Rubies", "cinquante rubis", "Cincuenta rubíes" }, + Text{ "Rupoor (50)", "Roupir (50)", "Rupobre (50)" }, + Text{ "Fifty Rupees", "Cinquante rubis", "Balboa hyliano" }, + Text{ "Rupee (50)", "Rubis (50)", "Peso hyliano" }, }; trickNameTable[RG_HUGE_RUPEE] = { - Text{"Hugo", "Or Rubi", "Oro Rubi"}, - Text{"Two Hundred Rubies", "deux cents rubis", "Doscientos rubíes"}, - Text{"Diamond", "Diamant", "Diamante"}, - Text{"Huge Ruby", "Énorme rubis", "Rubi gigante"}, - Text{"Two Hundred Rupees", "Deux cent rubis", "Euro hyliano"}, - Text{"Rupee (200)", "Rubis (200)", "Dólar hyliano"}, + Text{ "Hugo", "Or Rubi", "Oro Rubi" }, + Text{ "Two Hundred Rubies", "deux cents rubis", "Doscientos rubíes" }, + Text{ "Diamond", "Diamant", "Diamante" }, + Text{ "Huge Ruby", "Énorme rubis", "Rubi gigante" }, + Text{ "Two Hundred Rupees", "Deux cent rubis", "Euro hyliano" }, + Text{ "Rupee (200)", "Rubis (200)", "Dólar hyliano" }, }; trickNameTable[RG_PIECE_OF_HEART] = { - Text{"Pizza Heart", "Fromage de cœur", "Pieza de Chorizo"}, - Text{"Little Bit Of Love", "Un peu d'amour", "Un poco de amor"}, - Text{"Rare Peach Stone", "Pierre de pêche rare", "Pierre de pêche rare"}, + Text{ "Pizza Heart", "Fromage de cœur", "Pieza de Chorizo" }, + Text{ "Little Bit Of Love", "Un peu d'amour", "Un poco de amor" }, + Text{ "Rare Peach Stone", "Pierre de pêche rare", "Pierre de pêche rare" }, }; trickNameTable[RG_HEART_CONTAINER] = { - Text{"Crystal Heart", "Cœur de cristal", "Corazón de cristal"}, - Text{"Life Heart", "Cœur de vie", "Vida Corazón"}, - Text{"Lots of Love", "Beaucoup d'amour", "Mucho amor"}, + Text{ "Crystal Heart", "Cœur de cristal", "Corazón de cristal" }, + Text{ "Life Heart", "Cœur de vie", "Vida Corazón" }, + Text{ "Lots of Love", "Beaucoup d'amour", "Mucho amor" }, }; trickNameTable[RG_TRIFORCE_PIECE] = { - Text{"Piece of Cheese", "Morceau de Fromage", "Piece of Cheese"}, - Text{"Triforce Shard", "Éclat de Triforce", "Triforce Shard"}, - Text{"Shiny Rock", "Caiiloux Brillant", "Shiny Rock"}, + Text{ "Piece of Cheese", "Morceau de Fromage", "Piece of Cheese" }, + Text{ "Triforce Shard", "Éclat de Triforce", "Triforce Shard" }, + Text{ "Shiny Rock", "Caiiloux Brillant", "Shiny Rock" }, }; trickNameTable[RG_GOHMA_SOUL] = { - Text{"Spider Sense", "", ""}, - Text{"Deku Spirit", "", ""}, - Text{"Ghost of Ghoma", "", ""}, + Text{ "Spider Sense", "", "" }, + Text{ "Deku Spirit", "", "" }, + Text{ "Ghost of Ghoma", "", "" }, }; trickNameTable[RG_KING_DODONGO_SOUL] = { - Text{"Lizard Soul", "", ""}, - Text{"Regal Remains", "", ""}, - Text{"Dodongo's Core", "", ""}, + Text{ "Lizard Soul", "", "" }, + Text{ "Regal Remains", "", "" }, + Text{ "Dodongo's Core", "", "" }, }; trickNameTable[RG_BARINADE_SOUL] = { - Text{"Parasitic Poltergeist", "", ""}, - Text{"Jabu Insides", "", ""}, - Text{"Barinade Bacteria", "", ""}, + Text{ "Parasitic Poltergeist", "", "" }, + Text{ "Jabu Insides", "", "" }, + Text{ "Barinade Bacteria", "", "" }, }; trickNameTable[RG_PHANTOM_GANON_SOUL] = { - Text{"Bigger Poe", "", ""}, - Text{"Sacred Forest Pine Tree", "", ""}, - Text{"Ganon's Phantom", "", ""}, + Text{ "Bigger Poe", "", "" }, + Text{ "Sacred Forest Pine Tree", "", "" }, + Text{ "Ganon's Phantom", "", "" }, }; trickNameTable[RG_VOLVAGIA_SOUL] = { - Text{"Dragon Roast", "", ""}, - Text{"Hot n' Ready", "", ""}, - Text{"Volvagia's Vitality", "", ""}, + Text{ "Dragon Roast", "", "" }, + Text{ "Hot n' Ready", "", "" }, + Text{ "Volvagia's Vitality", "", "" }, }; trickNameTable[RG_MORPHA_SOUL] = { - Text{"Dihydrogen Monoxide", "", ""}, - Text{"Morpha Molecules", "", ""}, - Text{"Wet Stuff", "", ""}, + Text{ "Dihydrogen Monoxide", "", "" }, + Text{ "Morpha Molecules", "", "" }, + Text{ "Wet Stuff", "", "" }, }; trickNameTable[RG_BONGO_BONGO_SOUL] = { - Text{"Shadow Soul", "", ""}, - Text{"Dark Essence", "", ""}, - Text{"Bongo Bongo's Bongo", "", ""}, + Text{ "Shadow Soul", "", "" }, + Text{ "Dark Essence", "", "" }, + Text{ "Bongo Bongo's Bongo", "", "" }, }; trickNameTable[RG_TWINROVA_SOUL] = { - Text{"Sandy Ashes", "", ""}, - Text{"Spiritual Spirit", "", ""}, - Text{"Twin Rovers", "", ""}, + Text{ "Sandy Ashes", "", "" }, + Text{ "Spiritual Spirit", "", "" }, + Text{ "Twin Rovers", "", "" }, }; trickNameTable[RG_GANON_SOUL] = { - Text{"Pure Evil", "", ""}, - Text{"Ganon's Ghost", "", ""}, - Text{"Pork", "", ""}, + Text{ "Pure Evil", "", "" }, + Text{ "Ganon's Ghost", "", "" }, + Text{ "Pork", "", "" }, }; trickNameTable[RG_FISHING_POLE] = { - Text{"Fish Tickler", "Fish Tickler", "Fish Tickler"}, - Text{"Floating Lure", "Floating Lure", "Floating Lure"}, - Text{"Fishing Reel", "Fishing Reel", "Fishing Reel"}, + Text{ "Fish Tickler", "Fish Tickler", "Fish Tickler" }, + Text{ "Floating Lure", "Floating Lure", "Floating Lure" }, + Text{ "Fishing Reel", "Fishing Reel", "Fishing Reel" }, }; trickNameTable[RG_OCARINA_A_BUTTON] = { - Text{"Ocarina J Button", "", ""}, - Text{"Ocarina Ayy Button", "", ""}, - Text{"Ocarina A Trigger", "", ""}, + Text{ "Ocarina J Button", "", "" }, + Text{ "Ocarina Ayy Button", "", "" }, + Text{ "Ocarina A Trigger", "", "" }, }; trickNameTable[RG_OCARINA_C_UP_BUTTON] = { - Text{"Ocarina C North Button", "", ""}, - Text{"Ocarina C App Button", "", ""}, - Text{"Ocarina Sup Button", "", ""}, + Text{ "Ocarina C North Button", "", "" }, + Text{ "Ocarina C App Button", "", "" }, + Text{ "Ocarina Sup Button", "", "" }, }; trickNameTable[RG_OCARINA_C_DOWN_BUTTON] = { - Text{"Ocarina C South Button", "", ""}, - Text{"Ocarina Z Down Button", "", ""}, - Text{"Ocarina See Down Button", "", ""}, - Text{"Ocarina C Dawn Button", "", ""}, + Text{ "Ocarina C South Button", "", "" }, + Text{ "Ocarina Z Down Button", "", "" }, + Text{ "Ocarina See Down Button", "", "" }, + Text{ "Ocarina C Dawn Button", "", "" }, }; trickNameTable[RG_OCARINA_C_LEFT_BUTTON] = { - Text{"Ocarina C West Button", "", ""}, - Text{"Ocarina Sea Left Button", "", ""}, - Text{"Ocarina C Lift Button", "", ""}, - Text{"Ocarina Rewind Button", "", ""}, + Text{ "Ocarina C West Button", "", "" }, + Text{ "Ocarina Sea Left Button", "", "" }, + Text{ "Ocarina C Lift Button", "", "" }, + Text{ "Ocarina Rewind Button", "", "" }, }; trickNameTable[RG_OCARINA_C_RIGHT_BUTTON] = { - Text{"Ocarina C East Button", "", ""}, - Text{"Ocarina C Wright Button", "", ""}, - Text{"Overworld C Right Button", "", ""}, + Text{ "Ocarina C East Button", "", "" }, + Text{ "Ocarina C Wright Button", "", "" }, + Text{ "Overworld C Right Button", "", "" }, }; /* @@ -1127,13 +1074,13 @@ void InitTrickNames() { */ } -//Generate a fake name for the ice trap based on the item it's displayed as +// Generate a fake name for the ice trap based on the item it's displayed as Text GetIceTrapName(uint8_t id) { - //If the trick names table has not been initialized, do so + // If the trick names table has not been initialized, do so if (!initTrickNames) { InitTrickNames(); initTrickNames = true; } - //Randomly get the easy, medium, or hard name for the given item id + // Randomly get the easy, medium, or hard name for the given item id return RandomElement(trickNameTable[id]); } \ No newline at end of file diff --git a/soh/soh/Enhancements/randomizer/3drando/spoiler_log.cpp b/soh/soh/Enhancements/randomizer/3drando/spoiler_log.cpp index da4c3eb43..7938d8665 100644 --- a/soh/soh/Enhancements/randomizer/3drando/spoiler_log.cpp +++ b/soh/soh/Enhancements/randomizer/3drando/spoiler_log.cpp @@ -66,16 +66,15 @@ static auto GetSpoilerLogPath() { } static auto GetPlacementLogPath() { - return GetGeneralPath(); + return GetGeneralPath(); } // Writes the location to the specified node. -static void WriteLocation( - std::string sphere, const RandomizerCheck locationKey, const bool withPadding = false) { - Rando::Location* location = Rando::StaticData::GetLocation(locationKey); - Rando::ItemLocation* itemLocation = Rando::Context::GetInstance()->GetItemLocation(locationKey); +static void WriteLocation(std::string sphere, const RandomizerCheck locationKey, const bool withPadding = false) { + Rando::Location* location = Rando::StaticData::GetLocation(locationKey); + Rando::ItemLocation* itemLocation = Rando::Context::GetInstance()->GetItemLocation(locationKey); - switch (gSaveContext.language) { + switch (gSaveContext.language) { case LANGUAGE_ENG: default: jsonData["playthrough"][sphere][location->GetName()] = itemLocation->GetPlacedItemName().GetEnglish(); @@ -86,48 +85,48 @@ static void WriteLocation( } } -//Writes a shuffled entrance to the specified node +// Writes a shuffled entrance to the specified node static void WriteShuffledEntrance(std::string sphereString, Entrance* entrance) { - int16_t originalIndex = entrance->GetIndex(); - int16_t destinationIndex = -1; - int16_t replacementIndex = entrance->GetReplacement()->GetIndex(); - int16_t replacementDestinationIndex = -1; - std::string name = GetEntranceData(originalIndex)->source; - std::string text = GetEntranceData(replacementIndex)->destination; + int16_t originalIndex = entrance->GetIndex(); + int16_t destinationIndex = -1; + int16_t replacementIndex = entrance->GetReplacement()->GetIndex(); + int16_t replacementDestinationIndex = -1; + std::string name = GetEntranceData(originalIndex)->source; + std::string text = GetEntranceData(replacementIndex)->destination; - // Track the reverse destination, useful for savewarp handling - if (entrance->GetReverse() != nullptr) { - destinationIndex = entrance->GetReverse()->GetIndex(); - // When decouple is off we track the replacement's reverse destination, useful for recording visited entrances - if (!entrance->IsDecoupled()) { - replacementDestinationIndex = entrance->GetReplacement()->GetReverse()->GetIndex(); + // Track the reverse destination, useful for savewarp handling + if (entrance->GetReverse() != nullptr) { + destinationIndex = entrance->GetReverse()->GetIndex(); + // When decouple is off we track the replacement's reverse destination, useful for recording visited entrances + if (!entrance->IsDecoupled()) { + replacementDestinationIndex = entrance->GetReplacement()->GetReverse()->GetIndex(); + } } - } - json entranceJson = json::object({ - {"type", entrance->GetType()}, - {"index", originalIndex}, - {"destination", destinationIndex}, - {"override", replacementIndex}, - {"overrideDestination", replacementDestinationIndex}, - }); - - jsonData["entrances"].push_back(entranceJson); - - // When decoupled entrances is off, handle saving reverse entrances - if (entrance->GetReverse() != nullptr && !entrance->IsDecoupled()) { - json reverseEntranceJson = json::object({ - {"type", entrance->GetReverse()->GetType()}, - {"index", replacementDestinationIndex}, - {"destination", replacementIndex}, - {"override", destinationIndex}, - {"overrideDestination", originalIndex}, + json entranceJson = json::object({ + { "type", entrance->GetType() }, + { "index", originalIndex }, + { "destination", destinationIndex }, + { "override", replacementIndex }, + { "overrideDestination", replacementDestinationIndex }, }); - jsonData["entrances"].push_back(reverseEntranceJson); - } + jsonData["entrances"].push_back(entranceJson); - switch (gSaveContext.language) { + // When decoupled entrances is off, handle saving reverse entrances + if (entrance->GetReverse() != nullptr && !entrance->IsDecoupled()) { + json reverseEntranceJson = json::object({ + { "type", entrance->GetReverse()->GetType() }, + { "index", replacementDestinationIndex }, + { "destination", replacementIndex }, + { "override", destinationIndex }, + { "overrideDestination", originalIndex }, + }); + + jsonData["entrances"].push_back(reverseEntranceJson); + } + + switch (gSaveContext.language) { case LANGUAGE_ENG: case LANGUAGE_FRA: default: @@ -141,32 +140,31 @@ static void WriteSettings() { auto ctx = Rando::Context::GetInstance(); std::array options = Rando::Settings::GetInstance()->GetAllOptions(); for (const Rando::Option& option : options) { - if (option.GetName() != ""){ - jsonData["settings"][option.GetName()] = option.GetOptionText(ctx->GetOption(option.GetKey()).Get()); - } + if (option.GetName() != "") { + jsonData["settings"][option.GetName()] = option.GetOptionText(ctx->GetOption(option.GetKey()).Get()); + } } } // Removes any line breaks from s. std::string RemoveLineBreaks(std::string s) { - s.erase(std::remove(s.begin(), s.end(), '\n'), s.end()); - return s; + s.erase(std::remove(s.begin(), s.end(), '\n'), s.end()); + return s; } // Writes the excluded locations to the spoiler log, if there are any. static void WriteExcludedLocations() { - auto ctx = Rando::Context::GetInstance(); + auto ctx = Rando::Context::GetInstance(); - for (size_t i = 1; i < Rando::Settings::GetInstance()->GetExcludeLocationsOptions().size(); i++) { - for (const auto& location : Rando::Settings::GetInstance()->GetExcludeLocationsOptions()[i]) { - if (ctx->GetLocationOption(static_cast(location->GetKey())).Get() == RO_LOCATION_INCLUDE) { - continue; - } - - jsonData["excludedLocations"].push_back(RemoveLineBreaks(location->GetName())); + for (size_t i = 1; i < Rando::Settings::GetInstance()->GetExcludeLocationsOptions().size(); i++) { + for (const auto& location : Rando::Settings::GetInstance()->GetExcludeLocationsOptions()[i]) { + if (ctx->GetLocationOption(static_cast(location->GetKey())).Get() == RO_LOCATION_INCLUDE) { + continue; + } + jsonData["excludedLocations"].push_back(RemoveLineBreaks(location->GetName())); + } } - } } // Writes the starting inventory to the spoiler log, if there is any. @@ -182,16 +180,16 @@ static void WriteStartingInventory() { } } -//Writes the enabled tricks to the spoiler log, if there are any. +// Writes the enabled tricks to the spoiler log, if there are any. static void WriteEnabledTricks() { - auto ctx = Rando::Context::GetInstance(); + auto ctx = Rando::Context::GetInstance(); - for (const auto& setting : Rando::Settings::GetInstance()->GetOptionGroup(RSG_TRICKS).GetOptions()) { - if (ctx->GetTrickOption(static_cast(setting->GetKey())).IsNot(RO_GENERIC_ON)) { - continue; + for (const auto& setting : Rando::Settings::GetInstance()->GetOptionGroup(RSG_TRICKS).GetOptions()) { + if (ctx->GetTrickOption(static_cast(setting->GetKey())).IsNot(RO_GENERIC_ON)) { + continue; + } + jsonData["enabledTricks"].push_back(RemoveLineBreaks(setting->GetName()).c_str()); } - jsonData["enabledTricks"].push_back(RemoveLineBreaks(setting->GetName()).c_str()); - } } // Writes the Master Quest dungeons to the spoiler log, if there are any. @@ -208,47 +206,49 @@ static void WriteMasterQuestDungeons() { // Writes the required trials to the spoiler log, if there are any. static void WriteChosenOptions() { - auto ctx = Rando::Context::GetInstance(); - for (const auto& trial : ctx->GetTrials()->GetTrialList()) { - if (trial->IsRequired()) { - std::string trialName = trial->GetName().GetForCurrentLanguage(MF_CLEAN); - jsonData["requiredTrials"].push_back(RemoveLineBreaks(trialName)); + auto ctx = Rando::Context::GetInstance(); + for (const auto& trial : ctx->GetTrials()->GetTrialList()) { + if (trial->IsRequired()) { + std::string trialName = trial->GetName().GetForCurrentLanguage(MF_CLEAN); + jsonData["requiredTrials"].push_back(RemoveLineBreaks(trialName)); + } + } + if (ctx->GetOption(RSK_SELECTED_STARTING_AGE).Is(RO_AGE_ADULT)) { + jsonData["SelectedStartingAge"] = "Adult"; + } else { + jsonData["SelectedStartingAge"] = "Child"; } - } - if (ctx->GetOption(RSK_SELECTED_STARTING_AGE).Is(RO_AGE_ADULT)){ - jsonData["SelectedStartingAge"] = "Adult"; - } else { - jsonData["SelectedStartingAge"] = "Child"; - } } // Writes the intended playthrough to the spoiler log, separated into spheres. static void WritePlaythrough() { - auto ctx = Rando::Context::GetInstance(); + auto ctx = Rando::Context::GetInstance(); - for (uint32_t i = 0; i < ctx->playthroughLocations.size(); ++i) { - auto sphereNum = std::to_string(i); - std::string sphereString = "sphere "; - if (i < 10) sphereString += "0"; - sphereString += sphereNum; - for (const RandomizerCheck key : ctx->playthroughLocations[i]) { - WriteLocation(sphereString, key, true); + for (uint32_t i = 0; i < ctx->playthroughLocations.size(); ++i) { + auto sphereNum = std::to_string(i); + std::string sphereString = "sphere "; + if (i < 10) + sphereString += "0"; + sphereString += sphereNum; + for (const RandomizerCheck key : ctx->playthroughLocations[i]) { + WriteLocation(sphereString, key, true); + } } - } } -//Write the randomized entrance playthrough to the spoiler log, if applicable +// Write the randomized entrance playthrough to the spoiler log, if applicable static void WriteShuffledEntrances() { - auto ctx = Rando::Context::GetInstance(); - for (uint32_t i = 0; i < ctx->GetEntranceShuffler()->playthroughEntrances.size(); ++i) { - auto sphereNum = std::to_string(i); - std::string sphereString = "sphere "; - if (i < 10) sphereString += "0"; - sphereString += sphereNum; - for (Entrance* entrance : ctx->GetEntranceShuffler()->playthroughEntrances[i]) { - WriteShuffledEntrance(sphereString, entrance); + auto ctx = Rando::Context::GetInstance(); + for (uint32_t i = 0; i < ctx->GetEntranceShuffler()->playthroughEntrances.size(); ++i) { + auto sphereNum = std::to_string(i); + std::string sphereString = "sphere "; + if (i < 10) + sphereString += "0"; + sphereString += sphereNum; + for (Entrance* entrance : ctx->GetEntranceShuffler()->playthroughEntrances[i]) { + WriteShuffledEntrance(sphereString, entrance); + } } - } } Rando::ItemLocation* GetItemLocation(RandomizerGet item) { @@ -265,52 +265,59 @@ static void WriteAllLocations() { std::string placedItemName; switch (gSaveContext.language) { - case 0: - default: - placedItemName = location->GetPlacedItemName().english; - break; - case 2: - placedItemName = location->GetPlacedItemName().french; - break; + case 0: + default: + placedItemName = location->GetPlacedItemName().english; + break; + case 2: + placedItemName = location->GetPlacedItemName().french; + break; } // If it's a simple item (not an ice trap, doesn't have a price) // just add the name of the item and move on - if (!location->HasCustomPrice() && - location->GetPlacedRandomizerGet() != RG_ICE_TRAP) { - - jsonData["locations"][Rando::StaticData::GetLocation(location->GetRandomizerCheck())->GetName()] = placedItemName; + if (!location->HasCustomPrice() && location->GetPlacedRandomizerGet() != RG_ICE_TRAP) { + + jsonData["locations"][Rando::StaticData::GetLocation(location->GetRandomizerCheck())->GetName()] = + placedItemName; continue; } // We're dealing with a complex item, build out the json object for it - jsonData["locations"][Rando::StaticData::GetLocation(location->GetRandomizerCheck())->GetName()]["item"] = placedItemName; + jsonData["locations"][Rando::StaticData::GetLocation(location->GetRandomizerCheck())->GetName()]["item"] = + placedItemName; if (location->HasCustomPrice()) { jsonData["locations"][Rando::StaticData::GetLocation(location->GetRandomizerCheck())->GetName()]["price"] = location->GetPrice(); } if (location->IsAHintAccessible()) { - hintedLocations.emplace(Rando::StaticData::GetLocation(key)->GetHintKey(), location); + hintedLocations.emplace(Rando::StaticData::GetLocation(key)->GetHintKey(), location); } if (location->GetPlacedRandomizerGet() == RG_ICE_TRAP) { - switch (gSaveContext.language) { - case 0: - default: - jsonData["locations"][Rando::StaticData::GetLocation(location->GetRandomizerCheck())->GetName()]["model"] = - Rando::StaticData::RetrieveItem(ctx->overrides[location->GetRandomizerCheck()].LooksLike()).GetName().english; - jsonData["locations"][Rando::StaticData::GetLocation(location->GetRandomizerCheck())->GetName()]["trickName"] = - ctx->overrides[location->GetRandomizerCheck()].GetTrickName().english; - break; - case 2: - jsonData["locations"][Rando::StaticData::GetLocation(location->GetRandomizerCheck())->GetName()]["model"] = - Rando::StaticData::RetrieveItem(ctx->overrides[location->GetRandomizerCheck()].LooksLike()).GetName().french; - jsonData["locations"][Rando::StaticData::GetLocation(location->GetRandomizerCheck())->GetName()]["trickName"] = - ctx->overrides[location->GetRandomizerCheck()].GetTrickName().french; - break; - } - } + switch (gSaveContext.language) { + case 0: + default: + jsonData["locations"][Rando::StaticData::GetLocation(location->GetRandomizerCheck())->GetName()] + ["model"] = Rando::StaticData::RetrieveItem( + ctx->overrides[location->GetRandomizerCheck()].LooksLike()) + .GetName() + .english; + jsonData["locations"][Rando::StaticData::GetLocation(location->GetRandomizerCheck())->GetName()] + ["trickName"] = ctx->overrides[location->GetRandomizerCheck()].GetTrickName().english; + break; + case 2: + jsonData["locations"][Rando::StaticData::GetLocation(location->GetRandomizerCheck())->GetName()] + ["model"] = Rando::StaticData::RetrieveItem( + ctx->overrides[location->GetRandomizerCheck()].LooksLike()) + .GetName() + .french; + jsonData["locations"][Rando::StaticData::GetLocation(location->GetRandomizerCheck())->GetName()] + ["trickName"] = ctx->overrides[location->GetRandomizerCheck()].GetTrickName().french; + break; + } + } } } @@ -319,9 +326,9 @@ const char* SpoilerLog_Write() { jsonData.clear(); - jsonData["version"] = (char*) gBuildVersion; - jsonData["git_branch"] = (char*) gGitBranch; - jsonData["git_commit"] = (char*) gGitCommitHash; + jsonData["version"] = (char*)gBuildVersion; + jsonData["git_branch"] = (char*)gGitBranch; + jsonData["git_commit"] = (char*)gGitCommitHash; jsonData["seed"] = ctx->GetSeedString(); jsonData["finalSeed"] = ctx->GetSeed(); @@ -335,7 +342,7 @@ const char* SpoilerLog_Write() { WriteSettings(); WriteExcludedLocations(); WriteStartingInventory(); - WriteEnabledTricks(); + WriteEnabledTricks(); WriteMasterQuestDungeons(); WriteChosenOptions(); WritePlaythrough(); @@ -353,7 +360,7 @@ const char* SpoilerLog_Write() { std::string jsonString = jsonData.dump(4); std::ostringstream fileNameStream; - for (uint8_t i = 0; i < ctx->hashIconIndexes.size(); i ++) { + for (uint8_t i = 0; i < ctx->hashIconIndexes.size(); i++) { if (i) { fileNameStream << '-'; } @@ -384,4 +391,3 @@ void PlacementLog_Msg(std::string_view msg) { void PlacementLog_Clear() { placementtxt = ""; } - diff --git a/soh/soh/Enhancements/randomizer/3drando/starting_inventory.cpp b/soh/soh/Enhancements/randomizer/3drando/starting_inventory.cpp index 04a7e3040..dda37b18a 100644 --- a/soh/soh/Enhancements/randomizer/3drando/starting_inventory.cpp +++ b/soh/soh/Enhancements/randomizer/3drando/starting_inventory.cpp @@ -10,188 +10,188 @@ std::vector StartingInventory; uint8_t AdditionalHeartContainers; static void AddItemToInventory(RandomizerGet item, size_t count = 1) { - StartingInventory.insert(StartingInventory.end(), count, item); + StartingInventory.insert(StartingInventory.end(), count, item); } void GenerateStartingInventory() { - auto ctx = Rando::Context::GetInstance(); - StartingInventory.clear(); + auto ctx = Rando::Context::GetInstance(); + StartingInventory.clear(); - if (ctx->GetOption(RSK_SHUFFLE_MAPANDCOMPASS).Is(RO_DUNGEON_ITEM_LOC_STARTWITH)) { - for (auto* dungeon : ctx->GetDungeons()->GetDungeonList()) { - if (dungeon->GetMap() != RG_NONE) { - AddItemToInventory(dungeon->GetMap()); - } + if (ctx->GetOption(RSK_SHUFFLE_MAPANDCOMPASS).Is(RO_DUNGEON_ITEM_LOC_STARTWITH)) { + for (auto* dungeon : ctx->GetDungeons()->GetDungeonList()) { + if (dungeon->GetMap() != RG_NONE) { + AddItemToInventory(dungeon->GetMap()); + } - if (dungeon->GetCompass() != RG_NONE) { - AddItemToInventory(dungeon->GetCompass()); - } - } - } - - if (ctx->GetOption(RSK_KEYSANITY).Is(RO_DUNGEON_ITEM_LOC_STARTWITH)) { - for (auto* dungeon : ctx->GetDungeons()->GetDungeonList()) { - if (dungeon->GetSmallKeyCount() > 0) { - AddItemToInventory(dungeon->GetSmallKey(), dungeon->GetSmallKeyCount()); - } - } - } else if (ctx->GetOption(RSK_KEYSANITY).Is(RO_DUNGEON_ITEM_LOC_VANILLA)) { - // Logic cannot handle vanilla key layout in some dungeons - // this is because vanilla expects the dungeon major item to be - // locked behind the keys, which is not always true in rando. - // We can resolve this by starting with some extra keys - // - OoT Randomizer - if (ctx->GetDungeon(Rando::SPIRIT_TEMPLE)->IsMQ()) { - AddItemToInventory(RG_SPIRIT_TEMPLE_SMALL_KEY, 3); - } - } - - if (ctx->GetOption(RSK_BOSS_KEYSANITY).Is(RO_DUNGEON_ITEM_LOC_STARTWITH)) { - AddItemToInventory(RG_FOREST_TEMPLE_BOSS_KEY); - AddItemToInventory(RG_FIRE_TEMPLE_BOSS_KEY); - AddItemToInventory(RG_WATER_TEMPLE_BOSS_KEY); - AddItemToInventory(RG_SPIRIT_TEMPLE_BOSS_KEY); - AddItemToInventory(RG_SHADOW_TEMPLE_BOSS_KEY); - } - - // Add Ganon's Boss key with Triforce Hunt so the game thinks it's obtainable from the start. - // During save init, the boss key isn't actually given and it's instead given when completing the triforce. - if (ctx->GetOption(RSK_GANONS_BOSS_KEY).Is(RO_GANON_BOSS_KEY_STARTWITH) || - ctx->GetOption(RSK_TRIFORCE_HUNT)) { - AddItemToInventory(RG_GANONS_CASTLE_BOSS_KEY); - } - - if (ctx->GetOption(RSK_GERUDO_FORTRESS).Is(RO_GF_CARPENTERS_FREE) && !ctx->GetOption(RSK_SHUFFLE_GERUDO_MEMBERSHIP_CARD)) { - AddItemToInventory(RG_GERUDO_MEMBERSHIP_CARD); - } - - //Starting Inventory Menu - //Values are associated so that the count of items matches the index of - //the option selected. If None is selected, the value will be zero and - //zero of the item will be added to the starting inventory. - // TODO: Uncomment when these options are implemented. - // AddItemToInventory(RG_PROGRESSIVE_STICK_UPGRADE, StartingStickCapacity.Value()); - // AddItemToInventory(RG_PROGRESSIVE_NUT_UPGRADE, StartingNutCapacity.Value()); - // AddItemToInventory(RG_PROGRESSIVE_BOMB_BAG, StartingBombBag.Value()); - // AddItemToInventory((BombchuBag ? RG_PROGRESSIVE_BOMBCHUS : RG_BOMBCHU_20), StartingBombchus.Value()); - // AddItemToInventory(RG_PROGRESSIVE_BOW, StartingBow.Value()); - // AddItemToInventory(RG_FIRE_ARROWS, StartingFireArrows.Value()); - // AddItemToInventory(RG_ICE_ARROWS, StartingIceArrows.Value()); - // AddItemToInventory(RG_LIGHT_ARROWS, StartingLightArrows.Value()); - // AddItemToInventory(RG_DINS_FIRE, StartingDinsFire.Value()); - // AddItemToInventory(RG_FARORES_WIND, StartingFaroresWind.Value()); - // AddItemToInventory(RG_NAYRUS_LOVE, StartingNayrusLove.Value()); - // AddItemToInventory(RG_PROGRESSIVE_SLINGSHOT, StartingSlingshot.Value()); - // AddItemToInventory(RG_BOOMERANG, StartingBoomerang.Value()); - // AddItemToInventory(RG_LENS_OF_TRUTH, StartingLensOfTruth.Value()); - // AddItemToInventory(RG_MAGIC_BEAN_PACK, StartingMagicBean.Value()); - // AddItemToInventory(RG_MEGATON_HAMMER, StartingMegatonHammer.Value()); - // AddItemToInventory(RG_PROGRESSIVE_HOOKSHOT, StartingHookshot.Value()); - // AddItemToInventory(RG_IRON_BOOTS, StartingIronBoots.Value()); - // AddItemToInventory(RG_HOVER_BOOTS, StartingHoverBoots.Value()); - //For starting bottles, we need to check if they are a big poe and add that if so - // since a big poe bottle is not logically equivalent to an empty bottle. - // if (StartingBottle1.Value() == STARTINGBOTTLE_BIG_POE) { - // AddItemToInventory(RG_BOTTLE_WITH_BIG_POE, 1); - // } else if (StartingBottle1.Value()) { - // AddItemToInventory(RG_EMPTY_BOTTLE, 1); - // } - // if (StartingBottle2.Value() == STARTINGBOTTLE_BIG_POE) { - // AddItemToInventory(RG_BOTTLE_WITH_BIG_POE, 1); - // } else if (StartingBottle2.Value()) { - // AddItemToInventory(RG_EMPTY_BOTTLE, 1); - // } - // if (StartingBottle3.Value() == STARTINGBOTTLE_BIG_POE) { - // AddItemToInventory(RG_BOTTLE_WITH_BIG_POE, 1); - // } else if (StartingBottle3.Value()) { - // AddItemToInventory(RG_EMPTY_BOTTLE, 1); - // } - // if (StartingBottle4.Value() == STARTINGBOTTLE_BIG_POE) { - // AddItemToInventory(RG_BOTTLE_WITH_BIG_POE, 1); - // } else if (StartingBottle4.Value()) { - // AddItemToInventory(RG_EMPTY_BOTTLE, 1); - // } - // AddItemToInventory(RG_RUTOS_LETTER, StartingRutoBottle.Value()); - AddItemToInventory(RG_PROGRESSIVE_OCARINA, ctx->GetOption(RSK_STARTING_OCARINA).Get()); - AddItemToInventory(RG_ZELDAS_LULLABY, ctx->GetOption(RSK_STARTING_ZELDAS_LULLABY) ? 1 : 0); - AddItemToInventory(RG_EPONAS_SONG, ctx->GetOption(RSK_STARTING_EPONAS_SONG) ? 1 : 0); - AddItemToInventory(RG_SARIAS_SONG, ctx->GetOption(RSK_STARTING_SARIAS_SONG) ? 1 : 0); - AddItemToInventory(RG_SUNS_SONG, ctx->GetOption(RSK_STARTING_SUNS_SONG) ? 1 : 0); - AddItemToInventory(RG_SONG_OF_TIME, ctx->GetOption(RSK_STARTING_SONG_OF_TIME) ? 1 : 0); - AddItemToInventory(RG_SONG_OF_STORMS, ctx->GetOption(RSK_STARTING_SONG_OF_STORMS) ? 1 : 0); - AddItemToInventory(RG_MINUET_OF_FOREST, ctx->GetOption(RSK_STARTING_MINUET_OF_FOREST) ? 1 : 0); - AddItemToInventory(RG_BOLERO_OF_FIRE, ctx->GetOption(RSK_STARTING_BOLERO_OF_FIRE) ? 1 : 0); - AddItemToInventory(RG_SERENADE_OF_WATER, ctx->GetOption(RSK_STARTING_SERENADE_OF_WATER) ? 1 : 0); - AddItemToInventory(RG_REQUIEM_OF_SPIRIT, ctx->GetOption(RSK_STARTING_REQUIEM_OF_SPIRIT) ? 1 : 0); - AddItemToInventory(RG_NOCTURNE_OF_SHADOW, ctx->GetOption(RSK_STARTING_NOCTURNE_OF_SHADOW) ? 1 : 0); - AddItemToInventory(RG_PRELUDE_OF_LIGHT, ctx->GetOption(RSK_STARTING_PRELUDE_OF_LIGHT) ? 1 : 0); - AddItemToInventory(RG_KOKIRI_SWORD, ctx->GetOption(RSK_STARTING_KOKIRI_SWORD) ? 1 : 0); - // if (ProgressiveGoronSword) { - // AddItemToInventory(RG_PROGRESSIVE_GORONSWORD, StartingBiggoronSword.Value()); - // } else { - // AddItemToInventory(RG_GIANTS_KNIFE, (StartingBiggoronSword.Is(STARTINGBGS_GIANTS_KNIFE)) ? 1 : 0); - // AddItemToInventory(RG_BIGGORON_SWORD, (StartingBiggoronSword.Is(STARTINGBGS_BIGGORON_SWORD)) ? 1 : 0); - // } - AddItemToInventory(RG_MASTER_SWORD, ctx->GetOption(RSK_STARTING_MASTER_SWORD) ? 1 : 0); - AddItemToInventory(RG_DEKU_SHIELD, ctx->GetOption(RSK_STARTING_DEKU_SHIELD) ? 1 : 0); - // AddItemToInventory(RG_HYLIAN_SHIELD, StartingHylianShield.Value()); - // AddItemToInventory(RG_MIRROR_SHIELD, StartingMirrorShield.Value()); - // AddItemToInventory(RG_GORON_TUNIC, StartingGoronTunic.Value()); - // AddItemToInventory(RG_ZORA_TUNIC, StartingZoraTunic.Value()); - // AddItemToInventory(RG_PROGRESSIVE_MAGIC_METER, StartingMagicMeter.Value()); - // AddItemToInventory(RG_PROGRESSIVE_STRENGTH, StartingStrength.Value()); - // AddItemToInventory(RG_PROGRESSIVE_SCALE, StartingScale.Value()); - // AddItemToInventory(RG_PROGRESSIVE_WALLET, StartingWallet.Value()); - // AddItemToInventory(RG_STONE_OF_AGONY, StartingShardOfAgony.Value()); - // AddItemToInventory(RG_DOUBLE_DEFENSE, StartingDoubleDefense.Value()); - // AddItemToInventory(RG_KOKIRI_EMERALD, StartingKokiriEmerald.Value()); - // AddItemToInventory(RG_GORON_RUBY, StartingGoronRuby.Value()); - // AddItemToInventory(RG_ZORA_SAPPHIRE, StartingZoraSapphire.Value()); - // AddItemToInventory(RG_FOREST_MEDALLION, StartingForestMedallion.Value()); - // AddItemToInventory(RG_FIRE_MEDALLION, StartingFireMedallion.Value()); - // AddItemToInventory(RG_WATER_MEDALLION, StartingWaterMedallion.Value()); - // AddItemToInventory(RG_SPIRIT_MEDALLION, StartingSpiritMedallion.Value()); - // AddItemToInventory(RG_SHADOW_MEDALLION, StartingShadowMedallion.Value()); - // AddItemToInventory(RG_LIGHT_MEDALLION, StartingLightMedallion.Value()); - AddItemToInventory(RG_GOLD_SKULLTULA_TOKEN, ctx->GetOption(RSK_STARTING_SKULLTULA_TOKEN).Get()); - - int8_t hearts = ctx->GetOption(RSK_STARTING_HEARTS).Get() - 2; - AdditionalHeartContainers = 0; - if (hearts < 0) { - AddItemToInventory(RG_PIECE_OF_HEART, 4); - // Plentiful and minimal have less than 4 standard pieces of heart so also replace the winner heart - if (ctx->GetOption(RSK_ITEM_POOL).Get() == 0 || ctx->GetOption(RSK_ITEM_POOL).Get() == 3) { - AddItemToInventory(RG_TREASURE_GAME_HEART); + if (dungeon->GetCompass() != RG_NONE) { + AddItemToInventory(dungeon->GetCompass()); + } + } } - AdditionalHeartContainers = 1 - hearts; - } else if (hearts > 0) { - // 16 containers in plentiful, 8 in balanced and 0 in the others - uint8_t maxContainers = 8 * std::max(0, 2 - ctx->GetOption(RSK_ITEM_POOL).Get()); - - if (hearts <= maxContainers) { - AddItemToInventory(RG_HEART_CONTAINER, hearts); - } else { - AddItemToInventory(RG_HEART_CONTAINER, maxContainers); - AddItemToInventory(RG_PIECE_OF_HEART, (hearts - maxContainers) * 4); + if (ctx->GetOption(RSK_KEYSANITY).Is(RO_DUNGEON_ITEM_LOC_STARTWITH)) { + for (auto* dungeon : ctx->GetDungeons()->GetDungeonList()) { + if (dungeon->GetSmallKeyCount() > 0) { + AddItemToInventory(dungeon->GetSmallKey(), dungeon->GetSmallKeyCount()); + } + } + } else if (ctx->GetOption(RSK_KEYSANITY).Is(RO_DUNGEON_ITEM_LOC_VANILLA)) { + // Logic cannot handle vanilla key layout in some dungeons + // this is because vanilla expects the dungeon major item to be + // locked behind the keys, which is not always true in rando. + // We can resolve this by starting with some extra keys + // - OoT Randomizer + if (ctx->GetDungeon(Rando::SPIRIT_TEMPLE)->IsMQ()) { + AddItemToInventory(RG_SPIRIT_TEMPLE_SMALL_KEY, 3); + } } - if (hearts == 17) { - AddItemToInventory(RG_TREASURE_GAME_HEART); + if (ctx->GetOption(RSK_BOSS_KEYSANITY).Is(RO_DUNGEON_ITEM_LOC_STARTWITH)) { + AddItemToInventory(RG_FOREST_TEMPLE_BOSS_KEY); + AddItemToInventory(RG_FIRE_TEMPLE_BOSS_KEY); + AddItemToInventory(RG_WATER_TEMPLE_BOSS_KEY); + AddItemToInventory(RG_SPIRIT_TEMPLE_BOSS_KEY); + AddItemToInventory(RG_SHADOW_TEMPLE_BOSS_KEY); + } + + // Add Ganon's Boss key with Triforce Hunt so the game thinks it's obtainable from the start. + // During save init, the boss key isn't actually given and it's instead given when completing the triforce. + if (ctx->GetOption(RSK_GANONS_BOSS_KEY).Is(RO_GANON_BOSS_KEY_STARTWITH) || ctx->GetOption(RSK_TRIFORCE_HUNT)) { + AddItemToInventory(RG_GANONS_CASTLE_BOSS_KEY); + } + + if (ctx->GetOption(RSK_GERUDO_FORTRESS).Is(RO_GF_CARPENTERS_FREE) && + !ctx->GetOption(RSK_SHUFFLE_GERUDO_MEMBERSHIP_CARD)) { + AddItemToInventory(RG_GERUDO_MEMBERSHIP_CARD); + } + + // Starting Inventory Menu + // Values are associated so that the count of items matches the index of + // the option selected. If None is selected, the value will be zero and + // zero of the item will be added to the starting inventory. + // TODO: Uncomment when these options are implemented. + // AddItemToInventory(RG_PROGRESSIVE_STICK_UPGRADE, StartingStickCapacity.Value()); + // AddItemToInventory(RG_PROGRESSIVE_NUT_UPGRADE, StartingNutCapacity.Value()); + // AddItemToInventory(RG_PROGRESSIVE_BOMB_BAG, StartingBombBag.Value()); + // AddItemToInventory((BombchuBag ? RG_PROGRESSIVE_BOMBCHUS : RG_BOMBCHU_20), StartingBombchus.Value()); + // AddItemToInventory(RG_PROGRESSIVE_BOW, StartingBow.Value()); + // AddItemToInventory(RG_FIRE_ARROWS, StartingFireArrows.Value()); + // AddItemToInventory(RG_ICE_ARROWS, StartingIceArrows.Value()); + // AddItemToInventory(RG_LIGHT_ARROWS, StartingLightArrows.Value()); + // AddItemToInventory(RG_DINS_FIRE, StartingDinsFire.Value()); + // AddItemToInventory(RG_FARORES_WIND, StartingFaroresWind.Value()); + // AddItemToInventory(RG_NAYRUS_LOVE, StartingNayrusLove.Value()); + // AddItemToInventory(RG_PROGRESSIVE_SLINGSHOT, StartingSlingshot.Value()); + // AddItemToInventory(RG_BOOMERANG, StartingBoomerang.Value()); + // AddItemToInventory(RG_LENS_OF_TRUTH, StartingLensOfTruth.Value()); + // AddItemToInventory(RG_MAGIC_BEAN_PACK, StartingMagicBean.Value()); + // AddItemToInventory(RG_MEGATON_HAMMER, StartingMegatonHammer.Value()); + // AddItemToInventory(RG_PROGRESSIVE_HOOKSHOT, StartingHookshot.Value()); + // AddItemToInventory(RG_IRON_BOOTS, StartingIronBoots.Value()); + // AddItemToInventory(RG_HOVER_BOOTS, StartingHoverBoots.Value()); + // For starting bottles, we need to check if they are a big poe and add that if so + // since a big poe bottle is not logically equivalent to an empty bottle. + // if (StartingBottle1.Value() == STARTINGBOTTLE_BIG_POE) { + // AddItemToInventory(RG_BOTTLE_WITH_BIG_POE, 1); + // } else if (StartingBottle1.Value()) { + // AddItemToInventory(RG_EMPTY_BOTTLE, 1); + // } + // if (StartingBottle2.Value() == STARTINGBOTTLE_BIG_POE) { + // AddItemToInventory(RG_BOTTLE_WITH_BIG_POE, 1); + // } else if (StartingBottle2.Value()) { + // AddItemToInventory(RG_EMPTY_BOTTLE, 1); + // } + // if (StartingBottle3.Value() == STARTINGBOTTLE_BIG_POE) { + // AddItemToInventory(RG_BOTTLE_WITH_BIG_POE, 1); + // } else if (StartingBottle3.Value()) { + // AddItemToInventory(RG_EMPTY_BOTTLE, 1); + // } + // if (StartingBottle4.Value() == STARTINGBOTTLE_BIG_POE) { + // AddItemToInventory(RG_BOTTLE_WITH_BIG_POE, 1); + // } else if (StartingBottle4.Value()) { + // AddItemToInventory(RG_EMPTY_BOTTLE, 1); + // } + // AddItemToInventory(RG_RUTOS_LETTER, StartingRutoBottle.Value()); + AddItemToInventory(RG_PROGRESSIVE_OCARINA, ctx->GetOption(RSK_STARTING_OCARINA).Get()); + AddItemToInventory(RG_ZELDAS_LULLABY, ctx->GetOption(RSK_STARTING_ZELDAS_LULLABY) ? 1 : 0); + AddItemToInventory(RG_EPONAS_SONG, ctx->GetOption(RSK_STARTING_EPONAS_SONG) ? 1 : 0); + AddItemToInventory(RG_SARIAS_SONG, ctx->GetOption(RSK_STARTING_SARIAS_SONG) ? 1 : 0); + AddItemToInventory(RG_SUNS_SONG, ctx->GetOption(RSK_STARTING_SUNS_SONG) ? 1 : 0); + AddItemToInventory(RG_SONG_OF_TIME, ctx->GetOption(RSK_STARTING_SONG_OF_TIME) ? 1 : 0); + AddItemToInventory(RG_SONG_OF_STORMS, ctx->GetOption(RSK_STARTING_SONG_OF_STORMS) ? 1 : 0); + AddItemToInventory(RG_MINUET_OF_FOREST, ctx->GetOption(RSK_STARTING_MINUET_OF_FOREST) ? 1 : 0); + AddItemToInventory(RG_BOLERO_OF_FIRE, ctx->GetOption(RSK_STARTING_BOLERO_OF_FIRE) ? 1 : 0); + AddItemToInventory(RG_SERENADE_OF_WATER, ctx->GetOption(RSK_STARTING_SERENADE_OF_WATER) ? 1 : 0); + AddItemToInventory(RG_REQUIEM_OF_SPIRIT, ctx->GetOption(RSK_STARTING_REQUIEM_OF_SPIRIT) ? 1 : 0); + AddItemToInventory(RG_NOCTURNE_OF_SHADOW, ctx->GetOption(RSK_STARTING_NOCTURNE_OF_SHADOW) ? 1 : 0); + AddItemToInventory(RG_PRELUDE_OF_LIGHT, ctx->GetOption(RSK_STARTING_PRELUDE_OF_LIGHT) ? 1 : 0); + AddItemToInventory(RG_KOKIRI_SWORD, ctx->GetOption(RSK_STARTING_KOKIRI_SWORD) ? 1 : 0); + // if (ProgressiveGoronSword) { + // AddItemToInventory(RG_PROGRESSIVE_GORONSWORD, StartingBiggoronSword.Value()); + // } else { + // AddItemToInventory(RG_GIANTS_KNIFE, (StartingBiggoronSword.Is(STARTINGBGS_GIANTS_KNIFE)) ? 1 : 0); + // AddItemToInventory(RG_BIGGORON_SWORD, (StartingBiggoronSword.Is(STARTINGBGS_BIGGORON_SWORD)) ? 1 : 0); + // } + AddItemToInventory(RG_MASTER_SWORD, ctx->GetOption(RSK_STARTING_MASTER_SWORD) ? 1 : 0); + AddItemToInventory(RG_DEKU_SHIELD, ctx->GetOption(RSK_STARTING_DEKU_SHIELD) ? 1 : 0); + // AddItemToInventory(RG_HYLIAN_SHIELD, StartingHylianShield.Value()); + // AddItemToInventory(RG_MIRROR_SHIELD, StartingMirrorShield.Value()); + // AddItemToInventory(RG_GORON_TUNIC, StartingGoronTunic.Value()); + // AddItemToInventory(RG_ZORA_TUNIC, StartingZoraTunic.Value()); + // AddItemToInventory(RG_PROGRESSIVE_MAGIC_METER, StartingMagicMeter.Value()); + // AddItemToInventory(RG_PROGRESSIVE_STRENGTH, StartingStrength.Value()); + // AddItemToInventory(RG_PROGRESSIVE_SCALE, StartingScale.Value()); + // AddItemToInventory(RG_PROGRESSIVE_WALLET, StartingWallet.Value()); + // AddItemToInventory(RG_STONE_OF_AGONY, StartingShardOfAgony.Value()); + // AddItemToInventory(RG_DOUBLE_DEFENSE, StartingDoubleDefense.Value()); + // AddItemToInventory(RG_KOKIRI_EMERALD, StartingKokiriEmerald.Value()); + // AddItemToInventory(RG_GORON_RUBY, StartingGoronRuby.Value()); + // AddItemToInventory(RG_ZORA_SAPPHIRE, StartingZoraSapphire.Value()); + // AddItemToInventory(RG_FOREST_MEDALLION, StartingForestMedallion.Value()); + // AddItemToInventory(RG_FIRE_MEDALLION, StartingFireMedallion.Value()); + // AddItemToInventory(RG_WATER_MEDALLION, StartingWaterMedallion.Value()); + // AddItemToInventory(RG_SPIRIT_MEDALLION, StartingSpiritMedallion.Value()); + // AddItemToInventory(RG_SHADOW_MEDALLION, StartingShadowMedallion.Value()); + // AddItemToInventory(RG_LIGHT_MEDALLION, StartingLightMedallion.Value()); + AddItemToInventory(RG_GOLD_SKULLTULA_TOKEN, ctx->GetOption(RSK_STARTING_SKULLTULA_TOKEN).Get()); + + int8_t hearts = ctx->GetOption(RSK_STARTING_HEARTS).Get() - 2; + AdditionalHeartContainers = 0; + if (hearts < 0) { + AddItemToInventory(RG_PIECE_OF_HEART, 4); + // Plentiful and minimal have less than 4 standard pieces of heart so also replace the winner heart + if (ctx->GetOption(RSK_ITEM_POOL).Get() == 0 || ctx->GetOption(RSK_ITEM_POOL).Get() == 3) { + AddItemToInventory(RG_TREASURE_GAME_HEART); + } + + AdditionalHeartContainers = 1 - hearts; + } else if (hearts > 0) { + // 16 containers in plentiful, 8 in balanced and 0 in the others + uint8_t maxContainers = 8 * std::max(0, 2 - ctx->GetOption(RSK_ITEM_POOL).Get()); + + if (hearts <= maxContainers) { + AddItemToInventory(RG_HEART_CONTAINER, hearts); + } else { + AddItemToInventory(RG_HEART_CONTAINER, maxContainers); + AddItemToInventory(RG_PIECE_OF_HEART, (hearts - maxContainers) * 4); + } + + if (hearts == 17) { + AddItemToInventory(RG_TREASURE_GAME_HEART); + } } - } } bool StartingInventoryHasBottle() { - RandomizerGet bottle = RG_EMPTY_BOTTLE; - return ElementInContainer(bottle, StartingInventory); + RandomizerGet bottle = RG_EMPTY_BOTTLE; + return ElementInContainer(bottle, StartingInventory); } void ApplyStartingInventory() { for (RandomizerGet item : StartingInventory) { - if (item == RG_PIECE_OF_HEART || item == RG_HEART_CONTAINER || item == RG_TREASURE_GAME_HEART) - continue; + if (item == RG_PIECE_OF_HEART || item == RG_HEART_CONTAINER || item == RG_TREASURE_GAME_HEART) + continue; - Rando::StaticData::RetrieveItem(item).ApplyEffect(); - } + Rando::StaticData::RetrieveItem(item).ApplyEffect(); + } } diff --git a/soh/soh/Enhancements/randomizer/ColoredMapsAndCompasses.cpp b/soh/soh/Enhancements/randomizer/ColoredMapsAndCompasses.cpp index fcfa13d97..6c1db52f7 100644 --- a/soh/soh/Enhancements/randomizer/ColoredMapsAndCompasses.cpp +++ b/soh/soh/Enhancements/randomizer/ColoredMapsAndCompasses.cpp @@ -7,18 +7,20 @@ #include "objects/object_gi_map/object_gi_map.h" extern "C" { - extern SaveContext gSaveContext; - #include "variables.h" - #include "macros.h" - u8 Randomizer_GetSettingValue(RandomizerSettingKey randoSettingKey); +extern SaveContext gSaveContext; +#include "variables.h" +#include "macros.h" +u8 Randomizer_GetSettingValue(RandomizerSettingKey randoSettingKey); } #define CVAR_COLORED_MAPS_AND_COMPASSES_NAME CVAR_RANDOMIZER_ENHANCEMENT("ColoredMapsAndCompasses") #define CVAR_COLORED_MAPS_AND_COMPASSES_DEFAULT 1 -#define CVAR_COLORED_MAPS_AND_COMPASSES_VALUE CVarGetInteger(CVAR_COLORED_MAPS_AND_COMPASSES_NAME, CVAR_COLORED_MAPS_AND_COMPASSES_DEFAULT) +#define CVAR_COLORED_MAPS_AND_COMPASSES_VALUE \ + CVarGetInteger(CVAR_COLORED_MAPS_AND_COMPASSES_NAME, CVAR_COLORED_MAPS_AND_COMPASSES_DEFAULT) void OnLoadFileColoredMapsAndCompasses(int32_t _) { - s8 mapsAndCompassesCanBeOutsideDungeon = IS_RANDO && DUNGEON_ITEMS_CAN_BE_OUTSIDE_DUNGEON(RSK_SHUFFLE_MAPANDCOMPASS); + s8 mapsAndCompassesCanBeOutsideDungeon = + IS_RANDO && DUNGEON_ITEMS_CAN_BE_OUTSIDE_DUNGEON(RSK_SHUFFLE_MAPANDCOMPASS); s8 isColoredMapsAndCompassesEnabled = mapsAndCompassesCanBeOutsideDungeon && CVAR_COLORED_MAPS_AND_COMPASSES_VALUE; if (isColoredMapsAndCompassesEnabled) { ResourceMgr_PatchGfxByName(gGiDungeonMapDL, "Map_PrimColor", 5, gsDPNoOp()); @@ -36,7 +38,7 @@ void OnLoadFileColoredMapsAndCompasses(int32_t _) { void RegisterColoredMapsAndCompasses() { COND_HOOK(OnLoadFile, CVAR_COLORED_MAPS_AND_COMPASSES_VALUE, OnLoadFileColoredMapsAndCompasses) - //Also need to call it directly to patch/unpatch on cvar change + // Also need to call it directly to patch/unpatch on cvar change OnLoadFileColoredMapsAndCompasses(0); } diff --git a/soh/soh/Enhancements/randomizer/LockOverworldDoors.cpp b/soh/soh/Enhancements/randomizer/LockOverworldDoors.cpp index 2d9d34e2b..642fa7f42 100644 --- a/soh/soh/Enhancements/randomizer/LockOverworldDoors.cpp +++ b/soh/soh/Enhancements/randomizer/LockOverworldDoors.cpp @@ -70,7 +70,7 @@ static void OnDoorInit(void* actorRef) { EnDoor* enDoor = static_cast(actorRef); enDoor->randomizerInf = RAND_INF_MAX; - auto it = lookupTable.find({gPlayState->sceneNum, enDoor->actor.params}); + auto it = lookupTable.find({ gPlayState->sceneNum, enDoor->actor.params }); if (it != lookupTable.end()) { enDoor->randomizerInf = it->second; if (!Flags_GetRandomizerInf(enDoor->randomizerInf)) { @@ -93,7 +93,8 @@ void RegisterLockOverworldDoors() { COND_VB_SHOULD(VB_CONSUME_SMALL_KEY, shouldRegister, { EnDoor* enDoor = va_arg(args, EnDoor*); - if (enDoor->randomizerInf >= RAND_INF_GUARD_HOUSE_UNLOCKED && enDoor->randomizerInf <= RAND_INF_FISHING_HOLE_KEY_OBTAINED) { + if (enDoor->randomizerInf >= RAND_INF_GUARD_HOUSE_UNLOCKED && + enDoor->randomizerInf <= RAND_INF_FISHING_HOLE_KEY_OBTAINED) { Flags_SetRandomizerInf(enDoor->randomizerInf); *should = false; } @@ -102,7 +103,8 @@ void RegisterLockOverworldDoors() { COND_VB_SHOULD(VB_NOT_HAVE_SMALL_KEY, shouldRegister, { EnDoor* enDoor = va_arg(args, EnDoor*); - if (enDoor->randomizerInf >= RAND_INF_GUARD_HOUSE_UNLOCKED && enDoor->randomizerInf <= RAND_INF_FISHING_HOLE_KEY_OBTAINED) { + if (enDoor->randomizerInf >= RAND_INF_GUARD_HOUSE_UNLOCKED && + enDoor->randomizerInf <= RAND_INF_FISHING_HOLE_KEY_OBTAINED) { *should = !Flags_GetRandomizerInf((RandomizerInf)(enDoor->randomizerInf + 1)); } }); @@ -110,21 +112,20 @@ void RegisterLockOverworldDoors() { COND_VB_SHOULD(VB_DOOR_BE_LOCKED, shouldRegister, { EnDoor* enDoor = va_arg(args, EnDoor*); - if (enDoor->randomizerInf >= RAND_INF_GUARD_HOUSE_UNLOCKED && enDoor->randomizerInf <= RAND_INF_FISHING_HOLE_KEY_OBTAINED) { + if (enDoor->randomizerInf >= RAND_INF_GUARD_HOUSE_UNLOCKED && + enDoor->randomizerInf <= RAND_INF_FISHING_HOLE_KEY_OBTAINED) { *should = !Flags_GetRandomizerInf(enDoor->randomizerInf); } }); - // The door actor uses the same param to indicate if a door should be locked or be a scene transition, so it cannot be both. Here we're - // overriding the check for scene transition to also check if the door is being unlocked and should be a scene transition. + // The door actor uses the same param to indicate if a door should be locked or be a scene transition, so it cannot + // be both. Here we're overriding the check for scene transition to also check if the door is being unlocked and + // should be a scene transition. COND_VB_SHOULD(VB_DOOR_PLAY_SCENE_TRANSITION, shouldRegister, { EnDoor* enDoor = va_arg(args, EnDoor*); - if (!*should && ( - enDoor->actor.id == ACTOR_EN_DOOR && - ((enDoor->actor.params >> 7) & 7) == 1 && - enDoor->randomizerInf != RAND_INF_MAX - )) { + if (!*should && (enDoor->actor.id == ACTOR_EN_DOOR && ((enDoor->actor.params >> 7) & 7) == 1 && + enDoor->randomizerInf != RAND_INF_MAX)) { *should = true; } }); diff --git a/soh/soh/Enhancements/randomizer/Plandomizer.cpp b/soh/soh/Enhancements/randomizer/Plandomizer.cpp index 39b20d876..dc32dc999 100644 --- a/soh/soh/Enhancements/randomizer/Plandomizer.cpp +++ b/soh/soh/Enhancements/randomizer/Plandomizer.cpp @@ -18,10 +18,10 @@ #include "soh/Enhancements/randomizer/3drando/shops.hpp" extern "C" { - #include "include/z64item.h" - #include "objects/gameplay_keep/gameplay_keep.h" - extern SaveContext gSaveContext; - extern PlayState* gPlayState; +#include "include/z64item.h" +#include "objects/gameplay_keep/gameplay_keep.h" +extern SaveContext gSaveContext; +extern PlayState* gPlayState; } const std::string randomizeButton = ICON_FA_RANDOM; @@ -34,14 +34,14 @@ std::string shortName = ""; std::string logTemp = ""; std::string lastLoadedSpoiler = ""; int32_t temporaryItemIndex = -1; -RandomizerCheckArea selectedArea = RCAREA_INVALID; +RandomizerCheckArea selectedArea = RCAREA_INVALID; -ImVec4 itemColor = ImVec4( 1.0f, 1.0f, 1.0f, 1.0f ); +ImVec4 itemColor = ImVec4(1.0f, 1.0f, 1.0f, 1.0f); ImTextureID textureID; ImVec2 imageSize = ImVec2(32.0f, 32.0f); float imagePadding = 2.0f; -ImVec2 textureUV0 = ImVec2( 0, 0 ); -ImVec2 textureUV1 = ImVec2( 1, 1 ); +ImVec2 textureUV0 = ImVec2(0, 0); +ImVec2 textureUV1 = ImVec2(1, 1); bool shouldPopup = false; bool shouldTrapPopup = false; @@ -62,208 +62,196 @@ std::vector plandoHintData; extern std::map rcAreaNames; std::unordered_map bossKeyShortNames = { - { RG_FOREST_TEMPLE_BOSS_KEY, "Frst" }, - { RG_FIRE_TEMPLE_BOSS_KEY, "Fire" }, - { RG_WATER_TEMPLE_BOSS_KEY, "Watr" }, - { RG_SPIRIT_TEMPLE_BOSS_KEY, "Sprt" }, - { RG_SHADOW_TEMPLE_BOSS_KEY, "Shdw" }, - { RG_GANONS_CASTLE_BOSS_KEY, "Ganon" }, + { RG_FOREST_TEMPLE_BOSS_KEY, "Frst" }, { RG_FIRE_TEMPLE_BOSS_KEY, "Fire" }, + { RG_WATER_TEMPLE_BOSS_KEY, "Watr" }, { RG_SPIRIT_TEMPLE_BOSS_KEY, "Sprt" }, + { RG_SHADOW_TEMPLE_BOSS_KEY, "Shdw" }, { RG_GANONS_CASTLE_BOSS_KEY, "Ganon" }, }; std::unordered_map ocarinaButtonNames = { - { RG_OCARINA_A_BUTTON, "A" }, - { RG_OCARINA_C_UP_BUTTON, "C-UP" }, - { RG_OCARINA_C_DOWN_BUTTON, "C-DWN" }, - { RG_OCARINA_C_LEFT_BUTTON, "C-LFT" }, - { RG_OCARINA_C_RIGHT_BUTTON, "C-RHT" }, + { RG_OCARINA_A_BUTTON, "A" }, { RG_OCARINA_C_UP_BUTTON, "C-UP" }, + { RG_OCARINA_C_DOWN_BUTTON, "C-DWN" }, { RG_OCARINA_C_LEFT_BUTTON, "C-LFT" }, + { RG_OCARINA_C_RIGHT_BUTTON, "C-RHT" }, }; std::map bossSoulColorMapping = { - { RG_GOHMA_SOUL, { 0.00f, 1.00f, 0.00f, 1.0f } }, - { RG_KING_DODONGO_SOUL, { 1.00f, 0.00f, 0.39f, 1.0f } }, - { RG_BARINADE_SOUL, { 0.20f, 1.00f, 1.00f, 1.0f } }, - { RG_PHANTOM_GANON_SOUL, { 0.02f, 0.76f, 0.18f, 1.0f } }, - { RG_VOLVAGIA_SOUL, { 0.93f, 0.37f, 0.37f, 1.0f } }, - { RG_MORPHA_SOUL, { 0.33f, 0.71f, 0.87f, 1.0f } }, - { RG_BONGO_BONGO_SOUL, { 0.49f, 0.06f, 0.69f, 1.0f } }, - { RG_TWINROVA_SOUL, { 0.87f, 0.62f, 0.18f, 1.0f } }, - { RG_GANON_SOUL, { 0.31f, 0.31f, 0.31f, 1.0f } } + { RG_GOHMA_SOUL, { 0.00f, 1.00f, 0.00f, 1.0f } }, { RG_KING_DODONGO_SOUL, { 1.00f, 0.00f, 0.39f, 1.0f } }, + { RG_BARINADE_SOUL, { 0.20f, 1.00f, 1.00f, 1.0f } }, { RG_PHANTOM_GANON_SOUL, { 0.02f, 0.76f, 0.18f, 1.0f } }, + { RG_VOLVAGIA_SOUL, { 0.93f, 0.37f, 0.37f, 1.0f } }, { RG_MORPHA_SOUL, { 0.33f, 0.71f, 0.87f, 1.0f } }, + { RG_BONGO_BONGO_SOUL, { 0.49f, 0.06f, 0.69f, 1.0f } }, { RG_TWINROVA_SOUL, { 0.87f, 0.62f, 0.18f, 1.0f } }, + { RG_GANON_SOUL, { 0.31f, 0.31f, 0.31f, 1.0f } } }; - std::vector infiniteItemList = { - RG_GREEN_RUPEE, RG_BLUE_RUPEE, RG_RED_RUPEE, RG_PURPLE_RUPEE, RG_HUGE_RUPEE, - RG_ARROWS_5, RG_ARROWS_10, RG_ARROWS_30, - RG_DEKU_STICK_1, RG_DEKU_SEEDS_30, RG_DEKU_NUTS_5, RG_DEKU_NUTS_10, - RG_BOMBS_5, RG_BOMBS_10, RG_BOMBS_20, RG_BOMBCHU_5, RG_BOMBCHU_10, RG_BOMBCHU_20, - RG_RECOVERY_HEART, RG_ICE_TRAP, RG_SOLD_OUT + RG_GREEN_RUPEE, RG_BLUE_RUPEE, RG_RED_RUPEE, RG_PURPLE_RUPEE, RG_HUGE_RUPEE, RG_ARROWS_5, RG_ARROWS_10, + RG_ARROWS_30, RG_DEKU_STICK_1, RG_DEKU_SEEDS_30, RG_DEKU_NUTS_5, RG_DEKU_NUTS_10, RG_BOMBS_5, RG_BOMBS_10, + RG_BOMBS_20, RG_BOMBCHU_5, RG_BOMBCHU_10, RG_BOMBCHU_20, RG_RECOVERY_HEART, RG_ICE_TRAP, RG_SOLD_OUT }; std::unordered_map itemImageMap = { - { RG_NONE, "ITEM_SOLD_OUT" }, - { RG_KOKIRI_SWORD, "ITEM_SWORD_KOKIRI" }, - { RG_GIANTS_KNIFE, "ITEM_SWORD_KNIFE" }, - { RG_BIGGORON_SWORD, "ITEM_SWORD_BGS" }, - { RG_DEKU_SHIELD, "ITEM_SHIELD_DEKU" }, - { RG_HYLIAN_SHIELD, "ITEM_SHIELD_HYLIAN" }, - { RG_MIRROR_SHIELD, "ITEM_SHIELD_MIRROR" }, - { RG_GORON_TUNIC, "ITEM_TUNIC_GORON" }, - { RG_ZORA_TUNIC, "ITEM_TUNIC_ZORA" }, - { RG_IRON_BOOTS, "ITEM_BOOTS_IRON" }, - { RG_HOVER_BOOTS, "ITEM_BOOTS_HOVER" }, - { RG_BOOMERANG, "ITEM_BOOMERANG" }, - { RG_LENS_OF_TRUTH, "ITEM_LENS" }, - { RG_MEGATON_HAMMER, "ITEM_HAMMER" }, - { RG_STONE_OF_AGONY, "ITEM_STONE_OF_AGONY" }, - { RG_DINS_FIRE, "ITEM_DINS_FIRE" }, - { RG_FARORES_WIND, "ITEM_FARORES_WIND" }, - { RG_NAYRUS_LOVE, "ITEM_NAYRUS_LOVE" }, - { RG_FIRE_ARROWS, "ITEM_ARROW_FIRE" }, - { RG_ICE_ARROWS, "ITEM_ARROW_ICE" }, - { RG_LIGHT_ARROWS, "ITEM_ARROW_LIGHT" }, - { RG_GERUDO_MEMBERSHIP_CARD, "ITEM_GERUDO_CARD" }, - { RG_MAGIC_BEAN, "ITEM_BEAN" }, - { RG_MAGIC_BEAN_PACK, "ITEM_BEAN" }, - { RG_DOUBLE_DEFENSE, "ITEM_HEART_CONTAINER" }, - { RG_WEIRD_EGG, "ITEM_WEIRD_EGG" }, - { RG_ZELDAS_LETTER, "ITEM_LETTER_ZELDA" }, - { RG_POCKET_EGG, "ITEM_POCKET_EGG" }, - { RG_COJIRO, "ITEM_COJIRO" }, - { RG_ODD_MUSHROOM, "ITEM_ODD_MUSHROOM" }, - { RG_ODD_POTION, "ITEM_ODD_POTION" }, - { RG_POACHERS_SAW, "ITEM_SAW" }, - { RG_BROKEN_SWORD, "ITEM_SWORD_BROKEN" }, - { RG_PRESCRIPTION, "ITEM_PRESCRIPTION" }, - { RG_EYEBALL_FROG, "ITEM_FROG" }, - { RG_EYEDROPS, "ITEM_EYEDROPS" }, - { RG_CLAIM_CHECK, "ITEM_CLAIM_CHECK" }, - { RG_GOLD_SKULLTULA_TOKEN, "ITEM_SKULL_TOKEN" }, - { RG_PROGRESSIVE_HOOKSHOT, "ITEM_HOOKSHOT" }, - { RG_PROGRESSIVE_STRENGTH, "ITEM_BRACELET" }, - { RG_PROGRESSIVE_BOMB_BAG, "ITEM_BOMB_BAG_30" }, - { RG_PROGRESSIVE_BOW, "ITEM_QUIVER_30" }, - { RG_PROGRESSIVE_SLINGSHOT, "ITEM_SLINGSHOT" }, - { RG_PROGRESSIVE_WALLET, "ITEM_WALLET_ADULT" }, - { RG_PROGRESSIVE_SCALE, "ITEM_SCALE_SILVER" }, - { RG_PROGRESSIVE_NUT_UPGRADE, "ITEM_NUT" }, - { RG_PROGRESSIVE_STICK_UPGRADE, "ITEM_STICK" }, - { RG_PROGRESSIVE_BOMBCHUS, "ITEM_BOMBCHU" }, - { RG_PROGRESSIVE_MAGIC_METER, "ITEM_MAGIC_SMALL" }, - { RG_MAGIC_SINGLE, "ITEM_MAGIC_SMALL" }, - { RG_MAGIC_DOUBLE, "ITEM_MAGIC_LARGE" }, - { RG_PROGRESSIVE_OCARINA, "ITEM_OCARINA_FAIRY" }, - { RG_PROGRESSIVE_GORONSWORD, "ITEM_SWORD_BGS" }, - { RG_EMPTY_BOTTLE, "ITEM_BOTTLE" }, - { RG_BOTTLE_WITH_MILK, "ITEM_MILK_BOTTLE" }, - { RG_BOTTLE_WITH_RED_POTION, "ITEM_POTION_RED" }, - { RG_BOTTLE_WITH_GREEN_POTION, "ITEM_POTION_GREEN" }, - { RG_BOTTLE_WITH_BLUE_POTION, "ITEM_POTION_BLUE" }, - { RG_BOTTLE_WITH_FAIRY, "ITEM_FAIRY" }, - { RG_BOTTLE_WITH_FISH, "ITEM_FISH" }, - { RG_BOTTLE_WITH_BLUE_FIRE, "ITEM_BLUE_FIRE" }, - { RG_BOTTLE_WITH_BUGS, "ITEM_BUG" }, - { RG_BOTTLE_WITH_POE, "ITEM_POE" }, - { RG_RUTOS_LETTER, "ITEM_LETTER_RUTO" }, - { RG_BOTTLE_WITH_BIG_POE, "ITEM_BIG_POE" }, - { RG_ZELDAS_LULLABY, "ITEM_SONG_LULLABY" }, - { RG_EPONAS_SONG, "ITEM_SONG_EPONA" }, - { RG_SARIAS_SONG, "ITEM_SONG_SARIA" }, - { RG_SUNS_SONG, "ITEM_SONG_SUN" }, - { RG_SONG_OF_TIME, "ITEM_SONG_TIME" }, - { RG_SONG_OF_STORMS, "ITEM_SONG_STORMS" }, - { RG_MINUET_OF_FOREST, "ITEM_SONG_MINUET" }, - { RG_BOLERO_OF_FIRE, "ITEM_SONG_BOLERO" }, - { RG_SERENADE_OF_WATER, "ITEM_SONG_SERENADE" }, - { RG_REQUIEM_OF_SPIRIT, "ITEM_SONG_REQUIEM" }, - { RG_NOCTURNE_OF_SHADOW, "ITEM_SONG_NOCTURNE" }, - { RG_PRELUDE_OF_LIGHT, "ITEM_SONG_PRELUDE" }, - { RG_DEKU_TREE_MAP, "ITEM_DUNGEON_MAP" }, - { RG_DODONGOS_CAVERN_MAP, "ITEM_DUNGEON_MAP" }, - { RG_JABU_JABUS_BELLY_MAP, "ITEM_DUNGEON_MAP" }, - { RG_FOREST_TEMPLE_MAP, "ITEM_DUNGEON_MAP" }, - { RG_FIRE_TEMPLE_MAP, "ITEM_DUNGEON_MAP" }, - { RG_WATER_TEMPLE_MAP, "ITEM_DUNGEON_MAP" }, - { RG_SPIRIT_TEMPLE_MAP, "ITEM_DUNGEON_MAP" }, - { RG_SHADOW_TEMPLE_MAP, "ITEM_DUNGEON_MAP" }, - { RG_BOTTOM_OF_THE_WELL_MAP, "ITEM_DUNGEON_MAP" }, - { RG_ICE_CAVERN_MAP, "ITEM_DUNGEON_MAP" }, - { RG_DEKU_TREE_COMPASS, "ITEM_COMPASS" }, - { RG_DODONGOS_CAVERN_COMPASS, "ITEM_COMPASS" }, - { RG_JABU_JABUS_BELLY_COMPASS, "ITEM_COMPASS" }, - { RG_FOREST_TEMPLE_COMPASS, "ITEM_COMPASS" }, - { RG_FIRE_TEMPLE_COMPASS, "ITEM_COMPASS" }, - { RG_WATER_TEMPLE_COMPASS, "ITEM_COMPASS" }, - { RG_SPIRIT_TEMPLE_COMPASS, "ITEM_COMPASS" }, - { RG_SHADOW_TEMPLE_COMPASS, "ITEM_COMPASS" }, - { RG_BOTTOM_OF_THE_WELL_COMPASS, "ITEM_COMPASS" }, - { RG_ICE_CAVERN_COMPASS, "ITEM_COMPASS" }, - { RG_FOREST_TEMPLE_BOSS_KEY, "ITEM_KEY_BOSS" }, - { RG_FIRE_TEMPLE_BOSS_KEY, "ITEM_KEY_BOSS" }, - { RG_WATER_TEMPLE_BOSS_KEY, "ITEM_KEY_BOSS" }, - { RG_SPIRIT_TEMPLE_BOSS_KEY, "ITEM_KEY_BOSS" }, - { RG_SHADOW_TEMPLE_BOSS_KEY, "ITEM_KEY_BOSS" }, - { RG_GANONS_CASTLE_BOSS_KEY, "ITEM_KEY_BOSS" }, - { RG_FOREST_TEMPLE_SMALL_KEY, "ITEM_KEY_SMALL" }, - { RG_FIRE_TEMPLE_SMALL_KEY, "ITEM_KEY_SMALL" }, - { RG_WATER_TEMPLE_SMALL_KEY, "ITEM_KEY_SMALL" }, - { RG_SPIRIT_TEMPLE_SMALL_KEY, "ITEM_KEY_SMALL" }, - { RG_SHADOW_TEMPLE_SMALL_KEY, "ITEM_KEY_SMALL" }, - { RG_BOTTOM_OF_THE_WELL_SMALL_KEY, "ITEM_KEY_SMALL" }, + { RG_NONE, "ITEM_SOLD_OUT" }, + { RG_KOKIRI_SWORD, "ITEM_SWORD_KOKIRI" }, + { RG_GIANTS_KNIFE, "ITEM_SWORD_KNIFE" }, + { RG_BIGGORON_SWORD, "ITEM_SWORD_BGS" }, + { RG_DEKU_SHIELD, "ITEM_SHIELD_DEKU" }, + { RG_HYLIAN_SHIELD, "ITEM_SHIELD_HYLIAN" }, + { RG_MIRROR_SHIELD, "ITEM_SHIELD_MIRROR" }, + { RG_GORON_TUNIC, "ITEM_TUNIC_GORON" }, + { RG_ZORA_TUNIC, "ITEM_TUNIC_ZORA" }, + { RG_IRON_BOOTS, "ITEM_BOOTS_IRON" }, + { RG_HOVER_BOOTS, "ITEM_BOOTS_HOVER" }, + { RG_BOOMERANG, "ITEM_BOOMERANG" }, + { RG_LENS_OF_TRUTH, "ITEM_LENS" }, + { RG_MEGATON_HAMMER, "ITEM_HAMMER" }, + { RG_STONE_OF_AGONY, "ITEM_STONE_OF_AGONY" }, + { RG_DINS_FIRE, "ITEM_DINS_FIRE" }, + { RG_FARORES_WIND, "ITEM_FARORES_WIND" }, + { RG_NAYRUS_LOVE, "ITEM_NAYRUS_LOVE" }, + { RG_FIRE_ARROWS, "ITEM_ARROW_FIRE" }, + { RG_ICE_ARROWS, "ITEM_ARROW_ICE" }, + { RG_LIGHT_ARROWS, "ITEM_ARROW_LIGHT" }, + { RG_GERUDO_MEMBERSHIP_CARD, "ITEM_GERUDO_CARD" }, + { RG_MAGIC_BEAN, "ITEM_BEAN" }, + { RG_MAGIC_BEAN_PACK, "ITEM_BEAN" }, + { RG_DOUBLE_DEFENSE, "ITEM_HEART_CONTAINER" }, + { RG_WEIRD_EGG, "ITEM_WEIRD_EGG" }, + { RG_ZELDAS_LETTER, "ITEM_LETTER_ZELDA" }, + { RG_POCKET_EGG, "ITEM_POCKET_EGG" }, + { RG_COJIRO, "ITEM_COJIRO" }, + { RG_ODD_MUSHROOM, "ITEM_ODD_MUSHROOM" }, + { RG_ODD_POTION, "ITEM_ODD_POTION" }, + { RG_POACHERS_SAW, "ITEM_SAW" }, + { RG_BROKEN_SWORD, "ITEM_SWORD_BROKEN" }, + { RG_PRESCRIPTION, "ITEM_PRESCRIPTION" }, + { RG_EYEBALL_FROG, "ITEM_FROG" }, + { RG_EYEDROPS, "ITEM_EYEDROPS" }, + { RG_CLAIM_CHECK, "ITEM_CLAIM_CHECK" }, + { RG_GOLD_SKULLTULA_TOKEN, "ITEM_SKULL_TOKEN" }, + { RG_PROGRESSIVE_HOOKSHOT, "ITEM_HOOKSHOT" }, + { RG_PROGRESSIVE_STRENGTH, "ITEM_BRACELET" }, + { RG_PROGRESSIVE_BOMB_BAG, "ITEM_BOMB_BAG_30" }, + { RG_PROGRESSIVE_BOW, "ITEM_QUIVER_30" }, + { RG_PROGRESSIVE_SLINGSHOT, "ITEM_SLINGSHOT" }, + { RG_PROGRESSIVE_WALLET, "ITEM_WALLET_ADULT" }, + { RG_PROGRESSIVE_SCALE, "ITEM_SCALE_SILVER" }, + { RG_PROGRESSIVE_NUT_UPGRADE, "ITEM_NUT" }, + { RG_PROGRESSIVE_STICK_UPGRADE, "ITEM_STICK" }, + { RG_PROGRESSIVE_BOMBCHUS, "ITEM_BOMBCHU" }, + { RG_PROGRESSIVE_MAGIC_METER, "ITEM_MAGIC_SMALL" }, + { RG_MAGIC_SINGLE, "ITEM_MAGIC_SMALL" }, + { RG_MAGIC_DOUBLE, "ITEM_MAGIC_LARGE" }, + { RG_PROGRESSIVE_OCARINA, "ITEM_OCARINA_FAIRY" }, + { RG_PROGRESSIVE_GORONSWORD, "ITEM_SWORD_BGS" }, + { RG_EMPTY_BOTTLE, "ITEM_BOTTLE" }, + { RG_BOTTLE_WITH_MILK, "ITEM_MILK_BOTTLE" }, + { RG_BOTTLE_WITH_RED_POTION, "ITEM_POTION_RED" }, + { RG_BOTTLE_WITH_GREEN_POTION, "ITEM_POTION_GREEN" }, + { RG_BOTTLE_WITH_BLUE_POTION, "ITEM_POTION_BLUE" }, + { RG_BOTTLE_WITH_FAIRY, "ITEM_FAIRY" }, + { RG_BOTTLE_WITH_FISH, "ITEM_FISH" }, + { RG_BOTTLE_WITH_BLUE_FIRE, "ITEM_BLUE_FIRE" }, + { RG_BOTTLE_WITH_BUGS, "ITEM_BUG" }, + { RG_BOTTLE_WITH_POE, "ITEM_POE" }, + { RG_RUTOS_LETTER, "ITEM_LETTER_RUTO" }, + { RG_BOTTLE_WITH_BIG_POE, "ITEM_BIG_POE" }, + { RG_ZELDAS_LULLABY, "ITEM_SONG_LULLABY" }, + { RG_EPONAS_SONG, "ITEM_SONG_EPONA" }, + { RG_SARIAS_SONG, "ITEM_SONG_SARIA" }, + { RG_SUNS_SONG, "ITEM_SONG_SUN" }, + { RG_SONG_OF_TIME, "ITEM_SONG_TIME" }, + { RG_SONG_OF_STORMS, "ITEM_SONG_STORMS" }, + { RG_MINUET_OF_FOREST, "ITEM_SONG_MINUET" }, + { RG_BOLERO_OF_FIRE, "ITEM_SONG_BOLERO" }, + { RG_SERENADE_OF_WATER, "ITEM_SONG_SERENADE" }, + { RG_REQUIEM_OF_SPIRIT, "ITEM_SONG_REQUIEM" }, + { RG_NOCTURNE_OF_SHADOW, "ITEM_SONG_NOCTURNE" }, + { RG_PRELUDE_OF_LIGHT, "ITEM_SONG_PRELUDE" }, + { RG_DEKU_TREE_MAP, "ITEM_DUNGEON_MAP" }, + { RG_DODONGOS_CAVERN_MAP, "ITEM_DUNGEON_MAP" }, + { RG_JABU_JABUS_BELLY_MAP, "ITEM_DUNGEON_MAP" }, + { RG_FOREST_TEMPLE_MAP, "ITEM_DUNGEON_MAP" }, + { RG_FIRE_TEMPLE_MAP, "ITEM_DUNGEON_MAP" }, + { RG_WATER_TEMPLE_MAP, "ITEM_DUNGEON_MAP" }, + { RG_SPIRIT_TEMPLE_MAP, "ITEM_DUNGEON_MAP" }, + { RG_SHADOW_TEMPLE_MAP, "ITEM_DUNGEON_MAP" }, + { RG_BOTTOM_OF_THE_WELL_MAP, "ITEM_DUNGEON_MAP" }, + { RG_ICE_CAVERN_MAP, "ITEM_DUNGEON_MAP" }, + { RG_DEKU_TREE_COMPASS, "ITEM_COMPASS" }, + { RG_DODONGOS_CAVERN_COMPASS, "ITEM_COMPASS" }, + { RG_JABU_JABUS_BELLY_COMPASS, "ITEM_COMPASS" }, + { RG_FOREST_TEMPLE_COMPASS, "ITEM_COMPASS" }, + { RG_FIRE_TEMPLE_COMPASS, "ITEM_COMPASS" }, + { RG_WATER_TEMPLE_COMPASS, "ITEM_COMPASS" }, + { RG_SPIRIT_TEMPLE_COMPASS, "ITEM_COMPASS" }, + { RG_SHADOW_TEMPLE_COMPASS, "ITEM_COMPASS" }, + { RG_BOTTOM_OF_THE_WELL_COMPASS, "ITEM_COMPASS" }, + { RG_ICE_CAVERN_COMPASS, "ITEM_COMPASS" }, + { RG_FOREST_TEMPLE_BOSS_KEY, "ITEM_KEY_BOSS" }, + { RG_FIRE_TEMPLE_BOSS_KEY, "ITEM_KEY_BOSS" }, + { RG_WATER_TEMPLE_BOSS_KEY, "ITEM_KEY_BOSS" }, + { RG_SPIRIT_TEMPLE_BOSS_KEY, "ITEM_KEY_BOSS" }, + { RG_SHADOW_TEMPLE_BOSS_KEY, "ITEM_KEY_BOSS" }, + { RG_GANONS_CASTLE_BOSS_KEY, "ITEM_KEY_BOSS" }, + { RG_FOREST_TEMPLE_SMALL_KEY, "ITEM_KEY_SMALL" }, + { RG_FIRE_TEMPLE_SMALL_KEY, "ITEM_KEY_SMALL" }, + { RG_WATER_TEMPLE_SMALL_KEY, "ITEM_KEY_SMALL" }, + { RG_SPIRIT_TEMPLE_SMALL_KEY, "ITEM_KEY_SMALL" }, + { RG_SHADOW_TEMPLE_SMALL_KEY, "ITEM_KEY_SMALL" }, + { RG_BOTTOM_OF_THE_WELL_SMALL_KEY, "ITEM_KEY_SMALL" }, { RG_GERUDO_TRAINING_GROUND_SMALL_KEY, "ITEM_KEY_SMALL" }, - { RG_GERUDO_FORTRESS_SMALL_KEY, "ITEM_KEY_SMALL" }, - { RG_GANONS_CASTLE_SMALL_KEY, "ITEM_KEY_SMALL" }, - { RG_TREASURE_GAME_SMALL_KEY, "ITEM_KEY_SMALL" }, - { RG_KOKIRI_EMERALD, "ITEM_KOKIRI_EMERALD" }, - { RG_GORON_RUBY, "ITEM_GORON_RUBY" }, - { RG_ZORA_SAPPHIRE, "ITEM_ZORA_SAPPHIRE" }, - { RG_FOREST_MEDALLION, "ITEM_MEDALLION_FOREST" }, - { RG_FIRE_MEDALLION, "ITEM_MEDALLION_FIRE" }, - { RG_WATER_MEDALLION, "ITEM_MEDALLION_WATER" }, - { RG_SPIRIT_MEDALLION, "ITEM_MEDALLION_SPIRIT" }, - { RG_SHADOW_MEDALLION, "ITEM_MEDALLION_SHADOW" }, - { RG_LIGHT_MEDALLION, "ITEM_MEDALLION_LIGHT" }, - { RG_RECOVERY_HEART, "ITEM_HEART_GRAYSCALE" }, - { RG_GREEN_RUPEE, "ITEM_RUPEE_GRAYSCALE" }, - { RG_GREG_RUPEE, "ITEM_RUPEE_GRAYSCALE" }, - { RG_BLUE_RUPEE, "ITEM_RUPEE_GRAYSCALE" }, - { RG_RED_RUPEE, "ITEM_RUPEE_GRAYSCALE" }, - { RG_PURPLE_RUPEE, "ITEM_RUPEE_GRAYSCALE" }, - { RG_HUGE_RUPEE, "ITEM_RUPEE_GRAYSCALE" }, - { RG_TREASURE_GAME_GREEN_RUPEE, "ITEM_RUPEE_GRAYSCALE" }, - { RG_PIECE_OF_HEART, "ITEM_HEART_PIECE" }, - { RG_HEART_CONTAINER, "ITEM_HEART_CONTAINER" }, - { RG_ICE_TRAP, "ITEM_ICE_TRAP" }, - { RG_MILK, "ITEM_MILK_BOTTLE"}, - { RG_BOMBS_5, "ITEM_BOMB" }, - { RG_BOMBS_10, "ITEM_BOMB" }, - { RG_BOMBS_20, "ITEM_BOMB" }, - { RG_BUY_BOMBS_525, "ITEM_BOMB" }, - { RG_BUY_BOMBS_535, "ITEM_BOMB" }, - { RG_BUY_BOMBS_10, "ITEM_BOMB" }, - { RG_BUY_BOMBS_20, "ITEM_BOMB" }, - { RG_BUY_BOMBS_30, "ITEM_BOMB" }, - { RG_DEKU_NUTS_5, "ITEM_NUT" }, - { RG_DEKU_NUTS_10, "ITEM_NUT" }, - { RG_BUY_DEKU_NUTS_5, "ITEM_NUT" }, - { RG_BUY_DEKU_NUTS_10, "ITEM_NUT" }, - { RG_BOMBCHU_5, "ITEM_BOMBCHU" }, - { RG_BOMBCHU_10, "ITEM_BOMBCHU" }, - { RG_BOMBCHU_20, "ITEM_BOMBCHU" }, - { RG_BUY_BOMBCHUS_20, "ITEM_BOMBCHU" }, - { RG_ARROWS_5, "ITEM_ARROWS_SMALL" }, - { RG_BUY_ARROWS_10, "ITEM_ARROWS_SMALL" }, - { RG_ARROWS_10, "ITEM_ARROWS_MEDIUM" }, - { RG_BUY_ARROWS_30, "ITEM_ARROWS_MEDIUM" }, - { RG_ARROWS_30, "ITEM_ARROWS_LARGE" }, - { RG_BUY_ARROWS_50, "ITEM_ARROWS_LARGE" }, - { RG_TREASURE_GAME_HEART, "ITEM_HEART_PIECE" }, - { RG_DEKU_SEEDS_30, "ITEM_SEEDS" }, - { RG_BUY_DEKU_SEEDS_30, "ITEM_SEEDS" }, - { RG_BUY_HEART, "ITEM_HEART_GRAYSCALE" }, - { RG_FISHING_POLE, "ITEM_FISHING_POLE" }, - { RG_SOLD_OUT, "ITEM_SOLD_OUT" }, - { RG_TRIFORCE_PIECE, "TRIFORCE_PIECE" }, - { RG_SKELETON_KEY, "ITEM_KEY_SMALL" } + { RG_GERUDO_FORTRESS_SMALL_KEY, "ITEM_KEY_SMALL" }, + { RG_GANONS_CASTLE_SMALL_KEY, "ITEM_KEY_SMALL" }, + { RG_TREASURE_GAME_SMALL_KEY, "ITEM_KEY_SMALL" }, + { RG_KOKIRI_EMERALD, "ITEM_KOKIRI_EMERALD" }, + { RG_GORON_RUBY, "ITEM_GORON_RUBY" }, + { RG_ZORA_SAPPHIRE, "ITEM_ZORA_SAPPHIRE" }, + { RG_FOREST_MEDALLION, "ITEM_MEDALLION_FOREST" }, + { RG_FIRE_MEDALLION, "ITEM_MEDALLION_FIRE" }, + { RG_WATER_MEDALLION, "ITEM_MEDALLION_WATER" }, + { RG_SPIRIT_MEDALLION, "ITEM_MEDALLION_SPIRIT" }, + { RG_SHADOW_MEDALLION, "ITEM_MEDALLION_SHADOW" }, + { RG_LIGHT_MEDALLION, "ITEM_MEDALLION_LIGHT" }, + { RG_RECOVERY_HEART, "ITEM_HEART_GRAYSCALE" }, + { RG_GREEN_RUPEE, "ITEM_RUPEE_GRAYSCALE" }, + { RG_GREG_RUPEE, "ITEM_RUPEE_GRAYSCALE" }, + { RG_BLUE_RUPEE, "ITEM_RUPEE_GRAYSCALE" }, + { RG_RED_RUPEE, "ITEM_RUPEE_GRAYSCALE" }, + { RG_PURPLE_RUPEE, "ITEM_RUPEE_GRAYSCALE" }, + { RG_HUGE_RUPEE, "ITEM_RUPEE_GRAYSCALE" }, + { RG_TREASURE_GAME_GREEN_RUPEE, "ITEM_RUPEE_GRAYSCALE" }, + { RG_PIECE_OF_HEART, "ITEM_HEART_PIECE" }, + { RG_HEART_CONTAINER, "ITEM_HEART_CONTAINER" }, + { RG_ICE_TRAP, "ITEM_ICE_TRAP" }, + { RG_MILK, "ITEM_MILK_BOTTLE" }, + { RG_BOMBS_5, "ITEM_BOMB" }, + { RG_BOMBS_10, "ITEM_BOMB" }, + { RG_BOMBS_20, "ITEM_BOMB" }, + { RG_BUY_BOMBS_525, "ITEM_BOMB" }, + { RG_BUY_BOMBS_535, "ITEM_BOMB" }, + { RG_BUY_BOMBS_10, "ITEM_BOMB" }, + { RG_BUY_BOMBS_20, "ITEM_BOMB" }, + { RG_BUY_BOMBS_30, "ITEM_BOMB" }, + { RG_DEKU_NUTS_5, "ITEM_NUT" }, + { RG_DEKU_NUTS_10, "ITEM_NUT" }, + { RG_BUY_DEKU_NUTS_5, "ITEM_NUT" }, + { RG_BUY_DEKU_NUTS_10, "ITEM_NUT" }, + { RG_BOMBCHU_5, "ITEM_BOMBCHU" }, + { RG_BOMBCHU_10, "ITEM_BOMBCHU" }, + { RG_BOMBCHU_20, "ITEM_BOMBCHU" }, + { RG_BUY_BOMBCHUS_20, "ITEM_BOMBCHU" }, + { RG_ARROWS_5, "ITEM_ARROWS_SMALL" }, + { RG_BUY_ARROWS_10, "ITEM_ARROWS_SMALL" }, + { RG_ARROWS_10, "ITEM_ARROWS_MEDIUM" }, + { RG_BUY_ARROWS_30, "ITEM_ARROWS_MEDIUM" }, + { RG_ARROWS_30, "ITEM_ARROWS_LARGE" }, + { RG_BUY_ARROWS_50, "ITEM_ARROWS_LARGE" }, + { RG_TREASURE_GAME_HEART, "ITEM_HEART_PIECE" }, + { RG_DEKU_SEEDS_30, "ITEM_SEEDS" }, + { RG_BUY_DEKU_SEEDS_30, "ITEM_SEEDS" }, + { RG_BUY_HEART, "ITEM_HEART_GRAYSCALE" }, + { RG_FISHING_POLE, "ITEM_FISHING_POLE" }, + { RG_SOLD_OUT, "ITEM_SOLD_OUT" }, + { RG_TRIFORCE_PIECE, "TRIFORCE_PIECE" }, + { RG_SKELETON_KEY, "ITEM_KEY_SMALL" } }; Rando::Item plandomizerRandoRetrieveItem(RandomizerGet randoGetItem) { @@ -271,70 +259,71 @@ Rando::Item plandomizerRandoRetrieveItem(RandomizerGet randoGetItem) { return randoGetItemEntry; } -void PlandoPushImageButtonStyle(){ +void PlandoPushImageButtonStyle() { ImGui::PushStyleColor(ImGuiCol_Button, ImVec4(1.0f, 1.0f, 1.0f, 0.0f)); ImGui::PushStyleColor(ImGuiCol_ButtonHovered, ImVec4(1.0f, 1.0f, 1.0f, 0.2f)); ImGui::PushStyleColor(ImGuiCol_ButtonActive, ImVec4(1.0f, 1.0f, 1.0f, 0.1f)); } -void PlandoPopImageButtonStyle(){ +void PlandoPopImageButtonStyle() { ImGui::PopStyleColor(3); } ImVec4 plandomizerGetItemColor(Rando::Item randoItem) { - itemColor = ImVec4( 1.0f, 1.0f, 1.0f, 1.0f ); - if (randoItem.GetItemType() == ITEMTYPE_SMALLKEY || randoItem.GetItemType() == ITEMTYPE_FORTRESS_SMALLKEY - || randoItem.GetItemType() == ITEMTYPE_BOSSKEY) { - if (randoItem.GetRandomizerGet() == RG_FOREST_TEMPLE_SMALL_KEY || + itemColor = ImVec4(1.0f, 1.0f, 1.0f, 1.0f); + if (randoItem.GetItemType() == ITEMTYPE_SMALLKEY || randoItem.GetItemType() == ITEMTYPE_FORTRESS_SMALLKEY || + randoItem.GetItemType() == ITEMTYPE_BOSSKEY) { + if (randoItem.GetRandomizerGet() == RG_FOREST_TEMPLE_SMALL_KEY || randoItem.GetRandomizerGet() == RG_FOREST_TEMPLE_KEY_RING) { - itemColor = ImVec4( 0.02f, 0.76f, 0.18f, 1.0f ); - } else if (randoItem.GetRandomizerGet() == RG_FIRE_TEMPLE_SMALL_KEY || - randoItem.GetRandomizerGet() == RG_FIRE_TEMPLE_KEY_RING) { - itemColor = ImVec4( 0.93f, 0.37f, 0.37f, 1.0f ); - } else if (randoItem.GetRandomizerGet() == RG_WATER_TEMPLE_SMALL_KEY || - randoItem.GetRandomizerGet() == RG_WATER_TEMPLE_KEY_RING) { - itemColor = ImVec4( 0.33f, 0.71f, 0.87f, 1.0f ); - } else if (randoItem.GetRandomizerGet() == RG_SPIRIT_TEMPLE_SMALL_KEY || - randoItem.GetRandomizerGet() == RG_SPIRIT_TEMPLE_KEY_RING) { - itemColor = ImVec4( 0.87f, 0.62f, 0.18f, 1.0f ); - } else if (randoItem.GetRandomizerGet() == RG_SHADOW_TEMPLE_SMALL_KEY || - randoItem.GetRandomizerGet() == RG_SHADOW_TEMPLE_KEY_RING) { - itemColor = ImVec4( 0.49f, 0.06f, 0.69f, 1.0f ); - } else if (randoItem.GetRandomizerGet() == RG_BOTTOM_OF_THE_WELL_SMALL_KEY || - randoItem.GetRandomizerGet() == RG_BOTTOM_OF_THE_WELL_KEY_RING) { - itemColor = ImVec4( 0.89f, 0.43f, 1.0f, 1.0f ); - } else if (randoItem.GetRandomizerGet() == RG_GERUDO_TRAINING_GROUND_SMALL_KEY || - randoItem.GetRandomizerGet() == RG_GERUDO_TRAINING_GROUND_KEY_RING) { - itemColor = ImVec4( 1.0f, 1.0f, 0, 1.0f ); - } else if (randoItem.GetRandomizerGet() == RG_GERUDO_FORTRESS_SMALL_KEY || - randoItem.GetRandomizerGet() == RG_GERUDO_FORTRESS_KEY_RING) { - itemColor = ImVec4( 1.0f, 1.0f, 1.0f, 1.0f ); - } else if (randoItem.GetRandomizerGet() == RG_GANONS_CASTLE_SMALL_KEY || - randoItem.GetRandomizerGet() == RG_GANONS_CASTLE_KEY_RING) { - itemColor = ImVec4( 0.5f, 0.5f, 0.5f, 1.0f ); + itemColor = ImVec4(0.02f, 0.76f, 0.18f, 1.0f); + } else if (randoItem.GetRandomizerGet() == RG_FIRE_TEMPLE_SMALL_KEY || + randoItem.GetRandomizerGet() == RG_FIRE_TEMPLE_KEY_RING) { + itemColor = ImVec4(0.93f, 0.37f, 0.37f, 1.0f); + } else if (randoItem.GetRandomizerGet() == RG_WATER_TEMPLE_SMALL_KEY || + randoItem.GetRandomizerGet() == RG_WATER_TEMPLE_KEY_RING) { + itemColor = ImVec4(0.33f, 0.71f, 0.87f, 1.0f); + } else if (randoItem.GetRandomizerGet() == RG_SPIRIT_TEMPLE_SMALL_KEY || + randoItem.GetRandomizerGet() == RG_SPIRIT_TEMPLE_KEY_RING) { + itemColor = ImVec4(0.87f, 0.62f, 0.18f, 1.0f); + } else if (randoItem.GetRandomizerGet() == RG_SHADOW_TEMPLE_SMALL_KEY || + randoItem.GetRandomizerGet() == RG_SHADOW_TEMPLE_KEY_RING) { + itemColor = ImVec4(0.49f, 0.06f, 0.69f, 1.0f); + } else if (randoItem.GetRandomizerGet() == RG_BOTTOM_OF_THE_WELL_SMALL_KEY || + randoItem.GetRandomizerGet() == RG_BOTTOM_OF_THE_WELL_KEY_RING) { + itemColor = ImVec4(0.89f, 0.43f, 1.0f, 1.0f); + } else if (randoItem.GetRandomizerGet() == RG_GERUDO_TRAINING_GROUND_SMALL_KEY || + randoItem.GetRandomizerGet() == RG_GERUDO_TRAINING_GROUND_KEY_RING) { + itemColor = ImVec4(1.0f, 1.0f, 0, 1.0f); + } else if (randoItem.GetRandomizerGet() == RG_GERUDO_FORTRESS_SMALL_KEY || + randoItem.GetRandomizerGet() == RG_GERUDO_FORTRESS_KEY_RING) { + itemColor = ImVec4(1.0f, 1.0f, 1.0f, 1.0f); + } else if (randoItem.GetRandomizerGet() == RG_GANONS_CASTLE_SMALL_KEY || + randoItem.GetRandomizerGet() == RG_GANONS_CASTLE_KEY_RING) { + itemColor = ImVec4(0.5f, 0.5f, 0.5f, 1.0f); } return itemColor; } if (randoItem.GetItemType() == ITEMTYPE_SONG) { uint32_t questID = Rando::Logic::RandoGetToQuestItem[randoItem.GetRandomizerGet()]; - textureID = Ship::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName(songMapping.at((QuestItem)questID).name); + textureID = Ship::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName( + songMapping.at((QuestItem)questID).name); itemColor = songMapping.at((QuestItem)questID).color; imageSize = ImVec2(24.0f, 32.0f); imagePadding = 6.0f; return itemColor; } if (randoItem.GetRandomizerGet() >= RG_GREEN_RUPEE && randoItem.GetRandomizerGet() <= RG_HUGE_RUPEE) { - if (randoItem.GetRandomizerGet() == RG_GREG_RUPEE || randoItem.GetRandomizerGet() == RG_GREEN_RUPEE - || randoItem.GetRandomizerGet() == RG_TREASURE_GAME_GREEN_RUPEE) { - itemColor = ImVec4( 0.02f, 0.76f, 0.18f, 1.0f ); + if (randoItem.GetRandomizerGet() == RG_GREG_RUPEE || randoItem.GetRandomizerGet() == RG_GREEN_RUPEE || + randoItem.GetRandomizerGet() == RG_TREASURE_GAME_GREEN_RUPEE) { + itemColor = ImVec4(0.02f, 0.76f, 0.18f, 1.0f); } else if (randoItem.GetRandomizerGet() == RG_BLUE_RUPEE) { - itemColor = ImVec4( 0.33f, 0.71f, 0.87f, 1.0f ); + itemColor = ImVec4(0.33f, 0.71f, 0.87f, 1.0f); } else if (randoItem.GetRandomizerGet() == RG_RED_RUPEE) { - itemColor = ImVec4( 0.93f, 0.37f, 0.37f, 1.0f ); + itemColor = ImVec4(0.93f, 0.37f, 0.37f, 1.0f); } else if (randoItem.GetRandomizerGet() == RG_PURPLE_RUPEE) { - itemColor = ImVec4( 0.89f, 0.43f, 1.0f, 1.0f ); + itemColor = ImVec4(0.89f, 0.43f, 1.0f, 1.0f); } else if (randoItem.GetRandomizerGet() == RG_HUGE_RUPEE) { - itemColor = ImVec4( 1.0f, 1.0f, 0, 1.0f ); + itemColor = ImVec4(1.0f, 1.0f, 0, 1.0f); } return itemColor; } @@ -342,18 +331,17 @@ ImVec4 plandomizerGetItemColor(Rando::Item randoItem) { if (randoItem.GetRandomizerGet() >= RG_GOHMA_SOUL && randoItem.GetRandomizerGet() <= RG_GANON_SOUL) { itemColor = bossSoulColorMapping.at(randoItem.GetRandomizerGet()); } - + return itemColor; } std::string plandomizerHintsTooltip() { std::string hintTootip; - hintTootip = - "The following options are available:\n" - "- Use \\n to create New Lines.\n" - "- Use %g to change the text color to Green,\n" - " - %r for Red, %y for Yellow, and %w for White\n" - " can also be used as color examples."; + hintTootip = "The following options are available:\n" + "- Use \\n to create New Lines.\n" + "- Use %g to change the text color to Green,\n" + " - %r for Red, %y for Yellow, and %w for White\n" + " can also be used as color examples."; return hintTootip; } @@ -383,11 +371,10 @@ void PlandomizerPopulateSeedList() { void PlandomizerItemImageCorrection(Rando::Item randoItem) { textureID = 0; - imageSize = ImVec2( 32.0f, 32.0f ); + imageSize = ImVec2(32.0f, 32.0f); imagePadding = 2.0f; - textureUV0 = ImVec2( 0, 0 ); - textureUV1 = ImVec2( 1, 1 ); - + textureUV0 = ImVec2(0, 0); + textureUV1 = ImVec2(1, 1); itemColor = plandomizerGetItemColor(randoItem); @@ -404,12 +391,12 @@ void PlandomizerItemImageCorrection(Rando::Item randoItem) { if (map.first == randoItem.GetRandomizerGet()) { textureID = Ship::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName(map.second.c_str()); if (map.second.find("ITEM_ARROWS") != std::string::npos) { - textureUV0 = ImVec2( 0, 1 ); - textureUV1 = ImVec2( 1, 0 ); + textureUV0 = ImVec2(0, 1); + textureUV1 = ImVec2(1, 0); } if (map.second == "ITEM_TRIFORCE" || map.first == RG_SKELETON_KEY) { - textureUV0 = ImVec2( 1, 1 ); - textureUV1 = ImVec2( 0, 0 ); + textureUV0 = ImVec2(1, 1); + textureUV1 = ImVec2(0, 0); } break; } @@ -419,21 +406,25 @@ void PlandomizerItemImageCorrection(Rando::Item randoItem) { textureID = Ship::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName("BOSS_SOUL"); } - if (randoItem.GetRandomizerGet() >= RG_OCARINA_A_BUTTON && randoItem.GetRandomizerGet() <= RG_OCARINA_C_RIGHT_BUTTON) { + if (randoItem.GetRandomizerGet() >= RG_OCARINA_A_BUTTON && + randoItem.GetRandomizerGet() <= RG_OCARINA_C_RIGHT_BUTTON) { textureID = Ship::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName("ITEM_OCARINA_TIME"); } if (textureID == 0) { - textureID = Ship::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName(itemMapping[randoItem.GetGIEntry()->itemId].name); + textureID = Ship::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName( + itemMapping[randoItem.GetGIEntry()->itemId].name); } } void PlandomizerRandomizeHint(int32_t status, int32_t index) { if (status == HINT_SINGLE) { - plandoHintData[index].hintText = Rando::StaticData::hintTextTable[GetRandomJunkHint()].GetHintMessage().GetForCurrentLanguage(MF_ENCODE); + plandoHintData[index].hintText = + Rando::StaticData::hintTextTable[GetRandomJunkHint()].GetHintMessage().GetForCurrentLanguage(MF_ENCODE); } else { for (auto& hint : plandoHintData) { - hint.hintText = Rando::StaticData::hintTextTable[GetRandomJunkHint()].GetHintMessage().GetForCurrentLanguage(MF_ENCODE); + hint.hintText = + Rando::StaticData::hintTextTable[GetRandomJunkHint()].GetHintMessage().GetForCurrentLanguage(MF_ENCODE); } } } @@ -447,15 +438,14 @@ void PlandomizerRemoveAllHints() { } void PlandomizerSortDrawnItems() { - std::sort(drawnItemsList.begin(), drawnItemsList.end(), - [](const auto& a, const auto& b) { + std::sort(drawnItemsList.begin(), drawnItemsList.end(), [](const auto& a, const auto& b) { auto typeA = a.first.GetItemType(); auto typeB = b.first.GetItemType(); - if (typeA != typeB){ - return typeA < typeB; + if (typeA != typeB) { + return typeA < typeB; } return a.first.GetRandomizerGet() < b.first.GetRandomizerGet(); - }); + }); } void PlandomizerRemoveAllItems() { @@ -463,7 +453,8 @@ void PlandomizerRemoveAllItems() { drawnItemsList.clear(); } for (auto& remove : plandoLogData) { - if (std::find(infiniteItemList.begin(), infiniteItemList.end(), remove.checkRewardItem.GetRandomizerGet()) == infiniteItemList.end()) { + if (std::find(infiniteItemList.begin(), infiniteItemList.end(), remove.checkRewardItem.GetRandomizerGet()) == + infiniteItemList.end()) { bool itemExists = false; for (auto& itemToCheck : drawnItemsList) { if (itemToCheck.first.GetRandomizerGet() == remove.checkRewardItem.GetRandomizerGet()) { @@ -482,7 +473,8 @@ void PlandomizerRemoveAllItems() { } void PlandomizerRemoveFromItemList(Rando::Item randoItem) { - if (std::find(infiniteItemList.begin(), infiniteItemList.end(), randoItem.GetRandomizerGet()) == infiniteItemList.end()) { + if (std::find(infiniteItemList.begin(), infiniteItemList.end(), randoItem.GetRandomizerGet()) == + infiniteItemList.end()) { uint32_t index = 0; for (auto& itemToCheck : drawnItemsList) { if (itemToCheck.first.GetRandomizerGet() == randoItem.GetRandomizerGet()) { @@ -501,7 +493,8 @@ void PlandomizerRemoveFromItemList(Rando::Item randoItem) { } void PlandomizerAddToItemList(Rando::Item randoItem) { - if (std::find(infiniteItemList.begin(), infiniteItemList.end(), randoItem.GetRandomizerGet()) == infiniteItemList.end()) { + if (std::find(infiniteItemList.begin(), infiniteItemList.end(), randoItem.GetRandomizerGet()) == + infiniteItemList.end()) { bool itemExists = false; for (auto& itemToCheck : drawnItemsList) { if (itemToCheck.first.GetRandomizerGet() == randoItem.GetRandomizerGet()) { @@ -510,7 +503,7 @@ void PlandomizerAddToItemList(Rando::Item randoItem) { break; } } - + if (!itemExists) { drawnItemsList.push_back(std::make_pair(randoItem, 1)); } @@ -528,32 +521,24 @@ void PlandomizerSaveSpoilerLog() { inputFile.close(); } - spoilerSave["file_hash"] = { - plandoHash[0], plandoHash[1], plandoHash[2], plandoHash[3], plandoHash[4] - }; + spoilerSave["file_hash"] = { plandoHash[0], plandoHash[1], plandoHash[2], plandoHash[3], plandoHash[4] }; for (auto& import : plandoHintData) { - spoilerSave["Gossip Stone Hints"][import.hintName] = { - { "type", import.hintType.c_str() }, - { "message", import.hintText.c_str() } - }; + spoilerSave["Gossip Stone Hints"][import.hintName] = { { "type", import.hintType.c_str() }, + { "message", import.hintText.c_str() } }; } - + for (auto& import : plandoLogData) { if (import.checkRewardItem.GetRandomizerGet() == RG_ICE_TRAP) { - spoilerSave["locations"][import.checkName] = { - { "item", import.checkRewardItem.GetName().english }, - { "model", import.iceTrapModel.GetName().english }, - { "trickName", import.iceTrapName.c_str() } - }; + spoilerSave["locations"][import.checkName] = { { "item", import.checkRewardItem.GetName().english }, + { "model", import.iceTrapModel.GetName().english }, + { "trickName", import.iceTrapName.c_str() } }; if (import.shopPrice > -1) { spoilerSave["locations"][import.checkName]["price"] = import.shopPrice; } } else if (import.shopPrice > -1) { - spoilerSave["locations"][import.checkName] = { - { "item", import.checkRewardItem.GetName().english }, - { "price", import.shopPrice } - }; + spoilerSave["locations"][import.checkName] = { { "item", import.checkRewardItem.GetName().english }, + { "price", import.shopPrice } }; } else { spoilerSave["locations"][import.checkName] = import.checkRewardItem.GetName().english; } @@ -563,7 +548,7 @@ void PlandomizerSaveSpoilerLog() { if (outputFile.is_open()) { outputFile << spoilerSave.dump(4); outputFile.close(); - } + } } void PlandomizerLoadSpoilerLog(std::string logFile) { @@ -621,21 +606,24 @@ void PlandomizerLoadSpoilerLog(std::string logFile) { checkObject.checkName = key; auto type = value; if (value.is_object()) { - checkObject.checkRewardItem = plandomizerRandoRetrieveItem(Rando::StaticData::itemNameToEnum[value["item"]]); + checkObject.checkRewardItem = + plandomizerRandoRetrieveItem(Rando::StaticData::itemNameToEnum[value["item"]]); if (value["price"].is_number()) { checkObject.shopPrice = value["price"]; } else { checkObject.shopPrice = -1; } if (checkObject.checkRewardItem.GetRandomizerGet() == RG_ICE_TRAP) { - checkObject.iceTrapModel = plandomizerRandoRetrieveItem(Rando::StaticData::itemNameToEnum[value["model"]]); + checkObject.iceTrapModel = + plandomizerRandoRetrieveItem(Rando::StaticData::itemNameToEnum[value["model"]]); checkObject.iceTrapName = value["trickName"]; } } else { - checkObject.checkRewardItem = plandomizerRandoRetrieveItem(Rando::StaticData::itemNameToEnum[value.get()]); + checkObject.checkRewardItem = + plandomizerRandoRetrieveItem(Rando::StaticData::itemNameToEnum[value.get()]); checkObject.shopPrice = -1; - if (checkObject.shopPrice == -1 - && checkObject.checkRewardItem.GetName().english.find("Buy") != std::string::npos) { + if (checkObject.shopPrice == -1 && + checkObject.checkRewardItem.GetName().english.find("Buy") != std::string::npos) { checkObject.shopPrice = checkObject.checkRewardItem.GetPrice(); } } @@ -651,7 +639,7 @@ void PlandomizerLoadSpoilerLog(std::string logFile) { lastLoadedSpoiler = spoilerStr; } -void PlandomizerOverlayText(std::pair drawObject ) { +void PlandomizerOverlayText(std::pair drawObject) { // Overlay the item count text on the existing button ImVec2 imageMin = ImGui::GetItemRectMin(); ImVec2 imageMax = ImGui::GetItemRectMax(); @@ -662,15 +650,15 @@ void PlandomizerOverlayText(std::pair drawObject ) { ImGui::Text(std::to_string(drawObject.second).c_str()); // Overlay item info - if (drawObject.first.GetRandomizerGet() >= RG_PROGRESSIVE_HOOKSHOT && + if (drawObject.first.GetRandomizerGet() >= RG_PROGRESSIVE_HOOKSHOT && drawObject.first.GetRandomizerGet() <= RG_PROGRESSIVE_GORONSWORD) { textPos = ImVec2(imageMin.x + 2, imageMin.y + 2); ImGui::SetCursorScreenPos(textPos); ImGui::Text("+"); } - if (extractNumberInParentheses(drawObject.first.GetName().english.c_str()) != "" && - extractNumberInParentheses(drawObject.first.GetName().english.c_str()) != "WINNER" && + if (extractNumberInParentheses(drawObject.first.GetName().english.c_str()) != "" && + extractNumberInParentheses(drawObject.first.GetName().english.c_str()) != "WINNER" && extractNumberInParentheses(drawObject.first.GetName().english.c_str()) != "LOSER") { textPos = ImVec2(imageMin.x + 2, imageMin.y + 2); @@ -679,7 +667,7 @@ void PlandomizerOverlayText(std::pair drawObject ) { overlayText += extractNumberInParentheses(drawObject.first.GetName().english.c_str()); ImGui::Text(overlayText.c_str()); } - if (drawObject.first.GetRandomizerGet() >= RG_FOREST_TEMPLE_BOSS_KEY && + if (drawObject.first.GetRandomizerGet() >= RG_FOREST_TEMPLE_BOSS_KEY && drawObject.first.GetRandomizerGet() <= RG_GANONS_CASTLE_BOSS_KEY) { textPos = ImVec2(imageMin.x + 1, imageMin.y + 1); ImGui::SetCursorScreenPos(textPos); @@ -718,10 +706,12 @@ void PlandomizerDrawItemPopup(uint32_t index) { PlandomizerItemImageCorrection(plandomizerRandoRetrieveItem(item)); auto name = plandomizerRandoRetrieveItem(item).GetName().english; ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, ImVec2(imagePadding, imagePadding)); - auto ret = ImGui::ImageButton(name.c_str(), textureID, imageSize, textureUV0, textureUV1, ImVec4(0, 0, 0, 0), itemColor); + auto ret = ImGui::ImageButton(name.c_str(), textureID, imageSize, textureUV0, textureUV1, + ImVec4(0, 0, 0, 0), itemColor); ImGui::PopStyleVar(); if (ret) { - if (std::find(infiniteItemList.begin(), infiniteItemList.end(), plandoLogData[index].checkRewardItem.GetRandomizerGet()) == infiniteItemList.end()) { + if (std::find(infiniteItemList.begin(), infiniteItemList.end(), + plandoLogData[index].checkRewardItem.GetRandomizerGet()) == infiniteItemList.end()) { PlandomizerAddToItemList(plandoLogData[index].checkRewardItem); } plandoLogData[index].checkRewardItem = plandomizerRandoRetrieveItem(item); @@ -731,8 +721,7 @@ void PlandomizerDrawItemPopup(uint32_t index) { PlandomizerOverlayText(std::make_pair(plandomizerRandoRetrieveItem(item), 1)); ImGui::PopID(); } - - + ImGui::EndTable(); ImGui::SeparatorText("Spoiler Log Rewards"); ImGui::BeginTable("Item Button Table", 8); @@ -747,10 +736,11 @@ void PlandomizerDrawItemPopup(uint32_t index) { PlandomizerItemImageCorrection(drawSlots.first); auto name = drawSlots.first.GetName().english; ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, ImVec2(imagePadding, imagePadding)); - auto ret = ImGui::ImageButton(name.c_str(), textureID, imageSize, textureUV0, textureUV1, ImVec4(0, 0, 0, 0), itemColor); + auto ret = ImGui::ImageButton(name.c_str(), textureID, imageSize, textureUV0, textureUV1, + ImVec4(0, 0, 0, 0), itemColor); ImGui::PopStyleVar(); if (ret) { - if (itemToDraw.GetRandomizerGet() >= RG_PROGRESSIVE_HOOKSHOT && + if (itemToDraw.GetRandomizerGet() >= RG_PROGRESSIVE_HOOKSHOT && itemToDraw.GetRandomizerGet() <= RG_PROGRESSIVE_GORONSWORD) { plandoLogData[index].checkRewardItem = drawSlots.first; } else { @@ -796,7 +786,8 @@ void PlandomizerDrawIceTrapPopUp(uint32_t index) { auto name = Rando::StaticData::RetrieveItem(items.first).GetName().english; PlandomizerItemImageCorrection(Rando::StaticData::RetrieveItem(items.first)); ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, ImVec2(imagePadding, imagePadding)); - auto ret = ImGui::ImageButton(name.c_str(), textureID, imageSize, textureUV0, textureUV1, ImVec4(0, 0, 0, 0), itemColor); + auto ret = ImGui::ImageButton(name.c_str(), textureID, imageSize, textureUV0, textureUV1, + ImVec4(0, 0, 0, 0), itemColor); ImGui::PopStyleVar(); if (ret) { plandoLogData[index].iceTrapModel = Rando::StaticData::RetrieveItem(items.first); @@ -821,7 +812,8 @@ void PlandomizerDrawItemSlots(uint32_t index) { PlandomizerItemImageCorrection(plandoLogData[index].checkRewardItem); auto name = plandoLogData[index].checkRewardItem.GetName().english; ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, ImVec2(imagePadding, imagePadding)); - auto ret = ImGui::ImageButton(name.c_str(), textureID, imageSize, textureUV0, textureUV1, ImVec4(0, 0, 0, 0), itemColor); + auto ret = + ImGui::ImageButton(name.c_str(), textureID, imageSize, textureUV0, textureUV1, ImVec4(0, 0, 0, 0), itemColor); ImGui::PopStyleVar(); if (ret) { shouldPopup = true; @@ -837,9 +829,15 @@ void PlandomizerDrawItemSlots(uint32_t index) { void PlandomizerDrawShopSlider(uint32_t index) { ImGui::PushID(index); - UIWidgets::SliderInt("Price:", &plandoLogData[index].shopPrice, UIWidgets::IntSliderOptions() - .Color(THEME_COLOR).Format("%d Rupees").Min(0).Max(999).LabelPosition(UIWidgets::LabelPositions::Near) - .ComponentAlignment(UIWidgets::ComponentAlignments::Right).Size(UIWidgets::Sizes::Inline)); + UIWidgets::SliderInt("Price:", &plandoLogData[index].shopPrice, + UIWidgets::IntSliderOptions() + .Color(THEME_COLOR) + .Format("%d Rupees") + .Min(0) + .Max(999) + .LabelPosition(UIWidgets::LabelPositions::Near) + .ComponentAlignment(UIWidgets::ComponentAlignments::Right) + .Size(UIWidgets::Sizes::Inline)); ImGui::PopID(); } @@ -857,7 +855,8 @@ void PlandomizerDrawIceTrapSetup(uint32_t index) { PlandoPushImageButtonStyle(); auto name = plandoLogData[index].iceTrapModel.GetName().english; ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, ImVec2(imagePadding, imagePadding)); - auto ret = ImGui::ImageButton(name.c_str(), textureID, imageSize, textureUV0, textureUV1, ImVec4(0, 0, 0, 0), itemColor); + auto ret = + ImGui::ImageButton(name.c_str(), textureID, imageSize, textureUV0, textureUV1, ImVec4(0, 0, 0, 0), itemColor); ImGui::PopStyleVar(); if (ret) { shouldTrapPopup = true; @@ -870,23 +869,29 @@ void PlandomizerDrawIceTrapSetup(uint32_t index) { ImGui::TableNextColumn(); ImGui::Text("Name: "); ImGui::SameLine(); - if (plandoLogData[index].iceTrapModel.GetRandomizerGet() != RG_NONE && + if (plandoLogData[index].iceTrapModel.GetRandomizerGet() != RG_NONE && plandoLogData[index].iceTrapModel.GetRandomizerGet() != RG_SOLD_OUT) { - if (UIWidgets::Button(randomizeButton.c_str(), UIWidgets::ButtonOptions().Color(THEME_COLOR).Size(UIWidgets::Sizes::Inline).Padding(ImVec2(10.f, 6.f)))) { - plandoLogData[index].iceTrapName = - GetIceTrapName(plandoLogData[index].iceTrapModel.GetRandomizerGet()).GetForLanguage(CVarGetInteger(CVAR_SETTING("Languages"), 0)).c_str(); + if (UIWidgets::Button(randomizeButton.c_str(), UIWidgets::ButtonOptions() + .Color(THEME_COLOR) + .Size(UIWidgets::Sizes::Inline) + .Padding(ImVec2(10.f, 6.f)))) { + plandoLogData[index].iceTrapName = GetIceTrapName(plandoLogData[index].iceTrapModel.GetRandomizerGet()) + .GetForLanguage(CVarGetInteger(CVAR_SETTING("Languages"), 0)) + .c_str(); } ImGui::SameLine(); } - if (UIWidgets::InputString("##TrapName", &trapTextInput, UIWidgets::InputOptions().Color(THEME_COLOR).LabelPosition(UIWidgets::LabelPositions::None))) { - plandoLogData[index].iceTrapName = trapTextInput.c_str(); - } - + if (UIWidgets::InputString( + "##TrapName", &trapTextInput, + UIWidgets::InputOptions().Color(THEME_COLOR).LabelPosition(UIWidgets::LabelPositions::None))) { + plandoLogData[index].iceTrapName = trapTextInput.c_str(); + } + if (plandoLogData[index].shopPrice >= 0) { PlandomizerDrawShopSlider(index); } ImGui::EndTable(); - + ImGui::PopID(); } static std::unordered_map rcAreaNameMap = { @@ -933,9 +938,10 @@ void PlandomizerDrawOptions() { PlandomizerPopulateSeedList(); static size_t selectedList = 0; if (existingSeedList.size() != 0) { - UIWidgets::Combobox("##JsonFiles", &selectedList, existingSeedList, UIWidgets::ComboboxOptions().Color(THEME_COLOR).LabelPosition(UIWidgets::LabelPositions::None)); - } - else { + UIWidgets::Combobox( + "##JsonFiles", &selectedList, existingSeedList, + UIWidgets::ComboboxOptions().Color(THEME_COLOR).LabelPosition(UIWidgets::LabelPositions::None)); + } else { ImGui::Text("No Spoiler Logs found."); } ImGui::BeginDisabled(existingSeedList.empty()); @@ -965,29 +971,32 @@ void PlandomizerDrawOptions() { PlandoPushImageButtonStyle(); for (auto& hash : plandoHash) { ImGui::PushID(index); - textureID = Ship::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName(gSeedTextures[hash].tex); + textureID = + Ship::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName(gSeedTextures[hash].tex); ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, ImVec2(2.0f, 2.0f)); - auto upRet = ImGui::ImageButton("HASH_ARROW_UP", Ship::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName("HASH_ARROW_UP"), - ImVec2(35.0f, 18.0f), ImVec2(1, 1), ImVec2(0, 0), ImVec4(0, 0, 0, 0), ImVec4(1, 1, 1, 1)); + auto upRet = ImGui::ImageButton( + "HASH_ARROW_UP", + Ship::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName("HASH_ARROW_UP"), + ImVec2(35.0f, 18.0f), ImVec2(1, 1), ImVec2(0, 0), ImVec4(0, 0, 0, 0), ImVec4(1, 1, 1, 1)); ImGui::PopStyleVar(); if (upRet) { if (hash + 1 >= gSeedTextures.size()) { hash = 0; - } - else { + } else { hash++; } } ImGui::Image(textureID, ImVec2(35.0f, 35.0f)); ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, ImVec2(2.0f, 2.0f)); - auto downRet = ImGui::ImageButton("HASH_ARROW_DWN", Ship::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName("HASH_ARROW_DWN"), - ImVec2(35.0f, 18.0f), ImVec2(0, 0), ImVec2(1, 1), ImVec4(0, 0, 0, 0), ImVec4(1, 1, 1, 1)); + auto downRet = ImGui::ImageButton( + "HASH_ARROW_DWN", + Ship::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName("HASH_ARROW_DWN"), + ImVec2(35.0f, 18.0f), ImVec2(0, 0), ImVec2(1, 1), ImVec4(0, 0, 0, 0), ImVec4(1, 1, 1, 1)); ImGui::PopStyleVar(); if (downRet) { if (hash == 0) { hash = gSeedTextures.size() - 1; - } - else { + } else { hash--; } } @@ -1000,13 +1009,12 @@ void PlandomizerDrawOptions() { PlandoPopImageButtonStyle(); ImGui::EndTable(); } - } - else { + } else { ImGui::Text("No Spoiler Log Loaded"); } ImGui::EndTable(); } - + ImGui::SeparatorText("Options"); if (plandoLogData.size() == 0) { ImGui::Text("Please Load Spoiler Data..."); @@ -1014,19 +1022,28 @@ void PlandomizerDrawOptions() { } if (getTabID == TAB_HINTS) { - if (UIWidgets::Button("Clear All Hints", UIWidgets::ButtonOptions().Color(THEME_COLOR).Size(UIWidgets::Sizes::Inline))) { + if (UIWidgets::Button("Clear All Hints", + UIWidgets::ButtonOptions().Color(THEME_COLOR).Size(UIWidgets::Sizes::Inline))) { PlandomizerRemoveAllHints(); } ImGui::SameLine(); - if (UIWidgets::Button("Randomize All Hints", UIWidgets::ButtonOptions().Color(THEME_COLOR).Size(UIWidgets::Sizes::Inline))) { + if (UIWidgets::Button("Randomize All Hints", + UIWidgets::ButtonOptions().Color(THEME_COLOR).Size(UIWidgets::Sizes::Inline))) { PlandomizerRandomizeHint(HINT_ALL, 0); } } if (getTabID == TAB_LOCATIONS) { if (plandoLogData.size() > 0) { - UIWidgets::Combobox("Filter by Area:##AreaFilter", &selectedArea, rcAreaNameMap, UIWidgets::ComboboxOptions().Color(THEME_COLOR).LabelPosition(UIWidgets::LabelPositions::Near).ComponentAlignment(UIWidgets::ComponentAlignments::Right)); + UIWidgets::Combobox("Filter by Area:##AreaFilter", &selectedArea, rcAreaNameMap, + UIWidgets::ComboboxOptions() + .Color(THEME_COLOR) + .LabelPosition(UIWidgets::LabelPositions::Near) + .ComponentAlignment(UIWidgets::ComponentAlignments::Right)); ImGui::SameLine(); - if (UIWidgets::Button("Empty All Rewards", UIWidgets::ButtonOptions().Color(THEME_COLOR).Size(UIWidgets::Sizes::Inline).Padding(ImVec2(10.f, 6.f)))) { + if (UIWidgets::Button("Empty All Rewards", UIWidgets::ButtonOptions() + .Color(THEME_COLOR) + .Size(UIWidgets::Sizes::Inline) + .Padding(ImVec2(10.f, 6.f)))) { PlandomizerRemoveAllItems(); } } @@ -1056,12 +1073,20 @@ void PlandomizerDrawHintsWindow() { } ImGui::Text("New Hint: "); ImGui::SameLine(); - if (UIWidgets::Button(randomizeButton.c_str(), UIWidgets::ButtonOptions().Color(THEME_COLOR).Padding(ImVec2(10.f, 6.f)).Size(UIWidgets::Sizes::Inline).Tooltip("Randomize Hint"))) { + if (UIWidgets::Button(randomizeButton.c_str(), UIWidgets::ButtonOptions() + .Color(THEME_COLOR) + .Padding(ImVec2(10.f, 6.f)) + .Size(UIWidgets::Sizes::Inline) + .Tooltip("Randomize Hint"))) { PlandomizerRandomizeHint(HINT_SINGLE, index); } ImGui::SameLine(); ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x - 10); - if (UIWidgets::InputString("##HintMessage", &hintInputText, UIWidgets::InputOptions().Color(THEME_COLOR).LabelPosition(UIWidgets::LabelPositions::None).Tooltip(plandomizerHintsTooltip().c_str()))) { + if (UIWidgets::InputString("##HintMessage", &hintInputText, + UIWidgets::InputOptions() + .Color(THEME_COLOR) + .LabelPosition(UIWidgets::LabelPositions::None) + .Tooltip(plandomizerHintsTooltip().c_str()))) { plandoHintData[index].hintText = hintInputText.c_str(); } index++; @@ -1079,7 +1104,8 @@ void PlandomizerDrawLocationsWindow(RandomizerCheckArea rcArea) { if (ImGui::BeginTable("Locations Window", 4, ImGuiTableFlags_BordersInnerV | ImGuiTableFlags_ScrollY)) { ImGui::TableSetupColumn("Spoiler Log Check Name", ImGuiTableColumnFlags_WidthFixed, 250.0f); ImGui::TableSetupColumn("Spoiler Log Reward", ImGuiTableColumnFlags_WidthFixed, 190.0f); - ImGui::TableSetupColumn("New Reward", ImGuiTableColumnFlags_WidthFixed | ImGuiTableColumnFlags_NoHeaderLabel, 34.0f); + ImGui::TableSetupColumn("New Reward", ImGuiTableColumnFlags_WidthFixed | ImGuiTableColumnFlags_NoHeaderLabel, + 34.0f); ImGui::TableSetupColumn("Additional Options"); ImGui::TableSetupScrollFreeze(0, 1); ImGui::TableHeadersRow(); @@ -1097,8 +1123,7 @@ void PlandomizerDrawLocationsWindow(RandomizerCheckArea rcArea) { if (plandoLogData[index].checkRewardItem.GetRandomizerGet() == RG_ICE_TRAP) { ImGui::TableNextColumn(); PlandomizerDrawIceTrapSetup(index); - } - else if (spoilerData.shopPrice != -1) { + } else if (spoilerData.shopPrice != -1) { ImGui::TableNextColumn(); ImGui::BeginTable("Shops", 1, ImGuiTableFlags_BordersOuter | ImGuiTableFlags_BordersInner); ImGui::TableSetupColumn("Shop Price"); @@ -1106,8 +1131,7 @@ void PlandomizerDrawLocationsWindow(RandomizerCheckArea rcArea) { ImGui::TableNextColumn(); PlandomizerDrawShopSlider(index); ImGui::EndTable(); - } - else { + } else { ImGui::TableNextColumn(); } } @@ -1145,15 +1169,25 @@ void PlandomizerWindow::DrawElement() { } void PlandomizerWindow::InitElement() { - Ship::Context::GetInstance()->GetWindow()->GetGui()->LoadGuiTexture("ITEM_RUPEE_GRAYSCALE", gRupeeCounterIconTex, ImVec4(1, 1, 1, 1)); - Ship::Context::GetInstance()->GetWindow()->GetGui()->LoadGuiTexture("ITEM_HEART_GRAYSCALE", gHeartFullTex, ImVec4(0.87f, 0.10f, 0.10f, 1)); - Ship::Context::GetInstance()->GetWindow()->GetGui()->LoadGuiTexture("ITEM_SEEDS", gItemIconDekuSeedsTex, ImVec4( 1, 1, 1, 1 )); - Ship::Context::GetInstance()->GetWindow()->GetGui()->LoadGuiTexture("ITEM_ARROWS_SMALL", gDropArrows1Tex, ImVec4( 1, 1, 1, 1 )); - Ship::Context::GetInstance()->GetWindow()->GetGui()->LoadGuiTexture("ITEM_ARROWS_MEDIUM", gDropArrows2Tex, ImVec4( 1, 1, 1, 1 )); - Ship::Context::GetInstance()->GetWindow()->GetGui()->LoadGuiTexture("ITEM_ARROWS_LARGE", gDropArrows3Tex, ImVec4( 1, 1, 1, 1 )); - Ship::Context::GetInstance()->GetWindow()->GetGui()->LoadGuiTexture("ITEM_ICE_TRAP", gMagicArrowEquipEffectTex, ImVec4( 1, 1, 1, 1 )); - Ship::Context::GetInstance()->GetWindow()->GetGui()->LoadGuiTexture("HASH_ARROW_UP", gEmptyCDownArrowTex, ImVec4( 1, 1, 1, 1 )); - Ship::Context::GetInstance()->GetWindow()->GetGui()->LoadGuiTexture("HASH_ARROW_DWN", gEmptyCDownArrowTex, ImVec4( 1, 1, 1, 1 )); + Ship::Context::GetInstance()->GetWindow()->GetGui()->LoadGuiTexture("ITEM_RUPEE_GRAYSCALE", gRupeeCounterIconTex, + ImVec4(1, 1, 1, 1)); + Ship::Context::GetInstance()->GetWindow()->GetGui()->LoadGuiTexture("ITEM_HEART_GRAYSCALE", gHeartFullTex, + ImVec4(0.87f, 0.10f, 0.10f, 1)); + Ship::Context::GetInstance()->GetWindow()->GetGui()->LoadGuiTexture("ITEM_SEEDS", gItemIconDekuSeedsTex, + ImVec4(1, 1, 1, 1)); + Ship::Context::GetInstance()->GetWindow()->GetGui()->LoadGuiTexture("ITEM_ARROWS_SMALL", gDropArrows1Tex, + ImVec4(1, 1, 1, 1)); + Ship::Context::GetInstance()->GetWindow()->GetGui()->LoadGuiTexture("ITEM_ARROWS_MEDIUM", gDropArrows2Tex, + ImVec4(1, 1, 1, 1)); + Ship::Context::GetInstance()->GetWindow()->GetGui()->LoadGuiTexture("ITEM_ARROWS_LARGE", gDropArrows3Tex, + ImVec4(1, 1, 1, 1)); + Ship::Context::GetInstance()->GetWindow()->GetGui()->LoadGuiTexture("ITEM_ICE_TRAP", gMagicArrowEquipEffectTex, + ImVec4(1, 1, 1, 1)); + Ship::Context::GetInstance()->GetWindow()->GetGui()->LoadGuiTexture("HASH_ARROW_UP", gEmptyCDownArrowTex, + ImVec4(1, 1, 1, 1)); + Ship::Context::GetInstance()->GetWindow()->GetGui()->LoadGuiTexture("HASH_ARROW_DWN", gEmptyCDownArrowTex, + ImVec4(1, 1, 1, 1)); Ship::Context::GetInstance()->GetWindow()->GetGui()->LoadGuiTexture("BOSS_SOUL", gBossSoulTex, ImVec4(1, 1, 1, 1)); - Ship::Context::GetInstance()->GetWindow()->GetGui()->LoadGuiTexture("TRIFORCE_PIECE", gTriforcePieceTex, ImVec4(1, 1, 1, 1)); + Ship::Context::GetInstance()->GetWindow()->GetGui()->LoadGuiTexture("TRIFORCE_PIECE", gTriforcePieceTex, + ImVec4(1, 1, 1, 1)); } diff --git a/soh/soh/Enhancements/randomizer/ShuffleCows.cpp b/soh/soh/Enhancements/randomizer/ShuffleCows.cpp index 168dcee45..203981133 100644 --- a/soh/soh/Enhancements/randomizer/ShuffleCows.cpp +++ b/soh/soh/Enhancements/randomizer/ShuffleCows.cpp @@ -38,7 +38,8 @@ void RegisterShuffleCows() { COND_VB_SHOULD(VB_GIVE_ITEM_FROM_COW, shouldRegister, { EnCow* enCow = va_arg(args, EnCow*); - CowIdentity cowIdentity = OTRGlobals::Instance->gRandomizer->IdentifyCow(gPlayState->sceneNum, enCow->actor.world.pos.x, enCow->actor.world.pos.z); + CowIdentity cowIdentity = OTRGlobals::Instance->gRandomizer->IdentifyCow( + gPlayState->sceneNum, enCow->actor.world.pos.x, enCow->actor.world.pos.z); // Has this cow already rewarded an item? if (!Flags_GetRandomizerInf(cowIdentity.randomizerInf)) { Flags_SetRandomizerInf(cowIdentity.randomizerInf); @@ -60,7 +61,8 @@ static RegisterShipInitFunc initFunc(RegisterShuffleCows, { "IS_RANDO" }); void Rando::StaticData::RegisterCowLocations() { static bool registered = false; - if (registered) return; + if (registered) + return; registered = true; // clang-format off locationTable[RC_KF_LINKS_HOUSE_COW] = Location::Base(RC_KF_LINKS_HOUSE_COW, RCQUEST_BOTH, RCTYPE_COW, ACTOR_EN_COW, SCENE_LINKS_HOUSE, 0x00, "Links House Cow", RHT_KF_LINKS_HOUSE_COW, RG_MILK, SpoilerCollectionCheck::RandomizerInf(RAND_INF_COWS_MILKED_KF_LINKS_HOUSE_COW)); diff --git a/soh/soh/Enhancements/randomizer/ShuffleCrates.cpp b/soh/soh/Enhancements/randomizer/ShuffleCrates.cpp index 3c75c7c6c..3cb341980 100644 --- a/soh/soh/Enhancements/randomizer/ShuffleCrates.cpp +++ b/soh/soh/Enhancements/randomizer/ShuffleCrates.cpp @@ -25,63 +25,66 @@ extern "C" void ObjKibako2_RandomizerDraw(Actor* thisx, PlayState* play) { int csmc = CVarGetInteger(CVAR_ENHANCEMENT("ChestSizeAndTextureMatchContents"), CSMC_DISABLED); int requiresStoneAgony = CVarGetInteger(CVAR_ENHANCEMENT("ChestSizeDependsStoneOfAgony"), 0); - int isVanilla = csmc == CSMC_DISABLED || csmc == CSMC_SIZE || (requiresStoneAgony && !CHECK_QUEST_ITEM(QUEST_STONE_OF_AGONY)); + int isVanilla = + csmc == CSMC_DISABLED || csmc == CSMC_SIZE || (requiresStoneAgony && !CHECK_QUEST_ITEM(QUEST_STONE_OF_AGONY)); if (isVanilla) { Gfx_DrawDListOpa(play, (Gfx*)gLargeRandoCrateDL); return; - } - + } + GetItemEntry crateItem = Rando::Context::GetInstance()->GetFinalGIEntry(crateActor->crateIdentity.randomizerCheck, true, GI_NONE); getItemCategory = crateItem.getItemCategory; - + // If they have bombchus, don't consider the bombchu item major if (INV_CONTENT(ITEM_BOMBCHU) == ITEM_BOMBCHU && - ((crateItem.modIndex == MOD_RANDOMIZER && crateItem.getItemId == RG_PROGRESSIVE_BOMBCHUS) || - (crateItem.modIndex == MOD_NONE && - (crateItem.getItemId == GI_BOMBCHUS_5 || crateItem.getItemId == GI_BOMBCHUS_10 || + ((crateItem.modIndex == MOD_RANDOMIZER && crateItem.getItemId == RG_PROGRESSIVE_BOMBCHUS) || + (crateItem.modIndex == MOD_NONE && + (crateItem.getItemId == GI_BOMBCHUS_5 || crateItem.getItemId == GI_BOMBCHUS_10 || crateItem.getItemId == GI_BOMBCHUS_20)))) { getItemCategory = ITEM_CATEGORY_JUNK; // If it's a bottle and they already have one, consider the item lesser - } else if ((crateItem.modIndex == MOD_RANDOMIZER && crateItem.getItemId >= RG_BOTTLE_WITH_RED_POTION && crateItem.getItemId <= RG_BOTTLE_WITH_POE) || - (crateItem.modIndex == MOD_NONE && (crateItem.getItemId == GI_BOTTLE || crateItem.getItemId == GI_MILK_BOTTLE))) { + } else if ((crateItem.modIndex == MOD_RANDOMIZER && crateItem.getItemId >= RG_BOTTLE_WITH_RED_POTION && + crateItem.getItemId <= RG_BOTTLE_WITH_POE) || + (crateItem.modIndex == MOD_NONE && + (crateItem.getItemId == GI_BOTTLE || crateItem.getItemId == GI_MILK_BOTTLE))) { if (gSaveContext.inventory.items[SLOT_BOTTLE_1] != ITEM_NONE) { getItemCategory = ITEM_CATEGORY_LESSER; } } - // Change texture - switch (getItemCategory) { - case ITEM_CATEGORY_MAJOR: - Gfx_DrawDListOpa(play, (Gfx*)gLargeMajorCrateDL); - break; - case ITEM_CATEGORY_SKULLTULA_TOKEN: - Gfx_DrawDListOpa(play, (Gfx*)gLargeTokenCrateDL); - break; - case ITEM_CATEGORY_SMALL_KEY: - Gfx_DrawDListOpa(play, (Gfx*)gLargeSmallKeyCrateDL); - break; - case ITEM_CATEGORY_BOSS_KEY: - Gfx_DrawDListOpa(play, (Gfx*)gLargeBossKeyCrateDL); - break; - case ITEM_CATEGORY_LESSER: - switch (crateItem.itemId) { - case ITEM_HEART_PIECE: - case ITEM_HEART_PIECE_2: - case ITEM_HEART_CONTAINER: - Gfx_DrawDListOpa(play, (Gfx*)gLargeHeartCrateDL); - break; - default: - Gfx_DrawDListOpa(play, (Gfx*)gLargeMinorCrateDL); - break; - } - break; - case ITEM_CATEGORY_JUNK: - default: - Gfx_DrawDListOpa(play, (Gfx*)gLargeJunkCrateDL); - break; - } + // Change texture + switch (getItemCategory) { + case ITEM_CATEGORY_MAJOR: + Gfx_DrawDListOpa(play, (Gfx*)gLargeMajorCrateDL); + break; + case ITEM_CATEGORY_SKULLTULA_TOKEN: + Gfx_DrawDListOpa(play, (Gfx*)gLargeTokenCrateDL); + break; + case ITEM_CATEGORY_SMALL_KEY: + Gfx_DrawDListOpa(play, (Gfx*)gLargeSmallKeyCrateDL); + break; + case ITEM_CATEGORY_BOSS_KEY: + Gfx_DrawDListOpa(play, (Gfx*)gLargeBossKeyCrateDL); + break; + case ITEM_CATEGORY_LESSER: + switch (crateItem.itemId) { + case ITEM_HEART_PIECE: + case ITEM_HEART_PIECE_2: + case ITEM_HEART_CONTAINER: + Gfx_DrawDListOpa(play, (Gfx*)gLargeHeartCrateDL); + break; + default: + Gfx_DrawDListOpa(play, (Gfx*)gLargeMinorCrateDL); + break; + } + break; + case ITEM_CATEGORY_JUNK: + default: + Gfx_DrawDListOpa(play, (Gfx*)gLargeJunkCrateDL); + break; + } } extern "C" void ObjKibako_RandomizerDraw(Actor* thisx, PlayState* play) { @@ -90,62 +93,66 @@ extern "C" void ObjKibako_RandomizerDraw(Actor* thisx, PlayState* play) { int csmc = CVarGetInteger(CVAR_ENHANCEMENT("ChestSizeAndTextureMatchContents"), CSMC_DISABLED); int requiresStoneAgony = CVarGetInteger(CVAR_ENHANCEMENT("ChestSizeDependsStoneOfAgony"), 0); - int isVanilla = csmc == CSMC_DISABLED || csmc == CSMC_SIZE || (requiresStoneAgony && !CHECK_QUEST_ITEM(QUEST_STONE_OF_AGONY)); - + int isVanilla = + csmc == CSMC_DISABLED || csmc == CSMC_SIZE || (requiresStoneAgony && !CHECK_QUEST_ITEM(QUEST_STONE_OF_AGONY)); + if (isVanilla) { Gfx_DrawDListOpa(play, (Gfx*)gSmallRandoCrateDL); return; - } + } - GetItemEntry smallCrateItem = Rando::Context::GetInstance()->GetFinalGIEntry(smallCrateActor->smallCrateIdentity.randomizerCheck, true, GI_NONE); + GetItemEntry smallCrateItem = Rando::Context::GetInstance()->GetFinalGIEntry( + smallCrateActor->smallCrateIdentity.randomizerCheck, true, GI_NONE); getItemCategory = smallCrateItem.getItemCategory; // If they have bombchus, don't consider the bombchu item major if (INV_CONTENT(ITEM_BOMBCHU) == ITEM_BOMBCHU && ((smallCrateItem.modIndex == MOD_RANDOMIZER && smallCrateItem.getItemId == RG_PROGRESSIVE_BOMBCHUS) || (smallCrateItem.modIndex == MOD_NONE && - (smallCrateItem.getItemId == GI_BOMBCHUS_5 || smallCrateItem.getItemId == GI_BOMBCHUS_10 || smallCrateItem.getItemId == GI_BOMBCHUS_20)))) { + (smallCrateItem.getItemId == GI_BOMBCHUS_5 || smallCrateItem.getItemId == GI_BOMBCHUS_10 || + smallCrateItem.getItemId == GI_BOMBCHUS_20)))) { getItemCategory = ITEM_CATEGORY_JUNK; // If it's a bottle and they already have one, consider the item lesser } else if ((smallCrateItem.modIndex == MOD_RANDOMIZER && smallCrateItem.getItemId >= RG_BOTTLE_WITH_RED_POTION && smallCrateItem.getItemId <= RG_BOTTLE_WITH_POE) || - (smallCrateItem.modIndex == MOD_NONE && (smallCrateItem.getItemId == GI_BOTTLE || smallCrateItem.getItemId == GI_MILK_BOTTLE))) { + (smallCrateItem.modIndex == MOD_NONE && + (smallCrateItem.getItemId == GI_BOTTLE || smallCrateItem.getItemId == GI_MILK_BOTTLE))) { if (gSaveContext.inventory.items[SLOT_BOTTLE_1] != ITEM_NONE) { getItemCategory = ITEM_CATEGORY_LESSER; } } // Change texture - switch (getItemCategory) { - case ITEM_CATEGORY_MAJOR: - Gfx_DrawDListOpa(play, (Gfx*)gSmallMajorCrateDL); - break; - case ITEM_CATEGORY_SKULLTULA_TOKEN: - Gfx_DrawDListOpa(play, (Gfx*)gSmallTokenCrateDL); - break; - case ITEM_CATEGORY_SMALL_KEY: - Gfx_DrawDListOpa(play, (Gfx*)gSmallSmallKeyCrateDL); - break; - case ITEM_CATEGORY_BOSS_KEY: - Gfx_DrawDListOpa(play, (Gfx*)gSmallBossKeyCrateDL); - break; - case ITEM_CATEGORY_LESSER: - switch (smallCrateItem.itemId) { - case ITEM_HEART_PIECE: - case ITEM_HEART_PIECE_2: - case ITEM_HEART_CONTAINER: - Gfx_DrawDListOpa(play, (Gfx*)gSmallHeartCrateDL); - break; - default: - Gfx_DrawDListOpa(play, (Gfx*)gSmallMinorCrateDL); - break; - } - break; - case ITEM_CATEGORY_JUNK: - default: - Gfx_DrawDListOpa(play, (Gfx*)gSmallJunkCrateDL); - break; - } + switch (getItemCategory) { + case ITEM_CATEGORY_MAJOR: + Gfx_DrawDListOpa(play, (Gfx*)gSmallMajorCrateDL); + break; + case ITEM_CATEGORY_SKULLTULA_TOKEN: + Gfx_DrawDListOpa(play, (Gfx*)gSmallTokenCrateDL); + break; + case ITEM_CATEGORY_SMALL_KEY: + Gfx_DrawDListOpa(play, (Gfx*)gSmallSmallKeyCrateDL); + break; + case ITEM_CATEGORY_BOSS_KEY: + Gfx_DrawDListOpa(play, (Gfx*)gSmallBossKeyCrateDL); + break; + case ITEM_CATEGORY_LESSER: + switch (smallCrateItem.itemId) { + case ITEM_HEART_PIECE: + case ITEM_HEART_PIECE_2: + case ITEM_HEART_CONTAINER: + Gfx_DrawDListOpa(play, (Gfx*)gSmallHeartCrateDL); + break; + default: + Gfx_DrawDListOpa(play, (Gfx*)gSmallMinorCrateDL); + break; + } + break; + case ITEM_CATEGORY_JUNK: + default: + Gfx_DrawDListOpa(play, (Gfx*)gSmallJunkCrateDL); + break; + } } uint8_t ObjKibako2_RandomizerHoldsItem(ObjKibako2* crateActor, PlayState* play) { @@ -183,7 +190,8 @@ uint8_t ObjKibako_RandomizerHoldsItem(ObjKibako* smallCrateActor, PlayState* pla void ObjKibako2_RandomizerSpawnCollectible(ObjKibako2* crateActor, PlayState* play) { EnItem00* item00 = (EnItem00*)Item_DropCollectible2(play, &crateActor->dyna.actor.world.pos, ITEM00_SOH_DUMMY); item00->randoInf = crateActor->crateIdentity.randomizerInf; - item00->itemEntry = Rando::Context::GetInstance()->GetFinalGIEntry(crateActor->crateIdentity.randomizerCheck, true, GI_NONE); + item00->itemEntry = + Rando::Context::GetInstance()->GetFinalGIEntry(crateActor->crateIdentity.randomizerCheck, true, GI_NONE); item00->actor.draw = (ActorFunc)EnItem00_DrawRandomizedItem; item00->actor.velocity.y = 8.0f; item00->actor.speedXZ = 2.0f; @@ -193,8 +201,8 @@ void ObjKibako2_RandomizerSpawnCollectible(ObjKibako2* crateActor, PlayState* pl void ObjKibako_RandomizerSpawnCollectible(ObjKibako* smallCrateActor, PlayState* play) { EnItem00* item00 = (EnItem00*)Item_DropCollectible2(play, &smallCrateActor->actor.world.pos, ITEM00_SOH_DUMMY); item00->randoInf = smallCrateActor->smallCrateIdentity.randomizerInf; - item00->itemEntry = - Rando::Context::GetInstance()->GetFinalGIEntry(smallCrateActor->smallCrateIdentity.randomizerCheck, true, GI_NONE); + item00->itemEntry = Rando::Context::GetInstance()->GetFinalGIEntry( + smallCrateActor->smallCrateIdentity.randomizerCheck, true, GI_NONE); item00->actor.draw = (ActorFunc)EnItem00_DrawRandomizedItem; item00->actor.velocity.y = 8.0f; item00->actor.speedXZ = 2.0f; @@ -207,29 +215,38 @@ void ObjKibako2_RandomizerInit(void* actorRef) { // don't shuffle two OOB crates in GF and don't shuffle child GV/GF crates when not in no logic if (actor->id != ACTOR_OBJ_KIBAKO2 || - (gPlayState->sceneNum == SCENE_GERUDOS_FORTRESS && (s16)actor->world.pos.x == -4051 && (s16)actor->world.pos.z == -3429) || - (gPlayState->sceneNum == SCENE_GERUDOS_FORTRESS && (s16)actor->world.pos.x == -4571 && (s16)actor->world.pos.z == -3429) || - (logicSetting != RO_LOGIC_NO_LOGIC && - ((gPlayState->sceneNum == SCENE_GERUDOS_FORTRESS && (s16)actor->world.pos.x == 3443 && (s16)actor->world.pos.z == -4876) || - (gPlayState->sceneNum == SCENE_GERUDO_VALLEY && (s16)actor->world.pos.x == -764 && (s16)actor->world.pos.z == 148) || - (gPlayState->sceneNum == SCENE_GERUDO_VALLEY && (s16)actor->world.pos.x == -860 && (s16)actor->world.pos.z == -125) || - (gPlayState->sceneNum == SCENE_GERUDO_VALLEY && (s16)actor->world.pos.x == -860 && (s16)actor->world.pos.z == -150) || - (gPlayState->sceneNum == SCENE_GERUDO_VALLEY && (s16)actor->world.pos.x == -860 && (s16)actor->world.pos.z == -90)))) + (gPlayState->sceneNum == SCENE_GERUDOS_FORTRESS && (s16)actor->world.pos.x == -4051 && + (s16)actor->world.pos.z == -3429) || + (gPlayState->sceneNum == SCENE_GERUDOS_FORTRESS && (s16)actor->world.pos.x == -4571 && + (s16)actor->world.pos.z == -3429) || + (logicSetting != RO_LOGIC_NO_LOGIC && ((gPlayState->sceneNum == SCENE_GERUDOS_FORTRESS && + (s16)actor->world.pos.x == 3443 && (s16)actor->world.pos.z == -4876) || + (gPlayState->sceneNum == SCENE_GERUDO_VALLEY && + (s16)actor->world.pos.x == -764 && (s16)actor->world.pos.z == 148) || + (gPlayState->sceneNum == SCENE_GERUDO_VALLEY && + (s16)actor->world.pos.x == -860 && (s16)actor->world.pos.z == -125) || + (gPlayState->sceneNum == SCENE_GERUDO_VALLEY && + (s16)actor->world.pos.x == -860 && (s16)actor->world.pos.z == -150) || + (gPlayState->sceneNum == SCENE_GERUDO_VALLEY && + (s16)actor->world.pos.x == -860 && (s16)actor->world.pos.z == -90)))) return; ObjKibako2* crateActor = static_cast(actorRef); - crateActor->crateIdentity = OTRGlobals::Instance->gRandomizer->IdentifyCrate(gPlayState->sceneNum, (s16)actor->world.pos.x, (s16)actor->world.pos.z); + crateActor->crateIdentity = OTRGlobals::Instance->gRandomizer->IdentifyCrate( + gPlayState->sceneNum, (s16)actor->world.pos.x, (s16)actor->world.pos.z); } void ObjKibako_RandomizerInit(void* actorRef) { Actor* actor = static_cast(actorRef); - if (actor->id != ACTOR_OBJ_KIBAKO) return; + if (actor->id != ACTOR_OBJ_KIBAKO) + return; ObjKibako* smallCrateActor = static_cast(actorRef); - smallCrateActor->smallCrateIdentity = OTRGlobals::Instance->gRandomizer->IdentifySmallCrate(gPlayState->sceneNum, (s16)actor->home.pos.x, (s16)actor->home.pos.z); + smallCrateActor->smallCrateIdentity = OTRGlobals::Instance->gRandomizer->IdentifySmallCrate( + gPlayState->sceneNum, (s16)actor->home.pos.x, (s16)actor->home.pos.z); } void RegisterShuffleCrates() { @@ -274,12 +291,12 @@ void RegisterShuffleCrates() { *should = true; } }); - } void Rando::StaticData::RegisterCrateLocations() { static bool registered = false; - if (registered) return; + if (registered) + return; registered = true; // clang-format off // Overworld Crates diff --git a/soh/soh/Enhancements/randomizer/ShuffleCrates.h b/soh/soh/Enhancements/randomizer/ShuffleCrates.h index 60cd51dc2..eb0325f89 100644 --- a/soh/soh/Enhancements/randomizer/ShuffleCrates.h +++ b/soh/soh/Enhancements/randomizer/ShuffleCrates.h @@ -13,4 +13,4 @@ void ObjKibako_RandomizerInit(void* actorRef); }; #endif -#endif //ShuffleCrates_H +#endif // ShuffleCrates_H diff --git a/soh/soh/Enhancements/randomizer/ShuffleFairies.cpp b/soh/soh/Enhancements/randomizer/ShuffleFairies.cpp index a2b8015d4..41fd6d4e8 100644 --- a/soh/soh/Enhancements/randomizer/ShuffleFairies.cpp +++ b/soh/soh/Enhancements/randomizer/ShuffleFairies.cpp @@ -52,14 +52,16 @@ FairyIdentity ShuffleFairies_GetFairyIdentity(int32_t params) { sceneNum = SCENE_TEMPLE_OF_TIME_EXTERIOR_DAY; } - Rando::Location* location = OTRGlobals::Instance->gRandomizer->GetCheckObjectFromActor(ACTOR_EN_ELF, sceneNum, params); + Rando::Location* location = + OTRGlobals::Instance->gRandomizer->GetCheckObjectFromActor(ACTOR_EN_ELF, sceneNum, params); if (location->GetRandomizerCheck() == RC_UNKNOWN_CHECK) { LUSLOG_WARN("FairyGetIdentity did not receive a valid RC value (%d).", location->GetRandomizerCheck()); assert(false); } else { fairyIdentity.randomizerInf = static_cast(location->GetCollectionCheck().flag); - fairyIdentity.itemEntry = Rando::Context::GetInstance()->GetFinalGIEntry(location->GetRandomizerCheck(), true, GI_FAIRY); + fairyIdentity.itemEntry = + Rando::Context::GetInstance()->GetFinalGIEntry(location->GetRandomizerCheck(), true, GI_FAIRY); } return fairyIdentity; @@ -91,44 +93,42 @@ void ShuffleFairies_OnVanillaBehaviorHandler(GIVanillaBehavior id, bool* should, if (enElf->sohFairyIdentity.randomizerInf && enElf->sohFairyIdentity.randomizerInf != RAND_INF_MAX) { Flags_SetRandomizerInf(enElf->sohFairyIdentity.randomizerInf); } - // Spawn fairies in fairy fountains + // Spawn fairies in fairy fountains } else if (id == VB_SPAWN_FOUNTAIN_FAIRIES) { bool fairySpawned = false; s16 grottoId = (gPlayState->sceneNum == SCENE_FAIRYS_FOUNTAIN) ? Grotto_CurrentGrotto() : 0; for (s16 index = 0; index < 8; index++) { int32_t params = (grottoId << 8) | index; - if (ShuffleFairies_SpawnFairy(actor->world.pos.x, actor->world.pos.y, actor->world.pos.z, - params)) { + if (ShuffleFairies_SpawnFairy(actor->world.pos.x, actor->world.pos.y, actor->world.pos.z, params)) { fairySpawned = true; } } if (fairySpawned) { *should = false; } - // Spawn 3 fairies when playing Song of Storms next to a planted bean + // Spawn 3 fairies when playing Song of Storms next to a planted bean } else if (id == VB_SPAWN_BEAN_STALK_FAIRIES) { ObjBean* objBean = (ObjBean*)(actor); bool fairySpawned = false; for (s16 index = 0; index < 3; index++) { int32_t params = ((objBean->dyna.actor.params & 0x3F) << 8) | index; if (ShuffleFairies_SpawnFairy(objBean->dyna.actor.world.pos.x, objBean->dyna.actor.world.pos.y, - objBean->dyna.actor.world.pos.z, - params)) { + objBean->dyna.actor.world.pos.z, params)) { fairySpawned = true; } } if (fairySpawned) { *should = false; } - // Spawn a fairy from a ShotSun when playing the right song near it + // Spawn a fairy from a ShotSun when playing the right song near it } else if (id == VB_SPAWN_SONG_FAIRY) { ShotSun* shotSun = (ShotSun*)(actor); if (ShuffleFairies_SpawnFairy(shotSun->actor.world.pos.x, shotSun->actor.world.pos.y, - shotSun->actor.world.pos.z, - TWO_ACTOR_PARAMS(0x1000, (int32_t)shotSun->actor.world.pos.z))) { + shotSun->actor.world.pos.z, + TWO_ACTOR_PARAMS(0x1000, (int32_t)shotSun->actor.world.pos.z))) { *should = false; } - // Handle playing both misc songs and song of storms in front of a gossip stone. + // Handle playing both misc songs and song of storms in front of a gossip stone. } else if (id == VB_SPAWN_GOSSIP_STONE_FAIRY) { EnGs* gossipStone = (EnGs*)(actor); @@ -136,11 +136,9 @@ void ShuffleFairies_OnVanillaBehaviorHandler(GIVanillaBehavior id, bool* should, // Otherwise fall back to vanilla behaviour. if (gPlayState->msgCtx.ocarinaMode == OCARINA_MODE_04 && (gPlayState->msgCtx.unk_E3F2 == OCARINA_SONG_LULLABY || - gPlayState->msgCtx.unk_E3F2 == OCARINA_SONG_SARIAS || - gPlayState->msgCtx.unk_E3F2 == OCARINA_SONG_EPONAS || - gPlayState->msgCtx.unk_E3F2 == OCARINA_SONG_SUNS || - gPlayState->msgCtx.unk_E3F2 == OCARINA_SONG_TIME || - gPlayState->msgCtx.unk_E3F2 == OCARINA_SONG_STORMS)) { + gPlayState->msgCtx.unk_E3F2 == OCARINA_SONG_SARIAS || gPlayState->msgCtx.unk_E3F2 == OCARINA_SONG_EPONAS || + gPlayState->msgCtx.unk_E3F2 == OCARINA_SONG_SUNS || gPlayState->msgCtx.unk_E3F2 == OCARINA_SONG_TIME || + gPlayState->msgCtx.unk_E3F2 == OCARINA_SONG_STORMS)) { int32_t params = (gPlayState->sceneNum == SCENE_GROTTOS) ? Grotto_CurrentGrotto() : 0; // Distinguish storms fairies from the normal song fairies @@ -159,7 +157,7 @@ void ShuffleFairies_OnVanillaBehaviorHandler(GIVanillaBehavior id, bool* should, FairyIdentity fairyIdentity = ShuffleFairies_GetFairyIdentity(params); if (!ShuffleFairies_FairyExists(fairyIdentity)) { if (ShuffleFairies_SpawnFairy(gossipStone->actor.world.pos.x, gossipStone->actor.world.pos.y, - gossipStone->actor.world.pos.z, params)) { + gossipStone->actor.world.pos.z, params)) { Audio_PlayActorSound2(&gossipStone->actor, NA_SE_EV_BUTTERFRY_TO_FAIRY); // Set vanilla check for fairy spawned so it doesn't spawn the vanilla fairy afterwards as well. gossipStone->unk_19D = 0; @@ -175,7 +173,8 @@ void ShuffleFairies_OnVanillaBehaviorHandler(GIVanillaBehavior id, bool* should, uint32_t onVanillaBehaviorHook = 0; void ShuffleFairies_RegisterHooks() { - onVanillaBehaviorHook = GameInteractor::Instance->RegisterGameHook(ShuffleFairies_OnVanillaBehaviorHandler); + onVanillaBehaviorHook = GameInteractor::Instance->RegisterGameHook( + ShuffleFairies_OnVanillaBehaviorHandler); } void ShuffleFairies_UnregisterHooks() { @@ -186,7 +185,8 @@ void ShuffleFairies_UnregisterHooks() { void Rando::StaticData::RegisterFairyLocations() { static bool registered = false; - if (registered) return; + if (registered) + return; registered = true; // clang-format off locationTable[RC_SFM_FAIRY_GROTTO_FAIRY_1] = Location::Fairy(RC_SFM_FAIRY_GROTTO_FAIRY_1, RCQUEST_BOTH, RCAREA_SACRED_FOREST_MEADOW, SCENE_FAIRYS_FOUNTAIN, 0x1800, "Grotto Fairy 1", RHT_SFM_FAIRY_GROTTO_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SFM_FAIRY_GROTTO_FAIRY_1)); diff --git a/soh/soh/Enhancements/randomizer/ShuffleFreestanding.cpp b/soh/soh/Enhancements/randomizer/ShuffleFreestanding.cpp index 15a7df4db..03fd33981 100644 --- a/soh/soh/Enhancements/randomizer/ShuffleFreestanding.cpp +++ b/soh/soh/Enhancements/randomizer/ShuffleFreestanding.cpp @@ -20,17 +20,17 @@ void ShuffleFreestanding_OnVanillaBehaviorHandler(GIVanillaBehavior id, bool* sh } uint32_t params = TWO_ACTOR_PARAMS((int32_t)item00->actor.world.pos.x, (int32_t)item00->actor.world.pos.z); - Rando::Location* loc = OTRGlobals::Instance->gRandomizer->GetCheckObjectFromActor(item00->actor.id, gPlayState->sceneNum, params); + Rando::Location* loc = + OTRGlobals::Instance->gRandomizer->GetCheckObjectFromActor(item00->actor.id, gPlayState->sceneNum, params); uint8_t isDungeon = loc->IsDungeon(); - uint8_t freestandingSetting = - Rando::Context::GetInstance()->GetOption(RSK_SHUFFLE_FREESTANDING).Get(); + uint8_t freestandingSetting = Rando::Context::GetInstance()->GetOption(RSK_SHUFFLE_FREESTANDING).Get(); RandomizerCheck randomizerCheck = loc->GetRandomizerCheck(); bool checkObtained = Rando::Context::GetInstance()->GetItemLocation(randomizerCheck)->HasObtained(); - + // Don't change to randomized item if current freestanding item isn't shuffled or already obtained. if ((freestandingSetting == RO_SHUFFLE_FREESTANDING_OVERWORLD && isDungeon) || - (freestandingSetting == RO_SHUFFLE_FREESTANDING_DUNGEONS && !isDungeon) || - checkObtained || randomizerCheck == RC_UNKNOWN_CHECK) { + (freestandingSetting == RO_SHUFFLE_FREESTANDING_DUNGEONS && !isDungeon) || checkObtained || + randomizerCheck == RC_UNKNOWN_CHECK) { return; } @@ -46,7 +46,8 @@ void ShuffleFreestanding_OnVanillaBehaviorHandler(GIVanillaBehavior id, bool* sh void Rando::StaticData::RegisterFreestandingLocations() { static bool registered = false; - if (registered) return; + if (registered) + return; registered = true; // clang-format off locationTable[RC_KF_BOULDER_RUPEE_2] = Location::Collectable(RC_KF_BOULDER_RUPEE_2, RCQUEST_BOTH, RCTYPE_FREESTANDING, ACTOR_EN_ITEM00, SCENE_KOKIRI_FOREST, TWO_ACTOR_PARAMS(-712, 1857), "Boulder Maze Second Rupee", RHT_KOKIRI_FOREST_RUPEE, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_KF_BOULDER_RUPEE_2)); diff --git a/soh/soh/Enhancements/randomizer/ShuffleGrass.cpp b/soh/soh/Enhancements/randomizer/ShuffleGrass.cpp index 92eb1cb9c..f318ad948 100644 --- a/soh/soh/Enhancements/randomizer/ShuffleGrass.cpp +++ b/soh/soh/Enhancements/randomizer/ShuffleGrass.cpp @@ -25,18 +25,20 @@ void DrawTypeOfGrass(EnKusa* grassActor, Gfx* bushDList, Gfx* grassDList, PlaySt } extern "C" void EnKusa_RandomizerDraw(Actor* thisx, PlayState* play) { - //static Gfx* dLists[] = { (Gfx*)gRandoBushDL, (Gfx*)object_kusa_DL_000140, (Gfx*)object_kusa_DL_000140 }; + // static Gfx* dLists[] = { (Gfx*)gRandoBushDL, (Gfx*)object_kusa_DL_000140, (Gfx*)object_kusa_DL_000140 }; static Gfx* dLists[] = { (Gfx*)gRandoBushJunkDL, (Gfx*)gRandoCuttableGrassJunkDL, (Gfx*)gRandoCuttableGrassJunkDL }; auto grassActor = ((EnKusa*)thisx); OPEN_DISPS(play->state.gfxCtx); Gfx_SetupDL_25Opa(play->state.gfxCtx); - if (grassActor->grassIdentity.randomizerCheck != RC_MAX && Flags_GetRandomizerInf(grassActor->grassIdentity.randomizerInf) == 0) { + if (grassActor->grassIdentity.randomizerCheck != RC_MAX && + Flags_GetRandomizerInf(grassActor->grassIdentity.randomizerInf) == 0) { int csmc = CVarGetInteger(CVAR_ENHANCEMENT("ChestSizeAndTextureMatchContents"), CSMC_DISABLED); if (csmc == CSMC_BOTH || csmc == CSMC_TEXTURE) { - auto itemEntry = Rando::Context::GetInstance()->GetFinalGIEntry(grassActor->grassIdentity.randomizerCheck, true, GI_NONE); + auto itemEntry = Rando::Context::GetInstance()->GetFinalGIEntry(grassActor->grassIdentity.randomizerCheck, + true, GI_NONE); GetItemCategory getItemCategory = itemEntry.getItemCategory; switch (getItemCategory) { @@ -48,10 +50,12 @@ extern "C" void EnKusa_RandomizerDraw(Actor* thisx, PlayState* play) { case ITEM_HEART_PIECE: case ITEM_HEART_PIECE_2: case ITEM_HEART_CONTAINER: - DrawTypeOfGrass(grassActor, (Gfx*)gRandoBushHeartDL, (Gfx*)gRandoCuttableGrassHeartDL, play); + DrawTypeOfGrass(grassActor, (Gfx*)gRandoBushHeartDL, (Gfx*)gRandoCuttableGrassHeartDL, + play); break; default: - DrawTypeOfGrass(grassActor, (Gfx*)gRandoBushMinorDL, (Gfx*)gRandoCuttableGrassMinorDL, play); + DrawTypeOfGrass(grassActor, (Gfx*)gRandoBushMinorDL, (Gfx*)gRandoCuttableGrassMinorDL, + play); break; } break; @@ -155,10 +159,10 @@ void RegisterShuffleGrass() { }); } - void Rando::StaticData::RegisterGrassLocations() { static bool registered = false; - if (registered) return; + if (registered) + return; registered = true; // clang-format off // Overworld Grass diff --git a/soh/soh/Enhancements/randomizer/ShuffleGrass.h b/soh/soh/Enhancements/randomizer/ShuffleGrass.h index e666f107e..bc9a130d4 100644 --- a/soh/soh/Enhancements/randomizer/ShuffleGrass.h +++ b/soh/soh/Enhancements/randomizer/ShuffleGrass.h @@ -12,4 +12,4 @@ void EnKusa_RandomizerInit(void* actorRef); }; #endif -#endif //SHUFFLEGRASS_H +#endif // SHUFFLEGRASS_H diff --git a/soh/soh/Enhancements/randomizer/ShufflePots.cpp b/soh/soh/Enhancements/randomizer/ShufflePots.cpp index 0d45df189..9e6f50f42 100644 --- a/soh/soh/Enhancements/randomizer/ShufflePots.cpp +++ b/soh/soh/Enhancements/randomizer/ShufflePots.cpp @@ -11,7 +11,6 @@ extern PlayState* gPlayState; extern void EnItem00_DrawRandomizedItem(EnItem00* enItem00, PlayState* play); - extern "C" void ObjTsubo_RandomizerDraw(Actor* thisx, PlayState* play) { float potSize = 1.0f; @@ -19,7 +18,7 @@ extern "C" void ObjTsubo_RandomizerDraw(Actor* thisx, PlayState* play) { Gfx_SetupDL_25Opa(play->state.gfxCtx); Matrix_Scale(potSize, potSize, potSize, MTXMODE_APPLY); gSPMatrix(POLY_OPA_DISP++, Matrix_NewMtx(play->state.gfxCtx, (char*)__FILE__, __LINE__), - G_MTX_MODELVIEW | G_MTX_LOAD); + G_MTX_MODELVIEW | G_MTX_LOAD); gSPDisplayList(POLY_OPA_DISP++, (Gfx*)gRandoPotDL); CLOSE_DISPS(play->state.gfxCtx); @@ -44,7 +43,8 @@ uint8_t ObjTsubo_RandomizerHoldsItem(ObjTsubo* potActor, PlayState* play) { void ObjTsubo_RandomizerSpawnCollectible(ObjTsubo* potActor, PlayState* play) { EnItem00* item00 = (EnItem00*)Item_DropCollectible2(play, &potActor->actor.world.pos, ITEM00_SOH_DUMMY); item00->randoInf = potActor->potIdentity.randomizerInf; - item00->itemEntry = Rando::Context::GetInstance()->GetFinalGIEntry(potActor->potIdentity.randomizerCheck, true, GI_NONE); + item00->itemEntry = + Rando::Context::GetInstance()->GetFinalGIEntry(potActor->potIdentity.randomizerCheck, true, GI_NONE); item00->actor.draw = (ActorFunc)EnItem00_DrawRandomizedItem; item00->actor.velocity.y = 8.0f; item00->actor.speedXZ = 2.0f; @@ -56,7 +56,8 @@ void ObjTsubo_RandomizerInit(void* actorRef) { ObjTsubo* potActor = static_cast(actorRef); - potActor->potIdentity = OTRGlobals::Instance->gRandomizer->IdentifyPot(gPlayState->sceneNum, (s16)actor->world.pos.x, (s16)actor->world.pos.z); + potActor->potIdentity = OTRGlobals::Instance->gRandomizer->IdentifyPot( + gPlayState->sceneNum, (s16)actor->world.pos.x, (s16)actor->world.pos.z); } void ShufflePots_OnVanillaBehaviorHandler(GIVanillaBehavior id, bool* should, va_list originalArgs) { @@ -96,7 +97,8 @@ void ShufflePots_OnVanillaBehaviorHandler(GIVanillaBehavior id, bool* should, va void Rando::StaticData::RegisterPotLocations() { static bool registered = false; - if (registered) return; + if (registered) + return; registered = true; // clang-format off // Overworld Pots diff --git a/soh/soh/Enhancements/randomizer/ShufflePots.h b/soh/soh/Enhancements/randomizer/ShufflePots.h index 28c4e2f4a..cbe6ddaf5 100644 --- a/soh/soh/Enhancements/randomizer/ShufflePots.h +++ b/soh/soh/Enhancements/randomizer/ShufflePots.h @@ -14,4 +14,4 @@ void ObjTsubo_RandomizerInit(void* actorRef); void ShufflePots_OnVanillaBehaviorHandler(GIVanillaBehavior id, bool* should, va_list originalArgs); -#endif //SHUFFLEPOTS_H +#endif // SHUFFLEPOTS_H diff --git a/soh/soh/Enhancements/randomizer/ShuffleTradeItems.c b/soh/soh/Enhancements/randomizer/ShuffleTradeItems.c index 62e0bc9f0..8b43884e4 100644 --- a/soh/soh/Enhancements/randomizer/ShuffleTradeItems.c +++ b/soh/soh/Enhancements/randomizer/ShuffleTradeItems.c @@ -8,7 +8,7 @@ u8 Randomizer_GetNextChildTradeItem() { for (int i = 0; i < numTradeItems; i++) { u8 tradeIndex = (currentTradeItemIndex + i + 1) % numTradeItems; if (Flags_GetRandomizerInf(tradeIndex + RAND_INF_CHILD_TRADES_HAS_WEIRD_EGG)) { - return ITEM_WEIRD_EGG + tradeIndex; + return ITEM_WEIRD_EGG + tradeIndex; } } return ITEM_NONE; @@ -20,7 +20,7 @@ u8 Randomizer_GetPrevChildTradeItem() { for (int i = 0; i < numTradeItems; i++) { u8 tradeIndex = (currentTradeItemIndex - i - 1 + numTradeItems) % numTradeItems; if (Flags_GetRandomizerInf(tradeIndex + RAND_INF_CHILD_TRADES_HAS_WEIRD_EGG)) { - return ITEM_WEIRD_EGG + tradeIndex; + return ITEM_WEIRD_EGG + tradeIndex; } } return ITEM_NONE; @@ -32,7 +32,7 @@ u8 Randomizer_GetNextAdultTradeItem() { for (int i = 0; i < numTradeItems; i++) { u8 tradeIndex = (currentTradeItemIndex + i + 1) % numTradeItems; if (Flags_GetRandomizerInf(tradeIndex + RAND_INF_ADULT_TRADES_HAS_POCKET_EGG)) { - return ITEM_POCKET_EGG + tradeIndex; + return ITEM_POCKET_EGG + tradeIndex; } } return ITEM_NONE; @@ -44,7 +44,7 @@ u8 Randomizer_GetPrevAdultTradeItem() { for (int i = 0; i < numTradeItems; i++) { u8 tradeIndex = (currentTradeItemIndex - i - 1 + numTradeItems) % numTradeItems; if (Flags_GetRandomizerInf(tradeIndex + RAND_INF_ADULT_TRADES_HAS_POCKET_EGG)) { - return ITEM_POCKET_EGG + tradeIndex; + return ITEM_POCKET_EGG + tradeIndex; } } return ITEM_NONE; diff --git a/soh/soh/Enhancements/randomizer/context.cpp b/soh/soh/Enhancements/randomizer/context.cpp index 1f50ad58d..fa755325e 100644 --- a/soh/soh/Enhancements/randomizer/context.cpp +++ b/soh/soh/Enhancements/randomizer/context.cpp @@ -88,7 +88,7 @@ Hint* Context::GetHint(const RandomizerHint hintKey) { } void Context::AddHint(const RandomizerHint hintId, const Hint hint) { - hintTable[hintId] = hint; //RANDOTODO this should probably be an rvalue + hintTable[hintId] = hint; // RANDOTODO this should probably be an rvalue } ItemLocation* Context::GetItemLocation(const RandomizerCheck locKey) { @@ -117,12 +117,14 @@ ItemOverride& Context::GetItemOverride(size_t locKey) { return overrides.at(static_cast(locKey)); } -void Context::PlaceItemInLocation(const RandomizerCheck locKey, const RandomizerGet item, const bool applyEffectImmediately, - const bool setHidden) { +void Context::PlaceItemInLocation(const RandomizerCheck locKey, const RandomizerGet item, + const bool applyEffectImmediately, const bool setHidden) { const auto loc = GetItemLocation(locKey); - SPDLOG_DEBUG(StaticData::RetrieveItem(item).GetName().GetEnglish() + " placed at " + StaticData::GetLocation(locKey)->GetName() + "\n"); - - if (applyEffectImmediately || mOptions[RSK_LOGIC_RULES].Is(RO_LOGIC_GLITCHLESS) || mOptions[RSK_LOGIC_RULES].Is(RO_LOGIC_VANILLA)) { + SPDLOG_DEBUG(StaticData::RetrieveItem(item).GetName().GetEnglish() + " placed at " + + StaticData::GetLocation(locKey)->GetName() + "\n"); + + if (applyEffectImmediately || mOptions[RSK_LOGIC_RULES].Is(RO_LOGIC_GLITCHLESS) || + mOptions[RSK_LOGIC_RULES].Is(RO_LOGIC_VANILLA)) { StaticData::RetrieveItem(item).ApplyEffect(); } @@ -152,8 +154,8 @@ void Context::AddLocations(const Container& locations, std::vectorGetQuest() == RCQUEST_BOTH || - loc->GetQuest() == RCQUEST_MQ && mDungeons->GetDungeonFromScene(loc->GetScene())->IsMQ() || - loc->GetQuest() == RCQUEST_VANILLA && mDungeons->GetDungeonFromScene(loc->GetScene())->IsVanilla(); + loc->GetQuest() == RCQUEST_MQ && mDungeons->GetDungeonFromScene(loc->GetScene())->IsMQ() || + loc->GetQuest() == RCQUEST_VANILLA && mDungeons->GetDungeonFromScene(loc->GetScene())->IsVanilla(); } void Context::GenerateLocationPool() { @@ -163,26 +165,29 @@ void Context::GenerateLocationPool() { // TODO: Exclude checks for some of the older shuffles from the pool too i.e. Frog Songs, Scrubs, etc.) if (location.GetRandomizerCheck() == RC_UNKNOWN_CHECK || location.GetRandomizerCheck() == RC_TRIFORCE_COMPLETED || // already in pool - (location.GetRandomizerCheck() == RC_MASTER_SWORD_PEDESTAL && mOptions[RSK_SHUFFLE_MASTER_SWORD].Is(RO_GENERIC_OFF)) || - (location.GetRandomizerCheck() == RC_KAK_100_GOLD_SKULLTULA_REWARD && mOptions[RSK_SHUFFLE_100_GS_REWARD].Is(RO_GENERIC_OFF)) || - location.GetRCType() == RCTYPE_CHEST_GAME || // not supported yet - location.GetRCType() == RCTYPE_STATIC_HINT || // can't have items - location.GetRCType() == RCTYPE_GOSSIP_STONE || // can't have items + (location.GetRandomizerCheck() == RC_MASTER_SWORD_PEDESTAL && + mOptions[RSK_SHUFFLE_MASTER_SWORD].Is(RO_GENERIC_OFF)) || + (location.GetRandomizerCheck() == RC_KAK_100_GOLD_SKULLTULA_REWARD && + mOptions[RSK_SHUFFLE_100_GS_REWARD].Is(RO_GENERIC_OFF)) || + location.GetRCType() == RCTYPE_CHEST_GAME || // not supported yet + location.GetRCType() == RCTYPE_STATIC_HINT || // can't have items + location.GetRCType() == RCTYPE_GOSSIP_STONE || // can't have items (location.GetRCType() == RCTYPE_FROG_SONG && mOptions[RSK_SHUFFLE_FROG_SONG_RUPEES].Is(RO_GENERIC_OFF)) || (location.GetRCType() == RCTYPE_SCRUB && mOptions[RSK_SHUFFLE_SCRUBS].Is(RO_SCRUBS_OFF)) || - (location.GetRCType() == RCTYPE_SCRUB && mOptions[RSK_SHUFFLE_SCRUBS].Is(RO_SCRUBS_ONE_TIME_ONLY) && !( - location.GetRandomizerCheck() == RC_LW_DEKU_SCRUB_GROTTO_FRONT || - location.GetRandomizerCheck() == RC_LW_DEKU_SCRUB_NEAR_BRIDGE || - location.GetRandomizerCheck() == RC_HF_DEKU_SCRUB_GROTTO - )) || + (location.GetRCType() == RCTYPE_SCRUB && mOptions[RSK_SHUFFLE_SCRUBS].Is(RO_SCRUBS_ONE_TIME_ONLY) && + !(location.GetRandomizerCheck() == RC_LW_DEKU_SCRUB_GROTTO_FRONT || + location.GetRandomizerCheck() == RC_LW_DEKU_SCRUB_NEAR_BRIDGE || + location.GetRandomizerCheck() == RC_HF_DEKU_SCRUB_GROTTO)) || (location.GetRCType() == RCTYPE_ADULT_TRADE && mOptions[RSK_SHUFFLE_ADULT_TRADE].Is(RO_GENERIC_OFF)) || (location.GetRCType() == RCTYPE_COW && mOptions[RSK_SHUFFLE_COWS].Is(RO_GENERIC_OFF)) || - (location.GetRandomizerCheck() == RC_LH_HYRULE_LOACH && mOptions[RSK_FISHSANITY].IsNot(RO_FISHSANITY_HYRULE_LOACH)) || + (location.GetRandomizerCheck() == RC_LH_HYRULE_LOACH && + mOptions[RSK_FISHSANITY].IsNot(RO_FISHSANITY_HYRULE_LOACH)) || (location.GetRCType() == RCTYPE_FISH && !mFishsanity->GetFishLocationIncluded(&location)) || (location.GetRCType() == RCTYPE_POT && mOptions[RSK_SHUFFLE_POTS].Is(RO_SHUFFLE_POTS_OFF)) || (location.GetRCType() == RCTYPE_GRASS && mOptions[RSK_SHUFFLE_GRASS].Is(RO_SHUFFLE_GRASS_OFF)) || - (location.GetRCType() == RCTYPE_CRATE && mOptions[RSK_SHUFFLE_CRATES].Is(RO_SHUFFLE_CRATES_OFF)) || - (location.GetRCType() == RCTYPE_NLCRATE && (mOptions[RSK_SHUFFLE_CRATES].Is(RO_SHUFFLE_CRATES_OFF) || !mOptions[RSK_LOGIC_RULES].Is(RO_LOGIC_NO_LOGIC))) || + (location.GetRCType() == RCTYPE_CRATE && mOptions[RSK_SHUFFLE_CRATES].Is(RO_SHUFFLE_CRATES_OFF)) || + (location.GetRCType() == RCTYPE_NLCRATE && (mOptions[RSK_SHUFFLE_CRATES].Is(RO_SHUFFLE_CRATES_OFF) || + !mOptions[RSK_LOGIC_RULES].Is(RO_LOGIC_NO_LOGIC))) || (location.GetRCType() == RCTYPE_SMALL_CRATE && mOptions[RSK_SHUFFLE_CRATES].Is(RO_SHUFFLE_CRATES_OFF)) || (location.GetRCType() == RCTYPE_FAIRY && !mOptions[RSK_SHUFFLE_FAIRIES]) || (location.GetRCType() == RCTYPE_FREESTANDING && @@ -193,13 +198,17 @@ void Context::GenerateLocationPool() { if (location.IsOverworld()) { // Skip stuff that is shuffled to dungeon only, i.e. tokens, pots, etc., or other checks that // should not have a shuffled item. - if ((location.GetRCType() == RCTYPE_FREESTANDING && mOptions[RSK_SHUFFLE_FREESTANDING].Is(RO_SHUFFLE_FREESTANDING_DUNGEONS)) || + if ((location.GetRCType() == RCTYPE_FREESTANDING && + mOptions[RSK_SHUFFLE_FREESTANDING].Is(RO_SHUFFLE_FREESTANDING_DUNGEONS)) || (location.GetRCType() == RCTYPE_POT && mOptions[RSK_SHUFFLE_POTS].Is(RO_SHUFFLE_POTS_DUNGEONS)) || (location.GetRCType() == RCTYPE_GRASS && mOptions[RSK_SHUFFLE_GRASS].Is(RO_SHUFFLE_GRASS_DUNGEONS)) || - (location.GetRCType() == RCTYPE_POT && mOptions[RSK_SHUFFLE_POTS].Is(RO_SHUFFLE_POTS_DUNGEONS)) || + (location.GetRCType() == RCTYPE_POT && mOptions[RSK_SHUFFLE_POTS].Is(RO_SHUFFLE_POTS_DUNGEONS)) || (location.GetRCType() == RCTYPE_CRATE && mOptions[RSK_SHUFFLE_CRATES].Is(RO_SHUFFLE_CRATES_DUNGEONS)) || - (location.GetRCType() == RCTYPE_NLCRATE && 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))) { + (location.GetRCType() == RCTYPE_NLCRATE && + 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))) { continue; } // If we've gotten past all the conditions where an overworld location should not be @@ -212,10 +221,15 @@ void Context::GenerateLocationPool() { if ((location.GetRCType() == RCTYPE_FREESTANDING && mOptions[RSK_SHUFFLE_FREESTANDING].Is(RO_SHUFFLE_FREESTANDING_OVERWORLD)) || (location.GetRCType() == RCTYPE_POT && mOptions[RSK_SHUFFLE_POTS].Is(RO_SHUFFLE_POTS_OVERWORLD)) || - (location.GetRCType() == RCTYPE_GRASS && mOptions[RSK_SHUFFLE_GRASS].Is(RO_SHUFFLE_GRASS_OVERWORLD)) || - (location.GetRCType() == RCTYPE_CRATE && mOptions[RSK_SHUFFLE_CRATES].Is(RO_SHUFFLE_CRATES_OVERWORLD)) || - (location.GetRCType() == RCTYPE_NLCRATE && 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))) { + (location.GetRCType() == RCTYPE_GRASS && + mOptions[RSK_SHUFFLE_GRASS].Is(RO_SHUFFLE_GRASS_OVERWORLD)) || + (location.GetRCType() == RCTYPE_CRATE && + mOptions[RSK_SHUFFLE_CRATES].Is(RO_SHUFFLE_CRATES_OVERWORLD)) || + (location.GetRCType() == RCTYPE_NLCRATE && + 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))) { continue; } // also add to that dungeon's location list. @@ -229,15 +243,14 @@ void Context::GenerateLocationPool() { void Context::AddExcludedOptions() { for (auto& loc : StaticData::GetLocationTable()) { // Checks of these types don't have items, skip them. - if (loc.GetRandomizerCheck() == RC_UNKNOWN_CHECK || - loc.GetRandomizerCheck() == RC_TRIFORCE_COMPLETED || loc.GetRCType() == RCTYPE_CHEST_GAME || - loc.GetRCType() == RCTYPE_STATIC_HINT || loc.GetRCType() == RCTYPE_GOSSIP_STONE) { + if (loc.GetRandomizerCheck() == RC_UNKNOWN_CHECK || loc.GetRandomizerCheck() == RC_TRIFORCE_COMPLETED || + loc.GetRCType() == RCTYPE_CHEST_GAME || loc.GetRCType() == RCTYPE_STATIC_HINT || + loc.GetRCType() == RCTYPE_GOSSIP_STONE) { continue; } AddLocation(loc.GetRandomizerCheck(), &everyPossibleLocation); bool alreadyAdded = false; - for (Option* location : Rando::Settings::GetInstance()->GetExcludeOptionsForArea(loc.GetArea())) - { + for (Option* location : Rando::Settings::GetInstance()->GetExcludeOptionsForArea(loc.GetArea())) { if (location->GetName() == loc.GetExcludedOption()->GetName()) { alreadyAdded = true; } @@ -248,7 +261,8 @@ void Context::AddExcludedOptions() { } } -std::vector Context::GetLocations(const std::vector& locationPool, const RandomizerCheckType checkType) { +std::vector Context::GetLocations(const std::vector& locationPool, + const RandomizerCheckType checkType) { std::vector locationsOfType; for (RandomizerCheck locKey : locationPool) { if (StaticData::GetLocation(locKey)->GetRCType() == checkType) { @@ -287,7 +301,7 @@ void Context::HintReset() { for (const RandomizerCheck il : StaticData::GetGossipStoneLocations()) { GetItemLocation(il)->ResetVariables(); } - for (Hint& hint : hintTable){ + for (Hint& hint : hintTable) { hint.ResetVariables(); } } @@ -330,7 +344,8 @@ void Context::SetSpoilerLoaded(const bool spoilerLoaded) { mSpoilerLoaded = spoilerLoaded; } -GetItemEntry Context::GetFinalGIEntry(const RandomizerCheck rc, const bool checkObtainability, const GetItemID ogItemId) { +GetItemEntry Context::GetFinalGIEntry(const RandomizerCheck rc, const bool checkObtainability, + const GetItemID ogItemId) { const auto itemLoc = GetItemLocation(rc); if (itemLoc->GetPlacedRandomizerGet() == RG_NONE) { if (ogItemId != GI_NONE) { @@ -391,9 +406,7 @@ void Context::ParseSpoiler(const char* spoilerFileName) { mTrials->ParseJson(spoilerFileJson); mSpoilerLoaded = true; mSeedGenerated = false; - } catch (...) { - LUSLOG_ERROR("Failed to load Spoiler File: %s", spoilerFileName); - } + } catch (...) { LUSLOG_ERROR("Failed to load Spoiler File: %s", spoilerFileName); } } void Context::ParseHashIconIndexesJson(nlohmann::json spoilerFileJson) { @@ -428,16 +441,16 @@ void Context::ParseItemLocationsJson(nlohmann::json spoilerFileJson) { } } -void Context::WriteHintJson(nlohmann::ordered_json& spoilerFileJson){ - for (Hint hint: hintTable){ +void Context::WriteHintJson(nlohmann::ordered_json& spoilerFileJson) { + for (Hint hint : hintTable) { hint.logHint(spoilerFileJson); } } -nlohmann::json getValueForMessage(std::unordered_map map, CustomMessage message){ +nlohmann::json getValueForMessage(std::unordered_map map, CustomMessage message) { std::vector strings = message.GetAllMessages(); - for (uint8_t language = 0; language < LANGUAGE_MAX; language++){ - if (map.contains(strings[language])){ + for (uint8_t language = 0; language < LANGUAGE_MAX; language++) { + if (map.contains(strings[language])) { return strings[language]; } } @@ -445,11 +458,11 @@ nlohmann::json getValueForMessage(std::unordered_map* destination = nullptr); bool IsQuestOfLocationActive(RandomizerCheck rc); void GenerateLocationPool(); - static std::vector GetLocations(const std::vector& locationPool, const RandomizerCheckType checkType); + static std::vector GetLocations(const std::vector& locationPool, + const RandomizerCheckType checkType); void AddExcludedOptions(); void LocationReset(); void ClearItemLocations(); diff --git a/soh/soh/Enhancements/randomizer/draw.cpp b/soh/soh/Enhancements/randomizer/draw.cpp index 9c9cfd829..0403966b7 100644 --- a/soh/soh/Enhancements/randomizer/draw.cpp +++ b/soh/soh/Enhancements/randomizer/draw.cpp @@ -40,29 +40,19 @@ extern SaveContext gSaveContext; } const char* SmallBodyCvarValue[10] = { - CVAR_COSMETIC("Key.ForestSmallBody.Value"), - CVAR_COSMETIC("Key.FireSmallBody.Value"), - CVAR_COSMETIC("Key.WaterSmallBody.Value"), - CVAR_COSMETIC("Key.SpiritSmallBody.Value"), - CVAR_COSMETIC("Key.ShadowSmallBody.Value"), - CVAR_COSMETIC("Key.WellSmallBody.Value"), - CVAR_COSMETIC("Key.GTGSmallBody.Value"), - CVAR_COSMETIC("Key.FortSmallBody.Value"), - CVAR_COSMETIC("Key.GanonsSmallBody.Value"), - CVAR_COSMETIC("Key.ChestGameSmallBody.Value"), + CVAR_COSMETIC("Key.ForestSmallBody.Value"), CVAR_COSMETIC("Key.FireSmallBody.Value"), + CVAR_COSMETIC("Key.WaterSmallBody.Value"), CVAR_COSMETIC("Key.SpiritSmallBody.Value"), + CVAR_COSMETIC("Key.ShadowSmallBody.Value"), CVAR_COSMETIC("Key.WellSmallBody.Value"), + CVAR_COSMETIC("Key.GTGSmallBody.Value"), CVAR_COSMETIC("Key.FortSmallBody.Value"), + CVAR_COSMETIC("Key.GanonsSmallBody.Value"), CVAR_COSMETIC("Key.ChestGameSmallBody.Value"), }; const char* SmallEmblemCvarValue[10] = { - CVAR_COSMETIC("Key.ForestSmallEmblem.Value"), - CVAR_COSMETIC("Key.FireSmallEmblem.Value"), - CVAR_COSMETIC("Key.WaterSmallEmblem.Value"), - CVAR_COSMETIC("Key.SpiritSmallEmblem.Value"), - CVAR_COSMETIC("Key.ShadowSmallEmblem.Value"), - CVAR_COSMETIC("Key.WellSmallEmblem.Value"), - CVAR_COSMETIC("Key.GTGSmallEmblem.Value"), - CVAR_COSMETIC("Key.FortSmallEmblem.Value"), - CVAR_COSMETIC("Key.GanonsSmallEmblem.Value"), - CVAR_COSMETIC("Key.ChestGameEmblem.Value"), + CVAR_COSMETIC("Key.ForestSmallEmblem.Value"), CVAR_COSMETIC("Key.FireSmallEmblem.Value"), + CVAR_COSMETIC("Key.WaterSmallEmblem.Value"), CVAR_COSMETIC("Key.SpiritSmallEmblem.Value"), + CVAR_COSMETIC("Key.ShadowSmallEmblem.Value"), CVAR_COSMETIC("Key.WellSmallEmblem.Value"), + CVAR_COSMETIC("Key.GTGSmallEmblem.Value"), CVAR_COSMETIC("Key.FortSmallEmblem.Value"), + CVAR_COSMETIC("Key.GanonsSmallEmblem.Value"), CVAR_COSMETIC("Key.ChestGameEmblem.Value"), }; Color_RGB8 SmallEmblemDefaultValue[10] = { @@ -85,16 +75,11 @@ extern "C" void Randomizer_DrawSmallKey(PlayState* play, GetItemEntry* getItemEn int slot = getItemEntry->drawItemId - RG_FOREST_TEMPLE_SMALL_KEY; Gfx* customIconDLs[] = { - (Gfx*)gSmallKeyIconForestTempleDL, - (Gfx*)gSmallKeyIconFireTempleDL, - (Gfx*)gSmallKeyIconWaterTempleDL, - (Gfx*)gSmallKeyIconSpiritTempleDL, - (Gfx*)gSmallKeyIconShadowTempleDL, - (Gfx*)gSmallKeyIconBottomoftheWellDL, - (Gfx*)gSmallKeyIconGerudoTrainingGroundDL, - (Gfx*)gSmallKeyIconGerudoFortressDL, - (Gfx*)gSmallKeyIconGanonsCastleDL, - (Gfx*)gSmallKeyIconTreasureChestGameDL, + (Gfx*)gSmallKeyIconForestTempleDL, (Gfx*)gSmallKeyIconFireTempleDL, + (Gfx*)gSmallKeyIconWaterTempleDL, (Gfx*)gSmallKeyIconSpiritTempleDL, + (Gfx*)gSmallKeyIconShadowTempleDL, (Gfx*)gSmallKeyIconBottomoftheWellDL, + (Gfx*)gSmallKeyIconGerudoTrainingGroundDL, (Gfx*)gSmallKeyIconGerudoFortressDL, + (Gfx*)gSmallKeyIconGanonsCastleDL, (Gfx*)gSmallKeyIconTreasureChestGameDL, }; OPEN_DISPS(play->state.gfxCtx); @@ -117,7 +102,7 @@ extern "C" void Randomizer_DrawSmallKey(PlayState* play, GetItemEntry* getItemEn emblemColor = CVarGetColor24(SmallEmblemCvarValue[slot], emblemColor); gSPMatrix(POLY_XLU_DISP++, Matrix_NewMtx(play->state.gfxCtx, (char*)__FILE__, __LINE__), - G_MTX_MODELVIEW | G_MTX_LOAD); + G_MTX_MODELVIEW | G_MTX_LOAD); gDPSetEnvColor(POLY_XLU_DISP++, emblemColor.r, emblemColor.g, emblemColor.b, 255); gSPDisplayList(POLY_XLU_DISP++, customIconDLs[slot]); @@ -144,13 +129,14 @@ extern "C" void Randomizer_DrawMap(PlayState* play, GetItemEntry* getItemEntry) { 222, 158, 47 }, // Spirit Temple { 126, 16, 177 }, // Shadow Temple { 227, 110, 255 }, // Bottom of the Well - { 0, 255, 255 }, // Ice Cavern + { 0, 255, 255 }, // Ice Cavern }; OPEN_DISPS(play->state.gfxCtx); Gfx_SetupDL_25Opa(play->state.gfxCtx); - gSPMatrix(POLY_OPA_DISP++, Matrix_NewMtx(play->state.gfxCtx, (char*)__FILE__, __LINE__), G_MTX_MODELVIEW | G_MTX_LOAD); + gSPMatrix(POLY_OPA_DISP++, Matrix_NewMtx(play->state.gfxCtx, (char*)__FILE__, __LINE__), + G_MTX_MODELVIEW | G_MTX_LOAD); gDPSetPrimColor(POLY_OPA_DISP++, 0, 0, colors[color_slot][0], colors[color_slot][1], colors[color_slot][2], 255); @@ -179,15 +165,18 @@ extern "C" void Randomizer_DrawCompass(PlayState* play, GetItemEntry* getItemEnt OPEN_DISPS(play->state.gfxCtx); Gfx_SetupDL_25Opa(play->state.gfxCtx); - gSPMatrix(POLY_OPA_DISP++, Matrix_NewMtx(play->state.gfxCtx, (char*)__FILE__, __LINE__), G_MTX_MODELVIEW | G_MTX_LOAD); + gSPMatrix(POLY_OPA_DISP++, Matrix_NewMtx(play->state.gfxCtx, (char*)__FILE__, __LINE__), + G_MTX_MODELVIEW | G_MTX_LOAD); gDPSetPrimColor(POLY_OPA_DISP++, 0, 0, colors[color_slot][0], colors[color_slot][1], colors[color_slot][2], 255); - gDPSetEnvColor(POLY_OPA_DISP++, colors[color_slot][0] / 2, colors[color_slot][1] / 2, colors[color_slot][2] / 2, 255); + gDPSetEnvColor(POLY_OPA_DISP++, colors[color_slot][0] / 2, colors[color_slot][1] / 2, colors[color_slot][2] / 2, + 255); gSPDisplayList(POLY_OPA_DISP++, (Gfx*)gGiCompassDL); POLY_XLU_DISP = Gfx_SetupDL(POLY_XLU_DISP, 5); - gSPMatrix(POLY_XLU_DISP++, Matrix_NewMtx(play->state.gfxCtx, (char*)__FILE__, __LINE__), G_MTX_MODELVIEW | G_MTX_LOAD); + gSPMatrix(POLY_XLU_DISP++, Matrix_NewMtx(play->state.gfxCtx, (char*)__FILE__, __LINE__), + G_MTX_MODELVIEW | G_MTX_LOAD); gSPDisplayList(POLY_XLU_DISP++, (Gfx*)gGiCompassGlassDL); CLOSE_DISPS(play->state.gfxCtx); @@ -198,21 +187,13 @@ extern "C" void Randomizer_DrawBossKey(PlayState* play, GetItemEntry* getItemEnt s16 slot = getItemEntry->getItemId - RG_FOREST_TEMPLE_BOSS_KEY; std::string CvarValue[6] = { - "gCosmetics.Key.ForestBoss", - "gCosmetics.Key.FireBoss", - "gCosmetics.Key.WaterBoss", - "gCosmetics.Key.SpiritBoss", - "gCosmetics.Key.ShadowBoss", - "gCosmetics.Key.GanonsBoss", + "gCosmetics.Key.ForestBoss", "gCosmetics.Key.FireBoss", "gCosmetics.Key.WaterBoss", + "gCosmetics.Key.SpiritBoss", "gCosmetics.Key.ShadowBoss", "gCosmetics.Key.GanonsBoss", }; Gfx* CustomdLists[] = { - (Gfx*)gBossKeyIconForestTempleDL, - (Gfx*)gBossKeyIconFireTempleDL, - (Gfx*)gBossKeyIconWaterTempleDL, - (Gfx*)gBossKeyIconSpiritTempleDL, - (Gfx*)gBossKeyIconShadowTempleDL, - (Gfx*)gBossKeyIconGanonsCastleDL, + (Gfx*)gBossKeyIconForestTempleDL, (Gfx*)gBossKeyIconFireTempleDL, (Gfx*)gBossKeyIconWaterTempleDL, + (Gfx*)gBossKeyIconSpiritTempleDL, (Gfx*)gBossKeyIconShadowTempleDL, (Gfx*)gBossKeyIconGanonsCastleDL, }; OPEN_DISPS(play->state.gfxCtx); @@ -223,14 +204,14 @@ extern "C" void Randomizer_DrawBossKey(PlayState* play, GetItemEntry* getItemEnt G_MTX_MODELVIEW | G_MTX_LOAD); Color_RGB8 keyColor = { 255, 255, 0 }; - //Supposed to use CVAR_COSMETIC but I can't figure out the syntax + // Supposed to use CVAR_COSMETIC but I can't figure out the syntax keyColor = CVarGetColor24((CvarValue[slot] + "Body.Value").c_str(), keyColor); - - if (isCustomKeysEnabled){ + + if (isCustomKeysEnabled) { gDPSetEnvColor(POLY_OPA_DISP++, keyColor.r, keyColor.g, keyColor.b, 255); gSPDisplayList(POLY_OPA_DISP++, (Gfx*)gBossKeyCustomDL); } else { - if (CVarGetInteger((CvarValue[slot] + "Body.Changed").c_str(), false)){ + if (CVarGetInteger((CvarValue[slot] + "Body.Changed").c_str(), false)) { gDPSetGrayscaleColor(POLY_OPA_DISP++, keyColor.r, keyColor.g, keyColor.b, 255); gSPGrayscale(POLY_OPA_DISP++, true); gSPDisplayList(POLY_OPA_DISP++, (Gfx*)gGiBossKeyDL); @@ -247,12 +228,12 @@ extern "C" void Randomizer_DrawBossKey(PlayState* play, GetItemEntry* getItemEnt Color_RGB8 gemColor = { 255, 0, 0 }; gemColor = CVarGetColor24((CvarValue[slot] + "Gem.Value").c_str(), gemColor); - - if (isCustomKeysEnabled){ + + if (isCustomKeysEnabled) { gDPSetEnvColor(POLY_XLU_DISP++, gemColor.r, gemColor.g, gemColor.b, 255); gSPDisplayList(POLY_XLU_DISP++, CustomdLists[slot]); } else { - if (CVarGetInteger((CvarValue[slot] + "Gem.Changed").c_str(), false)){ + if (CVarGetInteger((CvarValue[slot] + "Gem.Changed").c_str(), false)) { gDPSetGrayscaleColor(POLY_XLU_DISP++, gemColor.r, gemColor.g, gemColor.b, 255); gSPGrayscale(POLY_XLU_DISP++, true); gSPDisplayList(POLY_XLU_DISP++, (Gfx*)gGiBossKeyGemDL); @@ -270,57 +251,38 @@ extern "C" void Randomizer_DrawKeyRing(PlayState* play, GetItemEntry* getItemEnt int slot = getItemEntry->drawItemId - RG_FOREST_TEMPLE_KEY_RING; Gfx* CustomIconDLs[] = { - (Gfx*)gKeyringIconForestTempleDL, - (Gfx*)gKeyringIconFireTempleDL, - (Gfx*)gKeyringIconWaterTempleDL, - (Gfx*)gKeyringIconSpiritTempleDL, - (Gfx*)gKeyringIconShadowTempleDL, - (Gfx*)gKeyringIconBottomoftheWellDL, - (Gfx*)gKeyringIconGerudoTrainingGroundDL, - (Gfx*)gKeyringIconGerudoFortressDL, - (Gfx*)gKeyringIconGanonsCastleDL, - (Gfx*)gKeyringIconTreasureChestGameDL, + (Gfx*)gKeyringIconForestTempleDL, (Gfx*)gKeyringIconFireTempleDL, + (Gfx*)gKeyringIconWaterTempleDL, (Gfx*)gKeyringIconSpiritTempleDL, + (Gfx*)gKeyringIconShadowTempleDL, (Gfx*)gKeyringIconBottomoftheWellDL, + (Gfx*)gKeyringIconGerudoTrainingGroundDL, (Gfx*)gKeyringIconGerudoFortressDL, + (Gfx*)gKeyringIconGanonsCastleDL, (Gfx*)gKeyringIconTreasureChestGameDL, }; Gfx* CustomKeysDLs[] = { - (Gfx*)gKeyringKeysForestTempleDL, - (Gfx*)gKeyringKeysFireTempleDL, - (Gfx*)gKeyringKeysWaterTempleDL, - (Gfx*)gKeyringKeysSpiritTempleDL, - (Gfx*)gKeyringKeysShadowTempleDL, - (Gfx*)gKeyringKeysBottomoftheWellDL, - (Gfx*)gKeyringKeysGerudoTrainingGroundDL, - (Gfx*)gKeyringKeysGerudoFortressDL, - (Gfx*)gKeyringKeysGanonsCastleDL, - (Gfx*)gKeyringKeysTreasureChestGameDL, + (Gfx*)gKeyringKeysForestTempleDL, (Gfx*)gKeyringKeysFireTempleDL, + (Gfx*)gKeyringKeysWaterTempleDL, (Gfx*)gKeyringKeysSpiritTempleDL, + (Gfx*)gKeyringKeysShadowTempleDL, (Gfx*)gKeyringKeysBottomoftheWellDL, + (Gfx*)gKeyringKeysGerudoTrainingGroundDL, (Gfx*)gKeyringKeysGerudoFortressDL, + (Gfx*)gKeyringKeysGanonsCastleDL, (Gfx*)gKeyringKeysTreasureChestGameDL, }; Gfx* CustomKeysMQDLs[] = { - (Gfx*)gKeyringKeysForestTempleMQDL, - (Gfx*)gKeyringKeysFireTempleMQDL, - (Gfx*)gKeyringKeysWaterTempleMQDL, - (Gfx*)gKeyringKeysSpiritTempleMQDL, - (Gfx*)gKeyringKeysShadowTempleMQDL, - (Gfx*)gKeyringKeysBottomoftheWellMQDL, - (Gfx*)gKeyringKeysGerudoTrainingGroundMQDL, - (Gfx*)gKeyringKeysGerudoFortressDL, - (Gfx*)gKeyringKeysGanonsCastleMQDL, - (Gfx*)gKeyringKeysTreasureChestGameDL, + (Gfx*)gKeyringKeysForestTempleMQDL, (Gfx*)gKeyringKeysFireTempleMQDL, + (Gfx*)gKeyringKeysWaterTempleMQDL, (Gfx*)gKeyringKeysSpiritTempleMQDL, + (Gfx*)gKeyringKeysShadowTempleMQDL, (Gfx*)gKeyringKeysBottomoftheWellMQDL, + (Gfx*)gKeyringKeysGerudoTrainingGroundMQDL, (Gfx*)gKeyringKeysGerudoFortressDL, + (Gfx*)gKeyringKeysGanonsCastleMQDL, (Gfx*)gKeyringKeysTreasureChestGameDL, }; - //RANDOTODO make DungeonInfo static and vanilla accessible to allow all these key model data vars to be stored there. - //(Rando::DungeonKey)0 means the keyring is not tied to a dungeon and should not be checked for an MQ variant + // RANDOTODO make DungeonInfo static and vanilla accessible to allow all these key model data vars to be stored + // there. (Rando::DungeonKey)0 means the keyring is not tied to a dungeon and should not be checked for an MQ + // variant Rando::DungeonKey SlotToDungeon[10] = { - Rando::FOREST_TEMPLE, - Rando::FIRE_TEMPLE, - Rando::WATER_TEMPLE, - Rando::SPIRIT_TEMPLE, - Rando::SHADOW_TEMPLE, - Rando::BOTTOM_OF_THE_WELL, - Rando::GERUDO_TRAINING_GROUND, - (Rando::DungeonKey)0, //Gerudo Fortress + Rando::FOREST_TEMPLE, Rando::FIRE_TEMPLE, Rando::WATER_TEMPLE, Rando::SPIRIT_TEMPLE, + Rando::SHADOW_TEMPLE, Rando::BOTTOM_OF_THE_WELL, Rando::GERUDO_TRAINING_GROUND, + (Rando::DungeonKey)0, // Gerudo Fortress Rando::GANONS_CASTLE, - (Rando::DungeonKey)0, //Treasure Chest Game + (Rando::DungeonKey)0, // Treasure Chest Game }; OPEN_DISPS(play->state.gfxCtx); @@ -332,12 +294,12 @@ extern "C" void Randomizer_DrawKeyRing(PlayState* play, GetItemEntry* getItemEnt if (isCustomKeysEnabled) { gSPMatrix(POLY_OPA_DISP++, Matrix_NewMtx(play->state.gfxCtx, (char*)__FILE__, __LINE__), - G_MTX_MODELVIEW | G_MTX_LOAD); + G_MTX_MODELVIEW | G_MTX_LOAD); gDPSetEnvColor(POLY_OPA_DISP++, keyColor.r, keyColor.g, keyColor.b, 255); - if (SlotToDungeon[slot] != 0 && Rando::Context::GetInstance()->GetDungeon(SlotToDungeon[slot])->IsMQ()){ + if (SlotToDungeon[slot] != 0 && Rando::Context::GetInstance()->GetDungeon(SlotToDungeon[slot])->IsMQ()) { gSPDisplayList(POLY_OPA_DISP++, (Gfx*)CustomKeysMQDLs[slot]); - } else { + } else { gSPDisplayList(POLY_OPA_DISP++, (Gfx*)CustomKeysDLs[slot]); } @@ -351,7 +313,7 @@ extern "C" void Randomizer_DrawKeyRing(PlayState* play, GetItemEntry* getItemEnt Gfx_SetupDL_25Opa(play->state.gfxCtx); gSPMatrix(POLY_OPA_DISP++, Matrix_NewMtx(play->state.gfxCtx, (char*)__FILE__, __LINE__), - G_MTX_MODELVIEW | G_MTX_LOAD); + G_MTX_MODELVIEW | G_MTX_LOAD); gDPSetEnvColor(POLY_OPA_DISP++, emblemColor.r, emblemColor.g, emblemColor.b, 255); gSPDisplayList(POLY_OPA_DISP++, CustomIconDLs[slot]); @@ -370,7 +332,7 @@ extern "C" void Randomizer_DrawKeyRing(PlayState* play, GetItemEntry* getItemEnt Matrix_RotateZ(-(0.20f * 2), MTXMODE_APPLY); for (int i = 0; i < 5; i++) { gSPMatrix(POLY_OPA_DISP++, Matrix_NewMtx(play->state.gfxCtx, (char*)__FILE__, __LINE__), - G_MTX_MODELVIEW | G_MTX_LOAD); + G_MTX_MODELVIEW | G_MTX_LOAD); Matrix_Translate(3.12f, -0.34f, 17.53f, MTXMODE_APPLY); Matrix_RotateX(-0.31f, MTXMODE_APPLY); Matrix_RotateY(0.19f, MTXMODE_APPLY); @@ -387,8 +349,9 @@ extern "C" void Randomizer_DrawDoubleDefense(PlayState* play, GetItemEntry* getI OPEN_DISPS(play->state.gfxCtx); Gfx_SetupDL_25Xlu(play->state.gfxCtx); - - gSPMatrix(POLY_XLU_DISP++, Matrix_NewMtx(play->state.gfxCtx, (char*)__FILE__, __LINE__), G_MTX_MODELVIEW | G_MTX_LOAD); + + gSPMatrix(POLY_XLU_DISP++, Matrix_NewMtx(play->state.gfxCtx, (char*)__FILE__, __LINE__), + G_MTX_MODELVIEW | G_MTX_LOAD); gDPSetGrayscaleColor(POLY_XLU_DISP++, 255, 255, 255, 255); gSPGrayscale(POLY_XLU_DISP++, true); @@ -409,8 +372,8 @@ extern "C" void Randomizer_DrawMasterSword(PlayState* play, GetItemEntry* getIte gSPSegment(POLY_OPA_DISP++, 0x08, (uintptr_t)Gfx_TwoTexScroll(play->state.gfxCtx, 0, 1 * (play->state.frames * 1), - 0 * (play->state.frames * 1), 32, 32, 1, 0 * (play->state.frames * 1), - 0 * (play->state.frames * 1), 32, 32)); + 0 * (play->state.frames * 1), 32, 32, 1, 0 * (play->state.frames * 1), + 0 * (play->state.frames * 1), 32, 32)); Matrix_Scale(0.05f, 0.05f, 0.05f, MTXMODE_APPLY); Matrix_RotateZ(2.1f, MTXMODE_APPLY); @@ -419,7 +382,7 @@ extern "C" void Randomizer_DrawMasterSword(PlayState* play, GetItemEntry* getIte G_MTX_MODELVIEW | G_MTX_LOAD); gSPDisplayList(POLY_OPA_DISP++, (Gfx*)object_toki_objects_DL_001BD0); - + CLOSE_DISPS(play->state.gfxCtx); } @@ -482,7 +445,7 @@ extern "C" void Randomizer_DrawTriforcePieceGI(PlayState* play, GetItemEntry get } else if (triforcePieceScale < 0.035f) { triforcePieceScale += 0.0005f; } - } else if (triforcePieceScale > 0.00008f && triforcePieceScale < 0.035f) { + } else if (triforcePieceScale > 0.00008f && triforcePieceScale < 0.035f) { triforcePieceScale += 0.0005f; } @@ -514,7 +477,8 @@ extern "C" void Randomizer_DrawMysteryItem(PlayState* play, GetItemEntry* getIte Gfx_SetupDL_25Xlu(play->state.gfxCtx); - gSPMatrix(POLY_XLU_DISP++, Matrix_NewMtx(play->state.gfxCtx, (char*)__FILE__, __LINE__), G_MTX_MODELVIEW | G_MTX_LOAD); + gSPMatrix(POLY_XLU_DISP++, Matrix_NewMtx(play->state.gfxCtx, (char*)__FILE__, __LINE__), + G_MTX_MODELVIEW | G_MTX_LOAD); gDPSetGrayscaleColor(POLY_XLU_DISP++, color.r, color.g, color.b, 255); gSPGrayscale(POLY_XLU_DISP++, true); @@ -619,7 +583,8 @@ extern "C" void DrawKingDodongo(PlayState* play) { CLOSE_DISPS(play->state.gfxCtx); } -extern "C" s32 OverrideLimbDrawBarinade(PlayState* play, s32 limbIndex, Gfx** dList, Vec3f* pos, Vec3s* rot, void* thisx) { +extern "C" s32 OverrideLimbDrawBarinade(PlayState* play, s32 limbIndex, Gfx** dList, Vec3f* pos, Vec3s* rot, + void* thisx) { OPEN_DISPS(play->state.gfxCtx); s16 unk_1AC = play->gameplayFrames * 0xC31; @@ -860,7 +825,8 @@ extern "C" void DrawBongoBongo(PlayState* play) { CLOSE_DISPS(play->state.gfxCtx); } -extern "C" s32 OverrideLimbDrawKotake(PlayState* play, s32 limbIndex, Gfx** dList, Vec3f* pos, Vec3s* rot, void* thisx) { +extern "C" s32 OverrideLimbDrawKotake(PlayState* play, s32 limbIndex, Gfx** dList, Vec3f* pos, Vec3s* rot, + void* thisx) { if (limbIndex == 21) { // Head *dList = (Gfx*)gTwinrovaKotakeHeadDL; } @@ -971,18 +937,18 @@ extern "C" void Randomizer_DrawBossSoul(PlayState* play, GetItemEntry* getItemEn } else { slot = getItemEntry->drawItemId - RG_GOHMA_SOUL; } - + s16 flameColors[9][3] = { { 0, 255, 0 }, // Gohma { 255, 0, 100 }, // King Dodongo - { 50, 255, 255}, // Barinade + { 50, 255, 255 }, // Barinade { 4, 195, 46 }, // Phantom Ganon { 237, 95, 95 }, // Volvagia { 85, 180, 223 }, // Morpha { 126, 16, 177 }, // Bongo Bongo { 222, 158, 47 }, // Twinrova { 150, 150, 150 }, // Ganon/Dorf - }; + }; // Draw the blue fire DL but coloured to the boss soul. OPEN_DISPS(play->state.gfxCtx); @@ -1016,7 +982,7 @@ extern "C" void Randomizer_DrawBossSoul(PlayState* play, GetItemEntry* getItemEn } gSPDisplayList(POLY_XLU_DISP++, (Gfx*)gBossSoulSkullDL); CLOSE_DISPS(play->state.gfxCtx); - // Draw the boss' skeleton + // Draw the boss' skeleton } else { switch (slot) { case 0: // Gohma @@ -1084,26 +1050,20 @@ extern "C" void Randomizer_DrawOcarinaButton(PlayState* play, GetItemEntry* getI s16 slot = getItemEntry->drawItemId - RG_OCARINA_A_BUTTON; Gfx* dLists[] = { - (Gfx*)gOcarinaAButtonDL, - (Gfx*)gOcarinaCUpButtonDL, - (Gfx*)gOcarinaCDownButtonDL, - (Gfx*)gOcarinaCLeftButtonDL, - (Gfx*)gOcarinaCRightButtonDL, + (Gfx*)gOcarinaAButtonDL, (Gfx*)gOcarinaCUpButtonDL, (Gfx*)gOcarinaCDownButtonDL, + (Gfx*)gOcarinaCLeftButtonDL, (Gfx*)gOcarinaCRightButtonDL, }; Color_RGB8 colors[] = { - aButtonColor, - cUpButtonColor, - cDownButtonColor, - cLeftButtonColor, - cRightButtonColor, + aButtonColor, cUpButtonColor, cDownButtonColor, cLeftButtonColor, cRightButtonColor, }; OPEN_DISPS(play->state.gfxCtx); Gfx_SetupDL_25Xlu(play->state.gfxCtx); - gSPMatrix(POLY_XLU_DISP++, Matrix_NewMtx(play->state.gfxCtx, (char*)__FILE__, __LINE__), G_MTX_MODELVIEW | G_MTX_LOAD); + gSPMatrix(POLY_XLU_DISP++, Matrix_NewMtx(play->state.gfxCtx, (char*)__FILE__, __LINE__), + G_MTX_MODELVIEW | G_MTX_LOAD); gDPSetGrayscaleColor(POLY_XLU_DISP++, colors[slot].r, colors[slot].g, colors[slot].b, 255); gSPGrayscale(POLY_XLU_DISP++, true); @@ -1135,11 +1095,12 @@ extern "C" void Randomizer_DrawBronzeScale(PlayState* play, GetItemEntry* getIte Gfx_SetupDL_25Xlu(play->state.gfxCtx); gSPSegment(POLY_XLU_DISP++, 0x08, - (uintptr_t)Gfx_TwoTexScroll(play->state.gfxCtx, 0, 1 * (play->state.frames * 2), - -1 * (play->state.frames * 2), 64, 64, 1, 1 * (play->state.frames * 4), - 1 * -(play->state.frames * 4), 32, 32)); + (uintptr_t)Gfx_TwoTexScroll(play->state.gfxCtx, 0, 1 * (play->state.frames * 2), + -1 * (play->state.frames * 2), 64, 64, 1, 1 * (play->state.frames * 4), + 1 * -(play->state.frames * 4), 32, 32)); - gSPMatrix(POLY_XLU_DISP++, Matrix_NewMtx(play->state.gfxCtx, (char*)__FILE__, __LINE__), G_MTX_MODELVIEW | G_MTX_LOAD); + gSPMatrix(POLY_XLU_DISP++, Matrix_NewMtx(play->state.gfxCtx, (char*)__FILE__, __LINE__), + G_MTX_MODELVIEW | G_MTX_LOAD); gSPDisplayList(POLY_XLU_DISP++, (Gfx*)gGiBronzeScaleColorDL); gSPDisplayList(POLY_XLU_DISP++, (Gfx*)gGiScaleDL); @@ -1198,7 +1159,6 @@ extern "C" void Randomizer_DrawFishingPoleGI(PlayState* play, GetItemEntry* getI CLOSE_DISPS(play->state.gfxCtx); } - extern "C" void Randomizer_DrawSkeletonKey(PlayState* play, GetItemEntry* getItemEntry) { OPEN_DISPS(play->state.gfxCtx); @@ -1215,7 +1175,7 @@ extern "C" void Randomizer_DrawSkeletonKey(PlayState* play, GetItemEntry* getIte CLOSE_DISPS(play->state.gfxCtx); } -extern "C" void Randomizer_DrawBombchuBag(PlayState* play, GetItemEntry* getItemEntry){ +extern "C" void Randomizer_DrawBombchuBag(PlayState* play, GetItemEntry* getItemEntry) { OPEN_DISPS(play->state.gfxCtx); Gfx_SetupDL_26Opa(play->state.gfxCtx); @@ -1237,13 +1197,13 @@ extern "C" void Randomizer_DrawBombchuBag(PlayState* play, GetItemEntry* getItem } extern "C" void Randomizer_DrawBombchuBagInLogic(PlayState* play, GetItemEntry* getItemEntry) { - if(IS_RANDO && OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_BOMBCHU_BAG)){ + if (IS_RANDO && OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_BOMBCHU_BAG)) { Randomizer_DrawBombchuBag(play, getItemEntry); } else { OPEN_DISPS(play->state.gfxCtx); Gfx_SetupDL_26Opa(play->state.gfxCtx); gSPMatrix(POLY_OPA_DISP++, Matrix_NewMtx(play->state.gfxCtx, (char*)__FILE__, __LINE__), - G_MTX_MODELVIEW | G_MTX_LOAD); + G_MTX_MODELVIEW | G_MTX_LOAD); gSPDisplayList(POLY_OPA_DISP++, (Gfx*)gGiBombchuDL); CLOSE_DISPS(play->state.gfxCtx); } diff --git a/soh/soh/Enhancements/randomizer/draw.h b/soh/soh/Enhancements/randomizer/draw.h index 22d8466c6..8483a7bf9 100644 --- a/soh/soh/Enhancements/randomizer/draw.h +++ b/soh/soh/Enhancements/randomizer/draw.h @@ -28,8 +28,11 @@ void Randomizer_DrawBombchuBagInLogic(PlayState* play, GetItemEntry* getItemEntr void Randomizer_DrawBombchuBag(PlayState* play, GetItemEntry* getItemEntry); void Randomizer_DrawOverworldKey(PlayState* play, GetItemEntry* getItemEntry); -#define GET_ITEM_MYSTERY \ - { ITEM_NONE_FE, 0, 0, 0, 0, MOD_RANDOMIZER, MOD_RANDOMIZER, ITEM_NONE_FE, 0, false, ITEM_FROM_NPC, ITEM_CATEGORY_JUNK, ITEM_NONE_FE, MOD_RANDOMIZER, (CustomDrawFunc)Randomizer_DrawMysteryItem } +#define GET_ITEM_MYSTERY \ + { \ + ITEM_NONE_FE, 0, 0, 0, 0, MOD_RANDOMIZER, MOD_RANDOMIZER, ITEM_NONE_FE, 0, false, ITEM_FROM_NPC, \ + ITEM_CATEGORY_JUNK, ITEM_NONE_FE, MOD_RANDOMIZER, (CustomDrawFunc)Randomizer_DrawMysteryItem \ + } #ifdef __cplusplus }; #endif diff --git a/soh/soh/Enhancements/randomizer/dungeon.cpp b/soh/soh/Enhancements/randomizer/dungeon.cpp index 8b749faf8..1eb88ed73 100644 --- a/soh/soh/Enhancements/randomizer/dungeon.cpp +++ b/soh/soh/Enhancements/randomizer/dungeon.cpp @@ -6,15 +6,16 @@ namespace Rando { DungeonInfo::DungeonInfo(std::string name_, const RandomizerHintTextKey hintKey_, const RandomizerGet map_, - const RandomizerGet compass_, const RandomizerGet smallKey_, const RandomizerGet keyRing_, - const RandomizerGet bossKey_, RandomizerArea area_, const uint8_t vanillaKeyCount_, const uint8_t mqKeyCount_, - const RandomizerSettingKey mqSetting_) + const RandomizerGet compass_, const RandomizerGet smallKey_, const RandomizerGet keyRing_, + const RandomizerGet bossKey_, RandomizerArea area_, const uint8_t vanillaKeyCount_, + const uint8_t mqKeyCount_, const RandomizerSettingKey mqSetting_) : name(std::move(name_)), hintKey(hintKey_), map(map_), compass(compass_), smallKey(smallKey_), keyRing(keyRing_), bossKey(bossKey_), area(area_), vanillaKeyCount(vanillaKeyCount_), mqKeyCount(mqKeyCount_), mqSetting(mqSetting_) { } -DungeonInfo::DungeonInfo() : hintKey(RHT_NONE), map(RG_NONE), compass(RG_NONE), smallKey(RG_NONE), keyRing(RG_NONE), - bossKey(RG_NONE) {} +DungeonInfo::DungeonInfo() + : hintKey(RHT_NONE), map(RG_NONE), compass(RG_NONE), smallKey(RG_NONE), keyRing(RG_NONE), bossKey(RG_NONE) { +} DungeonInfo::~DungeonInfo() = default; const std::string& DungeonInfo::GetName() const { @@ -145,35 +146,38 @@ std::vector DungeonInfo::GetDungeonLocations() const { } Dungeons::Dungeons() { - dungeonList[DEKU_TREE] = - DungeonInfo("Deku Tree", RHT_DEKU_TREE, RG_DEKU_TREE_MAP, RG_DEKU_TREE_COMPASS, RG_NONE, RG_NONE, RG_NONE, RA_DEKU_TREE, 0, 0, RSK_MQ_DEKU_TREE); - dungeonList[DODONGOS_CAVERN] = DungeonInfo("Dodongo's Cavern", RHT_DODONGOS_CAVERN, RG_DODONGOS_CAVERN_MAP, - RG_DODONGOS_CAVERN_COMPASS, RG_NONE, RG_NONE, RG_NONE, RA_DODONGOS_CAVERN, 0, 0, RSK_MQ_DODONGOS_CAVERN); - dungeonList[JABU_JABUS_BELLY] = DungeonInfo("Jabu Jabu's Belly", RHT_JABU_JABUS_BELLY, RG_JABU_JABUS_BELLY_MAP, - RG_JABU_JABUS_BELLY_COMPASS, RG_NONE, RG_NONE, RG_NONE, RA_JABU_JABUS_BELLY, 0, 0, RSK_MQ_JABU_JABU); - dungeonList[FOREST_TEMPLE] = - DungeonInfo("Forest Temple", RHT_FOREST_TEMPLE, RG_FOREST_TEMPLE_MAP, RG_FOREST_TEMPLE_COMPASS, - RG_FOREST_TEMPLE_SMALL_KEY, RG_FOREST_TEMPLE_KEY_RING, RG_FOREST_TEMPLE_BOSS_KEY, RA_FOREST_TEMPLE, 5, 6, RSK_MQ_FOREST_TEMPLE); - dungeonList[FIRE_TEMPLE] = - DungeonInfo("Fire Temple", RHT_FIRE_TEMPLE, RG_FIRE_TEMPLE_MAP, RG_FIRE_TEMPLE_COMPASS, - RG_FIRE_TEMPLE_SMALL_KEY, RG_FIRE_TEMPLE_KEY_RING, RG_FIRE_TEMPLE_BOSS_KEY, RA_FIRE_TEMPLE, 8, 5, RSK_MQ_FIRE_TEMPLE); - dungeonList[WATER_TEMPLE] = - DungeonInfo("Water Temple", RHT_WATER_TEMPLE, RG_WATER_TEMPLE_MAP, RG_WATER_TEMPLE_COMPASS, - RG_WATER_TEMPLE_SMALL_KEY, RG_WATER_TEMPLE_KEY_RING, RG_WATER_TEMPLE_BOSS_KEY, RA_WATER_TEMPLE, 6, 2, RSK_MQ_WATER_TEMPLE); - dungeonList[SPIRIT_TEMPLE] = - DungeonInfo("Spirit Temple", RHT_SPIRIT_TEMPLE, RG_SPIRIT_TEMPLE_MAP, RG_SPIRIT_TEMPLE_COMPASS, - RG_SPIRIT_TEMPLE_SMALL_KEY, RG_SPIRIT_TEMPLE_KEY_RING, RG_SPIRIT_TEMPLE_BOSS_KEY, RA_SPIRIT_TEMPLE, 5, 7, RSK_MQ_SPIRIT_TEMPLE); - dungeonList[SHADOW_TEMPLE] = - DungeonInfo("Shadow Temple", RHT_SHADOW_TEMPLE, RG_SHADOW_TEMPLE_MAP, RG_SHADOW_TEMPLE_COMPASS, - RG_SHADOW_TEMPLE_SMALL_KEY, RG_SHADOW_TEMPLE_KEY_RING, RG_SHADOW_TEMPLE_BOSS_KEY, RA_SHADOW_TEMPLE, 5, 6, RSK_MQ_SHADOW_TEMPLE); - dungeonList[BOTTOM_OF_THE_WELL] = DungeonInfo( - "Bottom of the Well", RHT_BOTTOM_OF_THE_WELL, RG_BOTTOM_OF_THE_WELL_MAP, RG_BOTTOM_OF_THE_WELL_COMPASS, - RG_BOTTOM_OF_THE_WELL_SMALL_KEY, RG_BOTTOM_OF_THE_WELL_KEY_RING, RG_NONE, RA_BOTTOM_OF_THE_WELL, 3, 2, RSK_MQ_BOTTOM_OF_THE_WELL); + dungeonList[DEKU_TREE] = DungeonInfo("Deku Tree", RHT_DEKU_TREE, RG_DEKU_TREE_MAP, RG_DEKU_TREE_COMPASS, RG_NONE, + RG_NONE, RG_NONE, RA_DEKU_TREE, 0, 0, RSK_MQ_DEKU_TREE); + dungeonList[DODONGOS_CAVERN] = + DungeonInfo("Dodongo's Cavern", RHT_DODONGOS_CAVERN, RG_DODONGOS_CAVERN_MAP, RG_DODONGOS_CAVERN_COMPASS, + RG_NONE, RG_NONE, RG_NONE, RA_DODONGOS_CAVERN, 0, 0, RSK_MQ_DODONGOS_CAVERN); + dungeonList[JABU_JABUS_BELLY] = + DungeonInfo("Jabu Jabu's Belly", RHT_JABU_JABUS_BELLY, RG_JABU_JABUS_BELLY_MAP, RG_JABU_JABUS_BELLY_COMPASS, + RG_NONE, RG_NONE, RG_NONE, RA_JABU_JABUS_BELLY, 0, 0, RSK_MQ_JABU_JABU); + dungeonList[FOREST_TEMPLE] = DungeonInfo( + "Forest Temple", RHT_FOREST_TEMPLE, RG_FOREST_TEMPLE_MAP, RG_FOREST_TEMPLE_COMPASS, RG_FOREST_TEMPLE_SMALL_KEY, + RG_FOREST_TEMPLE_KEY_RING, RG_FOREST_TEMPLE_BOSS_KEY, RA_FOREST_TEMPLE, 5, 6, RSK_MQ_FOREST_TEMPLE); + dungeonList[FIRE_TEMPLE] = DungeonInfo("Fire Temple", RHT_FIRE_TEMPLE, RG_FIRE_TEMPLE_MAP, RG_FIRE_TEMPLE_COMPASS, + RG_FIRE_TEMPLE_SMALL_KEY, RG_FIRE_TEMPLE_KEY_RING, RG_FIRE_TEMPLE_BOSS_KEY, + RA_FIRE_TEMPLE, 8, 5, RSK_MQ_FIRE_TEMPLE); + dungeonList[WATER_TEMPLE] = DungeonInfo( + "Water Temple", RHT_WATER_TEMPLE, RG_WATER_TEMPLE_MAP, RG_WATER_TEMPLE_COMPASS, RG_WATER_TEMPLE_SMALL_KEY, + RG_WATER_TEMPLE_KEY_RING, RG_WATER_TEMPLE_BOSS_KEY, RA_WATER_TEMPLE, 6, 2, RSK_MQ_WATER_TEMPLE); + dungeonList[SPIRIT_TEMPLE] = DungeonInfo( + "Spirit Temple", RHT_SPIRIT_TEMPLE, RG_SPIRIT_TEMPLE_MAP, RG_SPIRIT_TEMPLE_COMPASS, RG_SPIRIT_TEMPLE_SMALL_KEY, + RG_SPIRIT_TEMPLE_KEY_RING, RG_SPIRIT_TEMPLE_BOSS_KEY, RA_SPIRIT_TEMPLE, 5, 7, RSK_MQ_SPIRIT_TEMPLE); + dungeonList[SHADOW_TEMPLE] = DungeonInfo( + "Shadow Temple", RHT_SHADOW_TEMPLE, RG_SHADOW_TEMPLE_MAP, RG_SHADOW_TEMPLE_COMPASS, RG_SHADOW_TEMPLE_SMALL_KEY, + RG_SHADOW_TEMPLE_KEY_RING, RG_SHADOW_TEMPLE_BOSS_KEY, RA_SHADOW_TEMPLE, 5, 6, RSK_MQ_SHADOW_TEMPLE); + dungeonList[BOTTOM_OF_THE_WELL] = + DungeonInfo("Bottom of the Well", RHT_BOTTOM_OF_THE_WELL, RG_BOTTOM_OF_THE_WELL_MAP, + RG_BOTTOM_OF_THE_WELL_COMPASS, RG_BOTTOM_OF_THE_WELL_SMALL_KEY, RG_BOTTOM_OF_THE_WELL_KEY_RING, + RG_NONE, RA_BOTTOM_OF_THE_WELL, 3, 2, RSK_MQ_BOTTOM_OF_THE_WELL); dungeonList[ICE_CAVERN] = DungeonInfo("Ice Cavern", RHT_ICE_CAVERN, RG_ICE_CAVERN_MAP, RG_ICE_CAVERN_COMPASS, RG_NONE, RG_NONE, RG_NONE, RA_ICE_CAVERN, 0, 0, RSK_MQ_ICE_CAVERN); - dungeonList[GERUDO_TRAINING_GROUND] = - DungeonInfo("Gerudo Training Ground", RHT_GERUDO_TRAINING_GROUND, RG_NONE, RG_NONE, - RG_GERUDO_TRAINING_GROUND_SMALL_KEY, RG_GERUDO_TRAINING_GROUND_KEY_RING, RG_NONE, RA_GERUDO_TRAINING_GROUND, 9, 3, RSK_MQ_GTG); + dungeonList[GERUDO_TRAINING_GROUND] = DungeonInfo( + "Gerudo Training Ground", RHT_GERUDO_TRAINING_GROUND, RG_NONE, RG_NONE, RG_GERUDO_TRAINING_GROUND_SMALL_KEY, + RG_GERUDO_TRAINING_GROUND_KEY_RING, RG_NONE, RA_GERUDO_TRAINING_GROUND, 9, 3, RSK_MQ_GTG); dungeonList[GANONS_CASTLE] = DungeonInfo("Ganon's Castle", RHT_GANONS_CASTLE, RG_NONE, RG_NONE, RG_GANONS_CASTLE_SMALL_KEY, RG_GANONS_CASTLE_KEY_RING, RG_GANONS_CASTLE_BOSS_KEY, RA_GANONS_CASTLE, 2, 3, RSK_MQ_GANONS_CASTLE); diff --git a/soh/soh/Enhancements/randomizer/dungeon.h b/soh/soh/Enhancements/randomizer/dungeon.h index 5d26036eb..ba81d289d 100644 --- a/soh/soh/Enhancements/randomizer/dungeon.h +++ b/soh/soh/Enhancements/randomizer/dungeon.h @@ -11,7 +11,7 @@ namespace Rando { class DungeonInfo { public: DungeonInfo(std::string name_, RandomizerHintTextKey hintKey_, RandomizerGet map_, RandomizerGet compass_, - RandomizerGet smallKey_, RandomizerGet keyRing_, RandomizerGet bossKey_, RandomizerArea area_, + RandomizerGet smallKey_, RandomizerGet keyRing_, RandomizerGet bossKey_, RandomizerArea area_, uint8_t vanillaKeyCount_, uint8_t mqKeyCount_, RandomizerSettingKey mqSetting_); DungeonInfo(); ~DungeonInfo(); @@ -86,11 +86,12 @@ class Dungeons { /// this new array can be shuffled for the purposes of randomizing MQ dungeons. /// If you want an individual DungeonInfo entry you should use the GetDungeon /// function from either here or the Context class. - /// @return + /// @return std::array GetDungeonList(); size_t GetDungeonListSize() const; void ParseJson(nlohmann::json spoilerFileJson); + private: std::array dungeonList; }; -} \ No newline at end of file +} // namespace Rando \ No newline at end of file diff --git a/soh/soh/Enhancements/randomizer/entrance.cpp b/soh/soh/Enhancements/randomizer/entrance.cpp index 74eaaa50e..05638a2b3 100644 --- a/soh/soh/Enhancements/randomizer/entrance.cpp +++ b/soh/soh/Enhancements/randomizer/entrance.cpp @@ -11,7 +11,8 @@ namespace Rando { EntranceLinkInfo NO_RETURN_ENTRANCE = { EntranceType::None, RR_NONE, RR_NONE, -1 }; Entrance::Entrance(RandomizerRegion connectedRegion_, ConditionFn condition_function_, bool spreadsAreasWithPriority_) - : connectedRegion(connectedRegion_), condition_function(condition_function_), spreadsAreasWithPriority(spreadsAreasWithPriority_){ + : connectedRegion(connectedRegion_), condition_function(condition_function_), + spreadsAreasWithPriority(spreadsAreasWithPriority_) { originalConnectedRegion = connectedRegion_; } @@ -20,11 +21,11 @@ void Entrance::SetCondition(ConditionFn newCondition) { } bool Entrance::GetConditionsMet() const { - auto ctx = Rando::Context::GetInstance(); - if (ctx->GetOption(RSK_LOGIC_RULES).Is(RO_LOGIC_GLITCHLESS)) { - return condition_function(); - } - return true; + auto ctx = Rando::Context::GetInstance(); + if (ctx->GetOption(RSK_LOGIC_RULES).Is(RO_LOGIC_GLITCHLESS)) { + return condition_function(); + } + return true; } std::string Entrance::to_string() const { @@ -60,24 +61,24 @@ void Entrance::printAgeTimeAccess() { } bool Entrance::ConditionsMet(bool allAgeTimes) const { - auto ctx = Rando::Context::GetInstance(); - StartPerformanceTimer(PT_ENTRANCE_LOGIC); - Region* parent = RegionTable(parentRegion); - int conditionsMet = 0; + auto ctx = Rando::Context::GetInstance(); + StartPerformanceTimer(PT_ENTRANCE_LOGIC); + Region* parent = RegionTable(parentRegion); + int conditionsMet = 0; - if (allAgeTimes && !parent->AllAccess()) { - StopPerformanceTimer(PT_ENTRANCE_LOGIC); - return false; - } + if (allAgeTimes && !parent->AllAccess()) { + StopPerformanceTimer(PT_ENTRANCE_LOGIC); + return false; + } - // check all possible day/night condition combinations - conditionsMet = (parent->childDay && CheckConditionAtAgeTime(logic->IsChild, logic->AtDay, allAgeTimes)) + - (parent->childNight && CheckConditionAtAgeTime(logic->IsChild, logic->AtNight, allAgeTimes)) + - (parent->adultDay && CheckConditionAtAgeTime(logic->IsAdult, logic->AtDay, allAgeTimes)) + - (parent->adultNight && CheckConditionAtAgeTime(logic->IsAdult, logic->AtNight, allAgeTimes)); + // check all possible day/night condition combinations + conditionsMet = (parent->childDay && CheckConditionAtAgeTime(logic->IsChild, logic->AtDay, allAgeTimes)) + + (parent->childNight && CheckConditionAtAgeTime(logic->IsChild, logic->AtNight, allAgeTimes)) + + (parent->adultDay && CheckConditionAtAgeTime(logic->IsAdult, logic->AtDay, allAgeTimes)) + + (parent->adultNight && CheckConditionAtAgeTime(logic->IsAdult, logic->AtNight, allAgeTimes)); - StopPerformanceTimer(PT_ENTRANCE_LOGIC); - return conditionsMet && (!allAgeTimes || conditionsMet == 4); + StopPerformanceTimer(PT_ENTRANCE_LOGIC); + return conditionsMet && (!allAgeTimes || conditionsMet == 4); } uint32_t Entrance::Getuint32_t() const { @@ -227,13 +228,13 @@ Entrance* Entrance::AssumeReachable() { return assumed; } -bool Entrance::DoesSpreadAreas(){ - return spreadsAreasWithPriority; +bool Entrance::DoesSpreadAreas() { + return spreadsAreasWithPriority; } EntranceShuffler::EntranceShuffler() { - playthroughEntrances = {}; - entranceOverrides = {}; + playthroughEntrances = {}; + entranceOverrides = {}; } bool EntranceShuffler::HasNoRandomEntrances() { @@ -532,7 +533,8 @@ static bool ValidateWorld(Entrance* entrancePlaced) { // The player should be able to get back to ToT after going through time, without having collected any items // This is important to ensure that the player never loses access to the pedestal after going through time - if (ctx->GetOption(RSK_SELECTED_STARTING_AGE).Is(RO_AGE_CHILD) && !RegionTable(RR_TEMPLE_OF_TIME)->Adult()) { + if (ctx->GetOption(RSK_SELECTED_STARTING_AGE).Is(RO_AGE_CHILD) && + !RegionTable(RR_TEMPLE_OF_TIME)->Adult()) { SPDLOG_DEBUG("Path to Temple of Time as adult is not guaranteed\n"); return false; } else if (ctx->GetOption(RSK_SELECTED_STARTING_AGE).Is(RO_AGE_ADULT) && @@ -1574,7 +1576,7 @@ int EntranceShuffler::ShuffleAllEntrances() { void EntranceShuffler::CreateEntranceOverrides() { auto ctx = Rando::Context::GetInstance(); - entranceOverrides.fill({0, 0, 0, 0, 0}); + entranceOverrides.fill({ 0, 0, 0, 0, 0 }); if (mNoRandomEntrances) { return; } diff --git a/soh/soh/Enhancements/randomizer/entrance.h b/soh/soh/Enhancements/randomizer/entrance.h index 48a80c550..026da7426 100644 --- a/soh/soh/Enhancements/randomizer/entrance.h +++ b/soh/soh/Enhancements/randomizer/entrance.h @@ -96,8 +96,8 @@ class Entrance { bool addedToPool = false; bool decoupled = false; std::string name = ""; - //If this is false, areas only spread to interiors through this entrance if there is no other choice - //Set to false for owl drops, the windmill path between dampe's grave and windmill and blue warps + // If this is false, areas only spread to interiors through this entrance if there is no other choice + // Set to false for owl drops, the windmill path between dampe's grave and windmill and blue warps bool spreadsAreasWithPriority = true; }; @@ -128,6 +128,7 @@ class EntranceShuffler { void CreateEntranceOverrides(); void UnshuffleAllEntrances(); void ParseJson(nlohmann::json spoilerFileJson); + private: std::vector AssumeEntrancePool(std::vector& entrancePool); bool ShuffleOneWayPriorityEntrances(std::map& oneWayPriorities, @@ -150,7 +151,7 @@ class EntranceShuffler { extern "C" { #endif - EntranceOverride* Randomizer_GetEntranceOverrides(); +EntranceOverride* Randomizer_GetEntranceOverrides(); #ifdef __cplusplus } #endif diff --git a/soh/soh/Enhancements/randomizer/fishsanity.cpp b/soh/soh/Enhancements/randomizer/fishsanity.cpp index d6a76acc0..fe9b4c0f1 100644 --- a/soh/soh/Enhancements/randomizer/fishsanity.cpp +++ b/soh/soh/Enhancements/randomizer/fishsanity.cpp @@ -21,18 +21,18 @@ extern PlayState* gPlayState; /** * @brief Parallel list of pond fish checks for both ages -*/ + */ std::array, 17> Rando::StaticData::randomizerFishingPondFish = { { /* Child Check Adult Check */ - { RC_LH_CHILD_FISH_1, RC_LH_ADULT_FISH_1 }, - { RC_LH_CHILD_FISH_2, RC_LH_ADULT_FISH_2 }, - { RC_LH_CHILD_FISH_3, RC_LH_ADULT_FISH_3 }, - { RC_LH_CHILD_FISH_4, RC_LH_ADULT_FISH_4 }, - { RC_LH_CHILD_FISH_5, RC_LH_ADULT_FISH_5 }, - { RC_LH_CHILD_FISH_6, RC_LH_ADULT_FISH_6 }, - { RC_LH_CHILD_FISH_7, RC_LH_ADULT_FISH_7 }, - { RC_LH_CHILD_FISH_8, RC_LH_ADULT_FISH_8 }, - { RC_LH_CHILD_FISH_9, RC_LH_ADULT_FISH_9 }, + { RC_LH_CHILD_FISH_1, RC_LH_ADULT_FISH_1 }, + { RC_LH_CHILD_FISH_2, RC_LH_ADULT_FISH_2 }, + { RC_LH_CHILD_FISH_3, RC_LH_ADULT_FISH_3 }, + { RC_LH_CHILD_FISH_4, RC_LH_ADULT_FISH_4 }, + { RC_LH_CHILD_FISH_5, RC_LH_ADULT_FISH_5 }, + { RC_LH_CHILD_FISH_6, RC_LH_ADULT_FISH_6 }, + { RC_LH_CHILD_FISH_7, RC_LH_ADULT_FISH_7 }, + { RC_LH_CHILD_FISH_8, RC_LH_ADULT_FISH_8 }, + { RC_LH_CHILD_FISH_9, RC_LH_ADULT_FISH_9 }, { RC_LH_CHILD_FISH_10, RC_LH_ADULT_FISH_10 }, { RC_LH_CHILD_FISH_11, RC_LH_ADULT_FISH_11 }, { RC_LH_CHILD_FISH_12, RC_LH_ADULT_FISH_12 }, @@ -56,279 +56,284 @@ ActorFunc drawEnFish = NULL; Color_RGB8 fsPulseColor = { 30, 240, 200 }; namespace Rando { - const FishIdentity Fishsanity::defaultIdentity = { RAND_INF_MAX, RC_UNKNOWN_CHECK }; - bool Fishsanity::fishsanityHelpersInit = false; - s16 Fishsanity::fishGroupCounter = 0; - bool Fishsanity::enableAdvance = false; - std::unordered_map Fishsanity::pondFishAgeMap; - std::vector Fishsanity::childPondFish; - std::vector Fishsanity::adultPondFish; +const FishIdentity Fishsanity::defaultIdentity = { RAND_INF_MAX, RC_UNKNOWN_CHECK }; +bool Fishsanity::fishsanityHelpersInit = false; +s16 Fishsanity::fishGroupCounter = 0; +bool Fishsanity::enableAdvance = false; +std::unordered_map Fishsanity::pondFishAgeMap; +std::vector Fishsanity::childPondFish; +std::vector Fishsanity::adultPondFish; - Fishsanity::Fishsanity() { - InitializeHelpers(); - } +Fishsanity::Fishsanity() { + InitializeHelpers(); +} - Fishsanity::~Fishsanity() { - - } +Fishsanity::~Fishsanity() { +} - bool Fishsanity::GetFishLocationIncluded(Rando::Location* loc, - FishsanityOptionsSource optionsSource) { - auto [mode, numFish, ageSplit] = GetOptions(optionsSource); +bool Fishsanity::GetFishLocationIncluded(Rando::Location* loc, FishsanityOptionsSource optionsSource) { + auto [mode, numFish, ageSplit] = GetOptions(optionsSource); - if (loc->GetRCType() != RCTYPE_FISH || mode == RO_FISHSANITY_OFF) { - return false; - } - RandomizerCheck rc = loc->GetRandomizerCheck(); - // Are pond fish enabled, and is this a pond fish location? - if (mode != RO_FISHSANITY_OVERWORLD && numFish > 0 && loc->GetScene() == SCENE_FISHING_POND && - loc->GetActorID() == ACTOR_FISHING) { - // Is this a child fish location? If so, is it within the defined number of pond fish checks? - if (rc >= RC_LH_CHILD_FISH_1 && rc <= RC_LH_CHILD_LOACH_2 && numFish > (loc->GetActorParams() - 100)) { - return true; - } - // Are adult fish available, and is this an adult fish location? If so, is it within the defined number of pond - // fish checks? - if (ageSplit && rc >= RC_LH_ADULT_FISH_1 && rc <= RC_LH_ADULT_LOACH && numFish > (loc->GetActorParams() - 100)) { - return true; - } - } - // Are overworld fish enabled, and is this an overworld fish location? - if (mode != RO_FISHSANITY_POND && (loc->GetScene() == SCENE_GROTTOS || loc->GetScene() == SCENE_ZORAS_DOMAIN) - && loc->GetActorID() == ACTOR_EN_FISH && (loc->GetActorParams() >> 8)) { - return true; - } - // Must not be an included fish location! + if (loc->GetRCType() != RCTYPE_FISH || mode == RO_FISHSANITY_OFF) { return false; } - - std::pair, std::vector> - Fishsanity::GetFishingPondLocations(FishsanityOptionsSource optionsSource) { - auto [mode, numFish, ageSplit] = GetOptions(optionsSource); - std::vector activeFish; - std::vector remainingFish; - std::vector pondFish = Rando::StaticData::GetPondFishLocations(); - - // Fishsanity_InitializeHelpers(); - remainingFish.insert(remainingFish.end(), pondFish.begin(), pondFish.end()); - - // No pond fish shuffled - if (numFish == 0) { - return std::make_pair(activeFish, remainingFish); + RandomizerCheck rc = loc->GetRandomizerCheck(); + // Are pond fish enabled, and is this a pond fish location? + if (mode != RO_FISHSANITY_OVERWORLD && numFish > 0 && loc->GetScene() == SCENE_FISHING_POND && + loc->GetActorID() == ACTOR_FISHING) { + // Is this a child fish location? If so, is it within the defined number of pond fish checks? + if (rc >= RC_LH_CHILD_FISH_1 && rc <= RC_LH_CHILD_LOACH_2 && numFish > (loc->GetActorParams() - 100)) { + return true; } - // Every pond fish is shuffled, so we can save some time - if (numFish > 16) { - // Child and adult pond fish are both shuffled, set activeFish to remainingFish and return an empty vector for - // inactive fish. - if (ageSplit) { - return std::make_pair(remainingFish, activeFish); - } - // Activate all child fish only - activeFish = FilterAndEraseFromPool( - remainingFish, [](const RandomizerCheck loc) { return pondFishAgeMap[loc] == LINK_AGE_CHILD; }); - return std::make_pair(activeFish, remainingFish); + // Are adult fish available, and is this an adult fish location? If so, is it within the defined number of pond + // fish checks? + if (ageSplit && rc >= RC_LH_ADULT_FISH_1 && rc <= RC_LH_ADULT_LOACH && + numFish > (loc->GetActorParams() - 100)) { + return true; } - // Only some pond fish are shuffled, so we have to only activate the requested number. - activeFish.insert(activeFish.end(), childPondFish.begin(), childPondFish.begin() + numFish); - // If pond is split, also add the requested number of adult fish. + } + // Are overworld fish enabled, and is this an overworld fish location? + if (mode != RO_FISHSANITY_POND && (loc->GetScene() == SCENE_GROTTOS || loc->GetScene() == SCENE_ZORAS_DOMAIN) && + loc->GetActorID() == ACTOR_EN_FISH && (loc->GetActorParams() >> 8)) { + return true; + } + // Must not be an included fish location! + return false; +} + +std::pair, std::vector> +Fishsanity::GetFishingPondLocations(FishsanityOptionsSource optionsSource) { + auto [mode, numFish, ageSplit] = GetOptions(optionsSource); + std::vector activeFish; + std::vector remainingFish; + std::vector pondFish = Rando::StaticData::GetPondFishLocations(); + + // Fishsanity_InitializeHelpers(); + remainingFish.insert(remainingFish.end(), pondFish.begin(), pondFish.end()); + + // No pond fish shuffled + if (numFish == 0) { + return std::make_pair(activeFish, remainingFish); + } + // Every pond fish is shuffled, so we can save some time + if (numFish > 16) { + // Child and adult pond fish are both shuffled, set activeFish to remainingFish and return an empty vector for + // inactive fish. if (ageSplit) { - activeFish.insert(activeFish.end(), adultPondFish.begin(), - adultPondFish.begin() + std::min(numFish, 16)); + return std::make_pair(remainingFish, activeFish); } - // NOTE: This only works because we can assume activeFish is already sorted; changes that break this assumption will - // also break this - FilterAndEraseFromPool(remainingFish, - [&](uint32_t loc) { return std::binary_search(activeFish.begin(), activeFish.end(), loc); }); - + // Activate all child fish only + activeFish = FilterAndEraseFromPool( + remainingFish, [](const RandomizerCheck loc) { return pondFishAgeMap[loc] == LINK_AGE_CHILD; }); return std::make_pair(activeFish, remainingFish); } + // Only some pond fish are shuffled, so we have to only activate the requested number. + activeFish.insert(activeFish.end(), childPondFish.begin(), childPondFish.begin() + numFish); + // If pond is split, also add the requested number of adult fish. + if (ageSplit) { + activeFish.insert(activeFish.end(), adultPondFish.begin(), + adultPondFish.begin() + std::min(numFish, 16)); + } + // NOTE: This only works because we can assume activeFish is already sorted; changes that break this assumption will + // also break this + FilterAndEraseFromPool(remainingFish, + [&](uint32_t loc) { return std::binary_search(activeFish.begin(), activeFish.end(), loc); }); - std::pair, std::vector> - Fishsanity::GetFishsanityLocations(FishsanityOptionsSource optionsSource) { - auto [mode, numFish, ageSplit] = GetOptions(optionsSource); - std::vector activeFish; - std::vector remainingFish; + return std::make_pair(activeFish, remainingFish); +} - // Add pond fish - if (mode == RO_FISHSANITY_POND || mode == RO_FISHSANITY_BOTH) { - auto pondLocations = GetFishingPondLocations(optionsSource); - activeFish.insert(activeFish.end(), pondLocations.first.begin(), pondLocations.first.end()); - remainingFish.insert(remainingFish.end(), pondLocations.second.begin(), pondLocations.second.end()); - } +std::pair, std::vector> +Fishsanity::GetFishsanityLocations(FishsanityOptionsSource optionsSource) { + auto [mode, numFish, ageSplit] = GetOptions(optionsSource); + std::vector activeFish; + std::vector remainingFish; - // Add overworld fish - if (mode == RO_FISHSANITY_OVERWORLD || mode == RO_FISHSANITY_BOTH) { - std::vector overworldFish = Rando::StaticData::GetOverworldFishLocations(); - activeFish.insert(activeFish.end(), overworldFish.begin(), overworldFish.end()); - } - - return std::make_pair(activeFish, remainingFish); + // Add pond fish + if (mode == RO_FISHSANITY_POND || mode == RO_FISHSANITY_BOTH) { + auto pondLocations = GetFishingPondLocations(optionsSource); + activeFish.insert(activeFish.end(), pondLocations.first.begin(), pondLocations.first.end()); + remainingFish.insert(remainingFish.end(), pondLocations.second.begin(), pondLocations.second.end()); } - FishIdentity Fishsanity::IdentifyPondFish(u8 fishParams) { - auto [mode, pondCount, ageSplit] = GetOptions(); - FishIdentity identity = defaultIdentity; + // Add overworld fish + if (mode == RO_FISHSANITY_OVERWORLD || mode == RO_FISHSANITY_BOTH) { + std::vector overworldFish = Rando::StaticData::GetOverworldFishLocations(); + activeFish.insert(activeFish.end(), overworldFish.begin(), overworldFish.end()); + } - if (!GetPondFishShuffled()) { - return identity; - } + return std::make_pair(activeFish, remainingFish); +} - if (pondCount > 16) { - identity = GetPondFish(fishParams, IsAdultPond()); - } else { - identity = LINK_IS_ADULT ? mCurrPondFish.second : mCurrPondFish.first; - } +FishIdentity Fishsanity::IdentifyPondFish(u8 fishParams) { + auto [mode, pondCount, ageSplit] = GetOptions(); + FishIdentity identity = defaultIdentity; + if (!GetPondFishShuffled()) { return identity; } - FishsanityPondOptions Fishsanity::GetOptions(FishsanityOptionsSource optionsSource) { - FishsanityPondOptions options{}; - switch (optionsSource) { - // Used in check tracker - case FSO_SOURCE_CVARS: - options.mode = CVarGetInteger(CVAR_RANDOMIZER_SETTING("Fishsanity"), RO_FISHSANITY_OFF); - options.numFish = CVarGetInteger(CVAR_RANDOMIZER_SETTING("FishsanityPondCount"), 0); - options.ageSplit = CVarGetInteger(CVAR_RANDOMIZER_SETTING("FishsanityAgeSplit"), 0) == 1; - break; - case FSO_SOURCE_RANDO: - default: - options.mode = OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_FISHSANITY); - options.numFish = OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_FISHSANITY_POND_COUNT); - options.ageSplit = OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_FISHSANITY_AGE_SPLIT); - break; - } - return options; + if (pondCount > 16) { + identity = GetPondFish(fishParams, IsAdultPond()); + } else { + identity = LINK_IS_ADULT ? mCurrPondFish.second : mCurrPondFish.first; } - void Fishsanity::UpdateCurrentPondFish() { - auto [mode, pondCount, ageSplit] = GetOptions(); - mCurrPondFish = std::pair(); - mCurrPondFish.first = defaultIdentity; - mCurrPondFish.second = defaultIdentity; + return identity; +} - // Initialize mCurrPondFish if we're shuffling pond fish, but if all fish are shuffled, we don't need to use this. - if ((mode == RO_FISHSANITY_BOTH || mode == RO_FISHSANITY_POND) && pondCount < 17) { - // find the first inf that isn't set yet for each age - // but don't go past the max number - std::pair tableEntry; - for (s16 i = 0, params = 100; i < pondCount; i++, params++) { - tableEntry = Rando::StaticData::randomizerFishingPondFish[i]; - if (!Flags_GetRandomizerInf(OTRGlobals::Instance->gRandomizer->GetRandomizerInfFromCheck(tableEntry.first)) || i == pondCount - 1) { - // Found first child check - if (!IsFish(&mCurrPondFish.first)) { - mCurrPondFish.first = GetPondFish(params, false); - } +FishsanityPondOptions Fishsanity::GetOptions(FishsanityOptionsSource optionsSource) { + FishsanityPondOptions options{}; + switch (optionsSource) { + // Used in check tracker + case FSO_SOURCE_CVARS: + options.mode = CVarGetInteger(CVAR_RANDOMIZER_SETTING("Fishsanity"), RO_FISHSANITY_OFF); + options.numFish = CVarGetInteger(CVAR_RANDOMIZER_SETTING("FishsanityPondCount"), 0); + options.ageSplit = CVarGetInteger(CVAR_RANDOMIZER_SETTING("FishsanityAgeSplit"), 0) == 1; + break; + case FSO_SOURCE_RANDO: + default: + options.mode = OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_FISHSANITY); + options.numFish = OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_FISHSANITY_POND_COUNT); + options.ageSplit = OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_FISHSANITY_AGE_SPLIT); + break; + } + return options; +} - if (!ageSplit && !IsFish(&mCurrPondFish.second)) { - mCurrPondFish.second = GetPondFish(params, false); - // both ages are resolved! we can quit here - break; - } +void Fishsanity::UpdateCurrentPondFish() { + auto [mode, pondCount, ageSplit] = GetOptions(); + mCurrPondFish = std::pair(); + mCurrPondFish.first = defaultIdentity; + mCurrPondFish.second = defaultIdentity; + + // Initialize mCurrPondFish if we're shuffling pond fish, but if all fish are shuffled, we don't need to use this. + if ((mode == RO_FISHSANITY_BOTH || mode == RO_FISHSANITY_POND) && pondCount < 17) { + // find the first inf that isn't set yet for each age + // but don't go past the max number + std::pair tableEntry; + for (s16 i = 0, params = 100; i < pondCount; i++, params++) { + tableEntry = Rando::StaticData::randomizerFishingPondFish[i]; + if (!Flags_GetRandomizerInf( + OTRGlobals::Instance->gRandomizer->GetRandomizerInfFromCheck(tableEntry.first)) || + i == pondCount - 1) { + // Found first child check + if (!IsFish(&mCurrPondFish.first)) { + mCurrPondFish.first = GetPondFish(params, false); } - if (ageSplit && !IsFish(&mCurrPondFish.second) && tableEntry.second != RC_UNKNOWN_CHECK && - (!Flags_GetRandomizerInf(OTRGlobals::Instance->gRandomizer->GetRandomizerInfFromCheck(tableEntry.second)) || i == pondCount - 1)) { - mCurrPondFish.second = GetPondFish(params, true); + if (!ageSplit && !IsFish(&mCurrPondFish.second)) { + mCurrPondFish.second = GetPondFish(params, false); + // both ages are resolved! we can quit here + break; } } + + if (ageSplit && !IsFish(&mCurrPondFish.second) && tableEntry.second != RC_UNKNOWN_CHECK && + (!Flags_GetRandomizerInf( + OTRGlobals::Instance->gRandomizer->GetRandomizerInfFromCheck(tableEntry.second)) || + i == pondCount - 1)) { + mCurrPondFish.second = GetPondFish(params, true); + } } } +} - void Fishsanity::InitializeFromSave() { - UpdateCurrentPondFish(); - } +void Fishsanity::InitializeFromSave() { + UpdateCurrentPondFish(); +} - bool Fishsanity::GetPondFishShuffled() { - u8 fsMode = OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_FISHSANITY); - return OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_FISHSANITY_POND_COUNT) > 0 && - (fsMode == RO_FISHSANITY_POND || fsMode == RO_FISHSANITY_BOTH); - } +bool Fishsanity::GetPondFishShuffled() { + u8 fsMode = OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_FISHSANITY); + return OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_FISHSANITY_POND_COUNT) > 0 && + (fsMode == RO_FISHSANITY_POND || fsMode == RO_FISHSANITY_BOTH); +} - bool Fishsanity::GetOverworldFishShuffled() { - u8 fsMode = OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_FISHSANITY); - return fsMode == RO_FISHSANITY_OVERWORLD || fsMode == RO_FISHSANITY_BOTH; - } +bool Fishsanity::GetOverworldFishShuffled() { + u8 fsMode = OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_FISHSANITY); + return fsMode == RO_FISHSANITY_OVERWORLD || fsMode == RO_FISHSANITY_BOTH; +} - bool Fishsanity::IsAdultPond() { - return LINK_IS_ADULT && OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_FISHSANITY_AGE_SPLIT); - } +bool Fishsanity::IsAdultPond() { + return LINK_IS_ADULT && OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_FISHSANITY_AGE_SPLIT); +} - bool Fishsanity::GetPondCleared() { - auto [mode, pondCount, ageSplit] = GetOptions(); - // no fish shuffled, so pond is always cleared :thumbsup: - if (pondCount == 0) { - return true; - } - - bool adultPond = LINK_IS_ADULT && ageSplit; - // if we've collected the final shuffled fish, pond is complete - if (pondCount <= 16) { - auto tableEntry = Rando::StaticData::randomizerFishingPondFish[pondCount - 1]; - return Flags_GetRandomizerInf(OTRGlobals::Instance->gRandomizer->GetRandomizerInfFromCheck(adultPond ? tableEntry.second : tableEntry.first)); - } - - // the last two checks actually don't matter because logically they will never be true, but maybe one day they will - // if every fish is shuffled, check if we've collected every fish - for (auto tableEntry : Rando::StaticData::randomizerFishingPondFish) { - RandomizerCheck rc = adultPond ? tableEntry.second : tableEntry.first; - // if we haven't collected this fish, then we're not done yet! get back in there, soldier - if (rc != RC_UNKNOWN_CHECK && !Flags_GetRandomizerInf(OTRGlobals::Instance->gRandomizer->GetRandomizerInfFromCheck(rc))) { - return false; - } - } +bool Fishsanity::GetPondCleared() { + auto [mode, pondCount, ageSplit] = GetOptions(); + // no fish shuffled, so pond is always cleared :thumbsup: + if (pondCount == 0) { return true; } - bool Fishsanity::GetDomainCleared() { - for (RandomizerInf i = RAND_INF_ZD_FISH_1; i <= RAND_INF_ZD_FISH_5; i = (RandomizerInf)(i + 1)) { - if (!Flags_GetRandomizerInf(i)) { - return false; - } - } - return true; + bool adultPond = LINK_IS_ADULT && ageSplit; + // if we've collected the final shuffled fish, pond is complete + if (pondCount <= 16) { + auto tableEntry = Rando::StaticData::randomizerFishingPondFish[pondCount - 1]; + return Flags_GetRandomizerInf(OTRGlobals::Instance->gRandomizer->GetRandomizerInfFromCheck( + adultPond ? tableEntry.second : tableEntry.first)); } - void Fishsanity::InitializeHelpers() { - if (fishsanityHelpersInit) { - return; - } - - for (auto pair : Rando::StaticData::randomizerFishingPondFish) { - pondFishAgeMap[pair.first] = LINK_AGE_CHILD; - pondFishAgeMap[pair.second] = LINK_AGE_ADULT; - childPondFish.push_back(pair.first); - adultPondFish.push_back(pair.second); + // the last two checks actually don't matter because logically they will never be true, but maybe one day they will + // if every fish is shuffled, check if we've collected every fish + for (auto tableEntry : Rando::StaticData::randomizerFishingPondFish) { + RandomizerCheck rc = adultPond ? tableEntry.second : tableEntry.first; + // if we haven't collected this fish, then we're not done yet! get back in there, soldier + if (rc != RC_UNKNOWN_CHECK && + !Flags_GetRandomizerInf(OTRGlobals::Instance->gRandomizer->GetRandomizerInfFromCheck(rc))) { + return false; } } + return true; +} - FishIdentity Fishsanity::GetPondFish(s16 params, bool adultPond) { - auto pair = Rando::StaticData::randomizerFishingPondFish[params - 100]; - RandomizerCheck rc = adultPond ? pair.second : pair.first; - return { OTRGlobals::Instance->gRandomizer->GetRandomizerInfFromCheck(rc), rc }; +bool Fishsanity::GetDomainCleared() { + for (RandomizerInf i = RAND_INF_ZD_FISH_1; i <= RAND_INF_ZD_FISH_5; i = (RandomizerInf)(i + 1)) { + if (!Flags_GetRandomizerInf(i)) { + return false; + } + } + return true; +} + +void Fishsanity::InitializeHelpers() { + if (fishsanityHelpersInit) { + return; } - FishIdentity Fishsanity::AdvancePond() { - auto [mode, pondCount, ageSplit] = GetOptions(); + for (auto pair : Rando::StaticData::randomizerFishingPondFish) { + pondFishAgeMap[pair.first] = LINK_AGE_CHILD; + pondFishAgeMap[pair.second] = LINK_AGE_ADULT; + childPondFish.push_back(pair.first); + adultPondFish.push_back(pair.second); + } +} - // No need to update state with full pond shuffle - if (pondCount > 16) { - return defaultIdentity; - } +FishIdentity Fishsanity::GetPondFish(s16 params, bool adultPond) { + auto pair = Rando::StaticData::randomizerFishingPondFish[params - 100]; + RandomizerCheck rc = adultPond ? pair.second : pair.first; + return { OTRGlobals::Instance->gRandomizer->GetRandomizerInfFromCheck(rc), rc }; +} - UpdateCurrentPondFish(); +FishIdentity Fishsanity::AdvancePond() { + auto [mode, pondCount, ageSplit] = GetOptions(); - return IsAdultPond() ? mCurrPondFish.second : mCurrPondFish.first; + // No need to update state with full pond shuffle + if (pondCount > 16) { + return defaultIdentity; } - FishsanityCheckType Fishsanity::GetCheckType(RandomizerCheck rc) { - // if it's not RCTYPE_FISH, obviously it's not a fish - if (Rando::StaticData::GetLocation(rc)->GetRCType() != RCTYPE_FISH) { - return FSC_NONE; - } + UpdateCurrentPondFish(); - auto loc = Rando::StaticData::GetLocation(rc); - switch (loc->GetScene()) { + return IsAdultPond() ? mCurrPondFish.second : mCurrPondFish.first; +} + +FishsanityCheckType Fishsanity::GetCheckType(RandomizerCheck rc) { + // if it's not RCTYPE_FISH, obviously it's not a fish + if (Rando::StaticData::GetLocation(rc)->GetRCType() != RCTYPE_FISH) { + return FSC_NONE; + } + + auto loc = Rando::StaticData::GetLocation(rc); + switch (loc->GetScene()) { case SCENE_FISHING_POND: return FSC_POND; case SCENE_ZORAS_DOMAIN: @@ -337,251 +342,246 @@ namespace Rando { return FSC_GROTTO; default: return FSC_NONE; - } + } +} + +bool Fishsanity::IsFish(FishIdentity* fish) { + if (fish->randomizerCheck == RC_UNKNOWN_CHECK || fish->randomizerInf == RAND_INF_MAX) { + return false; } - bool Fishsanity::IsFish(FishIdentity* fish) { - if (fish->randomizerCheck == RC_UNKNOWN_CHECK || fish->randomizerInf == RAND_INF_MAX) { - return false; + return GetCheckType(fish->randomizerCheck) != FSC_NONE; +} + +void Fishsanity::OnActorInitHandler(void* refActor) { + Actor* actor = static_cast(refActor); + + auto fs = OTRGlobals::Instance->gRandoContext->GetFishsanity(); + FishIdentity fish; + + if (actor->id == ACTOR_EN_FISH && fs->GetOverworldFishShuffled()) { + // Set fish ID for ZD fish + if (gPlayState->sceneNum == SCENE_ZORAS_DOMAIN && actor->params == -1) { + actor->params ^= fishGroupCounter++; + } else if (gPlayState->sceneNum == SCENE_GROTTOS && actor->params == 1) { + actor->params = 0x100 | gSaveContext.respawn[RESPAWN_MODE_RETURN].data; } - return GetCheckType(fish->randomizerCheck) != FSC_NONE; - } - - void Fishsanity::OnActorInitHandler(void* refActor) { - Actor* actor = static_cast(refActor); - - auto fs = OTRGlobals::Instance->gRandoContext->GetFishsanity(); - FishIdentity fish; - - if (actor->id == ACTOR_EN_FISH && fs->GetOverworldFishShuffled()) { - // Set fish ID for ZD fish - if (gPlayState->sceneNum == SCENE_ZORAS_DOMAIN && actor->params == -1) { - actor->params ^= fishGroupCounter++; - } else if (gPlayState->sceneNum == SCENE_GROTTOS && actor->params == 1) { - actor->params = 0x100 | gSaveContext.respawn[RESPAWN_MODE_RETURN].data; + fish = OTRGlobals::Instance->gRandomizer->IdentifyFish(gPlayState->sceneNum, actor->params); + // Render fish as randomized item + if (Rando::Fishsanity::IsFish(&fish) && !Flags_GetRandomizerInf(fish.randomizerInf)) { + if (!drawEnFish) { + drawEnFish = actor->draw; } + actor->draw = Fishsanity_DrawEnFish; + } + return; + } - fish = OTRGlobals::Instance->gRandomizer->IdentifyFish(gPlayState->sceneNum, actor->params); - // Render fish as randomized item - if (Rando::Fishsanity::IsFish(&fish) && !Flags_GetRandomizerInf(fish.randomizerInf)) { - if (!drawEnFish) { - drawEnFish = actor->draw; + if (actor->id == ACTOR_FISHING && gPlayState->sceneNum == SCENE_FISHING_POND && actor->params >= 100 && + actor->params <= 117 && fs->GetPondFishShuffled()) { + // Initialize pond fish for fishsanity + // Initialize fishsanity metadata on this actor + Fishing* fishActor = static_cast(refActor); + // fishActor->fishsanityParams = actor->params; + fish = OTRGlobals::Instance->gRandomizer->IdentifyFish(gPlayState->sceneNum, actor->params); + + // With every pond fish shuffled, caught fish will not spawn unless all fish have been caught. + if (RAND_GET_OPTION(RSK_FISHSANITY_POND_COUNT) > 16 && !fs->GetPondCleared()) { + // Create effect for uncaught fish + if (!Flags_GetRandomizerInf(fish.randomizerInf)) { + actor->shape.shadowDraw = Fishsanity_DrawEffShadow; + if (!drawFishing) { + drawFishing = actor->draw; } - actor->draw = Fishsanity_DrawEnFish; + actor->draw = Fishsanity_DrawFishing; } - return; } + } +} - if (actor->id == ACTOR_FISHING && gPlayState->sceneNum == SCENE_FISHING_POND && actor->params >= 100 && - actor->params <= 117 && fs->GetPondFishShuffled()) { - // Initialize pond fish for fishsanity - // Initialize fishsanity metadata on this actor - Fishing* fishActor = static_cast(refActor); - //fishActor->fishsanityParams = actor->params; - fish = OTRGlobals::Instance->gRandomizer->IdentifyFish(gPlayState->sceneNum, actor->params); +void Fishsanity::OnActorUpdateHandler(void* refActor) { + if (gPlayState->sceneNum != SCENE_GROTTOS && gPlayState->sceneNum != SCENE_ZORAS_DOMAIN && + gPlayState->sceneNum != SCENE_FISHING_POND) { + return; + } - // With every pond fish shuffled, caught fish will not spawn unless all fish have been caught. - if (RAND_GET_OPTION(RSK_FISHSANITY_POND_COUNT) > 16 && - !fs->GetPondCleared()) { - // Create effect for uncaught fish - if (!Flags_GetRandomizerInf(fish.randomizerInf)) { - actor->shape.shadowDraw = Fishsanity_DrawEffShadow; - if (!drawFishing) { - drawFishing = actor->draw; - } - actor->draw = Fishsanity_DrawFishing; + Actor* actor = static_cast(refActor); + auto fs = OTRGlobals::Instance->gRandoContext->GetFishsanity(); + + // Detect fish catch + if (actor->id == ACTOR_FISHING && fs->GetPondFishShuffled()) { + Fishing* fish = static_cast(refActor); + + // State 6 -> Fish caught and hoisted + if (fish->fishState == 6) { + FishIdentity identity = + OTRGlobals::Instance->gRandomizer->IdentifyFish(gPlayState->sceneNum, actor->params); + if (identity.randomizerCheck != RC_UNKNOWN_CHECK) { + Flags_SetRandomizerInf(identity.randomizerInf); + enableAdvance = true; + // Remove uncaught effect + if (actor->shape.shadowDraw != NULL) { + actor->shape.shadowDraw = NULL; + actor->draw = drawFishing; } } } } - void Fishsanity::OnActorUpdateHandler(void* refActor) { - if (gPlayState->sceneNum != SCENE_GROTTOS && gPlayState->sceneNum != SCENE_ZORAS_DOMAIN && gPlayState->sceneNum != SCENE_FISHING_POND) { - return; - } - - Actor* actor = static_cast(refActor); - auto fs = OTRGlobals::Instance->gRandoContext->GetFishsanity(); - - // Detect fish catch - if (actor->id == ACTOR_FISHING && fs->GetPondFishShuffled()) { - Fishing* fish = static_cast(refActor); - - // State 6 -> Fish caught and hoisted - if (fish->fishState == 6) { - FishIdentity identity = OTRGlobals::Instance->gRandomizer->IdentifyFish(gPlayState->sceneNum, actor->params); - if (identity.randomizerCheck != RC_UNKNOWN_CHECK) { - Flags_SetRandomizerInf(identity.randomizerInf); - enableAdvance = true; - // Remove uncaught effect - if (actor->shape.shadowDraw != NULL) { - actor->shape.shadowDraw = NULL; - actor->draw = drawFishing; - } - } + if (actor->id == ACTOR_EN_FISH && fs->GetOverworldFishShuffled()) { + FishIdentity fish = OTRGlobals::Instance->gRandomizer->IdentifyFish(gPlayState->sceneNum, actor->params); + EnFish* fishActor = static_cast(refActor); + if (Rando::Fishsanity::IsFish(&fish) && Flags_GetRandomizerInf(fish.randomizerInf)) { + // Reset draw method + if (actor->draw == Fishsanity_DrawEnFish) { + actor->draw = drawEnFish; } } - if (actor->id == ACTOR_EN_FISH && fs->GetOverworldFishShuffled()) { - FishIdentity fish = OTRGlobals::Instance->gRandomizer->IdentifyFish(gPlayState->sceneNum, actor->params); - EnFish* fishActor = static_cast(refActor); - if (Rando::Fishsanity::IsFish(&fish) && Flags_GetRandomizerInf(fish.randomizerInf)) { - // Reset draw method - if (actor->draw == Fishsanity_DrawEnFish) { - actor->draw = drawEnFish; - } - } - - if (((actor->params >> 8) > 0) && fishActor->respawnTimer > 0) { - Actor_Kill(actor); - } - } - - // Reset fish group counter when the group gets culled - if (actor->id == ACTOR_OBJ_MURE && gPlayState->sceneNum == SCENE_ZORAS_DOMAIN && fishGroupCounter > 0 && - !(actor->flags & ACTOR_FLAG_UPDATE_CULLING_DISABLED) && fs->GetOverworldFishShuffled()) { - fishGroupCounter = 0; + if (((actor->params >> 8) > 0) && fishActor->respawnTimer > 0) { + Actor_Kill(actor); } } - void Fishsanity::OnSceneInitHandler(int16_t sceneNum) { - if (sceneNum == SCENE_ZORAS_DOMAIN) { - fishGroupCounter = 0; + // Reset fish group counter when the group gets culled + if (actor->id == ACTOR_OBJ_MURE && gPlayState->sceneNum == SCENE_ZORAS_DOMAIN && fishGroupCounter > 0 && + !(actor->flags & ACTOR_FLAG_UPDATE_CULLING_DISABLED) && fs->GetOverworldFishShuffled()) { + fishGroupCounter = 0; + } +} + +void Fishsanity::OnSceneInitHandler(int16_t sceneNum) { + if (sceneNum == SCENE_ZORAS_DOMAIN) { + fishGroupCounter = 0; + } +} + +void Fishsanity::OnVanillaBehaviorHandler(GIVanillaBehavior id, bool* should, va_list originalArgs) { + va_list args; + va_copy(args, originalArgs); + + Actor* actor = va_arg(args, Actor*); + auto fs = OTRGlobals::Instance->gRandoContext->GetFishsanity(); + + va_end(args); + + if (id == VB_BOTTLE_ACTOR && actor->id == ACTOR_EN_FISH && fs->GetOverworldFishShuffled()) { + FishIdentity fish = OTRGlobals::Instance->gRandomizer->IdentifyFish(gPlayState->sceneNum, actor->params); + if (fish.randomizerCheck != RC_UNKNOWN_CHECK && !Flags_GetRandomizerInf(fish.randomizerInf)) { + Flags_SetRandomizerInf(fish.randomizerInf); + actor->parent = &GET_PLAYER(gPlayState)->actor; + *should = false; } } +} - void Fishsanity::OnVanillaBehaviorHandler(GIVanillaBehavior id, bool* should, va_list originalArgs) { - va_list args; - va_copy(args, originalArgs); - - Actor* actor = va_arg(args, Actor*); - auto fs = OTRGlobals::Instance->gRandoContext->GetFishsanity(); - - va_end(args); - - if (id == VB_BOTTLE_ACTOR && actor->id == ACTOR_EN_FISH && fs->GetOverworldFishShuffled()) { - FishIdentity fish = OTRGlobals::Instance->gRandomizer->IdentifyFish(gPlayState->sceneNum, actor->params); - if (fish.randomizerCheck != RC_UNKNOWN_CHECK && !Flags_GetRandomizerInf(fish.randomizerInf)) { - Flags_SetRandomizerInf(fish.randomizerInf); - actor->parent = &GET_PLAYER(gPlayState)->actor; - *should = false; - } - } - } - - void Fishsanity::OnItemReceiveHandler(GetItemEntry itemEntry) { - if (enableAdvance) { - enableAdvance = false; - OTRGlobals::Instance->gRandoContext->GetFishsanity()->AdvancePond(); - } +void Fishsanity::OnItemReceiveHandler(GetItemEntry itemEntry) { + if (enableAdvance) { + enableAdvance = false; + OTRGlobals::Instance->gRandoContext->GetFishsanity()->AdvancePond(); } +} } // namespace Rando // C interface extern "C" { - bool Randomizer_GetPondFishShuffled() { - return FSi->GetPondFishShuffled(); +bool Randomizer_GetPondFishShuffled() { + return FSi->GetPondFishShuffled(); +} + +bool Randomizer_GetOverworldFishShuffled() { + return FSi->GetOverworldFishShuffled(); +} + +bool Randomizer_IsAdultPond() { + return FSi->IsAdultPond(); +} + +void Fishsanity_DrawEffShadow(Actor* actor, Lights* lights, PlayState* play) { + Vec3f pos, ripplePos; + static Vec3f velocity = { 0.0f, 0.0f, 0.0f }; + static Vec3f accel = { 0.0f, 0.0f, 0.0f }; + Color_RGBA8 primColor; + Color_RGBA8 envColor; + + // Color of the circle for the particles + static Color_RGBA8 mainColors[5][4] = { { 240, 154, 137, 200 }, + { 240, 190, 137, 200 }, + { 240, 171, 137, 200 }, + { 240, 141, 146, 200 }, + { 240, 204, 137, 200 } }; + + // Color of the faded flares stretching off the particles + static Color_RGBA8 flareColors[5][3] = { + { 128, 85, 82, 200 }, { 128, 101, 82, 200 }, { 128, 93, 82, 200 }, { 128, 82, 98, 200 }, { 128, 108, 82, 200 } + }; + + Color_RGBA8_Copy(&primColor, mainColors[ABS(actor->params) % 5]); + Color_RGBA8_Copy(&envColor, flareColors[ABS(actor->params) % 5]); + + // Spawn sparkles + pos.x = Rand_CenteredFloat(23.0f) + actor->world.pos.x; + pos.y = (Rand_Centered() * 12.0f) + actor->world.pos.y; + pos.z = Rand_CenteredFloat(23.0f) + actor->world.pos.z; + velocity.y = 0.05f; + accel.y = 0.025f; + Math_Vec3f_Copy(&ripplePos, &pos); + ripplePos.y += actor->yDistToWater; + + if (Rand_ZeroOne() < 0.3f) { + EffectSsKiraKira_SpawnDispersed(play, &pos, &velocity, &accel, &primColor, &envColor, 1800, 10); } - bool Randomizer_GetOverworldFishShuffled() { - return FSi->GetOverworldFishShuffled(); + if (actor->bgCheckFlags & 0x20 && Rand_ZeroOne() < 0.15f) { + EffectSsGRipple_Spawn(play, &ripplePos, 100, 200, 2); + } +} + +void Fishsanity_DrawEnFish(struct Actor* actor, struct PlayState* play) { + FishIdentity fish = OTRGlobals::Instance->gRandomizer->IdentifyFish(play->sceneNum, actor->params); + GetItemEntry randoItem = Rando::Context::GetInstance()->GetFinalGIEntry(fish.randomizerCheck, true, GI_FISH); + if (CVarGetInteger(CVAR_RANDOMIZER_ENHANCEMENT("MysteriousShuffle"), 0)) { + randoItem = GET_ITEM_MYSTERY; } - bool Randomizer_IsAdultPond() { - return FSi->IsAdultPond(); - } + Matrix_Push(); + Matrix_Scale(30.0, 30.0, 30.0, MTXMODE_APPLY); - void Fishsanity_DrawEffShadow(Actor* actor, Lights* lights, PlayState* play) { - Vec3f pos, ripplePos; - static Vec3f velocity = { 0.0f, 0.0f, 0.0f }; - static Vec3f accel = { 0.0f, 0.0f, 0.0f }; - Color_RGBA8 primColor; - Color_RGBA8 envColor; + func_8002EBCC(actor, play, 0); + func_8002ED80(actor, play, 0); + EnItem00_CustomItemsParticles(actor, play, randoItem); + GetItemEntry_Draw(play, randoItem); - // Color of the circle for the particles - static Color_RGBA8 mainColors[5][4] = { - { 240, 154, 137, 200 }, - { 240, 190, 137, 200 }, - { 240, 171, 137, 200 }, - { 240, 141, 146, 200 }, - { 240, 204, 137, 200 } - }; + Matrix_Pop(); +} - // Color of the faded flares stretching off the particles - static Color_RGBA8 flareColors[5][3] = { - { 128, 85, 82, 200 }, - { 128, 101, 82, 200 }, - { 128, 93, 82, 200 }, - { 128, 82, 98, 200 }, - { 128, 108, 82, 200 } - }; +void Fishsanity_DrawFishing(struct Actor* actor, struct PlayState* play) { + Fishsanity_OpenGreyscaleColor(play, &fsPulseColor, (actor->params - 100) * 20); + drawFishing(actor, play); + Fishsanity_CloseGreyscaleColor(play); +} - Color_RGBA8_Copy(&primColor, mainColors[ABS(actor->params) % 5]); - Color_RGBA8_Copy(&envColor, flareColors[ABS(actor->params) % 5]); +void Fishsanity_OpenGreyscaleColor(PlayState* play, Color_RGB8* color, int16_t frameOffset) { + OPEN_DISPS(play->state.gfxCtx); + gDPSetGrayscaleColor(POLY_OPA_DISP++, color->r, color->g, color->b, + // Make color pulse, offset a bit by the actor params + ABS(255.0f * Math_CosS((play->gameplayFrames + frameOffset) * 1000))); + gSPGrayscale(POLY_OPA_DISP++, true); + CLOSE_DISPS(play->state.gfxCtx); +} - // Spawn sparkles - pos.x = Rand_CenteredFloat(23.0f) + actor->world.pos.x; - pos.y = (Rand_Centered() * 12.0f) + actor->world.pos.y; - pos.z = Rand_CenteredFloat(23.0f) + actor->world.pos.z; - velocity.y = 0.05f; - accel.y = 0.025f; - Math_Vec3f_Copy(&ripplePos, &pos); - ripplePos.y += actor->yDistToWater; - - if (Rand_ZeroOne() < 0.3f) { - EffectSsKiraKira_SpawnDispersed(play, &pos, &velocity, &accel, &primColor, &envColor, 1800, 10); - } - - if (actor->bgCheckFlags & 0x20 && Rand_ZeroOne() < 0.15f) { - EffectSsGRipple_Spawn(play, &ripplePos, 100, 200, 2); - } - } - - void Fishsanity_DrawEnFish(struct Actor* actor, struct PlayState* play) { - FishIdentity fish = OTRGlobals::Instance->gRandomizer->IdentifyFish(play->sceneNum, actor->params); - GetItemEntry randoItem = Rando::Context::GetInstance()->GetFinalGIEntry(fish.randomizerCheck, true, GI_FISH); - if (CVarGetInteger(CVAR_RANDOMIZER_ENHANCEMENT("MysteriousShuffle"), 0)) { - randoItem = GET_ITEM_MYSTERY; - } - - Matrix_Push(); - Matrix_Scale(30.0, 30.0, 30.0, MTXMODE_APPLY); - - func_8002EBCC(actor, play, 0); - func_8002ED80(actor, play, 0); - EnItem00_CustomItemsParticles(actor, play, randoItem); - GetItemEntry_Draw(play, randoItem); - - Matrix_Pop(); - } - - void Fishsanity_DrawFishing(struct Actor* actor, struct PlayState* play) { - Fishsanity_OpenGreyscaleColor(play, &fsPulseColor, (actor->params - 100) * 20); - drawFishing(actor, play); - Fishsanity_CloseGreyscaleColor(play); - } - - void Fishsanity_OpenGreyscaleColor(PlayState* play, Color_RGB8* color, int16_t frameOffset) { - OPEN_DISPS(play->state.gfxCtx); - gDPSetGrayscaleColor( - POLY_OPA_DISP++, color->r, color->g, color->b, - // Make color pulse, offset a bit by the actor params - ABS(255.0f * Math_CosS((play->gameplayFrames + frameOffset) * 1000))); - gSPGrayscale(POLY_OPA_DISP++, true); - CLOSE_DISPS(play->state.gfxCtx); - } - - void Fishsanity_CloseGreyscaleColor(PlayState* play) { - OPEN_DISPS(play->state.gfxCtx); - gSPGrayscale(POLY_OPA_DISP++, false); - CLOSE_DISPS(play->state.gfxCtx); - } +void Fishsanity_CloseGreyscaleColor(PlayState* play) { + OPEN_DISPS(play->state.gfxCtx); + gSPGrayscale(POLY_OPA_DISP++, false); + CLOSE_DISPS(play->state.gfxCtx); +} } void Rando::StaticData::RegisterFishLocations() { static bool registered = false; - if (registered) return; + if (registered) + return; registered = true; // clang-format off // Fishing Pond diff --git a/soh/soh/Enhancements/randomizer/fishsanity.h b/soh/soh/Enhancements/randomizer/fishsanity.h index 13ae86583..16271f28f 100644 --- a/soh/soh/Enhancements/randomizer/fishsanity.h +++ b/soh/soh/Enhancements/randomizer/fishsanity.h @@ -29,7 +29,7 @@ namespace Rando { /** * @brief Class to provide an interface for and direct Fishsanity features -*/ + */ class Fishsanity { public: Fishsanity(); @@ -47,110 +47,114 @@ class Fishsanity { /** * @brief Returns true if the given FishIdentity represents an actual fish * @param fish The fish to check - */ + */ static bool IsFish(FishIdentity* fish); /** * @brief Returns true if the given fish location is active - * + * * @param loc The Location to check * @param optionsSource Optionally declare from which source to pull settings - */ + */ bool GetFishLocationIncluded(Rando::Location* loc, FishsanityOptionsSource optionsSource = FSO_SOURCE_RANDO); /** * @brief Get the active and inactive locations in the fishing pond. - * + * * @param optionsSource Optionally declare from which source to pull settings - * @return A pair of vectors, where the fist is all active pond fish checks, and the second is all inactive pond fish checks. - */ - std::pair, std::vector> GetFishingPondLocations(FishsanityOptionsSource optionsSource = FSO_SOURCE_RANDO); + * @return A pair of vectors, where the fist is all active pond fish checks, and the second is all inactive pond + * fish checks. + */ + std::pair, std::vector> + GetFishingPondLocations(FishsanityOptionsSource optionsSource = FSO_SOURCE_RANDO); /** * @brief Get all active fishsanity locations, and all inactive fishing pond locations. - * - * @param optionsSource Optionally declare from which source to pull settings - * @return A pair of vectors, where the first is all active fishsanity checks, and the second is all inactive fishsanity checks. - */ - std::pair, std::vector> GetFishsanityLocations(FishsanityOptionsSource optionsSource = FSO_SOURCE_RANDO); + * + * @param optionsSource Optionally declare from which source to pull settings + * @return A pair of vectors, where the first is all active fishsanity checks, and the second is all inactive + * fishsanity checks. + */ + std::pair, std::vector> + GetFishsanityLocations(FishsanityOptionsSource optionsSource = FSO_SOURCE_RANDO); /** * @brief Returns the identity for a caught pond fish given its params. * Not for use externally from rando, use Randomizer::IdentifyFish or Randomizer_IdentifyFish for that - * + * * @param fishParams Actor parameters for the fish to identify - */ + */ FishIdentity IdentifyPondFish(u8 fishParams); /** * @brief Get fishsanity fishing pond options from the requested source - */ + */ FishsanityPondOptions GetOptions(FishsanityOptionsSource optionsSource = FSO_SOURCE_RANDO); - + /** * @brief Updates current pond fish according to save data - */ + */ void UpdateCurrentPondFish(); - + /** * @brief Initializes internal state from save - */ + */ void InitializeFromSave(); /** * @brief Returns true if the fishing pond is shuffled - */ + */ bool GetPondFishShuffled(); /** - * @brief Returns true if overworld fish are shuffled - */ + * @brief Returns true if overworld fish are shuffled + */ bool GetOverworldFishShuffled(); /** * @brief Returns true if the fishing pond is currently adult (i.e., age split is enabled and Link is adult) - */ + */ bool IsAdultPond(); /** * @brief Returns true if all available pond fish checks have been collected for the current age - */ + */ bool GetPondCleared(); /** * @brief Returns true if all available Zora's Domain fish checks have been collected - */ + */ bool GetDomainCleared(); /** * @brief Advances current fishing pond check; no effect if every fish is shuffled * @return The new FishIdentity for the current pond, or default identity if every fish is shuffled - */ + */ FishIdentity AdvancePond(); /** * @brief ActorInit hook handler for fishsanity - */ + */ static void OnActorInitHandler(void* refActor); /** * @brief PlayerUpdate hook handler for fishsanity - */ + */ static void OnPlayerUpdateHandler(); /** * @brief ActorUpdate hook handler for fishsanity - */ + */ static void OnActorUpdateHandler(void* refActor); /** * @brief SceneInit hook handler for fishsanity - */ + */ static void OnSceneInitHandler(int16_t sceneNum); /** * @brief VB hook handler for fishsanity - */ + */ static void OnVanillaBehaviorHandler(GIVanillaBehavior id, bool* should, va_list originalArgs); static void OnItemReceiveHandler(GetItemEntry itemEntry); @@ -158,26 +162,26 @@ class Fishsanity { private: /** * @brief Initialize helper statics if they have not been initialized yet - */ + */ void InitializeHelpers(); - + /** * @brief Resolves a pond fish's FishIdentity directly from params & pond age - * + * * @param params Params for Fishing actor * @param adultPond Whether to resolve this fish as an adult check * @return The FishIdentity for the described fish - */ + */ static FishIdentity GetPondFish(s16 params, bool adultPond); /** * @brief Current pond fish when all pond fish are not randomized - */ + */ std::pair mCurrPondFish; - + /** * @brief True if fishsanity helpers have been initialized - */ + */ static bool fishsanityHelpersInit; static s16 fishGroupCounter; @@ -189,20 +193,20 @@ class Fishsanity { /** * @brief Mapping from pond fish check to the age where that check can be collected - */ + */ static std::unordered_map pondFishAgeMap; /** * @brief List of child pond fish checks - */ + */ static std::vector childPondFish; /** * @brief List of adult pond fish checks - */ + */ static std::vector adultPondFish; }; -} +} // namespace Rando extern "C" { #endif diff --git a/soh/soh/Enhancements/randomizer/hint.cpp b/soh/soh/Enhancements/randomizer/hint.cpp index 2648c4623..d81e94f2f 100644 --- a/soh/soh/Enhancements/randomizer/hint.cpp +++ b/soh/soh/Enhancements/randomizer/hint.cpp @@ -6,639 +6,624 @@ #include "static_data.h" namespace Rando { -Hint::Hint(){} - -Hint::Hint(RandomizerHint ownKey_, - HintType hintType_, - std::string distribution_, - std::vector hintKeys_, - std::vector locations_, - std::vector areas_, - std::vector trials_) - : ownKey(ownKey_), hintType(hintType_), distribution(std::move(distribution_)), hintKeys(hintKeys_), locations(locations_), areas(areas_), trials(trials_) { - FillGapsInData(); - SetLocationsAsHinted(); - NamesChosen(); - enabled = true; +Hint::Hint() { } -Hint::Hint(RandomizerHint ownKey_, - HintType hintType_, - std::vector hintKeys_, - std::vector locations_, - std::vector areas_, - std::vector trials_, - bool yourPocket_, - int num_) - : ownKey(ownKey_), hintType(hintType_), hintKeys(hintKeys_), locations(locations_), areas(areas_), trials(trials_), yourPocket(yourPocket_), num(num_) { - FillGapsInData(); - SetLocationsAsHinted(); - NamesChosen(); - enabled = true; +Hint::Hint(RandomizerHint ownKey_, HintType hintType_, std::string distribution_, + std::vector hintKeys_, std::vector locations_, + std::vector areas_, std::vector trials_) + : ownKey(ownKey_), hintType(hintType_), distribution(std::move(distribution_)), hintKeys(hintKeys_), + locations(locations_), areas(areas_), trials(trials_) { + FillGapsInData(); + SetLocationsAsHinted(); + NamesChosen(); + enabled = true; } -Hint::Hint(RandomizerHint ownKey_, std::vector messages_) -: ownKey(ownKey_), messages(messages_){ - hintType = HINT_TYPE_MESSAGE; - enabled = true; +Hint::Hint(RandomizerHint ownKey_, HintType hintType_, std::vector hintKeys_, + std::vector locations_, std::vector areas_, std::vector trials_, + bool yourPocket_, int num_) + : ownKey(ownKey_), hintType(hintType_), hintKeys(hintKeys_), locations(locations_), areas(areas_), trials(trials_), + yourPocket(yourPocket_), num(num_) { + FillGapsInData(); + SetLocationsAsHinted(); + NamesChosen(); + enabled = true; } -Hint::Hint(RandomizerHint ownKey_, nlohmann::json json_){ - ownKey = ownKey_; - if (json_.contains("enabled") && !json_["enabled"].get()){ - return; - } - enabled = true; - - if (json_.contains("type")){ - hintType = (HintType)StaticData::hintTypeNameToEnum[json_["type"].get()]; - } - - if (hintType == HINT_TYPE_MESSAGE){ - if (json_.contains("messages")){ - for (auto message: json_["messages"]){ - messages.push_back(CustomMessage(message.get())); - } - } else if (json_.contains("message")){ - messages.push_back(CustomMessage(json_["message"].get())); - } - } - - if (json_.contains("distribution")){ - distribution = json_["distribution"].get(); - } - - if (json_.contains("locations")){ - for (auto loc: json_["locations"]){ - locations.push_back(StaticData::locationNameToEnum[loc.get()]); - } - } else if (json_.contains("location")){ - locations.push_back(StaticData::locationNameToEnum[json_["location"].get()]); - } - - if (json_.contains("itemNamesChosen")){ - for (auto name: json_["itemNamesChosen"]){ - itemNamesChosen.push_back(name.get()); - } - } else if (json_.contains("itemNameChosen")){ - itemNamesChosen.push_back(json_["itemNameChosen"].get()); - } - - if (json_.contains("areas")){ - for (auto area: json_["areas"]){ - areas.push_back((RandomizerArea)Rando::StaticData::areaNameToEnum[area]); - } - } else if (json_.contains("area")){ - areas.push_back((RandomizerArea)Rando::StaticData::areaNameToEnum[json_["area"]]); - } - - if (json_.contains("areaNamesChosen")){ - for (auto name: json_["areaNamesChosen"]){ - areaNamesChosen.push_back(name.get()); - } - } else if (json_.contains("areaNameChosen")){ - areaNamesChosen.push_back(json_["areaNameChosen"].get()); - } - - if (json_.contains("trials")){ - for (auto trial: json_["trials"]){ - trials.push_back((TrialKey)Rando::StaticData::trialNameToEnum[trial]); - } - } else if (json_.contains("trial")){ - trials.push_back((TrialKey)Rando::StaticData::trialNameToEnum[json_["trial"]]); - } - - if (json_.contains("hintKeys")){ - for (auto hintKey: json_["hintKeys"]){ - hintKeys.push_back((RandomizerHintTextKey)hintKey.get()); - } - } else if (json_.contains("hintKey")){ - hintKeys.push_back((RandomizerHintTextKey)json_["hintKey"].get()); - } - - if (json_.contains("hintTextsChosen")){ - for (auto name: json_["hintTextsChosen"]){ - hintTextsChosen.push_back(name.get()); - } - } else if (json_.contains("hintTextChosen")){ - hintTextsChosen.push_back(json_["hintTextChosen"].get()); - } - - if (json_.contains("num")){ - num = json_["num"].get(); - } - - FillGapsInData(); - SetLocationsAsHinted(); +Hint::Hint(RandomizerHint ownKey_, std::vector messages_) : ownKey(ownKey_), messages(messages_) { + hintType = HINT_TYPE_MESSAGE; + enabled = true; } -void Hint::FillGapsInData(){ - auto ctx = Rando::Context::GetInstance(); - if (locations.size() == 0 && StaticData::staticHintInfoMap.contains(ownKey)){ - locations = StaticData::staticHintInfoMap[ownKey].targetChecks; - } - bool fillAreas = true; - bool fillItems = true; - if (areas.size() > 0){ - fillAreas = false; - } - if (items.size() > 0){ - fillItems = false; - } - for(uint8_t c = 0; c < locations.size(); c++){ - //if area matters for the hint, it should be specified and not left to this - if (fillAreas){ - areas.push_back(ctx->GetItemLocation(locations[c])->GetFirstArea()); +Hint::Hint(RandomizerHint ownKey_, nlohmann::json json_) { + ownKey = ownKey_; + if (json_.contains("enabled") && !json_["enabled"].get()) { + return; } - if (fillItems){ - items.push_back(ctx->GetItemLocation(locations[c])->GetPlacedRandomizerGet()); + enabled = true; + + if (json_.contains("type")) { + hintType = (HintType)StaticData::hintTypeNameToEnum[json_["type"].get()]; + } + + if (hintType == HINT_TYPE_MESSAGE) { + if (json_.contains("messages")) { + for (auto message : json_["messages"]) { + messages.push_back(CustomMessage(message.get())); + } + } else if (json_.contains("message")) { + messages.push_back(CustomMessage(json_["message"].get())); + } + } + + if (json_.contains("distribution")) { + distribution = json_["distribution"].get(); + } + + if (json_.contains("locations")) { + for (auto loc : json_["locations"]) { + locations.push_back(StaticData::locationNameToEnum[loc.get()]); + } + } else if (json_.contains("location")) { + locations.push_back(StaticData::locationNameToEnum[json_["location"].get()]); + } + + if (json_.contains("itemNamesChosen")) { + for (auto name : json_["itemNamesChosen"]) { + itemNamesChosen.push_back(name.get()); + } + } else if (json_.contains("itemNameChosen")) { + itemNamesChosen.push_back(json_["itemNameChosen"].get()); + } + + if (json_.contains("areas")) { + for (auto area : json_["areas"]) { + areas.push_back((RandomizerArea)Rando::StaticData::areaNameToEnum[area]); + } + } else if (json_.contains("area")) { + areas.push_back((RandomizerArea)Rando::StaticData::areaNameToEnum[json_["area"]]); + } + + if (json_.contains("areaNamesChosen")) { + for (auto name : json_["areaNamesChosen"]) { + areaNamesChosen.push_back(name.get()); + } + } else if (json_.contains("areaNameChosen")) { + areaNamesChosen.push_back(json_["areaNameChosen"].get()); + } + + if (json_.contains("trials")) { + for (auto trial : json_["trials"]) { + trials.push_back((TrialKey)Rando::StaticData::trialNameToEnum[trial]); + } + } else if (json_.contains("trial")) { + trials.push_back((TrialKey)Rando::StaticData::trialNameToEnum[json_["trial"]]); + } + + if (json_.contains("hintKeys")) { + for (auto hintKey : json_["hintKeys"]) { + hintKeys.push_back((RandomizerHintTextKey)hintKey.get()); + } + } else if (json_.contains("hintKey")) { + hintKeys.push_back((RandomizerHintTextKey)json_["hintKey"].get()); + } + + if (json_.contains("hintTextsChosen")) { + for (auto name : json_["hintTextsChosen"]) { + hintTextsChosen.push_back(name.get()); + } + } else if (json_.contains("hintTextChosen")) { + hintTextsChosen.push_back(json_["hintTextChosen"].get()); + } + + if (json_.contains("num")) { + num = json_["num"].get(); + } + + FillGapsInData(); + SetLocationsAsHinted(); +} + +void Hint::FillGapsInData() { + auto ctx = Rando::Context::GetInstance(); + if (locations.size() == 0 && StaticData::staticHintInfoMap.contains(ownKey)) { + locations = StaticData::staticHintInfoMap[ownKey].targetChecks; + } + bool fillAreas = true; + bool fillItems = true; + if (areas.size() > 0) { + fillAreas = false; + } + if (items.size() > 0) { + fillItems = false; + } + for (uint8_t c = 0; c < locations.size(); c++) { + // if area matters for the hint, it should be specified and not left to this + if (fillAreas) { + areas.push_back(ctx->GetItemLocation(locations[c])->GetFirstArea()); + } + if (fillItems) { + items.push_back(ctx->GetItemLocation(locations[c])->GetPlacedRandomizerGet()); + } } - } } void Hint::SetLocationsAsHinted() const { - auto ctx = Rando::Context::GetInstance(); - for (uint8_t count = 0; count < locations.size(); count++){ - ctx->GetItemLocation(locations[count])->AddHintedBy(ownKey); - } + auto ctx = Rando::Context::GetInstance(); + for (uint8_t count = 0; count < locations.size(); count++) { + ctx->GetItemLocation(locations[count])->AddHintedBy(ownKey); + } } -uint8_t GetRandomHintTextEntry(const HintText hintText){ - auto ctx = Rando::Context::GetInstance(); - uint8_t size = 0; - if (ctx->GetOption(RSK_HINT_CLARITY).Is(RO_HINT_CLARITY_AMBIGUOUS)){ - size = hintText.GetAmbiguousSize(); - } else if (ctx->GetOption(RSK_HINT_CLARITY).Is(RO_HINT_CLARITY_OBSCURE)){ - size = hintText.GetObscureSize(); - } - if (size > 0){ - return Random(0, size); - } - return 0; +uint8_t GetRandomHintTextEntry(const HintText hintText) { + auto ctx = Rando::Context::GetInstance(); + uint8_t size = 0; + if (ctx->GetOption(RSK_HINT_CLARITY).Is(RO_HINT_CLARITY_AMBIGUOUS)) { + size = hintText.GetAmbiguousSize(); + } else if (ctx->GetOption(RSK_HINT_CLARITY).Is(RO_HINT_CLARITY_OBSCURE)) { + size = hintText.GetObscureSize(); + } + if (size > 0) { + return Random(0, size); + } + return 0; } -void Hint::NamesChosen(){ - auto ctx = Rando::Context::GetInstance(); - std::vector namesTemp = {}; - bool saveNames = false; - uint8_t numMessages = GetNumberOfMessages(); - for (uint8_t c = 0; c < numMessages; c++){ - uint8_t selection = GetRandomHintTextEntry(GetHintText(c)); - if (selection > 0){ - saveNames = true; - } - namesTemp.push_back(selection); - } - if (saveNames) { - hintTextsChosen = namesTemp; - } - - if (hintType == HINT_TYPE_ITEM || hintType == HINT_TYPE_ITEM_AREA){ - for(uint8_t c = 0; c < locations.size(); c++){ - namesTemp = {}; - saveNames = false; - uint8_t selection = GetRandomHintTextEntry(GetItemHintText(c)); - if (selection > 0){ - saveNames = true; - } - namesTemp.push_back(selection); +void Hint::NamesChosen() { + auto ctx = Rando::Context::GetInstance(); + std::vector namesTemp = {}; + bool saveNames = false; + uint8_t numMessages = GetNumberOfMessages(); + for (uint8_t c = 0; c < numMessages; c++) { + uint8_t selection = GetRandomHintTextEntry(GetHintText(c)); + if (selection > 0) { + saveNames = true; + } + namesTemp.push_back(selection); } if (saveNames) { - itemNamesChosen = namesTemp; + hintTextsChosen = namesTemp; } - } - if (hintType == HINT_TYPE_FOOLISH || hintType == HINT_TYPE_ITEM_AREA || hintType == HINT_TYPE_WOTH || - hintType == HINT_TYPE_ALTAR_CHILD || hintType == HINT_TYPE_ALTAR_ADULT){ - namesTemp = {}; - saveNames = false; - for(uint8_t c = 0; c < areas.size(); c++){ - uint8_t selection = GetRandomHintTextEntry(GetAreaHintText(c)); - if (selection > 0){ - saveNames = true; - } - namesTemp.push_back(selection); + if (hintType == HINT_TYPE_ITEM || hintType == HINT_TYPE_ITEM_AREA) { + for (uint8_t c = 0; c < locations.size(); c++) { + namesTemp = {}; + saveNames = false; + uint8_t selection = GetRandomHintTextEntry(GetItemHintText(c)); + if (selection > 0) { + saveNames = true; + } + namesTemp.push_back(selection); + } + if (saveNames) { + itemNamesChosen = namesTemp; + } } - if (saveNames) { - areaNamesChosen = namesTemp; + + if (hintType == HINT_TYPE_FOOLISH || hintType == HINT_TYPE_ITEM_AREA || hintType == HINT_TYPE_WOTH || + hintType == HINT_TYPE_ALTAR_CHILD || hintType == HINT_TYPE_ALTAR_ADULT) { + namesTemp = {}; + saveNames = false; + for (uint8_t c = 0; c < areas.size(); c++) { + uint8_t selection = GetRandomHintTextEntry(GetAreaHintText(c)); + if (selection > 0) { + saveNames = true; + } + namesTemp.push_back(selection); + } + if (saveNames) { + areaNamesChosen = namesTemp; + } } - } } uint8_t Hint::GetNumberOfMessages() const { - size_t numMessages = std::max(messages.size(), hintKeys.size()); - if (StaticData::staticHintInfoMap.contains(ownKey)){ - numMessages = std::max(StaticData::staticHintInfoMap[ownKey].hintKeys.size(), numMessages); - } - if (numMessages == 0){ - numMessages = 1; //RANDOTODO make std::max actually fucking work for 3 arguments - } - return numMessages; + size_t numMessages = std::max(messages.size(), hintKeys.size()); + if (StaticData::staticHintInfoMap.contains(ownKey)) { + numMessages = std::max(StaticData::staticHintInfoMap[ownKey].hintKeys.size(), numMessages); + } + if (numMessages == 0) { + numMessages = 1; // RANDOTODO make std::max actually fucking work for 3 arguments + } + return numMessages; } const std::vector Hint::GetAllMessageStrings(MessageFormat format) const { - std::vector hintMessages = {}; - uint8_t numMessages = GetNumberOfMessages(); - for (int c = 0; c < numMessages; c++){ - hintMessages.push_back(GetHintMessage(format, c).GetForCurrentLanguage(format)); - } - return hintMessages; + std::vector hintMessages = {}; + uint8_t numMessages = GetNumberOfMessages(); + for (int c = 0; c < numMessages; c++) { + hintMessages.push_back(GetHintMessage(format, c).GetForCurrentLanguage(format)); + } + return hintMessages; } const HintText Hint::GetHintText(uint8_t id) const { - auto ctx = Rando::Context::GetInstance(); - if (hintKeys.size() > id){ - return StaticData::hintTextTable[hintKeys[id]]; - } -// If a static hint, load default from staticHintInfoMap - if (StaticData::staticHintInfoMap.contains(ownKey) && StaticData::staticHintInfoMap[ownKey].hintKeys.size() > id){ - return StaticData::hintTextTable[StaticData::staticHintInfoMap[ownKey].hintKeys[id]]; - } + auto ctx = Rando::Context::GetInstance(); + if (hintKeys.size() > id) { + return StaticData::hintTextTable[hintKeys[id]]; + } + // If a static hint, load default from staticHintInfoMap + if (StaticData::staticHintInfoMap.contains(ownKey) && StaticData::staticHintInfoMap[ownKey].hintKeys.size() > id) { + return StaticData::hintTextTable[StaticData::staticHintInfoMap[ownKey].hintKeys[id]]; + } - switch (hintType){ - case HINT_TYPE_HINT_KEY: - return StaticData::hintTextTable[0]; - break; - case HINT_TYPE_TRIAL: - if (ctx->GetTrial(trials[0])->IsRequired()) { - return StaticData::hintTextTable[RHT_TRIAL_ON]; - } else { - return StaticData::hintTextTable[RHT_TRIAL_OFF]; - } - case HINT_TYPE_WOTH: - return StaticData::hintTextTable[RHT_WAY_OF_THE_HERO]; - case HINT_TYPE_FOOLISH: - return StaticData::hintTextTable[RHT_FOOLISH]; - case HINT_TYPE_ITEM: - if (locations.size() > 0) { - return *StaticData::GetLocation(locations[0])->GetHint(); - } else { - return CustomMessage("ERROR: ITEM HINT WITH NO LOCATIONS OR HINT KEY"); - } - case HINT_TYPE_ITEM_AREA: - if (locations.size() > 0) { - if (StaticData::GetLocation(locations[0])->IsDungeon()) { - return StaticData::hintTextTable[RHT_HOARDS]; - } else { - return StaticData::hintTextTable[RHT_CAN_BE_FOUND_AT]; - } - } else { - return CustomMessage("ERROR: ITEM AREA HINT WITH NO LOCATION"); //RANDOTODO get isDungeon from area? - } - default: - return CustomMessage("ERROR: NO HINTKEY PROVIDED AND HINT TYPE HAS NO DEFAULT"); - } + switch (hintType) { + case HINT_TYPE_HINT_KEY: + return StaticData::hintTextTable[0]; + break; + case HINT_TYPE_TRIAL: + if (ctx->GetTrial(trials[0])->IsRequired()) { + return StaticData::hintTextTable[RHT_TRIAL_ON]; + } else { + return StaticData::hintTextTable[RHT_TRIAL_OFF]; + } + case HINT_TYPE_WOTH: + return StaticData::hintTextTable[RHT_WAY_OF_THE_HERO]; + case HINT_TYPE_FOOLISH: + return StaticData::hintTextTable[RHT_FOOLISH]; + case HINT_TYPE_ITEM: + if (locations.size() > 0) { + return *StaticData::GetLocation(locations[0])->GetHint(); + } else { + return CustomMessage("ERROR: ITEM HINT WITH NO LOCATIONS OR HINT KEY"); + } + case HINT_TYPE_ITEM_AREA: + if (locations.size() > 0) { + if (StaticData::GetLocation(locations[0])->IsDungeon()) { + return StaticData::hintTextTable[RHT_HOARDS]; + } else { + return StaticData::hintTextTable[RHT_CAN_BE_FOUND_AT]; + } + } else { + return CustomMessage("ERROR: ITEM AREA HINT WITH NO LOCATION"); // RANDOTODO get isDungeon from area? + } + default: + return CustomMessage("ERROR: NO HINTKEY PROVIDED AND HINT TYPE HAS NO DEFAULT"); + } } const CustomMessage Hint::GetHintMessage(MessageFormat format, uint8_t id) const { - auto ctx = Rando::Context::GetInstance(); - CustomMessage hintText = CustomMessage(""); + auto ctx = Rando::Context::GetInstance(); + CustomMessage hintText = CustomMessage(""); - uint8_t chosenMessage = 0; - if (hintTextsChosen.size() > id){ - chosenMessage = id; - } + uint8_t chosenMessage = 0; + if (hintTextsChosen.size() > id) { + chosenMessage = id; + } - if (hintType == HINT_TYPE_MESSAGE){ - if (id < messages.size()){ - hintText = messages[id]; - } - } else if (hintType == HINT_TYPE_ALTAR_CHILD){ - if (ctx->GetOption(RSK_TOT_ALTAR_HINT)){ - hintText = StaticData::hintTextTable[RHT_CHILD_ALTAR_STONES].GetHintMessage(); - } - if (ctx->GetOption(RSK_DOOR_OF_TIME).Is(RO_DOOROFTIME_OPEN)) { - hintText += CustomMessage(StaticData::hintTextTable[RHT_CHILD_ALTAR_TEXT_END_DOTOPEN].GetHintMessage()); - } else if (ctx->GetOption(RSK_DOOR_OF_TIME).Is(RO_DOOROFTIME_SONGONLY)) { - hintText += CustomMessage(StaticData::hintTextTable[RHT_CHILD_ALTAR_TEXT_END_DOTSONGONLY].GetHintMessage()); + if (hintType == HINT_TYPE_MESSAGE) { + if (id < messages.size()) { + hintText = messages[id]; + } + } else if (hintType == HINT_TYPE_ALTAR_CHILD) { + if (ctx->GetOption(RSK_TOT_ALTAR_HINT)) { + hintText = StaticData::hintTextTable[RHT_CHILD_ALTAR_STONES].GetHintMessage(); + } + if (ctx->GetOption(RSK_DOOR_OF_TIME).Is(RO_DOOROFTIME_OPEN)) { + hintText += CustomMessage(StaticData::hintTextTable[RHT_CHILD_ALTAR_TEXT_END_DOTOPEN].GetHintMessage()); + } else if (ctx->GetOption(RSK_DOOR_OF_TIME).Is(RO_DOOROFTIME_SONGONLY)) { + hintText += CustomMessage(StaticData::hintTextTable[RHT_CHILD_ALTAR_TEXT_END_DOTSONGONLY].GetHintMessage()); + } else { + hintText += CustomMessage(StaticData::hintTextTable[RHT_CHILD_ALTAR_TEXT_END_DOTCLOSED].GetHintMessage()); + } + } else if (hintType == HINT_TYPE_ALTAR_ADULT) { + if (ctx->GetOption(RSK_TOT_ALTAR_HINT)) { + hintText = StaticData::hintTextTable[RHT_ADULT_ALTAR_MEDALLIONS].GetHintMessage(); + } + hintText += GetBridgeReqsText() + GetGanonBossKeyText() + + StaticData::hintTextTable[RHT_ADULT_ALTAR_TEXT_END].GetHintMessage(); } else { - hintText += CustomMessage(StaticData::hintTextTable[RHT_CHILD_ALTAR_TEXT_END_DOTCLOSED].GetHintMessage()); + hintText = GetHintText(id).GetHintMessage(chosenMessage); } - } else if (hintType == HINT_TYPE_ALTAR_ADULT){ - if (ctx->GetOption(RSK_TOT_ALTAR_HINT)){ - hintText = StaticData::hintTextTable[RHT_ADULT_ALTAR_MEDALLIONS].GetHintMessage(); + + std::vector toInsert = {}; + + switch (hintType) { + case HINT_TYPE_ITEM: { + // if we write items + for (uint8_t b = 0; b < locations.size(); b++) { + toInsert.push_back(GetItemName(b)); + } + break; + } + case HINT_TYPE_TRIAL: { + // If we write trials + for (uint8_t b = 0; b < trials.size(); b++) { + toInsert.push_back(ctx->GetTrial(trials[b])->GetName()); + } + break; + } + case HINT_TYPE_ITEM_AREA: { + // If we write items and areas + for (uint8_t b = 0; b < items.size(); b++) { + toInsert.push_back(GetItemName(b)); + toInsert.push_back(GetAreaName(b)); + } + break; + } + case HINT_TYPE_ALTAR_CHILD: + case HINT_TYPE_ALTAR_ADULT: + case HINT_TYPE_AREA: + case HINT_TYPE_WOTH: + case HINT_TYPE_FOOLISH: { + // If we write areas + for (uint8_t b = 0; b < areas.size(); b++) { + toInsert.push_back(GetAreaName(b)); + } + break; + } + default: + break; } - hintText += GetBridgeReqsText() + GetGanonBossKeyText() + StaticData::hintTextTable[RHT_ADULT_ALTAR_TEXT_END].GetHintMessage(); - } else { - hintText = GetHintText(id).GetHintMessage(chosenMessage); - } - std::vector toInsert = {}; + hintText.InsertNames(toInsert); - switch (hintType){ - case HINT_TYPE_ITEM:{ - //if we write items - for(uint8_t b = 0; b < locations.size(); b++){ - toInsert.push_back(GetItemName(b)); - } - break;} - case HINT_TYPE_TRIAL:{ - //If we write trials - for(uint8_t b = 0; b < trials.size(); b++){ - toInsert.push_back(ctx->GetTrial(trials[b])->GetName()); - } - break;} - case HINT_TYPE_ITEM_AREA:{ - //If we write items and areas - for(uint8_t b = 0; b < items.size(); b++){ - toInsert.push_back(GetItemName(b)); - toInsert.push_back(GetAreaName(b)); - } - break;} - case HINT_TYPE_ALTAR_CHILD: - case HINT_TYPE_ALTAR_ADULT: - case HINT_TYPE_AREA: - case HINT_TYPE_WOTH: - case HINT_TYPE_FOOLISH:{ - //If we write areas - for(uint8_t b = 0; b < areas.size(); b++){ - toInsert.push_back(GetAreaName(b)); - } - break;} - default: - break; - } + if (num != 0) { + hintText.InsertNumber(num); + } - hintText.InsertNames(toInsert); + if (format == MF_FORMATTED) { + hintText.Format(); + } else if (format == MF_AUTO_FORMAT) { + hintText.AutoFormat(); + } else if (format == MF_CLEAN) { + hintText.Clean(); + } - if (num != 0){ - hintText.InsertNumber(num); - } - - if (format == MF_FORMATTED){ - hintText.Format(); - } else if (format == MF_AUTO_FORMAT){ - hintText.AutoFormat(); - } else if (format == MF_CLEAN){ - hintText.Clean(); - } - - return hintText; + return hintText; } oJson Hint::toJSON() { - auto ctx = Rando::Context::GetInstance(); - nlohmann::ordered_json log = {}; - if (enabled){ - log["type"] = StaticData::hintTypeNames[hintType].GetForCurrentLanguage(MF_CLEAN); - - std::vector hintMessages = GetAllMessageStrings(MF_CLEAN); - if (hintMessages.size() == 1){ - log["message"] = hintMessages[0]; - } else if (hintMessages.size() > 1){ - log["messages"] = hintMessages; - } + auto ctx = Rando::Context::GetInstance(); + nlohmann::ordered_json log = {}; + if (enabled) { + log["type"] = StaticData::hintTypeNames[hintType].GetForCurrentLanguage(MF_CLEAN); - if (distribution != ""){ - log["distribution"] = distribution; - } - - if (hintType != HINT_TYPE_FOOLISH){ - if (!(StaticData::staticHintInfoMap.contains(ownKey) && - StaticData::staticHintInfoMap[ownKey].targetChecks.size() > 0)){ - if (locations.size() == 1){ - log["location"] = StaticData::GetLocation(locations[0])->GetName();//RANDOTODO change to CustomMessage when VB is done; - } else if (locations.size() > 1){ - //If we have defaults, no need to write more - std::vector locStrings = {}; - for (size_t c = 0; c < locations.size(); c++){ - locStrings.push_back(StaticData::GetLocation(locations[c])->GetName());//RANDOTODO change to CustomMessage when VB is done - } - log["locations"] = locStrings; + std::vector hintMessages = GetAllMessageStrings(MF_CLEAN); + if (hintMessages.size() == 1) { + log["message"] = hintMessages[0]; + } else if (hintMessages.size() > 1) { + log["messages"] = hintMessages; } - } - - if (!(StaticData::staticHintInfoMap.contains(ownKey) && - StaticData::staticHintInfoMap[ownKey].targetItems.size() > 0)){ - if (items.size() == 1){ - log["item"] = StaticData::GetItemTable()[items[0]].GetName().GetEnglish();//RANDOTODO change to CustomMessage; - } else if (items.size() > 1){ - std::vector itemStrings = {}; - for (size_t c = 0; c < items.size(); c++){ - itemStrings.push_back(StaticData::GetItemTable()[items[c]].GetName().GetEnglish());//RANDOTODO change to CustomMessage - } - log["items"] = itemStrings; + + if (distribution != "") { + log["distribution"] = distribution; } - } - if (itemNamesChosen.size() == 1){ - log["itemNameChosen"] = itemNamesChosen[0]; - } else if (itemNamesChosen.size() > 1){ - std::vector nameNums = {}; - for (size_t c = 0; c < itemNamesChosen.size(); c++){ - nameNums.push_back(itemNamesChosen[c]); + if (hintType != HINT_TYPE_FOOLISH) { + if (!(StaticData::staticHintInfoMap.contains(ownKey) && + StaticData::staticHintInfoMap[ownKey].targetChecks.size() > 0)) { + if (locations.size() == 1) { + log["location"] = StaticData::GetLocation(locations[0]) + ->GetName(); // RANDOTODO change to CustomMessage when VB is done; + } else if (locations.size() > 1) { + // If we have defaults, no need to write more + std::vector locStrings = {}; + for (size_t c = 0; c < locations.size(); c++) { + locStrings.push_back(StaticData::GetLocation(locations[c]) + ->GetName()); // RANDOTODO change to CustomMessage when VB is done + } + log["locations"] = locStrings; + } + } + + if (!(StaticData::staticHintInfoMap.contains(ownKey) && + StaticData::staticHintInfoMap[ownKey].targetItems.size() > 0)) { + if (items.size() == 1) { + log["item"] = StaticData::GetItemTable()[items[0]] + .GetName() + .GetEnglish(); // RANDOTODO change to CustomMessage; + } else if (items.size() > 1) { + std::vector itemStrings = {}; + for (size_t c = 0; c < items.size(); c++) { + itemStrings.push_back(StaticData::GetItemTable()[items[c]] + .GetName() + .GetEnglish()); // RANDOTODO change to CustomMessage + } + log["items"] = itemStrings; + } + } + + if (itemNamesChosen.size() == 1) { + log["itemNameChosen"] = itemNamesChosen[0]; + } else if (itemNamesChosen.size() > 1) { + std::vector nameNums = {}; + for (size_t c = 0; c < itemNamesChosen.size(); c++) { + nameNums.push_back(itemNamesChosen[c]); + } + log["itemNamesChosen"] = nameNums; + } + } + if (areas.size() == 1) { + log["area"] = + StaticData::hintTextTable[StaticData::areaNames[areas[0]]].GetClear().GetForCurrentLanguage(MF_CLEAN); + } else if (areas.size() > 0 && !(StaticData::staticHintInfoMap.contains(ownKey) && + StaticData::staticHintInfoMap[ownKey].targetChecks.size() > 0)) { + // If we got locations from defaults, areas are derived from them and don't need logging + std::vector areaStrings = {}; + for (size_t c = 0; c < areas.size(); c++) { + areaStrings.push_back( + StaticData::hintTextTable[StaticData::areaNames[areas[c]]].GetClear().GetForCurrentLanguage( + MF_CLEAN)); + } + log["areas"] = areaStrings; } - log["itemNamesChosen"] = nameNums; - } - } - if (areas.size() == 1){ - log["area"] = StaticData::hintTextTable[StaticData::areaNames[areas[0]]].GetClear().GetForCurrentLanguage(MF_CLEAN); - } else if (areas.size() > 0 && - !(StaticData::staticHintInfoMap.contains(ownKey) && StaticData::staticHintInfoMap[ownKey].targetChecks.size() > 0)){ - // If we got locations from defaults, areas are derived from them and don't need logging - std::vector areaStrings = {}; - for (size_t c = 0; c < areas.size(); c++){ - areaStrings.push_back(StaticData::hintTextTable[StaticData::areaNames[areas[c]]].GetClear().GetForCurrentLanguage(MF_CLEAN)); - } - log["areas"] = areaStrings; - } - if (areaNamesChosen.size() == 1){ - log["areaNameChosen"] = areaNamesChosen[0]; - } else if (areaNamesChosen.size() > 1){ - std::vector nameNums = {}; - for (size_t c = 0; c < areaNamesChosen.size(); c++){ - nameNums.push_back(areaNamesChosen[c]); - } - log["areaNamesChosen"] = nameNums; - } + if (areaNamesChosen.size() == 1) { + log["areaNameChosen"] = areaNamesChosen[0]; + } else if (areaNamesChosen.size() > 1) { + std::vector nameNums = {}; + for (size_t c = 0; c < areaNamesChosen.size(); c++) { + nameNums.push_back(areaNamesChosen[c]); + } + log["areaNamesChosen"] = nameNums; + } - if (trials.size() == 1){ - log["trial"] = ctx->GetTrial(trials[0])->GetName().GetForCurrentLanguage(MF_CLEAN); - } else if (trials.size() > 0){ - std::vector trialStrings = {}; - for (size_t c = 0; c < trials.size(); c++){ - trialStrings.push_back(ctx->GetTrial(trials[c])->GetName().GetForCurrentLanguage(MF_CLEAN)); - } - log["trials"] = trialStrings; - } + if (trials.size() == 1) { + log["trial"] = ctx->GetTrial(trials[0])->GetName().GetForCurrentLanguage(MF_CLEAN); + } else if (trials.size() > 0) { + std::vector trialStrings = {}; + for (size_t c = 0; c < trials.size(); c++) { + trialStrings.push_back(ctx->GetTrial(trials[c])->GetName().GetForCurrentLanguage(MF_CLEAN)); + } + log["trials"] = trialStrings; + } - if (hintKeys.size() == 1){ - log["hintKey"] = hintKeys[0]; - } else if (hintKeys.size() > 1){ - std::vector hintKeyNums = {}; - for (size_t c = 0; c < hintKeys.size(); c++){ - hintKeyNums.push_back(hintKeys[c]); - } - log["hintKeys"] = hintKeyNums; - } + if (hintKeys.size() == 1) { + log["hintKey"] = hintKeys[0]; + } else if (hintKeys.size() > 1) { + std::vector hintKeyNums = {}; + for (size_t c = 0; c < hintKeys.size(); c++) { + hintKeyNums.push_back(hintKeys[c]); + } + log["hintKeys"] = hintKeyNums; + } - if (hintTextsChosen.size() == 1){ - log["hintTextChosen"] = hintTextsChosen[0]; - } else if (hintTextsChosen.size() > 1){ - std::vector nameNums = {}; - for (size_t c = 0; c < hintTextsChosen.size(); c++){ - nameNums.push_back(hintTextsChosen[c]); - } - log["hintTextsChosen"] = nameNums; - } + if (hintTextsChosen.size() == 1) { + log["hintTextChosen"] = hintTextsChosen[0]; + } else if (hintTextsChosen.size() > 1) { + std::vector nameNums = {}; + for (size_t c = 0; c < hintTextsChosen.size(); c++) { + nameNums.push_back(hintTextsChosen[c]); + } + log["hintTextsChosen"] = nameNums; + } - if (num != 0){ - log["num"] = num; + if (num != 0) { + log["num"] = num; + } } - - } - return log; + return log; } -void Hint::logHint(oJson& jsonData){ - auto ctx = Rando::Context::GetInstance(); - std::string logMap = "Static Hints"; - bool staticHint = true; - if (ownKey < RH_GANONDORF_HINT){ - logMap = "Gossip Stone Hints"; - staticHint = false; - } - if (enabled && - (!(staticHint && (hintType == HINT_TYPE_ITEM) && ctx->GetOption(RSK_HINT_CLARITY).Is(RO_HINT_CLARITY_CLEAR)))){ - //skip if not enabled or if a static hint with no possible variance - jsonData[logMap][Rando::StaticData::hintNames[ownKey].GetForCurrentLanguage(MF_CLEAN)] = toJSON(); - } +void Hint::logHint(oJson& jsonData) { + auto ctx = Rando::Context::GetInstance(); + std::string logMap = "Static Hints"; + bool staticHint = true; + if (ownKey < RH_GANONDORF_HINT) { + logMap = "Gossip Stone Hints"; + staticHint = false; + } + if (enabled && + (!(staticHint && (hintType == HINT_TYPE_ITEM) && ctx->GetOption(RSK_HINT_CLARITY).Is(RO_HINT_CLARITY_CLEAR)))) { + // skip if not enabled or if a static hint with no possible variance + jsonData[logMap][Rando::StaticData::hintNames[ownKey].GetForCurrentLanguage(MF_CLEAN)] = toJSON(); + } } const HintText Hint::GetItemHintText(uint8_t slot, bool mysterious) const { - //RANDOTODO make unreliant on locations, or make Hint accept ItemLocation - auto ctx = Rando::Context::GetInstance(); - RandomizerCheck hintedCheck = locations[slot]; - RandomizerGet targetRG = ctx->GetItemLocation(hintedCheck)->GetPlacedRandomizerGet(); - if (mysterious){ - return StaticData::hintTextTable[RHT_MYSTERIOUS_ITEM]; - } else if (!ctx->GetOption(RSK_HINT_CLARITY).Is(RO_HINT_CLARITY_AMBIGUOUS) && targetRG == RG_ICE_TRAP) { //RANDOTODO store in item hint instead of item - return HintText(CustomMessage({ctx->overrides[hintedCheck].GetTrickName()})); - } else { - return ctx->GetItemLocation(hintedCheck)->GetPlacedItem().GetHint(); - } + // RANDOTODO make unreliant on locations, or make Hint accept ItemLocation + auto ctx = Rando::Context::GetInstance(); + RandomizerCheck hintedCheck = locations[slot]; + RandomizerGet targetRG = ctx->GetItemLocation(hintedCheck)->GetPlacedRandomizerGet(); + if (mysterious) { + return StaticData::hintTextTable[RHT_MYSTERIOUS_ITEM]; + } else if (!ctx->GetOption(RSK_HINT_CLARITY).Is(RO_HINT_CLARITY_AMBIGUOUS) && + targetRG == RG_ICE_TRAP) { // RANDOTODO store in item hint instead of item + return HintText(CustomMessage({ ctx->overrides[hintedCheck].GetTrickName() })); + } else { + return ctx->GetItemLocation(hintedCheck)->GetPlacedItem().GetHint(); + } } -const HintText Hint::GetAreaHintText(uint8_t slot) const { - CustomMessage areaText; - if (yourPocket && areas[slot] == RA_LINKS_POCKET){ - return StaticData::hintTextTable[RHT_YOUR_POCKET]; - } else { - return StaticData::hintTextTable[Rando::StaticData::areaNames[areas[slot]]]; - } +const HintText Hint::GetAreaHintText(uint8_t slot) const { + CustomMessage areaText; + if (yourPocket && areas[slot] == RA_LINKS_POCKET) { + return StaticData::hintTextTable[RHT_YOUR_POCKET]; + } else { + return StaticData::hintTextTable[Rando::StaticData::areaNames[areas[slot]]]; + } } - -const CustomMessage Hint::GetItemName(uint8_t slot, bool mysterious) const { - uint8_t nameNum = 0; - if (itemNamesChosen.size() > slot){ - nameNum = itemNamesChosen[slot]; - } - return GetItemHintText(slot, mysterious).GetHintMessage(nameNum); +const CustomMessage Hint::GetItemName(uint8_t slot, bool mysterious) const { + uint8_t nameNum = 0; + if (itemNamesChosen.size() > slot) { + nameNum = itemNamesChosen[slot]; + } + return GetItemHintText(slot, mysterious).GetHintMessage(nameNum); } -const CustomMessage Hint::GetAreaName(uint8_t slot) const { - uint8_t nameNum = 0; - if (areaNamesChosen.size() > slot){ - nameNum = areaNamesChosen[slot]; - } - return GetAreaHintText(slot).GetHintMessage(nameNum); +const CustomMessage Hint::GetAreaName(uint8_t slot) const { + uint8_t nameNum = 0; + if (areaNamesChosen.size() > slot) { + nameNum = areaNamesChosen[slot]; + } + return GetAreaHintText(slot).GetHintMessage(nameNum); } - CustomMessage Hint::GetBridgeReqsText() { - auto ctx = Rando::Context::GetInstance(); - CustomMessage bridgeMessage; + auto ctx = Rando::Context::GetInstance(); + CustomMessage bridgeMessage; - if (ctx->GetOption(RSK_RAINBOW_BRIDGE).Is(RO_BRIDGE_ALWAYS_OPEN)) { - return StaticData::hintTextTable[RHT_BRIDGE_OPEN_HINT].GetHintMessage(); - } - else if (ctx->GetOption(RSK_RAINBOW_BRIDGE).Is(RO_BRIDGE_VANILLA)) { - return StaticData::hintTextTable[RHT_BRIDGE_VANILLA_HINT].GetHintMessage(); - } - else if (ctx->GetOption(RSK_RAINBOW_BRIDGE).Is(RO_BRIDGE_STONES)) { - bridgeMessage = StaticData::hintTextTable[RHT_BRIDGE_STONES_HINT].GetHintMessage(); - bridgeMessage.InsertNumber(ctx->GetOption(RSK_RAINBOW_BRIDGE_STONE_COUNT).Get()); - } - else if (ctx->GetOption(RSK_RAINBOW_BRIDGE).Is(RO_BRIDGE_MEDALLIONS)) { - bridgeMessage = StaticData::hintTextTable[RHT_BRIDGE_MEDALLIONS_HINT].GetHintMessage(); - bridgeMessage.InsertNumber(ctx->GetOption(RSK_RAINBOW_BRIDGE_MEDALLION_COUNT).Get()); - } - else if (ctx->GetOption(RSK_RAINBOW_BRIDGE).Is(RO_BRIDGE_DUNGEON_REWARDS)) { - bridgeMessage = StaticData::hintTextTable[RHT_BRIDGE_REWARDS_HINT].GetHintMessage(); - bridgeMessage.InsertNumber(ctx->GetOption(RSK_RAINBOW_BRIDGE_REWARD_COUNT).Get()); - } - else if (ctx->GetOption(RSK_RAINBOW_BRIDGE).Is(RO_BRIDGE_DUNGEONS)) { - bridgeMessage = StaticData::hintTextTable[RHT_BRIDGE_DUNGEONS_HINT].GetHintMessage(); - bridgeMessage.InsertNumber(ctx->GetOption(RSK_RAINBOW_BRIDGE_DUNGEON_COUNT).Get()); - } - else if (ctx->GetOption(RSK_RAINBOW_BRIDGE).Is(RO_BRIDGE_TOKENS)) { - bridgeMessage = StaticData::hintTextTable[RHT_BRIDGE_TOKENS_HINT].GetHintMessage(); - bridgeMessage.InsertNumber(ctx->GetOption(RSK_RAINBOW_BRIDGE_TOKEN_COUNT).Get()); - } - else if (ctx->GetOption(RSK_RAINBOW_BRIDGE).Is(RO_BRIDGE_GREG)) { - return StaticData::hintTextTable[RHT_BRIDGE_GREG_HINT].GetHintMessage(); - } - return bridgeMessage; + if (ctx->GetOption(RSK_RAINBOW_BRIDGE).Is(RO_BRIDGE_ALWAYS_OPEN)) { + return StaticData::hintTextTable[RHT_BRIDGE_OPEN_HINT].GetHintMessage(); + } else if (ctx->GetOption(RSK_RAINBOW_BRIDGE).Is(RO_BRIDGE_VANILLA)) { + return StaticData::hintTextTable[RHT_BRIDGE_VANILLA_HINT].GetHintMessage(); + } else if (ctx->GetOption(RSK_RAINBOW_BRIDGE).Is(RO_BRIDGE_STONES)) { + bridgeMessage = StaticData::hintTextTable[RHT_BRIDGE_STONES_HINT].GetHintMessage(); + bridgeMessage.InsertNumber(ctx->GetOption(RSK_RAINBOW_BRIDGE_STONE_COUNT).Get()); + } else if (ctx->GetOption(RSK_RAINBOW_BRIDGE).Is(RO_BRIDGE_MEDALLIONS)) { + bridgeMessage = StaticData::hintTextTable[RHT_BRIDGE_MEDALLIONS_HINT].GetHintMessage(); + bridgeMessage.InsertNumber(ctx->GetOption(RSK_RAINBOW_BRIDGE_MEDALLION_COUNT).Get()); + } else if (ctx->GetOption(RSK_RAINBOW_BRIDGE).Is(RO_BRIDGE_DUNGEON_REWARDS)) { + bridgeMessage = StaticData::hintTextTable[RHT_BRIDGE_REWARDS_HINT].GetHintMessage(); + bridgeMessage.InsertNumber(ctx->GetOption(RSK_RAINBOW_BRIDGE_REWARD_COUNT).Get()); + } else if (ctx->GetOption(RSK_RAINBOW_BRIDGE).Is(RO_BRIDGE_DUNGEONS)) { + bridgeMessage = StaticData::hintTextTable[RHT_BRIDGE_DUNGEONS_HINT].GetHintMessage(); + bridgeMessage.InsertNumber(ctx->GetOption(RSK_RAINBOW_BRIDGE_DUNGEON_COUNT).Get()); + } else if (ctx->GetOption(RSK_RAINBOW_BRIDGE).Is(RO_BRIDGE_TOKENS)) { + bridgeMessage = StaticData::hintTextTable[RHT_BRIDGE_TOKENS_HINT].GetHintMessage(); + bridgeMessage.InsertNumber(ctx->GetOption(RSK_RAINBOW_BRIDGE_TOKEN_COUNT).Get()); + } else if (ctx->GetOption(RSK_RAINBOW_BRIDGE).Is(RO_BRIDGE_GREG)) { + return StaticData::hintTextTable[RHT_BRIDGE_GREG_HINT].GetHintMessage(); + } + return bridgeMessage; } CustomMessage Hint::GetGanonBossKeyText() { - auto ctx = Rando::Context::GetInstance(); - CustomMessage ganonBossKeyMessage; + auto ctx = Rando::Context::GetInstance(); + CustomMessage ganonBossKeyMessage; - if (ctx->GetOption(RSK_TRIFORCE_HUNT)) { - return StaticData::hintTextTable[RHT_GANON_BK_TRIFORCE_HINT].GetHintMessage(); - } + if (ctx->GetOption(RSK_TRIFORCE_HUNT)) { + return StaticData::hintTextTable[RHT_GANON_BK_TRIFORCE_HINT].GetHintMessage(); + } - if (ctx->GetOption(RSK_GANONS_BOSS_KEY).Is(RO_GANON_BOSS_KEY_STARTWITH)) { - return StaticData::hintTextTable[RHT_GANON_BK_START_WITH_HINT].GetHintMessage(); - } - else if (ctx->GetOption(RSK_GANONS_BOSS_KEY).Is(RO_GANON_BOSS_KEY_VANILLA)) { - return StaticData::hintTextTable[RHT_GANON_BK_VANILLA_HINT].GetHintMessage(); - } - else if (ctx->GetOption(RSK_GANONS_BOSS_KEY).Is(RO_GANON_BOSS_KEY_OWN_DUNGEON)) { - return StaticData::hintTextTable[RHT_GANON_BK_OWN_DUNGEON_HINT].GetHintMessage(); - } - else if (ctx->GetOption(RSK_GANONS_BOSS_KEY).Is(RO_GANON_BOSS_KEY_ANY_DUNGEON)) { - return StaticData::hintTextTable[RHT_GANON_BK_ANY_DUNGEON_HINT].GetHintMessage(); - } - else if (ctx->GetOption(RSK_GANONS_BOSS_KEY).Is(RO_GANON_BOSS_KEY_OVERWORLD)) { - return StaticData::hintTextTable[RHT_GANON_BK_OVERWORLD_HINT].GetHintMessage(); - } - else if (ctx->GetOption(RSK_GANONS_BOSS_KEY).Is(RO_GANON_BOSS_KEY_ANYWHERE)) { - return StaticData::hintTextTable[RHT_GANON_BK_ANYWHERE_HINT].GetHintMessage(); - } - else if (ctx->GetOption(RSK_GANONS_BOSS_KEY).Is(RO_GANON_BOSS_KEY_KAK_TOKENS)) { - return StaticData::hintTextTable[RHT_GANON_BK_SKULLTULA_HINT].GetHintMessage(); - } - else if (ctx->GetOption(RSK_GANONS_BOSS_KEY).Is(RO_GANON_BOSS_KEY_LACS_VANILLA)) { - return StaticData::hintTextTable[RHT_LACS_VANILLA_HINT].GetHintMessage(); - } - else if (ctx->GetOption(RSK_GANONS_BOSS_KEY).Is(RO_GANON_BOSS_KEY_LACS_STONES)) { - ganonBossKeyMessage = StaticData::hintTextTable[RHT_LACS_STONES_HINT].GetHintMessage(); - ganonBossKeyMessage.InsertNumber(ctx->GetOption(RSK_LACS_STONE_COUNT).Get()); - } - else if (ctx->GetOption(RSK_GANONS_BOSS_KEY).Is(RO_GANON_BOSS_KEY_LACS_MEDALLIONS)) { - ganonBossKeyMessage = StaticData::hintTextTable[RHT_LACS_MEDALLIONS_HINT].GetHintMessage(); - ganonBossKeyMessage.InsertNumber(ctx->GetOption(RSK_LACS_MEDALLION_COUNT).Get()); - } - else if (ctx->GetOption(RSK_GANONS_BOSS_KEY).Is(RO_GANON_BOSS_KEY_LACS_REWARDS)) { - ganonBossKeyMessage = StaticData::hintTextTable[RHT_LACS_REWARDS_HINT].GetHintMessage(); - ganonBossKeyMessage.InsertNumber(ctx->GetOption(RSK_LACS_REWARD_COUNT).Get()); - } - else if (ctx->GetOption(RSK_GANONS_BOSS_KEY).Is(RO_GANON_BOSS_KEY_LACS_DUNGEONS)) { - ganonBossKeyMessage = StaticData::hintTextTable[RHT_LACS_DUNGEONS_HINT].GetHintMessage(); - ganonBossKeyMessage.InsertNumber(ctx->GetOption(RSK_LACS_DUNGEON_COUNT).Get()); - } - else if (ctx->GetOption(RSK_GANONS_BOSS_KEY).Is(RO_GANON_BOSS_KEY_LACS_TOKENS)) { - ganonBossKeyMessage = StaticData::hintTextTable[RHT_LACS_TOKENS_HINT].GetHintMessage(); - ganonBossKeyMessage.InsertNumber(ctx->GetOption(RSK_LACS_TOKEN_COUNT).Get()); - } - return ganonBossKeyMessage; + if (ctx->GetOption(RSK_GANONS_BOSS_KEY).Is(RO_GANON_BOSS_KEY_STARTWITH)) { + return StaticData::hintTextTable[RHT_GANON_BK_START_WITH_HINT].GetHintMessage(); + } else if (ctx->GetOption(RSK_GANONS_BOSS_KEY).Is(RO_GANON_BOSS_KEY_VANILLA)) { + return StaticData::hintTextTable[RHT_GANON_BK_VANILLA_HINT].GetHintMessage(); + } else if (ctx->GetOption(RSK_GANONS_BOSS_KEY).Is(RO_GANON_BOSS_KEY_OWN_DUNGEON)) { + return StaticData::hintTextTable[RHT_GANON_BK_OWN_DUNGEON_HINT].GetHintMessage(); + } else if (ctx->GetOption(RSK_GANONS_BOSS_KEY).Is(RO_GANON_BOSS_KEY_ANY_DUNGEON)) { + return StaticData::hintTextTable[RHT_GANON_BK_ANY_DUNGEON_HINT].GetHintMessage(); + } else if (ctx->GetOption(RSK_GANONS_BOSS_KEY).Is(RO_GANON_BOSS_KEY_OVERWORLD)) { + return StaticData::hintTextTable[RHT_GANON_BK_OVERWORLD_HINT].GetHintMessage(); + } else if (ctx->GetOption(RSK_GANONS_BOSS_KEY).Is(RO_GANON_BOSS_KEY_ANYWHERE)) { + return StaticData::hintTextTable[RHT_GANON_BK_ANYWHERE_HINT].GetHintMessage(); + } else if (ctx->GetOption(RSK_GANONS_BOSS_KEY).Is(RO_GANON_BOSS_KEY_KAK_TOKENS)) { + return StaticData::hintTextTable[RHT_GANON_BK_SKULLTULA_HINT].GetHintMessage(); + } else if (ctx->GetOption(RSK_GANONS_BOSS_KEY).Is(RO_GANON_BOSS_KEY_LACS_VANILLA)) { + return StaticData::hintTextTable[RHT_LACS_VANILLA_HINT].GetHintMessage(); + } else if (ctx->GetOption(RSK_GANONS_BOSS_KEY).Is(RO_GANON_BOSS_KEY_LACS_STONES)) { + ganonBossKeyMessage = StaticData::hintTextTable[RHT_LACS_STONES_HINT].GetHintMessage(); + ganonBossKeyMessage.InsertNumber(ctx->GetOption(RSK_LACS_STONE_COUNT).Get()); + } else if (ctx->GetOption(RSK_GANONS_BOSS_KEY).Is(RO_GANON_BOSS_KEY_LACS_MEDALLIONS)) { + ganonBossKeyMessage = StaticData::hintTextTable[RHT_LACS_MEDALLIONS_HINT].GetHintMessage(); + ganonBossKeyMessage.InsertNumber(ctx->GetOption(RSK_LACS_MEDALLION_COUNT).Get()); + } else if (ctx->GetOption(RSK_GANONS_BOSS_KEY).Is(RO_GANON_BOSS_KEY_LACS_REWARDS)) { + ganonBossKeyMessage = StaticData::hintTextTable[RHT_LACS_REWARDS_HINT].GetHintMessage(); + ganonBossKeyMessage.InsertNumber(ctx->GetOption(RSK_LACS_REWARD_COUNT).Get()); + } else if (ctx->GetOption(RSK_GANONS_BOSS_KEY).Is(RO_GANON_BOSS_KEY_LACS_DUNGEONS)) { + ganonBossKeyMessage = StaticData::hintTextTable[RHT_LACS_DUNGEONS_HINT].GetHintMessage(); + ganonBossKeyMessage.InsertNumber(ctx->GetOption(RSK_LACS_DUNGEON_COUNT).Get()); + } else if (ctx->GetOption(RSK_GANONS_BOSS_KEY).Is(RO_GANON_BOSS_KEY_LACS_TOKENS)) { + ganonBossKeyMessage = StaticData::hintTextTable[RHT_LACS_TOKENS_HINT].GetHintMessage(); + ganonBossKeyMessage.InsertNumber(ctx->GetOption(RSK_LACS_TOKEN_COUNT).Get()); + } + return ganonBossKeyMessage; } - void Hint::AddHintedLocation(RandomizerCheck location) { locations.push_back(location); } @@ -671,53 +656,53 @@ const std::string& Hint::GetDistribution() const { return distribution; } -bool Hint::IsEnabled() const{ - return enabled; +bool Hint::IsEnabled() const { + return enabled; } -std::vector Hint::GetHintTextKeys() const{ - return hintKeys; +std::vector Hint::GetHintTextKeys() const { + return hintKeys; } -std::vector Hint::GetHintedItems() const{ - return items; +std::vector Hint::GetHintedItems() const { + return items; } -std::vector Hint::GetItemNamesChosen() const{ - return itemNamesChosen; +std::vector Hint::GetItemNamesChosen() const { + return itemNamesChosen; } -std::vector Hint::GetHintTextsChosen() const{ - return hintTextsChosen; +std::vector Hint::GetHintTextsChosen() const { + return hintTextsChosen; } -std::vector Hint::GetAreaTextsChosen() const{ - return areaNamesChosen; +std::vector Hint::GetAreaTextsChosen() const { + return areaNamesChosen; } -std::vector Hint::GetHintedTrials() const{ - return trials; +std::vector Hint::GetHintedTrials() const { + return trials; } -int Hint::GetNum(){ - return num; +int Hint::GetNum() { + return num; } void Hint::ResetVariables() { - ownKey = RH_NONE; - num = 0; - yourPocket = false; - messages = {}; - hintKeys = {}; - locations = {}; - items = {}; - trials = {}; - hintType = HINT_TYPE_HINT_KEY; - areas = {}; - distribution = ""; - enabled = false; - itemNamesChosen = {}; - hintTextsChosen = {}; - areaNamesChosen = {}; + ownKey = RH_NONE; + num = 0; + yourPocket = false; + messages = {}; + hintKeys = {}; + locations = {}; + items = {}; + trials = {}; + hintType = HINT_TYPE_HINT_KEY; + areas = {}; + distribution = ""; + enabled = false; + itemNamesChosen = {}; + hintTextsChosen = {}; + areaNamesChosen = {}; } -} \ No newline at end of file +} // namespace Rando \ No newline at end of file diff --git a/soh/soh/Enhancements/randomizer/hint.h b/soh/soh/Enhancements/randomizer/hint.h index 03e1af850..e0e595395 100644 --- a/soh/soh/Enhancements/randomizer/hint.h +++ b/soh/soh/Enhancements/randomizer/hint.h @@ -10,73 +10,64 @@ using oJson = nlohmann::ordered_json; namespace Rando { class Hint { - public: - Hint(); - Hint(RandomizerHint ownKey_, - HintType hintType_, - std::string distributionName_, - std::vector hintKeys_, - std::vector locations_, - std::vector areas_ = {}, - std::vector trials_ = {}); - Hint(RandomizerHint ownKey_, - HintType hintType_, - std::vector hintKeys_, - std::vector locations_ = {}, - std::vector areas_ = {}, - std::vector trials_ = {}, - bool yourPocket_ = false, - int num_ = 0); - Hint(RandomizerHint ownKey_, std::vector messages_); - Hint(RandomizerHint ownKey_, nlohmann::json json_); - void FillGapsInData(); - void SetLocationsAsHinted() const; - void NamesChosen(); - uint8_t GetNumberOfMessages() const; - const std::vector GetAllMessageStrings(MessageFormat format = MF_AUTO_FORMAT) const ; - const CustomMessage GetHintMessage(MessageFormat format = MF_AUTO_FORMAT, uint8_t id = 0) const ; - const HintText GetHintText(uint8_t id = 0) const; - oJson toJSON(); - void logHint(oJson& jsonData); - const HintText GetItemHintText(uint8_t slot, bool mysterious = false) const; - const HintText GetAreaHintText(uint8_t slot) const; - const CustomMessage GetItemName(uint8_t slot, bool mysterious = false) const; - const CustomMessage GetAreaName(uint8_t slot) const; - static CustomMessage GetBridgeReqsText(); - static CustomMessage GetGanonBossKeyText(); - void AddHintedLocation (RandomizerCheck location); - std::vector GetHintedLocations() const; - void SetHintType (HintType type); - HintType GetHintType() const; - void AddHintedArea (RandomizerArea area); - std::vector GetHintedAreas() const; - void SetDistribution (std::string distribution); - const std::string& GetDistribution() const; - bool IsEnabled() const; - std::vector GetHintTextKeys() const; - std::vector GetHintedItems() const; - std::vector GetItemNamesChosen() const; - std::vector GetHintTextsChosen() const; - std::vector GetAreaTextsChosen() const; - std::vector GetHintedTrials() const; - int GetNum(); - void ResetVariables(); + public: + Hint(); + Hint(RandomizerHint ownKey_, HintType hintType_, std::string distributionName_, + std::vector hintKeys_, std::vector locations_, + std::vector areas_ = {}, std::vector trials_ = {}); + Hint(RandomizerHint ownKey_, HintType hintType_, std::vector hintKeys_, + std::vector locations_ = {}, std::vector areas_ = {}, + std::vector trials_ = {}, bool yourPocket_ = false, int num_ = 0); + Hint(RandomizerHint ownKey_, std::vector messages_); + Hint(RandomizerHint ownKey_, nlohmann::json json_); + void FillGapsInData(); + void SetLocationsAsHinted() const; + void NamesChosen(); + uint8_t GetNumberOfMessages() const; + const std::vector GetAllMessageStrings(MessageFormat format = MF_AUTO_FORMAT) const; + const CustomMessage GetHintMessage(MessageFormat format = MF_AUTO_FORMAT, uint8_t id = 0) const; + const HintText GetHintText(uint8_t id = 0) const; + oJson toJSON(); + void logHint(oJson& jsonData); + const HintText GetItemHintText(uint8_t slot, bool mysterious = false) const; + const HintText GetAreaHintText(uint8_t slot) const; + const CustomMessage GetItemName(uint8_t slot, bool mysterious = false) const; + const CustomMessage GetAreaName(uint8_t slot) const; + static CustomMessage GetBridgeReqsText(); + static CustomMessage GetGanonBossKeyText(); + void AddHintedLocation(RandomizerCheck location); + std::vector GetHintedLocations() const; + void SetHintType(HintType type); + HintType GetHintType() const; + void AddHintedArea(RandomizerArea area); + std::vector GetHintedAreas() const; + void SetDistribution(std::string distribution); + const std::string& GetDistribution() const; + bool IsEnabled() const; + std::vector GetHintTextKeys() const; + std::vector GetHintedItems() const; + std::vector GetItemNamesChosen() const; + std::vector GetHintTextsChosen() const; + std::vector GetAreaTextsChosen() const; + std::vector GetHintedTrials() const; + int GetNum(); + void ResetVariables(); - private: - RandomizerHint ownKey = RH_NONE; - HintType hintType = HINT_TYPE_HINT_KEY; - std::string distribution = ""; - std::vector hintKeys = {}; - std::vector locations = {}; - std::vector areas = {}; - std::vector trials = {}; - bool yourPocket = false; - int num = 0; - std::vector messages = {}; - std::vector items = {}; - bool enabled = false; - std::vector itemNamesChosen = {}; - std::vector hintTextsChosen = {}; - std::vector areaNamesChosen = {}; + private: + RandomizerHint ownKey = RH_NONE; + HintType hintType = HINT_TYPE_HINT_KEY; + std::string distribution = ""; + std::vector hintKeys = {}; + std::vector locations = {}; + std::vector areas = {}; + std::vector trials = {}; + bool yourPocket = false; + int num = 0; + std::vector messages = {}; + std::vector items = {}; + bool enabled = false; + std::vector itemNamesChosen = {}; + std::vector hintTextsChosen = {}; + std::vector areaNamesChosen = {}; }; -} \ No newline at end of file +} // namespace Rando \ No newline at end of file diff --git a/soh/soh/Enhancements/randomizer/hook_handlers.cpp b/soh/soh/Enhancements/randomizer/hook_handlers.cpp index a3088aabc..5a803f39b 100644 --- a/soh/soh/Enhancements/randomizer/hook_handlers.cpp +++ b/soh/soh/Enhancements/randomizer/hook_handlers.cpp @@ -61,9 +61,10 @@ extern "C" { extern SaveContext gSaveContext; extern PlayState* gPlayState; extern void func_8084DFAC(PlayState* play, Player* player); -extern void Player_SetupActionPreserveAnimMovement(PlayState* play, Player* player, PlayerActionFunc actionFunc, s32 flags); +extern void Player_SetupActionPreserveAnimMovement(PlayState* play, Player* player, PlayerActionFunc actionFunc, + s32 flags); extern s32 Player_SetupWaitForPutAway(PlayState* play, Player* player, AfterPutAwayFunc func); -extern void Play_InitEnvironment(PlayState * play, s16 skyboxId); +extern void Play_InitEnvironment(PlayState* play, s16 skyboxId); extern void EnMk_Wait(EnMk* enMk, PlayState* play); extern void func_80ABA778(EnNiwLady* enNiwLady, PlayState* play); extern void EnGe1_Wait_Archery(EnGe1* enGe1, PlayState* play); @@ -77,20 +78,21 @@ bool LocMatchesQuest(Rando::Location loc) { return true; } else { auto dungeon = OTRGlobals::Instance->gRandoContext->GetDungeons()->GetDungeonFromScene(loc.GetScene()); - return (dungeon->IsMQ() && loc.GetQuest() == RCQUEST_MQ) || (dungeon->IsVanilla() && loc.GetQuest() == RCQUEST_VANILLA); + return (dungeon->IsMQ() && loc.GetQuest() == RCQUEST_MQ) || + (dungeon->IsVanilla() && loc.GetQuest() == RCQUEST_VANILLA); } } RandomizerCheck GetRandomizerCheckFromFlag(int16_t flagType, int16_t flag) { for (auto& loc : Rando::StaticData::GetLocationTable()) { - if ((loc.GetCollectionCheck().flag == flag && ( - (flagType == FLAG_INF_TABLE && loc.GetCollectionCheck().type == SPOILER_CHK_INF_TABLE) || - (flagType == FLAG_EVENT_CHECK_INF && loc.GetCollectionCheck().type == SPOILER_CHK_EVENT_CHK_INF) || - (flagType == FLAG_ITEM_GET_INF && loc.GetCollectionCheck().type == SPOILER_CHK_ITEM_GET_INF) || - (flagType == FLAG_RANDOMIZER_INF && loc.GetCollectionCheck().type == SPOILER_CHK_RANDOMIZER_INF) - ) || - (loc.GetActorParams() == flag && flagType == FLAG_GS_TOKEN && loc.GetCollectionCheck().type == SPOILER_CHK_GOLD_SKULLTULA) - ) && LocMatchesQuest(loc)) { + if ((loc.GetCollectionCheck().flag == flag && + ((flagType == FLAG_INF_TABLE && loc.GetCollectionCheck().type == SPOILER_CHK_INF_TABLE) || + (flagType == FLAG_EVENT_CHECK_INF && loc.GetCollectionCheck().type == SPOILER_CHK_EVENT_CHK_INF) || + (flagType == FLAG_ITEM_GET_INF && loc.GetCollectionCheck().type == SPOILER_CHK_ITEM_GET_INF) || + (flagType == FLAG_RANDOMIZER_INF && loc.GetCollectionCheck().type == SPOILER_CHK_RANDOMIZER_INF)) || + (loc.GetActorParams() == flag && flagType == FLAG_GS_TOKEN && + loc.GetCollectionCheck().type == SPOILER_CHK_GOLD_SKULLTULA)) && + LocMatchesQuest(loc)) { return loc.GetRandomizerCheck(); } } @@ -100,11 +102,11 @@ RandomizerCheck GetRandomizerCheckFromFlag(int16_t flagType, int16_t flag) { RandomizerCheck GetRandomizerCheckFromSceneFlag(int16_t sceneNum, int16_t flagType, int16_t flag) { for (auto& loc : Rando::StaticData::GetLocationTable()) { - if (loc.GetCollectionCheck().scene == sceneNum && loc.GetCollectionCheck().flag == flag && ( - (flagType == FLAG_SCENE_TREASURE && loc.GetCollectionCheck().type == SPOILER_CHK_CHEST) || - (flagType == FLAG_SCENE_COLLECTIBLE && loc.GetCollectionCheck().type == SPOILER_CHK_COLLECTABLE) || - (flagType == FLAG_GS_TOKEN && loc.GetCollectionCheck().type == SPOILER_CHK_GOLD_SKULLTULA) - ) && LocMatchesQuest(loc)) { + if (loc.GetCollectionCheck().scene == sceneNum && loc.GetCollectionCheck().flag == flag && + ((flagType == FLAG_SCENE_TREASURE && loc.GetCollectionCheck().type == SPOILER_CHK_CHEST) || + (flagType == FLAG_SCENE_COLLECTIBLE && loc.GetCollectionCheck().type == SPOILER_CHK_COLLECTABLE) || + (flagType == FLAG_GS_TOKEN && loc.GetCollectionCheck().type == SPOILER_CHK_GOLD_SKULLTULA)) && + LocMatchesQuest(loc)) { return loc.GetRandomizerCheck(); } } @@ -125,7 +127,8 @@ bool MeetsLACSRequirements() { } break; case RO_GANON_BOSS_KEY_LACS_REWARDS: - if ((CheckMedallionCount() + CheckStoneCount() + CheckLACSRewardCount()) >= RAND_GET_OPTION(RSK_LACS_REWARD_COUNT)) { + if ((CheckMedallionCount() + CheckStoneCount() + CheckLACSRewardCount()) >= + RAND_GET_OPTION(RSK_LACS_REWARD_COUNT)) { return true; } break; @@ -174,13 +177,15 @@ bool MeetsRainbowBridgeRequirements() { break; } case RO_BRIDGE_MEDALLIONS: { - if ((CheckMedallionCount() + CheckBridgeRewardCount()) >= RAND_GET_OPTION(RSK_RAINBOW_BRIDGE_MEDALLION_COUNT)) { + if ((CheckMedallionCount() + CheckBridgeRewardCount()) >= + RAND_GET_OPTION(RSK_RAINBOW_BRIDGE_MEDALLION_COUNT)) { return true; } break; } case RO_BRIDGE_DUNGEON_REWARDS: { - if ((CheckMedallionCount() + CheckStoneCount() + CheckBridgeRewardCount()) >= RAND_GET_OPTION(RSK_RAINBOW_BRIDGE_REWARD_COUNT)) { + if ((CheckMedallionCount() + CheckStoneCount() + CheckBridgeRewardCount()) >= + RAND_GET_OPTION(RSK_RAINBOW_BRIDGE_REWARD_COUNT)) { return true; } break; @@ -232,7 +237,7 @@ void RandomizerOnFlagSetHandler(int16_t flagType, int16_t flag) { } if (flagType == FLAG_EVENT_CHECK_INF && flag == EVENTCHKINF_TALON_WOKEN_IN_CASTLE) { - //remove chicken as this is the only use for it + // remove chicken as this is the only use for it Flags_UnsetRandomizerInf(RAND_INF_CHILD_TRADES_HAS_CHICKEN); } @@ -245,11 +250,15 @@ void RandomizerOnFlagSetHandler(int16_t flagType, int16_t flag) { } RandomizerCheck rc = GetRandomizerCheckFromFlag(flagType, flag); - if (rc == RC_UNKNOWN_CHECK) return; + if (rc == RC_UNKNOWN_CHECK) + return; - if (flagType == FLAG_GS_TOKEN && Rando::Context::GetInstance()->GetOption(RSK_SHUFFLE_TOKENS).Is(RO_TOKENSANITY_OFF)) return; + if (flagType == FLAG_GS_TOKEN && + Rando::Context::GetInstance()->GetOption(RSK_SHUFFLE_TOKENS).Is(RO_TOKENSANITY_OFF)) + return; auto loc = Rando::Context::GetInstance()->GetItemLocation(rc); - if (loc == nullptr || loc->HasObtained() || loc->GetPlacedRandomizerGet() == RG_NONE) return; + if (loc == nullptr || loc->HasObtained() || loc->GetPlacedRandomizerGet() == RG_NONE) + return; SPDLOG_INFO("Queuing RC: {}", static_cast(rc)); randomizerQueuedChecks.push(rc); @@ -257,17 +266,17 @@ void RandomizerOnFlagSetHandler(int16_t flagType, int16_t flag) { void RandomizerOnSceneFlagSetHandler(int16_t sceneNum, int16_t flagType, int16_t flag) { if (RAND_GET_OPTION(RSK_SHUFFLE_DUNGEON_ENTRANCES) != RO_DUNGEON_ENTRANCE_SHUFFLE_OFF && - sceneNum == SCENE_GERUDOS_FORTRESS && - flagType == FLAG_SCENE_SWITCH && - flag == 0x3A) { + sceneNum == SCENE_GERUDOS_FORTRESS && flagType == FLAG_SCENE_SWITCH && flag == 0x3A) { Flags_SetRandomizerInf(RAND_INF_GF_GTG_GATE_PERMANENTLY_OPEN); } RandomizerCheck rc = GetRandomizerCheckFromSceneFlag(sceneNum, flagType, flag); - if (rc == RC_UNKNOWN_CHECK) return; + if (rc == RC_UNKNOWN_CHECK) + return; auto loc = Rando::Context::GetInstance()->GetItemLocation(rc); - if (loc == nullptr || loc->HasObtained() || loc->GetPlacedRandomizerGet() == RG_NONE) return; + if (loc == nullptr || loc->HasObtained() || loc->GetPlacedRandomizerGet() == RG_NONE) + return; SPDLOG_INFO("Queuing RC: {}", static_cast(rc)); randomizerQueuedChecks.push(rc); @@ -277,14 +286,17 @@ static Vec3f spawnPos = { 0.0f, -999.0f, 0.0f }; void RandomizerOnPlayerUpdateForRCQueueHandler() { // If we're already queued, don't queue again - if (randomizerQueuedCheck != RC_UNKNOWN_CHECK) return; + if (randomizerQueuedCheck != RC_UNKNOWN_CHECK) + return; // If there's nothing to queue, don't queue - if (randomizerQueuedChecks.size() < 1) return; + if (randomizerQueuedChecks.size() < 1) + return; // If we're in a cutscene, don't queue Player* player = GET_PLAYER(gPlayState); - if (Player_InBlockingCsMode(gPlayState, player) || player->stateFlags1 & PLAYER_STATE1_IN_ITEM_CS || player->stateFlags1 & PLAYER_STATE1_GETTING_ITEM || player->stateFlags1 & PLAYER_STATE1_CARRYING_ACTOR) { + if (Player_InBlockingCsMode(gPlayState, player) || player->stateFlags1 & PLAYER_STATE1_IN_ITEM_CS || + player->stateFlags1 & PLAYER_STATE1_GETTING_ITEM || player->stateFlags1 & PLAYER_STATE1_CARRYING_ACTOR) { return; } @@ -292,7 +304,8 @@ void RandomizerOnPlayerUpdateForRCQueueHandler() { auto loc = Rando::Context::GetInstance()->GetItemLocation(rc); RandomizerGet vanillaRandomizerGet = Rando::StaticData::GetLocation(rc)->GetVanillaItem(); GetItemID vanillaItem = (GetItemID)Rando::StaticData::RetrieveItem(vanillaRandomizerGet).GetItemID(); - GetItemEntry getItemEntry = Rando::Context::GetInstance()->GetFinalGIEntry(rc, true, (GetItemID)vanillaRandomizerGet); + GetItemEntry getItemEntry = + Rando::Context::GetInstance()->GetFinalGIEntry(rc, true, (GetItemID)vanillaRandomizerGet); if (loc->HasObtained()) { SPDLOG_INFO("RC {} already obtained, skipping", static_cast(rc)); @@ -300,32 +313,25 @@ void RandomizerOnPlayerUpdateForRCQueueHandler() { iceTrapScale = 0.0f; randomizerQueuedCheck = rc; randomizerQueuedItemEntry = getItemEntry; - SPDLOG_INFO("Queueing Item mod {} item {} from RC {}", getItemEntry.modIndex, getItemEntry.itemId, static_cast(rc)); + SPDLOG_INFO("Queueing Item mod {} item {} from RC {}", getItemEntry.modIndex, getItemEntry.itemId, + static_cast(rc)); if ( // Skipping ItemGet animation incompatible with checks that require closing a text box to finish - rc != RC_HF_OCARINA_OF_TIME_ITEM && - rc != RC_SPIRIT_TEMPLE_SILVER_GAUNTLETS_CHEST && - rc != RC_MARKET_BOMBCHU_BOWLING_FIRST_PRIZE && - rc != RC_MARKET_BOMBCHU_BOWLING_SECOND_PRIZE && + rc != RC_HF_OCARINA_OF_TIME_ITEM && rc != RC_SPIRIT_TEMPLE_SILVER_GAUNTLETS_CHEST && + rc != RC_MARKET_BOMBCHU_BOWLING_FIRST_PRIZE && rc != RC_MARKET_BOMBCHU_BOWLING_SECOND_PRIZE && // Always show ItemGet animation for ice traps !(getItemEntry.modIndex == MOD_RANDOMIZER && getItemEntry.getItemId == RG_ICE_TRAP) && // Always show ItemGet animation outside of randomizer to keep behaviour consistent in vanilla IS_RANDO && - ( - CVarGetInteger(CVAR_RANDOMIZER_ENHANCEMENT("TimeSavers.SkipGetItemAnimation"), SGIA_JUNK) == SGIA_ALL || - ( - CVarGetInteger(CVAR_RANDOMIZER_ENHANCEMENT("TimeSavers.SkipGetItemAnimation"), SGIA_JUNK) == SGIA_JUNK && - ( - //crude fix to ensure map hints are readable. Ideally replace with better hint tracking. - !(getItemEntry.getItemId >= RG_DEKU_TREE_MAP && getItemEntry.getItemId <= RG_ICE_CAVERN_MAP && getItemEntry.modIndex == MOD_RANDOMIZER) && ( - getItemEntry.getItemCategory == ITEM_CATEGORY_JUNK || - getItemEntry.getItemCategory == ITEM_CATEGORY_SKULLTULA_TOKEN || - getItemEntry.getItemCategory == ITEM_CATEGORY_LESSER - ) - ) - ) - ) - ) { + (CVarGetInteger(CVAR_RANDOMIZER_ENHANCEMENT("TimeSavers.SkipGetItemAnimation"), SGIA_JUNK) == SGIA_ALL || + (CVarGetInteger(CVAR_RANDOMIZER_ENHANCEMENT("TimeSavers.SkipGetItemAnimation"), SGIA_JUNK) == SGIA_JUNK && + ( + // crude fix to ensure map hints are readable. Ideally replace with better hint tracking. + !(getItemEntry.getItemId >= RG_DEKU_TREE_MAP && getItemEntry.getItemId <= RG_ICE_CAVERN_MAP && + getItemEntry.modIndex == MOD_RANDOMIZER) && + (getItemEntry.getItemCategory == ITEM_CATEGORY_JUNK || + getItemEntry.getItemCategory == ITEM_CATEGORY_SKULLTULA_TOKEN || + getItemEntry.getItemCategory == ITEM_CATEGORY_LESSER))))) { Item_DropCollectible(gPlayState, &spawnPos, ITEM00_SOH_GIVE_ITEM_ENTRY | 0x8000); } } @@ -334,14 +340,18 @@ void RandomizerOnPlayerUpdateForRCQueueHandler() { } void RandomizerOnPlayerUpdateForItemQueueHandler() { - if (randomizerQueuedCheck == RC_UNKNOWN_CHECK) return; + if (randomizerQueuedCheck == RC_UNKNOWN_CHECK) + return; Player* player = GET_PLAYER(gPlayState); - if (player == NULL || Player_InBlockingCsMode(gPlayState, player) || player->stateFlags1 & PLAYER_STATE1_IN_ITEM_CS || player->stateFlags1 & PLAYER_STATE1_GETTING_ITEM || player->stateFlags1 & PLAYER_STATE1_CARRYING_ACTOR) { + if (player == NULL || Player_InBlockingCsMode(gPlayState, player) || + player->stateFlags1 & PLAYER_STATE1_IN_ITEM_CS || player->stateFlags1 & PLAYER_STATE1_GETTING_ITEM || + player->stateFlags1 & PLAYER_STATE1_CARRYING_ACTOR) { return; } - SPDLOG_INFO("Attempting to give Item mod {} item {} from RC {}", randomizerQueuedItemEntry.modIndex, randomizerQueuedItemEntry.itemId, static_cast(randomizerQueuedCheck)); + SPDLOG_INFO("Attempting to give Item mod {} item {} from RC {}", randomizerQueuedItemEntry.modIndex, + randomizerQueuedItemEntry.itemId, static_cast(randomizerQueuedCheck)); GiveItemEntryWithoutActor(gPlayState, randomizerQueuedItemEntry); if (player->stateFlags1 & PLAYER_STATE1_IN_WATER) { // Allow the player to receive the item while swimming @@ -351,11 +361,14 @@ void RandomizerOnPlayerUpdateForItemQueueHandler() { } void RandomizerOnItemReceiveHandler(GetItemEntry receivedItemEntry) { - if (randomizerQueuedCheck == RC_UNKNOWN_CHECK) return; + if (randomizerQueuedCheck == RC_UNKNOWN_CHECK) + return; auto loc = Rando::Context::GetInstance()->GetItemLocation(randomizerQueuedCheck); - if (randomizerQueuedItemEntry.modIndex == receivedItemEntry.modIndex && randomizerQueuedItemEntry.itemId == receivedItemEntry.itemId) { - SPDLOG_INFO("Item received mod {} item {} from RC {}", receivedItemEntry.modIndex, receivedItemEntry.itemId, static_cast(randomizerQueuedCheck)); + if (randomizerQueuedItemEntry.modIndex == receivedItemEntry.modIndex && + randomizerQueuedItemEntry.itemId == receivedItemEntry.itemId) { + SPDLOG_INFO("Item received mod {} item {} from RC {}", receivedItemEntry.modIndex, receivedItemEntry.itemId, + static_cast(randomizerQueuedCheck)); loc->SetCheckStatus(RCSHOW_COLLECTED); CheckTracker::SpoilAreaFromCheck(randomizerQueuedCheck); CheckTracker::RecalculateAllAreaTotals(); @@ -365,13 +378,9 @@ void RandomizerOnItemReceiveHandler(GetItemEntry receivedItemEntry) { randomizerQueuedItemEntry = GET_ITEM_NONE; } - if ( - receivedItemEntry.modIndex == MOD_NONE && ( - receivedItemEntry.itemId == ITEM_HEART_PIECE || - receivedItemEntry.itemId == ITEM_HEART_PIECE_2 || - receivedItemEntry.itemId == ITEM_HEART_CONTAINER - ) - ) { + if (receivedItemEntry.modIndex == MOD_NONE && + (receivedItemEntry.itemId == ITEM_HEART_PIECE || receivedItemEntry.itemId == ITEM_HEART_PIECE_2 || + receivedItemEntry.itemId == ITEM_HEART_CONTAINER)) { gSaveContext.healthAccumulator = 0x140; // Refill 20 hearts if ((s32)(gSaveContext.inventory.questItems & 0xF0000000) == 0x40000000) { gSaveContext.inventory.questItems ^= 0x40000000; @@ -380,11 +389,14 @@ void RandomizerOnItemReceiveHandler(GetItemEntry receivedItemEntry) { } } - if (loc->GetRandomizerCheck() == RC_SPIRIT_TEMPLE_SILVER_GAUNTLETS_CHEST && !CVarGetInteger(CVAR_ENHANCEMENT("TimeSavers.SkipCutscene.Story"), IS_RANDO)) { + if (loc->GetRandomizerCheck() == RC_SPIRIT_TEMPLE_SILVER_GAUNTLETS_CHEST && + !CVarGetInteger(CVAR_ENHANCEMENT("TimeSavers.SkipCutscene.Story"), IS_RANDO)) { static uint32_t updateHook; updateHook = GameInteractor::Instance->RegisterGameHook([]() { Player* player = GET_PLAYER(gPlayState); - if (player == NULL || Player_InBlockingCsMode(gPlayState, player) || player->stateFlags1 & PLAYER_STATE1_IN_ITEM_CS || player->stateFlags1 & PLAYER_STATE1_GETTING_ITEM || player->stateFlags1 & PLAYER_STATE1_CARRYING_ACTOR) { + if (player == NULL || Player_InBlockingCsMode(gPlayState, player) || + player->stateFlags1 & PLAYER_STATE1_IN_ITEM_CS || player->stateFlags1 & PLAYER_STATE1_GETTING_ITEM || + player->stateFlags1 & PLAYER_STATE1_CARRYING_ACTOR) { return; } @@ -415,7 +427,7 @@ void EnExItem_WaitForObjectRandomized(EnExItem* enExItem, PlayState* play) { if (Object_IsLoaded(&play->objectCtx, enExItem->objectIdx)) { enExItem->actor.draw = (ActorFunc)EnExItem_DrawRandomizedItem; Actor_SetScale(&enExItem->actor, enExItem->scale); - + // for now we're just using this to not have items float // below the bowling counter, but it would be nice to use // this to not draw gigantic skull tokens etc. @@ -482,8 +494,7 @@ void ItemEtcetera_DrawRandomizedItemThroughLens(ItemEtcetera* itemEtcetera, Play } void ItemEtcetera_func_80B858B4_Randomized(ItemEtcetera* itemEtcetera, PlayState* play) { - if (itemEtcetera->actor.xzDistToPlayer < 30.0f && - fabsf(itemEtcetera->actor.yDistToPlayer) < 50.0f) { + if (itemEtcetera->actor.xzDistToPlayer < 30.0f && fabsf(itemEtcetera->actor.yDistToPlayer) < 50.0f) { if ((itemEtcetera->actor.params & 0xFF) == 1) { Flags_SetEventChkInf(EVENTCHKINF_OBTAINED_RUTOS_LETTER); Flags_SetSwitch(play, 0xB); @@ -502,8 +513,7 @@ void ItemEtcetera_func_80B85824_Randomized(ItemEtcetera* itemEtcetera, PlayState return; } - if (itemEtcetera->actor.xzDistToPlayer < 30.0f && - fabsf(itemEtcetera->actor.yDistToPlayer) < 50.0f) { + if (itemEtcetera->actor.xzDistToPlayer < 30.0f && fabsf(itemEtcetera->actor.yDistToPlayer) < 50.0f) { Flags_SetTreasure(play, 0x1F); Actor_Kill(&itemEtcetera->actor); @@ -542,22 +552,21 @@ u8 EnDs_RandoCanGetGrannyItem() { // Traded odd mushroom when adult trade is on ((RAND_GET_OPTION(RSK_SHUFFLE_ADULT_TRADE) && Flags_GetItemGetInf(ITEMGETINF_30)) || // Found claim check when adult trade is off - (!RAND_GET_OPTION(RSK_SHUFFLE_ADULT_TRADE) && - INV_CONTENT(ITEM_CLAIM_CHECK) == ITEM_CLAIM_CHECK)); + (!RAND_GET_OPTION(RSK_SHUFFLE_ADULT_TRADE) && INV_CONTENT(ITEM_CLAIM_CHECK) == ITEM_CLAIM_CHECK)); } u8 EnJs_RandoCanGetCarpetMerchantItem() { - return (RAND_GET_OPTION(RSK_SHUFFLE_MERCHANTS) == RO_SHUFFLE_MERCHANTS_ALL || - RAND_GET_OPTION(RSK_SHUFFLE_MERCHANTS) == RO_SHUFFLE_MERCHANTS_ALL_BUT_BEANS) && - // If the rando check has already been awarded, use vanilla behavior. - !Flags_GetRandomizerInf(RAND_INF_MERCHANTS_CARPET_SALESMAN); + return (RAND_GET_OPTION(RSK_SHUFFLE_MERCHANTS) == RO_SHUFFLE_MERCHANTS_ALL || + RAND_GET_OPTION(RSK_SHUFFLE_MERCHANTS) == RO_SHUFFLE_MERCHANTS_ALL_BUT_BEANS) && + // If the rando check has already been awarded, use vanilla behavior. + !Flags_GetRandomizerInf(RAND_INF_MERCHANTS_CARPET_SALESMAN); } u8 EnGm_RandoCanGetMedigoronItem() { - return (RAND_GET_OPTION(RSK_SHUFFLE_MERCHANTS) == RO_SHUFFLE_MERCHANTS_ALL || - RAND_GET_OPTION(RSK_SHUFFLE_MERCHANTS) == RO_SHUFFLE_MERCHANTS_ALL_BUT_BEANS) && - // If the rando check has already been awarded, use vanilla behavior. - !Flags_GetRandomizerInf(RAND_INF_MERCHANTS_MEDIGORON); + return (RAND_GET_OPTION(RSK_SHUFFLE_MERCHANTS) == RO_SHUFFLE_MERCHANTS_ALL || + RAND_GET_OPTION(RSK_SHUFFLE_MERCHANTS) == RO_SHUFFLE_MERCHANTS_ALL_BUT_BEANS) && + // If the rando check has already been awarded, use vanilla behavior. + !Flags_GetRandomizerInf(RAND_INF_MERCHANTS_MEDIGORON); } void RandomizerSetChestGameRandomizerInf(RandomizerCheck rc) { @@ -608,44 +617,50 @@ void func_8083A434_override(PlayState* play, Player* player) { player->stateFlags1 |= PLAYER_STATE1_GETTING_ITEM | PLAYER_STATE1_IN_CUTSCENE; } -bool ShouldGiveFishingPrize(f32 sFishOnHandLength){ +bool ShouldGiveFishingPrize(f32 sFishOnHandLength) { // RANDOTODO: update the enhancement sliders to not allow // values above rando fish weight values when rando'd - if(LINK_IS_CHILD) { - int32_t weight = CVarGetInteger(CVAR_ENHANCEMENT("CustomizeFishing"), 0) ? CVarGetInteger(CVAR_ENHANCEMENT("MinimumFishWeightChild"), 10) : 10; + if (LINK_IS_CHILD) { + int32_t weight = CVarGetInteger(CVAR_ENHANCEMENT("CustomizeFishing"), 0) + ? CVarGetInteger(CVAR_ENHANCEMENT("MinimumFishWeightChild"), 10) + : 10; f32 score = sqrt(((f32)weight - 0.5f) / 0.0036f); - return sFishOnHandLength >= score && (IS_RANDO ? !Flags_GetRandomizerInf(RAND_INF_CHILD_FISHING) : !(HIGH_SCORE(HS_FISHING) & HS_FISH_PRIZE_CHILD)); - } else - { - int32_t weight = CVarGetInteger(CVAR_ENHANCEMENT("CustomizeFishing"), 0) ? CVarGetInteger(CVAR_ENHANCEMENT("MinimumFishWeightAdult"), 13) : 13; + return sFishOnHandLength >= score && (IS_RANDO ? !Flags_GetRandomizerInf(RAND_INF_CHILD_FISHING) + : !(HIGH_SCORE(HS_FISHING) & HS_FISH_PRIZE_CHILD)); + } else { + int32_t weight = CVarGetInteger(CVAR_ENHANCEMENT("CustomizeFishing"), 0) + ? CVarGetInteger(CVAR_ENHANCEMENT("MinimumFishWeightAdult"), 13) + : 13; f32 score = sqrt(((f32)weight - 0.5f) / 0.0036f); - return sFishOnHandLength >= score && (IS_RANDO ? !Flags_GetRandomizerInf(RAND_INF_ADULT_FISHING) : !(HIGH_SCORE(HS_FISHING) & HS_FISH_PRIZE_ADULT)); + return sFishOnHandLength >= score && (IS_RANDO ? !Flags_GetRandomizerInf(RAND_INF_ADULT_FISHING) + : !(HIGH_SCORE(HS_FISHING) & HS_FISH_PRIZE_ADULT)); } } void RandomizerOnDialogMessageHandler() { - MessageContext *msgCtx = &gPlayState->msgCtx; - Actor *actor = msgCtx->talkActor; + MessageContext* msgCtx = &gPlayState->msgCtx; + Actor* actor = msgCtx->talkActor; auto ctx = Rando::Context::GetInstance(); bool revealMerchant = ctx->GetOption(RSK_MERCHANT_TEXT_HINT).Get() != RO_GENERIC_OFF; bool nonBeanMerchants = ctx->GetOption(RSK_SHUFFLE_MERCHANTS).Is(RO_SHUFFLE_MERCHANTS_ALL_BUT_BEANS) || - ctx->GetOption(RSK_SHUFFLE_MERCHANTS).Is(RO_SHUFFLE_MERCHANTS_ALL); + ctx->GetOption(RSK_SHUFFLE_MERCHANTS).Is(RO_SHUFFLE_MERCHANTS_ALL); RandomizerCheck reveal = RC_UNKNOWN_CHECK; - if (ctx->GetOption(RSK_CHICKENS_HINT) && (msgCtx->textId >= TEXT_ANJU_PLEASE_BRING_MY_CUCCOS_BACK && msgCtx->textId <= TEXT_ANJU_PLEASE_BRING_1_CUCCO)) { + if (ctx->GetOption(RSK_CHICKENS_HINT) && + (msgCtx->textId >= TEXT_ANJU_PLEASE_BRING_MY_CUCCOS_BACK && msgCtx->textId <= TEXT_ANJU_PLEASE_BRING_1_CUCCO)) { reveal = RC_KAK_ANJU_AS_CHILD; } else { switch (msgCtx->textId) { case TEXT_SKULLTULA_PEOPLE_IM_CURSED: - if (actor->params == 1 && ctx->GetOption(RSK_KAK_10_SKULLS_HINT)){ + if (actor->params == 1 && ctx->GetOption(RSK_KAK_10_SKULLS_HINT)) { reveal = RC_KAK_10_GOLD_SKULLTULA_REWARD; - } else if (actor->params == 2 && ctx->GetOption(RSK_KAK_20_SKULLS_HINT)){ + } else if (actor->params == 2 && ctx->GetOption(RSK_KAK_20_SKULLS_HINT)) { reveal = RC_KAK_20_GOLD_SKULLTULA_REWARD; - } else if (actor->params == 3 && ctx->GetOption(RSK_KAK_30_SKULLS_HINT)){ + } else if (actor->params == 3 && ctx->GetOption(RSK_KAK_30_SKULLS_HINT)) { reveal = RC_KAK_30_GOLD_SKULLTULA_REWARD; - } else if (actor->params == 4 && ctx->GetOption(RSK_KAK_40_SKULLS_HINT)){ + } else if (actor->params == 4 && ctx->GetOption(RSK_KAK_40_SKULLS_HINT)) { reveal = RC_KAK_40_GOLD_SKULLTULA_REWARD; - } else if (ctx->GetOption(RSK_KAK_50_SKULLS_HINT)){ + } else if (ctx->GetOption(RSK_KAK_50_SKULLS_HINT)) { reveal = RC_KAK_50_GOLD_SKULLTULA_REWARD; } break; @@ -698,20 +713,21 @@ void RandomizerOnDialogMessageHandler() { case TEXT_SCRUB_RANDOM: if (ctx->GetOption(RSK_SCRUB_TEXT_HINT).Get() != RO_GENERIC_OFF) { EnDns* enDns = (EnDns*)actor; - reveal = OTRGlobals::Instance->gRandomizer->GetCheckFromRandomizerInf((RandomizerInf)enDns->sohScrubIdentity.randomizerInf); + reveal = OTRGlobals::Instance->gRandomizer->GetCheckFromRandomizerInf( + (RandomizerInf)enDns->sohScrubIdentity.randomizerInf); } break; case TEXT_BEAN_SALESMAN_BUY_FOR_10: if (revealMerchant && (ctx->GetOption(RSK_SHUFFLE_MERCHANTS).Is(RO_SHUFFLE_MERCHANTS_BEANS_ONLY) || - ctx->GetOption(RSK_SHUFFLE_MERCHANTS).Is(RO_SHUFFLE_MERCHANTS_ALL))) { + ctx->GetOption(RSK_SHUFFLE_MERCHANTS).Is(RO_SHUFFLE_MERCHANTS_ALL))) { reveal = RC_ZR_MAGIC_BEAN_SALESMAN; } break; case TEXT_GRANNYS_SHOP: if (revealMerchant && nonBeanMerchants && - (ctx->GetOption(RSK_SHUFFLE_ADULT_TRADE) || INV_CONTENT(ITEM_CLAIM_CHECK) == ITEM_CLAIM_CHECK)) { - reveal = RC_KAK_GRANNYS_SHOP; - } + (ctx->GetOption(RSK_SHUFFLE_ADULT_TRADE) || INV_CONTENT(ITEM_CLAIM_CHECK) == ITEM_CLAIM_CHECK)) { + reveal = RC_KAK_GRANNYS_SHOP; + } break; case TEXT_MEDIGORON: if (revealMerchant && nonBeanMerchants) { @@ -734,7 +750,7 @@ void RandomizerOnDialogMessageHandler() { case TEXT_SHEIK_NEED_HOOK: case TEXT_SHEIK_HAVE_HOOK: if (ctx->GetOption(RSK_OOT_HINT) && gPlayState->sceneNum == SCENE_TEMPLE_OF_TIME && - !ctx->GetItemLocation(RC_SONG_FROM_OCARINA_OF_TIME)->HasObtained()) { + !ctx->GetItemLocation(RC_SONG_FROM_OCARINA_OF_TIME)->HasObtained()) { auto itemoot_loc = ctx->GetItemLocation(RC_HF_OCARINA_OF_TIME_ITEM); if (itemoot_loc->GetCheckStatus() == RCSHOW_UNCHECKED) { itemoot_loc->SetCheckStatus(RCSHOW_IDENTIFIED); @@ -779,7 +795,8 @@ void RandomizerOnVanillaBehaviorHandler(GIVanillaBehavior id, bool* should, va_l break; } case VB_PLAY_SLOW_CHEST_CS: { - // We force fast chests if SkipGetItemAnimation is enabled because the camera in the CS looks pretty wonky otherwise + // We force fast chests if SkipGetItemAnimation is enabled because the camera in the CS looks pretty wonky + // otherwise if (CVarGetInteger(CVAR_RANDOMIZER_ENHANCEMENT("TimeSavers.SkipGetItemAnimation"), SGIA_JUNK)) { *should = false; } @@ -787,7 +804,8 @@ void RandomizerOnVanillaBehaviorHandler(GIVanillaBehavior id, bool* should, va_l } case VB_GIVE_ITEM_FROM_CHEST: { EnBox* chest = va_arg(args, EnBox*); - RandomizerCheck rc = OTRGlobals::Instance->gRandomizer->GetCheckFromActor(chest->dyna.actor.id, gPlayState->sceneNum, chest->dyna.actor.params); + RandomizerCheck rc = OTRGlobals::Instance->gRandomizer->GetCheckFromActor( + chest->dyna.actor.id, gPlayState->sceneNum, chest->dyna.actor.params); if (!OTRGlobals::Instance->gRandoContext->IsLocationShuffled(rc)) { break; } @@ -809,17 +827,21 @@ void RandomizerOnVanillaBehaviorHandler(GIVanillaBehavior id, bool* should, va_l *should = false; break; case VB_SHIEK_PREPARE_TO_GIVE_SERENADE_OF_WATER: { - *should = !Flags_GetEventChkInf(EVENTCHKINF_LEARNED_SERENADE_OF_WATER) && !Flags_GetTreasure(gPlayState, 0x2); + *should = + !Flags_GetEventChkInf(EVENTCHKINF_LEARNED_SERENADE_OF_WATER) && !Flags_GetTreasure(gPlayState, 0x2); break; } case VB_BE_ELIGIBLE_FOR_SERENADE_OF_WATER: - *should = !Flags_GetEventChkInf(EVENTCHKINF_LEARNED_SERENADE_OF_WATER) && Flags_GetTreasure(gPlayState, 0x2); + *should = + !Flags_GetEventChkInf(EVENTCHKINF_LEARNED_SERENADE_OF_WATER) && Flags_GetTreasure(gPlayState, 0x2); break; case VB_BE_ELIGIBLE_FOR_PRELUDE_OF_LIGHT: - *should = !Flags_GetEventChkInf(EVENTCHKINF_LEARNED_PRELUDE_OF_LIGHT) && CHECK_QUEST_ITEM(QUEST_MEDALLION_FOREST); + *should = + !Flags_GetEventChkInf(EVENTCHKINF_LEARNED_PRELUDE_OF_LIGHT) && CHECK_QUEST_ITEM(QUEST_MEDALLION_FOREST); break; case VB_MIDO_SPAWN: - if (RAND_GET_OPTION(RSK_FOREST) != RO_CLOSED_FOREST_OFF && !Flags_GetEventChkInf(EVENTCHKINF_SHOWED_MIDO_SWORD_SHIELD)) { + if (RAND_GET_OPTION(RSK_FOREST) != RO_CLOSED_FOREST_OFF && + !Flags_GetEventChkInf(EVENTCHKINF_SHOWED_MIDO_SWORD_SHIELD)) { *should = true; } break; @@ -832,26 +854,22 @@ void RandomizerOnVanillaBehaviorHandler(GIVanillaBehavior id, bool* should, va_l *should = Flags_GetEventChkInf(EVENTCHKINF_OBTAINED_KOKIRI_EMERALD_DEKU_TREE_DEAD); break; case VB_OPEN_KOKIRI_FOREST: - *should = Flags_GetEventChkInf(EVENTCHKINF_OBTAINED_KOKIRI_EMERALD_DEKU_TREE_DEAD) || RAND_GET_OPTION(RSK_FOREST) != RO_CLOSED_FOREST_ON; + *should = Flags_GetEventChkInf(EVENTCHKINF_OBTAINED_KOKIRI_EMERALD_DEKU_TREE_DEAD) || + RAND_GET_OPTION(RSK_FOREST) != RO_CLOSED_FOREST_ON; break; case VB_BE_ELIGIBLE_FOR_DARUNIAS_JOY_REWARD: *should = !Flags_GetRandomizerInf(RAND_INF_DARUNIAS_JOY); break; case VB_BE_ELIGIBLE_FOR_LIGHT_ARROWS: - *should = - LINK_IS_ADULT && - (gEntranceTable[gSaveContext.entranceIndex].scene == SCENE_TEMPLE_OF_TIME) && - !Flags_GetEventChkInf(EVENTCHKINF_RETURNED_TO_TEMPLE_OF_TIME_WITH_ALL_MEDALLIONS) && - MeetsLACSRequirements(); + *should = LINK_IS_ADULT && (gEntranceTable[gSaveContext.entranceIndex].scene == SCENE_TEMPLE_OF_TIME) && + !Flags_GetEventChkInf(EVENTCHKINF_RETURNED_TO_TEMPLE_OF_TIME_WITH_ALL_MEDALLIONS) && + MeetsLACSRequirements(); break; case VB_BE_ELIGIBLE_FOR_NOCTURNE_OF_SHADOW: - *should = - !Flags_GetEventChkInf(EVENTCHKINF_BONGO_BONGO_ESCAPED_FROM_WELL) && - LINK_IS_ADULT && - gEntranceTable[((void)0, gSaveContext.entranceIndex)].scene == SCENE_KAKARIKO_VILLAGE && - CHECK_QUEST_ITEM(QUEST_MEDALLION_FOREST) && - CHECK_QUEST_ITEM(QUEST_MEDALLION_FIRE) && - CHECK_QUEST_ITEM(QUEST_MEDALLION_WATER); + *should = !Flags_GetEventChkInf(EVENTCHKINF_BONGO_BONGO_ESCAPED_FROM_WELL) && LINK_IS_ADULT && + gEntranceTable[((void)0, gSaveContext.entranceIndex)].scene == SCENE_KAKARIKO_VILLAGE && + CHECK_QUEST_ITEM(QUEST_MEDALLION_FOREST) && CHECK_QUEST_ITEM(QUEST_MEDALLION_FIRE) && + CHECK_QUEST_ITEM(QUEST_MEDALLION_WATER); break; case VB_BE_ELIGIBLE_FOR_CHILD_ROLLING_GORON_REWARD: { // Don't require a bomb bag to get prize in rando @@ -861,7 +879,8 @@ void RandomizerOnVanillaBehaviorHandler(GIVanillaBehavior id, bool* should, va_l case VB_BE_ELIGIBLE_FOR_MAGIC_BEANS_PURCHASE: { if (RAND_GET_OPTION(RSK_SHUFFLE_MERCHANTS) == RO_SHUFFLE_MERCHANTS_BEANS_ONLY || RAND_GET_OPTION(RSK_SHUFFLE_MERCHANTS) == RO_SHUFFLE_MERCHANTS_ALL) { - *should = gSaveContext.rupees >= OTRGlobals::Instance->gRandoContext->GetItemLocation(RC_ZR_MAGIC_BEAN_SALESMAN)->GetPrice(); + *should = gSaveContext.rupees >= + OTRGlobals::Instance->gRandoContext->GetItemLocation(RC_ZR_MAGIC_BEAN_SALESMAN)->GetPrice(); } break; } @@ -897,9 +916,11 @@ void RandomizerOnVanillaBehaviorHandler(GIVanillaBehavior id, bool* should, va_l } case VB_ITEM_B_HEART_DESPAWN: { ItemBHeart* itemBHeart = va_arg(args, ItemBHeart*); - RandomizerCheck rc = OTRGlobals::Instance->gRandomizer->GetCheckFromActor(itemBHeart->actor.id, gPlayState->sceneNum, itemBHeart->actor.params); + RandomizerCheck rc = OTRGlobals::Instance->gRandomizer->GetCheckFromActor( + itemBHeart->actor.id, gPlayState->sceneNum, itemBHeart->actor.params); if (rc != RC_UNKNOWN_CHECK) { - itemBHeart->sohItemEntry = Rando::Context::GetInstance()->GetFinalGIEntry(rc, true, (GetItemID)Rando::StaticData::GetLocation(rc)->GetVanillaItem()); + itemBHeart->sohItemEntry = Rando::Context::GetInstance()->GetFinalGIEntry( + rc, true, (GetItemID)Rando::StaticData::GetLocation(rc)->GetVanillaItem()); itemBHeart->actor.draw = (ActorFunc)ItemBHeart_DrawRandomizedItem; itemBHeart->actor.update = (ActorFunc)ItemBHeart_UpdateRandomizedItem; *should = Rando::Context::GetInstance()->GetItemLocation(rc)->HasObtained(); @@ -962,7 +983,8 @@ void RandomizerOnVanillaBehaviorHandler(GIVanillaBehavior id, bool* should, va_l } case VB_BIGGORON_CONSIDER_TRADE_COMPLETE: { // This being true will prevent other biggoron trades, there are already safegaurds in place to prevent - // claim check from being traded multiple times, so we don't really need the quest to ever be considered "complete" + // claim check from being traded multiple times, so we don't really need the quest to ever be considered + // "complete" *should = false; break; } @@ -989,7 +1011,8 @@ void RandomizerOnVanillaBehaviorHandler(GIVanillaBehavior id, bool* should, va_l Actor_Kill(&item00->actor); *should = false; } else if (item00->actor.params == ITEM00_SOH_GIVE_ITEM_ENTRY) { - Audio_PlaySoundGeneral(NA_SE_SY_GET_ITEM, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb); + Audio_PlaySoundGeneral(NA_SE_SY_GET_ITEM, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, + &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb); if (item00->itemEntry.modIndex == MOD_NONE) { if (item00->itemEntry.getItemId == GI_SWORD_BGS) { gSaveContext.bgsFlag = true; @@ -1012,7 +1035,9 @@ void RandomizerOnVanillaBehaviorHandler(GIVanillaBehavior id, bool* should, va_l } else if (item00->itemEntry.modIndex == MOD_RANDOMIZER) { Notification::Emit({ .message = "You found ", - .suffix = Rando::StaticData::RetrieveItem((RandomizerGet)item00->itemEntry.getItemId).GetName().english, + .suffix = Rando::StaticData::RetrieveItem((RandomizerGet)item00->itemEntry.getItemId) + .GetName() + .english, }); } @@ -1070,15 +1095,19 @@ void RandomizerOnVanillaBehaviorHandler(GIVanillaBehavior id, bool* should, va_l break; } case VB_CHECK_RANDO_PRICE_OF_CARPET_SALESMAN: { - if (EnJs_RandoCanGetCarpetMerchantItem()){ - *should = gSaveContext.rupees < OTRGlobals::Instance->gRandoContext->GetItemLocation(RC_WASTELAND_BOMBCHU_SALESMAN)->GetPrice(); + if (EnJs_RandoCanGetCarpetMerchantItem()) { + *should = + gSaveContext.rupees < + OTRGlobals::Instance->gRandoContext->GetItemLocation(RC_WASTELAND_BOMBCHU_SALESMAN)->GetPrice(); } break; } case VB_GIVE_ITEM_FROM_CARPET_SALESMAN: { EnJs* enJs = va_arg(args, EnJs*); - if (EnJs_RandoCanGetCarpetMerchantItem()){ - Rupees_ChangeBy(OTRGlobals::Instance->gRandoContext->GetItemLocation(RC_WASTELAND_BOMBCHU_SALESMAN)->GetPrice() * -1); + if (EnJs_RandoCanGetCarpetMerchantItem()) { + Rupees_ChangeBy( + OTRGlobals::Instance->gRandoContext->GetItemLocation(RC_WASTELAND_BOMBCHU_SALESMAN)->GetPrice() * + -1); enJs->actor.parent = NULL; enJs->actor.textId = TEXT_CARPET_SALESMAN_ARMS_DEALER; enJs->actionFunc = (EnJsActionFunc)func_80A890C0; @@ -1093,8 +1122,9 @@ void RandomizerOnVanillaBehaviorHandler(GIVanillaBehavior id, bool* should, va_l break; } case VB_CHECK_RANDO_PRICE_OF_MEDIGORON: { - if (EnGm_RandoCanGetMedigoronItem()){ - *should = gSaveContext.rupees < OTRGlobals::Instance->gRandoContext->GetItemLocation(RC_GC_MEDIGORON)->GetPrice(); + if (EnGm_RandoCanGetMedigoronItem()) { + *should = gSaveContext.rupees < + OTRGlobals::Instance->gRandoContext->GetItemLocation(RC_GC_MEDIGORON)->GetPrice(); } break; } @@ -1108,7 +1138,8 @@ void RandomizerOnVanillaBehaviorHandler(GIVanillaBehavior id, bool* should, va_l Flags_SetRandomizerInf(RAND_INF_MERCHANTS_MEDIGORON); enGm->actor.parent = NULL; enGm->actionFunc = (EnGmActionFunc)func_80A3DC44; - Rupees_ChangeBy(OTRGlobals::Instance->gRandoContext->GetItemLocation(RC_GC_MEDIGORON)->GetPrice() * -1); + Rupees_ChangeBy(OTRGlobals::Instance->gRandoContext->GetItemLocation(RC_GC_MEDIGORON)->GetPrice() * + -1); *should = false; } else { // Resets "Talked to Medigoron" flag in infTable to restore initial conversation state @@ -1122,7 +1153,8 @@ void RandomizerOnVanillaBehaviorHandler(GIVanillaBehavior id, bool* should, va_l EnMs* enMs = va_arg(args, EnMs*); if (RAND_GET_OPTION(RSK_SHUFFLE_MERCHANTS) == RO_SHUFFLE_MERCHANTS_BEANS_ONLY || RAND_GET_OPTION(RSK_SHUFFLE_MERCHANTS) == RO_SHUFFLE_MERCHANTS_ALL) { - Rupees_ChangeBy(OTRGlobals::Instance->gRandoContext->GetItemLocation(RC_ZR_MAGIC_BEAN_SALESMAN)->GetPrice() * -1); + Rupees_ChangeBy( + OTRGlobals::Instance->gRandoContext->GetItemLocation(RC_ZR_MAGIC_BEAN_SALESMAN)->GetPrice() * -1); BEANS_BOUGHT = 10; // Only set inf for buying rando check Flags_SetRandomizerInf(RAND_INF_MERCHANTS_MAGIC_BEAN_SALESMAN); @@ -1134,10 +1166,8 @@ void RandomizerOnVanillaBehaviorHandler(GIVanillaBehavior id, bool* should, va_l case VB_FROGS_GO_TO_IDLE: { EnFr* enFr = va_arg(args, EnFr*); - if ( - (enFr->songIndex >= FROG_STORMS && enFr->reward == GI_HEART_PIECE) || - (enFr->songIndex < FROG_STORMS && enFr->reward == GI_RUPEE_PURPLE) - ) { + if ((enFr->songIndex >= FROG_STORMS && enFr->reward == GI_HEART_PIECE) || + (enFr->songIndex < FROG_STORMS && enFr->reward == GI_RUPEE_PURPLE)) { *should = true; } break; @@ -1225,7 +1255,8 @@ void RandomizerOnVanillaBehaviorHandler(GIVanillaBehavior id, bool* should, va_l case VB_BUSINESS_SCRUB_DESPAWN: { EnShopnuts* enShopnuts = va_arg(args, EnShopnuts*); s16 respawnData = gSaveContext.respawn[RESPAWN_MODE_RETURN].data & ((1 << 8) - 1); - ScrubIdentity scrubIdentity = OTRGlobals::Instance->gRandomizer->IdentifyScrub(gPlayState->sceneNum, enShopnuts->actor.params, respawnData); + ScrubIdentity scrubIdentity = OTRGlobals::Instance->gRandomizer->IdentifyScrub( + gPlayState->sceneNum, enShopnuts->actor.params, respawnData); if (scrubIdentity.isShuffled) { *should = Flags_GetRandomizerInf(scrubIdentity.randomizerInf); @@ -1280,16 +1311,18 @@ void RandomizerOnVanillaBehaviorHandler(GIVanillaBehavior id, bool* should, va_l break; } case VB_GRANNY_SAY_INSUFFICIENT_RUPEES: { - if (EnDs_RandoCanGetGrannyItem()){ - *should = gSaveContext.rupees < OTRGlobals::Instance->gRandoContext->GetItemLocation(RC_KAK_GRANNYS_SHOP)->GetPrice(); + if (EnDs_RandoCanGetGrannyItem()) { + *should = gSaveContext.rupees < + OTRGlobals::Instance->gRandoContext->GetItemLocation(RC_KAK_GRANNYS_SHOP)->GetPrice(); } break; } case VB_GRANNY_TAKE_MONEY: { - if (EnDs_RandoCanGetGrannyItem()){ - *should = false; - Rupees_ChangeBy(OTRGlobals::Instance->gRandoContext->GetItemLocation(RC_KAK_GRANNYS_SHOP)->GetPrice() * -1); - } + if (EnDs_RandoCanGetGrannyItem()) { + *should = false; + Rupees_ChangeBy(OTRGlobals::Instance->gRandoContext->GetItemLocation(RC_KAK_GRANNYS_SHOP)->GetPrice() * + -1); + } break; } case VB_NEED_BOTTLE_FOR_GRANNYS_ITEM: { @@ -1318,12 +1351,10 @@ void RandomizerOnVanillaBehaviorHandler(GIVanillaBehavior id, bool* should, va_l break; } case VB_BE_ELIGIBLE_TO_OPEN_DOT: { - bool eligible = RAND_GET_OPTION(RSK_DOOR_OF_TIME) != RO_DOOROFTIME_CLOSED || ( - INV_CONTENT(ITEM_OCARINA_FAIRY) == ITEM_OCARINA_TIME && - CHECK_QUEST_ITEM(QUEST_KOKIRI_EMERALD) && - CHECK_QUEST_ITEM(QUEST_GORON_RUBY) && - CHECK_QUEST_ITEM(QUEST_ZORA_SAPPHIRE) - ); + bool eligible = + RAND_GET_OPTION(RSK_DOOR_OF_TIME) != RO_DOOROFTIME_CLOSED || + (INV_CONTENT(ITEM_OCARINA_FAIRY) == ITEM_OCARINA_TIME && CHECK_QUEST_ITEM(QUEST_KOKIRI_EMERALD) && + CHECK_QUEST_ITEM(QUEST_GORON_RUBY) && CHECK_QUEST_ITEM(QUEST_ZORA_SAPPHIRE)); *should = eligible; break; } @@ -1336,10 +1367,10 @@ void RandomizerOnVanillaBehaviorHandler(GIVanillaBehavior id, bool* should, va_l if (gSaveContext.minigameScore >= 1500) { Flags_SetItemGetInf(ITEMGETINF_0F); } - //move gerudo actor onto her wait loop + // move gerudo actor onto her wait loop enGe1->actionFunc = EnGe1_Wait_Archery; EnGe1_SetAnimationIdle(enGe1); - //skip the vanilla gives. + // skip the vanilla gives. *should = false; break; } @@ -1361,7 +1392,7 @@ void RandomizerOnVanillaBehaviorHandler(GIVanillaBehavior id, bool* should, va_l // we're giving the 100 GS rando reward! set the rando inf Flags_SetRandomizerInf(RAND_INF_KAK_100_GOLD_SKULLTULA_REWARD); - + // also set the actionfunc so this doesn't immediately get // called again (and lead to a vanilla+rando item give // because the flag check will pass next time) @@ -1388,7 +1419,8 @@ void RandomizerOnVanillaBehaviorHandler(GIVanillaBehavior id, bool* should, va_l } case VB_GIVE_ITEM_FROM_BOMBCHU_BOWLING: { EnBomBowlPit* enBomBowlPit = va_arg(args, EnBomBowlPit*); - if (enBomBowlPit->prizeIndex == EXITEM_BOMB_BAG_BOWLING || enBomBowlPit->prizeIndex == EXITEM_HEART_PIECE_BOWLING) { + if (enBomBowlPit->prizeIndex == EXITEM_BOMB_BAG_BOWLING || + enBomBowlPit->prizeIndex == EXITEM_HEART_PIECE_BOWLING) { *should = false; } break; @@ -1424,17 +1456,17 @@ void RandomizerOnVanillaBehaviorHandler(GIVanillaBehavior id, bool* should, va_l case VB_DRAW_AMMO_COUNT: { s16 item = *va_arg(args, s16*); // don't draw ammo count if you have the infinite upgrade - if ( - (item == ITEM_NUT && Flags_GetRandomizerInf(RAND_INF_HAS_INFINITE_NUT_UPGRADE)) || + if ((item == ITEM_NUT && Flags_GetRandomizerInf(RAND_INF_HAS_INFINITE_NUT_UPGRADE)) || (item == ITEM_STICK && Flags_GetRandomizerInf(RAND_INF_HAS_INFINITE_STICK_UPGRADE)) || (item == ITEM_BOMB && Flags_GetRandomizerInf(RAND_INF_HAS_INFINITE_BOMB_BAG)) || - ( - (item == ITEM_BOW || item == ITEM_BOW_ARROW_FIRE || item == ITEM_BOW_ARROW_ICE || item == ITEM_BOW_ARROW_LIGHT) && - Flags_GetRandomizerInf(RAND_INF_HAS_INFINITE_QUIVER) && gPlayState->shootingGalleryStatus < 2 && gSaveContext.minigameState != 1 - ) || - (item == ITEM_SLINGSHOT && Flags_GetRandomizerInf(RAND_INF_HAS_INFINITE_BULLET_BAG) && gPlayState->shootingGalleryStatus < 2) || - (item == ITEM_BOMBCHU && Flags_GetRandomizerInf(RAND_INF_HAS_INFINITE_BOMBCHUS) && gPlayState->bombchuBowlingStatus < 1) - ) { + ((item == ITEM_BOW || item == ITEM_BOW_ARROW_FIRE || item == ITEM_BOW_ARROW_ICE || + item == ITEM_BOW_ARROW_LIGHT) && + Flags_GetRandomizerInf(RAND_INF_HAS_INFINITE_QUIVER) && gPlayState->shootingGalleryStatus < 2 && + gSaveContext.minigameState != 1) || + (item == ITEM_SLINGSHOT && Flags_GetRandomizerInf(RAND_INF_HAS_INFINITE_BULLET_BAG) && + gPlayState->shootingGalleryStatus < 2) || + (item == ITEM_BOMBCHU && Flags_GetRandomizerInf(RAND_INF_HAS_INFINITE_BOMBCHUS) && + gPlayState->bombchuBowlingStatus < 1)) { *should = false; } break; @@ -1520,7 +1552,7 @@ void RandomizerOnVanillaBehaviorHandler(GIVanillaBehavior id, bool* should, va_l case VB_SHOULD_SET_FISHING_RECORD: { VBFishingData* fishData = va_arg(args, VBFishingData*); *should = (s16)fishData->sFishingRecordLength < (s16)fishData->fishWeight; - if (!*should){ + if (!*should) { *fishData->sFishOnHandLength = 0.0f; } break; @@ -1531,19 +1563,20 @@ void RandomizerOnVanillaBehaviorHandler(GIVanillaBehavior id, bool* should, va_l break; } case VB_GIVE_RANDO_FISHING_PRIZE: { - if (IS_RANDO){ + if (IS_RANDO) { VBFishingData* fishData = va_arg(args, VBFishingData*); if (*fishData->sFishOnHandIsLoach) { if (!Flags_GetRandomizerInf(RAND_INF_CAUGHT_LOACH) && - OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_FISHSANITY) == RO_FISHSANITY_HYRULE_LOACH){ + OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_FISHSANITY) == + RO_FISHSANITY_HYRULE_LOACH) { Flags_SetRandomizerInf(RAND_INF_CAUGHT_LOACH); Message_StartTextbox(gPlayState, TEXT_FISHING_RELEASE_THIS_ONE, NULL); *should = true; fishData->actor->stateAndTimer = 20; } } else { - if (ShouldGiveFishingPrize(fishData->fishWeight)){ - if (LINK_IS_CHILD){ + if (ShouldGiveFishingPrize(fishData->fishWeight)) { + if (LINK_IS_CHILD) { Flags_SetRandomizerInf(RAND_INF_CHILD_FISHING); HIGH_SCORE(HS_FISHING) |= HS_FISH_PRIZE_CHILD; } else { @@ -1558,7 +1591,7 @@ void RandomizerOnVanillaBehaviorHandler(GIVanillaBehavior id, bool* should, va_l } break; } - case VB_TRADE_TIMER_EYEDROPS:{ + case VB_TRADE_TIMER_EYEDROPS: { EnMk* enMk = va_arg(args, EnMk*); Flags_SetRandomizerInf(RAND_INF_ADULT_TRADES_LH_TRADE_FROG); enMk->actor.flags &= ~ACTOR_FLAG_TALK_OFFER_AUTO_ACCEPTED; @@ -1567,8 +1600,8 @@ void RandomizerOnVanillaBehaviorHandler(GIVanillaBehavior id, bool* should, va_l *should = false; break; } - // We need to override the vanilla behavior here because the player might sequence break and get Ruto kidnapped before accessing other - // checks that require Ruto. So if she's kidnapped we allow her to spawn again + // We need to override the vanilla behavior here because the player might sequence break and get Ruto kidnapped + // before accessing other checks that require Ruto. So if she's kidnapped we allow her to spawn again case VB_RUTO_BE_CONSIDERED_NOT_KIDNAPPED: { *should = !Flags_GetInfTable(INFTABLE_145) || Flags_GetInfTable(INFTABLE_146); break; @@ -1590,7 +1623,8 @@ void RandomizerOnVanillaBehaviorHandler(GIVanillaBehavior id, bool* should, va_l if (*should == true && RAND_GET_OPTION(RSK_SHUFFLE_ENTRANCES)) { // Check for dungeon special entrances that are randomized to a new location if (std::find(entrPersistTempFlags.begin(), entrPersistTempFlags.end(), originalEntrance) != - entrPersistTempFlags.end() && originalEntrance != gPlayState->nextEntranceIndex) { + entrPersistTempFlags.end() && + originalEntrance != gPlayState->nextEntranceIndex) { // Normally dungeons use a special voidout between scenes so that entering/exiting a boss room, // or leaving via Spirit Hands and going back in persist temp flags across scenes. // For ER, the temp flags should be wiped out so that they aren't transferred to the new location. @@ -1615,7 +1649,7 @@ void RandomizerOnVanillaBehaviorHandler(GIVanillaBehavior id, bool* should, va_l } case VB_HEISHI2_ACCEPT_ITEM_AS_ZELDAS_LETTER: { if (*should) { - //remove zelda's letter as this is the only use for it + // remove zelda's letter as this is the only use for it Flags_UnsetRandomizerInf(RAND_INF_CHILD_TRADES_HAS_LETTER_ZELDA); } break; @@ -1661,25 +1695,45 @@ void RandomizerOnSceneInitHandler(int16_t sceneNum) { // probably need to do something different when we implement shuffle if (sceneNum == SCENE_TREASURE_BOX_SHOP) { Flags_UnsetRandomizerInf(RAND_INF_MARKET_TREASURE_CHEST_GAME_ITEM_1); - Rando::Context::GetInstance()->GetItemLocation(RC_MARKET_TREASURE_CHEST_GAME_ITEM_1)->SetCheckStatus(RCSHOW_UNCHECKED); + Rando::Context::GetInstance() + ->GetItemLocation(RC_MARKET_TREASURE_CHEST_GAME_ITEM_1) + ->SetCheckStatus(RCSHOW_UNCHECKED); Flags_UnsetRandomizerInf(RAND_INF_MARKET_TREASURE_CHEST_GAME_ITEM_2); - Rando::Context::GetInstance()->GetItemLocation(RC_MARKET_TREASURE_CHEST_GAME_ITEM_2)->SetCheckStatus(RCSHOW_UNCHECKED); + Rando::Context::GetInstance() + ->GetItemLocation(RC_MARKET_TREASURE_CHEST_GAME_ITEM_2) + ->SetCheckStatus(RCSHOW_UNCHECKED); Flags_UnsetRandomizerInf(RAND_INF_MARKET_TREASURE_CHEST_GAME_ITEM_3); - Rando::Context::GetInstance()->GetItemLocation(RC_MARKET_TREASURE_CHEST_GAME_ITEM_3)->SetCheckStatus(RCSHOW_UNCHECKED); + Rando::Context::GetInstance() + ->GetItemLocation(RC_MARKET_TREASURE_CHEST_GAME_ITEM_3) + ->SetCheckStatus(RCSHOW_UNCHECKED); Flags_UnsetRandomizerInf(RAND_INF_MARKET_TREASURE_CHEST_GAME_ITEM_4); - Rando::Context::GetInstance()->GetItemLocation(RC_MARKET_TREASURE_CHEST_GAME_ITEM_4)->SetCheckStatus(RCSHOW_UNCHECKED); + Rando::Context::GetInstance() + ->GetItemLocation(RC_MARKET_TREASURE_CHEST_GAME_ITEM_4) + ->SetCheckStatus(RCSHOW_UNCHECKED); Flags_UnsetRandomizerInf(RAND_INF_MARKET_TREASURE_CHEST_GAME_ITEM_5); - Rando::Context::GetInstance()->GetItemLocation(RC_MARKET_TREASURE_CHEST_GAME_ITEM_5)->SetCheckStatus(RCSHOW_UNCHECKED); + Rando::Context::GetInstance() + ->GetItemLocation(RC_MARKET_TREASURE_CHEST_GAME_ITEM_5) + ->SetCheckStatus(RCSHOW_UNCHECKED); Flags_UnsetRandomizerInf(RAND_INF_MARKET_TREASURE_CHEST_GAME_KEY_1); - Rando::Context::GetInstance()->GetItemLocation(RC_MARKET_TREASURE_CHEST_GAME_KEY_1)->SetCheckStatus(RCSHOW_UNCHECKED); + Rando::Context::GetInstance() + ->GetItemLocation(RC_MARKET_TREASURE_CHEST_GAME_KEY_1) + ->SetCheckStatus(RCSHOW_UNCHECKED); Flags_UnsetRandomizerInf(RAND_INF_MARKET_TREASURE_CHEST_GAME_KEY_2); - Rando::Context::GetInstance()->GetItemLocation(RC_MARKET_TREASURE_CHEST_GAME_KEY_2)->SetCheckStatus(RCSHOW_UNCHECKED); + Rando::Context::GetInstance() + ->GetItemLocation(RC_MARKET_TREASURE_CHEST_GAME_KEY_2) + ->SetCheckStatus(RCSHOW_UNCHECKED); Flags_UnsetRandomizerInf(RAND_INF_MARKET_TREASURE_CHEST_GAME_KEY_3); - Rando::Context::GetInstance()->GetItemLocation(RC_MARKET_TREASURE_CHEST_GAME_KEY_3)->SetCheckStatus(RCSHOW_UNCHECKED); + Rando::Context::GetInstance() + ->GetItemLocation(RC_MARKET_TREASURE_CHEST_GAME_KEY_3) + ->SetCheckStatus(RCSHOW_UNCHECKED); Flags_UnsetRandomizerInf(RAND_INF_MARKET_TREASURE_CHEST_GAME_KEY_4); - Rando::Context::GetInstance()->GetItemLocation(RC_MARKET_TREASURE_CHEST_GAME_KEY_4)->SetCheckStatus(RCSHOW_UNCHECKED); + Rando::Context::GetInstance() + ->GetItemLocation(RC_MARKET_TREASURE_CHEST_GAME_KEY_4) + ->SetCheckStatus(RCSHOW_UNCHECKED); Flags_UnsetRandomizerInf(RAND_INF_MARKET_TREASURE_CHEST_GAME_KEY_5); - Rando::Context::GetInstance()->GetItemLocation(RC_MARKET_TREASURE_CHEST_GAME_KEY_5)->SetCheckStatus(RCSHOW_UNCHECKED); + Rando::Context::GetInstance() + ->GetItemLocation(RC_MARKET_TREASURE_CHEST_GAME_KEY_5) + ->SetCheckStatus(RCSHOW_UNCHECKED); CheckTracker::RecalculateAllAreaTotals(); } @@ -1714,17 +1768,16 @@ void RandomizerOnSceneInitHandler(int16_t sceneNum) { updateHook = 0; } - // If we're not in the Temple of Time or we've already learned the Prelude of Light and received LACs, we don't need to do anything - if ( - sceneNum != SCENE_TEMPLE_OF_TIME || - ( - Flags_GetEventChkInf(EVENTCHKINF_LEARNED_PRELUDE_OF_LIGHT) && - Flags_GetEventChkInf(EVENTCHKINF_RETURNED_TO_TEMPLE_OF_TIME_WITH_ALL_MEDALLIONS) - ) - ) return; + // If we're not in the Temple of Time or we've already learned the Prelude of Light and received LACs, we don't need + // to do anything + if (sceneNum != SCENE_TEMPLE_OF_TIME || + (Flags_GetEventChkInf(EVENTCHKINF_LEARNED_PRELUDE_OF_LIGHT) && + Flags_GetEventChkInf(EVENTCHKINF_RETURNED_TO_TEMPLE_OF_TIME_WITH_ALL_MEDALLIONS))) + return; updateHook = GameInteractor::Instance->RegisterGameHook([]() { - if (!Flags_GetEventChkInf(EVENTCHKINF_LEARNED_PRELUDE_OF_LIGHT) && LINK_IS_ADULT && CHECK_QUEST_ITEM(QUEST_MEDALLION_FOREST) && gPlayState->roomCtx.curRoom.num == 0) { + if (!Flags_GetEventChkInf(EVENTCHKINF_LEARNED_PRELUDE_OF_LIGHT) && LINK_IS_ADULT && + CHECK_QUEST_ITEM(QUEST_MEDALLION_FOREST) && gPlayState->roomCtx.curRoom.num == 0) { Flags_SetEventChkInf(EVENTCHKINF_LEARNED_PRELUDE_OF_LIGHT); } @@ -1733,11 +1786,10 @@ void RandomizerOnSceneInitHandler(int16_t sceneNum) { Flags_SetEventChkInf(EVENTCHKINF_RETURNED_TO_TEMPLE_OF_TIME_WITH_ALL_MEDALLIONS); } - // If both awards have been given, we can unregister the hook, otherwise it will get unregistered when the player leaves the area - if ( - Flags_GetEventChkInf(EVENTCHKINF_LEARNED_PRELUDE_OF_LIGHT) && - Flags_GetEventChkInf(EVENTCHKINF_RETURNED_TO_TEMPLE_OF_TIME_WITH_ALL_MEDALLIONS) - ) { + // If both awards have been given, we can unregister the hook, otherwise it will get unregistered when the + // player leaves the area + if (Flags_GetEventChkInf(EVENTCHKINF_LEARNED_PRELUDE_OF_LIGHT) && + Flags_GetEventChkInf(EVENTCHKINF_RETURNED_TO_TEMPLE_OF_TIME_WITH_ALL_MEDALLIONS)) { GameInteractor::Instance->UnregisterGameHook(updateHook); updateHook = 0; } @@ -1773,13 +1825,11 @@ void EnDns_RandomizerPurchase(EnDns* enDns) { void ObjComb_RandomizerChooseItemDrop(ObjComb* objComb, PlayState* play) { s16 params = objComb->actor.params & 0x1F; - if ( - RAND_GET_OPTION(RSK_SHUFFLE_BEEHIVES) && - !Flags_GetRandomizerInf(objComb->beehiveIdentity.randomizerInf) - ) { + if (RAND_GET_OPTION(RSK_SHUFFLE_BEEHIVES) && !Flags_GetRandomizerInf(objComb->beehiveIdentity.randomizerInf)) { EnItem00* item00 = (EnItem00*)Item_DropCollectible2(play, &objComb->actor.world.pos, ITEM00_SOH_DUMMY); item00->randoInf = objComb->beehiveIdentity.randomizerInf; - item00->itemEntry = OTRGlobals::Instance->gRandomizer->GetItemFromKnownCheck(objComb->beehiveIdentity.randomizerCheck, GI_NONE); + item00->itemEntry = + OTRGlobals::Instance->gRandomizer->GetItemFromKnownCheck(objComb->beehiveIdentity.randomizerCheck, GI_NONE); item00->actor.draw = (ActorFunc)EnItem00_DrawRandomizedItem; return; } @@ -1804,10 +1854,7 @@ void ObjComb_RandomizerWait(ObjComb* objComb, PlayState* play) { s32 dmgFlags; objComb->unk_1B0 -= 50; - if ( - RAND_GET_OPTION(RSK_SHUFFLE_BEEHIVES) && - !Flags_GetRandomizerInf(objComb->beehiveIdentity.randomizerInf) - ) { + if (RAND_GET_OPTION(RSK_SHUFFLE_BEEHIVES) && !Flags_GetRandomizerInf(objComb->beehiveIdentity.randomizerInf)) { if (objComb->unk_1B0 <= -5000) { objComb->unk_1B0 = 1500; } @@ -1831,17 +1878,19 @@ void ObjComb_RandomizerWait(ObjComb* objComb, PlayState* play) { if (objComb->actor.update != NULL) { CollisionCheck_SetOC(play, &play->colChkCtx, &objComb->collider.base); - } + } } void RandomizerOnActorInitHandler(void* actorRef) { Actor* actor = static_cast(actorRef); if (actor->id == ACTOR_EN_SI) { - RandomizerCheck rc = OTRGlobals::Instance->gRandomizer->GetCheckFromActor(actor->id, gPlayState->sceneNum, actor->params); + RandomizerCheck rc = + OTRGlobals::Instance->gRandomizer->GetCheckFromActor(actor->id, gPlayState->sceneNum, actor->params); if (rc != RC_UNKNOWN_CHECK) { EnSi* enSi = static_cast(actorRef); - enSi->sohGetItemEntry = Rando::Context::GetInstance()->GetFinalGIEntry(rc, true, (GetItemID)Rando::StaticData::GetLocation(rc)->GetVanillaItem()); + enSi->sohGetItemEntry = Rando::Context::GetInstance()->GetFinalGIEntry( + rc, true, (GetItemID)Rando::StaticData::GetLocation(rc)->GetVanillaItem()); actor->draw = (ActorFunc)EnSi_DrawRandomizedItem; } } @@ -1849,15 +1898,13 @@ void RandomizerOnActorInitHandler(void* actorRef) { if (actor->id == ACTOR_EN_DNS) { EnDns* enDns = static_cast(actorRef); s16 respawnData = gSaveContext.respawn[RESPAWN_MODE_RETURN].data & ((1 << 8) - 1); - enDns->sohScrubIdentity = OTRGlobals::Instance->gRandomizer->IdentifyScrub(gPlayState->sceneNum, enDns->actor.params, respawnData); + enDns->sohScrubIdentity = + OTRGlobals::Instance->gRandomizer->IdentifyScrub(gPlayState->sceneNum, enDns->actor.params, respawnData); if (enDns->sohScrubIdentity.isShuffled) { // DNS uses pointers so we're creating our own entry instead of modifying the original enDns->sohDnsItemEntry = { - enDns->dnsItemEntry->itemPrice, - 1, - enDns->sohScrubIdentity.getItemId, - EnDns_RandomizerPurchaseableCheck, + enDns->dnsItemEntry->itemPrice, 1, enDns->sohScrubIdentity.getItemId, EnDns_RandomizerPurchaseableCheck, EnDns_RandomizerPurchase, }; enDns->dnsItemEntry = &enDns->sohDnsItemEntry; @@ -1871,30 +1918,34 @@ void RandomizerOnActorInitHandler(void* actorRef) { static uint32_t enDnsUpdateHook = 0; static uint32_t enDnsKillHook = 0; if (!enDnsUpdateHook) { - enDnsUpdateHook = GameInteractor::Instance->RegisterGameHook([](void* innerActorRef) { - Actor* innerActor = static_cast(innerActorRef); - if (innerActor->id == ACTOR_EN_DNS) { - EnDns* innerEnDns = static_cast(innerActorRef); - if (innerEnDns->sohScrubIdentity.isShuffled) { - innerActor->textId = TEXT_SCRUB_RANDOM; + enDnsUpdateHook = + GameInteractor::Instance->RegisterGameHook([](void* innerActorRef) { + Actor* innerActor = static_cast(innerActorRef); + if (innerActor->id == ACTOR_EN_DNS) { + EnDns* innerEnDns = static_cast(innerActorRef); + if (innerEnDns->sohScrubIdentity.isShuffled) { + innerActor->textId = TEXT_SCRUB_RANDOM; + } } - } - }); - enDnsKillHook = GameInteractor::Instance->RegisterGameHook([](int16_t sceneNum) { - GameInteractor::Instance->UnregisterGameHook(enDnsUpdateHook); - GameInteractor::Instance->UnregisterGameHook(enDnsKillHook); - enDnsUpdateHook = 0; - enDnsKillHook = 0; - }); + }); + enDnsKillHook = + GameInteractor::Instance->RegisterGameHook([](int16_t sceneNum) { + GameInteractor::Instance->UnregisterGameHook(enDnsUpdateHook); + GameInteractor::Instance->UnregisterGameHook(enDnsKillHook); + enDnsUpdateHook = 0; + enDnsKillHook = 0; + }); } } } if (actor->id == ACTOR_ITEM_ETCETERA) { ItemEtcetera* itemEtcetera = static_cast(actorRef); - RandomizerCheck rc = OTRGlobals::Instance->gRandomizer->GetCheckFromActor(itemEtcetera->actor.id, gPlayState->sceneNum, itemEtcetera->actor.params); + RandomizerCheck rc = OTRGlobals::Instance->gRandomizer->GetCheckFromActor( + itemEtcetera->actor.id, gPlayState->sceneNum, itemEtcetera->actor.params); if (rc != RC_UNKNOWN_CHECK) { - itemEtcetera->sohItemEntry = Rando::Context::GetInstance()->GetFinalGIEntry(rc, true, (GetItemID)Rando::StaticData::GetLocation(rc)->GetVanillaItem()); + itemEtcetera->sohItemEntry = Rando::Context::GetInstance()->GetFinalGIEntry( + rc, true, (GetItemID)Rando::StaticData::GetLocation(rc)->GetVanillaItem()); itemEtcetera->drawFunc = (ActorFunc)ItemEtcetera_DrawRandomizedItem; } @@ -1925,13 +1976,14 @@ void RandomizerOnActorInitHandler(void* actorRef) { if (actor->id == ACTOR_OBJ_COMB) { ObjComb* objComb = static_cast(actorRef); s16 respawnData = gSaveContext.respawn[RESPAWN_MODE_RETURN].data & ((1 << 8) - 1); - objComb->beehiveIdentity = OTRGlobals::Instance->gRandomizer->IdentifyBeehive(gPlayState->sceneNum, (s16)actor->world.pos.x, respawnData); + objComb->beehiveIdentity = OTRGlobals::Instance->gRandomizer->IdentifyBeehive( + gPlayState->sceneNum, (s16)actor->world.pos.x, respawnData); objComb->actionFunc = (ObjCombActionFunc)ObjComb_RandomizerWait; } if (actor->id == ACTOR_EN_EX_ITEM) { EnExItem* enExItem = static_cast(actorRef); - + RandomizerCheck rc = RC_UNKNOWN_CHECK; switch (enExItem->type) { case EXITEM_BOMB_BAG_COUNTER: @@ -1944,14 +1996,16 @@ void RandomizerOnActorInitHandler(void* actorRef) { break; case EXITEM_BOMBCHUS_COUNTER: case EXITEM_BOMBCHUS_BOWLING: - //RC_MARKET_BOMBCHU_BOWLING_BOMBCHUS was removed as a 3DS holdover not in anyones near term plans due to being pretty useless. + // RC_MARKET_BOMBCHU_BOWLING_BOMBCHUS was removed as a 3DS holdover not in anyones near term plans due + // to being pretty useless. break; case EXITEM_BULLET_BAG: rc = RC_LW_TARGET_IN_WOODS; break; } if (rc != RC_UNKNOWN_CHECK) { - enExItem->sohItemEntry = Rando::Context::GetInstance()->GetFinalGIEntry(rc, true, (GetItemID)Rando::StaticData::GetLocation(rc)->GetVanillaItem()); + enExItem->sohItemEntry = Rando::Context::GetInstance()->GetFinalGIEntry( + rc, true, (GetItemID)Rando::StaticData::GetLocation(rc)->GetVanillaItem()); enExItem->actionFunc = (EnExItemActionFunc)EnExItem_WaitForObjectRandomized; } } @@ -1974,34 +2028,23 @@ void RandomizerOnActorInitHandler(void* actorRef) { if (actor->id == ACTOR_BG_TREEMOUTH && LINK_IS_ADULT && RAND_GET_OPTION(RSK_SHUFFLE_DUNGEON_ENTRANCES) != RO_DUNGEON_ENTRANCE_SHUFFLE_OFF && (RAND_GET_OPTION(RSK_FOREST) == RO_CLOSED_FOREST_OFF || - Flags_GetEventChkInf(EVENTCHKINF_SHOWED_MIDO_SWORD_SHIELD))) { + Flags_GetEventChkInf(EVENTCHKINF_SHOWED_MIDO_SWORD_SHIELD))) { BgTreemouth* bgTreemouth = static_cast(actorRef); bgTreemouth->unk_168 = 1.0f; } - //consumable bags - if ( - actor->id == ACTOR_EN_ITEM00 && - ( - ( - RAND_GET_OPTION(RSK_SHUFFLE_DEKU_STICK_BAG) && - CUR_UPG_VALUE(UPG_STICKS) == 0 && - actor->params == ITEM00_STICK - ) || - ( - RAND_GET_OPTION(RSK_SHUFFLE_DEKU_NUT_BAG) && - CUR_UPG_VALUE(UPG_NUTS) == 0 && - actor->params == ITEM00_NUTS - ) - ) - ) { + // consumable bags + if (actor->id == ACTOR_EN_ITEM00 && + ((RAND_GET_OPTION(RSK_SHUFFLE_DEKU_STICK_BAG) && CUR_UPG_VALUE(UPG_STICKS) == 0 && + actor->params == ITEM00_STICK) || + (RAND_GET_OPTION(RSK_SHUFFLE_DEKU_NUT_BAG) && CUR_UPG_VALUE(UPG_NUTS) == 0 && actor->params == ITEM00_NUTS))) { Actor_Kill(actor); } if (RAND_GET_OPTION(RSK_SHUFFLE_BOSS_SOULS)) { - //Boss souls require an additional item (represented by a RAND_INF) to spawn a boss in a particular lair + // Boss souls require an additional item (represented by a RAND_INF) to spawn a boss in a particular lair RandomizerInf currentBossSoulRandInf = RAND_INF_MAX; - switch (gPlayState->sceneNum){ + switch (gPlayState->sceneNum) { case SCENE_DEKU_TREE_BOSS: currentBossSoulRandInf = RAND_INF_GOHMA_SOUL; break; @@ -2037,16 +2080,16 @@ void RandomizerOnActorInitHandler(void* actorRef) { } // Deletes all actors in the boss category if the soul isn't found. - // Some actors, like Dark Link, Arwings, and Zora's Sapphire...?, are in this category despite not being actual bosses, - // so ignore any "boss" if `currentBossSoulRandInf` doesn't change from RAND_INF_MAX. - // Iron Knuckle (Nabooru) in Twinrova's room is a special exception, so exclude knuckles too. + // Some actors, like Dark Link, Arwings, and Zora's Sapphire...?, are in this category despite not being actual + // bosses, so ignore any "boss" if `currentBossSoulRandInf` doesn't change from RAND_INF_MAX. Iron Knuckle + // (Nabooru) in Twinrova's room is a special exception, so exclude knuckles too. if (currentBossSoulRandInf != RAND_INF_MAX) { if (!Flags_GetRandomizerInf(currentBossSoulRandInf) && actor->category == ACTORCAT_BOSS && actor->id != ACTOR_EN_IK) { Actor_Delete(&gPlayState->actorCtx, actor, gPlayState); } - //Special case for Phantom Ganon's horse (and fake), as they're considered "background actors", - //but still control the boss fight flow. + // Special case for Phantom Ganon's horse (and fake), as they're considered "background actors", + // but still control the boss fight flow. if (!Flags_GetRandomizerInf(RAND_INF_PHANTOM_GANON_SOUL) && actor->id == ACTOR_EN_FHG) { Actor_Delete(&gPlayState->actorCtx, actor, gPlayState); } @@ -2055,12 +2098,9 @@ void RandomizerOnActorInitHandler(void* actorRef) { // In MQ Spirit, remove the large silver block in the hole as child so the chest in the silver block hallway // can be guaranteed accessible - if ( - actor->id == ACTOR_OBJ_OSHIHIKI && - LINK_IS_CHILD && - ResourceMgr_IsGameMasterQuest() && + if (actor->id == ACTOR_OBJ_OSHIHIKI && LINK_IS_CHILD && ResourceMgr_IsGameMasterQuest() && gPlayState->sceneNum == SCENE_SPIRIT_TEMPLE && actor->room == 6 && // Spirit Temple silver block hallway - actor->params == 0x9C7 // Silver block that is marked as in the hole + actor->params == 0x9C7 // Silver block that is marked as in the hole ) { Actor_Kill(actor); return; @@ -2145,85 +2185,61 @@ void RandomizerOnActorUpdateHandler(void* refActor) { } // In ER, override the warp song locations. Also removes the warp song cutscene - if (RAND_GET_OPTION(RSK_SHUFFLE_ENTRANCES) && actor->id == ACTOR_DEMO_KANKYO && actor->params == 0x000F) { // Warp Song particles + if (RAND_GET_OPTION(RSK_SHUFFLE_ENTRANCES) && actor->id == ACTOR_DEMO_KANKYO && + actor->params == 0x000F) { // Warp Song particles Entrance_SetWarpSongEntrance(); } if (actor->id == ACTOR_OBJ_COMB) { ObjComb* combActor = reinterpret_cast(actor); - combActor->actor.shape.rot.x = Math_SinS(combActor->unk_1B2) * CLAMP_MIN(combActor->unk_1B0, 0) + combActor->actor.home.rot.x; + combActor->actor.shape.rot.x = + Math_SinS(combActor->unk_1B2) * CLAMP_MIN(combActor->unk_1B0, 0) + combActor->actor.home.rot.x; } } -//from z_player.c +// from z_player.c typedef struct { /* 0x00 */ Vec3f pos; /* 0x0C */ s16 yaw; } SpecialRespawnInfo; // size = 0x10 -//special respawns used when voided out without swim to prevent infinite loops +// special respawns used when voided out without swim to prevent infinite loops std::map swimSpecialRespawnInfo = { - { - ENTR_ZORAS_RIVER_3,//hf to zr in water - { { -1455.443, -20, 1384.826 }, 28761 } - }, - { - ENTR_HYRULE_FIELD_14,//zr to hf in water - { { 5730.209, -20, 3725.911 }, -20025 } - }, - { - ENTR_LOST_WOODS_UNDERWATER_SHORTCUT,//zr to lw - { { 1978.718, -36.908, -855 }, -16384 } - }, - { - ENTR_ZORAS_RIVER_UNDERWATER_SHORTCUT,//lw to zr - { { 4082.366, 860.442, -1018.949 }, -32768 } - }, - { - ENTR_LAKE_HYLIA_RIVER_EXIT,//gv to lh - { { -3276.416, -1033, 2908.421 }, 11228 } - }, - { - ENTR_WATER_TEMPLE_ENTRANCE,//lh to water temple - { { -182, 780, 759.5 }, -32768 } - }, - { - ENTR_LAKE_HYLIA_OUTSIDE_TEMPLE,//water temple to lh - { { -955.028, -1306.9, 6768.954 }, -32768 } - }, - { - ENTR_ZORAS_DOMAIN_UNDERWATER_SHORTCUT,//lh to zd - { { -109.86, 11.396, -9.933 }, -29131 } - }, - { - ENTR_LAKE_HYLIA_UNDERWATER_SHORTCUT,//zd to lh - { { -912, -1326.967, 3391 }, 0 } - }, - { - ENTR_GERUDO_VALLEY_1,//caught by gerudos as child - { { -424, -2051, -74 }, 16384 } - }, - { - ENTR_HYRULE_FIELD_ON_BRIDGE_SPAWN,//mk to hf (can be a problem when it then turns night) - { { 0, 0, 1100 }, 0 } - }, - { - ENTR_ZORAS_FOUNTAIN_JABU_JABU_BLUE_WARP,//jabu blue warp to zf - { { -1580, 150, 1670 }, 8000 } - }, + { ENTR_ZORAS_RIVER_3, // hf to zr in water + { { -1455.443, -20, 1384.826 }, 28761 } }, + { ENTR_HYRULE_FIELD_14, // zr to hf in water + { { 5730.209, -20, 3725.911 }, -20025 } }, + { ENTR_LOST_WOODS_UNDERWATER_SHORTCUT, // zr to lw + { { 1978.718, -36.908, -855 }, -16384 } }, + { ENTR_ZORAS_RIVER_UNDERWATER_SHORTCUT, // lw to zr + { { 4082.366, 860.442, -1018.949 }, -32768 } }, + { ENTR_LAKE_HYLIA_RIVER_EXIT, // gv to lh + { { -3276.416, -1033, 2908.421 }, 11228 } }, + { ENTR_WATER_TEMPLE_ENTRANCE, // lh to water temple + { { -182, 780, 759.5 }, -32768 } }, + { ENTR_LAKE_HYLIA_OUTSIDE_TEMPLE, // water temple to lh + { { -955.028, -1306.9, 6768.954 }, -32768 } }, + { ENTR_ZORAS_DOMAIN_UNDERWATER_SHORTCUT, // lh to zd + { { -109.86, 11.396, -9.933 }, -29131 } }, + { ENTR_LAKE_HYLIA_UNDERWATER_SHORTCUT, // zd to lh + { { -912, -1326.967, 3391 }, 0 } }, + { ENTR_GERUDO_VALLEY_1, // caught by gerudos as child + { { -424, -2051, -74 }, 16384 } }, + { ENTR_HYRULE_FIELD_ON_BRIDGE_SPAWN, // mk to hf (can be a problem when it then turns night) + { { 0, 0, 1100 }, 0 } }, + { ENTR_ZORAS_FOUNTAIN_JABU_JABU_BLUE_WARP, // jabu blue warp to zf + { { -1580, 150, 1670 }, 8000 } }, }; f32 triforcePieceScale; void RandomizerOnPlayerUpdateHandler() { - if ( - (GET_PLAYER(gPlayState)->stateFlags1 & PLAYER_STATE1_IN_WATER) && - !Flags_GetRandomizerInf(RAND_INF_CAN_SWIM) && - CUR_EQUIP_VALUE(EQUIP_TYPE_BOOTS) != EQUIP_VALUE_BOOTS_IRON - ) { - //if you void out in water temple without swim you get instantly kicked out to prevent softlocks + if ((GET_PLAYER(gPlayState)->stateFlags1 & PLAYER_STATE1_IN_WATER) && !Flags_GetRandomizerInf(RAND_INF_CAN_SWIM) && + CUR_EQUIP_VALUE(EQUIP_TYPE_BOOTS) != EQUIP_VALUE_BOOTS_IRON) { + // if you void out in water temple without swim you get instantly kicked out to prevent softlocks if (gPlayState->sceneNum == SCENE_WATER_TEMPLE) { - GameInteractor::RawAction::TeleportPlayer(Entrance_OverrideNextIndex(ENTR_LAKE_HYLIA_OUTSIDE_TEMPLE));//lake hylia from water temple + GameInteractor::RawAction::TeleportPlayer( + Entrance_OverrideNextIndex(ENTR_LAKE_HYLIA_OUTSIDE_TEMPLE)); // lake hylia from water temple } else { if (swimSpecialRespawnInfo.find(gSaveContext.entranceIndex) != swimSpecialRespawnInfo.end()) { SpecialRespawnInfo* respawnInfo = &swimSpecialRespawnInfo.at(gSaveContext.entranceIndex); @@ -2238,19 +2254,14 @@ void RandomizerOnPlayerUpdateHandler() { } // Triforce Hunt needs the check if the player isn't being teleported to the credits scene. - if ( - !GameInteractor::IsGameplayPaused() && - Flags_GetRandomizerInf(RAND_INF_GRANT_GANONS_BOSSKEY) && + if (!GameInteractor::IsGameplayPaused() && Flags_GetRandomizerInf(RAND_INF_GRANT_GANONS_BOSSKEY) && gPlayState->transitionTrigger != TRANS_TRIGGER_START && - (1 << 0 & gSaveContext.inventory.dungeonItems[SCENE_GANONS_TOWER]) == 0 - ) { - GiveItemEntryWithoutActor(gPlayState, *Rando::StaticData::GetItemTable().at(RG_GANONS_CASTLE_BOSS_KEY).GetGIEntry()); + (1 << 0 & gSaveContext.inventory.dungeonItems[SCENE_GANONS_TOWER]) == 0) { + GiveItemEntryWithoutActor(gPlayState, + *Rando::StaticData::GetItemTable().at(RG_GANONS_CASTLE_BOSS_KEY).GetGIEntry()); } - if ( - !GameInteractor::IsGameplayPaused() && - RAND_GET_OPTION(RSK_TRIFORCE_HUNT) - ) { + if (!GameInteractor::IsGameplayPaused() && RAND_GET_OPTION(RSK_TRIFORCE_HUNT)) { // Warp to credits if (GameInteractor::State::TriforceHuntCreditsWarpActive) { gPlayState->nextEntranceIndex = ENTR_CHAMBER_OF_THE_SAGES_0; @@ -2277,12 +2288,14 @@ void RandomizerOnSceneSpawnActorsHandler() { switch (gPlayState->sceneNum) { case SCENE_TEMPLE_OF_TIME: if (gPlayState->roomCtx.curRoom.num == 1) { - Actor_Spawn(&gPlayState->actorCtx, gPlayState, ACTOR_EN_XC, -104, -40, 2382, 0, 0x8000, 0, SHEIK_TYPE_RANDO, false); + Actor_Spawn(&gPlayState->actorCtx, gPlayState, ACTOR_EN_XC, -104, -40, 2382, 0, 0x8000, 0, + SHEIK_TYPE_RANDO, false); } break; case SCENE_INSIDE_GANONS_CASTLE: if (gPlayState->roomCtx.curRoom.num == 1) { - Actor_Spawn(&gPlayState->actorCtx, gPlayState, ACTOR_EN_XC, 101, 150, 137, 0, 0, 0, SHEIK_TYPE_RANDO, false); + Actor_Spawn(&gPlayState->actorCtx, gPlayState, ACTOR_EN_XC, 101, 150, 137, 0, 0, 0, + SHEIK_TYPE_RANDO, false); } break; default: @@ -2387,13 +2400,16 @@ void RandomizerRegisterHooks() { GameInteractor::Instance->UnregisterGameHook(fishsanityOnActorInitHook); GameInteractor::Instance->UnregisterGameHook(fishsanityOnActorUpdateHook); GameInteractor::Instance->UnregisterGameHook(fishsanityOnSceneInitHook); - GameInteractor::Instance->UnregisterGameHook(fishsanityOnVanillaBehaviorHook); + GameInteractor::Instance->UnregisterGameHook( + fishsanityOnVanillaBehaviorHook); GameInteractor::Instance->UnregisterGameHook(fishsanityOnItemReceiveHook); GameInteractor::Instance->UnregisterGameHookForID(shufflePotsOnActorInitHook); - GameInteractor::Instance->UnregisterGameHook(shufflePotsOnVanillaBehaviorHook); + GameInteractor::Instance->UnregisterGameHook( + shufflePotsOnVanillaBehaviorHook); - GameInteractor::Instance->UnregisterGameHook(shuffleFreestandingOnVanillaBehaviorHook); + GameInteractor::Instance->UnregisterGameHook( + shuffleFreestandingOnVanillaBehaviorHook); onFlagSetHook = 0; onSceneFlagSetHook = 0; @@ -2426,7 +2442,8 @@ void RandomizerRegisterHooks() { ShuffleFairies_UnregisterHooks(); - if (!IS_RANDO) return; + if (!IS_RANDO) + return; // ENTRTODO: Move all entrance rando handling to a dedicated file // Setup the modified entrance table and entrance shuffle table for rando @@ -2437,43 +2454,71 @@ void RandomizerRegisterHooks() { Entrance_SetSavewarpEntrance(); } - onFlagSetHook = GameInteractor::Instance->RegisterGameHook(RandomizerOnFlagSetHandler); - onSceneFlagSetHook = GameInteractor::Instance->RegisterGameHook(RandomizerOnSceneFlagSetHandler); - onPlayerUpdateForRCQueueHook = GameInteractor::Instance->RegisterGameHook(RandomizerOnPlayerUpdateForRCQueueHandler); - onPlayerUpdateForItemQueueHook = GameInteractor::Instance->RegisterGameHook(RandomizerOnPlayerUpdateForItemQueueHandler); - onItemReceiveHook = GameInteractor::Instance->RegisterGameHook(RandomizerOnItemReceiveHandler); - onDialogMessageHook = GameInteractor::Instance->RegisterGameHook(RandomizerOnDialogMessageHandler); - onVanillaBehaviorHook = GameInteractor::Instance->RegisterGameHook(RandomizerOnVanillaBehaviorHandler); - onSceneInitHook = GameInteractor::Instance->RegisterGameHook(RandomizerOnSceneInitHandler); - onActorInitHook = GameInteractor::Instance->RegisterGameHook(RandomizerOnActorInitHandler); - onActorUpdateHook = GameInteractor::Instance->RegisterGameHook(RandomizerOnActorUpdateHandler); - onPlayerUpdateHook = GameInteractor::Instance->RegisterGameHook(RandomizerOnPlayerUpdateHandler); - onGameFrameUpdateHook = GameInteractor::Instance->RegisterGameHook(RandomizerOnGameFrameUpdateHandler); - onSceneSpawnActorsHook = GameInteractor::Instance->RegisterGameHook(RandomizerOnSceneSpawnActorsHandler); - onPlayDestroyHook = GameInteractor::Instance->RegisterGameHook(RandomizerOnPlayDestroyHandler); - onExitGameHook = GameInteractor::Instance->RegisterGameHook(RandomizerOnExitGameHandler); - onKaleidoUpdateHook = GameInteractor::Instance->RegisterGameHook(RandomizerOnKaleidoscopeUpdateHandler); - onCuccoOrChickenHatchHook = GameInteractor::Instance->RegisterGameHook(RandomizerOnCuccoOrChickenHatch); + onFlagSetHook = + GameInteractor::Instance->RegisterGameHook(RandomizerOnFlagSetHandler); + onSceneFlagSetHook = + GameInteractor::Instance->RegisterGameHook(RandomizerOnSceneFlagSetHandler); + onPlayerUpdateForRCQueueHook = GameInteractor::Instance->RegisterGameHook( + RandomizerOnPlayerUpdateForRCQueueHandler); + onPlayerUpdateForItemQueueHook = GameInteractor::Instance->RegisterGameHook( + RandomizerOnPlayerUpdateForItemQueueHandler); + onItemReceiveHook = + GameInteractor::Instance->RegisterGameHook(RandomizerOnItemReceiveHandler); + onDialogMessageHook = GameInteractor::Instance->RegisterGameHook( + RandomizerOnDialogMessageHandler); + onVanillaBehaviorHook = GameInteractor::Instance->RegisterGameHook( + RandomizerOnVanillaBehaviorHandler); + onSceneInitHook = + GameInteractor::Instance->RegisterGameHook(RandomizerOnSceneInitHandler); + onActorInitHook = + GameInteractor::Instance->RegisterGameHook(RandomizerOnActorInitHandler); + onActorUpdateHook = + GameInteractor::Instance->RegisterGameHook(RandomizerOnActorUpdateHandler); + onPlayerUpdateHook = + GameInteractor::Instance->RegisterGameHook(RandomizerOnPlayerUpdateHandler); + onGameFrameUpdateHook = GameInteractor::Instance->RegisterGameHook( + RandomizerOnGameFrameUpdateHandler); + onSceneSpawnActorsHook = GameInteractor::Instance->RegisterGameHook( + RandomizerOnSceneSpawnActorsHandler); + onPlayDestroyHook = + GameInteractor::Instance->RegisterGameHook(RandomizerOnPlayDestroyHandler); + onExitGameHook = + GameInteractor::Instance->RegisterGameHook(RandomizerOnExitGameHandler); + onKaleidoUpdateHook = GameInteractor::Instance->RegisterGameHook( + RandomizerOnKaleidoscopeUpdateHandler); + onCuccoOrChickenHatchHook = GameInteractor::Instance->RegisterGameHook( + RandomizerOnCuccoOrChickenHatch); if (RAND_GET_OPTION(RSK_FISHSANITY) != RO_FISHSANITY_OFF) { OTRGlobals::Instance->gRandoContext->GetFishsanity()->InitializeFromSave(); - fishsanityOnActorInitHook = GameInteractor::Instance->RegisterGameHook(Rando::Fishsanity::OnActorInitHandler); - fishsanityOnActorUpdateHook = GameInteractor::Instance->RegisterGameHook(Rando::Fishsanity::OnActorUpdateHandler); - fishsanityOnSceneInitHook = GameInteractor::Instance->RegisterGameHook(Rando::Fishsanity::OnSceneInitHandler); - fishsanityOnVanillaBehaviorHook = GameInteractor::Instance->RegisterGameHook(Rando::Fishsanity::OnVanillaBehaviorHandler); - fishsanityOnItemReceiveHook = GameInteractor::Instance->RegisterGameHook(Rando::Fishsanity::OnItemReceiveHandler); + fishsanityOnActorInitHook = GameInteractor::Instance->RegisterGameHook( + Rando::Fishsanity::OnActorInitHandler); + fishsanityOnActorUpdateHook = GameInteractor::Instance->RegisterGameHook( + Rando::Fishsanity::OnActorUpdateHandler); + fishsanityOnSceneInitHook = GameInteractor::Instance->RegisterGameHook( + Rando::Fishsanity::OnSceneInitHandler); + fishsanityOnVanillaBehaviorHook = + GameInteractor::Instance->RegisterGameHook( + Rando::Fishsanity::OnVanillaBehaviorHandler); + fishsanityOnItemReceiveHook = GameInteractor::Instance->RegisterGameHook( + Rando::Fishsanity::OnItemReceiveHandler); } if (RAND_GET_OPTION(RSK_SHUFFLE_POTS) != RO_SHUFFLE_POTS_OFF) { - shufflePotsOnActorInitHook = GameInteractor::Instance->RegisterGameHookForID(ACTOR_OBJ_TSUBO, ObjTsubo_RandomizerInit); - shufflePotsOnVanillaBehaviorHook = GameInteractor::Instance->RegisterGameHook(ShufflePots_OnVanillaBehaviorHandler); + shufflePotsOnActorInitHook = GameInteractor::Instance->RegisterGameHookForID( + ACTOR_OBJ_TSUBO, ObjTsubo_RandomizerInit); + shufflePotsOnVanillaBehaviorHook = + GameInteractor::Instance->RegisterGameHook( + ShufflePots_OnVanillaBehaviorHandler); } if (RAND_GET_OPTION(RSK_SHUFFLE_FREESTANDING) != RO_SHUFFLE_FREESTANDING_OFF) { - shuffleFreestandingOnVanillaBehaviorHook = GameInteractor::Instance->RegisterGameHook(ShuffleFreestanding_OnVanillaBehaviorHandler); + shuffleFreestandingOnVanillaBehaviorHook = + GameInteractor::Instance->RegisterGameHook( + ShuffleFreestanding_OnVanillaBehaviorHandler); } - + if (RAND_GET_OPTION(RSK_SHUFFLE_FAIRIES)) { ShuffleFairies_RegisterHooks(); } diff --git a/soh/soh/Enhancements/randomizer/item.cpp b/soh/soh/Enhancements/randomizer/item.cpp index 1c315b47f..ee0dc9403 100644 --- a/soh/soh/Enhancements/randomizer/item.cpp +++ b/soh/soh/Enhancements/randomizer/item.cpp @@ -11,31 +11,38 @@ #include "../../OTRGlobals.h" namespace Rando { -Item::Item() : randomizerGet(RG_NONE), type(ITEMTYPE_ITEM), getItemId(GI_NONE), advancement(false), hintKey(RHT_NONE), - progressive(false), price(0) {} +Item::Item() + : randomizerGet(RG_NONE), type(ITEMTYPE_ITEM), getItemId(GI_NONE), advancement(false), hintKey(RHT_NONE), + progressive(false), price(0) { +} Item::Item(const RandomizerGet randomizerGet_, Text name_, const ItemType type_, const int16_t getItemId_, - const bool advancement_, LogicVal logicVal_, const RandomizerHintTextKey hintKey_, const uint16_t itemId_, - const uint16_t objectId_, const uint16_t gid_, const uint16_t textId_, const uint16_t field_, - const int16_t chestAnimation_, const GetItemCategory category_, const uint16_t modIndex_, - const bool progressive_, const uint16_t price_) + const bool advancement_, LogicVal logicVal_, const RandomizerHintTextKey hintKey_, const uint16_t itemId_, + const uint16_t objectId_, const uint16_t gid_, const uint16_t textId_, const uint16_t field_, + const int16_t chestAnimation_, const GetItemCategory category_, const uint16_t modIndex_, + const bool progressive_, const uint16_t price_) : randomizerGet(randomizerGet_), name(std::move(name_)), type(type_), getItemId(getItemId_), - advancement(advancement_), logicVal(logicVal_), hintKey(hintKey_), progressive(progressive_), price(price_) { + advancement(advancement_), logicVal(logicVal_), hintKey(hintKey_), progressive(progressive_), price(price_) { if (modIndex_ == MOD_RANDOMIZER || getItemId > 0x7D) { - giEntry = std::make_shared(GetItemEntry{ itemId_, field_, static_cast((chestAnimation_ != CHEST_ANIM_SHORT ? 1 : -1) * (gid_ + 1)), textId_, objectId_, modIndex_, TABLE_RANDOMIZER, static_cast(randomizerGet_), gid_, true, ITEM_FROM_NPC, category_, static_cast(randomizerGet_), MOD_RANDOMIZER, NULL }); - } - else { - giEntry = std::make_shared(GetItemEntry{ itemId_, field_, static_cast((chestAnimation_ != CHEST_ANIM_SHORT ? 1 : -1) * (gid_ + 1)), textId_, objectId_, modIndex_, TABLE_VANILLA, getItemId_, gid_, true, ITEM_FROM_NPC, category_, itemId_, modIndex_, NULL }); + giEntry = std::make_shared(GetItemEntry{ + itemId_, field_, static_cast((chestAnimation_ != CHEST_ANIM_SHORT ? 1 : -1) * (gid_ + 1)), textId_, + objectId_, modIndex_, TABLE_RANDOMIZER, static_cast(randomizerGet_), gid_, true, ITEM_FROM_NPC, + category_, static_cast(randomizerGet_), MOD_RANDOMIZER, NULL }); + } else { + giEntry = std::make_shared(GetItemEntry{ + itemId_, field_, static_cast((chestAnimation_ != CHEST_ANIM_SHORT ? 1 : -1) * (gid_ + 1)), textId_, + objectId_, modIndex_, TABLE_VANILLA, getItemId_, gid_, true, ITEM_FROM_NPC, category_, itemId_, modIndex_, + NULL }); } } Item::Item(const RandomizerGet randomizerGet_, Text name_, const ItemType type_, const int16_t getItemId_, - const bool advancement_, LogicVal logicVal_, const RandomizerHintTextKey hintKey_, const bool progressive_, - const uint16_t price_) + const bool advancement_, LogicVal logicVal_, const RandomizerHintTextKey hintKey_, const bool progressive_, + const uint16_t price_) : randomizerGet(randomizerGet_), name(std::move(name_)), type(type_), getItemId(getItemId_), - advancement(advancement_), logicVal(logicVal_), hintKey(hintKey_), progressive(progressive_), price(price_) { + advancement(advancement_), logicVal(logicVal_), hintKey(hintKey_), progressive(progressive_), price(price_) { } - Item::~Item() = default; +Item::~Item() = default; void Item::ApplyEffect() const { auto ctx = Rando::Context::GetInstance(); @@ -283,11 +290,11 @@ std::shared_ptr Item::GetGIEntry() const { // NOLINT(*-no-recursio actual = RG_GIANT_WALLET; break; case 2: - if(tycoonWallet){ + if (tycoonWallet) { actual = RG_TYCOON_WALLET; break; } - //fallthrough + // fallthrough case 3: case 4: if (infiniteUpgrades != RO_INF_UPGRADES_OFF) { @@ -338,8 +345,8 @@ std::shared_ptr Item::GetGIEntry() const { // NOLINT(*-no-recursio } break; case RG_PROGRESSIVE_GORONSWORD: // todo progressive? - actual = RG_BIGGORON_SWORD; - break; + actual = RG_BIGGORON_SWORD; + break; case RG_PROGRESSIVE_BOMBCHUS: if (logic->CurrentInventory(ITEM_BOMBCHU) == ITEM_NONE) { actual = RG_BOMBCHU_BAG; @@ -393,7 +400,8 @@ bool Item::IsMajorItem() const { return false; } - if (type == ITEMTYPE_DUNGEONREWARD && ctx->GetOption(RSK_SHUFFLE_DUNGEON_REWARDS).Is(RO_DUNGEON_REWARDS_END_OF_DUNGEON)) { + if (type == ITEMTYPE_DUNGEONREWARD && + ctx->GetOption(RSK_SHUFFLE_DUNGEON_REWARDS).Is(RO_DUNGEON_REWARDS_END_OF_DUNGEON)) { return false; } @@ -407,7 +415,8 @@ bool Item::IsMajorItem() const { return false; } - if (type == ITEMTYPE_SMALLKEY && (ctx->GetOption(RSK_KEYSANITY).Is(RO_DUNGEON_ITEM_LOC_VANILLA) || ctx->GetOption(RSK_KEYSANITY).Is(RO_DUNGEON_ITEM_LOC_OWN_DUNGEON))) { + if (type == ITEMTYPE_SMALLKEY && (ctx->GetOption(RSK_KEYSANITY).Is(RO_DUNGEON_ITEM_LOC_VANILLA) || + ctx->GetOption(RSK_KEYSANITY).Is(RO_DUNGEON_ITEM_LOC_OWN_DUNGEON))) { return false; } @@ -416,11 +425,13 @@ bool Item::IsMajorItem() const { } if (type == ITEMTYPE_BOSSKEY && getItemId != 0xAD && - (ctx->GetOption(RSK_BOSS_KEYSANITY).Is(RO_DUNGEON_ITEM_LOC_VANILLA) || ctx->GetOption(RSK_BOSS_KEYSANITY).Is(RO_DUNGEON_ITEM_LOC_OWN_DUNGEON))) { + (ctx->GetOption(RSK_BOSS_KEYSANITY).Is(RO_DUNGEON_ITEM_LOC_VANILLA) || + ctx->GetOption(RSK_BOSS_KEYSANITY).Is(RO_DUNGEON_ITEM_LOC_OWN_DUNGEON))) { return false; } // Ganons Castle Boss Key - if (getItemId == 0xAD && (ctx->GetOption(RSK_GANONS_BOSS_KEY).Is(RO_GANON_BOSS_KEY_VANILLA) || ctx->GetOption(RSK_GANONS_BOSS_KEY).Is(RO_GANON_BOSS_KEY_OWN_DUNGEON))) { + if (getItemId == 0xAD && (ctx->GetOption(RSK_GANONS_BOSS_KEY).Is(RO_GANON_BOSS_KEY_VANILLA) || + ctx->GetOption(RSK_GANONS_BOSS_KEY).Is(RO_GANON_BOSS_KEY_OWN_DUNGEON))) { return false; } @@ -446,4 +457,4 @@ bool Item::operator==(const Item& right) const { bool Item::operator!=(const Item& right) const { return !operator==(right); } -} +} // namespace Rando diff --git a/soh/soh/Enhancements/randomizer/item.h b/soh/soh/Enhancements/randomizer/item.h index f0df0f1bf..da8632151 100644 --- a/soh/soh/Enhancements/randomizer/item.h +++ b/soh/soh/Enhancements/randomizer/item.h @@ -31,17 +31,16 @@ class Item { public: Item(); Item(RandomizerGet randomizerGet_, Text name_, ItemType type_, int16_t getItemId_, bool advancement_, - LogicVal logicVal_, RandomizerHintTextKey hintKey_, uint16_t itemId_, uint16_t objectId_, uint16_t gid_, - uint16_t textId_, uint16_t field_, int16_t chestAnimation_, GetItemCategory category_, uint16_t modIndex_, - bool progressive_ = false, uint16_t price_ = 0); + LogicVal logicVal_, RandomizerHintTextKey hintKey_, uint16_t itemId_, uint16_t objectId_, uint16_t gid_, + uint16_t textId_, uint16_t field_, int16_t chestAnimation_, GetItemCategory category_, uint16_t modIndex_, + bool progressive_ = false, uint16_t price_ = 0); Item(RandomizerGet randomizerGet_, Text name_, ItemType type_, int16_t getItemId_, bool advancement_, - LogicVal logicVal_, RandomizerHintTextKey hintKey_, bool progressive_ = false, uint16_t price_ = 0); + LogicVal logicVal_, RandomizerHintTextKey hintKey_, bool progressive_ = false, uint16_t price_ = 0); ~Item(); void ApplyEffect() const; void UndoEffect() const; - const Text& GetName() const; bool IsAdvancement() const; int GetItemID() const; @@ -75,4 +74,4 @@ class Item { bool playthrough = false; std::shared_ptr giEntry; }; -} +} // namespace Rando diff --git a/soh/soh/Enhancements/randomizer/item_location.cpp b/soh/soh/Enhancements/randomizer/item_location.cpp index cfdfb4204..f7587ec5e 100644 --- a/soh/soh/Enhancements/randomizer/item_location.cpp +++ b/soh/soh/Enhancements/randomizer/item_location.cpp @@ -3,8 +3,10 @@ #include "logic.h" namespace Rando { -ItemLocation::ItemLocation() : rc(RC_UNKNOWN_CHECK) {} -ItemLocation::ItemLocation(const RandomizerCheck rc_) : rc(rc_) {} +ItemLocation::ItemLocation() : rc(RC_UNKNOWN_CHECK) { +} +ItemLocation::ItemLocation(const RandomizerCheck rc_) : rc(rc_) { +} RandomizerCheck ItemLocation::GetRandomizerCheck() const { return rc; @@ -40,14 +42,14 @@ RandomizerGet ItemLocation::GetPlacedRandomizerGet() const { void ItemLocation::SetPlacedItem(const RandomizerGet item) { placedItem = item; - SetPrice (StaticData::RetrieveItem(placedItem).GetPrice()); + SetPrice(StaticData::RetrieveItem(placedItem).GetPrice()); } void ItemLocation::SetDelayedItem(const RandomizerGet item) { delayedItem = item; } -void ItemLocation::SaveDelayedItem () { +void ItemLocation::SaveDelayedItem() { placedItem = delayedItem; delayedItem = RG_NONE; } @@ -56,15 +58,16 @@ void ItemLocation::SetParentRegion(const RandomizerRegion region) { parentRegion = region; } -//RANDOTODO only used in tracker now, could possibly be removed +// RANDOTODO only used in tracker now, could possibly be removed RandomizerRegion ItemLocation::GetParentRegionKey() const { return parentRegion; } void ItemLocation::MergeAreas(std::set newAreas) { areas.merge(newAreas); - if (areas.size() >= 2){ - //if we have more than 1 area, remove any RA_NONE as that's not a real area. can happen if an entrance is in 2 regions and 1 is disconnected + if (areas.size() >= 2) { + // if we have more than 1 area, remove any RA_NONE as that's not a real area. can happen if an entrance is in 2 + // regions and 1 is disconnected areas.erase(RA_NONE); } } @@ -74,7 +77,7 @@ std::set ItemLocation::GetAreas() const { } RandomizerArea ItemLocation::GetFirstArea() const { - if (areas.empty()){ + if (areas.empty()) { assert(false); return RA_NONE; } else { @@ -83,7 +86,7 @@ RandomizerArea ItemLocation::GetFirstArea() const { } RandomizerArea ItemLocation::GetRandomArea() const { - if (areas.empty()){ + if (areas.empty()) { SPDLOG_DEBUG("Attempted to get random area of location with no areas: "); SPDLOG_DEBUG(Rando::StaticData::GetLocation(rc)->GetName()); assert(false); @@ -102,7 +105,7 @@ void ItemLocation::ApplyPlacedItemEffect() const { } uint16_t ItemLocation::GetPrice() const { - //RANDOTODO if we ever change price of shop items, this needs replacing with proper price assignment in Fill + // RANDOTODO if we ever change price of shop items, this needs replacing with proper price assignment in Fill if (StaticData::RetrieveItem(placedItem).GetItemType() == ITEMTYPE_SHOP) { return StaticData::RetrieveItem(placedItem).GetPrice(); } @@ -167,7 +170,7 @@ const std::vector& ItemLocation::GetHintedBy() const { void ItemLocation::AddHintedBy(const RandomizerHint hintKey) { hintedBy.push_back(hintKey); -} +} bool ItemLocation::IsHidden() const { return hidden; @@ -194,7 +197,6 @@ bool ItemLocation::IsVisible() const { } void ItemLocation::SetVisible(const bool visibleInImGui_) { visibleInImGui = visibleInImGui_; - } bool ItemLocation::IsWothCandidate() const { @@ -238,4 +240,4 @@ bool ItemLocation::IsAvailable() const { void ItemLocation::SetAvailable(bool isAvailable_) { isAvailable = isAvailable_; } -} \ No newline at end of file +} // namespace Rando \ No newline at end of file diff --git a/soh/soh/Enhancements/randomizer/item_location.h b/soh/soh/Enhancements/randomizer/item_location.h index e60d358eb..a04f5c2cf 100644 --- a/soh/soh/Enhancements/randomizer/item_location.h +++ b/soh/soh/Enhancements/randomizer/item_location.h @@ -21,11 +21,11 @@ class ItemLocation { RandomizerGet& RefPlacedItem(); void SetDelayedItem(RandomizerGet item); RandomizerRegion GetParentRegionKey() const; - void SetParentRegion (RandomizerRegion region); + void SetParentRegion(RandomizerRegion region); std::set GetAreas() const; RandomizerArea GetFirstArea() const; RandomizerArea GetRandomArea() const; - void MergeAreas (std::set newAreas); + void MergeAreas(std::set newAreas); void PlaceVanillaItem(); void ApplyPlacedItemEffect() const; void SaveDelayedItem(); diff --git a/soh/soh/Enhancements/randomizer/item_override.cpp b/soh/soh/Enhancements/randomizer/item_override.cpp index 58789c579..cc25c8836 100644 --- a/soh/soh/Enhancements/randomizer/item_override.cpp +++ b/soh/soh/Enhancements/randomizer/item_override.cpp @@ -3,9 +3,11 @@ #include namespace Rando { -ItemOverride::ItemOverride() : mLocation(RC_UNKNOWN_CHECK), mLooksLike(RG_NONE) {} +ItemOverride::ItemOverride() : mLocation(RC_UNKNOWN_CHECK), mLooksLike(RG_NONE) { +} ItemOverride::ItemOverride(const RandomizerCheck location, const RandomizerGet looksLike) - : mLocation(location), mLooksLike(looksLike) {} + : mLocation(location), mLooksLike(looksLike) { +} RandomizerCheck ItemOverride::GetLocation() const { return mLocation; diff --git a/soh/soh/Enhancements/randomizer/item_override.h b/soh/soh/Enhancements/randomizer/item_override.h index 98a1f3d42..355d1e51e 100644 --- a/soh/soh/Enhancements/randomizer/item_override.h +++ b/soh/soh/Enhancements/randomizer/item_override.h @@ -14,7 +14,8 @@ class ItemOverride { RandomizerGet LooksLike() const; RandomizerGet& RefLooksLike(); Text& GetTrickName(); - void SetTrickName (Text trickName); + void SetTrickName(Text trickName); + private: RandomizerCheck mLocation; RandomizerGet mLooksLike; diff --git a/soh/soh/Enhancements/randomizer/location.cpp b/soh/soh/Enhancements/randomizer/location.cpp index 9ac4cabfd..f474397aa 100644 --- a/soh/soh/Enhancements/randomizer/location.cpp +++ b/soh/soh/Enhancements/randomizer/location.cpp @@ -252,173 +252,339 @@ RandomizerCheckArea GetAreaFromScene(uint8_t scene) { } } - -Rando::Location Rando::Location::Base(RandomizerCheck rc, RandomizerCheckQuest quest_, RandomizerCheckType checkType_, ActorID actorId_, SceneID scene_, int32_t actorParams_, - std::string&& shortName_, std::string&& spoilerName_, const RandomizerHintTextKey hintKey, const RandomizerGet vanillaItem, - SpoilerCollectionCheck collectionCheck, bool isVanillaCompletion_, uint16_t vanillaPrice_) { - return { rc, quest_, checkType_, GetAreaFromScene(scene_), actorId_, scene_, actorParams_, std::move(shortName_), std::move(spoilerName_), hintKey, vanillaItem, - isVanillaCompletion_, collectionCheck, vanillaPrice_ }; -} - -Rando::Location Rando::Location::Base(RandomizerCheck rc, RandomizerCheckQuest quest_, RandomizerCheckType checkType_, RandomizerCheckArea area_, ActorID actorId_, SceneID scene_, - int32_t actorParams_, std::string&& shortName_, std::string&& spoilerName_, const RandomizerHintTextKey hintKey, const RandomizerGet vanillaItem, - SpoilerCollectionCheck collectionCheck, bool isVanillaCompletion_, uint16_t vanillaPrice_) { - return { rc, quest_, checkType_, area_, actorId_, scene_, actorParams_, std::move(shortName_), std::move(spoilerName_), hintKey, vanillaItem, isVanillaCompletion_, collectionCheck, vanillaPrice_ }; -} - -Rando::Location Rando::Location::Base(RandomizerCheck rc, RandomizerCheckQuest quest_, RandomizerCheckType checkType_, ActorID actorId_, SceneID scene_, int32_t actorParams_, - std::string&& shortName_, const RandomizerHintTextKey hintKey, const RandomizerGet vanillaItem, SpoilerCollectionCheck collectionCheck, +Rando::Location Rando::Location::Base(RandomizerCheck rc, RandomizerCheckQuest quest_, RandomizerCheckType checkType_, + ActorID actorId_, SceneID scene_, int32_t actorParams_, std::string&& shortName_, + std::string&& spoilerName_, const RandomizerHintTextKey hintKey, + const RandomizerGet vanillaItem, SpoilerCollectionCheck collectionCheck, bool isVanillaCompletion_, uint16_t vanillaPrice_) { - return { rc, quest_, checkType_, GetAreaFromScene(scene_), actorId_, scene_, actorParams_, std::move(shortName_), hintKey, vanillaItem, isVanillaCompletion_, collectionCheck , vanillaPrice_ }; + return { rc, + quest_, + checkType_, + GetAreaFromScene(scene_), + actorId_, + scene_, + actorParams_, + std::move(shortName_), + std::move(spoilerName_), + hintKey, + vanillaItem, + isVanillaCompletion_, + collectionCheck, + vanillaPrice_ }; } -Rando::Location Rando::Location::Base(RandomizerCheck rc, RandomizerCheckQuest quest_, RandomizerCheckType checkType_, RandomizerCheckArea area_, ActorID actorId_, SceneID scene_, - int32_t actorParams_, std::string&& shortName_, const RandomizerHintTextKey hintKey, const RandomizerGet vanillaItem, - SpoilerCollectionCheck collectionCheck, bool isVanillaCompletion_, uint16_t vanillaPrice_) { - return { rc, quest_, checkType_, area_, actorId_, scene_, actorParams_, std::move(shortName_), hintKey, vanillaItem, isVanillaCompletion_, collectionCheck, vanillaPrice_ }; +Rando::Location Rando::Location::Base(RandomizerCheck rc, RandomizerCheckQuest quest_, RandomizerCheckType checkType_, + RandomizerCheckArea area_, ActorID actorId_, SceneID scene_, int32_t actorParams_, + std::string&& shortName_, std::string&& spoilerName_, + const RandomizerHintTextKey hintKey, const RandomizerGet vanillaItem, + SpoilerCollectionCheck collectionCheck, bool isVanillaCompletion_, + uint16_t vanillaPrice_) { + return { rc, + quest_, + checkType_, + area_, + actorId_, + scene_, + actorParams_, + std::move(shortName_), + std::move(spoilerName_), + hintKey, + vanillaItem, + isVanillaCompletion_, + collectionCheck, + vanillaPrice_ }; } -Rando::Location Rando::Location::Chest(RandomizerCheck rc, RandomizerCheckQuest quest_, RandomizerCheckType checkType_, ActorID actorId_, SceneID scene_, int32_t actorParams_, - uint8_t flag_, std::string&& shortName_, const RandomizerHintTextKey hintKey, const RandomizerGet vanillaItem, bool isVanillaCompletion_) { - return { rc, quest_, checkType_, GetAreaFromScene(scene_), actorId_, scene_, actorParams_, std::move(shortName_), hintKey, vanillaItem, isVanillaCompletion_, - SpoilerCollectionCheck(SPOILER_CHK_CHEST, scene_, flag_) }; +Rando::Location Rando::Location::Base(RandomizerCheck rc, RandomizerCheckQuest quest_, RandomizerCheckType checkType_, + ActorID actorId_, SceneID scene_, int32_t actorParams_, std::string&& shortName_, + const RandomizerHintTextKey hintKey, const RandomizerGet vanillaItem, + SpoilerCollectionCheck collectionCheck, bool isVanillaCompletion_, + uint16_t vanillaPrice_) { + return { rc, quest_, checkType_, GetAreaFromScene(scene_), + actorId_, scene_, actorParams_, std::move(shortName_), + hintKey, vanillaItem, isVanillaCompletion_, collectionCheck, + vanillaPrice_ }; } -Rando::Location Rando::Location::Chest(RandomizerCheck rc, RandomizerCheckQuest quest_, RandomizerCheckType checkType_, RandomizerCheckArea area_, ActorID actorId_, SceneID scene_, - int32_t actorParams_, uint8_t flag_, std::string&& shortName_, const RandomizerHintTextKey hintKey, const RandomizerGet vanillaItem, +Rando::Location Rando::Location::Base(RandomizerCheck rc, RandomizerCheckQuest quest_, RandomizerCheckType checkType_, + RandomizerCheckArea area_, ActorID actorId_, SceneID scene_, int32_t actorParams_, + std::string&& shortName_, const RandomizerHintTextKey hintKey, + const RandomizerGet vanillaItem, SpoilerCollectionCheck collectionCheck, + bool isVanillaCompletion_, uint16_t vanillaPrice_) { + return { rc, quest_, checkType_, area_, + actorId_, scene_, actorParams_, std::move(shortName_), + hintKey, vanillaItem, isVanillaCompletion_, collectionCheck, + vanillaPrice_ }; +} + +Rando::Location Rando::Location::Chest(RandomizerCheck rc, RandomizerCheckQuest quest_, RandomizerCheckType checkType_, + ActorID actorId_, SceneID scene_, int32_t actorParams_, uint8_t flag_, + std::string&& shortName_, const RandomizerHintTextKey hintKey, + const RandomizerGet vanillaItem, bool isVanillaCompletion_) { + return { rc, quest_, checkType_, GetAreaFromScene(scene_), + actorId_, scene_, actorParams_, std::move(shortName_), + hintKey, vanillaItem, isVanillaCompletion_, SpoilerCollectionCheck(SPOILER_CHK_CHEST, scene_, flag_) }; +} + +Rando::Location Rando::Location::Chest(RandomizerCheck rc, RandomizerCheckQuest quest_, RandomizerCheckType checkType_, + RandomizerCheckArea area_, ActorID actorId_, SceneID scene_, + int32_t actorParams_, uint8_t flag_, std::string&& shortName_, + const RandomizerHintTextKey hintKey, const RandomizerGet vanillaItem, bool isVanillaCompletion_) { - return { rc, quest_, checkType_, area_, actorId_, scene_, actorParams_, std::move(shortName_), hintKey, vanillaItem, isVanillaCompletion_, - SpoilerCollectionCheck(SPOILER_CHK_CHEST, scene_, flag_) }; + return { rc, quest_, checkType_, area_, + actorId_, scene_, actorParams_, std::move(shortName_), + hintKey, vanillaItem, isVanillaCompletion_, SpoilerCollectionCheck(SPOILER_CHK_CHEST, scene_, flag_) }; } -Rando::Location Rando::Location::Chest(RandomizerCheck rc, RandomizerCheckQuest quest_, RandomizerCheckType checkType_, ActorID actorId_, SceneID scene_, int32_t actorParams_, - std::string&& shortName_, const RandomizerHintTextKey hintKey, const RandomizerGet vanillaItem, SpoilerCollectionCheck collectionCheck, - bool isVanillaCompletion_) { - return { rc, quest_, checkType_, GetAreaFromScene(scene_), actorId_, scene_, actorParams_, std::move(shortName_), hintKey, vanillaItem, isVanillaCompletion_, collectionCheck }; -} - -Rando::Location Rando::Location::Chest(RandomizerCheck rc, RandomizerCheckQuest quest_, RandomizerCheckType checkType_, RandomizerCheckArea area_, ActorID actorId_, SceneID scene_, - int32_t actorParams_, std::string&& shortName_, const RandomizerHintTextKey hintKey, const RandomizerGet vanillaItem, +Rando::Location Rando::Location::Chest(RandomizerCheck rc, RandomizerCheckQuest quest_, RandomizerCheckType checkType_, + ActorID actorId_, SceneID scene_, int32_t actorParams_, std::string&& shortName_, + const RandomizerHintTextKey hintKey, const RandomizerGet vanillaItem, SpoilerCollectionCheck collectionCheck, bool isVanillaCompletion_) { - return { rc, quest_, checkType_, area_, actorId_, scene_, actorParams_, std::move(shortName_), hintKey, vanillaItem, isVanillaCompletion_, collectionCheck }; + return { rc, quest_, checkType_, GetAreaFromScene(scene_), + actorId_, scene_, actorParams_, std::move(shortName_), + hintKey, vanillaItem, isVanillaCompletion_, collectionCheck }; } -Rando::Location Rando::Location::Collectable(RandomizerCheck rc, RandomizerCheckQuest quest_, RandomizerCheckType checkType_, ActorID actorId_, SceneID scene_, int32_t actorParams_, - uint8_t flag_, std::string&& shortName_, const RandomizerHintTextKey hintKey, const RandomizerGet vanillaItem, bool isVanillaCompletion_) { - return { rc, quest_, checkType_, GetAreaFromScene(scene_), actorId_, scene_, actorParams_, std::move(shortName_), hintKey, vanillaItem, isVanillaCompletion_, - SpoilerCollectionCheck(SPOILER_CHK_COLLECTABLE, scene_, flag_) }; +Rando::Location Rando::Location::Chest(RandomizerCheck rc, RandomizerCheckQuest quest_, RandomizerCheckType checkType_, + RandomizerCheckArea area_, ActorID actorId_, SceneID scene_, + int32_t actorParams_, std::string&& shortName_, + const RandomizerHintTextKey hintKey, const RandomizerGet vanillaItem, + SpoilerCollectionCheck collectionCheck, bool isVanillaCompletion_) { + return { rc, quest_, checkType_, area_, + actorId_, scene_, actorParams_, std::move(shortName_), + hintKey, vanillaItem, isVanillaCompletion_, collectionCheck }; } -Rando::Location Rando::Location::Collectable(RandomizerCheck rc, RandomizerCheckQuest quest_, RandomizerCheckType checkType_, RandomizerCheckArea area_, ActorID actorId_, SceneID scene_, - int32_t actorParams_, uint8_t flag_, std::string&& shortName_, const RandomizerHintTextKey hintKey, const RandomizerGet vanillaItem, +Rando::Location Rando::Location::Collectable(RandomizerCheck rc, RandomizerCheckQuest quest_, + RandomizerCheckType checkType_, ActorID actorId_, SceneID scene_, + int32_t actorParams_, uint8_t flag_, std::string&& shortName_, + const RandomizerHintTextKey hintKey, const RandomizerGet vanillaItem, bool isVanillaCompletion_) { - return { rc, quest_, checkType_, area_, actorId_, scene_, actorParams_, std::move(shortName_), hintKey, vanillaItem, isVanillaCompletion_, - SpoilerCollectionCheck(SPOILER_CHK_COLLECTABLE, scene_, flag_) }; + return { + rc, quest_, checkType_, GetAreaFromScene(scene_), + actorId_, scene_, actorParams_, std::move(shortName_), + hintKey, vanillaItem, isVanillaCompletion_, SpoilerCollectionCheck(SPOILER_CHK_COLLECTABLE, scene_, flag_) + }; } -Rando::Location Rando::Location::Collectable(RandomizerCheck rc, RandomizerCheckQuest quest_, RandomizerCheckType checkType_, ActorID actorId_, SceneID scene_, int32_t actorParams_, - std::string&& shortName_, const RandomizerHintTextKey hintKey, const RandomizerGet vanillaItem, SpoilerCollectionCheck collectionCheck, - bool isVanillaCompletion_) { - return { rc, quest_, checkType_, GetAreaFromScene(scene_), actorId_, scene_, actorParams_, std::move(shortName_), hintKey, vanillaItem, isVanillaCompletion_, collectionCheck }; +Rando::Location Rando::Location::Collectable(RandomizerCheck rc, RandomizerCheckQuest quest_, + RandomizerCheckType checkType_, RandomizerCheckArea area_, + ActorID actorId_, SceneID scene_, int32_t actorParams_, uint8_t flag_, + std::string&& shortName_, const RandomizerHintTextKey hintKey, + const RandomizerGet vanillaItem, bool isVanillaCompletion_) { + return { + rc, quest_, checkType_, area_, + actorId_, scene_, actorParams_, std::move(shortName_), + hintKey, vanillaItem, isVanillaCompletion_, SpoilerCollectionCheck(SPOILER_CHK_COLLECTABLE, scene_, flag_) + }; } -Rando::Location Rando::Location::Collectable(RandomizerCheck rc, RandomizerCheckQuest quest_, RandomizerCheckType checkType_, RandomizerCheckArea area_, ActorID actorId_, SceneID scene_, - int32_t actorParams_, std::string&& shortName_, const RandomizerHintTextKey hintKey, const RandomizerGet vanillaItem, +Rando::Location Rando::Location::Collectable(RandomizerCheck rc, RandomizerCheckQuest quest_, + RandomizerCheckType checkType_, ActorID actorId_, SceneID scene_, + int32_t actorParams_, std::string&& shortName_, + const RandomizerHintTextKey hintKey, const RandomizerGet vanillaItem, SpoilerCollectionCheck collectionCheck, bool isVanillaCompletion_) { - return { rc, quest_, checkType_, area_, actorId_, scene_, actorParams_, std::move(shortName_), hintKey, vanillaItem, isVanillaCompletion_, collectionCheck }; + return { rc, quest_, checkType_, GetAreaFromScene(scene_), + actorId_, scene_, actorParams_, std::move(shortName_), + hintKey, vanillaItem, isVanillaCompletion_, collectionCheck }; } -Rando::Location Rando::Location::GSToken(RandomizerCheck rc, RandomizerCheckQuest quest_, SceneID scene_, int32_t actorParams_, uint8_t flag_, std::string&& shortName_, +Rando::Location Rando::Location::Collectable(RandomizerCheck rc, RandomizerCheckQuest quest_, + RandomizerCheckType checkType_, RandomizerCheckArea area_, + ActorID actorId_, SceneID scene_, int32_t actorParams_, + std::string&& shortName_, const RandomizerHintTextKey hintKey, + const RandomizerGet vanillaItem, SpoilerCollectionCheck collectionCheck, + bool isVanillaCompletion_) { + return { rc, quest_, checkType_, area_, + actorId_, scene_, actorParams_, std::move(shortName_), + hintKey, vanillaItem, isVanillaCompletion_, collectionCheck }; +} + +Rando::Location Rando::Location::GSToken(RandomizerCheck rc, RandomizerCheckQuest quest_, SceneID scene_, + int32_t actorParams_, uint8_t flag_, std::string&& shortName_, const RandomizerHintTextKey hintKey) { - return { rc, quest_, RCTYPE_SKULL_TOKEN, GetAreaFromScene(scene_), ACTOR_EN_SI, scene_, actorParams_, std::move(shortName_), hintKey, RG_GOLD_SKULLTULA_TOKEN, true, - SpoilerCollectionCheck(SPOILER_CHK_GOLD_SKULLTULA, scene_, flag_) }; + return { rc, + quest_, + RCTYPE_SKULL_TOKEN, + GetAreaFromScene(scene_), + ACTOR_EN_SI, + scene_, + actorParams_, + std::move(shortName_), + hintKey, + RG_GOLD_SKULLTULA_TOKEN, + true, + SpoilerCollectionCheck(SPOILER_CHK_GOLD_SKULLTULA, scene_, flag_) }; } -Rando::Location Rando::Location::GSToken(RandomizerCheck rc, RandomizerCheckQuest quest_, SceneID scene_, int32_t actorParams_, uint8_t flag_, std::string&& shortName_, +Rando::Location Rando::Location::GSToken(RandomizerCheck rc, RandomizerCheckQuest quest_, SceneID scene_, + int32_t actorParams_, uint8_t flag_, std::string&& shortName_, const RandomizerHintTextKey hintKey, const uint8_t skullScene_) { - return { rc, quest_, RCTYPE_SKULL_TOKEN, GetAreaFromScene(scene_), ACTOR_EN_SI, scene_, actorParams_, std::move(shortName_), hintKey, RG_GOLD_SKULLTULA_TOKEN, true, - SpoilerCollectionCheck(SPOILER_CHK_GOLD_SKULLTULA, skullScene_, flag_) }; + return { rc, + quest_, + RCTYPE_SKULL_TOKEN, + GetAreaFromScene(scene_), + ACTOR_EN_SI, + scene_, + actorParams_, + std::move(shortName_), + hintKey, + RG_GOLD_SKULLTULA_TOKEN, + true, + SpoilerCollectionCheck(SPOILER_CHK_GOLD_SKULLTULA, skullScene_, flag_) }; } -Rando::Location Rando::Location::GSToken(RandomizerCheck rc, RandomizerCheckQuest quest_, RandomizerCheckArea area_, SceneID scene_, int32_t actorParams_, uint8_t flag_, - std::string&& shortName_, const RandomizerHintTextKey hintKey, const uint8_t skullScene_) { - return { rc, quest_, RCTYPE_SKULL_TOKEN, area_, ACTOR_EN_SI, scene_, actorParams_, std::move(shortName_), hintKey, RG_GOLD_SKULLTULA_TOKEN, true, - SpoilerCollectionCheck(SPOILER_CHK_GOLD_SKULLTULA, skullScene_, flag_) }; +Rando::Location Rando::Location::GSToken(RandomizerCheck rc, RandomizerCheckQuest quest_, RandomizerCheckArea area_, + SceneID scene_, int32_t actorParams_, uint8_t flag_, std::string&& shortName_, + const RandomizerHintTextKey hintKey, const uint8_t skullScene_) { + return { rc, + quest_, + RCTYPE_SKULL_TOKEN, + area_, + ACTOR_EN_SI, + scene_, + actorParams_, + std::move(shortName_), + hintKey, + RG_GOLD_SKULLTULA_TOKEN, + true, + SpoilerCollectionCheck(SPOILER_CHK_GOLD_SKULLTULA, skullScene_, flag_) }; } -Rando::Location Rando::Location::OtherHint(RandomizerCheck rc, RandomizerCheckQuest quest_, RandomizerCheckArea area_, ActorID actorId_, SceneID scene_, std::string&& shortName_, +Rando::Location Rando::Location::OtherHint(RandomizerCheck rc, RandomizerCheckQuest quest_, RandomizerCheckArea area_, + ActorID actorId_, SceneID scene_, std::string&& shortName_, std::string&& spoilerName_) { - return { rc, quest_, RCTYPE_STATIC_HINT, area_, actorId_, scene_, 0x00, std::move(shortName_), std::move(spoilerName_), RHT_NONE, RG_NONE, false }; + return { rc, + quest_, + RCTYPE_STATIC_HINT, + area_, + actorId_, + scene_, + 0x00, + std::move(shortName_), + std::move(spoilerName_), + RHT_NONE, + RG_NONE, + false }; } -Rando::Location Rando::Location::OtherHint(RandomizerCheck rc, RandomizerCheckQuest quest_, ActorID actorId_, SceneID scene_, std::string&& shortName_) { - return { rc, quest_, RCTYPE_STATIC_HINT, GetAreaFromScene(scene_), actorId_, scene_, 0x00, std::move(shortName_), RHT_NONE, RG_NONE, false }; +Rando::Location Rando::Location::OtherHint(RandomizerCheck rc, RandomizerCheckQuest quest_, ActorID actorId_, + SceneID scene_, std::string&& shortName_) { + return { rc, + quest_, + RCTYPE_STATIC_HINT, + GetAreaFromScene(scene_), + actorId_, + scene_, + 0x00, + std::move(shortName_), + RHT_NONE, + RG_NONE, + false }; } -Rando::Location Rando::Location::OtherHint(RandomizerCheck rc, RandomizerCheckQuest quest_, RandomizerCheckArea area_, ActorID actorId_, SceneID scene_, std::string&& shortName_) { - return { rc, quest_, RCTYPE_STATIC_HINT, area_, actorId_, scene_, 0x00, std::move(shortName_), RHT_NONE, RG_NONE, false }; +Rando::Location Rando::Location::OtherHint(RandomizerCheck rc, RandomizerCheckQuest quest_, RandomizerCheckArea area_, + ActorID actorId_, SceneID scene_, std::string&& shortName_) { + return { rc, quest_, RCTYPE_STATIC_HINT, area_, actorId_, scene_, 0x00, std::move(shortName_), RHT_NONE, + RG_NONE, false }; } -Rando::Location Rando::Location::HintStone(RandomizerCheck rc, RandomizerCheckQuest quest_, SceneID scene_, int32_t actorParams_, std::string&& shortName_) { - return { rc, quest_, RCTYPE_GOSSIP_STONE, GetAreaFromScene(scene_), ACTOR_EN_GS, scene_, actorParams_, std::move(shortName_), RHT_NONE, RG_NONE, false }; +Rando::Location Rando::Location::HintStone(RandomizerCheck rc, RandomizerCheckQuest quest_, SceneID scene_, + int32_t actorParams_, std::string&& shortName_) { + return { rc, + quest_, + RCTYPE_GOSSIP_STONE, + GetAreaFromScene(scene_), + ACTOR_EN_GS, + scene_, + actorParams_, + std::move(shortName_), + RHT_NONE, + RG_NONE, + false }; } -Rando::Location Rando::Location::Fish(RandomizerCheck rc, RandomizerCheckQuest quest_, ActorID actorId_, SceneID scene_, int32_t actorParams_, RandomizerInf flag_, - std::string&& shortName_, RandomizerHintTextKey hintKey, RandomizerGet vanillaItem) { - return {rc, quest_, RCTYPE_FISH, GetAreaFromScene(scene_), actorId_, scene_, actorParams_, std::move(shortName_), hintKey, vanillaItem, false, - SpoilerCollectionCheck(SPOILER_CHK_RANDOMIZER_INF, scene_, flag_)}; +Rando::Location Rando::Location::Fish(RandomizerCheck rc, RandomizerCheckQuest quest_, ActorID actorId_, SceneID scene_, + int32_t actorParams_, RandomizerInf flag_, std::string&& shortName_, + RandomizerHintTextKey hintKey, RandomizerGet vanillaItem) { + return { rc, quest_, RCTYPE_FISH, GetAreaFromScene(scene_), + actorId_, scene_, actorParams_, std::move(shortName_), + hintKey, vanillaItem, false, SpoilerCollectionCheck(SPOILER_CHK_RANDOMIZER_INF, scene_, flag_) }; } -Rando::Location Rando::Location::GrottoFish(RandomizerCheck rc, RandomizerCheckQuest quest_, RandomizerCheckArea area_, int32_t actorParams_, RandomizerInf flag_, - std::string&& shortName_, RandomizerHintTextKey hintKey) { - return {rc, quest_, RCTYPE_FISH, area_, ACTOR_EN_FISH, SCENE_GROTTOS, actorParams_, std::move(shortName_), hintKey, RG_FISH, false, - SpoilerCollectionCheck(SPOILER_CHK_RANDOMIZER_INF, SCENE_GROTTOS, flag_)}; +Rando::Location Rando::Location::GrottoFish(RandomizerCheck rc, RandomizerCheckQuest quest_, RandomizerCheckArea area_, + int32_t actorParams_, RandomizerInf flag_, std::string&& shortName_, + RandomizerHintTextKey hintKey) { + return { rc, + quest_, + RCTYPE_FISH, + area_, + ACTOR_EN_FISH, + SCENE_GROTTOS, + actorParams_, + std::move(shortName_), + hintKey, + RG_FISH, + false, + SpoilerCollectionCheck(SPOILER_CHK_RANDOMIZER_INF, SCENE_GROTTOS, flag_) }; } Rando::Location Rando::Location::Pot(RandomizerCheck rc, RandomizerCheckQuest quest_, RandomizerCheckArea area_, - SceneID scene_, int32_t actorParams_, std::string&& shortName_, RandomizerHintTextKey hintKey, - RandomizerGet vanillaItem, SpoilerCollectionCheck collectionCheck) { - return {rc, quest_, RCTYPE_POT, area_, ACTOR_OBJ_TSUBO, scene_, actorParams_, std::move(shortName_), hintKey, vanillaItem, false, - collectionCheck }; + SceneID scene_, int32_t actorParams_, std::string&& shortName_, + RandomizerHintTextKey hintKey, RandomizerGet vanillaItem, + SpoilerCollectionCheck collectionCheck) { + return { + rc, quest_, RCTYPE_POT, area_, ACTOR_OBJ_TSUBO, scene_, actorParams_, std::move(shortName_), + hintKey, vanillaItem, false, collectionCheck + }; } Rando::Location Rando::Location::Crate(RandomizerCheck rc, RandomizerCheckQuest quest_, RandomizerCheckArea area_, - SceneID scene_, int32_t actorParams_, std::string&& shortName_, - RandomizerHintTextKey hintKey, - RandomizerGet vanillaItem, SpoilerCollectionCheck collectionCheck) { - return {rc, quest_, RCTYPE_CRATE, area_, ACTOR_OBJ_KIBAKO2, scene_, actorParams_, std::move(shortName_), hintKey, vanillaItem, false, - collectionCheck }; + SceneID scene_, int32_t actorParams_, std::string&& shortName_, + RandomizerHintTextKey hintKey, RandomizerGet vanillaItem, + SpoilerCollectionCheck collectionCheck) { + return { rc, quest_, RCTYPE_CRATE, area_, ACTOR_OBJ_KIBAKO2, + scene_, actorParams_, std::move(shortName_), hintKey, vanillaItem, + false, collectionCheck }; } Rando::Location Rando::Location::NLCrate(RandomizerCheck rc, RandomizerCheckQuest quest_, RandomizerCheckArea area_, - SceneID scene_, int32_t actorParams_, std::string&& shortName_, - RandomizerHintTextKey hintKey, - RandomizerGet vanillaItem, SpoilerCollectionCheck collectionCheck) { - return {rc, quest_, RCTYPE_NLCRATE, area_, ACTOR_OBJ_KIBAKO2, scene_, actorParams_, std::move(shortName_), hintKey, vanillaItem, false, - collectionCheck }; + SceneID scene_, int32_t actorParams_, std::string&& shortName_, + RandomizerHintTextKey hintKey, RandomizerGet vanillaItem, + SpoilerCollectionCheck collectionCheck) { + return { rc, quest_, RCTYPE_NLCRATE, area_, ACTOR_OBJ_KIBAKO2, + scene_, actorParams_, std::move(shortName_), hintKey, vanillaItem, + false, collectionCheck }; } Rando::Location Rando::Location::SmallCrate(RandomizerCheck rc, RandomizerCheckQuest quest_, RandomizerCheckArea area_, - SceneID scene_, int32_t actorParams_, std::string&& shortName_, - RandomizerHintTextKey hintKey, - RandomizerGet vanillaItem, SpoilerCollectionCheck collectionCheck) { - return {rc, quest_, RCTYPE_SMALL_CRATE, area_, ACTOR_OBJ_KIBAKO, scene_, actorParams_, std::move(shortName_), hintKey, vanillaItem, false, - collectionCheck }; + SceneID scene_, int32_t actorParams_, std::string&& shortName_, + RandomizerHintTextKey hintKey, RandomizerGet vanillaItem, + SpoilerCollectionCheck collectionCheck) { + return { rc, quest_, RCTYPE_SMALL_CRATE, area_, ACTOR_OBJ_KIBAKO, + scene_, actorParams_, std::move(shortName_), hintKey, vanillaItem, + false, collectionCheck }; } -Rando::Location Rando::Location::HintStone(RandomizerCheck rc, RandomizerCheckQuest quest_, RandomizerCheckArea area_, SceneID scene_, int32_t actorParams_, std::string&& shortName_) { - return { rc, quest_, RCTYPE_GOSSIP_STONE, area_, ACTOR_EN_GS, scene_, actorParams_, std::move(shortName_), RHT_NONE, RG_NONE, false }; +Rando::Location Rando::Location::HintStone(RandomizerCheck rc, RandomizerCheckQuest quest_, RandomizerCheckArea area_, + SceneID scene_, int32_t actorParams_, std::string&& shortName_) { + return { rc, quest_, RCTYPE_GOSSIP_STONE, area_, ACTOR_EN_GS, + scene_, actorParams_, std::move(shortName_), RHT_NONE, RG_NONE, + false }; } -Rando::Location Rando::Location::Fairy(RandomizerCheck rc, RandomizerCheckQuest quest_, - RandomizerCheckArea area_, SceneID scene_, - int32_t actorParams_, std::string&& shortName_, - RandomizerHintTextKey hintKey, SpoilerCollectionCheck collectionCheck) { - return {rc, quest_, RCTYPE_FAIRY, area_, ACTOR_EN_ELF, scene_, actorParams_, std::move(shortName_), hintKey, RG_NONE, false, collectionCheck}; +Rando::Location Rando::Location::Fairy(RandomizerCheck rc, RandomizerCheckQuest quest_, RandomizerCheckArea area_, + SceneID scene_, int32_t actorParams_, std::string&& shortName_, + RandomizerHintTextKey hintKey, SpoilerCollectionCheck collectionCheck) { + return { rc, quest_, RCTYPE_FAIRY, area_, ACTOR_EN_ELF, scene_, actorParams_, std::move(shortName_), + hintKey, RG_NONE, false, collectionCheck }; } Rando::Location Rando::Location::Grass(RandomizerCheck rc, RandomizerCheckQuest quest_, RandomizerCheckArea area_, - SceneID scene_, int32_t actorParams_, std::string&& shortName_, RandomizerHintTextKey hintKey, - RandomizerGet vanillaItem, SpoilerCollectionCheck collectionCheck) { - return { rc, quest_, RCTYPE_GRASS, area_, ACTOR_EN_KUSA, scene_, actorParams_, std::move(shortName_), hintKey, vanillaItem, false, collectionCheck }; + SceneID scene_, int32_t actorParams_, std::string&& shortName_, + RandomizerHintTextKey hintKey, RandomizerGet vanillaItem, + SpoilerCollectionCheck collectionCheck) { + return { rc, quest_, RCTYPE_GRASS, area_, ACTOR_EN_KUSA, + scene_, actorParams_, std::move(shortName_), hintKey, vanillaItem, + false, collectionCheck }; } diff --git a/soh/soh/Enhancements/randomizer/location.h b/soh/soh/Enhancements/randomizer/location.h index 1043cb3c5..f99499652 100644 --- a/soh/soh/Enhancements/randomizer/location.h +++ b/soh/soh/Enhancements/randomizer/location.h @@ -20,7 +20,9 @@ class SpoilerCollectionCheck { uint16_t flag = 0; SpoilerCollectionCheck() = default; - SpoilerCollectionCheck(const SpoilerCollectionCheckType type_, const uint8_t scene_, const uint16_t flag_) : type(type_), scene(scene_), flag(flag_) {} + SpoilerCollectionCheck(const SpoilerCollectionCheckType type_, const uint8_t scene_, const uint16_t flag_) + : type(type_), scene(scene_), flag(flag_) { + } static auto ItemGetInf(const uint8_t slot) { return SpoilerCollectionCheck(SPOILER_CHK_ITEM_GET_INF, 0x00, slot); @@ -49,46 +51,52 @@ class SpoilerCollectionCheck { class Location { public: - //RANDOTODO fix wacky ordering - Location() : rc(RC_UNKNOWN_CHECK), quest(RCQUEST_BOTH), checkType(RCTYPE_STANDARD), area(RCAREA_INVALID), actorId(ACTOR_ID_MAX), scene(SCENE_ID_MAX), actorParams(0), - hintKey(RHT_NONE), vanillaItem(RG_NONE), isVanillaCompletion(false), collectionCheck(SpoilerCollectionCheck()) {} + // RANDOTODO fix wacky ordering + Location() + : rc(RC_UNKNOWN_CHECK), quest(RCQUEST_BOTH), checkType(RCTYPE_STANDARD), area(RCAREA_INVALID), + actorId(ACTOR_ID_MAX), scene(SCENE_ID_MAX), actorParams(0), hintKey(RHT_NONE), vanillaItem(RG_NONE), + isVanillaCompletion(false), collectionCheck(SpoilerCollectionCheck()) { + } - Location(const RandomizerCheck rc_, const RandomizerCheckQuest quest_, const RandomizerCheckType checkType_, const RandomizerCheckArea area_, const ActorID actorId_, - const SceneID scene_, const int32_t actorParams_, std::string shortName_, std::string spoilerName_, const RandomizerHintTextKey hintKey_, - const RandomizerGet vanillaItem_, const bool isVanillaCompletion_ = false, const SpoilerCollectionCheck collectionCheck_ = SpoilerCollectionCheck(), - const int vanillaPrice_ = 0) - : rc(rc_), quest(quest_), checkType(checkType_), area(area_), actorId(actorId_), - scene(scene_), 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); - } - } - - Location(const RandomizerCheck rc_, const RandomizerCheckQuest quest_, const RandomizerCheckType checkType_, const RandomizerCheckArea area_, const ActorID actorId_, - const SceneID scene_, const int32_t actorParams_, std::string shortName_, const RandomizerHintTextKey hintKey_, const RandomizerGet vanillaItem_, - const bool isVanillaCompletion_ = false, const SpoilerCollectionCheck collectionCheck_ = SpoilerCollectionCheck(), - const int vanillaPrice_ = 0) - : rc(rc_), quest(quest_), checkType(checkType_), area(area_), actorId(actorId_), scene(scene_), actorParams(actorParams_), shortName(shortName_), - spoilerName(SpoilerNameFromShortName(shortName_, area_)), hintKey(hintKey_), vanillaItem(vanillaItem_), isVanillaCompletion(isVanillaCompletion_), + Location(const RandomizerCheck rc_, const RandomizerCheckQuest quest_, const RandomizerCheckType checkType_, + const RandomizerCheckArea area_, const ActorID actorId_, const SceneID scene_, const int32_t actorParams_, + std::string shortName_, std::string spoilerName_, const RandomizerHintTextKey hintKey_, + const RandomizerGet vanillaItem_, const bool isVanillaCompletion_ = false, + const SpoilerCollectionCheck collectionCheck_ = SpoilerCollectionCheck(), const int vanillaPrice_ = 0) + : rc(rc_), quest(quest_), checkType(checkType_), area(area_), actorId(actorId_), scene(scene_), + 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 "); + 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_, + const RandomizerCheckArea area_, const ActorID actorId_, const SceneID scene_, const int32_t actorParams_, + std::string shortName_, const RandomizerHintTextKey hintKey_, const RandomizerGet vanillaItem_, + const bool isVanillaCompletion_ = false, + const SpoilerCollectionCheck collectionCheck_ = SpoilerCollectionCheck(), const int vanillaPrice_ = 0) + : rc(rc_), quest(quest_), checkType(checkType_), area(area_), actorId(actorId_), scene(scene_), + 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); + } + } static std::string SpoilerNameFromShortName(std::string shortName, RandomizerCheckArea area) { if (area < 0 || area >= RCAREA_INVALID) { @@ -119,118 +127,143 @@ class Location { int16_t GetVanillaPrice() const; Option* GetExcludedOption(); - static Location Base(RandomizerCheck rc, RandomizerCheckQuest quest_, RandomizerCheckType checkType_, - ActorID actorId_, SceneID scene_, int32_t actorParams_, std::string&& shortName_, - std::string&& spoilerName_, RandomizerHintTextKey hintKey, RandomizerGet vanillaItem, - SpoilerCollectionCheck collectionCheck = SpoilerCollectionCheck(), - bool isVanillaCompletion_ = false, uint16_t vanillaPrice_ = 0); - - static Location Base(RandomizerCheck rc, RandomizerCheckQuest quest_, RandomizerCheckType checkType_, ActorID actorId_, SceneID scene_, int32_t actorParams_, - std::string&& shortName_, RandomizerHintTextKey hintKey, RandomizerGet vanillaItem, SpoilerCollectionCheck collectionCheck = SpoilerCollectionCheck(), + static Location Base(RandomizerCheck rc, RandomizerCheckQuest quest_, RandomizerCheckType checkType_, + ActorID actorId_, SceneID scene_, int32_t actorParams_, std::string&& shortName_, + std::string&& spoilerName_, RandomizerHintTextKey hintKey, RandomizerGet vanillaItem, + SpoilerCollectionCheck collectionCheck = SpoilerCollectionCheck(), bool isVanillaCompletion_ = false, uint16_t vanillaPrice_ = 0); - static Location Base(RandomizerCheck rc, RandomizerCheckQuest quest_, RandomizerCheckType checkType_, RandomizerCheckArea area_, ActorID actorId_, SceneID scene_, - int32_t actorParams_, std::string&& shortName_, std::string&& spoilerName_, RandomizerHintTextKey hintKey, RandomizerGet vanillaItem, - SpoilerCollectionCheck collectionCheck = SpoilerCollectionCheck(), bool isVanillaCompletion_ = false, uint16_t vanillaPrice_ = 0); + static Location Base(RandomizerCheck rc, RandomizerCheckQuest quest_, RandomizerCheckType checkType_, + ActorID actorId_, SceneID scene_, int32_t actorParams_, std::string&& shortName_, + RandomizerHintTextKey hintKey, RandomizerGet vanillaItem, + SpoilerCollectionCheck collectionCheck = SpoilerCollectionCheck(), + bool isVanillaCompletion_ = false, uint16_t vanillaPrice_ = 0); - static Location Base(RandomizerCheck rc, RandomizerCheckQuest quest_, RandomizerCheckType checkType_, RandomizerCheckArea area_, ActorID actorId_, SceneID scene_, - int32_t actorParams_, std::string&& shortName_, RandomizerHintTextKey hintKey, RandomizerGet vanillaItem, - SpoilerCollectionCheck collectionCheck = SpoilerCollectionCheck(), bool isVanillaCompletion_ = false, uint16_t vanillaPrice_ = 0); + static Location Base(RandomizerCheck rc, RandomizerCheckQuest quest_, RandomizerCheckType checkType_, + RandomizerCheckArea area_, ActorID actorId_, SceneID scene_, int32_t actorParams_, + std::string&& shortName_, std::string&& spoilerName_, RandomizerHintTextKey hintKey, + RandomizerGet vanillaItem, SpoilerCollectionCheck collectionCheck = SpoilerCollectionCheck(), + bool isVanillaCompletion_ = false, uint16_t vanillaPrice_ = 0); - static Location Chest(RandomizerCheck rc, RandomizerCheckQuest quest_, RandomizerCheckType checkType_, RandomizerCheckArea area_, ActorID actorId_, SceneID scene_, - int32_t actorParams_, uint8_t flag_, std::string&& shortName_, RandomizerHintTextKey hintKey, RandomizerGet vanillaItem, bool isVanillaCompletion_ = false); + static Location Base(RandomizerCheck rc, RandomizerCheckQuest quest_, RandomizerCheckType checkType_, + RandomizerCheckArea area_, ActorID actorId_, SceneID scene_, int32_t actorParams_, + std::string&& shortName_, RandomizerHintTextKey hintKey, RandomizerGet vanillaItem, + SpoilerCollectionCheck collectionCheck = SpoilerCollectionCheck(), + bool isVanillaCompletion_ = false, uint16_t vanillaPrice_ = 0); - static Location Chest(RandomizerCheck rc, RandomizerCheckQuest quest_, RandomizerCheckType checkType_, RandomizerCheckArea area_, ActorID actorId_, SceneID scene_, - int32_t actorParams_, std::string&& shortName_, RandomizerHintTextKey hintKey, RandomizerGet vanillaItem, SpoilerCollectionCheck collectionCheck, + static Location Chest(RandomizerCheck rc, RandomizerCheckQuest quest_, RandomizerCheckType checkType_, + RandomizerCheckArea area_, ActorID actorId_, SceneID scene_, int32_t actorParams_, + uint8_t flag_, std::string&& shortName_, RandomizerHintTextKey hintKey, + RandomizerGet vanillaItem, bool isVanillaCompletion_ = false); + + static Location Chest(RandomizerCheck rc, RandomizerCheckQuest quest_, RandomizerCheckType checkType_, + RandomizerCheckArea area_, ActorID actorId_, SceneID scene_, int32_t actorParams_, + std::string&& shortName_, RandomizerHintTextKey hintKey, RandomizerGet vanillaItem, + SpoilerCollectionCheck collectionCheck, bool isVanillaCompletion_ = false); + + static Location Chest(RandomizerCheck rc, RandomizerCheckQuest quest_, RandomizerCheckType checkType_, + ActorID actorId_, SceneID scene_, int32_t actorParams_, uint8_t flag_, + std::string&& shortName_, RandomizerHintTextKey hintKey, RandomizerGet vanillaItem, bool isVanillaCompletion_ = false); - static Location Chest(RandomizerCheck rc, RandomizerCheckQuest quest_, RandomizerCheckType checkType_, ActorID actorId_, SceneID scene_, int32_t actorParams_, uint8_t flag_, - std::string&& shortName_, RandomizerHintTextKey hintKey, RandomizerGet vanillaItem, bool isVanillaCompletion_ = false); + static Location Chest(RandomizerCheck rc, RandomizerCheckQuest quest_, RandomizerCheckType checkType_, + ActorID actorId_, SceneID scene_, int32_t actorParams_, std::string&& shortName_, + RandomizerHintTextKey hintKey, RandomizerGet vanillaItem, + SpoilerCollectionCheck collectionCheck, bool isVanillaCompletion_ = false); - static Location Chest(RandomizerCheck rc, RandomizerCheckQuest quest_, RandomizerCheckType checkType_, ActorID actorId_, SceneID scene_, int32_t actorParams_, - std::string&& shortName_, RandomizerHintTextKey hintKey, RandomizerGet vanillaItem, SpoilerCollectionCheck collectionCheck, - bool isVanillaCompletion_ = false); - - static Location Collectable(RandomizerCheck rc, RandomizerCheckQuest quest_, RandomizerCheckType checkType_, ActorID actorId_, SceneID scene_, int32_t actorParams_, uint8_t flag_, - std::string&& shortName_, RandomizerHintTextKey hintKey, RandomizerGet vanillaItem, bool isVanillaCompletion_ = false); - - static Location Collectable(RandomizerCheck rc, RandomizerCheckQuest quest_, RandomizerCheckType checkType_, RandomizerCheckArea area_, ActorID actorId_, SceneID scene_, - int32_t actorParams_, uint8_t flag_, std::string&& shortName_, RandomizerHintTextKey hintKey, RandomizerGet vanillaItem, + static Location Collectable(RandomizerCheck rc, RandomizerCheckQuest quest_, RandomizerCheckType checkType_, + ActorID actorId_, SceneID scene_, int32_t actorParams_, uint8_t flag_, + std::string&& shortName_, RandomizerHintTextKey hintKey, RandomizerGet vanillaItem, bool isVanillaCompletion_ = false); - static Location Collectable(RandomizerCheck rc, RandomizerCheckQuest quest_, RandomizerCheckType checkType_, ActorID actorId_, SceneID scene_, int32_t actorParams_, - std::string&& shortName_, RandomizerHintTextKey hintKey, RandomizerGet vanillaItem, SpoilerCollectionCheck collectionCheck = SpoilerCollectionCheck(), + static Location Collectable(RandomizerCheck rc, RandomizerCheckQuest quest_, RandomizerCheckType checkType_, + RandomizerCheckArea area_, ActorID actorId_, SceneID scene_, int32_t actorParams_, + uint8_t flag_, std::string&& shortName_, RandomizerHintTextKey hintKey, + RandomizerGet vanillaItem, bool isVanillaCompletion_ = false); + + static Location Collectable(RandomizerCheck rc, RandomizerCheckQuest quest_, RandomizerCheckType checkType_, + ActorID actorId_, SceneID scene_, int32_t actorParams_, std::string&& shortName_, + RandomizerHintTextKey hintKey, RandomizerGet vanillaItem, + SpoilerCollectionCheck collectionCheck = SpoilerCollectionCheck(), bool isVanillaCompletion_ = false); - static Location Collectable(RandomizerCheck rc, RandomizerCheckQuest quest_, RandomizerCheckType checkType_, RandomizerCheckArea area_, ActorID actorId_, - SceneID scene_, int32_t actorParams_, std::string&& shortName_, RandomizerHintTextKey hintKey, RandomizerGet vanillaItem, - SpoilerCollectionCheck collectionCheck = SpoilerCollectionCheck(), bool isVanillaCompletion_ = false); + static Location Collectable(RandomizerCheck rc, RandomizerCheckQuest quest_, RandomizerCheckType checkType_, + RandomizerCheckArea area_, ActorID actorId_, SceneID scene_, int32_t actorParams_, + std::string&& shortName_, RandomizerHintTextKey hintKey, RandomizerGet vanillaItem, + SpoilerCollectionCheck collectionCheck = SpoilerCollectionCheck(), + bool isVanillaCompletion_ = false); - static Location GSToken(RandomizerCheck rc, RandomizerCheckQuest quest_, SceneID scene_, int32_t actorParams_, uint8_t flag_, std::string&& shortName_, - RandomizerHintTextKey hintKey); + static Location GSToken(RandomizerCheck rc, RandomizerCheckQuest quest_, SceneID scene_, int32_t actorParams_, + uint8_t flag_, std::string&& shortName_, RandomizerHintTextKey hintKey); /// @brief For certain scenes, the sceneId and the "Scene" in spoiler collection check later used to check the - /// GS flags don't necessarily match. Use this constructor (or the next one) for those. scene_ should be the actual scene where - /// the GS is located, skullScene_ is the value passed to GET_GS_FLAGS to get the correct skulltula. It is normal - /// and expected that these don't always match, and the naming is a holdover from 3drando. - /// @param rc - /// @param quest_ - /// @param scene_ - /// @param actorParams_ - /// @param flag_ - /// @param shortName_ - /// @param hintKey - /// @param skullScene_ + /// GS flags don't necessarily match. Use this constructor (or the next one) for those. scene_ should be the actual + /// scene where the GS is located, skullScene_ is the value passed to GET_GS_FLAGS to get the correct skulltula. It + /// is normal and expected that these don't always match, and the naming is a holdover from 3drando. + /// @param rc + /// @param quest_ + /// @param scene_ + /// @param actorParams_ + /// @param flag_ + /// @param shortName_ + /// @param hintKey + /// @param skullScene_ /// @return - static Location GSToken(RandomizerCheck rc, RandomizerCheckQuest quest_, SceneID scene_, int32_t actorParams_, uint8_t flag_, std::string&& shortName_, + static Location GSToken(RandomizerCheck rc, RandomizerCheckQuest quest_, SceneID scene_, int32_t actorParams_, + uint8_t flag_, std::string&& shortName_, RandomizerHintTextKey hintKey, + uint8_t skullScene_); + + static Location GSToken(RandomizerCheck rc, RandomizerCheckQuest quest_, RandomizerCheckArea area_, SceneID scene_, + int32_t actorParams_, uint8_t flag_, std::string&& shortName_, RandomizerHintTextKey hintKey, uint8_t skullScene_); - static Location GSToken(RandomizerCheck rc, RandomizerCheckQuest quest_, RandomizerCheckArea area_, SceneID scene_, int32_t actorParams_, uint8_t flag_, - std::string&& shortName_, RandomizerHintTextKey hintKey, uint8_t skullScene_); + static Location Fish(RandomizerCheck rc, RandomizerCheckQuest quest_, ActorID actorId_, SceneID scene_, + int32_t actorParams_, RandomizerInf flag_, std::string&& shortName_, + RandomizerHintTextKey hintKey, RandomizerGet vanillaItem); - static Location Fish(RandomizerCheck rc, RandomizerCheckQuest quest_, ActorID actorId_, SceneID scene_, int32_t actorParams_, - RandomizerInf flag_, std::string&& shortName_, RandomizerHintTextKey hintKey, RandomizerGet vanillaItem); - - static Location GrottoFish(RandomizerCheck rc, RandomizerCheckQuest quest_, RandomizerCheckArea area_, int32_t actorParams_, - RandomizerInf flag_, std::string&& shortName_, RandomizerHintTextKey hintKey); + static Location GrottoFish(RandomizerCheck rc, RandomizerCheckQuest quest_, RandomizerCheckArea area_, + int32_t actorParams_, RandomizerInf flag_, std::string&& shortName_, + RandomizerHintTextKey hintKey); static Location Pot(RandomizerCheck rc, RandomizerCheckQuest quest_, RandomizerCheckArea area_, SceneID scene_, - int32_t actorParams_, std::string&& shortName_, - RandomizerHintTextKey hintKey, RandomizerGet vanillaItem, - SpoilerCollectionCheck collectionCheck); + int32_t actorParams_, std::string&& shortName_, RandomizerHintTextKey hintKey, + RandomizerGet vanillaItem, SpoilerCollectionCheck collectionCheck); static Location Grass(RandomizerCheck rc, RandomizerCheckQuest quest_, RandomizerCheckArea area_, SceneID scene_, - int32_t actorParams_, std::string&& shortName_, - RandomizerHintTextKey hintKey, RandomizerGet vanillaItem, - SpoilerCollectionCheck collectionCheck); + int32_t actorParams_, std::string&& shortName_, RandomizerHintTextKey hintKey, + RandomizerGet vanillaItem, SpoilerCollectionCheck collectionCheck); static Location Crate(RandomizerCheck rc, RandomizerCheckQuest quest_, RandomizerCheckArea area_, SceneID scene_, - int32_t actorParams_, std::string&& shortName_, - RandomizerHintTextKey hintKey, RandomizerGet vanillaItem, - SpoilerCollectionCheck collectionCheck); + int32_t actorParams_, std::string&& shortName_, RandomizerHintTextKey hintKey, + RandomizerGet vanillaItem, SpoilerCollectionCheck collectionCheck); static Location NLCrate(RandomizerCheck rc, RandomizerCheckQuest quest_, RandomizerCheckArea area_, SceneID scene_, - int32_t actorParams_, std::string&& shortName_, - RandomizerHintTextKey hintKey, RandomizerGet vanillaItem, - SpoilerCollectionCheck collectionCheck); + int32_t actorParams_, std::string&& shortName_, RandomizerHintTextKey hintKey, + RandomizerGet vanillaItem, SpoilerCollectionCheck collectionCheck); - static Location SmallCrate(RandomizerCheck rc, RandomizerCheckQuest quest_, RandomizerCheckArea area_, SceneID scene_, - int32_t actorParams_, std::string&& shortName_, - RandomizerHintTextKey hintKey, RandomizerGet vanillaItem, - SpoilerCollectionCheck collectionCheck); + static Location SmallCrate(RandomizerCheck rc, RandomizerCheckQuest quest_, RandomizerCheckArea area_, + SceneID scene_, int32_t actorParams_, std::string&& shortName_, + RandomizerHintTextKey hintKey, RandomizerGet vanillaItem, + SpoilerCollectionCheck collectionCheck); - static Location OtherHint(RandomizerCheck rc, RandomizerCheckQuest quest_, RandomizerCheckArea area_, ActorID actorId_, SceneID scene_, std::string&& shortName_, - std::string&& spoilerName_); + static Location OtherHint(RandomizerCheck rc, RandomizerCheckQuest quest_, RandomizerCheckArea area_, + ActorID actorId_, SceneID scene_, std::string&& shortName_, std::string&& spoilerName_); - static Location OtherHint(RandomizerCheck rc, RandomizerCheckQuest quest_, ActorID actorId_, SceneID scene_, std::string&& shortName_); + static Location OtherHint(RandomizerCheck rc, RandomizerCheckQuest quest_, ActorID actorId_, SceneID scene_, + std::string&& shortName_); - static Location OtherHint(RandomizerCheck rc, RandomizerCheckQuest quest_, RandomizerCheckArea area_, ActorID actorId_, SceneID scene_, std::string&& shortName_); + static Location OtherHint(RandomizerCheck rc, RandomizerCheckQuest quest_, RandomizerCheckArea area_, + ActorID actorId_, SceneID scene_, std::string&& shortName_); - static Location Fairy(RandomizerCheck rc, RandomizerCheckQuest quest_, RandomizerCheckArea area_, SceneID scene_, int32_t actorParams_, std::string&& shortName_, RandomizerHintTextKey hintKey, SpoilerCollectionCheck collectionCheck); + static Location Fairy(RandomizerCheck rc, RandomizerCheckQuest quest_, RandomizerCheckArea area_, SceneID scene_, + int32_t actorParams_, std::string&& shortName_, RandomizerHintTextKey hintKey, + SpoilerCollectionCheck collectionCheck); - static Location HintStone(RandomizerCheck rc, RandomizerCheckQuest quest_, SceneID scene_, int32_t actorParams_, std::string&& shortName_); + static Location HintStone(RandomizerCheck rc, RandomizerCheckQuest quest_, SceneID scene_, int32_t actorParams_, + std::string&& shortName_); - static Location HintStone(RandomizerCheck rc, RandomizerCheckQuest quest_, RandomizerCheckArea area_, SceneID scene_, int32_t actorParams_, std::string&& shortName_); + static Location HintStone(RandomizerCheck rc, RandomizerCheckQuest quest_, RandomizerCheckArea area_, + SceneID scene_, int32_t actorParams_, std::string&& shortName_); private: RandomizerCheck rc; diff --git a/soh/soh/Enhancements/randomizer/location_access.cpp b/soh/soh/Enhancements/randomizer/location_access.cpp index e2781e9fb..c06ca5d70 100644 --- a/soh/soh/Enhancements/randomizer/location_access.cpp +++ b/soh/soh/Enhancements/randomizer/location_access.cpp @@ -12,18 +12,18 @@ #include extern "C" { - extern SaveContext gSaveContext; - extern PlayState* gPlayState; +extern SaveContext gSaveContext; +extern PlayState* gPlayState; } -//generic grotto event list +// generic grotto event list std::vector grottoEvents; -//set the logic to be a specific age and time of day and see if the condition still holds +// set the logic to be a specific age and time of day and see if the condition still holds bool LocationAccess::CheckConditionAtAgeTime(bool& age, bool& time) const { logic->IsChild = false; logic->IsAdult = false; - logic->AtDay = false; + logic->AtDay = false; logic->AtNight = false; time = true; @@ -33,21 +33,20 @@ bool LocationAccess::CheckConditionAtAgeTime(bool& age, bool& time) const { } bool LocationAccess::ConditionsMet(Region* parentRegion, bool calculatingAvailableChecks) const { - //WARNING enterance validation can run this after resetting the access for sphere 0 validation - //When refactoring ToD access, either fix the above or do not assume that we - //have any access at all just because this is being run + // WARNING enterance validation can run this after resetting the access for sphere 0 validation + // When refactoring ToD access, either fix the above or do not assume that we + // have any access at all just because this is being run bool conditionsMet = false; - if ( - (parentRegion->childDay && CheckConditionAtAgeTime(logic->IsChild, logic->AtDay)) || + if ((parentRegion->childDay && CheckConditionAtAgeTime(logic->IsChild, logic->AtDay)) || (parentRegion->childNight && CheckConditionAtAgeTime(logic->IsChild, logic->AtNight)) || - (parentRegion->adultDay && CheckConditionAtAgeTime(logic->IsAdult, logic->AtDay)) || - (parentRegion->adultNight && CheckConditionAtAgeTime(logic->IsAdult, logic->AtNight)) - ) { + (parentRegion->adultDay && CheckConditionAtAgeTime(logic->IsAdult, logic->AtDay)) || + (parentRegion->adultNight && CheckConditionAtAgeTime(logic->IsAdult, logic->AtNight))) { conditionsMet = true; } - - return conditionsMet && (calculatingAvailableChecks || CanBuy()); // TODO: run CanBuy when price is known due to settings + + return conditionsMet && + (calculatingAvailableChecks || CanBuy()); // TODO: run CanBuy when price is known due to settings } bool LocationAccess::CanBuy() const { @@ -70,25 +69,16 @@ bool CanBuyAnother(RandomizerCheck rc) { } Region::Region() = default; -Region::Region( - std::string regionName_, - std::string scene_, - std::set areas, - bool timePass_, - std::vector events_, - std::vector locations_, - std::list exits_ -) : regionName(std::move(regionName_)), - scene(std::move(scene_)), - areas(areas), - timePass(timePass_), - events(std::move(events_)), - locations(std::move(locations_)), - exits(std::move(exits_)) {} +Region::Region(std::string regionName_, std::string scene_, std::set areas, bool timePass_, + std::vector events_, std::vector locations_, + std::list exits_) + : regionName(std::move(regionName_)), scene(std::move(scene_)), areas(areas), timePass(timePass_), + events(std::move(events_)), locations(std::move(locations_)), exits(std::move(exits_)) { +} Region::~Region() = default; -void Region::ApplyTimePass(){ +void Region::ApplyTimePass() { if (timePass) { StartPerformanceTimer(PT_TOD_ACCESS); if (Child()) { @@ -108,20 +98,18 @@ void Region::ApplyTimePass(){ } bool Region::UpdateEvents() { - bool eventsUpdated = false; + bool eventsUpdated = false; StartPerformanceTimer(PT_EVENT_ACCESS); for (EventAccess& event : events) { - //If the event has already happened, there's no reason to check it + // If the event has already happened, there's no reason to check it if (event.GetEvent()) { continue; } - if ( - (childDay && event.CheckConditionAtAgeTime(logic->IsChild, logic->AtDay)) || - (childNight && event.CheckConditionAtAgeTime(logic->IsChild, logic->AtNight)) || - (adultDay && event.CheckConditionAtAgeTime(logic->IsAdult, logic->AtDay)) || - (adultNight && event.CheckConditionAtAgeTime(logic->IsAdult, logic->AtNight)) - ) { + if ((childDay && event.CheckConditionAtAgeTime(logic->IsChild, logic->AtDay)) || + (childNight && event.CheckConditionAtAgeTime(logic->IsChild, logic->AtNight)) || + (adultDay && event.CheckConditionAtAgeTime(logic->IsAdult, logic->AtDay)) || + (adultNight && event.CheckConditionAtAgeTime(logic->IsAdult, logic->AtNight))) { event.EventOccurred(); eventsUpdated = true; } @@ -131,14 +119,14 @@ bool Region::UpdateEvents() { } void Region::AddExit(RandomizerRegion parentKey, RandomizerRegion newExitKey, ConditionFn condition) { - Rando::Entrance newExit = Rando::Entrance(newExitKey, {condition}); + Rando::Entrance newExit = Rando::Entrance(newExitKey, { condition }); newExit.SetParentRegion(parentKey); exits.push_front(newExit); } -//The exit will be completely removed from this region +// The exit will be completely removed from this region void Region::RemoveExit(Rando::Entrance* exitToRemove) { - exits.remove_if([exitToRemove](const auto exit){return &exit == exitToRemove;}); + exits.remove_if([exitToRemove](const auto exit) { return &exit == exitToRemove; }); } void Region::SetAsPrimary(RandomizerRegion exitToBePrimary) { @@ -157,7 +145,8 @@ Rando::Entrance* Region::GetExit(RandomizerRegion exitToReturn) { } } - LUSLOG_ERROR("ERROR: EXIT \"%s\" DOES NOT EXIST IN \"%s\"", RegionTable(exitToReturn)->regionName.c_str(), this->regionName.c_str()); + LUSLOG_ERROR("ERROR: EXIT \"%s\" DOES NOT EXIST IN \"%s\"", RegionTable(exitToReturn)->regionName.c_str(), + this->regionName.c_str()); assert(false); return nullptr; } @@ -195,9 +184,9 @@ bool Region::CheckAllAccess(const RandomizerRegion exitKey) { for (Rando::Entrance& exit : exits) { if (exit.GetConnectedRegionKey() == exitKey) { - return exit.CheckConditionAtAgeTime(logic->IsChild, logic->AtDay) && + return exit.CheckConditionAtAgeTime(logic->IsChild, logic->AtDay) && exit.CheckConditionAtAgeTime(logic->IsChild, logic->AtNight) && - exit.CheckConditionAtAgeTime(logic->IsAdult, logic->AtDay) && + exit.CheckConditionAtAgeTime(logic->IsAdult, logic->AtDay) && exit.CheckConditionAtAgeTime(logic->IsAdult, logic->AtNight); } } @@ -320,15 +309,15 @@ std::shared_ptr logic; void RegionTable_Init() { using namespace Rando; ctx = Context::GetInstance().get(); - logic = ctx->GetLogic(); //RANDOTODO do not hardcode, instead allow accepting a Logic class somehow + logic = ctx->GetLogic(); // RANDOTODO do not hardcode, instead allow accepting a Logic class somehow grottoEvents = { - EventAccess(&logic->GossipStoneFairy, []{return logic->CallGossipFairy();}), - EventAccess(&logic->ButterflyFairy, []{return logic->ButterflyFairy || (logic->CanUse(RG_STICKS));}), - EventAccess(&logic->BugShrub, []{return logic->CanCutShrubs();}), - EventAccess(&logic->LoneFish, []{return true;}), + EventAccess(&logic->GossipStoneFairy, [] { return logic->CallGossipFairy(); }), + EventAccess(&logic->ButterflyFairy, [] { return logic->ButterflyFairy || (logic->CanUse(RG_STICKS)); }), + EventAccess(&logic->BugShrub, [] { return logic->CanCutShrubs(); }), + EventAccess(&logic->LoneFish, [] { return true; }), }; - //Clear the array from any previous playthrough attempts. This is important so that - //locations which appear in both MQ and Vanilla dungeons don't get set in both areas. + // Clear the array from any previous playthrough attempts. This is important so that + // locations which appear in both MQ and Vanilla dungeons don't get set in both areas. areaTable.fill(Region("Invalid Region", "Invalid Region", {}, NO_DAY_NIGHT_CYCLE, {}, {}, {})); // clang-format off @@ -438,7 +427,7 @@ void RegionTable_Init() { RegionTable_Init_GerudoTrainingGround(); RegionTable_Init_GanonsCastle(); - //Set parent regions + // Set parent regions for (uint32_t i = RR_ROOT; i <= RR_GANONS_CASTLE; i++) { for (LocationAccess& locPair : areaTable[i].locations) { RandomizerCheck location = locPair.GetLocation(); @@ -491,130 +480,131 @@ std::string CleanCheckConditionString(std::string condition) { } namespace Regions { - const auto GetAllRegions() { - static const size_t regionCount = RR_MAX - (RR_NONE + 1); +const auto GetAllRegions() { + static const size_t regionCount = RR_MAX - (RR_NONE + 1); - static std::array allRegions = {}; + static std::array allRegions = {}; - static bool intialized = false; - if (!intialized) { - for (size_t i = 0; i < regionCount; i++) { - allRegions[i] = (RandomizerRegion)((RR_NONE + 1) + i); - } - intialized = true; + static bool intialized = false; + if (!intialized) { + for (size_t i = 0; i < regionCount; i++) { + allRegions[i] = (RandomizerRegion)((RR_NONE + 1) + i); } - - return allRegions; + intialized = true; } - void AccessReset() { - auto ctx = Rando::Context::GetInstance(); - for (const RandomizerRegion region : GetAllRegions()) { - RegionTable(region)->ResetVariables(); - } + return allRegions; +} - if (/*Settings::HasNightStart TODO:: Randomize Starting Time*/ false) { - if (ctx->GetOption(RSK_SELECTED_STARTING_AGE).Is(RO_AGE_CHILD)) { - RegionTable(RR_ROOT)->childNight = true; - } else { - RegionTable(RR_ROOT)->adultNight = true; - } +void AccessReset() { + auto ctx = Rando::Context::GetInstance(); + for (const RandomizerRegion region : GetAllRegions()) { + RegionTable(region)->ResetVariables(); + } + + if (/*Settings::HasNightStart TODO:: Randomize Starting Time*/ false) { + if (ctx->GetOption(RSK_SELECTED_STARTING_AGE).Is(RO_AGE_CHILD)) { + RegionTable(RR_ROOT)->childNight = true; } else { - if (ctx->GetOption(RSK_SELECTED_STARTING_AGE).Is(RO_AGE_CHILD)) { - RegionTable(RR_ROOT)->childDay = true; - } else { - RegionTable(RR_ROOT)->adultDay = true; - } + RegionTable(RR_ROOT)->adultNight = true; } - } - - //Reset exits and clear items from locations - void ResetAllLocations() { - auto ctx = Rando::Context::GetInstance(); - for (const RandomizerRegion region : GetAllRegions()) { - RegionTable(region)->ResetVariables(); - //Erase item from every location in this exit - for (LocationAccess& locPair : RegionTable(region)->locations) { - RandomizerCheck location = locPair.GetLocation(); - Rando::Context::GetInstance()->GetItemLocation(location)->ResetVariables(); - } - } - - if (/*Settings::HasNightStart TODO:: Randomize Starting Time*/ false) { - if (ctx->GetOption(RSK_SELECTED_STARTING_AGE).Is(RO_AGE_CHILD)) { - RegionTable(RR_ROOT)->childNight = true; - } else { - RegionTable(RR_ROOT)->adultNight = true; - } + } else { + if (ctx->GetOption(RSK_SELECTED_STARTING_AGE).Is(RO_AGE_CHILD)) { + RegionTable(RR_ROOT)->childDay = true; } else { - if (ctx->GetOption(RSK_SELECTED_STARTING_AGE).Is(RO_AGE_CHILD)) { - RegionTable(RR_ROOT)->childDay = true; - } else { - RegionTable(RR_ROOT)->adultDay = true; - } + RegionTable(RR_ROOT)->adultDay = true; + } + } +} + +// Reset exits and clear items from locations +void ResetAllLocations() { + auto ctx = Rando::Context::GetInstance(); + for (const RandomizerRegion region : GetAllRegions()) { + RegionTable(region)->ResetVariables(); + // Erase item from every location in this exit + for (LocationAccess& locPair : RegionTable(region)->locations) { + RandomizerCheck location = locPair.GetLocation(); + Rando::Context::GetInstance()->GetItemLocation(location)->ResetVariables(); } } - bool HasTimePassAccess(uint8_t age) { - for (const RandomizerRegion regionKey : GetAllRegions()) { - auto region = RegionTable(regionKey); - if (region->timePass && ((age == RO_AGE_CHILD && region->Child()) || (age == RO_AGE_ADULT && region->Adult()))) { - return true; - } + if (/*Settings::HasNightStart TODO:: Randomize Starting Time*/ false) { + if (ctx->GetOption(RSK_SELECTED_STARTING_AGE).Is(RO_AGE_CHILD)) { + RegionTable(RR_ROOT)->childNight = true; + } else { + RegionTable(RR_ROOT)->adultNight = true; + } + } else { + if (ctx->GetOption(RSK_SELECTED_STARTING_AGE).Is(RO_AGE_CHILD)) { + RegionTable(RR_ROOT)->childDay = true; + } else { + RegionTable(RR_ROOT)->adultDay = true; } - return false; } +} - // Will dump a file which can be turned into a visual graph using graphviz - // https://graphviz.org/download/ - // Use command: dot -Tsvg -o world.svg - // Then open in a browser and CTRL + F to find the area of interest - void DumpWorldGraph(std::string str) { - std::ofstream worldGraph; - worldGraph.open (str + ".dot"); - worldGraph << "digraph {\n\tcenter=true;\n"; +bool HasTimePassAccess(uint8_t age) { + for (const RandomizerRegion regionKey : GetAllRegions()) { + auto region = RegionTable(regionKey); + if (region->timePass && + ((age == RO_AGE_CHILD && region->Child()) || (age == RO_AGE_ADULT && region->Adult()))) { + return true; + } + } + return false; +} - for (const RandomizerRegion regionKey : GetAllRegions()) { - auto region = RegionTable(regionKey); - for (auto exit : region->exits) { - if (exit.GetConnectedRegion()->regionName != "Invalid Region") { - std::string parent = exit.GetParentRegion()->regionName; - if (region->childDay) { - parent += " CD"; - } - if (region->childNight) { - parent += " CN"; - } - if (region->adultDay) { - parent += " AD"; - } - if (region->adultNight) { - parent += " AN"; - } - Region* connected = exit.GetConnectedRegion(); - auto connectedStr = connected->regionName; - if (connected->childDay) { - connectedStr += " CD"; - } - if (connected->childNight) { - connectedStr += " CN"; - } - if (connected->adultDay) { - connectedStr += " AD"; - } - if (connected->adultNight) { - connectedStr += " AN"; - } - worldGraph << "\t\"" + parent + "\"[shape=\"plain\"];\n"; - worldGraph << "\t\"" + connectedStr + "\"[shape=\"plain\"];\n"; - worldGraph << "\t\"" + parent + "\" -> \"" + connectedStr + "\"\n"; +// Will dump a file which can be turned into a visual graph using graphviz +// https://graphviz.org/download/ +// Use command: dot -Tsvg -o world.svg +// Then open in a browser and CTRL + F to find the area of interest +void DumpWorldGraph(std::string str) { + std::ofstream worldGraph; + worldGraph.open(str + ".dot"); + worldGraph << "digraph {\n\tcenter=true;\n"; + + for (const RandomizerRegion regionKey : GetAllRegions()) { + auto region = RegionTable(regionKey); + for (auto exit : region->exits) { + if (exit.GetConnectedRegion()->regionName != "Invalid Region") { + std::string parent = exit.GetParentRegion()->regionName; + if (region->childDay) { + parent += " CD"; } + if (region->childNight) { + parent += " CN"; + } + if (region->adultDay) { + parent += " AD"; + } + if (region->adultNight) { + parent += " AN"; + } + Region* connected = exit.GetConnectedRegion(); + auto connectedStr = connected->regionName; + if (connected->childDay) { + connectedStr += " CD"; + } + if (connected->childNight) { + connectedStr += " CN"; + } + if (connected->adultDay) { + connectedStr += " AD"; + } + if (connected->adultNight) { + connectedStr += " AN"; + } + worldGraph << "\t\"" + parent + "\"[shape=\"plain\"];\n"; + worldGraph << "\t\"" + connectedStr + "\"[shape=\"plain\"];\n"; + worldGraph << "\t\"" + parent + "\" -> \"" + connectedStr + "\"\n"; } } - worldGraph << "}"; - worldGraph.close(); } -} //namespace Regions + worldGraph << "}"; + worldGraph.close(); +} +} // namespace Regions Region* RegionTable(const RandomizerRegion regionKey) { if (regionKey > RR_MAX) { @@ -623,12 +613,13 @@ Region* RegionTable(const RandomizerRegion regionKey) { return &(areaTable[regionKey]); } -//Retrieve all the shuffable entrances of a specific type +// Retrieve all the shuffable entrances of a specific type std::vector GetShuffleableEntrances(Rando::EntranceType type, bool onlyPrimary /*= true*/) { std::vector entrancesToShuffle = {}; for (RandomizerRegion region : Regions::GetAllRegions()) { for (auto& exit : RegionTable(region)->exits) { - if ((exit.GetType() == type || type == Rando::EntranceType::All) && (exit.IsPrimary() || !onlyPrimary) && exit.GetType() != Rando::EntranceType::None) { + if ((exit.GetType() == type || type == Rando::EntranceType::All) && (exit.IsPrimary() || !onlyPrimary) && + exit.GetType() != Rando::EntranceType::None) { entrancesToShuffle.push_back(&exit); } } diff --git a/soh/soh/Enhancements/randomizer/location_access.h b/soh/soh/Enhancements/randomizer/location_access.h index ad7061963..828c31a08 100644 --- a/soh/soh/Enhancements/randomizer/location_access.h +++ b/soh/soh/Enhancements/randomizer/location_access.h @@ -18,287 +18,317 @@ extern std::shared_ptr logic; class Region; class EventAccess { - public: - explicit EventAccess(bool* event_, ConditionFn condition_function_) : event(event_), condition_function(condition_function_) {} + public: + explicit EventAccess(bool* event_, ConditionFn condition_function_) + : event(event_), condition_function(condition_function_) { + } - bool ConditionsMet() const { - auto ctx = Rando::Context::GetInstance(); - if (ctx->GetOption(RSK_LOGIC_RULES).Is(RO_LOGIC_GLITCHLESS)) { - return condition_function(); - } - return true; + bool ConditionsMet() const { + auto ctx = Rando::Context::GetInstance(); + if (ctx->GetOption(RSK_LOGIC_RULES).Is(RO_LOGIC_GLITCHLESS)) { + return condition_function(); } + return true; + } - bool CheckConditionAtAgeTime(bool& age, bool& time) { - logic->IsChild = false; - logic->IsAdult = false; - logic->AtDay = false; - logic->AtNight = false; + bool CheckConditionAtAgeTime(bool& age, bool& time) { + logic->IsChild = false; + logic->IsAdult = false; + logic->AtDay = false; + logic->AtNight = false; - time = true; - age = true; + time = true; + age = true; - return ConditionsMet(); - } + return ConditionsMet(); + } - void EventOccurred() { - *event = true; - } + void EventOccurred() { + *event = true; + } - bool GetEvent() const { - return *event; - } + bool GetEvent() const { + return *event; + } - private: - bool* event; - ConditionFn condition_function; + private: + bool* event; + ConditionFn condition_function; }; std::string CleanCheckConditionString(std::string condition); -#define LOCATION(check, condition) LocationAccess(check, []{return condition;}, CleanCheckConditionString(#condition)) +#define LOCATION(check, condition) \ + LocationAccess( \ + check, [] { return condition; }, CleanCheckConditionString(#condition)) -//this class is meant to hold an item location with a boolean function to determine its accessibility from a specific area +// this class is meant to hold an item location with a boolean function to determine its accessibility from a specific +// area class LocationAccess { - public: - explicit LocationAccess(RandomizerCheck location_, ConditionFn condition_function_) : location(location_), condition_function(condition_function_), condition_str("") {} + public: + explicit LocationAccess(RandomizerCheck location_, ConditionFn condition_function_) + : location(location_), condition_function(condition_function_), condition_str("") { + } - explicit LocationAccess(RandomizerCheck location_, ConditionFn condition_function_, std::string condition_str_) : location(location_), condition_function(condition_function_), condition_str(condition_str_) {} + explicit LocationAccess(RandomizerCheck location_, ConditionFn condition_function_, std::string condition_str_) + : location(location_), condition_function(condition_function_), condition_str(condition_str_) { + } - bool GetConditionsMet() const { - auto ctx = Rando::Context::GetInstance(); - if (ctx->GetOption(RSK_LOGIC_RULES).Is(RO_LOGIC_GLITCHLESS)) { - return condition_function(); - } - return true; + bool GetConditionsMet() const { + auto ctx = Rando::Context::GetInstance(); + if (ctx->GetOption(RSK_LOGIC_RULES).Is(RO_LOGIC_GLITCHLESS)) { + return condition_function(); } + return true; + } - bool CheckConditionAtAgeTime(bool& age, bool& time) const; + bool CheckConditionAtAgeTime(bool& age, bool& time) const; - bool ConditionsMet(Region* parentRegion, bool calculatingAvailableChecks) const; + bool ConditionsMet(Region* parentRegion, bool calculatingAvailableChecks) const; - RandomizerCheck GetLocation() const { - return location; - } + RandomizerCheck GetLocation() const { + return location; + } - std::string GetConditionStr() const { - return condition_str; - } + std::string GetConditionStr() const { + return condition_str; + } - protected: - RandomizerCheck location; - ConditionFn condition_function; - std::string condition_str; + protected: + RandomizerCheck location; + ConditionFn condition_function; + std::string condition_str; - //Makes sure shop locations are buyable - bool CanBuy() const; + // Makes sure shop locations are buyable + bool CanBuy() const; }; bool CanBuyAnother(RandomizerCheck rc); namespace Rando { - class Entrance; - enum class EntranceType; -} +class Entrance; +enum class EntranceType; +} // namespace Rando class Region { - public: - Region(); - Region( - std::string regionName_, - std::string scene_, - std::set areas, - bool timePass_, - std::vector events_, - std::vector locations_, - std::list exits_ - ); - ~Region(); + public: + Region(); + Region(std::string regionName_, std::string scene_, std::set areas, bool timePass_, + std::vector events_, std::vector locations_, std::list exits_); + ~Region(); - std::string regionName; - std::string scene; - std::set areas; - bool timePass; - std::vector events; - std::vector locations; - std::list exits; - std::list entrances; - //^ The above exits are now stored in a list instead of a vector because - //the entrance randomization algorithm plays around with pointers to these - //entrances a lot. By putting the entrances in a list, we don't have to - //worry about a vector potentially reallocating itself and invalidating all our - //entrance pointers. + std::string regionName; + std::string scene; + std::set areas; + bool timePass; + std::vector events; + std::vector locations; + std::list exits; + std::list entrances; + //^ The above exits are now stored in a list instead of a vector because + // the entrance randomization algorithm plays around with pointers to these + // entrances a lot. By putting the entrances in a list, we don't have to + // worry about a vector potentially reallocating itself and invalidating all our + // entrance pointers. - bool childDay = false; - bool childNight = false; - bool adultDay = false; - bool adultNight = false; - bool addedToPool = false;; + bool childDay = false; + bool childNight = false; + bool adultDay = false; + bool adultNight = false; + bool addedToPool = false; + ; - void ApplyTimePass(); + void ApplyTimePass(); - bool UpdateEvents(); + bool UpdateEvents(); - void AddExit(RandomizerRegion parentKey, RandomizerRegion newExitKey, ConditionFn condition); + void AddExit(RandomizerRegion parentKey, RandomizerRegion newExitKey, ConditionFn condition); - void RemoveExit(Rando::Entrance* exitToRemove); + void RemoveExit(Rando::Entrance* exitToRemove); - void SetAsPrimary(RandomizerRegion exitToBePrimary); + void SetAsPrimary(RandomizerRegion exitToBePrimary); - Rando::Entrance* GetExit(RandomizerRegion exit); + Rando::Entrance* GetExit(RandomizerRegion exit); - bool Child() const { - return childDay || childNight; + bool Child() const { + return childDay || childNight; + } + + bool Adult() const { + return adultDay || adultNight; + } + + bool BothAgesCheck() const { + return Child() && Adult(); + } + + bool HasAccess() const { + return Child() || Adult(); + } + + bool AllAccess() const { + return childDay && childNight && adultDay && adultNight; + } + + // Check to see if an exit can be access as both ages at both times of day + bool CheckAllAccess(RandomizerRegion exitKey); + + std::set GetAllAreas() const { + return areas; + } + + RandomizerArea GetFirstArea() const { + if (areas.empty()) { + assert(false); + return RA_NONE; + } else { + return *areas.begin(); } + } - bool Adult() const { - return adultDay || adultNight; - } + void ReplaceAreas(std::set newAreas) { + areas = newAreas; + } - bool BothAgesCheck() const { - return Child() && Adult(); - } + // Here checks conditional access based on whether or not both ages have + // access to this area. For example: if there are rocks that block a path + // which both child and adult can access, adult having hammer can give + // both child and adult access to the path. + bool Here(ConditionFn condition) { + // store current age variables + bool pastAdult = logic->IsAdult; + bool pastChild = logic->IsChild; - bool HasAccess() const { - return Child() || Adult(); - } + // set age access as this areas ages + logic->IsChild = Child(); + logic->IsAdult = Adult(); - bool AllAccess() const { - return childDay && childNight && adultDay && adultNight; - } + // heck condition as well as having at least child or adult access + bool hereVal = condition() && (logic->IsAdult || logic->IsChild); - //Check to see if an exit can be access as both ages at both times of day - bool CheckAllAccess(RandomizerRegion exitKey); + // set back age variables + logic->IsChild = pastChild; + logic->IsAdult = pastAdult; - std::set GetAllAreas() const{ - return areas; - } + return hereVal; + } - RandomizerArea GetFirstArea() const{ - if (areas.empty()){ - assert(false); - return RA_NONE; - } else { - return *areas.begin(); + bool CanPlantBeanCheck() const; + bool AllAccountedFor() const; + + void ResetVariables(); + + void printAgeTimeAccess() const { + auto message = "Child Day: " + std::to_string(childDay) + + "\t" + "Child Night: " + + std::to_string(childNight) + + "\t" + "Adult Day: " + + std::to_string(adultDay) + + "\t" + "Adult Night: " + + std::to_string(adultNight); + } + + /* + * This logic covers checks that exist in the shared areas of MQ spirit from a glitchless standpoint. + * This room has Quantum logic that I am currently handling with this function, however this is NOT suitable for + glitch logic as it relies on specific ages + * In this chunk there are 3 possibilities for passing a check, but first I have to talk about parallel universes. + + * In MQ Spirit key logic, we mostly care about 2 possibilities for how the player can spend keys, creating 2 + Parralel universes + * In the first universe, the player did not enter spirit as adult until after climbing as child, thus child spends + keys linearly, only needing 2 to reach statue room. + * In the second universe, the player went in as adult, possibly out of logic, and started wasting the keys to lock + child out. + * These Universes converge when the player has 7 keys (meaning adult can no longer lock child out) and adult is + known to be able to reach Statue room. This creates "Certain Access", which is tracked seperatly for each age. + * Child Certain Access is simple, if we have 7 keys and child access, it's Certain Access. + * Adult Certain Access is also simple, adult is not key locked, so if they make it to a location, it's Certain + Access. + * Things get complicated when we handle the overlap of the 2 universes, + * though an important detail is that if we have Certain Access as either age, we don't need to checked the overlap + because overlap logic is strictly stricter than either Certain Access. + + * In order to track the first universe, the logic allows technical child access with the minimum number of keys, + and then checks in this function for if we have 7 keys to determine if that is Certain or not. + * This is for technical reasons, as areas with no access at all will simply not be checked. + * Normally we would need to do similar shenanigans to track the second universe, however adult must have go through + statue room to waste keys, + * so can go back there and get new keys for Child to use if they do, and the navigation logic for shared MQ spirit + from Statue Room is very simple for Adult. + * Additionally, we don't need to know if adult can actually reach spirit temple or climb to statue room, because if + the player can't do that, then universe 2 can't happen anyway, + * and if the player does so out of logic, they can do it again, as the only consumable used sets a permanent flag. + + * The Adult Navigation logic is as such: + * - Broken Wall room is 6 key locked, because if the player tries to spend 6 keys in a way that would block adults + access, they would have to give child access instead. + * - The child side hammer switch for the time travelling chest is 7 key locked for adult + * - Reaching gauntlets hand is 7 key locked + * - Going back into big block room is complex, but the only check there is child only so not a concern + * - Everything else is possible with basic adult movement, or is impossible for child to reach glitchlessly + * Anything 7 key locked does not need to be checked as shared, as all child access is Certain and because of this + workaround we don't need to fake Adult access, meaning that is also Certain. + * All of this combined means that when checking if adult can reach a location in universe 2, we only have to ask if + it is a 6 key locked location or not. + + * Knowing all of this this, we can confirm things are logical in 3 different ways: + * - If we have Adult Access, we know it is Certain Access, so they can get checks alone. + * - If we have 7 keys, child has Certain Access as we know they cannot be locked out, so can get checks alone, + otherwise we check the logical overlap + * - If Child and Adult can get the check (ignoring actual adult access to the location), and the location is either + not 6 key locked or we have 6 keys, we can get the check with the overlap + */ + bool MQSpiritShared(ConditionFn condition, bool IsBrokenWall, bool anyAge = false) { + // if we have Certain Access as child, we can check anyAge and if true, resolve a condition with Here as if + // adult is here it's also Certain Access + if (logic->SmallKeys(RR_SPIRIT_TEMPLE, 7)) { + if (anyAge) { + return Here(condition); } - } - - void ReplaceAreas(std::set newAreas) { - areas = newAreas; - } - - //Here checks conditional access based on whether or not both ages have - //access to this area. For example: if there are rocks that block a path - //which both child and adult can access, adult having hammer can give - //both child and adult access to the path. - bool Here(ConditionFn condition) { - //store current age variables + return condition(); + // else, if we are here as adult, we have Certain Access from that and don't need special handling for + // checking adult + } else if (Adult() && logic->IsAdult) { + return condition(); + // if we do not have Certain Access, we need to check the overlap by seeing if we are both here as child and + // meet the adult universe's access condition We only need to do it as child, as only child access matters + // for this check, as adult access is assumed based on keys + } else if (Child() && logic->IsChild && (!IsBrokenWall || logic->SmallKeys(RR_SPIRIT_TEMPLE, 6))) { + bool result = false; + // store current age variables bool pastAdult = logic->IsAdult; bool pastChild = logic->IsChild; - //set age access as this areas ages - logic->IsChild = Child(); - logic->IsAdult = Adult(); + // First check if the check is possible as child + logic->IsChild = true; + logic->IsAdult = false; + result = condition(); + // If so, check again as adult. both have to be true for result to be true + if (result) { + logic->IsChild = false; + logic->IsAdult = true; + result = condition(); + } - //heck condition as well as having at least child or adult access - bool hereVal = condition() && (logic->IsAdult || logic->IsChild); - - //set back age variables + // set back age variables logic->IsChild = pastChild; logic->IsAdult = pastAdult; - - return hereVal; - } - - bool CanPlantBeanCheck() const; - bool AllAccountedFor() const; - - void ResetVariables(); - - void printAgeTimeAccess() const { - auto message = "Child Day: " + std::to_string(childDay) + "\t" - "Child Night: " + std::to_string(childNight) + "\t" - "Adult Day: " + std::to_string(adultDay) + "\t" - "Adult Night: " + std::to_string(adultNight); - } - - /* - * This logic covers checks that exist in the shared areas of MQ spirit from a glitchless standpoint. - * This room has Quantum logic that I am currently handling with this function, however this is NOT suitable for glitch logic as it relies on specific ages - * In this chunk there are 3 possibilities for passing a check, but first I have to talk about parallel universes. - - * In MQ Spirit key logic, we mostly care about 2 possibilities for how the player can spend keys, creating 2 Parralel universes - * In the first universe, the player did not enter spirit as adult until after climbing as child, thus child spends keys linearly, only needing 2 to reach statue room. - * In the second universe, the player went in as adult, possibly out of logic, and started wasting the keys to lock child out. - * These Universes converge when the player has 7 keys (meaning adult can no longer lock child out) and adult is known to be able to reach Statue room. This creates "Certain Access", which is tracked seperatly for each age. - * Child Certain Access is simple, if we have 7 keys and child access, it's Certain Access. - * Adult Certain Access is also simple, adult is not key locked, so if they make it to a location, it's Certain Access. - * Things get complicated when we handle the overlap of the 2 universes, - * though an important detail is that if we have Certain Access as either age, we don't need to checked the overlap because overlap logic is strictly stricter than either Certain Access. - - * In order to track the first universe, the logic allows technical child access with the minimum number of keys, and then checks in this function for if we have 7 keys to determine if that is Certain or not. - * This is for technical reasons, as areas with no access at all will simply not be checked. - * Normally we would need to do similar shenanigans to track the second universe, however adult must have go through statue room to waste keys, - * so can go back there and get new keys for Child to use if they do, and the navigation logic for shared MQ spirit from Statue Room is very simple for Adult. - * Additionally, we don't need to know if adult can actually reach spirit temple or climb to statue room, because if the player can't do that, then universe 2 can't happen anyway, - * and if the player does so out of logic, they can do it again, as the only consumable used sets a permanent flag. - - * The Adult Navigation logic is as such: - * - Broken Wall room is 6 key locked, because if the player tries to spend 6 keys in a way that would block adults access, they would have to give child access instead. - * - The child side hammer switch for the time travelling chest is 7 key locked for adult - * - Reaching gauntlets hand is 7 key locked - * - Going back into big block room is complex, but the only check there is child only so not a concern - * - Everything else is possible with basic adult movement, or is impossible for child to reach glitchlessly - * Anything 7 key locked does not need to be checked as shared, as all child access is Certain and because of this workaround we don't need to fake Adult access, meaning that is also Certain. - * All of this combined means that when checking if adult can reach a location in universe 2, we only have to ask if it is a 6 key locked location or not. - - * Knowing all of this this, we can confirm things are logical in 3 different ways: - * - If we have Adult Access, we know it is Certain Access, so they can get checks alone. - * - If we have 7 keys, child has Certain Access as we know they cannot be locked out, so can get checks alone, otherwise we check the logical overlap - * - If Child and Adult can get the check (ignoring actual adult access to the location), and the location is either not 6 key locked or we have 6 keys, we can get the check with the overlap - */ - bool MQSpiritShared(ConditionFn condition, bool IsBrokenWall, bool anyAge = false) { - //if we have Certain Access as child, we can check anyAge and if true, resolve a condition with Here as if adult is here it's also Certain Access - if (logic->SmallKeys(RR_SPIRIT_TEMPLE, 7)){ - if (anyAge){ - return Here(condition); - } - return condition(); - //else, if we are here as adult, we have Certain Access from that and don't need special handling for checking adult - } else if (Adult() && logic->IsAdult){ - return condition(); - //if we do not have Certain Access, we need to check the overlap by seeing if we are both here as child and meet the adult universe's access condition - //We only need to do it as child, as only child access matters for this check, as adult access is assumed based on keys - } else if (Child() && logic->IsChild && (!IsBrokenWall || logic->SmallKeys(RR_SPIRIT_TEMPLE, 6))) { - bool result = false; - //store current age variables - bool pastAdult = logic->IsAdult; - bool pastChild = logic->IsChild; - - //First check if the check is possible as child - logic->IsChild = true; - logic->IsAdult = false; - result = condition(); - //If so, check again as adult. both have to be true for result to be true - if (result) { - logic->IsChild = false; - logic->IsAdult = true; - result = condition(); - } - - //set back age variables - logic->IsChild = pastChild; - logic->IsAdult = pastAdult; - return result; - } - return false; + return result; } + return false; + } }; extern std::array areaTable; extern std::vector grottoEvents; -bool Here(const RandomizerRegion region, ConditionFn condition); //RANDOTODO make a less stupid way to check own at either age than self referencing with this +bool Here(const RandomizerRegion region, + ConditionFn + condition); // RANDOTODO make a less stupid way to check own at either age than self referencing with this bool MQSpiritSharedStatueRoom(const RandomizerRegion region, ConditionFn condition, bool anyAge = false); bool MQSpiritSharedBrokenWallRoom(const RandomizerRegion region, ConditionFn condition, bool anyAge = false); bool CanPlantBean(const RandomizerRegion region); @@ -311,13 +341,13 @@ bool HasAccessTo(const RandomizerRegion region); #define NO_DAY_NIGHT_CYCLE false namespace Regions { - extern void AccessReset(); - extern void ResetAllLocations(); - extern bool HasTimePassAccess(uint8_t age); - extern void DumpWorldGraph(std::string str); -} //namespace Exits +extern void AccessReset(); +extern void ResetAllLocations(); +extern bool HasTimePassAccess(uint8_t age); +extern void DumpWorldGraph(std::string str); +} // namespace Regions -void RegionTable_Init(); +void RegionTable_Init(); Region* RegionTable(const RandomizerRegion regionKey); std::vector GetShuffleableEntrances(Rando::EntranceType type, bool onlyPrimary = true); Rando::Entrance* GetEntrance(const std::string name); diff --git a/soh/soh/Enhancements/randomizer/location_list.cpp b/soh/soh/Enhancements/randomizer/location_list.cpp index 2fb191a11..7b671994a 100644 --- a/soh/soh/Enhancements/randomizer/location_list.cpp +++ b/soh/soh/Enhancements/randomizer/location_list.cpp @@ -8,8 +8,7 @@ std::multimap, RandomizerCheck> Rando::StaticData::Che std::vector Rando::StaticData::dungeonRewardLocations = { // Bosses - RC_QUEEN_GOHMA, RC_KING_DODONGO, RC_BARINADE, - RC_PHANTOM_GANON, RC_VOLVAGIA, RC_MORPHA, RC_TWINROVA, RC_BONGO_BONGO, + RC_QUEEN_GOHMA, RC_KING_DODONGO, RC_BARINADE, RC_PHANTOM_GANON, RC_VOLVAGIA, RC_MORPHA, RC_TWINROVA, RC_BONGO_BONGO, }; using namespace Rando; @@ -17,7 +16,8 @@ using namespace Rando; std::vector Rando::StaticData::GetPondFishLocations() { std::vector pondFishLocations = {}; for (Location& location : locationTable) { - if (location.GetRCType() == RCTYPE_FISH && location.GetScene() == SCENE_FISHING_POND && location.GetRandomizerCheck() != RC_UNKNOWN_CHECK) { + if (location.GetRCType() == RCTYPE_FISH && location.GetScene() == SCENE_FISHING_POND && + location.GetRandomizerCheck() != RC_UNKNOWN_CHECK) { pondFishLocations.push_back(location.GetRandomizerCheck()); } } @@ -26,7 +26,8 @@ std::vector Rando::StaticData::GetPondFishLocations() { std::vector Rando::StaticData::GetOverworldFishLocations() { std::vector overworldFishLocations = {}; for (Location& location : locationTable) { - if (location.GetRCType() == RCTYPE_FISH && location.GetScene() != SCENE_FISHING_POND && location.GetRandomizerCheck() != RC_UNKNOWN_CHECK) { + if (location.GetRCType() == RCTYPE_FISH && location.GetScene() != SCENE_FISHING_POND && + location.GetRandomizerCheck() != RC_UNKNOWN_CHECK) { overworldFishLocations.push_back(location.GetRandomizerCheck()); } } diff --git a/soh/soh/Enhancements/randomizer/logic.cpp b/soh/soh/Enhancements/randomizer/logic.cpp index a567cd789..4a1ede8e7 100644 --- a/soh/soh/Enhancements/randomizer/logic.cpp +++ b/soh/soh/Enhancements/randomizer/logic.cpp @@ -21,794 +21,857 @@ namespace Rando { - bool Logic::HasItem(RandomizerGet itemName) { - switch (itemName) { - case RG_FAIRY_OCARINA: - return CheckInventory(ITEM_OCARINA_FAIRY, false); - case RG_OCARINA_OF_TIME: - return CheckInventory(ITEM_OCARINA_TIME, true); - case RG_DINS_FIRE: - return CheckInventory(ITEM_DINS_FIRE, true); - case RG_FARORES_WIND: - return CheckInventory(ITEM_FARORES_WIND, true); - case RG_NAYRUS_LOVE: - return CheckInventory(ITEM_NAYRUS_LOVE, true); - case RG_LENS_OF_TRUTH: - return CheckInventory(ITEM_LENS, true); - case RG_FAIRY_BOW: - return CheckInventory(ITEM_BOW, true); - case RG_MEGATON_HAMMER: - return CheckInventory(ITEM_HAMMER, true); - case RG_HOOKSHOT: - return CheckInventory(ITEM_HOOKSHOT, false); - case RG_LONGSHOT: - return CheckInventory(ITEM_LONGSHOT, true); - case RG_PROGRESSIVE_STICK_UPGRADE: - case RG_STICKS: - return CurrentUpgrade(UPG_STICKS); - case RG_FIRE_ARROWS: - return CheckInventory(ITEM_ARROW_FIRE, true); - case RG_ICE_ARROWS: - return CheckInventory(ITEM_ARROW_ICE, true); - case RG_LIGHT_ARROWS: - return CheckInventory(ITEM_ARROW_LIGHT, true); - case RG_PROGRESSIVE_BOMBCHUS: - case RG_BOMBCHU_5: - case RG_BOMBCHU_10: - case RG_BOMBCHU_20: - return (BombchusEnabled() && (GetInLogic(LOGIC_BUY_BOMBCHUS) || CouldPlayBowling || CarpetMerchant)) || CheckInventory(ITEM_BOMBCHU, true); - case RG_FAIRY_SLINGSHOT: - return CheckInventory(ITEM_SLINGSHOT, true); - case RG_BOOMERANG: - return CheckInventory(ITEM_BOOMERANG, true); - case RG_PROGRESSIVE_NUT_UPGRADE: - case RG_NUTS: - return CurrentUpgrade(UPG_NUTS); - //RANDOTODO handle cases where the scarecrow is persistent between age better when OI is added - case RG_SCARECROW: - return ScarecrowsSong() && CanUse(RG_HOOKSHOT); - case RG_DISTANT_SCARECROW: - return ScarecrowsSong() && CanUse(RG_LONGSHOT); - case RG_MAGIC_BEAN: - return GetAmmo(ITEM_BEAN) > 0; - case RG_KOKIRI_SWORD: - case RG_DEKU_SHIELD: - case RG_GORON_TUNIC: - case RG_ZORA_TUNIC: - case RG_HYLIAN_SHIELD: - case RG_MIRROR_SHIELD: - case RG_MASTER_SWORD: - case RG_BIGGORON_SWORD: - case RG_IRON_BOOTS: - case RG_HOVER_BOOTS: - return CheckEquipment(RandoGetToEquipFlag.at(itemName)); - case RG_GORONS_BRACELET: - return CurrentUpgrade(UPG_STRENGTH); - case RG_SILVER_GAUNTLETS: - return CurrentUpgrade(UPG_STRENGTH) >= 2; - case RG_GOLDEN_GAUNTLETS: - return CurrentUpgrade(UPG_STRENGTH) >= 3; - case RG_PROGRESSIVE_BOMB_BAG: - case RG_BOMB_BAG: - return CurrentUpgrade(UPG_BOMB_BAG); - case RG_MAGIC_SINGLE: - return GetSaveContext()->magicLevel >= 1 || GetSaveContext()->isMagicAcquired; - // Songs - case RG_ZELDAS_LULLABY: - case RG_EPONAS_SONG: - case RG_SARIAS_SONG: - case RG_SUNS_SONG: - case RG_SONG_OF_TIME: - case RG_SONG_OF_STORMS: - case RG_MINUET_OF_FOREST: - case RG_BOLERO_OF_FIRE: - case RG_SERENADE_OF_WATER: - case RG_REQUIEM_OF_SPIRIT: - case RG_NOCTURNE_OF_SHADOW: - case RG_PRELUDE_OF_LIGHT: - // Dungeon Rewards - case RG_KOKIRI_EMERALD: - case RG_GORON_RUBY: - case RG_ZORA_SAPPHIRE: - case RG_FOREST_MEDALLION: - case RG_FIRE_MEDALLION: - case RG_WATER_MEDALLION: - case RG_SPIRIT_MEDALLION: - case RG_SHADOW_MEDALLION: - case RG_LIGHT_MEDALLION: - // Misc Quest Items - case RG_STONE_OF_AGONY: - case RG_GERUDO_MEMBERSHIP_CARD: - return CheckQuestItem(RandoGetToQuestItem.at(itemName)); - case RG_RUTOS_LETTER: - return CheckEventChkInf(EVENTCHKINF_OBTAINED_RUTOS_LETTER); - case RG_DOUBLE_DEFENSE: - return GetSaveContext()->isDoubleDefenseAcquired; - case RG_FISHING_POLE: - case RG_ZELDAS_LETTER: - case RG_WEIRD_EGG: - case RG_GREG_RUPEE: - // Ocarina Buttons - case RG_OCARINA_A_BUTTON: - case RG_OCARINA_C_LEFT_BUTTON: - case RG_OCARINA_C_RIGHT_BUTTON: - case RG_OCARINA_C_DOWN_BUTTON: - case RG_OCARINA_C_UP_BUTTON: - // Boss Souls - case RG_GOHMA_SOUL: - case RG_KING_DODONGO_SOUL: - case RG_BARINADE_SOUL: - case RG_PHANTOM_GANON_SOUL: - case RG_VOLVAGIA_SOUL: - case RG_MORPHA_SOUL: - case RG_BONGO_BONGO_SOUL: - case RG_TWINROVA_SOUL: - case RG_GANON_SOUL: - case RG_SKELETON_KEY: - // Overworld Keys - case RG_GUARD_HOUSE_KEY: - case RG_MARKET_BAZAAR_KEY: - case RG_MARKET_POTION_SHOP_KEY: - case RG_MASK_SHOP_KEY: - case RG_MARKET_SHOOTING_GALLERY_KEY: - case RG_BOMBCHU_BOWLING_KEY: - case RG_TREASURE_CHEST_GAME_BUILDING_KEY: - case RG_BOMBCHU_SHOP_KEY: - case RG_RICHARDS_HOUSE_KEY: - case RG_ALLEY_HOUSE_KEY: - case RG_KAK_BAZAAR_KEY: - case RG_KAK_POTION_SHOP_KEY: - case RG_BOSS_HOUSE_KEY: - case RG_GRANNYS_POTION_SHOP_KEY: - case RG_SKULLTULA_HOUSE_KEY: - case RG_IMPAS_HOUSE_KEY: - case RG_WINDMILL_KEY: - case RG_KAK_SHOOTING_GALLERY_KEY: - case RG_DAMPES_HUT_KEY: - case RG_TALONS_HOUSE_KEY: - case RG_STABLES_KEY: - case RG_BACK_TOWER_KEY: - case RG_HYLIA_LAB_KEY: - case RG_FISHING_HOLE_KEY: - return CheckRandoInf(RandoGetToRandInf.at(itemName)); - // Boss Keys - case RG_EPONA: - return FreedEpona; - case RG_FOREST_TEMPLE_BOSS_KEY: - case RG_FIRE_TEMPLE_BOSS_KEY: - case RG_WATER_TEMPLE_BOSS_KEY: - case RG_SPIRIT_TEMPLE_BOSS_KEY: - case RG_SHADOW_TEMPLE_BOSS_KEY: - case RG_GANONS_CASTLE_BOSS_KEY: - return CheckDungeonItem(DUNGEON_KEY_BOSS, RandoGetToDungeonScene.at(itemName)); - // Maps - case RG_DEKU_TREE_MAP: - case RG_DODONGOS_CAVERN_MAP: - case RG_JABU_JABUS_BELLY_MAP: - case RG_FOREST_TEMPLE_MAP: - case RG_FIRE_TEMPLE_MAP: - case RG_WATER_TEMPLE_MAP: - case RG_SPIRIT_TEMPLE_MAP: - case RG_SHADOW_TEMPLE_MAP: - case RG_BOTTOM_OF_THE_WELL_MAP: - case RG_ICE_CAVERN_MAP: - return CheckDungeonItem(DUNGEON_MAP, RandoGetToDungeonScene.at(itemName)); - // Compasses - case RG_DEKU_TREE_COMPASS: - case RG_DODONGOS_CAVERN_COMPASS: - case RG_JABU_JABUS_BELLY_COMPASS: - case RG_FOREST_TEMPLE_COMPASS: - case RG_FIRE_TEMPLE_COMPASS: - case RG_WATER_TEMPLE_COMPASS: - case RG_SPIRIT_TEMPLE_COMPASS: - case RG_SHADOW_TEMPLE_COMPASS: - case RG_BOTTOM_OF_THE_WELL_COMPASS: - case RG_ICE_CAVERN_COMPASS: - return CheckDungeonItem(DUNGEON_COMPASS, RandoGetToDungeonScene.at(itemName)); - // Wallets - case RG_CHILD_WALLET: - return CheckRandoInf(RAND_INF_HAS_WALLET); - case RG_ADULT_WALLET: - return CurrentUpgrade(UPG_WALLET) >= 1; - case RG_GIANT_WALLET: - return CurrentUpgrade(UPG_WALLET) >= 2; - case RG_TYCOON_WALLET: - return CurrentUpgrade(UPG_WALLET) >= 3; - // Scales - case RG_BRONZE_SCALE: - return CheckRandoInf(RAND_INF_CAN_SWIM); - case RG_SILVER_SCALE: - return CurrentUpgrade(UPG_SCALE) >= 1; - case RG_GOLDEN_SCALE: - return CurrentUpgrade(UPG_SCALE) >= 2; - case RG_POCKET_EGG: - return CheckRandoInf(RAND_INF_ADULT_TRADES_HAS_POCKET_EGG); - case RG_COJIRO: - case RG_ODD_MUSHROOM: - case RG_ODD_POTION: - case RG_POACHERS_SAW: - case RG_BROKEN_SWORD: - case RG_PRESCRIPTION: - case RG_EYEBALL_FROG: - case RG_EYEDROPS: - case RG_CLAIM_CHECK: - return CheckRandoInf(itemName - RG_COJIRO + RAND_INF_ADULT_TRADES_HAS_COJIRO); - case RG_BOTTLE_WITH_BIG_POE: - case RG_BOTTLE_WITH_BLUE_FIRE: - case RG_BOTTLE_WITH_BLUE_POTION: - case RG_BOTTLE_WITH_BUGS: - case RG_BOTTLE_WITH_FAIRY: - case RG_BOTTLE_WITH_FISH: - case RG_BOTTLE_WITH_GREEN_POTION: - case RG_BOTTLE_WITH_MILK: - case RG_BOTTLE_WITH_POE: - case RG_BOTTLE_WITH_RED_POTION: - case RG_EMPTY_BOTTLE: - return HasBottle(); - default: - break; - } - SPDLOG_ERROR("HasItem reached `return false;`. Missing case for RandomizerGet of {}", static_cast(itemName)); - assert(false); - return false; - } - - //Can the passed in item be used? - //RANDOTODO catch magic items explicitly and add an assert on miss. - bool Logic::CanUse(RandomizerGet itemName) { - if (!HasItem(itemName)) - return false; - - switch (itemName) { - // Magic items - case RG_MAGIC_SINGLE: - return AmmoCanDrop || (HasBottle() && GetInLogic(LOGIC_BUY_MAGIC_POTION)); - case RG_DINS_FIRE: - case RG_FARORES_WIND: - case RG_NAYRUS_LOVE: - case RG_LENS_OF_TRUTH: - return CanUse(RG_MAGIC_SINGLE); - case RG_FIRE_ARROWS: - case RG_ICE_ARROWS: - case RG_LIGHT_ARROWS: - return CanUse(RG_MAGIC_SINGLE) && CanUse(RG_FAIRY_BOW); - - // Adult items - // TODO: Uncomment those if we ever implement more item usability settings - case RG_FAIRY_BOW: - return IsAdult && (AmmoCanDrop || GetInLogic(LOGIC_BUY_ARROW));// || BowAsChild; - case RG_MEGATON_HAMMER: - return IsAdult;// || HammerAsChild; - case RG_IRON_BOOTS: - return IsAdult;// || IronBootsAsChild; - case RG_HOVER_BOOTS: - return IsAdult;// || HoverBootsAsChild; - case RG_HOOKSHOT: - case RG_LONGSHOT: - case RG_SCARECROW: - case RG_DISTANT_SCARECROW: - return IsAdult;// || HookshotAsChild; - case RG_GORON_TUNIC: - return IsAdult;// || GoronTunicAsChild; - case RG_ZORA_TUNIC: - return IsAdult;// || ZoraTunicAsChild; - case RG_MIRROR_SHIELD: - return IsAdult;// || MirrorShieldAsChild; - case RG_MASTER_SWORD: - return IsAdult;// || MasterSwordAsChild; - case RG_BIGGORON_SWORD: - return IsAdult;// || BiggoronSwordAsChild; - case RG_SILVER_GAUNTLETS: - case RG_GOLDEN_GAUNTLETS: - // Adult Trade - case RG_POCKET_EGG: - case RG_COJIRO: - case RG_ODD_MUSHROOM: - case RG_ODD_POTION: - case RG_POACHERS_SAW: - case RG_BROKEN_SWORD: - case RG_PRESCRIPTION: - case RG_EYEBALL_FROG: - case RG_EYEDROPS: - case RG_CLAIM_CHECK: - return IsAdult; - - // Child items - case RG_FAIRY_SLINGSHOT: - return IsChild && (AmmoCanDrop || GetInLogic(LOGIC_BUY_SEED));// || SlingshotAsAdult; - case RG_BOOMERANG: - return IsChild;// || BoomerangAsAdult; - case RG_KOKIRI_SWORD: - return IsChild;// || KokiriSwordAsAdult; - case RG_NUTS: - return (NutPot || NutCrate || DekuBabaNuts) && AmmoCanDrop; //RANDOTODO BuyNuts currently mixed in with Nuts, should be seperate as BuyNuts are also a Nuts source - case RG_STICKS: - return IsChild /* || StickAsAdult;*/&& (StickPot || DekuBabaSticks); - case RG_DEKU_SHIELD: - return IsChild;// || DekuShieldAsAdult; - case RG_PROGRESSIVE_BOMB_BAG: - case RG_BOMB_BAG: - return AmmoCanDrop || GetInLogic(LOGIC_BUY_BOMB); - case RG_PROGRESSIVE_BOMBCHUS: - case RG_BOMBCHU_5: - case RG_BOMBCHU_10: - case RG_BOMBCHU_20: - return BombchuRefill() && BombchusEnabled(); - case RG_WEIRD_EGG: - case RG_RUTOS_LETTER: - return IsChild; - case RG_MAGIC_BEAN: - return IsChild; - +bool Logic::HasItem(RandomizerGet itemName) { + switch (itemName) { + case RG_FAIRY_OCARINA: + return CheckInventory(ITEM_OCARINA_FAIRY, false); + case RG_OCARINA_OF_TIME: + return CheckInventory(ITEM_OCARINA_TIME, true); + case RG_DINS_FIRE: + return CheckInventory(ITEM_DINS_FIRE, true); + case RG_FARORES_WIND: + return CheckInventory(ITEM_FARORES_WIND, true); + case RG_NAYRUS_LOVE: + return CheckInventory(ITEM_NAYRUS_LOVE, true); + case RG_LENS_OF_TRUTH: + return CheckInventory(ITEM_LENS, true); + case RG_FAIRY_BOW: + return CheckInventory(ITEM_BOW, true); + case RG_MEGATON_HAMMER: + return CheckInventory(ITEM_HAMMER, true); + case RG_HOOKSHOT: + return CheckInventory(ITEM_HOOKSHOT, false); + case RG_LONGSHOT: + return CheckInventory(ITEM_LONGSHOT, true); + case RG_PROGRESSIVE_STICK_UPGRADE: + case RG_STICKS: + return CurrentUpgrade(UPG_STICKS); + case RG_FIRE_ARROWS: + return CheckInventory(ITEM_ARROW_FIRE, true); + case RG_ICE_ARROWS: + return CheckInventory(ITEM_ARROW_ICE, true); + case RG_LIGHT_ARROWS: + return CheckInventory(ITEM_ARROW_LIGHT, true); + case RG_PROGRESSIVE_BOMBCHUS: + case RG_BOMBCHU_5: + case RG_BOMBCHU_10: + case RG_BOMBCHU_20: + return (BombchusEnabled() && (GetInLogic(LOGIC_BUY_BOMBCHUS) || CouldPlayBowling || CarpetMerchant)) || + CheckInventory(ITEM_BOMBCHU, true); + case RG_FAIRY_SLINGSHOT: + return CheckInventory(ITEM_SLINGSHOT, true); + case RG_BOOMERANG: + return CheckInventory(ITEM_BOOMERANG, true); + case RG_PROGRESSIVE_NUT_UPGRADE: + case RG_NUTS: + return CurrentUpgrade(UPG_NUTS); + // RANDOTODO handle cases where the scarecrow is persistent between age better when OI is added + case RG_SCARECROW: + return ScarecrowsSong() && CanUse(RG_HOOKSHOT); + case RG_DISTANT_SCARECROW: + return ScarecrowsSong() && CanUse(RG_LONGSHOT); + case RG_MAGIC_BEAN: + return GetAmmo(ITEM_BEAN) > 0; + case RG_KOKIRI_SWORD: + case RG_DEKU_SHIELD: + case RG_GORON_TUNIC: + case RG_ZORA_TUNIC: + case RG_HYLIAN_SHIELD: + case RG_MIRROR_SHIELD: + case RG_MASTER_SWORD: + case RG_BIGGORON_SWORD: + case RG_IRON_BOOTS: + case RG_HOVER_BOOTS: + return CheckEquipment(RandoGetToEquipFlag.at(itemName)); + case RG_GORONS_BRACELET: + return CurrentUpgrade(UPG_STRENGTH); + case RG_SILVER_GAUNTLETS: + return CurrentUpgrade(UPG_STRENGTH) >= 2; + case RG_GOLDEN_GAUNTLETS: + return CurrentUpgrade(UPG_STRENGTH) >= 3; + case RG_PROGRESSIVE_BOMB_BAG: + case RG_BOMB_BAG: + return CurrentUpgrade(UPG_BOMB_BAG); + case RG_MAGIC_SINGLE: + return GetSaveContext()->magicLevel >= 1 || GetSaveContext()->isMagicAcquired; // Songs - case RG_ZELDAS_LULLABY: - case RG_EPONAS_SONG: - case RG_PRELUDE_OF_LIGHT: - return HasItem(RG_FAIRY_OCARINA) && HasItem(RG_OCARINA_C_LEFT_BUTTON) && HasItem(RG_OCARINA_C_RIGHT_BUTTON) && HasItem(RG_OCARINA_C_UP_BUTTON); - case RG_SARIAS_SONG: - return HasItem(RG_FAIRY_OCARINA) && HasItem(RG_OCARINA_C_LEFT_BUTTON) && HasItem(RG_OCARINA_C_RIGHT_BUTTON) && HasItem(RG_OCARINA_C_DOWN_BUTTON); - case RG_SUNS_SONG: - return HasItem(RG_FAIRY_OCARINA) && HasItem(RG_OCARINA_C_RIGHT_BUTTON) && HasItem(RG_OCARINA_C_UP_BUTTON) && HasItem(RG_OCARINA_C_DOWN_BUTTON); - case RG_SONG_OF_TIME: - case RG_BOLERO_OF_FIRE: - case RG_REQUIEM_OF_SPIRIT: - return HasItem(RG_FAIRY_OCARINA) && HasItem(RG_OCARINA_A_BUTTON) && HasItem(RG_OCARINA_C_RIGHT_BUTTON) && HasItem(RG_OCARINA_C_DOWN_BUTTON); - case RG_SONG_OF_STORMS: - return HasItem(RG_FAIRY_OCARINA) && HasItem(RG_OCARINA_A_BUTTON) && HasItem(RG_OCARINA_C_UP_BUTTON) && HasItem(RG_OCARINA_C_DOWN_BUTTON); - case RG_MINUET_OF_FOREST: - return HasItem(RG_FAIRY_OCARINA) && HasItem(RG_OCARINA_A_BUTTON) && HasItem(RG_OCARINA_C_LEFT_BUTTON) && HasItem(RG_OCARINA_C_RIGHT_BUTTON) && HasItem(RG_OCARINA_C_UP_BUTTON); - case RG_SERENADE_OF_WATER: - case RG_NOCTURNE_OF_SHADOW: - return HasItem(RG_FAIRY_OCARINA) && HasItem(RG_OCARINA_A_BUTTON) && HasItem(RG_OCARINA_C_LEFT_BUTTON) && HasItem(RG_OCARINA_C_RIGHT_BUTTON) && HasItem(RG_OCARINA_C_DOWN_BUTTON); - - // Misc. Items - case RG_FISHING_POLE: - return HasItem(RG_CHILD_WALLET); // as long as you have enough rubies - case RG_EPONA: - return IsAdult && CanUse(RG_EPONAS_SONG); - - // Bottle Items - case RG_BOTTLE_WITH_BUGS: - return BugShrub || WanderingBugs || BugRock || GetInLogic(LOGIC_BUGS_ACCESS); - case RG_BOTTLE_WITH_FISH: - return LoneFish || FishGroup || GetInLogic(LOGIC_FISH_ACCESS); //is there any need to care about lone vs group? - case RG_BOTTLE_WITH_BLUE_FIRE: //RANDOTODO should probably be better named - return BlueFireAccess || GetInLogic(LOGIC_BLUE_FIRE_ACCESS); - case RG_BOTTLE_WITH_FAIRY: - return FairyPot || GossipStoneFairy || BeanPlantFairy || ButterflyFairy || FreeFairies || FairyPond || GetInLogic(LOGIC_FAIRY_ACCESS); - - default: - SPDLOG_ERROR("CanUse reached `default` for {}. Assuming intention is no extra requirements for use so returning true, but HasItem should be used instead.", static_cast(itemName)); - assert(false); - return true; - } + case RG_ZELDAS_LULLABY: + case RG_EPONAS_SONG: + case RG_SARIAS_SONG: + case RG_SUNS_SONG: + case RG_SONG_OF_TIME: + case RG_SONG_OF_STORMS: + case RG_MINUET_OF_FOREST: + case RG_BOLERO_OF_FIRE: + case RG_SERENADE_OF_WATER: + case RG_REQUIEM_OF_SPIRIT: + case RG_NOCTURNE_OF_SHADOW: + case RG_PRELUDE_OF_LIGHT: + // Dungeon Rewards + case RG_KOKIRI_EMERALD: + case RG_GORON_RUBY: + case RG_ZORA_SAPPHIRE: + case RG_FOREST_MEDALLION: + case RG_FIRE_MEDALLION: + case RG_WATER_MEDALLION: + case RG_SPIRIT_MEDALLION: + case RG_SHADOW_MEDALLION: + case RG_LIGHT_MEDALLION: + // Misc Quest Items + case RG_STONE_OF_AGONY: + case RG_GERUDO_MEMBERSHIP_CARD: + return CheckQuestItem(RandoGetToQuestItem.at(itemName)); + case RG_RUTOS_LETTER: + return CheckEventChkInf(EVENTCHKINF_OBTAINED_RUTOS_LETTER); + case RG_DOUBLE_DEFENSE: + return GetSaveContext()->isDoubleDefenseAcquired; + case RG_FISHING_POLE: + case RG_ZELDAS_LETTER: + case RG_WEIRD_EGG: + case RG_GREG_RUPEE: + // Ocarina Buttons + case RG_OCARINA_A_BUTTON: + case RG_OCARINA_C_LEFT_BUTTON: + case RG_OCARINA_C_RIGHT_BUTTON: + case RG_OCARINA_C_DOWN_BUTTON: + case RG_OCARINA_C_UP_BUTTON: + // Boss Souls + case RG_GOHMA_SOUL: + case RG_KING_DODONGO_SOUL: + case RG_BARINADE_SOUL: + case RG_PHANTOM_GANON_SOUL: + case RG_VOLVAGIA_SOUL: + case RG_MORPHA_SOUL: + case RG_BONGO_BONGO_SOUL: + case RG_TWINROVA_SOUL: + case RG_GANON_SOUL: + case RG_SKELETON_KEY: + // Overworld Keys + case RG_GUARD_HOUSE_KEY: + case RG_MARKET_BAZAAR_KEY: + case RG_MARKET_POTION_SHOP_KEY: + case RG_MASK_SHOP_KEY: + case RG_MARKET_SHOOTING_GALLERY_KEY: + case RG_BOMBCHU_BOWLING_KEY: + case RG_TREASURE_CHEST_GAME_BUILDING_KEY: + case RG_BOMBCHU_SHOP_KEY: + case RG_RICHARDS_HOUSE_KEY: + case RG_ALLEY_HOUSE_KEY: + case RG_KAK_BAZAAR_KEY: + case RG_KAK_POTION_SHOP_KEY: + case RG_BOSS_HOUSE_KEY: + case RG_GRANNYS_POTION_SHOP_KEY: + case RG_SKULLTULA_HOUSE_KEY: + case RG_IMPAS_HOUSE_KEY: + case RG_WINDMILL_KEY: + case RG_KAK_SHOOTING_GALLERY_KEY: + case RG_DAMPES_HUT_KEY: + case RG_TALONS_HOUSE_KEY: + case RG_STABLES_KEY: + case RG_BACK_TOWER_KEY: + case RG_HYLIA_LAB_KEY: + case RG_FISHING_HOLE_KEY: + return CheckRandoInf(RandoGetToRandInf.at(itemName)); + // Boss Keys + case RG_EPONA: + return FreedEpona; + case RG_FOREST_TEMPLE_BOSS_KEY: + case RG_FIRE_TEMPLE_BOSS_KEY: + case RG_WATER_TEMPLE_BOSS_KEY: + case RG_SPIRIT_TEMPLE_BOSS_KEY: + case RG_SHADOW_TEMPLE_BOSS_KEY: + case RG_GANONS_CASTLE_BOSS_KEY: + return CheckDungeonItem(DUNGEON_KEY_BOSS, RandoGetToDungeonScene.at(itemName)); + // Maps + case RG_DEKU_TREE_MAP: + case RG_DODONGOS_CAVERN_MAP: + case RG_JABU_JABUS_BELLY_MAP: + case RG_FOREST_TEMPLE_MAP: + case RG_FIRE_TEMPLE_MAP: + case RG_WATER_TEMPLE_MAP: + case RG_SPIRIT_TEMPLE_MAP: + case RG_SHADOW_TEMPLE_MAP: + case RG_BOTTOM_OF_THE_WELL_MAP: + case RG_ICE_CAVERN_MAP: + return CheckDungeonItem(DUNGEON_MAP, RandoGetToDungeonScene.at(itemName)); + // Compasses + case RG_DEKU_TREE_COMPASS: + case RG_DODONGOS_CAVERN_COMPASS: + case RG_JABU_JABUS_BELLY_COMPASS: + case RG_FOREST_TEMPLE_COMPASS: + case RG_FIRE_TEMPLE_COMPASS: + case RG_WATER_TEMPLE_COMPASS: + case RG_SPIRIT_TEMPLE_COMPASS: + case RG_SHADOW_TEMPLE_COMPASS: + case RG_BOTTOM_OF_THE_WELL_COMPASS: + case RG_ICE_CAVERN_COMPASS: + return CheckDungeonItem(DUNGEON_COMPASS, RandoGetToDungeonScene.at(itemName)); + // Wallets + case RG_CHILD_WALLET: + return CheckRandoInf(RAND_INF_HAS_WALLET); + case RG_ADULT_WALLET: + return CurrentUpgrade(UPG_WALLET) >= 1; + case RG_GIANT_WALLET: + return CurrentUpgrade(UPG_WALLET) >= 2; + case RG_TYCOON_WALLET: + return CurrentUpgrade(UPG_WALLET) >= 3; + // Scales + case RG_BRONZE_SCALE: + return CheckRandoInf(RAND_INF_CAN_SWIM); + case RG_SILVER_SCALE: + return CurrentUpgrade(UPG_SCALE) >= 1; + case RG_GOLDEN_SCALE: + return CurrentUpgrade(UPG_SCALE) >= 2; + case RG_POCKET_EGG: + return CheckRandoInf(RAND_INF_ADULT_TRADES_HAS_POCKET_EGG); + case RG_COJIRO: + case RG_ODD_MUSHROOM: + case RG_ODD_POTION: + case RG_POACHERS_SAW: + case RG_BROKEN_SWORD: + case RG_PRESCRIPTION: + case RG_EYEBALL_FROG: + case RG_EYEDROPS: + case RG_CLAIM_CHECK: + return CheckRandoInf(itemName - RG_COJIRO + RAND_INF_ADULT_TRADES_HAS_COJIRO); + case RG_BOTTLE_WITH_BIG_POE: + case RG_BOTTLE_WITH_BLUE_FIRE: + case RG_BOTTLE_WITH_BLUE_POTION: + case RG_BOTTLE_WITH_BUGS: + case RG_BOTTLE_WITH_FAIRY: + case RG_BOTTLE_WITH_FISH: + case RG_BOTTLE_WITH_GREEN_POTION: + case RG_BOTTLE_WITH_MILK: + case RG_BOTTLE_WITH_POE: + case RG_BOTTLE_WITH_RED_POTION: + case RG_EMPTY_BOTTLE: + return HasBottle(); + default: + break; } + SPDLOG_ERROR("HasItem reached `return false;`. Missing case for RandomizerGet of {}", + static_cast(itemName)); + assert(false); + return false; +} - bool Logic::HasProjectile(HasProjectileAge age) { - return HasExplosives() || - (age == HasProjectileAge::Child && (CanUse(RG_FAIRY_SLINGSHOT) || CanUse(RG_BOOMERANG))) || - (age == HasProjectileAge::Adult && (CanUse(RG_HOOKSHOT) || CanUse(RG_FAIRY_BOW) )) || - (age == HasProjectileAge::Both && (CanUse(RG_FAIRY_SLINGSHOT) || CanUse(RG_BOOMERANG)) && (CanUse(RG_HOOKSHOT) || CanUse(RG_FAIRY_BOW))) || - (age == HasProjectileAge::Either && (CanUse(RG_FAIRY_SLINGSHOT) || CanUse(RG_BOOMERANG) || CanUse(RG_HOOKSHOT) || CanUse(RG_FAIRY_BOW))); - } - - bool Logic::HasBossSoul(RandomizerGet itemName) { - if (!ctx->GetOption(RSK_SHUFFLE_BOSS_SOULS)) { - return true; - } - switch(itemName) { - case RG_GOHMA_SOUL: - case RG_KING_DODONGO_SOUL: - case RG_BARINADE_SOUL: - case RG_PHANTOM_GANON_SOUL: - case RG_VOLVAGIA_SOUL: - case RG_MORPHA_SOUL: - case RG_BONGO_BONGO_SOUL: - case RG_TWINROVA_SOUL: - return HasItem(itemName); - case RG_GANON_SOUL: - return ctx->GetOption(RSK_SHUFFLE_BOSS_SOULS).Is(RO_BOSS_SOULS_ON_PLUS_GANON) ? HasItem(RG_GANON_SOUL) : true; - default: - return false; - } - } - - //RANDOMISERTODO intergrate into HasItem - bool Logic::CanOpenOverworldDoor(RandomizerGet key) { - if (!ctx->GetOption(RSK_LOCK_OVERWORLD_DOORS)) { - return true; - } - - if (HasItem(RG_SKELETON_KEY)) { - return true; - } - - return HasItem(key); - } - - uint8_t GetDifficultyValueFromString(Rando::Option& glitchOption) { - return 0; - } - - //todo rewrite glitch section - - bool Logic::CanEquipSwap(RandomizerGet itemName) { - if (!HasItem(itemName)) - return false; - - if (CanDoGlitch(GlitchType::EquipSwapDins) || CanDoGlitch(GlitchType::EquipSwap)) - return true; - +// Can the passed in item be used? +// RANDOTODO catch magic items explicitly and add an assert on miss. +bool Logic::CanUse(RandomizerGet itemName) { + if (!HasItem(itemName)) return false; - } - bool Logic::CanDoGlitch(GlitchType glitch) { - // TODO: Uncomment when glitches are implemented - switch(glitch) { - case GlitchType::EquipSwapDins: - return ((IsAdult && HasItem(RG_DINS_FIRE)) || (IsChild && (HasItem(RG_STICKS) || HasItem(RG_DINS_FIRE)))) && false; //GlitchEquipSwapDins; - case GlitchType::EquipSwap: // todo: add bunny hood to adult item equippable list and child trade item to child item equippable list - return ((IsAdult && (HasItem(RG_DINS_FIRE) || HasItem(RG_FARORES_WIND) || HasItem(RG_NAYRUS_LOVE))) || (IsChild && (HasItem(RG_STICKS) || - HasItem(RG_FAIRY_SLINGSHOT) || HasItem(RG_BOOMERANG) || HasBottle() || CanUse(RG_NUTS) || HasItem(RG_FAIRY_OCARINA) || HasItem(RG_LENS_OF_TRUTH) || HasExplosives() || - GetAmmo(ITEM_BEAN) > 0 || HasItem(RG_DINS_FIRE) || HasItem(RG_FARORES_WIND) || HasItem(RG_NAYRUS_LOVE)))) && false; //GlitchEquipSwap; - } + switch (itemName) { + // Magic items + case RG_MAGIC_SINGLE: + return AmmoCanDrop || (HasBottle() && GetInLogic(LOGIC_BUY_MAGIC_POTION)); + case RG_DINS_FIRE: + case RG_FARORES_WIND: + case RG_NAYRUS_LOVE: + case RG_LENS_OF_TRUTH: + return CanUse(RG_MAGIC_SINGLE); + case RG_FIRE_ARROWS: + case RG_ICE_ARROWS: + case RG_LIGHT_ARROWS: + return CanUse(RG_MAGIC_SINGLE) && CanUse(RG_FAIRY_BOW); - //Shouldn't be reached - return false; - } + // Adult items + // TODO: Uncomment those if we ever implement more item usability settings + case RG_FAIRY_BOW: + return IsAdult && (AmmoCanDrop || GetInLogic(LOGIC_BUY_ARROW)); // || BowAsChild; + case RG_MEGATON_HAMMER: + return IsAdult; // || HammerAsChild; + case RG_IRON_BOOTS: + return IsAdult; // || IronBootsAsChild; + case RG_HOVER_BOOTS: + return IsAdult; // || HoverBootsAsChild; + case RG_HOOKSHOT: + case RG_LONGSHOT: + case RG_SCARECROW: + case RG_DISTANT_SCARECROW: + return IsAdult; // || HookshotAsChild; + case RG_GORON_TUNIC: + return IsAdult; // || GoronTunicAsChild; + case RG_ZORA_TUNIC: + return IsAdult; // || ZoraTunicAsChild; + case RG_MIRROR_SHIELD: + return IsAdult; // || MirrorShieldAsChild; + case RG_MASTER_SWORD: + return IsAdult; // || MasterSwordAsChild; + case RG_BIGGORON_SWORD: + return IsAdult; // || BiggoronSwordAsChild; + case RG_SILVER_GAUNTLETS: + case RG_GOLDEN_GAUNTLETS: + // Adult Trade + case RG_POCKET_EGG: + case RG_COJIRO: + case RG_ODD_MUSHROOM: + case RG_ODD_POTION: + case RG_POACHERS_SAW: + case RG_BROKEN_SWORD: + case RG_PRESCRIPTION: + case RG_EYEBALL_FROG: + case RG_EYEDROPS: + case RG_CLAIM_CHECK: + return IsAdult; -//RANDOTODO quantity is a placeholder for proper ammo use calculation logic. in time will want updating to account for ammo capacity -//Can we kill this enemy - bool Logic::CanKillEnemy(RandomizerEnemy enemy, EnemyDistance distance, bool wallOrFloor, uint8_t quantity, bool timer, bool inWater) { - bool killed = false; - switch(enemy) { - case RE_GOLD_SKULLTULA: - switch (distance){ - case ED_CLOSE: - //hammer jumpslash cannot damage these, but hammer swing can - killed = CanUse(RG_MEGATON_HAMMER); - [[fallthrough]]; - case ED_SHORT_JUMPSLASH: - killed = killed || CanUse(RG_KOKIRI_SWORD); - [[fallthrough]]; - case ED_MASTER_SWORD_JUMPSLASH: - killed = killed || CanUse(RG_MASTER_SWORD); - [[fallthrough]]; - case ED_LONG_JUMPSLASH: - killed = killed || CanUse(RG_BIGGORON_SWORD) || CanUse(RG_STICKS); - [[fallthrough]]; - case ED_BOMB_THROW: - killed = killed || CanUse(RG_BOMB_BAG); - [[fallthrough]]; - case ED_BOOMERANG: - killed = killed || CanUse(RG_BOOMERANG) || CanUse(RG_DINS_FIRE); - [[fallthrough]]; - case ED_HOOKSHOT: - //RANDOTODO test dins and chu range in a practical example - killed = killed || CanUse(RG_HOOKSHOT); - [[fallthrough]]; - case ED_LONGSHOT: - killed = killed || CanUse(RG_LONGSHOT) || (wallOrFloor && CanUse(RG_BOMBCHU_5)); - [[fallthrough]]; - case ED_FAR: - killed = killed || CanUse(RG_FAIRY_SLINGSHOT) || CanUse(RG_FAIRY_BOW); - break; - } - return killed; - case RE_GOHMA_LARVA: - case RE_MAD_SCRUB: - case RE_DEKU_BABA: - return CanAttack(); - case RE_BIG_SKULLTULA: - switch (distance){ - case ED_CLOSE: - //hammer jumpslash cannot damage these, but hammer swing can - killed = CanUse(RG_MEGATON_HAMMER); - [[fallthrough]]; - case ED_SHORT_JUMPSLASH: - killed = killed || CanUse(RG_KOKIRI_SWORD); - [[fallthrough]]; - case ED_MASTER_SWORD_JUMPSLASH: - killed = killed || CanUse(RG_MASTER_SWORD); - [[fallthrough]]; - case ED_LONG_JUMPSLASH: - killed = killed || CanUse(RG_BIGGORON_SWORD) || CanUse(RG_STICKS); - [[fallthrough]]; - case ED_BOMB_THROW: - killed = killed || CanUse(RG_BOMB_BAG); - [[fallthrough]]; - case ED_BOOMERANG: - //RANDOTODO test dins and chu range in a practical example - killed = killed || CanUse(RG_DINS_FIRE); - [[fallthrough]]; - case ED_HOOKSHOT: - //RANDOTODO test dins and chu range in a practical example - killed = killed || CanUse(RG_HOOKSHOT) || (wallOrFloor && CanUse(RG_BOMBCHU_5)); - [[fallthrough]]; - case ED_LONGSHOT: - killed = killed || CanUse(RG_LONGSHOT); - [[fallthrough]]; - case ED_FAR: - killed = killed || CanUse(RG_FAIRY_SLINGSHOT) || CanUse(RG_FAIRY_BOW); - break; - } - return killed; - case RE_DODONGO: - return CanUse(RG_KOKIRI_SWORD) || CanUse(RG_MASTER_SWORD) || CanUse(RG_BIGGORON_SWORD) || CanUse(RG_MEGATON_HAMMER) || (quantity <= 5 && CanUse(RG_STICKS)) || HasExplosives() || CanUse(RG_FAIRY_SLINGSHOT) || CanUse(RG_FAIRY_BOW); - case RE_LIZALFOS: - return CanJumpslash() || HasExplosives() || CanUse(RG_FAIRY_SLINGSHOT) || CanUse(RG_FAIRY_BOW); - case RE_KEESE: - case RE_FIRE_KEESE: - switch (distance){ - case ED_CLOSE: - case ED_SHORT_JUMPSLASH: - killed = CanUse(RG_MEGATON_HAMMER) || CanUse(RG_KOKIRI_SWORD); - [[fallthrough]]; - case ED_MASTER_SWORD_JUMPSLASH: - killed = killed || CanUse(RG_MASTER_SWORD); - [[fallthrough]]; - case ED_LONG_JUMPSLASH: - killed = killed || CanUse(RG_BIGGORON_SWORD) || CanUse(RG_STICKS); - [[fallthrough]]; - case ED_BOMB_THROW: - //RANDOTODO test dins and chu range in a practical example - killed = killed || (!inWater && CanUse(RG_BOMB_BAG)); - [[fallthrough]]; - case ED_BOOMERANG: - //RANDOTODO test dins and chu range in a practical example - killed = killed || CanUse(RG_BOOMERANG); - [[fallthrough]]; - case ED_HOOKSHOT: - //RANDOTODO test dins, bomb and chu range in a practical example - killed = killed || CanUse(RG_HOOKSHOT) || (wallOrFloor && CanUse(RG_BOMBCHU_5)); - [[fallthrough]]; - case ED_LONGSHOT: - killed = killed || CanUse(RG_LONGSHOT); - [[fallthrough]]; - case ED_FAR: - killed = killed || CanUse(RG_FAIRY_SLINGSHOT) || CanUse(RG_FAIRY_BOW); - break; - } - return killed; - case RE_BLUE_BUBBLE: - //RANDOTODO Trick to use shield hylian shield as child to stun these guys - //RANDOTODO check hammer damage - return BlastOrSmash() || CanUse(RG_FAIRY_BOW) || ((CanJumpslashExceptHammer() || CanUse(RG_FAIRY_SLINGSHOT)) && (CanUse(RG_NUTS) || HookshotOrBoomerang() || CanStandingShield())); - case RE_DEAD_HAND: - //RANDOTODO change Dead Hand trick to be sticks Dead Hand - return CanUse(RG_KOKIRI_SWORD) || CanUse(RG_MASTER_SWORD) || CanUse(RG_BIGGORON_SWORD) || (CanUse(RG_STICKS) && ctx->GetTrickOption(RT_BOTW_CHILD_DEADHAND)); - case RE_WITHERED_DEKU_BABA: - return CanUse(RG_KOKIRI_SWORD) || CanUse(RG_MASTER_SWORD) || CanUse(RG_BIGGORON_SWORD) || CanUse(RG_BOOMERANG); - case RE_LIKE_LIKE: - case RE_FLOORMASTER: - return CanDamage(); - case RE_STALFOS: - //RANDOTODO Add trick to kill stalfos with sticks, and a second one for bombs without stunning. Higher ammo logic for bombs is also plausible - switch (distance){ - case ED_CLOSE: - case ED_SHORT_JUMPSLASH: - killed = CanUse(RG_MEGATON_HAMMER) || CanUse(RG_KOKIRI_SWORD); - [[fallthrough]]; - case ED_MASTER_SWORD_JUMPSLASH: - killed = killed || CanUse(RG_MASTER_SWORD); - [[fallthrough]]; - case ED_LONG_JUMPSLASH: - killed = killed || CanUse(RG_BIGGORON_SWORD) || (quantity <= 1 && CanUse(RG_STICKS)); - [[fallthrough]]; - case ED_BOMB_THROW: - killed = killed || (quantity <= 2 && !timer && !inWater && (CanUse(RG_NUTS) || HookshotOrBoomerang()) && CanUse(RG_BOMB_BAG)); - [[fallthrough]]; - case ED_BOOMERANG: - case ED_HOOKSHOT: - //RANDOTODO test dins and chu range in a practical example - killed = killed || (wallOrFloor && CanUse(RG_BOMBCHU_5)); - [[fallthrough]]; - case ED_LONGSHOT: - case ED_FAR: - killed = killed || CanUse(RG_FAIRY_BOW); - break; - } - return killed; - //Needs 16 bombs, but is in default logic in N64, probably because getting the hits is quite easy. - //bow and sling can wake them and damage after they shed their armour, so could reduce ammo requirements for explosives to 10. - //requires 8 sticks to kill so would be a trick unless we apply higher stick bag logic - case RE_IRON_KNUCKLE: - return CanUse(RG_KOKIRI_SWORD) || CanUse(RG_MASTER_SWORD) || CanUse(RG_BIGGORON_SWORD) || CanUse(RG_MEGATON_HAMMER) || HasExplosives(); - //To stun flare dancer with chus, you have to hit the flame under it while it is spinning. It should eventually return to spinning after dashing for a while if you miss the window - //it is possible to damage the core with explosives, but difficult to get all 4 hits in even with chus, and if it reconstructs the core heals, so it would be a trick. - //the core takes damage from hookshot even if it doesn't show - //Dins killing isn't hard, but is obscure and tight on single magic, so is a trick - case RE_FLARE_DANCER: - return CanUse(RG_MEGATON_HAMMER) || CanUse(RG_HOOKSHOT) || (HasExplosives() && (CanJumpslashExceptHammer() || CanUse(RG_FAIRY_BOW) || CanUse(RG_FAIRY_SLINGSHOT) || CanUse(RG_BOOMERANG))); - case RE_WOLFOS: - case RE_WHITE_WOLFOS: - case RE_WALLMASTER: - return CanJumpslash() || CanUse(RG_FAIRY_BOW) || CanUse(RG_FAIRY_SLINGSHOT) || CanUse(RG_BOMBCHU_5) || CanUse(RG_DINS_FIRE) || (CanUse(RG_BOMB_BAG) && (CanUse(RG_NUTS) || CanUse(RG_HOOKSHOT) || CanUse(RG_BOOMERANG))); - case RE_GERUDO_WARRIOR: - return CanJumpslash() || CanUse(RG_FAIRY_BOW) || (ctx->GetTrickOption(RT_GF_WARRIOR_WITH_DIFFICULT_WEAPON) && (CanUse(RG_FAIRY_SLINGSHOT) || CanUse(RG_BOMBCHU_5))); - case RE_GIBDO: - case RE_REDEAD: - return CanJumpslash() || CanUse(RG_DINS_FIRE); - case RE_MEG: - return CanUse(RG_FAIRY_BOW) || CanUse(RG_HOOKSHOT) || HasExplosives(); - case RE_ARMOS: - return BlastOrSmash() || CanUse(RG_MASTER_SWORD) || CanUse(RG_BIGGORON_SWORD) || CanUse(RG_STICKS) || CanUse(RG_FAIRY_BOW) || ((CanUse(RG_NUTS) || CanUse(RG_HOOKSHOT) || CanUse(RG_BOOMERANG)) && (CanUse(RG_KOKIRI_SWORD) || CanUse(RG_FAIRY_SLINGSHOT))); - case RE_GREEN_BUBBLE: - //does not technically need to be stunned to kill with dins, but the flame must be off and timing it is awkward - //Also they don't trigger the kill room in ganons MQ if they die from dins? Vanilla bug? - return CanJumpslash() || CanUse(RG_FAIRY_BOW) || CanUse(RG_FAIRY_SLINGSHOT) || HasExplosives()/* || (CanUse(RG_DINS_FIRE) && (CanUse(RG_NUTS) || CanUse(RG_HOOKSHOT) || CanUse(RG_BOOMERANG)))*/; - case RE_DINOLFOS: - //stunning + bombs is possible but painful, as it loves to dodge the bombs and hookshot. it also dodges chus but if you cook it so it detonates under the dodge it usually gets caught on landing - return CanJumpslash() || CanUse(RG_FAIRY_BOW) || CanUse(RG_FAIRY_SLINGSHOT) || (!timer && CanUse(RG_BOMBCHU_5)); - case RE_TORCH_SLUG: - return CanJumpslash() || HasExplosives() || CanUse(RG_FAIRY_BOW); - case RE_FREEZARD: - return CanUse(RG_MASTER_SWORD) || CanUse(RG_BIGGORON_SWORD) || CanUse(RG_MEGATON_HAMMER) || CanUse(RG_STICKS) || HasExplosives() || CanUse(RG_HOOKSHOT) || CanUse(RG_DINS_FIRE) || CanUse(RG_FIRE_ARROWS); - case RE_SHELL_BLADE: - return CanUse(RG_KOKIRI_SWORD) || CanUse(RG_MASTER_SWORD) || CanUse(RG_BIGGORON_SWORD) || CanUse(RG_MEGATON_HAMMER) || CanUse(RG_STICKS) || HasExplosives() || CanUse(RG_HOOKSHOT) || CanUse(RG_FAIRY_BOW) || CanUse(RG_DINS_FIRE); - case RE_SPIKE: - return CanUse(RG_MASTER_SWORD) || CanUse(RG_BIGGORON_SWORD) || CanUse(RG_MEGATON_HAMMER) || CanUse(RG_STICKS) || HasExplosives() || CanUse(RG_HOOKSHOT) || CanUse(RG_FAIRY_BOW) || CanUse(RG_DINS_FIRE); - case RE_STINGER: - switch (distance){ - case ED_CLOSE: - case ED_SHORT_JUMPSLASH: - killed = CanUse(RG_MEGATON_HAMMER) || CanUse(RG_KOKIRI_SWORD); - [[fallthrough]]; - case ED_MASTER_SWORD_JUMPSLASH: - killed = killed || CanUse(RG_MASTER_SWORD); - [[fallthrough]]; - case ED_LONG_JUMPSLASH: - killed = killed || CanUse(RG_BIGGORON_SWORD) || CanUse(RG_STICKS); - [[fallthrough]]; - case ED_BOMB_THROW: - //RANDOTODO test dins and chu range in a practical example - killed = killed || (!inWater && CanUse(RG_BOMB_BAG)); - [[fallthrough]]; - case ED_BOOMERANG: - case ED_HOOKSHOT: - //RANDOTODO test dins, bomb and chu range in a practical example - killed = killed || CanUse(RG_HOOKSHOT) || (wallOrFloor && CanUse(RG_BOMBCHU_5)); - [[fallthrough]]; - case ED_LONGSHOT: - killed = killed || CanUse(RG_LONGSHOT); - [[fallthrough]]; - case ED_FAR: - killed = killed || CanUse(RG_FAIRY_SLINGSHOT) || CanUse(RG_FAIRY_BOW); - break; - } - return killed; - case RE_BIG_OCTO: - //If chasing octo is annoying but with rolls you can catch him, and you need rang to get into this room without shenanigans anyway. Bunny makes it free - return CanUse(RG_KOKIRI_SWORD) || CanUse(RG_STICKS) || CanUse(RG_MASTER_SWORD); - case RE_GOHMA: - return HasBossSoul(RG_GOHMA_SOUL) && CanJumpslash() && - (CanUse(RG_NUTS) || CanUse(RG_FAIRY_SLINGSHOT) || CanUse(RG_FAIRY_BOW) || HookshotOrBoomerang()); - case RE_KING_DODONGO: - return HasBossSoul(RG_KING_DODONGO_SOUL) && CanJumpslash() && - (CanUse(RG_BOMB_BAG) || HasItem(RG_GORONS_BRACELET)); - case RE_BARINADE: - return HasBossSoul(RG_BARINADE_SOUL) && CanUse(RG_BOOMERANG) && CanJumpslashExceptHammer(); - case RE_PHANTOM_GANON: - return HasBossSoul(RG_PHANTOM_GANON_SOUL) && - (CanUse(RG_KOKIRI_SWORD) || CanUse(RG_MASTER_SWORD) || CanUse(RG_BIGGORON_SWORD)) && - (CanUse(RG_HOOKSHOT) || CanUse(RG_FAIRY_BOW) || CanUse(RG_FAIRY_SLINGSHOT)); - case RE_VOLVAGIA: - return HasBossSoul(RG_VOLVAGIA_SOUL) && CanUse(RG_MEGATON_HAMMER); - case RE_MORPHA: - return HasBossSoul(RG_MORPHA_SOUL) && CanUse(RG_HOOKSHOT) && - (CanUse(RG_KOKIRI_SWORD) || CanUse(RG_MASTER_SWORD) || CanUse(RG_BIGGORON_SWORD) || CanUse(RG_MEGATON_HAMMER)); - case RE_BONGO_BONGO: - return HasBossSoul(RG_BONGO_BONGO_SOUL) && - (CanUse(RG_LENS_OF_TRUTH) || ctx->GetTrickOption(RT_LENS_BONGO)) && - (CanUse(RG_KOKIRI_SWORD) || CanUse(RG_MASTER_SWORD) || CanUse(RG_BIGGORON_SWORD)) && - (CanUse(RG_HOOKSHOT) || CanUse(RG_FAIRY_BOW) || CanUse(RG_FAIRY_SLINGSHOT) || ctx->GetTrickOption(RT_SHADOW_BONGO)); - case RE_TWINROVA: - return HasBossSoul(RG_TWINROVA_SOUL) && CanUse(RG_MIRROR_SHIELD) && - (CanUse(RG_KOKIRI_SWORD) || CanUse(RG_MASTER_SWORD) || CanUse(RG_BIGGORON_SWORD) || CanUse(RG_MEGATON_HAMMER)); - case RE_GANONDORF: - // RANDOTODO: Trick to use hammer (no jumpslash) or stick (only jumpslash) instead of a sword to reflect the energy ball - // and either of them regardless of jumpslashing to damage and kill ganondorf + // Child items + case RG_FAIRY_SLINGSHOT: + return IsChild && (AmmoCanDrop || GetInLogic(LOGIC_BUY_SEED)); // || SlingshotAsAdult; + case RG_BOOMERANG: + return IsChild; // || BoomerangAsAdult; + case RG_KOKIRI_SWORD: + return IsChild; // || KokiriSwordAsAdult; + case RG_NUTS: + return (NutPot || NutCrate || DekuBabaNuts) && + AmmoCanDrop; // RANDOTODO BuyNuts currently mixed in with Nuts, should be seperate as BuyNuts are + // also a Nuts source + case RG_STICKS: + return IsChild /* || StickAsAdult;*/ && (StickPot || DekuBabaSticks); + case RG_DEKU_SHIELD: + return IsChild; // || DekuShieldAsAdult; + case RG_PROGRESSIVE_BOMB_BAG: + case RG_BOMB_BAG: + return AmmoCanDrop || GetInLogic(LOGIC_BUY_BOMB); + case RG_PROGRESSIVE_BOMBCHUS: + case RG_BOMBCHU_5: + case RG_BOMBCHU_10: + case RG_BOMBCHU_20: + return BombchuRefill() && BombchusEnabled(); + case RG_WEIRD_EGG: + case RG_RUTOS_LETTER: + return IsChild; + case RG_MAGIC_BEAN: + return IsChild; - // Bottle is not taken into account since a sword, hammer or stick are required - // for killing ganondorf and all of those can reflect the energy ball - // This will not be the case once ammo logic in taken into account as - // sticks are limited and using a bottle might become a requirement in that case - return HasBossSoul(RG_GANON_SOUL) && CanUse(RG_LIGHT_ARROWS) && (CanUse(RG_KOKIRI_SWORD) || CanUse(RG_MASTER_SWORD) || CanUse(RG_BIGGORON_SWORD)); - case RE_GANON: - return HasBossSoul(RG_GANON_SOUL) && CanUse(RG_MASTER_SWORD); - case RE_DARK_LINK: - //RANDOTODO Dark link is buggy right now, retest when he is not - return CanJumpslash() || CanUse(RG_FAIRY_BOW); - case RE_ANUBIS: - //there's a restoration that allows beating them with mirror shield + some way to trigger their attack - return HasFireSource(); - case RE_BEAMOS: - return HasExplosives(); - case RE_PURPLE_LEEVER: - //dies on it's own, so this is the conditions to spawn it (killing 10 normal leevers) - //Sticks and Ice arrows work but will need ammo capacity logic - //other methods can damage them but not kill them, and they run when hit, making them impractical - return CanUse(RG_MASTER_SWORD) || CanUse(RG_BIGGORON_SWORD); - case RE_TENTACLE: - return CanUse(RG_BOOMERANG); - case RE_BARI: - return HookshotOrBoomerang() || CanUse(RG_FAIRY_BOW) || HasExplosives() || CanUse(RG_MEGATON_HAMMER) || CanUse(RG_STICKS) || CanUse(RG_DINS_FIRE) || (TakeDamage() && (CanUse(RG_KOKIRI_SWORD) || CanUse(RG_MASTER_SWORD) || CanUse(RG_BIGGORON_SWORD))); - case RE_SHABOM: - //RANDOTODO when you add better damage logic, you can kill this by taking hits - return CanUse(RG_BOOMERANG) || CanUse(RG_NUTS) || CanJumpslash() || CanUse(RG_DINS_FIRE) || CanUse(RG_ICE_ARROWS); - case RE_OCTOROK: - return CanReflectNuts() || HookshotOrBoomerang() || CanUse(RG_FAIRY_BOW) || CanUse(RG_FAIRY_SLINGSHOT) || CanUse(RG_BOMB_BAG) || (wallOrFloor && CanUse(RG_BOMBCHU_5)); - default: - SPDLOG_ERROR("CanKillEnemy reached `default`."); - assert(false); - return false; - } - } + // Songs + case RG_ZELDAS_LULLABY: + case RG_EPONAS_SONG: + case RG_PRELUDE_OF_LIGHT: + return HasItem(RG_FAIRY_OCARINA) && HasItem(RG_OCARINA_C_LEFT_BUTTON) && + HasItem(RG_OCARINA_C_RIGHT_BUTTON) && HasItem(RG_OCARINA_C_UP_BUTTON); + case RG_SARIAS_SONG: + return HasItem(RG_FAIRY_OCARINA) && HasItem(RG_OCARINA_C_LEFT_BUTTON) && + HasItem(RG_OCARINA_C_RIGHT_BUTTON) && HasItem(RG_OCARINA_C_DOWN_BUTTON); + case RG_SUNS_SONG: + return HasItem(RG_FAIRY_OCARINA) && HasItem(RG_OCARINA_C_RIGHT_BUTTON) && HasItem(RG_OCARINA_C_UP_BUTTON) && + HasItem(RG_OCARINA_C_DOWN_BUTTON); + case RG_SONG_OF_TIME: + case RG_BOLERO_OF_FIRE: + case RG_REQUIEM_OF_SPIRIT: + return HasItem(RG_FAIRY_OCARINA) && HasItem(RG_OCARINA_A_BUTTON) && HasItem(RG_OCARINA_C_RIGHT_BUTTON) && + HasItem(RG_OCARINA_C_DOWN_BUTTON); + case RG_SONG_OF_STORMS: + return HasItem(RG_FAIRY_OCARINA) && HasItem(RG_OCARINA_A_BUTTON) && HasItem(RG_OCARINA_C_UP_BUTTON) && + HasItem(RG_OCARINA_C_DOWN_BUTTON); + case RG_MINUET_OF_FOREST: + return HasItem(RG_FAIRY_OCARINA) && HasItem(RG_OCARINA_A_BUTTON) && HasItem(RG_OCARINA_C_LEFT_BUTTON) && + HasItem(RG_OCARINA_C_RIGHT_BUTTON) && HasItem(RG_OCARINA_C_UP_BUTTON); + case RG_SERENADE_OF_WATER: + case RG_NOCTURNE_OF_SHADOW: + return HasItem(RG_FAIRY_OCARINA) && HasItem(RG_OCARINA_A_BUTTON) && HasItem(RG_OCARINA_C_LEFT_BUTTON) && + HasItem(RG_OCARINA_C_RIGHT_BUTTON) && HasItem(RG_OCARINA_C_DOWN_BUTTON); -//It is rare for Pass Enemy to need distance, this only happens when the enemy blocks a platform and you can't reach it before it blocks you -//an example is the Big Skulltula in water room of MQ deku, which is out of sword swing height but blocks off the whole SoT block -//Can we get past this enemy in a tight space? - bool Logic::CanPassEnemy(RandomizerEnemy enemy, EnemyDistance distance, bool wallOrFloor) { - if (CanKillEnemy(enemy, distance, wallOrFloor)){ + // Misc. Items + case RG_FISHING_POLE: + return HasItem(RG_CHILD_WALLET); // as long as you have enough rubies + case RG_EPONA: + return IsAdult && CanUse(RG_EPONAS_SONG); + + // Bottle Items + case RG_BOTTLE_WITH_BUGS: + return BugShrub || WanderingBugs || BugRock || GetInLogic(LOGIC_BUGS_ACCESS); + case RG_BOTTLE_WITH_FISH: + return LoneFish || FishGroup || + GetInLogic(LOGIC_FISH_ACCESS); // is there any need to care about lone vs group? + case RG_BOTTLE_WITH_BLUE_FIRE: // RANDOTODO should probably be better named + return BlueFireAccess || GetInLogic(LOGIC_BLUE_FIRE_ACCESS); + case RG_BOTTLE_WITH_FAIRY: + return FairyPot || GossipStoneFairy || BeanPlantFairy || ButterflyFairy || FreeFairies || FairyPond || + GetInLogic(LOGIC_FAIRY_ACCESS); + + default: + SPDLOG_ERROR("CanUse reached `default` for {}. Assuming intention is no extra requirements for use so " + "returning true, but HasItem should be used instead.", + static_cast(itemName)); + assert(false); return true; - } - switch(enemy) { - case RE_GOLD_SKULLTULA: - case RE_GOHMA_LARVA: - case RE_LIZALFOS: - case RE_DODONGO: //RANDOTODO do dodongos block the way in tight corridors? - case RE_MAD_SCRUB: - case RE_KEESE: - case RE_FIRE_KEESE: - case RE_BLUE_BUBBLE: - case RE_DEAD_HAND: - case RE_DEKU_BABA: - case RE_WITHERED_DEKU_BABA: - case RE_STALFOS: - case RE_FLARE_DANCER: - case RE_WOLFOS: - case RE_WHITE_WOLFOS: - case RE_FLOORMASTER: - case RE_MEG: - case RE_ARMOS: - case RE_FREEZARD: - case RE_SPIKE: - case RE_DARK_LINK: - case RE_ANUBIS: - case RE_WALLMASTER: - case RE_PURPLE_LEEVER: - case RE_OCTOROK: - return true; - case RE_BIG_SKULLTULA: - //hammer jumpslash can pass, but only on flat land where you can kill with hammer swing - return CanUse(RG_NUTS) || CanUse(RG_BOOMERANG); - case RE_LIKE_LIKE: - return CanUse(RG_HOOKSHOT) || CanUse(RG_BOOMERANG); - case RE_GIBDO: - case RE_REDEAD: - // we need a way to check if suns won't force a reload - return CanUse(RG_HOOKSHOT) || CanUse(RG_SUNS_SONG); - case RE_IRON_KNUCKLE: - case RE_BIG_OCTO: - return false; - case RE_GREEN_BUBBLE: - return TakeDamage() || CanUse(RG_NUTS) || CanUse(RG_BOOMERANG) || CanUse(RG_HOOKSHOT); - default: - SPDLOG_ERROR("CanPassEnemy reached `default`."); - assert(false); - return false; - } } +} -//Can we avoid this enemy while climbing up a wall, or doing a difficult platforming challenge? -//use grounded if the challenge is such that the enemy interfears even if it cannot hit link out of the air - bool Logic::CanAvoidEnemy(RandomizerEnemy enemy, bool grounded, uint8_t quantity) { - //DISTANCE AND WALL ASSUMED, add more arguments later if needed - if (CanKillEnemy(enemy, ED_CLOSE, true, quantity)){ +bool Logic::HasProjectile(HasProjectileAge age) { + return HasExplosives() || + (age == HasProjectileAge::Child && (CanUse(RG_FAIRY_SLINGSHOT) || CanUse(RG_BOOMERANG))) || + (age == HasProjectileAge::Adult && (CanUse(RG_HOOKSHOT) || CanUse(RG_FAIRY_BOW))) || + (age == HasProjectileAge::Both && (CanUse(RG_FAIRY_SLINGSHOT) || CanUse(RG_BOOMERANG)) && + (CanUse(RG_HOOKSHOT) || CanUse(RG_FAIRY_BOW))) || + (age == HasProjectileAge::Either && + (CanUse(RG_FAIRY_SLINGSHOT) || CanUse(RG_BOOMERANG) || CanUse(RG_HOOKSHOT) || CanUse(RG_FAIRY_BOW))); +} + +bool Logic::HasBossSoul(RandomizerGet itemName) { + if (!ctx->GetOption(RSK_SHUFFLE_BOSS_SOULS)) { return true; - } - switch(enemy) { - case RE_GOLD_SKULLTULA: + } + switch (itemName) { + case RG_GOHMA_SOUL: + case RG_KING_DODONGO_SOUL: + case RG_BARINADE_SOUL: + case RG_PHANTOM_GANON_SOUL: + case RG_VOLVAGIA_SOUL: + case RG_MORPHA_SOUL: + case RG_BONGO_BONGO_SOUL: + case RG_TWINROVA_SOUL: + return HasItem(itemName); + case RG_GANON_SOUL: + return ctx->GetOption(RSK_SHUFFLE_BOSS_SOULS).Is(RO_BOSS_SOULS_ON_PLUS_GANON) ? HasItem(RG_GANON_SOUL) + : true; + default: + return false; + } +} + +// RANDOMISERTODO intergrate into HasItem +bool Logic::CanOpenOverworldDoor(RandomizerGet key) { + if (!ctx->GetOption(RSK_LOCK_OVERWORLD_DOORS)) { + return true; + } + + if (HasItem(RG_SKELETON_KEY)) { + return true; + } + + return HasItem(key); +} + +uint8_t GetDifficultyValueFromString(Rando::Option& glitchOption) { + return 0; +} + +// todo rewrite glitch section + +bool Logic::CanEquipSwap(RandomizerGet itemName) { + if (!HasItem(itemName)) + return false; + + if (CanDoGlitch(GlitchType::EquipSwapDins) || CanDoGlitch(GlitchType::EquipSwap)) + return true; + + return false; +} + +bool Logic::CanDoGlitch(GlitchType glitch) { + // TODO: Uncomment when glitches are implemented + switch (glitch) { + case GlitchType::EquipSwapDins: + return ((IsAdult && HasItem(RG_DINS_FIRE)) || (IsChild && (HasItem(RG_STICKS) || HasItem(RG_DINS_FIRE)))) && + false; // GlitchEquipSwapDins; + case GlitchType::EquipSwap: // todo: add bunny hood to adult item equippable list and child trade item to child + // item equippable list + return ((IsAdult && (HasItem(RG_DINS_FIRE) || HasItem(RG_FARORES_WIND) || HasItem(RG_NAYRUS_LOVE))) || + (IsChild && (HasItem(RG_STICKS) || HasItem(RG_FAIRY_SLINGSHOT) || HasItem(RG_BOOMERANG) || + HasBottle() || CanUse(RG_NUTS) || HasItem(RG_FAIRY_OCARINA) || + HasItem(RG_LENS_OF_TRUTH) || HasExplosives() || GetAmmo(ITEM_BEAN) > 0 || + HasItem(RG_DINS_FIRE) || HasItem(RG_FARORES_WIND) || HasItem(RG_NAYRUS_LOVE)))) && + false; // GlitchEquipSwap; + } + + // Shouldn't be reached + return false; +} + +// RANDOTODO quantity is a placeholder for proper ammo use calculation logic. in time will want updating to account for +// ammo capacity Can we kill this enemy +bool Logic::CanKillEnemy(RandomizerEnemy enemy, EnemyDistance distance, bool wallOrFloor, uint8_t quantity, bool timer, + bool inWater) { + bool killed = false; + switch (enemy) { + case RE_GOLD_SKULLTULA: + switch (distance) { + case ED_CLOSE: + // hammer jumpslash cannot damage these, but hammer swing can + killed = CanUse(RG_MEGATON_HAMMER); + [[fallthrough]]; + case ED_SHORT_JUMPSLASH: + killed = killed || CanUse(RG_KOKIRI_SWORD); + [[fallthrough]]; + case ED_MASTER_SWORD_JUMPSLASH: + killed = killed || CanUse(RG_MASTER_SWORD); + [[fallthrough]]; + case ED_LONG_JUMPSLASH: + killed = killed || CanUse(RG_BIGGORON_SWORD) || CanUse(RG_STICKS); + [[fallthrough]]; + case ED_BOMB_THROW: + killed = killed || CanUse(RG_BOMB_BAG); + [[fallthrough]]; + case ED_BOOMERANG: + killed = killed || CanUse(RG_BOOMERANG) || CanUse(RG_DINS_FIRE); + [[fallthrough]]; + case ED_HOOKSHOT: + // RANDOTODO test dins and chu range in a practical example + killed = killed || CanUse(RG_HOOKSHOT); + [[fallthrough]]; + case ED_LONGSHOT: + killed = killed || CanUse(RG_LONGSHOT) || (wallOrFloor && CanUse(RG_BOMBCHU_5)); + [[fallthrough]]; + case ED_FAR: + killed = killed || CanUse(RG_FAIRY_SLINGSHOT) || CanUse(RG_FAIRY_BOW); + break; + } + return killed; + case RE_GOHMA_LARVA: + case RE_MAD_SCRUB: + case RE_DEKU_BABA: + return CanAttack(); + case RE_BIG_SKULLTULA: + switch (distance) { + case ED_CLOSE: + // hammer jumpslash cannot damage these, but hammer swing can + killed = CanUse(RG_MEGATON_HAMMER); + [[fallthrough]]; + case ED_SHORT_JUMPSLASH: + killed = killed || CanUse(RG_KOKIRI_SWORD); + [[fallthrough]]; + case ED_MASTER_SWORD_JUMPSLASH: + killed = killed || CanUse(RG_MASTER_SWORD); + [[fallthrough]]; + case ED_LONG_JUMPSLASH: + killed = killed || CanUse(RG_BIGGORON_SWORD) || CanUse(RG_STICKS); + [[fallthrough]]; + case ED_BOMB_THROW: + killed = killed || CanUse(RG_BOMB_BAG); + [[fallthrough]]; + case ED_BOOMERANG: + // RANDOTODO test dins and chu range in a practical example + killed = killed || CanUse(RG_DINS_FIRE); + [[fallthrough]]; + case ED_HOOKSHOT: + // RANDOTODO test dins and chu range in a practical example + killed = killed || CanUse(RG_HOOKSHOT) || (wallOrFloor && CanUse(RG_BOMBCHU_5)); + [[fallthrough]]; + case ED_LONGSHOT: + killed = killed || CanUse(RG_LONGSHOT); + [[fallthrough]]; + case ED_FAR: + killed = killed || CanUse(RG_FAIRY_SLINGSHOT) || CanUse(RG_FAIRY_BOW); + break; + } + return killed; + case RE_DODONGO: + return CanUse(RG_KOKIRI_SWORD) || CanUse(RG_MASTER_SWORD) || CanUse(RG_BIGGORON_SWORD) || + CanUse(RG_MEGATON_HAMMER) || (quantity <= 5 && CanUse(RG_STICKS)) || HasExplosives() || + CanUse(RG_FAIRY_SLINGSHOT) || CanUse(RG_FAIRY_BOW); + case RE_LIZALFOS: + return CanJumpslash() || HasExplosives() || CanUse(RG_FAIRY_SLINGSHOT) || CanUse(RG_FAIRY_BOW); + case RE_KEESE: + case RE_FIRE_KEESE: + switch (distance) { + case ED_CLOSE: + case ED_SHORT_JUMPSLASH: + killed = CanUse(RG_MEGATON_HAMMER) || CanUse(RG_KOKIRI_SWORD); + [[fallthrough]]; + case ED_MASTER_SWORD_JUMPSLASH: + killed = killed || CanUse(RG_MASTER_SWORD); + [[fallthrough]]; + case ED_LONG_JUMPSLASH: + killed = killed || CanUse(RG_BIGGORON_SWORD) || CanUse(RG_STICKS); + [[fallthrough]]; + case ED_BOMB_THROW: + // RANDOTODO test dins and chu range in a practical example + killed = killed || (!inWater && CanUse(RG_BOMB_BAG)); + [[fallthrough]]; + case ED_BOOMERANG: + // RANDOTODO test dins and chu range in a practical example + killed = killed || CanUse(RG_BOOMERANG); + [[fallthrough]]; + case ED_HOOKSHOT: + // RANDOTODO test dins, bomb and chu range in a practical example + killed = killed || CanUse(RG_HOOKSHOT) || (wallOrFloor && CanUse(RG_BOMBCHU_5)); + [[fallthrough]]; + case ED_LONGSHOT: + killed = killed || CanUse(RG_LONGSHOT); + [[fallthrough]]; + case ED_FAR: + killed = killed || CanUse(RG_FAIRY_SLINGSHOT) || CanUse(RG_FAIRY_BOW); + break; + } + return killed; + case RE_BLUE_BUBBLE: + // RANDOTODO Trick to use shield hylian shield as child to stun these guys + // RANDOTODO check hammer damage + return BlastOrSmash() || CanUse(RG_FAIRY_BOW) || + ((CanJumpslashExceptHammer() || CanUse(RG_FAIRY_SLINGSHOT)) && + (CanUse(RG_NUTS) || HookshotOrBoomerang() || CanStandingShield())); + case RE_DEAD_HAND: + // RANDOTODO change Dead Hand trick to be sticks Dead Hand + return CanUse(RG_KOKIRI_SWORD) || CanUse(RG_MASTER_SWORD) || CanUse(RG_BIGGORON_SWORD) || + (CanUse(RG_STICKS) && ctx->GetTrickOption(RT_BOTW_CHILD_DEADHAND)); + case RE_WITHERED_DEKU_BABA: + return CanUse(RG_KOKIRI_SWORD) || CanUse(RG_MASTER_SWORD) || CanUse(RG_BIGGORON_SWORD) || + CanUse(RG_BOOMERANG); + case RE_LIKE_LIKE: + case RE_FLOORMASTER: + return CanDamage(); + case RE_STALFOS: + // RANDOTODO Add trick to kill stalfos with sticks, and a second one for bombs without stunning. Higher ammo + // logic for bombs is also plausible + switch (distance) { + case ED_CLOSE: + case ED_SHORT_JUMPSLASH: + killed = CanUse(RG_MEGATON_HAMMER) || CanUse(RG_KOKIRI_SWORD); + [[fallthrough]]; + case ED_MASTER_SWORD_JUMPSLASH: + killed = killed || CanUse(RG_MASTER_SWORD); + [[fallthrough]]; + case ED_LONG_JUMPSLASH: + killed = killed || CanUse(RG_BIGGORON_SWORD) || (quantity <= 1 && CanUse(RG_STICKS)); + [[fallthrough]]; + case ED_BOMB_THROW: + killed = killed || (quantity <= 2 && !timer && !inWater && + (CanUse(RG_NUTS) || HookshotOrBoomerang()) && CanUse(RG_BOMB_BAG)); + [[fallthrough]]; + case ED_BOOMERANG: + case ED_HOOKSHOT: + // RANDOTODO test dins and chu range in a practical example + killed = killed || (wallOrFloor && CanUse(RG_BOMBCHU_5)); + [[fallthrough]]; + case ED_LONGSHOT: + case ED_FAR: + killed = killed || CanUse(RG_FAIRY_BOW); + break; + } + return killed; + // Needs 16 bombs, but is in default logic in N64, probably because getting the hits is quite easy. + // bow and sling can wake them and damage after they shed their armour, so could reduce ammo requirements for + // explosives to 10. requires 8 sticks to kill so would be a trick unless we apply higher stick bag logic + case RE_IRON_KNUCKLE: + return CanUse(RG_KOKIRI_SWORD) || CanUse(RG_MASTER_SWORD) || CanUse(RG_BIGGORON_SWORD) || + CanUse(RG_MEGATON_HAMMER) || HasExplosives(); + // To stun flare dancer with chus, you have to hit the flame under it while it is spinning. It should eventually + // return to spinning after dashing for a while if you miss the window it is possible to damage the core with + // explosives, but difficult to get all 4 hits in even with chus, and if it reconstructs the core heals, so it + // would be a trick. the core takes damage from hookshot even if it doesn't show Dins killing isn't hard, but is + // obscure and tight on single magic, so is a trick + case RE_FLARE_DANCER: + return CanUse(RG_MEGATON_HAMMER) || CanUse(RG_HOOKSHOT) || + (HasExplosives() && (CanJumpslashExceptHammer() || CanUse(RG_FAIRY_BOW) || + CanUse(RG_FAIRY_SLINGSHOT) || CanUse(RG_BOOMERANG))); + case RE_WOLFOS: + case RE_WHITE_WOLFOS: + case RE_WALLMASTER: + return CanJumpslash() || CanUse(RG_FAIRY_BOW) || CanUse(RG_FAIRY_SLINGSHOT) || CanUse(RG_BOMBCHU_5) || + CanUse(RG_DINS_FIRE) || + (CanUse(RG_BOMB_BAG) && (CanUse(RG_NUTS) || CanUse(RG_HOOKSHOT) || CanUse(RG_BOOMERANG))); + case RE_GERUDO_WARRIOR: + return CanJumpslash() || CanUse(RG_FAIRY_BOW) || + (ctx->GetTrickOption(RT_GF_WARRIOR_WITH_DIFFICULT_WEAPON) && + (CanUse(RG_FAIRY_SLINGSHOT) || CanUse(RG_BOMBCHU_5))); + case RE_GIBDO: + case RE_REDEAD: + return CanJumpslash() || CanUse(RG_DINS_FIRE); + case RE_MEG: + return CanUse(RG_FAIRY_BOW) || CanUse(RG_HOOKSHOT) || HasExplosives(); + case RE_ARMOS: + return BlastOrSmash() || CanUse(RG_MASTER_SWORD) || CanUse(RG_BIGGORON_SWORD) || CanUse(RG_STICKS) || + CanUse(RG_FAIRY_BOW) || + ((CanUse(RG_NUTS) || CanUse(RG_HOOKSHOT) || CanUse(RG_BOOMERANG)) && + (CanUse(RG_KOKIRI_SWORD) || CanUse(RG_FAIRY_SLINGSHOT))); + case RE_GREEN_BUBBLE: + // does not technically need to be stunned to kill with dins, but the flame must be off and timing it is + // awkward Also they don't trigger the kill room in ganons MQ if they die from dins? Vanilla bug? + return CanJumpslash() || CanUse(RG_FAIRY_BOW) || CanUse(RG_FAIRY_SLINGSHOT) || + HasExplosives() /* || (CanUse(RG_DINS_FIRE) && (CanUse(RG_NUTS) || CanUse(RG_HOOKSHOT) || + CanUse(RG_BOOMERANG)))*/ + ; + case RE_DINOLFOS: + // stunning + bombs is possible but painful, as it loves to dodge the bombs and hookshot. it also dodges + // chus but if you cook it so it detonates under the dodge it usually gets caught on landing + return CanJumpslash() || CanUse(RG_FAIRY_BOW) || CanUse(RG_FAIRY_SLINGSHOT) || + (!timer && CanUse(RG_BOMBCHU_5)); + case RE_TORCH_SLUG: + return CanJumpslash() || HasExplosives() || CanUse(RG_FAIRY_BOW); + case RE_FREEZARD: + return CanUse(RG_MASTER_SWORD) || CanUse(RG_BIGGORON_SWORD) || CanUse(RG_MEGATON_HAMMER) || + CanUse(RG_STICKS) || HasExplosives() || CanUse(RG_HOOKSHOT) || CanUse(RG_DINS_FIRE) || + CanUse(RG_FIRE_ARROWS); + case RE_SHELL_BLADE: + return CanUse(RG_KOKIRI_SWORD) || CanUse(RG_MASTER_SWORD) || CanUse(RG_BIGGORON_SWORD) || + CanUse(RG_MEGATON_HAMMER) || CanUse(RG_STICKS) || HasExplosives() || CanUse(RG_HOOKSHOT) || + CanUse(RG_FAIRY_BOW) || CanUse(RG_DINS_FIRE); + case RE_SPIKE: + return CanUse(RG_MASTER_SWORD) || CanUse(RG_BIGGORON_SWORD) || CanUse(RG_MEGATON_HAMMER) || + CanUse(RG_STICKS) || HasExplosives() || CanUse(RG_HOOKSHOT) || CanUse(RG_FAIRY_BOW) || + CanUse(RG_DINS_FIRE); + case RE_STINGER: + switch (distance) { + case ED_CLOSE: + case ED_SHORT_JUMPSLASH: + killed = CanUse(RG_MEGATON_HAMMER) || CanUse(RG_KOKIRI_SWORD); + [[fallthrough]]; + case ED_MASTER_SWORD_JUMPSLASH: + killed = killed || CanUse(RG_MASTER_SWORD); + [[fallthrough]]; + case ED_LONG_JUMPSLASH: + killed = killed || CanUse(RG_BIGGORON_SWORD) || CanUse(RG_STICKS); + [[fallthrough]]; + case ED_BOMB_THROW: + // RANDOTODO test dins and chu range in a practical example + killed = killed || (!inWater && CanUse(RG_BOMB_BAG)); + [[fallthrough]]; + case ED_BOOMERANG: + case ED_HOOKSHOT: + // RANDOTODO test dins, bomb and chu range in a practical example + killed = killed || CanUse(RG_HOOKSHOT) || (wallOrFloor && CanUse(RG_BOMBCHU_5)); + [[fallthrough]]; + case ED_LONGSHOT: + killed = killed || CanUse(RG_LONGSHOT); + [[fallthrough]]; + case ED_FAR: + killed = killed || CanUse(RG_FAIRY_SLINGSHOT) || CanUse(RG_FAIRY_BOW); + break; + } + return killed; + case RE_BIG_OCTO: + // If chasing octo is annoying but with rolls you can catch him, and you need rang to get into this room + // without shenanigans anyway. Bunny makes it free + return CanUse(RG_KOKIRI_SWORD) || CanUse(RG_STICKS) || CanUse(RG_MASTER_SWORD); + case RE_GOHMA: + return HasBossSoul(RG_GOHMA_SOUL) && CanJumpslash() && + (CanUse(RG_NUTS) || CanUse(RG_FAIRY_SLINGSHOT) || CanUse(RG_FAIRY_BOW) || HookshotOrBoomerang()); + case RE_KING_DODONGO: + return HasBossSoul(RG_KING_DODONGO_SOUL) && CanJumpslash() && + (CanUse(RG_BOMB_BAG) || HasItem(RG_GORONS_BRACELET)); + case RE_BARINADE: + return HasBossSoul(RG_BARINADE_SOUL) && CanUse(RG_BOOMERANG) && CanJumpslashExceptHammer(); + case RE_PHANTOM_GANON: + return HasBossSoul(RG_PHANTOM_GANON_SOUL) && + (CanUse(RG_KOKIRI_SWORD) || CanUse(RG_MASTER_SWORD) || CanUse(RG_BIGGORON_SWORD)) && + (CanUse(RG_HOOKSHOT) || CanUse(RG_FAIRY_BOW) || CanUse(RG_FAIRY_SLINGSHOT)); + case RE_VOLVAGIA: + return HasBossSoul(RG_VOLVAGIA_SOUL) && CanUse(RG_MEGATON_HAMMER); + case RE_MORPHA: + return HasBossSoul(RG_MORPHA_SOUL) && CanUse(RG_HOOKSHOT) && + (CanUse(RG_KOKIRI_SWORD) || CanUse(RG_MASTER_SWORD) || CanUse(RG_BIGGORON_SWORD) || + CanUse(RG_MEGATON_HAMMER)); + case RE_BONGO_BONGO: + return HasBossSoul(RG_BONGO_BONGO_SOUL) && + (CanUse(RG_LENS_OF_TRUTH) || ctx->GetTrickOption(RT_LENS_BONGO)) && + (CanUse(RG_KOKIRI_SWORD) || CanUse(RG_MASTER_SWORD) || CanUse(RG_BIGGORON_SWORD)) && + (CanUse(RG_HOOKSHOT) || CanUse(RG_FAIRY_BOW) || CanUse(RG_FAIRY_SLINGSHOT) || + ctx->GetTrickOption(RT_SHADOW_BONGO)); + case RE_TWINROVA: + return HasBossSoul(RG_TWINROVA_SOUL) && CanUse(RG_MIRROR_SHIELD) && + (CanUse(RG_KOKIRI_SWORD) || CanUse(RG_MASTER_SWORD) || CanUse(RG_BIGGORON_SWORD) || + CanUse(RG_MEGATON_HAMMER)); + case RE_GANONDORF: + // RANDOTODO: Trick to use hammer (no jumpslash) or stick (only jumpslash) instead of a sword to reflect the + // energy ball and either of them regardless of jumpslashing to damage and kill ganondorf + + // Bottle is not taken into account since a sword, hammer or stick are required + // for killing ganondorf and all of those can reflect the energy ball + // This will not be the case once ammo logic in taken into account as + // sticks are limited and using a bottle might become a requirement in that case + return HasBossSoul(RG_GANON_SOUL) && CanUse(RG_LIGHT_ARROWS) && + (CanUse(RG_KOKIRI_SWORD) || CanUse(RG_MASTER_SWORD) || CanUse(RG_BIGGORON_SWORD)); + case RE_GANON: + return HasBossSoul(RG_GANON_SOUL) && CanUse(RG_MASTER_SWORD); + case RE_DARK_LINK: + // RANDOTODO Dark link is buggy right now, retest when he is not + return CanJumpslash() || CanUse(RG_FAIRY_BOW); + case RE_ANUBIS: + // there's a restoration that allows beating them with mirror shield + some way to trigger their attack + return HasFireSource(); + case RE_BEAMOS: + return HasExplosives(); + case RE_PURPLE_LEEVER: + // dies on it's own, so this is the conditions to spawn it (killing 10 normal leevers) + // Sticks and Ice arrows work but will need ammo capacity logic + // other methods can damage them but not kill them, and they run when hit, making them impractical + return CanUse(RG_MASTER_SWORD) || CanUse(RG_BIGGORON_SWORD); + case RE_TENTACLE: + return CanUse(RG_BOOMERANG); + case RE_BARI: + return HookshotOrBoomerang() || CanUse(RG_FAIRY_BOW) || HasExplosives() || CanUse(RG_MEGATON_HAMMER) || + CanUse(RG_STICKS) || CanUse(RG_DINS_FIRE) || + (TakeDamage() && (CanUse(RG_KOKIRI_SWORD) || CanUse(RG_MASTER_SWORD) || CanUse(RG_BIGGORON_SWORD))); + case RE_SHABOM: + // RANDOTODO when you add better damage logic, you can kill this by taking hits + return CanUse(RG_BOOMERANG) || CanUse(RG_NUTS) || CanJumpslash() || CanUse(RG_DINS_FIRE) || + CanUse(RG_ICE_ARROWS); + case RE_OCTOROK: + return CanReflectNuts() || HookshotOrBoomerang() || CanUse(RG_FAIRY_BOW) || CanUse(RG_FAIRY_SLINGSHOT) || + CanUse(RG_BOMB_BAG) || (wallOrFloor && CanUse(RG_BOMBCHU_5)); + default: + SPDLOG_ERROR("CanKillEnemy reached `default`."); + assert(false); + return false; + } +} + +// It is rare for Pass Enemy to need distance, this only happens when the enemy blocks a platform and you can't reach it +// before it blocks you an example is the Big Skulltula in water room of MQ deku, which is out of sword swing height but +// blocks off the whole SoT block Can we get past this enemy in a tight space? +bool Logic::CanPassEnemy(RandomizerEnemy enemy, EnemyDistance distance, bool wallOrFloor) { + if (CanKillEnemy(enemy, distance, wallOrFloor)) { + return true; + } + switch (enemy) { + case RE_GOLD_SKULLTULA: + case RE_GOHMA_LARVA: + case RE_LIZALFOS: + case RE_DODONGO: // RANDOTODO do dodongos block the way in tight corridors? + case RE_MAD_SCRUB: + case RE_KEESE: + case RE_FIRE_KEESE: + case RE_BLUE_BUBBLE: + case RE_DEAD_HAND: + case RE_DEKU_BABA: + case RE_WITHERED_DEKU_BABA: + case RE_STALFOS: + case RE_FLARE_DANCER: + case RE_WOLFOS: + case RE_WHITE_WOLFOS: + case RE_FLOORMASTER: + case RE_MEG: + case RE_ARMOS: + case RE_FREEZARD: + case RE_SPIKE: + case RE_DARK_LINK: + case RE_ANUBIS: + case RE_WALLMASTER: + case RE_PURPLE_LEEVER: + case RE_OCTOROK: + return true; + case RE_BIG_SKULLTULA: + // hammer jumpslash can pass, but only on flat land where you can kill with hammer swing + return CanUse(RG_NUTS) || CanUse(RG_BOOMERANG); + case RE_LIKE_LIKE: + return CanUse(RG_HOOKSHOT) || CanUse(RG_BOOMERANG); + case RE_GIBDO: + case RE_REDEAD: + // we need a way to check if suns won't force a reload + return CanUse(RG_HOOKSHOT) || CanUse(RG_SUNS_SONG); + case RE_IRON_KNUCKLE: + case RE_BIG_OCTO: + return false; + case RE_GREEN_BUBBLE: + return TakeDamage() || CanUse(RG_NUTS) || CanUse(RG_BOOMERANG) || CanUse(RG_HOOKSHOT); + default: + SPDLOG_ERROR("CanPassEnemy reached `default`."); + assert(false); + return false; + } +} + +// Can we avoid this enemy while climbing up a wall, or doing a difficult platforming challenge? +// use grounded if the challenge is such that the enemy interfears even if it cannot hit link out of the air +bool Logic::CanAvoidEnemy(RandomizerEnemy enemy, bool grounded, uint8_t quantity) { + // DISTANCE AND WALL ASSUMED, add more arguments later if needed + if (CanKillEnemy(enemy, ED_CLOSE, true, quantity)) { + return true; + } + switch (enemy) { + case RE_GOLD_SKULLTULA: case RE_GOHMA_LARVA: case RE_LIZALFOS: case RE_DODONGO: @@ -836,971 +899,991 @@ namespace Rando { case RE_WALLMASTER: case RE_ANUBIS: case RE_PURPLE_LEEVER: - return true; + return true; case RE_BEAMOS: - return !grounded || CanUse(RG_NUTS) || (quantity == 1 && (CanUse(RG_FAIRY_BOW) || CanUse(RG_FAIRY_SLINGSHOT))); + return !grounded || CanUse(RG_NUTS) || + (quantity == 1 && (CanUse(RG_FAIRY_BOW) || CanUse(RG_FAIRY_SLINGSHOT))); case RE_MAD_SCRUB: - return !grounded || CanUse(RG_NUTS); + return !grounded || CanUse(RG_NUTS); case RE_KEESE: case RE_FIRE_KEESE: - return CanUse(RG_NUTS); + return CanUse(RG_NUTS); case RE_BLUE_BUBBLE: - //RANDOTODO Trick to use shield hylian shield as child to stun these guys - return !grounded || CanUse(RG_NUTS) || HookshotOrBoomerang() || CanStandingShield(); + // RANDOTODO Trick to use shield hylian shield as child to stun these guys + return !grounded || CanUse(RG_NUTS) || HookshotOrBoomerang() || CanStandingShield(); default: - SPDLOG_ERROR("CanPassEnemy reached `default`."); - assert(false); - return false; - } - } - - bool Logic::CanGetEnemyDrop(RandomizerEnemy enemy, EnemyDistance distance, bool aboveLink) { - if (!CanKillEnemy(enemy, distance)){ + SPDLOG_ERROR("CanPassEnemy reached `default`."); + assert(false); return false; - } - if (distance <= ED_MASTER_SWORD_JUMPSLASH){ - return true; - } - bool drop = false; - switch(enemy) { - case RE_GOLD_SKULLTULA: - switch(distance){ - case ED_CLOSE: - case ED_SHORT_JUMPSLASH: - case ED_MASTER_SWORD_JUMPSLASH: - case ED_LONG_JUMPSLASH: - case ED_BOMB_THROW: - case ED_BOOMERANG: - drop = drop || CanUse(RG_BOOMERANG); - [[fallthrough]]; - case ED_HOOKSHOT: - drop = drop || CanUse(RG_HOOKSHOT); - [[fallthrough]]; - case ED_LONGSHOT: - drop = drop || CanUse(RG_LONGSHOT); - [[fallthrough]]; - case ED_FAR: - break; - //RANDOTODO double check all jumpslash kills that might be out of jump/backflip range - } - return drop; - break; - case RE_KEESE: - case RE_FIRE_KEESE: - return true; - default: - return aboveLink || (distance <= ED_BOOMERANG && CanUse(RG_BOOMERANG)); - } } +} - bool Logic::CanBreakMudWalls() { - return BlastOrSmash() || (ctx->GetTrickOption(RT_BLUE_FIRE_MUD_WALLS) && BlueFire()); - } - - bool Logic::CanGetDekuBabaSticks() { - return (CanUse(RG_KOKIRI_SWORD) || CanUse(RG_MASTER_SWORD) || CanUse(RG_BIGGORON_SWORD) || CanUse(RG_BOOMERANG)); - } - - bool Logic::CanGetDekuBabaNuts() { - return CanJumpslash() || CanUse(RG_FAIRY_SLINGSHOT) || CanUse(RG_FAIRY_BOW) || HasExplosives() || CanUse(RG_DINS_FIRE); - } - - bool Logic::CanHitEyeTargets() { - return CanUse(RG_FAIRY_BOW) || CanUse(RG_FAIRY_SLINGSHOT); - } - - bool Logic::CanDetonateBombFlowers() { - return CanUse(RG_FAIRY_BOW) || HasExplosives() || CanUse(RG_DINS_FIRE); - } - - bool Logic::CanDetonateUprightBombFlower() { - return CanDetonateBombFlowers() || HasItem(RG_GORONS_BRACELET); - } - - bool Logic::MQWaterLevel(RandoWaterLevel level) { - //For ease of reading, I will call the triforce emblem that sets the water to WL_LOW the "Low Emblem", the one that sets it to WL_MID the "Mid Emblem", and the one that sets it to WL_HIGH the "High Emblem" - switch(level){ - //While you have to go through WL_LOW to get to Mid, the requirements for WL_LOW are stricter than WL_MID because you can always go up to WL_MID and then could need to go back to WL_HIGH to reach the Low Emblem again - //Thanks to this caveat you need to be able to reach and play ZL to both the High and Low Emblems to have WL_LOW in logic. - //Alternativly a way to reach WL_LOW from WL_MID could exist, but all glitchless methods need you to do a Low-locked action - case WL_LOW: - return (CanWaterTempleHigh && CanWaterTempleLowFromHigh) || (CanWaterTempleLowFromMid && CanWaterTempleLowFromHigh); - case WL_LOW_OR_MID: - return (CanWaterTempleHigh && CanWaterTempleLowFromHigh) || (CanWaterTempleLowFromHigh && CanWaterTempleMiddle) || (CanWaterTempleLowFromMid && CanWaterTempleLowFromHigh); - //If we can set it to High out of logic we can just repeat what we did to lower the water in the first place as High is the default. - //Because of this you only need to be able to use the Low and Mid Emblems, WL_LOW could be skipped if it was ever possible to play ZL underwater. - case WL_MID: - return CanWaterTempleLowFromHigh && CanWaterTempleMiddle; - //Despite being the initial state of water temple, WL_HIGH has the extra requirement of making sure that, if we were to lower the water out of logic, we could put it back to WL_HIGH - //However because it is the default state, we do not need to check if we can actually change the water level, only to make sure we can return to WL_HIGH if we found the means to play ZL out of logic. - //There are 2 methods to lock yourself out after playing ZL already: Not being able to reach the High Emblem and being unable to replay ZL. (I will be ignoring other-age-access shenanigains) - //The former check would simply be a check to see if we can reach High Emblem, but we assume the water is WL_MID (as if we can set it to WL_LOW, we can set it to WL_MID, as Mid Emblem has no requirements) - //The latter check can be assumed for now but will want a revisit once OI tricks are added. - case WL_HIGH: - return ReachedWaterHighEmblem; - case WL_HIGH_OR_MID: - return ReachedWaterHighEmblem || (CanWaterTempleLowFromHigh && CanWaterTempleMiddle); - } - SPDLOG_ERROR("MQWaterLevel reached `return false;`. Missing case for a Water Level"); - assert(false); +bool Logic::CanGetEnemyDrop(RandomizerEnemy enemy, EnemyDistance distance, bool aboveLink) { + if (!CanKillEnemy(enemy, distance)) { return false; } - - Logic::Logic() { - + if (distance <= ED_MASTER_SWORD_JUMPSLASH) { + return true; } - - uint8_t Logic::BottleCount() { - uint8_t count = 0; - if (CouldEmptyBigPoes && !AreCheckingBigPoes){ - for (int i = SLOT_BOTTLE_1; i <= SLOT_BOTTLE_4; i++) { - uint8_t item = GetSaveContext()->inventory.items[i]; - switch (item) { - case ITEM_LETTER_RUTO: - if (DeliverLetter) { - count++; - } - break; - case ITEM_BIG_POE: - if (CanEmptyBigPoes) { - count++; - } - break; - case ITEM_NONE: - break; - default: - count++; - break; - } + bool drop = false; + switch (enemy) { + case RE_GOLD_SKULLTULA: + switch (distance) { + case ED_CLOSE: + case ED_SHORT_JUMPSLASH: + case ED_MASTER_SWORD_JUMPSLASH: + case ED_LONG_JUMPSLASH: + case ED_BOMB_THROW: + case ED_BOOMERANG: + drop = drop || CanUse(RG_BOOMERANG); + [[fallthrough]]; + case ED_HOOKSHOT: + drop = drop || CanUse(RG_HOOKSHOT); + [[fallthrough]]; + case ED_LONGSHOT: + drop = drop || CanUse(RG_LONGSHOT); + [[fallthrough]]; + case ED_FAR: + break; + // RANDOTODO double check all jumpslash kills that might be out of jump/backflip range } - } - return count; - } - - uint8_t Logic::OcarinaButtons(){ - return HasItem(RG_OCARINA_A_BUTTON) + HasItem(RG_OCARINA_C_LEFT_BUTTON) + HasItem(RG_OCARINA_C_RIGHT_BUTTON) + HasItem(RG_OCARINA_C_UP_BUTTON) + HasItem(RG_OCARINA_C_DOWN_BUTTON); - } - - bool Logic::HasBottle(){ - return BottleCount() >= 1; - } - - bool Logic::CanJumpslashExceptHammer() { - // Not including hammer as hammer jump attacks can be weird; - return CanUse(RG_STICKS) || CanUse(RG_KOKIRI_SWORD) || CanUse(RG_MASTER_SWORD) || CanUse(RG_BIGGORON_SWORD); - } - - bool Logic::CanJumpslash() { - return CanJumpslashExceptHammer() || CanUse(RG_MEGATON_HAMMER); - } - - bool Logic::CanHitSwitch(EnemyDistance distance, bool inWater) { - bool hit = false; - switch (distance){ - case ED_CLOSE: - case ED_SHORT_JUMPSLASH: - hit = CanUse(RG_KOKIRI_SWORD) || CanUse(RG_MEGATON_HAMMER); - [[fallthrough]]; - case ED_MASTER_SWORD_JUMPSLASH: - hit = hit || CanUse(RG_MASTER_SWORD); - [[fallthrough]]; - case ED_LONG_JUMPSLASH: - hit = hit || CanUse(RG_BIGGORON_SWORD) || CanUse(RG_STICKS); - [[fallthrough]]; - case ED_BOMB_THROW: - hit = hit || (!inWater && CanUse(RG_BOMB_BAG)); - [[fallthrough]]; - case ED_BOOMERANG: - hit = hit || CanUse(RG_BOOMERANG); - [[fallthrough]]; - case ED_HOOKSHOT: - //RANDOTODO test chu range in a practical example - hit = hit || CanUse(RG_HOOKSHOT) || CanUse(RG_BOMBCHU_5) ; - [[fallthrough]]; - case ED_LONGSHOT: - hit = hit || CanUse(RG_LONGSHOT); - [[fallthrough]]; - case ED_FAR: - hit = hit || CanUse(RG_FAIRY_SLINGSHOT) || CanUse(RG_FAIRY_BOW); - break; - } - return hit; - } - - bool Logic::CanDamage() { - return CanUse(RG_FAIRY_SLINGSHOT) || CanJumpslash() || HasExplosives() || CanUse(RG_DINS_FIRE) || CanUse(RG_FAIRY_BOW); - } - - bool Logic::CanAttack() { - return CanDamage() || CanUse(RG_BOOMERANG) || CanUse(RG_HOOKSHOT); - } - - bool Logic::BombchusEnabled(){ - return ctx->GetOption(RSK_BOMBCHU_BAG) ? CheckInventory(ITEM_BOMBCHU, true) : HasItem(RG_BOMB_BAG); - } - - // TODO: Implement Ammo Drop Setting in place of bombchu drops - bool Logic::BombchuRefill(){ - return GetInLogic(LOGIC_BUY_BOMBCHUS) || CouldPlayBowling || CarpetMerchant || (ctx->GetOption(RSK_ENABLE_BOMBCHU_DROPS).Is(RO_AMMO_DROPS_ON/*_PLUS_BOMBCHU*/)); - } - - bool Logic::HookshotOrBoomerang(){ - return CanUse(RG_HOOKSHOT) || CanUse(RG_BOOMERANG); - } - - bool Logic::ScarecrowsSong(){ - return (ctx->GetOption(RSK_SKIP_SCARECROWS_SONG) && HasItem(RG_FAIRY_OCARINA) && OcarinaButtons() >= 2) - || (ChildScarecrow && AdultScarecrow); - } - - bool Logic::BlueFire(){ - return CanUse(RG_BOTTLE_WITH_BLUE_FIRE) || (ctx->GetOption(RSK_BLUE_FIRE_ARROWS) && CanUse(RG_ICE_ARROWS)); - } - - bool Logic::CanBreakPots(){ - return true; - } - - bool Logic::CanBreakCrates() { - return true; - } - - bool Logic::CanBreakSmallCrates() { - return true; - } - - bool Logic::HasExplosives(){ - return CanUse(RG_BOMB_BAG) || CanUse(RG_BOMBCHU_5); - } - - bool Logic::BlastOrSmash(){ - return HasExplosives() || CanUse(RG_MEGATON_HAMMER); - } - - bool Logic::CanSpawnSoilSkull(){ - return IsChild && CanUse(RG_BOTTLE_WITH_BUGS); - } - - bool Logic::CanReflectNuts(){ - return CanUse(RG_DEKU_SHIELD) || (IsAdult && HasItem(RG_HYLIAN_SHIELD)); - } - - bool Logic::CanCutShrubs(){ - return CanUse(RG_KOKIRI_SWORD) || CanUse(RG_BOOMERANG) || HasExplosives() || CanUse(RG_MASTER_SWORD) || CanUse(RG_MEGATON_HAMMER) || CanUse(RG_BIGGORON_SWORD) || HasItem(RG_GORONS_BRACELET); - } - - bool Logic::CanStunDeku(){ - return CanAttack() || CanUse(RG_NUTS) || CanReflectNuts(); - } - - bool Logic::CanLeaveForest(){ - return ctx->GetOption(RSK_FOREST).IsNot(RO_CLOSED_FOREST_ON) || IsAdult || DekuTreeClear || ctx->GetOption(RSK_SHUFFLE_INTERIOR_ENTRANCES) || ctx->GetOption(RSK_SHUFFLE_OVERWORLD_ENTRANCES); - } - - bool Logic::CallGossipFairyExceptSuns(){ - return CanUse(RG_ZELDAS_LULLABY) || CanUse(RG_EPONAS_SONG) || CanUse(RG_SONG_OF_TIME); - } - - bool Logic::CallGossipFairy(){ - return CallGossipFairyExceptSuns() || CanUse(RG_SUNS_SONG); - } - - //the number returned by this is in half heart hits taken. - //RANDOTODO work in OoT side health instead for greater applicability (16 per heart) - uint8_t Logic::EffectiveHealth(){ - /* Multiplier will be: - 0 for half daamge - 1 for normal damage - 2 for double damage - 3 for quad damage - 4 for 8* damage - 5 for 16* damage - 10 for OHKO. - This is the number of shifts to apply, not a real multiplier - */ - uint8_t Multiplier = (ctx->GetOption(RSK_DAMAGE_MULTIPLIER).Get() < 6) ? ctx->GetOption(RSK_DAMAGE_MULTIPLIER).Get() : 10; - //(Hearts() << (2 + HasItem(RG_DOUBLE_DEFENSE))) is quarter hearts after DD - //>> Multiplier halves on normal and does nothing on half, meaning we're working with half hearts on normal damage - return ((Hearts() << (2 + HasItem(RG_DOUBLE_DEFENSE))) >> Multiplier) + - //As 1 is a quarter heart, (1 << Multiplier) is effectivly half-hearts of unmodified damage - //Adds an extra hit if the damage is not exact lethal - ((Hearts() << (2 + HasItem(RG_DOUBLE_DEFENSE))) % (1 << Multiplier) > 0); - } - - uint8_t Logic::Hearts(){ - return GetSaveContext()->healthCapacity / 16; - } - - uint8_t Logic::DungeonCount(){ - return DekuTreeClear + DodongosCavernClear + JabuJabusBellyClear + ForestTempleClear + FireTempleClear + WaterTempleClear + SpiritTempleClear + ShadowTempleClear; - } - - uint8_t Logic::StoneCount(){ - return HasItem(RG_KOKIRI_EMERALD) + HasItem(RG_GORON_RUBY) + HasItem(RG_ZORA_SAPPHIRE); - } - - uint8_t Logic::MedallionCount(){ - return HasItem(RG_FOREST_MEDALLION) + HasItem(RG_FIRE_MEDALLION) + HasItem(RG_WATER_MEDALLION) + HasItem(RG_SPIRIT_MEDALLION) + HasItem(RG_SHADOW_MEDALLION) + HasItem(RG_LIGHT_MEDALLION); - } - - uint8_t Logic::FireTimer(){ - return CanUse(RG_GORON_TUNIC) ? 255 : (ctx->GetTrickOption(RT_FEWER_TUNIC_REQUIREMENTS)) ? (Hearts() * 8) : 0; - } - - //Tunic is not required if you are using irons to do something that a simple gold scale dive could do, and you are not in water temple. (celing swimming and long walks through water do not count) - uint8_t Logic::WaterTimer(){ - return CanUse(RG_ZORA_TUNIC) ? 255 : (ctx->GetTrickOption(RT_FEWER_TUNIC_REQUIREMENTS)) ? (Hearts() * 8) : 0; - } - - bool Logic::TakeDamage(){ - return CanUse(RG_BOTTLE_WITH_FAIRY) || EffectiveHealth() != 1 || CanUse(RG_NAYRUS_LOVE); - } - - bool Logic::CanOpenBombGrotto(){ - return BlastOrSmash() && (HasItem(RG_STONE_OF_AGONY) || ctx->GetTrickOption(RT_GROTTOS_WITHOUT_AGONY)); - } - - bool Logic::CanOpenStormsGrotto(){ - return CanUse(RG_SONG_OF_STORMS) && (HasItem(RG_STONE_OF_AGONY) || ctx->GetTrickOption(RT_GROTTOS_WITHOUT_AGONY)); - } - - bool Logic::CanGetNightTimeGS(){ - return AtNight && (CanUse(RG_SUNS_SONG) || !ctx->GetOption(RSK_SKULLS_SUNS_SONG)); - } - - bool Logic::CanBreakUpperBeehives(){ - return HookshotOrBoomerang() || (ctx->GetTrickOption(RT_BOMBCHU_BEEHIVES) && CanUse(RG_BOMBCHU_5)); - } - - bool Logic::CanBreakLowerBeehives(){ - return CanBreakUpperBeehives() || CanUse(RG_BOMB_BAG); - } - - bool Logic::HasFireSource(){ - return CanUse(RG_DINS_FIRE) || CanUse(RG_FIRE_ARROWS); - } - - bool Logic::HasFireSourceWithTorch(){ - return HasFireSource() || CanUse(RG_STICKS); - } - -//Is this best off signaling what you have already traded, or what step you are currently on? - bool Logic::TradeQuestStep(RandomizerGet rg){ - if (ctx->GetOption(RSK_SHUFFLE_ADULT_TRADE)){ - return false; //This does not apply when we are shuffling trade items - } - bool hasState = false; - //Falling through each case to test each possibility - switch (rg){ - case RG_POCKET_EGG: - hasState = hasState || HasItem(RG_POCKET_EGG); - [[fallthrough]]; - case RG_COJIRO: - hasState = hasState || HasItem(RG_COJIRO); - [[fallthrough]]; - case RG_ODD_MUSHROOM: - hasState = hasState || HasItem(RG_ODD_MUSHROOM); - [[fallthrough]]; - case RG_ODD_POTION: - hasState = hasState || HasItem(RG_ODD_POTION); - [[fallthrough]]; - case RG_POACHERS_SAW: - hasState = hasState || HasItem(RG_POACHERS_SAW); - [[fallthrough]]; - case RG_BROKEN_SWORD: - hasState = hasState || HasItem(RG_BROKEN_SWORD); - [[fallthrough]]; - case RG_PRESCRIPTION: - hasState = hasState || HasItem(RG_PRESCRIPTION); - [[fallthrough]]; - case RG_EYEDROPS: - hasState = hasState || HasItem(RG_EYEDROPS); - [[fallthrough]]; - case RG_CLAIM_CHECK: - hasState = hasState || HasItem(RG_CLAIM_CHECK); - break; - default: - SPDLOG_ERROR("TradeQuestStep reached `return false;`. Missing case for RandomizerGet of {}", static_cast(rg)); - assert(false); - return false; - } - return hasState; - } - - bool Logic::CanFinishGerudoFortress(){ - return (ctx->GetOption(RSK_GERUDO_FORTRESS).Is(RO_GF_CARPENTERS_NORMAL) && SmallKeys(RR_GERUDO_FORTRESS, 4) && CanKillEnemy(RE_GERUDO_WARRIOR) && (HasItem(RG_GERUDO_MEMBERSHIP_CARD) || CanUse(RG_FAIRY_BOW) || CanUse(RG_HOOKSHOT) || CanUse(RG_HOVER_BOOTS) || ctx->GetTrickOption(RT_GF_KITCHEN))) || - (ctx->GetOption(RSK_GERUDO_FORTRESS).Is(RO_GF_CARPENTERS_FAST) && SmallKeys(RR_GERUDO_FORTRESS, 1) && CanKillEnemy(RE_GERUDO_WARRIOR)) || - ctx->GetOption(RSK_GERUDO_FORTRESS).Is(RO_GF_CARPENTERS_FREE); - } - - bool Logic::CanStandingShield(){ - return CanUse(RG_MIRROR_SHIELD) || (IsAdult && HasItem(RG_HYLIAN_SHIELD)) || CanUse(RG_DEKU_SHIELD); - } - - bool Logic::CanShield(){ - return CanUse(RG_MIRROR_SHIELD) || HasItem(RG_HYLIAN_SHIELD) || CanUse(RG_DEKU_SHIELD); - } - - bool Logic::CanUseProjectile(){ - return HasExplosives() || CanUse(RG_FAIRY_BOW) || CanUse(RG_HOOKSHOT) || CanUse(RG_FAIRY_SLINGSHOT) || CanUse(RG_BOOMERANG); - } - - bool Logic::CanBuildRainbowBridge(){ - return ctx->GetOption(RSK_RAINBOW_BRIDGE).Is(RO_BRIDGE_ALWAYS_OPEN) || - (ctx->GetOption(RSK_RAINBOW_BRIDGE).Is(RO_BRIDGE_VANILLA) && HasItem(RG_SHADOW_MEDALLION) && HasItem(RG_SPIRIT_MEDALLION) && CanUse(RG_LIGHT_ARROWS)) || - (ctx->GetOption(RSK_RAINBOW_BRIDGE).Is(RO_BRIDGE_STONES) && StoneCount() + (HasItem(RG_GREG_RUPEE) && ctx->GetOption(RSK_BRIDGE_OPTIONS).Is(RO_BRIDGE_GREG_REWARD)) >= ctx->GetOption(RSK_RAINBOW_BRIDGE_STONE_COUNT).Get()) || - (ctx->GetOption(RSK_RAINBOW_BRIDGE).Is(RO_BRIDGE_MEDALLIONS) && MedallionCount() + (HasItem(RG_GREG_RUPEE) && ctx->GetOption(RSK_BRIDGE_OPTIONS).Is(RO_BRIDGE_GREG_REWARD)) >= ctx->GetOption(RSK_RAINBOW_BRIDGE_MEDALLION_COUNT).Get()) || - (ctx->GetOption(RSK_RAINBOW_BRIDGE).Is(RO_BRIDGE_DUNGEON_REWARDS) && StoneCount() + MedallionCount() + (HasItem(RG_GREG_RUPEE) && ctx->GetOption(RSK_BRIDGE_OPTIONS).Is(RO_BRIDGE_GREG_REWARD)) >= ctx->GetOption(RSK_RAINBOW_BRIDGE_REWARD_COUNT).Get()) || - (ctx->GetOption(RSK_RAINBOW_BRIDGE).Is(RO_BRIDGE_DUNGEONS) && DungeonCount() + (HasItem(RG_GREG_RUPEE) && ctx->GetOption(RSK_BRIDGE_OPTIONS).Is(RO_BRIDGE_GREG_REWARD)) >= ctx->GetOption(RSK_RAINBOW_BRIDGE_DUNGEON_COUNT).Get()) || - (ctx->GetOption(RSK_RAINBOW_BRIDGE).Is(RO_BRIDGE_TOKENS) && GetGSCount() >= ctx->GetOption(RSK_RAINBOW_BRIDGE_TOKEN_COUNT).Get()) || - (ctx->GetOption(RSK_RAINBOW_BRIDGE).Is(RO_BRIDGE_GREG) && HasItem(RG_GREG_RUPEE)); - } - - bool Logic::CanTriggerLACS(){ - return (ctx->LACSCondition() == RO_LACS_VANILLA && HasItem(RG_SHADOW_MEDALLION) && HasItem(RG_SPIRIT_MEDALLION)) || - (ctx->LACSCondition() == RO_LACS_STONES && StoneCount() + (HasItem(RG_GREG_RUPEE) && ctx->GetOption(RSK_LACS_OPTIONS).Is(RO_LACS_GREG_REWARD)) >= ctx->GetOption(RSK_LACS_STONE_COUNT).Get()) || - (ctx->LACSCondition() == RO_LACS_MEDALLIONS && MedallionCount() + (HasItem(RG_GREG_RUPEE) && ctx->GetOption(RSK_LACS_OPTIONS).Is(RO_LACS_GREG_REWARD)) >= ctx->GetOption(RSK_LACS_MEDALLION_COUNT).Get()) || - (ctx->LACSCondition() == RO_LACS_REWARDS && StoneCount() + MedallionCount() + (HasItem(RG_GREG_RUPEE) && ctx->GetOption(RSK_LACS_OPTIONS).Is(RO_LACS_GREG_REWARD)) >= ctx->GetOption(RSK_LACS_REWARD_COUNT).Get()) || - (ctx->LACSCondition() == RO_LACS_DUNGEONS && DungeonCount() + (HasItem(RG_GREG_RUPEE) && ctx->GetOption(RSK_LACS_OPTIONS).Is(RO_LACS_GREG_REWARD)) >= ctx->GetOption(RSK_LACS_DUNGEON_COUNT).Get()) || - (ctx->LACSCondition() == RO_LACS_TOKENS && GetGSCount() >= ctx->GetOption(RSK_LACS_TOKEN_COUNT).Get()); - } - - bool Logic::SmallKeys(RandomizerRegion dungeon, uint8_t requiredAmount) { - return SmallKeys(dungeon, requiredAmount, requiredAmount); - } - - bool Logic::SmallKeys(RandomizerRegion dungeon, uint8_t requiredAmountGlitchless, uint8_t requiredAmountGlitched) { - if (HasItem(RG_SKELETON_KEY)) { + return drop; + break; + case RE_KEESE: + case RE_FIRE_KEESE: return true; - } - switch (dungeon) { - case RR_FOREST_TEMPLE: - /*if (IsGlitched && (GetDifficultyValueFromString(GlitchHookshotJump_Boots) >= static_cast(GlitchDifficulty::INTERMEDIATE) || GetDifficultyValueFromString(GlitchHoverBoost) >= static_cast(GlitchDifficulty::NOVICE) || - (GetDifficultyValueFromString(GlitchHover) >= static_cast(GlitchDifficulty::NOVICE) && GetDifficultyValueFromString(GlitchISG) >= static_cast(GlitchDifficulty::INTERMEDIATE)))) { - return ForestTempleKeys >= requiredAmountGlitched; - }*/ - return GetSmallKeyCount(SCENE_FOREST_TEMPLE) >= requiredAmountGlitchless; - - case RR_FIRE_TEMPLE: - /*if (IsGlitched && (GetDifficultyValueFromString(GlitchLedgeClip) >= static_cast(GlitchDifficulty::INTERMEDIATE) || GetDifficultyValueFromString(GlitchHover) >= static_cast(GlitchDifficulty::INTERMEDIATE))) { - return FireTempleKeys >= requiredAmountGlitched; - }*/ - return GetSmallKeyCount(SCENE_FIRE_TEMPLE) >= requiredAmountGlitchless; - - case RR_WATER_TEMPLE: - /*if (IsGlitched && (false)) { - return WaterTempleKeys >= requiredAmountGlitched; - }*/ - return GetSmallKeyCount(SCENE_WATER_TEMPLE) >= requiredAmountGlitchless; - - case RR_SPIRIT_TEMPLE: - /*if (IsGlitched && (false)) { - return SpiritTempleKeys >= requiredAmountGlitched; - }*/ - return GetSmallKeyCount(SCENE_SPIRIT_TEMPLE) >= requiredAmountGlitchless; - - case RR_SHADOW_TEMPLE: - /*if (IsGlitched && (GetDifficultyValueFromString(GlitchHookshotClip) >= static_cast(GlitchDifficulty::NOVICE))) { - return ShadowTempleKeys >= requiredAmountGlitched; - }*/ - return GetSmallKeyCount(SCENE_SHADOW_TEMPLE) >= requiredAmountGlitchless; - - case RR_BOTTOM_OF_THE_WELL: - /*if (IsGlitched && (false)) { - return BottomOfTheWellKeys >= requiredAmountGlitched; - }*/ - return GetSmallKeyCount(SCENE_BOTTOM_OF_THE_WELL) >= requiredAmountGlitchless; - - case RR_GERUDO_TRAINING_GROUND: - /*if (IsGlitched && (false)) { - return GerudoTrainingGroundsKeys >= requiredAmountGlitched; - }*/ - return GetSmallKeyCount(SCENE_GERUDO_TRAINING_GROUND) >= requiredAmountGlitchless; - - case RR_GANONS_CASTLE: - /*if (IsGlitched && (false)) { - return GanonsCastleKeys >= requiredAmountGlitched; - }*/ - return GetSmallKeyCount(SCENE_INSIDE_GANONS_CASTLE) >= requiredAmountGlitchless; - - case RR_MARKET_TREASURE_CHEST_GAME: - /*if (IsGlitched && (false)) { - return TreasureGameKeys >= requiredAmountGlitched; - }*/ - return GetSmallKeyCount(SCENE_TREASURE_BOX_SHOP) >= requiredAmountGlitchless; - - case RR_GERUDO_FORTRESS: - return GetSmallKeyCount(SCENE_THIEVES_HIDEOUT) >= requiredAmountGlitchless; - - default: - return false; - } + default: + return aboveLink || (distance <= ED_BOOMERANG && CanUse(RG_BOOMERANG)); } +} - std::map Logic::RandoGetToEquipFlag = { - { RG_KOKIRI_SWORD, EQUIP_FLAG_SWORD_KOKIRI }, - { RG_MASTER_SWORD, EQUIP_FLAG_SWORD_MASTER }, - { RG_BIGGORON_SWORD, EQUIP_FLAG_SWORD_BGS }, - { RG_DEKU_SHIELD, EQUIP_FLAG_SHIELD_DEKU }, - { RG_HYLIAN_SHIELD, EQUIP_FLAG_SHIELD_HYLIAN }, - { RG_MIRROR_SHIELD, EQUIP_FLAG_SHIELD_MIRROR }, - { RG_GORON_TUNIC, EQUIP_FLAG_TUNIC_GORON }, - { RG_ZORA_TUNIC, EQUIP_FLAG_TUNIC_ZORA }, - { RG_BUY_DEKU_SHIELD, EQUIP_FLAG_SHIELD_DEKU }, - { RG_BUY_HYLIAN_SHIELD, EQUIP_FLAG_SHIELD_HYLIAN }, - { RG_BUY_GORON_TUNIC, EQUIP_FLAG_TUNIC_GORON }, - { RG_BUY_ZORA_TUNIC, EQUIP_FLAG_TUNIC_ZORA }, - { RG_IRON_BOOTS, EQUIP_FLAG_BOOTS_IRON }, - { RG_HOVER_BOOTS, EQUIP_FLAG_BOOTS_HOVER } - }; +bool Logic::CanBreakMudWalls() { + return BlastOrSmash() || (ctx->GetTrickOption(RT_BLUE_FIRE_MUD_WALLS) && BlueFire()); +} - std::map Logic::RandoGetToRandInf = { - { RG_ZELDAS_LETTER, RAND_INF_ZELDAS_LETTER }, - { RG_WEIRD_EGG, RAND_INF_WEIRD_EGG }, - { RG_GOHMA_SOUL, RAND_INF_GOHMA_SOUL }, - { RG_KING_DODONGO_SOUL, RAND_INF_KING_DODONGO_SOUL }, - { RG_BARINADE_SOUL, RAND_INF_BARINADE_SOUL }, - { RG_PHANTOM_GANON_SOUL, RAND_INF_PHANTOM_GANON_SOUL }, - { RG_VOLVAGIA_SOUL, RAND_INF_VOLVAGIA_SOUL }, - { RG_MORPHA_SOUL, RAND_INF_MORPHA_SOUL }, - { RG_BONGO_BONGO_SOUL, RAND_INF_BONGO_BONGO_SOUL }, - { RG_TWINROVA_SOUL, RAND_INF_TWINROVA_SOUL }, - { RG_GANON_SOUL, RAND_INF_GANON_SOUL }, - { RG_OCARINA_A_BUTTON, RAND_INF_HAS_OCARINA_A }, - { RG_OCARINA_C_UP_BUTTON, RAND_INF_HAS_OCARINA_C_UP }, - { RG_OCARINA_C_DOWN_BUTTON, RAND_INF_HAS_OCARINA_C_DOWN }, - { RG_OCARINA_C_LEFT_BUTTON, RAND_INF_HAS_OCARINA_C_LEFT }, - { RG_OCARINA_C_RIGHT_BUTTON, RAND_INF_HAS_OCARINA_C_RIGHT }, - { RG_SKELETON_KEY, RAND_INF_HAS_SKELETON_KEY }, - { RG_GREG_RUPEE, RAND_INF_GREG_FOUND }, - { RG_FISHING_POLE, RAND_INF_FISHING_POLE_FOUND }, - { RG_GUARD_HOUSE_KEY, RAND_INF_GUARD_HOUSE_KEY_OBTAINED }, - { RG_MARKET_BAZAAR_KEY, RAND_INF_MARKET_BAZAAR_KEY_OBTAINED }, - { RG_MARKET_POTION_SHOP_KEY, RAND_INF_MARKET_POTION_SHOP_KEY_OBTAINED }, - { RG_MASK_SHOP_KEY, RAND_INF_MASK_SHOP_KEY_OBTAINED }, - { RG_MARKET_SHOOTING_GALLERY_KEY, RAND_INF_MARKET_SHOOTING_GALLERY_KEY_OBTAINED }, - { RG_BOMBCHU_BOWLING_KEY, RAND_INF_BOMBCHU_BOWLING_KEY_OBTAINED }, - { RG_TREASURE_CHEST_GAME_BUILDING_KEY, RAND_INF_TREASURE_CHEST_GAME_BUILDING_KEY_OBTAINED }, - { RG_BOMBCHU_SHOP_KEY, RAND_INF_BOMBCHU_SHOP_KEY_OBTAINED }, - { RG_RICHARDS_HOUSE_KEY, RAND_INF_RICHARDS_HOUSE_KEY_OBTAINED }, - { RG_ALLEY_HOUSE_KEY, RAND_INF_ALLEY_HOUSE_KEY_OBTAINED }, - { RG_KAK_BAZAAR_KEY, RAND_INF_KAK_BAZAAR_KEY_OBTAINED }, - { RG_KAK_POTION_SHOP_KEY, RAND_INF_KAK_POTION_SHOP_KEY_OBTAINED }, - { RG_BOSS_HOUSE_KEY, RAND_INF_BOSS_HOUSE_KEY_OBTAINED }, - { RG_GRANNYS_POTION_SHOP_KEY, RAND_INF_GRANNYS_POTION_SHOP_KEY_OBTAINED }, - { RG_SKULLTULA_HOUSE_KEY, RAND_INF_SKULLTULA_HOUSE_KEY_OBTAINED }, - { RG_IMPAS_HOUSE_KEY, RAND_INF_IMPAS_HOUSE_KEY_OBTAINED }, - { RG_WINDMILL_KEY, RAND_INF_WINDMILL_KEY_OBTAINED }, - { RG_KAK_SHOOTING_GALLERY_KEY, RAND_INF_KAK_SHOOTING_GALLERY_KEY_OBTAINED }, - { RG_DAMPES_HUT_KEY, RAND_INF_DAMPES_HUT_KEY_OBTAINED }, - { RG_TALONS_HOUSE_KEY, RAND_INF_TALONS_HOUSE_KEY_OBTAINED }, - { RG_STABLES_KEY, RAND_INF_STABLES_KEY_OBTAINED }, - { RG_BACK_TOWER_KEY, RAND_INF_BACK_TOWER_KEY_OBTAINED }, - { RG_HYLIA_LAB_KEY, RAND_INF_HYLIA_LAB_KEY_OBTAINED }, - { RG_FISHING_HOLE_KEY, RAND_INF_FISHING_HOLE_KEY_OBTAINED }, - }; +bool Logic::CanGetDekuBabaSticks() { + return (CanUse(RG_KOKIRI_SWORD) || CanUse(RG_MASTER_SWORD) || CanUse(RG_BIGGORON_SWORD) || CanUse(RG_BOOMERANG)); +} - std::map Logic::RandoGetToDungeonScene = { - { RG_FOREST_TEMPLE_SMALL_KEY, SCENE_FOREST_TEMPLE }, - { RG_FIRE_TEMPLE_SMALL_KEY, SCENE_FIRE_TEMPLE }, - { RG_WATER_TEMPLE_SMALL_KEY, SCENE_WATER_TEMPLE }, - { RG_SPIRIT_TEMPLE_SMALL_KEY, SCENE_SPIRIT_TEMPLE }, - { RG_SHADOW_TEMPLE_SMALL_KEY, SCENE_SHADOW_TEMPLE }, - { RG_BOTTOM_OF_THE_WELL_SMALL_KEY, SCENE_BOTTOM_OF_THE_WELL }, - { RG_GERUDO_TRAINING_GROUND_SMALL_KEY, SCENE_GERUDO_TRAINING_GROUND }, - { RG_GERUDO_FORTRESS_SMALL_KEY, SCENE_THIEVES_HIDEOUT }, - { RG_GANONS_CASTLE_SMALL_KEY, SCENE_INSIDE_GANONS_CASTLE }, - { RG_FOREST_TEMPLE_KEY_RING, SCENE_FOREST_TEMPLE }, - { RG_FIRE_TEMPLE_KEY_RING, SCENE_FIRE_TEMPLE }, - { RG_WATER_TEMPLE_KEY_RING, SCENE_WATER_TEMPLE }, - { RG_SPIRIT_TEMPLE_KEY_RING, SCENE_SPIRIT_TEMPLE }, - { RG_SHADOW_TEMPLE_KEY_RING, SCENE_SHADOW_TEMPLE }, - { RG_BOTTOM_OF_THE_WELL_KEY_RING, SCENE_BOTTOM_OF_THE_WELL }, - { RG_GERUDO_TRAINING_GROUND_KEY_RING, SCENE_GERUDO_TRAINING_GROUND }, - { RG_GERUDO_FORTRESS_KEY_RING, SCENE_THIEVES_HIDEOUT }, - { RG_GANONS_CASTLE_KEY_RING, SCENE_INSIDE_GANONS_CASTLE }, - { RG_FOREST_TEMPLE_BOSS_KEY, SCENE_FOREST_TEMPLE }, - { RG_FIRE_TEMPLE_BOSS_KEY, SCENE_FIRE_TEMPLE }, - { RG_WATER_TEMPLE_BOSS_KEY, SCENE_WATER_TEMPLE }, - { RG_SPIRIT_TEMPLE_BOSS_KEY, SCENE_SPIRIT_TEMPLE }, - { RG_SHADOW_TEMPLE_BOSS_KEY, SCENE_SHADOW_TEMPLE }, - { RG_GANONS_CASTLE_BOSS_KEY, SCENE_INSIDE_GANONS_CASTLE }, - { RG_DEKU_TREE_MAP, SCENE_DEKU_TREE }, - { RG_DODONGOS_CAVERN_MAP, SCENE_DODONGOS_CAVERN }, - { RG_JABU_JABUS_BELLY_MAP, SCENE_JABU_JABU }, - { RG_FOREST_TEMPLE_MAP, SCENE_FOREST_TEMPLE }, - { RG_FIRE_TEMPLE_MAP, SCENE_FIRE_TEMPLE }, - { RG_WATER_TEMPLE_MAP, SCENE_WATER_TEMPLE }, - { RG_SPIRIT_TEMPLE_MAP, SCENE_SPIRIT_TEMPLE }, - { RG_SHADOW_TEMPLE_MAP, SCENE_SHADOW_TEMPLE }, - { RG_BOTTOM_OF_THE_WELL_MAP, SCENE_BOTTOM_OF_THE_WELL }, - { RG_ICE_CAVERN_MAP, SCENE_ICE_CAVERN }, - { RG_DEKU_TREE_COMPASS, SCENE_DEKU_TREE }, - { RG_DODONGOS_CAVERN_COMPASS, SCENE_DODONGOS_CAVERN }, - { RG_JABU_JABUS_BELLY_COMPASS, SCENE_JABU_JABU }, - { RG_FOREST_TEMPLE_COMPASS, SCENE_FOREST_TEMPLE }, - { RG_FIRE_TEMPLE_COMPASS, SCENE_FIRE_TEMPLE }, - { RG_WATER_TEMPLE_COMPASS, SCENE_WATER_TEMPLE }, - { RG_SPIRIT_TEMPLE_COMPASS, SCENE_SPIRIT_TEMPLE }, - { RG_SHADOW_TEMPLE_COMPASS, SCENE_SHADOW_TEMPLE }, - { RG_BOTTOM_OF_THE_WELL_COMPASS, SCENE_BOTTOM_OF_THE_WELL }, - { RG_ICE_CAVERN_COMPASS, SCENE_ICE_CAVERN }, - { RG_TREASURE_GAME_SMALL_KEY, SCENE_TREASURE_BOX_SHOP } - }; +bool Logic::CanGetDekuBabaNuts() { + return CanJumpslash() || CanUse(RG_FAIRY_SLINGSHOT) || CanUse(RG_FAIRY_BOW) || HasExplosives() || + CanUse(RG_DINS_FIRE); +} - std::map Logic::RandoGetToQuestItem = { - { RG_FOREST_MEDALLION, QUEST_MEDALLION_FOREST }, - { RG_FIRE_MEDALLION, QUEST_MEDALLION_FIRE }, - { RG_WATER_MEDALLION, QUEST_MEDALLION_WATER }, - { RG_SPIRIT_MEDALLION, QUEST_MEDALLION_SPIRIT }, - { RG_SHADOW_MEDALLION, QUEST_MEDALLION_SHADOW }, - { RG_LIGHT_MEDALLION, QUEST_MEDALLION_LIGHT }, - { RG_MINUET_OF_FOREST, QUEST_SONG_MINUET }, - { RG_BOLERO_OF_FIRE, QUEST_SONG_BOLERO }, - { RG_SERENADE_OF_WATER, QUEST_SONG_SERENADE }, - { RG_REQUIEM_OF_SPIRIT, QUEST_SONG_REQUIEM }, - { RG_NOCTURNE_OF_SHADOW, QUEST_SONG_NOCTURNE }, - { RG_PRELUDE_OF_LIGHT, QUEST_SONG_PRELUDE }, - { RG_ZELDAS_LULLABY, QUEST_SONG_LULLABY }, - { RG_EPONAS_SONG, QUEST_SONG_EPONA }, - { RG_SARIAS_SONG, QUEST_SONG_SARIA }, - { RG_SUNS_SONG, QUEST_SONG_SUN }, - { RG_SONG_OF_TIME, QUEST_SONG_TIME }, - { RG_SONG_OF_STORMS, QUEST_SONG_STORMS }, - { RG_KOKIRI_EMERALD, QUEST_KOKIRI_EMERALD }, - { RG_GORON_RUBY, QUEST_GORON_RUBY }, - { RG_ZORA_SAPPHIRE, QUEST_ZORA_SAPPHIRE }, - { RG_STONE_OF_AGONY, QUEST_STONE_OF_AGONY }, - { RG_GERUDO_MEMBERSHIP_CARD, QUEST_GERUDO_CARD }, - }; +bool Logic::CanHitEyeTargets() { + return CanUse(RG_FAIRY_BOW) || CanUse(RG_FAIRY_SLINGSHOT); +} - std::map BottleRandomizerGetToItemID = { - { RG_BOTTLE_WITH_RED_POTION, ITEM_POTION_RED }, - { RG_BOTTLE_WITH_GREEN_POTION, ITEM_POTION_GREEN }, - { RG_BOTTLE_WITH_BLUE_POTION, ITEM_POTION_BLUE }, - { RG_BOTTLE_WITH_FAIRY, ITEM_FAIRY }, - { RG_BOTTLE_WITH_FISH, ITEM_FISH }, - { RG_BOTTLE_WITH_BLUE_FIRE, ITEM_BLUE_FIRE }, - { RG_BOTTLE_WITH_BUGS, ITEM_BUG }, - { RG_BOTTLE_WITH_POE, ITEM_POE }, - { RG_BOTTLE_WITH_BIG_POE, ITEM_BIG_POE }, - }; +bool Logic::CanDetonateBombFlowers() { + return CanUse(RG_FAIRY_BOW) || HasExplosives() || CanUse(RG_DINS_FIRE); +} - uint32_t HookshotLookup[3] = { ITEM_NONE, ITEM_HOOKSHOT, ITEM_LONGSHOT }; - uint32_t OcarinaLookup[3] = { ITEM_NONE, ITEM_OCARINA_FAIRY, ITEM_OCARINA_TIME }; +bool Logic::CanDetonateUprightBombFlower() { + return CanDetonateBombFlowers() || HasItem(RG_GORONS_BRACELET); +} - void Logic::ApplyItemEffect(Item& item, bool state) { - auto randoGet = item.GetRandomizerGet(); - if (item.GetGIEntry()->objectId == OBJECT_GI_STICK) { - SetInventory(ITEM_STICK, (!state ? ITEM_NONE : ITEM_STICK)); - } - if (item.GetGIEntry()->objectId == OBJECT_GI_NUTS) { - SetInventory(ITEM_NUT, (!state ? ITEM_NONE : ITEM_NUT)); - } - switch (item.GetItemType()) { - case ITEMTYPE_ITEM: - { - switch (randoGet) { - case RG_STONE_OF_AGONY: - case RG_GERUDO_MEMBERSHIP_CARD: - SetQuestItem(RandoGetToQuestItem.at(randoGet), state); - break; - case RG_WEIRD_EGG: - SetRandoInf(RAND_INF_WEIRD_EGG, state); - break; - case RG_ZELDAS_LETTER: - SetRandoInf(RAND_INF_ZELDAS_LETTER, state); - break; - case RG_DOUBLE_DEFENSE: - mSaveContext->isDoubleDefenseAcquired = state; - break; - case RG_POCKET_EGG: - SetRandoInf(RAND_INF_ADULT_TRADES_HAS_POCKET_EGG, state); - break; - case RG_COJIRO: - case RG_ODD_MUSHROOM: - case RG_ODD_POTION: - case RG_POACHERS_SAW: - case RG_BROKEN_SWORD: - case RG_PRESCRIPTION: - case RG_EYEBALL_FROG: - case RG_EYEDROPS: - case RG_CLAIM_CHECK: - SetRandoInf(randoGet - RG_COJIRO + RAND_INF_ADULT_TRADES_HAS_COJIRO, state); - break; - case RG_PROGRESSIVE_HOOKSHOT: - { - uint8_t i; - for (i = 0; i < 3; i++) { - if (CurrentInventory(ITEM_HOOKSHOT) == HookshotLookup[i]) { - break; +bool Logic::MQWaterLevel(RandoWaterLevel level) { + // For ease of reading, I will call the triforce emblem that sets the water to WL_LOW the "Low Emblem", the one that + // sets it to WL_MID the "Mid Emblem", and the one that sets it to WL_HIGH the "High Emblem" + switch (level) { + // While you have to go through WL_LOW to get to Mid, the requirements for WL_LOW are stricter than WL_MID + // because you can always go up to WL_MID and then could need to go back to WL_HIGH to reach the Low Emblem + // again Thanks to this caveat you need to be able to reach and play ZL to both the High and Low Emblems to have + // WL_LOW in logic. Alternativly a way to reach WL_LOW from WL_MID could exist, but all glitchless methods need + // you to do a Low-locked action + case WL_LOW: + return (CanWaterTempleHigh && CanWaterTempleLowFromHigh) || + (CanWaterTempleLowFromMid && CanWaterTempleLowFromHigh); + case WL_LOW_OR_MID: + return (CanWaterTempleHigh && CanWaterTempleLowFromHigh) || + (CanWaterTempleLowFromHigh && CanWaterTempleMiddle) || + (CanWaterTempleLowFromMid && CanWaterTempleLowFromHigh); + // If we can set it to High out of logic we can just repeat what we did to lower the water in the first place as + // High is the default. Because of this you only need to be able to use the Low and Mid Emblems, WL_LOW could be + // skipped if it was ever possible to play ZL underwater. + case WL_MID: + return CanWaterTempleLowFromHigh && CanWaterTempleMiddle; + // Despite being the initial state of water temple, WL_HIGH has the extra requirement of making sure that, if we + // were to lower the water out of logic, we could put it back to WL_HIGH However because it is the default + // state, we do not need to check if we can actually change the water level, only to make sure we can return to + // WL_HIGH if we found the means to play ZL out of logic. There are 2 methods to lock yourself out after playing + // ZL already: Not being able to reach the High Emblem and being unable to replay ZL. (I will be ignoring + // other-age-access shenanigains) The former check would simply be a check to see if we can reach High Emblem, + // but we assume the water is WL_MID (as if we can set it to WL_LOW, we can set it to WL_MID, as Mid Emblem has + // no requirements) The latter check can be assumed for now but will want a revisit once OI tricks are added. + case WL_HIGH: + return ReachedWaterHighEmblem; + case WL_HIGH_OR_MID: + return ReachedWaterHighEmblem || (CanWaterTempleLowFromHigh && CanWaterTempleMiddle); + } + SPDLOG_ERROR("MQWaterLevel reached `return false;`. Missing case for a Water Level"); + assert(false); + return false; +} + +Logic::Logic() { +} + +uint8_t Logic::BottleCount() { + uint8_t count = 0; + if (CouldEmptyBigPoes && !AreCheckingBigPoes) { + for (int i = SLOT_BOTTLE_1; i <= SLOT_BOTTLE_4; i++) { + uint8_t item = GetSaveContext()->inventory.items[i]; + switch (item) { + case ITEM_LETTER_RUTO: + if (DeliverLetter) { + count++; } - } - auto newItem = i + (!state ? -1 : 1); - if (newItem < 0) { - newItem = 0; - } - else if (newItem > 2) { - newItem = 2; - } - SetInventory(ITEM_HOOKSHOT, HookshotLookup[newItem]); - } break; - case RG_PROGRESSIVE_STRENGTH: - { - auto currentLevel = CurrentUpgrade(UPG_STRENGTH); - auto newLevel = currentLevel + (!state ? -1 : 1); - SetUpgrade(UPG_STRENGTH, newLevel); - } break; - case RG_PROGRESSIVE_BOMB_BAG: - { - auto realGI = item.GetGIEntry(); - if (realGI->itemId == RG_BOMB_BAG_INF && realGI->modIndex == MOD_RANDOMIZER) { - SetRandoInf(RAND_INF_HAS_INFINITE_BOMB_BAG, true); break; - } - auto currentLevel = CurrentUpgrade(UPG_BOMB_BAG); - auto newLevel = currentLevel + (!state ? -1 : 1); - if (currentLevel == 0 && state || currentLevel == 1 && !state) { - SetInventory(ITEM_BOMB, (!state ? ITEM_NONE : ITEM_BOMB)); - } - SetUpgrade(UPG_BOMB_BAG, newLevel); - } break; - case RG_PROGRESSIVE_BOW: - { - auto realGI = item.GetGIEntry(); - if (realGI->itemId == RG_QUIVER_INF && realGI->modIndex == MOD_RANDOMIZER) { - SetRandoInf(RAND_INF_HAS_INFINITE_QUIVER, true); - break; - } - auto currentLevel = CurrentUpgrade(UPG_QUIVER); - auto newLevel = currentLevel + (!state ? -1 : 1); - if (currentLevel == 0 && state || currentLevel == 1 && !state) { - SetInventory(ITEM_BOW, (!state ? ITEM_NONE : ITEM_BOW)); - } - SetUpgrade(UPG_QUIVER, newLevel); - } break; - case RG_PROGRESSIVE_SLINGSHOT: - { - auto realGI = item.GetGIEntry(); - if (realGI->itemId == RG_BULLET_BAG_INF && realGI->modIndex == MOD_RANDOMIZER) { - SetRandoInf(RAND_INF_HAS_INFINITE_BULLET_BAG, true); - break; - } - auto currentLevel = CurrentUpgrade(UPG_BULLET_BAG); - auto newLevel = currentLevel + (!state ? -1 : 1); - if (currentLevel == 0 && state || currentLevel == 1 && !state) { - SetInventory(ITEM_SLINGSHOT, (!state ? ITEM_NONE : ITEM_SLINGSHOT)); - } - SetUpgrade(UPG_BULLET_BAG, newLevel); - } break; - case RG_PROGRESSIVE_WALLET: - { - auto realGI = item.GetGIEntry(); - if (realGI->itemId == RG_WALLET_INF && realGI->modIndex == MOD_RANDOMIZER) { - SetRandoInf(RAND_INF_HAS_INFINITE_MONEY, true); - break; - } - auto currentLevel = CurrentUpgrade(UPG_WALLET); - if (!CheckRandoInf(RAND_INF_HAS_WALLET) && state) { - SetRandoInf(RAND_INF_HAS_WALLET, true); - } - else if (currentLevel == 0 && !state) { - SetRandoInf(RAND_INF_HAS_WALLET, false); - } - else { - auto newLevel = currentLevel + (!state ? -1 : 1); - SetUpgrade(UPG_WALLET, newLevel); - } - } break; - case RG_PROGRESSIVE_SCALE: - { - auto currentLevel = CurrentUpgrade(UPG_SCALE); - if (!CheckRandoInf(RAND_INF_CAN_SWIM) && state) { - SetRandoInf(RAND_INF_CAN_SWIM, true); - } - else if (currentLevel == 0 && !state) { - SetRandoInf(RAND_INF_CAN_SWIM, false); - } - else { - auto newLevel = currentLevel + (!state ? -1 : 1); - SetUpgrade(UPG_SCALE, newLevel); - } - } break; - case RG_PROGRESSIVE_NUT_UPGRADE: - { - auto realGI = item.GetGIEntry(); - if (realGI->itemId == RG_NUT_UPGRADE_INF && realGI->modIndex == MOD_RANDOMIZER) { - SetRandoInf(RAND_INF_HAS_INFINITE_NUT_UPGRADE, true); - break; - } - auto currentLevel = CurrentUpgrade(UPG_NUTS); - auto newLevel = currentLevel + (!state ? -1 : 1); - if (currentLevel == 0 && state || currentLevel == 1 && !state) { - SetInventory(ITEM_NUT, (!state ? ITEM_NONE : ITEM_NUT)); - } - SetUpgrade(UPG_NUTS, newLevel); - } break; - case RG_PROGRESSIVE_STICK_UPGRADE: - { - auto realGI = item.GetGIEntry(); - if (realGI->itemId == RG_STICK_UPGRADE_INF && realGI->modIndex == MOD_RANDOMIZER) { - SetRandoInf(RAND_INF_HAS_INFINITE_STICK_UPGRADE, true); - break; - } - auto currentLevel = CurrentUpgrade(UPG_STICKS); - auto newLevel = currentLevel + (!state ? -1 : 1); - if (currentLevel == 0 && state || currentLevel == 1 && !state) { - SetInventory(ITEM_STICK, (!state ? ITEM_NONE : ITEM_STICK)); - } - SetUpgrade(UPG_STICKS, newLevel); - } break; - case RG_PROGRESSIVE_BOMBCHUS: - { - auto realGI = item.GetGIEntry(); - if (realGI->itemId == RG_BOMBCHU_INF && realGI->modIndex == MOD_RANDOMIZER) { - SetRandoInf(RAND_INF_HAS_INFINITE_BOMBCHUS, true); - break; - } - SetInventory(ITEM_BOMBCHU, (!state ? ITEM_NONE : ITEM_BOMBCHU)); - } break; - case RG_PROGRESSIVE_MAGIC_METER: - { - auto realGI = item.GetGIEntry(); - if (realGI->itemId == RG_MAGIC_INF && realGI->modIndex == MOD_RANDOMIZER) { - SetRandoInf(RAND_INF_HAS_INFINITE_MAGIC_METER, true); - break; - } - mSaveContext->magicLevel += (!state ? -1 : 1); - } break; - case RG_PROGRESSIVE_OCARINA: - { - uint8_t i; - for (i = 0; i < 3; i++) { - if (CurrentInventory(ITEM_OCARINA_FAIRY) == OcarinaLookup[i]) { - break; + case ITEM_BIG_POE: + if (CanEmptyBigPoes) { + count++; } - } - i += (!state ? -1 : 1); - if (i < 0) { - i = 0; - } - else if (i > 2) { - i = 2; - } - SetInventory(ITEM_OCARINA_FAIRY, OcarinaLookup[i]); - } break; - case RG_HEART_CONTAINER: - mSaveContext->healthCapacity += (!state ? -16 : 16); - break; - case RG_PIECE_OF_HEART: - mSaveContext->healthCapacity += (!state ? -4 : 4); - break; - case RG_BOOMERANG: - case RG_LENS_OF_TRUTH: - case RG_MEGATON_HAMMER: - case RG_DINS_FIRE: - case RG_FARORES_WIND: - case RG_NAYRUS_LOVE: - case RG_FIRE_ARROWS: - case RG_ICE_ARROWS: - case RG_LIGHT_ARROWS: - SetInventory(item.GetGIEntry()->itemId, (!state ? ITEM_NONE : item.GetGIEntry()->itemId)); - break; - case RG_MAGIC_BEAN: - case RG_MAGIC_BEAN_PACK: - { - auto change = (item.GetRandomizerGet() == RG_MAGIC_BEAN ? 1 : 10); - auto current = GetAmmo(ITEM_BEAN); - SetAmmo(ITEM_BEAN, current + (!state ? -change : change)); - } break; - case RG_EMPTY_BOTTLE: - case RG_BOTTLE_WITH_MILK: - case RG_BOTTLE_WITH_RED_POTION: - case RG_BOTTLE_WITH_GREEN_POTION: - case RG_BOTTLE_WITH_BLUE_POTION: - case RG_BOTTLE_WITH_FAIRY: - case RG_BOTTLE_WITH_FISH: - case RG_BOTTLE_WITH_BLUE_FIRE: - case RG_BOTTLE_WITH_BUGS: - case RG_BOTTLE_WITH_POE: - case RG_BOTTLE_WITH_BIG_POE: - { - uint8_t slot = SLOT_BOTTLE_1; - while (slot != SLOT_BOTTLE_4) { - if (mSaveContext->inventory.items[slot] == ITEM_NONE) { - break; - } - slot++; - } - uint16_t itemId = item.GetGIEntry()->itemId; - if (BottleRandomizerGetToItemID.contains(randoGet)) { - itemId = BottleRandomizerGetToItemID[randoGet]; - } - if (randoGet == RG_BOTTLE_WITH_BIG_POE) { - BigPoes++; - } - mSaveContext->inventory.items[slot] = itemId; - } break; - case RG_RUTOS_LETTER: - SetEventChkInf(EVENTCHKINF_OBTAINED_RUTOS_LETTER, state); - break; - case RG_GOHMA_SOUL: - case RG_KING_DODONGO_SOUL: - case RG_BARINADE_SOUL: - case RG_PHANTOM_GANON_SOUL: - case RG_VOLVAGIA_SOUL: - case RG_MORPHA_SOUL: - case RG_BONGO_BONGO_SOUL: - case RG_TWINROVA_SOUL: - case RG_GANON_SOUL: - case RG_OCARINA_A_BUTTON: - case RG_OCARINA_C_UP_BUTTON: - case RG_OCARINA_C_DOWN_BUTTON: - case RG_OCARINA_C_LEFT_BUTTON: - case RG_OCARINA_C_RIGHT_BUTTON: - case RG_GREG_RUPEE: - case RG_FISHING_POLE: - case RG_GUARD_HOUSE_KEY: - case RG_MARKET_BAZAAR_KEY: - case RG_MARKET_POTION_SHOP_KEY: - case RG_MASK_SHOP_KEY: - case RG_MARKET_SHOOTING_GALLERY_KEY: - case RG_BOMBCHU_BOWLING_KEY: - case RG_TREASURE_CHEST_GAME_BUILDING_KEY: - case RG_BOMBCHU_SHOP_KEY: - case RG_RICHARDS_HOUSE_KEY: - case RG_ALLEY_HOUSE_KEY: - case RG_KAK_BAZAAR_KEY: - case RG_KAK_POTION_SHOP_KEY: - case RG_BOSS_HOUSE_KEY: - case RG_GRANNYS_POTION_SHOP_KEY: - case RG_SKULLTULA_HOUSE_KEY: - case RG_IMPAS_HOUSE_KEY: - case RG_WINDMILL_KEY: - case RG_KAK_SHOOTING_GALLERY_KEY: - case RG_DAMPES_HUT_KEY: - case RG_TALONS_HOUSE_KEY: - case RG_STABLES_KEY: - case RG_BACK_TOWER_KEY: - case RG_HYLIA_LAB_KEY: - case RG_FISHING_HOLE_KEY: - SetRandoInf(RandoGetToRandInf.at(randoGet), state); - break; - case RG_TRIFORCE_PIECE: - mSaveContext->ship.quest.data.randomizer.triforcePiecesCollected += (!state ? -1 : 1); - break; - case RG_BOMBCHU_5: - case RG_BOMBCHU_10: - case RG_BOMBCHU_20: - SetInventory(ITEM_BOMBCHU, (!state ? ITEM_NONE : ITEM_BOMBCHU)); - break; - default: - break; + break; + case ITEM_NONE: + break; + default: + count++; + break; } } - break; - case ITEMTYPE_EQUIP: - { + } + return count; +} + +uint8_t Logic::OcarinaButtons() { + return HasItem(RG_OCARINA_A_BUTTON) + HasItem(RG_OCARINA_C_LEFT_BUTTON) + HasItem(RG_OCARINA_C_RIGHT_BUTTON) + + HasItem(RG_OCARINA_C_UP_BUTTON) + HasItem(RG_OCARINA_C_DOWN_BUTTON); +} + +bool Logic::HasBottle() { + return BottleCount() >= 1; +} + +bool Logic::CanJumpslashExceptHammer() { + // Not including hammer as hammer jump attacks can be weird; + return CanUse(RG_STICKS) || CanUse(RG_KOKIRI_SWORD) || CanUse(RG_MASTER_SWORD) || CanUse(RG_BIGGORON_SWORD); +} + +bool Logic::CanJumpslash() { + return CanJumpslashExceptHammer() || CanUse(RG_MEGATON_HAMMER); +} + +bool Logic::CanHitSwitch(EnemyDistance distance, bool inWater) { + bool hit = false; + switch (distance) { + case ED_CLOSE: + case ED_SHORT_JUMPSLASH: + hit = CanUse(RG_KOKIRI_SWORD) || CanUse(RG_MEGATON_HAMMER); + [[fallthrough]]; + case ED_MASTER_SWORD_JUMPSLASH: + hit = hit || CanUse(RG_MASTER_SWORD); + [[fallthrough]]; + case ED_LONG_JUMPSLASH: + hit = hit || CanUse(RG_BIGGORON_SWORD) || CanUse(RG_STICKS); + [[fallthrough]]; + case ED_BOMB_THROW: + hit = hit || (!inWater && CanUse(RG_BOMB_BAG)); + [[fallthrough]]; + case ED_BOOMERANG: + hit = hit || CanUse(RG_BOOMERANG); + [[fallthrough]]; + case ED_HOOKSHOT: + // RANDOTODO test chu range in a practical example + hit = hit || CanUse(RG_HOOKSHOT) || CanUse(RG_BOMBCHU_5); + [[fallthrough]]; + case ED_LONGSHOT: + hit = hit || CanUse(RG_LONGSHOT); + [[fallthrough]]; + case ED_FAR: + hit = hit || CanUse(RG_FAIRY_SLINGSHOT) || CanUse(RG_FAIRY_BOW); + break; + } + return hit; +} + +bool Logic::CanDamage() { + return CanUse(RG_FAIRY_SLINGSHOT) || CanJumpslash() || HasExplosives() || CanUse(RG_DINS_FIRE) || + CanUse(RG_FAIRY_BOW); +} + +bool Logic::CanAttack() { + return CanDamage() || CanUse(RG_BOOMERANG) || CanUse(RG_HOOKSHOT); +} + +bool Logic::BombchusEnabled() { + return ctx->GetOption(RSK_BOMBCHU_BAG) ? CheckInventory(ITEM_BOMBCHU, true) : HasItem(RG_BOMB_BAG); +} + +// TODO: Implement Ammo Drop Setting in place of bombchu drops +bool Logic::BombchuRefill() { + return GetInLogic(LOGIC_BUY_BOMBCHUS) || CouldPlayBowling || CarpetMerchant || + (ctx->GetOption(RSK_ENABLE_BOMBCHU_DROPS).Is(RO_AMMO_DROPS_ON /*_PLUS_BOMBCHU*/)); +} + +bool Logic::HookshotOrBoomerang() { + return CanUse(RG_HOOKSHOT) || CanUse(RG_BOOMERANG); +} + +bool Logic::ScarecrowsSong() { + return (ctx->GetOption(RSK_SKIP_SCARECROWS_SONG) && HasItem(RG_FAIRY_OCARINA) && OcarinaButtons() >= 2) || + (ChildScarecrow && AdultScarecrow); +} + +bool Logic::BlueFire() { + return CanUse(RG_BOTTLE_WITH_BLUE_FIRE) || (ctx->GetOption(RSK_BLUE_FIRE_ARROWS) && CanUse(RG_ICE_ARROWS)); +} + +bool Logic::CanBreakPots() { + return true; +} + +bool Logic::CanBreakCrates() { + return true; +} + +bool Logic::CanBreakSmallCrates() { + return true; +} + +bool Logic::HasExplosives() { + return CanUse(RG_BOMB_BAG) || CanUse(RG_BOMBCHU_5); +} + +bool Logic::BlastOrSmash() { + return HasExplosives() || CanUse(RG_MEGATON_HAMMER); +} + +bool Logic::CanSpawnSoilSkull() { + return IsChild && CanUse(RG_BOTTLE_WITH_BUGS); +} + +bool Logic::CanReflectNuts() { + return CanUse(RG_DEKU_SHIELD) || (IsAdult && HasItem(RG_HYLIAN_SHIELD)); +} + +bool Logic::CanCutShrubs() { + return CanUse(RG_KOKIRI_SWORD) || CanUse(RG_BOOMERANG) || HasExplosives() || CanUse(RG_MASTER_SWORD) || + CanUse(RG_MEGATON_HAMMER) || CanUse(RG_BIGGORON_SWORD) || HasItem(RG_GORONS_BRACELET); +} + +bool Logic::CanStunDeku() { + return CanAttack() || CanUse(RG_NUTS) || CanReflectNuts(); +} + +bool Logic::CanLeaveForest() { + return ctx->GetOption(RSK_FOREST).IsNot(RO_CLOSED_FOREST_ON) || IsAdult || DekuTreeClear || + ctx->GetOption(RSK_SHUFFLE_INTERIOR_ENTRANCES) || ctx->GetOption(RSK_SHUFFLE_OVERWORLD_ENTRANCES); +} + +bool Logic::CallGossipFairyExceptSuns() { + return CanUse(RG_ZELDAS_LULLABY) || CanUse(RG_EPONAS_SONG) || CanUse(RG_SONG_OF_TIME); +} + +bool Logic::CallGossipFairy() { + return CallGossipFairyExceptSuns() || CanUse(RG_SUNS_SONG); +} + +// the number returned by this is in half heart hits taken. +// RANDOTODO work in OoT side health instead for greater applicability (16 per heart) +uint8_t Logic::EffectiveHealth() { + /* Multiplier will be: + 0 for half daamge + 1 for normal damage + 2 for double damage + 3 for quad damage + 4 for 8* damage + 5 for 16* damage + 10 for OHKO. + This is the number of shifts to apply, not a real multiplier + */ + uint8_t Multiplier = + (ctx->GetOption(RSK_DAMAGE_MULTIPLIER).Get() < 6) ? ctx->GetOption(RSK_DAMAGE_MULTIPLIER).Get() : 10; + //(Hearts() << (2 + HasItem(RG_DOUBLE_DEFENSE))) is quarter hearts after DD + //>> Multiplier halves on normal and does nothing on half, meaning we're working with half hearts on normal damage + return ((Hearts() << (2 + HasItem(RG_DOUBLE_DEFENSE))) >> Multiplier) + + // As 1 is a quarter heart, (1 << Multiplier) is effectivly half-hearts of unmodified damage + // Adds an extra hit if the damage is not exact lethal + ((Hearts() << (2 + HasItem(RG_DOUBLE_DEFENSE))) % (1 << Multiplier) > 0); +} + +uint8_t Logic::Hearts() { + return GetSaveContext()->healthCapacity / 16; +} + +uint8_t Logic::DungeonCount() { + return DekuTreeClear + DodongosCavernClear + JabuJabusBellyClear + ForestTempleClear + FireTempleClear + + WaterTempleClear + SpiritTempleClear + ShadowTempleClear; +} + +uint8_t Logic::StoneCount() { + return HasItem(RG_KOKIRI_EMERALD) + HasItem(RG_GORON_RUBY) + HasItem(RG_ZORA_SAPPHIRE); +} + +uint8_t Logic::MedallionCount() { + return HasItem(RG_FOREST_MEDALLION) + HasItem(RG_FIRE_MEDALLION) + HasItem(RG_WATER_MEDALLION) + + HasItem(RG_SPIRIT_MEDALLION) + HasItem(RG_SHADOW_MEDALLION) + HasItem(RG_LIGHT_MEDALLION); +} + +uint8_t Logic::FireTimer() { + return CanUse(RG_GORON_TUNIC) ? 255 : (ctx->GetTrickOption(RT_FEWER_TUNIC_REQUIREMENTS)) ? (Hearts() * 8) : 0; +} + +// Tunic is not required if you are using irons to do something that a simple gold scale dive could do, and you are not +// in water temple. (celing swimming and long walks through water do not count) +uint8_t Logic::WaterTimer() { + return CanUse(RG_ZORA_TUNIC) ? 255 : (ctx->GetTrickOption(RT_FEWER_TUNIC_REQUIREMENTS)) ? (Hearts() * 8) : 0; +} + +bool Logic::TakeDamage() { + return CanUse(RG_BOTTLE_WITH_FAIRY) || EffectiveHealth() != 1 || CanUse(RG_NAYRUS_LOVE); +} + +bool Logic::CanOpenBombGrotto() { + return BlastOrSmash() && (HasItem(RG_STONE_OF_AGONY) || ctx->GetTrickOption(RT_GROTTOS_WITHOUT_AGONY)); +} + +bool Logic::CanOpenStormsGrotto() { + return CanUse(RG_SONG_OF_STORMS) && (HasItem(RG_STONE_OF_AGONY) || ctx->GetTrickOption(RT_GROTTOS_WITHOUT_AGONY)); +} + +bool Logic::CanGetNightTimeGS() { + return AtNight && (CanUse(RG_SUNS_SONG) || !ctx->GetOption(RSK_SKULLS_SUNS_SONG)); +} + +bool Logic::CanBreakUpperBeehives() { + return HookshotOrBoomerang() || (ctx->GetTrickOption(RT_BOMBCHU_BEEHIVES) && CanUse(RG_BOMBCHU_5)); +} + +bool Logic::CanBreakLowerBeehives() { + return CanBreakUpperBeehives() || CanUse(RG_BOMB_BAG); +} + +bool Logic::HasFireSource() { + return CanUse(RG_DINS_FIRE) || CanUse(RG_FIRE_ARROWS); +} + +bool Logic::HasFireSourceWithTorch() { + return HasFireSource() || CanUse(RG_STICKS); +} + +// Is this best off signaling what you have already traded, or what step you are currently on? +bool Logic::TradeQuestStep(RandomizerGet rg) { + if (ctx->GetOption(RSK_SHUFFLE_ADULT_TRADE)) { + return false; // This does not apply when we are shuffling trade items + } + bool hasState = false; + // Falling through each case to test each possibility + switch (rg) { + case RG_POCKET_EGG: + hasState = hasState || HasItem(RG_POCKET_EGG); + [[fallthrough]]; + case RG_COJIRO: + hasState = hasState || HasItem(RG_COJIRO); + [[fallthrough]]; + case RG_ODD_MUSHROOM: + hasState = hasState || HasItem(RG_ODD_MUSHROOM); + [[fallthrough]]; + case RG_ODD_POTION: + hasState = hasState || HasItem(RG_ODD_POTION); + [[fallthrough]]; + case RG_POACHERS_SAW: + hasState = hasState || HasItem(RG_POACHERS_SAW); + [[fallthrough]]; + case RG_BROKEN_SWORD: + hasState = hasState || HasItem(RG_BROKEN_SWORD); + [[fallthrough]]; + case RG_PRESCRIPTION: + hasState = hasState || HasItem(RG_PRESCRIPTION); + [[fallthrough]]; + case RG_EYEDROPS: + hasState = hasState || HasItem(RG_EYEDROPS); + [[fallthrough]]; + case RG_CLAIM_CHECK: + hasState = hasState || HasItem(RG_CLAIM_CHECK); + break; + default: + SPDLOG_ERROR("TradeQuestStep reached `return false;`. Missing case for RandomizerGet of {}", + static_cast(rg)); + assert(false); + return false; + } + return hasState; +} + +bool Logic::CanFinishGerudoFortress() { + return (ctx->GetOption(RSK_GERUDO_FORTRESS).Is(RO_GF_CARPENTERS_NORMAL) && SmallKeys(RR_GERUDO_FORTRESS, 4) && + CanKillEnemy(RE_GERUDO_WARRIOR) && + (HasItem(RG_GERUDO_MEMBERSHIP_CARD) || CanUse(RG_FAIRY_BOW) || CanUse(RG_HOOKSHOT) || + CanUse(RG_HOVER_BOOTS) || ctx->GetTrickOption(RT_GF_KITCHEN))) || + (ctx->GetOption(RSK_GERUDO_FORTRESS).Is(RO_GF_CARPENTERS_FAST) && SmallKeys(RR_GERUDO_FORTRESS, 1) && + CanKillEnemy(RE_GERUDO_WARRIOR)) || + ctx->GetOption(RSK_GERUDO_FORTRESS).Is(RO_GF_CARPENTERS_FREE); +} + +bool Logic::CanStandingShield() { + return CanUse(RG_MIRROR_SHIELD) || (IsAdult && HasItem(RG_HYLIAN_SHIELD)) || CanUse(RG_DEKU_SHIELD); +} + +bool Logic::CanShield() { + return CanUse(RG_MIRROR_SHIELD) || HasItem(RG_HYLIAN_SHIELD) || CanUse(RG_DEKU_SHIELD); +} + +bool Logic::CanUseProjectile() { + return HasExplosives() || CanUse(RG_FAIRY_BOW) || CanUse(RG_HOOKSHOT) || CanUse(RG_FAIRY_SLINGSHOT) || + CanUse(RG_BOOMERANG); +} + +bool Logic::CanBuildRainbowBridge() { + return ctx->GetOption(RSK_RAINBOW_BRIDGE).Is(RO_BRIDGE_ALWAYS_OPEN) || + (ctx->GetOption(RSK_RAINBOW_BRIDGE).Is(RO_BRIDGE_VANILLA) && HasItem(RG_SHADOW_MEDALLION) && + HasItem(RG_SPIRIT_MEDALLION) && CanUse(RG_LIGHT_ARROWS)) || + (ctx->GetOption(RSK_RAINBOW_BRIDGE).Is(RO_BRIDGE_STONES) && + StoneCount() + (HasItem(RG_GREG_RUPEE) && ctx->GetOption(RSK_BRIDGE_OPTIONS).Is(RO_BRIDGE_GREG_REWARD)) >= + ctx->GetOption(RSK_RAINBOW_BRIDGE_STONE_COUNT).Get()) || + (ctx->GetOption(RSK_RAINBOW_BRIDGE).Is(RO_BRIDGE_MEDALLIONS) && + MedallionCount() + + (HasItem(RG_GREG_RUPEE) && ctx->GetOption(RSK_BRIDGE_OPTIONS).Is(RO_BRIDGE_GREG_REWARD)) >= + ctx->GetOption(RSK_RAINBOW_BRIDGE_MEDALLION_COUNT).Get()) || + (ctx->GetOption(RSK_RAINBOW_BRIDGE).Is(RO_BRIDGE_DUNGEON_REWARDS) && + StoneCount() + MedallionCount() + + (HasItem(RG_GREG_RUPEE) && ctx->GetOption(RSK_BRIDGE_OPTIONS).Is(RO_BRIDGE_GREG_REWARD)) >= + ctx->GetOption(RSK_RAINBOW_BRIDGE_REWARD_COUNT).Get()) || + (ctx->GetOption(RSK_RAINBOW_BRIDGE).Is(RO_BRIDGE_DUNGEONS) && + DungeonCount() + (HasItem(RG_GREG_RUPEE) && ctx->GetOption(RSK_BRIDGE_OPTIONS).Is(RO_BRIDGE_GREG_REWARD)) >= + ctx->GetOption(RSK_RAINBOW_BRIDGE_DUNGEON_COUNT).Get()) || + (ctx->GetOption(RSK_RAINBOW_BRIDGE).Is(RO_BRIDGE_TOKENS) && + GetGSCount() >= ctx->GetOption(RSK_RAINBOW_BRIDGE_TOKEN_COUNT).Get()) || + (ctx->GetOption(RSK_RAINBOW_BRIDGE).Is(RO_BRIDGE_GREG) && HasItem(RG_GREG_RUPEE)); +} + +bool Logic::CanTriggerLACS() { + return (ctx->LACSCondition() == RO_LACS_VANILLA && HasItem(RG_SHADOW_MEDALLION) && HasItem(RG_SPIRIT_MEDALLION)) || + (ctx->LACSCondition() == RO_LACS_STONES && + StoneCount() + (HasItem(RG_GREG_RUPEE) && ctx->GetOption(RSK_LACS_OPTIONS).Is(RO_LACS_GREG_REWARD)) >= + ctx->GetOption(RSK_LACS_STONE_COUNT).Get()) || + (ctx->LACSCondition() == RO_LACS_MEDALLIONS && + MedallionCount() + (HasItem(RG_GREG_RUPEE) && ctx->GetOption(RSK_LACS_OPTIONS).Is(RO_LACS_GREG_REWARD)) >= + ctx->GetOption(RSK_LACS_MEDALLION_COUNT).Get()) || + (ctx->LACSCondition() == RO_LACS_REWARDS && + StoneCount() + MedallionCount() + + (HasItem(RG_GREG_RUPEE) && ctx->GetOption(RSK_LACS_OPTIONS).Is(RO_LACS_GREG_REWARD)) >= + ctx->GetOption(RSK_LACS_REWARD_COUNT).Get()) || + (ctx->LACSCondition() == RO_LACS_DUNGEONS && + DungeonCount() + (HasItem(RG_GREG_RUPEE) && ctx->GetOption(RSK_LACS_OPTIONS).Is(RO_LACS_GREG_REWARD)) >= + ctx->GetOption(RSK_LACS_DUNGEON_COUNT).Get()) || + (ctx->LACSCondition() == RO_LACS_TOKENS && GetGSCount() >= ctx->GetOption(RSK_LACS_TOKEN_COUNT).Get()); +} + +bool Logic::SmallKeys(RandomizerRegion dungeon, uint8_t requiredAmount) { + return SmallKeys(dungeon, requiredAmount, requiredAmount); +} + +bool Logic::SmallKeys(RandomizerRegion dungeon, uint8_t requiredAmountGlitchless, uint8_t requiredAmountGlitched) { + if (HasItem(RG_SKELETON_KEY)) { + return true; + } + switch (dungeon) { + case RR_FOREST_TEMPLE: + /*if (IsGlitched && (GetDifficultyValueFromString(GlitchHookshotJump_Boots) >= + static_cast(GlitchDifficulty::INTERMEDIATE) || GetDifficultyValueFromString(GlitchHoverBoost) >= + static_cast(GlitchDifficulty::NOVICE) || (GetDifficultyValueFromString(GlitchHover) >= + static_cast(GlitchDifficulty::NOVICE) && GetDifficultyValueFromString(GlitchISG) >= + static_cast(GlitchDifficulty::INTERMEDIATE)))) { return ForestTempleKeys >= requiredAmountGlitched; + }*/ + return GetSmallKeyCount(SCENE_FOREST_TEMPLE) >= requiredAmountGlitchless; + + case RR_FIRE_TEMPLE: + /*if (IsGlitched && (GetDifficultyValueFromString(GlitchLedgeClip) >= + static_cast(GlitchDifficulty::INTERMEDIATE) || GetDifficultyValueFromString(GlitchHover) >= + static_cast(GlitchDifficulty::INTERMEDIATE))) { return FireTempleKeys >= requiredAmountGlitched; + }*/ + return GetSmallKeyCount(SCENE_FIRE_TEMPLE) >= requiredAmountGlitchless; + + case RR_WATER_TEMPLE: + /*if (IsGlitched && (false)) { + return WaterTempleKeys >= requiredAmountGlitched; + }*/ + return GetSmallKeyCount(SCENE_WATER_TEMPLE) >= requiredAmountGlitchless; + + case RR_SPIRIT_TEMPLE: + /*if (IsGlitched && (false)) { + return SpiritTempleKeys >= requiredAmountGlitched; + }*/ + return GetSmallKeyCount(SCENE_SPIRIT_TEMPLE) >= requiredAmountGlitchless; + + case RR_SHADOW_TEMPLE: + /*if (IsGlitched && (GetDifficultyValueFromString(GlitchHookshotClip) >= + static_cast(GlitchDifficulty::NOVICE))) { return ShadowTempleKeys >= requiredAmountGlitched; + }*/ + return GetSmallKeyCount(SCENE_SHADOW_TEMPLE) >= requiredAmountGlitchless; + + case RR_BOTTOM_OF_THE_WELL: + /*if (IsGlitched && (false)) { + return BottomOfTheWellKeys >= requiredAmountGlitched; + }*/ + return GetSmallKeyCount(SCENE_BOTTOM_OF_THE_WELL) >= requiredAmountGlitchless; + + case RR_GERUDO_TRAINING_GROUND: + /*if (IsGlitched && (false)) { + return GerudoTrainingGroundsKeys >= requiredAmountGlitched; + }*/ + return GetSmallKeyCount(SCENE_GERUDO_TRAINING_GROUND) >= requiredAmountGlitchless; + + case RR_GANONS_CASTLE: + /*if (IsGlitched && (false)) { + return GanonsCastleKeys >= requiredAmountGlitched; + }*/ + return GetSmallKeyCount(SCENE_INSIDE_GANONS_CASTLE) >= requiredAmountGlitchless; + + case RR_MARKET_TREASURE_CHEST_GAME: + /*if (IsGlitched && (false)) { + return TreasureGameKeys >= requiredAmountGlitched; + }*/ + return GetSmallKeyCount(SCENE_TREASURE_BOX_SHOP) >= requiredAmountGlitchless; + + case RR_GERUDO_FORTRESS: + return GetSmallKeyCount(SCENE_THIEVES_HIDEOUT) >= requiredAmountGlitchless; + + default: + return false; + } +} + +std::map Logic::RandoGetToEquipFlag = { + { RG_KOKIRI_SWORD, EQUIP_FLAG_SWORD_KOKIRI }, { RG_MASTER_SWORD, EQUIP_FLAG_SWORD_MASTER }, + { RG_BIGGORON_SWORD, EQUIP_FLAG_SWORD_BGS }, { RG_DEKU_SHIELD, EQUIP_FLAG_SHIELD_DEKU }, + { RG_HYLIAN_SHIELD, EQUIP_FLAG_SHIELD_HYLIAN }, { RG_MIRROR_SHIELD, EQUIP_FLAG_SHIELD_MIRROR }, + { RG_GORON_TUNIC, EQUIP_FLAG_TUNIC_GORON }, { RG_ZORA_TUNIC, EQUIP_FLAG_TUNIC_ZORA }, + { RG_BUY_DEKU_SHIELD, EQUIP_FLAG_SHIELD_DEKU }, { RG_BUY_HYLIAN_SHIELD, EQUIP_FLAG_SHIELD_HYLIAN }, + { RG_BUY_GORON_TUNIC, EQUIP_FLAG_TUNIC_GORON }, { RG_BUY_ZORA_TUNIC, EQUIP_FLAG_TUNIC_ZORA }, + { RG_IRON_BOOTS, EQUIP_FLAG_BOOTS_IRON }, { RG_HOVER_BOOTS, EQUIP_FLAG_BOOTS_HOVER } +}; + +std::map Logic::RandoGetToRandInf = { + { RG_ZELDAS_LETTER, RAND_INF_ZELDAS_LETTER }, + { RG_WEIRD_EGG, RAND_INF_WEIRD_EGG }, + { RG_GOHMA_SOUL, RAND_INF_GOHMA_SOUL }, + { RG_KING_DODONGO_SOUL, RAND_INF_KING_DODONGO_SOUL }, + { RG_BARINADE_SOUL, RAND_INF_BARINADE_SOUL }, + { RG_PHANTOM_GANON_SOUL, RAND_INF_PHANTOM_GANON_SOUL }, + { RG_VOLVAGIA_SOUL, RAND_INF_VOLVAGIA_SOUL }, + { RG_MORPHA_SOUL, RAND_INF_MORPHA_SOUL }, + { RG_BONGO_BONGO_SOUL, RAND_INF_BONGO_BONGO_SOUL }, + { RG_TWINROVA_SOUL, RAND_INF_TWINROVA_SOUL }, + { RG_GANON_SOUL, RAND_INF_GANON_SOUL }, + { RG_OCARINA_A_BUTTON, RAND_INF_HAS_OCARINA_A }, + { RG_OCARINA_C_UP_BUTTON, RAND_INF_HAS_OCARINA_C_UP }, + { RG_OCARINA_C_DOWN_BUTTON, RAND_INF_HAS_OCARINA_C_DOWN }, + { RG_OCARINA_C_LEFT_BUTTON, RAND_INF_HAS_OCARINA_C_LEFT }, + { RG_OCARINA_C_RIGHT_BUTTON, RAND_INF_HAS_OCARINA_C_RIGHT }, + { RG_SKELETON_KEY, RAND_INF_HAS_SKELETON_KEY }, + { RG_GREG_RUPEE, RAND_INF_GREG_FOUND }, + { RG_FISHING_POLE, RAND_INF_FISHING_POLE_FOUND }, + { RG_GUARD_HOUSE_KEY, RAND_INF_GUARD_HOUSE_KEY_OBTAINED }, + { RG_MARKET_BAZAAR_KEY, RAND_INF_MARKET_BAZAAR_KEY_OBTAINED }, + { RG_MARKET_POTION_SHOP_KEY, RAND_INF_MARKET_POTION_SHOP_KEY_OBTAINED }, + { RG_MASK_SHOP_KEY, RAND_INF_MASK_SHOP_KEY_OBTAINED }, + { RG_MARKET_SHOOTING_GALLERY_KEY, RAND_INF_MARKET_SHOOTING_GALLERY_KEY_OBTAINED }, + { RG_BOMBCHU_BOWLING_KEY, RAND_INF_BOMBCHU_BOWLING_KEY_OBTAINED }, + { RG_TREASURE_CHEST_GAME_BUILDING_KEY, RAND_INF_TREASURE_CHEST_GAME_BUILDING_KEY_OBTAINED }, + { RG_BOMBCHU_SHOP_KEY, RAND_INF_BOMBCHU_SHOP_KEY_OBTAINED }, + { RG_RICHARDS_HOUSE_KEY, RAND_INF_RICHARDS_HOUSE_KEY_OBTAINED }, + { RG_ALLEY_HOUSE_KEY, RAND_INF_ALLEY_HOUSE_KEY_OBTAINED }, + { RG_KAK_BAZAAR_KEY, RAND_INF_KAK_BAZAAR_KEY_OBTAINED }, + { RG_KAK_POTION_SHOP_KEY, RAND_INF_KAK_POTION_SHOP_KEY_OBTAINED }, + { RG_BOSS_HOUSE_KEY, RAND_INF_BOSS_HOUSE_KEY_OBTAINED }, + { RG_GRANNYS_POTION_SHOP_KEY, RAND_INF_GRANNYS_POTION_SHOP_KEY_OBTAINED }, + { RG_SKULLTULA_HOUSE_KEY, RAND_INF_SKULLTULA_HOUSE_KEY_OBTAINED }, + { RG_IMPAS_HOUSE_KEY, RAND_INF_IMPAS_HOUSE_KEY_OBTAINED }, + { RG_WINDMILL_KEY, RAND_INF_WINDMILL_KEY_OBTAINED }, + { RG_KAK_SHOOTING_GALLERY_KEY, RAND_INF_KAK_SHOOTING_GALLERY_KEY_OBTAINED }, + { RG_DAMPES_HUT_KEY, RAND_INF_DAMPES_HUT_KEY_OBTAINED }, + { RG_TALONS_HOUSE_KEY, RAND_INF_TALONS_HOUSE_KEY_OBTAINED }, + { RG_STABLES_KEY, RAND_INF_STABLES_KEY_OBTAINED }, + { RG_BACK_TOWER_KEY, RAND_INF_BACK_TOWER_KEY_OBTAINED }, + { RG_HYLIA_LAB_KEY, RAND_INF_HYLIA_LAB_KEY_OBTAINED }, + { RG_FISHING_HOLE_KEY, RAND_INF_FISHING_HOLE_KEY_OBTAINED }, +}; + +std::map Logic::RandoGetToDungeonScene = { + { RG_FOREST_TEMPLE_SMALL_KEY, SCENE_FOREST_TEMPLE }, + { RG_FIRE_TEMPLE_SMALL_KEY, SCENE_FIRE_TEMPLE }, + { RG_WATER_TEMPLE_SMALL_KEY, SCENE_WATER_TEMPLE }, + { RG_SPIRIT_TEMPLE_SMALL_KEY, SCENE_SPIRIT_TEMPLE }, + { RG_SHADOW_TEMPLE_SMALL_KEY, SCENE_SHADOW_TEMPLE }, + { RG_BOTTOM_OF_THE_WELL_SMALL_KEY, SCENE_BOTTOM_OF_THE_WELL }, + { RG_GERUDO_TRAINING_GROUND_SMALL_KEY, SCENE_GERUDO_TRAINING_GROUND }, + { RG_GERUDO_FORTRESS_SMALL_KEY, SCENE_THIEVES_HIDEOUT }, + { RG_GANONS_CASTLE_SMALL_KEY, SCENE_INSIDE_GANONS_CASTLE }, + { RG_FOREST_TEMPLE_KEY_RING, SCENE_FOREST_TEMPLE }, + { RG_FIRE_TEMPLE_KEY_RING, SCENE_FIRE_TEMPLE }, + { RG_WATER_TEMPLE_KEY_RING, SCENE_WATER_TEMPLE }, + { RG_SPIRIT_TEMPLE_KEY_RING, SCENE_SPIRIT_TEMPLE }, + { RG_SHADOW_TEMPLE_KEY_RING, SCENE_SHADOW_TEMPLE }, + { RG_BOTTOM_OF_THE_WELL_KEY_RING, SCENE_BOTTOM_OF_THE_WELL }, + { RG_GERUDO_TRAINING_GROUND_KEY_RING, SCENE_GERUDO_TRAINING_GROUND }, + { RG_GERUDO_FORTRESS_KEY_RING, SCENE_THIEVES_HIDEOUT }, + { RG_GANONS_CASTLE_KEY_RING, SCENE_INSIDE_GANONS_CASTLE }, + { RG_FOREST_TEMPLE_BOSS_KEY, SCENE_FOREST_TEMPLE }, + { RG_FIRE_TEMPLE_BOSS_KEY, SCENE_FIRE_TEMPLE }, + { RG_WATER_TEMPLE_BOSS_KEY, SCENE_WATER_TEMPLE }, + { RG_SPIRIT_TEMPLE_BOSS_KEY, SCENE_SPIRIT_TEMPLE }, + { RG_SHADOW_TEMPLE_BOSS_KEY, SCENE_SHADOW_TEMPLE }, + { RG_GANONS_CASTLE_BOSS_KEY, SCENE_INSIDE_GANONS_CASTLE }, + { RG_DEKU_TREE_MAP, SCENE_DEKU_TREE }, + { RG_DODONGOS_CAVERN_MAP, SCENE_DODONGOS_CAVERN }, + { RG_JABU_JABUS_BELLY_MAP, SCENE_JABU_JABU }, + { RG_FOREST_TEMPLE_MAP, SCENE_FOREST_TEMPLE }, + { RG_FIRE_TEMPLE_MAP, SCENE_FIRE_TEMPLE }, + { RG_WATER_TEMPLE_MAP, SCENE_WATER_TEMPLE }, + { RG_SPIRIT_TEMPLE_MAP, SCENE_SPIRIT_TEMPLE }, + { RG_SHADOW_TEMPLE_MAP, SCENE_SHADOW_TEMPLE }, + { RG_BOTTOM_OF_THE_WELL_MAP, SCENE_BOTTOM_OF_THE_WELL }, + { RG_ICE_CAVERN_MAP, SCENE_ICE_CAVERN }, + { RG_DEKU_TREE_COMPASS, SCENE_DEKU_TREE }, + { RG_DODONGOS_CAVERN_COMPASS, SCENE_DODONGOS_CAVERN }, + { RG_JABU_JABUS_BELLY_COMPASS, SCENE_JABU_JABU }, + { RG_FOREST_TEMPLE_COMPASS, SCENE_FOREST_TEMPLE }, + { RG_FIRE_TEMPLE_COMPASS, SCENE_FIRE_TEMPLE }, + { RG_WATER_TEMPLE_COMPASS, SCENE_WATER_TEMPLE }, + { RG_SPIRIT_TEMPLE_COMPASS, SCENE_SPIRIT_TEMPLE }, + { RG_SHADOW_TEMPLE_COMPASS, SCENE_SHADOW_TEMPLE }, + { RG_BOTTOM_OF_THE_WELL_COMPASS, SCENE_BOTTOM_OF_THE_WELL }, + { RG_ICE_CAVERN_COMPASS, SCENE_ICE_CAVERN }, + { RG_TREASURE_GAME_SMALL_KEY, SCENE_TREASURE_BOX_SHOP } +}; + +std::map Logic::RandoGetToQuestItem = { + { RG_FOREST_MEDALLION, QUEST_MEDALLION_FOREST }, + { RG_FIRE_MEDALLION, QUEST_MEDALLION_FIRE }, + { RG_WATER_MEDALLION, QUEST_MEDALLION_WATER }, + { RG_SPIRIT_MEDALLION, QUEST_MEDALLION_SPIRIT }, + { RG_SHADOW_MEDALLION, QUEST_MEDALLION_SHADOW }, + { RG_LIGHT_MEDALLION, QUEST_MEDALLION_LIGHT }, + { RG_MINUET_OF_FOREST, QUEST_SONG_MINUET }, + { RG_BOLERO_OF_FIRE, QUEST_SONG_BOLERO }, + { RG_SERENADE_OF_WATER, QUEST_SONG_SERENADE }, + { RG_REQUIEM_OF_SPIRIT, QUEST_SONG_REQUIEM }, + { RG_NOCTURNE_OF_SHADOW, QUEST_SONG_NOCTURNE }, + { RG_PRELUDE_OF_LIGHT, QUEST_SONG_PRELUDE }, + { RG_ZELDAS_LULLABY, QUEST_SONG_LULLABY }, + { RG_EPONAS_SONG, QUEST_SONG_EPONA }, + { RG_SARIAS_SONG, QUEST_SONG_SARIA }, + { RG_SUNS_SONG, QUEST_SONG_SUN }, + { RG_SONG_OF_TIME, QUEST_SONG_TIME }, + { RG_SONG_OF_STORMS, QUEST_SONG_STORMS }, + { RG_KOKIRI_EMERALD, QUEST_KOKIRI_EMERALD }, + { RG_GORON_RUBY, QUEST_GORON_RUBY }, + { RG_ZORA_SAPPHIRE, QUEST_ZORA_SAPPHIRE }, + { RG_STONE_OF_AGONY, QUEST_STONE_OF_AGONY }, + { RG_GERUDO_MEMBERSHIP_CARD, QUEST_GERUDO_CARD }, +}; + +std::map BottleRandomizerGetToItemID = { + { RG_BOTTLE_WITH_RED_POTION, ITEM_POTION_RED }, + { RG_BOTTLE_WITH_GREEN_POTION, ITEM_POTION_GREEN }, + { RG_BOTTLE_WITH_BLUE_POTION, ITEM_POTION_BLUE }, + { RG_BOTTLE_WITH_FAIRY, ITEM_FAIRY }, + { RG_BOTTLE_WITH_FISH, ITEM_FISH }, + { RG_BOTTLE_WITH_BLUE_FIRE, ITEM_BLUE_FIRE }, + { RG_BOTTLE_WITH_BUGS, ITEM_BUG }, + { RG_BOTTLE_WITH_POE, ITEM_POE }, + { RG_BOTTLE_WITH_BIG_POE, ITEM_BIG_POE }, +}; + +uint32_t HookshotLookup[3] = { ITEM_NONE, ITEM_HOOKSHOT, ITEM_LONGSHOT }; +uint32_t OcarinaLookup[3] = { ITEM_NONE, ITEM_OCARINA_FAIRY, ITEM_OCARINA_TIME }; + +void Logic::ApplyItemEffect(Item& item, bool state) { + auto randoGet = item.GetRandomizerGet(); + if (item.GetGIEntry()->objectId == OBJECT_GI_STICK) { + SetInventory(ITEM_STICK, (!state ? ITEM_NONE : ITEM_STICK)); + } + if (item.GetGIEntry()->objectId == OBJECT_GI_NUTS) { + SetInventory(ITEM_NUT, (!state ? ITEM_NONE : ITEM_NUT)); + } + switch (item.GetItemType()) { + case ITEMTYPE_ITEM: { + switch (randoGet) { + case RG_STONE_OF_AGONY: + case RG_GERUDO_MEMBERSHIP_CARD: + SetQuestItem(RandoGetToQuestItem.at(randoGet), state); + break; + case RG_WEIRD_EGG: + SetRandoInf(RAND_INF_WEIRD_EGG, state); + break; + case RG_ZELDAS_LETTER: + SetRandoInf(RAND_INF_ZELDAS_LETTER, state); + break; + case RG_DOUBLE_DEFENSE: + mSaveContext->isDoubleDefenseAcquired = state; + break; + case RG_POCKET_EGG: + SetRandoInf(RAND_INF_ADULT_TRADES_HAS_POCKET_EGG, state); + break; + case RG_COJIRO: + case RG_ODD_MUSHROOM: + case RG_ODD_POTION: + case RG_POACHERS_SAW: + case RG_BROKEN_SWORD: + case RG_PRESCRIPTION: + case RG_EYEBALL_FROG: + case RG_EYEDROPS: + case RG_CLAIM_CHECK: + SetRandoInf(randoGet - RG_COJIRO + RAND_INF_ADULT_TRADES_HAS_COJIRO, state); + break; + case RG_PROGRESSIVE_HOOKSHOT: { + uint8_t i; + for (i = 0; i < 3; i++) { + if (CurrentInventory(ITEM_HOOKSHOT) == HookshotLookup[i]) { + break; + } + } + auto newItem = i + (!state ? -1 : 1); + if (newItem < 0) { + newItem = 0; + } else if (newItem > 2) { + newItem = 2; + } + SetInventory(ITEM_HOOKSHOT, HookshotLookup[newItem]); + } break; + case RG_PROGRESSIVE_STRENGTH: { + auto currentLevel = CurrentUpgrade(UPG_STRENGTH); + auto newLevel = currentLevel + (!state ? -1 : 1); + SetUpgrade(UPG_STRENGTH, newLevel); + } break; + case RG_PROGRESSIVE_BOMB_BAG: { + auto realGI = item.GetGIEntry(); + if (realGI->itemId == RG_BOMB_BAG_INF && realGI->modIndex == MOD_RANDOMIZER) { + SetRandoInf(RAND_INF_HAS_INFINITE_BOMB_BAG, true); + break; + } + auto currentLevel = CurrentUpgrade(UPG_BOMB_BAG); + auto newLevel = currentLevel + (!state ? -1 : 1); + if (currentLevel == 0 && state || currentLevel == 1 && !state) { + SetInventory(ITEM_BOMB, (!state ? ITEM_NONE : ITEM_BOMB)); + } + SetUpgrade(UPG_BOMB_BAG, newLevel); + } break; + case RG_PROGRESSIVE_BOW: { + auto realGI = item.GetGIEntry(); + if (realGI->itemId == RG_QUIVER_INF && realGI->modIndex == MOD_RANDOMIZER) { + SetRandoInf(RAND_INF_HAS_INFINITE_QUIVER, true); + break; + } + auto currentLevel = CurrentUpgrade(UPG_QUIVER); + auto newLevel = currentLevel + (!state ? -1 : 1); + if (currentLevel == 0 && state || currentLevel == 1 && !state) { + SetInventory(ITEM_BOW, (!state ? ITEM_NONE : ITEM_BOW)); + } + SetUpgrade(UPG_QUIVER, newLevel); + } break; + case RG_PROGRESSIVE_SLINGSHOT: { + auto realGI = item.GetGIEntry(); + if (realGI->itemId == RG_BULLET_BAG_INF && realGI->modIndex == MOD_RANDOMIZER) { + SetRandoInf(RAND_INF_HAS_INFINITE_BULLET_BAG, true); + break; + } + auto currentLevel = CurrentUpgrade(UPG_BULLET_BAG); + auto newLevel = currentLevel + (!state ? -1 : 1); + if (currentLevel == 0 && state || currentLevel == 1 && !state) { + SetInventory(ITEM_SLINGSHOT, (!state ? ITEM_NONE : ITEM_SLINGSHOT)); + } + SetUpgrade(UPG_BULLET_BAG, newLevel); + } break; + case RG_PROGRESSIVE_WALLET: { + auto realGI = item.GetGIEntry(); + if (realGI->itemId == RG_WALLET_INF && realGI->modIndex == MOD_RANDOMIZER) { + SetRandoInf(RAND_INF_HAS_INFINITE_MONEY, true); + break; + } + auto currentLevel = CurrentUpgrade(UPG_WALLET); + if (!CheckRandoInf(RAND_INF_HAS_WALLET) && state) { + SetRandoInf(RAND_INF_HAS_WALLET, true); + } else if (currentLevel == 0 && !state) { + SetRandoInf(RAND_INF_HAS_WALLET, false); + } else { + auto newLevel = currentLevel + (!state ? -1 : 1); + SetUpgrade(UPG_WALLET, newLevel); + } + } break; + case RG_PROGRESSIVE_SCALE: { + auto currentLevel = CurrentUpgrade(UPG_SCALE); + if (!CheckRandoInf(RAND_INF_CAN_SWIM) && state) { + SetRandoInf(RAND_INF_CAN_SWIM, true); + } else if (currentLevel == 0 && !state) { + SetRandoInf(RAND_INF_CAN_SWIM, false); + } else { + auto newLevel = currentLevel + (!state ? -1 : 1); + SetUpgrade(UPG_SCALE, newLevel); + } + } break; + case RG_PROGRESSIVE_NUT_UPGRADE: { + auto realGI = item.GetGIEntry(); + if (realGI->itemId == RG_NUT_UPGRADE_INF && realGI->modIndex == MOD_RANDOMIZER) { + SetRandoInf(RAND_INF_HAS_INFINITE_NUT_UPGRADE, true); + break; + } + auto currentLevel = CurrentUpgrade(UPG_NUTS); + auto newLevel = currentLevel + (!state ? -1 : 1); + if (currentLevel == 0 && state || currentLevel == 1 && !state) { + SetInventory(ITEM_NUT, (!state ? ITEM_NONE : ITEM_NUT)); + } + SetUpgrade(UPG_NUTS, newLevel); + } break; + case RG_PROGRESSIVE_STICK_UPGRADE: { + auto realGI = item.GetGIEntry(); + if (realGI->itemId == RG_STICK_UPGRADE_INF && realGI->modIndex == MOD_RANDOMIZER) { + SetRandoInf(RAND_INF_HAS_INFINITE_STICK_UPGRADE, true); + break; + } + auto currentLevel = CurrentUpgrade(UPG_STICKS); + auto newLevel = currentLevel + (!state ? -1 : 1); + if (currentLevel == 0 && state || currentLevel == 1 && !state) { + SetInventory(ITEM_STICK, (!state ? ITEM_NONE : ITEM_STICK)); + } + SetUpgrade(UPG_STICKS, newLevel); + } break; + case RG_PROGRESSIVE_BOMBCHUS: { + auto realGI = item.GetGIEntry(); + if (realGI->itemId == RG_BOMBCHU_INF && realGI->modIndex == MOD_RANDOMIZER) { + SetRandoInf(RAND_INF_HAS_INFINITE_BOMBCHUS, true); + break; + } + SetInventory(ITEM_BOMBCHU, (!state ? ITEM_NONE : ITEM_BOMBCHU)); + } break; + case RG_PROGRESSIVE_MAGIC_METER: { + auto realGI = item.GetGIEntry(); + if (realGI->itemId == RG_MAGIC_INF && realGI->modIndex == MOD_RANDOMIZER) { + SetRandoInf(RAND_INF_HAS_INFINITE_MAGIC_METER, true); + break; + } + mSaveContext->magicLevel += (!state ? -1 : 1); + } break; + case RG_PROGRESSIVE_OCARINA: { + uint8_t i; + for (i = 0; i < 3; i++) { + if (CurrentInventory(ITEM_OCARINA_FAIRY) == OcarinaLookup[i]) { + break; + } + } + i += (!state ? -1 : 1); + if (i < 0) { + i = 0; + } else if (i > 2) { + i = 2; + } + SetInventory(ITEM_OCARINA_FAIRY, OcarinaLookup[i]); + } break; + case RG_HEART_CONTAINER: + mSaveContext->healthCapacity += (!state ? -16 : 16); + break; + case RG_PIECE_OF_HEART: + mSaveContext->healthCapacity += (!state ? -4 : 4); + break; + case RG_BOOMERANG: + case RG_LENS_OF_TRUTH: + case RG_MEGATON_HAMMER: + case RG_DINS_FIRE: + case RG_FARORES_WIND: + case RG_NAYRUS_LOVE: + case RG_FIRE_ARROWS: + case RG_ICE_ARROWS: + case RG_LIGHT_ARROWS: + SetInventory(item.GetGIEntry()->itemId, (!state ? ITEM_NONE : item.GetGIEntry()->itemId)); + break; + case RG_MAGIC_BEAN: + case RG_MAGIC_BEAN_PACK: { + auto change = (item.GetRandomizerGet() == RG_MAGIC_BEAN ? 1 : 10); + auto current = GetAmmo(ITEM_BEAN); + SetAmmo(ITEM_BEAN, current + (!state ? -change : change)); + } break; + case RG_EMPTY_BOTTLE: + case RG_BOTTLE_WITH_MILK: + case RG_BOTTLE_WITH_RED_POTION: + case RG_BOTTLE_WITH_GREEN_POTION: + case RG_BOTTLE_WITH_BLUE_POTION: + case RG_BOTTLE_WITH_FAIRY: + case RG_BOTTLE_WITH_FISH: + case RG_BOTTLE_WITH_BLUE_FIRE: + case RG_BOTTLE_WITH_BUGS: + case RG_BOTTLE_WITH_POE: + case RG_BOTTLE_WITH_BIG_POE: { + uint8_t slot = SLOT_BOTTLE_1; + while (slot != SLOT_BOTTLE_4) { + if (mSaveContext->inventory.items[slot] == ITEM_NONE) { + break; + } + slot++; + } + uint16_t itemId = item.GetGIEntry()->itemId; + if (BottleRandomizerGetToItemID.contains(randoGet)) { + itemId = BottleRandomizerGetToItemID[randoGet]; + } + if (randoGet == RG_BOTTLE_WITH_BIG_POE) { + BigPoes++; + } + mSaveContext->inventory.items[slot] = itemId; + } break; + case RG_RUTOS_LETTER: + SetEventChkInf(EVENTCHKINF_OBTAINED_RUTOS_LETTER, state); + break; + case RG_GOHMA_SOUL: + case RG_KING_DODONGO_SOUL: + case RG_BARINADE_SOUL: + case RG_PHANTOM_GANON_SOUL: + case RG_VOLVAGIA_SOUL: + case RG_MORPHA_SOUL: + case RG_BONGO_BONGO_SOUL: + case RG_TWINROVA_SOUL: + case RG_GANON_SOUL: + case RG_OCARINA_A_BUTTON: + case RG_OCARINA_C_UP_BUTTON: + case RG_OCARINA_C_DOWN_BUTTON: + case RG_OCARINA_C_LEFT_BUTTON: + case RG_OCARINA_C_RIGHT_BUTTON: + case RG_GREG_RUPEE: + case RG_FISHING_POLE: + case RG_GUARD_HOUSE_KEY: + case RG_MARKET_BAZAAR_KEY: + case RG_MARKET_POTION_SHOP_KEY: + case RG_MASK_SHOP_KEY: + case RG_MARKET_SHOOTING_GALLERY_KEY: + case RG_BOMBCHU_BOWLING_KEY: + case RG_TREASURE_CHEST_GAME_BUILDING_KEY: + case RG_BOMBCHU_SHOP_KEY: + case RG_RICHARDS_HOUSE_KEY: + case RG_ALLEY_HOUSE_KEY: + case RG_KAK_BAZAAR_KEY: + case RG_KAK_POTION_SHOP_KEY: + case RG_BOSS_HOUSE_KEY: + case RG_GRANNYS_POTION_SHOP_KEY: + case RG_SKULLTULA_HOUSE_KEY: + case RG_IMPAS_HOUSE_KEY: + case RG_WINDMILL_KEY: + case RG_KAK_SHOOTING_GALLERY_KEY: + case RG_DAMPES_HUT_KEY: + case RG_TALONS_HOUSE_KEY: + case RG_STABLES_KEY: + case RG_BACK_TOWER_KEY: + case RG_HYLIA_LAB_KEY: + case RG_FISHING_HOLE_KEY: + SetRandoInf(RandoGetToRandInf.at(randoGet), state); + break; + case RG_TRIFORCE_PIECE: + mSaveContext->ship.quest.data.randomizer.triforcePiecesCollected += (!state ? -1 : 1); + break; + case RG_BOMBCHU_5: + case RG_BOMBCHU_10: + case RG_BOMBCHU_20: + SetInventory(ITEM_BOMBCHU, (!state ? ITEM_NONE : ITEM_BOMBCHU)); + break; + default: + break; + } + } break; + case ITEMTYPE_EQUIP: { RandomizerGet itemRG = item.GetRandomizerGet(); if (itemRG == RG_GIANTS_KNIFE || itemRG == RG_DEKU_SHIELD || itemRG == RG_HYLIAN_SHIELD) { return; @@ -1811,15 +1894,13 @@ namespace Rando { if (equipId == EQUIP_FLAG_SWORD_BGS) { mSaveContext->bgsFlag = false; } - } - else { + } else { mSaveContext->inventory.equipment |= equipId; if (equipId == EQUIP_FLAG_SWORD_BGS) { mSaveContext->bgsFlag = true; } } - } - break; + } break; case ITEMTYPE_DUNGEONREWARD: case ITEMTYPE_SONG: SetQuestItem(RandoGetToQuestItem.find(item.GetRandomizerGet())->second, state); @@ -1834,8 +1915,7 @@ namespace Rando { SetDungeonItem(DUNGEON_KEY_BOSS, RandoGetToDungeonScene.find(item.GetRandomizerGet())->second, state); break; case ITEMTYPE_FORTRESS_SMALLKEY: - case ITEMTYPE_SMALLKEY: - { + case ITEMTYPE_SMALLKEY: { auto randoGet = item.GetRandomizerGet(); auto keyring = randoGet >= RG_FOREST_TEMPLE_KEY_RING && randoGet <= RG_GANONS_CASTLE_KEY_RING; auto dungeonIndex = RandoGetToDungeonScene.find(randoGet)->second; @@ -1843,16 +1923,13 @@ namespace Rando { if (!state) { if (keyring) { count = 0; - } - else { + } else { count -= 1; } - } - else { + } else { if (keyring) { count = 10; - } - else { + } else { count += 1; } } @@ -1865,589 +1942,590 @@ namespace Rando { break; case ITEMTYPE_DROP: case ITEMTYPE_REFILL: - case ITEMTYPE_SHOP: - { + case ITEMTYPE_SHOP: { RandomizerGet itemRG = item.GetRandomizerGet(); - if (itemRG == RG_BUY_HYLIAN_SHIELD || itemRG == RG_BUY_DEKU_SHIELD || itemRG == RG_BUY_GORON_TUNIC || itemRG == RG_BUY_ZORA_TUNIC) { + if (itemRG == RG_BUY_HYLIAN_SHIELD || itemRG == RG_BUY_DEKU_SHIELD || itemRG == RG_BUY_GORON_TUNIC || + itemRG == RG_BUY_ZORA_TUNIC) { uint32_t equipId = RandoGetToEquipFlag.find(itemRG)->second; if (!state) { mSaveContext->inventory.equipment &= ~equipId; - } - else { + } else { mSaveContext->inventory.equipment |= equipId; } } switch (itemRG) { - case RG_DEKU_NUTS_5: - case RG_DEKU_NUTS_10: - case RG_BUY_DEKU_NUTS_5: - case RG_BUY_DEKU_NUTS_10: - SetInventory(ITEM_NUT, (!state ? ITEM_NONE : ITEM_NUT)); - break; - case RG_DEKU_STICK_1: - case RG_BUY_DEKU_STICK_1: - case RG_STICKS: - SetInventory(ITEM_STICK, (!state ? ITEM_NONE : ITEM_STICK)); - break; - case RG_BOMBCHU_5: - case RG_BOMBCHU_10: - case RG_BOMBCHU_20: - SetInventory(ITEM_BOMBCHU, (!state ? ITEM_NONE : ITEM_BOMBCHU)); - break; - default: - break; + case RG_DEKU_NUTS_5: + case RG_DEKU_NUTS_10: + case RG_BUY_DEKU_NUTS_5: + case RG_BUY_DEKU_NUTS_10: + SetInventory(ITEM_NUT, (!state ? ITEM_NONE : ITEM_NUT)); + break; + case RG_DEKU_STICK_1: + case RG_BUY_DEKU_STICK_1: + case RG_STICKS: + SetInventory(ITEM_STICK, (!state ? ITEM_NONE : ITEM_STICK)); + break; + case RG_BOMBCHU_5: + case RG_BOMBCHU_10: + case RG_BOMBCHU_20: + SetInventory(ITEM_BOMBCHU, (!state ? ITEM_NONE : ITEM_BOMBCHU)); + break; + default: + break; } } break; - } - } - - SaveContext* Logic::GetSaveContext() { - if (mSaveContext == nullptr) { - NewSaveContext(); - } - return mSaveContext; - } - - void Logic::SetSaveContext(SaveContext* context) { - mSaveContext = context; - } - - void Logic::InitSaveContext() { - mSaveContext->totalDays = 0; - mSaveContext->bgsDayCount = 0; - - mSaveContext->deaths = 0; - for (int i = 0; i < ARRAY_COUNT(mSaveContext->playerName); i++) { - mSaveContext->playerName[i] = 0x3E; - } - mSaveContext->n64ddFlag = 0; - mSaveContext->healthCapacity = 0x30; - mSaveContext->health = 0x30; - mSaveContext->magicLevel = 0; - mSaveContext->magic = 0x30; - mSaveContext->rupees = 0; - mSaveContext->swordHealth = 0; - mSaveContext->naviTimer = 0; - mSaveContext->isMagicAcquired = 0; - mSaveContext->isDoubleMagicAcquired = 0; - mSaveContext->isDoubleDefenseAcquired = 0; - mSaveContext->bgsFlag = 0; - mSaveContext->ocarinaGameRoundNum = 0; - for (int button = 0; button < ARRAY_COUNT(mSaveContext->childEquips.buttonItems); button++) { - mSaveContext->childEquips.buttonItems[button] = ITEM_NONE; - } - for (int button = 0; button < ARRAY_COUNT(mSaveContext->childEquips.cButtonSlots); button++) { - mSaveContext->childEquips.cButtonSlots[button] = SLOT_NONE; - } - mSaveContext->childEquips.equipment = 0; - for (int button = 0; button < ARRAY_COUNT(mSaveContext->adultEquips.buttonItems); button++) { - mSaveContext->adultEquips.buttonItems[button] = ITEM_NONE; - } - for (int button = 0; button < ARRAY_COUNT(mSaveContext->adultEquips.cButtonSlots); button++) { - mSaveContext->adultEquips.cButtonSlots[button] = SLOT_NONE; - } - mSaveContext->adultEquips.equipment = 0; - mSaveContext->unk_54 = 0; - mSaveContext->savedSceneNum = SCENE_LINKS_HOUSE; - - // Equipment - for (int button = 0; button < ARRAY_COUNT(mSaveContext->equips.buttonItems); button++) { - mSaveContext->equips.buttonItems[button] = ITEM_NONE; - } - for (int button = 0; button < ARRAY_COUNT(mSaveContext->equips.cButtonSlots); button++) { - mSaveContext->equips.cButtonSlots[button] = SLOT_NONE; - } - mSaveContext->equips.equipment = 0; - - // Inventory - for (int item = 0; item < ARRAY_COUNT(mSaveContext->inventory.items); item++) { - mSaveContext->inventory.items[item] = ITEM_NONE; - } - for (int ammo = 0; ammo < ARRAY_COUNT(mSaveContext->inventory.ammo); ammo++) { - mSaveContext->inventory.ammo[ammo] = 0; - } - mSaveContext->inventory.equipment = 0; - mSaveContext->inventory.upgrades = 0; - mSaveContext->inventory.questItems = 0; - for (int dungeon = 0; dungeon < ARRAY_COUNT(mSaveContext->inventory.dungeonItems); dungeon++) { - mSaveContext->inventory.dungeonItems[dungeon] = 0; - } - for (int dungeon = 0; dungeon < ARRAY_COUNT(mSaveContext->inventory.dungeonKeys); dungeon++) { - mSaveContext->inventory.dungeonKeys[dungeon] = 0x0; - } - mSaveContext->inventory.defenseHearts = 0; - mSaveContext->inventory.gsTokens = 0; - for (int scene = 0; scene < ARRAY_COUNT(mSaveContext->sceneFlags); scene++) { - mSaveContext->sceneFlags[scene].chest = 0; - mSaveContext->sceneFlags[scene].swch = 0; - mSaveContext->sceneFlags[scene].clear = 0; - mSaveContext->sceneFlags[scene].collect = 0; - mSaveContext->sceneFlags[scene].unk = 0; - mSaveContext->sceneFlags[scene].rooms = 0; - mSaveContext->sceneFlags[scene].floors = 0; - } - mSaveContext->fw.pos.x = 0; - mSaveContext->fw.pos.y = 0; - mSaveContext->fw.pos.z = 0; - mSaveContext->fw.yaw = 0; - mSaveContext->fw.playerParams = 0; - mSaveContext->fw.entranceIndex = 0; - mSaveContext->fw.roomIndex = 0; - mSaveContext->fw.set = 0; - mSaveContext->fw.tempSwchFlags = 0; - mSaveContext->fw.tempCollectFlags = 0; - for (int flag = 0; flag < ARRAY_COUNT(mSaveContext->gsFlags); flag++) { - mSaveContext->gsFlags[flag] = 0; - } - for (int highscore = 0; highscore < ARRAY_COUNT(mSaveContext->highScores); highscore++) { - mSaveContext->highScores[highscore] = 0; - } - for (int flag = 0; flag < ARRAY_COUNT(mSaveContext->eventChkInf); flag++) { - mSaveContext->eventChkInf[flag] = 0; - } - for (int flag = 0; flag < ARRAY_COUNT(mSaveContext->itemGetInf); flag++) { - mSaveContext->itemGetInf[flag] = 0; - } - for (int flag = 0; flag < ARRAY_COUNT(mSaveContext->infTable); flag++) { - mSaveContext->infTable[flag] = 0; - } - mSaveContext->worldMapAreaData = 0; - mSaveContext->scarecrowLongSongSet = 0; - for (int i = 0; i < ARRAY_COUNT(mSaveContext->scarecrowLongSong); i++) { - mSaveContext->scarecrowLongSong[i].noteIdx = 0; - mSaveContext->scarecrowLongSong[i].unk_01 = 0; - mSaveContext->scarecrowLongSong[i].unk_02 = 0; - mSaveContext->scarecrowLongSong[i].volume = 0; - mSaveContext->scarecrowLongSong[i].vibrato = 0; - mSaveContext->scarecrowLongSong[i].tone = 0; - mSaveContext->scarecrowLongSong[i].semitone = 0; - } - mSaveContext->scarecrowSpawnSongSet = 0; - for (int i = 0; i < ARRAY_COUNT(mSaveContext->scarecrowSpawnSong); i++) { - mSaveContext->scarecrowSpawnSong[i].noteIdx = 0; - mSaveContext->scarecrowSpawnSong[i].unk_01 = 0; - mSaveContext->scarecrowSpawnSong[i].unk_02 = 0; - mSaveContext->scarecrowSpawnSong[i].volume = 0; - mSaveContext->scarecrowSpawnSong[i].vibrato = 0; - mSaveContext->scarecrowSpawnSong[i].tone = 0; - mSaveContext->scarecrowSpawnSong[i].semitone = 0; - } - - mSaveContext->horseData.scene = SCENE_HYRULE_FIELD; - mSaveContext->horseData.pos.x = -1840; - mSaveContext->horseData.pos.y = 72; - mSaveContext->horseData.pos.z = 5497; - mSaveContext->horseData.angle = -0x6AD9; - mSaveContext->magicLevel = 0; - mSaveContext->infTable[29] = 1; - mSaveContext->sceneFlags[5].swch = 0x40000000; - - // SoH specific - mSaveContext->ship.backupFW = mSaveContext->fw; - mSaveContext->ship.pendingSale = ITEM_NONE; - mSaveContext->ship.pendingSaleMod = MOD_NONE; - mSaveContext->ship.pendingIceTrapCount = 0; - - // Init with normal quest unless only an MQ rom is provided - mSaveContext->ship.quest.id = OTRGlobals::Instance->HasOriginal() ? QUEST_NORMAL : QUEST_MASTER; - - //RANDOTODO (ADD ITEMLOCATIONS TO GSAVECONTEXT) - } - - void Logic::NewSaveContext() { - if (mSaveContext != nullptr && mSaveContext != &gSaveContext) { - free(mSaveContext); - } - mSaveContext = new SaveContext(); - InitSaveContext(); - } - - uint8_t Logic::InventorySlot(uint32_t item) { - return gItemSlots[item]; - } - - uint32_t Logic::CurrentUpgrade(uint32_t upgrade) { - return (mSaveContext->inventory.upgrades & gUpgradeMasks[upgrade]) >> gUpgradeShifts[upgrade]; - } - - uint32_t Logic::CurrentInventory(uint32_t item) { - return mSaveContext->inventory.items[InventorySlot(item)]; - } - - void Logic::SetUpgrade(uint32_t upgrade, uint8_t level) { - mSaveContext->inventory.upgrades &= gUpgradeNegMasks[upgrade]; - mSaveContext->inventory.upgrades |= level << gUpgradeShifts[upgrade]; - } - - bool Logic::CheckInventory(uint32_t item, bool exact) { - auto current = mSaveContext->inventory.items[InventorySlot(item)]; - return exact ? (current == item) : (current != ITEM_NONE); - } - - void Logic::SetInventory(uint32_t itemSlot, uint32_t item) { - mSaveContext->inventory.items[InventorySlot(itemSlot)] = item; - } - - bool Logic::CheckEquipment(uint32_t equipFlag) { - return (equipFlag & mSaveContext->inventory.equipment); - } - - bool Logic::CheckQuestItem(uint32_t item) { - return ((1 << item) & mSaveContext->inventory.questItems); - } - - void Logic::SetQuestItem(uint32_t item, bool state) { - if (!state) { - mSaveContext->inventory.questItems &= ~(1 << item); - } else { - mSaveContext->inventory.questItems |= (1 << item); - } - } - - // Get the swch bit positions for the dungeon - const std::vector& GetDungeonSmallKeyDoors(SceneID sceneId) { - static const std::vector emptyVector; - - auto dungeonInfo = Rando::Context::GetInstance()->GetDungeons()->GetDungeonFromScene(sceneId); - if (dungeonInfo == nullptr) { - return emptyVector; - } - - bool masterQuest = dungeonInfo->IsMQ(); - - // Create a unique key for the dungeon and master quest - uint8_t key = sceneId | (masterQuest << 7); - - static std::unordered_map> dungeonSmallKeyDoors; - auto foundEntry = dungeonSmallKeyDoors.find(key); - if (foundEntry != dungeonSmallKeyDoors.end()) { - return foundEntry->second; - } - dungeonSmallKeyDoors[key] = {}; - - // Get the scene path - SceneTableEntry* sceneTableEntry = &gSceneTable[sceneId]; - std::string scenePath = StringHelper::Sprintf("scenes/%s/%s/%s", masterQuest ? "mq" : "nonmq", - sceneTableEntry->sceneFile.fileName, sceneTableEntry->sceneFile.fileName); - - // Load the scene - std::shared_ptr scene = std::dynamic_pointer_cast( - Ship::Context::GetInstance()->GetResourceManager()->LoadResource(scenePath)); - if (scene == nullptr) { - return emptyVector; - } - - // Find the SetTransitionActorList command - std::shared_ptr transitionActorListCommand = nullptr; - for (auto& command : scene->commands) { - if (command->cmdId == SOH::SceneCommandID::SetTransitionActorList) { - transitionActorListCommand = std::dynamic_pointer_cast(command); - break; - } - } - if (transitionActorListCommand == nullptr) { - return emptyVector; - } - - // Find the bit position for the small key doors - for (auto& transitionActor : transitionActorListCommand->transitionActorList) { - if (transitionActor.id == ACTOR_EN_DOOR) { - uint8_t doorType = (transitionActor.params >> 7) & 7; - if (doorType == DOOR_LOCKED) { - dungeonSmallKeyDoors[key].emplace_back(transitionActor.params & 0x3F); - } - } else if (transitionActor.id == ACTOR_DOOR_SHUTTER) { - uint8_t doorType = (transitionActor.params >> 7) & 15; - if (doorType == SHUTTER_BACK_LOCKED || doorType == SHUTTER_BOSS || doorType == SHUTTER_KEY_LOCKED) { - dungeonSmallKeyDoors[key].emplace_back(transitionActor.params & 0x3F); - } - } - } - - return dungeonSmallKeyDoors[key]; - } - - int8_t GetUsedSmallKeyCount(SceneID sceneId) { - const auto& smallKeyDoors = GetDungeonSmallKeyDoors(sceneId); - - // Get the swch value for the scene - uint32_t swch; - if (gPlayState != nullptr && gPlayState->sceneNum == sceneId) { - swch = gPlayState->actorCtx.flags.swch; - } else { - swch = gSaveContext.sceneFlags[sceneId].swch; - } - - // Count the number of small keys doors unlocked - int8_t unlockedSmallKeyDoors = 0; - for (auto& smallKeyDoor : smallKeyDoors) { - unlockedSmallKeyDoors += swch >> smallKeyDoor & 1; - } - - // RANDOTODO: Account for MQ Water trick that causes the basement lock to unlock when the player clears the stalfos pit. - return unlockedSmallKeyDoors; - } - - uint8_t Logic::GetSmallKeyCount(uint32_t dungeonIndex) { - int8_t dungeonKeys = mSaveContext->inventory.dungeonKeys[dungeonIndex]; - if (dungeonKeys == -1) { - // never got keys, so can't have used keys - return 0; - } - return dungeonKeys + GetUsedSmallKeyCount(SceneID(dungeonIndex)); - } - - void Logic::SetSmallKeyCount(uint32_t dungeonIndex, uint8_t count) { - mSaveContext->inventory.dungeonKeys[dungeonIndex] = count; - } - - bool Logic::CheckDungeonItem(uint32_t item, uint32_t dungeonIndex) { - return mSaveContext->inventory.dungeonItems[dungeonIndex] & gBitFlags[item]; - } - - void Logic::SetDungeonItem(uint32_t item, uint32_t dungeonIndex, bool state) { - if (!state) { - mSaveContext->inventory.dungeonItems[dungeonIndex] &= ~gBitFlags[item]; - } else { - mSaveContext->inventory.dungeonItems[dungeonIndex] |= gBitFlags[item]; - } - } - - bool Logic::CheckRandoInf(uint32_t flag) { - return mSaveContext->ship.randomizerInf[flag >> 4] & (1 << (flag & 0xF)); - } - - void Logic::SetRandoInf(uint32_t flag, bool state) { - if (!state) { - mSaveContext->ship.randomizerInf[flag >> 4] &= ~(1 << (flag & 0xF)); - } else { - mSaveContext->ship.randomizerInf[flag >> 4] |= (1 << (flag & 0xF)); - } - } - - bool Logic::CheckEventChkInf(int32_t flag) { - return mSaveContext->eventChkInf[flag >> 4] & (1 << (flag & 0xF)); - } - - void Logic::SetEventChkInf(int32_t flag, bool state) { - if (!state) { - mSaveContext->eventChkInf[flag >> 4] &= ~(1 << (flag & 0xF)); - } else { - mSaveContext->eventChkInf[flag >> 4] |= (1 << (flag & 0xF)); - } - } - - uint8_t Logic::GetGSCount() { - return mSaveContext->inventory.gsTokens; - } - - uint8_t Logic::GetAmmo(uint32_t item) { - return mSaveContext->inventory.ammo[gItemSlots[item]]; - } - - void Logic::SetAmmo(uint32_t item, uint8_t count) { - mSaveContext->inventory.ammo[gItemSlots[item]] = count; - } - - void Logic::SetContext(std::shared_ptr _ctx) { - ctx = _ctx; - } - - bool Logic::GetInLogic(LogicVal logicVal) { - return inLogic[logicVal]; - } - - void Logic::SetInLogic(LogicVal logicVal, bool value) { - inLogic[logicVal] = value; - } - - void Logic::Reset() { - NewSaveContext(); - StartPerformanceTimer(PT_LOGIC_RESET); - memset(inLogic, false, sizeof(inLogic)); - //Settings-dependent variables - IsKeysanity = ctx->GetOption(RSK_KEYSANITY).Is(RO_DUNGEON_ITEM_LOC_ANYWHERE) || - ctx->GetOption(RSK_KEYSANITY).Is(RO_DUNGEON_ITEM_LOC_ANYWHERE) || - ctx->GetOption(RSK_KEYSANITY).Is(RO_DUNGEON_ITEM_LOC_ANYWHERE); - - //AmmoCanDrop = /*AmmoDrops.IsNot(AMMODROPS_NONE)*/ false; TODO: AmmoDrop setting - - //Child item logic - SkullMask = false; - MaskOfTruth = false; - - //Adult logic - FreedEpona = false; - //BigPoe = false; - - //Trade Quest Events - WakeUpAdultTalon = false; - - //Dungeon Clears - DekuTreeClear = false; - DodongosCavernClear = false; - JabuJabusBellyClear = false; - ForestTempleClear = false; - FireTempleClear = false; - WaterTempleClear = false; - SpiritTempleClear = false; - ShadowTempleClear = false; - - //Trial Clears - ForestTrialClear = false; - FireTrialClear = false; - WaterTrialClear = false; - SpiritTrialClear = false; - ShadowTrialClear = false; - LightTrialClear = false; - - //Ocarina C Buttons - bool ocBtnShuffle = ctx->GetOption(RSK_SHUFFLE_OCARINA_BUTTONS).Is(true); - SetRandoInf(RAND_INF_HAS_OCARINA_A, !ocBtnShuffle); - SetRandoInf(RAND_INF_HAS_OCARINA_C_UP, !ocBtnShuffle); - SetRandoInf(RAND_INF_HAS_OCARINA_C_DOWN, !ocBtnShuffle); - SetRandoInf(RAND_INF_HAS_OCARINA_C_LEFT, !ocBtnShuffle); - SetRandoInf(RAND_INF_HAS_OCARINA_C_RIGHT, !ocBtnShuffle); - - //Progressive Items - SetUpgrade(UPG_STICKS, ctx->GetOption(RSK_SHUFFLE_DEKU_STICK_BAG).Is(true) ? 0 : 1); - SetUpgrade(UPG_NUTS, ctx->GetOption(RSK_SHUFFLE_DEKU_NUT_BAG).Is(true) ? 0 : 1); - - //If we're not shuffling swim, we start with it - if (ctx->GetOption(RSK_SHUFFLE_SWIM).Is(false)) { - SetRandoInf(RAND_INF_CAN_SWIM, true); - } - - //If we're not shuffling child's wallet, we start with it - if (ctx->GetOption(RSK_SHUFFLE_CHILD_WALLET).Is(false)) { - SetRandoInf(RAND_INF_HAS_WALLET, true); - } - - //If we're not shuffling fishing pole, we start with it - if (ctx->GetOption(RSK_SHUFFLE_FISHING_POLE).Is(false)) { - SetRandoInf(RAND_INF_FISHING_POLE_FOUND, true); - } - - //If not keysanity, start with 1 logical key to account for automatically unlocking the basement door in vanilla FiT - if (!IsKeysanity && ctx->GetDungeon(Rando::FIRE_TEMPLE)->IsVanilla()) { - SetSmallKeyCount(SCENE_FIRE_TEMPLE, 1); - } - - //Bottle Count - Bottles = 0; - NumBottles = 0; - CanEmptyBigPoes = false; - CouldEmptyBigPoes = false; - - //Drops and Bottle Contents Access - NutPot = false; - NutCrate = false; - DekuBabaNuts = false; - StickPot = false; - DekuBabaSticks = false; - BugShrub = false; - WanderingBugs = false; - BugRock = false; - BlueFireAccess = false; - FishGroup = false; - LoneFish = false; - GossipStoneFairy = false; - BeanPlantFairy = false; - ButterflyFairy = false; - FairyPot = false; - FreeFairies = false; - FairyPond = false; - - PieceOfHeart = 0; - HeartContainer = 0; - - /* --- HELPERS, EVENTS, AND LOCATION ACCESS --- */ - /* These are used to simplify reading the logic, but need to be updated - / every time a base value is updated. */ - - ChildScarecrow = false; - AdultScarecrow = false; - - CouldPlayBowling = false; - IsChild = false; - IsAdult = false; - //CanPlantBean = false; - BigPoeKill = false; - BigPoes = 0; - - BaseHearts = ctx->GetOption(RSK_STARTING_HEARTS).Get() + 1; - - - //Bridge Requirements - BuiltRainbowBridge = false; - - //Other - AtDay = false; - AtNight = false; - GetSaveContext()->linkAge = !ctx->GetOption(RSK_SELECTED_STARTING_AGE).Get(); - - //Events - ShowedMidoSwordAndShield = false; - CarpenterRescue = false; - GF_GateOpen = false; - GtG_GateOpen = false; - DampesWindmillAccess = false; - DrainWell = false; - GoronCityChildFire = false; - GCWoodsWarpOpen = false; - GCDaruniasDoorOpenChild = false; - StopGCRollingGoronAsAdult = false; - CanWaterTempleLowFromHigh = false; - CanWaterTempleLowFromMid = false; - CanWaterTempleMiddle = false; - CanWaterTempleHigh = false; - KakarikoVillageGateOpen = false; - KingZoraThawed = false; - ForestTempleJoelle = false; - ForestTempleBeth = false; - ForestTempleAmy = false; - ForestTempleMeg = false; - FireLoopSwitch = false; - LinksCow = false; - DeliverLetter = false; - ClearMQDCUpperLobbyRocks = false; - LoweredWaterInsideBotw = false; - OpenedWestRoomMQBotw = false; - OpenedMiddleHoleMQBotw = false; - BrokeDeku1FWeb = false; - ClearedMQDekuSERoom = false; - MQDekuWaterRoomTorches = false; - PushedDekuBasementBlock = false; - OpenedLowestGoronCage = false; - OpenedUpperFireShortcut = false; - HitFireTemplePlatform = false; - OpenedFireMQFireMazeDoor = false; - MQForestBlockRoomTargets = false; - ForestCanTwistHallway = false; - ForestClearBelowBowChest = false; - ForestOpenBossCorridor = false; - ShadowTrialFirstChest = false; - MQGTGMazeSwitch = false; - GTGPlatformSilverRupees = false; - MQJabuHolesRoomDoor = false; - JabuWestTentacle = false; - JabuEastTentacle = false; - JabuNorthTentacle = false; - LoweredJabuPath = false; - MQJabuLiftRoomCow = false; - MQShadowFloorSpikeRupees = false; - ShadowShortcutBlock = false; - MQWaterStalfosPit = false; - MQWaterDragonTorches = false; - MQWaterB1Switch = false; - //MQWaterPillarSoTBlock = false; - MQWaterOpenedPillarB1 = false; - MQSpiritCrawlBoulder = false; - MQSpiritMapRoomEnemies = false; - MQSpirit3SunsEnemies = false; - Spirit1FSilverRupees = false; - JabuRutoIn1F = false; - - StopPerformanceTimer(PT_LOGIC_RESET); } } + +SaveContext* Logic::GetSaveContext() { + if (mSaveContext == nullptr) { + NewSaveContext(); + } + return mSaveContext; +} + +void Logic::SetSaveContext(SaveContext* context) { + mSaveContext = context; +} + +void Logic::InitSaveContext() { + mSaveContext->totalDays = 0; + mSaveContext->bgsDayCount = 0; + + mSaveContext->deaths = 0; + for (int i = 0; i < ARRAY_COUNT(mSaveContext->playerName); i++) { + mSaveContext->playerName[i] = 0x3E; + } + mSaveContext->n64ddFlag = 0; + mSaveContext->healthCapacity = 0x30; + mSaveContext->health = 0x30; + mSaveContext->magicLevel = 0; + mSaveContext->magic = 0x30; + mSaveContext->rupees = 0; + mSaveContext->swordHealth = 0; + mSaveContext->naviTimer = 0; + mSaveContext->isMagicAcquired = 0; + mSaveContext->isDoubleMagicAcquired = 0; + mSaveContext->isDoubleDefenseAcquired = 0; + mSaveContext->bgsFlag = 0; + mSaveContext->ocarinaGameRoundNum = 0; + for (int button = 0; button < ARRAY_COUNT(mSaveContext->childEquips.buttonItems); button++) { + mSaveContext->childEquips.buttonItems[button] = ITEM_NONE; + } + for (int button = 0; button < ARRAY_COUNT(mSaveContext->childEquips.cButtonSlots); button++) { + mSaveContext->childEquips.cButtonSlots[button] = SLOT_NONE; + } + mSaveContext->childEquips.equipment = 0; + for (int button = 0; button < ARRAY_COUNT(mSaveContext->adultEquips.buttonItems); button++) { + mSaveContext->adultEquips.buttonItems[button] = ITEM_NONE; + } + for (int button = 0; button < ARRAY_COUNT(mSaveContext->adultEquips.cButtonSlots); button++) { + mSaveContext->adultEquips.cButtonSlots[button] = SLOT_NONE; + } + mSaveContext->adultEquips.equipment = 0; + mSaveContext->unk_54 = 0; + mSaveContext->savedSceneNum = SCENE_LINKS_HOUSE; + + // Equipment + for (int button = 0; button < ARRAY_COUNT(mSaveContext->equips.buttonItems); button++) { + mSaveContext->equips.buttonItems[button] = ITEM_NONE; + } + for (int button = 0; button < ARRAY_COUNT(mSaveContext->equips.cButtonSlots); button++) { + mSaveContext->equips.cButtonSlots[button] = SLOT_NONE; + } + mSaveContext->equips.equipment = 0; + + // Inventory + for (int item = 0; item < ARRAY_COUNT(mSaveContext->inventory.items); item++) { + mSaveContext->inventory.items[item] = ITEM_NONE; + } + for (int ammo = 0; ammo < ARRAY_COUNT(mSaveContext->inventory.ammo); ammo++) { + mSaveContext->inventory.ammo[ammo] = 0; + } + mSaveContext->inventory.equipment = 0; + mSaveContext->inventory.upgrades = 0; + mSaveContext->inventory.questItems = 0; + for (int dungeon = 0; dungeon < ARRAY_COUNT(mSaveContext->inventory.dungeonItems); dungeon++) { + mSaveContext->inventory.dungeonItems[dungeon] = 0; + } + for (int dungeon = 0; dungeon < ARRAY_COUNT(mSaveContext->inventory.dungeonKeys); dungeon++) { + mSaveContext->inventory.dungeonKeys[dungeon] = 0x0; + } + mSaveContext->inventory.defenseHearts = 0; + mSaveContext->inventory.gsTokens = 0; + for (int scene = 0; scene < ARRAY_COUNT(mSaveContext->sceneFlags); scene++) { + mSaveContext->sceneFlags[scene].chest = 0; + mSaveContext->sceneFlags[scene].swch = 0; + mSaveContext->sceneFlags[scene].clear = 0; + mSaveContext->sceneFlags[scene].collect = 0; + mSaveContext->sceneFlags[scene].unk = 0; + mSaveContext->sceneFlags[scene].rooms = 0; + mSaveContext->sceneFlags[scene].floors = 0; + } + mSaveContext->fw.pos.x = 0; + mSaveContext->fw.pos.y = 0; + mSaveContext->fw.pos.z = 0; + mSaveContext->fw.yaw = 0; + mSaveContext->fw.playerParams = 0; + mSaveContext->fw.entranceIndex = 0; + mSaveContext->fw.roomIndex = 0; + mSaveContext->fw.set = 0; + mSaveContext->fw.tempSwchFlags = 0; + mSaveContext->fw.tempCollectFlags = 0; + for (int flag = 0; flag < ARRAY_COUNT(mSaveContext->gsFlags); flag++) { + mSaveContext->gsFlags[flag] = 0; + } + for (int highscore = 0; highscore < ARRAY_COUNT(mSaveContext->highScores); highscore++) { + mSaveContext->highScores[highscore] = 0; + } + for (int flag = 0; flag < ARRAY_COUNT(mSaveContext->eventChkInf); flag++) { + mSaveContext->eventChkInf[flag] = 0; + } + for (int flag = 0; flag < ARRAY_COUNT(mSaveContext->itemGetInf); flag++) { + mSaveContext->itemGetInf[flag] = 0; + } + for (int flag = 0; flag < ARRAY_COUNT(mSaveContext->infTable); flag++) { + mSaveContext->infTable[flag] = 0; + } + mSaveContext->worldMapAreaData = 0; + mSaveContext->scarecrowLongSongSet = 0; + for (int i = 0; i < ARRAY_COUNT(mSaveContext->scarecrowLongSong); i++) { + mSaveContext->scarecrowLongSong[i].noteIdx = 0; + mSaveContext->scarecrowLongSong[i].unk_01 = 0; + mSaveContext->scarecrowLongSong[i].unk_02 = 0; + mSaveContext->scarecrowLongSong[i].volume = 0; + mSaveContext->scarecrowLongSong[i].vibrato = 0; + mSaveContext->scarecrowLongSong[i].tone = 0; + mSaveContext->scarecrowLongSong[i].semitone = 0; + } + mSaveContext->scarecrowSpawnSongSet = 0; + for (int i = 0; i < ARRAY_COUNT(mSaveContext->scarecrowSpawnSong); i++) { + mSaveContext->scarecrowSpawnSong[i].noteIdx = 0; + mSaveContext->scarecrowSpawnSong[i].unk_01 = 0; + mSaveContext->scarecrowSpawnSong[i].unk_02 = 0; + mSaveContext->scarecrowSpawnSong[i].volume = 0; + mSaveContext->scarecrowSpawnSong[i].vibrato = 0; + mSaveContext->scarecrowSpawnSong[i].tone = 0; + mSaveContext->scarecrowSpawnSong[i].semitone = 0; + } + + mSaveContext->horseData.scene = SCENE_HYRULE_FIELD; + mSaveContext->horseData.pos.x = -1840; + mSaveContext->horseData.pos.y = 72; + mSaveContext->horseData.pos.z = 5497; + mSaveContext->horseData.angle = -0x6AD9; + mSaveContext->magicLevel = 0; + mSaveContext->infTable[29] = 1; + mSaveContext->sceneFlags[5].swch = 0x40000000; + + // SoH specific + mSaveContext->ship.backupFW = mSaveContext->fw; + mSaveContext->ship.pendingSale = ITEM_NONE; + mSaveContext->ship.pendingSaleMod = MOD_NONE; + mSaveContext->ship.pendingIceTrapCount = 0; + + // Init with normal quest unless only an MQ rom is provided + mSaveContext->ship.quest.id = OTRGlobals::Instance->HasOriginal() ? QUEST_NORMAL : QUEST_MASTER; + + // RANDOTODO (ADD ITEMLOCATIONS TO GSAVECONTEXT) +} + +void Logic::NewSaveContext() { + if (mSaveContext != nullptr && mSaveContext != &gSaveContext) { + free(mSaveContext); + } + mSaveContext = new SaveContext(); + InitSaveContext(); +} + +uint8_t Logic::InventorySlot(uint32_t item) { + return gItemSlots[item]; +} + +uint32_t Logic::CurrentUpgrade(uint32_t upgrade) { + return (mSaveContext->inventory.upgrades & gUpgradeMasks[upgrade]) >> gUpgradeShifts[upgrade]; +} + +uint32_t Logic::CurrentInventory(uint32_t item) { + return mSaveContext->inventory.items[InventorySlot(item)]; +} + +void Logic::SetUpgrade(uint32_t upgrade, uint8_t level) { + mSaveContext->inventory.upgrades &= gUpgradeNegMasks[upgrade]; + mSaveContext->inventory.upgrades |= level << gUpgradeShifts[upgrade]; +} + +bool Logic::CheckInventory(uint32_t item, bool exact) { + auto current = mSaveContext->inventory.items[InventorySlot(item)]; + return exact ? (current == item) : (current != ITEM_NONE); +} + +void Logic::SetInventory(uint32_t itemSlot, uint32_t item) { + mSaveContext->inventory.items[InventorySlot(itemSlot)] = item; +} + +bool Logic::CheckEquipment(uint32_t equipFlag) { + return (equipFlag & mSaveContext->inventory.equipment); +} + +bool Logic::CheckQuestItem(uint32_t item) { + return ((1 << item) & mSaveContext->inventory.questItems); +} + +void Logic::SetQuestItem(uint32_t item, bool state) { + if (!state) { + mSaveContext->inventory.questItems &= ~(1 << item); + } else { + mSaveContext->inventory.questItems |= (1 << item); + } +} + +// Get the swch bit positions for the dungeon +const std::vector& GetDungeonSmallKeyDoors(SceneID sceneId) { + static const std::vector emptyVector; + + auto dungeonInfo = Rando::Context::GetInstance()->GetDungeons()->GetDungeonFromScene(sceneId); + if (dungeonInfo == nullptr) { + return emptyVector; + } + + bool masterQuest = dungeonInfo->IsMQ(); + + // Create a unique key for the dungeon and master quest + uint8_t key = sceneId | (masterQuest << 7); + + static std::unordered_map> dungeonSmallKeyDoors; + auto foundEntry = dungeonSmallKeyDoors.find(key); + if (foundEntry != dungeonSmallKeyDoors.end()) { + return foundEntry->second; + } + dungeonSmallKeyDoors[key] = {}; + + // Get the scene path + SceneTableEntry* sceneTableEntry = &gSceneTable[sceneId]; + std::string scenePath = + StringHelper::Sprintf("scenes/%s/%s/%s", masterQuest ? "mq" : "nonmq", sceneTableEntry->sceneFile.fileName, + sceneTableEntry->sceneFile.fileName); + + // Load the scene + std::shared_ptr scene = std::dynamic_pointer_cast( + Ship::Context::GetInstance()->GetResourceManager()->LoadResource(scenePath)); + if (scene == nullptr) { + return emptyVector; + } + + // Find the SetTransitionActorList command + std::shared_ptr transitionActorListCommand = nullptr; + for (auto& command : scene->commands) { + if (command->cmdId == SOH::SceneCommandID::SetTransitionActorList) { + transitionActorListCommand = std::dynamic_pointer_cast(command); + break; + } + } + if (transitionActorListCommand == nullptr) { + return emptyVector; + } + + // Find the bit position for the small key doors + for (auto& transitionActor : transitionActorListCommand->transitionActorList) { + if (transitionActor.id == ACTOR_EN_DOOR) { + uint8_t doorType = (transitionActor.params >> 7) & 7; + if (doorType == DOOR_LOCKED) { + dungeonSmallKeyDoors[key].emplace_back(transitionActor.params & 0x3F); + } + } else if (transitionActor.id == ACTOR_DOOR_SHUTTER) { + uint8_t doorType = (transitionActor.params >> 7) & 15; + if (doorType == SHUTTER_BACK_LOCKED || doorType == SHUTTER_BOSS || doorType == SHUTTER_KEY_LOCKED) { + dungeonSmallKeyDoors[key].emplace_back(transitionActor.params & 0x3F); + } + } + } + + return dungeonSmallKeyDoors[key]; +} + +int8_t GetUsedSmallKeyCount(SceneID sceneId) { + const auto& smallKeyDoors = GetDungeonSmallKeyDoors(sceneId); + + // Get the swch value for the scene + uint32_t swch; + if (gPlayState != nullptr && gPlayState->sceneNum == sceneId) { + swch = gPlayState->actorCtx.flags.swch; + } else { + swch = gSaveContext.sceneFlags[sceneId].swch; + } + + // Count the number of small keys doors unlocked + int8_t unlockedSmallKeyDoors = 0; + for (auto& smallKeyDoor : smallKeyDoors) { + unlockedSmallKeyDoors += swch >> smallKeyDoor & 1; + } + + // RANDOTODO: Account for MQ Water trick that causes the basement lock to unlock when the player clears the stalfos + // pit. + return unlockedSmallKeyDoors; +} + +uint8_t Logic::GetSmallKeyCount(uint32_t dungeonIndex) { + int8_t dungeonKeys = mSaveContext->inventory.dungeonKeys[dungeonIndex]; + if (dungeonKeys == -1) { + // never got keys, so can't have used keys + return 0; + } + return dungeonKeys + GetUsedSmallKeyCount(SceneID(dungeonIndex)); +} + +void Logic::SetSmallKeyCount(uint32_t dungeonIndex, uint8_t count) { + mSaveContext->inventory.dungeonKeys[dungeonIndex] = count; +} + +bool Logic::CheckDungeonItem(uint32_t item, uint32_t dungeonIndex) { + return mSaveContext->inventory.dungeonItems[dungeonIndex] & gBitFlags[item]; +} + +void Logic::SetDungeonItem(uint32_t item, uint32_t dungeonIndex, bool state) { + if (!state) { + mSaveContext->inventory.dungeonItems[dungeonIndex] &= ~gBitFlags[item]; + } else { + mSaveContext->inventory.dungeonItems[dungeonIndex] |= gBitFlags[item]; + } +} + +bool Logic::CheckRandoInf(uint32_t flag) { + return mSaveContext->ship.randomizerInf[flag >> 4] & (1 << (flag & 0xF)); +} + +void Logic::SetRandoInf(uint32_t flag, bool state) { + if (!state) { + mSaveContext->ship.randomizerInf[flag >> 4] &= ~(1 << (flag & 0xF)); + } else { + mSaveContext->ship.randomizerInf[flag >> 4] |= (1 << (flag & 0xF)); + } +} + +bool Logic::CheckEventChkInf(int32_t flag) { + return mSaveContext->eventChkInf[flag >> 4] & (1 << (flag & 0xF)); +} + +void Logic::SetEventChkInf(int32_t flag, bool state) { + if (!state) { + mSaveContext->eventChkInf[flag >> 4] &= ~(1 << (flag & 0xF)); + } else { + mSaveContext->eventChkInf[flag >> 4] |= (1 << (flag & 0xF)); + } +} + +uint8_t Logic::GetGSCount() { + return mSaveContext->inventory.gsTokens; +} + +uint8_t Logic::GetAmmo(uint32_t item) { + return mSaveContext->inventory.ammo[gItemSlots[item]]; +} + +void Logic::SetAmmo(uint32_t item, uint8_t count) { + mSaveContext->inventory.ammo[gItemSlots[item]] = count; +} + +void Logic::SetContext(std::shared_ptr _ctx) { + ctx = _ctx; +} + +bool Logic::GetInLogic(LogicVal logicVal) { + return inLogic[logicVal]; +} + +void Logic::SetInLogic(LogicVal logicVal, bool value) { + inLogic[logicVal] = value; +} + +void Logic::Reset() { + NewSaveContext(); + StartPerformanceTimer(PT_LOGIC_RESET); + memset(inLogic, false, sizeof(inLogic)); + // Settings-dependent variables + IsKeysanity = ctx->GetOption(RSK_KEYSANITY).Is(RO_DUNGEON_ITEM_LOC_ANYWHERE) || + ctx->GetOption(RSK_KEYSANITY).Is(RO_DUNGEON_ITEM_LOC_ANYWHERE) || + ctx->GetOption(RSK_KEYSANITY).Is(RO_DUNGEON_ITEM_LOC_ANYWHERE); + + // AmmoCanDrop = /*AmmoDrops.IsNot(AMMODROPS_NONE)*/ false; TODO: AmmoDrop setting + + // Child item logic + SkullMask = false; + MaskOfTruth = false; + + // Adult logic + FreedEpona = false; + // BigPoe = false; + + // Trade Quest Events + WakeUpAdultTalon = false; + + // Dungeon Clears + DekuTreeClear = false; + DodongosCavernClear = false; + JabuJabusBellyClear = false; + ForestTempleClear = false; + FireTempleClear = false; + WaterTempleClear = false; + SpiritTempleClear = false; + ShadowTempleClear = false; + + // Trial Clears + ForestTrialClear = false; + FireTrialClear = false; + WaterTrialClear = false; + SpiritTrialClear = false; + ShadowTrialClear = false; + LightTrialClear = false; + + // Ocarina C Buttons + bool ocBtnShuffle = ctx->GetOption(RSK_SHUFFLE_OCARINA_BUTTONS).Is(true); + SetRandoInf(RAND_INF_HAS_OCARINA_A, !ocBtnShuffle); + SetRandoInf(RAND_INF_HAS_OCARINA_C_UP, !ocBtnShuffle); + SetRandoInf(RAND_INF_HAS_OCARINA_C_DOWN, !ocBtnShuffle); + SetRandoInf(RAND_INF_HAS_OCARINA_C_LEFT, !ocBtnShuffle); + SetRandoInf(RAND_INF_HAS_OCARINA_C_RIGHT, !ocBtnShuffle); + + // Progressive Items + SetUpgrade(UPG_STICKS, ctx->GetOption(RSK_SHUFFLE_DEKU_STICK_BAG).Is(true) ? 0 : 1); + SetUpgrade(UPG_NUTS, ctx->GetOption(RSK_SHUFFLE_DEKU_NUT_BAG).Is(true) ? 0 : 1); + + // If we're not shuffling swim, we start with it + if (ctx->GetOption(RSK_SHUFFLE_SWIM).Is(false)) { + SetRandoInf(RAND_INF_CAN_SWIM, true); + } + + // If we're not shuffling child's wallet, we start with it + if (ctx->GetOption(RSK_SHUFFLE_CHILD_WALLET).Is(false)) { + SetRandoInf(RAND_INF_HAS_WALLET, true); + } + + // If we're not shuffling fishing pole, we start with it + if (ctx->GetOption(RSK_SHUFFLE_FISHING_POLE).Is(false)) { + SetRandoInf(RAND_INF_FISHING_POLE_FOUND, true); + } + + // If not keysanity, start with 1 logical key to account for automatically unlocking the basement door in vanilla + // FiT + if (!IsKeysanity && ctx->GetDungeon(Rando::FIRE_TEMPLE)->IsVanilla()) { + SetSmallKeyCount(SCENE_FIRE_TEMPLE, 1); + } + + // Bottle Count + Bottles = 0; + NumBottles = 0; + CanEmptyBigPoes = false; + CouldEmptyBigPoes = false; + + // Drops and Bottle Contents Access + NutPot = false; + NutCrate = false; + DekuBabaNuts = false; + StickPot = false; + DekuBabaSticks = false; + BugShrub = false; + WanderingBugs = false; + BugRock = false; + BlueFireAccess = false; + FishGroup = false; + LoneFish = false; + GossipStoneFairy = false; + BeanPlantFairy = false; + ButterflyFairy = false; + FairyPot = false; + FreeFairies = false; + FairyPond = false; + + PieceOfHeart = 0; + HeartContainer = 0; + + /* --- HELPERS, EVENTS, AND LOCATION ACCESS --- */ + /* These are used to simplify reading the logic, but need to be updated + / every time a base value is updated. */ + + ChildScarecrow = false; + AdultScarecrow = false; + + CouldPlayBowling = false; + IsChild = false; + IsAdult = false; + // CanPlantBean = false; + BigPoeKill = false; + BigPoes = 0; + + BaseHearts = ctx->GetOption(RSK_STARTING_HEARTS).Get() + 1; + + // Bridge Requirements + BuiltRainbowBridge = false; + + // Other + AtDay = false; + AtNight = false; + GetSaveContext()->linkAge = !ctx->GetOption(RSK_SELECTED_STARTING_AGE).Get(); + + // Events + ShowedMidoSwordAndShield = false; + CarpenterRescue = false; + GF_GateOpen = false; + GtG_GateOpen = false; + DampesWindmillAccess = false; + DrainWell = false; + GoronCityChildFire = false; + GCWoodsWarpOpen = false; + GCDaruniasDoorOpenChild = false; + StopGCRollingGoronAsAdult = false; + CanWaterTempleLowFromHigh = false; + CanWaterTempleLowFromMid = false; + CanWaterTempleMiddle = false; + CanWaterTempleHigh = false; + KakarikoVillageGateOpen = false; + KingZoraThawed = false; + ForestTempleJoelle = false; + ForestTempleBeth = false; + ForestTempleAmy = false; + ForestTempleMeg = false; + FireLoopSwitch = false; + LinksCow = false; + DeliverLetter = false; + ClearMQDCUpperLobbyRocks = false; + LoweredWaterInsideBotw = false; + OpenedWestRoomMQBotw = false; + OpenedMiddleHoleMQBotw = false; + BrokeDeku1FWeb = false; + ClearedMQDekuSERoom = false; + MQDekuWaterRoomTorches = false; + PushedDekuBasementBlock = false; + OpenedLowestGoronCage = false; + OpenedUpperFireShortcut = false; + HitFireTemplePlatform = false; + OpenedFireMQFireMazeDoor = false; + MQForestBlockRoomTargets = false; + ForestCanTwistHallway = false; + ForestClearBelowBowChest = false; + ForestOpenBossCorridor = false; + ShadowTrialFirstChest = false; + MQGTGMazeSwitch = false; + GTGPlatformSilverRupees = false; + MQJabuHolesRoomDoor = false; + JabuWestTentacle = false; + JabuEastTentacle = false; + JabuNorthTentacle = false; + LoweredJabuPath = false; + MQJabuLiftRoomCow = false; + MQShadowFloorSpikeRupees = false; + ShadowShortcutBlock = false; + MQWaterStalfosPit = false; + MQWaterDragonTorches = false; + MQWaterB1Switch = false; + // MQWaterPillarSoTBlock = false; + MQWaterOpenedPillarB1 = false; + MQSpiritCrawlBoulder = false; + MQSpiritMapRoomEnemies = false; + MQSpirit3SunsEnemies = false; + Spirit1FSilverRupees = false; + JabuRutoIn1F = false; + + StopPerformanceTimer(PT_LOGIC_RESET); +} +} // namespace Rando diff --git a/soh/soh/Enhancements/randomizer/logic.h b/soh/soh/Enhancements/randomizer/logic.h index 5b0922d6e..4549c9952 100644 --- a/soh/soh/Enhancements/randomizer/logic.h +++ b/soh/soh/Enhancements/randomizer/logic.h @@ -64,12 +64,13 @@ class Logic { // Bottle Count uint8_t Bottles = 0; uint8_t NumBottles = 0; - //this event covers if the player can currently empty big poes in logic + // this event covers if the player can currently empty big poes in logic bool CanEmptyBigPoes = false; - //this event covers if the player could, if they filled their bottle with big poes in field, empty them at the poe merchant. - //Works in tandem with the big poes safety check during entrance validation + // this event covers if the player could, if they filled their bottle with big poes in field, empty them at the poe + // merchant. Works in tandem with the big poes safety check during entrance validation bool CouldEmptyBigPoes = false; - //this check is used to tell logic that we are checking big poes accessibility in logic, to ensure it's not bottle-locked. + // this check is used to tell logic that we are checking big poes accessibility in logic, to ensure it's not + // bottle-locked. bool AreCheckingBigPoes = false; // Drops and Bottle Contents Access @@ -154,7 +155,7 @@ class Logic { bool OpenedFireMQFireMazeDoor = false; bool MQForestBlockRoomTargets = false; bool ForestCanTwistHallway = false; - bool ForestClearBelowBowChest = false; //a better name that covers both versions would be nice + bool ForestClearBelowBowChest = false; // a better name that covers both versions would be nice bool ForestOpenBossCorridor = false; bool ShadowTrialFirstChest = false; bool MQGTGMazeSwitch = false; @@ -171,7 +172,7 @@ class Logic { bool MQWaterStalfosPit = false; bool MQWaterDragonTorches = false; bool MQWaterB1Switch = false; - //bool MQWaterPillarSoTBlock = false; should be irrelevant. SHOULD. + // bool MQWaterPillarSoTBlock = false; should be irrelevant. SHOULD. bool MQWaterOpenedPillarB1 = false; bool MQSpiritCrawlBoulder = false; bool MQSpiritMapRoomEnemies = false; @@ -193,7 +194,8 @@ class Logic { bool SmallKeys(RandomizerRegion dungeon, uint8_t requiredAmountGlitchless, uint8_t requiredAmountGlitched); bool CanDoGlitch(GlitchType glitch); bool CanEquipSwap(RandomizerGet itemName); - bool CanKillEnemy(RandomizerEnemy enemy, EnemyDistance distance = ED_CLOSE, bool wallOrFloor = true, uint8_t quantity = 1, bool timer = false, bool inWater = false); + bool CanKillEnemy(RandomizerEnemy enemy, EnemyDistance distance = ED_CLOSE, bool wallOrFloor = true, + uint8_t quantity = 1, bool timer = false, bool inWater = false); bool CanPassEnemy(RandomizerEnemy enemy, EnemyDistance distance = ED_CLOSE, bool wallOrFloor = true); bool CanAvoidEnemy(RandomizerEnemy enemy, bool grounded = false, uint8_t quantity = 1); bool CanGetEnemyDrop(RandomizerEnemy enemy, EnemyDistance distance = ED_CLOSE, bool aboveLink = false); diff --git a/soh/soh/Enhancements/randomizer/option.cpp b/soh/soh/Enhancements/randomizer/option.cpp index 84fc4c28b..43fcc2f65 100644 --- a/soh/soh/Enhancements/randomizer/option.cpp +++ b/soh/soh/Enhancements/randomizer/option.cpp @@ -10,29 +10,30 @@ namespace Rando { Option Option::Bool(RandomizerSettingKey key_, std::string name_, std::vector options_, const OptionCategory category_, std::string cvarName_, std::string description_, WidgetType widgetType_, const uint8_t defaultOption_, const bool defaultHidden_, int imFlags_) { - return {static_cast(key_), std::move(name_), std::move(options_), category_, - std::move(cvarName_), std::move(description_), widgetType_, defaultOption_, defaultHidden_, imFlags_}; + return { static_cast(key_), std::move(name_), std::move(options_), category_, std::move(cvarName_), + std::move(description_), widgetType_, defaultOption_, defaultHidden_, imFlags_ }; } Option Option::Bool(RandomizerSettingKey key_, std::string name_, std::string cvarName_, std::string description_, const int imFlags_, const WidgetType widgetType_, const bool defaultOption_) { - return Option(key_, std::move(name_), {"Off", "On"}, OptionCategory::Setting, std::move(cvarName_), + return Option(key_, std::move(name_), { "Off", "On" }, OptionCategory::Setting, std::move(cvarName_), std::move(description_), widgetType_, defaultOption_, false, imFlags_); } Option Option::U8(RandomizerSettingKey key_, std::string name_, std::vector options_, const OptionCategory category_, std::string cvarName_, std::string description_, WidgetType widgetType_, const uint8_t defaultOption_, const bool defaultHidden_, int imFlags_) { - return {static_cast(key_), std::move(name_), std::move(options_), category_, std::move(cvarName_), - std::move(description_), widgetType_, defaultOption_, defaultHidden_, imFlags_}; + return { static_cast(key_), std::move(name_), std::move(options_), category_, std::move(cvarName_), + std::move(description_), widgetType_, defaultOption_, defaultHidden_, imFlags_ }; } Option Option::LogicTrick(RandomizerTrick rt_, std::string name_) { - return Option(rt_, std::move(name_), { "Disabled", "Enabled" }, OptionCategory::Setting, "", - "", WidgetType::Checkbox, 0, false, IMFLAG_NONE); + return Option(rt_, std::move(name_), { "Disabled", "Enabled" }, OptionCategory::Setting, "", "", + WidgetType::Checkbox, 0, false, IMFLAG_NONE); } -OptionValue::OptionValue(uint8_t val) : mVal(val) {} +OptionValue::OptionValue(uint8_t val) : mVal(val) { +} uint8_t OptionValue::Get() { return mVal; @@ -169,7 +170,7 @@ uint8_t Option::GetValueFromText(const std::string text) { } void Option::SetContextIndexFromText(const std::string text) { - if (optionsTextToVar.contains(text)){ + if (optionsTextToVar.contains(text)) { SetContextIndex(optionsTextToVar[text]); } else { SPDLOG_ERROR("Option {} does not have a var named {}.", name, text); @@ -191,7 +192,8 @@ Option::Option(size_t key_, std::string name_, std::vector options_ bool Option::RenderCheckbox() { bool changed = false; bool val = static_cast(CVarGetInteger(cvarName.c_str(), defaultOption)); - UIWidgets::CheckboxOptions widgetOptions = static_cast(UIWidgets::CheckboxOptions().Color(THEME_COLOR).Tooltip(description.c_str())); + UIWidgets::CheckboxOptions widgetOptions = static_cast( + UIWidgets::CheckboxOptions().Color(THEME_COLOR).Tooltip(description.c_str())); widgetOptions.disabled = disabled; if (UIWidgets::Checkbox(name.c_str(), &val, widgetOptions)) { CVarSetInteger(cvarName.c_str(), val); @@ -210,12 +212,14 @@ bool Option::RenderCombobox() { changed = true; Ship::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesNextFrame(); } - UIWidgets::ComboboxOptions widgetOptions = UIWidgets::ComboboxOptions().Color(THEME_COLOR).Tooltip(description.c_str()); + UIWidgets::ComboboxOptions widgetOptions = + UIWidgets::ComboboxOptions().Color(THEME_COLOR).Tooltip(description.c_str()); if (this->GetKey() == RSK_LOGIC_RULES) { - widgetOptions = widgetOptions.LabelPosition(UIWidgets::LabelPositions::None).ComponentAlignment(UIWidgets::ComponentAlignments::Right); + widgetOptions = widgetOptions.LabelPosition(UIWidgets::LabelPositions::None) + .ComponentAlignment(UIWidgets::ComponentAlignments::Right); } widgetOptions.disabled = disabled; - if(UIWidgets::Combobox(name.c_str(), &selected, options, widgetOptions)) { + if (UIWidgets::Combobox(name.c_str(), &selected, options, widgetOptions)) { CVarSetInteger(cvarName.c_str(), static_cast(selected)); changed = true; Ship::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesNextFrame(); @@ -230,7 +234,13 @@ bool Option::RenderSlider() { val = options.size() - 1; changed = true; } - UIWidgets::IntSliderOptions widgetOptions = UIWidgets::IntSliderOptions().Color(THEME_COLOR).Min(0).Max(options.size() - 1).Tooltip(description.c_str()).Format(options[val].c_str()).DefaultValue(defaultOption); + UIWidgets::IntSliderOptions widgetOptions = UIWidgets::IntSliderOptions() + .Color(THEME_COLOR) + .Min(0) + .Max(options.size() - 1) + .Tooltip(description.c_str()) + .Format(options[val].c_str()) + .DefaultValue(defaultOption); widgetOptions.disabled = disabled; if (UIWidgets::SliderInt(name.c_str(), &val, widgetOptions)) { changed = true; @@ -250,27 +260,31 @@ bool Option::RenderSlider() { return changed; } -void Option::PopulateTextToNum(){ - for (uint8_t count = 0; count < options.size(); count++){ +void Option::PopulateTextToNum() { + for (uint8_t count = 0; count < options.size(); count++) { optionsTextToVar[options[count]] = count; } } -LocationOption::LocationOption(RandomizerCheck key_, const std::string& name_) : - Option(key_, name_, {"Included", "Excluded"}, OptionCategory::Setting, "", "", WidgetType::Checkbox, - RO_LOCATION_INCLUDE, false, IMFLAG_NONE) {} +LocationOption::LocationOption(RandomizerCheck key_, const std::string& name_) + : Option(key_, name_, { "Included", "Excluded" }, OptionCategory::Setting, "", "", WidgetType::Checkbox, + RO_LOCATION_INCLUDE, false, IMFLAG_NONE) { +} RandomizerCheck LocationOption::GetKey() const { return static_cast(key); } -TrickOption::TrickOption(RandomizerTrick key_, const RandomizerCheckQuest quest_, const RandomizerArea area_, std::set tags_, const std::string& name_, std::string description_) : - Option(key_, name_, {"Disabled", "Enabled"}, OptionCategory::Setting, "", - std::move(description_), WidgetType::Checkbox, 0, false, IMFLAG_NONE), - mQuest(quest_), mArea(area_), mTags(std::move(tags_)) {} +TrickOption::TrickOption(RandomizerTrick key_, const RandomizerCheckQuest quest_, const RandomizerArea area_, + std::set tags_, const std::string& name_, std::string description_) + : Option(key_, name_, { "Disabled", "Enabled" }, OptionCategory::Setting, "", std::move(description_), + WidgetType::Checkbox, 0, false, IMFLAG_NONE), + mQuest(quest_), mArea(area_), mTags(std::move(tags_)) { +} -TrickOption TrickOption::LogicTrick(RandomizerTrick key_, RandomizerCheckQuest quest_, RandomizerArea area_, std::set tags_, const std::string& name_, std::string description_) { - return {key_, quest_, area_, std::move(tags_), name_, std::move(description_)}; +TrickOption TrickOption::LogicTrick(RandomizerTrick key_, RandomizerCheckQuest quest_, RandomizerArea area_, + std::set tags_, const std::string& name_, std::string description_) { + return { key_, quest_, area_, std::move(tags_), name_, std::move(description_) }; } RandomizerTrick TrickOption::GetKey() const { @@ -295,8 +309,8 @@ const std::set& TrickOption::GetTags() const { OptionGroup::OptionGroup(std::string name, std::vector options, const OptionGroupType groupType, const WidgetContainerType containerType, std::string description) - : mName(std::move(name)), mOptions(std::move(options)), mGroupType(groupType), - mContainerType(containerType), mDescription(std::move(description)) { + : mName(std::move(name)), mOptions(std::move(options)), mGroupType(groupType), mContainerType(containerType), + mDescription(std::move(description)) { } OptionGroup::OptionGroup(std::string name, std::vector subGroups, const OptionGroupType groupType, @@ -307,14 +321,12 @@ OptionGroup::OptionGroup(std::string name, std::vector subGroups, OptionGroup OptionGroup::SubGroup(std::string name, std::vector options, const WidgetContainerType containerType, std::string description) { - return {std::move(name), std::move(options), OptionGroupType::SUBGROUP, containerType, - std::move(description)}; + return { std::move(name), std::move(options), OptionGroupType::SUBGROUP, containerType, std::move(description) }; } OptionGroup OptionGroup::SubGroup(std::string name, std::vector subGroups, const WidgetContainerType containerType, std::string description) { - return {std::move(name), std::move(subGroups), OptionGroupType::SUBGROUP, containerType, - std::move(description)}; + return { std::move(name), std::move(subGroups), OptionGroupType::SUBGROUP, containerType, std::move(description) }; } const std::string& OptionGroup::GetName() const { @@ -358,7 +370,8 @@ bool OptionGroup::RenderImGui() const { // NOLINT(*-no-recursion) bool changed = false; ImGui::BeginDisabled(mDisabled); if (mContainerType == WidgetContainerType::TABLE) { - if (ImGui::BeginTable(mName.c_str(), static_cast(mSubGroups.size()), ImGuiTableFlags_BordersH | ImGuiTableFlags_BordersV)) { + if (ImGui::BeginTable(mName.c_str(), static_cast(mSubGroups.size()), + ImGuiTableFlags_BordersH | ImGuiTableFlags_BordersV)) { for (const auto column : mSubGroups) { if (column->GetContainerType() == WidgetContainerType::COLUMN) { ImGui::TableSetupColumn(column->GetName().c_str(), ImGuiTableColumnFlags_WidthStretch, 200.0f); diff --git a/soh/soh/Enhancements/randomizer/option.h b/soh/soh/Enhancements/randomizer/option.h index 3b1ae8521..d92fa4473 100644 --- a/soh/soh/Enhancements/randomizer/option.h +++ b/soh/soh/Enhancements/randomizer/option.h @@ -16,28 +16,31 @@ namespace Rando { enum ImGuiMenuFlags { - IMFLAG_NONE = 0, - IMFLAG_SEPARATOR_BOTTOM = 1 << 0, /** Adds a padded separator below the widget. */ - IMFLAG_SEPARATOR_TOP = 1 << 1, /** Adds a padded separator above the widget. */ - IMFLAG_INDENT = 1 << 2, /** Indents this widget and all proceeding widgets. */ - IMFLAG_UNINDENT = 1 << 3, /** Unindents this widget and all proceeding widgets. */ + IMFLAG_NONE = 0, + IMFLAG_SEPARATOR_BOTTOM = 1 << 0, /** Adds a padded separator below the widget. */ + IMFLAG_SEPARATOR_TOP = 1 << 1, /** Adds a padded separator above the widget. */ + IMFLAG_INDENT = 1 << 2, /** Indents this widget and all proceeding widgets. */ + IMFLAG_UNINDENT = 1 << 3, /** Unindents this widget and all proceeding widgets. */ }; /** * @brief Affects how options are handled when writing a spoiler/patch file */ enum class OptionCategory { - Setting, /** An option that typically affects the logic/item pool/etc. of the seed. Typically gets written out to the spoiler file. */ - Toggle, /** An option that typically affects other options rather than affecting the seed directly. i.e. A toggle for randomizing the values of other options. */ + Setting, /** An option that typically affects the logic/item pool/etc. of the seed. Typically gets written out to + the spoiler file. */ + Toggle, /** An option that typically affects other options rather than affecting the seed directly. i.e. A toggle + for randomizing the values of other options. */ }; /** * @brief Controls how this option is rendered in the menu. */ enum class WidgetType { - Checkbox, /** Default for Bools, not compatible if options.size() > 2. */ - Combobox, /** Default for U8s, works with U8s and Bools. */ - Slider, /** Compatible with U8s. If constructed with NumOpts, consider using this. Technically can be used for Bool or non-NumOpts options but it would be a bit weird semantically. */ + Checkbox, /** Default for Bools, not compatible if options.size() > 2. */ + Combobox, /** Default for U8s, works with U8s and Bools. */ + Slider, /** Compatible with U8s. If constructed with NumOpts, consider using this. Technically can be used for Bool + or non-NumOpts options but it would be a bit weird semantically. */ }; class OptionValue { @@ -47,15 +50,15 @@ class OptionValue { /** * @brief Returns the value of the OptionValue's mVal - * - * @return uint8_t + * + * @return uint8_t */ uint8_t Get(); /** * @brief Set the OptionValue's mVal to the provided val. - * - * @param val + * + * @param val */ void Set(uint8_t val); @@ -146,8 +149,8 @@ class Option { * @return Option */ static Option Bool(RandomizerSettingKey key_, std::string name_, std::string cvarName_, - std::string description_ = "", int imFlags_ = IMFLAG_SEPARATOR_BOTTOM, - WidgetType widgetType_ = WidgetType::Checkbox, bool defaultOption_ = false); + std::string description_ = "", int imFlags_ = IMFLAG_SEPARATOR_BOTTOM, + WidgetType widgetType_ = WidgetType::Checkbox, bool defaultOption_ = false); /** * @brief Constructs a U8 Option. @@ -192,8 +195,8 @@ class Option { /** * @brief Get the Key Option - * - * @return const RandomizerSettingKey + * + * @return const RandomizerSettingKey */ RandomizerSettingKey GetKey() const; @@ -207,9 +210,9 @@ class Option { /** * @brief Get the text of the Option value of the selected index. - * - * @param index - * @return const std::string& + * + * @param index + * @return const std::string& */ const std::string& GetOptionText(size_t index) const; @@ -279,7 +282,7 @@ class Option { * "Enable" in this context refers to the ability to change the option in the * settings menu. The actual value of the option is not decided by whether or not * the option is "Enabled". - */ + */ void Enable(); /** @@ -312,7 +315,7 @@ class Option { uint8_t GetValueFromText(std::string text); void SetContextIndexFromText(std::string text); -protected: + protected: Option(size_t key_, std::string name_, std::vector options_, OptionCategory category_, std::string cvarName_, std::string description_, WidgetType widgetType_, uint8_t defaultOption_, bool defaultHidden_, int imFlags_); @@ -341,14 +344,14 @@ protected: }; class LocationOption : public Option { -public: - LocationOption() = default; - LocationOption(RandomizerCheck key_, const std::string& name_); - RandomizerCheck GetKey() const; + public: + LocationOption() = default; + LocationOption(RandomizerCheck key_, const std::string& name_); + RandomizerCheck GetKey() const; }; class TrickOption : public Option { -public: + public: TrickOption() = default; /** * @brief A convenience function for constructing the Option for a trick. @@ -361,7 +364,8 @@ public: * @param description_ A brief description of the trick. * @return Option */ - static TrickOption LogicTrick(RandomizerTrick key_, RandomizerCheckQuest quest_, RandomizerArea area_, std::set tags_, const std::string& name_, std::string description_); + static TrickOption LogicTrick(RandomizerTrick key_, RandomizerCheckQuest quest_, RandomizerArea area_, + std::set tags_, const std::string& name_, std::string description_); RandomizerTrick GetKey() const; @@ -389,8 +393,9 @@ public: const std::set& GetTags() const; -private: - TrickOption(RandomizerTrick key_, RandomizerCheckQuest quest_, RandomizerArea area_, std::set tags_, const std::string& name_, std::string description_); + private: + TrickOption(RandomizerTrick key_, RandomizerCheckQuest quest_, RandomizerArea area_, std::set tags_, + const std::string& name_, std::string description_); RandomizerCheckQuest mQuest; RandomizerArea mArea; std::set mTags; @@ -402,11 +407,11 @@ enum class OptionGroupType { }; enum class WidgetContainerType { - BASIC, /** Barebones container, just lists the options within. */ - SECTION, /** Similar to Barebones, but has a header with the section name. */ - COLUMN, /** Signifies the container should be the start of new column within a table. */ - TABLE, /** Signifies the container is a table (should contain other subgroups with type column)*/ - TABBED, /** Signifies this container's contents should be contained within a tabbed interface. */ + BASIC, /** Barebones container, just lists the options within. */ + SECTION, /** Similar to Barebones, but has a header with the section name. */ + COLUMN, /** Signifies the container should be the start of new column within a table. */ + TABLE, /** Signifies the container is a table (should contain other subgroups with type column)*/ + TABBED, /** Signifies this container's contents should be contained within a tabbed interface. */ }; class OptionGroup { @@ -436,7 +441,8 @@ class OptionGroup { * @param containerType Specifies the type of container this widget should render as in ImGui. * @param description A description that can appear in a tooltip in ImGui. */ - OptionGroup(std::string name, std::vector subGroups, OptionGroupType groupType = OptionGroupType::DEFAULT, + OptionGroup(std::string name, std::vector subGroups, + OptionGroupType groupType = OptionGroupType::DEFAULT, WidgetContainerType containerType = WidgetContainerType::BASIC, std::string description = ""); /** @@ -449,7 +455,8 @@ class OptionGroup { * @param description A description that can appear in a tooltip in ImGui. * @return OptionGroup */ - static OptionGroup SubGroup(std::string name, std::vector options, WidgetContainerType containerType = WidgetContainerType::BASIC, + static OptionGroup SubGroup(std::string name, std::vector options, + WidgetContainerType containerType = WidgetContainerType::BASIC, std::string description = ""); /** @@ -462,7 +469,8 @@ class OptionGroup { * @param description A description that can appear in a tooltip in ImGui. * @return OptionGroup */ - static OptionGroup SubGroup(std::string name, std::vector subGroups, WidgetContainerType containerType = WidgetContainerType::BASIC, + static OptionGroup SubGroup(std::string name, std::vector subGroups, + WidgetContainerType containerType = WidgetContainerType::BASIC, std::string description = ""); /** @@ -526,4 +534,4 @@ class OptionGroup { }; } // namespace Rando -#endif //RANDOPTION_H \ No newline at end of file +#endif // RANDOPTION_H \ No newline at end of file diff --git a/soh/soh/Enhancements/randomizer/option_descriptions.cpp b/soh/soh/Enhancements/randomizer/option_descriptions.cpp index fed7e033f..8dc07ce7a 100644 --- a/soh/soh/Enhancements/randomizer/option_descriptions.cpp +++ b/soh/soh/Enhancements/randomizer/option_descriptions.cpp @@ -2,18 +2,19 @@ namespace Rando { void Settings::CreateOptionDescriptions() { - mOptionDescriptions[RSK_FOREST] = "Determines if Kokiri forest can be left for the Lost Woods bridge or the Deku Tree.\n" - "\n" - "On - Kokiri Sword & Deku Shield are required to access " - "the Deku Tree, and completing the Deku Tree is required to " - "access the Lost Woods Bridge Exit.\n" - "\n" - "Deku Only - Kokiri boy no longer blocks the path to the Bridge " - "but Mido still requires the Kokiri Sword and Deku Shield " - "to access the tree.\n" - "\n" - "Off - Mido no longer blocks the path to the Deku Tree. Kokiri " - "boy no longer blocks the path out of the forest."; + mOptionDescriptions[RSK_FOREST] = + "Determines if Kokiri forest can be left for the Lost Woods bridge or the Deku Tree.\n" + "\n" + "On - Kokiri Sword & Deku Shield are required to access " + "the Deku Tree, and completing the Deku Tree is required to " + "access the Lost Woods Bridge Exit.\n" + "\n" + "Deku Only - Kokiri boy no longer blocks the path to the Bridge " + "but Mido still requires the Kokiri Sword and Deku Shield " + "to access the tree.\n" + "\n" + "Off - Mido no longer blocks the path to the Deku Tree. Kokiri " + "boy no longer blocks the path out of the forest."; mOptionDescriptions[RSK_KAK_GATE] = "Closed - The gate will remain closed until Zelda's Letter " "is shown to the guard.\n" "\n" @@ -41,22 +42,24 @@ void Settings::CreateOptionDescriptions() { "\n" "Open - Sleeping Waterfall is always open. " "Link may always enter Zora's Domain."; - mOptionDescriptions[RSK_LOCK_OVERWORLD_DOORS] = "Add locks to all wooden overworld doors, requiring specific small keys to open them"; + mOptionDescriptions[RSK_LOCK_OVERWORLD_DOORS] = + "Add locks to all wooden overworld doors, requiring specific small keys to open them"; mOptionDescriptions[RSK_STARTING_AGE] = "Choose which age Link will start as.\n\n" "Starting as adult means you start with the Master Sword in your inventory.\n" "The child option is forcefully set if it would conflict with other options."; - mOptionDescriptions[RSK_GERUDO_FORTRESS] = "Sets the state of the carpenters captured by Gerudo " - "in Gerudo Fortress, and with it the number of guards that spawn.\n" - "\n" - "Normal - All 4 carpenters are required to be saved.\n" - "\n" - "Fast - Only the bottom left carpenter requires rescuing.\n" - "\n" - "Free - The bridge is repaired from the start, and Nabooru cannot spawn.\n" - "If the Gerudo Membership Card isn't shuffled, you start with it.\n" - "\n" - "Only \"Normal\" is compatible with Gerudo Fortress Key Rings."; + mOptionDescriptions[RSK_GERUDO_FORTRESS] = + "Sets the state of the carpenters captured by Gerudo " + "in Gerudo Fortress, and with it the number of guards that spawn.\n" + "\n" + "Normal - All 4 carpenters are required to be saved.\n" + "\n" + "Fast - Only the bottom left carpenter requires rescuing.\n" + "\n" + "Free - The bridge is repaired from the start, and Nabooru cannot spawn.\n" + "If the Gerudo Membership Card isn't shuffled, you start with it.\n" + "\n" + "Only \"Normal\" is compatible with Gerudo Fortress Key Rings."; mOptionDescriptions[RSK_RAINBOW_BRIDGE] = "Alters the requirements to open the bridge to Ganon's Castle.\n" "\n" @@ -111,13 +114,13 @@ void Settings::CreateOptionDescriptions() { "Selection Only - Specify which dungeons are Vanilla, Master Quest or a 50/50 between the two.\n" "Differs from Random Number in that they are rolled individually, making the exact total a bell curve."; mOptionDescriptions[RSK_MQ_DUNGEON_SET] = - "Choose specific Dungeons to be Master Quest or Vanilla.\n" - "\n" - "If Master Quest Dungeons is set to Set Number or Random, the dungeons chosen " - "to be Master Quest here will count towards that total. Any Dungeons set to Vanilla " - "here will be guaranteed to be Vanilla. If Set Number is higher than the amount of dungeons " - "set to either MQ or Random here, you will have fewer MQ Dungeons than the number you " - "set."; + "Choose specific Dungeons to be Master Quest or Vanilla.\n" + "\n" + "If Master Quest Dungeons is set to Set Number or Random, the dungeons chosen " + "to be Master Quest here will count towards that total. Any Dungeons set to Vanilla " + "here will be guaranteed to be Vanilla. If Set Number is higher than the amount of dungeons " + "set to either MQ or Random here, you will have fewer MQ Dungeons than the number you " + "set."; mOptionDescriptions[RSK_TRIFORCE_HUNT] = "Pieces of the Triforce of Courage have been scattered across the world. Find them all to finish the game!\n\n" "When the required amount of pieces have been found, the game is saved and Ganon's Boss key is given " @@ -224,12 +227,11 @@ void Settings::CreateOptionDescriptions() { "\n" "Adult Link will start with a second free item instead of the Master Sword.\n" "If you haven't found the Master Sword before facing Ganon, you won't receive it during the fight."; - mOptionDescriptions[RSK_SHUFFLE_CHILD_WALLET] = - "Enabling this shuffles the Child's Wallet into the item pool.\n" - "\n" - "You will not be able to carry any rupees until you find a wallet."; - mOptionDescriptions[RSK_INCLUDE_TYCOON_WALLET] = - "Enabling this adds an extra Progressive Wallet to the pool and adds a new 999 capacity tier after Giant's Wallet.\n"; + mOptionDescriptions[RSK_SHUFFLE_CHILD_WALLET] = "Enabling this shuffles the Child's Wallet into the item pool.\n" + "\n" + "You will not be able to carry any rupees until you find a wallet."; + mOptionDescriptions[RSK_INCLUDE_TYCOON_WALLET] = "Enabling this adds an extra Progressive Wallet to the pool and " + "adds a new 999 capacity tier after Giant's Wallet.\n"; mOptionDescriptions[RSK_SHUFFLE_OCARINA] = "Enabling this shuffles the Fairy Ocarina and the Ocarina of Time into the item pool.\n" "\n" @@ -259,72 +261,79 @@ void Settings::CreateOptionDescriptions() { "\n" "The Gerudo Card is required to enter the Gerudo Training Ground, opening " "the gate to Haunted Wasteland and the Horseback Archery minigame."; - mOptionDescriptions[RSK_SHUFFLE_POTS] = "Pots will drop a randomized item the first time they're broken and collected. This does not include the flying pots." - " Pots will have a different appearance when they hold a randomized item.\n" - "With this option enabled, Ganon's boss key door is moved further up the stairs to\n" - "allow access to the pots before obtaining Ganon's Boss Key.\n" - "\n" - "Off - Pots will not be shuffled.\n" - "\n" - "Dungeons - Only shuffle pots that are within dungeons.\n" - "\n" - "Overworld - Only shuffle pots that are outside of dungeons.\n" - "\n" - "All pots - Shuffle all pots."; - mOptionDescriptions[RSK_SHUFFLE_CRATES] = "Crates will drop a randomized item the first time they're broken and collected. " - "Crates will have a different appearance when they hold a randomized item.\n" - "\n" - "Off - Crates will not be shuffled.\n" - "\n" - "Dungeons - Only shuffle crates that are within dungeons.\n" - "\n" - "Overworld - Only shuffle crates that are outside of dungeons.\n" - "\n" - "All Crates - Shuffle all crates."; - mOptionDescriptions[RSK_SHUFFLE_FISHING_POLE] = "Shuffles the fishing pole into the item pool.\n" + mOptionDescriptions[RSK_SHUFFLE_POTS] = + "Pots will drop a randomized item the first time they're broken and collected. This does not include the " + "flying pots." + " Pots will have a different appearance when they hold a randomized item.\n" + "With this option enabled, Ganon's boss key door is moved further up the stairs to\n" + "allow access to the pots before obtaining Ganon's Boss Key.\n" "\n" - "The fishing pole is required to play the fishing pond minigame."; - mOptionDescriptions[RSK_INFINITE_UPGRADES] = "Adds upgrades that hold infinite quantities of items (bombs, arrows, etc.).\n" + "Off - Pots will not be shuffled.\n" + "\n" + "Dungeons - Only shuffle pots that are within dungeons.\n" + "\n" + "Overworld - Only shuffle pots that are outside of dungeons.\n" + "\n" + "All pots - Shuffle all pots."; + mOptionDescriptions[RSK_SHUFFLE_CRATES] = + "Crates will drop a randomized item the first time they're broken and collected. " + "Crates will have a different appearance when they hold a randomized item.\n" + "\n" + "Off - Crates will not be shuffled.\n" + "\n" + "Dungeons - Only shuffle crates that are within dungeons.\n" + "\n" + "Overworld - Only shuffle crates that are outside of dungeons.\n" + "\n" + "All Crates - Shuffle all crates."; + mOptionDescriptions[RSK_SHUFFLE_FISHING_POLE] = "Shuffles the fishing pole into the item pool.\n" + "\n" + "The fishing pole is required to play the fishing pond minigame."; + mOptionDescriptions[RSK_INFINITE_UPGRADES] = + "Adds upgrades that hold infinite quantities of items (bombs, arrows, etc.).\n" "\n" "Progressive - The infinite upgrades are obtained after getting the last normal capacity upgrade.\n" "\n" - "Condensed Progressive - The infinite upgrades are obtained as the first capacity upgrade (doesn't apply to the infinite wallet or to infinite magic)."; + "Condensed Progressive - The infinite upgrades are obtained as the first capacity upgrade (doesn't apply to " + "the infinite wallet or to infinite magic)."; mOptionDescriptions[RSK_SHUFFLE_DEKU_STICK_BAG] = "Shuffles the Deku Stick bag into the item pool.\n" - "\n" - "The Deku Stick bag is required to hold Deku Sticks."; + "\n" + "The Deku Stick bag is required to hold Deku Sticks."; mOptionDescriptions[RSK_SHUFFLE_DEKU_NUT_BAG] = "Shuffles the Deku Nut bag into the item pool.\n" + "\n" + "The Deku Nut bag is required to hold Deku Nuts."; + mOptionDescriptions[RSK_SHOPSANITY] = + "Off - All shop items will be the same as vanilla.\n" "\n" - "The Deku Nut bag is required to hold Deku Nuts."; - mOptionDescriptions[RSK_SHOPSANITY] = "Off - All shop items will be the same as vanilla.\n" - "\n" - "Specific Count - Vanilla shop items will be shuffled among different shops, and " - "each shop will contain a specific number (0-7) of non-vanilla shop items.\n" - "\n" - "Random - Vanilla shop items will be shuffled among different shops, and " - "each shop will contain a random number (1-7) of non-vanilla shop items."; - mOptionDescriptions[RSK_SHOPSANITY_COUNT] = "0 Items - Vanilla shop items will be shuffled among different shops.\n" - "\n" - "1-7 Items - Vanilla shop items will be shuffled among different shops, and " - "each shop will contain 1-7 non-vanilla shop items.\n" - /* - "\n" - "8 Items - All shops will contain 8 non-vanilla shop items.\n" - */; + "Specific Count - Vanilla shop items will be shuffled among different shops, and " + "each shop will contain a specific number (0-7) of non-vanilla shop items.\n" + "\n" + "Random - Vanilla shop items will be shuffled among different shops, and " + "each shop will contain a random number (1-7) of non-vanilla shop items."; + mOptionDescriptions[RSK_SHOPSANITY_COUNT] = + "0 Items - Vanilla shop items will be shuffled among different shops.\n" + "\n" + "1-7 Items - Vanilla shop items will be shuffled among different shops, and " + "each shop will contain 1-7 non-vanilla shop items.\n" + /* + "\n" + "8 Items - All shops will contain 8 non-vanilla shop items.\n" + */ + ; mOptionDescriptions[RSK_SHOPSANITY_PRICES] = "Vanilla - The same price as the item it replaced.\n" "Cheap Balanced - Prices will range between 0 to 95 rupees, favoring lower numbers.\n" "Balanced - Prices will range between 0 to 300 rupees, favoring lower numbers.\n" "Fixed - A fixed number.\n" "Range - A random point between specific ranges.\n" - "Set By Wallet - Set weights that decide the choice of each wallet, and get a random price in that range if that wallet is chosen."; - mOptionDescriptions[RSK_SHOPSANITY_PRICES_FIXED_PRICE] = - "The price for Shopsanity checks."; + "Set By Wallet - Set weights that decide the choice of each wallet, and get a random price in that range if " + "that wallet is chosen."; + mOptionDescriptions[RSK_SHOPSANITY_PRICES_FIXED_PRICE] = "The price for Shopsanity checks."; mOptionDescriptions[RSK_SHOPSANITY_PRICES_RANGE_1] = "The first part of the inclusive range of prices to allow for Shopsanity checks."; mOptionDescriptions[RSK_SHOPSANITY_PRICES_RANGE_2] = "The second part of the inclusive range of prices to allow for Shopsanity checks."; - mOptionDescriptions[RSK_SHOPSANITY_PRICES_NO_WALLET_WEIGHT] = - "The chance for Shopsanity checks to be free."; + mOptionDescriptions[RSK_SHOPSANITY_PRICES_NO_WALLET_WEIGHT] = "The chance for Shopsanity checks to be free."; mOptionDescriptions[RSK_SHOPSANITY_PRICES_CHILD_WALLET_WEIGHT] = "The chance for Shopsanity checks to be purchasable with Child's Wallet (1-99)."; mOptionDescriptions[RSK_SHOPSANITY_PRICES_ADULT_WALLET_WEIGHT] = @@ -337,16 +346,24 @@ void Settings::CreateOptionDescriptions() { "After choosing a price, set it to the affordable amount based on the wallet required.\n\n" "Affordable prices per tier: starter = 1, adult = 100, giant = 201, tycoon = 501\n\n" "Use this to enable wallet tier locking, but make shop items not as expensive as they could be."; - mOptionDescriptions[RSK_FISHSANITY] = "Off - Fish will not be shuffled. No changes will be made to fishing behavior.\n\n" - "Shuffle only Hyrule Loach - Allows you to earn an item by catching the Hyrule Loach at the fishing pond and giving it to the owner.\n\n" - "Shuffle Fishing Pond - The fishing pond's fish will be shuffled. Catching a fish in the fishing pond will grant a reward.\n\n" - "Shuffle Overworld Fish - Fish in generic grottos and Zora's Domain will be shuffled. Catching a fish in a bottle will give a reward.\n\n" + mOptionDescriptions[RSK_FISHSANITY] = + "Off - Fish will not be shuffled. No changes will be made to fishing behavior.\n\n" + "Shuffle only Hyrule Loach - Allows you to earn an item by catching the Hyrule Loach at the fishing pond and " + "giving it to the owner.\n\n" + "Shuffle Fishing Pond - The fishing pond's fish will be shuffled. Catching a fish in the fishing pond will " + "grant a reward.\n\n" + "Shuffle Overworld Fish - Fish in generic grottos and Zora's Domain will be shuffled. Catching a fish in a " + "bottle will give a reward.\n\n" "Shuffle Both - Both overworld fish and fish in the fishing pond will be shuffled."; - mOptionDescriptions[RSK_FISHSANITY_POND_COUNT] = "The number of fish to randomize in the fishing pool.\n\n" - "If set to maximum, each fish will have a unique check, including a Hyrule Loach which appears only as child, and " + mOptionDescriptions[RSK_FISHSANITY_POND_COUNT] = + "The number of fish to randomize in the fishing pool.\n\n" + "If set to maximum, each fish will have a unique check, including a Hyrule Loach which appears only as child, " + "and " "uncaught fish will be given a visual indicator to distinguish from already-caught fish.\n\n" "Otherwise, any fish caught in the pond will give a reward, until all rewards have been given."; - mOptionDescriptions[RSK_FISHSANITY_AGE_SPLIT] = "Enabling this will split the fishing pond fish by age, making fishing pond fish grant different rewards as child and adult.\n\n" + mOptionDescriptions[RSK_FISHSANITY_AGE_SPLIT] = + "Enabling this will split the fishing pond fish by age, making fishing pond fish grant different rewards as " + "child and adult.\n\n" "If disabled, then the child pond will be shuffled and shared between both ages.\n\n" "Note that, as child, there is a second loach available in the pond!"; mOptionDescriptions[RSK_SHUFFLE_SCRUBS] = @@ -363,15 +380,14 @@ void Settings::CreateOptionDescriptions() { "Balanced - Prices will range between 0 to 300 rupees, favoring lower numbers.\n" "Fixed - A fixed number.\n" "Range - A random point between specific ranges.\n" - "Set By Wallet - Set weights that decide the choice of each wallet, and get a random price in that range if that wallet is chosen."; - mOptionDescriptions[RSK_SCRUBS_PRICES_FIXED_PRICE] = - "The price for Scrub checks."; + "Set By Wallet - Set weights that decide the choice of each wallet, and get a random price in that range if " + "that wallet is chosen."; + mOptionDescriptions[RSK_SCRUBS_PRICES_FIXED_PRICE] = "The price for Scrub checks."; mOptionDescriptions[RSK_SCRUBS_PRICES_RANGE_1] = "The first part of the inclusive range of prices to allow for Scrub checks."; mOptionDescriptions[RSK_SCRUBS_PRICES_RANGE_2] = "The second part of the inclusive range of prices to allow for Scrub checks."; - mOptionDescriptions[RSK_SCRUBS_PRICES_NO_WALLET_WEIGHT] = - "The chance for Scrub checks to be free."; + mOptionDescriptions[RSK_SCRUBS_PRICES_NO_WALLET_WEIGHT] = "The chance for Scrub checks to be free."; mOptionDescriptions[RSK_SCRUBS_PRICES_CHILD_WALLET_WEIGHT] = "The chance for Scrub checks to be purchasable with Child's Wallet (1-99)."; mOptionDescriptions[RSK_SCRUBS_PRICES_ADULT_WALLET_WEIGHT] = @@ -384,8 +400,7 @@ void Settings::CreateOptionDescriptions() { "After choosing a price, set it to the affordable amount based on the wallet required.\n\n" "Affordable prices per tier: starter = 1, adult = 100, giant = 201, tycoon = 501\n\n" "Use this to enable wallet tier locking, but make scrub items not as expensive as they could be."; - mOptionDescriptions[RSK_SHUFFLE_BEEHIVES] = - "Beehives give a randomized item from the pool when broken."; + mOptionDescriptions[RSK_SHUFFLE_BEEHIVES] = "Beehives give a randomized item from the pool when broken."; mOptionDescriptions[RSK_SHUFFLE_COWS] = "Cows give a randomized item from the pool upon performing Epona's Song in front of them."; mOptionDescriptions[RSK_SHUFFLE_MERCHANTS] = @@ -407,15 +422,14 @@ void Settings::CreateOptionDescriptions() { "Balanced - Prices will range between 0 to 300 rupees, favoring lower numbers.\n" "Fixed - A fixed number.\n" "Range - A random point between specific ranges.\n" - "Set By Wallet - Set weights that decide the choice of each wallet, and get a random price in that range if that wallet is chosen."; - mOptionDescriptions[RSK_MERCHANT_PRICES_FIXED_PRICE] = - "The price for Merchant checks."; + "Set By Wallet - Set weights that decide the choice of each wallet, and get a random price in that range if " + "that wallet is chosen."; + mOptionDescriptions[RSK_MERCHANT_PRICES_FIXED_PRICE] = "The price for Merchant checks."; mOptionDescriptions[RSK_MERCHANT_PRICES_RANGE_1] = "The first part of the inclusive range of prices to allow for Merchant checks."; mOptionDescriptions[RSK_MERCHANT_PRICES_RANGE_2] = "The second part of the inclusive range of prices to allow for Merchant checks."; - mOptionDescriptions[RSK_MERCHANT_PRICES_NO_WALLET_WEIGHT] = - "The chance for Merchant checks to be free."; + mOptionDescriptions[RSK_MERCHANT_PRICES_NO_WALLET_WEIGHT] = "The chance for Merchant checks to be free."; mOptionDescriptions[RSK_MERCHANT_PRICES_CHILD_WALLET_WEIGHT] = "The chance for Merchant checks to be purchasable with Child's Wallet (1-99)."; mOptionDescriptions[RSK_MERCHANT_PRICES_ADULT_WALLET_WEIGHT] = @@ -447,18 +461,18 @@ void Settings::CreateOptionDescriptions() { "have collected all 100 Gold Skulltula Tokens.\n" "\n" "You can still talk to him multiple times to get Huge Rupees."; - mOptionDescriptions[RSK_SHUFFLE_FREESTANDING] = "Freestanding rupees & hearts are shuffles to random items. " - "Freestanding heart pieces and small keys are already shuffled by default.\n" - "\n" - "Off - freestanding rupees & hearts will not be shuffled.\n" - "\n" - "Dungeons - Only freestanding rupees & hearts that are within dungeons.\n" - "\n" - "Overworld - Only freestanding rupees & hearts that are outside of dungeons.\n" - "\n" - "All Items - Shuffle all freestanding rupees & hearts."; - mOptionDescriptions[RSK_SHUFFLE_FAIRIES] = - "Shuffle fairy locations."; + mOptionDescriptions[RSK_SHUFFLE_FREESTANDING] = + "Freestanding rupees & hearts are shuffles to random items. " + "Freestanding heart pieces and small keys are already shuffled by default.\n" + "\n" + "Off - freestanding rupees & hearts will not be shuffled.\n" + "\n" + "Dungeons - Only freestanding rupees & hearts that are within dungeons.\n" + "\n" + "Overworld - Only freestanding rupees & hearts that are outside of dungeons.\n" + "\n" + "All Items - Shuffle all freestanding rupees & hearts."; + mOptionDescriptions[RSK_SHUFFLE_FAIRIES] = "Shuffle fairy locations."; mOptionDescriptions[RSK_SHUFFLE_GRASS] = "Grass/Bushes will drop a randomized item the first time they're cut and collected. " "Grass/Bushes will have a different appearance when they hold a randomized item.\n" @@ -653,7 +667,8 @@ void Settings::CreateOptionDescriptions() { mOptionDescriptions[RSK_GANONDORF_HINT] = "Talking to Ganondorf in his boss room will tell you the location of the Light Arrows and Master Sword." "If this option is enabled and Ganondorf is reachable without these items, Gossip Stones will never hint the " - "appropriate items.";//RANDOTODO make this hint text about no dupe hints a global hint for static hints. Add to navi? + "appropriate items."; // RANDOTODO make this hint text about no dupe hints a global hint for static hints. Add + // to navi? mOptionDescriptions[RSK_SHEIK_LA_HINT] = "Talking to Sheik inside Ganon's Castle will tell you the location of the Light Arrows." "If this option is enabled and Sheik is reachable without Light Arrows, Gossip Stones will never hint the " @@ -662,29 +677,46 @@ void Settings::CreateOptionDescriptions() { "Reading the diary of Dampé the gravekeeper as adult will tell you the location of one of the Hookshots."; mOptionDescriptions[RSK_GREG_HINT] = "Talking to the chest game owner after buying a key will tell you the location of Greg the Green Rupee."; - mOptionDescriptions[RSK_LOACH_HINT] = - "Talking to the fishing pond owner and asking to talk about something will tell you what's the reward for the Hyrule Loach."; + mOptionDescriptions[RSK_LOACH_HINT] = "Talking to the fishing pond owner and asking to talk about something will " + "tell you what's the reward for the Hyrule Loach."; mOptionDescriptions[RSK_SARIA_HINT] = "Talking to Saria either in person or through Saria's Song will tell you the " "location of a progressive magic meter."; - mOptionDescriptions[RSK_FISHING_POLE_HINT] = "Talking to the fishing pond owner without the fishing pole will tell you its location."; - mOptionDescriptions[RSK_OOT_HINT] = "Sheik in the Temple of Time will tell you the item and song on the Ocarina of Time."; + mOptionDescriptions[RSK_FISHING_POLE_HINT] = + "Talking to the fishing pond owner without the fishing pole will tell you its location."; + mOptionDescriptions[RSK_OOT_HINT] = + "Sheik in the Temple of Time will tell you the item and song on the Ocarina of Time."; mOptionDescriptions[RSK_FROGS_HINT] = "Standing near the pedestal for the frogs in Zora's River will tell you the " "reward for the frogs' Ocarina game."; - mOptionDescriptions[RSK_BIGGORON_HINT] = "Talking to Biggoron will tell you the item he will give you in exchange for the Claim Check."; - mOptionDescriptions[RSK_BIG_POES_HINT] = "Talking to the Poe Collector in the Market Guardhouse while adult will tell you what you receive for handing in Big Poes."; - mOptionDescriptions[RSK_CHICKENS_HINT] = "Talking to Anju as a child will tell you the item she will give you for delivering her cuccos to the pen."; - mOptionDescriptions[RSK_MALON_HINT] = "Talking to Malon as adult will tell you the item on \"Link's cow\", the cow you win from beating her time on the Lon Lon Obstacle Course."; - mOptionDescriptions[RSK_HBA_HINT] = "Talking to the Horseback Archery gerudo in Gerudo Fortress, or the nearby sign, will tell you what you win for scoring 1000 and 1500 points on Horseback Archery."; - mOptionDescriptions[RSK_WARP_SONG_HINTS] = "Playing a warp song will tell you where it leads. (If warp song destinations are vanilla, this is always enabled.)"; + mOptionDescriptions[RSK_BIGGORON_HINT] = + "Talking to Biggoron will tell you the item he will give you in exchange for the Claim Check."; + mOptionDescriptions[RSK_BIG_POES_HINT] = "Talking to the Poe Collector in the Market Guardhouse while adult will " + "tell you what you receive for handing in Big Poes."; + mOptionDescriptions[RSK_CHICKENS_HINT] = + "Talking to Anju as a child will tell you the item she will give you for delivering her cuccos to the pen."; + mOptionDescriptions[RSK_MALON_HINT] = "Talking to Malon as adult will tell you the item on \"Link's cow\", the cow " + "you win from beating her time on the Lon Lon Obstacle Course."; + mOptionDescriptions[RSK_HBA_HINT] = + "Talking to the Horseback Archery gerudo in Gerudo Fortress, or the nearby sign, will tell you what you win " + "for scoring 1000 and 1500 points on Horseback Archery."; + mOptionDescriptions[RSK_WARP_SONG_HINTS] = "Playing a warp song will tell you where it leads. (If warp song " + "destinations are vanilla, this is always enabled.)"; mOptionDescriptions[RSK_SCRUB_TEXT_HINT] = "Business scrubs will reveal the identity of what they're selling."; - mOptionDescriptions[RSK_MERCHANT_TEXT_HINT] = "Merchants will reveal the identity of what they're selling (Shops are not affected by this setting)."; - mOptionDescriptions[RSK_KAK_10_SKULLS_HINT] = "Talking to the Cursed Resident in the Skulltula House who is saved after 10 tokens will tell you the reward."; - mOptionDescriptions[RSK_KAK_20_SKULLS_HINT] = "Talking to the Cursed Resident in the Skulltula House who is saved after 20 tokens will tell you the reward."; - mOptionDescriptions[RSK_KAK_30_SKULLS_HINT] = "Talking to the Cursed Resident in the Skulltula House who is saved after 30 tokens will tell you the reward."; - mOptionDescriptions[RSK_KAK_40_SKULLS_HINT] = "Talking to the Cursed Resident in the Skulltula House who is saved after 40 tokens will tell you the reward."; - mOptionDescriptions[RSK_KAK_50_SKULLS_HINT] = "Talking to the Cursed Resident in the Skulltula House who is saved after 50 tokens will tell you the reward."; - mOptionDescriptions[RSK_KAK_100_SKULLS_HINT] = "Talking to the Cursed Resident in the Skulltula House who is saved after 100 tokens will tell you the reward."; - mOptionDescriptions[RSK_MASK_SHOP_HINT] = "Reading the mask shop sign will tell you rewards from showing masks at the Deku Theatre."; + mOptionDescriptions[RSK_MERCHANT_TEXT_HINT] = + "Merchants will reveal the identity of what they're selling (Shops are not affected by this setting)."; + mOptionDescriptions[RSK_KAK_10_SKULLS_HINT] = + "Talking to the Cursed Resident in the Skulltula House who is saved after 10 tokens will tell you the reward."; + mOptionDescriptions[RSK_KAK_20_SKULLS_HINT] = + "Talking to the Cursed Resident in the Skulltula House who is saved after 20 tokens will tell you the reward."; + mOptionDescriptions[RSK_KAK_30_SKULLS_HINT] = + "Talking to the Cursed Resident in the Skulltula House who is saved after 30 tokens will tell you the reward."; + mOptionDescriptions[RSK_KAK_40_SKULLS_HINT] = + "Talking to the Cursed Resident in the Skulltula House who is saved after 40 tokens will tell you the reward."; + mOptionDescriptions[RSK_KAK_50_SKULLS_HINT] = + "Talking to the Cursed Resident in the Skulltula House who is saved after 50 tokens will tell you the reward."; + mOptionDescriptions[RSK_KAK_100_SKULLS_HINT] = + "Talking to the Cursed Resident in the Skulltula House who is saved after 100 tokens will tell you the reward."; + mOptionDescriptions[RSK_MASK_SHOP_HINT] = + "Reading the mask shop sign will tell you rewards from showing masks at the Deku Theatre."; mOptionDescriptions[RSK_FULL_WALLETS] = "Start with a full wallet. All wallet upgrades come filled with rupees."; mOptionDescriptions[RSK_BOMBCHU_BAG] = "Bombchus require their own bag to be found before use. Without this setting, any Bombchu requirement " @@ -702,7 +734,8 @@ void Settings::CreateOptionDescriptions() { mOptionDescriptions[RSK_BLUE_FIRE_ARROWS] = "Ice Arrows act like Blue Fire, making them able to melt red ice. " "Item placement logic will respect this option, so it might be required to use this to progress."; - mOptionDescriptions[RSK_SKELETON_KEY] = "Adds a new item called the \"Skeleton Key\", it unlocks every dungeon door locked by a small key."; + mOptionDescriptions[RSK_SKELETON_KEY] = + "Adds a new item called the \"Skeleton Key\", it unlocks every dungeon door locked by a small key."; mOptionDescriptions[RSK_SUNLIGHT_ARROWS] = "Light Arrows can be used to light up the sun switches instead of using the Mirror Shield. " "Item placement logic will respect this option, so it might be required to use this to progress."; @@ -720,7 +753,9 @@ void Settings::CreateOptionDescriptions() { "location is reachable. When disabled, only " "required items and locations to beat the game " "will be guaranteed reachable."; - mOptionDescriptions[RSK_SHUFFLE_BOSS_SOULS] = "Shuffles 8 boss souls (one for each blue warp dungeon). A boss will not appear until you collect its respective soul." - "\n\"On + Ganon\" will also hide Ganon and Ganondorf behind a boss soul."; + mOptionDescriptions[RSK_SHUFFLE_BOSS_SOULS] = + "Shuffles 8 boss souls (one for each blue warp dungeon). A boss will not appear until you collect its " + "respective soul." + "\n\"On + Ganon\" will also hide Ganon and Ganondorf behind a boss soul."; } } // namespace Rando diff --git a/soh/soh/Enhancements/randomizer/randomizer.cpp b/soh/soh/Enhancements/randomizer/randomizer.cpp index 5b1a7fc55..d567a3d8e 100644 --- a/soh/soh/Enhancements/randomizer/randomizer.cpp +++ b/soh/soh/Enhancements/randomizer/randomizer.cpp @@ -66,68 +66,201 @@ const std::string Randomizer::IceTrapRandoMessageTableID = "RandomizerIceTrap"; const std::string Randomizer::randoMiscHintsTableID = "RandomizerMiscHints"; static const char* englishRupeeNames[175] = { - "[P]", "Bad RNG Rolls", "Bananas", "Beanbean Coins", "Beans", - "Beli", "Bells", "Berries", "Bison Dollars", "Bitcoin", - "Blue Essence", "Bolts", "Bones", "Boondollars", "Bottle Caps", - "Bratwürste", "Bucks", "BugFrags", "Canadian Dollars", "Cards", - "Chaos Orbs", "Clams", "Coal", "Cocoa Beans", "Coins", - "Cookies", "Copper", "Cor", "Cornflakes", "Credits", - "Crimebucks", "Crystal Shards", "Cubits", "Cucumbers", "Dalmations", - "Dampécoin", "Dark Elixir", "Darseks", "Dead Memes", "Diamonds", - "DNA", "Doge", "Dogecoin", "Doll Hairs", "Dollars", - "Dollarydoos", "Dosh", "Doubloons", "Dwarfbucks", "Elexit", - "Emeralds", "Energon", "Eris", "Ether", "Euro", - "Experience", "Extinction Points", "Floopies", "Flurbos", "FPS", - "Friends", "Frog Coins", "Gald", "Gekz", "Gems", - "Geo", "Gil", "Glimmer", "Glitches", "Gold", - "Gold Dragons", "Goober Dollars", "Green Herbs", "Greg Siblings", "Grouses", - "Gummybears", "Hell", "Hyrule Loaches", "Ice Traps", "ISK", - "Jiggies", "KF7 Ammo", "Kinstones", "Kremcoins", "Kroner", - "Leaves", "Lemmings", "Lien", "Lira", "Lumber", - "Lungmen Dollars", "Macca", "Mana", "Mann Co. Keys", "Meat", - "Meat Stacks", "Medaparts", "Meseta", "Mesetas", "Minerals", - "Monopoly Money", "Moons", "Mora", "Mumbo Tokens", "Munny", - "Mushrooms", "Mysteries", "Neopoints", "Notes", "Nuyen", - "Orbs", "Ore", "Pix", "Pixels", "Plastyks", - "Platinum", "Pokédollars", "Pokémon", "Poko", "Pokos", - "Potch", "Pounds", "Power Pellets", "Primogems", "Réals", - "Refined Metal", "Remote Mines", "Retweets", "Rhinu", "Rings", - "Riot Points", "Robux", "Rubies", "Rubles", "Runite Ore", - "Rupees", "Saint Quartz", "Septims", "Shekels", "Shillings", - "Silver", "Simoleons", "Smackaroos", "Social Credit", "Souls", - "Spent Casings", "Spice", "Spondulicks", "Spoons", "Star Bits", - "Star Chips", "Stars", "Stones of Jordan", "Store Credit", "Strawbs", - "Studs", "Super Sea Snails", "Talent", "Teef", "Telecrystals", - "Tiberium", "TokKul", "Toys", "Turnips", "Upvotes", - "V-Bucks", "Vespene Gas", "Watts", "Widgets", "Woolongs", - "World Dollars", "Wumpa Fruit", "Yen", "Zenny", "Zorkmids", + "[P]", + "Bad RNG Rolls", + "Bananas", + "Beanbean Coins", + "Beans", + "Beli", + "Bells", + "Berries", + "Bison Dollars", + "Bitcoin", + "Blue Essence", + "Bolts", + "Bones", + "Boondollars", + "Bottle Caps", + "Bratwürste", + "Bucks", + "BugFrags", + "Canadian Dollars", + "Cards", + "Chaos Orbs", + "Clams", + "Coal", + "Cocoa Beans", + "Coins", + "Cookies", + "Copper", + "Cor", + "Cornflakes", + "Credits", + "Crimebucks", + "Crystal Shards", + "Cubits", + "Cucumbers", + "Dalmations", + "Dampécoin", + "Dark Elixir", + "Darseks", + "Dead Memes", + "Diamonds", + "DNA", + "Doge", + "Dogecoin", + "Doll Hairs", + "Dollars", + "Dollarydoos", + "Dosh", + "Doubloons", + "Dwarfbucks", + "Elexit", + "Emeralds", + "Energon", + "Eris", + "Ether", + "Euro", + "Experience", + "Extinction Points", + "Floopies", + "Flurbos", + "FPS", + "Friends", + "Frog Coins", + "Gald", + "Gekz", + "Gems", + "Geo", + "Gil", + "Glimmer", + "Glitches", + "Gold", + "Gold Dragons", + "Goober Dollars", + "Green Herbs", + "Greg Siblings", + "Grouses", + "Gummybears", + "Hell", + "Hyrule Loaches", + "Ice Traps", + "ISK", + "Jiggies", + "KF7 Ammo", + "Kinstones", + "Kremcoins", + "Kroner", + "Leaves", + "Lemmings", + "Lien", + "Lira", + "Lumber", + "Lungmen Dollars", + "Macca", + "Mana", + "Mann Co. Keys", + "Meat", + "Meat Stacks", + "Medaparts", + "Meseta", + "Mesetas", + "Minerals", + "Monopoly Money", + "Moons", + "Mora", + "Mumbo Tokens", + "Munny", + "Mushrooms", + "Mysteries", + "Neopoints", + "Notes", + "Nuyen", + "Orbs", + "Ore", + "Pix", + "Pixels", + "Plastyks", + "Platinum", + "Pokédollars", + "Pokémon", + "Poko", + "Pokos", + "Potch", + "Pounds", + "Power Pellets", + "Primogems", + "Réals", + "Refined Metal", + "Remote Mines", + "Retweets", + "Rhinu", + "Rings", + "Riot Points", + "Robux", + "Rubies", + "Rubles", + "Runite Ore", + "Rupees", + "Saint Quartz", + "Septims", + "Shekels", + "Shillings", + "Silver", + "Simoleons", + "Smackaroos", + "Social Credit", + "Souls", + "Spent Casings", + "Spice", + "Spondulicks", + "Spoons", + "Star Bits", + "Star Chips", + "Stars", + "Stones of Jordan", + "Store Credit", + "Strawbs", + "Studs", + "Super Sea Snails", + "Talent", + "Teef", + "Telecrystals", + "Tiberium", + "TokKul", + "Toys", + "Turnips", + "Upvotes", + "V-Bucks", + "Vespene Gas", + "Watts", + "Widgets", + "Woolongs", + "World Dollars", + "Wumpa Fruit", + "Yen", + "Zenny", + "Zorkmids", }; static const char* germanRupeeNames[65] = { - "Bananen", "Bitcoin", "Bonbons", "Bratwürste", "Brause UFOs", - "Brötchen", "Cent", "Diamanten", "Diridari", "Dogecoin", - "ECU", "Elexit", "Erz", "Erzbrocken", "Euro", - "EXP", "Forint", "Franken", "Freunde", "Gil", - "Gold", "Groschen", "Gulden", "Gummibären", "Heller", - "Juwelen", "Karolin", "Kartoffeln", "Kies", "Knete", - "Knochen", "Kohle", "Kraniche", "Kreuzer", "Kronen", - "Kronkorken", "Kröten", "Mark", "Mäuse", "Monde", - "Moorhühner", "Moos", "Münzen", "Penunze", "Pesa", - "Pfandflaschen", "Pfennig", "Pfund", "Pilze", "Plastiks", - "Pokédollar", "Radieschen", "Rappen", "Rubine", "Saphire", - "Schilling", "Seelen", "Smaragde", "Steine", "Sterne", - "Sternis", "Tael", "Taler", "Wagenchips", "Zenny" + "Bananen", "Bitcoin", "Bonbons", "Bratwürste", "Brause UFOs", "Brötchen", "Cent", "Diamanten", + "Diridari", "Dogecoin", "ECU", "Elexit", "Erz", "Erzbrocken", "Euro", "EXP", + "Forint", "Franken", "Freunde", "Gil", "Gold", "Groschen", "Gulden", "Gummibären", + "Heller", "Juwelen", "Karolin", "Kartoffeln", "Kies", "Knete", "Knochen", "Kohle", + "Kraniche", "Kreuzer", "Kronen", "Kronkorken", "Kröten", "Mark", "Mäuse", "Monde", + "Moorhühner", "Moos", "Münzen", "Penunze", "Pesa", "Pfandflaschen", "Pfennig", "Pfund", + "Pilze", "Plastiks", "Pokédollar", "Radieschen", "Rappen", "Rubine", "Saphire", "Schilling", + "Seelen", "Smaragde", "Steine", "Sterne", "Sternis", "Tael", "Taler", "Wagenchips", + "Zenny" }; static const char* frenchRupeeNames[40] = { - "Anneaux", "Baguettes", "Balles", "Bananes", "Bitcoin", - "Blés", "Bling", "Capsules", "Centimes", "Champignons", - "Clochettes", "Crédits", "Croissants", "Diamants", "Dogecoin", - "Dollars", "Émeraudes", "Éthers", "Étoiles", "Euros", - "Florens", "Francs", "Galds", "Gils", "Grouses", - "Halos", "Joyaux", "Lunes", "Mailles", "Munnies", - "Orbes", "Orens", "Pépètes", "Pièces", "Plastyks", - "Pokédollars", "Pokémon", "Radis", "Rubis", "Zennies" + "Anneaux", "Baguettes", "Balles", "Bananes", "Bitcoin", "Blés", "Bling", "Capsules", + "Centimes", "Champignons", "Clochettes", "Crédits", "Croissants", "Diamants", "Dogecoin", "Dollars", + "Émeraudes", "Éthers", "Étoiles", "Euros", "Florens", "Francs", "Galds", "Gils", + "Grouses", "Halos", "Joyaux", "Lunes", "Mailles", "Munnies", "Orbes", "Orens", + "Pépètes", "Pièces", "Plastyks", "Pokédollars", "Pokémon", "Radis", "Rubis", "Zennies" }; Randomizer::Randomizer() { @@ -166,7 +299,7 @@ std::unordered_map spoilerFileDungeonToScene = { { "Ganon's Castle", SCENE_INSIDE_GANONS_CASTLE } }; -std::unordered_map getItemIdToItemId = { +std::unordered_map getItemIdToItemId = { { GI_BOW, ITEM_BOW }, { GI_ARROW_FIRE, ITEM_ARROW_FIRE }, { GI_DINS_FIRE, ITEM_DINS_FIRE }, @@ -210,7 +343,7 @@ std::unordered_map getItemIdToItemId = { #pragma optimize("", off) #pragma GCC push_options -#pragma GCC optimize ("O0") +#pragma GCC optimize("O0") bool Randomizer::SpoilerFileExists(const char* spoilerFileName) { if (strcmp(spoilerFileName, "") != 0) { std::ifstream spoilerFileStream(SohUtils::Sanitize(spoilerFileName)); @@ -232,65 +365,69 @@ void Randomizer::LoadHintMessages() { CustomMessageManager::Instance->ClearMessageTable(Randomizer::hintMessageTableID); CustomMessageManager::Instance->AddCustomMessageTable(Randomizer::hintMessageTableID); - //Extra Hints + // Extra Hints CustomMessageManager::Instance->ClearMessageTable(Randomizer::randoMiscHintsTableID); CustomMessageManager::Instance->AddCustomMessageTable(Randomizer::randoMiscHintsTableID); - // Bow Shooting Gallery reminder - CustomMessageManager::Instance->CreateMessage(Randomizer::hintMessageTableID, TEXT_SHOOTING_GALLERY_MAN_COME_BACK_WITH_BOW, + CustomMessageManager::Instance->CreateMessage( + Randomizer::hintMessageTableID, TEXT_SHOOTING_GALLERY_MAN_COME_BACK_WITH_BOW, CustomMessage("Come back when you have your own bow and you'll get a #different prize#!", - "Komm wieder sobald Du Deinen eigenen Bogen hast, um einen #speziellen Preis# zu erhalten!", - "J'aurai #une autre récompense# pour toi lorsque tu auras ton propre arc.", - {QM_RED})); + "Komm wieder sobald Du Deinen eigenen Bogen hast, um einen #speziellen Preis# zu erhalten!", + "J'aurai #une autre récompense# pour toi lorsque tu auras ton propre arc.", { QM_RED })); // Warp Song Mysterious text - CustomMessageManager::Instance->CreateMessage(Randomizer::hintMessageTableID, TEXT_WARP_MINUET_OF_FOREST, + CustomMessageManager::Instance->CreateMessage( + Randomizer::hintMessageTableID, TEXT_WARP_MINUET_OF_FOREST, CustomMessage("Warp to&#a mysterious place?#&" + CustomMessages::TWO_WAY_CHOICE() + "#OK&No#", - "Zu&#einem mysteriösen Ort#?&" + CustomMessages::TWO_WAY_CHOICE() + "#OK&No#", - "Se téléporter vers&#un endroit mystérieux#?&" + CustomMessages::TWO_WAY_CHOICE() + "#OK!&Non#", - {QM_RED, QM_GREEN})); + "Zu&#einem mysteriösen Ort#?&" + CustomMessages::TWO_WAY_CHOICE() + "#OK&No#", + "Se téléporter vers&#un endroit mystérieux#?&" + CustomMessages::TWO_WAY_CHOICE() + "#OK!&Non#", + { QM_RED, QM_GREEN })); // Lake Hylia water level system - CustomMessageManager::Instance->CreateMessage(Randomizer::hintMessageTableID, TEXT_LAKE_HYLIA_WATER_SWITCH_SIGN, - CustomMessage("Water level control system.&Keep away!", - "Wasserstand Kontrollsystem&Finger weg!", - "Système de contrôle du niveau&d'eau.&Ne pas toucher!")); - CustomMessageManager::Instance->CreateMessage(Randomizer::hintMessageTableID, TEXT_LAKE_HYLIA_WATER_SWITCH_NAVI, - CustomMessage("%cThis switch is rustier than you think.^%cSomething must be wrong with the pipe system in the %bWater Temple%c.", - "%cDieser Schalter scheint rostiger zu sein als er aussieht.^%cEtwas muss mit dem Leitungssystem im %bWassertempel%c nicht stimmen.", - "%cCet interrupteur est très rouillé.^%cIl doit y avoir un problème avec la tuyauterie du %bTemple de l'Eau%c.")); + CustomMessageManager::Instance->CreateMessage( + Randomizer::hintMessageTableID, TEXT_LAKE_HYLIA_WATER_SWITCH_SIGN, + CustomMessage("Water level control system.&Keep away!", "Wasserstand Kontrollsystem&Finger weg!", + "Système de contrôle du niveau&d'eau.&Ne pas toucher!")); + CustomMessageManager::Instance->CreateMessage( + Randomizer::hintMessageTableID, TEXT_LAKE_HYLIA_WATER_SWITCH_NAVI, + CustomMessage("%cThis switch is rustier than you think.^%cSomething must be wrong with the pipe system in the " + "%bWater Temple%c.", + "%cDieser Schalter scheint rostiger zu sein als er aussieht.^%cEtwas muss mit dem Leitungssystem " + "im %bWassertempel%c nicht stimmen.", + "%cCet interrupteur est très rouillé.^%cIl doit y avoir un problème avec la tuyauterie du " + "%bTemple de l'Eau%c.")); } // Reference soh/src/overlays/actors/ovl_En_GirlA/z_en_girla.h std::unordered_map randomizerGetToEnGirlShopItem = { - { RG_BUY_DEKU_NUTS_5, SI_DEKU_NUTS_5 }, - { RG_BUY_ARROWS_30, SI_ARROWS_30 }, - { RG_BUY_ARROWS_50, SI_ARROWS_50 }, - { RG_BUY_BOMBS_525, SI_BOMBS_5_R25 }, - { RG_BUY_DEKU_NUTS_10, SI_DEKU_NUTS_10 }, - { RG_BUY_DEKU_STICK_1, SI_DEKU_STICK }, - { RG_BUY_BOMBS_10, SI_BOMBS_10 }, - { RG_BUY_FISH, SI_FISH }, + { RG_BUY_DEKU_NUTS_5, SI_DEKU_NUTS_5 }, + { RG_BUY_ARROWS_30, SI_ARROWS_30 }, + { RG_BUY_ARROWS_50, SI_ARROWS_50 }, + { RG_BUY_BOMBS_525, SI_BOMBS_5_R25 }, + { RG_BUY_DEKU_NUTS_10, SI_DEKU_NUTS_10 }, + { RG_BUY_DEKU_STICK_1, SI_DEKU_STICK }, + { RG_BUY_BOMBS_10, SI_BOMBS_10 }, + { RG_BUY_FISH, SI_FISH }, { RG_BUY_RED_POTION_30, SI_RED_POTION_R30 }, - { RG_BUY_GREEN_POTION, SI_GREEN_POTION }, - { RG_BUY_BLUE_POTION, SI_BLUE_POTION }, + { RG_BUY_GREEN_POTION, SI_GREEN_POTION }, + { RG_BUY_BLUE_POTION, SI_BLUE_POTION }, { RG_BUY_HYLIAN_SHIELD, SI_HYLIAN_SHIELD }, - { RG_BUY_DEKU_SHIELD, SI_DEKU_SHIELD }, - { RG_BUY_GORON_TUNIC, SI_GORON_TUNIC }, - { RG_BUY_ZORA_TUNIC, SI_ZORA_TUNIC }, - { RG_BUY_HEART, SI_RECOVERY_HEART }, - { RG_BUY_BOMBCHUS_10, SI_BOMBCHU_10_1 }, - { RG_BUY_BOMBCHUS_20, SI_BOMBCHU_20_1 }, + { RG_BUY_DEKU_SHIELD, SI_DEKU_SHIELD }, + { RG_BUY_GORON_TUNIC, SI_GORON_TUNIC }, + { RG_BUY_ZORA_TUNIC, SI_ZORA_TUNIC }, + { RG_BUY_HEART, SI_RECOVERY_HEART }, + { RG_BUY_BOMBCHUS_10, SI_BOMBCHU_10_1 }, + { RG_BUY_BOMBCHUS_20, SI_BOMBCHU_20_1 }, { RG_BUY_DEKU_SEEDS_30, SI_DEKU_SEEDS_30 }, - { RG_BUY_BLUE_FIRE, SI_BLUE_FIRE }, - { RG_BUY_BOTTLE_BUG, SI_BUGS }, - { RG_BUY_POE, SI_POE }, + { RG_BUY_BLUE_FIRE, SI_BLUE_FIRE }, + { RG_BUY_BOTTLE_BUG, SI_BUGS }, + { RG_BUY_POE, SI_POE }, { RG_BUY_FAIRYS_SPIRIT, SI_FAIRY }, - { RG_BUY_ARROWS_10, SI_ARROWS_10 }, - { RG_BUY_BOMBS_20, SI_BOMBS_20 }, - { RG_BUY_BOMBS_30, SI_BOMBS_30 }, - { RG_BUY_BOMBS_535, SI_BOMBS_5_R35 }, + { RG_BUY_ARROWS_10, SI_ARROWS_10 }, + { RG_BUY_BOMBS_20, SI_BOMBS_20 }, + { RG_BUY_BOMBS_30, SI_BOMBS_30 }, + { RG_BUY_BOMBS_535, SI_BOMBS_5_R35 }, { RG_BUY_RED_POTION_40, SI_RED_POTION_R40 }, { RG_BUY_RED_POTION_50, SI_RED_POTION_R50 }, }; @@ -300,112 +437,137 @@ void Randomizer::LoadMerchantMessages() { CustomMessageManager::Instance->ClearMessageTable(Randomizer::merchantMessageTableID); CustomMessageManager::Instance->AddCustomMessageTable(Randomizer::merchantMessageTableID); - // Prices have a chance of being 0, and the "sell" message below doesn't really make sense for a free item, so adding a "free" variation here - CustomMessageManager::Instance->CreateMessage(Randomizer::merchantMessageTableID, TEXT_SCRUB_RANDOM_FREE, - CustomMessage("\x12\x38\x82" "All right! You win! In return for sparing me, I will give you a #[[1]]#!&Please, take it!\x07\x10\xA3", - "\x12\x38\x82" "In Ordnung! Du gewinnst! Im Austausch dafür, dass Du mich verschont hast, werde ich Dir einen #[[1]]# geben!\x07\x10\xA3", - "\x12\x38\x82" "J'me rends! Laisse-moi partir et en échange, je te donne un #[[1]]#! Vas-y prends le!\x07\x10\xA3", - {QM_GREEN})); - CustomMessageManager::Instance->CreateMessage(Randomizer::merchantMessageTableID, TEXT_SCRUB_RANDOM, - CustomMessage("\x12\x38\x82" "All right! You win! In return for sparing me, I will sell you a #[[1]]#! #[[2]] Rupees# it is!\x07\x10\xA3", - "\x12\x38\x82" "Ich gebe auf! Ich verkaufe Dir einen #[[1]]# für #[[2]] Rubine#!\x07\x10\xA3", - "\x12\x38\x82" "J'abandonne! Tu veux bien m'acheter un #[[1]]#? Ça fera #[[2]] Rubis#!\x07\x10\xA3", - {QM_GREEN, QM_YELLOW})); + // Prices have a chance of being 0, and the "sell" message below doesn't really make sense for a free item, so + // adding a "free" variation here + CustomMessageManager::Instance->CreateMessage( + Randomizer::merchantMessageTableID, TEXT_SCRUB_RANDOM_FREE, + CustomMessage( + "\x12\x38\x82" + "All right! You win! In return for sparing me, I will give you a #[[1]]#!&Please, take it!\x07\x10\xA3", + "\x12\x38\x82" + "In Ordnung! Du gewinnst! Im Austausch dafür, dass Du mich verschont hast, werde ich Dir einen #[[1]]# " + "geben!\x07\x10\xA3", + "\x12\x38\x82" + "J'me rends! Laisse-moi partir et en échange, je te donne un #[[1]]#! Vas-y prends le!\x07\x10\xA3", + { QM_GREEN })); + CustomMessageManager::Instance->CreateMessage( + Randomizer::merchantMessageTableID, TEXT_SCRUB_RANDOM, + CustomMessage("\x12\x38\x82" + "All right! You win! In return for sparing me, I will sell you a #[[1]]#! #[[2]] Rupees# it " + "is!\x07\x10\xA3", + "\x12\x38\x82" + "Ich gebe auf! Ich verkaufe Dir einen #[[1]]# für #[[2]] Rubine#!\x07\x10\xA3", + "\x12\x38\x82" + "J'abandonne! Tu veux bien m'acheter un #[[1]]#? Ça fera #[[2]] Rubis#!\x07\x10\xA3", + { QM_GREEN, QM_YELLOW })); - //Carpet Salesman + // Carpet Salesman CustomMessageManager::Instance->CreateMessage( Randomizer::merchantMessageTableID, TEXT_CARPET_SALESMAN_ARMS_DEALER, CustomMessage("Finally! Now I can go back to being an #arms dealer#!", - /*german*/"Endlich! Schon bald kann ich wieder #Krabbelminen-Händler# sein!", - /*french*/"Squalala! Je vais enfin pouvoir #prendre des vacances#!", - {QM_RED})); + /*german*/ "Endlich! Schon bald kann ich wieder #Krabbelminen-Händler# sein!", + /*french*/ "Squalala! Je vais enfin pouvoir #prendre des vacances#!", { QM_RED })); // Each shop item has two messages, one for when the cursor is over it, and one for when you select it and are // prompted buy/don't buy CustomMessageManager::Instance->CreateMessage( Randomizer::merchantMessageTableID, TEXT_SHOP_ITEM_RANDOM, - CustomMessage("\x08#[[1]]# #[[2]]_Rupees#&Special deal! #ONE LEFT#!&Get it while it lasts!\x0A\x02", + CustomMessage( + "\x08#[[1]]# #[[2]]_Rupees#&Special deal! #ONE LEFT#!&Get it while it lasts!\x0A\x02", "\x08#[[1]]# #[[2]]_Rubine#&Sonderangebot! #NUR NOCH EINES VERFÜGBAR#!&Beeilen Sie sich!\x0A\x02", "\x08#[[1]]# #[[2]]_Rubis#&Offre spéciale! #DERNIER EN STOCK#!&Faites vite!\x0A\x02", - {QM_GREEN, QM_YELLOW, QM_RED})); + { QM_GREEN, QM_YELLOW, QM_RED })); CustomMessageManager::Instance->CreateMessage( Randomizer::merchantMessageTableID, TEXT_SHOP_ITEM_RANDOM_CONFIRM, CustomMessage("\x08#[[1]]# #[[2]]_Rupees#\x09\x1B#Buy&Don't buy#\x09\x02", - "\x08#[[1]]# #[[2]]_Rubine#\x09\x1B#Kaufen&Nicht kaufen#\x09\x02", - "\x08#[[1]]# #[[2]]_Rubis#\x09\x1B#Acheter&Ne pas acheter#\x09\x02", - {QM_GREEN, QM_YELLOW, QM_GREEN})); - + "\x08#[[1]]# #[[2]]_Rubine#\x09\x1B#Kaufen&Nicht kaufen#\x09\x02", + "\x08#[[1]]# #[[2]]_Rubis#\x09\x1B#Acheter&Ne pas acheter#\x09\x02", + { QM_GREEN, QM_YELLOW, QM_GREEN })); + CustomMessageManager::Instance->CreateMessage( Randomizer::merchantMessageTableID, TEXT_BEAN_SALESMAN_BUY_FOR_10, - CustomMessage("I tried to be a #magic bean# salesman, but it turns out my marketing skills weren't worth " - "beans!^Anyway, want to buy #[[1]]# for #[[2]] Rupees#?\x1B#Yes&No#", - /*german*/ "Möchten Sie #[[1]]# für #[[2]] Rubine# kaufen?\x1B#Ja&Nein#", - /*french*/ "J'ai essayé d'être un vendeur de #haricots magiques#, mais j'étais mauvais au niveau du marketing et ça " - "me courait sur le haricot...^Enfin bref, ça te dirait de m'acheter #[[1]]# pour #[[2]] Rubis#?\x1B#Oui&Non#", - {QM_RED, QM_GREEN, QM_YELLOW, QM_GREEN})); + CustomMessage( + "I tried to be a #magic bean# salesman, but it turns out my marketing skills weren't worth " + "beans!^Anyway, want to buy #[[1]]# for #[[2]] Rupees#?\x1B#Yes&No#", + /*german*/ "Möchten Sie #[[1]]# für #[[2]] Rubine# kaufen?\x1B#Ja&Nein#", + /*french*/ + "J'ai essayé d'être un vendeur de #haricots magiques#, mais j'étais mauvais au niveau du marketing et ça " + "me courait sur le haricot...^Enfin bref, ça te dirait de m'acheter #[[1]]# pour #[[2]] " + "Rubis#?\x1B#Oui&Non#", + { QM_RED, QM_GREEN, QM_YELLOW, QM_GREEN })); CustomMessageManager::Instance->CreateMessage( Randomizer::merchantMessageTableID, TEXT_BEAN_SALESMAN_BUY_FOR_100, - CustomMessage("I never thought I'd say this, but I'm selling the last #Magic Bean#.^#99 Rupees#, no less.\x1B#Yes&No#", - "Ich hätte nie gedacht, daß ich das sage, aber ich verkaufe die letzte^#Wundererbse# für #99 Rubine#.\x1B&#Ja&Nein#", - "Je te vends mon dernier #Haricot&magique# pour #99 Rubis#.\x1B&#AcheterNe pas acheter#", - {QM_RED, QM_YELLOW, QM_GREEN})); + CustomMessage( + "I never thought I'd say this, but I'm selling the last #Magic Bean#.^#99 Rupees#, no less.\x1B#Yes&No#", + "Ich hätte nie gedacht, daß ich das sage, aber ich verkaufe die letzte^#Wundererbse# für #99 " + "Rubine#.\x1B&#Ja&Nein#", + "Je te vends mon dernier #Haricot&magique# pour #99 Rubis#.\x1B&#AcheterNe pas acheter#", + { QM_RED, QM_YELLOW, QM_GREEN })); CustomMessageManager::Instance->CreateMessage( Randomizer::merchantMessageTableID, TEXT_MEDIGORON, CustomMessage("How about buying #[[1]]# for #[[2]] Rupees#?\x1B#Buy&Don't buy#", - /*german*/ "Möchtest Du #[[1]]# für #[[2]] Rubine# kaufen?\x1B#Klar!&Nie im Leben!#", - /*french*/ "Veux-tu acheter #[[1]]# pour #[[2]] rubis#?\x1B#Acheter&Ne pas acheter#", - {QM_GREEN, QM_YELLOW, QM_GREEN})); - /*spanish*/ // ¿Me compras #[[1]]# por #[[2]] rupias#?\x1B#Comprar&No comprar# + /*german*/ "Möchtest Du #[[1]]# für #[[2]] Rubine# kaufen?\x1B#Klar!&Nie im Leben!#", + /*french*/ "Veux-tu acheter #[[1]]# pour #[[2]] rubis#?\x1B#Acheter&Ne pas acheter#", + { QM_GREEN, QM_YELLOW, QM_GREEN })); + /*spanish*/ // ¿Me compras #[[1]]# por #[[2]] rupias#?\x1B#Comprar&No comprar# + + CustomMessage firstCarpet = CustomMessage( + "Welcome!^I am selling stuff, strange and rare, from all over the world to everybody. Today's special is...^", + /*german*/ + "Sei gegrüßt!^Ich verkaufe allerlei Kuriositäten. Stets sonderliche und seltene Ware aus " + "aller Welt für jedermann. Das heutige Angebot bleibt...^", + /*french*/ "Bienvenue!^Je vends des objets rares et merveilleux du monde entier. En spécial aujourd'hui...^"); + /*spanish*/ // ¡Acércate!^Vendo productos extraños y difíciles de encontrar... De todo el mundo a todo el mundo. La + // oferta de hoy es...^#¡ - CustomMessage firstCarpet = CustomMessage("Welcome!^I am selling stuff, strange and rare, from all over the world to everybody. Today's special is...^", - /*german*/ "Sei gegrüßt!^Ich verkaufe allerlei Kuriositäten. Stets sonderliche und seltene Ware aus " - "aller Welt für jedermann. Das heutige Angebot bleibt...^", - /*french*/ "Bienvenue!^Je vends des objets rares et merveilleux du monde entier. En spécial aujourd'hui...^"); - /*spanish*/ // ¡Acércate!^Vendo productos extraños y difíciles de encontrar... De todo el mundo a todo el mundo. La oferta de hoy es...^#¡ - CustomMessageManager::Instance->CreateMessage( Randomizer::merchantMessageTableID, TEXT_CARPET_SALESMAN_MYSTERIOUS, firstCarpet + - CustomMessage("Terrifying! I won't tell you what it is until I see the #money#...^How about #[[2]] Rupees#?&&" - "\x1B#Buy&Don't buy#", - /*german*/ "Furchterregend, oder? Ich erzähle Euch mehr, wenn ich #Geld# sehe...^Wie wär's mit #[[2]] Rubinen#?&&" - "\x1B#Aber sicher!&Ich bin weg!#", - /*french*/ "Terrible! Mais montre tes #rubis# avant que je te dise ce que c'est...^Disons #[[2]] " - "rubis#?&&\x1B#Acheter&Ne pas acheter#", - {QM_RED, QM_YELLOW, QM_GREEN})); - /*spanish*/ // ¡Terrorífico! No te revelaré su nombre hasta que vea el #dinero#...^#[[2]] rupias#, ¿qué te parece?&&" - // "\x1B#Comprar&No comprar# + CustomMessage( + "Terrifying! I won't tell you what it is until I see the #money#...^How about #[[2]] Rupees#?&&" + "\x1B#Buy&Don't buy#", + /*german*/ + "Furchterregend, oder? Ich erzähle Euch mehr, wenn ich #Geld# sehe...^Wie wär's mit #[[2]] Rubinen#?&&" + "\x1B#Aber sicher!&Ich bin weg!#", + /*french*/ + "Terrible! Mais montre tes #rubis# avant que je te dise ce que c'est...^Disons #[[2]] " + "rubis#?&&\x1B#Acheter&Ne pas acheter#", + { QM_RED, QM_YELLOW, QM_GREEN })); + /*spanish*/ // ¡Terrorífico! No te revelaré su nombre hasta que vea el #dinero#...^#[[2]] rupias#, ¿qué te + // parece?&&" + // "\x1B#Comprar&No comprar# CustomMessageManager::Instance->CreateMessage( Randomizer::merchantMessageTableID, TEXT_CARPET_SALESMAN_1, firstCarpet + - CustomMessage("#[[1]]!# It's real, I promise! A lonely man such as myself wouldn't #lie# to you, hmm?^" - "How about #[[2]] Rupees#?\x1B#Buy&Don't buy#", - /*german*/ "#[[1]]#! Ich kann versichern, es ist ein aufrichtiges Angebot!^Ein einsamer Mann wie ich würde Dich doch " - "nicht #anlügen#, oder?^Wie wär's mit #[[2]] Rubinen#?\x1B#Aber sicher!&Ich bin weg!#", - /*french*/ "#[[1]]!# C'est vrai! J'te jure! Un gars comme moi ne te #mentirai# pas tu ne crois pas?^Disons #[[2]] " - "rubis#?\x1B#Acheter&Ne pas acheter#", - {QM_GREEN, QM_RED, QM_YELLOW})); + CustomMessage( + "#[[1]]!# It's real, I promise! A lonely man such as myself wouldn't #lie# to you, hmm?^" + "How about #[[2]] Rupees#?\x1B#Buy&Don't buy#", + /*german*/ + "#[[1]]#! Ich kann versichern, es ist ein aufrichtiges Angebot!^Ein einsamer Mann wie ich würde Dich " + "doch " + "nicht #anlügen#, oder?^Wie wär's mit #[[2]] Rubinen#?\x1B#Aber sicher!&Ich bin weg!#", + /*french*/ + "#[[1]]!# C'est vrai! J'te jure! Un gars comme moi ne te #mentirai# pas tu ne crois pas?^Disons #[[2]] " + "rubis#?\x1B#Acheter&Ne pas acheter#", + { QM_GREEN, QM_RED, QM_YELLOW })); CustomMessageManager::Instance->CreateMessage( Randomizer::merchantMessageTableID, TEXT_GRANNYS_SHOP, CustomMessage("#[[1]]#! How about #[[2]] Rupees#?\x1B#Buy&Don't buy#", - /*german*/ "#[[1]]#! Sagen wir #[[2]] Rubine#?\x1B#Gerne!&Auf keinen Fall!#", - /*french*/ "#[[1]]#! Que dis-tu de #[[2]] rubis#?\x1B#Acheter&Ne pas acheter#", - {QM_GREEN, QM_YELLOW, QM_GREEN}, {true})); - // /*spanish*/#[[1]]#. Vendo por #[[2]] rupias#.&\x1B#Comprar&No comprar# + /*german*/ "#[[1]]#! Sagen wir #[[2]] Rubine#?\x1B#Gerne!&Auf keinen Fall!#", + /*french*/ "#[[1]]#! Que dis-tu de #[[2]] rubis#?\x1B#Acheter&Ne pas acheter#", + { QM_GREEN, QM_YELLOW, QM_GREEN }, { true })); + // /*spanish*/#[[1]]#. Vendo por #[[2]] rupias#.&\x1B#Comprar&No comprar# } std::map trialFlagToTrialKey = { - { EVENTCHKINF_COMPLETED_LIGHT_TRIAL, TK_LIGHT_TRIAL }, - { EVENTCHKINF_COMPLETED_FOREST_TRIAL, TK_FOREST_TRIAL }, - { EVENTCHKINF_COMPLETED_FIRE_TRIAL, TK_FIRE_TRIAL }, - { EVENTCHKINF_COMPLETED_WATER_TRIAL, TK_WATER_TRIAL }, - { EVENTCHKINF_COMPLETED_SPIRIT_TRIAL, TK_SPIRIT_TRIAL }, - { EVENTCHKINF_COMPLETED_SHADOW_TRIAL, TK_SHADOW_TRIAL }, + { EVENTCHKINF_COMPLETED_LIGHT_TRIAL, TK_LIGHT_TRIAL }, { EVENTCHKINF_COMPLETED_FOREST_TRIAL, TK_FOREST_TRIAL }, + { EVENTCHKINF_COMPLETED_FIRE_TRIAL, TK_FIRE_TRIAL }, { EVENTCHKINF_COMPLETED_WATER_TRIAL, TK_WATER_TRIAL }, + { EVENTCHKINF_COMPLETED_SPIRIT_TRIAL, TK_SPIRIT_TRIAL }, { EVENTCHKINF_COMPLETED_SHADOW_TRIAL, TK_SHADOW_TRIAL }, }; bool Randomizer::IsTrialRequired(s32 trialFlag) { @@ -455,9 +617,11 @@ ItemObtainability Randomizer::GetItemObtainabilityFromRandomizerGet(RandomizerGe return !CHECK_OWNED_EQUIP(EQUIP_TYPE_SHIELD, EQUIP_INV_SHIELD_DEKU) ? CAN_OBTAIN : CANT_OBTAIN_ALREADY_HAVE; case RG_HYLIAN_SHIELD: case RG_BUY_HYLIAN_SHIELD: - return !CHECK_OWNED_EQUIP(EQUIP_TYPE_SHIELD, EQUIP_INV_SHIELD_HYLIAN) ? CAN_OBTAIN : CANT_OBTAIN_ALREADY_HAVE; + return !CHECK_OWNED_EQUIP(EQUIP_TYPE_SHIELD, EQUIP_INV_SHIELD_HYLIAN) ? CAN_OBTAIN + : CANT_OBTAIN_ALREADY_HAVE; case RG_MIRROR_SHIELD: - return !CHECK_OWNED_EQUIP(EQUIP_TYPE_SHIELD, EQUIP_INV_SHIELD_MIRROR) ? CAN_OBTAIN : CANT_OBTAIN_ALREADY_HAVE; + return !CHECK_OWNED_EQUIP(EQUIP_TYPE_SHIELD, EQUIP_INV_SHIELD_MIRROR) ? CAN_OBTAIN + : CANT_OBTAIN_ALREADY_HAVE; case RG_GORON_TUNIC: case RG_BUY_GORON_TUNIC: return !CHECK_OWNED_EQUIP(EQUIP_TYPE_TUNIC, EQUIP_INV_TUNIC_GORON) ? CAN_OBTAIN : CANT_OBTAIN_ALREADY_HAVE; @@ -471,27 +635,34 @@ ItemObtainability Randomizer::GetItemObtainabilityFromRandomizerGet(RandomizerGe // Inventory Items case RG_PROGRESSIVE_STICK_UPGRADE: - return infiniteUpgrades != RO_INF_UPGRADES_OFF ? - (Flags_GetRandomizerInf(RAND_INF_HAS_INFINITE_STICK_UPGRADE) ? CANT_OBTAIN_ALREADY_HAVE : CAN_OBTAIN) : - (CUR_UPG_VALUE(UPG_STICKS) < 3 ? CAN_OBTAIN : CANT_OBTAIN_ALREADY_HAVE); + return infiniteUpgrades != RO_INF_UPGRADES_OFF + ? (Flags_GetRandomizerInf(RAND_INF_HAS_INFINITE_STICK_UPGRADE) ? CANT_OBTAIN_ALREADY_HAVE + : CAN_OBTAIN) + : (CUR_UPG_VALUE(UPG_STICKS) < 3 ? CAN_OBTAIN : CANT_OBTAIN_ALREADY_HAVE); case RG_DEKU_STICK_1: case RG_BUY_DEKU_STICK_1: - return CUR_UPG_VALUE(UPG_STICKS) || !OTRGlobals::Instance->gRandoContext->GetOption(RSK_SHUFFLE_DEKU_STICK_BAG).Get() - ? CAN_OBTAIN : CANT_OBTAIN_NEED_UPGRADE; + return CUR_UPG_VALUE(UPG_STICKS) || + !OTRGlobals::Instance->gRandoContext->GetOption(RSK_SHUFFLE_DEKU_STICK_BAG).Get() + ? CAN_OBTAIN + : CANT_OBTAIN_NEED_UPGRADE; case RG_PROGRESSIVE_NUT_UPGRADE: - return infiniteUpgrades != RO_INF_UPGRADES_OFF ? - (Flags_GetRandomizerInf(RAND_INF_HAS_INFINITE_NUT_UPGRADE) ? CANT_OBTAIN_ALREADY_HAVE : CAN_OBTAIN) : - (CUR_UPG_VALUE(UPG_NUTS) < 3 ? CAN_OBTAIN : CANT_OBTAIN_ALREADY_HAVE); + return infiniteUpgrades != RO_INF_UPGRADES_OFF + ? (Flags_GetRandomizerInf(RAND_INF_HAS_INFINITE_NUT_UPGRADE) ? CANT_OBTAIN_ALREADY_HAVE + : CAN_OBTAIN) + : (CUR_UPG_VALUE(UPG_NUTS) < 3 ? CAN_OBTAIN : CANT_OBTAIN_ALREADY_HAVE); case RG_DEKU_NUTS_5: case RG_DEKU_NUTS_10: case RG_BUY_DEKU_NUTS_5: case RG_BUY_DEKU_NUTS_10: - return CUR_UPG_VALUE(UPG_NUTS) || !OTRGlobals::Instance->gRandoContext->GetOption(RSK_SHUFFLE_DEKU_NUT_BAG).Get() - ? CAN_OBTAIN : CANT_OBTAIN_NEED_UPGRADE; + return CUR_UPG_VALUE(UPG_NUTS) || + !OTRGlobals::Instance->gRandoContext->GetOption(RSK_SHUFFLE_DEKU_NUT_BAG).Get() + ? CAN_OBTAIN + : CANT_OBTAIN_NEED_UPGRADE; case RG_PROGRESSIVE_BOMB_BAG: - return infiniteUpgrades != RO_INF_UPGRADES_OFF ? - (Flags_GetRandomizerInf(RAND_INF_HAS_INFINITE_BOMB_BAG) ? CANT_OBTAIN_ALREADY_HAVE : CAN_OBTAIN) : - (CUR_UPG_VALUE(UPG_BOMB_BAG) < 3 ? CAN_OBTAIN : CANT_OBTAIN_ALREADY_HAVE); + return infiniteUpgrades != RO_INF_UPGRADES_OFF + ? (Flags_GetRandomizerInf(RAND_INF_HAS_INFINITE_BOMB_BAG) ? CANT_OBTAIN_ALREADY_HAVE + : CAN_OBTAIN) + : (CUR_UPG_VALUE(UPG_BOMB_BAG) < 3 ? CAN_OBTAIN : CANT_OBTAIN_ALREADY_HAVE); case RG_BOMBS_5: case RG_BOMBS_10: case RG_BOMBS_20: @@ -502,9 +673,9 @@ ItemObtainability Randomizer::GetItemObtainabilityFromRandomizerGet(RandomizerGe case RG_BUY_BOMBS_30: return CUR_UPG_VALUE(UPG_BOMB_BAG) ? CAN_OBTAIN : CANT_OBTAIN_NEED_UPGRADE; case RG_PROGRESSIVE_BOW: - return infiniteUpgrades != RO_INF_UPGRADES_OFF ? - (Flags_GetRandomizerInf(RAND_INF_HAS_INFINITE_QUIVER) ? CANT_OBTAIN_ALREADY_HAVE : CAN_OBTAIN) : - (CUR_UPG_VALUE(UPG_QUIVER) < 3 ? CAN_OBTAIN : CANT_OBTAIN_ALREADY_HAVE); + return infiniteUpgrades != RO_INF_UPGRADES_OFF + ? (Flags_GetRandomizerInf(RAND_INF_HAS_INFINITE_QUIVER) ? CANT_OBTAIN_ALREADY_HAVE : CAN_OBTAIN) + : (CUR_UPG_VALUE(UPG_QUIVER) < 3 ? CAN_OBTAIN : CANT_OBTAIN_ALREADY_HAVE); case RG_ARROWS_5: case RG_ARROWS_10: case RG_ARROWS_30: @@ -513,9 +684,10 @@ ItemObtainability Randomizer::GetItemObtainabilityFromRandomizerGet(RandomizerGe case RG_BUY_ARROWS_50: return CUR_UPG_VALUE(UPG_QUIVER) ? CAN_OBTAIN : CANT_OBTAIN_NEED_UPGRADE; case RG_PROGRESSIVE_SLINGSHOT: - return infiniteUpgrades != RO_INF_UPGRADES_OFF ? - (Flags_GetRandomizerInf(RAND_INF_HAS_INFINITE_BULLET_BAG) ? CANT_OBTAIN_ALREADY_HAVE : CAN_OBTAIN) : - (CUR_UPG_VALUE(UPG_BULLET_BAG) < 3 ? CAN_OBTAIN : CANT_OBTAIN_ALREADY_HAVE); + return infiniteUpgrades != RO_INF_UPGRADES_OFF + ? (Flags_GetRandomizerInf(RAND_INF_HAS_INFINITE_BULLET_BAG) ? CANT_OBTAIN_ALREADY_HAVE + : CAN_OBTAIN) + : (CUR_UPG_VALUE(UPG_BULLET_BAG) < 3 ? CAN_OBTAIN : CANT_OBTAIN_ALREADY_HAVE); case RG_DEKU_SEEDS_30: case RG_BUY_DEKU_SEEDS_30: return CUR_UPG_VALUE(UPG_BULLET_BAG) ? CAN_OBTAIN : CANT_OBTAIN_NEED_UPGRADE; @@ -533,7 +705,8 @@ ItemObtainability Randomizer::GetItemObtainabilityFromRandomizerGet(RandomizerGe case RG_BOMBCHU_20: case RG_BUY_BOMBCHUS_10: case RG_BUY_BOMBCHUS_20: - case RG_PROGRESSIVE_BOMBCHUS: //RANDOTODO Do we want bombchu refills to exist seperatly from bombchu bags? If so, this needs changing. + case RG_PROGRESSIVE_BOMBCHUS: // RANDOTODO Do we want bombchu refills to exist seperatly from bombchu bags? If + // so, this needs changing. return CAN_OBTAIN; case RG_PROGRESSIVE_HOOKSHOT: switch (INV_CONTENT(ITEM_HOOKSHOT)) { @@ -634,9 +807,10 @@ ItemObtainability Randomizer::GetItemObtainabilityFromRandomizerGet(RandomizerGe case RG_PROGRESSIVE_MAGIC_METER: case RG_MAGIC_SINGLE: case RG_MAGIC_DOUBLE: - return infiniteUpgrades != RO_INF_UPGRADES_OFF ? - (Flags_GetRandomizerInf(RAND_INF_HAS_INFINITE_MAGIC_METER) ? CANT_OBTAIN_ALREADY_HAVE : CAN_OBTAIN) : - (gSaveContext.magicLevel < 2 ? CAN_OBTAIN : CANT_OBTAIN_ALREADY_HAVE); + return infiniteUpgrades != RO_INF_UPGRADES_OFF + ? (Flags_GetRandomizerInf(RAND_INF_HAS_INFINITE_MAGIC_METER) ? CANT_OBTAIN_ALREADY_HAVE + : CAN_OBTAIN) + : (gSaveContext.magicLevel < 2 ? CAN_OBTAIN : CANT_OBTAIN_ALREADY_HAVE); case RG_FISHING_POLE: return !Flags_GetRandomizerInf(RAND_INF_FISHING_POLE_FOUND) ? CAN_OBTAIN : CANT_OBTAIN_ALREADY_HAVE; @@ -704,7 +878,8 @@ ItemObtainability Randomizer::GetItemObtainabilityFromRandomizerGet(RandomizerGe case RG_SHADOW_TEMPLE_COMPASS: return !CHECK_DUNGEON_ITEM(DUNGEON_COMPASS, SCENE_SHADOW_TEMPLE) ? CAN_OBTAIN : CANT_OBTAIN_ALREADY_HAVE; case RG_BOTTOM_OF_THE_WELL_COMPASS: - return !CHECK_DUNGEON_ITEM(DUNGEON_COMPASS, SCENE_BOTTOM_OF_THE_WELL) ? CAN_OBTAIN : CANT_OBTAIN_ALREADY_HAVE; + return !CHECK_DUNGEON_ITEM(DUNGEON_COMPASS, SCENE_BOTTOM_OF_THE_WELL) ? CAN_OBTAIN + : CANT_OBTAIN_ALREADY_HAVE; case RG_ICE_CAVERN_COMPASS: return !CHECK_DUNGEON_ITEM(DUNGEON_COMPASS, SCENE_ICE_CAVERN) ? CAN_OBTAIN : CANT_OBTAIN_ALREADY_HAVE; case RG_FOREST_TEMPLE_BOSS_KEY: @@ -720,25 +895,46 @@ ItemObtainability Randomizer::GetItemObtainabilityFromRandomizerGet(RandomizerGe case RG_GANONS_CASTLE_BOSS_KEY: return !CHECK_DUNGEON_ITEM(DUNGEON_KEY_BOSS, SCENE_GANONS_TOWER) ? CAN_OBTAIN : CANT_OBTAIN_ALREADY_HAVE; case RG_FOREST_TEMPLE_SMALL_KEY: - return gSaveContext.inventory.dungeonKeys[SCENE_FOREST_TEMPLE] < FOREST_TEMPLE_SMALL_KEY_MAX ? CAN_OBTAIN : CANT_OBTAIN_ALREADY_HAVE; + return gSaveContext.inventory.dungeonKeys[SCENE_FOREST_TEMPLE] < FOREST_TEMPLE_SMALL_KEY_MAX + ? CAN_OBTAIN + : CANT_OBTAIN_ALREADY_HAVE; case RG_FIRE_TEMPLE_SMALL_KEY: - return gSaveContext.inventory.dungeonKeys[SCENE_FIRE_TEMPLE] < FIRE_TEMPLE_SMALL_KEY_MAX ? CAN_OBTAIN : CANT_OBTAIN_ALREADY_HAVE; + return gSaveContext.inventory.dungeonKeys[SCENE_FIRE_TEMPLE] < FIRE_TEMPLE_SMALL_KEY_MAX + ? CAN_OBTAIN + : CANT_OBTAIN_ALREADY_HAVE; case RG_WATER_TEMPLE_SMALL_KEY: - return gSaveContext.inventory.dungeonKeys[SCENE_WATER_TEMPLE] < WATER_TEMPLE_SMALL_KEY_MAX ? CAN_OBTAIN : CANT_OBTAIN_ALREADY_HAVE; + return gSaveContext.inventory.dungeonKeys[SCENE_WATER_TEMPLE] < WATER_TEMPLE_SMALL_KEY_MAX + ? CAN_OBTAIN + : CANT_OBTAIN_ALREADY_HAVE; case RG_SPIRIT_TEMPLE_SMALL_KEY: - return gSaveContext.inventory.dungeonKeys[SCENE_SPIRIT_TEMPLE] < SPIRIT_TEMPLE_SMALL_KEY_MAX ? CAN_OBTAIN : CANT_OBTAIN_ALREADY_HAVE; + return gSaveContext.inventory.dungeonKeys[SCENE_SPIRIT_TEMPLE] < SPIRIT_TEMPLE_SMALL_KEY_MAX + ? CAN_OBTAIN + : CANT_OBTAIN_ALREADY_HAVE; case RG_SHADOW_TEMPLE_SMALL_KEY: - return gSaveContext.inventory.dungeonKeys[SCENE_SHADOW_TEMPLE] < SHADOW_TEMPLE_SMALL_KEY_MAX ? CAN_OBTAIN : CANT_OBTAIN_ALREADY_HAVE; + return gSaveContext.inventory.dungeonKeys[SCENE_SHADOW_TEMPLE] < SHADOW_TEMPLE_SMALL_KEY_MAX + ? CAN_OBTAIN + : CANT_OBTAIN_ALREADY_HAVE; case RG_BOTTOM_OF_THE_WELL_SMALL_KEY: - return gSaveContext.inventory.dungeonKeys[SCENE_BOTTOM_OF_THE_WELL] < BOTTOM_OF_THE_WELL_SMALL_KEY_MAX ? CAN_OBTAIN : CANT_OBTAIN_ALREADY_HAVE; + return gSaveContext.inventory.dungeonKeys[SCENE_BOTTOM_OF_THE_WELL] < BOTTOM_OF_THE_WELL_SMALL_KEY_MAX + ? CAN_OBTAIN + : CANT_OBTAIN_ALREADY_HAVE; case RG_GERUDO_TRAINING_GROUND_SMALL_KEY: - return gSaveContext.inventory.dungeonKeys[SCENE_GERUDO_TRAINING_GROUND] < GERUDO_TRAINING_GROUND_SMALL_KEY_MAX ? CAN_OBTAIN : CANT_OBTAIN_ALREADY_HAVE; + return gSaveContext.inventory.dungeonKeys[SCENE_GERUDO_TRAINING_GROUND] < + GERUDO_TRAINING_GROUND_SMALL_KEY_MAX + ? CAN_OBTAIN + : CANT_OBTAIN_ALREADY_HAVE; case RG_GERUDO_FORTRESS_SMALL_KEY: - return gSaveContext.inventory.dungeonKeys[SCENE_THIEVES_HIDEOUT] < GERUDO_FORTRESS_SMALL_KEY_MAX ? CAN_OBTAIN : CANT_OBTAIN_ALREADY_HAVE; + return gSaveContext.inventory.dungeonKeys[SCENE_THIEVES_HIDEOUT] < GERUDO_FORTRESS_SMALL_KEY_MAX + ? CAN_OBTAIN + : CANT_OBTAIN_ALREADY_HAVE; case RG_GANONS_CASTLE_SMALL_KEY: - return gSaveContext.inventory.dungeonKeys[SCENE_INSIDE_GANONS_CASTLE] < GANONS_CASTLE_SMALL_KEY_MAX ? CAN_OBTAIN : CANT_OBTAIN_ALREADY_HAVE; + return gSaveContext.inventory.dungeonKeys[SCENE_INSIDE_GANONS_CASTLE] < GANONS_CASTLE_SMALL_KEY_MAX + ? CAN_OBTAIN + : CANT_OBTAIN_ALREADY_HAVE; case RG_TREASURE_GAME_SMALL_KEY: - return gSaveContext.inventory.dungeonKeys[SCENE_TREASURE_BOX_SHOP] < TREASURE_GAME_SMALL_KEY_MAX ? CAN_OBTAIN : CANT_OBTAIN_ALREADY_HAVE; + return gSaveContext.inventory.dungeonKeys[SCENE_TREASURE_BOX_SHOP] < TREASURE_GAME_SMALL_KEY_MAX + ? CAN_OBTAIN + : CANT_OBTAIN_ALREADY_HAVE; // Dungeon Rewards case RG_KOKIRI_EMERALD: @@ -794,469 +990,474 @@ ItemObtainability Randomizer::GetItemObtainabilityFromRandomizerGet(RandomizerGe // There has been some talk about potentially just using the RC identifier to store flags rather than randomizer inf, so // for now we're not going to store randomzierInf in the randomizer check objects, we're just going to map them 1:1 here std::map rcToRandomizerInf = { - { RC_KF_LINKS_HOUSE_COW, RAND_INF_COWS_MILKED_KF_LINKS_HOUSE_COW }, - { RC_LW_DEKU_SCRUB_NEAR_DEKU_THEATER_RIGHT, RAND_INF_SCRUBS_PURCHASED_LW_DEKU_SCRUB_NEAR_DEKU_THEATER_RIGHT }, - { RC_LW_DEKU_SCRUB_NEAR_DEKU_THEATER_LEFT, RAND_INF_SCRUBS_PURCHASED_LW_DEKU_SCRUB_NEAR_DEKU_THEATER_LEFT }, - { RC_LW_DEKU_SCRUB_NEAR_BRIDGE, RAND_INF_SCRUBS_PURCHASED_LW_DEKU_SCRUB_NEAR_BRIDGE }, - { RC_LW_DEKU_SCRUB_GROTTO_REAR, RAND_INF_SCRUBS_PURCHASED_LW_DEKU_SCRUB_GROTTO_REAR }, - { RC_LW_DEKU_SCRUB_GROTTO_FRONT, RAND_INF_SCRUBS_PURCHASED_LW_DEKU_SCRUB_GROTTO_FRONT }, - { RC_SFM_DEKU_SCRUB_GROTTO_REAR, RAND_INF_SCRUBS_PURCHASED_SFM_DEKU_SCRUB_GROTTO_REAR }, - { RC_SFM_DEKU_SCRUB_GROTTO_FRONT, RAND_INF_SCRUBS_PURCHASED_SFM_DEKU_SCRUB_GROTTO_FRONT }, - { RC_HF_DEKU_SCRUB_GROTTO, RAND_INF_SCRUBS_PURCHASED_HF_DEKU_SCRUB_GROTTO }, - { RC_HF_COW_GROTTO_COW, RAND_INF_COWS_MILKED_HF_COW_GROTTO_COW }, - { RC_LH_DEKU_SCRUB_GROTTO_LEFT, RAND_INF_SCRUBS_PURCHASED_LH_DEKU_SCRUB_GROTTO_LEFT }, - { RC_LH_DEKU_SCRUB_GROTTO_RIGHT, RAND_INF_SCRUBS_PURCHASED_LH_DEKU_SCRUB_GROTTO_RIGHT }, - { RC_LH_DEKU_SCRUB_GROTTO_CENTER, RAND_INF_SCRUBS_PURCHASED_LH_DEKU_SCRUB_GROTTO_CENTER }, - { RC_GV_DEKU_SCRUB_GROTTO_REAR, RAND_INF_SCRUBS_PURCHASED_GV_DEKU_SCRUB_GROTTO_REAR }, - { RC_GV_DEKU_SCRUB_GROTTO_FRONT, RAND_INF_SCRUBS_PURCHASED_GV_DEKU_SCRUB_GROTTO_FRONT }, - { RC_GV_COW, RAND_INF_COWS_MILKED_GV_COW }, - { RC_COLOSSUS_DEKU_SCRUB_GROTTO_REAR, RAND_INF_SCRUBS_PURCHASED_COLOSSUS_DEKU_SCRUB_GROTTO_REAR }, - { RC_COLOSSUS_DEKU_SCRUB_GROTTO_FRONT, RAND_INF_SCRUBS_PURCHASED_COLOSSUS_DEKU_SCRUB_GROTTO_FRONT }, - { RC_KAK_IMPAS_HOUSE_COW, RAND_INF_COWS_MILKED_KAK_IMPAS_HOUSE_COW }, - { RC_DMT_COW_GROTTO_COW, RAND_INF_COWS_MILKED_DMT_COW_GROTTO_COW }, - { RC_GC_DEKU_SCRUB_GROTTO_LEFT, RAND_INF_SCRUBS_PURCHASED_GC_DEKU_SCRUB_GROTTO_LEFT }, - { RC_GC_DEKU_SCRUB_GROTTO_RIGHT, RAND_INF_SCRUBS_PURCHASED_GC_DEKU_SCRUB_GROTTO_RIGHT }, - { RC_GC_DEKU_SCRUB_GROTTO_CENTER, RAND_INF_SCRUBS_PURCHASED_GC_DEKU_SCRUB_GROTTO_CENTER }, - { RC_DMC_DEKU_SCRUB, RAND_INF_SCRUBS_PURCHASED_DMC_DEKU_SCRUB }, - { RC_DMC_DEKU_SCRUB_GROTTO_LEFT, RAND_INF_SCRUBS_PURCHASED_DMC_DEKU_SCRUB_GROTTO_LEFT }, - { RC_DMC_DEKU_SCRUB_GROTTO_RIGHT, RAND_INF_SCRUBS_PURCHASED_DMC_DEKU_SCRUB_GROTTO_RIGHT }, - { RC_DMC_DEKU_SCRUB_GROTTO_CENTER, RAND_INF_SCRUBS_PURCHASED_DMC_DEKU_SCRUB_GROTTO_CENTER }, - { RC_ZR_DEKU_SCRUB_GROTTO_REAR, RAND_INF_SCRUBS_PURCHASED_ZR_DEKU_SCRUB_GROTTO_REAR }, - { RC_ZR_DEKU_SCRUB_GROTTO_FRONT, RAND_INF_SCRUBS_PURCHASED_ZR_DEKU_SCRUB_GROTTO_FRONT }, - { RC_LLR_DEKU_SCRUB_GROTTO_LEFT, RAND_INF_SCRUBS_PURCHASED_LLR_DEKU_SCRUB_GROTTO_LEFT }, - { RC_LLR_DEKU_SCRUB_GROTTO_RIGHT, RAND_INF_SCRUBS_PURCHASED_LLR_DEKU_SCRUB_GROTTO_RIGHT }, - { RC_LLR_DEKU_SCRUB_GROTTO_CENTER, RAND_INF_SCRUBS_PURCHASED_LLR_DEKU_SCRUB_GROTTO_CENTER }, - { RC_LLR_STABLES_LEFT_COW, RAND_INF_COWS_MILKED_LLR_STABLES_LEFT_COW }, - { RC_LLR_STABLES_RIGHT_COW, RAND_INF_COWS_MILKED_LLR_STABLES_RIGHT_COW }, - { RC_LLR_TOWER_LEFT_COW, RAND_INF_COWS_MILKED_LLR_TOWER_LEFT_COW }, - { RC_LLR_TOWER_RIGHT_COW, RAND_INF_COWS_MILKED_LLR_TOWER_RIGHT_COW }, - { RC_DEKU_TREE_MQ_DEKU_SCRUB, RAND_INF_SCRUBS_PURCHASED_DEKU_TREE_MQ_DEKU_SCRUB }, - { RC_DODONGOS_CAVERN_DEKU_SCRUB_NEAR_BOMB_BAG_LEFT, RAND_INF_SCRUBS_PURCHASED_DODONGOS_CAVERN_DEKU_SCRUB_NEAR_BOMB_BAG_LEFT }, - { RC_DODONGOS_CAVERN_DEKU_SCRUB_SIDE_ROOM_NEAR_DODONGOS, RAND_INF_SCRUBS_PURCHASED_DODONGOS_CAVERN_DEKU_SCRUB_SIDE_ROOM_NEAR_DODONGOS }, - { RC_DODONGOS_CAVERN_DEKU_SCRUB_NEAR_BOMB_BAG_RIGHT, RAND_INF_SCRUBS_PURCHASED_DODONGOS_CAVERN_DEKU_SCRUB_NEAR_BOMB_BAG_RIGHT }, - { RC_DODONGOS_CAVERN_DEKU_SCRUB_LOBBY, RAND_INF_SCRUBS_PURCHASED_DODONGOS_CAVERN_DEKU_SCRUB_LOBBY }, - { RC_DODONGOS_CAVERN_MQ_DEKU_SCRUB_LOBBY_REAR, RAND_INF_SCRUBS_PURCHASED_DODONGOS_CAVERN_MQ_DEKU_SCRUB_LOBBY_REAR }, - { RC_DODONGOS_CAVERN_MQ_DEKU_SCRUB_LOBBY_FRONT, RAND_INF_SCRUBS_PURCHASED_DODONGOS_CAVERN_MQ_DEKU_SCRUB_LOBBY_FRONT }, - { RC_DODONGOS_CAVERN_MQ_DEKU_SCRUB_STAIRCASE, RAND_INF_SCRUBS_PURCHASED_DODONGOS_CAVERN_MQ_DEKU_SCRUB_STAIRCASE }, - { RC_DODONGOS_CAVERN_MQ_DEKU_SCRUB_SIDE_ROOM_NEAR_LOWER_LIZALFOS, RAND_INF_SCRUBS_PURCHASED_DODONGOS_CAVERN_MQ_DEKU_SCRUB_SIDE_ROOM_NEAR_LOWER_LIZALFOS }, - { RC_JABU_JABUS_BELLY_DEKU_SCRUB, RAND_INF_SCRUBS_PURCHASED_JABU_JABUS_BELLY_DEKU_SCRUB }, - { RC_JABU_JABUS_BELLY_MQ_COW, RAND_INF_COWS_MILKED_JABU_JABUS_BELLY_MQ_COW }, - { RC_GANONS_CASTLE_DEKU_SCRUB_CENTER_LEFT, RAND_INF_SCRUBS_PURCHASED_GANONS_CASTLE_DEKU_SCRUB_CENTER_LEFT }, - { RC_GANONS_CASTLE_DEKU_SCRUB_CENTER_RIGHT, RAND_INF_SCRUBS_PURCHASED_GANONS_CASTLE_DEKU_SCRUB_CENTER_RIGHT }, - { RC_GANONS_CASTLE_DEKU_SCRUB_RIGHT, RAND_INF_SCRUBS_PURCHASED_GANONS_CASTLE_DEKU_SCRUB_RIGHT }, - { RC_GANONS_CASTLE_DEKU_SCRUB_LEFT, RAND_INF_SCRUBS_PURCHASED_GANONS_CASTLE_DEKU_SCRUB_LEFT }, - { RC_GANONS_CASTLE_MQ_DEKU_SCRUB_RIGHT, RAND_INF_SCRUBS_PURCHASED_GANONS_CASTLE_MQ_DEKU_SCRUB_RIGHT }, - { RC_GANONS_CASTLE_MQ_DEKU_SCRUB_CENTER_LEFT, RAND_INF_SCRUBS_PURCHASED_GANONS_CASTLE_MQ_DEKU_SCRUB_CENTER_LEFT }, - { RC_GANONS_CASTLE_MQ_DEKU_SCRUB_CENTER, RAND_INF_SCRUBS_PURCHASED_GANONS_CASTLE_MQ_DEKU_SCRUB_CENTER }, - { RC_GANONS_CASTLE_MQ_DEKU_SCRUB_CENTER_RIGHT, RAND_INF_SCRUBS_PURCHASED_GANONS_CASTLE_MQ_DEKU_SCRUB_CENTER_RIGHT }, - { RC_GANONS_CASTLE_MQ_DEKU_SCRUB_LEFT, RAND_INF_SCRUBS_PURCHASED_GANONS_CASTLE_MQ_DEKU_SCRUB_LEFT }, - { RC_KF_SHOP_ITEM_1, RAND_INF_SHOP_ITEMS_KF_SHOP_ITEM_1 }, - { RC_KF_SHOP_ITEM_2, RAND_INF_SHOP_ITEMS_KF_SHOP_ITEM_2 }, - { RC_KF_SHOP_ITEM_3, RAND_INF_SHOP_ITEMS_KF_SHOP_ITEM_3 }, - { RC_KF_SHOP_ITEM_4, RAND_INF_SHOP_ITEMS_KF_SHOP_ITEM_4 }, - { RC_KF_SHOP_ITEM_5, RAND_INF_SHOP_ITEMS_KF_SHOP_ITEM_5 }, - { RC_KF_SHOP_ITEM_6, RAND_INF_SHOP_ITEMS_KF_SHOP_ITEM_6 }, - { RC_KF_SHOP_ITEM_7, RAND_INF_SHOP_ITEMS_KF_SHOP_ITEM_7 }, - { RC_KF_SHOP_ITEM_8, RAND_INF_SHOP_ITEMS_KF_SHOP_ITEM_8 }, - { RC_GC_SHOP_ITEM_1, RAND_INF_SHOP_ITEMS_GC_SHOP_ITEM_1 }, - { RC_GC_SHOP_ITEM_2, RAND_INF_SHOP_ITEMS_GC_SHOP_ITEM_2 }, - { RC_GC_SHOP_ITEM_3, RAND_INF_SHOP_ITEMS_GC_SHOP_ITEM_3 }, - { RC_GC_SHOP_ITEM_4, RAND_INF_SHOP_ITEMS_GC_SHOP_ITEM_4 }, - { RC_GC_SHOP_ITEM_5, RAND_INF_SHOP_ITEMS_GC_SHOP_ITEM_5 }, - { RC_GC_SHOP_ITEM_6, RAND_INF_SHOP_ITEMS_GC_SHOP_ITEM_6 }, - { RC_GC_SHOP_ITEM_7, RAND_INF_SHOP_ITEMS_GC_SHOP_ITEM_7 }, - { RC_GC_SHOP_ITEM_8, RAND_INF_SHOP_ITEMS_GC_SHOP_ITEM_8 }, - { RC_ZD_SHOP_ITEM_1, RAND_INF_SHOP_ITEMS_ZD_SHOP_ITEM_1 }, - { RC_ZD_SHOP_ITEM_2, RAND_INF_SHOP_ITEMS_ZD_SHOP_ITEM_2 }, - { RC_ZD_SHOP_ITEM_3, RAND_INF_SHOP_ITEMS_ZD_SHOP_ITEM_3 }, - { RC_ZD_SHOP_ITEM_4, RAND_INF_SHOP_ITEMS_ZD_SHOP_ITEM_4 }, - { RC_ZD_SHOP_ITEM_5, RAND_INF_SHOP_ITEMS_ZD_SHOP_ITEM_5 }, - { RC_ZD_SHOP_ITEM_6, RAND_INF_SHOP_ITEMS_ZD_SHOP_ITEM_6 }, - { RC_ZD_SHOP_ITEM_7, RAND_INF_SHOP_ITEMS_ZD_SHOP_ITEM_7 }, - { RC_ZD_SHOP_ITEM_8, RAND_INF_SHOP_ITEMS_ZD_SHOP_ITEM_8 }, - { RC_KAK_BAZAAR_ITEM_1, RAND_INF_SHOP_ITEMS_KAK_BAZAAR_ITEM_1 }, - { RC_KAK_BAZAAR_ITEM_2, RAND_INF_SHOP_ITEMS_KAK_BAZAAR_ITEM_2 }, - { RC_KAK_BAZAAR_ITEM_3, RAND_INF_SHOP_ITEMS_KAK_BAZAAR_ITEM_3 }, - { RC_KAK_BAZAAR_ITEM_4, RAND_INF_SHOP_ITEMS_KAK_BAZAAR_ITEM_4 }, - { RC_KAK_BAZAAR_ITEM_5, RAND_INF_SHOP_ITEMS_KAK_BAZAAR_ITEM_5 }, - { RC_KAK_BAZAAR_ITEM_6, RAND_INF_SHOP_ITEMS_KAK_BAZAAR_ITEM_6 }, - { RC_KAK_BAZAAR_ITEM_7, RAND_INF_SHOP_ITEMS_KAK_BAZAAR_ITEM_7 }, - { RC_KAK_BAZAAR_ITEM_8, RAND_INF_SHOP_ITEMS_KAK_BAZAAR_ITEM_8 }, - { RC_KAK_POTION_SHOP_ITEM_1, RAND_INF_SHOP_ITEMS_KAK_POTION_SHOP_ITEM_1 }, - { RC_KAK_POTION_SHOP_ITEM_2, RAND_INF_SHOP_ITEMS_KAK_POTION_SHOP_ITEM_2 }, - { RC_KAK_POTION_SHOP_ITEM_3, RAND_INF_SHOP_ITEMS_KAK_POTION_SHOP_ITEM_3 }, - { RC_KAK_POTION_SHOP_ITEM_4, RAND_INF_SHOP_ITEMS_KAK_POTION_SHOP_ITEM_4 }, - { RC_KAK_POTION_SHOP_ITEM_5, RAND_INF_SHOP_ITEMS_KAK_POTION_SHOP_ITEM_5 }, - { RC_KAK_POTION_SHOP_ITEM_6, RAND_INF_SHOP_ITEMS_KAK_POTION_SHOP_ITEM_6 }, - { RC_KAK_POTION_SHOP_ITEM_7, RAND_INF_SHOP_ITEMS_KAK_POTION_SHOP_ITEM_7 }, - { RC_KAK_POTION_SHOP_ITEM_8, RAND_INF_SHOP_ITEMS_KAK_POTION_SHOP_ITEM_8 }, - { RC_MARKET_BAZAAR_ITEM_1, RAND_INF_SHOP_ITEMS_MARKET_BAZAAR_ITEM_1 }, - { RC_MARKET_BAZAAR_ITEM_2, RAND_INF_SHOP_ITEMS_MARKET_BAZAAR_ITEM_2 }, - { RC_MARKET_BAZAAR_ITEM_3, RAND_INF_SHOP_ITEMS_MARKET_BAZAAR_ITEM_3 }, - { RC_MARKET_BAZAAR_ITEM_4, RAND_INF_SHOP_ITEMS_MARKET_BAZAAR_ITEM_4 }, - { RC_MARKET_BAZAAR_ITEM_5, RAND_INF_SHOP_ITEMS_MARKET_BAZAAR_ITEM_5 }, - { RC_MARKET_BAZAAR_ITEM_6, RAND_INF_SHOP_ITEMS_MARKET_BAZAAR_ITEM_6 }, - { RC_MARKET_BAZAAR_ITEM_7, RAND_INF_SHOP_ITEMS_MARKET_BAZAAR_ITEM_7 }, - { RC_MARKET_BAZAAR_ITEM_8, RAND_INF_SHOP_ITEMS_MARKET_BAZAAR_ITEM_8 }, - { RC_MARKET_POTION_SHOP_ITEM_1, RAND_INF_SHOP_ITEMS_MARKET_POTION_SHOP_ITEM_1 }, - { RC_MARKET_POTION_SHOP_ITEM_2, RAND_INF_SHOP_ITEMS_MARKET_POTION_SHOP_ITEM_2 }, - { RC_MARKET_POTION_SHOP_ITEM_3, RAND_INF_SHOP_ITEMS_MARKET_POTION_SHOP_ITEM_3 }, - { RC_MARKET_POTION_SHOP_ITEM_4, RAND_INF_SHOP_ITEMS_MARKET_POTION_SHOP_ITEM_4 }, - { RC_MARKET_POTION_SHOP_ITEM_5, RAND_INF_SHOP_ITEMS_MARKET_POTION_SHOP_ITEM_5 }, - { RC_MARKET_POTION_SHOP_ITEM_6, RAND_INF_SHOP_ITEMS_MARKET_POTION_SHOP_ITEM_6 }, - { RC_MARKET_POTION_SHOP_ITEM_7, RAND_INF_SHOP_ITEMS_MARKET_POTION_SHOP_ITEM_7 }, - { RC_MARKET_POTION_SHOP_ITEM_8, RAND_INF_SHOP_ITEMS_MARKET_POTION_SHOP_ITEM_8 }, - { RC_MARKET_BOMBCHU_SHOP_ITEM_1, RAND_INF_SHOP_ITEMS_MARKET_BOMBCHU_SHOP_ITEM_1 }, - { RC_MARKET_BOMBCHU_SHOP_ITEM_2, RAND_INF_SHOP_ITEMS_MARKET_BOMBCHU_SHOP_ITEM_2 }, - { RC_MARKET_BOMBCHU_SHOP_ITEM_3, RAND_INF_SHOP_ITEMS_MARKET_BOMBCHU_SHOP_ITEM_3 }, - { RC_MARKET_BOMBCHU_SHOP_ITEM_4, RAND_INF_SHOP_ITEMS_MARKET_BOMBCHU_SHOP_ITEM_4 }, - { RC_MARKET_BOMBCHU_SHOP_ITEM_5, RAND_INF_SHOP_ITEMS_MARKET_BOMBCHU_SHOP_ITEM_5 }, - { RC_MARKET_BOMBCHU_SHOP_ITEM_6, RAND_INF_SHOP_ITEMS_MARKET_BOMBCHU_SHOP_ITEM_6 }, - { RC_MARKET_BOMBCHU_SHOP_ITEM_7, RAND_INF_SHOP_ITEMS_MARKET_BOMBCHU_SHOP_ITEM_7 }, - { RC_MARKET_BOMBCHU_SHOP_ITEM_8, RAND_INF_SHOP_ITEMS_MARKET_BOMBCHU_SHOP_ITEM_8 }, - { RC_TOT_MASTER_SWORD, RAND_INF_TOT_MASTER_SWORD }, - { RC_GC_MEDIGORON, RAND_INF_MERCHANTS_MEDIGORON }, - { RC_KAK_GRANNYS_SHOP, RAND_INF_MERCHANTS_GRANNYS_SHOP }, - { RC_WASTELAND_BOMBCHU_SALESMAN, RAND_INF_MERCHANTS_CARPET_SALESMAN }, - { RC_ZR_MAGIC_BEAN_SALESMAN, RAND_INF_MERCHANTS_MAGIC_BEAN_SALESMAN }, - { RC_LW_TRADE_COJIRO, RAND_INF_ADULT_TRADES_LW_TRADE_COJIRO }, - { RC_GV_TRADE_SAW, RAND_INF_ADULT_TRADES_GV_TRADE_SAW }, - { RC_DMT_TRADE_BROKEN_SWORD, RAND_INF_ADULT_TRADES_DMT_TRADE_BROKEN_SWORD }, - { RC_LH_TRADE_FROG, RAND_INF_ADULT_TRADES_LH_TRADE_FROG }, - { RC_DMT_TRADE_EYEDROPS, RAND_INF_ADULT_TRADES_DMT_TRADE_EYEDROPS }, - { RC_LH_CHILD_FISHING, RAND_INF_CHILD_FISHING }, - { RC_LH_ADULT_FISHING, RAND_INF_ADULT_FISHING }, - { RC_MARKET_10_BIG_POES, RAND_INF_10_BIG_POES }, - { RC_KAK_100_GOLD_SKULLTULA_REWARD, RAND_INF_KAK_100_GOLD_SKULLTULA_REWARD }, - { RC_KF_STORMS_GROTTO_BEEHIVE_LEFT, RAND_INF_BEEHIVE_KF_STORMS_GROTTO_LEFT }, - { RC_KF_STORMS_GROTTO_BEEHIVE_RIGHT, RAND_INF_BEEHIVE_KF_STORMS_GROTTO_RIGHT }, - { RC_LW_NEAR_SHORTCUTS_GROTTO_BEEHIVE_LEFT, RAND_INF_BEEHIVE_LW_NEAR_SHORTCUTS_GROTTO_LEFT }, - { RC_LW_NEAR_SHORTCUTS_GROTTO_BEEHIVE_RIGHT, RAND_INF_BEEHIVE_LW_NEAR_SHORTCUTS_GROTTO_RIGHT }, - { RC_LW_DEKU_SCRUB_GROTTO_BEEHIVE, RAND_INF_BEEHIVE_LW_DEKU_SCRUB_GROTTO }, - { RC_SFM_STORMS_GROTTO_BEEHIVE, RAND_INF_BEEHIVE_SFM_STORMS_GROTTO }, - { RC_HF_NEAR_MARKET_GROTTO_BEEHIVE_LEFT, RAND_INF_BEEHIVE_HF_NEAR_MARKET_GROTTO_LEFT }, - { RC_HF_NEAR_MARKET_GROTTO_BEEHIVE_RIGHT, RAND_INF_BEEHIVE_HF_NEAR_MARKET_GROTTO_RIGHT }, - { RC_HF_OPEN_GROTTO_BEEHIVE_LEFT, RAND_INF_BEEHIVE_HF_OPEN_GROTTO_LEFT }, - { RC_HF_OPEN_GROTTO_BEEHIVE_RIGHT, RAND_INF_BEEHIVE_HF_OPEN_GROTTO_RIGHT }, - { RC_HF_SOUTHEAST_GROTTO_BEEHIVE_LEFT, RAND_INF_BEEHIVE_HF_SOUTHEAST_GROTTO_LEFT }, - { RC_HF_SOUTHEAST_GROTTO_BEEHIVE_RIGHT, RAND_INF_BEEHIVE_HF_SOUTHEAST_GROTTO_RIGHT }, - { RC_HF_INSIDE_FENCE_GROTTO_BEEHIVE, RAND_INF_BEEHIVE_HF_INSIDE_FENCE_GROTTO }, - { RC_LLR_GROTTO_BEEHIVE, RAND_INF_BEEHIVE_LLR_GROTTO }, - { RC_KAK_OPEN_GROTTO_BEEHIVE_LEFT, RAND_INF_BEEHIVE_KAK_OPEN_GROTTO_LEFT }, - { RC_KAK_OPEN_GROTTO_BEEHIVE_RIGHT, RAND_INF_BEEHIVE_KAK_OPEN_GROTTO_RIGHT }, - { RC_DMT_COW_GROTTO_BEEHIVE, RAND_INF_BEEHIVE_DMT_COW_GROTTO }, - { RC_DMT_STORMS_GROTTO_BEEHIVE_LEFT, RAND_INF_BEEHIVE_DMT_STORMS_GROTTO_LEFT }, - { RC_DMT_STORMS_GROTTO_BEEHIVE_RIGHT, RAND_INF_BEEHIVE_DMT_STORMS_GROTTO_RIGHT }, - { RC_GC_GROTTO_BEEHIVE, RAND_INF_BEEHIVE_GC_GROTTO }, - { RC_DMC_UPPER_GROTTO_BEEHIVE_LEFT, RAND_INF_BEEHIVE_DMC_UPPER_GROTTO_LEFT }, - { RC_DMC_UPPER_GROTTO_BEEHIVE_RIGHT, RAND_INF_BEEHIVE_DMC_UPPER_GROTTO_RIGHT }, - { RC_DMC_HAMMER_GROTTO_BEEHIVE, RAND_INF_BEEHIVE_DMC_HAMMER_GROTTO }, - { RC_ZR_OPEN_GROTTO_BEEHIVE_LEFT, RAND_INF_BEEHIVE_ZR_OPEN_GROTTO_LEFT }, - { RC_ZR_OPEN_GROTTO_BEEHIVE_RIGHT, RAND_INF_BEEHIVE_ZR_OPEN_GROTTO_RIGHT }, - { RC_ZR_STORMS_GROTTO_BEEHIVE, RAND_INF_BEEHIVE_ZR_STORMS_GROTTO }, - { RC_ZD_IN_FRONT_OF_KING_ZORA_BEEHIVE_LEFT, RAND_INF_BEEHIVE_ZD_IN_FRONT_OF_KING_ZORA_LEFT }, - { RC_ZD_IN_FRONT_OF_KING_ZORA_BEEHIVE_RIGHT, RAND_INF_BEEHIVE_ZD_IN_FRONT_OF_KING_ZORA_RIGHT }, - { RC_ZD_BEHIND_KING_ZORA_BEEHIVE, RAND_INF_BEEHIVE_ZD_BEHIND_KING_ZORA }, - { RC_LH_GROTTO_BEEHIVE, RAND_INF_BEEHIVE_LH_GROTTO }, - { RC_GV_DEKU_SCRUB_GROTTO_BEEHIVE, RAND_INF_BEEHIVE_GV_DEKU_SCRUB_GROTTO }, - { RC_COLOSSUS_GROTTO_BEEHIVE, RAND_INF_BEEHIVE_COLOSSUS_GROTTO }, - { RC_LH_CHILD_FISH_1, RAND_INF_CHILD_FISH_1 }, - { RC_LH_CHILD_FISH_2, RAND_INF_CHILD_FISH_2 }, - { RC_LH_CHILD_FISH_3, RAND_INF_CHILD_FISH_3 }, - { RC_LH_CHILD_FISH_4, RAND_INF_CHILD_FISH_4 }, - { RC_LH_CHILD_FISH_5, RAND_INF_CHILD_FISH_5 }, - { RC_LH_CHILD_FISH_6, RAND_INF_CHILD_FISH_6 }, - { RC_LH_CHILD_FISH_7, RAND_INF_CHILD_FISH_7 }, - { RC_LH_CHILD_FISH_8, RAND_INF_CHILD_FISH_8 }, - { RC_LH_CHILD_FISH_9, RAND_INF_CHILD_FISH_9 }, - { RC_LH_CHILD_FISH_10, RAND_INF_CHILD_FISH_10 }, - { RC_LH_CHILD_FISH_11, RAND_INF_CHILD_FISH_11 }, - { RC_LH_CHILD_FISH_12, RAND_INF_CHILD_FISH_12 }, - { RC_LH_CHILD_FISH_13, RAND_INF_CHILD_FISH_13 }, - { RC_LH_CHILD_FISH_14, RAND_INF_CHILD_FISH_14 }, - { RC_LH_CHILD_FISH_15, RAND_INF_CHILD_FISH_15 }, - { RC_LH_CHILD_LOACH_1, RAND_INF_CHILD_LOACH_1 }, - { RC_LH_CHILD_LOACH_2, RAND_INF_CHILD_LOACH_2 }, - { RC_LH_ADULT_FISH_1, RAND_INF_ADULT_FISH_1 }, - { RC_LH_ADULT_FISH_2, RAND_INF_ADULT_FISH_2 }, - { RC_LH_ADULT_FISH_3, RAND_INF_ADULT_FISH_3 }, - { RC_LH_ADULT_FISH_4, RAND_INF_ADULT_FISH_4 }, - { RC_LH_ADULT_FISH_5, RAND_INF_ADULT_FISH_5 }, - { RC_LH_ADULT_FISH_6, RAND_INF_ADULT_FISH_6 }, - { RC_LH_ADULT_FISH_7, RAND_INF_ADULT_FISH_7 }, - { RC_LH_ADULT_FISH_8, RAND_INF_ADULT_FISH_8 }, - { RC_LH_ADULT_FISH_9, RAND_INF_ADULT_FISH_9 }, - { RC_LH_ADULT_FISH_10, RAND_INF_ADULT_FISH_10 }, - { RC_LH_ADULT_FISH_11, RAND_INF_ADULT_FISH_11 }, - { RC_LH_ADULT_FISH_12, RAND_INF_ADULT_FISH_12 }, - { RC_LH_ADULT_FISH_13, RAND_INF_ADULT_FISH_13 }, - { RC_LH_ADULT_FISH_14, RAND_INF_ADULT_FISH_14 }, - { RC_LH_ADULT_FISH_15, RAND_INF_ADULT_FISH_15 }, - { RC_LH_ADULT_LOACH, RAND_INF_ADULT_LOACH }, - { RC_ZR_OPEN_GROTTO_FISH, RAND_INF_GROTTO_FISH_ZR_OPEN_GROTTO }, - { RC_DMC_UPPER_GROTTO_FISH, RAND_INF_GROTTO_FISH_DMC_UPPER_GROTTO }, - { RC_DMT_STORMS_GROTTO_FISH, RAND_INF_GROTTO_FISH_DMT_STORMS_GROTTO }, - { RC_KAK_OPEN_GROTTO_FISH, RAND_INF_GROTTO_FISH_KAK_OPEN_GROTTO }, - { RC_HF_NEAR_MARKET_GROTTO_FISH, RAND_INF_GROTTO_FISH_HF_NEAR_MARKET_GROTTO }, - { RC_HF_OPEN_GROTTO_FISH, RAND_INF_GROTTO_FISH_HF_OPEN_GROTTO }, - { RC_HF_SOUTHEAST_GROTTO_FISH, RAND_INF_GROTTO_FISH_HF_SOUTHEAST_GROTTO }, - { RC_LW_NEAR_SHORTCUTS_GROTTO_FISH, RAND_INF_GROTTO_FISH_LW_NEAR_SHORTCUTS_GROTTO }, - { RC_KF_STORMS_GROTTO_FISH, RAND_INF_GROTTO_FISH_KF_STORMS_GROTTO }, - { RC_ZD_FISH_1, RAND_INF_ZD_FISH_1 }, - { RC_ZD_FISH_2, RAND_INF_ZD_FISH_2 }, - { RC_ZD_FISH_3, RAND_INF_ZD_FISH_3 }, - { RC_ZD_FISH_4, RAND_INF_ZD_FISH_4 }, - { RC_ZD_FISH_5, RAND_INF_ZD_FISH_5 }, + { RC_KF_LINKS_HOUSE_COW, RAND_INF_COWS_MILKED_KF_LINKS_HOUSE_COW }, + { RC_LW_DEKU_SCRUB_NEAR_DEKU_THEATER_RIGHT, RAND_INF_SCRUBS_PURCHASED_LW_DEKU_SCRUB_NEAR_DEKU_THEATER_RIGHT }, + { RC_LW_DEKU_SCRUB_NEAR_DEKU_THEATER_LEFT, RAND_INF_SCRUBS_PURCHASED_LW_DEKU_SCRUB_NEAR_DEKU_THEATER_LEFT }, + { RC_LW_DEKU_SCRUB_NEAR_BRIDGE, RAND_INF_SCRUBS_PURCHASED_LW_DEKU_SCRUB_NEAR_BRIDGE }, + { RC_LW_DEKU_SCRUB_GROTTO_REAR, RAND_INF_SCRUBS_PURCHASED_LW_DEKU_SCRUB_GROTTO_REAR }, + { RC_LW_DEKU_SCRUB_GROTTO_FRONT, RAND_INF_SCRUBS_PURCHASED_LW_DEKU_SCRUB_GROTTO_FRONT }, + { RC_SFM_DEKU_SCRUB_GROTTO_REAR, RAND_INF_SCRUBS_PURCHASED_SFM_DEKU_SCRUB_GROTTO_REAR }, + { RC_SFM_DEKU_SCRUB_GROTTO_FRONT, RAND_INF_SCRUBS_PURCHASED_SFM_DEKU_SCRUB_GROTTO_FRONT }, + { RC_HF_DEKU_SCRUB_GROTTO, RAND_INF_SCRUBS_PURCHASED_HF_DEKU_SCRUB_GROTTO }, + { RC_HF_COW_GROTTO_COW, RAND_INF_COWS_MILKED_HF_COW_GROTTO_COW }, + { RC_LH_DEKU_SCRUB_GROTTO_LEFT, RAND_INF_SCRUBS_PURCHASED_LH_DEKU_SCRUB_GROTTO_LEFT }, + { RC_LH_DEKU_SCRUB_GROTTO_RIGHT, RAND_INF_SCRUBS_PURCHASED_LH_DEKU_SCRUB_GROTTO_RIGHT }, + { RC_LH_DEKU_SCRUB_GROTTO_CENTER, RAND_INF_SCRUBS_PURCHASED_LH_DEKU_SCRUB_GROTTO_CENTER }, + { RC_GV_DEKU_SCRUB_GROTTO_REAR, RAND_INF_SCRUBS_PURCHASED_GV_DEKU_SCRUB_GROTTO_REAR }, + { RC_GV_DEKU_SCRUB_GROTTO_FRONT, RAND_INF_SCRUBS_PURCHASED_GV_DEKU_SCRUB_GROTTO_FRONT }, + { RC_GV_COW, RAND_INF_COWS_MILKED_GV_COW }, + { RC_COLOSSUS_DEKU_SCRUB_GROTTO_REAR, RAND_INF_SCRUBS_PURCHASED_COLOSSUS_DEKU_SCRUB_GROTTO_REAR }, + { RC_COLOSSUS_DEKU_SCRUB_GROTTO_FRONT, RAND_INF_SCRUBS_PURCHASED_COLOSSUS_DEKU_SCRUB_GROTTO_FRONT }, + { RC_KAK_IMPAS_HOUSE_COW, RAND_INF_COWS_MILKED_KAK_IMPAS_HOUSE_COW }, + { RC_DMT_COW_GROTTO_COW, RAND_INF_COWS_MILKED_DMT_COW_GROTTO_COW }, + { RC_GC_DEKU_SCRUB_GROTTO_LEFT, RAND_INF_SCRUBS_PURCHASED_GC_DEKU_SCRUB_GROTTO_LEFT }, + { RC_GC_DEKU_SCRUB_GROTTO_RIGHT, RAND_INF_SCRUBS_PURCHASED_GC_DEKU_SCRUB_GROTTO_RIGHT }, + { RC_GC_DEKU_SCRUB_GROTTO_CENTER, RAND_INF_SCRUBS_PURCHASED_GC_DEKU_SCRUB_GROTTO_CENTER }, + { RC_DMC_DEKU_SCRUB, RAND_INF_SCRUBS_PURCHASED_DMC_DEKU_SCRUB }, + { RC_DMC_DEKU_SCRUB_GROTTO_LEFT, RAND_INF_SCRUBS_PURCHASED_DMC_DEKU_SCRUB_GROTTO_LEFT }, + { RC_DMC_DEKU_SCRUB_GROTTO_RIGHT, RAND_INF_SCRUBS_PURCHASED_DMC_DEKU_SCRUB_GROTTO_RIGHT }, + { RC_DMC_DEKU_SCRUB_GROTTO_CENTER, RAND_INF_SCRUBS_PURCHASED_DMC_DEKU_SCRUB_GROTTO_CENTER }, + { RC_ZR_DEKU_SCRUB_GROTTO_REAR, RAND_INF_SCRUBS_PURCHASED_ZR_DEKU_SCRUB_GROTTO_REAR }, + { RC_ZR_DEKU_SCRUB_GROTTO_FRONT, RAND_INF_SCRUBS_PURCHASED_ZR_DEKU_SCRUB_GROTTO_FRONT }, + { RC_LLR_DEKU_SCRUB_GROTTO_LEFT, RAND_INF_SCRUBS_PURCHASED_LLR_DEKU_SCRUB_GROTTO_LEFT }, + { RC_LLR_DEKU_SCRUB_GROTTO_RIGHT, RAND_INF_SCRUBS_PURCHASED_LLR_DEKU_SCRUB_GROTTO_RIGHT }, + { RC_LLR_DEKU_SCRUB_GROTTO_CENTER, RAND_INF_SCRUBS_PURCHASED_LLR_DEKU_SCRUB_GROTTO_CENTER }, + { RC_LLR_STABLES_LEFT_COW, RAND_INF_COWS_MILKED_LLR_STABLES_LEFT_COW }, + { RC_LLR_STABLES_RIGHT_COW, RAND_INF_COWS_MILKED_LLR_STABLES_RIGHT_COW }, + { RC_LLR_TOWER_LEFT_COW, RAND_INF_COWS_MILKED_LLR_TOWER_LEFT_COW }, + { RC_LLR_TOWER_RIGHT_COW, RAND_INF_COWS_MILKED_LLR_TOWER_RIGHT_COW }, + { RC_DEKU_TREE_MQ_DEKU_SCRUB, RAND_INF_SCRUBS_PURCHASED_DEKU_TREE_MQ_DEKU_SCRUB }, + { RC_DODONGOS_CAVERN_DEKU_SCRUB_NEAR_BOMB_BAG_LEFT, + RAND_INF_SCRUBS_PURCHASED_DODONGOS_CAVERN_DEKU_SCRUB_NEAR_BOMB_BAG_LEFT }, + { RC_DODONGOS_CAVERN_DEKU_SCRUB_SIDE_ROOM_NEAR_DODONGOS, + RAND_INF_SCRUBS_PURCHASED_DODONGOS_CAVERN_DEKU_SCRUB_SIDE_ROOM_NEAR_DODONGOS }, + { RC_DODONGOS_CAVERN_DEKU_SCRUB_NEAR_BOMB_BAG_RIGHT, + RAND_INF_SCRUBS_PURCHASED_DODONGOS_CAVERN_DEKU_SCRUB_NEAR_BOMB_BAG_RIGHT }, + { RC_DODONGOS_CAVERN_DEKU_SCRUB_LOBBY, RAND_INF_SCRUBS_PURCHASED_DODONGOS_CAVERN_DEKU_SCRUB_LOBBY }, + { RC_DODONGOS_CAVERN_MQ_DEKU_SCRUB_LOBBY_REAR, RAND_INF_SCRUBS_PURCHASED_DODONGOS_CAVERN_MQ_DEKU_SCRUB_LOBBY_REAR }, + { RC_DODONGOS_CAVERN_MQ_DEKU_SCRUB_LOBBY_FRONT, + RAND_INF_SCRUBS_PURCHASED_DODONGOS_CAVERN_MQ_DEKU_SCRUB_LOBBY_FRONT }, + { RC_DODONGOS_CAVERN_MQ_DEKU_SCRUB_STAIRCASE, RAND_INF_SCRUBS_PURCHASED_DODONGOS_CAVERN_MQ_DEKU_SCRUB_STAIRCASE }, + { RC_DODONGOS_CAVERN_MQ_DEKU_SCRUB_SIDE_ROOM_NEAR_LOWER_LIZALFOS, + RAND_INF_SCRUBS_PURCHASED_DODONGOS_CAVERN_MQ_DEKU_SCRUB_SIDE_ROOM_NEAR_LOWER_LIZALFOS }, + { RC_JABU_JABUS_BELLY_DEKU_SCRUB, RAND_INF_SCRUBS_PURCHASED_JABU_JABUS_BELLY_DEKU_SCRUB }, + { RC_JABU_JABUS_BELLY_MQ_COW, RAND_INF_COWS_MILKED_JABU_JABUS_BELLY_MQ_COW }, + { RC_GANONS_CASTLE_DEKU_SCRUB_CENTER_LEFT, RAND_INF_SCRUBS_PURCHASED_GANONS_CASTLE_DEKU_SCRUB_CENTER_LEFT }, + { RC_GANONS_CASTLE_DEKU_SCRUB_CENTER_RIGHT, RAND_INF_SCRUBS_PURCHASED_GANONS_CASTLE_DEKU_SCRUB_CENTER_RIGHT }, + { RC_GANONS_CASTLE_DEKU_SCRUB_RIGHT, RAND_INF_SCRUBS_PURCHASED_GANONS_CASTLE_DEKU_SCRUB_RIGHT }, + { RC_GANONS_CASTLE_DEKU_SCRUB_LEFT, RAND_INF_SCRUBS_PURCHASED_GANONS_CASTLE_DEKU_SCRUB_LEFT }, + { RC_GANONS_CASTLE_MQ_DEKU_SCRUB_RIGHT, RAND_INF_SCRUBS_PURCHASED_GANONS_CASTLE_MQ_DEKU_SCRUB_RIGHT }, + { RC_GANONS_CASTLE_MQ_DEKU_SCRUB_CENTER_LEFT, RAND_INF_SCRUBS_PURCHASED_GANONS_CASTLE_MQ_DEKU_SCRUB_CENTER_LEFT }, + { RC_GANONS_CASTLE_MQ_DEKU_SCRUB_CENTER, RAND_INF_SCRUBS_PURCHASED_GANONS_CASTLE_MQ_DEKU_SCRUB_CENTER }, + { RC_GANONS_CASTLE_MQ_DEKU_SCRUB_CENTER_RIGHT, RAND_INF_SCRUBS_PURCHASED_GANONS_CASTLE_MQ_DEKU_SCRUB_CENTER_RIGHT }, + { RC_GANONS_CASTLE_MQ_DEKU_SCRUB_LEFT, RAND_INF_SCRUBS_PURCHASED_GANONS_CASTLE_MQ_DEKU_SCRUB_LEFT }, + { RC_KF_SHOP_ITEM_1, RAND_INF_SHOP_ITEMS_KF_SHOP_ITEM_1 }, + { RC_KF_SHOP_ITEM_2, RAND_INF_SHOP_ITEMS_KF_SHOP_ITEM_2 }, + { RC_KF_SHOP_ITEM_3, RAND_INF_SHOP_ITEMS_KF_SHOP_ITEM_3 }, + { RC_KF_SHOP_ITEM_4, RAND_INF_SHOP_ITEMS_KF_SHOP_ITEM_4 }, + { RC_KF_SHOP_ITEM_5, RAND_INF_SHOP_ITEMS_KF_SHOP_ITEM_5 }, + { RC_KF_SHOP_ITEM_6, RAND_INF_SHOP_ITEMS_KF_SHOP_ITEM_6 }, + { RC_KF_SHOP_ITEM_7, RAND_INF_SHOP_ITEMS_KF_SHOP_ITEM_7 }, + { RC_KF_SHOP_ITEM_8, RAND_INF_SHOP_ITEMS_KF_SHOP_ITEM_8 }, + { RC_GC_SHOP_ITEM_1, RAND_INF_SHOP_ITEMS_GC_SHOP_ITEM_1 }, + { RC_GC_SHOP_ITEM_2, RAND_INF_SHOP_ITEMS_GC_SHOP_ITEM_2 }, + { RC_GC_SHOP_ITEM_3, RAND_INF_SHOP_ITEMS_GC_SHOP_ITEM_3 }, + { RC_GC_SHOP_ITEM_4, RAND_INF_SHOP_ITEMS_GC_SHOP_ITEM_4 }, + { RC_GC_SHOP_ITEM_5, RAND_INF_SHOP_ITEMS_GC_SHOP_ITEM_5 }, + { RC_GC_SHOP_ITEM_6, RAND_INF_SHOP_ITEMS_GC_SHOP_ITEM_6 }, + { RC_GC_SHOP_ITEM_7, RAND_INF_SHOP_ITEMS_GC_SHOP_ITEM_7 }, + { RC_GC_SHOP_ITEM_8, RAND_INF_SHOP_ITEMS_GC_SHOP_ITEM_8 }, + { RC_ZD_SHOP_ITEM_1, RAND_INF_SHOP_ITEMS_ZD_SHOP_ITEM_1 }, + { RC_ZD_SHOP_ITEM_2, RAND_INF_SHOP_ITEMS_ZD_SHOP_ITEM_2 }, + { RC_ZD_SHOP_ITEM_3, RAND_INF_SHOP_ITEMS_ZD_SHOP_ITEM_3 }, + { RC_ZD_SHOP_ITEM_4, RAND_INF_SHOP_ITEMS_ZD_SHOP_ITEM_4 }, + { RC_ZD_SHOP_ITEM_5, RAND_INF_SHOP_ITEMS_ZD_SHOP_ITEM_5 }, + { RC_ZD_SHOP_ITEM_6, RAND_INF_SHOP_ITEMS_ZD_SHOP_ITEM_6 }, + { RC_ZD_SHOP_ITEM_7, RAND_INF_SHOP_ITEMS_ZD_SHOP_ITEM_7 }, + { RC_ZD_SHOP_ITEM_8, RAND_INF_SHOP_ITEMS_ZD_SHOP_ITEM_8 }, + { RC_KAK_BAZAAR_ITEM_1, RAND_INF_SHOP_ITEMS_KAK_BAZAAR_ITEM_1 }, + { RC_KAK_BAZAAR_ITEM_2, RAND_INF_SHOP_ITEMS_KAK_BAZAAR_ITEM_2 }, + { RC_KAK_BAZAAR_ITEM_3, RAND_INF_SHOP_ITEMS_KAK_BAZAAR_ITEM_3 }, + { RC_KAK_BAZAAR_ITEM_4, RAND_INF_SHOP_ITEMS_KAK_BAZAAR_ITEM_4 }, + { RC_KAK_BAZAAR_ITEM_5, RAND_INF_SHOP_ITEMS_KAK_BAZAAR_ITEM_5 }, + { RC_KAK_BAZAAR_ITEM_6, RAND_INF_SHOP_ITEMS_KAK_BAZAAR_ITEM_6 }, + { RC_KAK_BAZAAR_ITEM_7, RAND_INF_SHOP_ITEMS_KAK_BAZAAR_ITEM_7 }, + { RC_KAK_BAZAAR_ITEM_8, RAND_INF_SHOP_ITEMS_KAK_BAZAAR_ITEM_8 }, + { RC_KAK_POTION_SHOP_ITEM_1, RAND_INF_SHOP_ITEMS_KAK_POTION_SHOP_ITEM_1 }, + { RC_KAK_POTION_SHOP_ITEM_2, RAND_INF_SHOP_ITEMS_KAK_POTION_SHOP_ITEM_2 }, + { RC_KAK_POTION_SHOP_ITEM_3, RAND_INF_SHOP_ITEMS_KAK_POTION_SHOP_ITEM_3 }, + { RC_KAK_POTION_SHOP_ITEM_4, RAND_INF_SHOP_ITEMS_KAK_POTION_SHOP_ITEM_4 }, + { RC_KAK_POTION_SHOP_ITEM_5, RAND_INF_SHOP_ITEMS_KAK_POTION_SHOP_ITEM_5 }, + { RC_KAK_POTION_SHOP_ITEM_6, RAND_INF_SHOP_ITEMS_KAK_POTION_SHOP_ITEM_6 }, + { RC_KAK_POTION_SHOP_ITEM_7, RAND_INF_SHOP_ITEMS_KAK_POTION_SHOP_ITEM_7 }, + { RC_KAK_POTION_SHOP_ITEM_8, RAND_INF_SHOP_ITEMS_KAK_POTION_SHOP_ITEM_8 }, + { RC_MARKET_BAZAAR_ITEM_1, RAND_INF_SHOP_ITEMS_MARKET_BAZAAR_ITEM_1 }, + { RC_MARKET_BAZAAR_ITEM_2, RAND_INF_SHOP_ITEMS_MARKET_BAZAAR_ITEM_2 }, + { RC_MARKET_BAZAAR_ITEM_3, RAND_INF_SHOP_ITEMS_MARKET_BAZAAR_ITEM_3 }, + { RC_MARKET_BAZAAR_ITEM_4, RAND_INF_SHOP_ITEMS_MARKET_BAZAAR_ITEM_4 }, + { RC_MARKET_BAZAAR_ITEM_5, RAND_INF_SHOP_ITEMS_MARKET_BAZAAR_ITEM_5 }, + { RC_MARKET_BAZAAR_ITEM_6, RAND_INF_SHOP_ITEMS_MARKET_BAZAAR_ITEM_6 }, + { RC_MARKET_BAZAAR_ITEM_7, RAND_INF_SHOP_ITEMS_MARKET_BAZAAR_ITEM_7 }, + { RC_MARKET_BAZAAR_ITEM_8, RAND_INF_SHOP_ITEMS_MARKET_BAZAAR_ITEM_8 }, + { RC_MARKET_POTION_SHOP_ITEM_1, RAND_INF_SHOP_ITEMS_MARKET_POTION_SHOP_ITEM_1 }, + { RC_MARKET_POTION_SHOP_ITEM_2, RAND_INF_SHOP_ITEMS_MARKET_POTION_SHOP_ITEM_2 }, + { RC_MARKET_POTION_SHOP_ITEM_3, RAND_INF_SHOP_ITEMS_MARKET_POTION_SHOP_ITEM_3 }, + { RC_MARKET_POTION_SHOP_ITEM_4, RAND_INF_SHOP_ITEMS_MARKET_POTION_SHOP_ITEM_4 }, + { RC_MARKET_POTION_SHOP_ITEM_5, RAND_INF_SHOP_ITEMS_MARKET_POTION_SHOP_ITEM_5 }, + { RC_MARKET_POTION_SHOP_ITEM_6, RAND_INF_SHOP_ITEMS_MARKET_POTION_SHOP_ITEM_6 }, + { RC_MARKET_POTION_SHOP_ITEM_7, RAND_INF_SHOP_ITEMS_MARKET_POTION_SHOP_ITEM_7 }, + { RC_MARKET_POTION_SHOP_ITEM_8, RAND_INF_SHOP_ITEMS_MARKET_POTION_SHOP_ITEM_8 }, + { RC_MARKET_BOMBCHU_SHOP_ITEM_1, RAND_INF_SHOP_ITEMS_MARKET_BOMBCHU_SHOP_ITEM_1 }, + { RC_MARKET_BOMBCHU_SHOP_ITEM_2, RAND_INF_SHOP_ITEMS_MARKET_BOMBCHU_SHOP_ITEM_2 }, + { RC_MARKET_BOMBCHU_SHOP_ITEM_3, RAND_INF_SHOP_ITEMS_MARKET_BOMBCHU_SHOP_ITEM_3 }, + { RC_MARKET_BOMBCHU_SHOP_ITEM_4, RAND_INF_SHOP_ITEMS_MARKET_BOMBCHU_SHOP_ITEM_4 }, + { RC_MARKET_BOMBCHU_SHOP_ITEM_5, RAND_INF_SHOP_ITEMS_MARKET_BOMBCHU_SHOP_ITEM_5 }, + { RC_MARKET_BOMBCHU_SHOP_ITEM_6, RAND_INF_SHOP_ITEMS_MARKET_BOMBCHU_SHOP_ITEM_6 }, + { RC_MARKET_BOMBCHU_SHOP_ITEM_7, RAND_INF_SHOP_ITEMS_MARKET_BOMBCHU_SHOP_ITEM_7 }, + { RC_MARKET_BOMBCHU_SHOP_ITEM_8, RAND_INF_SHOP_ITEMS_MARKET_BOMBCHU_SHOP_ITEM_8 }, + { RC_TOT_MASTER_SWORD, RAND_INF_TOT_MASTER_SWORD }, + { RC_GC_MEDIGORON, RAND_INF_MERCHANTS_MEDIGORON }, + { RC_KAK_GRANNYS_SHOP, RAND_INF_MERCHANTS_GRANNYS_SHOP }, + { RC_WASTELAND_BOMBCHU_SALESMAN, RAND_INF_MERCHANTS_CARPET_SALESMAN }, + { RC_ZR_MAGIC_BEAN_SALESMAN, RAND_INF_MERCHANTS_MAGIC_BEAN_SALESMAN }, + { RC_LW_TRADE_COJIRO, RAND_INF_ADULT_TRADES_LW_TRADE_COJIRO }, + { RC_GV_TRADE_SAW, RAND_INF_ADULT_TRADES_GV_TRADE_SAW }, + { RC_DMT_TRADE_BROKEN_SWORD, RAND_INF_ADULT_TRADES_DMT_TRADE_BROKEN_SWORD }, + { RC_LH_TRADE_FROG, RAND_INF_ADULT_TRADES_LH_TRADE_FROG }, + { RC_DMT_TRADE_EYEDROPS, RAND_INF_ADULT_TRADES_DMT_TRADE_EYEDROPS }, + { RC_LH_CHILD_FISHING, RAND_INF_CHILD_FISHING }, + { RC_LH_ADULT_FISHING, RAND_INF_ADULT_FISHING }, + { RC_MARKET_10_BIG_POES, RAND_INF_10_BIG_POES }, + { RC_KAK_100_GOLD_SKULLTULA_REWARD, RAND_INF_KAK_100_GOLD_SKULLTULA_REWARD }, + { RC_KF_STORMS_GROTTO_BEEHIVE_LEFT, RAND_INF_BEEHIVE_KF_STORMS_GROTTO_LEFT }, + { RC_KF_STORMS_GROTTO_BEEHIVE_RIGHT, RAND_INF_BEEHIVE_KF_STORMS_GROTTO_RIGHT }, + { RC_LW_NEAR_SHORTCUTS_GROTTO_BEEHIVE_LEFT, RAND_INF_BEEHIVE_LW_NEAR_SHORTCUTS_GROTTO_LEFT }, + { RC_LW_NEAR_SHORTCUTS_GROTTO_BEEHIVE_RIGHT, RAND_INF_BEEHIVE_LW_NEAR_SHORTCUTS_GROTTO_RIGHT }, + { RC_LW_DEKU_SCRUB_GROTTO_BEEHIVE, RAND_INF_BEEHIVE_LW_DEKU_SCRUB_GROTTO }, + { RC_SFM_STORMS_GROTTO_BEEHIVE, RAND_INF_BEEHIVE_SFM_STORMS_GROTTO }, + { RC_HF_NEAR_MARKET_GROTTO_BEEHIVE_LEFT, RAND_INF_BEEHIVE_HF_NEAR_MARKET_GROTTO_LEFT }, + { RC_HF_NEAR_MARKET_GROTTO_BEEHIVE_RIGHT, RAND_INF_BEEHIVE_HF_NEAR_MARKET_GROTTO_RIGHT }, + { RC_HF_OPEN_GROTTO_BEEHIVE_LEFT, RAND_INF_BEEHIVE_HF_OPEN_GROTTO_LEFT }, + { RC_HF_OPEN_GROTTO_BEEHIVE_RIGHT, RAND_INF_BEEHIVE_HF_OPEN_GROTTO_RIGHT }, + { RC_HF_SOUTHEAST_GROTTO_BEEHIVE_LEFT, RAND_INF_BEEHIVE_HF_SOUTHEAST_GROTTO_LEFT }, + { RC_HF_SOUTHEAST_GROTTO_BEEHIVE_RIGHT, RAND_INF_BEEHIVE_HF_SOUTHEAST_GROTTO_RIGHT }, + { RC_HF_INSIDE_FENCE_GROTTO_BEEHIVE, RAND_INF_BEEHIVE_HF_INSIDE_FENCE_GROTTO }, + { RC_LLR_GROTTO_BEEHIVE, RAND_INF_BEEHIVE_LLR_GROTTO }, + { RC_KAK_OPEN_GROTTO_BEEHIVE_LEFT, RAND_INF_BEEHIVE_KAK_OPEN_GROTTO_LEFT }, + { RC_KAK_OPEN_GROTTO_BEEHIVE_RIGHT, RAND_INF_BEEHIVE_KAK_OPEN_GROTTO_RIGHT }, + { RC_DMT_COW_GROTTO_BEEHIVE, RAND_INF_BEEHIVE_DMT_COW_GROTTO }, + { RC_DMT_STORMS_GROTTO_BEEHIVE_LEFT, RAND_INF_BEEHIVE_DMT_STORMS_GROTTO_LEFT }, + { RC_DMT_STORMS_GROTTO_BEEHIVE_RIGHT, RAND_INF_BEEHIVE_DMT_STORMS_GROTTO_RIGHT }, + { RC_GC_GROTTO_BEEHIVE, RAND_INF_BEEHIVE_GC_GROTTO }, + { RC_DMC_UPPER_GROTTO_BEEHIVE_LEFT, RAND_INF_BEEHIVE_DMC_UPPER_GROTTO_LEFT }, + { RC_DMC_UPPER_GROTTO_BEEHIVE_RIGHT, RAND_INF_BEEHIVE_DMC_UPPER_GROTTO_RIGHT }, + { RC_DMC_HAMMER_GROTTO_BEEHIVE, RAND_INF_BEEHIVE_DMC_HAMMER_GROTTO }, + { RC_ZR_OPEN_GROTTO_BEEHIVE_LEFT, RAND_INF_BEEHIVE_ZR_OPEN_GROTTO_LEFT }, + { RC_ZR_OPEN_GROTTO_BEEHIVE_RIGHT, RAND_INF_BEEHIVE_ZR_OPEN_GROTTO_RIGHT }, + { RC_ZR_STORMS_GROTTO_BEEHIVE, RAND_INF_BEEHIVE_ZR_STORMS_GROTTO }, + { RC_ZD_IN_FRONT_OF_KING_ZORA_BEEHIVE_LEFT, RAND_INF_BEEHIVE_ZD_IN_FRONT_OF_KING_ZORA_LEFT }, + { RC_ZD_IN_FRONT_OF_KING_ZORA_BEEHIVE_RIGHT, RAND_INF_BEEHIVE_ZD_IN_FRONT_OF_KING_ZORA_RIGHT }, + { RC_ZD_BEHIND_KING_ZORA_BEEHIVE, RAND_INF_BEEHIVE_ZD_BEHIND_KING_ZORA }, + { RC_LH_GROTTO_BEEHIVE, RAND_INF_BEEHIVE_LH_GROTTO }, + { RC_GV_DEKU_SCRUB_GROTTO_BEEHIVE, RAND_INF_BEEHIVE_GV_DEKU_SCRUB_GROTTO }, + { RC_COLOSSUS_GROTTO_BEEHIVE, RAND_INF_BEEHIVE_COLOSSUS_GROTTO }, + { RC_LH_CHILD_FISH_1, RAND_INF_CHILD_FISH_1 }, + { RC_LH_CHILD_FISH_2, RAND_INF_CHILD_FISH_2 }, + { RC_LH_CHILD_FISH_3, RAND_INF_CHILD_FISH_3 }, + { RC_LH_CHILD_FISH_4, RAND_INF_CHILD_FISH_4 }, + { RC_LH_CHILD_FISH_5, RAND_INF_CHILD_FISH_5 }, + { RC_LH_CHILD_FISH_6, RAND_INF_CHILD_FISH_6 }, + { RC_LH_CHILD_FISH_7, RAND_INF_CHILD_FISH_7 }, + { RC_LH_CHILD_FISH_8, RAND_INF_CHILD_FISH_8 }, + { RC_LH_CHILD_FISH_9, RAND_INF_CHILD_FISH_9 }, + { RC_LH_CHILD_FISH_10, RAND_INF_CHILD_FISH_10 }, + { RC_LH_CHILD_FISH_11, RAND_INF_CHILD_FISH_11 }, + { RC_LH_CHILD_FISH_12, RAND_INF_CHILD_FISH_12 }, + { RC_LH_CHILD_FISH_13, RAND_INF_CHILD_FISH_13 }, + { RC_LH_CHILD_FISH_14, RAND_INF_CHILD_FISH_14 }, + { RC_LH_CHILD_FISH_15, RAND_INF_CHILD_FISH_15 }, + { RC_LH_CHILD_LOACH_1, RAND_INF_CHILD_LOACH_1 }, + { RC_LH_CHILD_LOACH_2, RAND_INF_CHILD_LOACH_2 }, + { RC_LH_ADULT_FISH_1, RAND_INF_ADULT_FISH_1 }, + { RC_LH_ADULT_FISH_2, RAND_INF_ADULT_FISH_2 }, + { RC_LH_ADULT_FISH_3, RAND_INF_ADULT_FISH_3 }, + { RC_LH_ADULT_FISH_4, RAND_INF_ADULT_FISH_4 }, + { RC_LH_ADULT_FISH_5, RAND_INF_ADULT_FISH_5 }, + { RC_LH_ADULT_FISH_6, RAND_INF_ADULT_FISH_6 }, + { RC_LH_ADULT_FISH_7, RAND_INF_ADULT_FISH_7 }, + { RC_LH_ADULT_FISH_8, RAND_INF_ADULT_FISH_8 }, + { RC_LH_ADULT_FISH_9, RAND_INF_ADULT_FISH_9 }, + { RC_LH_ADULT_FISH_10, RAND_INF_ADULT_FISH_10 }, + { RC_LH_ADULT_FISH_11, RAND_INF_ADULT_FISH_11 }, + { RC_LH_ADULT_FISH_12, RAND_INF_ADULT_FISH_12 }, + { RC_LH_ADULT_FISH_13, RAND_INF_ADULT_FISH_13 }, + { RC_LH_ADULT_FISH_14, RAND_INF_ADULT_FISH_14 }, + { RC_LH_ADULT_FISH_15, RAND_INF_ADULT_FISH_15 }, + { RC_LH_ADULT_LOACH, RAND_INF_ADULT_LOACH }, + { RC_ZR_OPEN_GROTTO_FISH, RAND_INF_GROTTO_FISH_ZR_OPEN_GROTTO }, + { RC_DMC_UPPER_GROTTO_FISH, RAND_INF_GROTTO_FISH_DMC_UPPER_GROTTO }, + { RC_DMT_STORMS_GROTTO_FISH, RAND_INF_GROTTO_FISH_DMT_STORMS_GROTTO }, + { RC_KAK_OPEN_GROTTO_FISH, RAND_INF_GROTTO_FISH_KAK_OPEN_GROTTO }, + { RC_HF_NEAR_MARKET_GROTTO_FISH, RAND_INF_GROTTO_FISH_HF_NEAR_MARKET_GROTTO }, + { RC_HF_OPEN_GROTTO_FISH, RAND_INF_GROTTO_FISH_HF_OPEN_GROTTO }, + { RC_HF_SOUTHEAST_GROTTO_FISH, RAND_INF_GROTTO_FISH_HF_SOUTHEAST_GROTTO }, + { RC_LW_NEAR_SHORTCUTS_GROTTO_FISH, RAND_INF_GROTTO_FISH_LW_NEAR_SHORTCUTS_GROTTO }, + { RC_KF_STORMS_GROTTO_FISH, RAND_INF_GROTTO_FISH_KF_STORMS_GROTTO }, + { RC_ZD_FISH_1, RAND_INF_ZD_FISH_1 }, + { RC_ZD_FISH_2, RAND_INF_ZD_FISH_2 }, + { RC_ZD_FISH_3, RAND_INF_ZD_FISH_3 }, + { RC_ZD_FISH_4, RAND_INF_ZD_FISH_4 }, + { RC_ZD_FISH_5, RAND_INF_ZD_FISH_5 }, // Grass - { RC_KF_CHILD_GRASS_1, RAND_INF_KF_CHILD_GRASS_1 }, - { RC_KF_CHILD_GRASS_2, RAND_INF_KF_CHILD_GRASS_2 }, - { RC_KF_CHILD_GRASS_3, RAND_INF_KF_CHILD_GRASS_3 }, - { RC_KF_CHILD_GRASS_4, RAND_INF_KF_CHILD_GRASS_4 }, - { RC_KF_CHILD_GRASS_5, RAND_INF_KF_CHILD_GRASS_5 }, - { RC_KF_CHILD_GRASS_6, RAND_INF_KF_CHILD_GRASS_6 }, - { RC_KF_CHILD_GRASS_7, RAND_INF_KF_CHILD_GRASS_7 }, - { RC_KF_CHILD_GRASS_8, RAND_INF_KF_CHILD_GRASS_8 }, - { RC_KF_CHILD_GRASS_9, RAND_INF_KF_CHILD_GRASS_9 }, - { RC_KF_CHILD_GRASS_10, RAND_INF_KF_CHILD_GRASS_10 }, - { RC_KF_CHILD_GRASS_11, RAND_INF_KF_CHILD_GRASS_11 }, - { RC_KF_CHILD_GRASS_12, RAND_INF_KF_CHILD_GRASS_12 }, - { RC_KF_CHILD_GRASS_MAZE_1, RAND_INF_KF_CHILD_GRASS_MAZE_1 }, - { RC_KF_CHILD_GRASS_MAZE_2, RAND_INF_KF_CHILD_GRASS_MAZE_2 }, - { RC_KF_CHILD_GRASS_MAZE_3, RAND_INF_KF_CHILD_GRASS_MAZE_3 }, - { RC_KF_ADULT_GRASS_1, RAND_INF_KF_ADULT_GRASS_1 }, - { RC_KF_ADULT_GRASS_2, RAND_INF_KF_ADULT_GRASS_2 }, - { RC_KF_ADULT_GRASS_3, RAND_INF_KF_ADULT_GRASS_3 }, - { RC_KF_ADULT_GRASS_4, RAND_INF_KF_ADULT_GRASS_4 }, - { RC_KF_ADULT_GRASS_5, RAND_INF_KF_ADULT_GRASS_5 }, - { RC_KF_ADULT_GRASS_6, RAND_INF_KF_ADULT_GRASS_6 }, - { RC_KF_ADULT_GRASS_7, RAND_INF_KF_ADULT_GRASS_7 }, - { RC_KF_ADULT_GRASS_8, RAND_INF_KF_ADULT_GRASS_8 }, - { RC_KF_ADULT_GRASS_9, RAND_INF_KF_ADULT_GRASS_9 }, - { RC_KF_ADULT_GRASS_10, RAND_INF_KF_ADULT_GRASS_10 }, - { RC_KF_ADULT_GRASS_11, RAND_INF_KF_ADULT_GRASS_11 }, - { RC_KF_ADULT_GRASS_12, RAND_INF_KF_ADULT_GRASS_12 }, - { RC_KF_ADULT_GRASS_13, RAND_INF_KF_ADULT_GRASS_13 }, - { RC_KF_ADULT_GRASS_14, RAND_INF_KF_ADULT_GRASS_14 }, - { RC_KF_ADULT_GRASS_15, RAND_INF_KF_ADULT_GRASS_15 }, - { RC_KF_ADULT_GRASS_16, RAND_INF_KF_ADULT_GRASS_16 }, - { RC_KF_ADULT_GRASS_17, RAND_INF_KF_ADULT_GRASS_17 }, - { RC_KF_ADULT_GRASS_18, RAND_INF_KF_ADULT_GRASS_18 }, - { RC_KF_ADULT_GRASS_19, RAND_INF_KF_ADULT_GRASS_19 }, - { RC_KF_ADULT_GRASS_20, RAND_INF_KF_ADULT_GRASS_20 }, - { RC_LW_GRASS_1, RAND_INF_LW_GRASS_1 }, - { RC_LW_GRASS_2, RAND_INF_LW_GRASS_2 }, - { RC_LW_GRASS_3, RAND_INF_LW_GRASS_3 }, - { RC_LW_GRASS_4, RAND_INF_LW_GRASS_4 }, - { RC_LW_GRASS_5, RAND_INF_LW_GRASS_5 }, - { RC_LW_GRASS_6, RAND_INF_LW_GRASS_6 }, - { RC_LW_GRASS_7, RAND_INF_LW_GRASS_7 }, - { RC_LW_GRASS_8, RAND_INF_LW_GRASS_8 }, - { RC_LW_GRASS_9, RAND_INF_LW_GRASS_9 }, - { RC_MARKET_GRASS_1, RAND_INF_MARKET_GRASS_1 }, - { RC_MARKET_GRASS_2, RAND_INF_MARKET_GRASS_2 }, - { RC_MARKET_GRASS_3, RAND_INF_MARKET_GRASS_3 }, - { RC_MARKET_GRASS_4, RAND_INF_MARKET_GRASS_4 }, - { RC_MARKET_GRASS_5, RAND_INF_MARKET_GRASS_5 }, - { RC_MARKET_GRASS_6, RAND_INF_MARKET_GRASS_6 }, - { RC_MARKET_GRASS_7, RAND_INF_MARKET_GRASS_7 }, - { RC_MARKET_GRASS_8, RAND_INF_MARKET_GRASS_8 }, - { RC_HC_GRASS_1, RAND_INF_HC_GRASS_1 }, - { RC_HC_GRASS_2, RAND_INF_HC_GRASS_2 }, - { RC_KAK_GRASS_1, RAND_INF_KAK_GRASS_1 }, - { RC_KAK_GRASS_2, RAND_INF_KAK_GRASS_2 }, - { RC_KAK_GRASS_3, RAND_INF_KAK_GRASS_3 }, - { RC_KAK_GRASS_4, RAND_INF_KAK_GRASS_4 }, - { RC_KAK_GRASS_5, RAND_INF_KAK_GRASS_5 }, - { RC_KAK_GRASS_6, RAND_INF_KAK_GRASS_6 }, - { RC_KAK_GRASS_7, RAND_INF_KAK_GRASS_7 }, - { RC_KAK_GRASS_8, RAND_INF_KAK_GRASS_8 }, - { RC_GY_GRASS_1, RAND_INF_GY_GRASS_1 }, - { RC_GY_GRASS_2, RAND_INF_GY_GRASS_2 }, - { RC_GY_GRASS_3, RAND_INF_GY_GRASS_3 }, - { RC_GY_GRASS_4, RAND_INF_GY_GRASS_4 }, - { RC_GY_GRASS_5, RAND_INF_GY_GRASS_5 }, - { RC_GY_GRASS_6, RAND_INF_GY_GRASS_6 }, - { RC_GY_GRASS_7, RAND_INF_GY_GRASS_7 }, - { RC_GY_GRASS_8, RAND_INF_GY_GRASS_8 }, - { RC_GY_GRASS_9, RAND_INF_GY_GRASS_9 }, - { RC_GY_GRASS_10, RAND_INF_GY_GRASS_10 }, - { RC_GY_GRASS_11, RAND_INF_GY_GRASS_11 }, - { RC_GY_GRASS_12, RAND_INF_GY_GRASS_12 }, - { RC_LH_GRASS_1, RAND_INF_LH_GRASS_1 }, - { RC_LH_GRASS_2, RAND_INF_LH_GRASS_2 }, - { RC_LH_GRASS_3, RAND_INF_LH_GRASS_3 }, - { RC_LH_GRASS_4, RAND_INF_LH_GRASS_4 }, - { RC_LH_GRASS_5, RAND_INF_LH_GRASS_5 }, - { RC_LH_GRASS_6, RAND_INF_LH_GRASS_6 }, - { RC_LH_GRASS_7, RAND_INF_LH_GRASS_7 }, - { RC_LH_GRASS_8, RAND_INF_LH_GRASS_8 }, - { RC_LH_GRASS_9, RAND_INF_LH_GRASS_9 }, - { RC_LH_GRASS_10, RAND_INF_LH_GRASS_10 }, - { RC_LH_GRASS_11, RAND_INF_LH_GRASS_11 }, - { RC_LH_GRASS_12, RAND_INF_LH_GRASS_12 }, - { RC_LH_GRASS_13, RAND_INF_LH_GRASS_13 }, - { RC_LH_GRASS_14, RAND_INF_LH_GRASS_14 }, - { RC_LH_GRASS_15, RAND_INF_LH_GRASS_15 }, - { RC_LH_GRASS_16, RAND_INF_LH_GRASS_16 }, - { RC_LH_GRASS_17, RAND_INF_LH_GRASS_17 }, - { RC_LH_GRASS_18, RAND_INF_LH_GRASS_18 }, - { RC_LH_GRASS_19, RAND_INF_LH_GRASS_19 }, - { RC_LH_GRASS_20, RAND_INF_LH_GRASS_20 }, - { RC_LH_GRASS_21, RAND_INF_LH_GRASS_21 }, - { RC_LH_GRASS_22, RAND_INF_LH_GRASS_22 }, - { RC_LH_GRASS_23, RAND_INF_LH_GRASS_23 }, - { RC_LH_GRASS_24, RAND_INF_LH_GRASS_24 }, - { RC_LH_GRASS_25, RAND_INF_LH_GRASS_25 }, - { RC_LH_GRASS_26, RAND_INF_LH_GRASS_26 }, - { RC_LH_GRASS_27, RAND_INF_LH_GRASS_27 }, - { RC_LH_GRASS_28, RAND_INF_LH_GRASS_28 }, - { RC_LH_GRASS_29, RAND_INF_LH_GRASS_29 }, - { RC_LH_GRASS_30, RAND_INF_LH_GRASS_30 }, - { RC_LH_GRASS_31, RAND_INF_LH_GRASS_31 }, - { RC_LH_GRASS_32, RAND_INF_LH_GRASS_32 }, - { RC_LH_GRASS_33, RAND_INF_LH_GRASS_33 }, - { RC_LH_GRASS_34, RAND_INF_LH_GRASS_34 }, - { RC_LH_GRASS_35, RAND_INF_LH_GRASS_35 }, - { RC_LH_GRASS_36, RAND_INF_LH_GRASS_36 }, - { RC_LH_CHILD_GRASS_1, RAND_INF_LH_CHILD_GRASS_1 }, - { RC_LH_CHILD_GRASS_2, RAND_INF_LH_CHILD_GRASS_2 }, - { RC_LH_CHILD_GRASS_3, RAND_INF_LH_CHILD_GRASS_3 }, - { RC_LH_CHILD_GRASS_4, RAND_INF_LH_CHILD_GRASS_4 }, - { RC_LH_WARP_PAD_GRASS_1, RAND_INF_LH_WARP_PAD_GRASS_1 }, - { RC_LH_WARP_PAD_GRASS_2, RAND_INF_LH_WARP_PAD_GRASS_2 }, - { RC_HF_NEAR_KF_GRASS_1, RAND_INF_HF_NEAR_KF_GRASS_1 }, - { RC_HF_NEAR_KF_GRASS_2, RAND_INF_HF_NEAR_KF_GRASS_2 }, - { RC_HF_NEAR_KF_GRASS_3, RAND_INF_HF_NEAR_KF_GRASS_3 }, - { RC_HF_NEAR_KF_GRASS_4, RAND_INF_HF_NEAR_KF_GRASS_4 }, - { RC_HF_NEAR_KF_GRASS_5, RAND_INF_HF_NEAR_KF_GRASS_5 }, - { RC_HF_NEAR_KF_GRASS_6, RAND_INF_HF_NEAR_KF_GRASS_6 }, - { RC_HF_NEAR_KF_GRASS_7, RAND_INF_HF_NEAR_KF_GRASS_7 }, - { RC_HF_NEAR_KF_GRASS_8, RAND_INF_HF_NEAR_KF_GRASS_8 }, - { RC_HF_NEAR_KF_GRASS_9, RAND_INF_HF_NEAR_KF_GRASS_9 }, - { RC_HF_NEAR_KF_GRASS_10, RAND_INF_HF_NEAR_KF_GRASS_10 }, - { RC_HF_NEAR_KF_GRASS_11, RAND_INF_HF_NEAR_KF_GRASS_11 }, - { RC_HF_NEAR_KF_GRASS_12, RAND_INF_HF_NEAR_KF_GRASS_12 }, - { RC_HF_NEAR_MARKET_GRASS_1, RAND_INF_HF_NEAR_MARKET_GRASS_1 }, - { RC_HF_NEAR_MARKET_GRASS_2, RAND_INF_HF_NEAR_MARKET_GRASS_2 }, - { RC_HF_NEAR_MARKET_GRASS_3, RAND_INF_HF_NEAR_MARKET_GRASS_3 }, - { RC_HF_NEAR_MARKET_GRASS_4, RAND_INF_HF_NEAR_MARKET_GRASS_4 }, - { RC_HF_NEAR_MARKET_GRASS_5, RAND_INF_HF_NEAR_MARKET_GRASS_5 }, - { RC_HF_NEAR_MARKET_GRASS_6, RAND_INF_HF_NEAR_MARKET_GRASS_6 }, - { RC_HF_NEAR_MARKET_GRASS_7, RAND_INF_HF_NEAR_MARKET_GRASS_7 }, - { RC_HF_NEAR_MARKET_GRASS_8, RAND_INF_HF_NEAR_MARKET_GRASS_8 }, - { RC_HF_NEAR_MARKET_GRASS_9, RAND_INF_HF_NEAR_MARKET_GRASS_9 }, - { RC_HF_NEAR_MARKET_GRASS_10, RAND_INF_HF_NEAR_MARKET_GRASS_10 }, - { RC_HF_NEAR_MARKET_GRASS_11, RAND_INF_HF_NEAR_MARKET_GRASS_11 }, - { RC_HF_NEAR_MARKET_GRASS_12, RAND_INF_HF_NEAR_MARKET_GRASS_12 }, - { RC_HF_SOUTH_GRASS_1, RAND_INF_HF_SOUTH_GRASS_1 }, - { RC_HF_SOUTH_GRASS_2, RAND_INF_HF_SOUTH_GRASS_2 }, - { RC_HF_SOUTH_GRASS_3, RAND_INF_HF_SOUTH_GRASS_3 }, - { RC_HF_SOUTH_GRASS_4, RAND_INF_HF_SOUTH_GRASS_4 }, - { RC_HF_SOUTH_GRASS_5, RAND_INF_HF_SOUTH_GRASS_5 }, - { RC_HF_SOUTH_GRASS_6, RAND_INF_HF_SOUTH_GRASS_6 }, - { RC_HF_SOUTH_GRASS_7, RAND_INF_HF_SOUTH_GRASS_7 }, - { RC_HF_SOUTH_GRASS_8, RAND_INF_HF_SOUTH_GRASS_8 }, - { RC_HF_SOUTH_GRASS_9, RAND_INF_HF_SOUTH_GRASS_9 }, - { RC_HF_SOUTH_GRASS_10, RAND_INF_HF_SOUTH_GRASS_10 }, - { RC_HF_SOUTH_GRASS_11, RAND_INF_HF_SOUTH_GRASS_11 }, - { RC_HF_SOUTH_GRASS_12, RAND_INF_HF_SOUTH_GRASS_12 }, - { RC_HF_CENTRAL_GRASS_1, RAND_INF_HF_CENTRAL_GRASS_1 }, - { RC_HF_CENTRAL_GRASS_2, RAND_INF_HF_CENTRAL_GRASS_2 }, - { RC_HF_CENTRAL_GRASS_3, RAND_INF_HF_CENTRAL_GRASS_3 }, - { RC_HF_CENTRAL_GRASS_4, RAND_INF_HF_CENTRAL_GRASS_4 }, - { RC_HF_CENTRAL_GRASS_5, RAND_INF_HF_CENTRAL_GRASS_5 }, - { RC_HF_CENTRAL_GRASS_6, RAND_INF_HF_CENTRAL_GRASS_6 }, - { RC_HF_CENTRAL_GRASS_7, RAND_INF_HF_CENTRAL_GRASS_7 }, - { RC_HF_CENTRAL_GRASS_8, RAND_INF_HF_CENTRAL_GRASS_8 }, - { RC_HF_CENTRAL_GRASS_9, RAND_INF_HF_CENTRAL_GRASS_9 }, - { RC_HF_CENTRAL_GRASS_10, RAND_INF_HF_CENTRAL_GRASS_10 }, - { RC_HF_CENTRAL_GRASS_11, RAND_INF_HF_CENTRAL_GRASS_11 }, - { RC_HF_CENTRAL_GRASS_12, RAND_INF_HF_CENTRAL_GRASS_12 }, - { RC_ZR_GRASS_1, RAND_INF_ZR_GRASS_1 }, - { RC_ZR_GRASS_2, RAND_INF_ZR_GRASS_2 }, - { RC_ZR_GRASS_3, RAND_INF_ZR_GRASS_3 }, - { RC_ZR_GRASS_4, RAND_INF_ZR_GRASS_4 }, - { RC_ZR_GRASS_5, RAND_INF_ZR_GRASS_5 }, - { RC_ZR_GRASS_6, RAND_INF_ZR_GRASS_6 }, - { RC_ZR_GRASS_7, RAND_INF_ZR_GRASS_7 }, - { RC_ZR_GRASS_8, RAND_INF_ZR_GRASS_8 }, - { RC_ZR_GRASS_9, RAND_INF_ZR_GRASS_9 }, - { RC_ZR_GRASS_10, RAND_INF_ZR_GRASS_10 }, - { RC_ZR_GRASS_11, RAND_INF_ZR_GRASS_11 }, - { RC_ZR_GRASS_12, RAND_INF_ZR_GRASS_12 }, - { RC_ZR_NEAR_FREESTANDING_POH_GRASS, RAND_INF_ZR_NEAR_FREESTANDING_POH_GRASS }, + { RC_KF_CHILD_GRASS_1, RAND_INF_KF_CHILD_GRASS_1 }, + { RC_KF_CHILD_GRASS_2, RAND_INF_KF_CHILD_GRASS_2 }, + { RC_KF_CHILD_GRASS_3, RAND_INF_KF_CHILD_GRASS_3 }, + { RC_KF_CHILD_GRASS_4, RAND_INF_KF_CHILD_GRASS_4 }, + { RC_KF_CHILD_GRASS_5, RAND_INF_KF_CHILD_GRASS_5 }, + { RC_KF_CHILD_GRASS_6, RAND_INF_KF_CHILD_GRASS_6 }, + { RC_KF_CHILD_GRASS_7, RAND_INF_KF_CHILD_GRASS_7 }, + { RC_KF_CHILD_GRASS_8, RAND_INF_KF_CHILD_GRASS_8 }, + { RC_KF_CHILD_GRASS_9, RAND_INF_KF_CHILD_GRASS_9 }, + { RC_KF_CHILD_GRASS_10, RAND_INF_KF_CHILD_GRASS_10 }, + { RC_KF_CHILD_GRASS_11, RAND_INF_KF_CHILD_GRASS_11 }, + { RC_KF_CHILD_GRASS_12, RAND_INF_KF_CHILD_GRASS_12 }, + { RC_KF_CHILD_GRASS_MAZE_1, RAND_INF_KF_CHILD_GRASS_MAZE_1 }, + { RC_KF_CHILD_GRASS_MAZE_2, RAND_INF_KF_CHILD_GRASS_MAZE_2 }, + { RC_KF_CHILD_GRASS_MAZE_3, RAND_INF_KF_CHILD_GRASS_MAZE_3 }, + { RC_KF_ADULT_GRASS_1, RAND_INF_KF_ADULT_GRASS_1 }, + { RC_KF_ADULT_GRASS_2, RAND_INF_KF_ADULT_GRASS_2 }, + { RC_KF_ADULT_GRASS_3, RAND_INF_KF_ADULT_GRASS_3 }, + { RC_KF_ADULT_GRASS_4, RAND_INF_KF_ADULT_GRASS_4 }, + { RC_KF_ADULT_GRASS_5, RAND_INF_KF_ADULT_GRASS_5 }, + { RC_KF_ADULT_GRASS_6, RAND_INF_KF_ADULT_GRASS_6 }, + { RC_KF_ADULT_GRASS_7, RAND_INF_KF_ADULT_GRASS_7 }, + { RC_KF_ADULT_GRASS_8, RAND_INF_KF_ADULT_GRASS_8 }, + { RC_KF_ADULT_GRASS_9, RAND_INF_KF_ADULT_GRASS_9 }, + { RC_KF_ADULT_GRASS_10, RAND_INF_KF_ADULT_GRASS_10 }, + { RC_KF_ADULT_GRASS_11, RAND_INF_KF_ADULT_GRASS_11 }, + { RC_KF_ADULT_GRASS_12, RAND_INF_KF_ADULT_GRASS_12 }, + { RC_KF_ADULT_GRASS_13, RAND_INF_KF_ADULT_GRASS_13 }, + { RC_KF_ADULT_GRASS_14, RAND_INF_KF_ADULT_GRASS_14 }, + { RC_KF_ADULT_GRASS_15, RAND_INF_KF_ADULT_GRASS_15 }, + { RC_KF_ADULT_GRASS_16, RAND_INF_KF_ADULT_GRASS_16 }, + { RC_KF_ADULT_GRASS_17, RAND_INF_KF_ADULT_GRASS_17 }, + { RC_KF_ADULT_GRASS_18, RAND_INF_KF_ADULT_GRASS_18 }, + { RC_KF_ADULT_GRASS_19, RAND_INF_KF_ADULT_GRASS_19 }, + { RC_KF_ADULT_GRASS_20, RAND_INF_KF_ADULT_GRASS_20 }, + { RC_LW_GRASS_1, RAND_INF_LW_GRASS_1 }, + { RC_LW_GRASS_2, RAND_INF_LW_GRASS_2 }, + { RC_LW_GRASS_3, RAND_INF_LW_GRASS_3 }, + { RC_LW_GRASS_4, RAND_INF_LW_GRASS_4 }, + { RC_LW_GRASS_5, RAND_INF_LW_GRASS_5 }, + { RC_LW_GRASS_6, RAND_INF_LW_GRASS_6 }, + { RC_LW_GRASS_7, RAND_INF_LW_GRASS_7 }, + { RC_LW_GRASS_8, RAND_INF_LW_GRASS_8 }, + { RC_LW_GRASS_9, RAND_INF_LW_GRASS_9 }, + { RC_MARKET_GRASS_1, RAND_INF_MARKET_GRASS_1 }, + { RC_MARKET_GRASS_2, RAND_INF_MARKET_GRASS_2 }, + { RC_MARKET_GRASS_3, RAND_INF_MARKET_GRASS_3 }, + { RC_MARKET_GRASS_4, RAND_INF_MARKET_GRASS_4 }, + { RC_MARKET_GRASS_5, RAND_INF_MARKET_GRASS_5 }, + { RC_MARKET_GRASS_6, RAND_INF_MARKET_GRASS_6 }, + { RC_MARKET_GRASS_7, RAND_INF_MARKET_GRASS_7 }, + { RC_MARKET_GRASS_8, RAND_INF_MARKET_GRASS_8 }, + { RC_HC_GRASS_1, RAND_INF_HC_GRASS_1 }, + { RC_HC_GRASS_2, RAND_INF_HC_GRASS_2 }, + { RC_KAK_GRASS_1, RAND_INF_KAK_GRASS_1 }, + { RC_KAK_GRASS_2, RAND_INF_KAK_GRASS_2 }, + { RC_KAK_GRASS_3, RAND_INF_KAK_GRASS_3 }, + { RC_KAK_GRASS_4, RAND_INF_KAK_GRASS_4 }, + { RC_KAK_GRASS_5, RAND_INF_KAK_GRASS_5 }, + { RC_KAK_GRASS_6, RAND_INF_KAK_GRASS_6 }, + { RC_KAK_GRASS_7, RAND_INF_KAK_GRASS_7 }, + { RC_KAK_GRASS_8, RAND_INF_KAK_GRASS_8 }, + { RC_GY_GRASS_1, RAND_INF_GY_GRASS_1 }, + { RC_GY_GRASS_2, RAND_INF_GY_GRASS_2 }, + { RC_GY_GRASS_3, RAND_INF_GY_GRASS_3 }, + { RC_GY_GRASS_4, RAND_INF_GY_GRASS_4 }, + { RC_GY_GRASS_5, RAND_INF_GY_GRASS_5 }, + { RC_GY_GRASS_6, RAND_INF_GY_GRASS_6 }, + { RC_GY_GRASS_7, RAND_INF_GY_GRASS_7 }, + { RC_GY_GRASS_8, RAND_INF_GY_GRASS_8 }, + { RC_GY_GRASS_9, RAND_INF_GY_GRASS_9 }, + { RC_GY_GRASS_10, RAND_INF_GY_GRASS_10 }, + { RC_GY_GRASS_11, RAND_INF_GY_GRASS_11 }, + { RC_GY_GRASS_12, RAND_INF_GY_GRASS_12 }, + { RC_LH_GRASS_1, RAND_INF_LH_GRASS_1 }, + { RC_LH_GRASS_2, RAND_INF_LH_GRASS_2 }, + { RC_LH_GRASS_3, RAND_INF_LH_GRASS_3 }, + { RC_LH_GRASS_4, RAND_INF_LH_GRASS_4 }, + { RC_LH_GRASS_5, RAND_INF_LH_GRASS_5 }, + { RC_LH_GRASS_6, RAND_INF_LH_GRASS_6 }, + { RC_LH_GRASS_7, RAND_INF_LH_GRASS_7 }, + { RC_LH_GRASS_8, RAND_INF_LH_GRASS_8 }, + { RC_LH_GRASS_9, RAND_INF_LH_GRASS_9 }, + { RC_LH_GRASS_10, RAND_INF_LH_GRASS_10 }, + { RC_LH_GRASS_11, RAND_INF_LH_GRASS_11 }, + { RC_LH_GRASS_12, RAND_INF_LH_GRASS_12 }, + { RC_LH_GRASS_13, RAND_INF_LH_GRASS_13 }, + { RC_LH_GRASS_14, RAND_INF_LH_GRASS_14 }, + { RC_LH_GRASS_15, RAND_INF_LH_GRASS_15 }, + { RC_LH_GRASS_16, RAND_INF_LH_GRASS_16 }, + { RC_LH_GRASS_17, RAND_INF_LH_GRASS_17 }, + { RC_LH_GRASS_18, RAND_INF_LH_GRASS_18 }, + { RC_LH_GRASS_19, RAND_INF_LH_GRASS_19 }, + { RC_LH_GRASS_20, RAND_INF_LH_GRASS_20 }, + { RC_LH_GRASS_21, RAND_INF_LH_GRASS_21 }, + { RC_LH_GRASS_22, RAND_INF_LH_GRASS_22 }, + { RC_LH_GRASS_23, RAND_INF_LH_GRASS_23 }, + { RC_LH_GRASS_24, RAND_INF_LH_GRASS_24 }, + { RC_LH_GRASS_25, RAND_INF_LH_GRASS_25 }, + { RC_LH_GRASS_26, RAND_INF_LH_GRASS_26 }, + { RC_LH_GRASS_27, RAND_INF_LH_GRASS_27 }, + { RC_LH_GRASS_28, RAND_INF_LH_GRASS_28 }, + { RC_LH_GRASS_29, RAND_INF_LH_GRASS_29 }, + { RC_LH_GRASS_30, RAND_INF_LH_GRASS_30 }, + { RC_LH_GRASS_31, RAND_INF_LH_GRASS_31 }, + { RC_LH_GRASS_32, RAND_INF_LH_GRASS_32 }, + { RC_LH_GRASS_33, RAND_INF_LH_GRASS_33 }, + { RC_LH_GRASS_34, RAND_INF_LH_GRASS_34 }, + { RC_LH_GRASS_35, RAND_INF_LH_GRASS_35 }, + { RC_LH_GRASS_36, RAND_INF_LH_GRASS_36 }, + { RC_LH_CHILD_GRASS_1, RAND_INF_LH_CHILD_GRASS_1 }, + { RC_LH_CHILD_GRASS_2, RAND_INF_LH_CHILD_GRASS_2 }, + { RC_LH_CHILD_GRASS_3, RAND_INF_LH_CHILD_GRASS_3 }, + { RC_LH_CHILD_GRASS_4, RAND_INF_LH_CHILD_GRASS_4 }, + { RC_LH_WARP_PAD_GRASS_1, RAND_INF_LH_WARP_PAD_GRASS_1 }, + { RC_LH_WARP_PAD_GRASS_2, RAND_INF_LH_WARP_PAD_GRASS_2 }, + { RC_HF_NEAR_KF_GRASS_1, RAND_INF_HF_NEAR_KF_GRASS_1 }, + { RC_HF_NEAR_KF_GRASS_2, RAND_INF_HF_NEAR_KF_GRASS_2 }, + { RC_HF_NEAR_KF_GRASS_3, RAND_INF_HF_NEAR_KF_GRASS_3 }, + { RC_HF_NEAR_KF_GRASS_4, RAND_INF_HF_NEAR_KF_GRASS_4 }, + { RC_HF_NEAR_KF_GRASS_5, RAND_INF_HF_NEAR_KF_GRASS_5 }, + { RC_HF_NEAR_KF_GRASS_6, RAND_INF_HF_NEAR_KF_GRASS_6 }, + { RC_HF_NEAR_KF_GRASS_7, RAND_INF_HF_NEAR_KF_GRASS_7 }, + { RC_HF_NEAR_KF_GRASS_8, RAND_INF_HF_NEAR_KF_GRASS_8 }, + { RC_HF_NEAR_KF_GRASS_9, RAND_INF_HF_NEAR_KF_GRASS_9 }, + { RC_HF_NEAR_KF_GRASS_10, RAND_INF_HF_NEAR_KF_GRASS_10 }, + { RC_HF_NEAR_KF_GRASS_11, RAND_INF_HF_NEAR_KF_GRASS_11 }, + { RC_HF_NEAR_KF_GRASS_12, RAND_INF_HF_NEAR_KF_GRASS_12 }, + { RC_HF_NEAR_MARKET_GRASS_1, RAND_INF_HF_NEAR_MARKET_GRASS_1 }, + { RC_HF_NEAR_MARKET_GRASS_2, RAND_INF_HF_NEAR_MARKET_GRASS_2 }, + { RC_HF_NEAR_MARKET_GRASS_3, RAND_INF_HF_NEAR_MARKET_GRASS_3 }, + { RC_HF_NEAR_MARKET_GRASS_4, RAND_INF_HF_NEAR_MARKET_GRASS_4 }, + { RC_HF_NEAR_MARKET_GRASS_5, RAND_INF_HF_NEAR_MARKET_GRASS_5 }, + { RC_HF_NEAR_MARKET_GRASS_6, RAND_INF_HF_NEAR_MARKET_GRASS_6 }, + { RC_HF_NEAR_MARKET_GRASS_7, RAND_INF_HF_NEAR_MARKET_GRASS_7 }, + { RC_HF_NEAR_MARKET_GRASS_8, RAND_INF_HF_NEAR_MARKET_GRASS_8 }, + { RC_HF_NEAR_MARKET_GRASS_9, RAND_INF_HF_NEAR_MARKET_GRASS_9 }, + { RC_HF_NEAR_MARKET_GRASS_10, RAND_INF_HF_NEAR_MARKET_GRASS_10 }, + { RC_HF_NEAR_MARKET_GRASS_11, RAND_INF_HF_NEAR_MARKET_GRASS_11 }, + { RC_HF_NEAR_MARKET_GRASS_12, RAND_INF_HF_NEAR_MARKET_GRASS_12 }, + { RC_HF_SOUTH_GRASS_1, RAND_INF_HF_SOUTH_GRASS_1 }, + { RC_HF_SOUTH_GRASS_2, RAND_INF_HF_SOUTH_GRASS_2 }, + { RC_HF_SOUTH_GRASS_3, RAND_INF_HF_SOUTH_GRASS_3 }, + { RC_HF_SOUTH_GRASS_4, RAND_INF_HF_SOUTH_GRASS_4 }, + { RC_HF_SOUTH_GRASS_5, RAND_INF_HF_SOUTH_GRASS_5 }, + { RC_HF_SOUTH_GRASS_6, RAND_INF_HF_SOUTH_GRASS_6 }, + { RC_HF_SOUTH_GRASS_7, RAND_INF_HF_SOUTH_GRASS_7 }, + { RC_HF_SOUTH_GRASS_8, RAND_INF_HF_SOUTH_GRASS_8 }, + { RC_HF_SOUTH_GRASS_9, RAND_INF_HF_SOUTH_GRASS_9 }, + { RC_HF_SOUTH_GRASS_10, RAND_INF_HF_SOUTH_GRASS_10 }, + { RC_HF_SOUTH_GRASS_11, RAND_INF_HF_SOUTH_GRASS_11 }, + { RC_HF_SOUTH_GRASS_12, RAND_INF_HF_SOUTH_GRASS_12 }, + { RC_HF_CENTRAL_GRASS_1, RAND_INF_HF_CENTRAL_GRASS_1 }, + { RC_HF_CENTRAL_GRASS_2, RAND_INF_HF_CENTRAL_GRASS_2 }, + { RC_HF_CENTRAL_GRASS_3, RAND_INF_HF_CENTRAL_GRASS_3 }, + { RC_HF_CENTRAL_GRASS_4, RAND_INF_HF_CENTRAL_GRASS_4 }, + { RC_HF_CENTRAL_GRASS_5, RAND_INF_HF_CENTRAL_GRASS_5 }, + { RC_HF_CENTRAL_GRASS_6, RAND_INF_HF_CENTRAL_GRASS_6 }, + { RC_HF_CENTRAL_GRASS_7, RAND_INF_HF_CENTRAL_GRASS_7 }, + { RC_HF_CENTRAL_GRASS_8, RAND_INF_HF_CENTRAL_GRASS_8 }, + { RC_HF_CENTRAL_GRASS_9, RAND_INF_HF_CENTRAL_GRASS_9 }, + { RC_HF_CENTRAL_GRASS_10, RAND_INF_HF_CENTRAL_GRASS_10 }, + { RC_HF_CENTRAL_GRASS_11, RAND_INF_HF_CENTRAL_GRASS_11 }, + { RC_HF_CENTRAL_GRASS_12, RAND_INF_HF_CENTRAL_GRASS_12 }, + { RC_ZR_GRASS_1, RAND_INF_ZR_GRASS_1 }, + { RC_ZR_GRASS_2, RAND_INF_ZR_GRASS_2 }, + { RC_ZR_GRASS_3, RAND_INF_ZR_GRASS_3 }, + { RC_ZR_GRASS_4, RAND_INF_ZR_GRASS_4 }, + { RC_ZR_GRASS_5, RAND_INF_ZR_GRASS_5 }, + { RC_ZR_GRASS_6, RAND_INF_ZR_GRASS_6 }, + { RC_ZR_GRASS_7, RAND_INF_ZR_GRASS_7 }, + { RC_ZR_GRASS_8, RAND_INF_ZR_GRASS_8 }, + { RC_ZR_GRASS_9, RAND_INF_ZR_GRASS_9 }, + { RC_ZR_GRASS_10, RAND_INF_ZR_GRASS_10 }, + { RC_ZR_GRASS_11, RAND_INF_ZR_GRASS_11 }, + { RC_ZR_GRASS_12, RAND_INF_ZR_GRASS_12 }, + { RC_ZR_NEAR_FREESTANDING_POH_GRASS, RAND_INF_ZR_NEAR_FREESTANDING_POH_GRASS }, // Grotto Grass - { RC_KF_STORMS_GROTTO_GRASS_1, RAND_INF_KF_STORMS_GROTTO_GRASS_1 }, - { RC_KF_STORMS_GROTTO_GRASS_2, RAND_INF_KF_STORMS_GROTTO_GRASS_2 }, - { RC_KF_STORMS_GROTTO_GRASS_3, RAND_INF_KF_STORMS_GROTTO_GRASS_3 }, - { RC_KF_STORMS_GROTTO_GRASS_4, RAND_INF_KF_STORMS_GROTTO_GRASS_4 }, - { RC_LW_NEAR_SHORTCUTS_GROTTO_GRASS_1, RAND_INF_LW_NEAR_SHORTCUTS_GROTTO_GRASS_1 }, - { RC_LW_NEAR_SHORTCUTS_GROTTO_GRASS_2, RAND_INF_LW_NEAR_SHORTCUTS_GROTTO_GRASS_2 }, - { RC_LW_NEAR_SHORTCUTS_GROTTO_GRASS_3, RAND_INF_LW_NEAR_SHORTCUTS_GROTTO_GRASS_3 }, - { RC_LW_NEAR_SHORTCUTS_GROTTO_GRASS_4, RAND_INF_LW_NEAR_SHORTCUTS_GROTTO_GRASS_4 }, - { RC_HF_NEAR_MARKET_GROTTO_GRASS_1, RAND_INF_HF_NEAR_MARKET_GROTTO_GRASS_1 }, - { RC_HF_NEAR_MARKET_GROTTO_GRASS_2, RAND_INF_HF_NEAR_MARKET_GROTTO_GRASS_2 }, - { RC_HF_NEAR_MARKET_GROTTO_GRASS_3, RAND_INF_HF_NEAR_MARKET_GROTTO_GRASS_3 }, - { RC_HF_NEAR_MARKET_GROTTO_GRASS_4, RAND_INF_HF_NEAR_MARKET_GROTTO_GRASS_4 }, - { RC_HF_OPEN_GROTTO_GRASS_1, RAND_INF_HF_OPEN_GROTTO_GRASS_1 }, - { RC_HF_OPEN_GROTTO_GRASS_2, RAND_INF_HF_OPEN_GROTTO_GRASS_2 }, - { RC_HF_OPEN_GROTTO_GRASS_3, RAND_INF_HF_OPEN_GROTTO_GRASS_3 }, - { RC_HF_OPEN_GROTTO_GRASS_4, RAND_INF_HF_OPEN_GROTTO_GRASS_4 }, - { RC_HF_SOUTHEAST_GROTTO_GRASS_1, RAND_INF_HF_SOUTHEAST_GROTTO_GRASS_1 }, - { RC_HF_SOUTHEAST_GROTTO_GRASS_2, RAND_INF_HF_SOUTHEAST_GROTTO_GRASS_2 }, - { RC_HF_SOUTHEAST_GROTTO_GRASS_3, RAND_INF_HF_SOUTHEAST_GROTTO_GRASS_3 }, - { RC_HF_SOUTHEAST_GROTTO_GRASS_4, RAND_INF_HF_SOUTHEAST_GROTTO_GRASS_4 }, - { RC_HF_COW_GROTTO_GRASS_1, RAND_INF_HF_COW_GROTTO_GRASS_1 }, - { RC_HF_COW_GROTTO_GRASS_2, RAND_INF_HF_COW_GROTTO_GRASS_2 }, - { RC_KAK_OPEN_GROTTO_GRASS_1, RAND_INF_KAK_OPEN_GROTTO_GRASS_1 }, - { RC_KAK_OPEN_GROTTO_GRASS_2, RAND_INF_KAK_OPEN_GROTTO_GRASS_2 }, - { RC_KAK_OPEN_GROTTO_GRASS_3, RAND_INF_KAK_OPEN_GROTTO_GRASS_3 }, - { RC_KAK_OPEN_GROTTO_GRASS_4, RAND_INF_KAK_OPEN_GROTTO_GRASS_4 }, - { RC_DMT_STORMS_GROTTO_GRASS_1, RAND_INF_DMT_STORMS_GROTTO_GRASS_1 }, - { RC_DMT_STORMS_GROTTO_GRASS_2, RAND_INF_DMT_STORMS_GROTTO_GRASS_2 }, - { RC_DMT_STORMS_GROTTO_GRASS_3, RAND_INF_DMT_STORMS_GROTTO_GRASS_3 }, - { RC_DMT_STORMS_GROTTO_GRASS_4, RAND_INF_DMT_STORMS_GROTTO_GRASS_4 }, - { RC_DMT_COW_GROTTO_GRASS_1, RAND_INF_DMT_COW_GROTTO_GRASS_1 }, - { RC_DMT_COW_GROTTO_GRASS_2, RAND_INF_DMT_COW_GROTTO_GRASS_2 }, - { RC_DMC_UPPER_GROTTO_GRASS_1, RAND_INF_DMC_UPPER_GROTTO_GRASS_1 }, - { RC_DMC_UPPER_GROTTO_GRASS_2, RAND_INF_DMC_UPPER_GROTTO_GRASS_2 }, - { RC_DMC_UPPER_GROTTO_GRASS_3, RAND_INF_DMC_UPPER_GROTTO_GRASS_3 }, - { RC_DMC_UPPER_GROTTO_GRASS_4, RAND_INF_DMC_UPPER_GROTTO_GRASS_4 }, - { RC_ZR_OPEN_GROTTO_GRASS_1, RAND_INF_ZR_OPEN_GROTTO_GRASS_1 }, - { RC_ZR_OPEN_GROTTO_GRASS_2, RAND_INF_ZR_OPEN_GROTTO_GRASS_2 }, - { RC_ZR_OPEN_GROTTO_GRASS_3, RAND_INF_ZR_OPEN_GROTTO_GRASS_3 }, - { RC_ZR_OPEN_GROTTO_GRASS_4, RAND_INF_ZR_OPEN_GROTTO_GRASS_4 }, + { RC_KF_STORMS_GROTTO_GRASS_1, RAND_INF_KF_STORMS_GROTTO_GRASS_1 }, + { RC_KF_STORMS_GROTTO_GRASS_2, RAND_INF_KF_STORMS_GROTTO_GRASS_2 }, + { RC_KF_STORMS_GROTTO_GRASS_3, RAND_INF_KF_STORMS_GROTTO_GRASS_3 }, + { RC_KF_STORMS_GROTTO_GRASS_4, RAND_INF_KF_STORMS_GROTTO_GRASS_4 }, + { RC_LW_NEAR_SHORTCUTS_GROTTO_GRASS_1, RAND_INF_LW_NEAR_SHORTCUTS_GROTTO_GRASS_1 }, + { RC_LW_NEAR_SHORTCUTS_GROTTO_GRASS_2, RAND_INF_LW_NEAR_SHORTCUTS_GROTTO_GRASS_2 }, + { RC_LW_NEAR_SHORTCUTS_GROTTO_GRASS_3, RAND_INF_LW_NEAR_SHORTCUTS_GROTTO_GRASS_3 }, + { RC_LW_NEAR_SHORTCUTS_GROTTO_GRASS_4, RAND_INF_LW_NEAR_SHORTCUTS_GROTTO_GRASS_4 }, + { RC_HF_NEAR_MARKET_GROTTO_GRASS_1, RAND_INF_HF_NEAR_MARKET_GROTTO_GRASS_1 }, + { RC_HF_NEAR_MARKET_GROTTO_GRASS_2, RAND_INF_HF_NEAR_MARKET_GROTTO_GRASS_2 }, + { RC_HF_NEAR_MARKET_GROTTO_GRASS_3, RAND_INF_HF_NEAR_MARKET_GROTTO_GRASS_3 }, + { RC_HF_NEAR_MARKET_GROTTO_GRASS_4, RAND_INF_HF_NEAR_MARKET_GROTTO_GRASS_4 }, + { RC_HF_OPEN_GROTTO_GRASS_1, RAND_INF_HF_OPEN_GROTTO_GRASS_1 }, + { RC_HF_OPEN_GROTTO_GRASS_2, RAND_INF_HF_OPEN_GROTTO_GRASS_2 }, + { RC_HF_OPEN_GROTTO_GRASS_3, RAND_INF_HF_OPEN_GROTTO_GRASS_3 }, + { RC_HF_OPEN_GROTTO_GRASS_4, RAND_INF_HF_OPEN_GROTTO_GRASS_4 }, + { RC_HF_SOUTHEAST_GROTTO_GRASS_1, RAND_INF_HF_SOUTHEAST_GROTTO_GRASS_1 }, + { RC_HF_SOUTHEAST_GROTTO_GRASS_2, RAND_INF_HF_SOUTHEAST_GROTTO_GRASS_2 }, + { RC_HF_SOUTHEAST_GROTTO_GRASS_3, RAND_INF_HF_SOUTHEAST_GROTTO_GRASS_3 }, + { RC_HF_SOUTHEAST_GROTTO_GRASS_4, RAND_INF_HF_SOUTHEAST_GROTTO_GRASS_4 }, + { RC_HF_COW_GROTTO_GRASS_1, RAND_INF_HF_COW_GROTTO_GRASS_1 }, + { RC_HF_COW_GROTTO_GRASS_2, RAND_INF_HF_COW_GROTTO_GRASS_2 }, + { RC_KAK_OPEN_GROTTO_GRASS_1, RAND_INF_KAK_OPEN_GROTTO_GRASS_1 }, + { RC_KAK_OPEN_GROTTO_GRASS_2, RAND_INF_KAK_OPEN_GROTTO_GRASS_2 }, + { RC_KAK_OPEN_GROTTO_GRASS_3, RAND_INF_KAK_OPEN_GROTTO_GRASS_3 }, + { RC_KAK_OPEN_GROTTO_GRASS_4, RAND_INF_KAK_OPEN_GROTTO_GRASS_4 }, + { RC_DMT_STORMS_GROTTO_GRASS_1, RAND_INF_DMT_STORMS_GROTTO_GRASS_1 }, + { RC_DMT_STORMS_GROTTO_GRASS_2, RAND_INF_DMT_STORMS_GROTTO_GRASS_2 }, + { RC_DMT_STORMS_GROTTO_GRASS_3, RAND_INF_DMT_STORMS_GROTTO_GRASS_3 }, + { RC_DMT_STORMS_GROTTO_GRASS_4, RAND_INF_DMT_STORMS_GROTTO_GRASS_4 }, + { RC_DMT_COW_GROTTO_GRASS_1, RAND_INF_DMT_COW_GROTTO_GRASS_1 }, + { RC_DMT_COW_GROTTO_GRASS_2, RAND_INF_DMT_COW_GROTTO_GRASS_2 }, + { RC_DMC_UPPER_GROTTO_GRASS_1, RAND_INF_DMC_UPPER_GROTTO_GRASS_1 }, + { RC_DMC_UPPER_GROTTO_GRASS_2, RAND_INF_DMC_UPPER_GROTTO_GRASS_2 }, + { RC_DMC_UPPER_GROTTO_GRASS_3, RAND_INF_DMC_UPPER_GROTTO_GRASS_3 }, + { RC_DMC_UPPER_GROTTO_GRASS_4, RAND_INF_DMC_UPPER_GROTTO_GRASS_4 }, + { RC_ZR_OPEN_GROTTO_GRASS_1, RAND_INF_ZR_OPEN_GROTTO_GRASS_1 }, + { RC_ZR_OPEN_GROTTO_GRASS_2, RAND_INF_ZR_OPEN_GROTTO_GRASS_2 }, + { RC_ZR_OPEN_GROTTO_GRASS_3, RAND_INF_ZR_OPEN_GROTTO_GRASS_3 }, + { RC_ZR_OPEN_GROTTO_GRASS_4, RAND_INF_ZR_OPEN_GROTTO_GRASS_4 }, // Dungeon Grass - { RC_DEKU_TREE_LOBBY_GRASS_1, RAND_INF_DEKU_TREE_LOBBY_GRASS_1 }, - { RC_DEKU_TREE_LOBBY_GRASS_2, RAND_INF_DEKU_TREE_LOBBY_GRASS_2 }, - { RC_DEKU_TREE_LOBBY_GRASS_3, RAND_INF_DEKU_TREE_LOBBY_GRASS_3 }, - { RC_DEKU_TREE_LOBBY_GRASS_4, RAND_INF_DEKU_TREE_LOBBY_GRASS_4 }, - { RC_DEKU_TREE_LOBBY_GRASS_5, RAND_INF_DEKU_TREE_LOBBY_GRASS_5 }, - { RC_DEKU_TREE_SLINGSHOT_GRASS_1, RAND_INF_DEKU_TREE_SLINGSHOT_GRASS_1 }, - { RC_DEKU_TREE_SLINGSHOT_GRASS_2, RAND_INF_DEKU_TREE_SLINGSHOT_GRASS_2 }, - { RC_DEKU_TREE_SLINGSHOT_GRASS_3, RAND_INF_DEKU_TREE_SLINGSHOT_GRASS_3 }, - { RC_DEKU_TREE_SLINGSHOT_GRASS_4, RAND_INF_DEKU_TREE_SLINGSHOT_GRASS_4 }, - { RC_DEKU_TREE_COMPASS_GRASS_1, RAND_INF_DEKU_TREE_COMPASS_GRASS_1 }, - { RC_DEKU_TREE_COMPASS_GRASS_2, RAND_INF_DEKU_TREE_COMPASS_GRASS_2 }, - { RC_DEKU_TREE_BASEMENT_GRASS_1, RAND_INF_DEKU_TREE_BASEMENT_GRASS_1 }, - { RC_DEKU_TREE_BASEMENT_GRASS_2, RAND_INF_DEKU_TREE_BASEMENT_GRASS_2 }, - { RC_DEKU_TREE_BASEMENT_SCRUB_ROOM_GRASS_1, RAND_INF_DEKU_TREE_BASEMENT_SCRUB_ROOM_GRASS_1 }, - { RC_DEKU_TREE_BASEMENT_SCRUB_ROOM_GRASS_2, RAND_INF_DEKU_TREE_BASEMENT_SCRUB_ROOM_GRASS_2 }, - { RC_DEKU_TREE_BASEMENT_SCRUB_ROOM_GRASS_3, RAND_INF_DEKU_TREE_BASEMENT_SCRUB_ROOM_GRASS_3 }, - { RC_DEKU_TREE_BASEMENT_SCRUB_ROOM_GRASS_4, RAND_INF_DEKU_TREE_BASEMENT_SCRUB_ROOM_GRASS_4 }, - { RC_DEKU_TREE_BASEMENT_SPIKE_ROLLER_GRASS_1, RAND_INF_DEKU_TREE_BASEMENT_SPIKE_ROLLER_GRASS_1 }, - { RC_DEKU_TREE_BASEMENT_SPIKE_ROLLER_GRASS_2, RAND_INF_DEKU_TREE_BASEMENT_SPIKE_ROLLER_GRASS_2 }, - { RC_DEKU_TREE_BASEMENT_TORCHES_GRASS_1, RAND_INF_DEKU_TREE_BASEMENT_TORCHES_GRASS_1 }, - { RC_DEKU_TREE_BASEMENT_TORCHES_GRASS_2, RAND_INF_DEKU_TREE_BASEMENT_TORCHES_GRASS_2 }, - { RC_DEKU_TREE_BASEMENT_LARVAE_GRASS_1, RAND_INF_DEKU_TREE_BASEMENT_LARVAE_GRASS_1 }, - { RC_DEKU_TREE_BASEMENT_LARVAE_GRASS_2, RAND_INF_DEKU_TREE_BASEMENT_LARVAE_GRASS_2 }, - { RC_DEKU_TREE_BEFORE_BOSS_GRASS_1, RAND_INF_DEKU_TREE_BEFORE_BOSS_GRASS_1 }, - { RC_DEKU_TREE_BEFORE_BOSS_GRASS_2, RAND_INF_DEKU_TREE_BEFORE_BOSS_GRASS_2 }, - { RC_DEKU_TREE_BEFORE_BOSS_GRASS_3, RAND_INF_DEKU_TREE_BEFORE_BOSS_GRASS_3 }, - { RC_DODONGOS_CAVERN_FIRST_BRIDGE_GRASS, RAND_INF_DODONGOS_CAVERN_FIRST_BRIDGE_GRASS }, - { RC_DODONGOS_CAVERN_BLADE_GRASS, RAND_INF_DODONGOS_CAVERN_BLADE_GRASS }, - { RC_DODONGOS_CAVERN_SINGLE_EYE_GRASS, RAND_INF_DODONGOS_CAVERN_SINGLE_EYE_GRASS }, - { RC_DODONGOS_CAVERN_BEFORE_BOSS_GRASS, RAND_INF_DODONGOS_CAVERN_BEFORE_BOSS_GRASS }, + { RC_DEKU_TREE_LOBBY_GRASS_1, RAND_INF_DEKU_TREE_LOBBY_GRASS_1 }, + { RC_DEKU_TREE_LOBBY_GRASS_2, RAND_INF_DEKU_TREE_LOBBY_GRASS_2 }, + { RC_DEKU_TREE_LOBBY_GRASS_3, RAND_INF_DEKU_TREE_LOBBY_GRASS_3 }, + { RC_DEKU_TREE_LOBBY_GRASS_4, RAND_INF_DEKU_TREE_LOBBY_GRASS_4 }, + { RC_DEKU_TREE_LOBBY_GRASS_5, RAND_INF_DEKU_TREE_LOBBY_GRASS_5 }, + { RC_DEKU_TREE_SLINGSHOT_GRASS_1, RAND_INF_DEKU_TREE_SLINGSHOT_GRASS_1 }, + { RC_DEKU_TREE_SLINGSHOT_GRASS_2, RAND_INF_DEKU_TREE_SLINGSHOT_GRASS_2 }, + { RC_DEKU_TREE_SLINGSHOT_GRASS_3, RAND_INF_DEKU_TREE_SLINGSHOT_GRASS_3 }, + { RC_DEKU_TREE_SLINGSHOT_GRASS_4, RAND_INF_DEKU_TREE_SLINGSHOT_GRASS_4 }, + { RC_DEKU_TREE_COMPASS_GRASS_1, RAND_INF_DEKU_TREE_COMPASS_GRASS_1 }, + { RC_DEKU_TREE_COMPASS_GRASS_2, RAND_INF_DEKU_TREE_COMPASS_GRASS_2 }, + { RC_DEKU_TREE_BASEMENT_GRASS_1, RAND_INF_DEKU_TREE_BASEMENT_GRASS_1 }, + { RC_DEKU_TREE_BASEMENT_GRASS_2, RAND_INF_DEKU_TREE_BASEMENT_GRASS_2 }, + { RC_DEKU_TREE_BASEMENT_SCRUB_ROOM_GRASS_1, RAND_INF_DEKU_TREE_BASEMENT_SCRUB_ROOM_GRASS_1 }, + { RC_DEKU_TREE_BASEMENT_SCRUB_ROOM_GRASS_2, RAND_INF_DEKU_TREE_BASEMENT_SCRUB_ROOM_GRASS_2 }, + { RC_DEKU_TREE_BASEMENT_SCRUB_ROOM_GRASS_3, RAND_INF_DEKU_TREE_BASEMENT_SCRUB_ROOM_GRASS_3 }, + { RC_DEKU_TREE_BASEMENT_SCRUB_ROOM_GRASS_4, RAND_INF_DEKU_TREE_BASEMENT_SCRUB_ROOM_GRASS_4 }, + { RC_DEKU_TREE_BASEMENT_SPIKE_ROLLER_GRASS_1, RAND_INF_DEKU_TREE_BASEMENT_SPIKE_ROLLER_GRASS_1 }, + { RC_DEKU_TREE_BASEMENT_SPIKE_ROLLER_GRASS_2, RAND_INF_DEKU_TREE_BASEMENT_SPIKE_ROLLER_GRASS_2 }, + { RC_DEKU_TREE_BASEMENT_TORCHES_GRASS_1, RAND_INF_DEKU_TREE_BASEMENT_TORCHES_GRASS_1 }, + { RC_DEKU_TREE_BASEMENT_TORCHES_GRASS_2, RAND_INF_DEKU_TREE_BASEMENT_TORCHES_GRASS_2 }, + { RC_DEKU_TREE_BASEMENT_LARVAE_GRASS_1, RAND_INF_DEKU_TREE_BASEMENT_LARVAE_GRASS_1 }, + { RC_DEKU_TREE_BASEMENT_LARVAE_GRASS_2, RAND_INF_DEKU_TREE_BASEMENT_LARVAE_GRASS_2 }, + { RC_DEKU_TREE_BEFORE_BOSS_GRASS_1, RAND_INF_DEKU_TREE_BEFORE_BOSS_GRASS_1 }, + { RC_DEKU_TREE_BEFORE_BOSS_GRASS_2, RAND_INF_DEKU_TREE_BEFORE_BOSS_GRASS_2 }, + { RC_DEKU_TREE_BEFORE_BOSS_GRASS_3, RAND_INF_DEKU_TREE_BEFORE_BOSS_GRASS_3 }, + { RC_DODONGOS_CAVERN_FIRST_BRIDGE_GRASS, RAND_INF_DODONGOS_CAVERN_FIRST_BRIDGE_GRASS }, + { RC_DODONGOS_CAVERN_BLADE_GRASS, RAND_INF_DODONGOS_CAVERN_BLADE_GRASS }, + { RC_DODONGOS_CAVERN_SINGLE_EYE_GRASS, RAND_INF_DODONGOS_CAVERN_SINGLE_EYE_GRASS }, + { RC_DODONGOS_CAVERN_BEFORE_BOSS_GRASS, RAND_INF_DODONGOS_CAVERN_BEFORE_BOSS_GRASS }, { RC_BOTTOM_OF_THE_WELL_BASEMENT_BEHIND_ROCKS_GRASS_1, RAND_INF_BOTTOM_OF_THE_WELL_BASEMENT_BEHIND_ROCKS_GRASS_1 }, { RC_BOTTOM_OF_THE_WELL_BASEMENT_BEHIND_ROCKS_GRASS_2, RAND_INF_BOTTOM_OF_THE_WELL_BASEMENT_BEHIND_ROCKS_GRASS_2 }, { RC_BOTTOM_OF_THE_WELL_BASEMENT_BEHIND_ROCKS_GRASS_3, RAND_INF_BOTTOM_OF_THE_WELL_BASEMENT_BEHIND_ROCKS_GRASS_3 }, @@ -1266,894 +1467,1647 @@ std::map rcToRandomizerInf = { { RC_BOTTOM_OF_THE_WELL_BASEMENT_BEHIND_ROCKS_GRASS_7, RAND_INF_BOTTOM_OF_THE_WELL_BASEMENT_BEHIND_ROCKS_GRASS_7 }, { RC_BOTTOM_OF_THE_WELL_BASEMENT_BEHIND_ROCKS_GRASS_8, RAND_INF_BOTTOM_OF_THE_WELL_BASEMENT_BEHIND_ROCKS_GRASS_8 }, { RC_BOTTOM_OF_THE_WELL_BASEMENT_BEHIND_ROCKS_GRASS_9, RAND_INF_BOTTOM_OF_THE_WELL_BASEMENT_BEHIND_ROCKS_GRASS_9 }, - { RC_BOTTOM_OF_THE_WELL_BASEMENT_GRASS_1, RAND_INF_BOTTOM_OF_THE_WELL_BASEMENT_GRASS_1 }, - { RC_BOTTOM_OF_THE_WELL_BASEMENT_GRASS_2, RAND_INF_BOTTOM_OF_THE_WELL_BASEMENT_GRASS_2 }, - { RC_BOTTOM_OF_THE_WELL_BASEMENT_GRASS_3, RAND_INF_BOTTOM_OF_THE_WELL_BASEMENT_GRASS_3 }, + { RC_BOTTOM_OF_THE_WELL_BASEMENT_GRASS_1, RAND_INF_BOTTOM_OF_THE_WELL_BASEMENT_GRASS_1 }, + { RC_BOTTOM_OF_THE_WELL_BASEMENT_GRASS_2, RAND_INF_BOTTOM_OF_THE_WELL_BASEMENT_GRASS_2 }, + { RC_BOTTOM_OF_THE_WELL_BASEMENT_GRASS_3, RAND_INF_BOTTOM_OF_THE_WELL_BASEMENT_GRASS_3 }, // MQ Dungeon Grass - { RC_DEKU_TREE_MQ_LOBBY_GRASS_1, RAND_INF_DEKU_TREE_MQ_LOBBY_GRASS_1 }, - { RC_DEKU_TREE_MQ_LOBBY_GRASS_2, RAND_INF_DEKU_TREE_MQ_LOBBY_GRASS_2 }, - { RC_DEKU_TREE_MQ_LOBBY_GRASS_3, RAND_INF_DEKU_TREE_MQ_LOBBY_GRASS_3 }, - { RC_DEKU_TREE_MQ_LOBBY_GRASS_4, RAND_INF_DEKU_TREE_MQ_LOBBY_GRASS_4 }, - { RC_DEKU_TREE_MQ_LOBBY_GRASS_5, RAND_INF_DEKU_TREE_MQ_LOBBY_GRASS_5 }, - { RC_DEKU_TREE_MQ_LOBBY_GRASS_6, RAND_INF_DEKU_TREE_MQ_LOBBY_GRASS_6 }, - { RC_DEKU_TREE_MQ_LOBBY_GRASS_7, RAND_INF_DEKU_TREE_MQ_LOBBY_GRASS_7 }, - { RC_DEKU_TREE_MQ_SLINGSHOT_GRASS_1, RAND_INF_DEKU_TREE_MQ_SLINGSHOT_GRASS_1 }, - { RC_DEKU_TREE_MQ_SLINGSHOT_GRASS_2, RAND_INF_DEKU_TREE_MQ_SLINGSHOT_GRASS_2 }, - { RC_DEKU_TREE_MQ_SLINGSHOT_GRASS_3, RAND_INF_DEKU_TREE_MQ_SLINGSHOT_GRASS_3 }, - { RC_DEKU_TREE_MQ_SLINGSHOT_GRASS_4, RAND_INF_DEKU_TREE_MQ_SLINGSHOT_GRASS_4 }, - { RC_DEKU_TREE_MQ_BEFORE_COMPASS_GRASS_1, RAND_INF_DEKU_TREE_MQ_BEFORE_COMPASS_GRASS_1 }, - { RC_DEKU_TREE_MQ_BEFORE_COMPASS_GRASS_2, RAND_INF_DEKU_TREE_MQ_BEFORE_COMPASS_GRASS_2 }, - { RC_DEKU_TREE_MQ_BEFORE_COMPASS_GRASS_3, RAND_INF_DEKU_TREE_MQ_BEFORE_COMPASS_GRASS_3 }, - { RC_DEKU_TREE_MQ_BEFORE_COMPASS_GRASS_4, RAND_INF_DEKU_TREE_MQ_BEFORE_COMPASS_GRASS_4 }, - { RC_DEKU_TREE_MQ_BEFORE_COMPASS_GRASS_5, RAND_INF_DEKU_TREE_MQ_BEFORE_COMPASS_GRASS_5 }, - { RC_DEKU_TREE_MQ_BEFORE_COMPASS_GRASS_6, RAND_INF_DEKU_TREE_MQ_BEFORE_COMPASS_GRASS_6 }, - { RC_DEKU_TREE_MQ_BEFORE_COMPASS_GRASS_7, RAND_INF_DEKU_TREE_MQ_BEFORE_COMPASS_GRASS_7 }, - { RC_DEKU_TREE_MQ_COMPASS_GRASS_1, RAND_INF_DEKU_TREE_MQ_COMPASS_GRASS_1 }, - { RC_DEKU_TREE_MQ_COMPASS_GRASS_2, RAND_INF_DEKU_TREE_MQ_COMPASS_GRASS_2 }, - { RC_DEKU_TREE_MQ_COMPASS_GRASS_3, RAND_INF_DEKU_TREE_MQ_COMPASS_GRASS_3 }, - { RC_DEKU_TREE_MQ_COMPASS_GRASS_4, RAND_INF_DEKU_TREE_MQ_COMPASS_GRASS_4 }, - { RC_DEKU_TREE_MQ_BASEMENT_LOWER_GRASS_1, RAND_INF_DEKU_TREE_MQ_BASEMENT_LOWER_GRASS_1 }, - { RC_DEKU_TREE_MQ_BASEMENT_LOWER_GRASS_2, RAND_INF_DEKU_TREE_MQ_BASEMENT_LOWER_GRASS_2 }, - { RC_DEKU_TREE_MQ_BASEMENT_LOWER_GRASS_3, RAND_INF_DEKU_TREE_MQ_BASEMENT_LOWER_GRASS_3 }, - { RC_DEKU_TREE_MQ_BASEMENT_LOWER_GRASS_4, RAND_INF_DEKU_TREE_MQ_BASEMENT_LOWER_GRASS_4 }, - { RC_DEKU_TREE_MQ_BASEMENT_UPPER_GRASS_1, RAND_INF_DEKU_TREE_MQ_BASEMENT_UPPER_GRASS_1 }, - { RC_DEKU_TREE_MQ_BASEMENT_UPPER_GRASS_2, RAND_INF_DEKU_TREE_MQ_BASEMENT_UPPER_GRASS_2 }, - { RC_DEKU_TREE_MQ_BASEMENT_UPPER_GRASS_3, RAND_INF_DEKU_TREE_MQ_BASEMENT_UPPER_GRASS_3 }, + { RC_DEKU_TREE_MQ_LOBBY_GRASS_1, RAND_INF_DEKU_TREE_MQ_LOBBY_GRASS_1 }, + { RC_DEKU_TREE_MQ_LOBBY_GRASS_2, RAND_INF_DEKU_TREE_MQ_LOBBY_GRASS_2 }, + { RC_DEKU_TREE_MQ_LOBBY_GRASS_3, RAND_INF_DEKU_TREE_MQ_LOBBY_GRASS_3 }, + { RC_DEKU_TREE_MQ_LOBBY_GRASS_4, RAND_INF_DEKU_TREE_MQ_LOBBY_GRASS_4 }, + { RC_DEKU_TREE_MQ_LOBBY_GRASS_5, RAND_INF_DEKU_TREE_MQ_LOBBY_GRASS_5 }, + { RC_DEKU_TREE_MQ_LOBBY_GRASS_6, RAND_INF_DEKU_TREE_MQ_LOBBY_GRASS_6 }, + { RC_DEKU_TREE_MQ_LOBBY_GRASS_7, RAND_INF_DEKU_TREE_MQ_LOBBY_GRASS_7 }, + { RC_DEKU_TREE_MQ_SLINGSHOT_GRASS_1, RAND_INF_DEKU_TREE_MQ_SLINGSHOT_GRASS_1 }, + { RC_DEKU_TREE_MQ_SLINGSHOT_GRASS_2, RAND_INF_DEKU_TREE_MQ_SLINGSHOT_GRASS_2 }, + { RC_DEKU_TREE_MQ_SLINGSHOT_GRASS_3, RAND_INF_DEKU_TREE_MQ_SLINGSHOT_GRASS_3 }, + { RC_DEKU_TREE_MQ_SLINGSHOT_GRASS_4, RAND_INF_DEKU_TREE_MQ_SLINGSHOT_GRASS_4 }, + { RC_DEKU_TREE_MQ_BEFORE_COMPASS_GRASS_1, RAND_INF_DEKU_TREE_MQ_BEFORE_COMPASS_GRASS_1 }, + { RC_DEKU_TREE_MQ_BEFORE_COMPASS_GRASS_2, RAND_INF_DEKU_TREE_MQ_BEFORE_COMPASS_GRASS_2 }, + { RC_DEKU_TREE_MQ_BEFORE_COMPASS_GRASS_3, RAND_INF_DEKU_TREE_MQ_BEFORE_COMPASS_GRASS_3 }, + { RC_DEKU_TREE_MQ_BEFORE_COMPASS_GRASS_4, RAND_INF_DEKU_TREE_MQ_BEFORE_COMPASS_GRASS_4 }, + { RC_DEKU_TREE_MQ_BEFORE_COMPASS_GRASS_5, RAND_INF_DEKU_TREE_MQ_BEFORE_COMPASS_GRASS_5 }, + { RC_DEKU_TREE_MQ_BEFORE_COMPASS_GRASS_6, RAND_INF_DEKU_TREE_MQ_BEFORE_COMPASS_GRASS_6 }, + { RC_DEKU_TREE_MQ_BEFORE_COMPASS_GRASS_7, RAND_INF_DEKU_TREE_MQ_BEFORE_COMPASS_GRASS_7 }, + { RC_DEKU_TREE_MQ_COMPASS_GRASS_1, RAND_INF_DEKU_TREE_MQ_COMPASS_GRASS_1 }, + { RC_DEKU_TREE_MQ_COMPASS_GRASS_2, RAND_INF_DEKU_TREE_MQ_COMPASS_GRASS_2 }, + { RC_DEKU_TREE_MQ_COMPASS_GRASS_3, RAND_INF_DEKU_TREE_MQ_COMPASS_GRASS_3 }, + { RC_DEKU_TREE_MQ_COMPASS_GRASS_4, RAND_INF_DEKU_TREE_MQ_COMPASS_GRASS_4 }, + { RC_DEKU_TREE_MQ_BASEMENT_LOWER_GRASS_1, RAND_INF_DEKU_TREE_MQ_BASEMENT_LOWER_GRASS_1 }, + { RC_DEKU_TREE_MQ_BASEMENT_LOWER_GRASS_2, RAND_INF_DEKU_TREE_MQ_BASEMENT_LOWER_GRASS_2 }, + { RC_DEKU_TREE_MQ_BASEMENT_LOWER_GRASS_3, RAND_INF_DEKU_TREE_MQ_BASEMENT_LOWER_GRASS_3 }, + { RC_DEKU_TREE_MQ_BASEMENT_LOWER_GRASS_4, RAND_INF_DEKU_TREE_MQ_BASEMENT_LOWER_GRASS_4 }, + { RC_DEKU_TREE_MQ_BASEMENT_UPPER_GRASS_1, RAND_INF_DEKU_TREE_MQ_BASEMENT_UPPER_GRASS_1 }, + { RC_DEKU_TREE_MQ_BASEMENT_UPPER_GRASS_2, RAND_INF_DEKU_TREE_MQ_BASEMENT_UPPER_GRASS_2 }, + { RC_DEKU_TREE_MQ_BASEMENT_UPPER_GRASS_3, RAND_INF_DEKU_TREE_MQ_BASEMENT_UPPER_GRASS_3 }, { RC_DEKU_TREE_MQ_BASEMENT_SPIKE_ROLLER_FRONT_GRASS_1, RAND_INF_DEKU_TREE_MQ_BASEMENT_SPIKE_ROLLER_FRONT_GRASS_1 }, { RC_DEKU_TREE_MQ_BASEMENT_SPIKE_ROLLER_FRONT_GRASS_2, RAND_INF_DEKU_TREE_MQ_BASEMENT_SPIKE_ROLLER_FRONT_GRASS_2 }, { RC_DEKU_TREE_MQ_BASEMENT_SPIKE_ROLLER_FRONT_GRASS_3, RAND_INF_DEKU_TREE_MQ_BASEMENT_SPIKE_ROLLER_FRONT_GRASS_3 }, - { RC_DEKU_TREE_MQ_BASEMENT_SPIKE_ROLLER_BACK_GRASS_1, RAND_INF_DEKU_TREE_MQ_BASEMENT_SPIKE_ROLLER_BACK_GRASS_1 }, - { RC_DEKU_TREE_MQ_BASEMENT_SPIKE_ROLLER_BACK_GRASS_2, RAND_INF_DEKU_TREE_MQ_BASEMENT_SPIKE_ROLLER_BACK_GRASS_2 }, - { RC_DEKU_TREE_MQ_BASEMENT_TORCHES_GRASS_1, RAND_INF_DEKU_TREE_MQ_BASEMENT_TORCHES_GRASS_1 }, - { RC_DEKU_TREE_MQ_BASEMENT_TORCHES_GRASS_2, RAND_INF_DEKU_TREE_MQ_BASEMENT_TORCHES_GRASS_2 }, - { RC_DEKU_TREE_MQ_BASEMENT_TORCHES_GRASS_3, RAND_INF_DEKU_TREE_MQ_BASEMENT_TORCHES_GRASS_3 }, - { RC_DEKU_TREE_MQ_BASEMENT_TORCHES_GRASS_4, RAND_INF_DEKU_TREE_MQ_BASEMENT_TORCHES_GRASS_4 }, - { RC_DEKU_TREE_MQ_BASEMENT_LARVAE_GRASS_1, RAND_INF_DEKU_TREE_MQ_BASEMENT_LARVAE_GRASS_1 }, - { RC_DEKU_TREE_MQ_BASEMENT_LARVAE_GRASS_2, RAND_INF_DEKU_TREE_MQ_BASEMENT_LARVAE_GRASS_2 }, - { RC_DEKU_TREE_MQ_BASEMENT_GRAVES_GRASS_1, RAND_INF_DEKU_TREE_MQ_BASEMENT_GRAVES_GRASS_1 }, - { RC_DEKU_TREE_MQ_BASEMENT_GRAVES_GRASS_2, RAND_INF_DEKU_TREE_MQ_BASEMENT_GRAVES_GRASS_2 }, - { RC_DEKU_TREE_MQ_BASEMENT_GRAVES_GRASS_3, RAND_INF_DEKU_TREE_MQ_BASEMENT_GRAVES_GRASS_3 }, - { RC_DEKU_TREE_MQ_BASEMENT_GRAVES_GRASS_4, RAND_INF_DEKU_TREE_MQ_BASEMENT_GRAVES_GRASS_4 }, - { RC_DEKU_TREE_MQ_BASEMENT_GRAVES_GRASS_5, RAND_INF_DEKU_TREE_MQ_BASEMENT_GRAVES_GRASS_5 }, - { RC_DEKU_TREE_MQ_BASEMENT_BACK_GRASS_1, RAND_INF_DEKU_TREE_MQ_BASEMENT_BACK_GRASS_1 }, - { RC_DEKU_TREE_MQ_BASEMENT_BACK_GRASS_2, RAND_INF_DEKU_TREE_MQ_BASEMENT_BACK_GRASS_2 }, - { RC_DEKU_TREE_MQ_BASEMENT_BACK_GRASS_3, RAND_INF_DEKU_TREE_MQ_BASEMENT_BACK_GRASS_3 }, - { RC_DEKU_TREE_MQ_BEFORE_BOSS_GRASS_1, RAND_INF_DEKU_TREE_MQ_BEFORE_BOSS_GRASS_1 }, - { RC_DEKU_TREE_MQ_BEFORE_BOSS_GRASS_2, RAND_INF_DEKU_TREE_MQ_BEFORE_BOSS_GRASS_2 }, - { RC_DEKU_TREE_MQ_BEFORE_BOSS_GRASS_3, RAND_INF_DEKU_TREE_MQ_BEFORE_BOSS_GRASS_3 }, - { RC_DODONGOS_CAVERN_MQ_COMPASS_GRASS_1, RAND_INF_DODONGOS_CAVERN_MQ_COMPASS_GRASS_1 }, - { RC_DODONGOS_CAVERN_MQ_COMPASS_GRASS_2, RAND_INF_DODONGOS_CAVERN_MQ_COMPASS_GRASS_2 }, - { RC_DODONGOS_CAVERN_MQ_COMPASS_GRASS_3, RAND_INF_DODONGOS_CAVERN_MQ_COMPASS_GRASS_3 }, - { RC_DODONGOS_CAVERN_MQ_COMPASS_GRASS_4, RAND_INF_DODONGOS_CAVERN_MQ_COMPASS_GRASS_4 }, - { RC_DODONGOS_CAVERN_MQ_ARMOS_GRASS, RAND_INF_DODONGOS_CAVERN_MQ_ARMOS_GRASS }, - { RC_DODONGOS_CAVERN_MQ_BACK_POE_GRASS, RAND_INF_DODONGOS_CAVERN_MQ_BACK_POE_GRASS }, - { RC_DODONGOS_CAVERN_MQ_SCRUB_GRASS_1, RAND_INF_DODONGOS_CAVERN_MQ_SCRUB_GRASS_1 }, - { RC_DODONGOS_CAVERN_MQ_SCRUB_GRASS_2, RAND_INF_DODONGOS_CAVERN_MQ_SCRUB_GRASS_2 }, - { RC_JABU_JABUS_BELLY_MQ_FIRST_GRASS_1, RAND_INF_JABU_JABUS_BELLY_MQ_FIRST_GRASS_1 }, - { RC_JABU_JABUS_BELLY_MQ_FIRST_GRASS_2, RAND_INF_JABU_JABUS_BELLY_MQ_FIRST_GRASS_2 }, - { RC_JABU_JABUS_BELLY_MQ_PIT_GRASS_1, RAND_INF_JABU_JABUS_BELLY_MQ_PIT_GRASS_1 }, - { RC_JABU_JABUS_BELLY_MQ_PIT_GRASS_2, RAND_INF_JABU_JABUS_BELLY_MQ_PIT_GRASS_2 }, - { RC_JABU_JABUS_BELLY_MQ_BASEMENT_GRASS_1, RAND_INF_JABU_JABUS_BELLY_MQ_BASEMENT_GRASS_1 }, - { RC_JABU_JABUS_BELLY_MQ_BASEMENT_GRASS_2, RAND_INF_JABU_JABUS_BELLY_MQ_BASEMENT_GRASS_2 }, - { RC_JABU_JABUS_BELLY_MQ_BASEMENT_GRASS_3, RAND_INF_JABU_JABUS_BELLY_MQ_BASEMENT_GRASS_3 }, - { RC_JABU_JABUS_BELLY_MQ_WIGGLERS_GRASS, RAND_INF_JABU_JABUS_BELLY_MQ_WIGGLERS_GRASS }, - { RC_JABU_JABUS_BELLY_MQ_AFTER_BIG_OCTO_GRASS_1, RAND_INF_JABU_JABUS_BELLY_MQ_AFTER_BIG_OCTO_GRASS_1 }, - { RC_JABU_JABUS_BELLY_MQ_AFTER_BIG_OCTO_GRASS_2, RAND_INF_JABU_JABUS_BELLY_MQ_AFTER_BIG_OCTO_GRASS_2 }, - { RC_JABU_JABUS_BELLY_MQ_FALLING_LIKE_LIKE_GRASS, RAND_INF_JABU_JABUS_BELLY_MQ_FALLING_LIKE_LIKE_GRASS }, - { RC_JABU_JABUS_BELLY_MQ_BASEMENT_BOOMERANG_GRASS, RAND_INF_JABU_JABUS_BELLY_MQ_BASEMENT_BOOMERANG_GRASS }, - { RC_JABU_JABUS_BELLY_MQ_BEFORE_BOSS_GRASS_1, RAND_INF_JABU_JABUS_BELLY_MQ_BEFORE_BOSS_GRASS_1 }, - { RC_JABU_JABUS_BELLY_MQ_BEFORE_BOSS_GRASS_2, RAND_INF_JABU_JABUS_BELLY_MQ_BEFORE_BOSS_GRASS_2 }, - { RC_BOTTOM_OF_THE_WELL_MQ_DEAD_HAND_GRASS_1, RAND_INF_BOTTOM_OF_THE_WELL_MQ_DEAD_HAND_GRASS_1 }, - { RC_BOTTOM_OF_THE_WELL_MQ_DEAD_HAND_GRASS_2, RAND_INF_BOTTOM_OF_THE_WELL_MQ_DEAD_HAND_GRASS_2 }, - { RC_BOTTOM_OF_THE_WELL_MQ_DEAD_HAND_GRASS_3, RAND_INF_BOTTOM_OF_THE_WELL_MQ_DEAD_HAND_GRASS_3 }, - { RC_BOTTOM_OF_THE_WELL_MQ_DEAD_HAND_GRASS_4, RAND_INF_BOTTOM_OF_THE_WELL_MQ_DEAD_HAND_GRASS_4 }, + { RC_DEKU_TREE_MQ_BASEMENT_SPIKE_ROLLER_BACK_GRASS_1, RAND_INF_DEKU_TREE_MQ_BASEMENT_SPIKE_ROLLER_BACK_GRASS_1 }, + { RC_DEKU_TREE_MQ_BASEMENT_SPIKE_ROLLER_BACK_GRASS_2, RAND_INF_DEKU_TREE_MQ_BASEMENT_SPIKE_ROLLER_BACK_GRASS_2 }, + { RC_DEKU_TREE_MQ_BASEMENT_TORCHES_GRASS_1, RAND_INF_DEKU_TREE_MQ_BASEMENT_TORCHES_GRASS_1 }, + { RC_DEKU_TREE_MQ_BASEMENT_TORCHES_GRASS_2, RAND_INF_DEKU_TREE_MQ_BASEMENT_TORCHES_GRASS_2 }, + { RC_DEKU_TREE_MQ_BASEMENT_TORCHES_GRASS_3, RAND_INF_DEKU_TREE_MQ_BASEMENT_TORCHES_GRASS_3 }, + { RC_DEKU_TREE_MQ_BASEMENT_TORCHES_GRASS_4, RAND_INF_DEKU_TREE_MQ_BASEMENT_TORCHES_GRASS_4 }, + { RC_DEKU_TREE_MQ_BASEMENT_LARVAE_GRASS_1, RAND_INF_DEKU_TREE_MQ_BASEMENT_LARVAE_GRASS_1 }, + { RC_DEKU_TREE_MQ_BASEMENT_LARVAE_GRASS_2, RAND_INF_DEKU_TREE_MQ_BASEMENT_LARVAE_GRASS_2 }, + { RC_DEKU_TREE_MQ_BASEMENT_GRAVES_GRASS_1, RAND_INF_DEKU_TREE_MQ_BASEMENT_GRAVES_GRASS_1 }, + { RC_DEKU_TREE_MQ_BASEMENT_GRAVES_GRASS_2, RAND_INF_DEKU_TREE_MQ_BASEMENT_GRAVES_GRASS_2 }, + { RC_DEKU_TREE_MQ_BASEMENT_GRAVES_GRASS_3, RAND_INF_DEKU_TREE_MQ_BASEMENT_GRAVES_GRASS_3 }, + { RC_DEKU_TREE_MQ_BASEMENT_GRAVES_GRASS_4, RAND_INF_DEKU_TREE_MQ_BASEMENT_GRAVES_GRASS_4 }, + { RC_DEKU_TREE_MQ_BASEMENT_GRAVES_GRASS_5, RAND_INF_DEKU_TREE_MQ_BASEMENT_GRAVES_GRASS_5 }, + { RC_DEKU_TREE_MQ_BASEMENT_BACK_GRASS_1, RAND_INF_DEKU_TREE_MQ_BASEMENT_BACK_GRASS_1 }, + { RC_DEKU_TREE_MQ_BASEMENT_BACK_GRASS_2, RAND_INF_DEKU_TREE_MQ_BASEMENT_BACK_GRASS_2 }, + { RC_DEKU_TREE_MQ_BASEMENT_BACK_GRASS_3, RAND_INF_DEKU_TREE_MQ_BASEMENT_BACK_GRASS_3 }, + { RC_DEKU_TREE_MQ_BEFORE_BOSS_GRASS_1, RAND_INF_DEKU_TREE_MQ_BEFORE_BOSS_GRASS_1 }, + { RC_DEKU_TREE_MQ_BEFORE_BOSS_GRASS_2, RAND_INF_DEKU_TREE_MQ_BEFORE_BOSS_GRASS_2 }, + { RC_DEKU_TREE_MQ_BEFORE_BOSS_GRASS_3, RAND_INF_DEKU_TREE_MQ_BEFORE_BOSS_GRASS_3 }, + { RC_DODONGOS_CAVERN_MQ_COMPASS_GRASS_1, RAND_INF_DODONGOS_CAVERN_MQ_COMPASS_GRASS_1 }, + { RC_DODONGOS_CAVERN_MQ_COMPASS_GRASS_2, RAND_INF_DODONGOS_CAVERN_MQ_COMPASS_GRASS_2 }, + { RC_DODONGOS_CAVERN_MQ_COMPASS_GRASS_3, RAND_INF_DODONGOS_CAVERN_MQ_COMPASS_GRASS_3 }, + { RC_DODONGOS_CAVERN_MQ_COMPASS_GRASS_4, RAND_INF_DODONGOS_CAVERN_MQ_COMPASS_GRASS_4 }, + { RC_DODONGOS_CAVERN_MQ_ARMOS_GRASS, RAND_INF_DODONGOS_CAVERN_MQ_ARMOS_GRASS }, + { RC_DODONGOS_CAVERN_MQ_BACK_POE_GRASS, RAND_INF_DODONGOS_CAVERN_MQ_BACK_POE_GRASS }, + { RC_DODONGOS_CAVERN_MQ_SCRUB_GRASS_1, RAND_INF_DODONGOS_CAVERN_MQ_SCRUB_GRASS_1 }, + { RC_DODONGOS_CAVERN_MQ_SCRUB_GRASS_2, RAND_INF_DODONGOS_CAVERN_MQ_SCRUB_GRASS_2 }, + { RC_JABU_JABUS_BELLY_MQ_FIRST_GRASS_1, RAND_INF_JABU_JABUS_BELLY_MQ_FIRST_GRASS_1 }, + { RC_JABU_JABUS_BELLY_MQ_FIRST_GRASS_2, RAND_INF_JABU_JABUS_BELLY_MQ_FIRST_GRASS_2 }, + { RC_JABU_JABUS_BELLY_MQ_PIT_GRASS_1, RAND_INF_JABU_JABUS_BELLY_MQ_PIT_GRASS_1 }, + { RC_JABU_JABUS_BELLY_MQ_PIT_GRASS_2, RAND_INF_JABU_JABUS_BELLY_MQ_PIT_GRASS_2 }, + { RC_JABU_JABUS_BELLY_MQ_BASEMENT_GRASS_1, RAND_INF_JABU_JABUS_BELLY_MQ_BASEMENT_GRASS_1 }, + { RC_JABU_JABUS_BELLY_MQ_BASEMENT_GRASS_2, RAND_INF_JABU_JABUS_BELLY_MQ_BASEMENT_GRASS_2 }, + { RC_JABU_JABUS_BELLY_MQ_BASEMENT_GRASS_3, RAND_INF_JABU_JABUS_BELLY_MQ_BASEMENT_GRASS_3 }, + { RC_JABU_JABUS_BELLY_MQ_WIGGLERS_GRASS, RAND_INF_JABU_JABUS_BELLY_MQ_WIGGLERS_GRASS }, + { RC_JABU_JABUS_BELLY_MQ_AFTER_BIG_OCTO_GRASS_1, RAND_INF_JABU_JABUS_BELLY_MQ_AFTER_BIG_OCTO_GRASS_1 }, + { RC_JABU_JABUS_BELLY_MQ_AFTER_BIG_OCTO_GRASS_2, RAND_INF_JABU_JABUS_BELLY_MQ_AFTER_BIG_OCTO_GRASS_2 }, + { RC_JABU_JABUS_BELLY_MQ_FALLING_LIKE_LIKE_GRASS, RAND_INF_JABU_JABUS_BELLY_MQ_FALLING_LIKE_LIKE_GRASS }, + { RC_JABU_JABUS_BELLY_MQ_BASEMENT_BOOMERANG_GRASS, RAND_INF_JABU_JABUS_BELLY_MQ_BASEMENT_BOOMERANG_GRASS }, + { RC_JABU_JABUS_BELLY_MQ_BEFORE_BOSS_GRASS_1, RAND_INF_JABU_JABUS_BELLY_MQ_BEFORE_BOSS_GRASS_1 }, + { RC_JABU_JABUS_BELLY_MQ_BEFORE_BOSS_GRASS_2, RAND_INF_JABU_JABUS_BELLY_MQ_BEFORE_BOSS_GRASS_2 }, + { RC_BOTTOM_OF_THE_WELL_MQ_DEAD_HAND_GRASS_1, RAND_INF_BOTTOM_OF_THE_WELL_MQ_DEAD_HAND_GRASS_1 }, + { RC_BOTTOM_OF_THE_WELL_MQ_DEAD_HAND_GRASS_2, RAND_INF_BOTTOM_OF_THE_WELL_MQ_DEAD_HAND_GRASS_2 }, + { RC_BOTTOM_OF_THE_WELL_MQ_DEAD_HAND_GRASS_3, RAND_INF_BOTTOM_OF_THE_WELL_MQ_DEAD_HAND_GRASS_3 }, + { RC_BOTTOM_OF_THE_WELL_MQ_DEAD_HAND_GRASS_4, RAND_INF_BOTTOM_OF_THE_WELL_MQ_DEAD_HAND_GRASS_4 }, // Shared Dungeon Grass - { RC_DEKU_TREE_QUEEN_GOHMA_GRASS_1, RAND_INF_DEKU_TREE_QUEEN_GOHMA_GRASS_1 }, - { RC_DEKU_TREE_QUEEN_GOHMA_GRASS_2, RAND_INF_DEKU_TREE_QUEEN_GOHMA_GRASS_2 }, - { RC_DEKU_TREE_QUEEN_GOHMA_GRASS_3, RAND_INF_DEKU_TREE_QUEEN_GOHMA_GRASS_3 }, - { RC_DEKU_TREE_QUEEN_GOHMA_GRASS_4, RAND_INF_DEKU_TREE_QUEEN_GOHMA_GRASS_4 }, - { RC_DEKU_TREE_QUEEN_GOHMA_GRASS_5, RAND_INF_DEKU_TREE_QUEEN_GOHMA_GRASS_5 }, - { RC_DEKU_TREE_QUEEN_GOHMA_GRASS_6, RAND_INF_DEKU_TREE_QUEEN_GOHMA_GRASS_6 }, - { RC_DEKU_TREE_QUEEN_GOHMA_GRASS_7, RAND_INF_DEKU_TREE_QUEEN_GOHMA_GRASS_7 }, - { RC_DEKU_TREE_QUEEN_GOHMA_GRASS_8, RAND_INF_DEKU_TREE_QUEEN_GOHMA_GRASS_8 }, - // End Grass - - { RC_KF_LINKS_HOUSE_POT, RAND_INF_KF_LINKS_HOUSE_POT }, - { RC_KF_TWINS_HOUSE_POT_1, RAND_INF_KF_TWINS_HOUSE_POT_1 }, - { RC_KF_TWINS_HOUSE_POT_2, RAND_INF_KF_TWINS_HOUSE_POT_2 }, - { RC_KF_BROTHERS_HOUSE_POT_1, RAND_INF_KF_BROTHERS_HOUSE_POT_1 }, - { RC_KF_BROTHERS_HOUSE_POT_2, RAND_INF_KF_BROTHERS_HOUSE_POT_2 }, - { RC_GF_BREAK_ROOM_POT_1, RAND_INF_GF_BREAK_ROOM_POT_1 }, - { RC_GF_BREAK_ROOM_POT_2, RAND_INF_GF_BREAK_ROOM_POT_2 }, - { RC_GF_KITCHEN_POT_1, RAND_INF_GF_KITCHEN_POT_1 }, - { RC_GF_KITCHEN_POT_2, RAND_INF_GF_KITCHEN_POT_2 }, - { RC_GF_NORTH_F1_CARPENTER_POT_1, RAND_INF_GF_NORTH_F1_CARPENTER_POT_1 }, - { RC_GF_NORTH_F1_CARPENTER_POT_2, RAND_INF_GF_NORTH_F1_CARPENTER_POT_2 }, - { RC_GF_NORTH_F1_CARPENTER_POT_3, RAND_INF_GF_NORTH_F1_CARPENTER_POT_3 }, - { RC_GF_NORTH_F2_CARPENTER_POT_1, RAND_INF_GF_NORTH_F2_CARPENTER_POT_1 }, - { RC_GF_NORTH_F2_CARPENTER_POT_2, RAND_INF_GF_NORTH_F2_CARPENTER_POT_2 }, - { RC_GF_SOUTH_F1_CARPENTER_POT_1, RAND_INF_GF_SOUTH_F1_CARPENTER_POT_1 }, - { RC_GF_SOUTH_F1_CARPENTER_POT_2, RAND_INF_GF_SOUTH_F1_CARPENTER_POT_2 }, - { RC_GF_SOUTH_F1_CARPENTER_POT_3, RAND_INF_GF_SOUTH_F1_CARPENTER_POT_3 }, - { RC_GF_SOUTH_F1_CARPENTER_CELL_POT_1, RAND_INF_GF_SOUTH_F1_CARPENTER_CELL_POT_1 }, - { RC_GF_SOUTH_F1_CARPENTER_CELL_POT_2, RAND_INF_GF_SOUTH_F1_CARPENTER_CELL_POT_2 }, - { RC_GF_SOUTH_F1_CARPENTER_CELL_POT_3, RAND_INF_GF_SOUTH_F1_CARPENTER_CELL_POT_3 }, - { RC_GF_SOUTH_F1_CARPENTER_CELL_POT_4, RAND_INF_GF_SOUTH_F1_CARPENTER_CELL_POT_4 }, - { RC_WASTELAND_NEAR_GS_POT_1, RAND_INF_WASTELAND_NEAR_GS_POT_1 }, - { RC_WASTELAND_NEAR_GS_POT_2, RAND_INF_WASTELAND_NEAR_GS_POT_2 }, - { RC_WASTELAND_NEAR_GS_POT_3, RAND_INF_WASTELAND_NEAR_GS_POT_3 }, - { RC_WASTELAND_NEAR_GS_POT_4, RAND_INF_WASTELAND_NEAR_GS_POT_4 }, - { RC_MK_GUARD_HOUSE_CHILD_POT_1, RAND_INF_MK_GUARD_HOUSE_CHILD_POT_1 }, - { RC_MK_GUARD_HOUSE_CHILD_POT_2, RAND_INF_MK_GUARD_HOUSE_CHILD_POT_2 }, - { RC_MK_GUARD_HOUSE_CHILD_POT_3, RAND_INF_MK_GUARD_HOUSE_CHILD_POT_3 }, - { RC_MK_GUARD_HOUSE_CHILD_POT_4, RAND_INF_MK_GUARD_HOUSE_CHILD_POT_4 }, - { RC_MK_GUARD_HOUSE_CHILD_POT_5, RAND_INF_MK_GUARD_HOUSE_CHILD_POT_5 }, - { RC_MK_GUARD_HOUSE_CHILD_POT_6, RAND_INF_MK_GUARD_HOUSE_CHILD_POT_6 }, - { RC_MK_GUARD_HOUSE_CHILD_POT_7, RAND_INF_MK_GUARD_HOUSE_CHILD_POT_7 }, - { RC_MK_GUARD_HOUSE_CHILD_POT_8, RAND_INF_MK_GUARD_HOUSE_CHILD_POT_8 }, - { RC_MK_GUARD_HOUSE_CHILD_POT_9, RAND_INF_MK_GUARD_HOUSE_CHILD_POT_9 }, - { RC_MK_GUARD_HOUSE_CHILD_POT_10, RAND_INF_MK_GUARD_HOUSE_CHILD_POT_10 }, - { RC_MK_GUARD_HOUSE_CHILD_POT_11, RAND_INF_MK_GUARD_HOUSE_CHILD_POT_11 }, - { RC_MK_GUARD_HOUSE_CHILD_POT_12, RAND_INF_MK_GUARD_HOUSE_CHILD_POT_12 }, - { RC_MK_GUARD_HOUSE_CHILD_POT_13, RAND_INF_MK_GUARD_HOUSE_CHILD_POT_13 }, - { RC_MK_GUARD_HOUSE_CHILD_POT_14, RAND_INF_MK_GUARD_HOUSE_CHILD_POT_14 }, - { RC_MK_GUARD_HOUSE_CHILD_POT_15, RAND_INF_MK_GUARD_HOUSE_CHILD_POT_15 }, - { RC_MK_GUARD_HOUSE_CHILD_POT_16, RAND_INF_MK_GUARD_HOUSE_CHILD_POT_16 }, - { RC_MK_GUARD_HOUSE_CHILD_POT_17, RAND_INF_MK_GUARD_HOUSE_CHILD_POT_17 }, - { RC_MK_GUARD_HOUSE_CHILD_POT_18, RAND_INF_MK_GUARD_HOUSE_CHILD_POT_18 }, - { RC_MK_GUARD_HOUSE_CHILD_POT_19, RAND_INF_MK_GUARD_HOUSE_CHILD_POT_19 }, - { RC_MK_GUARD_HOUSE_CHILD_POT_20, RAND_INF_MK_GUARD_HOUSE_CHILD_POT_20 }, - { RC_MK_GUARD_HOUSE_CHILD_POT_21, RAND_INF_MK_GUARD_HOUSE_CHILD_POT_21 }, - { RC_MK_GUARD_HOUSE_CHILD_POT_22, RAND_INF_MK_GUARD_HOUSE_CHILD_POT_22 }, - { RC_MK_GUARD_HOUSE_CHILD_POT_23, RAND_INF_MK_GUARD_HOUSE_CHILD_POT_23 }, - { RC_MK_GUARD_HOUSE_CHILD_POT_24, RAND_INF_MK_GUARD_HOUSE_CHILD_POT_24 }, - { RC_MK_GUARD_HOUSE_CHILD_POT_25, RAND_INF_MK_GUARD_HOUSE_CHILD_POT_25 }, - { RC_MK_GUARD_HOUSE_CHILD_POT_26, RAND_INF_MK_GUARD_HOUSE_CHILD_POT_26 }, - { RC_MK_GUARD_HOUSE_CHILD_POT_27, RAND_INF_MK_GUARD_HOUSE_CHILD_POT_27 }, - { RC_MK_GUARD_HOUSE_CHILD_POT_28, RAND_INF_MK_GUARD_HOUSE_CHILD_POT_28 }, - { RC_MK_GUARD_HOUSE_CHILD_POT_29, RAND_INF_MK_GUARD_HOUSE_CHILD_POT_29 }, - { RC_MK_GUARD_HOUSE_CHILD_POT_30, RAND_INF_MK_GUARD_HOUSE_CHILD_POT_30 }, - { RC_MK_GUARD_HOUSE_CHILD_POT_31, RAND_INF_MK_GUARD_HOUSE_CHILD_POT_31 }, - { RC_MK_GUARD_HOUSE_CHILD_POT_32, RAND_INF_MK_GUARD_HOUSE_CHILD_POT_32 }, - { RC_MK_GUARD_HOUSE_CHILD_POT_33, RAND_INF_MK_GUARD_HOUSE_CHILD_POT_33 }, - { RC_MK_GUARD_HOUSE_CHILD_POT_34, RAND_INF_MK_GUARD_HOUSE_CHILD_POT_34 }, - { RC_MK_GUARD_HOUSE_CHILD_POT_35, RAND_INF_MK_GUARD_HOUSE_CHILD_POT_35 }, - { RC_MK_GUARD_HOUSE_CHILD_POT_36, RAND_INF_MK_GUARD_HOUSE_CHILD_POT_36 }, - { RC_MK_GUARD_HOUSE_CHILD_POT_37, RAND_INF_MK_GUARD_HOUSE_CHILD_POT_37 }, - { RC_MK_GUARD_HOUSE_CHILD_POT_38, RAND_INF_MK_GUARD_HOUSE_CHILD_POT_38 }, - { RC_MK_GUARD_HOUSE_CHILD_POT_39, RAND_INF_MK_GUARD_HOUSE_CHILD_POT_39 }, - { RC_MK_GUARD_HOUSE_CHILD_POT_40, RAND_INF_MK_GUARD_HOUSE_CHILD_POT_40 }, - { RC_MK_GUARD_HOUSE_CHILD_POT_41, RAND_INF_MK_GUARD_HOUSE_CHILD_POT_41 }, - { RC_MK_GUARD_HOUSE_CHILD_POT_42, RAND_INF_MK_GUARD_HOUSE_CHILD_POT_42 }, - { RC_MK_GUARD_HOUSE_CHILD_POT_43, RAND_INF_MK_GUARD_HOUSE_CHILD_POT_43 }, - { RC_MK_GUARD_HOUSE_CHILD_POT_44, RAND_INF_MK_GUARD_HOUSE_CHILD_POT_44 }, - { RC_MK_GUARD_HOUSE_ADULT_POT_1, RAND_INF_MK_GUARD_HOUSE_ADULT_POT_1 }, - { RC_MK_GUARD_HOUSE_ADULT_POT_2, RAND_INF_MK_GUARD_HOUSE_ADULT_POT_2 }, - { RC_MK_GUARD_HOUSE_ADULT_POT_3, RAND_INF_MK_GUARD_HOUSE_ADULT_POT_3 }, - { RC_MK_GUARD_HOUSE_ADULT_POT_4, RAND_INF_MK_GUARD_HOUSE_ADULT_POT_4 }, - { RC_MK_GUARD_HOUSE_ADULT_POT_5, RAND_INF_MK_GUARD_HOUSE_ADULT_POT_5 }, - { RC_MK_GUARD_HOUSE_ADULT_POT_6, RAND_INF_MK_GUARD_HOUSE_ADULT_POT_6 }, - { RC_MK_GUARD_HOUSE_ADULT_POT_7, RAND_INF_MK_GUARD_HOUSE_ADULT_POT_7 }, - { RC_MK_GUARD_HOUSE_ADULT_POT_8, RAND_INF_MK_GUARD_HOUSE_ADULT_POT_8 }, - { RC_MK_GUARD_HOUSE_ADULT_POT_9, RAND_INF_MK_GUARD_HOUSE_ADULT_POT_9 }, - { RC_MK_GUARD_HOUSE_ADULT_POT_10, RAND_INF_MK_GUARD_HOUSE_ADULT_POT_10 }, - { RC_MK_GUARD_HOUSE_ADULT_POT_11, RAND_INF_MK_GUARD_HOUSE_ADULT_POT_11 }, - { RC_MK_BACK_ALLEY_HOUSE_POT_1, RAND_INF_MK_BACK_ALLEY_HOUSE_POT_1 }, - { RC_MK_BACK_ALLEY_HOUSE_POT_2, RAND_INF_MK_BACK_ALLEY_HOUSE_POT_2 }, - { RC_MK_BACK_ALLEY_HOUSE_POT_3, RAND_INF_MK_BACK_ALLEY_HOUSE_POT_3 }, - { RC_KAK_NEAR_POTION_SHOP_POT_1, RAND_INF_KAK_NEAR_POTION_SHOP_POT_1 }, - { RC_KAK_NEAR_POTION_SHOP_POT_2, RAND_INF_KAK_NEAR_POTION_SHOP_POT_2 }, - { RC_KAK_NEAR_POTION_SHOP_POT_3, RAND_INF_KAK_NEAR_POTION_SHOP_POT_3 }, - { RC_KAK_NEAR_IMPAS_HOUSE_POT_1, RAND_INF_KAK_NEAR_IMPAS_HOUSE_POT_1 }, - { RC_KAK_NEAR_IMPAS_HOUSE_POT_2, RAND_INF_KAK_NEAR_IMPAS_HOUSE_POT_2 }, - { RC_KAK_NEAR_IMPAS_HOUSE_POT_3, RAND_INF_KAK_NEAR_IMPAS_HOUSE_POT_3 }, - { RC_KAK_NEAR_GUARDS_HOUSE_POT_1, RAND_INF_KAK_NEAR_GUARDS_HOUSE_POT_1 }, - { RC_KAK_NEAR_GUARDS_HOUSE_POT_2, RAND_INF_KAK_NEAR_GUARDS_HOUSE_POT_2 }, - { RC_KAK_NEAR_GUARDS_HOUSE_POT_3, RAND_INF_KAK_NEAR_GUARDS_HOUSE_POT_3 }, - { RC_KAK_NEAR_MEDICINE_SHOP_POT_1, RAND_INF_KAK_NEAR_MEDICINE_SHOP_POT_1 }, - { RC_KAK_NEAR_MEDICINE_SHOP_POT_2, RAND_INF_KAK_NEAR_MEDICINE_SHOP_POT_2 }, - { RC_GY_DAMPES_GRAVE_POT_1, RAND_INF_GY_DAMPES_GRAVE_POT_1 }, - { RC_GY_DAMPES_GRAVE_POT_2, RAND_INF_GY_DAMPES_GRAVE_POT_2 }, - { RC_GY_DAMPES_GRAVE_POT_3, RAND_INF_GY_DAMPES_GRAVE_POT_3 }, - { RC_GY_DAMPES_GRAVE_POT_4, RAND_INF_GY_DAMPES_GRAVE_POT_4 }, - { RC_GY_DAMPES_GRAVE_POT_5, RAND_INF_GY_DAMPES_GRAVE_POT_5 }, - { RC_GY_DAMPES_GRAVE_POT_6, RAND_INF_GY_DAMPES_GRAVE_POT_6 }, - { RC_GC_LOWER_STAIRCASE_POT_1, RAND_INF_GC_LOWER_STAIRCASE_POT_1 }, - { RC_GC_LOWER_STAIRCASE_POT_2, RAND_INF_GC_LOWER_STAIRCASE_POT_2 }, - { RC_GC_UPPER_STAIRCASE_POT_1, RAND_INF_GC_UPPER_STAIRCASE_POT_1 }, - { RC_GC_UPPER_STAIRCASE_POT_2, RAND_INF_GC_UPPER_STAIRCASE_POT_2 }, - { RC_GC_UPPER_STAIRCASE_POT_3, RAND_INF_GC_UPPER_STAIRCASE_POT_3 }, - { RC_GC_MEDIGORON_POT_1, RAND_INF_GC_MEDIGORON_POT_1 }, - { RC_GC_DARUNIA_POT_1, RAND_INF_GC_DARUNIA_POT_1 }, - { RC_GC_DARUNIA_POT_2, RAND_INF_GC_DARUNIA_POT_2 }, - { RC_GC_DARUNIA_POT_3, RAND_INF_GC_DARUNIA_POT_3 }, - { RC_DMC_NEAR_GC_POT_1, RAND_INF_DMC_NEAR_GC_POT_1 }, - { RC_DMC_NEAR_GC_POT_2, RAND_INF_DMC_NEAR_GC_POT_2 }, - { RC_DMC_NEAR_GC_POT_3, RAND_INF_DMC_NEAR_GC_POT_3 }, - { RC_DMC_NEAR_GC_POT_4, RAND_INF_DMC_NEAR_GC_POT_4 }, - { RC_ZD_NEAR_SHOP_POT_1, RAND_INF_ZD_NEAR_SHOP_POT_1 }, - { RC_ZD_NEAR_SHOP_POT_2, RAND_INF_ZD_NEAR_SHOP_POT_2 }, - { RC_ZD_NEAR_SHOP_POT_3, RAND_INF_ZD_NEAR_SHOP_POT_3 }, - { RC_ZD_NEAR_SHOP_POT_4, RAND_INF_ZD_NEAR_SHOP_POT_4 }, - { RC_ZD_NEAR_SHOP_POT_5, RAND_INF_ZD_NEAR_SHOP_POT_5 }, - { RC_ZF_HIDDEN_CAVE_POT_1, RAND_INF_ZF_HIDDEN_CAVE_POT_1 }, - { RC_ZF_HIDDEN_CAVE_POT_2, RAND_INF_ZF_HIDDEN_CAVE_POT_2 }, - { RC_ZF_HIDDEN_CAVE_POT_3, RAND_INF_ZF_HIDDEN_CAVE_POT_3 }, - { RC_ZF_NEAR_JABU_POT_1, RAND_INF_ZF_NEAR_JABU_POT_1 }, - { RC_ZF_NEAR_JABU_POT_2, RAND_INF_ZF_NEAR_JABU_POT_2 }, - { RC_ZF_NEAR_JABU_POT_3, RAND_INF_ZF_NEAR_JABU_POT_3 }, - { RC_ZF_NEAR_JABU_POT_4, RAND_INF_ZF_NEAR_JABU_POT_4 }, - { RC_LLR_FRONT_POT_1, RAND_INF_LLR_FRONT_POT_1 }, - { RC_LLR_FRONT_POT_2, RAND_INF_LLR_FRONT_POT_2 }, - { RC_LLR_FRONT_POT_3, RAND_INF_LLR_FRONT_POT_3 }, - { RC_LLR_FRONT_POT_4, RAND_INF_LLR_FRONT_POT_4 }, - { RC_LLR_RAIN_SHED_POT_1, RAND_INF_LLR_RAIN_SHED_POT_1 }, - { RC_LLR_RAIN_SHED_POT_2, RAND_INF_LLR_RAIN_SHED_POT_2 }, - { RC_LLR_RAIN_SHED_POT_3, RAND_INF_LLR_RAIN_SHED_POT_3 }, - { RC_LLR_TALONS_HOUSE_POT_1, RAND_INF_LLR_TALONS_HOUSE_POT_1 }, - { RC_LLR_TALONS_HOUSE_POT_2, RAND_INF_LLR_TALONS_HOUSE_POT_2 }, - { RC_LLR_TALONS_HOUSE_POT_3, RAND_INF_LLR_TALONS_HOUSE_POT_3 }, - { RC_HF_COW_GROTTO_POT_1, RAND_INF_HF_COW_GROTTO_POT_1 }, - { RC_HF_COW_GROTTO_POT_2, RAND_INF_HF_COW_GROTTO_POT_2 }, - { RC_HC_STORMS_GROTTO_POT_1, RAND_INF_HC_STORMS_GROTTO_POT_1 }, - { RC_HC_STORMS_GROTTO_POT_2, RAND_INF_HC_STORMS_GROTTO_POT_2 }, - { RC_HC_STORMS_GROTTO_POT_3, RAND_INF_HC_STORMS_GROTTO_POT_3 }, - { RC_HC_STORMS_GROTTO_POT_4, RAND_INF_HC_STORMS_GROTTO_POT_4 }, - { RC_DODONGOS_CAVERN_LIZALFOS_POT_1, RAND_INF_DODONGOS_CAVERN_LIZALFOS_POT_1 }, - { RC_DODONGOS_CAVERN_LIZALFOS_POT_2, RAND_INF_DODONGOS_CAVERN_LIZALFOS_POT_2 }, - { RC_DODONGOS_CAVERN_LIZALFOS_POT_3, RAND_INF_DODONGOS_CAVERN_LIZALFOS_POT_3 }, - { RC_DODONGOS_CAVERN_LIZALFOS_POT_4, RAND_INF_DODONGOS_CAVERN_LIZALFOS_POT_4 }, - { RC_DODONGOS_CAVERN_SIDE_ROOM_POT_1, RAND_INF_DODONGOS_CAVERN_SIDE_ROOM_POT_1 }, - { RC_DODONGOS_CAVERN_SIDE_ROOM_POT_2, RAND_INF_DODONGOS_CAVERN_SIDE_ROOM_POT_2 }, - { RC_DODONGOS_CAVERN_SIDE_ROOM_POT_3, RAND_INF_DODONGOS_CAVERN_SIDE_ROOM_POT_3 }, - { RC_DODONGOS_CAVERN_SIDE_ROOM_POT_4, RAND_INF_DODONGOS_CAVERN_SIDE_ROOM_POT_4 }, - { RC_DODONGOS_CAVERN_SIDE_ROOM_POT_5, RAND_INF_DODONGOS_CAVERN_SIDE_ROOM_POT_5 }, - { RC_DODONGOS_CAVERN_SIDE_ROOM_POT_6, RAND_INF_DODONGOS_CAVERN_SIDE_ROOM_POT_6 }, - { RC_DODONGOS_CAVERN_TORCH_ROOM_POT_1, RAND_INF_DODONGOS_CAVERN_TORCH_ROOM_POT_1 }, - { RC_DODONGOS_CAVERN_TORCH_ROOM_POT_2, RAND_INF_DODONGOS_CAVERN_TORCH_ROOM_POT_2 }, - { RC_DODONGOS_CAVERN_TORCH_ROOM_POT_3, RAND_INF_DODONGOS_CAVERN_TORCH_ROOM_POT_3 }, - { RC_DODONGOS_CAVERN_TORCH_ROOM_POT_4, RAND_INF_DODONGOS_CAVERN_TORCH_ROOM_POT_4 }, - { RC_DODONGOS_CAVERN_STAIRCASE_POT_1, RAND_INF_DODONGOS_CAVERN_STAIRCASE_POT_1 }, - { RC_DODONGOS_CAVERN_STAIRCASE_POT_2, RAND_INF_DODONGOS_CAVERN_STAIRCASE_POT_2 }, - { RC_DODONGOS_CAVERN_STAIRCASE_POT_3, RAND_INF_DODONGOS_CAVERN_STAIRCASE_POT_3 }, - { RC_DODONGOS_CAVERN_STAIRCASE_POT_4, RAND_INF_DODONGOS_CAVERN_STAIRCASE_POT_4 }, - { RC_DODONGOS_CAVERN_SINGLE_EYE_POT_1, RAND_INF_DODONGOS_CAVERN_SINGLE_EYE_POT_1 }, - { RC_DODONGOS_CAVERN_SINGLE_EYE_POT_2, RAND_INF_DODONGOS_CAVERN_SINGLE_EYE_POT_2 }, - { RC_DODONGOS_CAVERN_BLADE_POT_1, RAND_INF_DODONGOS_CAVERN_BLADE_POT_1 }, - { RC_DODONGOS_CAVERN_BLADE_POT_2, RAND_INF_DODONGOS_CAVERN_BLADE_POT_2 }, - { RC_DODONGOS_CAVERN_DOUBLE_EYE_POT_1, RAND_INF_DODONGOS_CAVERN_DOUBLE_EYE_POT_1 }, - { RC_DODONGOS_CAVERN_DOUBLE_EYE_POT_2, RAND_INF_DODONGOS_CAVERN_DOUBLE_EYE_POT_2 }, - { RC_DODONGOS_CAVERN_BACK_ROOM_POT_1, RAND_INF_DODONGOS_CAVERN_BACK_ROOM_POT_1 }, - { RC_DODONGOS_CAVERN_BACK_ROOM_POT_2, RAND_INF_DODONGOS_CAVERN_BACK_ROOM_POT_2 }, - { RC_DODONGOS_CAVERN_BACK_ROOM_POT_3, RAND_INF_DODONGOS_CAVERN_BACK_ROOM_POT_3 }, - { RC_DODONGOS_CAVERN_BACK_ROOM_POT_4, RAND_INF_DODONGOS_CAVERN_BACK_ROOM_POT_4 }, - { RC_JABU_JABUS_BELLY_ABOVE_BIG_OCTO_POT_1, RAND_INF_JABU_JABUS_BELLY_ABOVE_BIG_OCTO_POT_1 }, - { RC_JABU_JABUS_BELLY_ABOVE_BIG_OCTO_POT_2, RAND_INF_JABU_JABUS_BELLY_ABOVE_BIG_OCTO_POT_2 }, - { RC_JABU_JABUS_BELLY_ABOVE_BIG_OCTO_POT_3, RAND_INF_JABU_JABUS_BELLY_ABOVE_BIG_OCTO_POT_3 }, - { RC_JABU_JABUS_BELLY_BARINADE_POT_1, RAND_INF_JABU_JABUS_BELLY_BARINADE_POT_1 }, - { RC_JABU_JABUS_BELLY_BARINADE_POT_2, RAND_INF_JABU_JABUS_BELLY_BARINADE_POT_2 }, - { RC_JABU_JABUS_BELLY_BARINADE_POT_3, RAND_INF_JABU_JABUS_BELLY_BARINADE_POT_3 }, - { RC_JABU_JABUS_BELLY_BARINADE_POT_4, RAND_INF_JABU_JABUS_BELLY_BARINADE_POT_4 }, - { RC_JABU_JABUS_BELLY_BARINADE_POT_5, RAND_INF_JABU_JABUS_BELLY_BARINADE_POT_5 }, - { RC_JABU_JABUS_BELLY_BARINADE_POT_6, RAND_INF_JABU_JABUS_BELLY_BARINADE_POT_6 }, - { RC_JABU_JABUS_BELLY_BASEMENT_POT_1, RAND_INF_JABU_JABUS_BELLY_BASEMENT_POT_1 }, - { RC_JABU_JABUS_BELLY_BASEMENT_POT_2, RAND_INF_JABU_JABUS_BELLY_BASEMENT_POT_2 }, - { RC_JABU_JABUS_BELLY_BASEMENT_POT_3, RAND_INF_JABU_JABUS_BELLY_BASEMENT_POT_3 }, - { RC_JABU_JABUS_BELLY_TWO_OCTOROK_POT_1, RAND_INF_JABU_JABUS_BELLY_TWO_OCTOROK_POT_1 }, - { RC_JABU_JABUS_BELLY_TWO_OCTOROK_POT_2, RAND_INF_JABU_JABUS_BELLY_TWO_OCTOROK_POT_2 }, - { RC_JABU_JABUS_BELLY_TWO_OCTOROK_POT_3, RAND_INF_JABU_JABUS_BELLY_TWO_OCTOROK_POT_3 }, - { RC_JABU_JABUS_BELLY_TWO_OCTOROK_POT_4, RAND_INF_JABU_JABUS_BELLY_TWO_OCTOROK_POT_4 }, - { RC_JABU_JABUS_BELLY_TWO_OCTOROK_POT_5, RAND_INF_JABU_JABUS_BELLY_TWO_OCTOROK_POT_5 }, - { RC_FOREST_TEMPLE_LOBBY_POT_1, RAND_INF_FOREST_TEMPLE_LOBBY_POT_1 }, - { RC_FOREST_TEMPLE_LOBBY_POT_2, RAND_INF_FOREST_TEMPLE_LOBBY_POT_2 }, - { RC_FOREST_TEMPLE_LOBBY_POT_3, RAND_INF_FOREST_TEMPLE_LOBBY_POT_3 }, - { RC_FOREST_TEMPLE_LOBBY_POT_4, RAND_INF_FOREST_TEMPLE_LOBBY_POT_4 }, - { RC_FOREST_TEMPLE_LOBBY_POT_5, RAND_INF_FOREST_TEMPLE_LOBBY_POT_5 }, - { RC_FOREST_TEMPLE_LOBBY_POT_6, RAND_INF_FOREST_TEMPLE_LOBBY_POT_6 }, - { RC_FOREST_TEMPLE_LOWER_STALFOS_POT_1, RAND_INF_FOREST_TEMPLE_LOWER_STALFOS_POT_1 }, - { RC_FOREST_TEMPLE_LOWER_STALFOS_POT_2, RAND_INF_FOREST_TEMPLE_LOWER_STALFOS_POT_2 }, - { RC_FOREST_TEMPLE_GREEN_POE_POT_1, RAND_INF_FOREST_TEMPLE_GREEN_POE_POT_1 }, - { RC_FOREST_TEMPLE_GREEN_POE_POT_2, RAND_INF_FOREST_TEMPLE_GREEN_POE_POT_2 }, - { RC_FOREST_TEMPLE_UPPER_STALFOS_POT_1, RAND_INF_FOREST_TEMPLE_UPPER_STALFOS_POT_1 }, - { RC_FOREST_TEMPLE_UPPER_STALFOS_POT_2, RAND_INF_FOREST_TEMPLE_UPPER_STALFOS_POT_2 }, - { RC_FOREST_TEMPLE_UPPER_STALFOS_POT_3, RAND_INF_FOREST_TEMPLE_UPPER_STALFOS_POT_3 }, - { RC_FOREST_TEMPLE_UPPER_STALFOS_POT_4, RAND_INF_FOREST_TEMPLE_UPPER_STALFOS_POT_4 }, - { RC_FOREST_TEMPLE_BLUE_POE_POT_1, RAND_INF_FOREST_TEMPLE_BLUE_POE_POT_1 }, - { RC_FOREST_TEMPLE_BLUE_POE_POT_2, RAND_INF_FOREST_TEMPLE_BLUE_POE_POT_2 }, - { RC_FOREST_TEMPLE_BLUE_POE_POT_3, RAND_INF_FOREST_TEMPLE_BLUE_POE_POT_3 }, - { RC_FOREST_TEMPLE_FROZEN_EYE_POT_1, RAND_INF_FOREST_TEMPLE_FROZEN_EYE_POT_1 }, - { RC_FOREST_TEMPLE_FROZEN_EYE_POT_2, RAND_INF_FOREST_TEMPLE_FROZEN_EYE_POT_2 }, - { RC_FIRE_TEMPLE_NEAR_BOSS_POT_1, RAND_INF_FIRE_TEMPLE_NEAR_BOSS_POT_1 }, - { RC_FIRE_TEMPLE_NEAR_BOSS_POT_2, RAND_INF_FIRE_TEMPLE_NEAR_BOSS_POT_2 }, - { RC_FIRE_TEMPLE_NEAR_BOSS_POT_3, RAND_INF_FIRE_TEMPLE_NEAR_BOSS_POT_3 }, - { RC_FIRE_TEMPLE_NEAR_BOSS_POT_4, RAND_INF_FIRE_TEMPLE_NEAR_BOSS_POT_4 }, - { RC_FIRE_TEMPLE_BIG_LAVA_POT_1, RAND_INF_FIRE_TEMPLE_BIG_LAVA_POT_1 }, - { RC_FIRE_TEMPLE_BIG_LAVA_POT_2, RAND_INF_FIRE_TEMPLE_BIG_LAVA_POT_2 }, - { RC_FIRE_TEMPLE_BIG_LAVA_POT_3, RAND_INF_FIRE_TEMPLE_BIG_LAVA_POT_3 }, - { RC_FIRE_TEMPLE_FLAME_MAZE_LEFT_POT_1, RAND_INF_FIRE_TEMPLE_FLAME_MAZE_LEFT_POT_1 }, - { RC_FIRE_TEMPLE_FLAME_MAZE_LEFT_POT_2, RAND_INF_FIRE_TEMPLE_FLAME_MAZE_LEFT_POT_2 }, - { RC_FIRE_TEMPLE_FLAME_MAZE_LEFT_POT_3, RAND_INF_FIRE_TEMPLE_FLAME_MAZE_LEFT_POT_3 }, - { RC_FIRE_TEMPLE_FLAME_MAZE_LEFT_POT_4, RAND_INF_FIRE_TEMPLE_FLAME_MAZE_LEFT_POT_4 }, - { RC_FIRE_TEMPLE_FLAME_MAZE_RIGHT_POT_1, RAND_INF_FIRE_TEMPLE_FLAME_MAZE_RIGHT_POT_1 }, - { RC_FIRE_TEMPLE_FLAME_MAZE_RIGHT_POT_2, RAND_INF_FIRE_TEMPLE_FLAME_MAZE_RIGHT_POT_2 }, - { RC_FIRE_TEMPLE_FLAME_MAZE_RIGHT_POT_3, RAND_INF_FIRE_TEMPLE_FLAME_MAZE_RIGHT_POT_3 }, - { RC_FIRE_TEMPLE_FLAME_MAZE_RIGHT_POT_4, RAND_INF_FIRE_TEMPLE_FLAME_MAZE_RIGHT_POT_4 }, - { RC_WATER_TEMPLE_MAIN_LEVEL_2_POT_1, RAND_INF_WATER_TEMPLE_MAIN_LEVEL_2_POT_1 }, - { RC_WATER_TEMPLE_MAIN_LEVEL_2_POT_2, RAND_INF_WATER_TEMPLE_MAIN_LEVEL_2_POT_2 }, - { RC_WATER_TEMPLE_MAIN_LEVEL_1_POT_1, RAND_INF_WATER_TEMPLE_MAIN_LEVEL_1_POT_1 }, - { RC_WATER_TEMPLE_MAIN_LEVEL_1_POT_2, RAND_INF_WATER_TEMPLE_MAIN_LEVEL_1_POT_2 }, - { RC_WATER_TEMPLE_TORCH_POT_1, RAND_INF_WATER_TEMPLE_TORCH_POT_1 }, - { RC_WATER_TEMPLE_TORCH_POT_2, RAND_INF_WATER_TEMPLE_TORCH_POT_2 }, - { RC_WATER_TEMPLE_NEAR_COMPASS_POT_1, RAND_INF_WATER_TEMPLE_NEAR_COMPASS_POT_1 }, - { RC_WATER_TEMPLE_NEAR_COMPASS_POT_2, RAND_INF_WATER_TEMPLE_NEAR_COMPASS_POT_2 }, - { RC_WATER_TEMPLE_NEAR_COMPASS_POT_3, RAND_INF_WATER_TEMPLE_NEAR_COMPASS_POT_3 }, - { RC_WATER_TEMPLE_CENTRAL_BOW_POT_1, RAND_INF_WATER_TEMPLE_CENTRAL_BOW_POT_1 }, - { RC_WATER_TEMPLE_CENTRAL_BOW_POT_2, RAND_INF_WATER_TEMPLE_CENTRAL_BOW_POT_2 }, - { RC_WATER_TEMPLE_BEHIND_GATE_POT_1, RAND_INF_WATER_TEMPLE_BEHIND_GATE_POT_1 }, - { RC_WATER_TEMPLE_BEHIND_GATE_POT_2, RAND_INF_WATER_TEMPLE_BEHIND_GATE_POT_2 }, - { RC_WATER_TEMPLE_BEHIND_GATE_POT_3, RAND_INF_WATER_TEMPLE_BEHIND_GATE_POT_3 }, - { RC_WATER_TEMPLE_BEHIND_GATE_POT_4, RAND_INF_WATER_TEMPLE_BEHIND_GATE_POT_4 }, - { RC_WATER_TEMPLE_BASEMENT_BLOCK_PUZZLE_POT_1, RAND_INF_WATER_TEMPLE_BASEMENT_BLOCK_PUZZLE_POT_1 }, - { RC_WATER_TEMPLE_BASEMENT_BLOCK_PUZZLE_POT_2, RAND_INF_WATER_TEMPLE_BASEMENT_BLOCK_PUZZLE_POT_2 }, - { RC_WATER_TEMPLE_RIVER_POT_1, RAND_INF_WATER_TEMPLE_RIVER_POT_1 }, - { RC_WATER_TEMPLE_RIVER_POT_2, RAND_INF_WATER_TEMPLE_RIVER_POT_2 }, - { RC_WATER_TEMPLE_LIKE_LIKE_POT_1, RAND_INF_WATER_TEMPLE_LIKE_LIKE_POT_1 }, - { RC_WATER_TEMPLE_LIKE_LIKE_POT_2, RAND_INF_WATER_TEMPLE_LIKE_LIKE_POT_2 }, - { RC_WATER_TEMPLE_BOSS_KEY_POT_1, RAND_INF_WATER_TEMPLE_BOSS_KEY_POT_1 }, - { RC_WATER_TEMPLE_BOSS_KEY_POT_2, RAND_INF_WATER_TEMPLE_BOSS_KEY_POT_2 }, - { RC_SHADOW_TEMPLE_NEAR_DEAD_HAND_POT_1, RAND_INF_SHADOW_TEMPLE_NEAR_DEAD_HAND_POT_1 }, - { RC_SHADOW_TEMPLE_WHISPERING_WALLS_POT_1, RAND_INF_SHADOW_TEMPLE_WHISPERING_WALLS_POT_1 }, - { RC_SHADOW_TEMPLE_WHISPERING_WALLS_POT_2, RAND_INF_SHADOW_TEMPLE_WHISPERING_WALLS_POT_2 }, - { RC_SHADOW_TEMPLE_WHISPERING_WALLS_POT_3, RAND_INF_SHADOW_TEMPLE_WHISPERING_WALLS_POT_3 }, - { RC_SHADOW_TEMPLE_WHISPERING_WALLS_POT_4, RAND_INF_SHADOW_TEMPLE_WHISPERING_WALLS_POT_4 }, - { RC_SHADOW_TEMPLE_WHISPERING_WALLS_POT_5, RAND_INF_SHADOW_TEMPLE_WHISPERING_WALLS_POT_5 }, - { RC_SHADOW_TEMPLE_MAP_CHEST_POT_1, RAND_INF_SHADOW_TEMPLE_MAP_CHEST_POT_1 }, - { RC_SHADOW_TEMPLE_MAP_CHEST_POT_2, RAND_INF_SHADOW_TEMPLE_MAP_CHEST_POT_2 }, - { RC_SHADOW_TEMPLE_FALLING_SPIKES_POT_1, RAND_INF_SHADOW_TEMPLE_FALLING_SPIKES_POT_1 }, - { RC_SHADOW_TEMPLE_FALLING_SPIKES_POT_2, RAND_INF_SHADOW_TEMPLE_FALLING_SPIKES_POT_2 }, - { RC_SHADOW_TEMPLE_FALLING_SPIKES_POT_3, RAND_INF_SHADOW_TEMPLE_FALLING_SPIKES_POT_3 }, - { RC_SHADOW_TEMPLE_FALLING_SPIKES_POT_4, RAND_INF_SHADOW_TEMPLE_FALLING_SPIKES_POT_4 }, - { RC_SHADOW_TEMPLE_AFTER_WIND_POT_1, RAND_INF_SHADOW_TEMPLE_AFTER_WIND_POT_1 }, - { RC_SHADOW_TEMPLE_AFTER_WIND_POT_2, RAND_INF_SHADOW_TEMPLE_AFTER_WIND_POT_2 }, - { RC_SHADOW_TEMPLE_SPIKE_WALLS_POT_1, RAND_INF_SHADOW_TEMPLE_SPIKE_WALLS_POT_1 }, - { RC_SHADOW_TEMPLE_FLOORMASTER_POT_1, RAND_INF_SHADOW_TEMPLE_FLOORMASTER_POT_1 }, - { RC_SHADOW_TEMPLE_FLOORMASTER_POT_2, RAND_INF_SHADOW_TEMPLE_FLOORMASTER_POT_2 }, - { RC_SHADOW_TEMPLE_AFTER_BOAT_POT_1, RAND_INF_SHADOW_TEMPLE_AFTER_BOAT_POT_1 }, - { RC_SHADOW_TEMPLE_AFTER_BOAT_POT_2, RAND_INF_SHADOW_TEMPLE_AFTER_BOAT_POT_2 }, - { RC_SHADOW_TEMPLE_AFTER_BOAT_POT_3, RAND_INF_SHADOW_TEMPLE_AFTER_BOAT_POT_3 }, - { RC_SHADOW_TEMPLE_AFTER_BOAT_POT_4, RAND_INF_SHADOW_TEMPLE_AFTER_BOAT_POT_4 }, - { RC_SPIRIT_TEMPLE_LOBBY_POT_1, RAND_INF_SPIRIT_TEMPLE_LOBBY_POT_1 }, - { RC_SPIRIT_TEMPLE_LOBBY_POT_2, RAND_INF_SPIRIT_TEMPLE_LOBBY_POT_2 }, - { RC_SPIRIT_TEMPLE_ANUBIS_POT_1, RAND_INF_SPIRIT_TEMPLE_ANUBIS_POT_1 }, - { RC_SPIRIT_TEMPLE_ANUBIS_POT_2, RAND_INF_SPIRIT_TEMPLE_ANUBIS_POT_2 }, - { RC_SPIRIT_TEMPLE_ANUBIS_POT_3, RAND_INF_SPIRIT_TEMPLE_ANUBIS_POT_3 }, - { RC_SPIRIT_TEMPLE_ANUBIS_POT_4, RAND_INF_SPIRIT_TEMPLE_ANUBIS_POT_4 }, - { RC_SPIRIT_TEMPLE_CHILD_CLIMB_POT_1, RAND_INF_SPIRIT_TEMPLE_CHILD_CLIMB_POT_1 }, - { RC_SPIRIT_TEMPLE_AFTER_SUN_BLOCK_POT_1, RAND_INF_SPIRIT_TEMPLE_AFTER_SUN_BLOCK_POT_1 }, - { RC_SPIRIT_TEMPLE_AFTER_SUN_BLOCK_POT_2, RAND_INF_SPIRIT_TEMPLE_AFTER_SUN_BLOCK_POT_2 }, - { RC_SPIRIT_TEMPLE_CENTRAL_CHAMBER_POT_1, RAND_INF_SPIRIT_TEMPLE_CENTRAL_CHAMBER_POT_1 }, - { RC_SPIRIT_TEMPLE_CENTRAL_CHAMBER_POT_2, RAND_INF_SPIRIT_TEMPLE_CENTRAL_CHAMBER_POT_2 }, - { RC_SPIRIT_TEMPLE_CENTRAL_CHAMBER_POT_3, RAND_INF_SPIRIT_TEMPLE_CENTRAL_CHAMBER_POT_3 }, - { RC_SPIRIT_TEMPLE_CENTRAL_CHAMBER_POT_4, RAND_INF_SPIRIT_TEMPLE_CENTRAL_CHAMBER_POT_4 }, - { RC_SPIRIT_TEMPLE_CENTRAL_CHAMBER_POT_5, RAND_INF_SPIRIT_TEMPLE_CENTRAL_CHAMBER_POT_5 }, - { RC_SPIRIT_TEMPLE_CENTRAL_CHAMBER_POT_6, RAND_INF_SPIRIT_TEMPLE_CENTRAL_CHAMBER_POT_6 }, - { RC_SPIRIT_TEMPLE_BEAMOS_HALL_POT_1, RAND_INF_SPIRIT_TEMPLE_BEAMOS_HALL_POT_1 }, - { RC_GANONS_CASTLE_FOREST_TRIAL_POT_1, RAND_INF_GANONS_CASTLE_FOREST_TRIAL_POT_1 }, - { RC_GANONS_CASTLE_FOREST_TRIAL_POT_2, RAND_INF_GANONS_CASTLE_FOREST_TRIAL_POT_2 }, - { RC_GANONS_CASTLE_FIRE_TRIAL_POT_1, RAND_INF_GANONS_CASTLE_FIRE_TRIAL_POT_1 }, - { RC_GANONS_CASTLE_FIRE_TRIAL_POT_2, RAND_INF_GANONS_CASTLE_FIRE_TRIAL_POT_2 }, - { RC_GANONS_CASTLE_WATER_TRIAL_POT_1, RAND_INF_GANONS_CASTLE_WATER_TRIAL_POT_1 }, - { RC_GANONS_CASTLE_WATER_TRIAL_POT_2, RAND_INF_GANONS_CASTLE_WATER_TRIAL_POT_2 }, - { RC_GANONS_CASTLE_WATER_TRIAL_POT_3, RAND_INF_GANONS_CASTLE_WATER_TRIAL_POT_3 }, - { RC_GANONS_CASTLE_SHADOW_TRIAL_POT_1, RAND_INF_GANONS_CASTLE_SHADOW_TRIAL_POT_1 }, - { RC_GANONS_CASTLE_SHADOW_TRIAL_POT_2, RAND_INF_GANONS_CASTLE_SHADOW_TRIAL_POT_2 }, - { RC_GANONS_CASTLE_SHADOW_TRIAL_POT_3, RAND_INF_GANONS_CASTLE_SHADOW_TRIAL_POT_3 }, - { RC_GANONS_CASTLE_SHADOW_TRIAL_POT_4, RAND_INF_GANONS_CASTLE_SHADOW_TRIAL_POT_4 }, - { RC_GANONS_CASTLE_SPIRIT_TRIAL_POT_1, RAND_INF_GANONS_CASTLE_SPIRIT_TRIAL_POT_1 }, - { RC_GANONS_CASTLE_SPIRIT_TRIAL_POT_2, RAND_INF_GANONS_CASTLE_SPIRIT_TRIAL_POT_2 }, - { RC_GANONS_CASTLE_LIGHT_TRIAL_BOULDER_POT_1, RAND_INF_GANONS_CASTLE_LIGHT_TRIAL_BOULDER_POT_1 }, - { RC_GANONS_CASTLE_LIGHT_TRIAL_POT_1, RAND_INF_GANONS_CASTLE_LIGHT_TRIAL_POT_1 }, - { RC_GANONS_CASTLE_LIGHT_TRIAL_POT_2, RAND_INF_GANONS_CASTLE_LIGHT_TRIAL_POT_2 }, - { RC_GANONS_CASTLE_GANONS_TOWER_POT_1, RAND_INF_GANONS_CASTLE_GANONS_TOWER_POT_1 }, - { RC_GANONS_CASTLE_GANONS_TOWER_POT_2, RAND_INF_GANONS_CASTLE_GANONS_TOWER_POT_2 }, - { RC_GANONS_CASTLE_GANONS_TOWER_POT_3, RAND_INF_GANONS_CASTLE_GANONS_TOWER_POT_3 }, - { RC_GANONS_CASTLE_GANONS_TOWER_POT_4, RAND_INF_GANONS_CASTLE_GANONS_TOWER_POT_4 }, - { RC_GANONS_CASTLE_GANONS_TOWER_POT_5, RAND_INF_GANONS_CASTLE_GANONS_TOWER_POT_5 }, - { RC_GANONS_CASTLE_GANONS_TOWER_POT_6, RAND_INF_GANONS_CASTLE_GANONS_TOWER_POT_6 }, - { RC_GANONS_CASTLE_GANONS_TOWER_POT_7, RAND_INF_GANONS_CASTLE_GANONS_TOWER_POT_7 }, - { RC_GANONS_CASTLE_GANONS_TOWER_POT_8, RAND_INF_GANONS_CASTLE_GANONS_TOWER_POT_8 }, - { RC_GANONS_CASTLE_GANONS_TOWER_POT_9, RAND_INF_GANONS_CASTLE_GANONS_TOWER_POT_9 }, - { RC_GANONS_CASTLE_GANONS_TOWER_POT_10, RAND_INF_GANONS_CASTLE_GANONS_TOWER_POT_10 }, - { RC_GANONS_CASTLE_GANONS_TOWER_POT_11, RAND_INF_GANONS_CASTLE_GANONS_TOWER_POT_11 }, - { RC_GANONS_CASTLE_GANONS_TOWER_POT_12, RAND_INF_GANONS_CASTLE_GANONS_TOWER_POT_12 }, - { RC_GANONS_CASTLE_GANONS_TOWER_POT_13, RAND_INF_GANONS_CASTLE_GANONS_TOWER_POT_13 }, - { RC_GANONS_CASTLE_GANONS_TOWER_POT_14, RAND_INF_GANONS_CASTLE_GANONS_TOWER_POT_14 }, - { RC_GANONS_CASTLE_GANONS_TOWER_POT_15, RAND_INF_GANONS_CASTLE_GANONS_TOWER_POT_15 }, - { RC_GANONS_CASTLE_GANONS_TOWER_POT_16, RAND_INF_GANONS_CASTLE_GANONS_TOWER_POT_16 }, - { RC_GANONS_CASTLE_GANONS_TOWER_POT_17, RAND_INF_GANONS_CASTLE_GANONS_TOWER_POT_17 }, - { RC_GANONS_CASTLE_GANONS_TOWER_POT_18, RAND_INF_GANONS_CASTLE_GANONS_TOWER_POT_18 }, - { RC_BOTTOM_OF_THE_WELL_BASEMENT_POT_1, RAND_INF_BOTTOM_OF_THE_WELL_BASEMENT_POT_1 }, - { RC_BOTTOM_OF_THE_WELL_BASEMENT_POT_2, RAND_INF_BOTTOM_OF_THE_WELL_BASEMENT_POT_2 }, - { RC_BOTTOM_OF_THE_WELL_BASEMENT_POT_3, RAND_INF_BOTTOM_OF_THE_WELL_BASEMENT_POT_3 }, - { RC_BOTTOM_OF_THE_WELL_BASEMENT_POT_4, RAND_INF_BOTTOM_OF_THE_WELL_BASEMENT_POT_4 }, - { RC_BOTTOM_OF_THE_WELL_BASEMENT_POT_5, RAND_INF_BOTTOM_OF_THE_WELL_BASEMENT_POT_5 }, - { RC_BOTTOM_OF_THE_WELL_BASEMENT_POT_6, RAND_INF_BOTTOM_OF_THE_WELL_BASEMENT_POT_6 }, - { RC_BOTTOM_OF_THE_WELL_BASEMENT_POT_7, RAND_INF_BOTTOM_OF_THE_WELL_BASEMENT_POT_7 }, - { RC_BOTTOM_OF_THE_WELL_BASEMENT_POT_8, RAND_INF_BOTTOM_OF_THE_WELL_BASEMENT_POT_8 }, - { RC_BOTTOM_OF_THE_WELL_BASEMENT_POT_9, RAND_INF_BOTTOM_OF_THE_WELL_BASEMENT_POT_9 }, - { RC_BOTTOM_OF_THE_WELL_BASEMENT_POT_10, RAND_INF_BOTTOM_OF_THE_WELL_BASEMENT_POT_10 }, - { RC_BOTTOM_OF_THE_WELL_BASEMENT_POT_11, RAND_INF_BOTTOM_OF_THE_WELL_BASEMENT_POT_11 }, - { RC_BOTTOM_OF_THE_WELL_BASEMENT_POT_12, RAND_INF_BOTTOM_OF_THE_WELL_BASEMENT_POT_12 }, - { RC_BOTTOM_OF_THE_WELL_LEFT_SIDE_POT_1, RAND_INF_BOTTOM_OF_THE_WELL_LEFT_SIDE_POT_1 }, - { RC_BOTTOM_OF_THE_WELL_LEFT_SIDE_POT_2, RAND_INF_BOTTOM_OF_THE_WELL_LEFT_SIDE_POT_2 }, - { RC_BOTTOM_OF_THE_WELL_LEFT_SIDE_POT_3, RAND_INF_BOTTOM_OF_THE_WELL_LEFT_SIDE_POT_3 }, - { RC_BOTTOM_OF_THE_WELL_NEAR_ENTRANCE_POT_1, RAND_INF_BOTTOM_OF_THE_WELL_NEAR_ENTRANCE_POT_1 }, - { RC_BOTTOM_OF_THE_WELL_NEAR_ENTRANCE_POT_2, RAND_INF_BOTTOM_OF_THE_WELL_NEAR_ENTRANCE_POT_2 }, - { RC_BOTTOM_OF_THE_WELL_FIRE_KEESE_POT_1, RAND_INF_BOTTOM_OF_THE_WELL_FIRE_KEESE_POT_1 }, - { RC_BOTTOM_OF_THE_WELL_UNDERWATER_POT, RAND_INF_BOTTOM_OF_THE_WELL_UNDERWATER_POT }, - { RC_ICE_CAVERN_HALL_POT_1, RAND_INF_ICE_CAVERN_HALL_POT_1 }, - { RC_ICE_CAVERN_HALL_POT_2, RAND_INF_ICE_CAVERN_HALL_POT_2 }, - { RC_ICE_CAVERN_SPINNING_BLADE_POT_1, RAND_INF_ICE_CAVERN_SPINNING_BLADE_POT_1 }, - { RC_ICE_CAVERN_SPINNING_BLADE_POT_2, RAND_INF_ICE_CAVERN_SPINNING_BLADE_POT_2 }, - { RC_ICE_CAVERN_SPINNING_BLADE_POT_3, RAND_INF_ICE_CAVERN_SPINNING_BLADE_POT_3 }, - { RC_ICE_CAVERN_NEAR_END_POT_1, RAND_INF_ICE_CAVERN_NEAR_END_POT_1 }, - { RC_ICE_CAVERN_NEAR_END_POT_2, RAND_INF_ICE_CAVERN_NEAR_END_POT_2 }, - { RC_ICE_CAVERN_FROZEN_POT_1, RAND_INF_ICE_CAVERN_FROZEN_POT_1 }, + { RC_DEKU_TREE_QUEEN_GOHMA_GRASS_1, RAND_INF_DEKU_TREE_QUEEN_GOHMA_GRASS_1 }, + { RC_DEKU_TREE_QUEEN_GOHMA_GRASS_2, RAND_INF_DEKU_TREE_QUEEN_GOHMA_GRASS_2 }, + { RC_DEKU_TREE_QUEEN_GOHMA_GRASS_3, RAND_INF_DEKU_TREE_QUEEN_GOHMA_GRASS_3 }, + { RC_DEKU_TREE_QUEEN_GOHMA_GRASS_4, RAND_INF_DEKU_TREE_QUEEN_GOHMA_GRASS_4 }, + { RC_DEKU_TREE_QUEEN_GOHMA_GRASS_5, RAND_INF_DEKU_TREE_QUEEN_GOHMA_GRASS_5 }, + { RC_DEKU_TREE_QUEEN_GOHMA_GRASS_6, RAND_INF_DEKU_TREE_QUEEN_GOHMA_GRASS_6 }, + { RC_DEKU_TREE_QUEEN_GOHMA_GRASS_7, RAND_INF_DEKU_TREE_QUEEN_GOHMA_GRASS_7 }, + { RC_DEKU_TREE_QUEEN_GOHMA_GRASS_8, RAND_INF_DEKU_TREE_QUEEN_GOHMA_GRASS_8 }, + // End Grass - { RC_JABU_JABUS_BELLY_MQ_ENTRANCE_POT_1, RAND_INF_JABU_JABUS_BELLY_MQ_ENTRANCE_POT_1 }, - { RC_JABU_JABUS_BELLY_MQ_ENTRANCE_POT_2, RAND_INF_JABU_JABUS_BELLY_MQ_ENTRANCE_POT_2 }, - { RC_JABU_JABUS_BELLY_MQ_GEYSER_POT_1, RAND_INF_JABU_JABUS_BELLY_MQ_GEYSER_POT_1 }, - { RC_JABU_JABUS_BELLY_MQ_GEYSER_POT_2, RAND_INF_JABU_JABUS_BELLY_MQ_GEYSER_POT_2 }, - { RC_JABU_JABUS_BELLY_MQ_TIME_BLOCK_POT_1, RAND_INF_JABU_JABUS_BELLY_MQ_TIME_BLOCK_POT_1 }, - { RC_JABU_JABUS_BELLY_MQ_TIME_BLOCK_POT_2, RAND_INF_JABU_JABUS_BELLY_MQ_TIME_BLOCK_POT_2 }, - { RC_JABU_JABUS_BELLY_MQ_LIKE_LIKES_POT_1, RAND_INF_JABU_JABUS_BELLY_MQ_LIKE_LIKES_POT_1 }, - { RC_JABU_JABUS_BELLY_MQ_LIKE_LIKES_POT_2, RAND_INF_JABU_JABUS_BELLY_MQ_LIKE_LIKES_POT_2 }, - { RC_JABU_JABUS_BELLY_MQ_BEFORE_BOSS_POT_1, RAND_INF_JABU_JABUS_BELLY_MQ_BEFORE_BOSS_POT_1 }, - { RC_FOREST_TEMPLE_MQ_LOBBY_POT_1, RAND_INF_FOREST_TEMPLE_MQ_LOBBY_POT_1 }, - { RC_FOREST_TEMPLE_MQ_LOBBY_POT_2, RAND_INF_FOREST_TEMPLE_MQ_LOBBY_POT_2 }, - { RC_FOREST_TEMPLE_MQ_LOBBY_POT_3, RAND_INF_FOREST_TEMPLE_MQ_LOBBY_POT_3 }, - { RC_FOREST_TEMPLE_MQ_LOBBY_POT_4, RAND_INF_FOREST_TEMPLE_MQ_LOBBY_POT_4 }, - { RC_FOREST_TEMPLE_MQ_LOBBY_POT_5, RAND_INF_FOREST_TEMPLE_MQ_LOBBY_POT_5 }, - { RC_FOREST_TEMPLE_MQ_LOBBY_POT_6, RAND_INF_FOREST_TEMPLE_MQ_LOBBY_POT_6 }, - { RC_FOREST_TEMPLE_MQ_WOLFOS_POT_1, RAND_INF_FOREST_TEMPLE_MQ_LOWER_STALFOS_POT_1 }, - { RC_FOREST_TEMPLE_MQ_WOLFOS_POT_2, RAND_INF_FOREST_TEMPLE_MQ_LOWER_STALFOS_POT_2 }, - { RC_FOREST_TEMPLE_MQ_UPPER_STALFOS_POT_1, RAND_INF_FOREST_TEMPLE_MQ_UPPER_STALFOS_POT_1 }, - { RC_FOREST_TEMPLE_MQ_UPPER_STALFOS_POT_2, RAND_INF_FOREST_TEMPLE_MQ_UPPER_STALFOS_POT_2 }, - { RC_FOREST_TEMPLE_MQ_UPPER_STALFOS_POT_3, RAND_INF_FOREST_TEMPLE_MQ_UPPER_STALFOS_POT_3 }, - { RC_FOREST_TEMPLE_MQ_UPPER_STALFOS_POT_4, RAND_INF_FOREST_TEMPLE_MQ_UPPER_STALFOS_POT_4 }, - { RC_FOREST_TEMPLE_MQ_BLUE_POE_POT_1, RAND_INF_FOREST_TEMPLE_MQ_BLUE_POE_POT_1 }, - { RC_FOREST_TEMPLE_MQ_BLUE_POE_POT_2, RAND_INF_FOREST_TEMPLE_MQ_BLUE_POE_POT_2 }, - { RC_FOREST_TEMPLE_MQ_BLUE_POE_POT_3, RAND_INF_FOREST_TEMPLE_MQ_BLUE_POE_POT_3 }, - { RC_FOREST_TEMPLE_MQ_GREEN_POE_POT_1, RAND_INF_FOREST_TEMPLE_MQ_GREEN_POE_POT_1 }, - { RC_FOREST_TEMPLE_MQ_GREEN_POE_POT_2, RAND_INF_FOREST_TEMPLE_MQ_GREEN_POE_POT_2 }, - { RC_FOREST_TEMPLE_MQ_BASEMENT_POT_1, RAND_INF_FOREST_TEMPLE_MQ_BASEMENT_POT_1 }, - { RC_FOREST_TEMPLE_MQ_BASEMENT_POT_2, RAND_INF_FOREST_TEMPLE_MQ_BASEMENT_POT_2 }, - { RC_FOREST_TEMPLE_MQ_BASEMENT_POT_3, RAND_INF_FOREST_TEMPLE_MQ_BASEMENT_POT_3 }, - { RC_FOREST_TEMPLE_MQ_BASEMENT_POT_4, RAND_INF_FOREST_TEMPLE_MQ_BASEMENT_POT_4 }, - { RC_DODONGOS_CAVERN_MQ_RIGHT_SIDE_POT_1, RAND_INF_DODONGOS_CAVERN_MQ_RIGHT_SIDE_POT_1 }, - { RC_DODONGOS_CAVERN_MQ_RIGHT_SIDE_POT_2, RAND_INF_DODONGOS_CAVERN_MQ_RIGHT_SIDE_POT_2 }, - { RC_DODONGOS_CAVERN_MQ_RIGHT_SIDE_POT_3, RAND_INF_DODONGOS_CAVERN_MQ_RIGHT_SIDE_POT_3 }, - { RC_DODONGOS_CAVERN_MQ_RIGHT_SIDE_POT_4, RAND_INF_DODONGOS_CAVERN_MQ_RIGHT_SIDE_POT_4 }, - { RC_DODONGOS_CAVERN_MQ_UPPER_LIZALFOS_POT_1, RAND_INF_DODONGOS_CAVERN_MQ_UPPER_LIZALFOS_POT_1 }, - { RC_DODONGOS_CAVERN_MQ_UPPER_LIZALFOS_POT_2, RAND_INF_DODONGOS_CAVERN_MQ_UPPER_LIZALFOS_POT_2 }, - { RC_DODONGOS_CAVERN_MQ_UPPER_LIZALFOS_POT_3, RAND_INF_DODONGOS_CAVERN_MQ_UPPER_LIZALFOS_POT_3 }, - { RC_DODONGOS_CAVERN_MQ_UPPER_LIZALFOS_POT_4, RAND_INF_DODONGOS_CAVERN_MQ_UPPER_LIZALFOS_POT_4 }, - { RC_DODONGOS_CAVERN_MQ_POE_ROOM_POT_1, RAND_INF_DODONGOS_CAVERN_MQ_POE_ROOM_POT_1 }, - { RC_DODONGOS_CAVERN_MQ_POE_ROOM_POT_2, RAND_INF_DODONGOS_CAVERN_MQ_POE_ROOM_POT_2 }, - { RC_DODONGOS_CAVERN_MQ_POE_ROOM_POT_3, RAND_INF_DODONGOS_CAVERN_MQ_POE_ROOM_POT_3 }, - { RC_DODONGOS_CAVERN_MQ_POE_ROOM_POT_4, RAND_INF_DODONGOS_CAVERN_MQ_POE_ROOM_POT_4 }, - { RC_DODONGOS_CAVERN_MQ_TORCH_PUZZLE_CORNER_POT, RAND_INF_DODONGOS_CAVERN_MQ_BLOCK_ROOM_POT_1 }, - { RC_DODONGOS_CAVERN_MQ_TORCH_PUZZLE_MIDDLE_POT, RAND_INF_DODONGOS_CAVERN_MQ_BLOCK_ROOM_POT_2 }, - { RC_DODONGOS_CAVERN_MQ_TWO_FLAMES_POT_1, RAND_INF_DODONGOS_CAVERN_MQ_TWO_FLAMES_POT_1 }, - { RC_DODONGOS_CAVERN_MQ_TWO_FLAMES_POT_2, RAND_INF_DODONGOS_CAVERN_MQ_TWO_FLAMES_POT_2 }, - { RC_DODONGOS_CAVERN_MQ_BIG_BLOCK_POT_1, RAND_INF_DODONGOS_CAVERN_MQ_SILVER_BLOCK_POT_1 }, - { RC_DODONGOS_CAVERN_MQ_BIG_BLOCK_POT_2, RAND_INF_DODONGOS_CAVERN_MQ_SILVER_BLOCK_POT_2 }, - { RC_DODONGOS_CAVERN_MQ_STAIRCASE_POT_1, RAND_INF_DODONGOS_CAVERN_MQ_STAIRCASE_POT_1 }, - { RC_DODONGOS_CAVERN_MQ_STAIRCASE_POT_2, RAND_INF_DODONGOS_CAVERN_MQ_STAIRCASE_POT_2 }, - { RC_DODONGOS_CAVERN_MQ_STAIRCASE_POT_3, RAND_INF_DODONGOS_CAVERN_MQ_STAIRCASE_POT_3 }, - { RC_DODONGOS_CAVERN_MQ_STAIRCASE_POT_4, RAND_INF_DODONGOS_CAVERN_MQ_STAIRCASE_POT_4 }, - { RC_DODONGOS_CAVERN_MQ_ARMOS_ROOM_NW_POT, RAND_INF_DODONGOS_CAVERN_MQ_ARMOS_POT_1 }, - { RC_DODONGOS_CAVERN_MQ_ARMOS_ROOM_NE_POT, RAND_INF_DODONGOS_CAVERN_MQ_ARMOS_POT_2 }, - { RC_DODONGOS_CAVERN_MQ_ARMOS_ROOM_SE_POT, RAND_INF_DODONGOS_CAVERN_MQ_ARMOS_POT_3 }, - { RC_DODONGOS_CAVERN_MQ_ARMOS_ROOM_SW_POT, RAND_INF_DODONGOS_CAVERN_MQ_ARMOS_POT_4 }, - { RC_DODONGOS_CAVERN_MQ_BEFORE_BOSS_SW_POT, RAND_INF_DODONGOS_CAVERN_MQ_BEFORE_BOSS_POT_1 }, - { RC_DODONGOS_CAVERN_MQ_BEFORE_BOSS_NE_POT, RAND_INF_DODONGOS_CAVERN_MQ_BEFORE_BOSS_POT_2 }, - { RC_DODONGOS_CAVERN_MQ_BACKROOM_POT_1, RAND_INF_DODONGOS_CAVERN_MQ_BACKROOM_POT_1 }, - { RC_DODONGOS_CAVERN_MQ_BACKROOM_POT_2, RAND_INF_DODONGOS_CAVERN_MQ_BACKROOM_POT_2 }, - { RC_GANONS_CASTLE_MQ_FOREST_TRIAL_POT_1, RAND_INF_GANONS_CASTLE_MQ_FOREST_TRIAL_POT_1 }, - { RC_GANONS_CASTLE_MQ_FOREST_TRIAL_POT_2, RAND_INF_GANONS_CASTLE_MQ_FOREST_TRIAL_POT_2 }, - { RC_GANONS_CASTLE_MQ_WATER_TRIAL_POT_1, RAND_INF_GANONS_CASTLE_MQ_WATER_TRIAL_POT_1 }, - { RC_GANONS_CASTLE_MQ_WATER_TRIAL_POT_2, RAND_INF_GANONS_CASTLE_MQ_WATER_TRIAL_POT_2 }, - { RC_GANONS_CASTLE_MQ_SHADOW_TRIAL_POT_1, RAND_INF_GANONS_CASTLE_MQ_SHADOW_TRIAL_POT_1 }, - { RC_GANONS_CASTLE_MQ_SHADOW_TRIAL_POT_2, RAND_INF_GANONS_CASTLE_MQ_SHADOW_TRIAL_POT_2 }, - { RC_GANONS_CASTLE_MQ_FIRE_TRIAL_POT_1, RAND_INF_GANONS_CASTLE_MQ_FIRE_TRIAL_POT_1 }, - { RC_GANONS_CASTLE_MQ_FIRE_TRIAL_POT_2, RAND_INF_GANONS_CASTLE_MQ_FIRE_TRIAL_POT_2 }, - { RC_GANONS_CASTLE_MQ_LIGHT_TRIAL_POT_1, RAND_INF_GANONS_CASTLE_MQ_LIGHT_TRIAL_POT_1 }, - { RC_GANONS_CASTLE_MQ_LIGHT_TRIAL_POT_2, RAND_INF_GANONS_CASTLE_MQ_LIGHT_TRIAL_POT_2 }, - { RC_GANONS_CASTLE_MQ_SPIRIT_TRIAL_POT_1, RAND_INF_GANONS_CASTLE_MQ_SPIRIT_TRIAL_POT_1 }, - { RC_GANONS_CASTLE_MQ_SPIRIT_TRIAL_POT_2, RAND_INF_GANONS_CASTLE_MQ_SPIRIT_TRIAL_POT_2 }, - { RC_SHADOW_TEMPLE_MQ_WHISPERING_WALLS_POT_1, RAND_INF_SHADOW_TEMPLE_MQ_WHISPERING_WALLS_POT_1 }, - { RC_SHADOW_TEMPLE_MQ_WHISPERING_WALLS_POT_2, RAND_INF_SHADOW_TEMPLE_MQ_WHISPERING_WALLS_POT_2 }, - { RC_SHADOW_TEMPLE_MQ_ENTRANCE_REDEAD_POT_1, RAND_INF_SHADOW_TEMPLE_MQ_ENTRANCE_REDEAD_POT_1 }, - { RC_SHADOW_TEMPLE_MQ_ENTRANCE_REDEAD_POT_2, RAND_INF_SHADOW_TEMPLE_MQ_ENTRANCE_REDEAD_POT_2 }, - { RC_SHADOW_TEMPLE_MQ_LOWER_UMBRELLA_WEST_POT, RAND_INF_SHADOW_TEMPLE_MQ_FALLING_SPIKES_POT_1 }, - { RC_SHADOW_TEMPLE_MQ_LOWER_UMBRELLA_EAST_POT, RAND_INF_SHADOW_TEMPLE_MQ_FALLING_SPIKES_POT_2 }, - { RC_SHADOW_TEMPLE_MQ_UPPER_UMBRELLA_SOUTH_POT, RAND_INF_SHADOW_TEMPLE_MQ_FALLING_SPIKES_POT_3 }, - { RC_SHADOW_TEMPLE_MQ_UPPER_UMBRELLA_NORTH_POT, RAND_INF_SHADOW_TEMPLE_MQ_FALLING_SPIKES_POT_4 }, - { RC_SHADOW_TEMPLE_MQ_BEFORE_BOAT_POT_1, RAND_INF_SHADOW_TEMPLE_MQ_BEFORE_BOAT_POT_1 }, - { RC_SHADOW_TEMPLE_MQ_BEFORE_BOAT_POT_2, RAND_INF_SHADOW_TEMPLE_MQ_BEFORE_BOAT_POT_2 }, - { RC_SHADOW_TEMPLE_MQ_BEFORE_CHASM_WEST_POT, RAND_INF_SHADOW_TEMPLE_MQ_AFTER_BOAT_POT_1 }, - { RC_SHADOW_TEMPLE_MQ_BEFORE_CHASM_EAST_POT, RAND_INF_SHADOW_TEMPLE_MQ_AFTER_BOAT_POT_2 }, - { RC_SHADOW_TEMPLE_MQ_AFTER_CHASM_WEST_POT, RAND_INF_SHADOW_TEMPLE_MQ_AFTER_BOAT_POT_3 }, - { RC_SHADOW_TEMPLE_MQ_AFTER_CHASM_EAST_POT, RAND_INF_SHADOW_TEMPLE_MQ_AFTER_BOAT_POT_4 }, - { RC_SHADOW_TEMPLE_MQ_SPIKE_BARICADE_POT, RAND_INF_SHADOW_TEMPLE_MQ_SPIKE_BARICADE_POT }, - { RC_SHADOW_TEMPLE_MQ_DEAD_HAND_POT_1, RAND_INF_SHADOW_TEMPLE_MQ_DEAD_HAND_POT_1 }, - { RC_SHADOW_TEMPLE_MQ_DEAD_HAND_POT_2, RAND_INF_SHADOW_TEMPLE_MQ_DEAD_HAND_POT_2 }, - { RC_BOTTOM_OF_THE_WELL_MQ_INNER_LOBBY_POT_1, RAND_INF_BOTTOM_OF_THE_WELL_MQ_INNER_LOBBY_POT_1 }, - { RC_BOTTOM_OF_THE_WELL_MQ_INNER_LOBBY_POT_2, RAND_INF_BOTTOM_OF_THE_WELL_MQ_INNER_LOBBY_POT_2 }, - { RC_BOTTOM_OF_THE_WELL_MQ_INNER_LOBBY_POT_3, RAND_INF_BOTTOM_OF_THE_WELL_MQ_INNER_LOBBY_POT_3 }, - { RC_BOTTOM_OF_THE_WELL_MQ_OUTER_LOBBY_POT, RAND_INF_BOTTOM_OF_THE_WELL_MQ_OUTER_LOBBY_POT }, - { RC_BOTTOM_OF_THE_WELL_MQ_EAST_INNER_ROOM_POT_1, RAND_INF_BOTTOM_OF_THE_WELL_MQ_SOUTH_KEY_POT_1 }, - { RC_BOTTOM_OF_THE_WELL_MQ_EAST_INNER_ROOM_POT_2, RAND_INF_BOTTOM_OF_THE_WELL_MQ_SOUTH_KEY_POT_2 }, - { RC_BOTTOM_OF_THE_WELL_MQ_EAST_INNER_ROOM_POT_3, RAND_INF_BOTTOM_OF_THE_WELL_MQ_SOUTH_KEY_POT_3 }, - { RC_FIRE_TEMPLE_MQ_ENTRANCE_POT_1, RAND_INF_FIRE_TEMPLE_MQ_ENTRANCE_POT_1 }, - { RC_FIRE_TEMPLE_MQ_ENTRANCE_POT_2, RAND_INF_FIRE_TEMPLE_MQ_ENTRANCE_POT_2 }, - { RC_FIRE_TEMPLE_MQ_OUTSIDE_BOSS_POT_1, RAND_INF_FIRE_TEMPLE_MQ_OUTSIDE_BOSS_POT_1 }, - { RC_FIRE_TEMPLE_MQ_OUTSIDE_BOSS_POT_2, RAND_INF_FIRE_TEMPLE_MQ_OUTSIDE_BOSS_POT_2 }, - { RC_FIRE_TEMPLE_MQ_LAVA_ROOM_NORTH_POT, RAND_INF_FIRE_TEMPLE_MQ_LAVA_POT_1 }, - { RC_FIRE_TEMPLE_MQ_LAVA_ROOM_HIGH_POT, RAND_INF_FIRE_TEMPLE_MQ_LAVA_POT_2 }, - { RC_FIRE_TEMPLE_MQ_LAVA_ROOM_SOUTH_POT, RAND_INF_FIRE_TEMPLE_MQ_LAVA_POT_3 }, - { RC_FIRE_TEMPLE_MQ_LAVA_TORCH_POT_1, RAND_INF_FIRE_TEMPLE_MQ_LAVA_TORCH_POT_1 }, - { RC_FIRE_TEMPLE_MQ_LAVA_TORCH_POT_2, RAND_INF_FIRE_TEMPLE_MQ_LAVA_TORCH_POT_2 }, - { RC_FIRE_TEMPLE_MQ_ABOVE_LAVA_POT_1, RAND_INF_FIRE_TEMPLE_MQ_ABOVE_LAVA_POT_1 }, - { RC_FIRE_TEMPLE_MQ_ABOVE_LAVA_POT_2, RAND_INF_FIRE_TEMPLE_MQ_ABOVE_LAVA_POT_2 }, - { RC_FIRE_TEMPLE_MQ_ABOVE_LAVA_POT_3, RAND_INF_FIRE_TEMPLE_MQ_ABOVE_LAVA_POT_3 }, - { RC_FIRE_TEMPLE_MQ_FLAME_WALL_POT_1, RAND_INF_FIRE_TEMPLE_MQ_FLAME_WALL_POT_1 }, - { RC_FIRE_TEMPLE_MQ_FLAME_WALL_POT_2, RAND_INF_FIRE_TEMPLE_MQ_FLAME_WALL_POT_2 }, - { RC_FIRE_TEMPLE_MQ_PAST_FIRE_MAZE_SOUTH_POT, RAND_INF_FIRE_TEMPLE_MQ_FIRE_MAZE_POT_1 }, - { RC_FIRE_TEMPLE_MQ_PAST_FIRE_MAZE_NORTH_POT, RAND_INF_FIRE_TEMPLE_MQ_FIRE_MAZE_POT_2 }, - { RC_FIRE_TEMPLE_MQ_FIRE_MAZE_NORTHMOST_POT, RAND_INF_FIRE_TEMPLE_MQ_FIRE_MAZE_POT_3 }, - { RC_FIRE_TEMPLE_MQ_FIRE_MAZE_NORTHWEST_POT, RAND_INF_FIRE_TEMPLE_MQ_FIRE_MAZE_POT_4 }, - { RC_FIRE_TEMPLE_MQ_SOUTH_FIRE_MAZE_WEST_POT, RAND_INF_FIRE_TEMPLE_MQ_FIRE_MAZE_POT_5 }, - { RC_FIRE_TEMPLE_MQ_SOUTH_FIRE_MAZE_EAST_POT, RAND_INF_FIRE_TEMPLE_MQ_FIRE_MAZE_POT_6 }, - { RC_FIRE_TEMPLE_MQ_BEFORE_MINI_BOSS_POT_1, RAND_INF_FIRE_TEMPLE_MQ_BEFORE_MINI_BOSS_POT_1 }, - { RC_FIRE_TEMPLE_MQ_BEFORE_MINI_BOSS_POT_2, RAND_INF_FIRE_TEMPLE_MQ_BEFORE_MINI_BOSS_POT_2 }, - { RC_FIRE_TEMPLE_MQ_BEFORE_MINI_BOSS_POT_3, RAND_INF_FIRE_TEMPLE_MQ_BEFORE_MINI_BOSS_POT_3 }, - { RC_FIRE_TEMPLE_MQ_BEFORE_MINI_BOSS_POT_4, RAND_INF_FIRE_TEMPLE_MQ_BEFORE_MINI_BOSS_POT_4 }, - { RC_FIRE_TEMPLE_MQ_BEFORE_MINI_BOSS_POT_5, RAND_INF_FIRE_TEMPLE_MQ_BEFORE_MINI_BOSS_POT_5 }, - { RC_FIRE_TEMPLE_MQ_BEFORE_MINI_BOSS_POT_6, RAND_INF_FIRE_TEMPLE_MQ_BEFORE_MINI_BOSS_POT_6 }, - { RC_FIRE_TEMPLE_MQ_BEFORE_MINI_BOSS_POT_7, RAND_INF_FIRE_TEMPLE_MQ_BEFORE_MINI_BOSS_POT_7 }, - { RC_FIRE_TEMPLE_MQ_BEFORE_MINI_BOSS_POT_8, RAND_INF_FIRE_TEMPLE_MQ_BEFORE_MINI_BOSS_POT_8 }, - { RC_ICE_CAVERN_MQ_ENTRANCE_POT, RAND_INF_ICE_CAVERN_MQ_ENTRANCE_POT }, - { RC_ICE_CAVERN_MQ_FIRST_CRYSTAL_POT_1, RAND_INF_ICE_CAVERN_MQ_FIRST_CRYSTAL_POT_1 }, - { RC_ICE_CAVERN_MQ_FIRST_CRYSTAL_POT_2, RAND_INF_ICE_CAVERN_MQ_FIRST_CRYSTAL_POT_2 }, - { RC_ICE_CAVERN_MQ_EARLY_WOLFOS_POT_1, RAND_INF_ICE_CAVERN_MQ_EARLY_WOLFOS_POT_1 }, - { RC_ICE_CAVERN_MQ_EARLY_WOLFOS_POT_2, RAND_INF_ICE_CAVERN_MQ_EARLY_WOLFOS_POT_2 }, - { RC_ICE_CAVERN_MQ_EARLY_WOLFOS_POT_3, RAND_INF_ICE_CAVERN_MQ_EARLY_WOLFOS_POT_3 }, - { RC_ICE_CAVERN_MQ_EARLY_WOLFOS_POT_4, RAND_INF_ICE_CAVERN_MQ_EARLY_WOLFOS_POT_4 }, - { RC_ICE_CAVERN_MQ_PUSH_BLOCK_POT_1, RAND_INF_ICE_CAVERN_MQ_PUSH_BLOCK_POT_1 }, - { RC_ICE_CAVERN_MQ_PUSH_BLOCK_POT_2, RAND_INF_ICE_CAVERN_MQ_PUSH_BLOCK_POT_2 }, - { RC_ICE_CAVERN_MQ_COMPASS_POT_1, RAND_INF_ICE_CAVERN_MQ_COMPASS_POT_1 }, - { RC_ICE_CAVERN_MQ_COMPASS_POT_2, RAND_INF_ICE_CAVERN_MQ_COMPASS_POT_2 }, - { RC_SPIRIT_TEMPLE_MQ_ENTRANCE_POT_1, RAND_INF_SPIRIT_TEMPLE_MQ_ENTRANCE_POT_1 }, - { RC_SPIRIT_TEMPLE_MQ_ENTRANCE_POT_2, RAND_INF_SPIRIT_TEMPLE_MQ_ENTRANCE_POT_2 }, - { RC_SPIRIT_TEMPLE_MQ_ENTRANCE_POT_3, RAND_INF_SPIRIT_TEMPLE_MQ_ENTRANCE_POT_3 }, - { RC_SPIRIT_TEMPLE_MQ_ENTRANCE_POT_4, RAND_INF_SPIRIT_TEMPLE_MQ_ENTRANCE_POT_4 }, - { RC_SPIRIT_TEMPLE_MQ_CHILD_SLUGMA_POT, RAND_INF_SPIRIT_TEMPLE_MQ_CHILD_SLUGMA_POT }, - { RC_SPIRIT_TEMPLE_MQ_CHILD_GIBDO_POT_1, RAND_INF_SPIRIT_TEMPLE_MQ_CHILD_GIBDO_POT_1 }, - { RC_SPIRIT_TEMPLE_MQ_CHILD_GIBDO_POT_2, RAND_INF_SPIRIT_TEMPLE_MQ_CHILD_GIBDO_POT_2 }, - { RC_SPIRIT_TEMPLE_MQ_CHILD_LIKE_LIKE_POT, RAND_INF_SPIRIT_TEMPLE_MQ_CHILD_LIKE_LIKE_POT }, - { RC_SPIRIT_TEMPLE_MQ_CHILD_STALFOS_POT_1, RAND_INF_SPIRIT_TEMPLE_MQ_CHILD_STALFOS_POT_1 }, - { RC_SPIRIT_TEMPLE_MQ_CHILD_STALFOS_POT_2, RAND_INF_SPIRIT_TEMPLE_MQ_CHILD_STALFOS_POT_2 }, - { RC_SPIRIT_TEMPLE_MQ_CHILD_STALFOS_POT_3, RAND_INF_SPIRIT_TEMPLE_MQ_CHILD_STALFOS_POT_3 }, - { RC_SPIRIT_TEMPLE_MQ_CHILD_STALFOS_POT_4, RAND_INF_SPIRIT_TEMPLE_MQ_CHILD_STALFOS_POT_4 }, - { RC_SPIRIT_TEMPLE_MQ_STATUE_2F_CENTER_EAST_POT, RAND_INF_SPIRIT_TEMPLE_MQ_CENTRAL_CHAMBER_POT_1 }, - { RC_SPIRIT_TEMPLE_MQ_STATUE_3F_EAST_POT, RAND_INF_SPIRIT_TEMPLE_MQ_CENTRAL_CHAMBER_POT_2 }, - { RC_SPIRIT_TEMPLE_MQ_STATUE_3F_WEST_POT, RAND_INF_SPIRIT_TEMPLE_MQ_CENTRAL_CHAMBER_POT_3 }, - { RC_SPIRIT_TEMPLE_MQ_STATUE_2F_WEST_POT, RAND_INF_SPIRIT_TEMPLE_MQ_CENTRAL_CHAMBER_POT_4 }, - { RC_SPIRIT_TEMPLE_MQ_STATUE_2F_EASTMOST_POT, RAND_INF_SPIRIT_TEMPLE_MQ_CENTRAL_CHAMBER_POT_5 }, - { RC_SPIRIT_TEMPLE_MQ_SUN_BLOCKS_POT_1, RAND_INF_SPIRIT_TEMPLE_MQ_SUN_BLOCKS_POT_1 }, - { RC_SPIRIT_TEMPLE_MQ_SUN_BLOCKS_POT_2, RAND_INF_SPIRIT_TEMPLE_MQ_SUN_BLOCKS_POT_2 }, - { RC_SPIRIT_TEMPLE_MQ_LONG_CLIMB_POT_1, RAND_INF_SPIRIT_TEMPLE_MQ_LONG_CLIMB_POT_1 }, - { RC_SPIRIT_TEMPLE_MQ_LONG_CLIMB_POT_2, RAND_INF_SPIRIT_TEMPLE_MQ_LONG_CLIMB_POT_2 }, - { RC_SPIRIT_TEMPLE_MQ_BIG_MIRROR_POT_1, RAND_INF_SPIRIT_TEMPLE_MQ_BIG_MIRROR_POT_1 }, - { RC_SPIRIT_TEMPLE_MQ_BIG_MIRROR_POT_2, RAND_INF_SPIRIT_TEMPLE_MQ_BIG_MIRROR_POT_2 }, - { RC_SPIRIT_TEMPLE_MQ_BIG_MIRROR_POT_3, RAND_INF_SPIRIT_TEMPLE_MQ_BIG_MIRROR_POT_3 }, - { RC_SPIRIT_TEMPLE_MQ_BIG_MIRROR_POT_4, RAND_INF_SPIRIT_TEMPLE_MQ_BIG_MIRROR_POT_4 }, - { RC_SPIRIT_TEMPLE_MQ_BEFORE_MIRROR_POT_1, RAND_INF_SPIRIT_TEMPLE_MQ_BEFORE_MIRROR_POT_1 }, - { RC_SPIRIT_TEMPLE_MQ_BEFORE_MIRROR_POT_2, RAND_INF_SPIRIT_TEMPLE_MQ_BEFORE_MIRROR_POT_2 }, - { RC_SPIRIT_TEMPLE_MQ_EARLY_ADULT_POT_1, RAND_INF_SPIRIT_TEMPLE_MQ_EARLY_ADULT_POT_1 }, - { RC_SPIRIT_TEMPLE_MQ_EARLY_ADULT_POT_2, RAND_INF_SPIRIT_TEMPLE_MQ_EARLY_ADULT_POT_2 }, - { RC_WATER_TEMPLE_MQ_LIZALFOS_HALLWAY_WEST_POT, RAND_INF_WATER_TEMPLE_MQ_CENTRAL_GATE_POT_1 }, - { RC_WATER_TEMPLE_MQ_LIZALFOS_HALLWAY_SOUTH_POT, RAND_INF_WATER_TEMPLE_MQ_CENTRAL_GATE_POT_2 }, - { RC_WATER_TEMPLE_MQ_LIZALFOS_HALLWAY_SE_POT, RAND_INF_WATER_TEMPLE_MQ_CENTRAL_GATE_POT_3 }, - { RC_WATER_TEMPLE_MQ_LIZALFOS_CAGE_SOUTH_POT, RAND_INF_WATER_TEMPLE_MQ_CENTRAL_GATE_POT_4 }, - { RC_WATER_TEMPLE_MQ_LIZALFOS_CAGE_NORTH_POT, RAND_INF_WATER_TEMPLE_MQ_CENTRAL_GATE_POT_5 }, - { RC_WATER_TEMPLE_MQ_STORAGE_ROOM_A_POT_1, RAND_INF_WATER_TEMPLE_MQ_STORAGE_ROOM_A_POT_1 }, - { RC_WATER_TEMPLE_MQ_STORAGE_ROOM_A_POT_2, RAND_INF_WATER_TEMPLE_MQ_STORAGE_ROOM_A_POT_2 }, - { RC_WATER_TEMPLE_MQ_STORAGE_ROOM_A_POT_3, RAND_INF_WATER_TEMPLE_MQ_STORAGE_ROOM_A_POT_3 }, - { RC_WATER_TEMPLE_MQ_BEFORE_DARK_LINK_POT_1, RAND_INF_WATER_TEMPLE_MQ_BEFORE_DARK_LINK_POT_1 }, - { RC_WATER_TEMPLE_MQ_BEFORE_DARK_LINK_POT_2, RAND_INF_WATER_TEMPLE_MQ_BEFORE_DARK_LINK_POT_2 }, - { RC_WATER_TEMPLE_MQ_STALFOS_PIT_MIDDLE_POT, RAND_INF_WATER_TEMPLE_MQ_BEFORE_DARK_LINK_POT_3 }, - { RC_WATER_TEMPLE_MQ_STALFOS_PIT_SOUTH_POT, RAND_INF_WATER_TEMPLE_MQ_BEFORE_DARK_LINK_POT_4 }, - { RC_WATER_TEMPLE_MQ_STALFOS_PIT_NORTH_POT, RAND_INF_WATER_TEMPLE_MQ_BEFORE_DARK_LINK_POT_5 }, - { RC_WATER_TEMPLE_MQ_AFTER_DARK_LINK_POT_1, RAND_INF_WATER_TEMPLE_MQ_AFTER_DARK_LINK_POT_1 }, - { RC_WATER_TEMPLE_MQ_AFTER_DARK_LINK_POT_2, RAND_INF_WATER_TEMPLE_MQ_AFTER_DARK_LINK_POT_2 }, - { RC_WATER_TEMPLE_MQ_RIVER_POT_1, RAND_INF_WATER_TEMPLE_MQ_RIVER_POT_1 }, - { RC_WATER_TEMPLE_MQ_RIVER_POT_2, RAND_INF_WATER_TEMPLE_MQ_RIVER_POT_2 }, - { RC_WATER_TEMPLE_MQ_MINI_DODONGO_POT_1, RAND_INF_WATER_TEMPLE_MQ_MINI_DODONGO_POT_1 }, - { RC_WATER_TEMPLE_MQ_MINI_DODONGO_POT_2, RAND_INF_WATER_TEMPLE_MQ_MINI_DODONGO_POT_2 }, - { RC_WATER_TEMPLE_MQ_STORAGE_ROOM_B_POT_1, RAND_INF_WATER_TEMPLE_MQ_STORAGE_ROOM_B_POT_1 }, - { RC_WATER_TEMPLE_MQ_STORAGE_ROOM_B_POT_2, RAND_INF_WATER_TEMPLE_MQ_STORAGE_ROOM_B_POT_2 }, - { RC_WATER_TEMPLE_MQ_GS_STORAGE_ROOM_POT_1, RAND_INF_WATER_TEMPLE_MQ_GS_STORAGE_ROOM_POT_1 }, - { RC_WATER_TEMPLE_MQ_GS_STORAGE_ROOM_POT_2, RAND_INF_WATER_TEMPLE_MQ_GS_STORAGE_ROOM_POT_2 }, - { RC_WATER_TEMPLE_MQ_GS_STORAGE_ROOM_POT_3, RAND_INF_WATER_TEMPLE_MQ_GS_STORAGE_ROOM_POT_3 }, - { RC_WATER_TEMPLE_MQ_LOWER_TORCHES_POT_1, RAND_INF_WATER_TEMPLE_MQ_LOWER_TORCHES_POT_1 }, - { RC_WATER_TEMPLE_MQ_LOWER_TORCHES_POT_2, RAND_INF_WATER_TEMPLE_MQ_LOWER_TORCHES_POT_2 }, - { RC_WATER_TEMPLE_MQ_LOWEST_GS_POT_1, RAND_INF_WATER_TEMPLE_MQ_LOWEST_GS_POT_1 }, - { RC_WATER_TEMPLE_MQ_LOWEST_GS_POT_2, RAND_INF_WATER_TEMPLE_MQ_LOWEST_GS_POT_2 }, - { RC_WATER_TEMPLE_MQ_LOWEST_GS_POT_3, RAND_INF_WATER_TEMPLE_MQ_LOWEST_GS_POT_3 }, - { RC_WATER_TEMPLE_MQ_LOWEST_GS_POT_4, RAND_INF_WATER_TEMPLE_MQ_LOWEST_GS_POT_4 }, - { RC_WATER_TEMPLE_MQ_BOSS_KEY_POT, RAND_INF_WATER_TEMPLE_MQ_BOSS_KEY_POT }, - { RC_GERUDO_TRAINING_GROUND_MQ_LOBBY_LEFT_POT_1, RAND_INF_GERUDO_TRAINING_GROUND_MQ_LOBBY_LEFT_POT_1 }, - { RC_GERUDO_TRAINING_GROUND_MQ_LOBBY_LEFT_POT_2, RAND_INF_GERUDO_TRAINING_GROUND_MQ_LOBBY_LEFT_POT_2 }, - { RC_GERUDO_TRAINING_GROUND_MQ_LOBBY_RIGHT_POT_1, RAND_INF_GERUDO_TRAINING_GROUND_MQ_LOBBY_RIGHT_POT_1 }, - { RC_GERUDO_TRAINING_GROUND_MQ_LOBBY_RIGHT_POT_2, RAND_INF_GERUDO_TRAINING_GROUND_MQ_LOBBY_RIGHT_POT_2 }, + { RC_KF_LINKS_HOUSE_POT, RAND_INF_KF_LINKS_HOUSE_POT }, + { RC_KF_TWINS_HOUSE_POT_1, RAND_INF_KF_TWINS_HOUSE_POT_1 }, + { RC_KF_TWINS_HOUSE_POT_2, RAND_INF_KF_TWINS_HOUSE_POT_2 }, + { RC_KF_BROTHERS_HOUSE_POT_1, RAND_INF_KF_BROTHERS_HOUSE_POT_1 }, + { RC_KF_BROTHERS_HOUSE_POT_2, RAND_INF_KF_BROTHERS_HOUSE_POT_2 }, + { RC_GF_BREAK_ROOM_POT_1, RAND_INF_GF_BREAK_ROOM_POT_1 }, + { RC_GF_BREAK_ROOM_POT_2, RAND_INF_GF_BREAK_ROOM_POT_2 }, + { RC_GF_KITCHEN_POT_1, RAND_INF_GF_KITCHEN_POT_1 }, + { RC_GF_KITCHEN_POT_2, RAND_INF_GF_KITCHEN_POT_2 }, + { RC_GF_NORTH_F1_CARPENTER_POT_1, RAND_INF_GF_NORTH_F1_CARPENTER_POT_1 }, + { RC_GF_NORTH_F1_CARPENTER_POT_2, RAND_INF_GF_NORTH_F1_CARPENTER_POT_2 }, + { RC_GF_NORTH_F1_CARPENTER_POT_3, RAND_INF_GF_NORTH_F1_CARPENTER_POT_3 }, + { RC_GF_NORTH_F2_CARPENTER_POT_1, RAND_INF_GF_NORTH_F2_CARPENTER_POT_1 }, + { RC_GF_NORTH_F2_CARPENTER_POT_2, RAND_INF_GF_NORTH_F2_CARPENTER_POT_2 }, + { RC_GF_SOUTH_F1_CARPENTER_POT_1, RAND_INF_GF_SOUTH_F1_CARPENTER_POT_1 }, + { RC_GF_SOUTH_F1_CARPENTER_POT_2, RAND_INF_GF_SOUTH_F1_CARPENTER_POT_2 }, + { RC_GF_SOUTH_F1_CARPENTER_POT_3, RAND_INF_GF_SOUTH_F1_CARPENTER_POT_3 }, + { RC_GF_SOUTH_F1_CARPENTER_CELL_POT_1, RAND_INF_GF_SOUTH_F1_CARPENTER_CELL_POT_1 }, + { RC_GF_SOUTH_F1_CARPENTER_CELL_POT_2, RAND_INF_GF_SOUTH_F1_CARPENTER_CELL_POT_2 }, + { RC_GF_SOUTH_F1_CARPENTER_CELL_POT_3, RAND_INF_GF_SOUTH_F1_CARPENTER_CELL_POT_3 }, + { RC_GF_SOUTH_F1_CARPENTER_CELL_POT_4, RAND_INF_GF_SOUTH_F1_CARPENTER_CELL_POT_4 }, + { RC_WASTELAND_NEAR_GS_POT_1, RAND_INF_WASTELAND_NEAR_GS_POT_1 }, + { RC_WASTELAND_NEAR_GS_POT_2, RAND_INF_WASTELAND_NEAR_GS_POT_2 }, + { RC_WASTELAND_NEAR_GS_POT_3, RAND_INF_WASTELAND_NEAR_GS_POT_3 }, + { RC_WASTELAND_NEAR_GS_POT_4, RAND_INF_WASTELAND_NEAR_GS_POT_4 }, + { RC_MK_GUARD_HOUSE_CHILD_POT_1, RAND_INF_MK_GUARD_HOUSE_CHILD_POT_1 }, + { RC_MK_GUARD_HOUSE_CHILD_POT_2, RAND_INF_MK_GUARD_HOUSE_CHILD_POT_2 }, + { RC_MK_GUARD_HOUSE_CHILD_POT_3, RAND_INF_MK_GUARD_HOUSE_CHILD_POT_3 }, + { RC_MK_GUARD_HOUSE_CHILD_POT_4, RAND_INF_MK_GUARD_HOUSE_CHILD_POT_4 }, + { RC_MK_GUARD_HOUSE_CHILD_POT_5, RAND_INF_MK_GUARD_HOUSE_CHILD_POT_5 }, + { RC_MK_GUARD_HOUSE_CHILD_POT_6, RAND_INF_MK_GUARD_HOUSE_CHILD_POT_6 }, + { RC_MK_GUARD_HOUSE_CHILD_POT_7, RAND_INF_MK_GUARD_HOUSE_CHILD_POT_7 }, + { RC_MK_GUARD_HOUSE_CHILD_POT_8, RAND_INF_MK_GUARD_HOUSE_CHILD_POT_8 }, + { RC_MK_GUARD_HOUSE_CHILD_POT_9, RAND_INF_MK_GUARD_HOUSE_CHILD_POT_9 }, + { RC_MK_GUARD_HOUSE_CHILD_POT_10, RAND_INF_MK_GUARD_HOUSE_CHILD_POT_10 }, + { RC_MK_GUARD_HOUSE_CHILD_POT_11, RAND_INF_MK_GUARD_HOUSE_CHILD_POT_11 }, + { RC_MK_GUARD_HOUSE_CHILD_POT_12, RAND_INF_MK_GUARD_HOUSE_CHILD_POT_12 }, + { RC_MK_GUARD_HOUSE_CHILD_POT_13, RAND_INF_MK_GUARD_HOUSE_CHILD_POT_13 }, + { RC_MK_GUARD_HOUSE_CHILD_POT_14, RAND_INF_MK_GUARD_HOUSE_CHILD_POT_14 }, + { RC_MK_GUARD_HOUSE_CHILD_POT_15, RAND_INF_MK_GUARD_HOUSE_CHILD_POT_15 }, + { RC_MK_GUARD_HOUSE_CHILD_POT_16, RAND_INF_MK_GUARD_HOUSE_CHILD_POT_16 }, + { RC_MK_GUARD_HOUSE_CHILD_POT_17, RAND_INF_MK_GUARD_HOUSE_CHILD_POT_17 }, + { RC_MK_GUARD_HOUSE_CHILD_POT_18, RAND_INF_MK_GUARD_HOUSE_CHILD_POT_18 }, + { RC_MK_GUARD_HOUSE_CHILD_POT_19, RAND_INF_MK_GUARD_HOUSE_CHILD_POT_19 }, + { RC_MK_GUARD_HOUSE_CHILD_POT_20, RAND_INF_MK_GUARD_HOUSE_CHILD_POT_20 }, + { RC_MK_GUARD_HOUSE_CHILD_POT_21, RAND_INF_MK_GUARD_HOUSE_CHILD_POT_21 }, + { RC_MK_GUARD_HOUSE_CHILD_POT_22, RAND_INF_MK_GUARD_HOUSE_CHILD_POT_22 }, + { RC_MK_GUARD_HOUSE_CHILD_POT_23, RAND_INF_MK_GUARD_HOUSE_CHILD_POT_23 }, + { RC_MK_GUARD_HOUSE_CHILD_POT_24, RAND_INF_MK_GUARD_HOUSE_CHILD_POT_24 }, + { RC_MK_GUARD_HOUSE_CHILD_POT_25, RAND_INF_MK_GUARD_HOUSE_CHILD_POT_25 }, + { RC_MK_GUARD_HOUSE_CHILD_POT_26, RAND_INF_MK_GUARD_HOUSE_CHILD_POT_26 }, + { RC_MK_GUARD_HOUSE_CHILD_POT_27, RAND_INF_MK_GUARD_HOUSE_CHILD_POT_27 }, + { RC_MK_GUARD_HOUSE_CHILD_POT_28, RAND_INF_MK_GUARD_HOUSE_CHILD_POT_28 }, + { RC_MK_GUARD_HOUSE_CHILD_POT_29, RAND_INF_MK_GUARD_HOUSE_CHILD_POT_29 }, + { RC_MK_GUARD_HOUSE_CHILD_POT_30, RAND_INF_MK_GUARD_HOUSE_CHILD_POT_30 }, + { RC_MK_GUARD_HOUSE_CHILD_POT_31, RAND_INF_MK_GUARD_HOUSE_CHILD_POT_31 }, + { RC_MK_GUARD_HOUSE_CHILD_POT_32, RAND_INF_MK_GUARD_HOUSE_CHILD_POT_32 }, + { RC_MK_GUARD_HOUSE_CHILD_POT_33, RAND_INF_MK_GUARD_HOUSE_CHILD_POT_33 }, + { RC_MK_GUARD_HOUSE_CHILD_POT_34, RAND_INF_MK_GUARD_HOUSE_CHILD_POT_34 }, + { RC_MK_GUARD_HOUSE_CHILD_POT_35, RAND_INF_MK_GUARD_HOUSE_CHILD_POT_35 }, + { RC_MK_GUARD_HOUSE_CHILD_POT_36, RAND_INF_MK_GUARD_HOUSE_CHILD_POT_36 }, + { RC_MK_GUARD_HOUSE_CHILD_POT_37, RAND_INF_MK_GUARD_HOUSE_CHILD_POT_37 }, + { RC_MK_GUARD_HOUSE_CHILD_POT_38, RAND_INF_MK_GUARD_HOUSE_CHILD_POT_38 }, + { RC_MK_GUARD_HOUSE_CHILD_POT_39, RAND_INF_MK_GUARD_HOUSE_CHILD_POT_39 }, + { RC_MK_GUARD_HOUSE_CHILD_POT_40, RAND_INF_MK_GUARD_HOUSE_CHILD_POT_40 }, + { RC_MK_GUARD_HOUSE_CHILD_POT_41, RAND_INF_MK_GUARD_HOUSE_CHILD_POT_41 }, + { RC_MK_GUARD_HOUSE_CHILD_POT_42, RAND_INF_MK_GUARD_HOUSE_CHILD_POT_42 }, + { RC_MK_GUARD_HOUSE_CHILD_POT_43, RAND_INF_MK_GUARD_HOUSE_CHILD_POT_43 }, + { RC_MK_GUARD_HOUSE_CHILD_POT_44, RAND_INF_MK_GUARD_HOUSE_CHILD_POT_44 }, + { RC_MK_GUARD_HOUSE_ADULT_POT_1, RAND_INF_MK_GUARD_HOUSE_ADULT_POT_1 }, + { RC_MK_GUARD_HOUSE_ADULT_POT_2, RAND_INF_MK_GUARD_HOUSE_ADULT_POT_2 }, + { RC_MK_GUARD_HOUSE_ADULT_POT_3, RAND_INF_MK_GUARD_HOUSE_ADULT_POT_3 }, + { RC_MK_GUARD_HOUSE_ADULT_POT_4, RAND_INF_MK_GUARD_HOUSE_ADULT_POT_4 }, + { RC_MK_GUARD_HOUSE_ADULT_POT_5, RAND_INF_MK_GUARD_HOUSE_ADULT_POT_5 }, + { RC_MK_GUARD_HOUSE_ADULT_POT_6, RAND_INF_MK_GUARD_HOUSE_ADULT_POT_6 }, + { RC_MK_GUARD_HOUSE_ADULT_POT_7, RAND_INF_MK_GUARD_HOUSE_ADULT_POT_7 }, + { RC_MK_GUARD_HOUSE_ADULT_POT_8, RAND_INF_MK_GUARD_HOUSE_ADULT_POT_8 }, + { RC_MK_GUARD_HOUSE_ADULT_POT_9, RAND_INF_MK_GUARD_HOUSE_ADULT_POT_9 }, + { RC_MK_GUARD_HOUSE_ADULT_POT_10, RAND_INF_MK_GUARD_HOUSE_ADULT_POT_10 }, + { RC_MK_GUARD_HOUSE_ADULT_POT_11, RAND_INF_MK_GUARD_HOUSE_ADULT_POT_11 }, + { RC_MK_BACK_ALLEY_HOUSE_POT_1, RAND_INF_MK_BACK_ALLEY_HOUSE_POT_1 }, + { RC_MK_BACK_ALLEY_HOUSE_POT_2, RAND_INF_MK_BACK_ALLEY_HOUSE_POT_2 }, + { RC_MK_BACK_ALLEY_HOUSE_POT_3, RAND_INF_MK_BACK_ALLEY_HOUSE_POT_3 }, + { RC_KAK_NEAR_POTION_SHOP_POT_1, RAND_INF_KAK_NEAR_POTION_SHOP_POT_1 }, + { RC_KAK_NEAR_POTION_SHOP_POT_2, RAND_INF_KAK_NEAR_POTION_SHOP_POT_2 }, + { RC_KAK_NEAR_POTION_SHOP_POT_3, RAND_INF_KAK_NEAR_POTION_SHOP_POT_3 }, + { RC_KAK_NEAR_IMPAS_HOUSE_POT_1, RAND_INF_KAK_NEAR_IMPAS_HOUSE_POT_1 }, + { RC_KAK_NEAR_IMPAS_HOUSE_POT_2, RAND_INF_KAK_NEAR_IMPAS_HOUSE_POT_2 }, + { RC_KAK_NEAR_IMPAS_HOUSE_POT_3, RAND_INF_KAK_NEAR_IMPAS_HOUSE_POT_3 }, + { RC_KAK_NEAR_GUARDS_HOUSE_POT_1, RAND_INF_KAK_NEAR_GUARDS_HOUSE_POT_1 }, + { RC_KAK_NEAR_GUARDS_HOUSE_POT_2, RAND_INF_KAK_NEAR_GUARDS_HOUSE_POT_2 }, + { RC_KAK_NEAR_GUARDS_HOUSE_POT_3, RAND_INF_KAK_NEAR_GUARDS_HOUSE_POT_3 }, + { RC_KAK_NEAR_MEDICINE_SHOP_POT_1, RAND_INF_KAK_NEAR_MEDICINE_SHOP_POT_1 }, + { RC_KAK_NEAR_MEDICINE_SHOP_POT_2, RAND_INF_KAK_NEAR_MEDICINE_SHOP_POT_2 }, + { RC_GY_DAMPES_GRAVE_POT_1, RAND_INF_GY_DAMPES_GRAVE_POT_1 }, + { RC_GY_DAMPES_GRAVE_POT_2, RAND_INF_GY_DAMPES_GRAVE_POT_2 }, + { RC_GY_DAMPES_GRAVE_POT_3, RAND_INF_GY_DAMPES_GRAVE_POT_3 }, + { RC_GY_DAMPES_GRAVE_POT_4, RAND_INF_GY_DAMPES_GRAVE_POT_4 }, + { RC_GY_DAMPES_GRAVE_POT_5, RAND_INF_GY_DAMPES_GRAVE_POT_5 }, + { RC_GY_DAMPES_GRAVE_POT_6, RAND_INF_GY_DAMPES_GRAVE_POT_6 }, + { RC_GC_LOWER_STAIRCASE_POT_1, RAND_INF_GC_LOWER_STAIRCASE_POT_1 }, + { RC_GC_LOWER_STAIRCASE_POT_2, RAND_INF_GC_LOWER_STAIRCASE_POT_2 }, + { RC_GC_UPPER_STAIRCASE_POT_1, RAND_INF_GC_UPPER_STAIRCASE_POT_1 }, + { RC_GC_UPPER_STAIRCASE_POT_2, RAND_INF_GC_UPPER_STAIRCASE_POT_2 }, + { RC_GC_UPPER_STAIRCASE_POT_3, RAND_INF_GC_UPPER_STAIRCASE_POT_3 }, + { RC_GC_MEDIGORON_POT_1, RAND_INF_GC_MEDIGORON_POT_1 }, + { RC_GC_DARUNIA_POT_1, RAND_INF_GC_DARUNIA_POT_1 }, + { RC_GC_DARUNIA_POT_2, RAND_INF_GC_DARUNIA_POT_2 }, + { RC_GC_DARUNIA_POT_3, RAND_INF_GC_DARUNIA_POT_3 }, + { RC_DMC_NEAR_GC_POT_1, RAND_INF_DMC_NEAR_GC_POT_1 }, + { RC_DMC_NEAR_GC_POT_2, RAND_INF_DMC_NEAR_GC_POT_2 }, + { RC_DMC_NEAR_GC_POT_3, RAND_INF_DMC_NEAR_GC_POT_3 }, + { RC_DMC_NEAR_GC_POT_4, RAND_INF_DMC_NEAR_GC_POT_4 }, + { RC_ZD_NEAR_SHOP_POT_1, RAND_INF_ZD_NEAR_SHOP_POT_1 }, + { RC_ZD_NEAR_SHOP_POT_2, RAND_INF_ZD_NEAR_SHOP_POT_2 }, + { RC_ZD_NEAR_SHOP_POT_3, RAND_INF_ZD_NEAR_SHOP_POT_3 }, + { RC_ZD_NEAR_SHOP_POT_4, RAND_INF_ZD_NEAR_SHOP_POT_4 }, + { RC_ZD_NEAR_SHOP_POT_5, RAND_INF_ZD_NEAR_SHOP_POT_5 }, + { RC_ZF_HIDDEN_CAVE_POT_1, RAND_INF_ZF_HIDDEN_CAVE_POT_1 }, + { RC_ZF_HIDDEN_CAVE_POT_2, RAND_INF_ZF_HIDDEN_CAVE_POT_2 }, + { RC_ZF_HIDDEN_CAVE_POT_3, RAND_INF_ZF_HIDDEN_CAVE_POT_3 }, + { RC_ZF_NEAR_JABU_POT_1, RAND_INF_ZF_NEAR_JABU_POT_1 }, + { RC_ZF_NEAR_JABU_POT_2, RAND_INF_ZF_NEAR_JABU_POT_2 }, + { RC_ZF_NEAR_JABU_POT_3, RAND_INF_ZF_NEAR_JABU_POT_3 }, + { RC_ZF_NEAR_JABU_POT_4, RAND_INF_ZF_NEAR_JABU_POT_4 }, + { RC_LLR_FRONT_POT_1, RAND_INF_LLR_FRONT_POT_1 }, + { RC_LLR_FRONT_POT_2, RAND_INF_LLR_FRONT_POT_2 }, + { RC_LLR_FRONT_POT_3, RAND_INF_LLR_FRONT_POT_3 }, + { RC_LLR_FRONT_POT_4, RAND_INF_LLR_FRONT_POT_4 }, + { RC_LLR_RAIN_SHED_POT_1, RAND_INF_LLR_RAIN_SHED_POT_1 }, + { RC_LLR_RAIN_SHED_POT_2, RAND_INF_LLR_RAIN_SHED_POT_2 }, + { RC_LLR_RAIN_SHED_POT_3, RAND_INF_LLR_RAIN_SHED_POT_3 }, + { RC_LLR_TALONS_HOUSE_POT_1, RAND_INF_LLR_TALONS_HOUSE_POT_1 }, + { RC_LLR_TALONS_HOUSE_POT_2, RAND_INF_LLR_TALONS_HOUSE_POT_2 }, + { RC_LLR_TALONS_HOUSE_POT_3, RAND_INF_LLR_TALONS_HOUSE_POT_3 }, + { RC_HF_COW_GROTTO_POT_1, RAND_INF_HF_COW_GROTTO_POT_1 }, + { RC_HF_COW_GROTTO_POT_2, RAND_INF_HF_COW_GROTTO_POT_2 }, + { RC_HC_STORMS_GROTTO_POT_1, RAND_INF_HC_STORMS_GROTTO_POT_1 }, + { RC_HC_STORMS_GROTTO_POT_2, RAND_INF_HC_STORMS_GROTTO_POT_2 }, + { RC_HC_STORMS_GROTTO_POT_3, RAND_INF_HC_STORMS_GROTTO_POT_3 }, + { RC_HC_STORMS_GROTTO_POT_4, RAND_INF_HC_STORMS_GROTTO_POT_4 }, + { RC_DODONGOS_CAVERN_LIZALFOS_POT_1, RAND_INF_DODONGOS_CAVERN_LIZALFOS_POT_1 }, + { RC_DODONGOS_CAVERN_LIZALFOS_POT_2, RAND_INF_DODONGOS_CAVERN_LIZALFOS_POT_2 }, + { RC_DODONGOS_CAVERN_LIZALFOS_POT_3, RAND_INF_DODONGOS_CAVERN_LIZALFOS_POT_3 }, + { RC_DODONGOS_CAVERN_LIZALFOS_POT_4, RAND_INF_DODONGOS_CAVERN_LIZALFOS_POT_4 }, + { RC_DODONGOS_CAVERN_SIDE_ROOM_POT_1, RAND_INF_DODONGOS_CAVERN_SIDE_ROOM_POT_1 }, + { RC_DODONGOS_CAVERN_SIDE_ROOM_POT_2, RAND_INF_DODONGOS_CAVERN_SIDE_ROOM_POT_2 }, + { RC_DODONGOS_CAVERN_SIDE_ROOM_POT_3, RAND_INF_DODONGOS_CAVERN_SIDE_ROOM_POT_3 }, + { RC_DODONGOS_CAVERN_SIDE_ROOM_POT_4, RAND_INF_DODONGOS_CAVERN_SIDE_ROOM_POT_4 }, + { RC_DODONGOS_CAVERN_SIDE_ROOM_POT_5, RAND_INF_DODONGOS_CAVERN_SIDE_ROOM_POT_5 }, + { RC_DODONGOS_CAVERN_SIDE_ROOM_POT_6, RAND_INF_DODONGOS_CAVERN_SIDE_ROOM_POT_6 }, + { RC_DODONGOS_CAVERN_TORCH_ROOM_POT_1, RAND_INF_DODONGOS_CAVERN_TORCH_ROOM_POT_1 }, + { RC_DODONGOS_CAVERN_TORCH_ROOM_POT_2, RAND_INF_DODONGOS_CAVERN_TORCH_ROOM_POT_2 }, + { RC_DODONGOS_CAVERN_TORCH_ROOM_POT_3, RAND_INF_DODONGOS_CAVERN_TORCH_ROOM_POT_3 }, + { RC_DODONGOS_CAVERN_TORCH_ROOM_POT_4, RAND_INF_DODONGOS_CAVERN_TORCH_ROOM_POT_4 }, + { RC_DODONGOS_CAVERN_STAIRCASE_POT_1, RAND_INF_DODONGOS_CAVERN_STAIRCASE_POT_1 }, + { RC_DODONGOS_CAVERN_STAIRCASE_POT_2, RAND_INF_DODONGOS_CAVERN_STAIRCASE_POT_2 }, + { RC_DODONGOS_CAVERN_STAIRCASE_POT_3, RAND_INF_DODONGOS_CAVERN_STAIRCASE_POT_3 }, + { RC_DODONGOS_CAVERN_STAIRCASE_POT_4, RAND_INF_DODONGOS_CAVERN_STAIRCASE_POT_4 }, + { RC_DODONGOS_CAVERN_SINGLE_EYE_POT_1, RAND_INF_DODONGOS_CAVERN_SINGLE_EYE_POT_1 }, + { RC_DODONGOS_CAVERN_SINGLE_EYE_POT_2, RAND_INF_DODONGOS_CAVERN_SINGLE_EYE_POT_2 }, + { RC_DODONGOS_CAVERN_BLADE_POT_1, RAND_INF_DODONGOS_CAVERN_BLADE_POT_1 }, + { RC_DODONGOS_CAVERN_BLADE_POT_2, RAND_INF_DODONGOS_CAVERN_BLADE_POT_2 }, + { RC_DODONGOS_CAVERN_DOUBLE_EYE_POT_1, RAND_INF_DODONGOS_CAVERN_DOUBLE_EYE_POT_1 }, + { RC_DODONGOS_CAVERN_DOUBLE_EYE_POT_2, RAND_INF_DODONGOS_CAVERN_DOUBLE_EYE_POT_2 }, + { RC_DODONGOS_CAVERN_BACK_ROOM_POT_1, RAND_INF_DODONGOS_CAVERN_BACK_ROOM_POT_1 }, + { RC_DODONGOS_CAVERN_BACK_ROOM_POT_2, RAND_INF_DODONGOS_CAVERN_BACK_ROOM_POT_2 }, + { RC_DODONGOS_CAVERN_BACK_ROOM_POT_3, RAND_INF_DODONGOS_CAVERN_BACK_ROOM_POT_3 }, + { RC_DODONGOS_CAVERN_BACK_ROOM_POT_4, RAND_INF_DODONGOS_CAVERN_BACK_ROOM_POT_4 }, + { RC_JABU_JABUS_BELLY_ABOVE_BIG_OCTO_POT_1, RAND_INF_JABU_JABUS_BELLY_ABOVE_BIG_OCTO_POT_1 }, + { RC_JABU_JABUS_BELLY_ABOVE_BIG_OCTO_POT_2, RAND_INF_JABU_JABUS_BELLY_ABOVE_BIG_OCTO_POT_2 }, + { RC_JABU_JABUS_BELLY_ABOVE_BIG_OCTO_POT_3, RAND_INF_JABU_JABUS_BELLY_ABOVE_BIG_OCTO_POT_3 }, + { RC_JABU_JABUS_BELLY_BARINADE_POT_1, RAND_INF_JABU_JABUS_BELLY_BARINADE_POT_1 }, + { RC_JABU_JABUS_BELLY_BARINADE_POT_2, RAND_INF_JABU_JABUS_BELLY_BARINADE_POT_2 }, + { RC_JABU_JABUS_BELLY_BARINADE_POT_3, RAND_INF_JABU_JABUS_BELLY_BARINADE_POT_3 }, + { RC_JABU_JABUS_BELLY_BARINADE_POT_4, RAND_INF_JABU_JABUS_BELLY_BARINADE_POT_4 }, + { RC_JABU_JABUS_BELLY_BARINADE_POT_5, RAND_INF_JABU_JABUS_BELLY_BARINADE_POT_5 }, + { RC_JABU_JABUS_BELLY_BARINADE_POT_6, RAND_INF_JABU_JABUS_BELLY_BARINADE_POT_6 }, + { RC_JABU_JABUS_BELLY_BASEMENT_POT_1, RAND_INF_JABU_JABUS_BELLY_BASEMENT_POT_1 }, + { RC_JABU_JABUS_BELLY_BASEMENT_POT_2, RAND_INF_JABU_JABUS_BELLY_BASEMENT_POT_2 }, + { RC_JABU_JABUS_BELLY_BASEMENT_POT_3, RAND_INF_JABU_JABUS_BELLY_BASEMENT_POT_3 }, + { RC_JABU_JABUS_BELLY_TWO_OCTOROK_POT_1, RAND_INF_JABU_JABUS_BELLY_TWO_OCTOROK_POT_1 }, + { RC_JABU_JABUS_BELLY_TWO_OCTOROK_POT_2, RAND_INF_JABU_JABUS_BELLY_TWO_OCTOROK_POT_2 }, + { RC_JABU_JABUS_BELLY_TWO_OCTOROK_POT_3, RAND_INF_JABU_JABUS_BELLY_TWO_OCTOROK_POT_3 }, + { RC_JABU_JABUS_BELLY_TWO_OCTOROK_POT_4, RAND_INF_JABU_JABUS_BELLY_TWO_OCTOROK_POT_4 }, + { RC_JABU_JABUS_BELLY_TWO_OCTOROK_POT_5, RAND_INF_JABU_JABUS_BELLY_TWO_OCTOROK_POT_5 }, + { RC_FOREST_TEMPLE_LOBBY_POT_1, RAND_INF_FOREST_TEMPLE_LOBBY_POT_1 }, + { RC_FOREST_TEMPLE_LOBBY_POT_2, RAND_INF_FOREST_TEMPLE_LOBBY_POT_2 }, + { RC_FOREST_TEMPLE_LOBBY_POT_3, RAND_INF_FOREST_TEMPLE_LOBBY_POT_3 }, + { RC_FOREST_TEMPLE_LOBBY_POT_4, RAND_INF_FOREST_TEMPLE_LOBBY_POT_4 }, + { RC_FOREST_TEMPLE_LOBBY_POT_5, RAND_INF_FOREST_TEMPLE_LOBBY_POT_5 }, + { RC_FOREST_TEMPLE_LOBBY_POT_6, RAND_INF_FOREST_TEMPLE_LOBBY_POT_6 }, + { RC_FOREST_TEMPLE_LOWER_STALFOS_POT_1, RAND_INF_FOREST_TEMPLE_LOWER_STALFOS_POT_1 }, + { RC_FOREST_TEMPLE_LOWER_STALFOS_POT_2, RAND_INF_FOREST_TEMPLE_LOWER_STALFOS_POT_2 }, + { RC_FOREST_TEMPLE_GREEN_POE_POT_1, RAND_INF_FOREST_TEMPLE_GREEN_POE_POT_1 }, + { RC_FOREST_TEMPLE_GREEN_POE_POT_2, RAND_INF_FOREST_TEMPLE_GREEN_POE_POT_2 }, + { RC_FOREST_TEMPLE_UPPER_STALFOS_POT_1, RAND_INF_FOREST_TEMPLE_UPPER_STALFOS_POT_1 }, + { RC_FOREST_TEMPLE_UPPER_STALFOS_POT_2, RAND_INF_FOREST_TEMPLE_UPPER_STALFOS_POT_2 }, + { RC_FOREST_TEMPLE_UPPER_STALFOS_POT_3, RAND_INF_FOREST_TEMPLE_UPPER_STALFOS_POT_3 }, + { RC_FOREST_TEMPLE_UPPER_STALFOS_POT_4, RAND_INF_FOREST_TEMPLE_UPPER_STALFOS_POT_4 }, + { RC_FOREST_TEMPLE_BLUE_POE_POT_1, RAND_INF_FOREST_TEMPLE_BLUE_POE_POT_1 }, + { RC_FOREST_TEMPLE_BLUE_POE_POT_2, RAND_INF_FOREST_TEMPLE_BLUE_POE_POT_2 }, + { RC_FOREST_TEMPLE_BLUE_POE_POT_3, RAND_INF_FOREST_TEMPLE_BLUE_POE_POT_3 }, + { RC_FOREST_TEMPLE_FROZEN_EYE_POT_1, RAND_INF_FOREST_TEMPLE_FROZEN_EYE_POT_1 }, + { RC_FOREST_TEMPLE_FROZEN_EYE_POT_2, RAND_INF_FOREST_TEMPLE_FROZEN_EYE_POT_2 }, + { RC_FIRE_TEMPLE_NEAR_BOSS_POT_1, RAND_INF_FIRE_TEMPLE_NEAR_BOSS_POT_1 }, + { RC_FIRE_TEMPLE_NEAR_BOSS_POT_2, RAND_INF_FIRE_TEMPLE_NEAR_BOSS_POT_2 }, + { RC_FIRE_TEMPLE_NEAR_BOSS_POT_3, RAND_INF_FIRE_TEMPLE_NEAR_BOSS_POT_3 }, + { RC_FIRE_TEMPLE_NEAR_BOSS_POT_4, RAND_INF_FIRE_TEMPLE_NEAR_BOSS_POT_4 }, + { RC_FIRE_TEMPLE_BIG_LAVA_POT_1, RAND_INF_FIRE_TEMPLE_BIG_LAVA_POT_1 }, + { RC_FIRE_TEMPLE_BIG_LAVA_POT_2, RAND_INF_FIRE_TEMPLE_BIG_LAVA_POT_2 }, + { RC_FIRE_TEMPLE_BIG_LAVA_POT_3, RAND_INF_FIRE_TEMPLE_BIG_LAVA_POT_3 }, + { RC_FIRE_TEMPLE_FLAME_MAZE_LEFT_POT_1, RAND_INF_FIRE_TEMPLE_FLAME_MAZE_LEFT_POT_1 }, + { RC_FIRE_TEMPLE_FLAME_MAZE_LEFT_POT_2, RAND_INF_FIRE_TEMPLE_FLAME_MAZE_LEFT_POT_2 }, + { RC_FIRE_TEMPLE_FLAME_MAZE_LEFT_POT_3, RAND_INF_FIRE_TEMPLE_FLAME_MAZE_LEFT_POT_3 }, + { RC_FIRE_TEMPLE_FLAME_MAZE_LEFT_POT_4, RAND_INF_FIRE_TEMPLE_FLAME_MAZE_LEFT_POT_4 }, + { RC_FIRE_TEMPLE_FLAME_MAZE_RIGHT_POT_1, RAND_INF_FIRE_TEMPLE_FLAME_MAZE_RIGHT_POT_1 }, + { RC_FIRE_TEMPLE_FLAME_MAZE_RIGHT_POT_2, RAND_INF_FIRE_TEMPLE_FLAME_MAZE_RIGHT_POT_2 }, + { RC_FIRE_TEMPLE_FLAME_MAZE_RIGHT_POT_3, RAND_INF_FIRE_TEMPLE_FLAME_MAZE_RIGHT_POT_3 }, + { RC_FIRE_TEMPLE_FLAME_MAZE_RIGHT_POT_4, RAND_INF_FIRE_TEMPLE_FLAME_MAZE_RIGHT_POT_4 }, + { RC_WATER_TEMPLE_MAIN_LEVEL_2_POT_1, RAND_INF_WATER_TEMPLE_MAIN_LEVEL_2_POT_1 }, + { RC_WATER_TEMPLE_MAIN_LEVEL_2_POT_2, RAND_INF_WATER_TEMPLE_MAIN_LEVEL_2_POT_2 }, + { RC_WATER_TEMPLE_MAIN_LEVEL_1_POT_1, RAND_INF_WATER_TEMPLE_MAIN_LEVEL_1_POT_1 }, + { RC_WATER_TEMPLE_MAIN_LEVEL_1_POT_2, RAND_INF_WATER_TEMPLE_MAIN_LEVEL_1_POT_2 }, + { RC_WATER_TEMPLE_TORCH_POT_1, RAND_INF_WATER_TEMPLE_TORCH_POT_1 }, + { RC_WATER_TEMPLE_TORCH_POT_2, RAND_INF_WATER_TEMPLE_TORCH_POT_2 }, + { RC_WATER_TEMPLE_NEAR_COMPASS_POT_1, RAND_INF_WATER_TEMPLE_NEAR_COMPASS_POT_1 }, + { RC_WATER_TEMPLE_NEAR_COMPASS_POT_2, RAND_INF_WATER_TEMPLE_NEAR_COMPASS_POT_2 }, + { RC_WATER_TEMPLE_NEAR_COMPASS_POT_3, RAND_INF_WATER_TEMPLE_NEAR_COMPASS_POT_3 }, + { RC_WATER_TEMPLE_CENTRAL_BOW_POT_1, RAND_INF_WATER_TEMPLE_CENTRAL_BOW_POT_1 }, + { RC_WATER_TEMPLE_CENTRAL_BOW_POT_2, RAND_INF_WATER_TEMPLE_CENTRAL_BOW_POT_2 }, + { RC_WATER_TEMPLE_BEHIND_GATE_POT_1, RAND_INF_WATER_TEMPLE_BEHIND_GATE_POT_1 }, + { RC_WATER_TEMPLE_BEHIND_GATE_POT_2, RAND_INF_WATER_TEMPLE_BEHIND_GATE_POT_2 }, + { RC_WATER_TEMPLE_BEHIND_GATE_POT_3, RAND_INF_WATER_TEMPLE_BEHIND_GATE_POT_3 }, + { RC_WATER_TEMPLE_BEHIND_GATE_POT_4, RAND_INF_WATER_TEMPLE_BEHIND_GATE_POT_4 }, + { RC_WATER_TEMPLE_BASEMENT_BLOCK_PUZZLE_POT_1, RAND_INF_WATER_TEMPLE_BASEMENT_BLOCK_PUZZLE_POT_1 }, + { RC_WATER_TEMPLE_BASEMENT_BLOCK_PUZZLE_POT_2, RAND_INF_WATER_TEMPLE_BASEMENT_BLOCK_PUZZLE_POT_2 }, + { RC_WATER_TEMPLE_RIVER_POT_1, RAND_INF_WATER_TEMPLE_RIVER_POT_1 }, + { RC_WATER_TEMPLE_RIVER_POT_2, RAND_INF_WATER_TEMPLE_RIVER_POT_2 }, + { RC_WATER_TEMPLE_LIKE_LIKE_POT_1, RAND_INF_WATER_TEMPLE_LIKE_LIKE_POT_1 }, + { RC_WATER_TEMPLE_LIKE_LIKE_POT_2, RAND_INF_WATER_TEMPLE_LIKE_LIKE_POT_2 }, + { RC_WATER_TEMPLE_BOSS_KEY_POT_1, RAND_INF_WATER_TEMPLE_BOSS_KEY_POT_1 }, + { RC_WATER_TEMPLE_BOSS_KEY_POT_2, RAND_INF_WATER_TEMPLE_BOSS_KEY_POT_2 }, + { RC_SHADOW_TEMPLE_NEAR_DEAD_HAND_POT_1, RAND_INF_SHADOW_TEMPLE_NEAR_DEAD_HAND_POT_1 }, + { RC_SHADOW_TEMPLE_WHISPERING_WALLS_POT_1, RAND_INF_SHADOW_TEMPLE_WHISPERING_WALLS_POT_1 }, + { RC_SHADOW_TEMPLE_WHISPERING_WALLS_POT_2, RAND_INF_SHADOW_TEMPLE_WHISPERING_WALLS_POT_2 }, + { RC_SHADOW_TEMPLE_WHISPERING_WALLS_POT_3, RAND_INF_SHADOW_TEMPLE_WHISPERING_WALLS_POT_3 }, + { RC_SHADOW_TEMPLE_WHISPERING_WALLS_POT_4, RAND_INF_SHADOW_TEMPLE_WHISPERING_WALLS_POT_4 }, + { RC_SHADOW_TEMPLE_WHISPERING_WALLS_POT_5, RAND_INF_SHADOW_TEMPLE_WHISPERING_WALLS_POT_5 }, + { RC_SHADOW_TEMPLE_MAP_CHEST_POT_1, RAND_INF_SHADOW_TEMPLE_MAP_CHEST_POT_1 }, + { RC_SHADOW_TEMPLE_MAP_CHEST_POT_2, RAND_INF_SHADOW_TEMPLE_MAP_CHEST_POT_2 }, + { RC_SHADOW_TEMPLE_FALLING_SPIKES_POT_1, RAND_INF_SHADOW_TEMPLE_FALLING_SPIKES_POT_1 }, + { RC_SHADOW_TEMPLE_FALLING_SPIKES_POT_2, RAND_INF_SHADOW_TEMPLE_FALLING_SPIKES_POT_2 }, + { RC_SHADOW_TEMPLE_FALLING_SPIKES_POT_3, RAND_INF_SHADOW_TEMPLE_FALLING_SPIKES_POT_3 }, + { RC_SHADOW_TEMPLE_FALLING_SPIKES_POT_4, RAND_INF_SHADOW_TEMPLE_FALLING_SPIKES_POT_4 }, + { RC_SHADOW_TEMPLE_AFTER_WIND_POT_1, RAND_INF_SHADOW_TEMPLE_AFTER_WIND_POT_1 }, + { RC_SHADOW_TEMPLE_AFTER_WIND_POT_2, RAND_INF_SHADOW_TEMPLE_AFTER_WIND_POT_2 }, + { RC_SHADOW_TEMPLE_SPIKE_WALLS_POT_1, RAND_INF_SHADOW_TEMPLE_SPIKE_WALLS_POT_1 }, + { RC_SHADOW_TEMPLE_FLOORMASTER_POT_1, RAND_INF_SHADOW_TEMPLE_FLOORMASTER_POT_1 }, + { RC_SHADOW_TEMPLE_FLOORMASTER_POT_2, RAND_INF_SHADOW_TEMPLE_FLOORMASTER_POT_2 }, + { RC_SHADOW_TEMPLE_AFTER_BOAT_POT_1, RAND_INF_SHADOW_TEMPLE_AFTER_BOAT_POT_1 }, + { RC_SHADOW_TEMPLE_AFTER_BOAT_POT_2, RAND_INF_SHADOW_TEMPLE_AFTER_BOAT_POT_2 }, + { RC_SHADOW_TEMPLE_AFTER_BOAT_POT_3, RAND_INF_SHADOW_TEMPLE_AFTER_BOAT_POT_3 }, + { RC_SHADOW_TEMPLE_AFTER_BOAT_POT_4, RAND_INF_SHADOW_TEMPLE_AFTER_BOAT_POT_4 }, + { RC_SPIRIT_TEMPLE_LOBBY_POT_1, RAND_INF_SPIRIT_TEMPLE_LOBBY_POT_1 }, + { RC_SPIRIT_TEMPLE_LOBBY_POT_2, RAND_INF_SPIRIT_TEMPLE_LOBBY_POT_2 }, + { RC_SPIRIT_TEMPLE_ANUBIS_POT_1, RAND_INF_SPIRIT_TEMPLE_ANUBIS_POT_1 }, + { RC_SPIRIT_TEMPLE_ANUBIS_POT_2, RAND_INF_SPIRIT_TEMPLE_ANUBIS_POT_2 }, + { RC_SPIRIT_TEMPLE_ANUBIS_POT_3, RAND_INF_SPIRIT_TEMPLE_ANUBIS_POT_3 }, + { RC_SPIRIT_TEMPLE_ANUBIS_POT_4, RAND_INF_SPIRIT_TEMPLE_ANUBIS_POT_4 }, + { RC_SPIRIT_TEMPLE_CHILD_CLIMB_POT_1, RAND_INF_SPIRIT_TEMPLE_CHILD_CLIMB_POT_1 }, + { RC_SPIRIT_TEMPLE_AFTER_SUN_BLOCK_POT_1, RAND_INF_SPIRIT_TEMPLE_AFTER_SUN_BLOCK_POT_1 }, + { RC_SPIRIT_TEMPLE_AFTER_SUN_BLOCK_POT_2, RAND_INF_SPIRIT_TEMPLE_AFTER_SUN_BLOCK_POT_2 }, + { RC_SPIRIT_TEMPLE_CENTRAL_CHAMBER_POT_1, RAND_INF_SPIRIT_TEMPLE_CENTRAL_CHAMBER_POT_1 }, + { RC_SPIRIT_TEMPLE_CENTRAL_CHAMBER_POT_2, RAND_INF_SPIRIT_TEMPLE_CENTRAL_CHAMBER_POT_2 }, + { RC_SPIRIT_TEMPLE_CENTRAL_CHAMBER_POT_3, RAND_INF_SPIRIT_TEMPLE_CENTRAL_CHAMBER_POT_3 }, + { RC_SPIRIT_TEMPLE_CENTRAL_CHAMBER_POT_4, RAND_INF_SPIRIT_TEMPLE_CENTRAL_CHAMBER_POT_4 }, + { RC_SPIRIT_TEMPLE_CENTRAL_CHAMBER_POT_5, RAND_INF_SPIRIT_TEMPLE_CENTRAL_CHAMBER_POT_5 }, + { RC_SPIRIT_TEMPLE_CENTRAL_CHAMBER_POT_6, RAND_INF_SPIRIT_TEMPLE_CENTRAL_CHAMBER_POT_6 }, + { RC_SPIRIT_TEMPLE_BEAMOS_HALL_POT_1, RAND_INF_SPIRIT_TEMPLE_BEAMOS_HALL_POT_1 }, + { RC_GANONS_CASTLE_FOREST_TRIAL_POT_1, RAND_INF_GANONS_CASTLE_FOREST_TRIAL_POT_1 }, + { RC_GANONS_CASTLE_FOREST_TRIAL_POT_2, RAND_INF_GANONS_CASTLE_FOREST_TRIAL_POT_2 }, + { RC_GANONS_CASTLE_FIRE_TRIAL_POT_1, RAND_INF_GANONS_CASTLE_FIRE_TRIAL_POT_1 }, + { RC_GANONS_CASTLE_FIRE_TRIAL_POT_2, RAND_INF_GANONS_CASTLE_FIRE_TRIAL_POT_2 }, + { RC_GANONS_CASTLE_WATER_TRIAL_POT_1, RAND_INF_GANONS_CASTLE_WATER_TRIAL_POT_1 }, + { RC_GANONS_CASTLE_WATER_TRIAL_POT_2, RAND_INF_GANONS_CASTLE_WATER_TRIAL_POT_2 }, + { RC_GANONS_CASTLE_WATER_TRIAL_POT_3, RAND_INF_GANONS_CASTLE_WATER_TRIAL_POT_3 }, + { RC_GANONS_CASTLE_SHADOW_TRIAL_POT_1, RAND_INF_GANONS_CASTLE_SHADOW_TRIAL_POT_1 }, + { RC_GANONS_CASTLE_SHADOW_TRIAL_POT_2, RAND_INF_GANONS_CASTLE_SHADOW_TRIAL_POT_2 }, + { RC_GANONS_CASTLE_SHADOW_TRIAL_POT_3, RAND_INF_GANONS_CASTLE_SHADOW_TRIAL_POT_3 }, + { RC_GANONS_CASTLE_SHADOW_TRIAL_POT_4, RAND_INF_GANONS_CASTLE_SHADOW_TRIAL_POT_4 }, + { RC_GANONS_CASTLE_SPIRIT_TRIAL_POT_1, RAND_INF_GANONS_CASTLE_SPIRIT_TRIAL_POT_1 }, + { RC_GANONS_CASTLE_SPIRIT_TRIAL_POT_2, RAND_INF_GANONS_CASTLE_SPIRIT_TRIAL_POT_2 }, + { RC_GANONS_CASTLE_LIGHT_TRIAL_BOULDER_POT_1, RAND_INF_GANONS_CASTLE_LIGHT_TRIAL_BOULDER_POT_1 }, + { RC_GANONS_CASTLE_LIGHT_TRIAL_POT_1, RAND_INF_GANONS_CASTLE_LIGHT_TRIAL_POT_1 }, + { RC_GANONS_CASTLE_LIGHT_TRIAL_POT_2, RAND_INF_GANONS_CASTLE_LIGHT_TRIAL_POT_2 }, + { RC_GANONS_CASTLE_GANONS_TOWER_POT_1, RAND_INF_GANONS_CASTLE_GANONS_TOWER_POT_1 }, + { RC_GANONS_CASTLE_GANONS_TOWER_POT_2, RAND_INF_GANONS_CASTLE_GANONS_TOWER_POT_2 }, + { RC_GANONS_CASTLE_GANONS_TOWER_POT_3, RAND_INF_GANONS_CASTLE_GANONS_TOWER_POT_3 }, + { RC_GANONS_CASTLE_GANONS_TOWER_POT_4, RAND_INF_GANONS_CASTLE_GANONS_TOWER_POT_4 }, + { RC_GANONS_CASTLE_GANONS_TOWER_POT_5, RAND_INF_GANONS_CASTLE_GANONS_TOWER_POT_5 }, + { RC_GANONS_CASTLE_GANONS_TOWER_POT_6, RAND_INF_GANONS_CASTLE_GANONS_TOWER_POT_6 }, + { RC_GANONS_CASTLE_GANONS_TOWER_POT_7, RAND_INF_GANONS_CASTLE_GANONS_TOWER_POT_7 }, + { RC_GANONS_CASTLE_GANONS_TOWER_POT_8, RAND_INF_GANONS_CASTLE_GANONS_TOWER_POT_8 }, + { RC_GANONS_CASTLE_GANONS_TOWER_POT_9, RAND_INF_GANONS_CASTLE_GANONS_TOWER_POT_9 }, + { RC_GANONS_CASTLE_GANONS_TOWER_POT_10, RAND_INF_GANONS_CASTLE_GANONS_TOWER_POT_10 }, + { RC_GANONS_CASTLE_GANONS_TOWER_POT_11, RAND_INF_GANONS_CASTLE_GANONS_TOWER_POT_11 }, + { RC_GANONS_CASTLE_GANONS_TOWER_POT_12, RAND_INF_GANONS_CASTLE_GANONS_TOWER_POT_12 }, + { RC_GANONS_CASTLE_GANONS_TOWER_POT_13, RAND_INF_GANONS_CASTLE_GANONS_TOWER_POT_13 }, + { RC_GANONS_CASTLE_GANONS_TOWER_POT_14, RAND_INF_GANONS_CASTLE_GANONS_TOWER_POT_14 }, + { RC_GANONS_CASTLE_GANONS_TOWER_POT_15, RAND_INF_GANONS_CASTLE_GANONS_TOWER_POT_15 }, + { RC_GANONS_CASTLE_GANONS_TOWER_POT_16, RAND_INF_GANONS_CASTLE_GANONS_TOWER_POT_16 }, + { RC_GANONS_CASTLE_GANONS_TOWER_POT_17, RAND_INF_GANONS_CASTLE_GANONS_TOWER_POT_17 }, + { RC_GANONS_CASTLE_GANONS_TOWER_POT_18, RAND_INF_GANONS_CASTLE_GANONS_TOWER_POT_18 }, + { RC_BOTTOM_OF_THE_WELL_BASEMENT_POT_1, RAND_INF_BOTTOM_OF_THE_WELL_BASEMENT_POT_1 }, + { RC_BOTTOM_OF_THE_WELL_BASEMENT_POT_2, RAND_INF_BOTTOM_OF_THE_WELL_BASEMENT_POT_2 }, + { RC_BOTTOM_OF_THE_WELL_BASEMENT_POT_3, RAND_INF_BOTTOM_OF_THE_WELL_BASEMENT_POT_3 }, + { RC_BOTTOM_OF_THE_WELL_BASEMENT_POT_4, RAND_INF_BOTTOM_OF_THE_WELL_BASEMENT_POT_4 }, + { RC_BOTTOM_OF_THE_WELL_BASEMENT_POT_5, RAND_INF_BOTTOM_OF_THE_WELL_BASEMENT_POT_5 }, + { RC_BOTTOM_OF_THE_WELL_BASEMENT_POT_6, RAND_INF_BOTTOM_OF_THE_WELL_BASEMENT_POT_6 }, + { RC_BOTTOM_OF_THE_WELL_BASEMENT_POT_7, RAND_INF_BOTTOM_OF_THE_WELL_BASEMENT_POT_7 }, + { RC_BOTTOM_OF_THE_WELL_BASEMENT_POT_8, RAND_INF_BOTTOM_OF_THE_WELL_BASEMENT_POT_8 }, + { RC_BOTTOM_OF_THE_WELL_BASEMENT_POT_9, RAND_INF_BOTTOM_OF_THE_WELL_BASEMENT_POT_9 }, + { RC_BOTTOM_OF_THE_WELL_BASEMENT_POT_10, RAND_INF_BOTTOM_OF_THE_WELL_BASEMENT_POT_10 }, + { RC_BOTTOM_OF_THE_WELL_BASEMENT_POT_11, RAND_INF_BOTTOM_OF_THE_WELL_BASEMENT_POT_11 }, + { RC_BOTTOM_OF_THE_WELL_BASEMENT_POT_12, RAND_INF_BOTTOM_OF_THE_WELL_BASEMENT_POT_12 }, + { RC_BOTTOM_OF_THE_WELL_LEFT_SIDE_POT_1, RAND_INF_BOTTOM_OF_THE_WELL_LEFT_SIDE_POT_1 }, + { RC_BOTTOM_OF_THE_WELL_LEFT_SIDE_POT_2, RAND_INF_BOTTOM_OF_THE_WELL_LEFT_SIDE_POT_2 }, + { RC_BOTTOM_OF_THE_WELL_LEFT_SIDE_POT_3, RAND_INF_BOTTOM_OF_THE_WELL_LEFT_SIDE_POT_3 }, + { RC_BOTTOM_OF_THE_WELL_NEAR_ENTRANCE_POT_1, RAND_INF_BOTTOM_OF_THE_WELL_NEAR_ENTRANCE_POT_1 }, + { RC_BOTTOM_OF_THE_WELL_NEAR_ENTRANCE_POT_2, RAND_INF_BOTTOM_OF_THE_WELL_NEAR_ENTRANCE_POT_2 }, + { RC_BOTTOM_OF_THE_WELL_FIRE_KEESE_POT_1, RAND_INF_BOTTOM_OF_THE_WELL_FIRE_KEESE_POT_1 }, + { RC_BOTTOM_OF_THE_WELL_UNDERWATER_POT, RAND_INF_BOTTOM_OF_THE_WELL_UNDERWATER_POT }, + { RC_ICE_CAVERN_HALL_POT_1, RAND_INF_ICE_CAVERN_HALL_POT_1 }, + { RC_ICE_CAVERN_HALL_POT_2, RAND_INF_ICE_CAVERN_HALL_POT_2 }, + { RC_ICE_CAVERN_SPINNING_BLADE_POT_1, RAND_INF_ICE_CAVERN_SPINNING_BLADE_POT_1 }, + { RC_ICE_CAVERN_SPINNING_BLADE_POT_2, RAND_INF_ICE_CAVERN_SPINNING_BLADE_POT_2 }, + { RC_ICE_CAVERN_SPINNING_BLADE_POT_3, RAND_INF_ICE_CAVERN_SPINNING_BLADE_POT_3 }, + { RC_ICE_CAVERN_NEAR_END_POT_1, RAND_INF_ICE_CAVERN_NEAR_END_POT_1 }, + { RC_ICE_CAVERN_NEAR_END_POT_2, RAND_INF_ICE_CAVERN_NEAR_END_POT_2 }, + { RC_ICE_CAVERN_FROZEN_POT_1, RAND_INF_ICE_CAVERN_FROZEN_POT_1 }, + + { RC_JABU_JABUS_BELLY_MQ_ENTRANCE_POT_1, RAND_INF_JABU_JABUS_BELLY_MQ_ENTRANCE_POT_1 }, + { RC_JABU_JABUS_BELLY_MQ_ENTRANCE_POT_2, RAND_INF_JABU_JABUS_BELLY_MQ_ENTRANCE_POT_2 }, + { RC_JABU_JABUS_BELLY_MQ_GEYSER_POT_1, RAND_INF_JABU_JABUS_BELLY_MQ_GEYSER_POT_1 }, + { RC_JABU_JABUS_BELLY_MQ_GEYSER_POT_2, RAND_INF_JABU_JABUS_BELLY_MQ_GEYSER_POT_2 }, + { RC_JABU_JABUS_BELLY_MQ_TIME_BLOCK_POT_1, RAND_INF_JABU_JABUS_BELLY_MQ_TIME_BLOCK_POT_1 }, + { RC_JABU_JABUS_BELLY_MQ_TIME_BLOCK_POT_2, RAND_INF_JABU_JABUS_BELLY_MQ_TIME_BLOCK_POT_2 }, + { RC_JABU_JABUS_BELLY_MQ_LIKE_LIKES_POT_1, RAND_INF_JABU_JABUS_BELLY_MQ_LIKE_LIKES_POT_1 }, + { RC_JABU_JABUS_BELLY_MQ_LIKE_LIKES_POT_2, RAND_INF_JABU_JABUS_BELLY_MQ_LIKE_LIKES_POT_2 }, + { RC_JABU_JABUS_BELLY_MQ_BEFORE_BOSS_POT_1, RAND_INF_JABU_JABUS_BELLY_MQ_BEFORE_BOSS_POT_1 }, + { RC_FOREST_TEMPLE_MQ_LOBBY_POT_1, RAND_INF_FOREST_TEMPLE_MQ_LOBBY_POT_1 }, + { RC_FOREST_TEMPLE_MQ_LOBBY_POT_2, RAND_INF_FOREST_TEMPLE_MQ_LOBBY_POT_2 }, + { RC_FOREST_TEMPLE_MQ_LOBBY_POT_3, RAND_INF_FOREST_TEMPLE_MQ_LOBBY_POT_3 }, + { RC_FOREST_TEMPLE_MQ_LOBBY_POT_4, RAND_INF_FOREST_TEMPLE_MQ_LOBBY_POT_4 }, + { RC_FOREST_TEMPLE_MQ_LOBBY_POT_5, RAND_INF_FOREST_TEMPLE_MQ_LOBBY_POT_5 }, + { RC_FOREST_TEMPLE_MQ_LOBBY_POT_6, RAND_INF_FOREST_TEMPLE_MQ_LOBBY_POT_6 }, + { RC_FOREST_TEMPLE_MQ_WOLFOS_POT_1, RAND_INF_FOREST_TEMPLE_MQ_LOWER_STALFOS_POT_1 }, + { RC_FOREST_TEMPLE_MQ_WOLFOS_POT_2, RAND_INF_FOREST_TEMPLE_MQ_LOWER_STALFOS_POT_2 }, + { RC_FOREST_TEMPLE_MQ_UPPER_STALFOS_POT_1, RAND_INF_FOREST_TEMPLE_MQ_UPPER_STALFOS_POT_1 }, + { RC_FOREST_TEMPLE_MQ_UPPER_STALFOS_POT_2, RAND_INF_FOREST_TEMPLE_MQ_UPPER_STALFOS_POT_2 }, + { RC_FOREST_TEMPLE_MQ_UPPER_STALFOS_POT_3, RAND_INF_FOREST_TEMPLE_MQ_UPPER_STALFOS_POT_3 }, + { RC_FOREST_TEMPLE_MQ_UPPER_STALFOS_POT_4, RAND_INF_FOREST_TEMPLE_MQ_UPPER_STALFOS_POT_4 }, + { RC_FOREST_TEMPLE_MQ_BLUE_POE_POT_1, RAND_INF_FOREST_TEMPLE_MQ_BLUE_POE_POT_1 }, + { RC_FOREST_TEMPLE_MQ_BLUE_POE_POT_2, RAND_INF_FOREST_TEMPLE_MQ_BLUE_POE_POT_2 }, + { RC_FOREST_TEMPLE_MQ_BLUE_POE_POT_3, RAND_INF_FOREST_TEMPLE_MQ_BLUE_POE_POT_3 }, + { RC_FOREST_TEMPLE_MQ_GREEN_POE_POT_1, RAND_INF_FOREST_TEMPLE_MQ_GREEN_POE_POT_1 }, + { RC_FOREST_TEMPLE_MQ_GREEN_POE_POT_2, RAND_INF_FOREST_TEMPLE_MQ_GREEN_POE_POT_2 }, + { RC_FOREST_TEMPLE_MQ_BASEMENT_POT_1, RAND_INF_FOREST_TEMPLE_MQ_BASEMENT_POT_1 }, + { RC_FOREST_TEMPLE_MQ_BASEMENT_POT_2, RAND_INF_FOREST_TEMPLE_MQ_BASEMENT_POT_2 }, + { RC_FOREST_TEMPLE_MQ_BASEMENT_POT_3, RAND_INF_FOREST_TEMPLE_MQ_BASEMENT_POT_3 }, + { RC_FOREST_TEMPLE_MQ_BASEMENT_POT_4, RAND_INF_FOREST_TEMPLE_MQ_BASEMENT_POT_4 }, + { RC_DODONGOS_CAVERN_MQ_RIGHT_SIDE_POT_1, RAND_INF_DODONGOS_CAVERN_MQ_RIGHT_SIDE_POT_1 }, + { RC_DODONGOS_CAVERN_MQ_RIGHT_SIDE_POT_2, RAND_INF_DODONGOS_CAVERN_MQ_RIGHT_SIDE_POT_2 }, + { RC_DODONGOS_CAVERN_MQ_RIGHT_SIDE_POT_3, RAND_INF_DODONGOS_CAVERN_MQ_RIGHT_SIDE_POT_3 }, + { RC_DODONGOS_CAVERN_MQ_RIGHT_SIDE_POT_4, RAND_INF_DODONGOS_CAVERN_MQ_RIGHT_SIDE_POT_4 }, + { RC_DODONGOS_CAVERN_MQ_UPPER_LIZALFOS_POT_1, RAND_INF_DODONGOS_CAVERN_MQ_UPPER_LIZALFOS_POT_1 }, + { RC_DODONGOS_CAVERN_MQ_UPPER_LIZALFOS_POT_2, RAND_INF_DODONGOS_CAVERN_MQ_UPPER_LIZALFOS_POT_2 }, + { RC_DODONGOS_CAVERN_MQ_UPPER_LIZALFOS_POT_3, RAND_INF_DODONGOS_CAVERN_MQ_UPPER_LIZALFOS_POT_3 }, + { RC_DODONGOS_CAVERN_MQ_UPPER_LIZALFOS_POT_4, RAND_INF_DODONGOS_CAVERN_MQ_UPPER_LIZALFOS_POT_4 }, + { RC_DODONGOS_CAVERN_MQ_POE_ROOM_POT_1, RAND_INF_DODONGOS_CAVERN_MQ_POE_ROOM_POT_1 }, + { RC_DODONGOS_CAVERN_MQ_POE_ROOM_POT_2, RAND_INF_DODONGOS_CAVERN_MQ_POE_ROOM_POT_2 }, + { RC_DODONGOS_CAVERN_MQ_POE_ROOM_POT_3, RAND_INF_DODONGOS_CAVERN_MQ_POE_ROOM_POT_3 }, + { RC_DODONGOS_CAVERN_MQ_POE_ROOM_POT_4, RAND_INF_DODONGOS_CAVERN_MQ_POE_ROOM_POT_4 }, + { RC_DODONGOS_CAVERN_MQ_TORCH_PUZZLE_CORNER_POT, RAND_INF_DODONGOS_CAVERN_MQ_BLOCK_ROOM_POT_1 }, + { RC_DODONGOS_CAVERN_MQ_TORCH_PUZZLE_MIDDLE_POT, RAND_INF_DODONGOS_CAVERN_MQ_BLOCK_ROOM_POT_2 }, + { RC_DODONGOS_CAVERN_MQ_TWO_FLAMES_POT_1, RAND_INF_DODONGOS_CAVERN_MQ_TWO_FLAMES_POT_1 }, + { RC_DODONGOS_CAVERN_MQ_TWO_FLAMES_POT_2, RAND_INF_DODONGOS_CAVERN_MQ_TWO_FLAMES_POT_2 }, + { RC_DODONGOS_CAVERN_MQ_BIG_BLOCK_POT_1, RAND_INF_DODONGOS_CAVERN_MQ_SILVER_BLOCK_POT_1 }, + { RC_DODONGOS_CAVERN_MQ_BIG_BLOCK_POT_2, RAND_INF_DODONGOS_CAVERN_MQ_SILVER_BLOCK_POT_2 }, + { RC_DODONGOS_CAVERN_MQ_STAIRCASE_POT_1, RAND_INF_DODONGOS_CAVERN_MQ_STAIRCASE_POT_1 }, + { RC_DODONGOS_CAVERN_MQ_STAIRCASE_POT_2, RAND_INF_DODONGOS_CAVERN_MQ_STAIRCASE_POT_2 }, + { RC_DODONGOS_CAVERN_MQ_STAIRCASE_POT_3, RAND_INF_DODONGOS_CAVERN_MQ_STAIRCASE_POT_3 }, + { RC_DODONGOS_CAVERN_MQ_STAIRCASE_POT_4, RAND_INF_DODONGOS_CAVERN_MQ_STAIRCASE_POT_4 }, + { RC_DODONGOS_CAVERN_MQ_ARMOS_ROOM_NW_POT, RAND_INF_DODONGOS_CAVERN_MQ_ARMOS_POT_1 }, + { RC_DODONGOS_CAVERN_MQ_ARMOS_ROOM_NE_POT, RAND_INF_DODONGOS_CAVERN_MQ_ARMOS_POT_2 }, + { RC_DODONGOS_CAVERN_MQ_ARMOS_ROOM_SE_POT, RAND_INF_DODONGOS_CAVERN_MQ_ARMOS_POT_3 }, + { RC_DODONGOS_CAVERN_MQ_ARMOS_ROOM_SW_POT, RAND_INF_DODONGOS_CAVERN_MQ_ARMOS_POT_4 }, + { RC_DODONGOS_CAVERN_MQ_BEFORE_BOSS_SW_POT, RAND_INF_DODONGOS_CAVERN_MQ_BEFORE_BOSS_POT_1 }, + { RC_DODONGOS_CAVERN_MQ_BEFORE_BOSS_NE_POT, RAND_INF_DODONGOS_CAVERN_MQ_BEFORE_BOSS_POT_2 }, + { RC_DODONGOS_CAVERN_MQ_BACKROOM_POT_1, RAND_INF_DODONGOS_CAVERN_MQ_BACKROOM_POT_1 }, + { RC_DODONGOS_CAVERN_MQ_BACKROOM_POT_2, RAND_INF_DODONGOS_CAVERN_MQ_BACKROOM_POT_2 }, + { RC_GANONS_CASTLE_MQ_FOREST_TRIAL_POT_1, RAND_INF_GANONS_CASTLE_MQ_FOREST_TRIAL_POT_1 }, + { RC_GANONS_CASTLE_MQ_FOREST_TRIAL_POT_2, RAND_INF_GANONS_CASTLE_MQ_FOREST_TRIAL_POT_2 }, + { RC_GANONS_CASTLE_MQ_WATER_TRIAL_POT_1, RAND_INF_GANONS_CASTLE_MQ_WATER_TRIAL_POT_1 }, + { RC_GANONS_CASTLE_MQ_WATER_TRIAL_POT_2, RAND_INF_GANONS_CASTLE_MQ_WATER_TRIAL_POT_2 }, + { RC_GANONS_CASTLE_MQ_SHADOW_TRIAL_POT_1, RAND_INF_GANONS_CASTLE_MQ_SHADOW_TRIAL_POT_1 }, + { RC_GANONS_CASTLE_MQ_SHADOW_TRIAL_POT_2, RAND_INF_GANONS_CASTLE_MQ_SHADOW_TRIAL_POT_2 }, + { RC_GANONS_CASTLE_MQ_FIRE_TRIAL_POT_1, RAND_INF_GANONS_CASTLE_MQ_FIRE_TRIAL_POT_1 }, + { RC_GANONS_CASTLE_MQ_FIRE_TRIAL_POT_2, RAND_INF_GANONS_CASTLE_MQ_FIRE_TRIAL_POT_2 }, + { RC_GANONS_CASTLE_MQ_LIGHT_TRIAL_POT_1, RAND_INF_GANONS_CASTLE_MQ_LIGHT_TRIAL_POT_1 }, + { RC_GANONS_CASTLE_MQ_LIGHT_TRIAL_POT_2, RAND_INF_GANONS_CASTLE_MQ_LIGHT_TRIAL_POT_2 }, + { RC_GANONS_CASTLE_MQ_SPIRIT_TRIAL_POT_1, RAND_INF_GANONS_CASTLE_MQ_SPIRIT_TRIAL_POT_1 }, + { RC_GANONS_CASTLE_MQ_SPIRIT_TRIAL_POT_2, RAND_INF_GANONS_CASTLE_MQ_SPIRIT_TRIAL_POT_2 }, + { RC_SHADOW_TEMPLE_MQ_WHISPERING_WALLS_POT_1, RAND_INF_SHADOW_TEMPLE_MQ_WHISPERING_WALLS_POT_1 }, + { RC_SHADOW_TEMPLE_MQ_WHISPERING_WALLS_POT_2, RAND_INF_SHADOW_TEMPLE_MQ_WHISPERING_WALLS_POT_2 }, + { RC_SHADOW_TEMPLE_MQ_ENTRANCE_REDEAD_POT_1, RAND_INF_SHADOW_TEMPLE_MQ_ENTRANCE_REDEAD_POT_1 }, + { RC_SHADOW_TEMPLE_MQ_ENTRANCE_REDEAD_POT_2, RAND_INF_SHADOW_TEMPLE_MQ_ENTRANCE_REDEAD_POT_2 }, + { RC_SHADOW_TEMPLE_MQ_LOWER_UMBRELLA_WEST_POT, RAND_INF_SHADOW_TEMPLE_MQ_FALLING_SPIKES_POT_1 }, + { RC_SHADOW_TEMPLE_MQ_LOWER_UMBRELLA_EAST_POT, RAND_INF_SHADOW_TEMPLE_MQ_FALLING_SPIKES_POT_2 }, + { RC_SHADOW_TEMPLE_MQ_UPPER_UMBRELLA_SOUTH_POT, RAND_INF_SHADOW_TEMPLE_MQ_FALLING_SPIKES_POT_3 }, + { RC_SHADOW_TEMPLE_MQ_UPPER_UMBRELLA_NORTH_POT, RAND_INF_SHADOW_TEMPLE_MQ_FALLING_SPIKES_POT_4 }, + { RC_SHADOW_TEMPLE_MQ_BEFORE_BOAT_POT_1, RAND_INF_SHADOW_TEMPLE_MQ_BEFORE_BOAT_POT_1 }, + { RC_SHADOW_TEMPLE_MQ_BEFORE_BOAT_POT_2, RAND_INF_SHADOW_TEMPLE_MQ_BEFORE_BOAT_POT_2 }, + { RC_SHADOW_TEMPLE_MQ_BEFORE_CHASM_WEST_POT, RAND_INF_SHADOW_TEMPLE_MQ_AFTER_BOAT_POT_1 }, + { RC_SHADOW_TEMPLE_MQ_BEFORE_CHASM_EAST_POT, RAND_INF_SHADOW_TEMPLE_MQ_AFTER_BOAT_POT_2 }, + { RC_SHADOW_TEMPLE_MQ_AFTER_CHASM_WEST_POT, RAND_INF_SHADOW_TEMPLE_MQ_AFTER_BOAT_POT_3 }, + { RC_SHADOW_TEMPLE_MQ_AFTER_CHASM_EAST_POT, RAND_INF_SHADOW_TEMPLE_MQ_AFTER_BOAT_POT_4 }, + { RC_SHADOW_TEMPLE_MQ_SPIKE_BARICADE_POT, RAND_INF_SHADOW_TEMPLE_MQ_SPIKE_BARICADE_POT }, + { RC_SHADOW_TEMPLE_MQ_DEAD_HAND_POT_1, RAND_INF_SHADOW_TEMPLE_MQ_DEAD_HAND_POT_1 }, + { RC_SHADOW_TEMPLE_MQ_DEAD_HAND_POT_2, RAND_INF_SHADOW_TEMPLE_MQ_DEAD_HAND_POT_2 }, + { RC_BOTTOM_OF_THE_WELL_MQ_INNER_LOBBY_POT_1, RAND_INF_BOTTOM_OF_THE_WELL_MQ_INNER_LOBBY_POT_1 }, + { RC_BOTTOM_OF_THE_WELL_MQ_INNER_LOBBY_POT_2, RAND_INF_BOTTOM_OF_THE_WELL_MQ_INNER_LOBBY_POT_2 }, + { RC_BOTTOM_OF_THE_WELL_MQ_INNER_LOBBY_POT_3, RAND_INF_BOTTOM_OF_THE_WELL_MQ_INNER_LOBBY_POT_3 }, + { RC_BOTTOM_OF_THE_WELL_MQ_OUTER_LOBBY_POT, RAND_INF_BOTTOM_OF_THE_WELL_MQ_OUTER_LOBBY_POT }, + { RC_BOTTOM_OF_THE_WELL_MQ_EAST_INNER_ROOM_POT_1, RAND_INF_BOTTOM_OF_THE_WELL_MQ_SOUTH_KEY_POT_1 }, + { RC_BOTTOM_OF_THE_WELL_MQ_EAST_INNER_ROOM_POT_2, RAND_INF_BOTTOM_OF_THE_WELL_MQ_SOUTH_KEY_POT_2 }, + { RC_BOTTOM_OF_THE_WELL_MQ_EAST_INNER_ROOM_POT_3, RAND_INF_BOTTOM_OF_THE_WELL_MQ_SOUTH_KEY_POT_3 }, + { RC_FIRE_TEMPLE_MQ_ENTRANCE_POT_1, RAND_INF_FIRE_TEMPLE_MQ_ENTRANCE_POT_1 }, + { RC_FIRE_TEMPLE_MQ_ENTRANCE_POT_2, RAND_INF_FIRE_TEMPLE_MQ_ENTRANCE_POT_2 }, + { RC_FIRE_TEMPLE_MQ_OUTSIDE_BOSS_POT_1, RAND_INF_FIRE_TEMPLE_MQ_OUTSIDE_BOSS_POT_1 }, + { RC_FIRE_TEMPLE_MQ_OUTSIDE_BOSS_POT_2, RAND_INF_FIRE_TEMPLE_MQ_OUTSIDE_BOSS_POT_2 }, + { RC_FIRE_TEMPLE_MQ_LAVA_ROOM_NORTH_POT, RAND_INF_FIRE_TEMPLE_MQ_LAVA_POT_1 }, + { RC_FIRE_TEMPLE_MQ_LAVA_ROOM_HIGH_POT, RAND_INF_FIRE_TEMPLE_MQ_LAVA_POT_2 }, + { RC_FIRE_TEMPLE_MQ_LAVA_ROOM_SOUTH_POT, RAND_INF_FIRE_TEMPLE_MQ_LAVA_POT_3 }, + { RC_FIRE_TEMPLE_MQ_LAVA_TORCH_POT_1, RAND_INF_FIRE_TEMPLE_MQ_LAVA_TORCH_POT_1 }, + { RC_FIRE_TEMPLE_MQ_LAVA_TORCH_POT_2, RAND_INF_FIRE_TEMPLE_MQ_LAVA_TORCH_POT_2 }, + { RC_FIRE_TEMPLE_MQ_ABOVE_LAVA_POT_1, RAND_INF_FIRE_TEMPLE_MQ_ABOVE_LAVA_POT_1 }, + { RC_FIRE_TEMPLE_MQ_ABOVE_LAVA_POT_2, RAND_INF_FIRE_TEMPLE_MQ_ABOVE_LAVA_POT_2 }, + { RC_FIRE_TEMPLE_MQ_ABOVE_LAVA_POT_3, RAND_INF_FIRE_TEMPLE_MQ_ABOVE_LAVA_POT_3 }, + { RC_FIRE_TEMPLE_MQ_FLAME_WALL_POT_1, RAND_INF_FIRE_TEMPLE_MQ_FLAME_WALL_POT_1 }, + { RC_FIRE_TEMPLE_MQ_FLAME_WALL_POT_2, RAND_INF_FIRE_TEMPLE_MQ_FLAME_WALL_POT_2 }, + { RC_FIRE_TEMPLE_MQ_PAST_FIRE_MAZE_SOUTH_POT, RAND_INF_FIRE_TEMPLE_MQ_FIRE_MAZE_POT_1 }, + { RC_FIRE_TEMPLE_MQ_PAST_FIRE_MAZE_NORTH_POT, RAND_INF_FIRE_TEMPLE_MQ_FIRE_MAZE_POT_2 }, + { RC_FIRE_TEMPLE_MQ_FIRE_MAZE_NORTHMOST_POT, RAND_INF_FIRE_TEMPLE_MQ_FIRE_MAZE_POT_3 }, + { RC_FIRE_TEMPLE_MQ_FIRE_MAZE_NORTHWEST_POT, RAND_INF_FIRE_TEMPLE_MQ_FIRE_MAZE_POT_4 }, + { RC_FIRE_TEMPLE_MQ_SOUTH_FIRE_MAZE_WEST_POT, RAND_INF_FIRE_TEMPLE_MQ_FIRE_MAZE_POT_5 }, + { RC_FIRE_TEMPLE_MQ_SOUTH_FIRE_MAZE_EAST_POT, RAND_INF_FIRE_TEMPLE_MQ_FIRE_MAZE_POT_6 }, + { RC_FIRE_TEMPLE_MQ_BEFORE_MINI_BOSS_POT_1, RAND_INF_FIRE_TEMPLE_MQ_BEFORE_MINI_BOSS_POT_1 }, + { RC_FIRE_TEMPLE_MQ_BEFORE_MINI_BOSS_POT_2, RAND_INF_FIRE_TEMPLE_MQ_BEFORE_MINI_BOSS_POT_2 }, + { RC_FIRE_TEMPLE_MQ_BEFORE_MINI_BOSS_POT_3, RAND_INF_FIRE_TEMPLE_MQ_BEFORE_MINI_BOSS_POT_3 }, + { RC_FIRE_TEMPLE_MQ_BEFORE_MINI_BOSS_POT_4, RAND_INF_FIRE_TEMPLE_MQ_BEFORE_MINI_BOSS_POT_4 }, + { RC_FIRE_TEMPLE_MQ_BEFORE_MINI_BOSS_POT_5, RAND_INF_FIRE_TEMPLE_MQ_BEFORE_MINI_BOSS_POT_5 }, + { RC_FIRE_TEMPLE_MQ_BEFORE_MINI_BOSS_POT_6, RAND_INF_FIRE_TEMPLE_MQ_BEFORE_MINI_BOSS_POT_6 }, + { RC_FIRE_TEMPLE_MQ_BEFORE_MINI_BOSS_POT_7, RAND_INF_FIRE_TEMPLE_MQ_BEFORE_MINI_BOSS_POT_7 }, + { RC_FIRE_TEMPLE_MQ_BEFORE_MINI_BOSS_POT_8, RAND_INF_FIRE_TEMPLE_MQ_BEFORE_MINI_BOSS_POT_8 }, + { RC_ICE_CAVERN_MQ_ENTRANCE_POT, RAND_INF_ICE_CAVERN_MQ_ENTRANCE_POT }, + { RC_ICE_CAVERN_MQ_FIRST_CRYSTAL_POT_1, RAND_INF_ICE_CAVERN_MQ_FIRST_CRYSTAL_POT_1 }, + { RC_ICE_CAVERN_MQ_FIRST_CRYSTAL_POT_2, RAND_INF_ICE_CAVERN_MQ_FIRST_CRYSTAL_POT_2 }, + { RC_ICE_CAVERN_MQ_EARLY_WOLFOS_POT_1, RAND_INF_ICE_CAVERN_MQ_EARLY_WOLFOS_POT_1 }, + { RC_ICE_CAVERN_MQ_EARLY_WOLFOS_POT_2, RAND_INF_ICE_CAVERN_MQ_EARLY_WOLFOS_POT_2 }, + { RC_ICE_CAVERN_MQ_EARLY_WOLFOS_POT_3, RAND_INF_ICE_CAVERN_MQ_EARLY_WOLFOS_POT_3 }, + { RC_ICE_CAVERN_MQ_EARLY_WOLFOS_POT_4, RAND_INF_ICE_CAVERN_MQ_EARLY_WOLFOS_POT_4 }, + { RC_ICE_CAVERN_MQ_PUSH_BLOCK_POT_1, RAND_INF_ICE_CAVERN_MQ_PUSH_BLOCK_POT_1 }, + { RC_ICE_CAVERN_MQ_PUSH_BLOCK_POT_2, RAND_INF_ICE_CAVERN_MQ_PUSH_BLOCK_POT_2 }, + { RC_ICE_CAVERN_MQ_COMPASS_POT_1, RAND_INF_ICE_CAVERN_MQ_COMPASS_POT_1 }, + { RC_ICE_CAVERN_MQ_COMPASS_POT_2, RAND_INF_ICE_CAVERN_MQ_COMPASS_POT_2 }, + { RC_SPIRIT_TEMPLE_MQ_ENTRANCE_POT_1, RAND_INF_SPIRIT_TEMPLE_MQ_ENTRANCE_POT_1 }, + { RC_SPIRIT_TEMPLE_MQ_ENTRANCE_POT_2, RAND_INF_SPIRIT_TEMPLE_MQ_ENTRANCE_POT_2 }, + { RC_SPIRIT_TEMPLE_MQ_ENTRANCE_POT_3, RAND_INF_SPIRIT_TEMPLE_MQ_ENTRANCE_POT_3 }, + { RC_SPIRIT_TEMPLE_MQ_ENTRANCE_POT_4, RAND_INF_SPIRIT_TEMPLE_MQ_ENTRANCE_POT_4 }, + { RC_SPIRIT_TEMPLE_MQ_CHILD_SLUGMA_POT, RAND_INF_SPIRIT_TEMPLE_MQ_CHILD_SLUGMA_POT }, + { RC_SPIRIT_TEMPLE_MQ_CHILD_GIBDO_POT_1, RAND_INF_SPIRIT_TEMPLE_MQ_CHILD_GIBDO_POT_1 }, + { RC_SPIRIT_TEMPLE_MQ_CHILD_GIBDO_POT_2, RAND_INF_SPIRIT_TEMPLE_MQ_CHILD_GIBDO_POT_2 }, + { RC_SPIRIT_TEMPLE_MQ_CHILD_LIKE_LIKE_POT, RAND_INF_SPIRIT_TEMPLE_MQ_CHILD_LIKE_LIKE_POT }, + { RC_SPIRIT_TEMPLE_MQ_CHILD_STALFOS_POT_1, RAND_INF_SPIRIT_TEMPLE_MQ_CHILD_STALFOS_POT_1 }, + { RC_SPIRIT_TEMPLE_MQ_CHILD_STALFOS_POT_2, RAND_INF_SPIRIT_TEMPLE_MQ_CHILD_STALFOS_POT_2 }, + { RC_SPIRIT_TEMPLE_MQ_CHILD_STALFOS_POT_3, RAND_INF_SPIRIT_TEMPLE_MQ_CHILD_STALFOS_POT_3 }, + { RC_SPIRIT_TEMPLE_MQ_CHILD_STALFOS_POT_4, RAND_INF_SPIRIT_TEMPLE_MQ_CHILD_STALFOS_POT_4 }, + { RC_SPIRIT_TEMPLE_MQ_STATUE_2F_CENTER_EAST_POT, RAND_INF_SPIRIT_TEMPLE_MQ_CENTRAL_CHAMBER_POT_1 }, + { RC_SPIRIT_TEMPLE_MQ_STATUE_3F_EAST_POT, RAND_INF_SPIRIT_TEMPLE_MQ_CENTRAL_CHAMBER_POT_2 }, + { RC_SPIRIT_TEMPLE_MQ_STATUE_3F_WEST_POT, RAND_INF_SPIRIT_TEMPLE_MQ_CENTRAL_CHAMBER_POT_3 }, + { RC_SPIRIT_TEMPLE_MQ_STATUE_2F_WEST_POT, RAND_INF_SPIRIT_TEMPLE_MQ_CENTRAL_CHAMBER_POT_4 }, + { RC_SPIRIT_TEMPLE_MQ_STATUE_2F_EASTMOST_POT, RAND_INF_SPIRIT_TEMPLE_MQ_CENTRAL_CHAMBER_POT_5 }, + { RC_SPIRIT_TEMPLE_MQ_SUN_BLOCKS_POT_1, RAND_INF_SPIRIT_TEMPLE_MQ_SUN_BLOCKS_POT_1 }, + { RC_SPIRIT_TEMPLE_MQ_SUN_BLOCKS_POT_2, RAND_INF_SPIRIT_TEMPLE_MQ_SUN_BLOCKS_POT_2 }, + { RC_SPIRIT_TEMPLE_MQ_LONG_CLIMB_POT_1, RAND_INF_SPIRIT_TEMPLE_MQ_LONG_CLIMB_POT_1 }, + { RC_SPIRIT_TEMPLE_MQ_LONG_CLIMB_POT_2, RAND_INF_SPIRIT_TEMPLE_MQ_LONG_CLIMB_POT_2 }, + { RC_SPIRIT_TEMPLE_MQ_BIG_MIRROR_POT_1, RAND_INF_SPIRIT_TEMPLE_MQ_BIG_MIRROR_POT_1 }, + { RC_SPIRIT_TEMPLE_MQ_BIG_MIRROR_POT_2, RAND_INF_SPIRIT_TEMPLE_MQ_BIG_MIRROR_POT_2 }, + { RC_SPIRIT_TEMPLE_MQ_BIG_MIRROR_POT_3, RAND_INF_SPIRIT_TEMPLE_MQ_BIG_MIRROR_POT_3 }, + { RC_SPIRIT_TEMPLE_MQ_BIG_MIRROR_POT_4, RAND_INF_SPIRIT_TEMPLE_MQ_BIG_MIRROR_POT_4 }, + { RC_SPIRIT_TEMPLE_MQ_BEFORE_MIRROR_POT_1, RAND_INF_SPIRIT_TEMPLE_MQ_BEFORE_MIRROR_POT_1 }, + { RC_SPIRIT_TEMPLE_MQ_BEFORE_MIRROR_POT_2, RAND_INF_SPIRIT_TEMPLE_MQ_BEFORE_MIRROR_POT_2 }, + { RC_SPIRIT_TEMPLE_MQ_EARLY_ADULT_POT_1, RAND_INF_SPIRIT_TEMPLE_MQ_EARLY_ADULT_POT_1 }, + { RC_SPIRIT_TEMPLE_MQ_EARLY_ADULT_POT_2, RAND_INF_SPIRIT_TEMPLE_MQ_EARLY_ADULT_POT_2 }, + { RC_WATER_TEMPLE_MQ_LIZALFOS_HALLWAY_WEST_POT, RAND_INF_WATER_TEMPLE_MQ_CENTRAL_GATE_POT_1 }, + { RC_WATER_TEMPLE_MQ_LIZALFOS_HALLWAY_SOUTH_POT, RAND_INF_WATER_TEMPLE_MQ_CENTRAL_GATE_POT_2 }, + { RC_WATER_TEMPLE_MQ_LIZALFOS_HALLWAY_SE_POT, RAND_INF_WATER_TEMPLE_MQ_CENTRAL_GATE_POT_3 }, + { RC_WATER_TEMPLE_MQ_LIZALFOS_CAGE_SOUTH_POT, RAND_INF_WATER_TEMPLE_MQ_CENTRAL_GATE_POT_4 }, + { RC_WATER_TEMPLE_MQ_LIZALFOS_CAGE_NORTH_POT, RAND_INF_WATER_TEMPLE_MQ_CENTRAL_GATE_POT_5 }, + { RC_WATER_TEMPLE_MQ_STORAGE_ROOM_A_POT_1, RAND_INF_WATER_TEMPLE_MQ_STORAGE_ROOM_A_POT_1 }, + { RC_WATER_TEMPLE_MQ_STORAGE_ROOM_A_POT_2, RAND_INF_WATER_TEMPLE_MQ_STORAGE_ROOM_A_POT_2 }, + { RC_WATER_TEMPLE_MQ_STORAGE_ROOM_A_POT_3, RAND_INF_WATER_TEMPLE_MQ_STORAGE_ROOM_A_POT_3 }, + { RC_WATER_TEMPLE_MQ_BEFORE_DARK_LINK_POT_1, RAND_INF_WATER_TEMPLE_MQ_BEFORE_DARK_LINK_POT_1 }, + { RC_WATER_TEMPLE_MQ_BEFORE_DARK_LINK_POT_2, RAND_INF_WATER_TEMPLE_MQ_BEFORE_DARK_LINK_POT_2 }, + { RC_WATER_TEMPLE_MQ_STALFOS_PIT_MIDDLE_POT, RAND_INF_WATER_TEMPLE_MQ_BEFORE_DARK_LINK_POT_3 }, + { RC_WATER_TEMPLE_MQ_STALFOS_PIT_SOUTH_POT, RAND_INF_WATER_TEMPLE_MQ_BEFORE_DARK_LINK_POT_4 }, + { RC_WATER_TEMPLE_MQ_STALFOS_PIT_NORTH_POT, RAND_INF_WATER_TEMPLE_MQ_BEFORE_DARK_LINK_POT_5 }, + { RC_WATER_TEMPLE_MQ_AFTER_DARK_LINK_POT_1, RAND_INF_WATER_TEMPLE_MQ_AFTER_DARK_LINK_POT_1 }, + { RC_WATER_TEMPLE_MQ_AFTER_DARK_LINK_POT_2, RAND_INF_WATER_TEMPLE_MQ_AFTER_DARK_LINK_POT_2 }, + { RC_WATER_TEMPLE_MQ_RIVER_POT_1, RAND_INF_WATER_TEMPLE_MQ_RIVER_POT_1 }, + { RC_WATER_TEMPLE_MQ_RIVER_POT_2, RAND_INF_WATER_TEMPLE_MQ_RIVER_POT_2 }, + { RC_WATER_TEMPLE_MQ_MINI_DODONGO_POT_1, RAND_INF_WATER_TEMPLE_MQ_MINI_DODONGO_POT_1 }, + { RC_WATER_TEMPLE_MQ_MINI_DODONGO_POT_2, RAND_INF_WATER_TEMPLE_MQ_MINI_DODONGO_POT_2 }, + { RC_WATER_TEMPLE_MQ_STORAGE_ROOM_B_POT_1, RAND_INF_WATER_TEMPLE_MQ_STORAGE_ROOM_B_POT_1 }, + { RC_WATER_TEMPLE_MQ_STORAGE_ROOM_B_POT_2, RAND_INF_WATER_TEMPLE_MQ_STORAGE_ROOM_B_POT_2 }, + { RC_WATER_TEMPLE_MQ_GS_STORAGE_ROOM_POT_1, RAND_INF_WATER_TEMPLE_MQ_GS_STORAGE_ROOM_POT_1 }, + { RC_WATER_TEMPLE_MQ_GS_STORAGE_ROOM_POT_2, RAND_INF_WATER_TEMPLE_MQ_GS_STORAGE_ROOM_POT_2 }, + { RC_WATER_TEMPLE_MQ_GS_STORAGE_ROOM_POT_3, RAND_INF_WATER_TEMPLE_MQ_GS_STORAGE_ROOM_POT_3 }, + { RC_WATER_TEMPLE_MQ_LOWER_TORCHES_POT_1, RAND_INF_WATER_TEMPLE_MQ_LOWER_TORCHES_POT_1 }, + { RC_WATER_TEMPLE_MQ_LOWER_TORCHES_POT_2, RAND_INF_WATER_TEMPLE_MQ_LOWER_TORCHES_POT_2 }, + { RC_WATER_TEMPLE_MQ_LOWEST_GS_POT_1, RAND_INF_WATER_TEMPLE_MQ_LOWEST_GS_POT_1 }, + { RC_WATER_TEMPLE_MQ_LOWEST_GS_POT_2, RAND_INF_WATER_TEMPLE_MQ_LOWEST_GS_POT_2 }, + { RC_WATER_TEMPLE_MQ_LOWEST_GS_POT_3, RAND_INF_WATER_TEMPLE_MQ_LOWEST_GS_POT_3 }, + { RC_WATER_TEMPLE_MQ_LOWEST_GS_POT_4, RAND_INF_WATER_TEMPLE_MQ_LOWEST_GS_POT_4 }, + { RC_WATER_TEMPLE_MQ_BOSS_KEY_POT, RAND_INF_WATER_TEMPLE_MQ_BOSS_KEY_POT }, + { RC_GERUDO_TRAINING_GROUND_MQ_LOBBY_LEFT_POT_1, RAND_INF_GERUDO_TRAINING_GROUND_MQ_LOBBY_LEFT_POT_1 }, + { RC_GERUDO_TRAINING_GROUND_MQ_LOBBY_LEFT_POT_2, RAND_INF_GERUDO_TRAINING_GROUND_MQ_LOBBY_LEFT_POT_2 }, + { RC_GERUDO_TRAINING_GROUND_MQ_LOBBY_RIGHT_POT_1, RAND_INF_GERUDO_TRAINING_GROUND_MQ_LOBBY_RIGHT_POT_1 }, + { RC_GERUDO_TRAINING_GROUND_MQ_LOBBY_RIGHT_POT_2, RAND_INF_GERUDO_TRAINING_GROUND_MQ_LOBBY_RIGHT_POT_2 }, // Crates - { RC_GV_FREESTANDING_POH_CRATE, RAND_INF_GV_FREESTANDING_POH_CRATE, }, - { RC_GV_NEAR_COW_CRATE, RAND_INF_GV_NEAR_COW_CRATE, }, - { RC_GV_CRATE_BRIDGE_1, RAND_INF_GV_CRATE_BRIDGE_1, }, - { RC_GV_CRATE_BRIDGE_2, RAND_INF_GV_CRATE_BRIDGE_2, }, - { RC_GV_CRATE_BRIDGE_3, RAND_INF_GV_CRATE_BRIDGE_3, }, - { RC_GV_CRATE_BRIDGE_4, RAND_INF_GV_CRATE_BRIDGE_4, }, - { RC_GF_ABOVE_JAIL_CRATE, RAND_INF_GF_ABOVE_JAIL_CRATE, }, - { RC_GF_OUTSIDE_CENTER_CRATE_1, RAND_INF_GF_OUTSIDE_CENTER_CRATE_1, }, - { RC_GF_OUTSIDE_CENTER_CRATE_2, RAND_INF_GF_OUTSIDE_CENTER_CRATE_2, }, - { RC_GF_OUTSIDE_CENTER_CRATE_3, RAND_INF_GF_OUTSIDE_CENTER_CRATE_3, }, - { RC_GF_OUTSIDE_CENTER_CRATE_4, RAND_INF_GF_OUTSIDE_CENTER_CRATE_4, }, - { RC_GF_OUTSIDE_LEFT_CRATE_1, RAND_INF_GF_OUTSIDE_LEFT_CRATE_1, }, - { RC_GF_OUTSIDE_LEFT_CRATE_2, RAND_INF_GF_OUTSIDE_LEFT_CRATE_2, }, - { RC_GF_ARCHERY_RANGE_CRATE_1, RAND_INF_GF_ARCHERY_RANGE_CRATE_1, }, - { RC_GF_ARCHERY_RANGE_CRATE_2, RAND_INF_GF_ARCHERY_RANGE_CRATE_2, }, - { RC_GF_ARCHERY_RANGE_CRATE_3, RAND_INF_GF_ARCHERY_RANGE_CRATE_3, }, - { RC_GF_ARCHERY_RANGE_CRATE_4, RAND_INF_GF_ARCHERY_RANGE_CRATE_4, }, - { RC_GF_ARCHERY_RANGE_CRATE_5, RAND_INF_GF_ARCHERY_RANGE_CRATE_5, }, - { RC_GF_ARCHERY_RANGE_CRATE_6, RAND_INF_GF_ARCHERY_RANGE_CRATE_6, }, - { RC_GF_ARCHERY_RANGE_CRATE_7, RAND_INF_GF_ARCHERY_RANGE_CRATE_7, }, - { RC_GF_ARCHERY_START_CRATE_1, RAND_INF_GF_ARCHERY_START_CRATE_1, }, - { RC_GF_ARCHERY_START_CRATE_2, RAND_INF_GF_ARCHERY_START_CRATE_2, }, - { RC_GF_ARCHERY_LEFT_END_CRATE_1, RAND_INF_GF_ARCHERY_LEFT_END_CRATE_1, }, - { RC_GF_ARCHERY_LEFT_END_CRATE_2, RAND_INF_GF_ARCHERY_LEFT_END_CRATE_2, }, - { RC_GF_ARCHERY_LEFT_END_CHILD_CRATE, RAND_INF_GF_ARCHERY_LEFT_END_CHILD_CRATE, }, - { RC_GF_ARCHERY_RIGHT_END_CRATE_1, RAND_INF_GF_ARCHERY_RIGHT_END_CRATE_1, }, - { RC_GF_ARCHERY_RIGHT_END_CRATE_2, RAND_INF_GF_ARCHERY_RIGHT_END_CRATE_2, }, - { RC_GF_KITCHEN_CRATE_1, RAND_INF_GF_KITCHEN_CRATE_1, }, - { RC_GF_KITCHEN_CRATE_2, RAND_INF_GF_KITCHEN_CRATE_2, }, - { RC_GF_KITCHEN_CRATE_3, RAND_INF_GF_KITCHEN_CRATE_3, }, - { RC_GF_KITCHEN_CRATE_4, RAND_INF_GF_KITCHEN_CRATE_4, }, - { RC_GF_KITCHEN_CRATE_5, RAND_INF_GF_KITCHEN_CRATE_5, }, - { RC_GF_BREAK_ROOM_CRATE_1, RAND_INF_GF_BREAK_ROOM_CRATE_1, }, - { RC_GF_BREAK_ROOM_CRATE_2, RAND_INF_GF_BREAK_ROOM_CRATE_2, }, - { RC_GF_BREAK_ROOM_CRATE_3, RAND_INF_GF_BREAK_ROOM_CRATE_3, }, - { RC_GF_BREAK_ROOM_CRATE_4, RAND_INF_GF_BREAK_ROOM_CRATE_4, }, - { RC_GF_NORTH_F1_CARPENTER_CRATE, RAND_INF_GF_NORTH_F1_CARPENTER_CRATE, }, - { RC_GF_NORTH_F3_CARPENTER_CRATE, RAND_INF_GF_NORTH_F3_CARPENTER_CRATE, }, - { RC_GF_SOUTH_F2_CARPENTER_CRATE_1, RAND_INF_GF_SOUTH_F2_CARPENTER_CRATE_1, }, - { RC_GF_SOUTH_F2_CARPENTER_CRATE_2, RAND_INF_GF_SOUTH_F2_CARPENTER_CRATE_2, }, - { RC_HW_BEFORE_QUICKSAND_CRATE, RAND_INF_HW_BEFORE_QUICKSAND_CRATE, }, - { RC_HW_AFTER_QUICKSAND_CRATE_1, RAND_INF_HW_AFTER_QUICKSAND_CRATE_1, }, - { RC_HW_AFTER_QUICKSAND_CRATE_2, RAND_INF_HW_AFTER_QUICKSAND_CRATE_2, }, - { RC_HW_AFTER_QUICKSAND_CRATE_3, RAND_INF_HW_AFTER_QUICKSAND_CRATE_3, }, - { RC_HW_NEAR_COLOSSUS_CRATE, RAND_INF_HW_NEAR_COLOSSUS_CRATE, }, - { RC_MK_NEAR_BAZAAR_CRATE_1, RAND_INF_MK_NEAR_BAZAAR_CRATE_1, }, - { RC_MK_NEAR_BAZAAR_CRATE_2, RAND_INF_MK_NEAR_BAZAAR_CRATE_2, }, - { RC_MK_SHOOTING_GALLERY_CRATE_1, RAND_INF_MK_SHOOTING_GALLERY_CRATE_1, }, - { RC_MK_SHOOTING_GALLERY_CRATE_2, RAND_INF_MK_SHOOTING_GALLERY_CRATE_2, }, - { RC_MK_LOST_DOG_HOUSE_CRATE, RAND_INF_MK_LOST_DOG_HOUSE_CRATE, }, - { RC_MK_GUARD_HOUSE_CRATE_1, RAND_INF_MK_GUARD_HOUSE_CRATE_1, }, - { RC_MK_GUARD_HOUSE_CRATE_2, RAND_INF_MK_GUARD_HOUSE_CRATE_2, }, - { RC_MK_GUARD_HOUSE_CRATE_3, RAND_INF_MK_GUARD_HOUSE_CRATE_3, }, - { RC_MK_GUARD_HOUSE_CRATE_4, RAND_INF_MK_GUARD_HOUSE_CRATE_4, }, - { RC_MK_GUARD_HOUSE_CRATE_5, RAND_INF_MK_GUARD_HOUSE_CRATE_5, }, - { RC_KAK_NEAR_OPEN_GROTTO_ADULT_CRATE_1, RAND_INF_KAK_NEAR_OPEN_GROTTO_ADULT_CRATE_1, }, - { RC_KAK_NEAR_OPEN_GROTTO_ADULT_CRATE_2, RAND_INF_KAK_NEAR_OPEN_GROTTO_ADULT_CRATE_2, }, - { RC_KAK_NEAR_OPEN_GROTTO_ADULT_CRATE_3, RAND_INF_KAK_NEAR_OPEN_GROTTO_ADULT_CRATE_3, }, - { RC_KAK_NEAR_OPEN_GROTTO_ADULT_CRATE_4, RAND_INF_KAK_NEAR_OPEN_GROTTO_ADULT_CRATE_4, }, - { RC_KAK_NEAR_POTION_SHOP_ADULT_CRATE, RAND_INF_KAK_NEAR_POTION_SHOP_ADULT_CRATE, }, - { RC_KAK_NEAR_SHOOTING_GALLERY_ADULT_CRATE, RAND_INF_KAK_NEAR_SHOOTING_GALLERY_ADULT_CRATE, }, - { RC_KAK_NEAR_BOARDING_HOUSE_ADULT_CRATE_1, RAND_INF_KAK_NEAR_BOARDING_HOUSE_ADULT_CRATE_1, }, - { RC_KAK_NEAR_BOARDING_HOUSE_ADULT_CRATE_2, RAND_INF_KAK_NEAR_BOARDING_HOUSE_ADULT_CRATE_2, }, - { RC_KAK_NEAR_IMPAS_HOUSE_ADULT_CRATE_1, RAND_INF_KAK_NEAR_IMPAS_HOUSE_ADULT_CRATE_1, }, - { RC_KAK_NEAR_IMPAS_HOUSE_ADULT_CRATE_2, RAND_INF_KAK_NEAR_IMPAS_HOUSE_ADULT_CRATE_2, }, - { RC_KAK_NEAR_BAZAAR_ADULT_CRATE_1, RAND_INF_KAK_NEAR_BAZAAR_ADULT_CRATE_1, }, - { RC_KAK_NEAR_BAZAAR_ADULT_CRATE_2, RAND_INF_KAK_NEAR_BAZAAR_ADULT_CRATE_2, }, - { RC_KAK_BEHIND_GS_HOUSE_ADULT_CRATE, RAND_INF_KAK_BEHIND_GS_HOUSE_ADULT_CRATE, }, - { RC_KAK_NEAR_GY_CHILD_CRATE, RAND_INF_KAK_NEAR_GY_CHILD_CRATE, }, - { RC_KAK_NEAR_WINDMILL_CHILD_CRATE, RAND_INF_KAK_NEAR_WINDMILL_CHILD_CRATE, }, - { RC_KAK_NEAR_FENCE_CHILD_CRATE, RAND_INF_KAK_NEAR_FENCE_CHILD_CRATE, }, - { RC_KAK_NEAR_BOARDING_HOUSE_CHILD_CRATE, RAND_INF_KAK_NEAR_BOARDING_HOUSE_CHILD_CRATE, }, - { RC_KAK_NEAR_BAZAAR_CHILD_CRATE, RAND_INF_KAK_NEAR_BAZAAR_CHILD_CRATE, }, - { RC_GRAVEYARD_CRATE, RAND_INF_GRAVEYARD_CRATE, }, - { RC_GC_MAZE_CRATE, RAND_INF_GC_MAZE_CRATE, }, - { RC_DMC_CRATE, RAND_INF_DMC_CRATE, }, - { RC_LLR_NEAR_TREE_CRATE, RAND_INF_LLR_NEAR_TREE_CRATE, }, - { RC_LH_LAB_CRATE, RAND_INF_LH_LAB_CRATE, }, + { + RC_GV_FREESTANDING_POH_CRATE, + RAND_INF_GV_FREESTANDING_POH_CRATE, + }, + { + RC_GV_NEAR_COW_CRATE, + RAND_INF_GV_NEAR_COW_CRATE, + }, + { + RC_GV_CRATE_BRIDGE_1, + RAND_INF_GV_CRATE_BRIDGE_1, + }, + { + RC_GV_CRATE_BRIDGE_2, + RAND_INF_GV_CRATE_BRIDGE_2, + }, + { + RC_GV_CRATE_BRIDGE_3, + RAND_INF_GV_CRATE_BRIDGE_3, + }, + { + RC_GV_CRATE_BRIDGE_4, + RAND_INF_GV_CRATE_BRIDGE_4, + }, + { + RC_GF_ABOVE_JAIL_CRATE, + RAND_INF_GF_ABOVE_JAIL_CRATE, + }, + { + RC_GF_OUTSIDE_CENTER_CRATE_1, + RAND_INF_GF_OUTSIDE_CENTER_CRATE_1, + }, + { + RC_GF_OUTSIDE_CENTER_CRATE_2, + RAND_INF_GF_OUTSIDE_CENTER_CRATE_2, + }, + { + RC_GF_OUTSIDE_CENTER_CRATE_3, + RAND_INF_GF_OUTSIDE_CENTER_CRATE_3, + }, + { + RC_GF_OUTSIDE_CENTER_CRATE_4, + RAND_INF_GF_OUTSIDE_CENTER_CRATE_4, + }, + { + RC_GF_OUTSIDE_LEFT_CRATE_1, + RAND_INF_GF_OUTSIDE_LEFT_CRATE_1, + }, + { + RC_GF_OUTSIDE_LEFT_CRATE_2, + RAND_INF_GF_OUTSIDE_LEFT_CRATE_2, + }, + { + RC_GF_ARCHERY_RANGE_CRATE_1, + RAND_INF_GF_ARCHERY_RANGE_CRATE_1, + }, + { + RC_GF_ARCHERY_RANGE_CRATE_2, + RAND_INF_GF_ARCHERY_RANGE_CRATE_2, + }, + { + RC_GF_ARCHERY_RANGE_CRATE_3, + RAND_INF_GF_ARCHERY_RANGE_CRATE_3, + }, + { + RC_GF_ARCHERY_RANGE_CRATE_4, + RAND_INF_GF_ARCHERY_RANGE_CRATE_4, + }, + { + RC_GF_ARCHERY_RANGE_CRATE_5, + RAND_INF_GF_ARCHERY_RANGE_CRATE_5, + }, + { + RC_GF_ARCHERY_RANGE_CRATE_6, + RAND_INF_GF_ARCHERY_RANGE_CRATE_6, + }, + { + RC_GF_ARCHERY_RANGE_CRATE_7, + RAND_INF_GF_ARCHERY_RANGE_CRATE_7, + }, + { + RC_GF_ARCHERY_START_CRATE_1, + RAND_INF_GF_ARCHERY_START_CRATE_1, + }, + { + RC_GF_ARCHERY_START_CRATE_2, + RAND_INF_GF_ARCHERY_START_CRATE_2, + }, + { + RC_GF_ARCHERY_LEFT_END_CRATE_1, + RAND_INF_GF_ARCHERY_LEFT_END_CRATE_1, + }, + { + RC_GF_ARCHERY_LEFT_END_CRATE_2, + RAND_INF_GF_ARCHERY_LEFT_END_CRATE_2, + }, + { + RC_GF_ARCHERY_LEFT_END_CHILD_CRATE, + RAND_INF_GF_ARCHERY_LEFT_END_CHILD_CRATE, + }, + { + RC_GF_ARCHERY_RIGHT_END_CRATE_1, + RAND_INF_GF_ARCHERY_RIGHT_END_CRATE_1, + }, + { + RC_GF_ARCHERY_RIGHT_END_CRATE_2, + RAND_INF_GF_ARCHERY_RIGHT_END_CRATE_2, + }, + { + RC_GF_KITCHEN_CRATE_1, + RAND_INF_GF_KITCHEN_CRATE_1, + }, + { + RC_GF_KITCHEN_CRATE_2, + RAND_INF_GF_KITCHEN_CRATE_2, + }, + { + RC_GF_KITCHEN_CRATE_3, + RAND_INF_GF_KITCHEN_CRATE_3, + }, + { + RC_GF_KITCHEN_CRATE_4, + RAND_INF_GF_KITCHEN_CRATE_4, + }, + { + RC_GF_KITCHEN_CRATE_5, + RAND_INF_GF_KITCHEN_CRATE_5, + }, + { + RC_GF_BREAK_ROOM_CRATE_1, + RAND_INF_GF_BREAK_ROOM_CRATE_1, + }, + { + RC_GF_BREAK_ROOM_CRATE_2, + RAND_INF_GF_BREAK_ROOM_CRATE_2, + }, + { + RC_GF_BREAK_ROOM_CRATE_3, + RAND_INF_GF_BREAK_ROOM_CRATE_3, + }, + { + RC_GF_BREAK_ROOM_CRATE_4, + RAND_INF_GF_BREAK_ROOM_CRATE_4, + }, + { + RC_GF_NORTH_F1_CARPENTER_CRATE, + RAND_INF_GF_NORTH_F1_CARPENTER_CRATE, + }, + { + RC_GF_NORTH_F3_CARPENTER_CRATE, + RAND_INF_GF_NORTH_F3_CARPENTER_CRATE, + }, + { + RC_GF_SOUTH_F2_CARPENTER_CRATE_1, + RAND_INF_GF_SOUTH_F2_CARPENTER_CRATE_1, + }, + { + RC_GF_SOUTH_F2_CARPENTER_CRATE_2, + RAND_INF_GF_SOUTH_F2_CARPENTER_CRATE_2, + }, + { + RC_HW_BEFORE_QUICKSAND_CRATE, + RAND_INF_HW_BEFORE_QUICKSAND_CRATE, + }, + { + RC_HW_AFTER_QUICKSAND_CRATE_1, + RAND_INF_HW_AFTER_QUICKSAND_CRATE_1, + }, + { + RC_HW_AFTER_QUICKSAND_CRATE_2, + RAND_INF_HW_AFTER_QUICKSAND_CRATE_2, + }, + { + RC_HW_AFTER_QUICKSAND_CRATE_3, + RAND_INF_HW_AFTER_QUICKSAND_CRATE_3, + }, + { + RC_HW_NEAR_COLOSSUS_CRATE, + RAND_INF_HW_NEAR_COLOSSUS_CRATE, + }, + { + RC_MK_NEAR_BAZAAR_CRATE_1, + RAND_INF_MK_NEAR_BAZAAR_CRATE_1, + }, + { + RC_MK_NEAR_BAZAAR_CRATE_2, + RAND_INF_MK_NEAR_BAZAAR_CRATE_2, + }, + { + RC_MK_SHOOTING_GALLERY_CRATE_1, + RAND_INF_MK_SHOOTING_GALLERY_CRATE_1, + }, + { + RC_MK_SHOOTING_GALLERY_CRATE_2, + RAND_INF_MK_SHOOTING_GALLERY_CRATE_2, + }, + { + RC_MK_LOST_DOG_HOUSE_CRATE, + RAND_INF_MK_LOST_DOG_HOUSE_CRATE, + }, + { + RC_MK_GUARD_HOUSE_CRATE_1, + RAND_INF_MK_GUARD_HOUSE_CRATE_1, + }, + { + RC_MK_GUARD_HOUSE_CRATE_2, + RAND_INF_MK_GUARD_HOUSE_CRATE_2, + }, + { + RC_MK_GUARD_HOUSE_CRATE_3, + RAND_INF_MK_GUARD_HOUSE_CRATE_3, + }, + { + RC_MK_GUARD_HOUSE_CRATE_4, + RAND_INF_MK_GUARD_HOUSE_CRATE_4, + }, + { + RC_MK_GUARD_HOUSE_CRATE_5, + RAND_INF_MK_GUARD_HOUSE_CRATE_5, + }, + { + RC_KAK_NEAR_OPEN_GROTTO_ADULT_CRATE_1, + RAND_INF_KAK_NEAR_OPEN_GROTTO_ADULT_CRATE_1, + }, + { + RC_KAK_NEAR_OPEN_GROTTO_ADULT_CRATE_2, + RAND_INF_KAK_NEAR_OPEN_GROTTO_ADULT_CRATE_2, + }, + { + RC_KAK_NEAR_OPEN_GROTTO_ADULT_CRATE_3, + RAND_INF_KAK_NEAR_OPEN_GROTTO_ADULT_CRATE_3, + }, + { + RC_KAK_NEAR_OPEN_GROTTO_ADULT_CRATE_4, + RAND_INF_KAK_NEAR_OPEN_GROTTO_ADULT_CRATE_4, + }, + { + RC_KAK_NEAR_POTION_SHOP_ADULT_CRATE, + RAND_INF_KAK_NEAR_POTION_SHOP_ADULT_CRATE, + }, + { + RC_KAK_NEAR_SHOOTING_GALLERY_ADULT_CRATE, + RAND_INF_KAK_NEAR_SHOOTING_GALLERY_ADULT_CRATE, + }, + { + RC_KAK_NEAR_BOARDING_HOUSE_ADULT_CRATE_1, + RAND_INF_KAK_NEAR_BOARDING_HOUSE_ADULT_CRATE_1, + }, + { + RC_KAK_NEAR_BOARDING_HOUSE_ADULT_CRATE_2, + RAND_INF_KAK_NEAR_BOARDING_HOUSE_ADULT_CRATE_2, + }, + { + RC_KAK_NEAR_IMPAS_HOUSE_ADULT_CRATE_1, + RAND_INF_KAK_NEAR_IMPAS_HOUSE_ADULT_CRATE_1, + }, + { + RC_KAK_NEAR_IMPAS_HOUSE_ADULT_CRATE_2, + RAND_INF_KAK_NEAR_IMPAS_HOUSE_ADULT_CRATE_2, + }, + { + RC_KAK_NEAR_BAZAAR_ADULT_CRATE_1, + RAND_INF_KAK_NEAR_BAZAAR_ADULT_CRATE_1, + }, + { + RC_KAK_NEAR_BAZAAR_ADULT_CRATE_2, + RAND_INF_KAK_NEAR_BAZAAR_ADULT_CRATE_2, + }, + { + RC_KAK_BEHIND_GS_HOUSE_ADULT_CRATE, + RAND_INF_KAK_BEHIND_GS_HOUSE_ADULT_CRATE, + }, + { + RC_KAK_NEAR_GY_CHILD_CRATE, + RAND_INF_KAK_NEAR_GY_CHILD_CRATE, + }, + { + RC_KAK_NEAR_WINDMILL_CHILD_CRATE, + RAND_INF_KAK_NEAR_WINDMILL_CHILD_CRATE, + }, + { + RC_KAK_NEAR_FENCE_CHILD_CRATE, + RAND_INF_KAK_NEAR_FENCE_CHILD_CRATE, + }, + { + RC_KAK_NEAR_BOARDING_HOUSE_CHILD_CRATE, + RAND_INF_KAK_NEAR_BOARDING_HOUSE_CHILD_CRATE, + }, + { + RC_KAK_NEAR_BAZAAR_CHILD_CRATE, + RAND_INF_KAK_NEAR_BAZAAR_CHILD_CRATE, + }, + { + RC_GRAVEYARD_CRATE, + RAND_INF_GRAVEYARD_CRATE, + }, + { + RC_GC_MAZE_CRATE, + RAND_INF_GC_MAZE_CRATE, + }, + { + RC_DMC_CRATE, + RAND_INF_DMC_CRATE, + }, + { + RC_LLR_NEAR_TREE_CRATE, + RAND_INF_LLR_NEAR_TREE_CRATE, + }, + { + RC_LH_LAB_CRATE, + RAND_INF_LH_LAB_CRATE, + }, - { RC_DEKU_TREE_MQ_LOBBY_CRATE, RAND_INF_DEKU_TREE_MQ_LOBBY_CRATE, }, - { RC_DEKU_TREE_MQ_SLINGSHOT_ROOM_CRATE_1, RAND_INF_DEKU_TREE_MQ_SLINGSHOT_ROOM_CRATE_1, }, - { RC_DEKU_TREE_MQ_SLINGSHOT_ROOM_CRATE_2, RAND_INF_DEKU_TREE_MQ_SLINGSHOT_ROOM_CRATE_2, }, - { RC_DODONGOS_CAVERN_MQ_POE_ROOM_CRATE_1, RAND_INF_DODONGOS_CAVERN_MQ_POE_ROOM_CRATE_1, }, - { RC_DODONGOS_CAVERN_MQ_POE_ROOM_CRATE_2, RAND_INF_DODONGOS_CAVERN_MQ_POE_ROOM_CRATE_2, }, - { RC_DODONGOS_CAVERN_MQ_POE_ROOM_CRATE_3, RAND_INF_DODONGOS_CAVERN_MQ_POE_ROOM_CRATE_3, }, - { RC_DODONGOS_CAVERN_MQ_POE_ROOM_CRATE_4, RAND_INF_DODONGOS_CAVERN_MQ_POE_ROOM_CRATE_4, }, - { RC_DODONGOS_CAVERN_MQ_POE_ROOM_CRATE_5, RAND_INF_DODONGOS_CAVERN_MQ_POE_ROOM_CRATE_5, }, - { RC_DODONGOS_CAVERN_MQ_POE_ROOM_CRATE_6, RAND_INF_DODONGOS_CAVERN_MQ_POE_ROOM_CRATE_6, }, - { RC_DODONGOS_CAVERN_MQ_POE_ROOM_CRATE_7, RAND_INF_DODONGOS_CAVERN_MQ_POE_ROOM_CRATE_7, }, - { RC_DODONGOS_CAVERN_MQ_POE_ROOM_CRATE_8, RAND_INF_DODONGOS_CAVERN_MQ_POE_ROOM_CRATE_8, }, - { RC_DODONGOS_CAVERN_MQ_STAIRCASE_LOWER_CRATE_1, RAND_INF_DODONGOS_CAVERN_MQ_STAIRCASE_LOWER_CRATE_1, }, - { RC_DODONGOS_CAVERN_MQ_STAIRCASE_LOWER_CRATE_2, RAND_INF_DODONGOS_CAVERN_MQ_STAIRCASE_LOWER_CRATE_2, }, - { RC_DODONGOS_CAVERN_MQ_STAIRCASE_UPPER_CRATE_1, RAND_INF_DODONGOS_CAVERN_MQ_STAIRCASE_UPPER_CRATE_1, }, - { RC_DODONGOS_CAVERN_MQ_STAIRCASE_UPPER_CRATE_2, RAND_INF_DODONGOS_CAVERN_MQ_STAIRCASE_UPPER_CRATE_2, }, - { RC_DODONGOS_CAVERN_MQ_STAIRCASE_UPPER_CRATE_3, RAND_INF_DODONGOS_CAVERN_MQ_STAIRCASE_UPPER_CRATE_3, }, - { RC_DODONGOS_CAVERN_MQ_STAIRCASE_UPPER_CRATE_4, RAND_INF_DODONGOS_CAVERN_MQ_STAIRCASE_UPPER_CRATE_4, }, - { RC_DODONGOS_CAVERN_MQ_TWO_FLAMES_CRATE_1, RAND_INF_DODONGOS_CAVERN_MQ_TWO_FLAMES_CRATE_1, }, - { RC_DODONGOS_CAVERN_MQ_TWO_FLAMES_CRATE_2, RAND_INF_DODONGOS_CAVERN_MQ_TWO_FLAMES_CRATE_2, }, - { RC_DODONGOS_CAVERN_MQ_LARVAE_ROOM_CRATE_1, RAND_INF_DODONGOS_CAVERN_MQ_LARVAE_ROOM_CRATE_1, }, - { RC_DODONGOS_CAVERN_MQ_LARVAE_ROOM_CRATE_2, RAND_INF_DODONGOS_CAVERN_MQ_LARVAE_ROOM_CRATE_2, }, - { RC_DODONGOS_CAVERN_MQ_LARVAE_ROOM_CRATE_3, RAND_INF_DODONGOS_CAVERN_MQ_LARVAE_ROOM_CRATE_3, }, - { RC_DODONGOS_CAVERN_MQ_LARVAE_ROOM_CRATE_4, RAND_INF_DODONGOS_CAVERN_MQ_LARVAE_ROOM_CRATE_4, }, - { RC_DODONGOS_CAVERN_MQ_LARVAE_ROOM_CRATE_5, RAND_INF_DODONGOS_CAVERN_MQ_LARVAE_ROOM_CRATE_5, }, - { RC_DODONGOS_CAVERN_MQ_LARVAE_ROOM_CRATE_6, RAND_INF_DODONGOS_CAVERN_MQ_LARVAE_ROOM_CRATE_6, }, - { RC_FIRE_TEMPLE_MQ_OUTSIDE_BOSS_CRATE_1, RAND_INF_FIRE_TEMPLE_MQ_OUTSIDE_BOSS_CRATE_1, }, - { RC_FIRE_TEMPLE_MQ_OUTSIDE_BOSS_CRATE_2, RAND_INF_FIRE_TEMPLE_MQ_OUTSIDE_BOSS_CRATE_2, }, - { RC_FIRE_TEMPLE_MQ_OUTSIDE_BOSS_CRATE_3, RAND_INF_FIRE_TEMPLE_MQ_OUTSIDE_BOSS_CRATE_3, }, - { RC_FIRE_TEMPLE_MQ_OUTSIDE_BOSS_CRATE_4, RAND_INF_FIRE_TEMPLE_MQ_OUTSIDE_BOSS_CRATE_4, }, - { RC_FIRE_TEMPLE_MQ_OUTSIDE_BOSS_CRATE_5, RAND_INF_FIRE_TEMPLE_MQ_OUTSIDE_BOSS_CRATE_5, }, - { RC_FIRE_TEMPLE_MQ_OUTSIDE_BOSS_CRATE_6, RAND_INF_FIRE_TEMPLE_MQ_OUTSIDE_BOSS_CRATE_6, }, - { RC_FIRE_TEMPLE_MQ_SHORTCUT_CRATE_1, RAND_INF_FIRE_TEMPLE_MQ_SHORTCUT_CRATE_1, }, - { RC_FIRE_TEMPLE_MQ_SHORTCUT_CRATE_2, RAND_INF_FIRE_TEMPLE_MQ_SHORTCUT_CRATE_2, }, - { RC_FIRE_TEMPLE_MQ_SHORTCUT_CRATE_3, RAND_INF_FIRE_TEMPLE_MQ_SHORTCUT_CRATE_3, }, - { RC_FIRE_TEMPLE_MQ_SHORTCUT_CRATE_4, RAND_INF_FIRE_TEMPLE_MQ_SHORTCUT_CRATE_4, }, - { RC_FIRE_TEMPLE_MQ_SHORTCUT_CRATE_5, RAND_INF_FIRE_TEMPLE_MQ_SHORTCUT_CRATE_5, }, - { RC_FIRE_TEMPLE_MQ_SHORTCUT_CRATE_6, RAND_INF_FIRE_TEMPLE_MQ_SHORTCUT_CRATE_6, }, - { RC_FIRE_TEMPLE_MQ_LIZALFOS_MAZE_LOWER_CRATE_1, RAND_INF_FIRE_TEMPLE_MQ_LIZALFOS_MAZE_LOWER_CRATE_1, }, - { RC_FIRE_TEMPLE_MQ_LIZALFOS_MAZE_LOWER_CRATE_2, RAND_INF_FIRE_TEMPLE_MQ_LIZALFOS_MAZE_LOWER_CRATE_2, }, - { RC_FIRE_TEMPLE_MQ_LIZALFOS_MAZE_LOWER_CRATE_3, RAND_INF_FIRE_TEMPLE_MQ_LIZALFOS_MAZE_LOWER_CRATE_3, }, - { RC_FIRE_TEMPLE_MQ_LIZALFOS_MAZE_UPPER_CRATE_1, RAND_INF_FIRE_TEMPLE_MQ_LIZALFOS_MAZE_UPPER_CRATE_1, }, - { RC_FIRE_TEMPLE_MQ_LIZALFOS_MAZE_UPPER_CRATE_2, RAND_INF_FIRE_TEMPLE_MQ_LIZALFOS_MAZE_UPPER_CRATE_2, }, - { RC_FIRE_TEMPLE_MQ_LIZALFOS_MAZE_UPPER_CRATE_3, RAND_INF_FIRE_TEMPLE_MQ_LIZALFOS_MAZE_UPPER_CRATE_3, }, - { RC_FIRE_TEMPLE_MQ_LAVA_TORCH_CRATE_1, RAND_INF_FIRE_TEMPLE_MQ_LAVA_TORCH_CRATE_1, }, - { RC_FIRE_TEMPLE_MQ_LAVA_TORCH_CRATE_2, RAND_INF_FIRE_TEMPLE_MQ_LAVA_TORCH_CRATE_2, }, - { RC_FIRE_TEMPLE_MQ_LAVA_TORCH_CRATE_3, RAND_INF_FIRE_TEMPLE_MQ_LAVA_TORCH_CRATE_3, }, - { RC_FIRE_TEMPLE_MQ_LAVA_TORCH_CRATE_4, RAND_INF_FIRE_TEMPLE_MQ_LAVA_TORCH_CRATE_4, }, - { RC_FIRE_TEMPLE_MQ_LAVA_TORCH_CRATE_5, RAND_INF_FIRE_TEMPLE_MQ_LAVA_TORCH_CRATE_5, }, - { RC_WATER_TEMPLE_MQ_CENTRAL_PILLAR_UPPER_CRATE_1, RAND_INF_WATER_TEMPLE_MQ_CENTRAL_PILLAR_UPPER_CRATE_1, }, - { RC_WATER_TEMPLE_MQ_CENTRAL_PILLAR_UPPER_CRATE_2, RAND_INF_WATER_TEMPLE_MQ_CENTRAL_PILLAR_UPPER_CRATE_2, }, - { RC_WATER_TEMPLE_MQ_CENTRAL_PILLAR_LOWER_CRATE_1, RAND_INF_WATER_TEMPLE_MQ_CENTRAL_PILLAR_LOWER_CRATE_1, }, - { RC_WATER_TEMPLE_MQ_CENTRAL_PILLAR_LOWER_CRATE_2, RAND_INF_WATER_TEMPLE_MQ_CENTRAL_PILLAR_LOWER_CRATE_2, }, - { RC_WATER_TEMPLE_MQ_CENTRAL_PILLAR_LOWER_CRATE_3, RAND_INF_WATER_TEMPLE_MQ_CENTRAL_PILLAR_LOWER_CRATE_3, }, - { RC_WATER_TEMPLE_MQ_CENTRAL_PILLAR_LOWER_CRATE_4, RAND_INF_WATER_TEMPLE_MQ_CENTRAL_PILLAR_LOWER_CRATE_4, }, - { RC_WATER_TEMPLE_MQ_CENTRAL_PILLAR_LOWER_CRATE_5, RAND_INF_WATER_TEMPLE_MQ_CENTRAL_PILLAR_LOWER_CRATE_5, }, - { RC_WATER_TEMPLE_MQ_CENTRAL_PILLAR_LOWER_CRATE_6, RAND_INF_WATER_TEMPLE_MQ_CENTRAL_PILLAR_LOWER_CRATE_6, }, - { RC_WATER_TEMPLE_MQ_CENTRAL_PILLAR_LOWER_CRATE_7, RAND_INF_WATER_TEMPLE_MQ_CENTRAL_PILLAR_LOWER_CRATE_7, }, - { RC_WATER_TEMPLE_MQ_CENTRAL_PILLAR_LOWER_CRATE_8, RAND_INF_WATER_TEMPLE_MQ_CENTRAL_PILLAR_LOWER_CRATE_8, }, - { RC_WATER_TEMPLE_MQ_CENTRAL_PILLAR_LOWER_CRATE_9, RAND_INF_WATER_TEMPLE_MQ_CENTRAL_PILLAR_LOWER_CRATE_9, }, - { RC_WATER_TEMPLE_MQ_CENTRAL_PILLAR_LOWER_CRATE_10, RAND_INF_WATER_TEMPLE_MQ_CENTRAL_PILLAR_LOWER_CRATE_10, }, - { RC_WATER_TEMPLE_MQ_CENTRAL_PILLAR_LOWER_CRATE_11, RAND_INF_WATER_TEMPLE_MQ_CENTRAL_PILLAR_LOWER_CRATE_11, }, - { RC_WATER_TEMPLE_MQ_CENTRAL_PILLAR_LOWER_CRATE_12, RAND_INF_WATER_TEMPLE_MQ_CENTRAL_PILLAR_LOWER_CRATE_12, }, - { RC_WATER_TEMPLE_MQ_CENTRAL_PILLAR_LOWER_CRATE_13, RAND_INF_WATER_TEMPLE_MQ_CENTRAL_PILLAR_LOWER_CRATE_13, }, - { RC_WATER_TEMPLE_MQ_CENTRAL_PILLAR_LOWER_CRATE_14, RAND_INF_WATER_TEMPLE_MQ_CENTRAL_PILLAR_LOWER_CRATE_14, }, - { RC_WATER_TEMPLE_MQ_LIZALFOS_HALLWAY_CRATE_1, RAND_INF_WATER_TEMPLE_MQ_LIZALFOS_HALLWAY_CRATE_1, }, - { RC_WATER_TEMPLE_MQ_LIZALFOS_HALLWAY_CRATE_2, RAND_INF_WATER_TEMPLE_MQ_LIZALFOS_HALLWAY_CRATE_2, }, - { RC_WATER_TEMPLE_MQ_LIZALFOS_HALLWAY_CRATE_3, RAND_INF_WATER_TEMPLE_MQ_LIZALFOS_HALLWAY_CRATE_3, }, - { RC_WATER_TEMPLE_MQ_LIZALFOS_HALLWAY_ROOM_CRATE_1, RAND_INF_WATER_TEMPLE_MQ_LIZALFOS_HALLWAY_ROOM_CRATE_1, }, - { RC_WATER_TEMPLE_MQ_LIZALFOS_HALLWAY_ROOM_CRATE_2, RAND_INF_WATER_TEMPLE_MQ_LIZALFOS_HALLWAY_ROOM_CRATE_2, }, - { RC_WATER_TEMPLE_MQ_LIZALFOS_HALLWAY_ROOM_CRATE_3, RAND_INF_WATER_TEMPLE_MQ_LIZALFOS_HALLWAY_ROOM_CRATE_3, }, - { RC_WATER_TEMPLE_MQ_LIZALFOS_HALLWAY_ROOM_CRATE_4, RAND_INF_WATER_TEMPLE_MQ_LIZALFOS_HALLWAY_ROOM_CRATE_4, }, - { RC_WATER_TEMPLE_MQ_LIZALFOS_HALLWAY_ROOM_CRATE_5, RAND_INF_WATER_TEMPLE_MQ_LIZALFOS_HALLWAY_ROOM_CRATE_5, }, - { RC_WATER_TEMPLE_MQ_LIZALFOS_HALLWAY_GATE_CRATE_1, RAND_INF_WATER_TEMPLE_MQ_LIZALFOS_HALLWAY_GATE_CRATE_1, }, - { RC_WATER_TEMPLE_MQ_LIZALFOS_HALLWAY_GATE_CRATE_2, RAND_INF_WATER_TEMPLE_MQ_LIZALFOS_HALLWAY_GATE_CRATE_2, }, - { RC_WATER_TEMPLE_MQ_STORAGE_ROOM_A_CRATE_1, RAND_INF_WATER_TEMPLE_MQ_STORAGE_ROOM_A_CRATE_1, }, - { RC_WATER_TEMPLE_MQ_STORAGE_ROOM_A_CRATE_2, RAND_INF_WATER_TEMPLE_MQ_STORAGE_ROOM_A_CRATE_2, }, - { RC_WATER_TEMPLE_MQ_STORAGE_ROOM_A_CRATE_3, RAND_INF_WATER_TEMPLE_MQ_STORAGE_ROOM_A_CRATE_3, }, - { RC_WATER_TEMPLE_MQ_STORAGE_ROOM_A_CRATE_4, RAND_INF_WATER_TEMPLE_MQ_STORAGE_ROOM_A_CRATE_4, }, - { RC_WATER_TEMPLE_MQ_STORAGE_ROOM_A_CRATE_5, RAND_INF_WATER_TEMPLE_MQ_STORAGE_ROOM_A_CRATE_5, }, - { RC_WATER_TEMPLE_MQ_STORAGE_ROOM_A_CRATE_6, RAND_INF_WATER_TEMPLE_MQ_STORAGE_ROOM_A_CRATE_6, }, - { RC_WATER_TEMPLE_MQ_STORAGE_ROOM_A_CRATE_7, RAND_INF_WATER_TEMPLE_MQ_STORAGE_ROOM_A_CRATE_7, }, - { RC_WATER_TEMPLE_MQ_GS_STORAGE_ROOM_LOWER_CRATE_1, RAND_INF_WATER_TEMPLE_MQ_GS_STORAGE_ROOM_LOWER_CRATE_1, }, - { RC_WATER_TEMPLE_MQ_GS_STORAGE_ROOM_LOWER_CRATE_2, RAND_INF_WATER_TEMPLE_MQ_GS_STORAGE_ROOM_LOWER_CRATE_2, }, - { RC_WATER_TEMPLE_MQ_GS_STORAGE_ROOM_LOWER_CRATE_3, RAND_INF_WATER_TEMPLE_MQ_GS_STORAGE_ROOM_LOWER_CRATE_3, }, - { RC_WATER_TEMPLE_MQ_GS_STORAGE_ROOM_LOWER_CRATE_4, RAND_INF_WATER_TEMPLE_MQ_GS_STORAGE_ROOM_LOWER_CRATE_4, }, - { RC_WATER_TEMPLE_MQ_GS_STORAGE_ROOM_LOWER_CRATE_5, RAND_INF_WATER_TEMPLE_MQ_GS_STORAGE_ROOM_LOWER_CRATE_5, }, - { RC_WATER_TEMPLE_MQ_GS_STORAGE_ROOM_LOWER_CRATE_6, RAND_INF_WATER_TEMPLE_MQ_GS_STORAGE_ROOM_LOWER_CRATE_6, }, - { RC_WATER_TEMPLE_MQ_GS_STORAGE_ROOM_UPPER_CRATE_1, RAND_INF_WATER_TEMPLE_MQ_GS_STORAGE_ROOM_UPPER_CRATE_1, }, - { RC_WATER_TEMPLE_MQ_GS_STORAGE_ROOM_UPPER_CRATE_2, RAND_INF_WATER_TEMPLE_MQ_GS_STORAGE_ROOM_UPPER_CRATE_2, }, - { RC_WATER_TEMPLE_MQ_DRAGON_ROOM_TORCHES_CRATE_1, RAND_INF_WATER_TEMPLE_MQ_DRAGON_ROOM_TORCHES_CRATE_1, }, - { RC_WATER_TEMPLE_MQ_DRAGON_ROOM_TORCHES_CRATE_2, RAND_INF_WATER_TEMPLE_MQ_DRAGON_ROOM_TORCHES_CRATE_2, }, - { RC_WATER_TEMPLE_MQ_DRAGON_ROOM_SUBMERGED_CRATE_1, RAND_INF_WATER_TEMPLE_MQ_DRAGON_ROOM_SUBMERGED_CRATE_1, }, - { RC_WATER_TEMPLE_MQ_DRAGON_ROOM_SUBMERGED_CRATE_2, RAND_INF_WATER_TEMPLE_MQ_DRAGON_ROOM_SUBMERGED_CRATE_2, }, - { RC_WATER_TEMPLE_MQ_DRAGON_ROOM_SUBMERGED_CRATE_3, RAND_INF_WATER_TEMPLE_MQ_DRAGON_ROOM_SUBMERGED_CRATE_3, }, - { RC_WATER_TEMPLE_MQ_DRAGON_ROOM_SUBMERGED_CRATE_4, RAND_INF_WATER_TEMPLE_MQ_DRAGON_ROOM_SUBMERGED_CRATE_4, }, - { RC_WATER_TEMPLE_MQ_DRAGON_ROOM_DOOR_CRATE_1, RAND_INF_WATER_TEMPLE_MQ_DRAGON_ROOM_DOOR_CRATE_1, }, - { RC_WATER_TEMPLE_MQ_DRAGON_ROOM_DOOR_CRATE_2, RAND_INF_WATER_TEMPLE_MQ_DRAGON_ROOM_DOOR_CRATE_2, }, - { RC_WATER_TEMPLE_MQ_BK_ROOM_UPPER_CRATE, RAND_INF_WATER_TEMPLE_MQ_BK_ROOM_UPPER_CRATE, }, - { RC_WATER_TEMPLE_MQ_BK_ROOM_LOWER_CRATE_1, RAND_INF_WATER_TEMPLE_MQ_BK_ROOM_LOWER_CRATE_1, }, - { RC_WATER_TEMPLE_MQ_BK_ROOM_LOWER_CRATE_2, RAND_INF_WATER_TEMPLE_MQ_BK_ROOM_LOWER_CRATE_2, }, - { RC_WATER_TEMPLE_MQ_BK_ROOM_LOWER_CRATE_3, RAND_INF_WATER_TEMPLE_MQ_BK_ROOM_LOWER_CRATE_3, }, - { RC_WATER_TEMPLE_MQ_BK_ROOM_LOWER_CRATE_4, RAND_INF_WATER_TEMPLE_MQ_BK_ROOM_LOWER_CRATE_4, }, - { RC_WATER_TEMPLE_MQ_WHIRLPOOL_FRONT_CRATE_1, RAND_INF_WATER_TEMPLE_MQ_WHIRLPOOL_FRONT_CRATE_1, }, - { RC_WATER_TEMPLE_MQ_WHIRLPOOL_FRONT_CRATE_2, RAND_INF_WATER_TEMPLE_MQ_WHIRLPOOL_FRONT_CRATE_2, }, - { RC_WATER_TEMPLE_MQ_WHIRLPOOL_SUBMERGED_CRATE_1, RAND_INF_WATER_TEMPLE_MQ_WHIRLPOOL_SUBMERGED_CRATE_1, }, - { RC_WATER_TEMPLE_MQ_WHIRLPOOL_SUBMERGED_CRATE_2, RAND_INF_WATER_TEMPLE_MQ_WHIRLPOOL_SUBMERGED_CRATE_2, }, - { RC_WATER_TEMPLE_MQ_WHIRLPOOL_SUBMERGED_CRATE_3, RAND_INF_WATER_TEMPLE_MQ_WHIRLPOOL_SUBMERGED_CRATE_3, }, - { RC_WATER_TEMPLE_MQ_WHIRLPOOL_SUBMERGED_CRATE_4, RAND_INF_WATER_TEMPLE_MQ_WHIRLPOOL_SUBMERGED_CRATE_4, }, - { RC_WATER_TEMPLE_MQ_WHIRLPOOL_SUBMERGED_CRATE_5, RAND_INF_WATER_TEMPLE_MQ_WHIRLPOOL_SUBMERGED_CRATE_5, }, - { RC_WATER_TEMPLE_MQ_WHIRLPOOL_SUBMERGED_CRATE_6, RAND_INF_WATER_TEMPLE_MQ_WHIRLPOOL_SUBMERGED_CRATE_6, }, - { RC_WATER_TEMPLE_MQ_WHIRLPOOL_BEHIND_GATE_CRATE_1, RAND_INF_WATER_TEMPLE_MQ_WHIRLPOOL_BEHIND_GATE_CRATE_1, }, - { RC_WATER_TEMPLE_MQ_WHIRLPOOL_BEHIND_GATE_CRATE_2, RAND_INF_WATER_TEMPLE_MQ_WHIRLPOOL_BEHIND_GATE_CRATE_2, }, - { RC_WATER_TEMPLE_MQ_WHIRLPOOL_BEHIND_GATE_CRATE_3, RAND_INF_WATER_TEMPLE_MQ_WHIRLPOOL_BEHIND_GATE_CRATE_3, }, - { RC_WATER_TEMPLE_MQ_WHIRLPOOL_BEHIND_GATE_CRATE_4, RAND_INF_WATER_TEMPLE_MQ_WHIRLPOOL_BEHIND_GATE_CRATE_4, }, - { RC_WATER_TEMPLE_MQ_DODONGO_ROOM_UPPER_CRATE, RAND_INF_WATER_TEMPLE_MQ_DODONGO_ROOM_UPPER_CRATE, }, - { RC_WATER_TEMPLE_MQ_DODONGO_ROOM_HALL_CRATE, RAND_INF_WATER_TEMPLE_MQ_DODONGO_ROOM_HALL_CRATE, }, - { RC_WATER_TEMPLE_MQ_DODONGO_ROOM_LOWER_CRATE_1, RAND_INF_WATER_TEMPLE_MQ_DODONGO_ROOM_LOWER_CRATE_1, }, - { RC_WATER_TEMPLE_MQ_DODONGO_ROOM_LOWER_CRATE_2, RAND_INF_WATER_TEMPLE_MQ_DODONGO_ROOM_LOWER_CRATE_2, }, - { RC_WATER_TEMPLE_MQ_DODONGO_ROOM_LOWER_CRATE_3, RAND_INF_WATER_TEMPLE_MQ_DODONGO_ROOM_LOWER_CRATE_3, }, - { RC_WATER_TEMPLE_MQ_STORAGE_ROOM_B_CRATE_1, RAND_INF_WATER_TEMPLE_MQ_STORAGE_ROOM_B_CRATE_1, }, - { RC_WATER_TEMPLE_MQ_STORAGE_ROOM_B_CRATE_2, RAND_INF_WATER_TEMPLE_MQ_STORAGE_ROOM_B_CRATE_2, }, - { RC_WATER_TEMPLE_MQ_STORAGE_ROOM_B_CRATE_3, RAND_INF_WATER_TEMPLE_MQ_STORAGE_ROOM_B_CRATE_3, }, - { RC_WATER_TEMPLE_MQ_STORAGE_ROOM_B_CRATE_4, RAND_INF_WATER_TEMPLE_MQ_STORAGE_ROOM_B_CRATE_4, }, - { RC_WATER_TEMPLE_MQ_STORAGE_ROOM_B_CRATE_5, RAND_INF_WATER_TEMPLE_MQ_STORAGE_ROOM_B_CRATE_5, }, - { RC_WATER_TEMPLE_MQ_TRIPLE_TORCH_ROOM_SUBMERGED_CRATE_1, RAND_INF_WATER_TEMPLE_MQ_TRIPLE_TORCH_ROOM_SUBMERGED_CRATE_1, }, - { RC_WATER_TEMPLE_MQ_TRIPLE_TORCH_ROOM_SUBMERGED_CRATE_2, RAND_INF_WATER_TEMPLE_MQ_TRIPLE_TORCH_ROOM_SUBMERGED_CRATE_2, }, - { RC_WATER_TEMPLE_MQ_TRIPLE_TORCH_ROOM_SUBMERGED_CRATE_3, RAND_INF_WATER_TEMPLE_MQ_TRIPLE_TORCH_ROOM_SUBMERGED_CRATE_3, }, - { RC_WATER_TEMPLE_MQ_TRIPLE_TORCH_ROOM_SUBMERGED_CRATE_4, RAND_INF_WATER_TEMPLE_MQ_TRIPLE_TORCH_ROOM_SUBMERGED_CRATE_4, }, - { RC_WATER_TEMPLE_MQ_TRIPLE_TORCH_ROOM_SUBMERGED_CRATE_5, RAND_INF_WATER_TEMPLE_MQ_TRIPLE_TORCH_ROOM_SUBMERGED_CRATE_5, }, - { RC_WATER_TEMPLE_MQ_TRIPLE_TORCH_ROOM_SUBMERGED_CRATE_6, RAND_INF_WATER_TEMPLE_MQ_TRIPLE_TORCH_ROOM_SUBMERGED_CRATE_6, }, - { RC_WATER_TEMPLE_MQ_TRIPLE_TORCH_ROOM_GATE_CRATE_1, RAND_INF_WATER_TEMPLE_MQ_TRIPLE_TORCH_ROOM_GATE_CRATE_1, }, - { RC_WATER_TEMPLE_MQ_TRIPLE_TORCH_ROOM_GATE_CRATE_2, RAND_INF_WATER_TEMPLE_MQ_TRIPLE_TORCH_ROOM_GATE_CRATE_2, }, - { RC_WATER_TEMPLE_MQ_TRIPLE_TORCH_ROOM_GATE_CRATE_3, RAND_INF_WATER_TEMPLE_MQ_TRIPLE_TORCH_ROOM_GATE_CRATE_3, }, - { RC_SPIRIT_TEMPLE_MQ_STATUE_CRATE_1, RAND_INF_SPIRIT_TEMPLE_MQ_STATUE_CRATE_1, }, - { RC_SPIRIT_TEMPLE_MQ_STATUE_CRATE_2, RAND_INF_SPIRIT_TEMPLE_MQ_STATUE_CRATE_2, }, - { RC_SPIRIT_TEMPLE_MQ_BIG_MIRROR_CRATE_1, RAND_INF_SPIRIT_TEMPLE_MQ_BIG_MIRROR_CRATE_1, }, - { RC_SPIRIT_TEMPLE_MQ_BIG_MIRROR_CRATE_2, RAND_INF_SPIRIT_TEMPLE_MQ_BIG_MIRROR_CRATE_2, }, - { RC_SPIRIT_TEMPLE_MQ_BIG_MIRROR_CRATE_3, RAND_INF_SPIRIT_TEMPLE_MQ_BIG_MIRROR_CRATE_3, }, - { RC_SPIRIT_TEMPLE_MQ_BIG_MIRROR_CRATE_4, RAND_INF_SPIRIT_TEMPLE_MQ_BIG_MIRROR_CRATE_4, }, - { RC_GERUDO_TRAINING_GROUND_MQ_MAZE_CRATE, RAND_INF_GERUDO_TRAINING_GROUND_MQ_MAZE_CRATE, }, + { + RC_DEKU_TREE_MQ_LOBBY_CRATE, + RAND_INF_DEKU_TREE_MQ_LOBBY_CRATE, + }, + { + RC_DEKU_TREE_MQ_SLINGSHOT_ROOM_CRATE_1, + RAND_INF_DEKU_TREE_MQ_SLINGSHOT_ROOM_CRATE_1, + }, + { + RC_DEKU_TREE_MQ_SLINGSHOT_ROOM_CRATE_2, + RAND_INF_DEKU_TREE_MQ_SLINGSHOT_ROOM_CRATE_2, + }, + { + RC_DODONGOS_CAVERN_MQ_POE_ROOM_CRATE_1, + RAND_INF_DODONGOS_CAVERN_MQ_POE_ROOM_CRATE_1, + }, + { + RC_DODONGOS_CAVERN_MQ_POE_ROOM_CRATE_2, + RAND_INF_DODONGOS_CAVERN_MQ_POE_ROOM_CRATE_2, + }, + { + RC_DODONGOS_CAVERN_MQ_POE_ROOM_CRATE_3, + RAND_INF_DODONGOS_CAVERN_MQ_POE_ROOM_CRATE_3, + }, + { + RC_DODONGOS_CAVERN_MQ_POE_ROOM_CRATE_4, + RAND_INF_DODONGOS_CAVERN_MQ_POE_ROOM_CRATE_4, + }, + { + RC_DODONGOS_CAVERN_MQ_POE_ROOM_CRATE_5, + RAND_INF_DODONGOS_CAVERN_MQ_POE_ROOM_CRATE_5, + }, + { + RC_DODONGOS_CAVERN_MQ_POE_ROOM_CRATE_6, + RAND_INF_DODONGOS_CAVERN_MQ_POE_ROOM_CRATE_6, + }, + { + RC_DODONGOS_CAVERN_MQ_POE_ROOM_CRATE_7, + RAND_INF_DODONGOS_CAVERN_MQ_POE_ROOM_CRATE_7, + }, + { + RC_DODONGOS_CAVERN_MQ_POE_ROOM_CRATE_8, + RAND_INF_DODONGOS_CAVERN_MQ_POE_ROOM_CRATE_8, + }, + { + RC_DODONGOS_CAVERN_MQ_STAIRCASE_LOWER_CRATE_1, + RAND_INF_DODONGOS_CAVERN_MQ_STAIRCASE_LOWER_CRATE_1, + }, + { + RC_DODONGOS_CAVERN_MQ_STAIRCASE_LOWER_CRATE_2, + RAND_INF_DODONGOS_CAVERN_MQ_STAIRCASE_LOWER_CRATE_2, + }, + { + RC_DODONGOS_CAVERN_MQ_STAIRCASE_UPPER_CRATE_1, + RAND_INF_DODONGOS_CAVERN_MQ_STAIRCASE_UPPER_CRATE_1, + }, + { + RC_DODONGOS_CAVERN_MQ_STAIRCASE_UPPER_CRATE_2, + RAND_INF_DODONGOS_CAVERN_MQ_STAIRCASE_UPPER_CRATE_2, + }, + { + RC_DODONGOS_CAVERN_MQ_STAIRCASE_UPPER_CRATE_3, + RAND_INF_DODONGOS_CAVERN_MQ_STAIRCASE_UPPER_CRATE_3, + }, + { + RC_DODONGOS_CAVERN_MQ_STAIRCASE_UPPER_CRATE_4, + RAND_INF_DODONGOS_CAVERN_MQ_STAIRCASE_UPPER_CRATE_4, + }, + { + RC_DODONGOS_CAVERN_MQ_TWO_FLAMES_CRATE_1, + RAND_INF_DODONGOS_CAVERN_MQ_TWO_FLAMES_CRATE_1, + }, + { + RC_DODONGOS_CAVERN_MQ_TWO_FLAMES_CRATE_2, + RAND_INF_DODONGOS_CAVERN_MQ_TWO_FLAMES_CRATE_2, + }, + { + RC_DODONGOS_CAVERN_MQ_LARVAE_ROOM_CRATE_1, + RAND_INF_DODONGOS_CAVERN_MQ_LARVAE_ROOM_CRATE_1, + }, + { + RC_DODONGOS_CAVERN_MQ_LARVAE_ROOM_CRATE_2, + RAND_INF_DODONGOS_CAVERN_MQ_LARVAE_ROOM_CRATE_2, + }, + { + RC_DODONGOS_CAVERN_MQ_LARVAE_ROOM_CRATE_3, + RAND_INF_DODONGOS_CAVERN_MQ_LARVAE_ROOM_CRATE_3, + }, + { + RC_DODONGOS_CAVERN_MQ_LARVAE_ROOM_CRATE_4, + RAND_INF_DODONGOS_CAVERN_MQ_LARVAE_ROOM_CRATE_4, + }, + { + RC_DODONGOS_CAVERN_MQ_LARVAE_ROOM_CRATE_5, + RAND_INF_DODONGOS_CAVERN_MQ_LARVAE_ROOM_CRATE_5, + }, + { + RC_DODONGOS_CAVERN_MQ_LARVAE_ROOM_CRATE_6, + RAND_INF_DODONGOS_CAVERN_MQ_LARVAE_ROOM_CRATE_6, + }, + { + RC_FIRE_TEMPLE_MQ_OUTSIDE_BOSS_CRATE_1, + RAND_INF_FIRE_TEMPLE_MQ_OUTSIDE_BOSS_CRATE_1, + }, + { + RC_FIRE_TEMPLE_MQ_OUTSIDE_BOSS_CRATE_2, + RAND_INF_FIRE_TEMPLE_MQ_OUTSIDE_BOSS_CRATE_2, + }, + { + RC_FIRE_TEMPLE_MQ_OUTSIDE_BOSS_CRATE_3, + RAND_INF_FIRE_TEMPLE_MQ_OUTSIDE_BOSS_CRATE_3, + }, + { + RC_FIRE_TEMPLE_MQ_OUTSIDE_BOSS_CRATE_4, + RAND_INF_FIRE_TEMPLE_MQ_OUTSIDE_BOSS_CRATE_4, + }, + { + RC_FIRE_TEMPLE_MQ_OUTSIDE_BOSS_CRATE_5, + RAND_INF_FIRE_TEMPLE_MQ_OUTSIDE_BOSS_CRATE_5, + }, + { + RC_FIRE_TEMPLE_MQ_OUTSIDE_BOSS_CRATE_6, + RAND_INF_FIRE_TEMPLE_MQ_OUTSIDE_BOSS_CRATE_6, + }, + { + RC_FIRE_TEMPLE_MQ_SHORTCUT_CRATE_1, + RAND_INF_FIRE_TEMPLE_MQ_SHORTCUT_CRATE_1, + }, + { + RC_FIRE_TEMPLE_MQ_SHORTCUT_CRATE_2, + RAND_INF_FIRE_TEMPLE_MQ_SHORTCUT_CRATE_2, + }, + { + RC_FIRE_TEMPLE_MQ_SHORTCUT_CRATE_3, + RAND_INF_FIRE_TEMPLE_MQ_SHORTCUT_CRATE_3, + }, + { + RC_FIRE_TEMPLE_MQ_SHORTCUT_CRATE_4, + RAND_INF_FIRE_TEMPLE_MQ_SHORTCUT_CRATE_4, + }, + { + RC_FIRE_TEMPLE_MQ_SHORTCUT_CRATE_5, + RAND_INF_FIRE_TEMPLE_MQ_SHORTCUT_CRATE_5, + }, + { + RC_FIRE_TEMPLE_MQ_SHORTCUT_CRATE_6, + RAND_INF_FIRE_TEMPLE_MQ_SHORTCUT_CRATE_6, + }, + { + RC_FIRE_TEMPLE_MQ_LIZALFOS_MAZE_LOWER_CRATE_1, + RAND_INF_FIRE_TEMPLE_MQ_LIZALFOS_MAZE_LOWER_CRATE_1, + }, + { + RC_FIRE_TEMPLE_MQ_LIZALFOS_MAZE_LOWER_CRATE_2, + RAND_INF_FIRE_TEMPLE_MQ_LIZALFOS_MAZE_LOWER_CRATE_2, + }, + { + RC_FIRE_TEMPLE_MQ_LIZALFOS_MAZE_LOWER_CRATE_3, + RAND_INF_FIRE_TEMPLE_MQ_LIZALFOS_MAZE_LOWER_CRATE_3, + }, + { + RC_FIRE_TEMPLE_MQ_LIZALFOS_MAZE_UPPER_CRATE_1, + RAND_INF_FIRE_TEMPLE_MQ_LIZALFOS_MAZE_UPPER_CRATE_1, + }, + { + RC_FIRE_TEMPLE_MQ_LIZALFOS_MAZE_UPPER_CRATE_2, + RAND_INF_FIRE_TEMPLE_MQ_LIZALFOS_MAZE_UPPER_CRATE_2, + }, + { + RC_FIRE_TEMPLE_MQ_LIZALFOS_MAZE_UPPER_CRATE_3, + RAND_INF_FIRE_TEMPLE_MQ_LIZALFOS_MAZE_UPPER_CRATE_3, + }, + { + RC_FIRE_TEMPLE_MQ_LAVA_TORCH_CRATE_1, + RAND_INF_FIRE_TEMPLE_MQ_LAVA_TORCH_CRATE_1, + }, + { + RC_FIRE_TEMPLE_MQ_LAVA_TORCH_CRATE_2, + RAND_INF_FIRE_TEMPLE_MQ_LAVA_TORCH_CRATE_2, + }, + { + RC_FIRE_TEMPLE_MQ_LAVA_TORCH_CRATE_3, + RAND_INF_FIRE_TEMPLE_MQ_LAVA_TORCH_CRATE_3, + }, + { + RC_FIRE_TEMPLE_MQ_LAVA_TORCH_CRATE_4, + RAND_INF_FIRE_TEMPLE_MQ_LAVA_TORCH_CRATE_4, + }, + { + RC_FIRE_TEMPLE_MQ_LAVA_TORCH_CRATE_5, + RAND_INF_FIRE_TEMPLE_MQ_LAVA_TORCH_CRATE_5, + }, + { + RC_WATER_TEMPLE_MQ_CENTRAL_PILLAR_UPPER_CRATE_1, + RAND_INF_WATER_TEMPLE_MQ_CENTRAL_PILLAR_UPPER_CRATE_1, + }, + { + RC_WATER_TEMPLE_MQ_CENTRAL_PILLAR_UPPER_CRATE_2, + RAND_INF_WATER_TEMPLE_MQ_CENTRAL_PILLAR_UPPER_CRATE_2, + }, + { + RC_WATER_TEMPLE_MQ_CENTRAL_PILLAR_LOWER_CRATE_1, + RAND_INF_WATER_TEMPLE_MQ_CENTRAL_PILLAR_LOWER_CRATE_1, + }, + { + RC_WATER_TEMPLE_MQ_CENTRAL_PILLAR_LOWER_CRATE_2, + RAND_INF_WATER_TEMPLE_MQ_CENTRAL_PILLAR_LOWER_CRATE_2, + }, + { + RC_WATER_TEMPLE_MQ_CENTRAL_PILLAR_LOWER_CRATE_3, + RAND_INF_WATER_TEMPLE_MQ_CENTRAL_PILLAR_LOWER_CRATE_3, + }, + { + RC_WATER_TEMPLE_MQ_CENTRAL_PILLAR_LOWER_CRATE_4, + RAND_INF_WATER_TEMPLE_MQ_CENTRAL_PILLAR_LOWER_CRATE_4, + }, + { + RC_WATER_TEMPLE_MQ_CENTRAL_PILLAR_LOWER_CRATE_5, + RAND_INF_WATER_TEMPLE_MQ_CENTRAL_PILLAR_LOWER_CRATE_5, + }, + { + RC_WATER_TEMPLE_MQ_CENTRAL_PILLAR_LOWER_CRATE_6, + RAND_INF_WATER_TEMPLE_MQ_CENTRAL_PILLAR_LOWER_CRATE_6, + }, + { + RC_WATER_TEMPLE_MQ_CENTRAL_PILLAR_LOWER_CRATE_7, + RAND_INF_WATER_TEMPLE_MQ_CENTRAL_PILLAR_LOWER_CRATE_7, + }, + { + RC_WATER_TEMPLE_MQ_CENTRAL_PILLAR_LOWER_CRATE_8, + RAND_INF_WATER_TEMPLE_MQ_CENTRAL_PILLAR_LOWER_CRATE_8, + }, + { + RC_WATER_TEMPLE_MQ_CENTRAL_PILLAR_LOWER_CRATE_9, + RAND_INF_WATER_TEMPLE_MQ_CENTRAL_PILLAR_LOWER_CRATE_9, + }, + { + RC_WATER_TEMPLE_MQ_CENTRAL_PILLAR_LOWER_CRATE_10, + RAND_INF_WATER_TEMPLE_MQ_CENTRAL_PILLAR_LOWER_CRATE_10, + }, + { + RC_WATER_TEMPLE_MQ_CENTRAL_PILLAR_LOWER_CRATE_11, + RAND_INF_WATER_TEMPLE_MQ_CENTRAL_PILLAR_LOWER_CRATE_11, + }, + { + RC_WATER_TEMPLE_MQ_CENTRAL_PILLAR_LOWER_CRATE_12, + RAND_INF_WATER_TEMPLE_MQ_CENTRAL_PILLAR_LOWER_CRATE_12, + }, + { + RC_WATER_TEMPLE_MQ_CENTRAL_PILLAR_LOWER_CRATE_13, + RAND_INF_WATER_TEMPLE_MQ_CENTRAL_PILLAR_LOWER_CRATE_13, + }, + { + RC_WATER_TEMPLE_MQ_CENTRAL_PILLAR_LOWER_CRATE_14, + RAND_INF_WATER_TEMPLE_MQ_CENTRAL_PILLAR_LOWER_CRATE_14, + }, + { + RC_WATER_TEMPLE_MQ_LIZALFOS_HALLWAY_CRATE_1, + RAND_INF_WATER_TEMPLE_MQ_LIZALFOS_HALLWAY_CRATE_1, + }, + { + RC_WATER_TEMPLE_MQ_LIZALFOS_HALLWAY_CRATE_2, + RAND_INF_WATER_TEMPLE_MQ_LIZALFOS_HALLWAY_CRATE_2, + }, + { + RC_WATER_TEMPLE_MQ_LIZALFOS_HALLWAY_CRATE_3, + RAND_INF_WATER_TEMPLE_MQ_LIZALFOS_HALLWAY_CRATE_3, + }, + { + RC_WATER_TEMPLE_MQ_LIZALFOS_HALLWAY_ROOM_CRATE_1, + RAND_INF_WATER_TEMPLE_MQ_LIZALFOS_HALLWAY_ROOM_CRATE_1, + }, + { + RC_WATER_TEMPLE_MQ_LIZALFOS_HALLWAY_ROOM_CRATE_2, + RAND_INF_WATER_TEMPLE_MQ_LIZALFOS_HALLWAY_ROOM_CRATE_2, + }, + { + RC_WATER_TEMPLE_MQ_LIZALFOS_HALLWAY_ROOM_CRATE_3, + RAND_INF_WATER_TEMPLE_MQ_LIZALFOS_HALLWAY_ROOM_CRATE_3, + }, + { + RC_WATER_TEMPLE_MQ_LIZALFOS_HALLWAY_ROOM_CRATE_4, + RAND_INF_WATER_TEMPLE_MQ_LIZALFOS_HALLWAY_ROOM_CRATE_4, + }, + { + RC_WATER_TEMPLE_MQ_LIZALFOS_HALLWAY_ROOM_CRATE_5, + RAND_INF_WATER_TEMPLE_MQ_LIZALFOS_HALLWAY_ROOM_CRATE_5, + }, + { + RC_WATER_TEMPLE_MQ_LIZALFOS_HALLWAY_GATE_CRATE_1, + RAND_INF_WATER_TEMPLE_MQ_LIZALFOS_HALLWAY_GATE_CRATE_1, + }, + { + RC_WATER_TEMPLE_MQ_LIZALFOS_HALLWAY_GATE_CRATE_2, + RAND_INF_WATER_TEMPLE_MQ_LIZALFOS_HALLWAY_GATE_CRATE_2, + }, + { + RC_WATER_TEMPLE_MQ_STORAGE_ROOM_A_CRATE_1, + RAND_INF_WATER_TEMPLE_MQ_STORAGE_ROOM_A_CRATE_1, + }, + { + RC_WATER_TEMPLE_MQ_STORAGE_ROOM_A_CRATE_2, + RAND_INF_WATER_TEMPLE_MQ_STORAGE_ROOM_A_CRATE_2, + }, + { + RC_WATER_TEMPLE_MQ_STORAGE_ROOM_A_CRATE_3, + RAND_INF_WATER_TEMPLE_MQ_STORAGE_ROOM_A_CRATE_3, + }, + { + RC_WATER_TEMPLE_MQ_STORAGE_ROOM_A_CRATE_4, + RAND_INF_WATER_TEMPLE_MQ_STORAGE_ROOM_A_CRATE_4, + }, + { + RC_WATER_TEMPLE_MQ_STORAGE_ROOM_A_CRATE_5, + RAND_INF_WATER_TEMPLE_MQ_STORAGE_ROOM_A_CRATE_5, + }, + { + RC_WATER_TEMPLE_MQ_STORAGE_ROOM_A_CRATE_6, + RAND_INF_WATER_TEMPLE_MQ_STORAGE_ROOM_A_CRATE_6, + }, + { + RC_WATER_TEMPLE_MQ_STORAGE_ROOM_A_CRATE_7, + RAND_INF_WATER_TEMPLE_MQ_STORAGE_ROOM_A_CRATE_7, + }, + { + RC_WATER_TEMPLE_MQ_GS_STORAGE_ROOM_LOWER_CRATE_1, + RAND_INF_WATER_TEMPLE_MQ_GS_STORAGE_ROOM_LOWER_CRATE_1, + }, + { + RC_WATER_TEMPLE_MQ_GS_STORAGE_ROOM_LOWER_CRATE_2, + RAND_INF_WATER_TEMPLE_MQ_GS_STORAGE_ROOM_LOWER_CRATE_2, + }, + { + RC_WATER_TEMPLE_MQ_GS_STORAGE_ROOM_LOWER_CRATE_3, + RAND_INF_WATER_TEMPLE_MQ_GS_STORAGE_ROOM_LOWER_CRATE_3, + }, + { + RC_WATER_TEMPLE_MQ_GS_STORAGE_ROOM_LOWER_CRATE_4, + RAND_INF_WATER_TEMPLE_MQ_GS_STORAGE_ROOM_LOWER_CRATE_4, + }, + { + RC_WATER_TEMPLE_MQ_GS_STORAGE_ROOM_LOWER_CRATE_5, + RAND_INF_WATER_TEMPLE_MQ_GS_STORAGE_ROOM_LOWER_CRATE_5, + }, + { + RC_WATER_TEMPLE_MQ_GS_STORAGE_ROOM_LOWER_CRATE_6, + RAND_INF_WATER_TEMPLE_MQ_GS_STORAGE_ROOM_LOWER_CRATE_6, + }, + { + RC_WATER_TEMPLE_MQ_GS_STORAGE_ROOM_UPPER_CRATE_1, + RAND_INF_WATER_TEMPLE_MQ_GS_STORAGE_ROOM_UPPER_CRATE_1, + }, + { + RC_WATER_TEMPLE_MQ_GS_STORAGE_ROOM_UPPER_CRATE_2, + RAND_INF_WATER_TEMPLE_MQ_GS_STORAGE_ROOM_UPPER_CRATE_2, + }, + { + RC_WATER_TEMPLE_MQ_DRAGON_ROOM_TORCHES_CRATE_1, + RAND_INF_WATER_TEMPLE_MQ_DRAGON_ROOM_TORCHES_CRATE_1, + }, + { + RC_WATER_TEMPLE_MQ_DRAGON_ROOM_TORCHES_CRATE_2, + RAND_INF_WATER_TEMPLE_MQ_DRAGON_ROOM_TORCHES_CRATE_2, + }, + { + RC_WATER_TEMPLE_MQ_DRAGON_ROOM_SUBMERGED_CRATE_1, + RAND_INF_WATER_TEMPLE_MQ_DRAGON_ROOM_SUBMERGED_CRATE_1, + }, + { + RC_WATER_TEMPLE_MQ_DRAGON_ROOM_SUBMERGED_CRATE_2, + RAND_INF_WATER_TEMPLE_MQ_DRAGON_ROOM_SUBMERGED_CRATE_2, + }, + { + RC_WATER_TEMPLE_MQ_DRAGON_ROOM_SUBMERGED_CRATE_3, + RAND_INF_WATER_TEMPLE_MQ_DRAGON_ROOM_SUBMERGED_CRATE_3, + }, + { + RC_WATER_TEMPLE_MQ_DRAGON_ROOM_SUBMERGED_CRATE_4, + RAND_INF_WATER_TEMPLE_MQ_DRAGON_ROOM_SUBMERGED_CRATE_4, + }, + { + RC_WATER_TEMPLE_MQ_DRAGON_ROOM_DOOR_CRATE_1, + RAND_INF_WATER_TEMPLE_MQ_DRAGON_ROOM_DOOR_CRATE_1, + }, + { + RC_WATER_TEMPLE_MQ_DRAGON_ROOM_DOOR_CRATE_2, + RAND_INF_WATER_TEMPLE_MQ_DRAGON_ROOM_DOOR_CRATE_2, + }, + { + RC_WATER_TEMPLE_MQ_BK_ROOM_UPPER_CRATE, + RAND_INF_WATER_TEMPLE_MQ_BK_ROOM_UPPER_CRATE, + }, + { + RC_WATER_TEMPLE_MQ_BK_ROOM_LOWER_CRATE_1, + RAND_INF_WATER_TEMPLE_MQ_BK_ROOM_LOWER_CRATE_1, + }, + { + RC_WATER_TEMPLE_MQ_BK_ROOM_LOWER_CRATE_2, + RAND_INF_WATER_TEMPLE_MQ_BK_ROOM_LOWER_CRATE_2, + }, + { + RC_WATER_TEMPLE_MQ_BK_ROOM_LOWER_CRATE_3, + RAND_INF_WATER_TEMPLE_MQ_BK_ROOM_LOWER_CRATE_3, + }, + { + RC_WATER_TEMPLE_MQ_BK_ROOM_LOWER_CRATE_4, + RAND_INF_WATER_TEMPLE_MQ_BK_ROOM_LOWER_CRATE_4, + }, + { + RC_WATER_TEMPLE_MQ_WHIRLPOOL_FRONT_CRATE_1, + RAND_INF_WATER_TEMPLE_MQ_WHIRLPOOL_FRONT_CRATE_1, + }, + { + RC_WATER_TEMPLE_MQ_WHIRLPOOL_FRONT_CRATE_2, + RAND_INF_WATER_TEMPLE_MQ_WHIRLPOOL_FRONT_CRATE_2, + }, + { + RC_WATER_TEMPLE_MQ_WHIRLPOOL_SUBMERGED_CRATE_1, + RAND_INF_WATER_TEMPLE_MQ_WHIRLPOOL_SUBMERGED_CRATE_1, + }, + { + RC_WATER_TEMPLE_MQ_WHIRLPOOL_SUBMERGED_CRATE_2, + RAND_INF_WATER_TEMPLE_MQ_WHIRLPOOL_SUBMERGED_CRATE_2, + }, + { + RC_WATER_TEMPLE_MQ_WHIRLPOOL_SUBMERGED_CRATE_3, + RAND_INF_WATER_TEMPLE_MQ_WHIRLPOOL_SUBMERGED_CRATE_3, + }, + { + RC_WATER_TEMPLE_MQ_WHIRLPOOL_SUBMERGED_CRATE_4, + RAND_INF_WATER_TEMPLE_MQ_WHIRLPOOL_SUBMERGED_CRATE_4, + }, + { + RC_WATER_TEMPLE_MQ_WHIRLPOOL_SUBMERGED_CRATE_5, + RAND_INF_WATER_TEMPLE_MQ_WHIRLPOOL_SUBMERGED_CRATE_5, + }, + { + RC_WATER_TEMPLE_MQ_WHIRLPOOL_SUBMERGED_CRATE_6, + RAND_INF_WATER_TEMPLE_MQ_WHIRLPOOL_SUBMERGED_CRATE_6, + }, + { + RC_WATER_TEMPLE_MQ_WHIRLPOOL_BEHIND_GATE_CRATE_1, + RAND_INF_WATER_TEMPLE_MQ_WHIRLPOOL_BEHIND_GATE_CRATE_1, + }, + { + RC_WATER_TEMPLE_MQ_WHIRLPOOL_BEHIND_GATE_CRATE_2, + RAND_INF_WATER_TEMPLE_MQ_WHIRLPOOL_BEHIND_GATE_CRATE_2, + }, + { + RC_WATER_TEMPLE_MQ_WHIRLPOOL_BEHIND_GATE_CRATE_3, + RAND_INF_WATER_TEMPLE_MQ_WHIRLPOOL_BEHIND_GATE_CRATE_3, + }, + { + RC_WATER_TEMPLE_MQ_WHIRLPOOL_BEHIND_GATE_CRATE_4, + RAND_INF_WATER_TEMPLE_MQ_WHIRLPOOL_BEHIND_GATE_CRATE_4, + }, + { + RC_WATER_TEMPLE_MQ_DODONGO_ROOM_UPPER_CRATE, + RAND_INF_WATER_TEMPLE_MQ_DODONGO_ROOM_UPPER_CRATE, + }, + { + RC_WATER_TEMPLE_MQ_DODONGO_ROOM_HALL_CRATE, + RAND_INF_WATER_TEMPLE_MQ_DODONGO_ROOM_HALL_CRATE, + }, + { + RC_WATER_TEMPLE_MQ_DODONGO_ROOM_LOWER_CRATE_1, + RAND_INF_WATER_TEMPLE_MQ_DODONGO_ROOM_LOWER_CRATE_1, + }, + { + RC_WATER_TEMPLE_MQ_DODONGO_ROOM_LOWER_CRATE_2, + RAND_INF_WATER_TEMPLE_MQ_DODONGO_ROOM_LOWER_CRATE_2, + }, + { + RC_WATER_TEMPLE_MQ_DODONGO_ROOM_LOWER_CRATE_3, + RAND_INF_WATER_TEMPLE_MQ_DODONGO_ROOM_LOWER_CRATE_3, + }, + { + RC_WATER_TEMPLE_MQ_STORAGE_ROOM_B_CRATE_1, + RAND_INF_WATER_TEMPLE_MQ_STORAGE_ROOM_B_CRATE_1, + }, + { + RC_WATER_TEMPLE_MQ_STORAGE_ROOM_B_CRATE_2, + RAND_INF_WATER_TEMPLE_MQ_STORAGE_ROOM_B_CRATE_2, + }, + { + RC_WATER_TEMPLE_MQ_STORAGE_ROOM_B_CRATE_3, + RAND_INF_WATER_TEMPLE_MQ_STORAGE_ROOM_B_CRATE_3, + }, + { + RC_WATER_TEMPLE_MQ_STORAGE_ROOM_B_CRATE_4, + RAND_INF_WATER_TEMPLE_MQ_STORAGE_ROOM_B_CRATE_4, + }, + { + RC_WATER_TEMPLE_MQ_STORAGE_ROOM_B_CRATE_5, + RAND_INF_WATER_TEMPLE_MQ_STORAGE_ROOM_B_CRATE_5, + }, + { + RC_WATER_TEMPLE_MQ_TRIPLE_TORCH_ROOM_SUBMERGED_CRATE_1, + RAND_INF_WATER_TEMPLE_MQ_TRIPLE_TORCH_ROOM_SUBMERGED_CRATE_1, + }, + { + RC_WATER_TEMPLE_MQ_TRIPLE_TORCH_ROOM_SUBMERGED_CRATE_2, + RAND_INF_WATER_TEMPLE_MQ_TRIPLE_TORCH_ROOM_SUBMERGED_CRATE_2, + }, + { + RC_WATER_TEMPLE_MQ_TRIPLE_TORCH_ROOM_SUBMERGED_CRATE_3, + RAND_INF_WATER_TEMPLE_MQ_TRIPLE_TORCH_ROOM_SUBMERGED_CRATE_3, + }, + { + RC_WATER_TEMPLE_MQ_TRIPLE_TORCH_ROOM_SUBMERGED_CRATE_4, + RAND_INF_WATER_TEMPLE_MQ_TRIPLE_TORCH_ROOM_SUBMERGED_CRATE_4, + }, + { + RC_WATER_TEMPLE_MQ_TRIPLE_TORCH_ROOM_SUBMERGED_CRATE_5, + RAND_INF_WATER_TEMPLE_MQ_TRIPLE_TORCH_ROOM_SUBMERGED_CRATE_5, + }, + { + RC_WATER_TEMPLE_MQ_TRIPLE_TORCH_ROOM_SUBMERGED_CRATE_6, + RAND_INF_WATER_TEMPLE_MQ_TRIPLE_TORCH_ROOM_SUBMERGED_CRATE_6, + }, + { + RC_WATER_TEMPLE_MQ_TRIPLE_TORCH_ROOM_GATE_CRATE_1, + RAND_INF_WATER_TEMPLE_MQ_TRIPLE_TORCH_ROOM_GATE_CRATE_1, + }, + { + RC_WATER_TEMPLE_MQ_TRIPLE_TORCH_ROOM_GATE_CRATE_2, + RAND_INF_WATER_TEMPLE_MQ_TRIPLE_TORCH_ROOM_GATE_CRATE_2, + }, + { + RC_WATER_TEMPLE_MQ_TRIPLE_TORCH_ROOM_GATE_CRATE_3, + RAND_INF_WATER_TEMPLE_MQ_TRIPLE_TORCH_ROOM_GATE_CRATE_3, + }, + { + RC_SPIRIT_TEMPLE_MQ_STATUE_CRATE_1, + RAND_INF_SPIRIT_TEMPLE_MQ_STATUE_CRATE_1, + }, + { + RC_SPIRIT_TEMPLE_MQ_STATUE_CRATE_2, + RAND_INF_SPIRIT_TEMPLE_MQ_STATUE_CRATE_2, + }, + { + RC_SPIRIT_TEMPLE_MQ_BIG_MIRROR_CRATE_1, + RAND_INF_SPIRIT_TEMPLE_MQ_BIG_MIRROR_CRATE_1, + }, + { + RC_SPIRIT_TEMPLE_MQ_BIG_MIRROR_CRATE_2, + RAND_INF_SPIRIT_TEMPLE_MQ_BIG_MIRROR_CRATE_2, + }, + { + RC_SPIRIT_TEMPLE_MQ_BIG_MIRROR_CRATE_3, + RAND_INF_SPIRIT_TEMPLE_MQ_BIG_MIRROR_CRATE_3, + }, + { + RC_SPIRIT_TEMPLE_MQ_BIG_MIRROR_CRATE_4, + RAND_INF_SPIRIT_TEMPLE_MQ_BIG_MIRROR_CRATE_4, + }, + { + RC_GERUDO_TRAINING_GROUND_MQ_MAZE_CRATE, + RAND_INF_GERUDO_TRAINING_GROUND_MQ_MAZE_CRATE, + }, - { RC_JABU_JABUS_BELLY_PLATFORM_ROOM_SMALL_CRATE_1, RAND_INF_JABU_JABUS_BELLY_PLATFORM_ROOM_SMALL_CRATE_1, }, - { RC_JABU_JABUS_BELLY_PLATFORM_ROOM_SMALL_CRATE_2, RAND_INF_JABU_JABUS_BELLY_PLATFORM_ROOM_SMALL_CRATE_2, }, - { RC_FIRE_TEMPLE_AFTER_HAMMER_SMALL_CRATE_1, RAND_INF_FIRE_TEMPLE_AFTER_HAMMER_SMALL_CRATE_1, }, - { RC_FIRE_TEMPLE_AFTER_HAMMER_SMALL_CRATE_2, RAND_INF_FIRE_TEMPLE_AFTER_HAMMER_SMALL_CRATE_2, }, - { RC_SPIRIT_TEMPLE_BEFORE_CHILD_CLIMB_SMALL_CRATE_1, RAND_INF_SPIRIT_TEMPLE_BEFORE_CHILD_CLIMB_SMALL_CRATE_1, }, - { RC_SPIRIT_TEMPLE_BEFORE_CHILD_CLIMB_SMALL_CRATE_2, RAND_INF_SPIRIT_TEMPLE_BEFORE_CHILD_CLIMB_SMALL_CRATE_2, }, + { + RC_JABU_JABUS_BELLY_PLATFORM_ROOM_SMALL_CRATE_1, + RAND_INF_JABU_JABUS_BELLY_PLATFORM_ROOM_SMALL_CRATE_1, + }, + { + RC_JABU_JABUS_BELLY_PLATFORM_ROOM_SMALL_CRATE_2, + RAND_INF_JABU_JABUS_BELLY_PLATFORM_ROOM_SMALL_CRATE_2, + }, + { + RC_FIRE_TEMPLE_AFTER_HAMMER_SMALL_CRATE_1, + RAND_INF_FIRE_TEMPLE_AFTER_HAMMER_SMALL_CRATE_1, + }, + { + RC_FIRE_TEMPLE_AFTER_HAMMER_SMALL_CRATE_2, + RAND_INF_FIRE_TEMPLE_AFTER_HAMMER_SMALL_CRATE_2, + }, + { + RC_SPIRIT_TEMPLE_BEFORE_CHILD_CLIMB_SMALL_CRATE_1, + RAND_INF_SPIRIT_TEMPLE_BEFORE_CHILD_CLIMB_SMALL_CRATE_1, + }, + { + RC_SPIRIT_TEMPLE_BEFORE_CHILD_CLIMB_SMALL_CRATE_2, + RAND_INF_SPIRIT_TEMPLE_BEFORE_CHILD_CLIMB_SMALL_CRATE_2, + }, - { RC_JABU_JABUS_BELLY_MQ_TRIPLE_HALLWAY_SMALL_CRATE_1, RAND_INF_JABU_JABUS_BELLY_MQ_TRIPLE_HALLWAY_SMALL_CRATE_1, }, - { RC_JABU_JABUS_BELLY_MQ_TRIPLE_HALLWAY_SMALL_CRATE_2, RAND_INF_JABU_JABUS_BELLY_MQ_TRIPLE_HALLWAY_SMALL_CRATE_2, }, - { RC_FOREST_TEMPLE_MQ_FROZEN_EYE_SWITCH_SMALL_CRATE_1, RAND_INF_FOREST_TEMPLE_MQ_FROZEN_EYE_SWITCH_SMALL_CRATE_1, }, - { RC_FOREST_TEMPLE_MQ_FROZEN_EYE_SWITCH_SMALL_CRATE_2, RAND_INF_FOREST_TEMPLE_MQ_FROZEN_EYE_SWITCH_SMALL_CRATE_2, }, - { RC_FOREST_TEMPLE_MQ_FROZEN_EYE_SWITCH_SMALL_CRATE_3, RAND_INF_FOREST_TEMPLE_MQ_FROZEN_EYE_SWITCH_SMALL_CRATE_3, }, - { RC_FIRE_TEMPLE_MQ_LIZALFOS_MAZE_UPPER_SMALL_CRATE_1, RAND_INF_FIRE_TEMPLE_MQ_LIZALFOS_MAZE_UPPER_SMALL_CRATE_1, }, - { RC_FIRE_TEMPLE_MQ_LIZALFOS_MAZE_UPPER_SMALL_CRATE_2, RAND_INF_FIRE_TEMPLE_MQ_LIZALFOS_MAZE_UPPER_SMALL_CRATE_2, }, - { RC_FIRE_TEMPLE_MQ_LAVA_TORCH_SMALL_CRATE_1, RAND_INF_FIRE_TEMPLE_MQ_LAVA_TORCH_SMALL_CRATE_1, }, - { RC_FIRE_TEMPLE_MQ_LAVA_TORCH_SMALL_CRATE_2, RAND_INF_FIRE_TEMPLE_MQ_LAVA_TORCH_SMALL_CRATE_2, }, - { RC_FIRE_TEMPLE_MQ_LAVA_TORCH_SMALL_CRATE_3, RAND_INF_FIRE_TEMPLE_MQ_LAVA_TORCH_SMALL_CRATE_3, }, - { RC_FIRE_TEMPLE_MQ_LAVA_TORCH_SMALL_CRATE_4, RAND_INF_FIRE_TEMPLE_MQ_LAVA_TORCH_SMALL_CRATE_4, }, - { RC_FIRE_TEMPLE_MQ_LAVA_TORCH_SMALL_CRATE_5, RAND_INF_FIRE_TEMPLE_MQ_LAVA_TORCH_SMALL_CRATE_5, }, - { RC_WATER_TEMPLE_MQ_DRAGON_ROOM_TORCHES_SMALL_CRATE_1, RAND_INF_WATER_TEMPLE_MQ_DRAGON_ROOM_TORCHES_SMALL_CRATE_1, }, - { RC_WATER_TEMPLE_MQ_DRAGON_ROOM_TORCHES_SMALL_CRATE_2, RAND_INF_WATER_TEMPLE_MQ_DRAGON_ROOM_TORCHES_SMALL_CRATE_2, }, - { RC_WATER_TEMPLE_MQ_DRAGON_ROOM_TORCHES_SMALL_CRATE_3, RAND_INF_WATER_TEMPLE_MQ_DRAGON_ROOM_TORCHES_SMALL_CRATE_3, }, - { RC_WATER_TEMPLE_MQ_STORAGE_ROOM_A_SMALL_CRATE_1, RAND_INF_WATER_TEMPLE_MQ_STORAGE_ROOM_A_SMALL_CRATE_1, }, - { RC_WATER_TEMPLE_MQ_STORAGE_ROOM_A_SMALL_CRATE_2, RAND_INF_WATER_TEMPLE_MQ_STORAGE_ROOM_A_SMALL_CRATE_2, }, - { RC_WATER_TEMPLE_MQ_STORAGE_ROOM_A_SMALL_CRATE_3, RAND_INF_WATER_TEMPLE_MQ_STORAGE_ROOM_A_SMALL_CRATE_3, }, - { RC_WATER_TEMPLE_MQ_STORAGE_ROOM_A_SMALL_CRATE_4, RAND_INF_WATER_TEMPLE_MQ_STORAGE_ROOM_A_SMALL_CRATE_4, }, - { RC_WATER_TEMPLE_MQ_GS_STORAGE_ROOM_LOWER_SMALL_CRATE, RAND_INF_WATER_TEMPLE_MQ_GS_STORAGE_ROOM_LOWER_SMALL_CRATE, }, - { RC_WATER_TEMPLE_MQ_GS_STORAGE_ROOM_UPPER_SMALL_CRATE, RAND_INF_WATER_TEMPLE_MQ_GS_STORAGE_ROOM_UPPER_SMALL_CRATE, }, - { RC_SHADOW_TEMPLE_MQ_TRUTH_SPINNER_SMALL_CRATE_1, RAND_INF_SHADOW_TEMPLE_MQ_TRUTH_SPINNER_SMALL_CRATE_1, }, - { RC_SHADOW_TEMPLE_MQ_TRUTH_SPINNER_SMALL_CRATE_2, RAND_INF_SHADOW_TEMPLE_MQ_TRUTH_SPINNER_SMALL_CRATE_2, }, - { RC_SHADOW_TEMPLE_MQ_TRUTH_SPINNER_SMALL_CRATE_3, RAND_INF_SHADOW_TEMPLE_MQ_TRUTH_SPINNER_SMALL_CRATE_3, }, - { RC_SHADOW_TEMPLE_MQ_TRUTH_SPINNER_SMALL_CRATE_4, RAND_INF_SHADOW_TEMPLE_MQ_TRUTH_SPINNER_SMALL_CRATE_4, }, - { RC_SPIRIT_TEMPLE_MQ_STATUE_SMALL_CRATE, RAND_INF_SPIRIT_TEMPLE_MQ_STATUE_SMALL_CRATE, }, - { RC_SPIRIT_TEMPLE_MQ_BEAMOS_SMALL_CRATE, RAND_INF_SPIRIT_TEMPLE_MQ_BEAMOS_SMALL_CRATE, }, + { + RC_JABU_JABUS_BELLY_MQ_TRIPLE_HALLWAY_SMALL_CRATE_1, + RAND_INF_JABU_JABUS_BELLY_MQ_TRIPLE_HALLWAY_SMALL_CRATE_1, + }, + { + RC_JABU_JABUS_BELLY_MQ_TRIPLE_HALLWAY_SMALL_CRATE_2, + RAND_INF_JABU_JABUS_BELLY_MQ_TRIPLE_HALLWAY_SMALL_CRATE_2, + }, + { + RC_FOREST_TEMPLE_MQ_FROZEN_EYE_SWITCH_SMALL_CRATE_1, + RAND_INF_FOREST_TEMPLE_MQ_FROZEN_EYE_SWITCH_SMALL_CRATE_1, + }, + { + RC_FOREST_TEMPLE_MQ_FROZEN_EYE_SWITCH_SMALL_CRATE_2, + RAND_INF_FOREST_TEMPLE_MQ_FROZEN_EYE_SWITCH_SMALL_CRATE_2, + }, + { + RC_FOREST_TEMPLE_MQ_FROZEN_EYE_SWITCH_SMALL_CRATE_3, + RAND_INF_FOREST_TEMPLE_MQ_FROZEN_EYE_SWITCH_SMALL_CRATE_3, + }, + { + RC_FIRE_TEMPLE_MQ_LIZALFOS_MAZE_UPPER_SMALL_CRATE_1, + RAND_INF_FIRE_TEMPLE_MQ_LIZALFOS_MAZE_UPPER_SMALL_CRATE_1, + }, + { + RC_FIRE_TEMPLE_MQ_LIZALFOS_MAZE_UPPER_SMALL_CRATE_2, + RAND_INF_FIRE_TEMPLE_MQ_LIZALFOS_MAZE_UPPER_SMALL_CRATE_2, + }, + { + RC_FIRE_TEMPLE_MQ_LAVA_TORCH_SMALL_CRATE_1, + RAND_INF_FIRE_TEMPLE_MQ_LAVA_TORCH_SMALL_CRATE_1, + }, + { + RC_FIRE_TEMPLE_MQ_LAVA_TORCH_SMALL_CRATE_2, + RAND_INF_FIRE_TEMPLE_MQ_LAVA_TORCH_SMALL_CRATE_2, + }, + { + RC_FIRE_TEMPLE_MQ_LAVA_TORCH_SMALL_CRATE_3, + RAND_INF_FIRE_TEMPLE_MQ_LAVA_TORCH_SMALL_CRATE_3, + }, + { + RC_FIRE_TEMPLE_MQ_LAVA_TORCH_SMALL_CRATE_4, + RAND_INF_FIRE_TEMPLE_MQ_LAVA_TORCH_SMALL_CRATE_4, + }, + { + RC_FIRE_TEMPLE_MQ_LAVA_TORCH_SMALL_CRATE_5, + RAND_INF_FIRE_TEMPLE_MQ_LAVA_TORCH_SMALL_CRATE_5, + }, + { + RC_WATER_TEMPLE_MQ_DRAGON_ROOM_TORCHES_SMALL_CRATE_1, + RAND_INF_WATER_TEMPLE_MQ_DRAGON_ROOM_TORCHES_SMALL_CRATE_1, + }, + { + RC_WATER_TEMPLE_MQ_DRAGON_ROOM_TORCHES_SMALL_CRATE_2, + RAND_INF_WATER_TEMPLE_MQ_DRAGON_ROOM_TORCHES_SMALL_CRATE_2, + }, + { + RC_WATER_TEMPLE_MQ_DRAGON_ROOM_TORCHES_SMALL_CRATE_3, + RAND_INF_WATER_TEMPLE_MQ_DRAGON_ROOM_TORCHES_SMALL_CRATE_3, + }, + { + RC_WATER_TEMPLE_MQ_STORAGE_ROOM_A_SMALL_CRATE_1, + RAND_INF_WATER_TEMPLE_MQ_STORAGE_ROOM_A_SMALL_CRATE_1, + }, + { + RC_WATER_TEMPLE_MQ_STORAGE_ROOM_A_SMALL_CRATE_2, + RAND_INF_WATER_TEMPLE_MQ_STORAGE_ROOM_A_SMALL_CRATE_2, + }, + { + RC_WATER_TEMPLE_MQ_STORAGE_ROOM_A_SMALL_CRATE_3, + RAND_INF_WATER_TEMPLE_MQ_STORAGE_ROOM_A_SMALL_CRATE_3, + }, + { + RC_WATER_TEMPLE_MQ_STORAGE_ROOM_A_SMALL_CRATE_4, + RAND_INF_WATER_TEMPLE_MQ_STORAGE_ROOM_A_SMALL_CRATE_4, + }, + { + RC_WATER_TEMPLE_MQ_GS_STORAGE_ROOM_LOWER_SMALL_CRATE, + RAND_INF_WATER_TEMPLE_MQ_GS_STORAGE_ROOM_LOWER_SMALL_CRATE, + }, + { + RC_WATER_TEMPLE_MQ_GS_STORAGE_ROOM_UPPER_SMALL_CRATE, + RAND_INF_WATER_TEMPLE_MQ_GS_STORAGE_ROOM_UPPER_SMALL_CRATE, + }, + { + RC_SHADOW_TEMPLE_MQ_TRUTH_SPINNER_SMALL_CRATE_1, + RAND_INF_SHADOW_TEMPLE_MQ_TRUTH_SPINNER_SMALL_CRATE_1, + }, + { + RC_SHADOW_TEMPLE_MQ_TRUTH_SPINNER_SMALL_CRATE_2, + RAND_INF_SHADOW_TEMPLE_MQ_TRUTH_SPINNER_SMALL_CRATE_2, + }, + { + RC_SHADOW_TEMPLE_MQ_TRUTH_SPINNER_SMALL_CRATE_3, + RAND_INF_SHADOW_TEMPLE_MQ_TRUTH_SPINNER_SMALL_CRATE_3, + }, + { + RC_SHADOW_TEMPLE_MQ_TRUTH_SPINNER_SMALL_CRATE_4, + RAND_INF_SHADOW_TEMPLE_MQ_TRUTH_SPINNER_SMALL_CRATE_4, + }, + { + RC_SPIRIT_TEMPLE_MQ_STATUE_SMALL_CRATE, + RAND_INF_SPIRIT_TEMPLE_MQ_STATUE_SMALL_CRATE, + }, + { + RC_SPIRIT_TEMPLE_MQ_BEAMOS_SMALL_CRATE, + RAND_INF_SPIRIT_TEMPLE_MQ_BEAMOS_SMALL_CRATE, + }, }; BeehiveIdentity Randomizer::IdentifyBeehive(s32 sceneNum, s16 xPosition, s32 respawnData) { @@ -2182,9 +3136,10 @@ Rando::Location* Randomizer::GetCheckObjectFromActor(s16 actorId, s16 sceneNum, 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) { + switch (sceneNum) { case SCENE_TREASURE_BOX_SHOP: { - if ((actorId == ACTOR_EN_BOX && actorParams == 20170) || (actorId == ACTOR_ITEM_ETCETERA && actorParams == 2572)) { + if ((actorId == ACTOR_EN_BOX && actorParams == 20170) || + (actorId == ACTOR_ITEM_ETCETERA && actorParams == 2572)) { specialRc = RC_MARKET_TREASURE_CHEST_GAME_REWARD; } @@ -2231,11 +3186,21 @@ Rando::Location* Randomizer::GetCheckObjectFromActor(s16 actorId, s16 sceneNum, case SCENE_HOUSE_OF_SKULLTULA: if (actorId == ACTOR_EN_SSH) { switch (actorParams) { // actor params are used to differentiate between textboxes - case 1: specialRc = RC_KAK_10_GOLD_SKULLTULA_REWARD; break; - case 2: specialRc = RC_KAK_20_GOLD_SKULLTULA_REWARD; break; - case 3: specialRc = RC_KAK_30_GOLD_SKULLTULA_REWARD; break; - case 4: specialRc = RC_KAK_40_GOLD_SKULLTULA_REWARD; break; - case 5: specialRc = RC_KAK_50_GOLD_SKULLTULA_REWARD; break; + case 1: + specialRc = RC_KAK_10_GOLD_SKULLTULA_REWARD; + break; + case 2: + specialRc = RC_KAK_20_GOLD_SKULLTULA_REWARD; + break; + case 3: + specialRc = RC_KAK_30_GOLD_SKULLTULA_REWARD; + break; + case 4: + specialRc = RC_KAK_40_GOLD_SKULLTULA_REWARD; + break; + case 5: + specialRc = RC_KAK_50_GOLD_SKULLTULA_REWARD; + break; } } break; @@ -2293,11 +3258,10 @@ Rando::Location* Randomizer::GetCheckObjectFromActor(s16 actorId, s16 sceneNum, auto range = Rando::StaticData::CheckFromActorMultimap.equal_range(std::make_tuple(actorId, sceneNum, actorParams)); for (auto it = range.first; it != range.second; ++it) { - if ( - Rando::StaticData::GetLocation(it->second)->GetQuest() == RCQUEST_BOTH || - (Rando::StaticData::GetLocation(it->second)->GetQuest() == RCQUEST_VANILLA && !ResourceMgr_IsGameMasterQuest()) || - (Rando::StaticData::GetLocation(it->second)->GetQuest() == RCQUEST_MQ && ResourceMgr_IsGameMasterQuest()) - ) { + if (Rando::StaticData::GetLocation(it->second)->GetQuest() == RCQUEST_BOTH || + (Rando::StaticData::GetLocation(it->second)->GetQuest() == RCQUEST_VANILLA && + !ResourceMgr_IsGameMasterQuest()) || + (Rando::StaticData::GetLocation(it->second)->GetQuest() == RCQUEST_MQ && ResourceMgr_IsGameMasterQuest())) { return Rando::StaticData::GetLocation(it->second); } } @@ -2315,7 +3279,8 @@ ScrubIdentity Randomizer::IdentifyScrub(s32 sceneNum, s32 actorParams, s32 respa scrubIdentity.isShuffled = false; // Scrubs that are 0x06 are loaded as 0x03 when child, switching from selling arrows to seeds - if (actorParams == 0x06) actorParams = 0x03; + if (actorParams == 0x06) + actorParams = 0x03; if (sceneNum == SCENE_GROTTOS) { actorParams = TWO_ACTOR_PARAMS(actorParams, respawnData); @@ -2329,11 +3294,14 @@ ScrubIdentity Randomizer::IdentifyScrub(s32 sceneNum, s32 actorParams, s32 respa scrubIdentity.getItemId = (GetItemID)Rando::StaticData::RetrieveItem(location->GetVanillaItem()).GetItemID(); scrubIdentity.isShuffled = GetRandoSettingValue(RSK_SHUFFLE_SCRUBS) == RO_SCRUBS_ALL; - if (location->GetRandomizerCheck() == RC_HF_DEKU_SCRUB_GROTTO || location->GetRandomizerCheck() == RC_LW_DEKU_SCRUB_GROTTO_FRONT || location->GetRandomizerCheck() == RC_LW_DEKU_SCRUB_NEAR_BRIDGE) { + if (location->GetRandomizerCheck() == RC_HF_DEKU_SCRUB_GROTTO || + location->GetRandomizerCheck() == RC_LW_DEKU_SCRUB_GROTTO_FRONT || + location->GetRandomizerCheck() == RC_LW_DEKU_SCRUB_NEAR_BRIDGE) { scrubIdentity.isShuffled = GetRandoSettingValue(RSK_SHUFFLE_SCRUBS) != RO_SCRUBS_OFF; } - scrubIdentity.itemPrice = OTRGlobals::Instance->gRandoContext->GetItemLocation(scrubIdentity.randomizerCheck)->GetPrice(); + scrubIdentity.itemPrice = + OTRGlobals::Instance->gRandoContext->GetItemLocation(scrubIdentity.randomizerCheck)->GetPrice(); } return scrubIdentity; @@ -2352,9 +3320,11 @@ ShopItemIdentity Randomizer::IdentifyShopItem(s32 sceneNum, u8 slotIndex) { return shopItemIdentity; } - Rando::Location* location = GetCheckObjectFromActor(ACTOR_EN_GIRLA, + Rando::Location* location = GetCheckObjectFromActor( + ACTOR_EN_GIRLA, // Bazaar (SHOP1) scene is reused, so if entering from Kak use debug scene to identify - (sceneNum == SCENE_BAZAAR && gSaveContext.entranceIndex == ENTR_BAZAAR_0) ? SCENE_TEST01 : sceneNum, slotIndex - 1); + (sceneNum == SCENE_BAZAAR && gSaveContext.entranceIndex == ENTR_BAZAAR_0) ? SCENE_TEST01 : sceneNum, + slotIndex - 1); if (location->GetRandomizerCheck() != RC_UNKNOWN_CHECK) { shopItemIdentity.randomizerInf = rcToRandomizerInf[location->GetRandomizerCheck()]; @@ -2367,7 +3337,8 @@ ShopItemIdentity Randomizer::IdentifyShopItem(s32 sceneNum, u8 slotIndex) { shopItemIdentity.enGirlAShopItem = randomizerGetToEnGirlShopItem[randoGet]; } - shopItemIdentity.itemPrice = OTRGlobals::Instance->gRandoContext->GetItemLocation(shopItemIdentity.randomizerCheck)->GetPrice(); + shopItemIdentity.itemPrice = + OTRGlobals::Instance->gRandoContext->GetItemLocation(shopItemIdentity.randomizerCheck)->GetPrice(); } return shopItemIdentity; @@ -2501,7 +3472,6 @@ GrassIdentity Randomizer::IdentifyGrass(s32 sceneNum, s32 posX, s32 posZ, s32 re } return grassIdentity; - } CrateIdentity Randomizer::IdentifyCrate(s32 sceneNum, s32 posX, s32 posZ) { @@ -2512,11 +3482,11 @@ CrateIdentity Randomizer::IdentifyCrate(s32 sceneNum, s32 posX, s32 posZ) { if (sceneNum == SCENE_MARKET_NIGHT) { crateSceneNum = SCENE_MARKET_DAY; } else if (sceneNum == SCENE_GERUDOS_FORTRESS && gPlayState->linkAgeOnLoad == 1 && posX == 310) { - if (posZ == -1830) { - posZ = -1842.0f; - } else if (posZ == -1770) { - posZ = -1782.0f; - } + if (posZ == -1830) { + posZ = -1842.0f; + } else if (posZ == -1770) { + posZ = -1782.0f; + } } crateIdentity.randomizerInf = RAND_INF_MAX; @@ -2563,7 +3533,8 @@ u8 Randomizer::GetRandoSettingValue(RandomizerSettingKey randoSettingKey) { return Rando::Context::GetInstance()->GetOption(randoSettingKey).Get(); } -GetItemEntry Randomizer::GetItemFromKnownCheck(RandomizerCheck randomizerCheck, GetItemID ogItemId, bool checkObtainability) { +GetItemEntry Randomizer::GetItemFromKnownCheck(RandomizerCheck randomizerCheck, GetItemID ogItemId, + bool checkObtainability) { return Rando::Context::GetInstance()->GetFinalGIEntry(randomizerCheck, checkObtainability); } @@ -2575,13 +3546,14 @@ RandomizerInf Randomizer::GetRandomizerInfFromCheck(RandomizerCheck rc) { auto rcIt = rcToRandomizerInf.find(rc); if (rcIt == rcToRandomizerInf.end()) return RAND_INF_MAX; - + return rcIt->second; } RandomizerCheck Randomizer::GetCheckFromRandomizerInf(RandomizerInf randomizerInf) { for (auto const& [key, value] : rcToRandomizerInf) { - if (value == randomizerInf) return key; + if (value == randomizerInf) + return key; } return RC_UNKNOWN_CHECK; @@ -2593,9 +3565,9 @@ void GenerateRandomizerImgui(std::string seed = "") { CVarSetInteger(CVAR_GENERAL("RandoGenerating"), 1); CVarSave(); auto ctx = Rando::Context::GetInstance(); - //RANDOTODO proper UI for selecting if a spoiler loaded should be used for settings + // RANDOTODO proper UI for selecting if a spoiler loaded should be used for settings Rando::Settings::GetInstance()->SetAllToContext(); - + // todo: this efficently when we build out cvar array support std::set excludedLocations; std::stringstream excludedLocationStringStream(CVarGetString(CVAR_RANDOMIZER_SETTING("ExcludedLocations"), "")); @@ -2605,14 +3577,13 @@ void GenerateRandomizerImgui(std::string seed = "") { } // todo: better way to sort out linking tricks rather than name - + std::set enabledTricks; std::stringstream enabledTrickStringStream(CVarGetString(CVAR_RANDOMIZER_SETTING("EnabledTricks"), "")); std::string enabledTrickString; while (getline(enabledTrickStringStream, enabledTrickString, ',')) { enabledTricks.insert((RandomizerTrick)std::stoi(enabledTrickString)); } - // Update the visibilitiy before removing conflicting excludes (in case the locations tab wasn't viewed) RandomizerCheckObjects::UpdateImGuiVisibility(); @@ -2662,32 +3633,36 @@ void RandomizerSettingsWindow::DrawElement() { } static bool locationsTabOpen = false; static bool tricksTabOpen = false; - bool disableEditingRandoSettings = CVarGetInteger(CVAR_GENERAL("RandoGenerating"), 0) || CVarGetInteger(CVAR_GENERAL("OnFileSelectNameEntry"), 0); + bool disableEditingRandoSettings = + CVarGetInteger(CVAR_GENERAL("RandoGenerating"), 0) || CVarGetInteger(CVAR_GENERAL("OnFileSelectNameEntry"), 0); ImGui::BeginDisabled(CVarGetInteger(CVAR_SETTING("DisableChanges"), 0) || disableEditingRandoSettings); const PresetTypeDefinition presetTypeDef = presetTypes.at(PRESET_TYPE_RANDOMIZER); std::string comboboxTooltip = ""; for (auto iter = presetTypeDef.presets.begin(); iter != presetTypeDef.presets.end(); ++iter) { - if (iter->first != 0) comboboxTooltip += "\n\n"; + if (iter->first != 0) + comboboxTooltip += "\n\n"; comboboxTooltip += std::string(iter->second.label) + " - " + std::string(iter->second.description); } const std::string presetTypeCvar = CVAR_GENERAL("SelectedPresets.") + std::to_string(PRESET_TYPE_RANDOMIZER); randomizerPresetSelected = CVarGetInteger(presetTypeCvar.c_str(), RANDOMIZER_PRESET_DEFAULT); - if (UIWidgets::Combobox("Randomizer Presets", &randomizerPresetSelected, randomizerPresetList, UIWidgets::ComboboxOptions() - .DefaultIndex(RANDOMIZER_PRESET_DEFAULT) - .Tooltip(comboboxTooltip.c_str()) - .Color(THEME_COLOR)) - ) { + if (UIWidgets::Combobox("Randomizer Presets", &randomizerPresetSelected, randomizerPresetList, + UIWidgets::ComboboxOptions() + .DefaultIndex(RANDOMIZER_PRESET_DEFAULT) + .Tooltip(comboboxTooltip.c_str()) + .Color(THEME_COLOR))) { CVarSetInteger(presetTypeCvar.c_str(), randomizerPresetSelected); } ImGui::SameLine(); ImGui::SetCursorPosY(ImGui::GetCursorPos().y + 35.f); - if (UIWidgets::Button("Apply Preset##Randomizer", UIWidgets::ButtonOptions().Color(THEME_COLOR).Size(UIWidgets::Sizes::Inline).Padding(ImVec2(10.f, 6.f)))) { + if (UIWidgets::Button( + "Apply Preset##Randomizer", + UIWidgets::ButtonOptions().Color(THEME_COLOR).Size(UIWidgets::Sizes::Inline).Padding(ImVec2(10.f, 6.f)))) { if (randomizerPresetSelected >= presetTypeDef.presets.size()) { randomizerPresetSelected = 0; } const PresetDefinition selectedPresetDef = presetTypeDef.presets.at(randomizerPresetSelected); - for(const char* block : presetTypeDef.blocksToClear) { + for (const char* block : presetTypeDef.blocksToClear) { CVarClearBlock(block); } if (randomizerPresetSelected != 0) { @@ -2702,22 +3677,29 @@ void RandomizerSettingsWindow::DrawElement() { } UIWidgets::Spacer(0); - UIWidgets::CVarCheckbox("Manual seed entry", CVAR_RANDOMIZER_SETTING("ManualSeedEntry"), UIWidgets::CheckboxOptions().Color(THEME_COLOR)); + UIWidgets::CVarCheckbox("Manual seed entry", CVAR_RANDOMIZER_SETTING("ManualSeedEntry"), + UIWidgets::CheckboxOptions().Color(THEME_COLOR)); if (CVarGetInteger(CVAR_RANDOMIZER_SETTING("ManualSeedEntry"), 0)) { UIWidgets::PushStyleInput(THEME_COLOR); - ImGui::InputText("##RandomizerSeed", seedString, MAX_SEED_STRING_SIZE, ImGuiInputTextFlags_CallbackCharFilter, UIWidgets::TextFilters::FilterAlphaNum); - UIWidgets::Tooltip( - "Characters from a-z, A-Z, and 0-9 are supported.\n" - "Character limit is 1023, after which the seed will be truncated.\n" - ); + ImGui::InputText("##RandomizerSeed", seedString, MAX_SEED_STRING_SIZE, ImGuiInputTextFlags_CallbackCharFilter, + UIWidgets::TextFilters::FilterAlphaNum); + UIWidgets::Tooltip("Characters from a-z, A-Z, and 0-9 are supported.\n" + "Character limit is 1023, after which the seed will be truncated.\n"); ImGui::SameLine(); - if (UIWidgets::Button(ICON_FA_RANDOM, UIWidgets::ButtonOptions().Size(UIWidgets::Sizes::Inline).Color(THEME_COLOR).Padding(ImVec2(10.f, 6.f)).Tooltip( - "Creates a new random seed value to be used when generating a randomizer" - ))) { + if (UIWidgets::Button( + ICON_FA_RANDOM, + UIWidgets::ButtonOptions() + .Size(UIWidgets::Sizes::Inline) + .Color(THEME_COLOR) + .Padding(ImVec2(10.f, 6.f)) + .Tooltip("Creates a new random seed value to be used when generating a randomizer"))) { SohUtils::CopyStringToCharArray(seedString, std::to_string(rand() & 0xFFFFFFFF), MAX_SEED_STRING_SIZE); } ImGui::SameLine(); - if (UIWidgets::Button(ICON_FA_ERASER, UIWidgets::ButtonOptions().Size(UIWidgets::Sizes::Inline).Color(THEME_COLOR).Padding(ImVec2(10.f, 6.f)))) { + if (UIWidgets::Button(ICON_FA_ERASER, UIWidgets::ButtonOptions() + .Size(UIWidgets::Sizes::Inline) + .Color(THEME_COLOR) + .Padding(ImVec2(10.f, 6.f)))) { memset(seedString, 0, MAX_SEED_STRING_SIZE); } if (strnlen(seedString, MAX_SEED_STRING_SIZE) == 0) { @@ -2728,9 +3710,11 @@ void RandomizerSettingsWindow::DrawElement() { } UIWidgets::Spacer(0); - ImGui::BeginDisabled((CVarGetInteger(CVAR_RANDOMIZER_SETTING("DontGenerateSpoiler"), 0) && gSaveContext.gameMode != GAMEMODE_FILE_SELECT) || - GameInteractor::IsSaveLoaded()); - if (UIWidgets::Button("Generate Randomizer", UIWidgets::ButtonOptions().Size(ImVec2(250.f, 0.f)).Color(THEME_COLOR))) { + ImGui::BeginDisabled((CVarGetInteger(CVAR_RANDOMIZER_SETTING("DontGenerateSpoiler"), 0) && + gSaveContext.gameMode != GAMEMODE_FILE_SELECT) || + GameInteractor::IsSaveLoaded()); + if (UIWidgets::Button("Generate Randomizer", + UIWidgets::ButtonOptions().Size(ImVec2(250.f, 0.f)).Color(THEME_COLOR))) { ctx->SetSpoilerLoaded(false); GenerateRandomizer(CVarGetInteger(CVAR_RANDOMIZER_SETTING("ManualSeedEntry"), 0) ? seedString : ""); } @@ -2763,10 +3747,12 @@ void RandomizerSettingsWindow::DrawElement() { ImGui::EndTabItem(); } - ImGui::BeginDisabled(CVarGetInteger(CVAR_RANDOMIZER_SETTING("LogicRules"), RO_LOGIC_GLITCHLESS) == RO_LOGIC_VANILLA); + ImGui::BeginDisabled(CVarGetInteger(CVAR_RANDOMIZER_SETTING("LogicRules"), RO_LOGIC_GLITCHLESS) == + RO_LOGIC_VANILLA); if (ImGui::BeginTabItem("Items")) { ImGui::PushStyleVar(ImGuiStyleVar_CellPadding, cellPadding); - ImGui::BeginDisabled(CVarGetInteger(CVAR_RANDOMIZER_SETTING("LogicRules"), RO_LOGIC_GLITCHLESS) == RO_LOGIC_VANILLA); + ImGui::BeginDisabled(CVarGetInteger(CVAR_RANDOMIZER_SETTING("LogicRules"), RO_LOGIC_GLITCHLESS) == + RO_LOGIC_VANILLA); if (mSettings->GetOptionGroup(RSG_ITEMS_IMGUI_TABLE).RenderImGui()) { mNeedsUpdate = true; } @@ -2776,7 +3762,8 @@ void RandomizerSettingsWindow::DrawElement() { } ImGui::EndDisabled(); - ImGui::BeginDisabled(CVarGetInteger(CVAR_RANDOMIZER_SETTING("LogicRules"), RO_LOGIC_GLITCHLESS) == RO_LOGIC_VANILLA); + ImGui::BeginDisabled(CVarGetInteger(CVAR_RANDOMIZER_SETTING("LogicRules"), RO_LOGIC_GLITCHLESS) == + RO_LOGIC_VANILLA); if (ImGui::BeginTabItem("Gameplay")) { ImGui::PushStyleVar(ImGuiStyleVar_CellPadding, cellPadding); if (mSettings->GetOptionGroup(RSG_GAMEPLAY_IMGUI_TABLE).RenderImGui()) { @@ -2787,14 +3774,16 @@ void RandomizerSettingsWindow::DrawElement() { } ImGui::EndDisabled(); - ImGui::BeginDisabled(CVarGetInteger(CVAR_RANDOMIZER_SETTING("LogicRules"), RO_LOGIC_GLITCHLESS) == RO_LOGIC_VANILLA); + ImGui::BeginDisabled(CVarGetInteger(CVAR_RANDOMIZER_SETTING("LogicRules"), RO_LOGIC_GLITCHLESS) == + RO_LOGIC_VANILLA); if (ImGui::BeginTabItem("Locations")) { ImGui::PushStyleVar(ImGuiStyleVar_CellPadding, cellPadding); if (!locationsTabOpen) { locationsTabOpen = true; RandomizerCheckObjects::UpdateImGuiVisibility(); // todo: this efficently when we build out cvar array support - std::stringstream excludedLocationStringStream(CVarGetString(CVAR_RANDOMIZER_SETTING("ExcludedLocations"), "")); + std::stringstream excludedLocationStringStream( + CVarGetString(CVAR_RANDOMIZER_SETTING("ExcludedLocations"), "")); std::string excludedLocationString; excludedLocations.clear(); while (getline(excludedLocationStringStream, excludedLocationString, ',')) { @@ -2836,7 +3825,8 @@ void RandomizerSettingsWindow::DrawElement() { if (ImGui::TreeNode(RandomizerCheckObjects::GetRCAreaName(rcArea).c_str())) { for (auto& location : locations) { if (ctx->GetItemLocation(location)->IsVisible() && !excludedLocations.count(location) && - locationSearch.PassFilter(Rando::StaticData::GetLocation(location)->GetName().c_str())) { + locationSearch.PassFilter( + Rando::StaticData::GetLocation(location)->GetName().c_str())) { UIWidgets::PushStyleButton(THEME_COLOR, ImVec2(7.f, 5.f)); if (ImGui::ArrowButton(std::to_string(location).c_str(), ImGuiDir_Right)) { excludedLocations.insert(location); @@ -2846,8 +3836,12 @@ void RandomizerSettingsWindow::DrawElement() { excludedLocationString += std::to_string(excludedLocationIt); excludedLocationString += ","; } - CVarSetString(CVAR_RANDOMIZER_SETTING("ExcludedLocations"), excludedLocationString.c_str()); - Ship::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesNextFrame(); + CVarSetString(CVAR_RANDOMIZER_SETTING("ExcludedLocations"), + excludedLocationString.c_str()); + Ship::Context::GetInstance() + ->GetWindow() + ->GetGui() + ->SaveConsoleVariablesNextFrame(); } UIWidgets::PopStyleButton(); ImGui::SameLine(); @@ -2892,9 +3886,13 @@ void RandomizerSettingsWindow::DrawElement() { if (excludedLocationString == "") { CVarClear(CVAR_RANDOMIZER_SETTING("ExcludedLocations")); } else { - CVarSetString(CVAR_RANDOMIZER_SETTING("ExcludedLocations"), excludedLocationString.c_str()); + CVarSetString(CVAR_RANDOMIZER_SETTING("ExcludedLocations"), + excludedLocationString.c_str()); } - Ship::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesNextFrame(); + Ship::Context::GetInstance() + ->GetWindow() + ->GetGui() + ->SaveConsoleVariablesNextFrame(); } UIWidgets::PopStyleButton(); ImGui::SameLine(); @@ -2919,15 +3917,16 @@ void RandomizerSettingsWindow::DrawElement() { if (ImGui::BeginTabItem("Tricks/Glitches")) { if (!tricksTabOpen) { tricksTabOpen = true; - //RandomizerTricks::UpdateImGuiVisibility(); - // todo: this efficently when we build out cvar array support + // RandomizerTricks::UpdateImGuiVisibility(); + // todo: this efficently when we build out cvar array support std::stringstream enabledTrickStringStream(CVarGetString(CVAR_RANDOMIZER_SETTING("EnabledTricks"), "")); std::string enabledTrickString; enabledTricks.clear(); while (getline(enabledTrickStringStream, enabledTrickString, ',')) { enabledTricks.insert((RandomizerTrick)std::stoi(enabledTrickString)); } - std::stringstream enabledGlitchStringStream(CVarGetString(CVAR_RANDOMIZER_SETTING("EnabledGlitches"), "")); + std::stringstream enabledGlitchStringStream( + CVarGetString(CVAR_RANDOMIZER_SETTING("EnabledGlitches"), "")); std::string enabledGlitchString; enabledGlitches.clear(); while (getline(enabledGlitchStringStream, enabledGlitchString, ',')) { @@ -2953,93 +3952,93 @@ void RandomizerSettingsWindow::DrawElement() { } if (CVarGetInteger(CVAR_RANDOMIZER_SETTING("LogicRules"), RO_LOGIC_GLITCHLESS) == RO_LOGIC_VANILLA) { ImGui::SameLine(); - ImGui::TextColored(ImVec4(1.0f, 0.0f, 0.0f, 1.0f), "Heads up! This will disable all rando settings except for entrance shuffle and starter items"); + ImGui::TextColored( + ImVec4(1.0f, 0.0f, 0.0f, 1.0f), + "Heads up! This will disable all rando settings except for entrance shuffle and starter items"); } ImGui::PopItemWidth(); ImGui::EndTable(); } - ImGui::BeginDisabled(CVarGetInteger(CVAR_RANDOMIZER_SETTING("LogicRules"), RO_LOGIC_GLITCHLESS) == RO_LOGIC_VANILLA); + ImGui::BeginDisabled(CVarGetInteger(CVAR_RANDOMIZER_SETTING("LogicRules"), RO_LOGIC_GLITCHLESS) == + RO_LOGIC_VANILLA); // Tricks - static std::unordered_map areaTreeDisabled { - {RA_NONE, true}, - {RA_KOKIRI_FOREST, true}, - {RA_THE_LOST_WOODS, true}, - {RA_SACRED_FOREST_MEADOW, true}, - {RA_HYRULE_FIELD, true}, - {RA_LAKE_HYLIA, true}, - {RA_GERUDO_VALLEY, true}, - {RA_GERUDO_FORTRESS, true}, - {RA_HAUNTED_WASTELAND, true}, - {RA_DESERT_COLOSSUS, true}, - {RA_THE_MARKET, true}, - {RA_HYRULE_CASTLE, true}, - {RA_KAKARIKO_VILLAGE, true}, - {RA_THE_GRAVEYARD, true}, - {RA_DEATH_MOUNTAIN_TRAIL, true}, - {RA_GORON_CITY, true}, - {RA_DEATH_MOUNTAIN_CRATER, true}, - {RA_ZORAS_RIVER, true}, - {RA_ZORAS_DOMAIN, true}, - {RA_ZORAS_FOUNTAIN, true}, - {RA_LON_LON_RANCH, true}, - {RA_DEKU_TREE, true}, - {RA_DODONGOS_CAVERN, true}, - {RA_JABU_JABUS_BELLY, true}, - {RA_FOREST_TEMPLE, true}, - {RA_FIRE_TEMPLE, true}, - {RA_WATER_TEMPLE, true}, - {RA_SPIRIT_TEMPLE, true}, - {RA_SHADOW_TEMPLE, true}, - {RA_BOTTOM_OF_THE_WELL, true}, - {RA_ICE_CAVERN, true}, - {RA_GERUDO_TRAINING_GROUND, true}, - {RA_GANONS_CASTLE, true}, + static std::unordered_map areaTreeDisabled{ + { RA_NONE, true }, + { RA_KOKIRI_FOREST, true }, + { RA_THE_LOST_WOODS, true }, + { RA_SACRED_FOREST_MEADOW, true }, + { RA_HYRULE_FIELD, true }, + { RA_LAKE_HYLIA, true }, + { RA_GERUDO_VALLEY, true }, + { RA_GERUDO_FORTRESS, true }, + { RA_HAUNTED_WASTELAND, true }, + { RA_DESERT_COLOSSUS, true }, + { RA_THE_MARKET, true }, + { RA_HYRULE_CASTLE, true }, + { RA_KAKARIKO_VILLAGE, true }, + { RA_THE_GRAVEYARD, true }, + { RA_DEATH_MOUNTAIN_TRAIL, true }, + { RA_GORON_CITY, true }, + { RA_DEATH_MOUNTAIN_CRATER, true }, + { RA_ZORAS_RIVER, true }, + { RA_ZORAS_DOMAIN, true }, + { RA_ZORAS_FOUNTAIN, true }, + { RA_LON_LON_RANCH, true }, + { RA_DEKU_TREE, true }, + { RA_DODONGOS_CAVERN, true }, + { RA_JABU_JABUS_BELLY, true }, + { RA_FOREST_TEMPLE, true }, + { RA_FIRE_TEMPLE, true }, + { RA_WATER_TEMPLE, true }, + { RA_SPIRIT_TEMPLE, true }, + { RA_SHADOW_TEMPLE, true }, + { RA_BOTTOM_OF_THE_WELL, true }, + { RA_ICE_CAVERN, true }, + { RA_GERUDO_TRAINING_GROUND, true }, + { RA_GANONS_CASTLE, true }, }; - static std::unordered_map areaTreeEnabled { - {RA_NONE, true}, - {RA_KOKIRI_FOREST, true}, - {RA_THE_LOST_WOODS, true}, - {RA_SACRED_FOREST_MEADOW, true}, - {RA_HYRULE_FIELD, true}, - {RA_LAKE_HYLIA, true}, - {RA_GERUDO_VALLEY, true}, - {RA_GERUDO_FORTRESS, true}, - {RA_HAUNTED_WASTELAND, true}, - {RA_DESERT_COLOSSUS, true}, - {RA_THE_MARKET, true}, - {RA_HYRULE_CASTLE, true}, - {RA_KAKARIKO_VILLAGE, true}, - {RA_THE_GRAVEYARD, true}, - {RA_DEATH_MOUNTAIN_TRAIL, true}, - {RA_GORON_CITY, true}, - {RA_DEATH_MOUNTAIN_CRATER, true}, - {RA_ZORAS_RIVER, true}, - {RA_ZORAS_DOMAIN, true}, - {RA_ZORAS_FOUNTAIN, true}, - {RA_LON_LON_RANCH, true}, - {RA_DEKU_TREE, true}, - {RA_DODONGOS_CAVERN, true}, - {RA_JABU_JABUS_BELLY, true}, - {RA_FOREST_TEMPLE, true}, - {RA_FIRE_TEMPLE, true}, - {RA_WATER_TEMPLE, true}, - {RA_SPIRIT_TEMPLE, true}, - {RA_SHADOW_TEMPLE, true}, - {RA_BOTTOM_OF_THE_WELL, true}, - {RA_ICE_CAVERN, true}, - {RA_GERUDO_TRAINING_GROUND, true}, - {RA_GANONS_CASTLE, true}, + static std::unordered_map areaTreeEnabled{ + { RA_NONE, true }, + { RA_KOKIRI_FOREST, true }, + { RA_THE_LOST_WOODS, true }, + { RA_SACRED_FOREST_MEADOW, true }, + { RA_HYRULE_FIELD, true }, + { RA_LAKE_HYLIA, true }, + { RA_GERUDO_VALLEY, true }, + { RA_GERUDO_FORTRESS, true }, + { RA_HAUNTED_WASTELAND, true }, + { RA_DESERT_COLOSSUS, true }, + { RA_THE_MARKET, true }, + { RA_HYRULE_CASTLE, true }, + { RA_KAKARIKO_VILLAGE, true }, + { RA_THE_GRAVEYARD, true }, + { RA_DEATH_MOUNTAIN_TRAIL, true }, + { RA_GORON_CITY, true }, + { RA_DEATH_MOUNTAIN_CRATER, true }, + { RA_ZORAS_RIVER, true }, + { RA_ZORAS_DOMAIN, true }, + { RA_ZORAS_FOUNTAIN, true }, + { RA_LON_LON_RANCH, true }, + { RA_DEKU_TREE, true }, + { RA_DODONGOS_CAVERN, true }, + { RA_JABU_JABUS_BELLY, true }, + { RA_FOREST_TEMPLE, true }, + { RA_FIRE_TEMPLE, true }, + { RA_WATER_TEMPLE, true }, + { RA_SPIRIT_TEMPLE, true }, + { RA_SHADOW_TEMPLE, true }, + { RA_BOTTOM_OF_THE_WELL, true }, + { RA_ICE_CAVERN, true }, + { RA_GERUDO_TRAINING_GROUND, true }, + { RA_GANONS_CASTLE, true }, }; - static std::map showTag { - { Rando::Tricks::Tag::NOVICE, true }, - { Rando::Tricks::Tag::INTERMEDIATE, true }, - { Rando::Tricks::Tag::ADVANCED, true }, - { Rando::Tricks::Tag::EXPERT, true }, - { Rando::Tricks::Tag::EXTREME, true }, - { Rando::Tricks::Tag::EXPERIMENTAL, true }, + static std::map showTag{ + { Rando::Tricks::Tag::NOVICE, true }, { Rando::Tricks::Tag::INTERMEDIATE, true }, + { Rando::Tricks::Tag::ADVANCED, true }, { Rando::Tricks::Tag::EXPERT, true }, + { Rando::Tricks::Tag::EXTREME, true }, { Rando::Tricks::Tag::EXPERIMENTAL, true }, //{ Rando::Tricks::Tag::GLITCH, false }, }; static ImGuiTextFilter trickSearch; @@ -3048,7 +4047,8 @@ void RandomizerSettingsWindow::DrawElement() { UIWidgets::PopStyleInput(); if (CVarGetInteger(CVAR_RANDOMIZER_SETTING("LogicRules"), RO_LOGIC_GLITCHLESS) != RO_LOGIC_NO_LOGIC) { ImGui::SameLine(); - if (UIWidgets::Button("Disable All", UIWidgets::ButtonOptions().Color(THEME_COLOR).Size(ImVec2(250.f, 0.f)))) { + if (UIWidgets::Button("Disable All", + UIWidgets::ButtonOptions().Color(THEME_COLOR).Size(ImVec2(250.f, 0.f)))) { for (int i = 0; i < RT_MAX; i++) { auto etfound = enabledTricks.find(static_cast(i)); if (etfound != enabledTricks.end()) { @@ -3064,7 +4064,8 @@ void RandomizerSettingsWindow::DrawElement() { Ship::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesNextFrame(); } ImGui::SameLine(); - if (UIWidgets::Button("Enable All", UIWidgets::ButtonOptions().Color(THEME_COLOR).Size(ImVec2(250.f, 0.f)))) { + if (UIWidgets::Button("Enable All", + UIWidgets::ButtonOptions().Color(THEME_COLOR).Size(ImVec2(250.f, 0.f)))) { for (int i = 0; i < RT_MAX; i++) { if (!enabledTricks.count(static_cast(i))) { enabledTricks.insert(static_cast(i)); @@ -3079,7 +4080,9 @@ void RandomizerSettingsWindow::DrawElement() { Ship::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesNextFrame(); } } - if (ImGui::BeginTable("trickTags", showTag.size(), ImGuiTableFlags_Resizable | ImGuiTableFlags_NoSavedSettings | ImGuiTableFlags_Borders)) { + if (ImGui::BeginTable("trickTags", showTag.size(), + ImGuiTableFlags_Resizable | ImGuiTableFlags_NoSavedSettings | + ImGuiTableFlags_Borders)) { for (auto [rtTag, isShown] : showTag) { ImGui::TableNextColumn(); if (isShown) { @@ -3107,19 +4110,22 @@ void RandomizerSettingsWindow::DrawElement() { ImGui::TableNextColumn(); window->DC.CurrLineTextBaseOffset = 0.0f; - if (UIWidgets::Button("Collapse All##disabled", UIWidgets::ButtonOptions().Color(THEME_COLOR).Size(ImVec2(0.f, 0.f)))) { + if (UIWidgets::Button("Collapse All##disabled", + UIWidgets::ButtonOptions().Color(THEME_COLOR).Size(ImVec2(0.f, 0.f)))) { for (int i = 0; i < RA_MAX; i++) { areaTreeDisabled[static_cast(i)] = false; } } ImGui::SameLine(); - if (UIWidgets::Button("Open All##disabled", UIWidgets::ButtonOptions().Color(THEME_COLOR).Size(ImVec2(0.f, 0.f)))) { + if (UIWidgets::Button("Open All##disabled", + UIWidgets::ButtonOptions().Color(THEME_COLOR).Size(ImVec2(0.f, 0.f)))) { for (int i = 0; i < RA_MAX; i++) { areaTreeDisabled[static_cast(i)] = true; } } ImGui::SameLine(); - if (UIWidgets::Button("Enable Visible", UIWidgets::ButtonOptions().Color(THEME_COLOR).Size(ImVec2(0.f, 0.f)))) { + if (UIWidgets::Button("Enable Visible", + UIWidgets::ButtonOptions().Color(THEME_COLOR).Size(ImVec2(0.f, 0.f)))) { for (int i = 0; i < RT_MAX; i++) { auto option = mSettings->GetTrickOption(static_cast(i)); if (!enabledTricks.count(static_cast(i)) && @@ -3138,7 +4144,8 @@ void RandomizerSettingsWindow::DrawElement() { Ship::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesNextFrame(); } - ImGui::BeginChild("ChildTricksDisabled", ImVec2(0, -8), false, ImGuiWindowFlags_HorizontalScrollbar); + ImGui::BeginChild("ChildTricksDisabled", ImVec2(0, -8), false, + ImGuiWindowFlags_HorizontalScrollbar); for (auto [area, trickIds] : mSettings->mTricksByArea) { bool hasTricks = false; @@ -3151,14 +4158,20 @@ void RandomizerSettingsWindow::DrawElement() { } } if (hasTricks) { - ImGui::TreeNodeSetOpen(ImGui::GetID((Rando::Tricks::GetAreaName(area) + "##disabled").c_str()), areaTreeDisabled[area]); + ImGui::TreeNodeSetOpen( + ImGui::GetID((Rando::Tricks::GetAreaName(area) + "##disabled").c_str()), + areaTreeDisabled[area]); ImGui::SetNextItemOpen(true, ImGuiCond_Once); if (ImGui::TreeNode((Rando::Tricks::GetAreaName(area) + "##disabled").c_str())) { for (auto rt : trickIds) { auto option = mSettings->GetTrickOption(rt); if (!option.IsHidden() && trickSearch.PassFilter(option.GetName().c_str()) && - !enabledTricks.count(rt) && Rando::Tricks::CheckTags(showTag, option.GetTags())) { - ImGui::TreeNodeSetOpen(ImGui::GetID((Rando::Tricks::GetAreaName(option.GetArea()) + "##disabled").c_str()), areaTreeDisabled[option.GetArea()]); + !enabledTricks.count(rt) && + Rando::Tricks::CheckTags(showTag, option.GetTags())) { + ImGui::TreeNodeSetOpen( + ImGui::GetID( + (Rando::Tricks::GetAreaName(option.GetArea()) + "##disabled").c_str()), + areaTreeDisabled[option.GetArea()]); ImGui::SetNextItemOpen(true, ImGuiCond_Once); UIWidgets::PushStyleButton(THEME_COLOR, ImVec2(7.f, 5.f)); if (ImGui::ArrowButton(std::to_string(rt).c_str(), ImGuiDir_Right)) { @@ -3168,8 +4181,12 @@ void RandomizerSettingsWindow::DrawElement() { enabledTrickString += std::to_string(enabledTrickIt); enabledTrickString += ","; } - CVarSetString(CVAR_RANDOMIZER_SETTING("EnabledTricks"), enabledTrickString.c_str()); - Ship::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesNextFrame(); + CVarSetString(CVAR_RANDOMIZER_SETTING("EnabledTricks"), + enabledTrickString.c_str()); + Ship::Context::GetInstance() + ->GetWindow() + ->GetGui() + ->SaveConsoleVariablesNextFrame(); } UIWidgets::PopStyleButton(); Rando::Tricks::DrawTagChips(option.GetTags(), option.GetName()); @@ -3191,24 +4208,26 @@ void RandomizerSettingsWindow::DrawElement() { ImGui::TableNextColumn(); window->DC.CurrLineTextBaseOffset = 0.0f; - if (UIWidgets::Button("Collapse All##enabled", UIWidgets::ButtonOptions().Color(THEME_COLOR).Size(ImVec2(0.f, 0.f)))) { + if (UIWidgets::Button("Collapse All##enabled", + UIWidgets::ButtonOptions().Color(THEME_COLOR).Size(ImVec2(0.f, 0.f)))) { for (int i = 0; i < RA_MAX; i++) { areaTreeEnabled[static_cast(i)] = false; } } ImGui::SameLine(); - if (UIWidgets::Button("Open All##enabled", UIWidgets::ButtonOptions().Color(THEME_COLOR).Size(ImVec2(0.f, 0.f)))) { + if (UIWidgets::Button("Open All##enabled", + UIWidgets::ButtonOptions().Color(THEME_COLOR).Size(ImVec2(0.f, 0.f)))) { for (int i = 0; i < RA_MAX; i++) { areaTreeEnabled[static_cast(i)] = true; } } ImGui::SameLine(); - if (UIWidgets::Button("Disable Visible", UIWidgets::ButtonOptions().Color(THEME_COLOR).Size(ImVec2(0.f, 0.f)))) { + if (UIWidgets::Button("Disable Visible", + UIWidgets::ButtonOptions().Color(THEME_COLOR).Size(ImVec2(0.f, 0.f)))) { for (int i = 0; i < RT_MAX; i++) { auto option = mSettings->GetTrickOption(static_cast(i)); if (enabledTricks.count(static_cast(i)) && - trickSearch.PassFilter(option.GetName().c_str()) && - areaTreeEnabled[option.GetArea()] && + trickSearch.PassFilter(option.GetName().c_str()) && areaTreeEnabled[option.GetArea()] && Rando::Tricks::CheckTags(showTag, option.GetTags())) { enabledTricks.erase(static_cast(i)); } @@ -3239,14 +4258,20 @@ void RandomizerSettingsWindow::DrawElement() { } } if (hasTricks) { - ImGui::TreeNodeSetOpen(ImGui::GetID((Rando::Tricks::GetAreaName(area) + "##enabled").c_str()), areaTreeEnabled[area]); + ImGui::TreeNodeSetOpen( + ImGui::GetID((Rando::Tricks::GetAreaName(area) + "##enabled").c_str()), + areaTreeEnabled[area]); ImGui::SetNextItemOpen(true, ImGuiCond_Once); if (ImGui::TreeNode((Rando::Tricks::GetAreaName(area) + "##enabled").c_str())) { for (auto rt : trickIds) { auto option = mSettings->GetTrickOption(rt); if (!option.IsHidden() && trickSearch.PassFilter(option.GetName().c_str()) && - enabledTricks.count(rt) && Rando::Tricks::CheckTags(showTag, option.GetTags())) { - ImGui::TreeNodeSetOpen(ImGui::GetID((Rando::Tricks::GetAreaName(option.GetArea()) + "##enabled").c_str()), areaTreeEnabled[option.GetArea()]); + enabledTricks.count(rt) && + Rando::Tricks::CheckTags(showTag, option.GetTags())) { + ImGui::TreeNodeSetOpen( + ImGui::GetID( + (Rando::Tricks::GetAreaName(option.GetArea()) + "##enabled").c_str()), + areaTreeEnabled[option.GetArea()]); ImGui::SetNextItemOpen(true, ImGuiCond_Once); UIWidgets::PushStyleButton(THEME_COLOR, ImVec2(7.f, 5.f)); if (ImGui::ArrowButton(std::to_string(rt).c_str(), ImGuiDir_Left)) { @@ -3255,19 +4280,23 @@ void RandomizerSettingsWindow::DrawElement() { for (auto enabledTrickIt : enabledTricks) { enabledTrickString += std::to_string(enabledTrickIt); enabledTrickString += ","; + } + if (enabledTrickString == "") { + CVarClear(CVAR_RANDOMIZER_SETTING("EnabledTricks")); + } else { + CVarSetString(CVAR_RANDOMIZER_SETTING("EnabledTricks"), + enabledTrickString.c_str()); + } + Ship::Context::GetInstance() + ->GetWindow() + ->GetGui() + ->SaveConsoleVariablesNextFrame(); } - if (enabledTrickString == "") { - CVarClear(CVAR_RANDOMIZER_SETTING("EnabledTricks")); - } else { - CVarSetString(CVAR_RANDOMIZER_SETTING("EnabledTricks"), enabledTrickString.c_str()); - } - Ship::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesNextFrame(); - } - UIWidgets::PopStyleButton(); - Rando::Tricks::DrawTagChips(option.GetTags(), option.GetName()); - ImGui::SameLine(); - ImGui::Text("%s", option.GetName().c_str()); - UIWidgets::Tooltip(option.GetDescription().c_str()); + UIWidgets::PopStyleButton(); + Rando::Tricks::DrawTagChips(option.GetTags(), option.GetName()); + ImGui::SameLine(); + ImGui::Text("%s", option.GetName().c_str()); + UIWidgets::Tooltip(option.GetDescription().c_str()); } } areaTreeEnabled[area] = true; @@ -3326,41 +4355,48 @@ CustomMessage Randomizer::GetSheikMessage(s16 scene, u16 originalTextId) { CustomMessage messageEntry; switch (scene) { case SCENE_TEMPLE_OF_TIME: - if (ctx->GetOption(RSK_OOT_HINT) && !ctx->GetItemLocation(RC_SONG_FROM_OCARINA_OF_TIME)->HasObtained()){ + if (ctx->GetOption(RSK_OOT_HINT) && !ctx->GetItemLocation(RC_SONG_FROM_OCARINA_OF_TIME)->HasObtained()) { messageEntry = ctx->GetHint(RH_OOT_HINT)->GetHintMessage(MF_RAW); } else if (!CHECK_DUNGEON_ITEM(DUNGEON_KEY_BOSS, SCENE_GANONS_TOWER)) { messageEntry = CustomMessage( - "@, meet me at %gGanon's Castle%w once you obtain the %rkey to his lair%w.", - "@, wir treffen uns bei %gGanons Schloß%w, sobald Du den %rSchlüssel zu seinem Verlies%w hast.", - "Retrouve-moi au %gChâteau de Ganon%w une fois que tu auras obtenu la %rclé de son repaire%w."); + "@, meet me at %gGanon's Castle%w once you obtain the %rkey to his lair%w.", + "@, wir treffen uns bei %gGanons Schloß%w, sobald Du den %rSchlüssel zu seinem Verlies%w hast.", + "Retrouve-moi au %gChâteau de Ganon%w une fois que tu auras obtenu la %rclé de son repaire%w."); } else { - messageEntry = CustomMessage( - "The time has come. Prepare yourself.", - "Die Zeit ist gekommen.&Mach Dich bereit.", - "Le moment est venu @.&Tu ferais bien de te préparer."); + messageEntry = + CustomMessage("The time has come. Prepare yourself.", "Die Zeit ist gekommen.&Mach Dich bereit.", + "Le moment est venu @.&Tu ferais bien de te préparer."); } break; case SCENE_INSIDE_GANONS_CASTLE: if (ctx->GetOption(RSK_SHEIK_LA_HINT) && INV_CONTENT(ITEM_ARROW_LIGHT) != ITEM_ARROW_LIGHT) { messageEntry = ctx->GetHint(RH_SHEIK_HINT)->GetHintMessage(MF_RAW); - } else if (!(CHECK_OWNED_EQUIP(EQUIP_TYPE_SWORD, EQUIP_INV_SWORD_MASTER) && INV_CONTENT(ITEM_ARROW_LIGHT) == ITEM_ARROW_LIGHT && - CUR_CAPACITY(UPG_QUIVER) >= 30 && gSaveContext.isMagicAcquired)) { - messageEntry = CustomMessage("You are still ill-equipped to face %rGanondorf%w." - "^Seek out the %cMaster Sword%w, %rsomething to hold your arrows%w, and %gmagic%w to summon the %ylight%w.", + } else if (!(CHECK_OWNED_EQUIP(EQUIP_TYPE_SWORD, EQUIP_INV_SWORD_MASTER) && + INV_CONTENT(ITEM_ARROW_LIGHT) == ITEM_ARROW_LIGHT && CUR_CAPACITY(UPG_QUIVER) >= 30 && + gSaveContext.isMagicAcquired)) { + messageEntry = CustomMessage( + "You are still ill-equipped to face %rGanondorf%w." + "^Seek out the %cMaster Sword%w, %rsomething to hold your arrows%w, and %gmagic%w to summon the " + "%ylight%w.", "Du bist noch nicht gewappnet um Dich %rGanondorf%w stellen zu können.^" - "Begib Dich auf die Suche nach dem %cMaster-Schwert%w, %retwas um Deinen Pfeilen einen Sinn zu geben%w,^sowie %gdie Magie%w, um das %yLicht%w herauf beschwören zu können.", + "Begib Dich auf die Suche nach dem %cMaster-Schwert%w, %retwas um Deinen Pfeilen einen Sinn zu " + "geben%w,^sowie %gdie Magie%w, um das %yLicht%w herauf beschwören zu können.", "@, tu n'es toujours pas prêt à affronter %rGanondorf%w.^" - "Cherche l'%cÉpée de Légende%w, %rquelque chose pour ranger tes flèches%w et de la %gmagie%w pour invoquer la %ylumière%w."); - } else if (!Flags_GetEventChkInf(EVENTCHKINF_DISPELLED_GANONS_TOWER_BARRIER) && !ctx->GetOption(RSK_TRIAL_COUNT).Is(0)){ + "Cherche l'%cÉpée de Légende%w, %rquelque chose pour ranger tes flèches%w et de la %gmagie%w pour " + "invoquer la %ylumière%w."); + } else if (!Flags_GetEventChkInf(EVENTCHKINF_DISPELLED_GANONS_TOWER_BARRIER) && + !ctx->GetOption(RSK_TRIAL_COUNT).Is(0)) { messageEntry = CustomMessage( - "You may have what you need to defeat %rthe Evil King%w, but the %cbarrier%w still stands.^Complete the remaining %gtrials%w to destroy it.", - "Du magst das haben, was Du brauchst um %rden bösen König%w zu besiegen, aber die %cBarriere%w steht noch.^Absolviere die verbleibenden %gPrüfungen%w um sie zu zerstören.", - "@, tu as peut-être ce qu'il te faut pour vaincre %rle Malin%w, mais les barrières sont toujours actives.^Termine les épreuves restantes pour les détruire."); + "You may have what you need to defeat %rthe Evil King%w, but the %cbarrier%w still " + "stands.^Complete the remaining %gtrials%w to destroy it.", + "Du magst das haben, was Du brauchst um %rden bösen König%w zu besiegen, aber die %cBarriere%w " + "steht noch.^Absolviere die verbleibenden %gPrüfungen%w um sie zu zerstören.", + "@, tu as peut-être ce qu'il te faut pour vaincre %rle Malin%w, mais les barrières sont toujours " + "actives.^Termine les épreuves restantes pour les détruire."); } else { - messageEntry = CustomMessage( - "If you're ready, then proceed.^Good luck.", - "Wenn Du bereit bist, so schreite&voran.^Viel Glück.", - "Si tu es prêt, tu peux y aller.^Bonne chance."); + messageEntry = CustomMessage("If you're ready, then proceed.^Good luck.", + "Wenn Du bereit bist, so schreite&voran.^Viel Glück.", + "Si tu es prêt, tu peux y aller.^Bonne chance."); } break; } @@ -3371,10 +4407,10 @@ CustomMessage Randomizer::GetSheikMessage(s16 scene, u16 originalTextId) { CustomMessage Randomizer::GetFishingPondOwnerMessage(u16 originalTextId) { auto ctx = Rando::Context::GetInstance(); CustomMessage messageEntry = CustomMessage( - "Sorry, but the pond is closed.&I've lost my good %rfishing pole%w...&Can't go fishing without it!", - "Entschuldigung, aber der Teich ist zu.&Ich habe meine gute %rAngelrute%w verloren.&Ohne kann ich nicht fischen!", - "Désolé, mais l'étang est fermé.&J'ai perdu ma bonne %rCanne à Pêche%w...&Impossible de pêcher sans elle!" - ); + "Sorry, but the pond is closed.&I've lost my good %rfishing pole%w...&Can't go fishing without it!", + "Entschuldigung, aber der Teich ist zu.&Ich habe meine gute %rAngelrute%w verloren.&Ohne kann ich nicht " + "fischen!", + "Désolé, mais l'étang est fermé.&J'ai perdu ma bonne %rCanne à Pêche%w...&Impossible de pêcher sans elle!"); if (Rando::Context::GetInstance()->GetOption(RSK_FISHING_POLE_HINT)) { messageEntry = messageEntry + CustomMessage(ctx->GetHint(RH_FISHING_POLE)->GetHintMessage()); @@ -3382,14 +4418,13 @@ CustomMessage Randomizer::GetFishingPondOwnerMessage(u16 originalTextId) { // if the fishing pond guy doesnt remember me i will cry :( if (originalTextId == TEXT_FISHING_POND_START_MET) { - messageEntry = CustomMessage( - "Hey, mister! I remember you!&It's been a long time!^", - "Hallo, mein Herr! Ich erinnere mich an Sie!&Lang ist's her!", - "Hé, monsieur! Je me souviens de toi!&Ça fait longtemps!" - ) + messageEntry; + messageEntry = CustomMessage("Hey, mister! I remember you!&It's been a long time!^", + "Hallo, mein Herr! Ich erinnere mich an Sie!&Lang ist's her!", + "Hé, monsieur! Je me souviens de toi!&Ça fait longtemps!") + + messageEntry; } - messageEntry.Format(); //RANDOTODO why is this needed when it's not elsewhere.... + messageEntry.Format(); // RANDOTODO why is this needed when it's not elsewhere.... return messageEntry; } @@ -3406,24 +4441,27 @@ CustomMessage Randomizer::GetMerchantMessage(RandomizerCheck rc, TextIDs textId, } else if (shopItemGet == RG_ICE_TRAP) { shopItemGet = ctx->overrides[rc].LooksLike(); shopItemName = CustomMessage(ctx->overrides[rc].GetTrickName()); - } else { - auto shopItem = Rando::StaticData::RetrieveItem(shopItemGet); - shopItemName = {shopItem.GetName()}; - } - - if (freeTextId != TEXT_NONE && shopItemPrice == 0) { - messageEntry = CustomMessageManager::Instance->RetrieveMessage(Randomizer::merchantMessageTableID, freeTextId, MF_RAW); } else { - messageEntry = CustomMessageManager::Instance->RetrieveMessage(Randomizer::merchantMessageTableID, textId, MF_RAW); + auto shopItem = Rando::StaticData::RetrieveItem(shopItemGet); + shopItemName = { shopItem.GetName() }; } - messageEntry.InsertNames({shopItemName, {std::to_string(shopItemPrice)}}); + if (freeTextId != TEXT_NONE && shopItemPrice == 0) { + messageEntry = + CustomMessageManager::Instance->RetrieveMessage(Randomizer::merchantMessageTableID, freeTextId, MF_RAW); + } else { + messageEntry = + CustomMessageManager::Instance->RetrieveMessage(Randomizer::merchantMessageTableID, textId, MF_RAW); + } + + messageEntry.InsertNames({ shopItemName, { std::to_string(shopItemPrice) } }); messageEntry.AutoFormat(); return messageEntry; } CustomMessage Randomizer::GetMapGetItemMessageWithHint(GetItemEntry itemEntry) { - CustomMessage messageEntry = CustomMessageManager::Instance->RetrieveMessage(Randomizer::getItemMessageTableID, itemEntry.getItemId); + CustomMessage messageEntry = + CustomMessageManager::Instance->RetrieveMessage(Randomizer::getItemMessageTableID, itemEntry.getItemId); int sceneNum; switch (itemEntry.getItemId) { case RG_DEKU_TREE_MAP: @@ -3460,8 +4498,7 @@ CustomMessage Randomizer::GetMapGetItemMessageWithHint(GetItemEntry itemEntry) { if (GetRandoSettingValue(RSK_MQ_DUNGEON_RANDOM) == RO_MQ_DUNGEONS_NONE || (GetRandoSettingValue(RSK_MQ_DUNGEON_RANDOM) == RO_MQ_DUNGEONS_SET_NUMBER && - GetRandoSettingValue(RSK_MQ_DUNGEON_COUNT) == 12) - ) { + GetRandoSettingValue(RSK_MQ_DUNGEON_COUNT) == 12)) { messageEntry.Replace("[[typeHint]]", ""); } else if (ResourceMgr_IsSceneMasterQuest(sceneNum)) { messageEntry.Replace("[[typeHint]]", Rando::StaticData::hintTextTable[RHT_DUNGEON_MASTERFUL].GetHintMessage()); @@ -3472,8 +4509,7 @@ CustomMessage Randomizer::GetMapGetItemMessageWithHint(GetItemEntry itemEntry) { return messageEntry; } -template -void CreateGetItemMessages(const std::array& messageEntries) { +template void CreateGetItemMessages(const std::array& messageEntries) { CustomMessageManager* customMessageManager = CustomMessageManager::Instance; customMessageManager->AddCustomMessageTable(Randomizer::getItemMessageTableID); for (const GetItemMessage& messageEntry : messageEntries) { @@ -3506,17 +4542,15 @@ void CreateRupeeMessages() { } customMessageManager->CreateMessage( Randomizer::rupeeMessageTableID, rupee, - CustomMessage( - "You found" + rupeeText + " !", - "Du hast" + rupeeText + " gefunden!", - "Vous obtenez" + rupeeText + " !", TEXTBOX_TYPE_BLACK, TEXTBOX_POS_BOTTOM)); + CustomMessage("You found" + rupeeText + " !", "Du hast" + rupeeText + " gefunden!", + "Vous obtenez" + rupeeText + " !", TEXTBOX_TYPE_BLACK, TEXTBOX_POS_BOTTOM)); } } CustomMessage Randomizer::GetRupeeMessage(u16 rupeeTextId) { - CustomMessage messageEntry = CustomMessageManager::Instance->RetrieveMessage(Randomizer::rupeeMessageTableID, rupeeTextId, MF_AUTO_FORMAT); - messageEntry.Replace("[[rupee]]", CustomMessage(RandomElement(englishRupeeNames), - RandomElement(germanRupeeNames), + CustomMessage messageEntry = + CustomMessageManager::Instance->RetrieveMessage(Randomizer::rupeeMessageTableID, rupeeTextId, MF_AUTO_FORMAT); + messageEntry.Replace("[[rupee]]", CustomMessage(RandomElement(englishRupeeNames), RandomElement(germanRupeeNames), RandomElement(frenchRupeeNames))); return messageEntry; } @@ -3526,19 +4560,24 @@ void CreateTriforcePieceMessages() { { "You found a %yTriforce Piece%w!&%g[[current]]%w down, %c[[remaining]]%w to go. It's a start!", "Ein %yTriforce-Splitter%w! Du hast&%g[[current]]%w von %c[[required]]%w gefunden. Es ist ein&Anfang!", - "Vous trouvez un %yFragment de la&Triforce%w! Vous en avez %g[[current]]%w, il en&reste %c[[remaining]]%w à trouver. C'est un début!" }, + "Vous trouvez un %yFragment de la&Triforce%w! Vous en avez %g[[current]]%w, il en&reste %c[[remaining]]%w à " + "trouver. C'est un début!" }, { "You found a %yTriforce Piece%w!&%g[[current]]%w down, %c[[remaining]]%w to go. Progress!", "Ein %yTriforce-Splitter%w! Du hast&%g[[current]]%w von %c[[required]]%w gefunden. Es geht voran!", - "Vous trouvez un %yFragment de la&Triforce%w! Vous en avez %g[[current]]%w, il en&reste %c[[remaining]]%w à trouver. Ça avance!" }, + "Vous trouvez un %yFragment de la&Triforce%w! Vous en avez %g[[current]]%w, il en&reste %c[[remaining]]%w à " + "trouver. Ça avance!" }, { "You found a %yTriforce Piece%w!&%g[[current]]%w down, %c[[remaining]]%w to go. Over half-way&there!", - "Ein %yTriforce-Splitter%w! Du hast&schon %g[[current]]%w von %c[[required]]%w gefunden. Schon&über die Hälfte!", - "Vous trouvez un %yFragment de la&Triforce%w! Vous en avez %g[[current]]%w, il en&reste %c[[remaining]]%w à trouver. Il en reste un&peu moins que la moitié!" }, + "Ein %yTriforce-Splitter%w! Du hast&schon %g[[current]]%w von %c[[required]]%w gefunden. Schon&über die " + "Hälfte!", + "Vous trouvez un %yFragment de la&Triforce%w! Vous en avez %g[[current]]%w, il en&reste %c[[remaining]]%w à " + "trouver. Il en reste un&peu moins que la moitié!" }, { "You found a %yTriforce Piece%w!&%g[[current]]%w down, %c[[remaining]]%w to go. Almost done!", "Ein %yTriforce-Splitter%w! Du hast&schon %g[[current]]%w von %c[[required]]%w gefunden. Fast&geschafft!", - "Vous trouvez un %yFragment de la&Triforce%w! Vous en avez %g[[current]]%w, il en&reste %c[[remaining]]%w à trouver. C'est presque&terminé!" }, + "Vous trouvez un %yFragment de la&Triforce%w! Vous en avez %g[[current]]%w, il en&reste %c[[remaining]]%w à " + "trouver. C'est presque&terminé!" }, { "You completed the %yTriforce of&Courage%w! %gGG%w!", "Das %yTriforce des Mutes%w! Du hast&alle Splitter gefunden. %gGut gemacht%w!", @@ -3546,7 +4585,8 @@ void CreateTriforcePieceMessages() { { "You found a spare %yTriforce Piece%w!&You only needed %c[[required]]%w, but you have %g[[current]]%w!", "Ein übriger %yTriforce-Splitter%w! Du&hast nun %g[[current]]%w von %c[[required]]%w nötigen gefunden.", - "Vous avez trouvé un %yFragment de&Triforce%w en plus! Vous n'aviez besoin&que de %c[[required]]%w, mais vous en avez %g[[current]]%w en&tout!" }, + "Vous avez trouvé un %yFragment de&Triforce%w en plus! Vous n'aviez besoin&que de %c[[required]]%w, mais " + "vous en avez %g[[current]]%w en&tout!" }, }; CustomMessageManager* customMessageManager = CustomMessageManager::Instance; customMessageManager->AddCustomMessageTable(Randomizer::triforcePieceMessageTableID); @@ -3648,7 +4688,8 @@ void CreateNaviRandoMessages() { "%cMême un adulte ne peut pas pousser&de grands blocs sans un petit %wgain&de force%c!" }, { "%cI've heard that %rFlare Dancer&%cis weak to the %wMaster Sword%c!&Have you tried it?", - "%cIch habe gehört, daß der&%rFlammenderwisch %ceine Schwäche für&das %wMaster-Schwert %caufweist. Hast Du&es " + "%cIch habe gehört, daß der&%rFlammenderwisch %ceine Schwäche für&das %wMaster-Schwert %caufweist. Hast " + "Du&es " "schon einmal versucht einzusetzen?", "%cJ'ai entendu dire que les %rDanse-&Flammes %csont faîbles face à l'%wÉpée de&Légende%c! Est-ce que tu as " "essayé?" }, @@ -3672,12 +4713,14 @@ void CreateNaviRandoMessages() { "trop apprécier&le fait que tu %wportes un masque%c!" }, { "%cIf you get trapped somewhere, you&might have to %wsave your game %cand&%wreset%c!", - "%cSolltest Du irgendwo eingeschlossen&sein, mußt Du vielleicht Dein %wSpiel&speichern %cund %wneu starten%c!", + "%cSolltest Du irgendwo eingeschlossen&sein, mußt Du vielleicht Dein %wSpiel&speichern %cund %wneu " + "starten%c!", "%cSi tu es coincé quelque part, tu&devrais %wsauvegarder ta partie %cet&faire un %wreset%c!" }, { "%cSheik will meet you in a %rburning&village %conce you have %gForest%c,&%rFire%c, and %bWater " "%cMedallions!", - "%cShiek wird Dich in einem %rbrennenden&Dorf %ctreffen, sobald Du das Amulett&des %gWaldes%c, %rFeuers %cund " + "%cShiek wird Dich in einem %rbrennenden&Dorf %ctreffen, sobald Du das Amulett&des %gWaldes%c, %rFeuers " + "%cund " "%bWassers&%cbesitzt.", "%cSheik t'attendra dans un %rvillage&en feu %clorsque tu auras récupéré&les médaillons de la %gForêt%c, du " "%rFeu&%cet de l'%bEau%c!" }, @@ -3692,9 +4735,7 @@ void CreateNaviRandoMessages() { CustomMessageManager* customMessageManager = CustomMessageManager::Instance; customMessageManager->AddCustomMessageTable(Randomizer::NaviRandoMessageTableID); for (unsigned int i = 0; i <= (NUM_NAVI_MESSAGES - 1); i++) { - customMessageManager->CreateMessage( - Randomizer::NaviRandoMessageTableID, i, - NaviMessages[i]); + customMessageManager->CreateMessage(Randomizer::NaviRandoMessageTableID, i, NaviMessages[i]); } } @@ -3744,7 +4785,7 @@ CustomMessage Randomizer::GetIceTrapMessage() { "Would you like #ice# with that?", "You have obtained the #Ice# Medallion!", "Quick, do a #Zora# impression!", - "One item #on the rocks#!",//would be better if it could display the name of the item + "One item #on the rocks#!", // would be better if it could display the name of the item "How much does a polar bear weigh?&Enough to break the #ice#.", "You got Din's #Ice#!", "You got Nayru's #Cold#!", @@ -3807,12 +4848,13 @@ CustomMessage Randomizer::GetIceTrapMessage() { "STOP!&You violated the #Thaw#!", "I wanted to give you a treasure, but it looks like you got #cold feet#.", "You told me you wanted to deliver #just ice# to Ganondorf!", - "You got the triforce!&This ancient artifact of divine power can grant any- wait, no, sorry, it's just an ice trap. My bad.", + "You got the triforce!&This ancient artifact of divine power can grant any- wait, no, sorry, it's just an ice " + "trap. My bad.", "Time to #cool off#!", "The #Ice Cavern# sends its regards.", "Loading item, please #wait#...", "Mash A+B to not #die#.", - "Sorry, your item is in another location.", //would be better if it could have the name of the item + "Sorry, your item is in another location.", // would be better if it could have the name of the item "You only wish this was %gGreg%w.", "Do you want to drink a hot chocolate?", "The #cold# never bothered me anyway.", @@ -3833,7 +4875,8 @@ CustomMessage Randomizer::GetIceTrapMessage() { "Remember, there may be some momentary #discomfort#.", "In a perfect world #ice traps# like me would not exist, but this is not a perfect world.", "Gee, it sure is #cold# around here.", - "You tested the item with your #ice detector#, it beeped.", //would be better if it could have the name of the item + "You tested the item with your #ice detector#, it beeped.", // would be better if it could have the name of the + // item "You have found the way of the zero. The #sub-zero#.", "Mweep... mweep... mweep...", "Scum, #freezebag#! I mean #freeze#, scumbag!", @@ -3852,19 +4895,22 @@ CustomMessage Randomizer::GetIceTrapMessage() { "Hydration break! Hey, who #froze# my water?", "Oops, wrong #item model#.", "Whoops! You have to put the item #in your inventory#.", - "You dropped the item, shattering it into #shards of ice#!", //would be better if it could have the name of the item + "You dropped the item, shattering it into #shards of ice#!", // would be better if it could have the name of the + // item "Is this... golden age Simpsons?&BECAUSE I'M ABOUT TO #CHOKE A CHILD#.", "You are the weakest @, #goodbye#!", "Ugh... Why did we even randomize #this item#?", "The #Frost Moon# is rising...", - "According to all known laws of physics and biology, there is no way that @ should be able to survive #getting fully encased in ice#. The cells in @'s body would all die by the time they #unthaw#. Of course, this is a video game, so @ survives anyway... #Probably#.", + "According to all known laws of physics and biology, there is no way that @ should be able to survive #getting " + "fully encased in ice#. The cells in @'s body would all die by the time they #unthaw#. Of course, this is a " + "video game, so @ survives anyway... #Probably#.", "Okay, so stop me if you've heard this one - a gamer and a bottle of #liquid nitrogen# walk into a milk bar...", "Lástima, es una #trampa de hielo#...&&Nobody expects the Spanish #ice trap#!", "Gee, it sure is #BURR#ing around here.", "Navi? Oh! I thought she was called #Névé#!", "It's fine, @ knew this was a #trap#, they're just using it to take damage intentionally to manipulate RNG.", - "Unfortunately, the item has #stopped#.", //would be better if it could have the name of the item - "This item is #not available# in your country.", //would be better if it could have the name of the item + "Unfortunately, the item has #stopped#.", // would be better if it could have the name of the item + "This item is #not available# in your country.", // would be better if it could have the name of the item "#Ice# try. #;)#", "D'oh, I #missed#!", "Where is my #super suit#?", @@ -3923,12 +4969,13 @@ CustomMessage Randomizer::GetIceTrapMessage() { "J'espère que ça ne te fait ni chaud, ni #froid#.", "Je voulais t'offrir un trésor, mais il semble que tu aies eu #froid aux pieds#", "Tu m'as dit que tu voulais livrer #de la glace# à Ganondorf!", - "Tu as obtenu la Triforce!&Cet ancien artefact divin peut exaucer n'importe quel... ah non, désolé, c'est juste un piège de glace.", + "Tu as obtenu la Triforce!&Cet ancien artefact divin peut exaucer n'importe quel... ah non, désolé, c'est " + "juste un piège de glace.", "Il est temps de #te rafraîchir#!", "La #Caverne Polaire# te passe le bonjour.", "Chargement de l'objet, veuillez #patienter#...", "Martèle A+B pour ne pas #mourir#.", - "Désolé, ton objet est à un autre endroit.", //would be better if it could have the name of the item + "Désolé, ton objet est à un autre endroit.", // would be better if it could have the name of the item "Tu espérais que ce soit %gGreg%w.", "Tu veux boire un chocolat chaud?", "Le #froid# ne m'a jamais dérangé, de toute façon.", @@ -3947,9 +4994,11 @@ CustomMessage Randomizer::GetIceTrapMessage() { "Commence à marteler.", "Cet objet va #s'autodétruire# dans 5 secondes...", "Souviens-toi, il pourrait y avoir un léger #inconfort#.", - "Dans un monde parfait, les #pièges de glace# comme moi n'existeraient pas, mais ce n'est pas un monde parfait.", + "Dans un monde parfait, les #pièges de glace# comme moi n'existeraient pas, mais ce n'est pas un monde " + "parfait.", "Mon dieu qu'il fait #froid# ici.", - "Tu as testé l'objet avec ton #détecteur de glace#, il a bipé.", //would be better if it could have the name of the item + "Tu as testé l'objet avec ton #détecteur de glace#, il a bipé.", // would be better if it could have the name of + // the item "Tu as découvert le chemin du zéro. Le #sub-zéro#.", "Mweep... mweep... mweep...", "Gelé, #sac à glace#! Je veux dire #gèle-toi#, racaille!", @@ -3968,16 +5017,21 @@ CustomMessage Randomizer::GetIceTrapMessage() { "Pause hydratation ! Hé, qui a #gelé# mon eau?", "Oups, mauvais #modèle d'objet#.", "Oups! Tu dois mettre l'objet #dans ton inventaire#.", - "Tu as fait tomber l'objet, le brisant en #éclats de glace#!", //would be better if it could have the name of the item + "Tu as fait tomber l'objet, le brisant en #éclats de glace#!", // would be better if it could have the name of + // the item "Tu es le maillon faible @, #au revoir#!", "Ugh... Pourquoi avons-nous même randomisé #cet objet#?", "La #Lune de Givre# se lève...", - "Selon toutes les lois connues de la physique et de la biologie, @ ne devrait pas survivre à #être complètement enfermé dans la glace#. Les cellules de @ mourraient avant qu'elles ne #dégèlent#. Mais c'est un jeu vidéo, alors @ survit... #Probablement#.", - "OK, arrête-moi si tu l'as déjà entendue - un joueur et une bouteille de #nitrogène liquide# entrent dans un bar à lait...", + "Selon toutes les lois connues de la physique et de la biologie, @ ne devrait pas survivre à #être " + "complètement enfermé dans la glace#. Les cellules de @ mourraient avant qu'elles ne #dégèlent#. Mais c'est un " + "jeu vidéo, alors @ survit... #Probablement#.", + "OK, arrête-moi si tu l'as déjà entendue - un joueur et une bouteille de #nitrogène liquide# entrent dans un " + "bar à lait...", "Lástima, c'est un #piège de glace#...&&Personne ne s'attend à un #piège de glace espagnol#!", "Mon dieu qu'il fait #GLAGLA# ici.", - "C'est bon, @ savait que c'était un #piège#, il l'utilise juste pour prendre des dégâts intentionnellement et manipuler la RNG.", - "Cet objet n'est #pas disponible# dans votre pays.", //would be better if it could have the name of the item + "C'est bon, @ savait que c'était un #piège#, il l'utilise juste pour prendre des dégâts intentionnellement et " + "manipuler la RNG.", + "Cet objet n'est #pas disponible# dans votre pays.", // would be better if it could have the name of the item "#Bonne# tentative. #;)#", "Où est mon #Super Costume#?", "#La revanche du Titanic#.", @@ -3988,17 +5042,11 @@ CustomMessage Randomizer::GetIceTrapMessage() { if (CVarGetInteger(CVAR_GENERAL("LetItSnow"), 0)) { msg = CustomMessage( /*english*/ "This year for Christmas, all you get is #COAL#!", - /*german*/ "This year for Christmas, all you get is #COAL#!", - /*french*/ "Pour Noël, cette année, tu n'auras que du #CHARBON#! %rJoyeux Noël%w!", - { QM_BLUE } - ); + /*german*/ "This year for Christmas, all you get is #COAL#!", + /*french*/ "Pour Noël, cette année, tu n'auras que du #CHARBON#! %rJoyeux Noël%w!", { QM_BLUE }); } else { - msg = CustomMessage( - RandomElement(englishIceTrapMessages), - RandomElement(germanIceTrapMessages), - RandomElement(frenchIceTrapMessages), - { QM_BLUE, QM_BLUE, QM_BLUE } - ); + msg = CustomMessage(RandomElement(englishIceTrapMessages), RandomElement(germanIceTrapMessages), + RandomElement(frenchIceTrapMessages), { QM_BLUE, QM_BLUE, QM_BLUE }); } msg.AutoFormat(); @@ -4013,7 +5061,7 @@ static int goronIDs[9] = { TEXT_FIRE_TEMPLE_GORON_OWE_YOU_BIG_TIME, TEXT_FIRE_TEMPLE_GORON_OCARINA_SECRET, TEXT_FIRE_TEMPLE_GORON_PILLAR_SECRET, TEXT_FIRE_TEMPLE_GORON_HIDDEN_DOOR_SECRET, - TEXT_FIRE_TEMPLE_GORON_SOUNDS_DIFFERENT_SECRET}; + TEXT_FIRE_TEMPLE_GORON_SOUNDS_DIFFERENT_SECRET }; void CreateFireTempleGoronMessages() { CustomMessage FireTempleGoronMessages[NUM_GORON_MESSAGES] = { @@ -4108,461 +5156,374 @@ CustomMessage Randomizer::GetGoronMessage(u16 index) { void Randomizer::CreateCustomMessages() { // RANDTODO: Translate into french and german and replace GIMESSAGE_UNTRANSLATED // with GIMESSAGE(getItemID, itemID, english, german, french). - const std::array getItemMessages = {{ - GIMESSAGE(RG_GREG_RUPEE, ITEM_MASK_GORON, - "You found %gGreg%w!", - "%gGreg%w! Du hast ihn wirklich gefunden!", - "Félicitation! Vous avez trouvé %gGreg%w!"), - GIMESSAGE(RG_MASTER_SWORD, ITEM_SWORD_MASTER, - "You found the %gMaster Sword%w!", - "Du erhältst das %gMaster-Schwert%w!", - "Vous obtenez %gl'Épée de Légende%w!"), - GIMESSAGE(RG_BOTTLE_WITH_BLUE_FIRE, ITEM_BLUE_FIRE, - "You got a %rBottle with Blue &Fire%w! Use it to melt Red Ice!", - "Du erhältst eine %rFlasche mit&blauem Feuer%w! Nutze es um&%rRotes Eis%w zu schmelzen!", + const std::array getItemMessages = { { + GIMESSAGE(RG_GREG_RUPEE, ITEM_MASK_GORON, "You found %gGreg%w!", "%gGreg%w! Du hast ihn wirklich gefunden!", + "Félicitation! Vous avez trouvé %gGreg%w!"), + GIMESSAGE(RG_MASTER_SWORD, ITEM_SWORD_MASTER, "You found the %gMaster Sword%w!", + "Du erhältst das %gMaster-Schwert%w!", "Vous obtenez %gl'Épée de Légende%w!"), + GIMESSAGE( + RG_BOTTLE_WITH_BLUE_FIRE, ITEM_BLUE_FIRE, "You got a %rBottle with Blue &Fire%w! Use it to melt Red Ice!", + "Du erhältst eine %rFlasche mit&blauem Feuer%w! Nutze es um&%rRotes Eis%w zu schmelzen!", "Vous obtenez une %rBouteille avec&une Flamme Bleue%w! Utilisez-la&pour faire fondre la %rGlace&Rouge%w!"), - GIMESSAGE(RG_BOTTLE_WITH_BIG_POE, ITEM_BIG_POE, - "You got a %rBig Poe in a Bottle%w!&Sell it to the Ghost Shop!", - "Du hast einen %rNachtschwärmer%w&in einer Flasche gefangen!&Gehe zum %rGespenstermarkt%w&und verkaufe ihn!", - "Vous obtenez une %rBouteille avec&une Âme%w! Vendez-la au Marchand&d'Âme"), - GIMESSAGE(RG_BOTTLE_WITH_BLUE_POTION, ITEM_POTION_BLUE, - "You got a %rBottle of Blue Potion%w!&Drink it to replenish your&%ghealth%w and %bmagic%w!", - "Du erhältst ein %rBlaues Elixier%w!&Nutze es, um Deine %rMagie- und&Energieleiste%w komplett&aufzufüllen!", - "Vous obtenez une %rBouteille avec&une Potion Bleue%w! Buvez-la pour&restaurer votre %rénergie vitale%w&ainsi que votre %gmagie%w!"), + GIMESSAGE(RG_BOTTLE_WITH_BIG_POE, ITEM_BIG_POE, "You got a %rBig Poe in a Bottle%w!&Sell it to the Ghost Shop!", + "Du hast einen %rNachtschwärmer%w&in einer Flasche gefangen!&Gehe zum %rGespenstermarkt%w&und " + "verkaufe ihn!", + "Vous obtenez une %rBouteille avec&une Âme%w! Vendez-la au Marchand&d'Âme"), + GIMESSAGE( + RG_BOTTLE_WITH_BLUE_POTION, ITEM_POTION_BLUE, + "You got a %rBottle of Blue Potion%w!&Drink it to replenish your&%ghealth%w and %bmagic%w!", + "Du erhältst ein %rBlaues Elixier%w!&Nutze es, um Deine %rMagie- und&Energieleiste%w komplett&aufzufüllen!", + "Vous obtenez une %rBouteille avec&une Potion Bleue%w! Buvez-la pour&restaurer votre %rénergie " + "vitale%w&ainsi que votre %gmagie%w!"), GIMESSAGE(RG_BOTTLE_WITH_FISH, ITEM_FISH, - "You got a %rFish in a Bottle%w!&It looks fresh and delicious!&They say Jabu-Jabu loves them!", - "Du hast jetzt einen %rFisch in&einer Flasche%w! Er sieht richtig&frisch aus! Man sagt,&Lord Jabu-Jabu liebt Fische!", - "Vous obtenez une %rBouteille avec&un Poisson%w! Il a l'air délicieux!&Il paraîtrait que %bJabu-Jabu %wen&serait friand!"), - GIMESSAGE(RG_BOTTLE_WITH_BUGS, ITEM_BUG, - "You got a %rBug in a Bottle%w!&They love to burrow in&dirt holes!", - "Du hast jetzt %rKäfer in einer&Flasche&%w!&Sie graben gerne&in Erdlöchern.", - "Vous obtenez une %rBouteille avec&des Insectes%w! Ils adorent creuser&dans la terre meuble!"), - GIMESSAGE(RG_BOTTLE_WITH_FAIRY, ITEM_FAIRY, - "You got a %rFairy in a Bottle%w!&Use it wisely!", - "Du hast jetzt eine %rFee in einer&Flasche%w! Nutze sie weise!", - "Vous obtenez une %rBouteille avec&une Fée%w! Faites-en bon usage!"), - GIMESSAGE(RG_BOTTLE_WITH_RED_POTION, ITEM_POTION_RED, + "You got a %rFish in a Bottle%w!&It looks fresh and delicious!&They say Jabu-Jabu loves them!", + "Du hast jetzt einen %rFisch in&einer Flasche%w! Er sieht richtig&frisch aus! Man sagt,&Lord " + "Jabu-Jabu liebt Fische!", + "Vous obtenez une %rBouteille avec&un Poisson%w! Il a l'air délicieux!&Il paraîtrait que %bJabu-Jabu " + "%wen&serait friand!"), + GIMESSAGE(RG_BOTTLE_WITH_BUGS, ITEM_BUG, "You got a %rBug in a Bottle%w!&They love to burrow in&dirt holes!", + "Du hast jetzt %rKäfer in einer&Flasche&%w!&Sie graben gerne&in Erdlöchern.", + "Vous obtenez une %rBouteille avec&des Insectes%w! Ils adorent creuser&dans la terre meuble!"), + GIMESSAGE(RG_BOTTLE_WITH_FAIRY, ITEM_FAIRY, "You got a %rFairy in a Bottle%w!&Use it wisely!", + "Du hast jetzt eine %rFee in einer&Flasche%w! Nutze sie weise!", + "Vous obtenez une %rBouteille avec&une Fée%w! Faites-en bon usage!"), + GIMESSAGE( + RG_BOTTLE_WITH_RED_POTION, ITEM_POTION_RED, "You got a %rBottle of Red Potion%w!&Drink it to replenish your&%ghealth%w!", - "Du erhältst ein %rRotes Elixier%w!&Nutze es, um Deine %rEnergieleiste&%weinmalig komplett aufzufüllen!", + "Du erhältst ein %rRotes Elixier%w!&Nutze es, um Deine %rEnergieleiste&%weinmalig komplett aufzufüllen!", "Vous obtenez une %rBouteille avec&une Potion Rouge%w! Buvez-la pour&restaurer votre %rénergie vitale%w!"), - GIMESSAGE(RG_BOTTLE_WITH_GREEN_POTION, ITEM_POTION_GREEN, + GIMESSAGE( + RG_BOTTLE_WITH_GREEN_POTION, ITEM_POTION_GREEN, "You got a %rBottle of Green Potion%w!&Drink it to replenish your&%bmagic%w!", - "Du erhältst ein %rGrünes Elixier%w!&Nutze es, um Deine %bMagieleiste&%weinmalig komplett aufzufüllen!", + "Du erhältst ein %rGrünes Elixier%w!&Nutze es, um Deine %bMagieleiste&%weinmalig komplett aufzufüllen!", "Vous obtenez une %rBouteille avec&une Potion Verte%w! Buvez-la pour&restaurer votre %gmagie%w!"), GIMESSAGE(RG_BOTTLE_WITH_POE, ITEM_POE, - "You got a %rPoe in a Bottle%w!&That creepy Ghost Shop might&be interested in this...", - "Du hast jetzt ein %rIrrlicht in einer&Flasche%w! Der %rGespenstermarkt%w&interessiert sich für vielleicht&dafür...", - "Vous obtenez une %rBouteille avec&un Esprit%w! Ça intéresserait&peut-être le vendeur d'Âme "), + "You got a %rPoe in a Bottle%w!&That creepy Ghost Shop might&be interested in this...", + "Du hast jetzt ein %rIrrlicht in einer&Flasche%w! Der %rGespenstermarkt%w&interessiert sich für " + "vielleicht&dafür...", + "Vous obtenez une %rBouteille avec&un Esprit%w! Ça intéresserait&peut-être le vendeur d'Âme "), - GIMESSAGE(RG_GERUDO_FORTRESS_SMALL_KEY, ITEM_KEY_SMALL, - "You found a %yThieves Hideout &%wSmall Key!", - "Du erhältst einen %rkleinen&Schlüssel%w für das %yDiebesversteck%w!", - "Vous obtenez une %rPetite Clé %w&du %yRepaire des Voleurs%w!"), - GIMESSAGE(RG_FOREST_TEMPLE_SMALL_KEY, ITEM_KEY_SMALL, - "You found a %gForest Temple &%wSmall Key!", - "Du erhältst einen %rkleinen&Schlüssel%w für den %gWaldtempel%w!", - "Vous obtenez une %rPetite Clé %w&du %gTemple de la Forêt%w!"), - GIMESSAGE(RG_FIRE_TEMPLE_SMALL_KEY, ITEM_KEY_SMALL, - "You found a %rFire Temple &%wSmall Key!", - "Du erhältst einen %rkleinen&Schlüssel%w für den %rFeuertempel%w!", - "Vous obtenez une %rPetite Clé %w&du %rTemple du Feu%w!"), - GIMESSAGE(RG_WATER_TEMPLE_SMALL_KEY, ITEM_KEY_SMALL, - "You found a %bWater Temple &%wSmall Key!", - "Du erhältst einen %rkleinen&Schlüssel%w für den %bWassertempel%w!", - "Vous obtenez une %rPetite Clé %w&du %bTemple de l'Eau%w!"), - GIMESSAGE(RG_SPIRIT_TEMPLE_SMALL_KEY, ITEM_KEY_SMALL, - "You found a %ySpirit Temple &%wSmall Key!", - "Du erhältst einen %rkleinen&Schlüssel%w für den %yGeistertempel%w!", - "Vous obtenez une %rPetite Clé %w&du %yTemple de l'Esprit%w!"), - GIMESSAGE(RG_SHADOW_TEMPLE_SMALL_KEY, ITEM_KEY_SMALL, - "You found a %pShadow Temple &%wSmall Key!", - "Du erhältst einen %rkleinen&Schlüssel%w für den %pSchattentempel%w!", - "Vous obtenez une %rPetite Clé %w&du %pTemple de l'Ombre%w!"), - GIMESSAGE(RG_BOTTOM_OF_THE_WELL_SMALL_KEY, ITEM_KEY_SMALL, - "You found a %pBottom of the &Well %wSmall Key!", - "Du erhältst einen %rkleinen&Schlüssel%w für den %pGrund des Brunnens%w!", - "Vous obtenez une %rPetite Clé %w&du %pPuits%w!"), + GIMESSAGE(RG_GERUDO_FORTRESS_SMALL_KEY, ITEM_KEY_SMALL, "You found a %yThieves Hideout &%wSmall Key!", + "Du erhältst einen %rkleinen&Schlüssel%w für das %yDiebesversteck%w!", + "Vous obtenez une %rPetite Clé %w&du %yRepaire des Voleurs%w!"), + GIMESSAGE(RG_FOREST_TEMPLE_SMALL_KEY, ITEM_KEY_SMALL, "You found a %gForest Temple &%wSmall Key!", + "Du erhältst einen %rkleinen&Schlüssel%w für den %gWaldtempel%w!", + "Vous obtenez une %rPetite Clé %w&du %gTemple de la Forêt%w!"), + GIMESSAGE(RG_FIRE_TEMPLE_SMALL_KEY, ITEM_KEY_SMALL, "You found a %rFire Temple &%wSmall Key!", + "Du erhältst einen %rkleinen&Schlüssel%w für den %rFeuertempel%w!", + "Vous obtenez une %rPetite Clé %w&du %rTemple du Feu%w!"), + GIMESSAGE(RG_WATER_TEMPLE_SMALL_KEY, ITEM_KEY_SMALL, "You found a %bWater Temple &%wSmall Key!", + "Du erhältst einen %rkleinen&Schlüssel%w für den %bWassertempel%w!", + "Vous obtenez une %rPetite Clé %w&du %bTemple de l'Eau%w!"), + GIMESSAGE(RG_SPIRIT_TEMPLE_SMALL_KEY, ITEM_KEY_SMALL, "You found a %ySpirit Temple &%wSmall Key!", + "Du erhältst einen %rkleinen&Schlüssel%w für den %yGeistertempel%w!", + "Vous obtenez une %rPetite Clé %w&du %yTemple de l'Esprit%w!"), + GIMESSAGE(RG_SHADOW_TEMPLE_SMALL_KEY, ITEM_KEY_SMALL, "You found a %pShadow Temple &%wSmall Key!", + "Du erhältst einen %rkleinen&Schlüssel%w für den %pSchattentempel%w!", + "Vous obtenez une %rPetite Clé %w&du %pTemple de l'Ombre%w!"), + GIMESSAGE(RG_BOTTOM_OF_THE_WELL_SMALL_KEY, ITEM_KEY_SMALL, "You found a %pBottom of the &Well %wSmall Key!", + "Du erhältst einen %rkleinen&Schlüssel%w für den %pGrund des Brunnens%w!", + "Vous obtenez une %rPetite Clé %w&du %pPuits%w!"), GIMESSAGE(RG_GERUDO_TRAINING_GROUND_SMALL_KEY, ITEM_KEY_SMALL, - "You found a %yGerudo Training &Ground %wSmall Key!", - "Du erhältst einen %rkleinen&Schlüssel%w für das %yGerudo-Trainingsgelände%w!", - "Vous obtenez une %rPetite Clé %w&du %yGymnase Gerudo%w!"), - GIMESSAGE(RG_GANONS_CASTLE_SMALL_KEY, ITEM_KEY_SMALL, - "You found a %rGanon's Castle &%wSmall Key!", - "Du erhältst einen %rkleinen&Schlüssel%w für %rGanons Schloß%w!", - "Vous obtenez une %rPetite Clé %w&du %rChâteau de Ganon%w!"), - GIMESSAGE(RG_GUARD_HOUSE_KEY, ITEM_KEY_SMALL, - "You found the key to the&%gGuard House%w!", - "Du erhältst einen %rkleinen&Schlüssel%w für das %gHaus der Wachen%w!", - "Vous obtenez la %rClé %wde la&%gMaison des Gardes%w!"), - GIMESSAGE(RG_MARKET_BAZAAR_KEY, ITEM_KEY_SMALL, - "You found the key to the&%gMarket Bazaar%w!", - "Du erhältst einen %rkleinen&Schlüssel%w für den %gBasar des Marktes%w!", - "Vous obtenez la %rClé %wdu %gBazar&de la Place du Marché%w!"), - GIMESSAGE(RG_MARKET_POTION_SHOP_KEY, ITEM_KEY_SMALL, - "You found the key to the&%gMarket Potion Shop%w!", - "Du erhältst einen %rkleinen&Schlüssel%w für den %gMagie-Laden des Marktes%w!", - "Vous obtenez la %rClé %wde la&%gPlace du Marché%w!"), - GIMESSAGE(RG_MASK_SHOP_KEY, ITEM_KEY_SMALL, - "You found the key to the&%gMask Shop%w!", - "Du erhältst einen %rkleinen&Schlüssel%w für den %gMaskenladen%w!", - "Vous obtenez la %rClé %wde la&%gFoire aux Masques%w!"), + "You found a %yGerudo Training &Ground %wSmall Key!", + "Du erhältst einen %rkleinen&Schlüssel%w für das %yGerudo-Trainingsgelände%w!", + "Vous obtenez une %rPetite Clé %w&du %yGymnase Gerudo%w!"), + GIMESSAGE(RG_GANONS_CASTLE_SMALL_KEY, ITEM_KEY_SMALL, "You found a %rGanon's Castle &%wSmall Key!", + "Du erhältst einen %rkleinen&Schlüssel%w für %rGanons Schloß%w!", + "Vous obtenez une %rPetite Clé %w&du %rChâteau de Ganon%w!"), + GIMESSAGE(RG_GUARD_HOUSE_KEY, ITEM_KEY_SMALL, "You found the key to the&%gGuard House%w!", + "Du erhältst einen %rkleinen&Schlüssel%w für das %gHaus der Wachen%w!", + "Vous obtenez la %rClé %wde la&%gMaison des Gardes%w!"), + GIMESSAGE(RG_MARKET_BAZAAR_KEY, ITEM_KEY_SMALL, "You found the key to the&%gMarket Bazaar%w!", + "Du erhältst einen %rkleinen&Schlüssel%w für den %gBasar des Marktes%w!", + "Vous obtenez la %rClé %wdu %gBazar&de la Place du Marché%w!"), + GIMESSAGE(RG_MARKET_POTION_SHOP_KEY, ITEM_KEY_SMALL, "You found the key to the&%gMarket Potion Shop%w!", + "Du erhältst einen %rkleinen&Schlüssel%w für den %gMagie-Laden des Marktes%w!", + "Vous obtenez la %rClé %wde la&%gPlace du Marché%w!"), + GIMESSAGE(RG_MASK_SHOP_KEY, ITEM_KEY_SMALL, "You found the key to the&%gMask Shop%w!", + "Du erhältst einen %rkleinen&Schlüssel%w für den %gMaskenladen%w!", + "Vous obtenez la %rClé %wde la&%gFoire aux Masques%w!"), GIMESSAGE(RG_MARKET_SHOOTING_GALLERY_KEY, ITEM_KEY_SMALL, - "You found the key to the&%gMarket Shooting Gallery%w!", - "Du erhältst einen %rkleinen&Schlüssel%w für die %gSchießbude des Marktes%w!", - "Vous obtenez la %rClé %wdu %gStand de&Tir de la Place du Marché%w!"), - GIMESSAGE(RG_BOMBCHU_BOWLING_KEY, ITEM_KEY_SMALL, - "You found the key to the&%gBombchu Bowling Alley%w!", - "Du erhältst einen %rkleinen&Schlüssel%w für die %gMinenbowlingbahn%w!", - "Vous obtenez la %rClé %wdu %gBowling&Teigneux%w!"), + "You found the key to the&%gMarket Shooting Gallery%w!", + "Du erhältst einen %rkleinen&Schlüssel%w für die %gSchießbude des Marktes%w!", + "Vous obtenez la %rClé %wdu %gStand de&Tir de la Place du Marché%w!"), + GIMESSAGE(RG_BOMBCHU_BOWLING_KEY, ITEM_KEY_SMALL, "You found the key to the&%gBombchu Bowling Alley%w!", + "Du erhältst einen %rkleinen&Schlüssel%w für die %gMinenbowlingbahn%w!", + "Vous obtenez la %rClé %wdu %gBowling&Teigneux%w!"), GIMESSAGE(RG_TREASURE_CHEST_GAME_BUILDING_KEY, ITEM_KEY_SMALL, - "You found the key to the&%gTreasure Chest Game Building%w!", - "Du erhältst einen %rkleinen&Schlüssel%w für das %gHaus des Schatzkisten-Pokers%w!", - "Vous obtenez la %rClé %wdu %gJeu de la&Chasse au Trésor%w!"), - GIMESSAGE(RG_BOMBCHU_SHOP_KEY, ITEM_KEY_SMALL, - "You found the key to the&%gBombchu Shop%w!", - "Du erhältst einen %rkleinen&Schlüssel%w für den %gKrabbelminenladen%w!", - "Vous obtenez la %rClé %wdu %gMagasin&de Missiles%w!"), - GIMESSAGE(RG_RICHARDS_HOUSE_KEY, ITEM_KEY_SMALL, - "You found the key to&%gRichard's House%w!", - "Du erhältst einen %rkleinen&Schlüssel%w für das %gHaus von Richard%w!", - "Vous obtenez la %rClé %wde la %gMaison&de Kiki%w!"), - GIMESSAGE(RG_ALLEY_HOUSE_KEY, ITEM_KEY_SMALL, - "You found the key to&the %gAlley House%w!", - "Du erhältst einen %rkleinen&Schlüssel%w für das %gHaus in der Gasse%w!", - "Vous obtenez la %rClé %wde la %gMaison&de la Ruelle%w!"), - GIMESSAGE(RG_KAK_BAZAAR_KEY, ITEM_KEY_SMALL, - "You found the key to the&%gKakariko Bazaar%w!", - "Du erhältst einen %rkleinen&Schlüssel%w für den %gBasar von Kakariko%w!", - "Vous obtenez la %rClé %wdu %gBazar&de Cocorico%w!"), - GIMESSAGE(RG_KAK_POTION_SHOP_KEY, ITEM_KEY_SMALL, - "You found the key to the&%gKakariko Potion Shop%w!", - "Du erhältst einen %rkleinen&Schlüssel%w für den %gMagie-Laden von Kakariko%w!", - "Vous obtenez la %rClé %wdu %gMagasin de&Potions de Cocorico%w!"), - GIMESSAGE(RG_BOSS_HOUSE_KEY, ITEM_KEY_SMALL, - "You found the key to the&%gBoss's House%w!", - "Du erhältst einen %rkleinen&Schlüssel%w für das %gHaus des Chefs%w!", - "Vous obtenez la %rClé %wde la %gMaison&du chef des ouvriers%w!"), - GIMESSAGE(RG_GRANNYS_POTION_SHOP_KEY, ITEM_KEY_SMALL, - "You found the key to&%gGranny's Potion Shop%w!", - "Du erhältst einen %rkleinen&Schlüssel%w für %gAsas Hexenladen%w!", - "Vous obtenez la %rClé %wde&l'%gApothicaire%w!"), - GIMESSAGE(RG_SKULLTULA_HOUSE_KEY, ITEM_KEY_SMALL, - "You found the key to the&%gSkulltula House%w!", - "Du erhältst einen %rkleinen&Schlüssel%w für das %gSkulltula-Haus%w!", - "Vous obtenez la %rClé %wde la %gMaison&des Araignées%w!"), - GIMESSAGE(RG_IMPAS_HOUSE_KEY, ITEM_KEY_SMALL, - "You found the key to&%gImpa's House%w!", - "Du erhältst einen %rkleinen&Schlüssel%w für das %gHaus von Impa%w!", - "Vous obtenez la %rClé %wde la %gMaison&d'Impa%w!"), - GIMESSAGE(RG_WINDMILL_KEY, ITEM_KEY_SMALL, - "You found the key to the&%gWindmill%w!", - "Du erhältst einen %rkleinen&Schlüssel%w für die %gWindmühle%w!", - "Vous obtenez la %rClé %w du %gMoulin%w!"), + "You found the key to the&%gTreasure Chest Game Building%w!", + "Du erhältst einen %rkleinen&Schlüssel%w für das %gHaus des Schatzkisten-Pokers%w!", + "Vous obtenez la %rClé %wdu %gJeu de la&Chasse au Trésor%w!"), + GIMESSAGE(RG_BOMBCHU_SHOP_KEY, ITEM_KEY_SMALL, "You found the key to the&%gBombchu Shop%w!", + "Du erhältst einen %rkleinen&Schlüssel%w für den %gKrabbelminenladen%w!", + "Vous obtenez la %rClé %wdu %gMagasin&de Missiles%w!"), + GIMESSAGE(RG_RICHARDS_HOUSE_KEY, ITEM_KEY_SMALL, "You found the key to&%gRichard's House%w!", + "Du erhältst einen %rkleinen&Schlüssel%w für das %gHaus von Richard%w!", + "Vous obtenez la %rClé %wde la %gMaison&de Kiki%w!"), + GIMESSAGE(RG_ALLEY_HOUSE_KEY, ITEM_KEY_SMALL, "You found the key to&the %gAlley House%w!", + "Du erhältst einen %rkleinen&Schlüssel%w für das %gHaus in der Gasse%w!", + "Vous obtenez la %rClé %wde la %gMaison&de la Ruelle%w!"), + GIMESSAGE(RG_KAK_BAZAAR_KEY, ITEM_KEY_SMALL, "You found the key to the&%gKakariko Bazaar%w!", + "Du erhältst einen %rkleinen&Schlüssel%w für den %gBasar von Kakariko%w!", + "Vous obtenez la %rClé %wdu %gBazar&de Cocorico%w!"), + GIMESSAGE(RG_KAK_POTION_SHOP_KEY, ITEM_KEY_SMALL, "You found the key to the&%gKakariko Potion Shop%w!", + "Du erhältst einen %rkleinen&Schlüssel%w für den %gMagie-Laden von Kakariko%w!", + "Vous obtenez la %rClé %wdu %gMagasin de&Potions de Cocorico%w!"), + GIMESSAGE(RG_BOSS_HOUSE_KEY, ITEM_KEY_SMALL, "You found the key to the&%gBoss's House%w!", + "Du erhältst einen %rkleinen&Schlüssel%w für das %gHaus des Chefs%w!", + "Vous obtenez la %rClé %wde la %gMaison&du chef des ouvriers%w!"), + GIMESSAGE(RG_GRANNYS_POTION_SHOP_KEY, ITEM_KEY_SMALL, "You found the key to&%gGranny's Potion Shop%w!", + "Du erhältst einen %rkleinen&Schlüssel%w für %gAsas Hexenladen%w!", + "Vous obtenez la %rClé %wde&l'%gApothicaire%w!"), + GIMESSAGE(RG_SKULLTULA_HOUSE_KEY, ITEM_KEY_SMALL, "You found the key to the&%gSkulltula House%w!", + "Du erhältst einen %rkleinen&Schlüssel%w für das %gSkulltula-Haus%w!", + "Vous obtenez la %rClé %wde la %gMaison&des Araignées%w!"), + GIMESSAGE(RG_IMPAS_HOUSE_KEY, ITEM_KEY_SMALL, "You found the key to&%gImpa's House%w!", + "Du erhältst einen %rkleinen&Schlüssel%w für das %gHaus von Impa%w!", + "Vous obtenez la %rClé %wde la %gMaison&d'Impa%w!"), + GIMESSAGE(RG_WINDMILL_KEY, ITEM_KEY_SMALL, "You found the key to the&%gWindmill%w!", + "Du erhältst einen %rkleinen&Schlüssel%w für die %gWindmühle%w!", + "Vous obtenez la %rClé %w du %gMoulin%w!"), GIMESSAGE(RG_KAK_SHOOTING_GALLERY_KEY, ITEM_KEY_SMALL, - "You found the key to the&%gKakariko Shooting Gallery%w!", - "Du erhältst einen %rkleinen&Schlüssel%w für die %gSchießbude von Kakariko%w!", - "Vous obtenez la %rClé %w du %gStand de&Tir de Cocorico%w!"), - GIMESSAGE(RG_DAMPES_HUT_KEY, ITEM_KEY_SMALL, - "You found the key to&%gDampe's Hut%w!", - "Du erhältst einen %rkleinen&Schlüssel%w für die %gHütte von Boris%w!", - "Vous obtenez la %rClé %wde la %gCabane&d'Igor%w!"), - GIMESSAGE(RG_TALONS_HOUSE_KEY, ITEM_KEY_SMALL, - "You found the key to&%gTalon's House%w!", - "Du erhältst einen %rkleinen&Schlüssel%w für das %gHaus von Talon%w!", - "Vous obtenez la %rClé %wde la %gMaison&de Talon%w!"), - GIMESSAGE(RG_STABLES_KEY, ITEM_KEY_SMALL, - "You found the key to the&%gStables%w!", - "Du erhältst einen %rkleinen&Schlüssel%w für die %gStälle%w!", - "Vous obtenez la %rClé %wdes %gÉcuries%w!"), - GIMESSAGE(RG_BACK_TOWER_KEY, ITEM_KEY_SMALL, - "You found the key to the&%gBack Tower%w!", - "Du erhältst einen %rkleinen&Schlüssel%w für den %ghinteren Turm%w!", - "Vous obtenez la %rClé %wdu %gSilo%w!"), - GIMESSAGE(RG_HYLIA_LAB_KEY, ITEM_KEY_SMALL, - "You found the key to the&%gHylia Laboratory%w!", - "Du erhältst einen %rkleinen&Schlüssel%w für das %gHylia-Labor%w!", - "Vous obtenez la %rClé %wdu %gLaboratoire&du Lac Hylia%w!"), - GIMESSAGE(RG_FISHING_HOLE_KEY, ITEM_KEY_SMALL, - "You found the key to the&%gPond%w!", - "Du erhältst einen %rkleinen&Schlüssel%w für den %gFischweiher%w!", - "Vous obtenez la %rClé %wde l'%gÉtang%w!"), + "You found the key to the&%gKakariko Shooting Gallery%w!", + "Du erhältst einen %rkleinen&Schlüssel%w für die %gSchießbude von Kakariko%w!", + "Vous obtenez la %rClé %w du %gStand de&Tir de Cocorico%w!"), + GIMESSAGE(RG_DAMPES_HUT_KEY, ITEM_KEY_SMALL, "You found the key to&%gDampe's Hut%w!", + "Du erhältst einen %rkleinen&Schlüssel%w für die %gHütte von Boris%w!", + "Vous obtenez la %rClé %wde la %gCabane&d'Igor%w!"), + GIMESSAGE(RG_TALONS_HOUSE_KEY, ITEM_KEY_SMALL, "You found the key to&%gTalon's House%w!", + "Du erhältst einen %rkleinen&Schlüssel%w für das %gHaus von Talon%w!", + "Vous obtenez la %rClé %wde la %gMaison&de Talon%w!"), + GIMESSAGE(RG_STABLES_KEY, ITEM_KEY_SMALL, "You found the key to the&%gStables%w!", + "Du erhältst einen %rkleinen&Schlüssel%w für die %gStälle%w!", + "Vous obtenez la %rClé %wdes %gÉcuries%w!"), + GIMESSAGE(RG_BACK_TOWER_KEY, ITEM_KEY_SMALL, "You found the key to the&%gBack Tower%w!", + "Du erhältst einen %rkleinen&Schlüssel%w für den %ghinteren Turm%w!", + "Vous obtenez la %rClé %wdu %gSilo%w!"), + GIMESSAGE(RG_HYLIA_LAB_KEY, ITEM_KEY_SMALL, "You found the key to the&%gHylia Laboratory%w!", + "Du erhältst einen %rkleinen&Schlüssel%w für das %gHylia-Labor%w!", + "Vous obtenez la %rClé %wdu %gLaboratoire&du Lac Hylia%w!"), + GIMESSAGE(RG_FISHING_HOLE_KEY, ITEM_KEY_SMALL, "You found the key to the&%gPond%w!", + "Du erhältst einen %rkleinen&Schlüssel%w für den %gFischweiher%w!", + "Vous obtenez la %rClé %wde l'%gÉtang%w!"), - GIMESSAGE(RG_GERUDO_FORTRESS_KEY_RING, ITEM_KEY_SMALL, - "You found a %yThieves Hideout&%wKeyring!", - "Du erhältst ein %rSchlüsselbund%w&für das %yDiebesversteck%w!", - "Vous obtenez le trousseau de&clés du %yRepaire des Voleurs%w!"), - GIMESSAGE(RG_FOREST_TEMPLE_KEY_RING, ITEM_KEY_SMALL, - "You found a %gForest Temple&%wKeyring!", - "Du erhältst ein %rSchlüsselbund%w&für den %gWaldtempel%w!", - "Vous obtenez le trousseau de&clés du %gTemple de la Forêt%w!"), - GIMESSAGE(RG_FIRE_TEMPLE_KEY_RING, ITEM_KEY_SMALL, - "You found a %rFire Temple&%wKeyring!", - "Du erhältst ein %rSchlüsselbund%w&für den %rFeuertempel%w!", - "Vous obtenez le trousseau de&clés du %rTemple du Feu%w!"), - GIMESSAGE(RG_WATER_TEMPLE_KEY_RING, ITEM_KEY_SMALL, - "You found a %bWater Temple&%wKeyring!", - "Du erhältst ein %rSchlüsselbund%w&für den %bWassertempel%w!", - "Vous obtenez le trousseau de&clés du %bTemple de l'Eau%w!"), - GIMESSAGE(RG_SPIRIT_TEMPLE_KEY_RING, ITEM_KEY_SMALL, - "You found a %ySpirit Temple&%wKeyring!", - "Du erhältst ein %rSchlüsselbund%w&für den %yGeistertempel%w!", - "Vous obtenez le trousseau de&clés du %yTemple de l'Esprit%w!"), - GIMESSAGE(RG_SHADOW_TEMPLE_KEY_RING, ITEM_KEY_SMALL, - "You found a %pShadow Temple&%wKeyring!", - "Du erhältst ein %rSchlüsselbund%w&für den %pSchattentempel%w!", - "Vous obtenez le trousseau de&clés du %pTemple de l'Ombre%w!"), - GIMESSAGE(RG_BOTTOM_OF_THE_WELL_KEY_RING, ITEM_KEY_SMALL, - "You found a %pBottom of the&Well %wKeyring!", - "Du erhältst ein %rSchlüsselbund%w&für den %pGrund des Brunnens%w!", - "Vous obtenez le trousseau de&clés du %pPuits%w!"), - GIMESSAGE(RG_GERUDO_TRAINING_GROUND_KEY_RING, ITEM_KEY_SMALL, - "You found a %yGerudo Training&Ground %wKeyring!", - "Du erhältst ein %rSchlüsselbund%w&für das %yGerudo-Trainingsgelände%w!", - "Vous obtenez le trousseau de&clés du %yGymnase Gerudo%w!"), - GIMESSAGE(RG_GANONS_CASTLE_KEY_RING, ITEM_KEY_SMALL, - "You found a %rGanon's Castle&%wKeyring!", - "Du erhältst ein %rSchlüsselbund%w&für %rGanons Schloß%w!", - "Vous obtenez le trousseau de&clés du %rChâteau de Ganon%w!"), - GIMESSAGE(RG_TREASURE_GAME_KEY_RING, ITEM_KEY_SMALL, - "You found a %rTreasure Chest Game&%wKeyring!", - "Du erhältst ein %rSchlüsselbund%w& für das %rSchatztruhen-Poker&%w!", - "Vous obtenez le trousseau de&clés du %rJeu de la Chasse au Trésor%w!"), + GIMESSAGE(RG_GERUDO_FORTRESS_KEY_RING, ITEM_KEY_SMALL, "You found a %yThieves Hideout&%wKeyring!", + "Du erhältst ein %rSchlüsselbund%w&für das %yDiebesversteck%w!", + "Vous obtenez le trousseau de&clés du %yRepaire des Voleurs%w!"), + GIMESSAGE(RG_FOREST_TEMPLE_KEY_RING, ITEM_KEY_SMALL, "You found a %gForest Temple&%wKeyring!", + "Du erhältst ein %rSchlüsselbund%w&für den %gWaldtempel%w!", + "Vous obtenez le trousseau de&clés du %gTemple de la Forêt%w!"), + GIMESSAGE(RG_FIRE_TEMPLE_KEY_RING, ITEM_KEY_SMALL, "You found a %rFire Temple&%wKeyring!", + "Du erhältst ein %rSchlüsselbund%w&für den %rFeuertempel%w!", + "Vous obtenez le trousseau de&clés du %rTemple du Feu%w!"), + GIMESSAGE(RG_WATER_TEMPLE_KEY_RING, ITEM_KEY_SMALL, "You found a %bWater Temple&%wKeyring!", + "Du erhältst ein %rSchlüsselbund%w&für den %bWassertempel%w!", + "Vous obtenez le trousseau de&clés du %bTemple de l'Eau%w!"), + GIMESSAGE(RG_SPIRIT_TEMPLE_KEY_RING, ITEM_KEY_SMALL, "You found a %ySpirit Temple&%wKeyring!", + "Du erhältst ein %rSchlüsselbund%w&für den %yGeistertempel%w!", + "Vous obtenez le trousseau de&clés du %yTemple de l'Esprit%w!"), + GIMESSAGE(RG_SHADOW_TEMPLE_KEY_RING, ITEM_KEY_SMALL, "You found a %pShadow Temple&%wKeyring!", + "Du erhältst ein %rSchlüsselbund%w&für den %pSchattentempel%w!", + "Vous obtenez le trousseau de&clés du %pTemple de l'Ombre%w!"), + GIMESSAGE(RG_BOTTOM_OF_THE_WELL_KEY_RING, ITEM_KEY_SMALL, "You found a %pBottom of the&Well %wKeyring!", + "Du erhältst ein %rSchlüsselbund%w&für den %pGrund des Brunnens%w!", + "Vous obtenez le trousseau de&clés du %pPuits%w!"), + GIMESSAGE(RG_GERUDO_TRAINING_GROUND_KEY_RING, ITEM_KEY_SMALL, "You found a %yGerudo Training&Ground %wKeyring!", + "Du erhältst ein %rSchlüsselbund%w&für das %yGerudo-Trainingsgelände%w!", + "Vous obtenez le trousseau de&clés du %yGymnase Gerudo%w!"), + GIMESSAGE(RG_GANONS_CASTLE_KEY_RING, ITEM_KEY_SMALL, "You found a %rGanon's Castle&%wKeyring!", + "Du erhältst ein %rSchlüsselbund%w&für %rGanons Schloß%w!", + "Vous obtenez le trousseau de&clés du %rChâteau de Ganon%w!"), + GIMESSAGE(RG_TREASURE_GAME_KEY_RING, ITEM_KEY_SMALL, "You found a %rTreasure Chest Game&%wKeyring!", + "Du erhältst ein %rSchlüsselbund%w& für das %rSchatztruhen-Poker&%w!", + "Vous obtenez le trousseau de&clés du %rJeu de la Chasse au Trésor%w!"), - GIMESSAGE(RG_FOREST_TEMPLE_BOSS_KEY, ITEM_KEY_BOSS, - "You found the %gForest Temple&%wBoss Key!", - "Du erhältst den %rMaster-Schlüssel%w&für den %gWaldtempel%w!", - "Vous obtenez la %rClé d'or %wdu&%gTemple de la Forêt%w!"), - GIMESSAGE(RG_FIRE_TEMPLE_BOSS_KEY, ITEM_KEY_BOSS, - "You found the %rFire Temple&%wBoss Key!", - "Du erhältst den %rMaster-Schlüssel%w&für den %rFeuertempel%w!", - "Vous obtenez la %rClé d'or %wdu&%rTemple du Feu%w!"), - GIMESSAGE(RG_WATER_TEMPLE_BOSS_KEY, ITEM_KEY_BOSS, - "You found the %bWater Temple&%wBoss Key!", - "Du erhältst den %rMaster-Schlüssel%w&für den %bWassertempel%w!", - "Vous obtenez la %rClé d'or %wdu&%bTemple de l'Eau%w!"), - GIMESSAGE(RG_SPIRIT_TEMPLE_BOSS_KEY, ITEM_KEY_BOSS, - "You found the %ySpirit Temple&%wBoss Key!", - "Du erhältst den %rMaster-Schlüssel%w&für den %yGeistertempel%w!", - "Vous obtenez la %rClé d'or %wdu&%yTemple de l'Esprit%w!"), - GIMESSAGE(RG_SHADOW_TEMPLE_BOSS_KEY, ITEM_KEY_BOSS, - "You found the %pShadow Temple&%wBoss Key!", - "Du erhältst den %rMaster-Schlüssel%w&für den %pSchattentempel%w!", - "Vous obtenez la %rClé d'or %wdu&%pTemple de l'Ombre%w!"), - GIMESSAGE(RG_GANONS_CASTLE_BOSS_KEY, ITEM_KEY_BOSS, - "You found the %rGanon's Castle&%wBoss Key!", - "Du erhältst den %rMaster-Schlüssel%w&für %rGanons Schloß%w!", - "Vous obtenez la %rClé d'or %wdu&%rChâteau de Ganon%w!"), + GIMESSAGE(RG_FOREST_TEMPLE_BOSS_KEY, ITEM_KEY_BOSS, "You found the %gForest Temple&%wBoss Key!", + "Du erhältst den %rMaster-Schlüssel%w&für den %gWaldtempel%w!", + "Vous obtenez la %rClé d'or %wdu&%gTemple de la Forêt%w!"), + GIMESSAGE(RG_FIRE_TEMPLE_BOSS_KEY, ITEM_KEY_BOSS, "You found the %rFire Temple&%wBoss Key!", + "Du erhältst den %rMaster-Schlüssel%w&für den %rFeuertempel%w!", + "Vous obtenez la %rClé d'or %wdu&%rTemple du Feu%w!"), + GIMESSAGE(RG_WATER_TEMPLE_BOSS_KEY, ITEM_KEY_BOSS, "You found the %bWater Temple&%wBoss Key!", + "Du erhältst den %rMaster-Schlüssel%w&für den %bWassertempel%w!", + "Vous obtenez la %rClé d'or %wdu&%bTemple de l'Eau%w!"), + GIMESSAGE(RG_SPIRIT_TEMPLE_BOSS_KEY, ITEM_KEY_BOSS, "You found the %ySpirit Temple&%wBoss Key!", + "Du erhältst den %rMaster-Schlüssel%w&für den %yGeistertempel%w!", + "Vous obtenez la %rClé d'or %wdu&%yTemple de l'Esprit%w!"), + GIMESSAGE(RG_SHADOW_TEMPLE_BOSS_KEY, ITEM_KEY_BOSS, "You found the %pShadow Temple&%wBoss Key!", + "Du erhältst den %rMaster-Schlüssel%w&für den %pSchattentempel%w!", + "Vous obtenez la %rClé d'or %wdu&%pTemple de l'Ombre%w!"), + GIMESSAGE(RG_GANONS_CASTLE_BOSS_KEY, ITEM_KEY_BOSS, "You found the %rGanon's Castle&%wBoss Key!", + "Du erhältst den %rMaster-Schlüssel%w&für %rGanons Schloß%w!", + "Vous obtenez la %rClé d'or %wdu&%rChâteau de Ganon%w!"), - GIMESSAGE(RG_DEKU_TREE_MAP, ITEM_DUNGEON_MAP, - "You found the %gDeku Tree&%wMap![[typeHint]]", - "Du erhältst die %rKarte%w für den&%gDeku-Baum%w![[typeHint]]", - "Vous obtenez la %rCarte %wde&l'%gArbre Mojo%w![[typeHint]]"), - GIMESSAGE(RG_DODONGOS_CAVERN_MAP, ITEM_DUNGEON_MAP, - "You found the %rDodongo's Cavern&%wMap![[typeHint]]", - "Du erhältst die %rKarte%w für&%rDodongos Höhle%w![[typeHint]]", - "Vous obtenez la %rCarte %wde la&%rCaverne Dodongo%w![[typeHint]]"), - GIMESSAGE(RG_JABU_JABUS_BELLY_MAP, ITEM_DUNGEON_MAP, - "You found the %bJabu Jabu's Belly&%wMap![[typeHint]]", - "Du erhältst die %rKarte%w für&%bJabu-Jabus Bauch%w![[typeHint]]", - "Vous obtenez la %rCarte %wdu&%bVentre de Jabu-Jabu%w![[typeHint]]"), - GIMESSAGE(RG_FOREST_TEMPLE_MAP, ITEM_DUNGEON_MAP, - "You found the %gForest Temple&%wMap![[typeHint]]", - "Du erhältst die %rKarte%w für den&%gWaldtempel%w![[typeHint]]", - "Vous obtenez la %rCarte %wdu&%gTemple de la Forêt%w![[typeHint]]"), - GIMESSAGE(RG_FIRE_TEMPLE_MAP, ITEM_DUNGEON_MAP, - "You found the %rFire Temple&%wMap![[typeHint]]", - "Du erhältst die %rKarte%w für den&%rFeuertempel%w![[typeHint]]", - "Vous obtenez la %rCarte %wdu&%rTemple du Feu%w![[typeHint]]"), - GIMESSAGE(RG_WATER_TEMPLE_MAP, ITEM_DUNGEON_MAP, - "You found the %bWater Temple&%wMap![[typeHint]]", - "Du erhältst die %rKarte%w für den&%bWassertempel%w![[typeHint]]", - "Vous obtenez la %rCarte %wdu&%bTemple de l'Eau%w![[typeHint]]"), - GIMESSAGE(RG_SPIRIT_TEMPLE_MAP, ITEM_DUNGEON_MAP, - "You found the %ySpirit Temple&%wMap![[typeHint]]", - "Du erhältst die %rKarte%w für den&%yGeistertempel%w![[typeHint]]", - "Vous obtenez la %rCarte %wdu&%yTemple de l'Esprit%w![[typeHint]]"), - GIMESSAGE(RG_SHADOW_TEMPLE_MAP, ITEM_DUNGEON_MAP, - "You found the %pShadow Temple&%wMap![[typeHint]]", - "Du erhältst die %rKarte%w für den&%pSchattentempel%w![[typeHint]]", - "Vous obtenez la %rCarte %wdu&%pTemple de l'Ombre%w![[typeHint]]"), - GIMESSAGE(RG_BOTTOM_OF_THE_WELL_MAP, ITEM_DUNGEON_MAP, - "You found the %pBottom of the&Well %wMap![[typeHint]]", - "Du erhältst die %rKarte%w für den&%pGrund des Brunnens%w![[typeHint]]", - "Vous obtenez la %rCarte %wdu&%pPuits%w![[typeHint]]"), - GIMESSAGE(RG_ICE_CAVERN_MAP, ITEM_DUNGEON_MAP, - "You found the %cIce Cavern&%wMap![[typeHint]]", - "Du erhältst die %rKarte%w für die&%cEishöhle%w![[typeHint]]", - "Vous obtenez la %rCarte %wde&la %cCaverne Polaire%w![[typeHint]]"), + GIMESSAGE(RG_DEKU_TREE_MAP, ITEM_DUNGEON_MAP, "You found the %gDeku Tree&%wMap![[typeHint]]", + "Du erhältst die %rKarte%w für den&%gDeku-Baum%w![[typeHint]]", + "Vous obtenez la %rCarte %wde&l'%gArbre Mojo%w![[typeHint]]"), + GIMESSAGE(RG_DODONGOS_CAVERN_MAP, ITEM_DUNGEON_MAP, "You found the %rDodongo's Cavern&%wMap![[typeHint]]", + "Du erhältst die %rKarte%w für&%rDodongos Höhle%w![[typeHint]]", + "Vous obtenez la %rCarte %wde la&%rCaverne Dodongo%w![[typeHint]]"), + GIMESSAGE(RG_JABU_JABUS_BELLY_MAP, ITEM_DUNGEON_MAP, "You found the %bJabu Jabu's Belly&%wMap![[typeHint]]", + "Du erhältst die %rKarte%w für&%bJabu-Jabus Bauch%w![[typeHint]]", + "Vous obtenez la %rCarte %wdu&%bVentre de Jabu-Jabu%w![[typeHint]]"), + GIMESSAGE(RG_FOREST_TEMPLE_MAP, ITEM_DUNGEON_MAP, "You found the %gForest Temple&%wMap![[typeHint]]", + "Du erhältst die %rKarte%w für den&%gWaldtempel%w![[typeHint]]", + "Vous obtenez la %rCarte %wdu&%gTemple de la Forêt%w![[typeHint]]"), + GIMESSAGE(RG_FIRE_TEMPLE_MAP, ITEM_DUNGEON_MAP, "You found the %rFire Temple&%wMap![[typeHint]]", + "Du erhältst die %rKarte%w für den&%rFeuertempel%w![[typeHint]]", + "Vous obtenez la %rCarte %wdu&%rTemple du Feu%w![[typeHint]]"), + GIMESSAGE(RG_WATER_TEMPLE_MAP, ITEM_DUNGEON_MAP, "You found the %bWater Temple&%wMap![[typeHint]]", + "Du erhältst die %rKarte%w für den&%bWassertempel%w![[typeHint]]", + "Vous obtenez la %rCarte %wdu&%bTemple de l'Eau%w![[typeHint]]"), + GIMESSAGE(RG_SPIRIT_TEMPLE_MAP, ITEM_DUNGEON_MAP, "You found the %ySpirit Temple&%wMap![[typeHint]]", + "Du erhältst die %rKarte%w für den&%yGeistertempel%w![[typeHint]]", + "Vous obtenez la %rCarte %wdu&%yTemple de l'Esprit%w![[typeHint]]"), + GIMESSAGE(RG_SHADOW_TEMPLE_MAP, ITEM_DUNGEON_MAP, "You found the %pShadow Temple&%wMap![[typeHint]]", + "Du erhältst die %rKarte%w für den&%pSchattentempel%w![[typeHint]]", + "Vous obtenez la %rCarte %wdu&%pTemple de l'Ombre%w![[typeHint]]"), + GIMESSAGE(RG_BOTTOM_OF_THE_WELL_MAP, ITEM_DUNGEON_MAP, "You found the %pBottom of the&Well %wMap![[typeHint]]", + "Du erhältst die %rKarte%w für den&%pGrund des Brunnens%w![[typeHint]]", + "Vous obtenez la %rCarte %wdu&%pPuits%w![[typeHint]]"), + GIMESSAGE(RG_ICE_CAVERN_MAP, ITEM_DUNGEON_MAP, "You found the %cIce Cavern&%wMap![[typeHint]]", + "Du erhältst die %rKarte%w für die&%cEishöhle%w![[typeHint]]", + "Vous obtenez la %rCarte %wde&la %cCaverne Polaire%w![[typeHint]]"), - GIMESSAGE(RG_DEKU_TREE_COMPASS, ITEM_COMPASS, - "You found the %gDeku Tree&%wCompass!", - "Du erhältst den %rKompaß%w für den&%gDeku-Baum%w!", - "Vous obtenez la %rBoussole %wde&l'%gArbre Mojo%w!"), - GIMESSAGE(RG_DODONGOS_CAVERN_COMPASS, ITEM_COMPASS, - "You found the %rDodongo's Cavern&%wCompass!", - "Du erhältst den %rKompaß%w für&%rDodongos Höhle%w!", - "Vous obtenez la %rBoussole %wde la&%rCaverne Dodongo%w!"), - GIMESSAGE(RG_JABU_JABUS_BELLY_COMPASS, ITEM_COMPASS, - "You found the %bJabu Jabu's Belly&%wCompass!", - "Du erhältst den %rKompaß%w für den&%bJabu-Jabus Bauch%w!", - "Vous obtenez la %rBoussole %wdu&%bVentre de Jabu-Jabu%w!"), - GIMESSAGE(RG_FOREST_TEMPLE_COMPASS, ITEM_COMPASS, - "You found the %gForest Temple&%wCompass!", - "Du erhältst den %rKompaß%w für den&%gWaldtempel%w!", - "Vous obtenez la %rBoussole %wdu&%gTemple de la Forêt%w!"), - GIMESSAGE(RG_FIRE_TEMPLE_COMPASS, ITEM_COMPASS, - "You found the %rFire Temple&%wCompass!", - "Du erhältst den %rKompaß%w für den&%rFeuertempel%w!", - "Vous obtenez la %rBoussole %wdu&%rTemple du Feu%w!"), - GIMESSAGE(RG_WATER_TEMPLE_COMPASS, ITEM_COMPASS, - "You found the %bWater Temple&%wCompass!", - "Du erhältst den %rKompaß%w für den&%bWassertempel%w!", - "Vous obtenez la %rBoussole %wdu&%bTemple de l'Eau%w!"), - GIMESSAGE(RG_SPIRIT_TEMPLE_COMPASS, ITEM_COMPASS, - "You found the %ySpirit Temple&%wCompass!", - "Du erhältst den %rKompaß%w für den&%yGeistertempel%w!", - "Vous obtenez la %rBoussole %wdu&%yTemple de l'Esprit%w!"), - GIMESSAGE(RG_SHADOW_TEMPLE_COMPASS, ITEM_COMPASS, - "You found the %pShadow Temple&%wCompass!", - "Du erhältst den %rKompaß%w für den&%pSchattentempel%w!", - "Vous obtenez la %rBoussole %wdu&%pTemple de l'Ombre%w!"), - GIMESSAGE(RG_BOTTOM_OF_THE_WELL_COMPASS, ITEM_COMPASS, - "You found the %pBottom of the&Well %wCompass!", - "Du erhältst den %rKompaß%w für den&%pGrund des Brunnens%w!", - "Vous obtenez la %rBoussole %wdu&%pPuits%w!"), - GIMESSAGE(RG_ICE_CAVERN_COMPASS, ITEM_COMPASS, - "You found the %cIce Cavern&%wCompass!", - "Du erhältst den %rKompaß%w für die&%cEishöhle%w!", - "Vous obtenez la %rBoussole %wde&la %cCaverne Polaire%w!"), + GIMESSAGE(RG_DEKU_TREE_COMPASS, ITEM_COMPASS, "You found the %gDeku Tree&%wCompass!", + "Du erhältst den %rKompaß%w für den&%gDeku-Baum%w!", + "Vous obtenez la %rBoussole %wde&l'%gArbre Mojo%w!"), + GIMESSAGE(RG_DODONGOS_CAVERN_COMPASS, ITEM_COMPASS, "You found the %rDodongo's Cavern&%wCompass!", + "Du erhältst den %rKompaß%w für&%rDodongos Höhle%w!", + "Vous obtenez la %rBoussole %wde la&%rCaverne Dodongo%w!"), + GIMESSAGE(RG_JABU_JABUS_BELLY_COMPASS, ITEM_COMPASS, "You found the %bJabu Jabu's Belly&%wCompass!", + "Du erhältst den %rKompaß%w für den&%bJabu-Jabus Bauch%w!", + "Vous obtenez la %rBoussole %wdu&%bVentre de Jabu-Jabu%w!"), + GIMESSAGE(RG_FOREST_TEMPLE_COMPASS, ITEM_COMPASS, "You found the %gForest Temple&%wCompass!", + "Du erhältst den %rKompaß%w für den&%gWaldtempel%w!", + "Vous obtenez la %rBoussole %wdu&%gTemple de la Forêt%w!"), + GIMESSAGE(RG_FIRE_TEMPLE_COMPASS, ITEM_COMPASS, "You found the %rFire Temple&%wCompass!", + "Du erhältst den %rKompaß%w für den&%rFeuertempel%w!", + "Vous obtenez la %rBoussole %wdu&%rTemple du Feu%w!"), + GIMESSAGE(RG_WATER_TEMPLE_COMPASS, ITEM_COMPASS, "You found the %bWater Temple&%wCompass!", + "Du erhältst den %rKompaß%w für den&%bWassertempel%w!", + "Vous obtenez la %rBoussole %wdu&%bTemple de l'Eau%w!"), + GIMESSAGE(RG_SPIRIT_TEMPLE_COMPASS, ITEM_COMPASS, "You found the %ySpirit Temple&%wCompass!", + "Du erhältst den %rKompaß%w für den&%yGeistertempel%w!", + "Vous obtenez la %rBoussole %wdu&%yTemple de l'Esprit%w!"), + GIMESSAGE(RG_SHADOW_TEMPLE_COMPASS, ITEM_COMPASS, "You found the %pShadow Temple&%wCompass!", + "Du erhältst den %rKompaß%w für den&%pSchattentempel%w!", + "Vous obtenez la %rBoussole %wdu&%pTemple de l'Ombre%w!"), + GIMESSAGE(RG_BOTTOM_OF_THE_WELL_COMPASS, ITEM_COMPASS, "You found the %pBottom of the&Well %wCompass!", + "Du erhältst den %rKompaß%w für den&%pGrund des Brunnens%w!", + "Vous obtenez la %rBoussole %wdu&%pPuits%w!"), + GIMESSAGE(RG_ICE_CAVERN_COMPASS, ITEM_COMPASS, "You found the %cIce Cavern&%wCompass!", + "Du erhältst den %rKompaß%w für die&%cEishöhle%w!", + "Vous obtenez la %rBoussole %wde&la %cCaverne Polaire%w!"), GIMESSAGE(RG_MAGIC_BEAN_PACK, ITEM_BEAN, - "You got a %rPack of Magic Beans%w!&Find a suitable spot for a garden&and plant them. Then, wait for&something fun to happen!", - "Du erhältst eine %rPackung&Wundererbsen%w! Suche nach einer&Stelle um sie einzupflanzen.&Warte ab, was passiert!", - "Vous obtenez un %rPaquet de&Haricots Magiques%w! Trouvez&un endroit approprié pour un&jardin et plantez-les.^Attendez ensuite que quelque&chose d'amusant se produise!"), + "You got a %rPack of Magic Beans%w!&Find a suitable spot for a garden&and plant them. Then, wait " + "for&something fun to happen!", + "Du erhältst eine %rPackung&Wundererbsen%w! Suche nach einer&Stelle um sie einzupflanzen.&Warte ab, " + "was passiert!", + "Vous obtenez un %rPaquet de&Haricots Magiques%w! Trouvez&un endroit approprié pour un&jardin et " + "plantez-les.^Attendez ensuite que quelque&chose d'amusant se produise!"), GIMESSAGE(RG_TYCOON_WALLET, ITEM_WALLET_GIANT, - "You got a %rTycoon's Wallet%w!&It's gigantic! Now you can carry&up to %y999 rupees%w!", - "Du erhältst die %rGoldene&Geldbörse%w! Die größte aller&Geldbörsen! Jetzt kannst Du bis&zu %y999 Rubine%w mit Dir führen!", - "Vous obtenez la %rBourse de Magnat%w!&Elle peut contenir jusqu'à %y999 rubis%w!&C'est gigantesque!"), + "You got a %rTycoon's Wallet%w!&It's gigantic! Now you can carry&up to %y999 rupees%w!", + "Du erhältst die %rGoldene&Geldbörse%w! Die größte aller&Geldbörsen! Jetzt kannst Du bis&zu %y999 " + "Rubine%w mit Dir führen!", + "Vous obtenez la %rBourse de Magnat%w!&Elle peut contenir jusqu'à %y999 rubis%w!&C'est gigantesque!"), GIMESSAGE(RG_CHILD_WALLET, ITEM_WALLET_ADULT, - "You got a %rChild's Wallet%w!&Now you can carry&up to %y99 rupees%w!", - "Du erhältst die %rKindergeldbörse%w!&Jetzt kannst Du bis&zu %y99 Rubine%w mit Dir führen!", - "Vous obtenez la %rPetite Bourse%w!&Elle peut contenir jusqu'à %y99 rubis%w!"), + "You got a %rChild's Wallet%w!&Now you can carry&up to %y99 rupees%w!", + "Du erhältst die %rKindergeldbörse%w!&Jetzt kannst Du bis&zu %y99 Rubine%w mit Dir führen!", + "Vous obtenez la %rPetite Bourse%w!&Elle peut contenir jusqu'à %y99 rubis%w!"), - GIMESSAGE(RG_GOHMA_SOUL, ITEM_BIG_POE, - "You found the soul for %gGohma%w!", - "Du hast die Seele von %gGohma%w gefunden!", - "Vous obtenez l'âme de %gGohma%w!"), - GIMESSAGE(RG_KING_DODONGO_SOUL, ITEM_BIG_POE, - "You found the soul for %rKing&Dodongo%w!", - "Du hast die Seele von %rKönig&Dodongo%w gefunden!", - "Vous obtenez l'âme du %rRoi Dodongo%w!"), - GIMESSAGE(RG_BARINADE_SOUL, ITEM_BIG_POE, - "You found the soul for %bBarinade%w!", - "Du hast die Seele von %bBarinade%w gefunden!", - "Vous obtenez l'âme de %bBarinade%w!"), - GIMESSAGE(RG_PHANTOM_GANON_SOUL, ITEM_BIG_POE, - "You found the soul for %gPhantom&Ganon%w!", - "Du hast die Seele von %gPhantom-&Ganon%w gefunden!", - "Vous obtenez l'âme de %gGanon&Spectral%w!"), - GIMESSAGE(RG_VOLVAGIA_SOUL, ITEM_BIG_POE, - "You found the soul for %rVolvagia%w!", - "Du hast die Seele von %rVolvagia%w gefunden!", - "Vous obtenez l'âme de %rVolcania%w!"), - GIMESSAGE(RG_MORPHA_SOUL, ITEM_BIG_POE, - "You found the soul for %bMorpha%w!", - "Du hast die Seele von %bMorpha%w gefunden!", - "Vous obtenez l'âme de %bMorpha%w!"), - GIMESSAGE(RG_BONGO_BONGO_SOUL, ITEM_BIG_POE, - "You found the soul for %pBongo&Bongo%w!", - "Du hast die Seele von %pBongo&Bongo%w gefunden!", - "Vous obtenez l'âme de %pBongo&Bongo%w!"), - GIMESSAGE(RG_TWINROVA_SOUL, ITEM_BIG_POE, - "You found the soul for %yTwinrova%w!", - "Du hast die Seele von %yTwinrova%w gefunden!", - "Vous obtenez l'âme du %yDuo&Maléfique%w!"), - GIMESSAGE(RG_GANON_SOUL, ITEM_BIG_POE, - "You found the soul for %cGanon%w!", - "Du hast die Seele von %cGanon%w gefunden!", - "Vous obtenez l'âme de %cGanon%w!"), + GIMESSAGE(RG_GOHMA_SOUL, ITEM_BIG_POE, "You found the soul for %gGohma%w!", + "Du hast die Seele von %gGohma%w gefunden!", "Vous obtenez l'âme de %gGohma%w!"), + GIMESSAGE(RG_KING_DODONGO_SOUL, ITEM_BIG_POE, "You found the soul for %rKing&Dodongo%w!", + "Du hast die Seele von %rKönig&Dodongo%w gefunden!", "Vous obtenez l'âme du %rRoi Dodongo%w!"), + GIMESSAGE(RG_BARINADE_SOUL, ITEM_BIG_POE, "You found the soul for %bBarinade%w!", + "Du hast die Seele von %bBarinade%w gefunden!", "Vous obtenez l'âme de %bBarinade%w!"), + GIMESSAGE(RG_PHANTOM_GANON_SOUL, ITEM_BIG_POE, "You found the soul for %gPhantom&Ganon%w!", + "Du hast die Seele von %gPhantom-&Ganon%w gefunden!", "Vous obtenez l'âme de %gGanon&Spectral%w!"), + GIMESSAGE(RG_VOLVAGIA_SOUL, ITEM_BIG_POE, "You found the soul for %rVolvagia%w!", + "Du hast die Seele von %rVolvagia%w gefunden!", "Vous obtenez l'âme de %rVolcania%w!"), + GIMESSAGE(RG_MORPHA_SOUL, ITEM_BIG_POE, "You found the soul for %bMorpha%w!", + "Du hast die Seele von %bMorpha%w gefunden!", "Vous obtenez l'âme de %bMorpha%w!"), + GIMESSAGE(RG_BONGO_BONGO_SOUL, ITEM_BIG_POE, "You found the soul for %pBongo&Bongo%w!", + "Du hast die Seele von %pBongo&Bongo%w gefunden!", "Vous obtenez l'âme de %pBongo&Bongo%w!"), + GIMESSAGE(RG_TWINROVA_SOUL, ITEM_BIG_POE, "You found the soul for %yTwinrova%w!", + "Du hast die Seele von %yTwinrova%w gefunden!", "Vous obtenez l'âme du %yDuo&Maléfique%w!"), + GIMESSAGE(RG_GANON_SOUL, ITEM_BIG_POE, "You found the soul for %cGanon%w!", + "Du hast die Seele von %cGanon%w gefunden!", "Vous obtenez l'âme de %cGanon%w!"), GIMESSAGE(RG_OCARINA_A_BUTTON, ITEM_OCARINA_TIME, - "You got the %b\x9f%r button for the&Ocarina%w! You can now use it&while playing songs!", - "Der %b\x9f%r Knopf%w!&Du kannst ihn nun zum Spielen&von Liedern auf der %rOkarina%w&verwenden!", - "Vous obtenez la %rtouche %b\x9f%r de&l'Ocarina%w! Vous pouvez&maintenant l'utiliser lorsque&vous en jouez!"), + "You got the %b\x9f%r button for the&Ocarina%w! You can now use it&while playing songs!", + "Der %b\x9f%r Knopf%w!&Du kannst ihn nun zum Spielen&von Liedern auf der %rOkarina%w&verwenden!", + "Vous obtenez la %rtouche %b\x9f%r de&l'Ocarina%w! Vous pouvez&maintenant l'utiliser lorsque&vous en " + "jouez!"), GIMESSAGE(RG_OCARINA_C_LEFT_BUTTON, ITEM_OCARINA_TIME, - "You got the %y\xa7%r button for the&Ocarina%w! You can now use it&while playing songs!", - "Der %y\xa7%r Knopf%w!&Du kannst ihn nun zum Spielen&von Liedern auf der %rOkarina%w&verwenden!", - "Vous obtenez la %rtouche %y\xa7%r de&l'Ocarina%w! Vous pouvez&maintenant l'utiliser lorsque&vous en jouez!"), + "You got the %y\xa7%r button for the&Ocarina%w! You can now use it&while playing songs!", + "Der %y\xa7%r Knopf%w!&Du kannst ihn nun zum Spielen&von Liedern auf der %rOkarina%w&verwenden!", + "Vous obtenez la %rtouche %y\xa7%r de&l'Ocarina%w! Vous pouvez&maintenant l'utiliser lorsque&vous en " + "jouez!"), GIMESSAGE(RG_OCARINA_C_RIGHT_BUTTON, ITEM_OCARINA_TIME, - "You got the %y\xa8%r button for the&Ocarina%w! You can now use it&while playing songs!", - "Der %y\xa8%r Knopf%w!&Du kannst ihn nun zum Spielen&von Liedern auf der %rOkarina%w&verwenden!", - "Vous obtenez la %rtouche %y\xa8%r de&l'Ocarina%w! Vous pouvez&maintenant l'utiliser lorsque&vous en jouez!"), + "You got the %y\xa8%r button for the&Ocarina%w! You can now use it&while playing songs!", + "Der %y\xa8%r Knopf%w!&Du kannst ihn nun zum Spielen&von Liedern auf der %rOkarina%w&verwenden!", + "Vous obtenez la %rtouche %y\xa8%r de&l'Ocarina%w! Vous pouvez&maintenant l'utiliser lorsque&vous en " + "jouez!"), GIMESSAGE(RG_OCARINA_C_UP_BUTTON, ITEM_OCARINA_TIME, - "You got the %y\xa5%r button for the&Ocarina%w! You can now use it&while playing songs!", - "Der %y\xa5%r Knopf%w!&Du kannst ihn nun zum Spielen&von Liedern auf der %rOkarina%w&verwenden!", - "Vous obtenez la %rtouche %y\xa5%r de&l'Ocarina%w! Vous pouvez&maintenant l'utiliser lorsque&vous en jouez!"), + "You got the %y\xa5%r button for the&Ocarina%w! You can now use it&while playing songs!", + "Der %y\xa5%r Knopf%w!&Du kannst ihn nun zum Spielen&von Liedern auf der %rOkarina%w&verwenden!", + "Vous obtenez la %rtouche %y\xa5%r de&l'Ocarina%w! Vous pouvez&maintenant l'utiliser lorsque&vous en " + "jouez!"), GIMESSAGE(RG_OCARINA_C_DOWN_BUTTON, ITEM_OCARINA_TIME, - "You got the %y\xa6%r button for the&Ocarina%w! You can now use it&while playing songs!", - "Der %y\xa6%r Knopf%w!&Du kannst ihn nun zum Spielen&von Liedern auf der %rOkarina%w&verwenden!", - "Vous obtenez la %rtouche %y\xa6%r de&l'Ocarina%w! Vous pouvez&maintenant l'utiliser lorsque&vous en jouez!"), - - GIMESSAGE(RG_BRONZE_SCALE, ITEM_SCALE_SILVER, - "You got the %rBronze Scale%w!&The power of buoyancy is yours!", - "Du hast die %rBronzene Schuppe%w erhalten!&Die Macht der Schwungkraft ist dein!", - "Vous obtenez l'%rÉcaille de Bronze%w!&Le pouvoir de la flottabilité est&à vous!"), - GIMESSAGE(RG_FISHING_POLE, ITEM_FISHING_POLE, - "You found a lost %rFishing Pole%w!&Time to hit the pond!", - "Du hast eine verlorene %rAngelrute%w gefunden!&Zeit, im Teich zu angeln!", - "Vous obtenez une %rCanne à pêche%w&perdue!&Il est temps d'aller à %gl'étang%w!"), - GIMESSAGE(RG_BOMBCHU_BAG, ITEM_BOMBCHU, - "You found the %rBombchu Bag%w!", - "Du hast die %rKrabbelminentasche%w&gefunden!", - "Vous obtenez un %rSac de Missiles&Teigneux%w!"), - GIMESSAGE(RG_BOMB_BAG_INF, ITEM_BOMB_BAG_40, - "You got an %rInfinite Bomb Bag%w!&Now you have %yinfinite bombs%w!", - "Du hast eine %runendliche Bombentasche%w&gefunden! Nun hast Du &%yunendliche Bomben%w!", + "You got the %y\xa6%r button for the&Ocarina%w! You can now use it&while playing songs!", + "Der %y\xa6%r Knopf%w!&Du kannst ihn nun zum Spielen&von Liedern auf der %rOkarina%w&verwenden!", + "Vous obtenez la %rtouche %y\xa6%r de&l'Ocarina%w! Vous pouvez&maintenant l'utiliser lorsque&vous en " + "jouez!"), + + GIMESSAGE(RG_BRONZE_SCALE, ITEM_SCALE_SILVER, "You got the %rBronze Scale%w!&The power of buoyancy is yours!", + "Du hast die %rBronzene Schuppe%w erhalten!&Die Macht der Schwungkraft ist dein!", + "Vous obtenez l'%rÉcaille de Bronze%w!&Le pouvoir de la flottabilité est&à vous!"), + GIMESSAGE(RG_FISHING_POLE, ITEM_FISHING_POLE, "You found a lost %rFishing Pole%w!&Time to hit the pond!", + "Du hast eine verlorene %rAngelrute%w gefunden!&Zeit, im Teich zu angeln!", + "Vous obtenez une %rCanne à pêche%w&perdue!&Il est temps d'aller à %gl'étang%w!"), + GIMESSAGE(RG_BOMBCHU_BAG, ITEM_BOMBCHU, "You found the %rBombchu Bag%w!", + "Du hast die %rKrabbelminentasche%w&gefunden!", "Vous obtenez un %rSac de Missiles&Teigneux%w!"), + GIMESSAGE( + RG_BOMB_BAG_INF, ITEM_BOMB_BAG_40, "You got an %rInfinite Bomb Bag%w!&Now you have %yinfinite bombs%w!", + "Du hast eine %runendliche Bombentasche%w&gefunden! Nun hast Du &%yunendliche Bomben%w!", "Vous obtenez un %rSac de Bombes&sans fond%w!&Vous avez maintenant des %ybombes&en quantité illimitée%w!"), - GIMESSAGE(RG_QUIVER_INF, ITEM_QUIVER_50, - "You got an %rInfinite Quiver%w!&Now you have %yinfinite arrows%w!", - "Du hast einen %runendlichen Köcher%w&gefunden! Nun hast Du &%yunendliche Pfeile%w!", - "Vous obtenez un %rCarquois Infini%w!&Vous avez maintenant des %yflèches&de manière illimitée%w!"), + GIMESSAGE(RG_QUIVER_INF, ITEM_QUIVER_50, "You got an %rInfinite Quiver%w!&Now you have %yinfinite arrows%w!", + "Du hast einen %runendlichen Köcher%w&gefunden! Nun hast Du &%yunendliche Pfeile%w!", + "Vous obtenez un %rCarquois Infini%w!&Vous avez maintenant des %yflèches&de manière illimitée%w!"), GIMESSAGE(RG_BULLET_BAG_INF, ITEM_BULLET_BAG_50, - "You got an %rInfinite Bullet Bag%w!&Now you have %yinfinite&slingshot seeds%w!", - "Du hast eine %runendliche Samentasche%w&gefunden! Nun hast Du &%yunendliche Samen%w!", - "Vous obtenez un %rSac de Graines&sans fond%w!&Vous avez maintenant des %ygraines&de lance-pierres à l'infini%w!"), - GIMESSAGE(RG_STICK_UPGRADE_INF, ITEM_STICK, - "You now have %yinfinite%w %rDeku Sticks%w!", - "Du hast nun %yrunendliche%w %rDeku-Stäbe%w!", - "Vous avez maintenant des %yBâtons&Mojo de manière illimitée%w!"), - GIMESSAGE(RG_NUT_UPGRADE_INF, ITEM_NUT, - "You now have %yinfinite%w %rDeku Nuts%w!", - "Du hast nun %yunendliche%w %rDeku-Nüsse%w!", - "Vous avez maintenant des %yNoix&Mojo de manière illimitée%w!"), - GIMESSAGE(RG_MAGIC_INF, ITEM_MAGIC_LARGE, - "You now have %yinfinite%w %rMagic%w!", - "Du hast nun %yunendliche%w %rMagiew!", - "Vous avez maintenant une quantité&de %ymagie illimitée%w!"), - GIMESSAGE(RG_BOMBCHU_INF, ITEM_BOMBCHU, - "You now have %yinfinite%w %rBombchus%w!", - "Du hast nun %yunendliche%w %rKrabbelminen%w!", - "Vous avez maintenant des %yMissiles&Teigneux en quantité illimités%w!"), - GIMESSAGE(RG_WALLET_INF, ITEM_WALLET_GIANT, - "You now have %yinfinite%w %rmoney%w!", - "Du hast nun %yunendliche%w %rRubinew!", - "Vous avez maintenant des %yRubis en& quantité illimitée%w!"), - GIMESSAGE(RG_SKELETON_KEY, ITEM_KEY_SMALL, - "You found the %rSkeleton Key%w!", - "Du hast den %rSkelettschlüssel%w gefunden!", - "Vous avez trouvé la %rClé Squelette%w!"), - GIMESSAGE(RG_DEKU_STICK_BAG, ITEM_STICK, - "You found the %rDeku Stick Bag%w!&You can now hold Deku Sticks!", - "Du hast eine %rDeku-Stab-Tasche%w&gefunden! Nun kannst Du &%yDeku-Stäbe%w halten!", - "Vous avez trouvé le %rSac de Bâtons&Mojo%w!&Vous pouvez maintenant porter des&Bâtons Mojo!"), - GIMESSAGE(RG_DEKU_NUT_BAG, ITEM_NUT, - "You found the %rDeku Nut Bag%w!&You can now hold Deku Nuts!", - "Du hast eine %rDeku-Nuß-Tasche%w&gefunden! Nun kannst Du &%yDeku-Nüsse%w halten!", - "Vous avez trouvé le %rSac de Noix& Mojo%w!&Vous pouvez maintenant porter des&Noix Mojo!"), - }}; + "You got an %rInfinite Bullet Bag%w!&Now you have %yinfinite&slingshot seeds%w!", + "Du hast eine %runendliche Samentasche%w&gefunden! Nun hast Du &%yunendliche Samen%w!", + "Vous obtenez un %rSac de Graines&sans fond%w!&Vous avez maintenant des %ygraines&de lance-pierres à " + "l'infini%w!"), + GIMESSAGE(RG_STICK_UPGRADE_INF, ITEM_STICK, "You now have %yinfinite%w %rDeku Sticks%w!", + "Du hast nun %yrunendliche%w %rDeku-Stäbe%w!", + "Vous avez maintenant des %yBâtons&Mojo de manière illimitée%w!"), + GIMESSAGE(RG_NUT_UPGRADE_INF, ITEM_NUT, "You now have %yinfinite%w %rDeku Nuts%w!", + "Du hast nun %yunendliche%w %rDeku-Nüsse%w!", + "Vous avez maintenant des %yNoix&Mojo de manière illimitée%w!"), + GIMESSAGE(RG_MAGIC_INF, ITEM_MAGIC_LARGE, "You now have %yinfinite%w %rMagic%w!", + "Du hast nun %yunendliche%w %rMagiew!", "Vous avez maintenant une quantité&de %ymagie illimitée%w!"), + GIMESSAGE(RG_BOMBCHU_INF, ITEM_BOMBCHU, "You now have %yinfinite%w %rBombchus%w!", + "Du hast nun %yunendliche%w %rKrabbelminen%w!", + "Vous avez maintenant des %yMissiles&Teigneux en quantité illimités%w!"), + GIMESSAGE(RG_WALLET_INF, ITEM_WALLET_GIANT, "You now have %yinfinite%w %rmoney%w!", + "Du hast nun %yunendliche%w %rRubinew!", + "Vous avez maintenant des %yRubis en& quantité illimitée%w!"), + GIMESSAGE(RG_SKELETON_KEY, ITEM_KEY_SMALL, "You found the %rSkeleton Key%w!", + "Du hast den %rSkelettschlüssel%w gefunden!", "Vous avez trouvé la %rClé Squelette%w!"), + GIMESSAGE(RG_DEKU_STICK_BAG, ITEM_STICK, "You found the %rDeku Stick Bag%w!&You can now hold Deku Sticks!", + "Du hast eine %rDeku-Stab-Tasche%w&gefunden! Nun kannst Du &%yDeku-Stäbe%w halten!", + "Vous avez trouvé le %rSac de Bâtons&Mojo%w!&Vous pouvez maintenant porter des&Bâtons Mojo!"), + GIMESSAGE(RG_DEKU_NUT_BAG, ITEM_NUT, "You found the %rDeku Nut Bag%w!&You can now hold Deku Nuts!", + "Du hast eine %rDeku-Nuß-Tasche%w&gefunden! Nun kannst Du &%yDeku-Nüsse%w halten!", + "Vous avez trouvé le %rSac de Noix& Mojo%w!&Vous pouvez maintenant porter des&Noix Mojo!"), + } }; CreateGetItemMessages(getItemMessages); CreateRupeeMessages(); CreateTriforcePieceMessages(); @@ -4570,16 +5531,17 @@ void Randomizer::CreateCustomMessages() { CreateFireTempleGoronMessages(); } -class ExtendedVanillaTableInvalidItemIdException: public std::exception { - private: +class ExtendedVanillaTableInvalidItemIdException : public std::exception { + private: s16 itemID; - public: - ExtendedVanillaTableInvalidItemIdException(s16 itemID): itemID(itemID) {} - std::string what() { + public: + ExtendedVanillaTableInvalidItemIdException(s16 itemID) : itemID(itemID) { + } + std::string what() { return itemID + " is not a valid ItemID for the extendedVanillaGetItemTable. If you are adding a new" - "item, try adding it to randoGetItemTable instead."; - } + "item, try adding it to randoGetItemTable instead."; + } }; void RandomizerSettingsWindow::InitElement() { @@ -4631,36 +5593,38 @@ extern "C" u8 Return_Item_Entry(GetItemEntry itemEntry, u8 returnItem); // used for items that only set a rand inf when obtained std::map randomizerGetToRandInf = { - { RG_FISHING_POLE, RAND_INF_FISHING_POLE_FOUND }, - { RG_BRONZE_SCALE, RAND_INF_CAN_SWIM }, - { RG_QUIVER_INF, RAND_INF_HAS_INFINITE_QUIVER }, - { RG_BOMB_BAG_INF, RAND_INF_HAS_INFINITE_BOMB_BAG }, - { RG_BULLET_BAG_INF, RAND_INF_HAS_INFINITE_BULLET_BAG }, - { RG_STICK_UPGRADE_INF, RAND_INF_HAS_INFINITE_STICK_UPGRADE }, - { RG_NUT_UPGRADE_INF, RAND_INF_HAS_INFINITE_NUT_UPGRADE }, - { RG_MAGIC_INF, RAND_INF_HAS_INFINITE_MAGIC_METER }, - { RG_BOMBCHU_INF, RAND_INF_HAS_INFINITE_BOMBCHUS }, - { RG_WALLET_INF, RAND_INF_HAS_INFINITE_MONEY }, - { RG_SKELETON_KEY, RAND_INF_HAS_SKELETON_KEY }, - { RG_OCARINA_A_BUTTON, RAND_INF_HAS_OCARINA_A }, - { RG_OCARINA_C_UP_BUTTON, RAND_INF_HAS_OCARINA_C_UP }, - { RG_OCARINA_C_DOWN_BUTTON, RAND_INF_HAS_OCARINA_C_DOWN }, - { RG_OCARINA_C_LEFT_BUTTON, RAND_INF_HAS_OCARINA_C_LEFT }, + { RG_FISHING_POLE, RAND_INF_FISHING_POLE_FOUND }, + { RG_BRONZE_SCALE, RAND_INF_CAN_SWIM }, + { RG_QUIVER_INF, RAND_INF_HAS_INFINITE_QUIVER }, + { RG_BOMB_BAG_INF, RAND_INF_HAS_INFINITE_BOMB_BAG }, + { RG_BULLET_BAG_INF, RAND_INF_HAS_INFINITE_BULLET_BAG }, + { RG_STICK_UPGRADE_INF, RAND_INF_HAS_INFINITE_STICK_UPGRADE }, + { RG_NUT_UPGRADE_INF, RAND_INF_HAS_INFINITE_NUT_UPGRADE }, + { RG_MAGIC_INF, RAND_INF_HAS_INFINITE_MAGIC_METER }, + { RG_BOMBCHU_INF, RAND_INF_HAS_INFINITE_BOMBCHUS }, + { RG_WALLET_INF, RAND_INF_HAS_INFINITE_MONEY }, + { RG_SKELETON_KEY, RAND_INF_HAS_SKELETON_KEY }, + { RG_OCARINA_A_BUTTON, RAND_INF_HAS_OCARINA_A }, + { RG_OCARINA_C_UP_BUTTON, RAND_INF_HAS_OCARINA_C_UP }, + { RG_OCARINA_C_DOWN_BUTTON, RAND_INF_HAS_OCARINA_C_DOWN }, + { RG_OCARINA_C_LEFT_BUTTON, RAND_INF_HAS_OCARINA_C_LEFT }, { RG_OCARINA_C_RIGHT_BUTTON, RAND_INF_HAS_OCARINA_C_RIGHT }, - { RG_GOHMA_SOUL, RAND_INF_GOHMA_SOUL }, - { RG_KING_DODONGO_SOUL, RAND_INF_KING_DODONGO_SOUL }, - { RG_BARINADE_SOUL, RAND_INF_BARINADE_SOUL }, - { RG_PHANTOM_GANON_SOUL, RAND_INF_PHANTOM_GANON_SOUL }, - { RG_VOLVAGIA_SOUL, RAND_INF_VOLVAGIA_SOUL }, - { RG_MORPHA_SOUL, RAND_INF_MORPHA_SOUL }, - { RG_BONGO_BONGO_SOUL, RAND_INF_BONGO_BONGO_SOUL }, - { RG_TWINROVA_SOUL, RAND_INF_TWINROVA_SOUL }, - { RG_GANON_SOUL, RAND_INF_GANON_SOUL }, + { RG_GOHMA_SOUL, RAND_INF_GOHMA_SOUL }, + { RG_KING_DODONGO_SOUL, RAND_INF_KING_DODONGO_SOUL }, + { RG_BARINADE_SOUL, RAND_INF_BARINADE_SOUL }, + { RG_PHANTOM_GANON_SOUL, RAND_INF_PHANTOM_GANON_SOUL }, + { RG_VOLVAGIA_SOUL, RAND_INF_VOLVAGIA_SOUL }, + { RG_MORPHA_SOUL, RAND_INF_MORPHA_SOUL }, + { RG_BONGO_BONGO_SOUL, RAND_INF_BONGO_BONGO_SOUL }, + { RG_TWINROVA_SOUL, RAND_INF_TWINROVA_SOUL }, + { RG_GANON_SOUL, RAND_INF_GANON_SOUL }, }; extern "C" u16 Randomizer_Item_Give(PlayState* play, GetItemEntry giEntry) { if (giEntry.modIndex != MOD_RANDOMIZER) { - LUSLOG_WARN("Randomizer_Item_Give was called with a GetItemEntry with a mod index different from MOD_RANDOMIZER (%d)", giEntry.modIndex); + LUSLOG_WARN( + "Randomizer_Item_Give was called with a GetItemEntry with a mod index different from MOD_RANDOMIZER (%d)", + giEntry.modIndex); assert(false); return -1; } @@ -4670,13 +5634,13 @@ extern "C" u16 Randomizer_Item_Give(PlayState* play, GetItemEntry giEntry) { // Gameplay stats: Update the time the item was obtained Randomizer_GameplayStats_SetTimestamp(item); - //if it's an item that just sets a randomizerInf, set it + // if it's an item that just sets a randomizerInf, set it if (randomizerGetToRandInf.find(item) != randomizerGetToRandInf.end()) { Flags_SetRandomizerInf(randomizerGetToRandInf.find(item)->second); return Return_Item_Entry(giEntry, RG_NONE); } - //bottle items + // bottle items if (item >= RG_BOTTLE_WITH_RED_POTION && item <= RG_BOTTLE_WITH_BIG_POE) { for (u16 i = 0; i < 4; i++) { if (gSaveContext.inventory.items[SLOT_BOTTLE_1 + i] == ITEM_NONE) { @@ -4719,14 +5683,12 @@ extern "C" u16 Randomizer_Item_Give(PlayState* play, GetItemEntry giEntry) { } } - //dungeon items - if ( - (item >= RG_FOREST_TEMPLE_SMALL_KEY && item <= RG_GANONS_CASTLE_SMALL_KEY) || + // dungeon items + if ((item >= RG_FOREST_TEMPLE_SMALL_KEY && item <= RG_GANONS_CASTLE_SMALL_KEY) || (item >= RG_FOREST_TEMPLE_KEY_RING && item <= RG_GANONS_CASTLE_KEY_RING) || (item >= RG_FOREST_TEMPLE_BOSS_KEY && item <= RG_GANONS_CASTLE_BOSS_KEY) || (item >= RG_DEKU_TREE_MAP && item <= RG_ICE_CAVERN_MAP) || - (item >= RG_DEKU_TREE_COMPASS && item <= RG_ICE_CAVERN_COMPASS) - ) { + (item >= RG_DEKU_TREE_COMPASS && item <= RG_ICE_CAVERN_COMPASS)) { u16 mapIndex = gSaveContext.mapIndex; u8 numOfKeysOnKeyring = 0; switch (item) { @@ -4843,7 +5805,8 @@ extern "C" u16 Randomizer_Item_Give(PlayState* play, GetItemEntry giEntry) { gSaveContext.inventory.dungeonItems[mapIndex] |= bitmask; return Return_Item_Entry(giEntry, RG_NONE); } else if (item >= RG_GUARD_HOUSE_KEY && item <= RG_FISHING_HOLE_KEY) { - Flags_SetRandomizerInf((RandomizerInf)((int)RAND_INF_GUARD_HOUSE_UNLOCKED + ((item - RG_GUARD_HOUSE_KEY) * 2) + 1)); + Flags_SetRandomizerInf( + (RandomizerInf)((int)RAND_INF_GUARD_HOUSE_UNLOCKED + ((item - RG_GUARD_HOUSE_KEY) * 2) + 1)); return Return_Item_Entry(giEntry, RG_NONE); } @@ -4895,7 +5858,8 @@ extern "C" u16 Randomizer_Item_Give(PlayState* play, GetItemEntry giEntry) { GameInteractor_SetTriforceHuntPieceGiven(true); // Teleport to credits when goal is reached. - if (gSaveContext.ship.quest.data.randomizer.triforcePiecesCollected == (OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_TRIFORCE_HUNT_PIECES_REQUIRED) + 1)) { + if (gSaveContext.ship.quest.data.randomizer.triforcePiecesCollected == + (OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_TRIFORCE_HUNT_PIECES_REQUIRED) + 1)) { gSaveContext.ship.stats.itemTimestamp[TIMESTAMP_TRIFORCE_COMPLETED] = GAMEPLAYSTAT_TOTAL_TIME; gSaveContext.ship.stats.gameComplete = 1; Flags_SetRandomizerInf(RAND_INF_GRANT_GANONS_BOSSKEY); diff --git a/soh/soh/Enhancements/randomizer/randomizer.h b/soh/soh/Enhancements/randomizer/randomizer.h index 50bf6636c..78f48b01c 100644 --- a/soh/soh/Enhancements/randomizer/randomizer.h +++ b/soh/soh/Enhancements/randomizer/randomizer.h @@ -57,13 +57,16 @@ class Randomizer { GrassIdentity IdentifyGrass(s32 sceneNum, s32 posX, s32 posZ, s32 respawnData, s32 linkAge); CrateIdentity IdentifyCrate(s32 sceneNum, s32 posX, s32 posZ); SmallCrateIdentity IdentifySmallCrate(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, bool checkObtainability = true); + GetItemEntry GetItemFromKnownCheck(RandomizerCheck randomizerCheck, GetItemID ogItemId, + bool checkObtainability = true); + GetItemEntry GetItemFromActor(s16 actorId, s16 sceneNum, s16 actorParams, GetItemID ogItemId, + bool checkObtainability = true); ItemObtainability GetItemObtainabilityFromRandomizerCheck(RandomizerCheck randomizerCheck); ItemObtainability GetItemObtainabilityFromRandomizerGet(RandomizerGet randomizerCheck); CustomMessage GetSheikMessage(s16 scene, u16 originalTextId); CustomMessage GetFishingPondOwnerMessage(u16 originalTextId); - CustomMessage GetMerchantMessage(RandomizerCheck rc, TextIDs textId, TextIDs freeTextId = TEXT_NONE, bool mysterious = false); + CustomMessage GetMerchantMessage(RandomizerCheck rc, TextIDs textId, TextIDs freeTextId = TEXT_NONE, + bool mysterious = false); RandomizerCheck GetCheckFromActor(s16 actorId, s16 sceneNum, s16 actorParams); CustomMessage GetGoronMessage(u16 index); CustomMessage GetMapGetItemMessageWithHint(GetItemEntry itemEntry); @@ -82,4 +85,3 @@ bool GenerateRandomizer(std::string seed = ""); #ifdef __cplusplus } #endif - diff --git a/soh/soh/Enhancements/randomizer/randomizerTypes.h b/soh/soh/Enhancements/randomizer/randomizerTypes.h index 8378f25fb..34bddd0a5 100644 --- a/soh/soh/Enhancements/randomizer/randomizerTypes.h +++ b/soh/soh/Enhancements/randomizer/randomizerTypes.h @@ -209,7 +209,7 @@ typedef enum { LOGIC_OCARINA_C_UP_BUTTON, LOGIC_OCARINA_C_DOWN_BUTTON, LOGIC_OCARINA_C_LEFT_BUTTON, - LOGIC_OCARINA_C_RIGHT_BUTTON, + LOGIC_OCARINA_C_RIGHT_BUTTON, LOGIC_TRIFORCE_PIECES, LOGIC_MAX } LogicVal; @@ -2336,7 +2336,7 @@ typedef enum { RC_GANONS_CASTLE_MQ_SPIRIT_TRIAL_POT_1, RC_GANONS_CASTLE_MQ_SPIRIT_TRIAL_POT_2, // End Pots - + // Overworld Crates RC_GV_FREESTANDING_POH_CRATE, RC_GV_NEAR_COW_CRATE, @@ -3467,12 +3467,13 @@ typedef enum { RC_MAX } RandomizerCheck; -// Randomizer tricks and glitches (beta) based on knowledge of what is achievable in Ship of Harkinian randomizer, excludes Item manipulation (e.g. RBA/GIM/SRM) and Wrong Warping and Ganon BK Skip -// TODO Fill and alphabetize (area based tricks must have area in name and come alphetized after general tricks) +// Randomizer tricks and glitches (beta) based on knowledge of what is achievable in Ship of Harkinian randomizer, +// excludes Item manipulation (e.g. RBA/GIM/SRM) and Wrong Warping and Ganon BK Skip +// TODO Fill and alphabetize (area based tricks must have area in name and come alphetized after general tricks) // TODO test commented out tricks to see if consistent with console on SoH // TODO add area specific tricks typedef enum { - RT_VISIBLE_COLLISION, // -- general tricks + RT_VISIBLE_COLLISION, // -- general tricks RT_GROTTOS_WITHOUT_AGONY, RT_FEWER_TUNIC_REQUIREMENTS, RT_RUSTED_SWITCHES, @@ -3482,7 +3483,7 @@ typedef enum { RT_HOVER_BOOST_SIMPLE, RT_BOMBCHU_BEEHIVES, RT_BLUE_FIRE_MUD_WALLS, - RT_KF_ADULT_GS, // -- location tricks + RT_KF_ADULT_GS, // -- location tricks RT_LW_BRIDGE, RT_LW_MIDO_BACKFLIP, RT_LW_GS_BEAN, @@ -3490,7 +3491,7 @@ typedef enum { RT_KAK_MAN_ON_ROOF, RT_KAK_TOWER_GS, RT_KAK_ADULT_WINDMILL_POH, - RT_KAK_CHILD_WINDMILL_POH, + RT_KAK_CHILD_WINDMILL_POH, RT_KAK_ROOFTOP_GS, RT_GY_POH, RT_GY_CHILD_DAMPE_RACE_POH, @@ -3649,7 +3650,7 @@ typedef enum { RT_GANON_MQ_FIRE_TRIAL, RT_GANON_MQ_SHADOW_TRIAL, RT_GANON_MQ_LIGHT_TRIAL, - //RT_ROCS_FEATHER --if implemented with main branch + // RT_ROCS_FEATHER --if implemented with main branch RT_FOREST_TEMPLE_BK_SKIP, RT_FIRE_TEMPLE_BK_SKIP, RT_WATER_TEMPLE_BK_SKIP, @@ -3704,11 +3705,11 @@ typedef enum { RT_WEIRDSHOT, RT_WEIRDSHOT_CHU, RT_WEIRDSHOT_ENEMY, - //RT_FW_VOID_WARP_FAST_TEXT, --untested tricks: - //RT_ACTION_SWAP, - //RT_ACTOR_GLITCH, - //RT_ADULT_TRADE_TTG, - RT_TOT_DOT_SKIP_SWORDLESS, //AREA SPECIFIC GLITCHES + // RT_FW_VOID_WARP_FAST_TEXT, --untested tricks: + // RT_ACTION_SWAP, + // RT_ACTOR_GLITCH, + // RT_ADULT_TRADE_TTG, + RT_TOT_DOT_SKIP_SWORDLESS, // AREA SPECIFIC GLITCHES RT_TOT_DOT_SKIP_SWORD, RT_LLR_STEAL_EPONA, RT_KF_POKEY_SKIP, @@ -3724,7 +3725,7 @@ typedef enum { RT_ZF_JABU_ADULT_HOVERBOOT_BOMB, RT_FOREST_TEMPLE_FOUR_POE_SKIP, RT_FOREST_TEMPLE_JUNGLE_JUMP, - //RT_DARUNIA_CUTSCENE, + // RT_DARUNIA_CUTSCENE, RT_BOTTOM_OF_THE_WELL_SKULL_PUSH, RT_GANONS_CASTLE_BARRIER_SKIP_HOVER, RT_GANONS_CASTLE_GOLD_GAUNTLET_SKIP, @@ -3985,7 +3986,7 @@ typedef enum { RG_LONGSHOT, RG_SCARECROW, - //Overworld keys + // Overworld keys RG_GUARD_HOUSE_KEY, RG_MARKET_BAZAAR_KEY, RG_MARKET_POTION_SHOP_KEY, @@ -5405,7 +5406,7 @@ typedef enum { RHT_CRATE_WATER_TEMPLE, RHT_CRATE_SPIRIT_TEMPLE, RHT_CRATE_SHADOW_TEMPLE, - RHT_CRATE_GERUDO_TRAINING_GROUND, + RHT_CRATE_GERUDO_TRAINING_GROUND, // Ganon Line RHT_GANON_JOKE01, RHT_GANON_JOKE02, @@ -5589,7 +5590,6 @@ typedef enum { RHT_MAX, } RandomizerHintTextKey; - typedef struct { RandomizerGet rgID; RandomizerGet fakeRgID; @@ -5698,16 +5698,16 @@ typedef enum { RSK_STARTING_KOKIRI_SWORD, RSK_STARTING_MASTER_SWORD, RSK_STARTING_ZELDAS_LULLABY, - RSK_STARTING_EPONAS_SONG, - RSK_STARTING_SARIAS_SONG, + RSK_STARTING_EPONAS_SONG, + RSK_STARTING_SARIAS_SONG, RSK_STARTING_SUNS_SONG, RSK_STARTING_SONG_OF_TIME, RSK_STARTING_SONG_OF_STORMS, - RSK_STARTING_MINUET_OF_FOREST, + RSK_STARTING_MINUET_OF_FOREST, RSK_STARTING_BOLERO_OF_FIRE, RSK_STARTING_SERENADE_OF_WATER, - RSK_STARTING_REQUIEM_OF_SPIRIT, - RSK_STARTING_NOCTURNE_OF_SHADOW, + RSK_STARTING_REQUIEM_OF_SPIRIT, + RSK_STARTING_NOCTURNE_OF_SHADOW, RSK_STARTING_PRELUDE_OF_LIGHT, RSK_SHUFFLE_KOKIRI_SWORD, RSK_SHUFFLE_MASTER_SWORD, @@ -5882,8 +5882,8 @@ typedef enum { RSK_MAX } RandomizerSettingKey; -//Generic Settings (any binary option can use this) -// off/on +// Generic Settings (any binary option can use this) +// off/on typedef enum { RO_GENERIC_OFF, RO_GENERIC_ON, @@ -5901,54 +5901,54 @@ typedef enum { RO_GENERIC_SKIP, } RandoOptionGenericSkip; -//Closed Forest settings (On, Deku Only, Off) +// Closed Forest settings (On, Deku Only, Off) typedef enum { RO_CLOSED_FOREST_ON, RO_CLOSED_FOREST_DEKU_ONLY, RO_CLOSED_FOREST_OFF, } RandoOptionForest; -//Door of Time settings (closed, song only, open) +// Door of Time settings (closed, song only, open) typedef enum { RO_DOOROFTIME_CLOSED, RO_DOOROFTIME_SONGONLY, RO_DOOROFTIME_OPEN, } RandoOptionDoorOfTime; -//Zora's Fountain settings (closed, closed as child, open) +// Zora's Fountain settings (closed, closed as child, open) typedef enum { RO_ZF_CLOSED, RO_ZF_CLOSED_CHILD, RO_ZF_OPEN, } RandoOptionZorasFountain; -//Sleeping Waterfall settings (closed, open) +// Sleeping Waterfall settings (closed, open) typedef enum { RO_WATERFALL_CLOSED, RO_WATERFALL_OPEN, } RandoOptionSleepingWaterfall; -//Starting Age settings (child, adult, random) +// Starting Age settings (child, adult, random) typedef enum { RO_AGE_CHILD, RO_AGE_ADULT, RO_AGE_RANDOM, } RandoOptionStartingAge; -//Fortress Carpenters settings (normal, fast, free) +// Fortress Carpenters settings (normal, fast, free) typedef enum { RO_GF_CARPENTERS_NORMAL, RO_GF_CARPENTERS_FAST, RO_GF_CARPENTERS_FREE, } RandoOptionGerudoFortress; -//Kakariko Gate settings (closed/open) +// Kakariko Gate settings (closed/open) typedef enum { RO_KAK_GATE_CLOSED, RO_KAK_GATE_OPEN, } RandoOptionKakarikoGate; -//Rainbow Bridge settings (vanilla, always open, stones, medallions, dungeon rewards, dungeons, tokens) +// Rainbow Bridge settings (vanilla, always open, stones, medallions, dungeon rewards, dungeons, tokens) typedef enum { RO_BRIDGE_VANILLA = 0, RO_BRIDGE_ALWAYS_OPEN, @@ -5967,14 +5967,14 @@ typedef enum { RO_BRIDGE_WILDCARD_REWARD, } RandoOptionBridgeRewards; -//Shopsanity settings (off, specific count, random) +// Shopsanity settings (off, specific count, random) typedef enum { RO_SHOPSANITY_OFF, RO_SHOPSANITY_SPECIFIC_COUNT, RO_SHOPSANITY_RANDOM, } RandoOptionShopsanity; -//Shopsanity count settings (0-7 items) +// Shopsanity count settings (0-7 items) typedef enum { RO_SHOPSANITY_COUNT_ZERO_ITEMS, RO_SHOPSANITY_COUNT_ONE_ITEM, @@ -5987,27 +5987,27 @@ typedef enum { RO_SHOPSANITY_COUNT_EIGHT_ITEMS, } RandoOptionShopsanityCount; -//Shopsanity price ranges +// Shopsanity price ranges typedef enum { RO_PRICE_VANILLA, - RO_PRICE_CHEAP_BALANCED, //Balanced random from 0-95, favoring lower numbers - RO_PRICE_BALANCED, //Random from 0-300, favoring lower numbers + RO_PRICE_CHEAP_BALANCED, // Balanced random from 0-95, favoring lower numbers + RO_PRICE_BALANCED, // Random from 0-300, favoring lower numbers RO_PRICE_FIXED, RO_PRICE_RANGE, RO_PRICE_SET_BY_WALLET, } RandoOptionPrices; -//Scrubsanity settings (off, affordable, expensive, random) +// Scrubsanity settings (off, affordable, expensive, random) typedef enum { RO_SCRUBS_OFF, RO_SCRUBS_ONE_TIME_ONLY, RO_SCRUBS_ALL, } RandoOptionScrubsanity; -//Ammo drop settings (on, "on+bombchu", off) +// Ammo drop settings (on, "on+bombchu", off) typedef enum { RO_AMMO_DROPS_OFF, - //RO_AMMO_DROPS_ON_PLUS_BOMBCHU, + // RO_AMMO_DROPS_ON_PLUS_BOMBCHU, RO_AMMO_DROPS_ON, } RandoOptionAmmoDrops; @@ -6017,7 +6017,7 @@ typedef enum { RO_BOSS_SOULS_ON_PLUS_GANON, } RandoOptionBossSouls; -//Fishsanity settings (off, loach only, pond only, grottos only, both) +// Fishsanity settings (off, loach only, pond only, grottos only, both) typedef enum { RO_FISHSANITY_OFF, RO_FISHSANITY_HYRULE_LOACH, @@ -6026,15 +6026,15 @@ typedef enum { RO_FISHSANITY_BOTH } RandoOptionsFishsanity; -//Infinite Upgrades settings (off, progressive, condensed progressive) +// Infinite Upgrades settings (off, progressive, condensed progressive) typedef enum { RO_INF_UPGRADES_OFF, RO_INF_UPGRADES_PROGRESSIVE, RO_INF_UPGRADES_CONDENSED_PROGRESSIVE, } RandoOptionInfiniteUpgrades; -//Any Dungeon Item (start with, vanilla, own dungeon, any dungeon, -//overworld, anywhere) +// Any Dungeon Item (start with, vanilla, own dungeon, any dungeon, +// overworld, anywhere) typedef enum { RO_DUNGEON_ITEM_LOC_STARTWITH, RO_DUNGEON_ITEM_LOC_VANILLA, @@ -6044,7 +6044,7 @@ typedef enum { RO_DUNGEON_ITEM_LOC_ANYWHERE, } RandoOptionDungeonItemLocation; -//Dungeon reward settings +// Dungeon reward settings typedef enum { RO_DUNGEON_REWARDS_VANILLA, RO_DUNGEON_REWARDS_END_OF_DUNGEON, @@ -6053,7 +6053,7 @@ typedef enum { RO_DUNGEON_REWARDS_ANYWHERE, } RandoOptionDungeonRewards; -//Keyring Settings +// Keyring Settings typedef enum { RO_KEYRINGS_OFF, RO_KEYRINGS_RANDOM, @@ -6067,8 +6067,8 @@ typedef enum { RO_KEYRING_FOR_DUNGEON_ON, } RandoOptionKeyringForDungeon; -//Ganon's Boss Key Settings (vanilla, own dungeon, start with, -//overworld, anywhere, 100 GS reward) +// Ganon's Boss Key Settings (vanilla, own dungeon, start with, +// overworld, anywhere, 100 GS reward) typedef enum { RO_GANON_BOSS_KEY_VANILLA, RO_GANON_BOSS_KEY_OWN_DUNGEON, @@ -6101,42 +6101,42 @@ typedef enum { RO_LACS_WILDCARD_REWARD, } RandoOptionLACSRewards; -//Ganon's Trials +// Ganon's Trials typedef enum { RO_GANONS_TRIALS_SKIP, RO_GANONS_TRIALS_SET_NUMBER, RO_GANONS_TRIALS_RANDOM_NUMBER, } RandoOptionGanonsTrials; -//Shuffle Dungeon Entrance Settings (Off, on, plus ganon) +// Shuffle Dungeon Entrance Settings (Off, on, plus ganon) typedef enum { RO_DUNGEON_ENTRANCE_SHUFFLE_OFF, RO_DUNGEON_ENTRANCE_SHUFFLE_ON, RO_DUNGEON_ENTRANCE_SHUFFLE_ON_PLUS_GANON, } RandoOptionDungeonEntranceShuffle; -//Shuffle Boss Room Entrance Settings (Off, Age Restricted, Full) +// Shuffle Boss Room Entrance Settings (Off, Age Restricted, Full) typedef enum { RO_BOSS_ROOM_ENTRANCE_SHUFFLE_OFF, RO_BOSS_ROOM_ENTRANCE_SHUFFLE_AGE_RESTRICTED, RO_BOSS_ROOM_ENTRANCE_SHUFFLE_FULL, } RandoOptionBossRoomEntranceShuffle; -//Shuffle Interior Entrance Settings (Off, simple, all) +// Shuffle Interior Entrance Settings (Off, simple, all) typedef enum { RO_INTERIOR_ENTRANCE_SHUFFLE_OFF, RO_INTERIOR_ENTRANCE_SHUFFLE_SIMPLE, RO_INTERIOR_ENTRANCE_SHUFFLE_ALL, } RandoOptionInteriorEntranceShuffle; -//Song shuffle Settings (Song locations, Dungeon rewards, anywhere) +// Song shuffle Settings (Song locations, Dungeon rewards, anywhere) typedef enum { RO_SONG_SHUFFLE_SONG_LOCATIONS, RO_SONG_SHUFFLE_DUNGEON_REWARDS, RO_SONG_SHUFFLE_ANYWHERE, } RandoOptionSongShuffle; -//Shuffle Merchants Settings (Off, Beans Only, All but Beans, All) +// Shuffle Merchants Settings (Off, Beans Only, All but Beans, All) typedef enum { RO_SHUFFLE_MERCHANTS_OFF, RO_SHUFFLE_MERCHANTS_BEANS_ONLY, @@ -6144,14 +6144,14 @@ typedef enum { RO_SHUFFLE_MERCHANTS_ALL } RandoOptionShuffleMerchants; -//Starting Ocarina Settings (off, fairy) +// Starting Ocarina Settings (off, fairy) typedef enum { RO_STARTING_OCARINA_OFF, RO_STARTING_OCARINA_FAIRY, RO_STARTING_OCARINA_TIME, } RandoOptionStartingOcarina; -//Item Pool Settings +// Item Pool Settings typedef enum { RO_ITEM_POOL_PLENTIFUL, RO_ITEM_POOL_BALANCED, @@ -6159,7 +6159,7 @@ typedef enum { RO_ITEM_POOL_MINIMAL, } RandoOptionItemPool; -//Ice Trap Settings +// Ice Trap Settings typedef enum { RO_ICE_TRAPS_OFF, RO_ICE_TRAPS_NORMAL, @@ -6168,8 +6168,8 @@ typedef enum { RO_ICE_TRAPS_ONSLAUGHT, } RandoOptionIceTraps; -//Gossip Stone Hint Settings (no hints, needs nothing, -//needs mask of truth, needs stone of agony) +// Gossip Stone Hint Settings (no hints, needs nothing, +// needs mask of truth, needs stone of agony) typedef enum { RO_GOSSIP_STONES_NONE, RO_GOSSIP_STONES_NEED_NOTHING, @@ -6177,14 +6177,14 @@ typedef enum { RO_GOSSIP_STONES_NEED_STONE, } RandoOptionGossipStones; -//Hint Clarity Settings (obscure, ambiguous, clear) +// Hint Clarity Settings (obscure, ambiguous, clear) typedef enum { RO_HINT_CLARITY_OBSCURE, RO_HINT_CLARITY_AMBIGUOUS, RO_HINT_CLARITY_CLEAR, } RandoOptionHintClarity; -//Hint Distribution Settings (useless, balanced, strong, very strong) +// Hint Distribution Settings (useless, balanced, strong, very strong) typedef enum { RO_HINT_DIST_USELESS, RO_HINT_DIST_BALANCED, @@ -6192,8 +6192,8 @@ typedef enum { RO_HINT_DIST_VERY_STRONG, } RandoOptionHintDistribution; -//Gerudo Fortress Key Settings (vanilla, any dungeon, overworld, -//anywhere) +// Gerudo Fortress Key Settings (vanilla, any dungeon, overworld, +// anywhere) typedef enum { RO_GERUDO_KEYS_VANILLA, RO_GERUDO_KEYS_ANY_DUNGEON, @@ -6201,7 +6201,7 @@ typedef enum { RO_GERUDO_KEYS_ANYWHERE, } RandoOptionGerudoKeys; -//Tokensanity settings (off, dungeons, overworld, all) +// Tokensanity settings (off, dungeons, overworld, all) typedef enum { RO_TOKENSANITY_OFF, RO_TOKENSANITY_DUNGEONS, @@ -6209,7 +6209,7 @@ typedef enum { RO_TOKENSANITY_ALL, } RandoOptionTokensanity; -//Freestanding Hearts/Rupees settings (off, dungeons, overworld, all) +// Freestanding Hearts/Rupees settings (off, dungeons, overworld, all) typedef enum { RO_SHUFFLE_FREESTANDING_OFF, RO_SHUFFLE_FREESTANDING_DUNGEONS, @@ -6241,7 +6241,7 @@ typedef enum { RO_SHUFFLE_CRATES_ALL, } RandoOptionShuffleCrates; -//Link's Pocket Settings (dungeon reward, advancement, anything, nothing) +// Link's Pocket Settings (dungeon reward, advancement, anything, nothing) typedef enum { RO_LINKS_POCKET_DUNGEON_REWARD, RO_LINKS_POCKET_ADVANCEMENT, @@ -6441,13 +6441,13 @@ typedef enum { RE_OCTOROK, } RandomizerEnemy; -//RANDOTODO compare child long jumpslash range with adult short +// RANDOTODO compare child long jumpslash range with adult short typedef enum { ED_CLOSE, - //hammer or kokiri sword + // hammer or kokiri sword ED_SHORT_JUMPSLASH, ED_MASTER_SWORD_JUMPSLASH, - //sticks or BGS + // sticks or BGS ED_LONG_JUMPSLASH, ED_BOMB_THROW, ED_BOOMERANG, diff --git a/soh/soh/Enhancements/randomizer/randomizer_check_objects.cpp b/soh/soh/Enhancements/randomizer/randomizer_check_objects.cpp index 55a8deaa7..4d7d7a59a 100644 --- a/soh/soh/Enhancements/randomizer/randomizer_check_objects.cpp +++ b/soh/soh/Enhancements/randomizer/randomizer_check_objects.cpp @@ -113,23 +113,20 @@ void RandomizerCheckObjects::UpdateImGuiVisibility() { (location.GetRandomizerCheck() != RC_UNKNOWN_CHECK) && (location.GetQuest() == RCQUEST_BOTH || location.GetQuest() == RCQUEST_MQ && - ((CVarGetInteger(CVAR_RANDOMIZER_SETTING("MQDungeons"), RO_MQ_DUNGEONS_NONE) == RO_MQ_DUNGEONS_SET_NUMBER && + ((CVarGetInteger(CVAR_RANDOMIZER_SETTING("MQDungeons"), RO_MQ_DUNGEONS_NONE) == + RO_MQ_DUNGEONS_SET_NUMBER && (CVarGetInteger(CVAR_RANDOMIZER_SETTING("MQDungeonCount"), 12) > 0) || // at least one MQ dungeon - CVarGetInteger(CVAR_RANDOMIZER_SETTING("MQDungeons"), RO_MQ_DUNGEONS_NONE) == RO_MQ_DUNGEONS_RANDOM_NUMBER)) || + CVarGetInteger(CVAR_RANDOMIZER_SETTING("MQDungeons"), RO_MQ_DUNGEONS_NONE) == + RO_MQ_DUNGEONS_RANDOM_NUMBER)) || location.GetQuest() == RCQUEST_VANILLA && - (CVarGetInteger(CVAR_RANDOMIZER_SETTING("MQDungeons"), RO_MQ_DUNGEONS_NONE) != RO_MQ_DUNGEONS_SET_NUMBER || + (CVarGetInteger(CVAR_RANDOMIZER_SETTING("MQDungeons"), RO_MQ_DUNGEONS_NONE) != + RO_MQ_DUNGEONS_SET_NUMBER || CVarGetInteger(CVAR_RANDOMIZER_SETTING("MQDungeonCount"), 12) < 12) // at least one vanilla dungeon ) && - ( - location.GetRCType() != RCTYPE_SHOP || - !( - ctx->GetOption(RSK_SHOPSANITY).Is(RO_SHOPSANITY_OFF) || - ( - ctx->GetOption(RSK_SHOPSANITY).Is(RO_SHOPSANITY_SPECIFIC_COUNT) && - ctx->GetOption(RSK_SHOPSANITY_COUNT).Is(RO_SHOPSANITY_COUNT_ZERO_ITEMS) - ) - ) - ) && + (location.GetRCType() != RCTYPE_SHOP || + !(ctx->GetOption(RSK_SHOPSANITY).Is(RO_SHOPSANITY_OFF) || + (ctx->GetOption(RSK_SHOPSANITY).Is(RO_SHOPSANITY_SPECIFIC_COUNT) && + ctx->GetOption(RSK_SHOPSANITY_COUNT).Is(RO_SHOPSANITY_COUNT_ZERO_ITEMS)))) && (location.GetRCType() != RCTYPE_SCRUB || CVarGetInteger(CVAR_RANDOMIZER_SETTING("ShuffleScrubs"), RO_SCRUBS_OFF) != RO_SCRUBS_OFF || location.GetRandomizerCheck() == RC_HF_DEKU_SCRUB_GROTTO || @@ -137,7 +134,8 @@ void RandomizerCheckObjects::UpdateImGuiVisibility() { location.GetRandomizerCheck() == RC_LW_DEKU_SCRUB_NEAR_BRIDGE) && // The 3 scrubs that are always randomized (location.GetRCType() != RCTYPE_MERCHANT || - CVarGetInteger(CVAR_RANDOMIZER_SETTING("ShuffleMerchants"), RO_SHUFFLE_MERCHANTS_OFF) != RO_SHUFFLE_MERCHANTS_OFF) && + CVarGetInteger(CVAR_RANDOMIZER_SETTING("ShuffleMerchants"), RO_SHUFFLE_MERCHANTS_OFF) != + RO_SHUFFLE_MERCHANTS_OFF) && (location.GetRCType() != RCTYPE_SONG_LOCATION || CVarGetInteger(CVAR_RANDOMIZER_SETTING("ShuffleSongs"), RO_SONG_SHUFFLE_SONG_LOCATIONS) != RO_SONG_SHUFFLE_SONG_LOCATIONS) && // song locations @@ -152,31 +150,45 @@ void RandomizerCheckObjects::UpdateImGuiVisibility() { (location.GetRCType() != RCTYPE_OCARINA || CVarGetInteger(CVAR_RANDOMIZER_SETTING("ShuffleOcarinas"), RO_GENERIC_NO)) && // ocarina locations (location.GetRandomizerCheck() != RC_HC_ZELDAS_LETTER) && // don't show until we support shuffling letter - (location.GetRCType() != RCTYPE_GOSSIP_STONE) && // don't show gossip stones (maybe gossipsanity will be a thing eventually?) - (location.GetRCType() != RCTYPE_STATIC_HINT) && // don't show static hints + (location.GetRCType() != + RCTYPE_GOSSIP_STONE) && // don't show gossip stones (maybe gossipsanity will be a thing eventually?) + (location.GetRCType() != RCTYPE_STATIC_HINT) && // don't show static hints (location.GetRCType() != RCTYPE_LINKS_POCKET) && // links pocket can be set to nothing if needed (location.GetRCType() != RCTYPE_CHEST_GAME) && // don't show non final reward chest game checks until we support shuffling them (location.GetRCType() != RCTYPE_SKULL_TOKEN || (CVarGetInteger(CVAR_RANDOMIZER_SETTING("ShuffleTokens"), RO_TOKENSANITY_OFF) == RO_TOKENSANITY_ALL) || - ((CVarGetInteger(CVAR_RANDOMIZER_SETTING("ShuffleTokens"), RO_TOKENSANITY_OFF) == RO_TOKENSANITY_OVERWORLD) && + ((CVarGetInteger(CVAR_RANDOMIZER_SETTING("ShuffleTokens"), RO_TOKENSANITY_OFF) == + RO_TOKENSANITY_OVERWORLD) && RandomizerCheckObjects::AreaIsOverworld(location.GetArea())) || - ((CVarGetInteger(CVAR_RANDOMIZER_SETTING("ShuffleTokens"), RO_TOKENSANITY_OFF) == RO_TOKENSANITY_DUNGEONS) && + ((CVarGetInteger(CVAR_RANDOMIZER_SETTING("ShuffleTokens"), RO_TOKENSANITY_OFF) == + RO_TOKENSANITY_DUNGEONS) && RandomizerCheckObjects::AreaIsDungeon(location.GetArea()))) && (location.GetRCType() != RCTYPE_FREESTANDING || - (CVarGetInteger(CVAR_RANDOMIZER_SETTING("ShuffleFreestanding"), RO_SHUFFLE_FREESTANDING_OFF) == RO_SHUFFLE_FREESTANDING_ALL) || - ((CVarGetInteger(CVAR_RANDOMIZER_SETTING("ShuffleFreestanding"), RO_SHUFFLE_FREESTANDING_OFF) == RO_SHUFFLE_FREESTANDING_OVERWORLD) && + (CVarGetInteger(CVAR_RANDOMIZER_SETTING("ShuffleFreestanding"), RO_SHUFFLE_FREESTANDING_OFF) == + RO_SHUFFLE_FREESTANDING_ALL) || + ((CVarGetInteger(CVAR_RANDOMIZER_SETTING("ShuffleFreestanding"), RO_SHUFFLE_FREESTANDING_OFF) == + RO_SHUFFLE_FREESTANDING_OVERWORLD) && RandomizerCheckObjects::AreaIsOverworld(location.GetArea())) || - ((CVarGetInteger(CVAR_RANDOMIZER_SETTING("ShuffleFreestanding"), RO_SHUFFLE_FREESTANDING_OFF) == RO_SHUFFLE_FREESTANDING_DUNGEONS) && + ((CVarGetInteger(CVAR_RANDOMIZER_SETTING("ShuffleFreestanding"), RO_SHUFFLE_FREESTANDING_OFF) == + RO_SHUFFLE_FREESTANDING_DUNGEONS) && RandomizerCheckObjects::AreaIsDungeon(location.GetArea()))) && - (location.GetRCType() != RCTYPE_BEEHIVE || CVarGetInteger(CVAR_RANDOMIZER_SETTING("ShuffleBeehives"), RO_GENERIC_NO)) && - (location.GetRCType() != RCTYPE_COW || CVarGetInteger(CVAR_RANDOMIZER_SETTING("ShuffleCows"), RO_GENERIC_NO)) && - (location.GetRCType() != RCTYPE_POT || CVarGetInteger(CVAR_RANDOMIZER_SETTING("ShufflePots"), RO_GENERIC_NO)) && - (location.GetRCType() != RCTYPE_GRASS || CVarGetInteger(CVAR_RANDOMIZER_SETTING("ShuffleGrass"), RO_GENERIC_NO)) && - (location.GetRCType() != RCTYPE_CRATE || CVarGetInteger(CVAR_RANDOMIZER_SETTING("ShuffleCrates"), RO_GENERIC_NO)) && - (location.GetRCType() != RCTYPE_NLCRATE || CVarGetInteger(CVAR_RANDOMIZER_SETTING("ShuffleCrates"), RO_GENERIC_NO)) && - (location.GetRCType() != RCTYPE_SMALL_CRATE || CVarGetInteger(CVAR_RANDOMIZER_SETTING("ShuffleCrates"), RO_GENERIC_NO)) && - (location.GetRCType() != RCTYPE_FISH || ctx->GetFishsanity()->GetFishLocationIncluded(&location, FSO_SOURCE_CVARS)) && + (location.GetRCType() != RCTYPE_BEEHIVE || + CVarGetInteger(CVAR_RANDOMIZER_SETTING("ShuffleBeehives"), RO_GENERIC_NO)) && + (location.GetRCType() != RCTYPE_COW || + CVarGetInteger(CVAR_RANDOMIZER_SETTING("ShuffleCows"), RO_GENERIC_NO)) && + (location.GetRCType() != RCTYPE_POT || + CVarGetInteger(CVAR_RANDOMIZER_SETTING("ShufflePots"), RO_GENERIC_NO)) && + (location.GetRCType() != RCTYPE_GRASS || + CVarGetInteger(CVAR_RANDOMIZER_SETTING("ShuffleGrass"), RO_GENERIC_NO)) && + (location.GetRCType() != RCTYPE_CRATE || + CVarGetInteger(CVAR_RANDOMIZER_SETTING("ShuffleCrates"), RO_GENERIC_NO)) && + (location.GetRCType() != RCTYPE_NLCRATE || + CVarGetInteger(CVAR_RANDOMIZER_SETTING("ShuffleCrates"), RO_GENERIC_NO)) && + (location.GetRCType() != RCTYPE_SMALL_CRATE || + CVarGetInteger(CVAR_RANDOMIZER_SETTING("ShuffleCrates"), RO_GENERIC_NO)) && + (location.GetRCType() != RCTYPE_FISH || + ctx->GetFishsanity()->GetFishLocationIncluded(&location, FSO_SOURCE_CVARS)) && (location.GetRCType() != RCTYPE_ADULT_TRADE || CVarGetInteger(CVAR_RANDOMIZER_SETTING("ShuffleAdultTrade"), RO_GENERIC_NO)) && (location.GetRandomizerCheck() != RC_KF_KOKIRI_SWORD_CHEST || @@ -195,7 +207,8 @@ void RandomizerCheckObjects::UpdateImGuiVisibility() { CVarGetInteger(CVAR_RANDOMIZER_SETTING("StartingMapsCompasses"), RO_DUNGEON_ITEM_LOC_OWN_DUNGEON) != RO_DUNGEON_ITEM_LOC_VANILLA) && (location.GetRCType() != RCTYPE_SMALL_KEY || - CVarGetInteger(CVAR_RANDOMIZER_SETTING("Keysanity"), RO_DUNGEON_ITEM_LOC_OWN_DUNGEON) != RO_DUNGEON_ITEM_LOC_VANILLA) && + CVarGetInteger(CVAR_RANDOMIZER_SETTING("Keysanity"), RO_DUNGEON_ITEM_LOC_OWN_DUNGEON) != + RO_DUNGEON_ITEM_LOC_VANILLA) && (location.GetRCType() != RCTYPE_BOSS_KEY || CVarGetInteger(CVAR_RANDOMIZER_SETTING("BossKeysanity"), RO_DUNGEON_ITEM_LOC_OWN_DUNGEON) != RO_DUNGEON_ITEM_LOC_VANILLA) && @@ -219,17 +232,22 @@ void RandomizerCheckObjects::UpdateImGuiVisibility() { CVarGetInteger(CVAR_RANDOMIZER_SETTING("ShuffleGanonBossKey"), RO_GANON_BOSS_KEY_VANILLA) != RO_GANON_BOSS_KEY_KAK_TOKENS) && // 100 skull reward ganon boss key (location.GetRCType() != RCTYPE_GF_KEY && location.GetRandomizerCheck() != RC_GF_GERUDO_MEMBERSHIP_CARD || - (CVarGetInteger(CVAR_RANDOMIZER_SETTING("FortressCarpenters"), RO_GF_CARPENTERS_NORMAL) == RO_GF_CARPENTERS_FREE && + (CVarGetInteger(CVAR_RANDOMIZER_SETTING("FortressCarpenters"), RO_GF_CARPENTERS_NORMAL) == + RO_GF_CARPENTERS_FREE && location.GetRCType() != RCTYPE_GF_KEY && location.GetRandomizerCheck() != RC_GF_GERUDO_MEMBERSHIP_CARD) || - (CVarGetInteger(CVAR_RANDOMIZER_SETTING("FortressCarpenters"), RO_GF_CARPENTERS_NORMAL) == RO_GF_CARPENTERS_FAST && + (CVarGetInteger(CVAR_RANDOMIZER_SETTING("FortressCarpenters"), RO_GF_CARPENTERS_NORMAL) == + RO_GF_CARPENTERS_FAST && ((location.GetRandomizerCheck() == RC_GF_GERUDO_MEMBERSHIP_CARD && CVarGetInteger(CVAR_RANDOMIZER_SETTING("ShuffleGerudoToken"), RO_GENERIC_NO) == RO_GENERIC_YES) || (location.GetRandomizerCheck() == RC_GF_NORTH_F1_CARPENTER && - CVarGetInteger(CVAR_RANDOMIZER_SETTING("GerudoKeys"), RO_GERUDO_KEYS_VANILLA) != RO_GERUDO_KEYS_VANILLA))) || - (CVarGetInteger(CVAR_RANDOMIZER_SETTING("FortressCarpenters"), RO_GF_CARPENTERS_NORMAL) == RO_GF_CARPENTERS_NORMAL && + CVarGetInteger(CVAR_RANDOMIZER_SETTING("GerudoKeys"), RO_GERUDO_KEYS_VANILLA) != + RO_GERUDO_KEYS_VANILLA))) || + (CVarGetInteger(CVAR_RANDOMIZER_SETTING("FortressCarpenters"), RO_GF_CARPENTERS_NORMAL) == + RO_GF_CARPENTERS_NORMAL && ((location.GetRandomizerCheck() == RC_GF_GERUDO_MEMBERSHIP_CARD && CVarGetInteger(CVAR_RANDOMIZER_SETTING("ShuffleGerudoToken"), RO_GENERIC_NO) == RO_GENERIC_YES) || (location.GetRCType() == RCTYPE_GF_KEY && - CVarGetInteger(CVAR_RANDOMIZER_SETTING("GerudoKeys"), RO_GERUDO_KEYS_VANILLA) != RO_GERUDO_KEYS_VANILLA))))); + CVarGetInteger(CVAR_RANDOMIZER_SETTING("GerudoKeys"), RO_GERUDO_KEYS_VANILLA) != + RO_GERUDO_KEYS_VANILLA))))); } } diff --git a/soh/soh/Enhancements/randomizer/randomizer_check_objects.h b/soh/soh/Enhancements/randomizer/randomizer_check_objects.h index 6ab5b8314..7a7e605bb 100644 --- a/soh/soh/Enhancements/randomizer/randomizer_check_objects.h +++ b/soh/soh/Enhancements/randomizer/randomizer_check_objects.h @@ -7,11 +7,11 @@ #include namespace RandomizerCheckObjects { - bool AreaIsDungeon(RandomizerCheckArea area); - bool AreaIsOverworld(RandomizerCheckArea area); - std::string GetRCAreaName(RandomizerCheckArea area); - std::map> GetAllRCObjectsByArea(); - std::map GetAllRCAreaBySceneID(); - RandomizerCheckArea GetRCAreaBySceneID(SceneID sceneId); - void UpdateImGuiVisibility(); -} +bool AreaIsDungeon(RandomizerCheckArea area); +bool AreaIsOverworld(RandomizerCheckArea area); +std::string GetRCAreaName(RandomizerCheckArea area); +std::map> GetAllRCObjectsByArea(); +std::map GetAllRCAreaBySceneID(); +RandomizerCheckArea GetRCAreaBySceneID(SceneID sceneId); +void UpdateImGuiVisibility(); +} // namespace RandomizerCheckObjects diff --git a/soh/soh/Enhancements/randomizer/randomizer_check_tracker.cpp b/soh/soh/Enhancements/randomizer/randomizer_check_tracker.cpp index 270bdbb7f..eb935146a 100644 --- a/soh/soh/Enhancements/randomizer/randomizer_check_tracker.cpp +++ b/soh/soh/Enhancements/randomizer/randomizer_check_tracker.cpp @@ -90,27 +90,29 @@ bool previousShowHidden = false; bool hideShopUnshuffledChecks = false; bool alwaysShowGS = false; -std::map startingShopItem = { { SCENE_KOKIRI_SHOP, RC_KF_SHOP_ITEM_1 }, - { SCENE_BAZAAR, RC_MARKET_BAZAAR_ITEM_1 }, - { SCENE_POTION_SHOP_MARKET, RC_MARKET_POTION_SHOP_ITEM_1 }, - { SCENE_BOMBCHU_SHOP, RC_MARKET_BOMBCHU_SHOP_ITEM_1 }, - { SCENE_POTION_SHOP_KAKARIKO, RC_KAK_POTION_SHOP_ITEM_1 }, - { SCENE_ZORA_SHOP, RC_ZD_SHOP_ITEM_1 }, - { SCENE_GORON_SHOP, RC_GC_SHOP_ITEM_1 }, }; +std::map startingShopItem = { + { SCENE_KOKIRI_SHOP, RC_KF_SHOP_ITEM_1 }, + { SCENE_BAZAAR, RC_MARKET_BAZAAR_ITEM_1 }, + { SCENE_POTION_SHOP_MARKET, RC_MARKET_POTION_SHOP_ITEM_1 }, + { SCENE_BOMBCHU_SHOP, RC_MARKET_BOMBCHU_SHOP_ITEM_1 }, + { SCENE_POTION_SHOP_KAKARIKO, RC_KAK_POTION_SHOP_ITEM_1 }, + { SCENE_ZORA_SHOP, RC_ZD_SHOP_ITEM_1 }, + { SCENE_GORON_SHOP, RC_GC_SHOP_ITEM_1 }, +}; std::map DungeonRCAreasBySceneID = { - {SCENE_DEKU_TREE, RCAREA_DEKU_TREE}, - {SCENE_DODONGOS_CAVERN, RCAREA_DODONGOS_CAVERN}, - {SCENE_JABU_JABU, RCAREA_JABU_JABUS_BELLY}, - {SCENE_FOREST_TEMPLE, RCAREA_FOREST_TEMPLE}, - {SCENE_FIRE_TEMPLE, RCAREA_FIRE_TEMPLE}, - {SCENE_WATER_TEMPLE, RCAREA_WATER_TEMPLE}, - {SCENE_SHADOW_TEMPLE, RCAREA_SHADOW_TEMPLE}, - {SCENE_SPIRIT_TEMPLE, RCAREA_SPIRIT_TEMPLE}, - {SCENE_BOTTOM_OF_THE_WELL, RCAREA_BOTTOM_OF_THE_WELL}, - {SCENE_ICE_CAVERN, RCAREA_ICE_CAVERN}, - {SCENE_GERUDO_TRAINING_GROUND, RCAREA_GERUDO_TRAINING_GROUND}, - {SCENE_INSIDE_GANONS_CASTLE, RCAREA_GANONS_CASTLE}, + { SCENE_DEKU_TREE, RCAREA_DEKU_TREE }, + { SCENE_DODONGOS_CAVERN, RCAREA_DODONGOS_CAVERN }, + { SCENE_JABU_JABU, RCAREA_JABU_JABUS_BELLY }, + { SCENE_FOREST_TEMPLE, RCAREA_FOREST_TEMPLE }, + { SCENE_FIRE_TEMPLE, RCAREA_FIRE_TEMPLE }, + { SCENE_WATER_TEMPLE, RCAREA_WATER_TEMPLE }, + { SCENE_SHADOW_TEMPLE, RCAREA_SHADOW_TEMPLE }, + { SCENE_SPIRIT_TEMPLE, RCAREA_SPIRIT_TEMPLE }, + { SCENE_BOTTOM_OF_THE_WELL, RCAREA_BOTTOM_OF_THE_WELL }, + { SCENE_ICE_CAVERN, RCAREA_ICE_CAVERN }, + { SCENE_GERUDO_TRAINING_GROUND, RCAREA_GERUDO_TRAINING_GROUND }, + { SCENE_INSIDE_GANONS_CASTLE, RCAREA_GANONS_CASTLE }, }; // Dungeon entrances with obvious visual differences between MQ and vanilla qualifying as spoiling on sight @@ -141,7 +143,7 @@ uint16_t totalChecks = 0; uint16_t totalChecksAvailable = 0; uint16_t totalChecksGotten = 0; bool optCollapseAll; // A bool that will collapse all checks once -bool optExpandAll; // A bool that will expand all checks once +bool optExpandAll; // A bool that will expand all checks once RandomizerCheck lastLocationChecked = RC_UNKNOWN_CHECK; RandomizerCheckArea previousArea = RCAREA_INVALID; RandomizerCheckArea currentArea = RCAREA_INVALID; @@ -176,55 +178,68 @@ bool onlyShowAvailable = false; SceneID DungeonSceneLookupByArea(RandomizerCheckArea area) { switch (area) { - case RCAREA_DEKU_TREE: return SCENE_DEKU_TREE; - case RCAREA_DODONGOS_CAVERN: return SCENE_DODONGOS_CAVERN; - case RCAREA_JABU_JABUS_BELLY: return SCENE_JABU_JABU; - case RCAREA_FOREST_TEMPLE: return SCENE_FOREST_TEMPLE; - case RCAREA_FIRE_TEMPLE: return SCENE_FIRE_TEMPLE; - case RCAREA_WATER_TEMPLE: return SCENE_WATER_TEMPLE; - case RCAREA_SPIRIT_TEMPLE: return SCENE_SPIRIT_TEMPLE; - case RCAREA_SHADOW_TEMPLE: return SCENE_SHADOW_TEMPLE; - case RCAREA_BOTTOM_OF_THE_WELL: return SCENE_BOTTOM_OF_THE_WELL; - case RCAREA_ICE_CAVERN: return SCENE_ICE_CAVERN; - case RCAREA_GERUDO_TRAINING_GROUND: return SCENE_GERUDO_TRAINING_GROUND; - case RCAREA_GANONS_CASTLE: return SCENE_INSIDE_GANONS_CASTLE; - default: return SCENE_ID_MAX; + case RCAREA_DEKU_TREE: + return SCENE_DEKU_TREE; + case RCAREA_DODONGOS_CAVERN: + return SCENE_DODONGOS_CAVERN; + case RCAREA_JABU_JABUS_BELLY: + return SCENE_JABU_JABU; + case RCAREA_FOREST_TEMPLE: + return SCENE_FOREST_TEMPLE; + case RCAREA_FIRE_TEMPLE: + return SCENE_FIRE_TEMPLE; + case RCAREA_WATER_TEMPLE: + return SCENE_WATER_TEMPLE; + case RCAREA_SPIRIT_TEMPLE: + return SCENE_SPIRIT_TEMPLE; + case RCAREA_SHADOW_TEMPLE: + return SCENE_SHADOW_TEMPLE; + case RCAREA_BOTTOM_OF_THE_WELL: + return SCENE_BOTTOM_OF_THE_WELL; + case RCAREA_ICE_CAVERN: + return SCENE_ICE_CAVERN; + case RCAREA_GERUDO_TRAINING_GROUND: + return SCENE_GERUDO_TRAINING_GROUND; + case RCAREA_GANONS_CASTLE: + return SCENE_INSIDE_GANONS_CASTLE; + default: + return SCENE_ID_MAX; } } -Color_RGBA8 Color_Bg_Default = { 0, 0, 0, 255 }; // Black -Color_RGBA8 Color_Main_Default = { 255, 255, 255, 255 }; // White -Color_RGBA8 Color_Area_Incomplete_Extra_Default = { 255, 255, 255, 255 }; // White -Color_RGBA8 Color_Area_Complete_Extra_Default = { 255, 255, 255, 255 }; // White -Color_RGBA8 Color_Unchecked_Extra_Default = { 255, 255, 255, 255 }; // White -Color_RGBA8 Color_Skipped_Main_Default = { 160, 160, 160, 255 }; // Grey -Color_RGBA8 Color_Skipped_Extra_Default = { 160, 160, 160, 255 }; // Grey -Color_RGBA8 Color_Seen_Extra_Default = { 255, 255, 255, 255 }; // TODO -Color_RGBA8 Color_Hinted_Extra_Default = { 255, 255, 255, 255 }; // TODO -Color_RGBA8 Color_Collected_Extra_Default = { 242, 101, 34, 255 }; // Orange -Color_RGBA8 Color_Scummed_Extra_Default = { 0, 174, 239, 255 }; // Blue -Color_RGBA8 Color_Saved_Extra_Default = { 0, 185, 0, 255 }; // Green +Color_RGBA8 Color_Bg_Default = { 0, 0, 0, 255 }; // Black +Color_RGBA8 Color_Main_Default = { 255, 255, 255, 255 }; // White +Color_RGBA8 Color_Area_Incomplete_Extra_Default = { 255, 255, 255, 255 }; // White +Color_RGBA8 Color_Area_Complete_Extra_Default = { 255, 255, 255, 255 }; // White +Color_RGBA8 Color_Unchecked_Extra_Default = { 255, 255, 255, 255 }; // White +Color_RGBA8 Color_Skipped_Main_Default = { 160, 160, 160, 255 }; // Grey +Color_RGBA8 Color_Skipped_Extra_Default = { 160, 160, 160, 255 }; // Grey +Color_RGBA8 Color_Seen_Extra_Default = { 255, 255, 255, 255 }; // TODO +Color_RGBA8 Color_Hinted_Extra_Default = { 255, 255, 255, 255 }; // TODO +Color_RGBA8 Color_Collected_Extra_Default = { 242, 101, 34, 255 }; // Orange +Color_RGBA8 Color_Scummed_Extra_Default = { 0, 174, 239, 255 }; // Blue +Color_RGBA8 Color_Saved_Extra_Default = { 0, 185, 0, 255 }; // Green Color_RGBA8 Color_Background = { 0, 0, 0, 255 }; -Color_RGBA8 Color_Area_Incomplete_Main = { 255, 255, 255, 255 }; // White +Color_RGBA8 Color_Area_Incomplete_Main = { 255, 255, 255, 255 }; // White Color_RGBA8 Color_Area_Incomplete_Extra = { 255, 255, 255, 255 }; // White -Color_RGBA8 Color_Area_Complete_Main = { 255, 255, 255, 255 }; // White -Color_RGBA8 Color_Area_Complete_Extra = { 255, 255, 255, 255 }; // White -Color_RGBA8 Color_Unchecked_Main = { 255, 255, 255, 255 }; // White -Color_RGBA8 Color_Unchecked_Extra = { 255, 255, 255, 255 }; // Useless -Color_RGBA8 Color_Skipped_Main = { 160, 160, 160, 255 }; // Grey -Color_RGBA8 Color_Skipped_Extra = { 160, 160, 160, 255 }; // Grey -Color_RGBA8 Color_Seen_Main = { 255, 255, 255, 255 }; // TODO -Color_RGBA8 Color_Seen_Extra = { 160, 160, 160, 255 }; // TODO -Color_RGBA8 Color_Hinted_Main = { 255, 255, 255, 255 }; // TODO -Color_RGBA8 Color_Hinted_Extra = { 255, 255, 255, 255 }; // TODO -Color_RGBA8 Color_Collected_Main = { 255, 255, 255, 255 }; // White -Color_RGBA8 Color_Collected_Extra = { 242, 101, 34, 255 }; // Orange -Color_RGBA8 Color_Scummed_Main = { 255, 255, 255, 255 }; // White -Color_RGBA8 Color_Scummed_Extra = { 0, 174, 239, 255 }; // Blue -Color_RGBA8 Color_Saved_Main = { 255, 255, 255, 255 }; // White -Color_RGBA8 Color_Saved_Extra = { 0, 185, 0, 255 }; // Green +Color_RGBA8 Color_Area_Complete_Main = { 255, 255, 255, 255 }; // White +Color_RGBA8 Color_Area_Complete_Extra = { 255, 255, 255, 255 }; // White +Color_RGBA8 Color_Unchecked_Main = { 255, 255, 255, 255 }; // White +Color_RGBA8 Color_Unchecked_Extra = { 255, 255, 255, 255 }; // Useless +Color_RGBA8 Color_Skipped_Main = { 160, 160, 160, 255 }; // Grey +Color_RGBA8 Color_Skipped_Extra = { 160, 160, 160, 255 }; // Grey +Color_RGBA8 Color_Seen_Main = { 255, 255, 255, 255 }; // TODO +Color_RGBA8 Color_Seen_Extra = { 160, 160, 160, 255 }; // TODO +Color_RGBA8 Color_Hinted_Main = { 255, 255, 255, 255 }; // TODO +Color_RGBA8 Color_Hinted_Extra = { 255, 255, 255, 255 }; // TODO +Color_RGBA8 Color_Collected_Main = { 255, 255, 255, 255 }; // White +Color_RGBA8 Color_Collected_Extra = { 242, 101, 34, 255 }; // Orange +Color_RGBA8 Color_Scummed_Main = { 255, 255, 255, 255 }; // White +Color_RGBA8 Color_Scummed_Extra = { 0, 174, 239, 255 }; // Blue +Color_RGBA8 Color_Saved_Main = { 255, 255, 255, 255 }; // White +Color_RGBA8 Color_Saved_Extra = { 0, 185, 0, 255 }; // Green std::vector buttons = { BTN_A, BTN_B, BTN_CUP, BTN_CDOWN, BTN_CLEFT, BTN_CRIGHT, BTN_L, BTN_Z, BTN_R, BTN_START, BTN_DUP, BTN_DDOWN, BTN_DLEFT, BTN_DRIGHT }; @@ -270,12 +285,8 @@ bool IsCheckHidden(RandomizerCheck rc) { bool scummed = status == RCSHOW_SCUMMED; bool unchecked = status == RCSHOW_UNCHECKED; - return !showHidden && ( - (skipped && hideSkipped) || - (seen && hideSeen) || - (scummed && hideScummed) || - (unchecked && hideUnchecked) - ); + return !showHidden && + ((skipped && hideSkipped) || (seen && hideSeen) || (scummed && hideScummed) || (unchecked && hideUnchecked)); } void RecalculateAreaTotals(RandomizerCheckArea rcArea) { @@ -302,7 +313,7 @@ void RecalculateAreaTotals(RandomizerCheckArea rcArea) { } std::map MapRGtoRandomizerCheckArea = { - { RG_DEKU_TREE_MAP, RCAREA_DEKU_TREE}, + { RG_DEKU_TREE_MAP, RCAREA_DEKU_TREE }, { RG_DODONGOS_CAVERN_MAP, RCAREA_DODONGOS_CAVERN }, { RG_JABU_JABUS_BELLY_MAP, RCAREA_JABU_JABUS_BELLY }, { RG_FOREST_TEMPLE_MAP, RCAREA_FOREST_TEMPLE }, @@ -405,33 +416,19 @@ bool IsAreaScene(SceneID sceneNum) { } RandomizerCheckArea AreaFromEntranceGroup[] = { - RCAREA_INVALID, - RCAREA_KOKIRI_FOREST, - RCAREA_LOST_WOODS, - RCAREA_SACRED_FOREST_MEADOW, - RCAREA_KAKARIKO_VILLAGE, - RCAREA_GRAVEYARD, - RCAREA_DEATH_MOUNTAIN_TRAIL, - RCAREA_DEATH_MOUNTAIN_CRATER, - RCAREA_GORON_CITY, - RCAREA_ZORAS_RIVER, - RCAREA_ZORAS_DOMAIN, - RCAREA_ZORAS_FOUNTAIN, - RCAREA_HYRULE_FIELD, - RCAREA_LON_LON_RANCH, - RCAREA_LAKE_HYLIA, - RCAREA_GERUDO_VALLEY, - RCAREA_GERUDO_FORTRESS, - RCAREA_WASTELAND, - RCAREA_DESERT_COLOSSUS, - RCAREA_MARKET, + RCAREA_INVALID, RCAREA_KOKIRI_FOREST, RCAREA_LOST_WOODS, RCAREA_SACRED_FOREST_MEADOW, + RCAREA_KAKARIKO_VILLAGE, RCAREA_GRAVEYARD, RCAREA_DEATH_MOUNTAIN_TRAIL, RCAREA_DEATH_MOUNTAIN_CRATER, + RCAREA_GORON_CITY, RCAREA_ZORAS_RIVER, RCAREA_ZORAS_DOMAIN, RCAREA_ZORAS_FOUNTAIN, + RCAREA_HYRULE_FIELD, RCAREA_LON_LON_RANCH, RCAREA_LAKE_HYLIA, RCAREA_GERUDO_VALLEY, + RCAREA_GERUDO_FORTRESS, RCAREA_WASTELAND, RCAREA_DESERT_COLOSSUS, RCAREA_MARKET, RCAREA_HYRULE_CASTLE, }; RandomizerCheckArea GetCheckArea() { auto scene = static_cast(gPlayState->sceneNum); bool grottoScene = (scene == SCENE_GROTTOS || scene == SCENE_FAIRYS_FOUNTAIN); - const EntranceData* ent = GetEntranceData(grottoScene ? ENTRANCE_GROTTO_EXIT_START + GetCurrentGrottoId() : gSaveContext.entranceIndex); + const EntranceData* ent = + GetEntranceData(grottoScene ? ENTRANCE_GROTTO_EXIT_START + GetCurrentGrottoId() : gSaveContext.entranceIndex); RandomizerCheckArea area = RCAREA_INVALID; if (ent != nullptr && !IsAreaScene(scene) && ent->type != ENTRANCE_TYPE_DUNGEON) { if (ent->source == "Desert Colossus" || ent->destination == "Desert Colossus") { @@ -441,7 +438,8 @@ RandomizerCheckArea GetCheckArea() { } } if (area == RCAREA_INVALID) { - if (grottoScene && (GetCurrentGrottoId() == -1) && (OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_SHUFFLE_GROTTO_ENTRANCES) == RO_GENERIC_OFF)) { + if (grottoScene && (GetCurrentGrottoId() == -1) && + (OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_SHUFFLE_GROTTO_ENTRANCES) == RO_GENERIC_OFF)) { area = previousArea; } else { area = RandomizerCheckObjects::GetRCAreaBySceneID(scene); @@ -454,7 +452,13 @@ bool vector_contains_scene(std::vector vec, const int16_t scene) { return std::any_of(vec.begin(), vec.end(), [&](const auto& x) { return x == scene; }); } -std::vector skipScenes = {SCENE_GANON_BOSS, SCENE_GANONS_TOWER_COLLAPSE_EXTERIOR, SCENE_GANON_BOSS, SCENE_INSIDE_GANONS_CASTLE_COLLAPSE, SCENE_GANONS_TOWER_COLLAPSE_INTERIOR,}; +std::vector skipScenes = { + SCENE_GANON_BOSS, + SCENE_GANONS_TOWER_COLLAPSE_EXTERIOR, + SCENE_GANON_BOSS, + SCENE_INSIDE_GANONS_CASTLE_COLLAPSE, + SCENE_GANONS_TOWER_COLLAPSE_INTERIOR, +}; void ClearAreaChecksAndTotals() { for (auto& [rcArea, vec] : checksByArea) { @@ -518,7 +522,8 @@ void CheckTrackerLoadGame(int32_t fileNum) { } // Create check name overrides for child pond fish if age split is disabled - if (fishsanityMode != RO_FISHSANITY_OFF && fishsanityMode != RO_FISHSANITY_OVERWORLD && entry.GetRCType() == RCTYPE_FISH && entry.GetScene() == SCENE_FISHING_POND && + if (fishsanityMode != RO_FISHSANITY_OFF && fishsanityMode != RO_FISHSANITY_OVERWORLD && + entry.GetRCType() == RCTYPE_FISH && entry.GetScene() == SCENE_FISHING_POND && entry.GetActorParams() != 116 && !fishsanityAgeSplit) { if (entry.GetShortName().starts_with("Child")) { checkNameOverrides[rc] = entry.GetShortName().substr(6); @@ -526,19 +531,25 @@ void CheckTrackerLoadGame(int32_t fileNum) { } } for (int i = RCAREA_KOKIRI_FOREST; i < RCAREA_INVALID; i++) { - if (!IsAreaSpoiled(static_cast(i)) && (RandomizerCheckObjects::AreaIsOverworld(static_cast(i)) || !IS_RANDO || - OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_MQ_DUNGEON_RANDOM) == RO_MQ_DUNGEONS_NONE || - (OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_MQ_DUNGEON_RANDOM) == RO_MQ_DUNGEONS_SELECTION && - OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(static_cast(RSK_MQ_DEKU_TREE + (i - RCAREA_DEKU_TREE))) != RO_MQ_SET_RANDOM) || - (OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_MQ_DUNGEON_SET) == RO_GENERIC_ON && - OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(static_cast(RSK_MQ_DEKU_TREE + (i - RCAREA_DEKU_TREE))) != RO_MQ_SET_RANDOM) || - (OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_MQ_DUNGEON_RANDOM) == RO_MQ_DUNGEONS_SET_NUMBER && - (OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_MQ_DUNGEON_COUNT) == 12 || - OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_MQ_DUNGEON_COUNT) == 0)))) { + if (!IsAreaSpoiled(static_cast(i)) && + (RandomizerCheckObjects::AreaIsOverworld(static_cast(i)) || !IS_RANDO || + OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_MQ_DUNGEON_RANDOM) == RO_MQ_DUNGEONS_NONE || + (OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_MQ_DUNGEON_RANDOM) == + RO_MQ_DUNGEONS_SELECTION && + OTRGlobals::Instance->gRandomizer->GetRandoSettingValue( + static_cast(RSK_MQ_DEKU_TREE + (i - RCAREA_DEKU_TREE))) != RO_MQ_SET_RANDOM) || + (OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_MQ_DUNGEON_SET) == RO_GENERIC_ON && + OTRGlobals::Instance->gRandomizer->GetRandoSettingValue( + static_cast(RSK_MQ_DEKU_TREE + (i - RCAREA_DEKU_TREE))) != RO_MQ_SET_RANDOM) || + (OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_MQ_DUNGEON_RANDOM) == + RO_MQ_DUNGEONS_SET_NUMBER && + (OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_MQ_DUNGEON_COUNT) == 12 || + OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_MQ_DUNGEON_COUNT) == 0)))) { SetAreaSpoiled(static_cast(i)); } } - if (OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_LINKS_POCKET) != RO_LINKS_POCKET_NOTHING && IS_RANDO) { + if (OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_LINKS_POCKET) != RO_LINKS_POCKET_NOTHING && + IS_RANDO) { uint8_t startingAge = OTRGlobals::Instance->gRandoContext->GetOption(RSK_SELECTED_STARTING_AGE).Get(); RandomizerCheckArea startingArea; switch (startingAge) { @@ -558,9 +569,11 @@ void CheckTrackerLoadGame(int32_t fileNum) { areaCheckTotals[startingArea]++; } - showVOrMQ = (OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_MQ_DUNGEON_RANDOM) == RO_MQ_DUNGEONS_RANDOM_NUMBER || - (OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_MQ_DUNGEON_RANDOM) == RO_MQ_DUNGEONS_SET_NUMBER && - OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_MQ_DUNGEON_COUNT) < 12)); + showVOrMQ = + (OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_MQ_DUNGEON_RANDOM) == + RO_MQ_DUNGEONS_RANDOM_NUMBER || + (OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_MQ_DUNGEON_RANDOM) == RO_MQ_DUNGEONS_SET_NUMBER && + OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_MQ_DUNGEON_COUNT) < 12)); initialized = true; UpdateAllOrdering(); UpdateInventoryChecks(); @@ -603,7 +616,9 @@ void CheckTrackerTransition(uint32_t sceneNum) { SetShopSeen(sceneNum, false); break; } - if (!IsAreaSpoiled(currentArea) && (RandomizerCheckObjects::AreaIsOverworld(currentArea) || std::find(spoilingEntrances.begin(), spoilingEntrances.end(), gPlayState->nextEntranceIndex) != spoilingEntrances.end())) { + if (!IsAreaSpoiled(currentArea) && (RandomizerCheckObjects::AreaIsOverworld(currentArea) || + std::find(spoilingEntrances.begin(), spoilingEntrances.end(), + gPlayState->nextEntranceIndex) != spoilingEntrances.end())) { SetAreaSpoiled(currentArea); } } @@ -618,7 +633,7 @@ void CheckTrackerItemReceive(GetItemEntry giEntry) { if (giEntry.itemId == ITEM_SHIELD_DEKU) { SetCheckCollected(RC_KF_SHOP_ITEM_1); return; - }else if (giEntry.itemId == ITEM_KOKIRI_EMERALD) { + } else if (giEntry.itemId == ITEM_KOKIRI_EMERALD) { SetCheckCollected(RC_QUEEN_GOHMA); return; } else if (giEntry.itemId == ITEM_GORON_RUBY) { @@ -657,34 +672,34 @@ void CheckTrackerItemReceive(GetItemEntry giEntry) { } else if (giEntry.itemId == ITEM_BRACELET) { SetCheckCollected(RC_GC_DARUNIAS_JOY); return; - }/* else if (giEntry.itemId == ITEM_SONG_SUN) { - SetCheckCollected(RC_SONG_FROM_ROYAL_FAMILYS_TOMB); - return; - } else if (giEntry.itemId == ITEM_SONG_TIME) { - SetCheckCollected(RC_SONG_FROM_OCARINA_OF_TIME); - return; - } else if (giEntry.itemId == ITEM_SONG_STORMS) { - SetCheckCollected(RC_SONG_FROM_WINDMILL); - return; - } else if (giEntry.itemId == ITEM_SONG_MINUET) { - SetCheckCollected(RC_SHEIK_IN_FOREST); - return; - } else if (giEntry.itemId == ITEM_SONG_BOLERO) { - SetCheckCollected(RC_SHEIK_IN_CRATER); - return; - } else if (giEntry.itemId == ITEM_SONG_SERENADE) { - SetCheckCollected(RC_SHEIK_IN_ICE_CAVERN); - return; - } else if (giEntry.itemId == ITEM_SONG_NOCTURNE) { - SetCheckCollected(RC_SHEIK_IN_KAKARIKO); - return; - } else if (giEntry.itemId == ITEM_SONG_REQUIEM) { - SetCheckCollected(RC_SHEIK_AT_COLOSSUS); - return; - } else if (giEntry.itemId == ITEM_SONG_PRELUDE) { - SetCheckCollected(RC_SHEIK_AT_TEMPLE); - return; - }*/ + } /* else if (giEntry.itemId == ITEM_SONG_SUN) { + SetCheckCollected(RC_SONG_FROM_ROYAL_FAMILYS_TOMB); + return; + } else if (giEntry.itemId == ITEM_SONG_TIME) { + SetCheckCollected(RC_SONG_FROM_OCARINA_OF_TIME); + return; + } else if (giEntry.itemId == ITEM_SONG_STORMS) { + SetCheckCollected(RC_SONG_FROM_WINDMILL); + return; + } else if (giEntry.itemId == ITEM_SONG_MINUET) { + SetCheckCollected(RC_SHEIK_IN_FOREST); + return; + } else if (giEntry.itemId == ITEM_SONG_BOLERO) { + SetCheckCollected(RC_SHEIK_IN_CRATER); + return; + } else if (giEntry.itemId == ITEM_SONG_SERENADE) { + SetCheckCollected(RC_SHEIK_IN_ICE_CAVERN); + return; + } else if (giEntry.itemId == ITEM_SONG_NOCTURNE) { + SetCheckCollected(RC_SHEIK_IN_KAKARIKO); + return; + } else if (giEntry.itemId == ITEM_SONG_REQUIEM) { + SetCheckCollected(RC_SHEIK_AT_COLOSSUS); + return; + } else if (giEntry.itemId == ITEM_SONG_PRELUDE) { + SetCheckCollected(RC_SHEIK_AT_TEMPLE); + return; + }*/ } } @@ -696,7 +711,8 @@ void CheckTrackerSceneFlagSet(int16_t sceneNum, int16_t flagType, int32_t flag) if (flagType != FLAG_SCENE_TREASURE && flagType != FLAG_SCENE_COLLECTIBLE) { return; } - if (sceneNum == SCENE_GRAVEYARD && flag == 0x19 && flagType == FLAG_SCENE_COLLECTIBLE) { // Gravedigging tour special case + if (sceneNum == SCENE_GRAVEYARD && flag == 0x19 && + flagType == FLAG_SCENE_COLLECTIBLE) { // Gravedigging tour special case SetCheckCollected(RC_GRAVEYARD_DAMPE_GRAVEDIGGING_TOUR); return; } @@ -704,7 +720,9 @@ void CheckTrackerSceneFlagSet(int16_t sceneNum, int16_t flagType, int32_t flag) if (!IsVisibleInCheckTracker(loc.GetRandomizerCheck())) { continue; } - SpoilerCollectionCheckType checkMatchType = flagType == FLAG_SCENE_TREASURE ? SpoilerCollectionCheckType::SPOILER_CHK_CHEST : SpoilerCollectionCheckType::SPOILER_CHK_COLLECTABLE; + SpoilerCollectionCheckType checkMatchType = flagType == FLAG_SCENE_TREASURE + ? SpoilerCollectionCheckType::SPOILER_CHK_CHEST + : SpoilerCollectionCheckType::SPOILER_CHK_COLLECTABLE; Rando::SpoilerCollectionCheck scCheck = loc.GetCollectionCheck(); if (scCheck.scene == sceneNum && scCheck.flag == flag && scCheck.type == checkMatchType) { SetCheckCollected(loc.GetRandomizerCheck()); @@ -725,8 +743,8 @@ void CheckTrackerFlagSet(int16_t flagType, int32_t flag) { break; case FLAG_EVENT_CHECK_INF: if ((flag == EVENTCHKINF_CARPENTERS_FREE(0) || flag == EVENTCHKINF_CARPENTERS_FREE(1) || - flag == EVENTCHKINF_CARPENTERS_FREE(2) || flag == EVENTCHKINF_CARPENTERS_FREE(3)) - && GET_EVENTCHKINF_CARPENTERS_FREE_ALL()) { + flag == EVENTCHKINF_CARPENTERS_FREE(2) || flag == EVENTCHKINF_CARPENTERS_FREE(3)) && + GET_EVENTCHKINF_CARPENTERS_FREE_ALL()) { SetCheckCollected(RC_GF_GERUDO_MEMBERSHIP_CARD); return; } @@ -784,16 +802,18 @@ void CheckTrackerFlagSet(int16_t flagType, int32_t flag) { for (auto& loc : Rando::StaticData::GetLocationTable()) { if ((!IS_RANDO && ((loc.GetQuest() == RCQUEST_MQ && !IS_MASTER_QUEST) || (loc.GetQuest() == RCQUEST_VANILLA && IS_MASTER_QUEST))) || - (IS_RANDO && !(OTRGlobals::Instance->gRandoContext->GetDungeons()->GetDungeonFromScene(loc.GetScene()) == nullptr) && - ((OTRGlobals::Instance->gRandoContext->GetDungeons()->GetDungeonFromScene(loc.GetScene())->IsMQ() && - loc.GetQuest() == RCQUEST_VANILLA) || - OTRGlobals::Instance->gRandoContext->GetDungeons()->GetDungeonFromScene(loc.GetScene())->IsVanilla() && - loc.GetQuest() == RCQUEST_MQ))) { + (IS_RANDO && + !(OTRGlobals::Instance->gRandoContext->GetDungeons()->GetDungeonFromScene(loc.GetScene()) == nullptr) && + ((OTRGlobals::Instance->gRandoContext->GetDungeons()->GetDungeonFromScene(loc.GetScene())->IsMQ() && + loc.GetQuest() == RCQUEST_VANILLA) || + OTRGlobals::Instance->gRandoContext->GetDungeons()->GetDungeonFromScene(loc.GetScene())->IsVanilla() && + loc.GetQuest() == RCQUEST_MQ))) { continue; } Rando::SpoilerCollectionCheck scCheck = loc.GetCollectionCheck(); SpoilerCollectionCheckType scCheckType = scCheck.type; - if (checkMatchType == SpoilerCollectionCheckType::SPOILER_CHK_RANDOMIZER_INF && scCheckType == SpoilerCollectionCheckType::SPOILER_CHK_RANDOMIZER_INF) { + if (checkMatchType == SpoilerCollectionCheckType::SPOILER_CHK_RANDOMIZER_INF && + scCheckType == SpoilerCollectionCheckType::SPOILER_CHK_RANDOMIZER_INF) { if (flag == OTRGlobals::Instance->gRandomizer->GetRandomizerInfFromCheck(loc.GetRandomizerCheck())) { SetCheckCollected(loc.GetRandomizerCheck()); return; @@ -826,15 +846,15 @@ void SaveTrackerData(SaveContext* saveContext, int sectionID, bool fullSave) { } SaveManager::Instance->SaveArray("checkStatus", checkCount.size(), [&](size_t i) { RandomizerCheck check = checkCount.at(i); - RandomizerCheckStatus savedStatus = OTRGlobals::Instance->gRandoContext->GetItemLocation(check)->GetCheckStatus(); + RandomizerCheckStatus savedStatus = + OTRGlobals::Instance->gRandoContext->GetItemLocation(check)->GetCheckStatus(); bool isSkipped = OTRGlobals::Instance->gRandoContext->GetItemLocation(check)->GetIsSkipped(); if (savedStatus == RCSHOW_COLLECTED) { if (fullSave) { OTRGlobals::Instance->gRandoContext->GetItemLocation(check)->SetCheckStatus(RCSHOW_SAVED); savedStatus = RCSHOW_SAVED; updateOrdering = true; - } - else { + } else { savedStatus = RCSHOW_SCUMMED; } } @@ -843,7 +863,7 @@ void SaveTrackerData(SaveContext* saveContext, int sectionID, bool fullSave) { SaveManager::Instance->SaveData("randomizerCheck", check); SaveManager::Instance->SaveData("status", savedStatus); SaveManager::Instance->SaveData("skipped", isSkipped); - }); + }); } }); SaveManager::Instance->SaveData("areasSpoiled", areasSpoiled); @@ -871,8 +891,8 @@ void LoadFile() { SaveManager::Instance->LoadData("skipped", skipped, false); OTRGlobals::Instance->gRandoContext->GetItemLocation(rc)->SetCheckStatus(status); OTRGlobals::Instance->gRandoContext->GetItemLocation(rc)->SetIsSkipped(skipped); - }); }); + }); SaveManager::Instance->LoadData("areasSpoiled", areasSpoiled, (uint32_t)0); UpdateAllOrdering(); UpdateAllAreas(); @@ -900,51 +920,57 @@ void SetAreaSpoiled(RandomizerCheckArea rcArea) { } void CheckTrackerWindow::DrawElement() { - Color_Background = CVarGetColor(CVAR_TRACKER_CHECK("BgColor.Value"), Color_Bg_Default); - Color_Area_Incomplete_Main = CVarGetColor(CVAR_TRACKER_CHECK("AreaIncomplete.MainColor.Value"), Color_Main_Default); - Color_Area_Incomplete_Extra = CVarGetColor(CVAR_TRACKER_CHECK("AreaIncomplete.ExtraColor.Value"), Color_Area_Incomplete_Extra_Default); - Color_Area_Complete_Main = CVarGetColor(CVAR_TRACKER_CHECK("AreaComplete.MainColor.Value"), Color_Main_Default); - Color_Area_Complete_Extra = CVarGetColor(CVAR_TRACKER_CHECK("AreaComplete.ExtraColor.Value"), Color_Area_Complete_Extra_Default); - Color_Unchecked_Main = CVarGetColor(CVAR_TRACKER_CHECK("Unchecked.MainColor.Value"), Color_Main_Default); - Color_Unchecked_Extra = CVarGetColor(CVAR_TRACKER_CHECK("Unchecked.ExtraColor.Value"), Color_Unchecked_Extra_Default); - Color_Skipped_Main = CVarGetColor(CVAR_TRACKER_CHECK("Skipped.MainColor.Value"), Color_Main_Default); - Color_Skipped_Extra = CVarGetColor(CVAR_TRACKER_CHECK("Skipped.ExtraColor.Value"), Color_Skipped_Extra_Default); - Color_Seen_Main = CVarGetColor(CVAR_TRACKER_CHECK("Seen.MainColor.Value"), Color_Main_Default); - Color_Seen_Extra = CVarGetColor(CVAR_TRACKER_CHECK("Seen.ExtraColor.Value"), Color_Seen_Extra_Default); - Color_Hinted_Main = CVarGetColor(CVAR_TRACKER_CHECK("Hinted.MainColor.Value"), Color_Main_Default); - Color_Hinted_Extra = CVarGetColor(CVAR_TRACKER_CHECK("Hinted.ExtraColor.Value"), Color_Hinted_Extra_Default); - Color_Collected_Main = CVarGetColor(CVAR_TRACKER_CHECK("Collected.MainColor.Value"), Color_Main_Default); - Color_Collected_Extra = CVarGetColor(CVAR_TRACKER_CHECK("Collected.ExtraColor.Value"), Color_Collected_Extra_Default); - Color_Scummed_Main = CVarGetColor(CVAR_TRACKER_CHECK("Scummed.MainColor.Value"), Color_Main_Default); - Color_Scummed_Extra = CVarGetColor(CVAR_TRACKER_CHECK("Scummed.ExtraColor.Value"), Color_Scummed_Extra_Default); - Color_Saved_Main = CVarGetColor(CVAR_TRACKER_CHECK("Saved.MainColor.Value"), Color_Main_Default); - Color_Saved_Extra = CVarGetColor(CVAR_TRACKER_CHECK("Saved.ExtraColor.Value"), Color_Saved_Extra_Default); - hideUnchecked = CVarGetInteger(CVAR_TRACKER_CHECK("Unchecked.Hide"), 0); - hideScummed = CVarGetInteger(CVAR_TRACKER_CHECK("Scummed.Hide"), 0); - hideSeen = CVarGetInteger(CVAR_TRACKER_CHECK("Seen.Hide"), 0); - hideSkipped = CVarGetInteger(CVAR_TRACKER_CHECK("Skipped.Hide"), 0); - hideSaved = CVarGetInteger(CVAR_TRACKER_CHECK("Saved.Hide"), 0); - hideCollected = CVarGetInteger(CVAR_TRACKER_CHECK("Collected.Hide"), 0); - showHidden = CVarGetInteger(CVAR_TRACKER_CHECK("ShowHidden"), 0); - mystery = CVarGetInteger(CVAR_RANDOMIZER_ENHANCEMENT("MysteriousShuffle"), 0); - showLogicTooltip = CVarGetInteger(CVAR_TRACKER_CHECK("ShowLogic"), 0); - enableAvailableChecks = CVarGetInteger(CVAR_TRACKER_CHECK("EnableAvailableChecks"), 0); - onlyShowAvailable = CVarGetInteger(CVAR_TRACKER_CHECK("OnlyShowAvailable"), 0); + Color_Background = CVarGetColor(CVAR_TRACKER_CHECK("BgColor.Value"), Color_Bg_Default); + Color_Area_Incomplete_Main = CVarGetColor(CVAR_TRACKER_CHECK("AreaIncomplete.MainColor.Value"), Color_Main_Default); + Color_Area_Incomplete_Extra = + CVarGetColor(CVAR_TRACKER_CHECK("AreaIncomplete.ExtraColor.Value"), Color_Area_Incomplete_Extra_Default); + Color_Area_Complete_Main = CVarGetColor(CVAR_TRACKER_CHECK("AreaComplete.MainColor.Value"), Color_Main_Default); + Color_Area_Complete_Extra = + CVarGetColor(CVAR_TRACKER_CHECK("AreaComplete.ExtraColor.Value"), Color_Area_Complete_Extra_Default); + Color_Unchecked_Main = CVarGetColor(CVAR_TRACKER_CHECK("Unchecked.MainColor.Value"), Color_Main_Default); + Color_Unchecked_Extra = + CVarGetColor(CVAR_TRACKER_CHECK("Unchecked.ExtraColor.Value"), Color_Unchecked_Extra_Default); + Color_Skipped_Main = CVarGetColor(CVAR_TRACKER_CHECK("Skipped.MainColor.Value"), Color_Main_Default); + Color_Skipped_Extra = CVarGetColor(CVAR_TRACKER_CHECK("Skipped.ExtraColor.Value"), Color_Skipped_Extra_Default); + Color_Seen_Main = CVarGetColor(CVAR_TRACKER_CHECK("Seen.MainColor.Value"), Color_Main_Default); + Color_Seen_Extra = CVarGetColor(CVAR_TRACKER_CHECK("Seen.ExtraColor.Value"), Color_Seen_Extra_Default); + Color_Hinted_Main = CVarGetColor(CVAR_TRACKER_CHECK("Hinted.MainColor.Value"), Color_Main_Default); + Color_Hinted_Extra = CVarGetColor(CVAR_TRACKER_CHECK("Hinted.ExtraColor.Value"), Color_Hinted_Extra_Default); + Color_Collected_Main = CVarGetColor(CVAR_TRACKER_CHECK("Collected.MainColor.Value"), Color_Main_Default); + Color_Collected_Extra = + CVarGetColor(CVAR_TRACKER_CHECK("Collected.ExtraColor.Value"), Color_Collected_Extra_Default); + Color_Scummed_Main = CVarGetColor(CVAR_TRACKER_CHECK("Scummed.MainColor.Value"), Color_Main_Default); + Color_Scummed_Extra = CVarGetColor(CVAR_TRACKER_CHECK("Scummed.ExtraColor.Value"), Color_Scummed_Extra_Default); + Color_Saved_Main = CVarGetColor(CVAR_TRACKER_CHECK("Saved.MainColor.Value"), Color_Main_Default); + Color_Saved_Extra = CVarGetColor(CVAR_TRACKER_CHECK("Saved.ExtraColor.Value"), Color_Saved_Extra_Default); + hideUnchecked = CVarGetInteger(CVAR_TRACKER_CHECK("Unchecked.Hide"), 0); + hideScummed = CVarGetInteger(CVAR_TRACKER_CHECK("Scummed.Hide"), 0); + hideSeen = CVarGetInteger(CVAR_TRACKER_CHECK("Seen.Hide"), 0); + hideSkipped = CVarGetInteger(CVAR_TRACKER_CHECK("Skipped.Hide"), 0); + hideSaved = CVarGetInteger(CVAR_TRACKER_CHECK("Saved.Hide"), 0); + hideCollected = CVarGetInteger(CVAR_TRACKER_CHECK("Collected.Hide"), 0); + showHidden = CVarGetInteger(CVAR_TRACKER_CHECK("ShowHidden"), 0); + mystery = CVarGetInteger(CVAR_RANDOMIZER_ENHANCEMENT("MysteriousShuffle"), 0); + showLogicTooltip = CVarGetInteger(CVAR_TRACKER_CHECK("ShowLogic"), 0); + enableAvailableChecks = CVarGetInteger(CVAR_TRACKER_CHECK("EnableAvailableChecks"), 0); + onlyShowAvailable = CVarGetInteger(CVAR_TRACKER_CHECK("OnlyShowAvailable"), 0); hideShopUnshuffledChecks = CVarGetInteger(CVAR_TRACKER_CHECK("HideUnshuffledShopChecks"), 0); alwaysShowGS = CVarGetInteger(CVAR_TRACKER_CHECK("AlwaysShowGSLocs"), 0); if (CVarGetInteger(CVAR_TRACKER_CHECK("WindowType"), TRACKER_WINDOW_WINDOW) == TRACKER_WINDOW_FLOATING) { - if (CVarGetInteger(CVAR_TRACKER_CHECK("ShowOnlyPaused"), 0) && (gPlayState == nullptr || gPlayState->pauseCtx.state == 0)) { + if (CVarGetInteger(CVAR_TRACKER_CHECK("ShowOnlyPaused"), 0) && + (gPlayState == nullptr || gPlayState->pauseCtx.state == 0)) { return; } if (CVarGetInteger(CVAR_TRACKER_CHECK("DisplayType"), TRACKER_DISPLAY_ALWAYS) == TRACKER_DISPLAY_COMBO_BUTTON) { int comboButton1Mask = buttons[CVarGetInteger(CVAR_TRACKER_CHECK("ComboButton1"), TRACKER_COMBO_BUTTON_L)]; int comboButton2Mask = buttons[CVarGetInteger(CVAR_TRACKER_CHECK("ComboButton2"), TRACKER_COMBO_BUTTON_R)]; - OSContPad* trackerButtonsPressed = std::dynamic_pointer_cast(Ship::Context::GetInstance()->GetControlDeck())->GetPads(); + OSContPad* trackerButtonsPressed = + std::dynamic_pointer_cast(Ship::Context::GetInstance()->GetControlDeck())->GetPads(); bool comboButtonsHeld = trackerButtonsPressed != nullptr && - trackerButtonsPressed[0].button & comboButton1Mask && - trackerButtonsPressed[0].button & comboButton2Mask; + trackerButtonsPressed[0].button & comboButton1Mask && + trackerButtonsPressed[0].button & comboButton2Mask; if (!comboButtonsHeld) { return; } @@ -955,7 +981,7 @@ void CheckTrackerWindow::DrawElement() { BeginFloatWindows("Check Tracker", mIsVisible, ImGuiWindowFlags_NoScrollbar); if (!GameInteractor::IsSaveLoaded() || !initialized) { - ImGui::Text("Waiting for file load..."); //TODO Language + ImGui::Text("Waiting for file load..."); // TODO Language EndFloatWindows(); return; } @@ -965,7 +991,7 @@ void CheckTrackerWindow::DrawElement() { sceneId = (SceneID)gPlayState->sceneNum; } - //Quick Options + // Quick Options #ifdef __WIIU__ float headerHeight = 40.0f; #else @@ -981,16 +1007,19 @@ void CheckTrackerWindow::DrawElement() { ImGui::TableNextRow(0, headerHeight); ImGui::TableNextColumn(); if (UIWidgets::CVarCheckbox( - "Show Hidden Items", CVAR_TRACKER_CHECK("ShowHidden"), UIWidgets::CheckboxOptions({{.tooltip = "When active, items will show hidden checks by default when updated to this state." }}) - .Color(THEME_COLOR))) { + "Show Hidden Items", CVAR_TRACKER_CHECK("ShowHidden"), + UIWidgets::CheckboxOptions( + { { .tooltip = "When active, items will show hidden checks by default when updated to this state." } }) + .Color(THEME_COLOR))) { doAreaScroll = true; showHidden = CVarGetInteger(CVAR_TRACKER_CHECK("ShowHidden"), 0); RecalculateAllAreaTotals(); } if (enableAvailableChecks) { if (UIWidgets::CVarCheckbox( - "Only Show Available Checks", CVAR_TRACKER_CHECK("OnlyShowAvailable"), UIWidgets::CheckboxOptions({{ .tooltip = "When active, unavailable checks will be hidden." }}) - .Color(THEME_COLOR))) { + "Only Show Available Checks", CVAR_TRACKER_CHECK("OnlyShowAvailable"), + UIWidgets::CheckboxOptions({ { .tooltip = "When active, unavailable checks will be hidden." } }) + .Color(THEME_COLOR))) { doAreaScroll = true; RecalculateAllAreaTotals(); } @@ -1002,12 +1031,15 @@ void CheckTrackerWindow::DrawElement() { doAreaScroll = true; } ImGui::SameLine(); - if (UIWidgets::Button("Collapse All", UIWidgets::ButtonOptions().Color(THEME_COLOR).Size(UIWidgets::Sizes::Inline))) { + if (UIWidgets::Button("Collapse All", + UIWidgets::ButtonOptions().Color(THEME_COLOR).Size(UIWidgets::Sizes::Inline))) { optExpandAll = false; optCollapseAll = true; } ImGui::SameLine(); - if (UIWidgets::Button("Clear", UIWidgets::ButtonOptions({{ .tooltip = "Clear the search field" }}).Color(THEME_COLOR).Size(UIWidgets::Sizes::Inline))) { + if (UIWidgets::Button("Clear", UIWidgets::ButtonOptions({ { .tooltip = "Clear the search field" } }) + .Color(THEME_COLOR) + .Size(UIWidgets::Sizes::Inline))) { checkSearch.Clear(); UpdateFilters(); doAreaScroll = true; @@ -1030,7 +1062,7 @@ void CheckTrackerWindow::DrawElement() { UIWidgets::PaddedSeparator(); - //Checks Section Lead-in + // Checks Section Lead-in ImGui::TableNextRow(); ImGui::TableNextColumn(); size = ImGui::GetContentRegionAvail(); @@ -1042,7 +1074,7 @@ void CheckTrackerWindow::DrawElement() { ImGui::TableNextRow(); ImGui::TableNextColumn(); - //Prep for loop + // Prep for loop RainbowTick(); bool doDraw = false; bool thisAreaFullyChecked = false; @@ -1053,22 +1085,26 @@ void CheckTrackerWindow::DrawElement() { bool doingCollapseOrExpand = optExpandAll || optCollapseAll; bool isThisAreaSpoiled; RandomizerCheckArea lastArea = RCAREA_INVALID; - Color_RGBA8 areaCompleteColor = CVarGetColor(CVAR_TRACKER_CHECK("AreaComplete.MainColor.Value"), Color_Main_Default); - Color_RGBA8 areaIncompleteColor = CVarGetColor(CVAR_TRACKER_CHECK("AreaIncomplete.MainColor.Value"), Color_Main_Default); - Color_RGBA8 extraCompleteColor = CVarGetColor(CVAR_TRACKER_CHECK("AreaComplete.ExtraColor.Value"), Color_Area_Complete_Extra_Default); - Color_RGBA8 extraIncompleteColor = CVarGetColor(CVAR_TRACKER_CHECK("AreaIncomplete.ExtraColor.Value"), Color_Area_Incomplete_Extra_Default); + Color_RGBA8 areaCompleteColor = + CVarGetColor(CVAR_TRACKER_CHECK("AreaComplete.MainColor.Value"), Color_Main_Default); + Color_RGBA8 areaIncompleteColor = + CVarGetColor(CVAR_TRACKER_CHECK("AreaIncomplete.MainColor.Value"), Color_Main_Default); + Color_RGBA8 extraCompleteColor = + CVarGetColor(CVAR_TRACKER_CHECK("AreaComplete.ExtraColor.Value"), Color_Area_Complete_Extra_Default); + Color_RGBA8 extraIncompleteColor = + CVarGetColor(CVAR_TRACKER_CHECK("AreaIncomplete.ExtraColor.Value"), Color_Area_Incomplete_Extra_Default); Color_RGBA8 mainColor; Color_RGBA8 extraColor; std::string stemp; bool shouldHideFilteredAreas = CVarGetInteger(CVAR_TRACKER_CHECK("HideFilteredAreas"), 1); - + ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, ImVec2(4.0f, 3.0f)); for (auto& [rcArea, checks] : checksByArea) { RandomizerCheckArea thisArea = currentArea; thisAreaFullyChecked = (areaChecksGotten[rcArea] == areaCheckTotals[rcArea]); - //Last Area needs to be cleaned up + // Last Area needs to be cleaned up if (lastArea != RCAREA_INVALID && doDraw) { UIWidgets::PaddedSeparator(); } @@ -1079,11 +1115,10 @@ void CheckTrackerWindow::DrawElement() { } if ((shouldHideFilteredAreas && filterAreasHidden[rcArea]) || (!showHidden && ((hideComplete && thisAreaFullyChecked) || (hideIncomplete && !thisAreaFullyChecked))) || - (enableAvailableChecks && onlyShowAvailable && areaChecksAvailable[rcArea] == 0) - ) { + (enableAvailableChecks && onlyShowAvailable && areaChecksAvailable[rcArea] == 0)) { doDraw = false; } else { - //Get the colour for the area + // Get the colour for the area if (thisAreaFullyChecked) { mainColor = areaCompleteColor; extraColor = extraCompleteColor; @@ -1092,7 +1127,7 @@ void CheckTrackerWindow::DrawElement() { extraColor = extraIncompleteColor; } - //Draw the area + // Draw the area collapseLogic = !thisAreaFullyChecked; if (doingCollapseOrExpand) { if (optExpandAll) { @@ -1126,11 +1161,14 @@ void CheckTrackerWindow::DrawElement() { areaTotalsSS << static_cast(areaChecksAvailable[rcArea]) << " / "; areaTotalsTooltipSS << "Available / "; } - areaTotalsSS << static_cast(areaChecksGotten[rcArea]) << " / " << static_cast(areaCheckTotals[rcArea]) << ")"; + areaTotalsSS << static_cast(areaChecksGotten[rcArea]) << " / " + << static_cast(areaCheckTotals[rcArea]) << ")"; areaTotalsTooltipSS << "Checked / Total"; if (showVOrMQ && RandomizerCheckObjects::AreaIsDungeon(rcArea)) { - if (OTRGlobals::Instance->gRandoContext->GetDungeons()->GetDungeonFromScene(DungeonSceneLookupByArea(rcArea))->IsMQ()) { + if (OTRGlobals::Instance->gRandoContext->GetDungeons() + ->GetDungeonFromScene(DungeonSceneLookupByArea(rcArea)) + ->IsMQ()) { areaTotalsSS << " - MQ"; } else { areaTotalsSS << " - Vanilla"; @@ -1145,7 +1183,7 @@ void CheckTrackerWindow::DrawElement() { ImGui::PopStyleColor(); - //Keep areas loaded between transitions + // Keep areas loaded between transitions if (thisArea == rcArea && doAreaScroll) { ImGui::SetScrollHereY(0.0f); doAreaScroll = false; @@ -1163,8 +1201,8 @@ void CheckTrackerWindow::DrawElement() { } ImGui::PopStyleVar(); - ImGui::EndTable(); //Checks Lead-out - ImGui::EndTable(); //Quick Options Lead-out + ImGui::EndTable(); // Checks Lead-out + ImGui::EndTable(); // Quick Options Lead-out EndFloatWindows(); if (doingCollapseOrExpand) { optCollapseAll = false; @@ -1175,7 +1213,7 @@ void CheckTrackerWindow::DrawElement() { bool UpdateFilters() { for (auto& [rcArea, checks] : checksByArea) { filterAreasHidden[rcArea] = !checkSearch.PassFilter(RandomizerCheckObjects::GetRCAreaName(rcArea).c_str()); - for (auto check : checks) { + for (auto check : checks) { if (ShouldShowCheck(check)) { filterAreasHidden[rcArea] = false; filterChecksHidden[check] = false; @@ -1191,21 +1229,22 @@ bool UpdateFilters() { bool ShouldShowCheck(RandomizerCheck check) { auto itemLoc = Rando::Context::GetInstance()->GetItemLocation(check); std::string search = (Rando::StaticData::GetLocation(check)->GetShortName() + " " + - Rando::StaticData::GetLocation(check)->GetName() + " " + - RandomizerCheckObjects::GetRCAreaName(Rando::StaticData::GetLocation(check)->GetArea())); - if (itemLoc->HasObtained() || itemLoc->GetCheckStatus() == RCSHOW_SCUMMED || - (!mystery && (itemLoc->GetCheckStatus() == RCSHOW_IDENTIFIED || itemLoc->GetCheckStatus() == RCSHOW_SEEN) && itemLoc->GetPlacedRandomizerGet() != RG_ICE_TRAP)) { + Rando::StaticData::GetLocation(check)->GetName() + " " + + RandomizerCheckObjects::GetRCAreaName(Rando::StaticData::GetLocation(check)->GetArea())); + if (itemLoc->HasObtained() || itemLoc->GetCheckStatus() == RCSHOW_SCUMMED || + (!mystery && (itemLoc->GetCheckStatus() == RCSHOW_IDENTIFIED || itemLoc->GetCheckStatus() == RCSHOW_SEEN) && + itemLoc->GetPlacedRandomizerGet() != RG_ICE_TRAP)) { search += " " + itemLoc->GetPlacedItemName().GetForLanguage(gSaveContext.language); } else if (itemLoc->GetCheckStatus() == RCSHOW_IDENTIFIED && !mystery) { - search += OTRGlobals::Instance->gRandoContext->overrides[check].GetTrickName().GetForLanguage(gSaveContext.language); + search += + OTRGlobals::Instance->gRandoContext->overrides[check].GetTrickName().GetForLanguage(gSaveContext.language); } else if (itemLoc->GetCheckStatus() == RCSHOW_SEEN && !mystery) { - search += Rando::StaticData::RetrieveItem(OTRGlobals::Instance->gRandoContext->overrides[check].LooksLike()).GetName().GetForLanguage(gSaveContext.language); + search += Rando::StaticData::RetrieveItem(OTRGlobals::Instance->gRandoContext->overrides[check].LooksLike()) + .GetName() + .GetForLanguage(gSaveContext.language); } - return ( - IsVisibleInCheckTracker(check) && - (checkSearch.Filters.Size == 0 || - checkSearch.PassFilter(search.c_str())) - ); + return (IsVisibleInCheckTracker(check) && + (checkSearch.Filters.Size == 0 || checkSearch.PassFilter(search.c_str()))); } // Windowing stuff @@ -1213,8 +1252,7 @@ void BeginFloatWindows(std::string UniqueName, bool& open, ImGuiWindowFlags flag ImGuiWindowFlags windowFlags = flags; if (windowFlags == 0) { - windowFlags |= - ImGuiWindowFlags_AlwaysVerticalScrollbar | ImGuiWindowFlags_NoFocusOnAppearing; + windowFlags |= ImGuiWindowFlags_AlwaysVerticalScrollbar | ImGuiWindowFlags_NoFocusOnAppearing; } if (CVarGetInteger(CVAR_TRACKER_CHECK("WindowType"), TRACKER_WINDOW_WINDOW) == TRACKER_WINDOW_FLOATING) { @@ -1240,80 +1278,80 @@ void EndFloatWindows() { } void LoadSettings() { - //If in randomzer, then get the setting and check if in general we should be showing the settings - //If in vanilla, _try_ to show items that at least are needed for 100% + // If in randomzer, then get the setting and check if in general we should be showing the settings + // If in vanilla, _try_ to show items that at least are needed for 100% - showShops = IS_RANDO ? - OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_SHOPSANITY) != RO_SHOPSANITY_OFF - : false; - showBeans = IS_RANDO ? - OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_SHUFFLE_MERCHANTS) == RO_SHUFFLE_MERCHANTS_BEANS_ONLY || - OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_SHUFFLE_MERCHANTS) == RO_SHUFFLE_MERCHANTS_ALL - : true; - showScrubs = IS_RANDO ? - OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_SHUFFLE_SCRUBS) == RO_SCRUBS_ALL - : false; - showMajorScrubs = IS_RANDO ? - OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_SHUFFLE_SCRUBS) != RO_SCRUBS_OFF - : false; - showMerchants = IS_RANDO ? - OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_SHUFFLE_MERCHANTS) == RO_SHUFFLE_MERCHANTS_ALL_BUT_BEANS || - OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_SHUFFLE_MERCHANTS) == RO_SHUFFLE_MERCHANTS_ALL - : true; - showBeehives = IS_RANDO ? - OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_SHUFFLE_BEEHIVES) == RO_GENERIC_YES - : false; - showCows = IS_RANDO ? - OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_SHUFFLE_COWS) == RO_GENERIC_YES - : false; - showAdultTrade = IS_RANDO ? - OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_SHUFFLE_ADULT_TRADE) == RO_GENERIC_YES - : true; - showKokiriSword = IS_RANDO ? - OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_SHUFFLE_KOKIRI_SWORD) == RO_GENERIC_YES - : true; - showMasterSword = IS_RANDO ? - OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_SHUFFLE_MASTER_SWORD) == RO_GENERIC_YES - : true; - showHyruleLoach = IS_RANDO ? - OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_FISHSANITY) == RO_FISHSANITY_HYRULE_LOACH - : false; - showWeirdEgg = IS_RANDO ? - OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_SHUFFLE_WEIRD_EGG) == RO_GENERIC_YES - : true; - showGerudoCard = IS_RANDO ? - OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_SHUFFLE_GERUDO_MEMBERSHIP_CARD) == RO_GENERIC_YES - : true; - showFrogSongRupees = IS_RANDO ? - OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_SHUFFLE_FROG_SONG_RUPEES) == RO_GENERIC_YES - : false; - showFairies = IS_RANDO ? - OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_SHUFFLE_FAIRIES) == RO_GENERIC_YES - : false; - showStartingMapsCompasses = IS_RANDO ? - OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_SHUFFLE_MAPANDCOMPASS) != RO_DUNGEON_ITEM_LOC_VANILLA - : false; - showKeysanity = IS_RANDO ? - OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_KEYSANITY) != RO_DUNGEON_ITEM_LOC_VANILLA - : false; - showBossKeysanity = IS_RANDO ? - OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_BOSS_KEYSANITY) != RO_DUNGEON_ITEM_LOC_VANILLA - : false; - showGerudoFortressKeys = IS_RANDO ? - OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_GERUDO_KEYS) != RO_GERUDO_KEYS_VANILLA - : false; - showGanonBossKey = IS_RANDO ? - OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_GANONS_BOSS_KEY) != RO_GANON_BOSS_KEY_VANILLA - : false; - showOcarinas = IS_RANDO ? - OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_SHUFFLE_OCARINA) == RO_GENERIC_YES - : false; - show100SkullReward = IS_RANDO ? - OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_SHUFFLE_100_GS_REWARD) == RO_GENERIC_YES - : false; - showLinksPocket = IS_RANDO ? // don't show Link's Pocket if not randomizer, or if rando and pocket is disabled - OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_LINKS_POCKET) != RO_LINKS_POCKET_NOTHING - :false; + showShops = + IS_RANDO ? OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_SHOPSANITY) != RO_SHOPSANITY_OFF : false; + showBeans = IS_RANDO ? OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_SHUFFLE_MERCHANTS) == + RO_SHUFFLE_MERCHANTS_BEANS_ONLY || + OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_SHUFFLE_MERCHANTS) == + RO_SHUFFLE_MERCHANTS_ALL + : true; + showScrubs = + IS_RANDO ? OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_SHUFFLE_SCRUBS) == RO_SCRUBS_ALL : false; + showMajorScrubs = + IS_RANDO ? OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_SHUFFLE_SCRUBS) != RO_SCRUBS_OFF : false; + showMerchants = IS_RANDO ? OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_SHUFFLE_MERCHANTS) == + RO_SHUFFLE_MERCHANTS_ALL_BUT_BEANS || + OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_SHUFFLE_MERCHANTS) == + RO_SHUFFLE_MERCHANTS_ALL + : true; + showBeehives = IS_RANDO + ? OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_SHUFFLE_BEEHIVES) == RO_GENERIC_YES + : false; + showCows = + IS_RANDO ? OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_SHUFFLE_COWS) == RO_GENERIC_YES : false; + showAdultTrade = + IS_RANDO ? OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_SHUFFLE_ADULT_TRADE) == RO_GENERIC_YES + : true; + showKokiriSword = + IS_RANDO ? OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_SHUFFLE_KOKIRI_SWORD) == RO_GENERIC_YES + : true; + showMasterSword = + IS_RANDO ? OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_SHUFFLE_MASTER_SWORD) == RO_GENERIC_YES + : true; + showHyruleLoach = + IS_RANDO ? OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_FISHSANITY) == RO_FISHSANITY_HYRULE_LOACH + : false; + showWeirdEgg = + IS_RANDO ? OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_SHUFFLE_WEIRD_EGG) == RO_GENERIC_YES + : true; + showGerudoCard = IS_RANDO ? OTRGlobals::Instance->gRandomizer->GetRandoSettingValue( + RSK_SHUFFLE_GERUDO_MEMBERSHIP_CARD) == RO_GENERIC_YES + : true; + showFrogSongRupees = + IS_RANDO + ? OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_SHUFFLE_FROG_SONG_RUPEES) == RO_GENERIC_YES + : false; + showFairies = IS_RANDO + ? OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_SHUFFLE_FAIRIES) == RO_GENERIC_YES + : false; + showStartingMapsCompasses = IS_RANDO ? OTRGlobals::Instance->gRandomizer->GetRandoSettingValue( + RSK_SHUFFLE_MAPANDCOMPASS) != RO_DUNGEON_ITEM_LOC_VANILLA + : false; + showKeysanity = + IS_RANDO ? OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_KEYSANITY) != RO_DUNGEON_ITEM_LOC_VANILLA + : false; + showBossKeysanity = IS_RANDO ? OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_BOSS_KEYSANITY) != + RO_DUNGEON_ITEM_LOC_VANILLA + : false; + showGerudoFortressKeys = + IS_RANDO ? OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_GERUDO_KEYS) != RO_GERUDO_KEYS_VANILLA + : false; + showGanonBossKey = IS_RANDO ? OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_GANONS_BOSS_KEY) != + RO_GANON_BOSS_KEY_VANILLA + : false; + showOcarinas = IS_RANDO + ? OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_SHUFFLE_OCARINA) == RO_GENERIC_YES + : false; + show100SkullReward = + IS_RANDO ? OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_SHUFFLE_100_GS_REWARD) == RO_GENERIC_YES + : false; + showLinksPocket = + IS_RANDO ? // don't show Link's Pocket if not randomizer, or if rando and pocket is disabled + OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_LINKS_POCKET) != RO_LINKS_POCKET_NOTHING + : false; if (IS_RANDO) { switch (OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_SHUFFLE_TOKENS)) { @@ -1452,79 +1490,71 @@ bool IsCheckShuffled(RandomizerCheck rc) { auto identity = OTRGlobals::Instance->gRandomizer->IdentifyShopItem(loc->GetScene(), loc->GetActorParams() + 1); } if (IS_RANDO && OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_LOGIC_RULES) != RO_LOGIC_VANILLA) { - return - (loc->GetArea() != RCAREA_INVALID) && // don't show Invalid locations - (loc->GetRCType() != RCTYPE_GOSSIP_STONE) && //TODO: Don't show hints until tracker supports them - (loc->GetRCType() != RCTYPE_STATIC_HINT) && //TODO: Don't show hints until tracker supports them - (loc->GetRCType() != RCTYPE_CHEST_GAME) && // don't show non final reward chest game checks until we support shuffling them - (rc != RC_HC_ZELDAS_LETTER) && // don't show zeldas letter until we support shuffling it - (rc != RC_LINKS_POCKET || showLinksPocket) && - OTRGlobals::Instance->gRandoContext->IsQuestOfLocationActive(rc) && - (loc->GetRCType() != RCTYPE_SHOP || - (showShops && OTRGlobals::Instance->gRandomizer->IdentifyShopItem(loc->GetScene(), loc->GetActorParams() + 1).enGirlAShopItem == 50)) && - (rc != RC_TRIFORCE_COMPLETED) && - (rc != RC_GANON) && - (loc->GetRCType() != RCTYPE_SCRUB || - showScrubs || + return (loc->GetArea() != RCAREA_INVALID) && // don't show Invalid locations + (loc->GetRCType() != RCTYPE_GOSSIP_STONE) && // TODO: Don't show hints until tracker supports them + (loc->GetRCType() != RCTYPE_STATIC_HINT) && // TODO: Don't show hints until tracker supports them + (loc->GetRCType() != + RCTYPE_CHEST_GAME) && // don't show non final reward chest game checks until we support shuffling them + (rc != RC_HC_ZELDAS_LETTER) && // don't show zeldas letter until we support shuffling it + (rc != RC_LINKS_POCKET || showLinksPocket) && + OTRGlobals::Instance->gRandoContext->IsQuestOfLocationActive(rc) && + (loc->GetRCType() != RCTYPE_SHOP || + (showShops && + OTRGlobals::Instance->gRandomizer->IdentifyShopItem(loc->GetScene(), loc->GetActorParams() + 1) + .enGirlAShopItem == 50)) && + (rc != RC_TRIFORCE_COMPLETED) && (rc != RC_GANON) && + (loc->GetRCType() != RCTYPE_SCRUB || showScrubs || (showMajorScrubs && (rc == RC_LW_DEKU_SCRUB_NEAR_BRIDGE || // The 3 scrubs that are always randomized - rc == RC_HF_DEKU_SCRUB_GROTTO || - rc == RC_LW_DEKU_SCRUB_GROTTO_FRONT)) - ) && - (loc->GetRCType() != RCTYPE_MERCHANT || showMerchants) && - (loc->GetRCType() != RCTYPE_BEEHIVE || showBeehives) && - (loc->GetRCType() != RCTYPE_OCARINA || showOcarinas) && - (loc->GetRCType() != RCTYPE_SKULL_TOKEN || alwaysShowGS || + rc == RC_HF_DEKU_SCRUB_GROTTO || rc == RC_LW_DEKU_SCRUB_GROTTO_FRONT))) && + (loc->GetRCType() != RCTYPE_MERCHANT || showMerchants) && + (loc->GetRCType() != RCTYPE_BEEHIVE || showBeehives) && + (loc->GetRCType() != RCTYPE_OCARINA || showOcarinas) && + (loc->GetRCType() != RCTYPE_SKULL_TOKEN || alwaysShowGS || (showOverworldTokens && RandomizerCheckObjects::AreaIsOverworld(loc->GetArea())) || - (showDungeonTokens && RandomizerCheckObjects::AreaIsDungeon(loc->GetArea())) - ) && - (loc->GetRCType() != RCTYPE_POT || + (showDungeonTokens && RandomizerCheckObjects::AreaIsDungeon(loc->GetArea()))) && + (loc->GetRCType() != RCTYPE_POT || (showOverworldPots && RandomizerCheckObjects::AreaIsOverworld(loc->GetArea())) || (showDungeonPots && RandomizerCheckObjects::AreaIsDungeon(loc->GetArea()))) && - (loc->GetRCType() != RCTYPE_GRASS || + (loc->GetRCType() != RCTYPE_GRASS || (showOverworldGrass && RandomizerCheckObjects::AreaIsOverworld(loc->GetArea())) || (showDungeonGrass && RandomizerCheckObjects::AreaIsDungeon(loc->GetArea()))) && - (loc->GetRCType() != RCTYPE_CRATE || + (loc->GetRCType() != RCTYPE_CRATE || (showOverworldCrates && RandomizerCheckObjects::AreaIsOverworld(loc->GetArea())) || (showDungeonCrates && RandomizerCheckObjects::AreaIsDungeon(loc->GetArea()))) && - (loc->GetRCType() != RCTYPE_NLCRATE || + (loc->GetRCType() != RCTYPE_NLCRATE || (showOverworldCrates && RandomizerCheckObjects::AreaIsOverworld(loc->GetArea()) && - OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_LOGIC_RULES) == - RO_LOGIC_NO_LOGIC) || + OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_LOGIC_RULES) == RO_LOGIC_NO_LOGIC) || (showDungeonCrates && RandomizerCheckObjects::AreaIsDungeon(loc->GetArea()))) && - (loc->GetRCType() != RCTYPE_SMALL_CRATE || + (loc->GetRCType() != RCTYPE_SMALL_CRATE || (showOverworldCrates && RandomizerCheckObjects::AreaIsOverworld(loc->GetArea())) || (showDungeonCrates && RandomizerCheckObjects::AreaIsDungeon(loc->GetArea()))) && - (loc->GetRCType() != RCTYPE_COW || showCows) && - (loc->GetRCType() != RCTYPE_FISH || OTRGlobals::Instance->gRandoContext->GetFishsanity()->GetFishLocationIncluded(loc)) && - (loc->GetRCType() != RCTYPE_FREESTANDING || + (loc->GetRCType() != RCTYPE_COW || showCows) && + (loc->GetRCType() != RCTYPE_FISH || + OTRGlobals::Instance->gRandoContext->GetFishsanity()->GetFishLocationIncluded(loc)) && + (loc->GetRCType() != RCTYPE_FREESTANDING || (showOverworldFreestanding && RandomizerCheckObjects::AreaIsOverworld(loc->GetArea())) || - (showDungeonFreestanding && RandomizerCheckObjects::AreaIsDungeon(loc->GetArea())) - ) && - (loc->GetRCType() != RCTYPE_ADULT_TRADE || - showAdultTrade || + (showDungeonFreestanding && RandomizerCheckObjects::AreaIsDungeon(loc->GetArea()))) && + (loc->GetRCType() != RCTYPE_ADULT_TRADE || showAdultTrade || rc == RC_KAK_ANJU_AS_ADULT || // adult trade checks that are always shuffled rc == RC_DMT_TRADE_CLAIM_CHECK // even when shuffle adult trade is off ) && - (rc != RC_KF_KOKIRI_SWORD_CHEST || showKokiriSword) && - (rc != RC_TOT_MASTER_SWORD || showMasterSword) && - (rc != RC_LH_HYRULE_LOACH || showHyruleLoach) && - (rc != RC_ZR_MAGIC_BEAN_SALESMAN || showBeans) && - (rc != RC_HC_MALON_EGG || showWeirdEgg) && - (loc->GetRCType() != RCTYPE_FROG_SONG || showFrogSongRupees) && - ((loc->GetRCType() != RCTYPE_MAP && loc->GetRCType() != RCTYPE_COMPASS) || showStartingMapsCompasses) && - (loc->GetRCType() != RCTYPE_FAIRY || showFairies) && - (loc->GetRCType() != RCTYPE_SMALL_KEY || showKeysanity) && - (loc->GetRCType() != RCTYPE_BOSS_KEY || showBossKeysanity) && - (loc->GetRCType() != RCTYPE_GANON_BOSS_KEY || showGanonBossKey) && - (rc != RC_KAK_100_GOLD_SKULLTULA_REWARD || show100SkullReward) && - (loc->GetRCType() != RCTYPE_GF_KEY && rc != RC_GF_GERUDO_MEMBERSHIP_CARD || + (rc != RC_KF_KOKIRI_SWORD_CHEST || showKokiriSword) && (rc != RC_TOT_MASTER_SWORD || showMasterSword) && + (rc != RC_LH_HYRULE_LOACH || showHyruleLoach) && (rc != RC_ZR_MAGIC_BEAN_SALESMAN || showBeans) && + (rc != RC_HC_MALON_EGG || showWeirdEgg) && + (loc->GetRCType() != RCTYPE_FROG_SONG || showFrogSongRupees) && + ((loc->GetRCType() != RCTYPE_MAP && loc->GetRCType() != RCTYPE_COMPASS) || showStartingMapsCompasses) && + (loc->GetRCType() != RCTYPE_FAIRY || showFairies) && + (loc->GetRCType() != RCTYPE_SMALL_KEY || showKeysanity) && + (loc->GetRCType() != RCTYPE_BOSS_KEY || showBossKeysanity) && + (loc->GetRCType() != RCTYPE_GANON_BOSS_KEY || showGanonBossKey) && + (rc != RC_KAK_100_GOLD_SKULLTULA_REWARD || show100SkullReward) && + (loc->GetRCType() != RCTYPE_GF_KEY && rc != RC_GF_GERUDO_MEMBERSHIP_CARD || (showGerudoCard && rc == RC_GF_GERUDO_MEMBERSHIP_CARD) || (fortressNormal && showGerudoFortressKeys && loc->GetRCType() == RCTYPE_GF_KEY) || - (fortressFast && showGerudoFortressKeys && rc == RC_GF_NORTH_F1_CARPENTER) - ); - } - else if (loc->IsVanillaCompletion()) { - return (OTRGlobals::Instance->gRandoContext->IsQuestOfLocationActive(rc) || rc == RC_GIFT_FROM_RAURU) && rc != RC_LINKS_POCKET; + (fortressFast && showGerudoFortressKeys && rc == RC_GF_NORTH_F1_CARPENTER)); + } else if (loc->IsVanillaCompletion()) { + return (OTRGlobals::Instance->gRandoContext->IsQuestOfLocationActive(rc) || rc == RC_GIFT_FROM_RAURU) && + rc != RC_LINKS_POCKET; } return false; } @@ -1532,17 +1562,18 @@ bool IsCheckShuffled(RandomizerCheck rc) { bool IsVisibleInCheckTracker(RandomizerCheck rc) { auto loc = Rando::StaticData::GetLocation(rc); if (IS_RANDO) { - return IsCheckShuffled(rc) || (alwaysShowGS && - loc->GetRCType() == RCTYPE_SKULL_TOKEN && - OTRGlobals::Instance->gRandoContext->IsQuestOfLocationActive(rc) - ) || (loc->GetRCType() == RCTYPE_SHOP && showShops && !hideShopUnshuffledChecks); + return IsCheckShuffled(rc) || + (alwaysShowGS && loc->GetRCType() == RCTYPE_SKULL_TOKEN && + OTRGlobals::Instance->gRandoContext->IsQuestOfLocationActive(rc)) || + (loc->GetRCType() == RCTYPE_SHOP && showShops && !hideShopUnshuffledChecks); } else { - return loc->IsVanillaCompletion() && (!loc->IsDungeon() || (loc->IsDungeon() && loc->GetQuest() == gSaveContext.ship.quest.id)); + return loc->IsVanillaCompletion() && + (!loc->IsDungeon() || (loc->IsDungeon() && loc->GetQuest() == gSaveContext.ship.quest.id)); } } void UpdateInventoryChecks() { - //For all the areas with maps, if you have one, spoil the area + // For all the areas with maps, if you have one, spoil the area for (auto [scene, area] : DungeonRCAreasBySceneID) { if (CHECK_DUNGEON_ITEM(DUNGEON_MAP, scene)) { SetAreaSpoiled(area); @@ -1575,7 +1606,7 @@ void UpdateAllOrdering() { void UpdateOrdering(RandomizerCheckArea rcArea) { // Sort a single area - if(checksByArea.contains(rcArea)) { + if (checksByArea.contains(rcArea)) { std::sort(checksByArea.find(rcArea)->second.begin(), checksByArea.find(rcArea)->second.end(), CompareChecks); } RecalculateAllAreaTotals(); @@ -1689,8 +1720,8 @@ void DrawLocation(RandomizerCheck rc) { } mainColor = !IsHeartPiece((GetItemID)Rando::StaticData::RetrieveItem(loc->GetVanillaItem()).GetItemID()) && !IS_RANDO - ? Color_Scummed_Extra - : Color_Scummed_Main; + ? Color_Scummed_Extra + : Color_Scummed_Main; extraColor = Color_Scummed_Extra; } else if (status == RCSHOW_UNCHECKED) { if (!showHidden && hideUnchecked) { @@ -1703,22 +1734,24 @@ void DrawLocation(RandomizerCheck rc) { extraColor = Color_Unchecked_Extra; } - //Main Text + // Main Text if (checkNameOverrides.contains(loc->GetRandomizerCheck())) { txt = checkNameOverrides[loc->GetRandomizerCheck()]; } else { txt = loc->GetShortName(); } - + if (lastLocationChecked == loc->GetRandomizerCheck()) { txt = "* " + txt; } // Draw button - for Skipped/Seen/Scummed/Unchecked only - ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, {4.0f, 3.0f}); + ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, { 4.0f, 3.0f }); float sz = ImGui::GetFrameHeight(); - if (status == RCSHOW_UNCHECKED || status == RCSHOW_SEEN || status == RCSHOW_IDENTIFIED || status == RCSHOW_SCUMMED || skipped) { - if (UIWidgets::StateButton(std::to_string(rc).c_str(), skipped ? ICON_FA_PLUS : ICON_FA_TIMES, ImVec2(sz, sz), UIWidgets::ButtonOptions().Color(THEME_COLOR))) { + if (status == RCSHOW_UNCHECKED || status == RCSHOW_SEEN || status == RCSHOW_IDENTIFIED || + status == RCSHOW_SCUMMED || skipped) { + if (UIWidgets::StateButton(std::to_string(rc).c_str(), skipped ? ICON_FA_PLUS : ICON_FA_TIMES, ImVec2(sz, sz), + UIWidgets::ButtonOptions().Color(THEME_COLOR))) { if (skipped) { OTRGlobals::Instance->gRandoContext->GetItemLocation(rc)->SetIsSkipped(false); areaChecksGotten[loc->GetArea()]--; @@ -1747,7 +1780,7 @@ void DrawLocation(RandomizerCheck rc) { ImGui::SameLine(); - //Draw + // Draw ImVec4 styleColor(mainColor.r / 255.0f, mainColor.g / 255.0f, mainColor.b / 255.0f, mainColor.a / 255.0f); if (enableAvailableChecks) { if (itemLoc->HasObtained()) { @@ -1764,7 +1797,7 @@ void DrawLocation(RandomizerCheck rc) { ImGui::Text("%s", txt.c_str()); ImGui::PopStyleColor(); - //Draw the extra info + // Draw the extra info txt = ""; if (status != RCSHOW_UNCHECKED) { @@ -1776,7 +1809,8 @@ void DrawLocation(RandomizerCheck rc) { txt = itemLoc->GetPlacedItem().GetName().GetForLanguage(gSaveContext.language); } else { if (IsHeartPiece((GetItemID)Rando::StaticData::RetrieveItem(loc->GetVanillaItem()).GetItemID())) { - if (gSaveContext.language == LANGUAGE_ENG || gSaveContext.language == LANGUAGE_GER || gSaveContext.language == LANGUAGE_JPN) { + if (gSaveContext.language == LANGUAGE_ENG || gSaveContext.language == LANGUAGE_GER || + gSaveContext.language == LANGUAGE_JPN) { txt = Rando::StaticData::RetrieveItem(loc->GetVanillaItem()).GetName().english; } else if (gSaveContext.language == LANGUAGE_FRA) { txt = Rando::StaticData::RetrieveItem(loc->GetVanillaItem()).GetName().french; @@ -1789,14 +1823,19 @@ void DrawLocation(RandomizerCheck rc) { if (IS_RANDO) { if (itemLoc->GetPlacedRandomizerGet() == RG_ICE_TRAP && !mystery && !itemLoc->IsAddedToPool()) { if (status == RCSHOW_IDENTIFIED) { - txt = OTRGlobals::Instance->gRandoContext->overrides[rc].GetTrickName().GetForLanguage(gSaveContext.language); + txt = OTRGlobals::Instance->gRandoContext->overrides[rc].GetTrickName().GetForLanguage( + gSaveContext.language); } else { - txt = Rando::StaticData::RetrieveItem(OTRGlobals::Instance->gRandoContext->overrides[rc].LooksLike()).GetName().GetForLanguage(gSaveContext.language); + txt = Rando::StaticData::RetrieveItem( + OTRGlobals::Instance->gRandoContext->overrides[rc].LooksLike()) + .GetName() + .GetForLanguage(gSaveContext.language); } } else if (!mystery && !itemLoc->IsAddedToPool()) { txt = itemLoc->GetPlacedItem().GetName().GetForLanguage(gSaveContext.language); } - if (IsVisibleInCheckTracker(rc) && status == RCSHOW_IDENTIFIED && !mystery && !itemLoc->IsAddedToPool()) { + if (IsVisibleInCheckTracker(rc) && status == RCSHOW_IDENTIFIED && !mystery && + !itemLoc->IsAddedToPool()) { auto price = OTRGlobals::Instance->gRandoContext->GetItemLocation(rc)->GetPrice(); if (price) { txt += fmt::format(" - {}", price); @@ -1804,27 +1843,29 @@ void DrawLocation(RandomizerCheck rc) { } } else { if (IsHeartPiece((GetItemID)Rando::StaticData::RetrieveItem(loc->GetVanillaItem()).GetItemID())) { - if (gSaveContext.language == LANGUAGE_ENG || gSaveContext.language == LANGUAGE_GER || gSaveContext.language == LANGUAGE_JPN) { + if (gSaveContext.language == LANGUAGE_ENG || gSaveContext.language == LANGUAGE_GER || + gSaveContext.language == LANGUAGE_JPN) { txt = Rando::StaticData::RetrieveItem(loc->GetVanillaItem()).GetName().english; } else if (gSaveContext.language == LANGUAGE_FRA) { txt = Rando::StaticData::RetrieveItem(loc->GetVanillaItem()).GetName().french; } } } - break; + break; } } if (txt == "" && skipped) { txt = "Skipped"; // TODO language } - + if (txt != "") { - ImGui::PushStyleColor(ImGuiCol_Text, ImVec4(extraColor.r / 255.0f, extraColor.g / 255.0f, extraColor.b / 255.0f, extraColor.a / 255.0f)); + ImGui::PushStyleColor(ImGuiCol_Text, ImVec4(extraColor.r / 255.0f, extraColor.g / 255.0f, extraColor.b / 255.0f, + extraColor.a / 255.0f)); ImGui::SameLine(); ImGui::Text(" (%s)", txt.c_str()); ImGui::PopStyleColor(); } - + if (showLogicTooltip) { for (auto& locationInRegion : areaTable[itemLoc->GetParentRegionKey()].locations) { if (locationInRegion.GetLocation() == rc) { @@ -1859,7 +1900,7 @@ void RainbowTick() { } Color_RGBA8 newColor; - newColor.r = sin(freqHue + 0) * 127 + 128; + newColor.r = sin(freqHue + 0) * 127 + 128; newColor.g = sin(freqHue + (2 * M_PI / 3)) * 127 + 128; newColor.b = sin(freqHue + (4 * M_PI / 3)) * 127 + 128; newColor.a = 255; @@ -1872,8 +1913,9 @@ void RainbowTick() { } void ImGuiDrawTwoColorPickerSection(const char* text, const char* cvarMainName, const char* cvarExtraName, - Color_RGBA8& main_color, Color_RGBA8& extra_color, Color_RGBA8& main_default_color, - Color_RGBA8& extra_default_color, const char* cvarHideName, const char* tooltip, UIWidgets::Colors theme) { + Color_RGBA8& main_color, Color_RGBA8& extra_color, Color_RGBA8& main_default_color, + Color_RGBA8& extra_default_color, const char* cvarHideName, const char* tooltip, + UIWidgets::Colors theme) { Color_RGBA8 cvarMainColor = CVarGetColor(cvarMainName, main_default_color); Color_RGBA8 cvarExtraColor = CVarGetColor(cvarExtraName, extra_default_color); main_color = cvarMainColor; @@ -1885,20 +1927,27 @@ void ImGuiDrawTwoColorPickerSection(const char* text, const char* cvarMainName, std::string label = cvarHideName; label += "##Hidden"; ImGui::PushID(label.c_str()); - UIWidgets::CVarCheckbox("Hidden", cvarHideName, - UIWidgets::CheckboxOptions({{ .tooltip = "When active, checks will hide by default when updated to this state. Can " - "be overriden with the \"Show Hidden Items\" option." }}).Color(theme)); + UIWidgets::CVarCheckbox( + "Hidden", cvarHideName, + UIWidgets::CheckboxOptions( + { { .tooltip = "When active, checks will hide by default when updated to this state. Can " + "be overriden with the \"Show Hidden Items\" option." } }) + .Color(theme)); ImGui::PopID(); } std::string mainLabel = "Name##" + std::string(cvarMainName); if (UIWidgets::CVarColorPicker(mainLabel.c_str(), cvarMainName, main_default_color, false, - UIWidgets::ColorPickerRandomButton | UIWidgets::ColorPickerResetButton | UIWidgets::ColorPickerRainbowCheck, theme)) { + UIWidgets::ColorPickerRandomButton | UIWidgets::ColorPickerResetButton | + UIWidgets::ColorPickerRainbowCheck, + theme)) { main_color = CVarGetColor(cvarMainName, main_default_color); } std::string extraLabel = "Details##" + std::string(cvarExtraName); if (UIWidgets::CVarColorPicker(extraLabel.c_str(), cvarExtraName, extra_default_color, false, - UIWidgets::ColorPickerRandomButton | UIWidgets::ColorPickerResetButton | UIWidgets::ColorPickerRainbowCheck, theme)) { + UIWidgets::ColorPickerRandomButton | UIWidgets::ColorPickerResetButton | + UIWidgets::ColorPickerRainbowCheck, + theme)) { extra_color = CVarGetColor(cvarExtraName, extra_default_color); } } @@ -1955,10 +2004,10 @@ void RecalculateAvailableChecks() { } StopPerformanceTimer(PT_RECALCULATE_AVAILABLE_CHECKS); - SPDLOG_INFO("Recalculate Available Checks Time: {}ms", GetPerformanceTimer(PT_RECALCULATE_AVAILABLE_CHECKS).count()); + SPDLOG_INFO("Recalculate Available Checks Time: {}ms", + GetPerformanceTimer(PT_RECALCULATE_AVAILABLE_CHECKS).count()); } - void CheckTrackerWindow::Draw() { if (!IsVisible()) { return; @@ -1968,14 +2017,18 @@ void CheckTrackerWindow::Draw() { SyncVisibilityConsoleVariable(); } -static std::unordered_map windowType = {{ TRACKER_WINDOW_FLOATING, "Floating" }, { TRACKER_WINDOW_WINDOW, "Window" }}; -static std::unordered_map displayType = {{ 0, "Always" }, { 1, "Combo Button Hold" }}; +static std::unordered_map windowType = { { TRACKER_WINDOW_FLOATING, "Floating" }, + { TRACKER_WINDOW_WINDOW, "Window" } }; +static std::unordered_map displayType = { { 0, "Always" }, { 1, "Combo Button Hold" } }; static std::unordered_map buttonStrings = { - { TRACKER_COMBO_BUTTON_A, "A Button" }, { TRACKER_COMBO_BUTTON_B, "B Button" }, { TRACKER_COMBO_BUTTON_C_UP, "C-Up" }, - { TRACKER_COMBO_BUTTON_C_DOWN, "C-Down" }, { TRACKER_COMBO_BUTTON_C_LEFT, "C-Left" }, { TRACKER_COMBO_BUTTON_C_RIGHT, "C-Right" }, - { TRACKER_COMBO_BUTTON_L, "L Button" }, { TRACKER_COMBO_BUTTON_Z, "Z Button" }, { TRACKER_COMBO_BUTTON_R, "R Button" }, - { TRACKER_COMBO_BUTTON_START, "Start" }, { TRACKER_COMBO_BUTTON_D_UP, "D-Up" }, { TRACKER_COMBO_BUTTON_D_DOWN, "D-Down" }, - { TRACKER_COMBO_BUTTON_D_LEFT, "D-Left" }, { TRACKER_COMBO_BUTTON_D_RIGHT, "D-Right" }}; + { TRACKER_COMBO_BUTTON_A, "A Button" }, { TRACKER_COMBO_BUTTON_B, "B Button" }, + { TRACKER_COMBO_BUTTON_C_UP, "C-Up" }, { TRACKER_COMBO_BUTTON_C_DOWN, "C-Down" }, + { TRACKER_COMBO_BUTTON_C_LEFT, "C-Left" }, { TRACKER_COMBO_BUTTON_C_RIGHT, "C-Right" }, + { TRACKER_COMBO_BUTTON_L, "L Button" }, { TRACKER_COMBO_BUTTON_Z, "Z Button" }, + { TRACKER_COMBO_BUTTON_R, "R Button" }, { TRACKER_COMBO_BUTTON_START, "Start" }, + { TRACKER_COMBO_BUTTON_D_UP, "D-Up" }, { TRACKER_COMBO_BUTTON_D_DOWN, "D-Down" }, + { TRACKER_COMBO_BUTTON_D_LEFT, "D-Left" }, { TRACKER_COMBO_BUTTON_D_RIGHT, "D-Right" } +}; void CheckTrackerSettingsWindow::DrawElement() { ImGui::PushStyleVar(ImGuiStyleVar_CellPadding, { 8.0f, 8.0f }); @@ -1987,64 +2040,130 @@ void CheckTrackerSettingsWindow::DrawElement() { ImGui::TableNextColumn(); ImGui::PushItemWidth(ImGui::GetContentRegionAvail().x); UIWidgets::CVarColorPicker("BG Color", CVAR_TRACKER_CHECK("BgColor"), Color_Bg_Default, true, - UIWidgets::ColorPickerResetButton | UIWidgets::ColorPickerRandomButton, THEME_COLOR); + UIWidgets::ColorPickerResetButton | UIWidgets::ColorPickerRandomButton, THEME_COLOR); ImGui::PopItemWidth(); UIWidgets::CVarCombobox("Window Type", CVAR_TRACKER_CHECK("WindowType"), windowType, - UIWidgets::ComboboxOptions().LabelPosition(UIWidgets::LabelPositions::Far).ComponentAlignment(UIWidgets::ComponentAlignments::Right) - .Color(THEME_COLOR).DefaultIndex(TRACKER_WINDOW_WINDOW)); - + UIWidgets::ComboboxOptions() + .LabelPosition(UIWidgets::LabelPositions::Far) + .ComponentAlignment(UIWidgets::ComponentAlignments::Right) + .Color(THEME_COLOR) + .DefaultIndex(TRACKER_WINDOW_WINDOW)); + if (CVarGetInteger(CVAR_TRACKER_CHECK("WindowType"), TRACKER_WINDOW_WINDOW) == TRACKER_WINDOW_FLOATING) { - UIWidgets::CVarCheckbox("Enable Dragging", CVAR_TRACKER_CHECK("Draggable"), UIWidgets::CheckboxOptions().Color(THEME_COLOR)); - UIWidgets::CVarCheckbox("Only enable while paused", CVAR_TRACKER_CHECK("ShowOnlyPaused"), UIWidgets::CheckboxOptions().Color(THEME_COLOR)); + UIWidgets::CVarCheckbox("Enable Dragging", CVAR_TRACKER_CHECK("Draggable"), + UIWidgets::CheckboxOptions().Color(THEME_COLOR)); + UIWidgets::CVarCheckbox("Only enable while paused", CVAR_TRACKER_CHECK("ShowOnlyPaused"), + UIWidgets::CheckboxOptions().Color(THEME_COLOR)); UIWidgets::CVarCombobox("Display Mode", CVAR_TRACKER_CHECK("DisplayType"), displayType, - UIWidgets::ComboboxOptions().LabelPosition(UIWidgets::LabelPositions::Far).ComponentAlignment(UIWidgets::ComponentAlignments::Right) - .Color(THEME_COLOR).DefaultIndex(0)); - if (CVarGetInteger(CVAR_TRACKER_CHECK("DisplayType"), TRACKER_DISPLAY_ALWAYS) == TRACKER_DISPLAY_COMBO_BUTTON) { + UIWidgets::ComboboxOptions() + .LabelPosition(UIWidgets::LabelPositions::Far) + .ComponentAlignment(UIWidgets::ComponentAlignments::Right) + .Color(THEME_COLOR) + .DefaultIndex(0)); + if (CVarGetInteger(CVAR_TRACKER_CHECK("DisplayType"), TRACKER_DISPLAY_ALWAYS) == + TRACKER_DISPLAY_COMBO_BUTTON) { UIWidgets::CVarCombobox("Combo Button 1", CVAR_TRACKER_CHECK("ComboButton1"), buttonStrings, - UIWidgets::ComboboxOptions().LabelPosition(UIWidgets::LabelPositions::Far).ComponentAlignment(UIWidgets::ComponentAlignments::Right) - .Color(THEME_COLOR).DefaultIndex(TRACKER_COMBO_BUTTON_L)); + UIWidgets::ComboboxOptions() + .LabelPosition(UIWidgets::LabelPositions::Far) + .ComponentAlignment(UIWidgets::ComponentAlignments::Right) + .Color(THEME_COLOR) + .DefaultIndex(TRACKER_COMBO_BUTTON_L)); UIWidgets::CVarCombobox("Combo Button 2", CVAR_TRACKER_CHECK("ComboButton2"), buttonStrings, - UIWidgets::ComboboxOptions().LabelPosition(UIWidgets::LabelPositions::Far).ComponentAlignment(UIWidgets::ComponentAlignments::Right) - .Color(THEME_COLOR).DefaultIndex(TRACKER_COMBO_BUTTON_L)); + UIWidgets::ComboboxOptions() + .LabelPosition(UIWidgets::LabelPositions::Far) + .ComponentAlignment(UIWidgets::ComponentAlignments::Right) + .Color(THEME_COLOR) + .DefaultIndex(TRACKER_COMBO_BUTTON_L)); } } - UIWidgets::CVarCheckbox("Vanilla/MQ Dungeon Spoilers", CVAR_TRACKER_CHECK("MQSpoilers"), UIWidgets::CheckboxOptions() - .Tooltip("If enabled, Vanilla/MQ dungeons will show on the tracker immediately. Otherwise, Vanilla/MQ dungeon locations must be unlocked.").Color(THEME_COLOR)); - if (UIWidgets::CVarCheckbox("Hide unshuffled shop item checks", CVAR_TRACKER_CHECK("HideUnshuffledShopChecks"), - UIWidgets::CheckboxOptions().Tooltip("If enabled, will prevent the tracker from displaying slots with non-shop-item shuffles.").Color(THEME_COLOR))) { + UIWidgets::CVarCheckbox("Vanilla/MQ Dungeon Spoilers", CVAR_TRACKER_CHECK("MQSpoilers"), + UIWidgets::CheckboxOptions() + .Tooltip("If enabled, Vanilla/MQ dungeons will show on the tracker immediately. " + "Otherwise, Vanilla/MQ dungeon locations must be unlocked.") + .Color(THEME_COLOR)); + if (UIWidgets::CVarCheckbox( + "Hide unshuffled shop item checks", CVAR_TRACKER_CHECK("HideUnshuffledShopChecks"), + UIWidgets::CheckboxOptions() + .Tooltip("If enabled, will prevent the tracker from displaying slots with non-shop-item shuffles.") + .Color(THEME_COLOR))) { hideShopUnshuffledChecks = CVarGetInteger(CVAR_TRACKER_CHECK("HideUnshuffledShopChecks"), 0); UpdateFilters(); } - if (UIWidgets::CVarCheckbox("Always show gold skulltulas", CVAR_TRACKER_CHECK("AlwaysShowGSLocs"), - UIWidgets::CheckboxOptions().Tooltip("If enabled, will show GS locations in the tracker regardless of tokensanity settings.").Color(THEME_COLOR))) { + if (UIWidgets::CVarCheckbox( + "Always show gold skulltulas", CVAR_TRACKER_CHECK("AlwaysShowGSLocs"), + UIWidgets::CheckboxOptions() + .Tooltip("If enabled, will show GS locations in the tracker regardless of tokensanity settings.") + .Color(THEME_COLOR))) { alwaysShowGS = !alwaysShowGS; UpdateFilters(); } UIWidgets::CVarCheckbox("Show Logic", CVAR_TRACKER_CHECK("ShowLogic"), - UIWidgets::CheckboxOptions().Tooltip("If enabled, will show a check's logic when hovering over it.").Color(THEME_COLOR)); + UIWidgets::CheckboxOptions() + .Tooltip("If enabled, will show a check's logic when hovering over it.") + .Color(THEME_COLOR)); if (UIWidgets::CVarCheckbox("Enable Available Checks", CVAR_TRACKER_CHECK("EnableAvailableChecks"), - UIWidgets::CheckboxOptions().Tooltip("If enabled, will show the checks that are available to be collected with your current progress.").Color(THEME_COLOR))) { + UIWidgets::CheckboxOptions() + .Tooltip("If enabled, will show the checks that are available to be collected " + "with your current progress.") + .Color(THEME_COLOR))) { enableAvailableChecks = CVarGetInteger(CVAR_TRACKER_CHECK("EnableAvailableChecks"), 0); RecalculateAvailableChecks(); } // Filtering settings UIWidgets::PaddedSeparator(); - UIWidgets::CVarCheckbox("Filter Empty Areas", CVAR_TRACKER_CHECK("HideFilteredAreas"), - UIWidgets::CheckboxOptions().Tooltip("If enabled, will hide area headers that have no locations matching filter").Color(THEME_COLOR).DefaultValue(true)); + UIWidgets::CVarCheckbox( + "Filter Empty Areas", CVAR_TRACKER_CHECK("HideFilteredAreas"), + UIWidgets::CheckboxOptions() + .Tooltip("If enabled, will hide area headers that have no locations matching filter") + .Color(THEME_COLOR) + .DefaultValue(true)); ImGui::TableNextColumn(); - CheckTracker::ImGuiDrawTwoColorPickerSection("Area Incomplete", CVAR_TRACKER_CHECK("AreaIncomplete.MainColor"), CVAR_TRACKER_CHECK("AreaIncomplete.ExtraColor"), Color_Area_Incomplete_Main, Color_Area_Incomplete_Extra, Color_Main_Default, Color_Area_Incomplete_Extra_Default, CVAR_TRACKER_CHECK("AreaIncomplete.Hide"), "", THEME_COLOR); - CheckTracker::ImGuiDrawTwoColorPickerSection("Area Complete", CVAR_TRACKER_CHECK("AreaComplete.MainColor"), CVAR_TRACKER_CHECK("AreaComplete.ExtraColor"), Color_Area_Complete_Main, Color_Area_Complete_Extra, Color_Main_Default, Color_Area_Complete_Extra_Default, CVAR_TRACKER_CHECK("AreaComplete.Hide"), "", THEME_COLOR); - CheckTracker::ImGuiDrawTwoColorPickerSection("Unchecked", CVAR_TRACKER_CHECK("Unchecked.MainColor"), CVAR_TRACKER_CHECK("Unchecked.ExtraColor"), Color_Unchecked_Main, Color_Unchecked_Extra, Color_Main_Default, Color_Unchecked_Extra_Default, CVAR_TRACKER_CHECK("Unchecked.Hide"), "Checks you have not interacted with at all.", THEME_COLOR); - CheckTracker::ImGuiDrawTwoColorPickerSection("Skipped", CVAR_TRACKER_CHECK("Skipped.MainColor"), CVAR_TRACKER_CHECK("Skipped.ExtraColor"), Color_Skipped_Main, Color_Skipped_Extra, Color_Main_Default, Color_Skipped_Extra_Default, CVAR_TRACKER_CHECK("Skipped.Hide"), "", THEME_COLOR); - CheckTracker::ImGuiDrawTwoColorPickerSection("Seen", CVAR_TRACKER_CHECK("Seen.MainColor"), CVAR_TRACKER_CHECK("Seen.ExtraColor"), Color_Seen_Main, Color_Seen_Extra, Color_Main_Default, Color_Seen_Extra_Default, CVAR_TRACKER_CHECK("Seen.Hide"), "Used for shops. Shows item names for shop slots when walking in, and prices when highlighting them in buy mode.", THEME_COLOR); - CheckTracker::ImGuiDrawTwoColorPickerSection("Scummed", CVAR_TRACKER_CHECK("Scummed.MainColor"), CVAR_TRACKER_CHECK("Scummed.ExtraColor"), Color_Scummed_Main, Color_Scummed_Extra, Color_Main_Default, Color_Scummed_Extra_Default, CVAR_TRACKER_CHECK("Scummed.Hide"), "Checks you collect, but then reload before saving so you no longer have them.", THEME_COLOR); - //CheckTracker::ImGuiDrawTwoColorPickerSection("Hinted (WIP)", CVAR_TRACKER_CHECK("Hinted.MainColor"), CVAR_TRACKER_CHECK("Hinted.ExtraColor"), Color_Hinted_Main, Color_Hinted_Extra, Color_Main_Default, Color_Hinted_Extra_Default, CVAR_TRACKER_CHECK("Hinted.Hide"), "", THEME_COLOR); - CheckTracker::ImGuiDrawTwoColorPickerSection("Collected", CVAR_TRACKER_CHECK("Collected.MainColor"), CVAR_TRACKER_CHECK("Collected.ExtraColor"), Color_Collected_Main, Color_Collected_Extra, Color_Main_Default, Color_Collected_Extra_Default, CVAR_TRACKER_CHECK("Collected.Hide"), "Checks you have collected without saving or reloading yet.", THEME_COLOR); - CheckTracker::ImGuiDrawTwoColorPickerSection("Saved", CVAR_TRACKER_CHECK("Saved.MainColor"), CVAR_TRACKER_CHECK("Saved.ExtraColor"), Color_Saved_Main, Color_Saved_Extra, Color_Main_Default, Color_Saved_Extra_Default, CVAR_TRACKER_CHECK("Saved.Hide"), "Checks that you saved the game while having collected.", THEME_COLOR); + CheckTracker::ImGuiDrawTwoColorPickerSection("Area Incomplete", CVAR_TRACKER_CHECK("AreaIncomplete.MainColor"), + CVAR_TRACKER_CHECK("AreaIncomplete.ExtraColor"), + Color_Area_Incomplete_Main, Color_Area_Incomplete_Extra, + Color_Main_Default, Color_Area_Incomplete_Extra_Default, + CVAR_TRACKER_CHECK("AreaIncomplete.Hide"), "", THEME_COLOR); + CheckTracker::ImGuiDrawTwoColorPickerSection("Area Complete", CVAR_TRACKER_CHECK("AreaComplete.MainColor"), + CVAR_TRACKER_CHECK("AreaComplete.ExtraColor"), + Color_Area_Complete_Main, Color_Area_Complete_Extra, + Color_Main_Default, Color_Area_Complete_Extra_Default, + CVAR_TRACKER_CHECK("AreaComplete.Hide"), "", THEME_COLOR); + CheckTracker::ImGuiDrawTwoColorPickerSection( + "Unchecked", CVAR_TRACKER_CHECK("Unchecked.MainColor"), CVAR_TRACKER_CHECK("Unchecked.ExtraColor"), + Color_Unchecked_Main, Color_Unchecked_Extra, Color_Main_Default, Color_Unchecked_Extra_Default, + CVAR_TRACKER_CHECK("Unchecked.Hide"), "Checks you have not interacted with at all.", THEME_COLOR); + CheckTracker::ImGuiDrawTwoColorPickerSection( + "Skipped", CVAR_TRACKER_CHECK("Skipped.MainColor"), CVAR_TRACKER_CHECK("Skipped.ExtraColor"), + Color_Skipped_Main, Color_Skipped_Extra, Color_Main_Default, Color_Skipped_Extra_Default, + CVAR_TRACKER_CHECK("Skipped.Hide"), "", THEME_COLOR); + CheckTracker::ImGuiDrawTwoColorPickerSection( + "Seen", CVAR_TRACKER_CHECK("Seen.MainColor"), CVAR_TRACKER_CHECK("Seen.ExtraColor"), Color_Seen_Main, + Color_Seen_Extra, Color_Main_Default, Color_Seen_Extra_Default, CVAR_TRACKER_CHECK("Seen.Hide"), + "Used for shops. Shows item names for shop slots when walking in, and prices when highlighting them in buy " + "mode.", + THEME_COLOR); + CheckTracker::ImGuiDrawTwoColorPickerSection( + "Scummed", CVAR_TRACKER_CHECK("Scummed.MainColor"), CVAR_TRACKER_CHECK("Scummed.ExtraColor"), + Color_Scummed_Main, Color_Scummed_Extra, Color_Main_Default, Color_Scummed_Extra_Default, + CVAR_TRACKER_CHECK("Scummed.Hide"), + "Checks you collect, but then reload before saving so you no longer have them.", THEME_COLOR); + // CheckTracker::ImGuiDrawTwoColorPickerSection("Hinted (WIP)", CVAR_TRACKER_CHECK("Hinted.MainColor"), + // CVAR_TRACKER_CHECK("Hinted.ExtraColor"), Color_Hinted_Main, Color_Hinted_Extra, + // Color_Main_Default, Color_Hinted_Extra_Default, CVAR_TRACKER_CHECK("Hinted.Hide"), "", + // THEME_COLOR); + CheckTracker::ImGuiDrawTwoColorPickerSection( + "Collected", CVAR_TRACKER_CHECK("Collected.MainColor"), CVAR_TRACKER_CHECK("Collected.ExtraColor"), + Color_Collected_Main, Color_Collected_Extra, Color_Main_Default, Color_Collected_Extra_Default, + CVAR_TRACKER_CHECK("Collected.Hide"), "Checks you have collected without saving or reloading yet.", + THEME_COLOR); + CheckTracker::ImGuiDrawTwoColorPickerSection( + "Saved", CVAR_TRACKER_CHECK("Saved.MainColor"), CVAR_TRACKER_CHECK("Saved.ExtraColor"), Color_Saved_Main, + Color_Saved_Extra, Color_Main_Default, Color_Saved_Extra_Default, CVAR_TRACKER_CHECK("Saved.Hide"), + "Checks that you saved the game while having collected.", THEME_COLOR); ImGui::PopStyleVar(1); } @@ -2056,9 +2175,7 @@ void CheckTrackerWindow::InitElement() { sectionId = SaveManager::Instance->AddSaveFunction("trackerData", 1, SaveFile, true, SECTION_PARENT_NONE); SaveManager::Instance->AddLoadFunction("trackerData", 1, LoadFile); GameInteractor::Instance->RegisterGameHook(CheckTrackerLoadGame); - GameInteractor::Instance->RegisterGameHook([](uint32_t fileNum) { - Teardown(); - }); + GameInteractor::Instance->RegisterGameHook([](uint32_t fileNum) { Teardown(); }); GameInteractor::Instance->RegisterGameHook(CheckTrackerItemReceive); GameInteractor::Instance->RegisterGameHook(CheckTrackerTransition); GameInteractor::Instance->RegisterGameHook(CheckTrackerShopSlotChange); diff --git a/soh/soh/Enhancements/randomizer/randomizer_check_tracker.h b/soh/soh/Enhancements/randomizer/randomizer_check_tracker.h index 962da88e3..d6fd503b3 100644 --- a/soh/soh/Enhancements/randomizer/randomizer_check_tracker.h +++ b/soh/soh/Enhancements/randomizer/randomizer_check_tracker.h @@ -11,19 +11,19 @@ namespace CheckTracker { class CheckTrackerSettingsWindow : public Ship::GuiWindow { public: using GuiWindow::GuiWindow; - ~CheckTrackerSettingsWindow() {}; + ~CheckTrackerSettingsWindow(){}; protected: - void InitElement() override {}; + void InitElement() override{}; void DrawElement() override; - void UpdateElement() override {}; + void UpdateElement() override{}; }; class CheckTrackerWindow : public Ship::GuiWindow { public: using GuiWindow::GuiWindow; void Draw() override; - ~CheckTrackerWindow() {}; + ~CheckTrackerWindow(){}; protected: void InitElement() override; @@ -31,18 +31,18 @@ class CheckTrackerWindow : public Ship::GuiWindow { void UpdateElement() override; }; -//Converts an index into a Little Endian bitmask, as follows: -//00: 0000000100000000 -//01: 0000001000000000 +// Converts an index into a Little Endian bitmask, as follows: +// 00: 0000000100000000 +// 01: 0000001000000000 //... -//06: 0100000000000000 -//07: 1000000000000000 -//08: 0000000000000001 -//09: 0000000000000010 +// 06: 0100000000000000 +// 07: 1000000000000000 +// 08: 0000000000000001 +// 09: 0000000000000010 //... -//14: 0000000001000000 -//15: 0000000010000000 -//repeat... +// 14: 0000000001000000 +// 15: 0000000010000000 +// repeat... #define INDEX_TO_16BIT_LITTLE_ENDIAN_BITMASK(idx) (0x8000 >> (7 - (idx % 8) + ((idx % 16) / 8) * 8)) void Teardown(); diff --git a/soh/soh/Enhancements/randomizer/randomizer_entrance.c b/soh/soh/Enhancements/randomizer/randomizer_entrance.c index 9d15c7cc1..3c7b433af 100644 --- a/soh/soh/Enhancements/randomizer/randomizer_entrance.c +++ b/soh/soh/Enhancements/randomizer/randomizer_entrance.c @@ -1,7 +1,8 @@ /* * Much of the code here was borrowed from https://github.com/gamestabled/OoT3D_Randomizer/blob/main/code/src/entrance.c - * It's been adapted for SoH to use our gPlayState vs their gGlobalContext with slightly different named properties, and our enums for some scenes/entrances. - * + * It's been adapted for SoH to use our gPlayState vs their gGlobalContext with slightly different named properties, and + * our enums for some scenes/entrances. + * * Unlike 3DS rando, we need to be able to support the user loading up vanilla and rando saves, so the logic around * modifying the entrance table requires that we save the original table and reset whenever loading a vanilla save. * A modified dynamicExitList is manually included since we can't read it from addressing like 3ds rando. @@ -18,8 +19,8 @@ extern PlayState* gPlayState; -//Overwrite the dynamic exit for the OGC Fairy Fountain to be 0x3E8 instead -//of 0x340 (0x340 will stay as the exit for the HC Fairy Fountain -> Castle Grounds) +// Overwrite the dynamic exit for the OGC Fairy Fountain to be 0x3E8 instead +// of 0x340 (0x340 will stay as the exit for the HC Fairy Fountain -> Castle Grounds) s16 dynamicExitList[] = { ENTR_DEATH_MOUNTAIN_TRAIL_GREAT_FAIRY_EXIT, ENTR_DEATH_MOUNTAIN_CRATER_GREAT_FAIRY_EXIT, @@ -45,12 +46,12 @@ s16 dynamicExitList[] = { // Owl Flights : 0x492064 and 0x492080 -static s16 entranceOverrideTable[ENTRANCE_TABLE_SIZE] = {0}; +static s16 entranceOverrideTable[ENTRANCE_TABLE_SIZE] = { 0 }; // Boss scenes (normalize boss scene range to 0 on lookup) mapped to save/death warp entrance -static s16 bossSceneSaveDeathWarps[SHUFFLEABLE_BOSS_COUNT] = {0}; -static ActorEntry modifiedLinkActorEntry = {0}; +static s16 bossSceneSaveDeathWarps[SHUFFLEABLE_BOSS_COUNT] = { 0 }; +static ActorEntry modifiedLinkActorEntry = { 0 }; -EntranceInfo originalEntranceTable[ENTRANCE_TABLE_SIZE] = {0}; +EntranceInfo originalEntranceTable[ENTRANCE_TABLE_SIZE] = { 0 }; typedef struct { s16 entryway; @@ -88,16 +89,16 @@ u8 Entrance_EntranceIsNull(EntranceOverride* entranceOverride) { } static void Entrance_SeparateOGCFairyFountainExit(void) { - //Overwrite unused entrance 0x03E8 (ENTR_POTION_SHOP_KAKARIKO_1) with values from 0x0340 (ENTR_CASTLE_GROUNDS_GREAT_FAIRY_EXIT) to use it as the - //exit from OGC Great Fairy Fountain -> Castle Grounds + // Overwrite unused entrance 0x03E8 (ENTR_POTION_SHOP_KAKARIKO_1) with values from 0x0340 + // (ENTR_CASTLE_GROUNDS_GREAT_FAIRY_EXIT) to use it as the exit from OGC Great Fairy Fountain -> Castle Grounds for (size_t i = 0; i < 4; ++i) { gEntranceTable[ENTR_POTION_SHOP_KAKARIKO_1 + i] = gEntranceTable[ENTR_CASTLE_GROUNDS_GREAT_FAIRY_EXIT + i]; } } static void Entrance_SeparateAdultSpawnAndPrelude() { - // Overwrite unused entrance 0x0282 (ENTR_HYRULE_FIELD_10) with values from 0x05F4 (ENTR_TEMPLE_OF_TIME_WARP_PAD) to use it as the - // Adult Spawn index and separate it from Prelude of Light + // Overwrite unused entrance 0x0282 (ENTR_HYRULE_FIELD_10) with values from 0x05F4 (ENTR_TEMPLE_OF_TIME_WARP_PAD) to + // use it as the Adult Spawn index and separate it from Prelude of Light for (size_t i = 0; i < 4; ++i) { gEntranceTable[ENTR_HYRULE_FIELD_10 + i] = gEntranceTable[ENTR_TEMPLE_OF_TIME_WARP_PAD + i]; } @@ -108,10 +109,12 @@ static void Entrance_ReplaceChildTempleWarps() { if (Randomizer_GetSettingValue(RSK_SHUFFLE_DUNGEON_ENTRANCES) != RO_DUNGEON_ENTRANCE_SHUFFLE_OFF || Randomizer_GetSettingValue(RSK_SHUFFLE_BOSS_ENTRANCES) != RO_BOSS_ROOM_ENTRANCE_SHUFFLE_OFF) { // Forest Temple - gEntranceTable[ENTR_SACRED_FOREST_MEADOW_FOREST_TEMPLE_BLUE_WARP] = gEntranceTable[ENTR_SACRED_FOREST_MEADOW_WARP_PAD]; + gEntranceTable[ENTR_SACRED_FOREST_MEADOW_FOREST_TEMPLE_BLUE_WARP] = + gEntranceTable[ENTR_SACRED_FOREST_MEADOW_WARP_PAD]; gEntranceTable[ENTR_SACRED_FOREST_MEADOW_3_1] = gEntranceTable[ENTR_SACRED_FOREST_MEADOW_2_1]; // Fire Temple - gEntranceTable[ENTR_DEATH_MOUNTAIN_CRATER_FIRE_TEMPLE_BLUE_WARP] = gEntranceTable[ENTR_DEATH_MOUNTAIN_CRATER_WARP_PAD]; + gEntranceTable[ENTR_DEATH_MOUNTAIN_CRATER_FIRE_TEMPLE_BLUE_WARP] = + gEntranceTable[ENTR_DEATH_MOUNTAIN_CRATER_WARP_PAD]; gEntranceTable[ENTR_DEATH_MOUNTAIN_CRATER_5_1] = gEntranceTable[ENTR_DEATH_MOUNTAIN_CRATER_4_1]; // Water Temple gEntranceTable[ENTR_LAKE_HYLIA_WATER_TEMPLE_BLUE_WARP] = gEntranceTable[ENTR_LAKE_HYLIA_WARP_PAD]; @@ -149,7 +152,8 @@ void Entrance_Init(void) { if (Randomizer_GetSettingValue(RSK_SKIP_CHILD_STEALTH)) { gEntranceTable[ENTR_CASTLE_COURTYARD_GUARDS_DAY_0].scene = SCENE_CASTLE_COURTYARD_ZELDA; gEntranceTable[ENTR_CASTLE_COURTYARD_GUARDS_DAY_0].spawn = 0; - gEntranceTable[ENTR_CASTLE_COURTYARD_GUARDS_DAY_0].field = ENTRANCE_INFO_FIELD(false, false, TRANS_TYPE_FADE_WHITE, TRANS_TYPE_FADE_WHITE); + gEntranceTable[ENTR_CASTLE_COURTYARD_GUARDS_DAY_0].field = + ENTRANCE_INFO_FIELD(false, false, TRANS_TYPE_FADE_WHITE, TRANS_TYPE_FADE_WHITE); } // Delete the title card and add a fade in for Hyrule Field from Ocarina of Time cutscene @@ -221,10 +225,10 @@ void Entrance_Init(void) { // Overwrite the indices which we want to shuffle, leaving the rest as they are entranceOverrideTable[originalIndex] = overrideIndex; - //Override both land and water entrances for Hyrule Field -> ZR Front and vice versa - if (originalIndex == ENTR_ZORAS_RIVER_WEST_EXIT) { //Hyrule Field -> ZR Front land entrance + // Override both land and water entrances for Hyrule Field -> ZR Front and vice versa + if (originalIndex == ENTR_ZORAS_RIVER_WEST_EXIT) { // Hyrule Field -> ZR Front land entrance entranceOverrideTable[ENTR_ZORAS_RIVER_3] = overrideIndex; - } else if (originalIndex == ENTR_HYRULE_FIELD_RIVER_EXIT) { //ZR Front -> Hyrule Field land entrance + } else if (originalIndex == ENTR_HYRULE_FIELD_RIVER_EXIT) { // ZR Front -> Hyrule Field land entrance entranceOverrideTable[ENTR_HYRULE_FIELD_14] = overrideIndex; } } @@ -276,7 +280,9 @@ s16 Entrance_PeekNextIndexOverride(int16_t nextEntranceIndex) { s16 Entrance_OverrideNextIndex(s16 nextEntranceIndex) { // Exiting through the crawl space from Hyrule Castle courtyard is the same exit as leaving Ganon's castle // Don't override the entrance if we came from the Castle courtyard (day and night scenes) - if (gPlayState != NULL && (gPlayState->sceneNum == SCENE_CASTLE_COURTYARD_GUARDS_DAY || gPlayState->sceneNum == SCENE_CASTLE_COURTYARD_GUARDS_NIGHT) && + if (gPlayState != NULL && + (gPlayState->sceneNum == SCENE_CASTLE_COURTYARD_GUARDS_DAY || + gPlayState->sceneNum == SCENE_CASTLE_COURTYARD_GUARDS_NIGHT) && nextEntranceIndex == ENTR_CASTLE_GROUNDS_RAINBOW_BRIDGE_EXIT) { return nextEntranceIndex; } @@ -323,37 +329,38 @@ void Entrance_SetGameOverEntrance(void) { if (Randomizer_GetSettingValue(RSK_SHUFFLE_BOSS_ENTRANCES) != RO_BOSS_ROOM_ENTRANCE_SHUFFLE_OFF && scene >= SCENE_DEKU_TREE_BOSS && scene <= SCENE_SHADOW_TEMPLE_BOSS) { // Normalize boss scene range to 0 on lookup and handle for grotto entrances - gSaveContext.entranceIndex = Grotto_OverrideSpecialEntrance(bossSceneSaveDeathWarps[scene - SCENE_DEKU_TREE_BOSS]); + gSaveContext.entranceIndex = + Grotto_OverrideSpecialEntrance(bossSceneSaveDeathWarps[scene - SCENE_DEKU_TREE_BOSS]); return; } - //Set the current entrance depending on which entrance the player last came through + // Set the current entrance depending on which entrance the player last came through switch (gSaveContext.entranceIndex) { - case ENTR_DEKU_TREE_BOSS_ENTRANCE : //Deku Tree Boss Room + case ENTR_DEKU_TREE_BOSS_ENTRANCE: // Deku Tree Boss Room gSaveContext.entranceIndex = ENTR_DEKU_TREE_ENTRANCE; return; - case ENTR_DODONGOS_CAVERN_BOSS_ENTRANCE : //Dodongos Cavern Boss Room + case ENTR_DODONGOS_CAVERN_BOSS_ENTRANCE: // Dodongos Cavern Boss Room gSaveContext.entranceIndex = ENTR_DODONGOS_CAVERN_ENTRANCE; return; - case ENTR_JABU_JABU_BOSS_ENTRANCE : //Jabu Jabus Belly Boss Room + case ENTR_JABU_JABU_BOSS_ENTRANCE: // Jabu Jabus Belly Boss Room gSaveContext.entranceIndex = ENTR_JABU_JABU_ENTRANCE; return; - case ENTR_FOREST_TEMPLE_BOSS_ENTRANCE : //Forest Temple Boss Room + case ENTR_FOREST_TEMPLE_BOSS_ENTRANCE: // Forest Temple Boss Room gSaveContext.entranceIndex = ENTR_FOREST_TEMPLE_ENTRANCE; return; - case ENTR_FIRE_TEMPLE_BOSS_ENTRANCE : //Fire Temple Boss Room + case ENTR_FIRE_TEMPLE_BOSS_ENTRANCE: // Fire Temple Boss Room gSaveContext.entranceIndex = ENTR_FIRE_TEMPLE_ENTRANCE; return; - case ENTR_WATER_TEMPLE_BOSS_ENTRANCE : //Water Temple Boss Room + case ENTR_WATER_TEMPLE_BOSS_ENTRANCE: // Water Temple Boss Room gSaveContext.entranceIndex = ENTR_WATER_TEMPLE_ENTRANCE; return; - case ENTR_SPIRIT_TEMPLE_BOSS_ENTRANCE : //Spirit Temple Boss Room + case ENTR_SPIRIT_TEMPLE_BOSS_ENTRANCE: // Spirit Temple Boss Room gSaveContext.entranceIndex = ENTR_SPIRIT_TEMPLE_ENTRANCE; return; - case ENTR_SHADOW_TEMPLE_BOSS_ENTRANCE : //Shadow Temple Boss Room + case ENTR_SHADOW_TEMPLE_BOSS_ENTRANCE: // Shadow Temple Boss Room gSaveContext.entranceIndex = ENTR_SHADOW_TEMPLE_ENTRANCE; return; - case ENTR_GANONDORF_BOSS_0 : //Ganondorf Boss Room + case ENTR_GANONDORF_BOSS_0: // Ganondorf Boss Room gSaveContext.entranceIndex = ENTR_GANONS_TOWER_0; // Inside Ganon's Castle -> Ganon's Tower Climb return; } @@ -368,7 +375,8 @@ void Entrance_SetSavewarpEntrance(void) { if (Randomizer_GetSettingValue(RSK_SHUFFLE_BOSS_ENTRANCES) != RO_BOSS_ROOM_ENTRANCE_SHUFFLE_OFF && scene >= SCENE_DEKU_TREE_BOSS && scene <= SCENE_SHADOW_TEMPLE_BOSS) { // Normalize boss scene range to 0 on lookup and handle for grotto entrances - gSaveContext.entranceIndex = Grotto_OverrideSpecialEntrance(bossSceneSaveDeathWarps[scene - SCENE_DEKU_TREE_BOSS]); + gSaveContext.entranceIndex = + Grotto_OverrideSpecialEntrance(bossSceneSaveDeathWarps[scene - SCENE_DEKU_TREE_BOSS]); return; } @@ -378,15 +386,15 @@ void Entrance_SetSavewarpEntrance(void) { gSaveContext.entranceIndex = ENTR_DODONGOS_CAVERN_ENTRANCE; } else if (scene == SCENE_JABU_JABU || scene == SCENE_JABU_JABU_BOSS) { gSaveContext.entranceIndex = ENTR_JABU_JABU_ENTRANCE; - } else if (scene == SCENE_FOREST_TEMPLE || scene == SCENE_FOREST_TEMPLE_BOSS) { //Forest Temple Boss Room + } else if (scene == SCENE_FOREST_TEMPLE || scene == SCENE_FOREST_TEMPLE_BOSS) { // Forest Temple Boss Room gSaveContext.entranceIndex = ENTR_FOREST_TEMPLE_ENTRANCE; - } else if (scene == SCENE_FIRE_TEMPLE || scene == SCENE_FIRE_TEMPLE_BOSS) { //Fire Temple Boss Room + } else if (scene == SCENE_FIRE_TEMPLE || scene == SCENE_FIRE_TEMPLE_BOSS) { // Fire Temple Boss Room gSaveContext.entranceIndex = ENTR_FIRE_TEMPLE_ENTRANCE; - } else if (scene == SCENE_WATER_TEMPLE || scene == SCENE_WATER_TEMPLE_BOSS) { //Water Temple Boss Room + } else if (scene == SCENE_WATER_TEMPLE || scene == SCENE_WATER_TEMPLE_BOSS) { // Water Temple Boss Room gSaveContext.entranceIndex = ENTR_WATER_TEMPLE_ENTRANCE; - } else if (scene == SCENE_SPIRIT_TEMPLE || scene == SCENE_SPIRIT_TEMPLE_BOSS) { //Spirit Temple Boss Room + } else if (scene == SCENE_SPIRIT_TEMPLE || scene == SCENE_SPIRIT_TEMPLE_BOSS) { // Spirit Temple Boss Room gSaveContext.entranceIndex = ENTR_SPIRIT_TEMPLE_ENTRANCE; - } else if (scene == SCENE_SHADOW_TEMPLE || scene == SCENE_SHADOW_TEMPLE_BOSS) { //Shadow Temple Boss Room + } else if (scene == SCENE_SHADOW_TEMPLE || scene == SCENE_SHADOW_TEMPLE_BOSS) { // Shadow Temple Boss Room gSaveContext.entranceIndex = ENTR_SHADOW_TEMPLE_ENTRANCE; } else if (scene == SCENE_BOTTOM_OF_THE_WELL) { // BOTW gSaveContext.entranceIndex = ENTR_BOTTOM_OF_THE_WELL_ENTRANCE; @@ -396,24 +404,29 @@ void Entrance_SetSavewarpEntrance(void) { gSaveContext.entranceIndex = ENTR_ICE_CAVERN_ENTRANCE; } else if (scene == SCENE_INSIDE_GANONS_CASTLE) { gSaveContext.entranceIndex = ENTR_INSIDE_GANONS_CASTLE_ENTRANCE; - } else if (scene == SCENE_GANONS_TOWER || scene == SCENE_INSIDE_GANONS_CASTLE_COLLAPSE || scene == SCENE_GANONS_TOWER_COLLAPSE_INTERIOR || scene == SCENE_GANON_BOSS || scene == SCENE_GANONS_TOWER_COLLAPSE_EXTERIOR) { - gSaveContext.entranceIndex = ENTR_GANONS_TOWER_0; // Inside Ganon's Castle -> Ganon's Tower Climb - } else if (scene == SCENE_THIEVES_HIDEOUT) { // Theives hideout + } else if (scene == SCENE_GANONS_TOWER || scene == SCENE_INSIDE_GANONS_CASTLE_COLLAPSE || + scene == SCENE_GANONS_TOWER_COLLAPSE_INTERIOR || scene == SCENE_GANON_BOSS || + scene == SCENE_GANONS_TOWER_COLLAPSE_EXTERIOR) { + gSaveContext.entranceIndex = ENTR_GANONS_TOWER_0; // Inside Ganon's Castle -> Ganon's Tower Climb + } else if (scene == SCENE_THIEVES_HIDEOUT) { // Theives hideout gSaveContext.entranceIndex = ENTR_THIEVES_HIDEOUT_0; // Gerudo Fortress -> Thieve's Hideout spawn 0 } else if (scene == SCENE_LINKS_HOUSE && Randomizer_GetSettingValue(RSK_SHUFFLE_INTERIOR_ENTRANCES) != RO_INTERIOR_ENTRANCE_SHUFFLE_ALL) { // Save warping in Link's house keeps the player there if Link's house not shuffled, // otherwise fallback to regular spawns gSaveContext.entranceIndex = ENTR_LINKS_HOUSE_CHILD_SPAWN; - } else if (CVarGetInteger(CVAR_ENHANCEMENT("RememberSaveLocation"), 0) && scene != SCENE_FAIRYS_FOUNTAIN && scene != SCENE_GROTTOS && - gSaveContext.entranceIndex != ENTR_LOAD_OPENING) { + } else if (CVarGetInteger(CVAR_ENHANCEMENT("RememberSaveLocation"), 0) && scene != SCENE_FAIRYS_FOUNTAIN && + scene != SCENE_GROTTOS && gSaveContext.entranceIndex != ENTR_LOAD_OPENING) { // Use the saved entrance value with remember save location, except when in grottos/fairy fountains or if // the entrance index is -1 (new save) return; } else if (LINK_IS_CHILD) { gSaveContext.entranceIndex = Entrance_OverrideNextIndex(ENTR_LINKS_HOUSE_CHILD_SPAWN); // Child Overworld Spawn } else { - gSaveContext.entranceIndex = Entrance_OverrideNextIndex(ENTR_HYRULE_FIELD_10); // Adult Overworld Spawn (Normally 0x5F4 (ENTR_TEMPLE_OF_TIME_WARP_PAD), but 0x282 (ENTR_HYRULE_FIELD_10) has been repurposed to differentiate from Prelude which also uses 0x5F4) + gSaveContext.entranceIndex = Entrance_OverrideNextIndex( + ENTR_HYRULE_FIELD_10); // Adult Overworld Spawn (Normally 0x5F4 (ENTR_TEMPLE_OF_TIME_WARP_PAD), but 0x282 + // (ENTR_HYRULE_FIELD_10) has been repurposed to differentiate from Prelude which + // also uses 0x5F4) } } @@ -471,14 +484,14 @@ void Entrance_OverrideBlueWarp(void) { } switch (gSaveContext.entranceIndex) { - case ENTR_KOKIRI_FOREST_DEKU_TREE_BLUE_WARP: // Gohma blue warp - case ENTR_DEATH_MOUNTAIN_TRAIL_DODONGO_BLUE_WARP: // KD blue warp - case ENTR_ZORAS_FOUNTAIN_JABU_JABU_BLUE_WARP: // Barinade blue warp + case ENTR_KOKIRI_FOREST_DEKU_TREE_BLUE_WARP: // Gohma blue warp + case ENTR_DEATH_MOUNTAIN_TRAIL_DODONGO_BLUE_WARP: // KD blue warp + case ENTR_ZORAS_FOUNTAIN_JABU_JABU_BLUE_WARP: // Barinade blue warp case ENTR_SACRED_FOREST_MEADOW_FOREST_TEMPLE_BLUE_WARP: // Phantom Ganon blue warp - case ENTR_DEATH_MOUNTAIN_CRATER_FIRE_TEMPLE_BLUE_WARP: // Volvagia blue warp - case ENTR_LAKE_HYLIA_WATER_TEMPLE_BLUE_WARP: // Morpha blue warp - case ENTR_DESERT_COLOSSUS_SPIRIT_TEMPLE_BLUE_WARP: // Bongo-Bongo blue warp - case ENTR_GRAVEYARD_SHADOW_TEMPLE_BLUE_WARP: // Twinrova blue warp + case ENTR_DEATH_MOUNTAIN_CRATER_FIRE_TEMPLE_BLUE_WARP: // Volvagia blue warp + case ENTR_LAKE_HYLIA_WATER_TEMPLE_BLUE_WARP: // Morpha blue warp + case ENTR_DESERT_COLOSSUS_SPIRIT_TEMPLE_BLUE_WARP: // Bongo-Bongo blue warp + case ENTR_GRAVEYARD_SHADOW_TEMPLE_BLUE_WARP: // Twinrova blue warp gSaveContext.entranceIndex = Entrance_OverrideNextIndex(gSaveContext.entranceIndex); return; } @@ -488,16 +501,18 @@ void Entrance_EnableFW(void) { Player* player = GET_PLAYER(gPlayState); // Leave restriction in Tower Collapse Interior, Castle Collapse, Treasure Box Shop, Tower Collapse Exterior, // Grottos area, Fishing Pond, Ganon Battle and for states that disable buttons. - if (!false /* farores wind anywhere */ || - gPlayState->sceneNum == SCENE_GANONS_TOWER_COLLAPSE_INTERIOR || gPlayState->sceneNum == SCENE_INSIDE_GANONS_CASTLE_COLLAPSE || + if (!false /* farores wind anywhere */ || gPlayState->sceneNum == SCENE_GANONS_TOWER_COLLAPSE_INTERIOR || + gPlayState->sceneNum == SCENE_INSIDE_GANONS_CASTLE_COLLAPSE || (gPlayState->sceneNum == SCENE_TREASURE_BOX_SHOP && !false /* shuffled chest mini game */) || gPlayState->sceneNum == SCENE_GANONS_TOWER_COLLAPSE_EXTERIOR || gPlayState->sceneNum == SCENE_GROTTOS || gPlayState->sceneNum == SCENE_FISHING_POND || gPlayState->sceneNum == SCENE_GANON_BOSS || - gSaveContext.eventInf[0] & 0x1 || // Ingo's Minigame state - player->stateFlags1 & (PLAYER_STATE1_HANGING_OFF_LEDGE | PLAYER_STATE1_CLIMBING_LADDER | PLAYER_STATE1_ON_HORSE | PLAYER_STATE1_IN_WATER) || // Swimming, riding horse, Down A, hanging from a ledge - player->stateFlags2 & PLAYER_STATE2_CRAWLING // Blank A + gSaveContext.eventInf[0] & 0x1 || // Ingo's Minigame state + player->stateFlags1 & + (PLAYER_STATE1_HANGING_OFF_LEDGE | PLAYER_STATE1_CLIMBING_LADDER | PLAYER_STATE1_ON_HORSE | + PLAYER_STATE1_IN_WATER) || // Swimming, riding horse, Down A, hanging from a ledge + player->stateFlags2 & PLAYER_STATE2_CRAWLING // Blank A // Shielding, spinning and getting skull tokens still disable buttons automatically - ) { + ) { return; } @@ -512,8 +527,8 @@ void Entrance_EnableFW(void) { void Entrance_HandleEponaState(void) { s32 entrance = gPlayState->nextEntranceIndex; Player* player = GET_PLAYER(gPlayState); - //If Link is riding Epona but he's about to go through an entrance where she can't spawn, - //unset the Epona flag to avoid Master glitch, and restore temp B. + // If Link is riding Epona but he's about to go through an entrance where she can't spawn, + // unset the Epona flag to avoid Master glitch, and restore temp B. if (Randomizer_GetSettingValue(RSK_SHUFFLE_OVERWORLD_ENTRANCES) && (player->stateFlags1 & PLAYER_STATE1_ON_HORSE)) { // Allow Master glitch to be performed on the Thieves Hideout entrance if (entrance == Entrance_GetOverride(ENTR_THIEVES_HIDEOUT_4)) { // Gerudo Fortress -> Theives Hideout @@ -521,27 +536,27 @@ void Entrance_HandleEponaState(void) { } static const s16 validEponaEntrances[] = { - ENTR_LAKE_HYLIA_NORTH_EXIT, // Hyrule Field -> Lake Hylia - ENTR_HYRULE_FIELD_FENCE_EXIT, // Lake Hylia -> Hyrule Field - ENTR_LAKE_HYLIA_OUTSIDE_FISHING_POND, // LH Fishing Hole -> LH Fishing Island - ENTR_LAKE_HYLIA_OUTSIDE_LAB, // LH Lab -> Lake Hylia - ENTR_GERUDO_VALLEY_EAST_EXIT, // Hyrule Field -> Gerudo Valley - ENTR_HYRULE_FIELD_ROCKY_PATH, // Gerudo Valley -> Hyrule Field - ENTR_LON_LON_RANCH_ENTRANCE, // Hyrule Field -> Lon Lon Ranch - ENTR_HYRULE_FIELD_CENTER_EXIT, // Lon Lon Ranch -> Hyrule Field - ENTR_HYRULE_FIELD_ON_BRIDGE_SPAWN, // Market Entrance -> Hyrule Field - ENTR_HYRULE_FIELD_RIVER_EXIT, // ZR Front -> Hyrule Field - ENTR_HYRULE_FIELD_WOODED_EXIT, // LW Bridge -> Hyrule Field - ENTR_GERUDOS_FORTRESS_EAST_EXIT, // GV Fortress Side -> Gerudo Fortress - ENTR_GERUDO_VALLEY_WEST_EXIT, // Gerudo Fortress -> GV Fortress Side - ENTR_GERUDO_VALLEY_OUTSIDE_TENT, // GV Carpenter Tent -> GV Fortress Side - ENTR_LON_LON_RANCH_OUTSIDE_STABLES, // LLR Stables -> Lon Lon Ranch - ENTR_LON_LON_RANCH_OUTSIDE_TOWER, // LLR Tower -> Lon Lon Ranch - ENTR_LON_LON_RANCH_OUTSIDE_TALONS_HOUSE, // LLR Talons House -> Lon Lon Ranch - ENTR_HYRULE_FIELD_11, // LLR Southern Fence Jump - ENTR_HYRULE_FIELD_12, // LLR Western Fence Jump - ENTR_HYRULE_FIELD_13, // LLR Eastern Fence Jump - ENTR_HYRULE_FIELD_15, // LLR Front Gate Jump + ENTR_LAKE_HYLIA_NORTH_EXIT, // Hyrule Field -> Lake Hylia + ENTR_HYRULE_FIELD_FENCE_EXIT, // Lake Hylia -> Hyrule Field + ENTR_LAKE_HYLIA_OUTSIDE_FISHING_POND, // LH Fishing Hole -> LH Fishing Island + ENTR_LAKE_HYLIA_OUTSIDE_LAB, // LH Lab -> Lake Hylia + ENTR_GERUDO_VALLEY_EAST_EXIT, // Hyrule Field -> Gerudo Valley + ENTR_HYRULE_FIELD_ROCKY_PATH, // Gerudo Valley -> Hyrule Field + ENTR_LON_LON_RANCH_ENTRANCE, // Hyrule Field -> Lon Lon Ranch + ENTR_HYRULE_FIELD_CENTER_EXIT, // Lon Lon Ranch -> Hyrule Field + ENTR_HYRULE_FIELD_ON_BRIDGE_SPAWN, // Market Entrance -> Hyrule Field + ENTR_HYRULE_FIELD_RIVER_EXIT, // ZR Front -> Hyrule Field + ENTR_HYRULE_FIELD_WOODED_EXIT, // LW Bridge -> Hyrule Field + ENTR_GERUDOS_FORTRESS_EAST_EXIT, // GV Fortress Side -> Gerudo Fortress + ENTR_GERUDO_VALLEY_WEST_EXIT, // Gerudo Fortress -> GV Fortress Side + ENTR_GERUDO_VALLEY_OUTSIDE_TENT, // GV Carpenter Tent -> GV Fortress Side + ENTR_LON_LON_RANCH_OUTSIDE_STABLES, // LLR Stables -> Lon Lon Ranch + ENTR_LON_LON_RANCH_OUTSIDE_TOWER, // LLR Tower -> Lon Lon Ranch + ENTR_LON_LON_RANCH_OUTSIDE_TALONS_HOUSE, // LLR Talons House -> Lon Lon Ranch + ENTR_HYRULE_FIELD_11, // LLR Southern Fence Jump + ENTR_HYRULE_FIELD_12, // LLR Western Fence Jump + ENTR_HYRULE_FIELD_13, // LLR Eastern Fence Jump + ENTR_HYRULE_FIELD_15, // LLR Front Gate Jump // The following indices currently aren't randomized, but we'll list // them in case they ever are. They're all Theives Hideout -> Gerudo Fortress ENTR_GERUDOS_FORTRESS_1, @@ -584,9 +599,9 @@ void Entrance_OverrideWeatherState() { return; } // Lon Lon Ranch (No Epona) - if (!Flags_GetEventChkInf(EVENTCHKINF_EPONA_OBTAINED)){ // if you don't have Epona + if (!Flags_GetEventChkInf(EVENTCHKINF_EPONA_OBTAINED)) { // if you don't have Epona switch (gSaveContext.entranceIndex) { - case ENTR_LON_LON_RANCH_ENTRANCE: // Lon Lon Ranch from HF + case ENTR_LON_LON_RANCH_ENTRANCE: // Lon Lon Ranch from HF case ENTR_HYRULE_FIELD_CENTER_EXIT: // Hyrule Field from LLR gWeatherMode = 2; return; @@ -595,14 +610,14 @@ void Entrance_OverrideWeatherState() { // Water Temple if (!Flags_GetEventChkInf(EVENTCHKINF_USED_WATER_TEMPLE_BLUE_WARP)) { // have not beaten Water Temple switch (gSaveContext.entranceIndex) { - case ENTR_ZORAS_RIVER_WATERFALL_EXIT: // Zora River from behind waterfall + case ENTR_ZORAS_RIVER_WATERFALL_EXIT: // Zora River from behind waterfall case ENTR_ZORAS_RIVER_UNDERWATER_SHORTCUT: // Zora River from LW water shortcut - case ENTR_LOST_WOODS_UNDERWATER_SHORTCUT: // Lost Woods water shortcut from ZR + case ENTR_LOST_WOODS_UNDERWATER_SHORTCUT: // Lost Woods water shortcut from ZR gWeatherMode = 3; return; } switch (gPlayState->sceneNum) { - case SCENE_ZORAS_DOMAIN: // Zora's Domain + case SCENE_ZORAS_DOMAIN: // Zora's Domain case SCENE_ZORAS_FOUNTAIN: // Zora's Fountain gWeatherMode = 3; return; @@ -610,15 +625,15 @@ void Entrance_OverrideWeatherState() { } // Kakariko Thunderstorm if (((gSaveContext.inventory.questItems & 0x7) == 0x7) && // Have forest, fire, and water medallion - !(gSaveContext.sceneFlags[24].clear & 0x02)) { // have not beaten Bongo Bongo + !(gSaveContext.sceneFlags[24].clear & 0x02)) { // have not beaten Bongo Bongo switch (gPlayState->sceneNum) { case SCENE_KAKARIKO_VILLAGE: // Kakariko - case SCENE_GRAVEYARD: // Graveyard + case SCENE_GRAVEYARD: // Graveyard gPlayState->envCtx.gloomySkyMode = 2; switch (gSaveContext.entranceIndex) { case ENTR_KAKARIKO_VILLAGE_FRONT_GATE: // Kakariko from HF case ENTR_KAKARIKO_VILLAGE_GUARD_GATE: // Kakariko from Death Mountain Trail - case ENTR_GRAVEYARD_OUTSIDE_TEMPLE: // Graveyard from Shadow Temple + case ENTR_GRAVEYARD_OUTSIDE_TEMPLE: // Graveyard from Shadow Temple break; default: gWeatherMode = 5; @@ -627,21 +642,21 @@ void Entrance_OverrideWeatherState() { } } // Death Mountain Cloudy - if (!Flags_GetEventChkInf(EVENTCHKINF_USED_FIRE_TEMPLE_BLUE_WARP)) { // have not beaten Fire Temple + if (!Flags_GetEventChkInf(EVENTCHKINF_USED_FIRE_TEMPLE_BLUE_WARP)) { // have not beaten Fire Temple if (gPlayState->nextEntranceIndex == ENTR_LOST_WOODS_TUNNEL_SHORTCUT) { // Lost Woods Goron City Shortcut gWeatherMode = 2; return; } switch (gPlayState->sceneNum) { - case SCENE_KAKARIKO_VILLAGE: // Kakariko - case SCENE_GRAVEYARD: // Graveyard - case SCENE_DEATH_MOUNTAIN_TRAIL: // Death Mountain Trail + case SCENE_KAKARIKO_VILLAGE: // Kakariko + case SCENE_GRAVEYARD: // Graveyard + case SCENE_DEATH_MOUNTAIN_TRAIL: // Death Mountain Trail case SCENE_DEATH_MOUNTAIN_CRATER: // Death Mountain Crater if (!gPlayState->envCtx.gloomySkyMode) { gPlayState->envCtx.gloomySkyMode = 1; } switch (gSaveContext.entranceIndex) { - case ENTR_KAKARIKO_VILLAGE_FRONT_GATE: // Kakariko from HF + case ENTR_KAKARIKO_VILLAGE_FRONT_GATE: // Kakariko from HF case ENTR_KAKARIKO_VILLAGE_SOUTHEAST_EXIT: // Kakariko from Graveyard break; default: @@ -653,16 +668,17 @@ void Entrance_OverrideWeatherState() { } // Rectify the "Getting Caught By Gerudo" entrance index if necessary, based on the age and current scene -// In ER, Adult should be placed at the fortress entrance when getting caught in the fortress without a hookshot, instead of being thrown in the valley -// Child should always be thrown in the stream when caught in the valley, and placed at the fortress entrance from valley when caught in the fortress +// In ER, Adult should be placed at the fortress entrance when getting caught in the fortress without a hookshot, +// instead of being thrown in the valley Child should always be thrown in the stream when caught in the valley, and +// placed at the fortress entrance from valley when caught in the fortress void Entrance_OverrideGeurdoGuardCapture(void) { if (LINK_IS_CHILD) { gPlayState->nextEntranceIndex = ENTR_GERUDO_VALLEY_1; // Geurdo Valley thrown out } if ((LINK_IS_CHILD || Randomizer_GetSettingValue(RSK_SHUFFLE_OVERWORLD_ENTRANCES)) && - gPlayState->nextEntranceIndex == ENTR_GERUDO_VALLEY_1) { // Geurdo Valley thrown out - if (gPlayState->sceneNum != SCENE_GERUDO_VALLEY) { // Geurdo Valley + gPlayState->nextEntranceIndex == ENTR_GERUDO_VALLEY_1) { // Geurdo Valley thrown out + if (gPlayState->sceneNum != SCENE_GERUDO_VALLEY) { // Geurdo Valley gPlayState->nextEntranceIndex = ENTR_GERUDOS_FORTRESS_EAST_EXIT; // Gerudo Fortress } } diff --git a/soh/soh/Enhancements/randomizer/randomizer_entrance.h b/soh/soh/Enhancements/randomizer/randomizer_entrance.h index d2c8c79cb..ca840f396 100644 --- a/soh/soh/Enhancements/randomizer/randomizer_entrance.h +++ b/soh/soh/Enhancements/randomizer/randomizer_entrance.h @@ -3,8 +3,8 @@ #include -//Entrance Table Data: https://wiki.cloudmodding.com/oot/Entrance_Table_(Data) -//Accessed June 2021, published content date at the time was 14 March 2020, at 21:47 +// Entrance Table Data: https://wiki.cloudmodding.com/oot/Entrance_Table_(Data) +// Accessed June 2021, published content date at the time was 14 March 2020, at 21:47 #define ENTRANCE_TABLE_SIZE ENTR_MAX @@ -13,12 +13,12 @@ #define SHUFFLEABLE_BOSS_COUNT 8 #define SAVEFILE_ENTRANCES_DISCOVERED_IDX_COUNT 66 // Max entrance rando index is 0x0820, (2080 / 32 == 65) + 1 -#define SAVEFILE_SCENES_DISCOVERED_IDX_COUNT 4 // Max scene ID is 0x6E, (110 / 32 == 3) + 1 +#define SAVEFILE_SCENES_DISCOVERED_IDX_COUNT 4 // Max scene ID is 0x6E, (110 / 32 == 3) + 1 -#define ENTRANCE_INFO_FIELD(continueBgm, displayTitleCard, endTransType, startTransType) \ - (((continueBgm) ? ENTRANCE_INFO_CONTINUE_BGM_FLAG : 0) | \ - ((displayTitleCard) ? ENTRANCE_INFO_DISPLAY_TITLE_CARD_FLAG : 0) | \ - (((endTransType) << ENTRANCE_INFO_END_TRANS_TYPE_SHIFT) & ENTRANCE_INFO_END_TRANS_TYPE_MASK) | \ +#define ENTRANCE_INFO_FIELD(continueBgm, displayTitleCard, endTransType, startTransType) \ + (((continueBgm) ? ENTRANCE_INFO_CONTINUE_BGM_FLAG : 0) | \ + ((displayTitleCard) ? ENTRANCE_INFO_DISPLAY_TITLE_CARD_FLAG : 0) | \ + (((endTransType) << ENTRANCE_INFO_END_TRANS_TYPE_SHIFT) & ENTRANCE_INFO_END_TRANS_TYPE_MASK) | \ (((startTransType) << ENTRANCE_INFO_START_TRANS_TYPE_SHIFT) & ENTRANCE_INFO_START_TRANS_TYPE_MASK)) typedef struct { diff --git a/soh/soh/Enhancements/randomizer/randomizer_entrance_tracker.cpp b/soh/soh/Enhancements/randomizer/randomizer_entrance_tracker.cpp index 0876f48ff..9170e8c67 100644 --- a/soh/soh/Enhancements/randomizer/randomizer_entrance_tracker.cpp +++ b/soh/soh/Enhancements/randomizer/randomizer_entrance_tracker.cpp @@ -27,13 +27,13 @@ extern PlayState* gPlayState; #define COLOR_GREEN IM_COL32(0, 158, 115, 255) #define COLOR_GRAY IM_COL32(155, 155, 155, 255) -EntranceOverride srcListSortedByArea[ENTRANCE_OVERRIDES_MAX_COUNT] = {0}; -EntranceOverride destListSortedByArea[ENTRANCE_OVERRIDES_MAX_COUNT] = {0}; -EntranceOverride srcListSortedByType[ENTRANCE_OVERRIDES_MAX_COUNT] = {0}; -EntranceOverride destListSortedByType[ENTRANCE_OVERRIDES_MAX_COUNT] = {0}; -EntranceTrackingData gEntranceTrackingData = {0}; +EntranceOverride srcListSortedByArea[ENTRANCE_OVERRIDES_MAX_COUNT] = { 0 }; +EntranceOverride destListSortedByArea[ENTRANCE_OVERRIDES_MAX_COUNT] = { 0 }; +EntranceOverride srcListSortedByType[ENTRANCE_OVERRIDES_MAX_COUNT] = { 0 }; +EntranceOverride destListSortedByType[ENTRANCE_OVERRIDES_MAX_COUNT] = { 0 }; +EntranceTrackingData gEntranceTrackingData = { 0 }; -static const EntranceOverride emptyOverride = {0}; +static const EntranceOverride emptyOverride = { 0 }; static s16 lastEntranceIndex = -1; static s16 currentGrottoId = -1; @@ -64,15 +64,11 @@ static std::string spoilerEntranceGroupNames[] = { }; static std::string groupTypeNames[] = { - "One Way", - "Overworld", - "Interior", - "Grotto", - "Dungeon", + "One Way", "Overworld", "Interior", "Grotto", "Dungeon", }; -// Entrance data for the tracker taken from the 3ds rando entrance tracker, and supplemented with scene/spawn info and meta search tags -// ENTR_HYRULE_FIELD_10 and ENTR_POTION_SHOP_KAKARIKO_1 have been repurposed for entrance randomizer +// Entrance data for the tracker taken from the 3ds rando entrance tracker, and supplemented with scene/spawn info and +// meta search tags ENTR_HYRULE_FIELD_10 and ENTR_POTION_SHOP_KAKARIKO_1 have been repurposed for entrance randomizer const EntranceData entranceData[] = { // clang-format off //index, reverse, scenes (and spawns), source name, destination name, source group, destination group, type, metaTag, oneExit @@ -428,9 +424,11 @@ bool IsEntranceDiscovered(s16 index) { if (!isDiscovered) { // If the pair included one of the hyrule field <-> zora's river entrances, // the randomizer will have also overriden the water-based entrances, so check those too - if ((index == ENTR_ZORAS_RIVER_WEST_EXIT && Entrance_GetIsEntranceDiscovered(ENTR_ZORAS_RIVER_3)) || (index == ENTR_ZORAS_RIVER_3 && Entrance_GetIsEntranceDiscovered(ENTR_ZORAS_RIVER_WEST_EXIT))) { + if ((index == ENTR_ZORAS_RIVER_WEST_EXIT && Entrance_GetIsEntranceDiscovered(ENTR_ZORAS_RIVER_3)) || + (index == ENTR_ZORAS_RIVER_3 && Entrance_GetIsEntranceDiscovered(ENTR_ZORAS_RIVER_WEST_EXIT))) { isDiscovered = true; - } else if ((index == ENTR_HYRULE_FIELD_RIVER_EXIT && Entrance_GetIsEntranceDiscovered(ENTR_HYRULE_FIELD_14)) || (index == ENTR_HYRULE_FIELD_14 && Entrance_GetIsEntranceDiscovered(ENTR_HYRULE_FIELD_RIVER_EXIT))) { + } else if ((index == ENTR_HYRULE_FIELD_RIVER_EXIT && Entrance_GetIsEntranceDiscovered(ENTR_HYRULE_FIELD_14)) || + (index == ENTR_HYRULE_FIELD_14 && Entrance_GetIsEntranceDiscovered(ENTR_HYRULE_FIELD_RIVER_EXIT))) { isDiscovered = true; } } @@ -447,16 +445,18 @@ const EntranceData* GetEntranceData(s16 index) { return nullptr; } -// Used for verifying the names on both sides of entrance pairs match. Keeping for ease of use for further name changes later +// Used for verifying the names on both sides of entrance pairs match. Keeping for ease of use for further name changes +// later // TODO: Figure out how to remove the need for duplicate entrance names so this is no longer necessary void CheckEntranceNames() { - SPDLOG_ERROR("Checking entrance names:"); + SPDLOG_ERROR("Checking entrance names:"); for (size_t i = 0; i < ARRAY_COUNT(entranceData); i++) { auto entrance = &entranceData[i]; auto reverse = GetEntranceData(entrance->reverseIndex); if (entrance != nullptr && reverse != nullptr) { if (entrance->source != reverse->destination) { - SPDLOG_ERROR("{}({}) -> {}({})", entrance->source, entrance->index, reverse->destination, reverse->reverseIndex); + SPDLOG_ERROR("{}({}) -> {}({})", entrance->source, entrance->index, reverse->destination, + reverse->reverseIndex); } } } @@ -590,12 +590,12 @@ void ClearEntranceTrackingData() { currentGrottoId = -1; lastEntranceIndex = -1; lastSceneOrEntranceDetected = -1; - gEntranceTrackingData = {0}; + gEntranceTrackingData = { 0 }; } void InitEntranceTrackingData() { auto entranceCtx = Rando::Context::GetInstance()->GetEntranceShuffler(); - gEntranceTrackingData = {0}; + gEntranceTrackingData = { 0 }; // Check if entrance randomization is disabled if (!OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_SHUFFLE_ENTRANCES)) { @@ -668,7 +668,8 @@ void EntranceTrackerSettingsWindow::DrawElement() { ImGui::TableNextColumn(); - if (ImGui::BeginTable("entranceTrackerSubSettings", 2, ImGuiTableFlags_BordersInnerV | ImGuiTableFlags_SizingStretchProp)) { + if (ImGui::BeginTable("entranceTrackerSubSettings", 2, + ImGuiTableFlags_BordersInnerV | ImGuiTableFlags_SizingStretchProp)) { ImGui::TableSetupColumn("column 1", ImGuiTableColumnFlags_WidthStretch, 150.0f); ImGui::TableSetupColumn("column 2", ImGuiTableColumnFlags_WidthStretch, 150.0f); @@ -676,26 +677,41 @@ void EntranceTrackerSettingsWindow::DrawElement() { ImGui::Text("Sort By"); UIWidgets::CVarRadioButton("To", CVAR_TRACKER_ENTRANCE("SortBy"), 0, - UIWidgets::RadioButtonsOptions() - .Color(THEME_COLOR).Tooltip("Sort entrances by the original source entrance")); - UIWidgets::CVarRadioButton("From", CVAR_TRACKER_ENTRANCE("SortBy"), 1, - UIWidgets::RadioButtonsOptions() - .Color(THEME_COLOR).Tooltip("Sort entrances by the overrided destination")); + UIWidgets::RadioButtonsOptions() + .Color(THEME_COLOR) + .Tooltip("Sort entrances by the original source entrance")); + UIWidgets::CVarRadioButton( + "From", CVAR_TRACKER_ENTRANCE("SortBy"), 1, + UIWidgets::RadioButtonsOptions().Color(THEME_COLOR).Tooltip("Sort entrances by the overrided destination")); ImGui::Text("List Items"); - UIWidgets::CVarCheckbox("Auto scroll", CVAR_TRACKER_ENTRANCE("AutoScroll"), - UIWidgets::CheckboxOptions().Tooltip("Automatically scroll to the first available entrance in the current scene").Color(THEME_COLOR)); + UIWidgets::CVarCheckbox( + "Auto scroll", CVAR_TRACKER_ENTRANCE("AutoScroll"), + UIWidgets::CheckboxOptions() + .Tooltip("Automatically scroll to the first available entrance in the current scene") + .Color(THEME_COLOR)); UIWidgets::CVarCheckbox("Highlight previous", CVAR_TRACKER_ENTRANCE("HighlightPrevious"), - UIWidgets::CheckboxOptions().Tooltip("Highlight the previous entrance that Link came from").Color(THEME_COLOR)); + UIWidgets::CheckboxOptions() + .Tooltip("Highlight the previous entrance that Link came from") + .Color(THEME_COLOR)); UIWidgets::CVarCheckbox("Highlight available", CVAR_TRACKER_ENTRANCE("HighlightAvailable"), - UIWidgets::CheckboxOptions().Tooltip("Highlight available entrances in the current scene").Color(THEME_COLOR)); + UIWidgets::CheckboxOptions() + .Tooltip("Highlight available entrances in the current scene") + .Color(THEME_COLOR)); UIWidgets::CVarCheckbox("Hide undiscovered", CVAR_TRACKER_ENTRANCE("CollapseUndiscovered"), - UIWidgets::CheckboxOptions().Tooltip("Collapse undiscovered entrances towards the bottom of each group").Color(THEME_COLOR)); - bool disableHideReverseEntrances = OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_DECOUPLED_ENTRANCES) == RO_GENERIC_ON; - static const char* disableHideReverseEntrancesText = "This option is disabled because \"Decouple Entrances\" is enabled."; + UIWidgets::CheckboxOptions() + .Tooltip("Collapse undiscovered entrances towards the bottom of each group") + .Color(THEME_COLOR)); + bool disableHideReverseEntrances = + OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_DECOUPLED_ENTRANCES) == RO_GENERIC_ON; + static const char* disableHideReverseEntrancesText = + "This option is disabled because \"Decouple Entrances\" is enabled."; UIWidgets::CVarCheckbox("Hide reverse", CVAR_TRACKER_ENTRANCE("HideReverseEntrances"), - UIWidgets::CheckboxOptions({ {.disabled = disableHideReverseEntrances, .disabledTooltip = disableHideReverseEntrancesText }}) - .Tooltip("Hide reverse entrance transitions when Decouple Entrances is off").DefaultValue(true).Color(THEME_COLOR)); + UIWidgets::CheckboxOptions({ { .disabled = disableHideReverseEntrances, + .disabledTooltip = disableHideReverseEntrancesText } }) + .Tooltip("Hide reverse entrance transitions when Decouple Entrances is off") + .DefaultValue(true) + .Color(THEME_COLOR)); ImGui::TableNextColumn(); @@ -708,10 +724,13 @@ void EntranceTrackerSettingsWindow::DrawElement() { UIWidgets::RadioButtonsOptions().Color(THEME_COLOR).Tooltip("Group entrances by their entrance type")); ImGui::Text("Spoiler Reveal"); - UIWidgets::CVarCheckbox("Show Source", CVAR_TRACKER_ENTRANCE("ShowFrom"), - UIWidgets::CheckboxOptions().Tooltip("Reveal the sourcefor undiscovered entrances").Color(THEME_COLOR)); + UIWidgets::CVarCheckbox( + "Show Source", CVAR_TRACKER_ENTRANCE("ShowFrom"), + UIWidgets::CheckboxOptions().Tooltip("Reveal the sourcefor undiscovered entrances").Color(THEME_COLOR)); UIWidgets::CVarCheckbox("Show Destination", CVAR_TRACKER_ENTRANCE("ShowTo"), - UIWidgets::CheckboxOptions().Tooltip("Reveal the destination for undiscovered entrances").Color(THEME_COLOR)); + UIWidgets::CheckboxOptions() + .Tooltip("Reveal the destination for undiscovered entrances") + .Color(THEME_COLOR)); ImGui::EndTable(); } @@ -745,18 +764,21 @@ void EntranceTrackerWindow::DrawElement() { static ImGuiTextFilter locationSearch; uint8_t nextTreeState = 0; - if (UIWidgets::Button("Collapse All", UIWidgets::ButtonOptions({{ .tooltip = "Collapse all entrance groups" }}) - .Color(THEME_COLOR).Size(UIWidgets::Sizes::Inline))) { + if (UIWidgets::Button("Collapse All", UIWidgets::ButtonOptions({ { .tooltip = "Collapse all entrance groups" } }) + .Color(THEME_COLOR) + .Size(UIWidgets::Sizes::Inline))) { nextTreeState = 1; } ImGui::SameLine(); - if (UIWidgets::Button("Expand All", UIWidgets::ButtonOptions({{ .tooltip = "Expand all entrance groups" }}) - .Color(THEME_COLOR).Size(UIWidgets::Sizes::Inline))) { + if (UIWidgets::Button("Expand All", UIWidgets::ButtonOptions({ { .tooltip = "Expand all entrance groups" } }) + .Color(THEME_COLOR) + .Size(UIWidgets::Sizes::Inline))) { nextTreeState = 2; } ImGui::SameLine(); - if (UIWidgets::Button("Clear", UIWidgets::ButtonOptions({{ .tooltip = "Clear the search field" }}) - .Color(THEME_COLOR).Size(UIWidgets::Sizes::Inline))) { + if (UIWidgets::Button("Clear", UIWidgets::ButtonOptions({ { .tooltip = "Clear the search field" } }) + .Color(THEME_COLOR) + .Size(UIWidgets::Sizes::Inline))) { locationSearch.Clear(); } @@ -774,7 +796,7 @@ void EntranceTrackerWindow::DrawElement() { size_t groupCount = groupToggle ? ENTRANCE_TYPE_COUNT : SPOILER_ENTRANCE_GROUP_COUNT; auto groupNames = groupToggle ? groupTypeNames : spoilerEntranceGroupNames; - EntranceOverride *entranceList; + EntranceOverride* entranceList; switch (groupType) { case ENTRANCE_SOURCE_AREA: @@ -819,14 +841,17 @@ void EntranceTrackerWindow::DrawElement() { const EntranceData* original = GetEntranceData(entrance.index); const EntranceData* override = GetEntranceData(entrance.override); - // If entrance is a dungeon, grotto, or interior entrance, the transition into that area has oneExit set, which means we can filter the return transitions as redundant - // if entrances are not decoupled, as this is redundant information. Also checks a setting, enabled by default, for hiding them. - // If all of these conditions are met, we skip adding this entrance to any lists. - // However, if entrances are decoupled, then all transitions need to be displayed, so we proceed with the filtering - if ((original->type == ENTRANCE_TYPE_DUNGEON || original->type == ENTRANCE_TYPE_GROTTO || original->type == ENTRANCE_TYPE_INTERIOR) && - (original->oneExit != 1 && OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_DECOUPLED_ENTRANCES) == RO_GENERIC_OFF) && + // If entrance is a dungeon, grotto, or interior entrance, the transition into that area has oneExit set, + // which means we can filter the return transitions as redundant if entrances are not decoupled, as this is + // redundant information. Also checks a setting, enabled by default, for hiding them. If all of these + // conditions are met, we skip adding this entrance to any lists. However, if entrances are decoupled, then + // all transitions need to be displayed, so we proceed with the filtering + if ((original->type == ENTRANCE_TYPE_DUNGEON || original->type == ENTRANCE_TYPE_GROTTO || + original->type == ENTRANCE_TYPE_INTERIOR) && + (original->oneExit != 1 && + OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_DECOUPLED_ENTRANCES) == RO_GENERIC_OFF) && hideReverse == 1) { - continue; + continue; } // RANDOTODO: Only show blue warps if bluewarp shuffle is on @@ -844,18 +869,21 @@ void EntranceTrackerWindow::DrawElement() { const char* rplcSrcAreaName = spoilerEntranceGroupNames[override->srcGroup].c_str(); const char* rplcTypeName = groupTypeNames[override->type].c_str(); - const char* origSrcName = showOriginal ? original->source.c_str() : ""; + const char* origSrcName = showOriginal ? original->source.c_str() : ""; const char* rplcDstName = showOverride ? override->destination.c_str() : ""; // Filter for entrances by group name, type, source/destination names, and meta tags if ((!locationSearch.IsActive() && (showOriginal || showOverride || !collapsUndiscovered)) || - ((showOriginal && (locationSearch.PassFilter(origSrcName) || locationSearch.PassFilter(origSrcAreaName) || - locationSearch.PassFilter(origTypeName) || locationSearch.PassFilter(original->metaTag.c_str()))) || - (showOverride && (locationSearch.PassFilter(rplcDstName) || locationSearch.PassFilter(rplcSrcAreaName) || - locationSearch.PassFilter(rplcTypeName) || locationSearch.PassFilter(override->metaTag.c_str()))))) { + ((showOriginal && + (locationSearch.PassFilter(origSrcName) || locationSearch.PassFilter(origSrcAreaName) || + locationSearch.PassFilter(origTypeName) || locationSearch.PassFilter(original->metaTag.c_str()))) || + (showOverride && + (locationSearch.PassFilter(rplcDstName) || locationSearch.PassFilter(rplcSrcAreaName) || + locationSearch.PassFilter(rplcTypeName) || locationSearch.PassFilter(override->metaTag.c_str()))))) { // Detect if a scroll should happen and remember the scene for that scroll - if (!doAreaScroll && (lastSceneOrEntranceDetected != LinkIsInArea(original) && LinkIsInArea(original) != -1)) { + if (!doAreaScroll && + (lastSceneOrEntranceDetected != LinkIsInArea(original) && LinkIsInArea(original) != -1)) { lastSceneOrEntranceDetected = LinkIsInArea(original); doAreaScroll = true; } @@ -889,16 +917,18 @@ void EntranceTrackerWindow::DrawElement() { const char* unknown = "???"; - const char* origSrcName = showOriginal ? original->source.c_str() : unknown; + const char* origSrcName = showOriginal ? original->source.c_str() : unknown; const char* rplcDstName = showOverride ? override->destination.c_str() : unknown; uint32_t color = isDiscovered ? IM_COL32_WHITE : COLOR_GRAY; // Handle highlighting and auto scroll if ((original->index == lastEntranceIndex || - (override->reverseIndex == lastEntranceIndex && OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_DECOUPLED_ENTRANCES) == RO_GENERIC_OFF)) && - highlightPrevious) { - color = COLOR_ORANGE; + (override->reverseIndex == lastEntranceIndex && + OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_DECOUPLED_ENTRANCES) == + RO_GENERIC_OFF)) && + highlightPrevious) { + color = COLOR_ORANGE; } else if (LinkIsInArea(original) != -1) { if (highlightAvailable) { color = COLOR_GREEN; @@ -940,10 +970,8 @@ void EntranceTrackerWindow::DrawElement() { void EntranceTrackerWindow::InitElement() { // Setup hooks for loading and clearing the entrance tracker data - GameInteractor::Instance->RegisterGameHook([](int32_t fileNum) { - InitEntranceTrackingData(); - }); - GameInteractor::Instance->RegisterGameHook([](int32_t fileNum) { - ClearEntranceTrackingData(); - }); + GameInteractor::Instance->RegisterGameHook( + [](int32_t fileNum) { InitEntranceTrackingData(); }); + GameInteractor::Instance->RegisterGameHook( + [](int32_t fileNum) { ClearEntranceTrackingData(); }); } diff --git a/soh/soh/Enhancements/randomizer/randomizer_entrance_tracker.h b/soh/soh/Enhancements/randomizer/randomizer_entrance_tracker.h index 0e1271e57..ff9462881 100644 --- a/soh/soh/Enhancements/randomizer/randomizer_entrance_tracker.h +++ b/soh/soh/Enhancements/randomizer/randomizer_entrance_tracker.h @@ -76,8 +76,12 @@ typedef struct { extern EntranceTrackingData gEntranceTrackingData; -#define SINGLE_SCENE_INFO(scene) {{ scene, -1 }} -#define SCENE_NO_SPAWN(scene) { scene, -1 } +#define SINGLE_SCENE_INFO(scene) \ + { \ + { scene, -1 } \ + } +#define SCENE_NO_SPAWN(scene) \ + { scene, -1 } void SetCurrentGrottoIDForTracker(int16_t entranceIndex); void SetLastEntranceOverrideForTracker(int16_t entranceIndex); @@ -92,9 +96,9 @@ class EntranceTrackerSettingsWindow : public Ship::GuiWindow { using GuiWindow::GuiWindow; protected: - void InitElement() override {}; + void InitElement() override{}; void DrawElement() override; - void UpdateElement() override {}; + void UpdateElement() override{}; }; class EntranceTrackerWindow : public Ship::GuiWindow { @@ -104,5 +108,5 @@ class EntranceTrackerWindow : public Ship::GuiWindow { void InitElement() override; void DrawElement() override; - void UpdateElement() override {}; + void UpdateElement() override{}; }; diff --git a/soh/soh/Enhancements/randomizer/randomizer_grotto.c b/soh/soh/Enhancements/randomizer/randomizer_grotto.c index eef1c3171..042efadf4 100644 --- a/soh/soh/Enhancements/randomizer/randomizer_grotto.c +++ b/soh/soh/Enhancements/randomizer/randomizer_grotto.c @@ -90,8 +90,8 @@ static const GrottoReturnInfo grottoReturnTable[NUM_GROTTOS] = { // clang-format on }; -static s16 grottoExitList[NUM_GROTTOS] = {0}; -static s16 grottoLoadList[NUM_GROTTOS] = {0}; +static s16 grottoExitList[NUM_GROTTOS] = { 0 }; +static s16 grottoLoadList[NUM_GROTTOS] = { 0 }; static s8 grottoId = 0xFF; static s8 lastEntranceType = NOT_GROTTO; static u8 overridingNextEntrance = false; @@ -143,7 +143,9 @@ static void Grotto_SetupReturnInfo(GrottoReturnInfo grotto, RespawnMode respawnM // This method doesn't change player respawn data, so only use this if you are querying an entrance index. s16 Grotto_GetEntranceValueHandlingGrottoRando(s16 nextEntranceIndex) { // Don't change anything unless grotto shuffle has been enabled - if (!Randomizer_GetSettingValue(RSK_SHUFFLE_GROTTO_ENTRANCES) && !Randomizer_GetSettingValue(RSK_SHUFFLE_OVERWORLD_SPAWNS) && !Randomizer_GetSettingValue(RSK_SHUFFLE_WARP_SONGS)) { + if (!Randomizer_GetSettingValue(RSK_SHUFFLE_GROTTO_ENTRANCES) && + !Randomizer_GetSettingValue(RSK_SHUFFLE_OVERWORLD_SPAWNS) && + !Randomizer_GetSettingValue(RSK_SHUFFLE_WARP_SONGS)) { return nextEntranceIndex; } @@ -157,7 +159,8 @@ s16 Grotto_GetEntranceValueHandlingGrottoRando(s16 nextEntranceIndex) { s8 tempGrottoId = nextEntranceIndex & 0x00FF; // Grotto Returns - if (nextEntranceIndex >= ENTRANCE_GROTTO_EXIT_START && nextEntranceIndex < ENTRANCE_GROTTO_EXIT_START + NUM_GROTTOS) { + if (nextEntranceIndex >= ENTRANCE_GROTTO_EXIT_START && + nextEntranceIndex < ENTRANCE_GROTTO_EXIT_START + NUM_GROTTOS) { GrottoReturnInfo grotto = grottoReturnTable[tempGrottoId]; // When the nextEntranceIndex is determined by a dynamic exit, @@ -167,11 +170,11 @@ s16 Grotto_GetEntranceValueHandlingGrottoRando(s16 nextEntranceIndex) { nextEntranceIndex = grotto.entranceIndex; } else if (gPlayState == NULL) { // Handle spawn position when loading from a save file nextEntranceIndex = grotto.entranceIndex; - // Otherwise return 0x7FFF (ENTR_RETURN_GROTTO) and let the game handle it + // Otherwise return 0x7FFF (ENTR_RETURN_GROTTO) and let the game handle it } else { nextEntranceIndex = ENTR_RETURN_GROTTO; } - // Grotto Loads + // Grotto Loads } else if (nextEntranceIndex >= ENTRANCE_GROTTO_LOAD_START && nextEntranceIndex < ENTRANCE_GROTTO_EXIT_START) { GrottoLoadInfo grotto = grottoLoadTable[tempGrottoId]; nextEntranceIndex = grotto.entranceIndex; @@ -185,7 +188,9 @@ s16 Grotto_GetEntranceValueHandlingGrottoRando(s16 nextEntranceIndex) { s16 Grotto_OverrideSpecialEntrance(s16 nextEntranceIndex) { // Don't change anything unless grotto shuffle has been enabled - if (!Randomizer_GetSettingValue(RSK_SHUFFLE_GROTTO_ENTRANCES) && !Randomizer_GetSettingValue(RSK_SHUFFLE_OVERWORLD_SPAWNS) && !Randomizer_GetSettingValue(RSK_SHUFFLE_WARP_SONGS)) { + if (!Randomizer_GetSettingValue(RSK_SHUFFLE_GROTTO_ENTRANCES) && + !Randomizer_GetSettingValue(RSK_SHUFFLE_OVERWORLD_SPAWNS) && + !Randomizer_GetSettingValue(RSK_SHUFFLE_WARP_SONGS)) { return nextEntranceIndex; } @@ -201,7 +206,8 @@ s16 Grotto_OverrideSpecialEntrance(s16 nextEntranceIndex) { grottoId = nextEntranceIndex & 0x00FF; // Grotto Returns - if (nextEntranceIndex >= ENTRANCE_GROTTO_EXIT_START && nextEntranceIndex < ENTRANCE_GROTTO_EXIT_START + NUM_GROTTOS) { + if (nextEntranceIndex >= ENTRANCE_GROTTO_EXIT_START && + nextEntranceIndex < ENTRANCE_GROTTO_EXIT_START + NUM_GROTTOS) { GrottoReturnInfo grotto = grottoReturnTable[grottoId]; Grotto_SetupReturnInfo(grotto, RESPAWN_MODE_RETURN); @@ -219,13 +225,13 @@ s16 Grotto_OverrideSpecialEntrance(s16 nextEntranceIndex) { gSaveContext.respawnFlag = 2; nextEntranceIndex = grotto.entranceIndex; gSaveContext.nextTransitionType = TRANS_TYPE_FADE_WHITE; - // Otherwise return 0x7FFF (ENTR_RETURN_GROTTO) and let the game handle it + // Otherwise return 0x7FFF (ENTR_RETURN_GROTTO) and let the game handle it } else { nextEntranceIndex = ENTR_RETURN_GROTTO; } lastEntranceType = GROTTO_RETURN; - // Grotto Loads + // Grotto Loads } else if (nextEntranceIndex >= ENTRANCE_GROTTO_LOAD_START && nextEntranceIndex < ENTRANCE_GROTTO_EXIT_START) { // Set the respawn data to load the correct grotto @@ -236,7 +242,7 @@ s16 Grotto_OverrideSpecialEntrance(s16 nextEntranceIndex) { EntranceTracker_SetCurrentGrottoID(grottoId); lastEntranceType = NOT_GROTTO; - // Otherwise just unset the current grotto ID + // Otherwise just unset the current grotto ID } else { grottoId = 0xFF; lastEntranceType = NOT_GROTTO; @@ -251,7 +257,9 @@ s16 Grotto_OverrideSpecialEntrance(s16 nextEntranceIndex) { void Grotto_OverrideActorEntrance(Actor* thisx) { // Vanilla Behavior if there's no possibility of ending up in a grotto randomly - if (!Randomizer_GetSettingValue(RSK_SHUFFLE_GROTTO_ENTRANCES) && !Randomizer_GetSettingValue(RSK_SHUFFLE_OVERWORLD_SPAWNS) && !Randomizer_GetSettingValue(RSK_SHUFFLE_WARP_SONGS)) { + if (!Randomizer_GetSettingValue(RSK_SHUFFLE_GROTTO_ENTRANCES) && + !Randomizer_GetSettingValue(RSK_SHUFFLE_OVERWORLD_SPAWNS) && + !Randomizer_GetSettingValue(RSK_SHUFFLE_WARP_SONGS)) { return; } @@ -277,7 +285,9 @@ void Grotto_OverrideActorEntrance(Actor* thisx) { // Set necessary flags for when warp songs/overworld spawns are shuffled to grotto return points void Grotto_ForceGrottoReturnOnSpecialEntrance(void) { - if (lastEntranceType == GROTTO_RETURN && (Randomizer_GetSettingValue(RSK_SHUFFLE_GROTTO_ENTRANCES) || Randomizer_GetSettingValue(RSK_SHUFFLE_OVERWORLD_SPAWNS) || Randomizer_GetSettingValue(RSK_SHUFFLE_WARP_SONGS))) { + if (lastEntranceType == GROTTO_RETURN && (Randomizer_GetSettingValue(RSK_SHUFFLE_GROTTO_ENTRANCES) || + Randomizer_GetSettingValue(RSK_SHUFFLE_OVERWORLD_SPAWNS) || + Randomizer_GetSettingValue(RSK_SHUFFLE_WARP_SONGS))) { gSaveContext.respawnFlag = 2; gSaveContext.respawn[RESPAWN_MODE_RETURN].playerParams = 0x04FF; gSaveContext.respawn[RESPAWN_MODE_RETURN].pos = grottoReturnTable[grottoId].pos; @@ -290,11 +300,13 @@ void Grotto_ForceGrottoReturnOnSpecialEntrance(void) { // Set the respawn flag for when we want to return from a grotto entrance // Used for Sun's Song and Game Over, which usually don't restore saved position data void Grotto_ForceGrottoReturn(void) { - if (lastEntranceType == GROTTO_RETURN && (Randomizer_GetSettingValue(RSK_SHUFFLE_GROTTO_ENTRANCES) || Randomizer_GetSettingValue(RSK_SHUFFLE_OVERWORLD_SPAWNS) || Randomizer_GetSettingValue(RSK_SHUFFLE_WARP_SONGS))) { + if (lastEntranceType == GROTTO_RETURN && (Randomizer_GetSettingValue(RSK_SHUFFLE_GROTTO_ENTRANCES) || + Randomizer_GetSettingValue(RSK_SHUFFLE_OVERWORLD_SPAWNS) || + Randomizer_GetSettingValue(RSK_SHUFFLE_WARP_SONGS))) { gSaveContext.respawnFlag = 2; gSaveContext.respawn[RESPAWN_MODE_RETURN].playerParams = 0x0DFF; gSaveContext.respawn[RESPAWN_MODE_RETURN].pos = grottoReturnTable[grottoId].pos; - //Save the current temp flags in the grotto return point, so they'll properly keep their values. + // Save the current temp flags in the grotto return point, so they'll properly keep their values. gSaveContext.respawn[RESPAWN_MODE_RETURN].tempSwchFlags = gPlayState->actorCtx.flags.tempSwch; gSaveContext.respawn[RESPAWN_MODE_RETURN].tempCollectFlags = gPlayState->actorCtx.flags.tempCollect; } @@ -302,7 +314,9 @@ void Grotto_ForceGrottoReturn(void) { // Used for the DMT special voids, which usually don't restore saved position data void Grotto_ForceRegularVoidOut(void) { - if (lastEntranceType == GROTTO_RETURN && (Randomizer_GetSettingValue(RSK_SHUFFLE_GROTTO_ENTRANCES) || Randomizer_GetSettingValue(RSK_SHUFFLE_OVERWORLD_SPAWNS) || Randomizer_GetSettingValue(RSK_SHUFFLE_WARP_SONGS))) { + if (lastEntranceType == GROTTO_RETURN && (Randomizer_GetSettingValue(RSK_SHUFFLE_GROTTO_ENTRANCES) || + Randomizer_GetSettingValue(RSK_SHUFFLE_OVERWORLD_SPAWNS) || + Randomizer_GetSettingValue(RSK_SHUFFLE_WARP_SONGS))) { gSaveContext.respawn[RESPAWN_MODE_DOWN] = gSaveContext.respawn[RESPAWN_MODE_RETURN]; gSaveContext.respawn[RESPAWN_MODE_DOWN].playerParams = 0x0DFF; gSaveContext.respawn[RESPAWN_MODE_DOWN].pos = grottoReturnTable[grottoId].pos; @@ -313,8 +327,9 @@ void Grotto_ForceRegularVoidOut(void) { // If returning to a FW point saved at a grotto exit, copy the FW data to the Grotto Return Point // so that Sun's Song and Game Over will behave correctly void Grotto_SetupReturnInfoOnFWReturn(void) { - if (Randomizer_GetSettingValue(RSK_SHUFFLE_GROTTO_ENTRANCES) || Randomizer_GetSettingValue(RSK_SHUFFLE_OVERWORLD_SPAWNS) || Randomizer_GetSettingValue(RSK_SHUFFLE_WARP_SONGS) && - gSaveContext.fw.playerParams == 0x04FF) { + if (Randomizer_GetSettingValue(RSK_SHUFFLE_GROTTO_ENTRANCES) || + Randomizer_GetSettingValue(RSK_SHUFFLE_OVERWORLD_SPAWNS) || + Randomizer_GetSettingValue(RSK_SHUFFLE_WARP_SONGS) && gSaveContext.fw.playerParams == 0x04FF) { gSaveContext.respawn[RESPAWN_MODE_RETURN] = gSaveContext.respawn[RESPAWN_MODE_TOP]; gSaveContext.respawn[RESPAWN_MODE_RETURN].playerParams = 0x0DFF; lastEntranceType = GROTTO_RETURN; @@ -345,7 +360,9 @@ s16 Grotto_GetRenamedGrottoIndexFromOriginal(s8 content, s8 scene) { } s8 Grotto_CurrentGrotto() { - if (Randomizer_GetSettingValue(RSK_SHUFFLE_GROTTO_ENTRANCES) || Randomizer_GetSettingValue(RSK_SHUFFLE_OVERWORLD_SPAWNS) || Randomizer_GetSettingValue(RSK_SHUFFLE_WARP_SONGS)) { + if (Randomizer_GetSettingValue(RSK_SHUFFLE_GROTTO_ENTRANCES) || + Randomizer_GetSettingValue(RSK_SHUFFLE_OVERWORLD_SPAWNS) || + Randomizer_GetSettingValue(RSK_SHUFFLE_WARP_SONGS)) { return grottoId; } else { s16 entrance = gSaveContext.respawn[RESPAWN_MODE_RETURN].entranceIndex; diff --git a/soh/soh/Enhancements/randomizer/randomizer_inf.h b/soh/soh/Enhancements/randomizer/randomizer_inf.h index 70aa11c06..048fcc86c 100644 --- a/soh/soh/Enhancements/randomizer/randomizer_inf.h +++ b/soh/soh/Enhancements/randomizer/randomizer_inf.h @@ -144,7 +144,6 @@ typedef enum { RAND_INF_GREG_FOUND, - RAND_INF_TOT_MASTER_SWORD, RAND_INF_CHILD_FISHING, @@ -999,7 +998,7 @@ typedef enum { RAND_INF_SHADOW_TEMPLE_MQ_TRUTH_SPINNER_SMALL_CRATE_4, RAND_INF_SPIRIT_TEMPLE_MQ_STATUE_SMALL_CRATE, RAND_INF_SPIRIT_TEMPLE_MQ_BEAMOS_SMALL_CRATE, - + RAND_INF_CAUGHT_LOACH, RAND_INF_CAN_SWIM, @@ -1603,7 +1602,6 @@ typedef enum { RAND_INF_ADULT_TRADES_HAS_EYEDROPS, RAND_INF_ADULT_TRADES_HAS_CLAIM_CHECK, - // Overworld Grass RAND_INF_KF_CHILD_GRASS_1, RAND_INF_KF_CHILD_GRASS_2, @@ -1954,7 +1952,8 @@ typedef enum { RAND_INF_DEKU_TREE_QUEEN_GOHMA_GRASS_7, RAND_INF_DEKU_TREE_QUEEN_GOHMA_GRASS_8, // End Grass - // If you add anything to this list, you need to update the size of randomizerInf in z64save.h to be ceil(RAND_INF_MAX / 16) + // If you add anything to this list, you need to update the size of randomizerInf in z64save.h to be + // ceil(RAND_INF_MAX / 16) RAND_INF_MAX, } RandomizerInf; diff --git a/soh/soh/Enhancements/randomizer/randomizer_item_tracker.cpp b/soh/soh/Enhancements/randomizer/randomizer_item_tracker.cpp index 0c24aa181..8d9d2559a 100644 --- a/soh/soh/Enhancements/randomizer/randomizer_item_tracker.cpp +++ b/soh/soh/Enhancements/randomizer/randomizer_item_tracker.cpp @@ -43,45 +43,65 @@ bool shouldUpdateVectors = true; std::vector mainWindowItems = {}; std::vector inventoryItems = { - ITEM_TRACKER_ITEM(ITEM_STICK, 0, DrawItem), ITEM_TRACKER_ITEM(ITEM_NUT, 0, DrawItem), ITEM_TRACKER_ITEM(ITEM_BOMB, 0, DrawItem), - ITEM_TRACKER_ITEM(ITEM_BOW, 0, DrawItem), ITEM_TRACKER_ITEM(ITEM_ARROW_FIRE, 0, DrawItem), ITEM_TRACKER_ITEM(ITEM_DINS_FIRE, 0, DrawItem), - ITEM_TRACKER_ITEM(ITEM_SLINGSHOT, 0, DrawItem), ITEM_TRACKER_ITEM(ITEM_OCARINA_FAIRY, 0, DrawItem), ITEM_TRACKER_ITEM(ITEM_BOMBCHU, 0, DrawItem), - ITEM_TRACKER_ITEM(ITEM_HOOKSHOT, 0, DrawItem), ITEM_TRACKER_ITEM(ITEM_ARROW_ICE, 0, DrawItem), ITEM_TRACKER_ITEM(ITEM_FARORES_WIND, 0, DrawItem), - ITEM_TRACKER_ITEM(ITEM_BOOMERANG, 0, DrawItem), ITEM_TRACKER_ITEM(ITEM_LENS, 0, DrawItem), ITEM_TRACKER_ITEM(ITEM_BEAN, 0, DrawItem), - ITEM_TRACKER_ITEM(ITEM_HAMMER, 0, DrawItem), ITEM_TRACKER_ITEM(ITEM_ARROW_LIGHT, 0, DrawItem), ITEM_TRACKER_ITEM(ITEM_NAYRUS_LOVE, 0, DrawItem), - ITEM_TRACKER_ITEM(ITEM_BOTTLE, 0, DrawBottle), ITEM_TRACKER_ITEM(ITEM_BOTTLE, 1, DrawBottle), ITEM_TRACKER_ITEM(ITEM_BOTTLE, 2, DrawBottle), - ITEM_TRACKER_ITEM(ITEM_BOTTLE, 3, DrawBottle), ITEM_TRACKER_ITEM(ITEM_POCKET_EGG, 0, DrawItem), ITEM_TRACKER_ITEM(ITEM_MASK_KEATON, 0, DrawItem), + ITEM_TRACKER_ITEM(ITEM_STICK, 0, DrawItem), ITEM_TRACKER_ITEM(ITEM_NUT, 0, DrawItem), + ITEM_TRACKER_ITEM(ITEM_BOMB, 0, DrawItem), ITEM_TRACKER_ITEM(ITEM_BOW, 0, DrawItem), + ITEM_TRACKER_ITEM(ITEM_ARROW_FIRE, 0, DrawItem), ITEM_TRACKER_ITEM(ITEM_DINS_FIRE, 0, DrawItem), + ITEM_TRACKER_ITEM(ITEM_SLINGSHOT, 0, DrawItem), ITEM_TRACKER_ITEM(ITEM_OCARINA_FAIRY, 0, DrawItem), + ITEM_TRACKER_ITEM(ITEM_BOMBCHU, 0, DrawItem), ITEM_TRACKER_ITEM(ITEM_HOOKSHOT, 0, DrawItem), + ITEM_TRACKER_ITEM(ITEM_ARROW_ICE, 0, DrawItem), ITEM_TRACKER_ITEM(ITEM_FARORES_WIND, 0, DrawItem), + ITEM_TRACKER_ITEM(ITEM_BOOMERANG, 0, DrawItem), ITEM_TRACKER_ITEM(ITEM_LENS, 0, DrawItem), + ITEM_TRACKER_ITEM(ITEM_BEAN, 0, DrawItem), ITEM_TRACKER_ITEM(ITEM_HAMMER, 0, DrawItem), + ITEM_TRACKER_ITEM(ITEM_ARROW_LIGHT, 0, DrawItem), ITEM_TRACKER_ITEM(ITEM_NAYRUS_LOVE, 0, DrawItem), + ITEM_TRACKER_ITEM(ITEM_BOTTLE, 0, DrawBottle), ITEM_TRACKER_ITEM(ITEM_BOTTLE, 1, DrawBottle), + ITEM_TRACKER_ITEM(ITEM_BOTTLE, 2, DrawBottle), ITEM_TRACKER_ITEM(ITEM_BOTTLE, 3, DrawBottle), + ITEM_TRACKER_ITEM(ITEM_POCKET_EGG, 0, DrawItem), ITEM_TRACKER_ITEM(ITEM_MASK_KEATON, 0, DrawItem), }; std::vector equipmentItems = { - ITEM_TRACKER_ITEM(ITEM_SWORD_KOKIRI, 1 << 0, DrawEquip), ITEM_TRACKER_ITEM(ITEM_SWORD_MASTER, 1 << 1, DrawEquip), ITEM_TRACKER_ITEM(ITEM_SWORD_BGS, 1 << 2, DrawEquip), - ITEM_TRACKER_ITEM(ITEM_TUNIC_KOKIRI, 1 << 8, DrawEquip), ITEM_TRACKER_ITEM(ITEM_TUNIC_GORON, 1 << 9, DrawEquip), ITEM_TRACKER_ITEM(ITEM_TUNIC_ZORA, 1 << 10, DrawEquip), - ITEM_TRACKER_ITEM(ITEM_SHIELD_DEKU, 1 << 4, DrawEquip), ITEM_TRACKER_ITEM(ITEM_SHIELD_HYLIAN, 1 << 5, DrawEquip), ITEM_TRACKER_ITEM(ITEM_SHIELD_MIRROR, 1 << 6, DrawEquip), - ITEM_TRACKER_ITEM(ITEM_BOOTS_KOKIRI, 1 << 12, DrawEquip), ITEM_TRACKER_ITEM(ITEM_BOOTS_IRON, 1 << 13, DrawEquip), ITEM_TRACKER_ITEM(ITEM_BOOTS_HOVER, 1 << 14, DrawEquip), + ITEM_TRACKER_ITEM(ITEM_SWORD_KOKIRI, 1 << 0, DrawEquip), ITEM_TRACKER_ITEM(ITEM_SWORD_MASTER, 1 << 1, DrawEquip), + ITEM_TRACKER_ITEM(ITEM_SWORD_BGS, 1 << 2, DrawEquip), ITEM_TRACKER_ITEM(ITEM_TUNIC_KOKIRI, 1 << 8, DrawEquip), + ITEM_TRACKER_ITEM(ITEM_TUNIC_GORON, 1 << 9, DrawEquip), ITEM_TRACKER_ITEM(ITEM_TUNIC_ZORA, 1 << 10, DrawEquip), + ITEM_TRACKER_ITEM(ITEM_SHIELD_DEKU, 1 << 4, DrawEquip), ITEM_TRACKER_ITEM(ITEM_SHIELD_HYLIAN, 1 << 5, DrawEquip), + ITEM_TRACKER_ITEM(ITEM_SHIELD_MIRROR, 1 << 6, DrawEquip), ITEM_TRACKER_ITEM(ITEM_BOOTS_KOKIRI, 1 << 12, DrawEquip), + ITEM_TRACKER_ITEM(ITEM_BOOTS_IRON, 1 << 13, DrawEquip), ITEM_TRACKER_ITEM(ITEM_BOOTS_HOVER, 1 << 14, DrawEquip), }; std::vector miscItems = { - ITEM_TRACKER_ITEM(ITEM_BRACELET, 0, DrawItem), ITEM_TRACKER_ITEM(ITEM_SCALE_SILVER, 0, DrawItem), ITEM_TRACKER_ITEM(ITEM_WALLET_ADULT, 0, DrawItem), - ITEM_TRACKER_ITEM(ITEM_HEART_CONTAINER, 0, DrawItem), ITEM_TRACKER_ITEM(ITEM_HEART_PIECE, 0, DrawItem), ITEM_TRACKER_ITEM(ITEM_MAGIC_SMALL, 0, DrawItem), - ITEM_TRACKER_ITEM(QUEST_GERUDO_CARD, 1 << 22, DrawQuest), ITEM_TRACKER_ITEM(QUEST_SKULL_TOKEN, 1 << 23, DrawQuest), ITEM_TRACKER_ITEM(QUEST_STONE_OF_AGONY, 1 << 21, DrawQuest), + ITEM_TRACKER_ITEM(ITEM_BRACELET, 0, DrawItem), + ITEM_TRACKER_ITEM(ITEM_SCALE_SILVER, 0, DrawItem), + ITEM_TRACKER_ITEM(ITEM_WALLET_ADULT, 0, DrawItem), + ITEM_TRACKER_ITEM(ITEM_HEART_CONTAINER, 0, DrawItem), + ITEM_TRACKER_ITEM(ITEM_HEART_PIECE, 0, DrawItem), + ITEM_TRACKER_ITEM(ITEM_MAGIC_SMALL, 0, DrawItem), + ITEM_TRACKER_ITEM(QUEST_GERUDO_CARD, 1 << 22, DrawQuest), + ITEM_TRACKER_ITEM(QUEST_SKULL_TOKEN, 1 << 23, DrawQuest), + ITEM_TRACKER_ITEM(QUEST_STONE_OF_AGONY, 1 << 21, DrawQuest), }; std::vector dungeonRewardStones = { - ITEM_TRACKER_ITEM(QUEST_KOKIRI_EMERALD, 1 << 18, DrawQuest), ITEM_TRACKER_ITEM(QUEST_GORON_RUBY, 1 << 19, DrawQuest), ITEM_TRACKER_ITEM(QUEST_ZORA_SAPPHIRE, 1 << 20, DrawQuest), + ITEM_TRACKER_ITEM(QUEST_KOKIRI_EMERALD, 1 << 18, DrawQuest), + ITEM_TRACKER_ITEM(QUEST_GORON_RUBY, 1 << 19, DrawQuest), + ITEM_TRACKER_ITEM(QUEST_ZORA_SAPPHIRE, 1 << 20, DrawQuest), }; std::vector dungeonRewardMedallions = { - ITEM_TRACKER_ITEM(QUEST_MEDALLION_FOREST, 1 << 0, DrawQuest), ITEM_TRACKER_ITEM(QUEST_MEDALLION_FIRE, 1 << 1, DrawQuest), ITEM_TRACKER_ITEM(QUEST_MEDALLION_WATER, 1 << 2, DrawQuest), - ITEM_TRACKER_ITEM(QUEST_MEDALLION_SPIRIT, 1 << 3, DrawQuest), ITEM_TRACKER_ITEM(QUEST_MEDALLION_SHADOW, 1 << 4, DrawQuest), ITEM_TRACKER_ITEM(QUEST_MEDALLION_LIGHT, 1 << 5, DrawQuest), + ITEM_TRACKER_ITEM(QUEST_MEDALLION_FOREST, 1 << 0, DrawQuest), + ITEM_TRACKER_ITEM(QUEST_MEDALLION_FIRE, 1 << 1, DrawQuest), + ITEM_TRACKER_ITEM(QUEST_MEDALLION_WATER, 1 << 2, DrawQuest), + ITEM_TRACKER_ITEM(QUEST_MEDALLION_SPIRIT, 1 << 3, DrawQuest), + ITEM_TRACKER_ITEM(QUEST_MEDALLION_SHADOW, 1 << 4, DrawQuest), + ITEM_TRACKER_ITEM(QUEST_MEDALLION_LIGHT, 1 << 5, DrawQuest), }; std::vector dungeonRewards = {}; std::vector songItems = { - ITEM_TRACKER_ITEM(QUEST_SONG_LULLABY, 0, DrawSong), ITEM_TRACKER_ITEM(QUEST_SONG_EPONA, 0, DrawSong), ITEM_TRACKER_ITEM(QUEST_SONG_SARIA, 0, DrawSong), - ITEM_TRACKER_ITEM(QUEST_SONG_SUN, 0, DrawSong), ITEM_TRACKER_ITEM(QUEST_SONG_TIME, 0, DrawSong), ITEM_TRACKER_ITEM(QUEST_SONG_STORMS, 0, DrawSong), - ITEM_TRACKER_ITEM(QUEST_SONG_MINUET, 0, DrawSong), ITEM_TRACKER_ITEM(QUEST_SONG_BOLERO, 0, DrawSong), ITEM_TRACKER_ITEM(QUEST_SONG_SERENADE, 0, DrawSong), - ITEM_TRACKER_ITEM(QUEST_SONG_REQUIEM, 0, DrawSong), ITEM_TRACKER_ITEM(QUEST_SONG_NOCTURNE, 0, DrawSong), ITEM_TRACKER_ITEM(QUEST_SONG_PRELUDE, 0, DrawSong), + ITEM_TRACKER_ITEM(QUEST_SONG_LULLABY, 0, DrawSong), ITEM_TRACKER_ITEM(QUEST_SONG_EPONA, 0, DrawSong), + ITEM_TRACKER_ITEM(QUEST_SONG_SARIA, 0, DrawSong), ITEM_TRACKER_ITEM(QUEST_SONG_SUN, 0, DrawSong), + ITEM_TRACKER_ITEM(QUEST_SONG_TIME, 0, DrawSong), ITEM_TRACKER_ITEM(QUEST_SONG_STORMS, 0, DrawSong), + ITEM_TRACKER_ITEM(QUEST_SONG_MINUET, 0, DrawSong), ITEM_TRACKER_ITEM(QUEST_SONG_BOLERO, 0, DrawSong), + ITEM_TRACKER_ITEM(QUEST_SONG_SERENADE, 0, DrawSong), ITEM_TRACKER_ITEM(QUEST_SONG_REQUIEM, 0, DrawSong), + ITEM_TRACKER_ITEM(QUEST_SONG_NOCTURNE, 0, DrawSong), ITEM_TRACKER_ITEM(QUEST_SONG_PRELUDE, 0, DrawSong), }; std::vector gregItems = { @@ -93,59 +113,53 @@ std::vector triforcePieces = { }; std::vector bossSoulItems = { - ITEM_TRACKER_ITEM(RG_GOHMA_SOUL, 0, DrawItem), - ITEM_TRACKER_ITEM(RG_KING_DODONGO_SOUL, 0, DrawItem ), - ITEM_TRACKER_ITEM(RG_BARINADE_SOUL, 0, DrawItem ), - ITEM_TRACKER_ITEM(RG_PHANTOM_GANON_SOUL, 0, DrawItem ), - ITEM_TRACKER_ITEM(RG_VOLVAGIA_SOUL, 0, DrawItem ), - ITEM_TRACKER_ITEM(RG_MORPHA_SOUL, 0, DrawItem ), - ITEM_TRACKER_ITEM(RG_BONGO_BONGO_SOUL, 0, DrawItem ), - ITEM_TRACKER_ITEM(RG_TWINROVA_SOUL, 0, DrawItem ), - ITEM_TRACKER_ITEM(RG_GANON_SOUL, 0, DrawItem ), + ITEM_TRACKER_ITEM(RG_GOHMA_SOUL, 0, DrawItem), ITEM_TRACKER_ITEM(RG_KING_DODONGO_SOUL, 0, DrawItem), + ITEM_TRACKER_ITEM(RG_BARINADE_SOUL, 0, DrawItem), ITEM_TRACKER_ITEM(RG_PHANTOM_GANON_SOUL, 0, DrawItem), + ITEM_TRACKER_ITEM(RG_VOLVAGIA_SOUL, 0, DrawItem), ITEM_TRACKER_ITEM(RG_MORPHA_SOUL, 0, DrawItem), + ITEM_TRACKER_ITEM(RG_BONGO_BONGO_SOUL, 0, DrawItem), ITEM_TRACKER_ITEM(RG_TWINROVA_SOUL, 0, DrawItem), + ITEM_TRACKER_ITEM(RG_GANON_SOUL, 0, DrawItem), }; std::vector ocarinaButtonItems = { - //Hack for right now, just gonna draw ocarina buttons as ocarinas. - //Will replace with other macro once we have a custom texture - ITEM_TRACKER_ITEM_CUSTOM(RG_OCARINA_A_BUTTON, ITEM_OCARINA_TIME, ITEM_OCARINA_TIME, 0, DrawItem), - ITEM_TRACKER_ITEM_CUSTOM(RG_OCARINA_C_UP_BUTTON, ITEM_OCARINA_TIME, ITEM_OCARINA_TIME, 0, DrawItem), - ITEM_TRACKER_ITEM_CUSTOM(RG_OCARINA_C_DOWN_BUTTON, ITEM_OCARINA_TIME, ITEM_OCARINA_TIME, 0, DrawItem), - ITEM_TRACKER_ITEM_CUSTOM(RG_OCARINA_C_LEFT_BUTTON, ITEM_OCARINA_TIME, ITEM_OCARINA_TIME, 0, DrawItem), + // Hack for right now, just gonna draw ocarina buttons as ocarinas. + // Will replace with other macro once we have a custom texture + ITEM_TRACKER_ITEM_CUSTOM(RG_OCARINA_A_BUTTON, ITEM_OCARINA_TIME, ITEM_OCARINA_TIME, 0, DrawItem), + ITEM_TRACKER_ITEM_CUSTOM(RG_OCARINA_C_UP_BUTTON, ITEM_OCARINA_TIME, ITEM_OCARINA_TIME, 0, DrawItem), + ITEM_TRACKER_ITEM_CUSTOM(RG_OCARINA_C_DOWN_BUTTON, ITEM_OCARINA_TIME, ITEM_OCARINA_TIME, 0, DrawItem), + ITEM_TRACKER_ITEM_CUSTOM(RG_OCARINA_C_LEFT_BUTTON, ITEM_OCARINA_TIME, ITEM_OCARINA_TIME, 0, DrawItem), ITEM_TRACKER_ITEM_CUSTOM(RG_OCARINA_C_RIGHT_BUTTON, ITEM_OCARINA_TIME, ITEM_OCARINA_TIME, 0, DrawItem), }; std::vector overworldKeyItems = { // Hack for right now, just gonna overworld keys as dungeon keys. // Will replace with other macro once we have a custom texture - ITEM_TRACKER_ITEM_CUSTOM(RG_GUARD_HOUSE_KEY, ITEM_KEY_SMALL, ITEM_KEY_SMALL, 0, DrawItem), - ITEM_TRACKER_ITEM_CUSTOM(RG_MARKET_BAZAAR_KEY, ITEM_KEY_SMALL, ITEM_KEY_SMALL, 0, DrawItem), - ITEM_TRACKER_ITEM_CUSTOM(RG_MARKET_POTION_SHOP_KEY, ITEM_KEY_SMALL, ITEM_KEY_SMALL, 0, DrawItem), - ITEM_TRACKER_ITEM_CUSTOM(RG_MASK_SHOP_KEY, ITEM_KEY_SMALL, ITEM_KEY_SMALL, 0, DrawItem), - ITEM_TRACKER_ITEM_CUSTOM(RG_MARKET_SHOOTING_GALLERY_KEY, ITEM_KEY_SMALL, ITEM_KEY_SMALL, 0, DrawItem), - ITEM_TRACKER_ITEM_CUSTOM(RG_BOMBCHU_BOWLING_KEY, ITEM_KEY_SMALL, ITEM_KEY_SMALL, 0, DrawItem), + ITEM_TRACKER_ITEM_CUSTOM(RG_GUARD_HOUSE_KEY, ITEM_KEY_SMALL, ITEM_KEY_SMALL, 0, DrawItem), + ITEM_TRACKER_ITEM_CUSTOM(RG_MARKET_BAZAAR_KEY, ITEM_KEY_SMALL, ITEM_KEY_SMALL, 0, DrawItem), + ITEM_TRACKER_ITEM_CUSTOM(RG_MARKET_POTION_SHOP_KEY, ITEM_KEY_SMALL, ITEM_KEY_SMALL, 0, DrawItem), + ITEM_TRACKER_ITEM_CUSTOM(RG_MASK_SHOP_KEY, ITEM_KEY_SMALL, ITEM_KEY_SMALL, 0, DrawItem), + ITEM_TRACKER_ITEM_CUSTOM(RG_MARKET_SHOOTING_GALLERY_KEY, ITEM_KEY_SMALL, ITEM_KEY_SMALL, 0, DrawItem), + ITEM_TRACKER_ITEM_CUSTOM(RG_BOMBCHU_BOWLING_KEY, ITEM_KEY_SMALL, ITEM_KEY_SMALL, 0, DrawItem), ITEM_TRACKER_ITEM_CUSTOM(RG_TREASURE_CHEST_GAME_BUILDING_KEY, ITEM_KEY_SMALL, ITEM_KEY_SMALL, 0, DrawItem), - ITEM_TRACKER_ITEM_CUSTOM(RG_BOMBCHU_SHOP_KEY, ITEM_KEY_SMALL, ITEM_KEY_SMALL, 0, DrawItem), - ITEM_TRACKER_ITEM_CUSTOM(RG_RICHARDS_HOUSE_KEY, ITEM_KEY_SMALL, ITEM_KEY_SMALL, 0, DrawItem), - ITEM_TRACKER_ITEM_CUSTOM(RG_ALLEY_HOUSE_KEY, ITEM_KEY_SMALL, ITEM_KEY_SMALL, 0, DrawItem), - ITEM_TRACKER_ITEM_CUSTOM(RG_KAK_BAZAAR_KEY, ITEM_KEY_SMALL, ITEM_KEY_SMALL, 0, DrawItem), - ITEM_TRACKER_ITEM_CUSTOM(RG_KAK_POTION_SHOP_KEY, ITEM_KEY_SMALL, ITEM_KEY_SMALL, 0, DrawItem), - ITEM_TRACKER_ITEM_CUSTOM(RG_BOSS_HOUSE_KEY, ITEM_KEY_SMALL, ITEM_KEY_SMALL, 0, DrawItem), - ITEM_TRACKER_ITEM_CUSTOM(RG_GRANNYS_POTION_SHOP_KEY, ITEM_KEY_SMALL, ITEM_KEY_SMALL, 0, DrawItem), - ITEM_TRACKER_ITEM_CUSTOM(RG_SKULLTULA_HOUSE_KEY, ITEM_KEY_SMALL, ITEM_KEY_SMALL, 0, DrawItem), - ITEM_TRACKER_ITEM_CUSTOM(RG_IMPAS_HOUSE_KEY, ITEM_KEY_SMALL, ITEM_KEY_SMALL, 0, DrawItem), - ITEM_TRACKER_ITEM_CUSTOM(RG_WINDMILL_KEY, ITEM_KEY_SMALL, ITEM_KEY_SMALL, 0, DrawItem), - ITEM_TRACKER_ITEM_CUSTOM(RG_KAK_SHOOTING_GALLERY_KEY, ITEM_KEY_SMALL, ITEM_KEY_SMALL, 0, DrawItem), - ITEM_TRACKER_ITEM_CUSTOM(RG_DAMPES_HUT_KEY, ITEM_KEY_SMALL, ITEM_KEY_SMALL, 0, DrawItem), - ITEM_TRACKER_ITEM_CUSTOM(RG_TALONS_HOUSE_KEY, ITEM_KEY_SMALL, ITEM_KEY_SMALL, 0, DrawItem), - ITEM_TRACKER_ITEM_CUSTOM(RG_STABLES_KEY, ITEM_KEY_SMALL, ITEM_KEY_SMALL, 0, DrawItem), - ITEM_TRACKER_ITEM_CUSTOM(RG_BACK_TOWER_KEY, ITEM_KEY_SMALL, ITEM_KEY_SMALL, 0, DrawItem), - ITEM_TRACKER_ITEM_CUSTOM(RG_HYLIA_LAB_KEY, ITEM_KEY_SMALL, ITEM_KEY_SMALL, 0, DrawItem), - ITEM_TRACKER_ITEM_CUSTOM(RG_FISHING_HOLE_KEY, ITEM_KEY_SMALL, ITEM_KEY_SMALL, 0, DrawItem), + ITEM_TRACKER_ITEM_CUSTOM(RG_BOMBCHU_SHOP_KEY, ITEM_KEY_SMALL, ITEM_KEY_SMALL, 0, DrawItem), + ITEM_TRACKER_ITEM_CUSTOM(RG_RICHARDS_HOUSE_KEY, ITEM_KEY_SMALL, ITEM_KEY_SMALL, 0, DrawItem), + ITEM_TRACKER_ITEM_CUSTOM(RG_ALLEY_HOUSE_KEY, ITEM_KEY_SMALL, ITEM_KEY_SMALL, 0, DrawItem), + ITEM_TRACKER_ITEM_CUSTOM(RG_KAK_BAZAAR_KEY, ITEM_KEY_SMALL, ITEM_KEY_SMALL, 0, DrawItem), + ITEM_TRACKER_ITEM_CUSTOM(RG_KAK_POTION_SHOP_KEY, ITEM_KEY_SMALL, ITEM_KEY_SMALL, 0, DrawItem), + ITEM_TRACKER_ITEM_CUSTOM(RG_BOSS_HOUSE_KEY, ITEM_KEY_SMALL, ITEM_KEY_SMALL, 0, DrawItem), + ITEM_TRACKER_ITEM_CUSTOM(RG_GRANNYS_POTION_SHOP_KEY, ITEM_KEY_SMALL, ITEM_KEY_SMALL, 0, DrawItem), + ITEM_TRACKER_ITEM_CUSTOM(RG_SKULLTULA_HOUSE_KEY, ITEM_KEY_SMALL, ITEM_KEY_SMALL, 0, DrawItem), + ITEM_TRACKER_ITEM_CUSTOM(RG_IMPAS_HOUSE_KEY, ITEM_KEY_SMALL, ITEM_KEY_SMALL, 0, DrawItem), + ITEM_TRACKER_ITEM_CUSTOM(RG_WINDMILL_KEY, ITEM_KEY_SMALL, ITEM_KEY_SMALL, 0, DrawItem), + ITEM_TRACKER_ITEM_CUSTOM(RG_KAK_SHOOTING_GALLERY_KEY, ITEM_KEY_SMALL, ITEM_KEY_SMALL, 0, DrawItem), + ITEM_TRACKER_ITEM_CUSTOM(RG_DAMPES_HUT_KEY, ITEM_KEY_SMALL, ITEM_KEY_SMALL, 0, DrawItem), + ITEM_TRACKER_ITEM_CUSTOM(RG_TALONS_HOUSE_KEY, ITEM_KEY_SMALL, ITEM_KEY_SMALL, 0, DrawItem), + ITEM_TRACKER_ITEM_CUSTOM(RG_STABLES_KEY, ITEM_KEY_SMALL, ITEM_KEY_SMALL, 0, DrawItem), + ITEM_TRACKER_ITEM_CUSTOM(RG_BACK_TOWER_KEY, ITEM_KEY_SMALL, ITEM_KEY_SMALL, 0, DrawItem), + ITEM_TRACKER_ITEM_CUSTOM(RG_HYLIA_LAB_KEY, ITEM_KEY_SMALL, ITEM_KEY_SMALL, 0, DrawItem), + ITEM_TRACKER_ITEM_CUSTOM(RG_FISHING_HOLE_KEY, ITEM_KEY_SMALL, ITEM_KEY_SMALL, 0, DrawItem), }; -std::vector fishingPoleItems = { - ITEM_TRACKER_ITEM(ITEM_FISHING_POLE, 0, DrawItem) -}; +std::vector fishingPoleItems = { ITEM_TRACKER_ITEM(ITEM_FISHING_POLE, 0, DrawItem) }; std::vector itemTrackerDungeonsWithMapsHorizontal = { { SCENE_DEKU_TREE, { ITEM_DUNGEON_MAP, ITEM_COMPASS } }, @@ -173,7 +187,6 @@ std::vector itemTrackerDungeonsHorizontal = { { SCENE_GERUDO_TRAINING_GROUND, { ITEM_KEY_SMALL } }, }; - std::vector itemTrackerDungeonsWithMapsCompact = { { SCENE_FOREST_TEMPLE, { ITEM_KEY_SMALL, ITEM_KEY_BOSS, ITEM_DUNGEON_MAP, ITEM_COMPASS } }, { SCENE_FIRE_TEMPLE, { ITEM_KEY_SMALL, ITEM_KEY_BOSS, ITEM_DUNGEON_MAP, ITEM_COMPASS } }, @@ -202,39 +215,22 @@ std::vector itemTrackerDungeonsCompact = { }; std::map itemTrackerDungeonShortNames = { - { SCENE_FOREST_TEMPLE, "FRST" }, - { SCENE_FIRE_TEMPLE, "FIRE" }, - { SCENE_WATER_TEMPLE, "WATR" }, - { SCENE_SPIRIT_TEMPLE, "SPRT" }, - { SCENE_SHADOW_TEMPLE, "SHDW" }, - { SCENE_BOTTOM_OF_THE_WELL, "BOTW" }, - { SCENE_DEKU_TREE, "DEKU" }, - { SCENE_DODONGOS_CAVERN, "DCVN" }, - { SCENE_JABU_JABU, "JABU" }, - { SCENE_ICE_CAVERN, "ICE" }, - { SCENE_INSIDE_GANONS_CASTLE, "GANON" }, - { SCENE_GERUDO_TRAINING_GROUND, "GTG" }, + { SCENE_FOREST_TEMPLE, "FRST" }, { SCENE_FIRE_TEMPLE, "FIRE" }, { SCENE_WATER_TEMPLE, "WATR" }, + { SCENE_SPIRIT_TEMPLE, "SPRT" }, { SCENE_SHADOW_TEMPLE, "SHDW" }, { SCENE_BOTTOM_OF_THE_WELL, "BOTW" }, + { SCENE_DEKU_TREE, "DEKU" }, { SCENE_DODONGOS_CAVERN, "DCVN" }, { SCENE_JABU_JABU, "JABU" }, + { SCENE_ICE_CAVERN, "ICE" }, { SCENE_INSIDE_GANONS_CASTLE, "GANON" }, { SCENE_GERUDO_TRAINING_GROUND, "GTG" }, { SCENE_THIEVES_HIDEOUT, "HIDE" }, }; std::map itemTrackerBossShortNames = { - { RG_GOHMA_SOUL, "GOHMA" }, - { RG_KING_DODONGO_SOUL, "KD" }, - { RG_BARINADE_SOUL, "BARI" }, - { RG_PHANTOM_GANON_SOUL, "PG"}, - { RG_VOLVAGIA_SOUL, "VOLV"}, - { RG_MORPHA_SOUL, "MORPH"}, - { RG_BONGO_BONGO_SOUL, "BONGO"}, - { RG_TWINROVA_SOUL, "TWIN"}, - { RG_GANON_SOUL, "GANON"}, + { RG_GOHMA_SOUL, "GOHMA" }, { RG_KING_DODONGO_SOUL, "KD" }, { RG_BARINADE_SOUL, "BARI" }, + { RG_PHANTOM_GANON_SOUL, "PG" }, { RG_VOLVAGIA_SOUL, "VOLV" }, { RG_MORPHA_SOUL, "MORPH" }, + { RG_BONGO_BONGO_SOUL, "BONGO" }, { RG_TWINROVA_SOUL, "TWIN" }, { RG_GANON_SOUL, "GANON" }, }; std::map itemTrackerOcarinaButtonShortNames = { - { RG_OCARINA_A_BUTTON, "A" }, - { RG_OCARINA_C_UP_BUTTON, "C-U" }, - { RG_OCARINA_C_DOWN_BUTTON, "C-D" }, - { RG_OCARINA_C_LEFT_BUTTON, "C-L"}, - { RG_OCARINA_C_RIGHT_BUTTON, "C-R"}, + { RG_OCARINA_A_BUTTON, "A" }, { RG_OCARINA_C_UP_BUTTON, "C-U" }, { RG_OCARINA_C_DOWN_BUTTON, "C-D" }, + { RG_OCARINA_C_LEFT_BUTTON, "C-L" }, { RG_OCARINA_C_RIGHT_BUTTON, "C-R" }, }; std::map itemTrackerOverworldKeyShortNames = { @@ -267,88 +263,76 @@ std::map itemTrackerOverworldKeyShortNames = { std::vector dungeonItems = {}; std::unordered_map actualItemTrackerItemMap = { - { ITEM_BOTTLE, ITEM_TRACKER_ITEM(ITEM_BOTTLE, 0, DrawItem) }, - { ITEM_BIG_POE, ITEM_TRACKER_ITEM(ITEM_BIG_POE, 0, DrawItem) }, - { ITEM_BLUE_FIRE, ITEM_TRACKER_ITEM(ITEM_BLUE_FIRE, 0, DrawItem) }, - { ITEM_BUG, ITEM_TRACKER_ITEM(ITEM_BUG, 0, DrawItem) }, - { ITEM_FAIRY, ITEM_TRACKER_ITEM(ITEM_FAIRY, 0, DrawItem) }, - { ITEM_FISH, ITEM_TRACKER_ITEM(ITEM_FISH, 0, DrawItem) }, - { ITEM_POTION_GREEN, ITEM_TRACKER_ITEM(ITEM_POTION_GREEN, 0, DrawItem) }, - { ITEM_POE, ITEM_TRACKER_ITEM(ITEM_POE, 0, DrawItem) }, - { ITEM_POTION_RED, ITEM_TRACKER_ITEM(ITEM_POTION_RED, 0, DrawItem) }, - { ITEM_POTION_BLUE, ITEM_TRACKER_ITEM(ITEM_POTION_BLUE, 0, DrawItem) }, - { ITEM_MILK_BOTTLE, ITEM_TRACKER_ITEM(ITEM_MILK_BOTTLE, 0, DrawItem) }, - { ITEM_MILK_HALF, ITEM_TRACKER_ITEM(ITEM_MILK_HALF, 0, DrawItem) }, - { ITEM_LETTER_RUTO, ITEM_TRACKER_ITEM(ITEM_LETTER_RUTO, 0, DrawItem) }, + { ITEM_BOTTLE, ITEM_TRACKER_ITEM(ITEM_BOTTLE, 0, DrawItem) }, + { ITEM_BIG_POE, ITEM_TRACKER_ITEM(ITEM_BIG_POE, 0, DrawItem) }, + { ITEM_BLUE_FIRE, ITEM_TRACKER_ITEM(ITEM_BLUE_FIRE, 0, DrawItem) }, + { ITEM_BUG, ITEM_TRACKER_ITEM(ITEM_BUG, 0, DrawItem) }, + { ITEM_FAIRY, ITEM_TRACKER_ITEM(ITEM_FAIRY, 0, DrawItem) }, + { ITEM_FISH, ITEM_TRACKER_ITEM(ITEM_FISH, 0, DrawItem) }, + { ITEM_POTION_GREEN, ITEM_TRACKER_ITEM(ITEM_POTION_GREEN, 0, DrawItem) }, + { ITEM_POE, ITEM_TRACKER_ITEM(ITEM_POE, 0, DrawItem) }, + { ITEM_POTION_RED, ITEM_TRACKER_ITEM(ITEM_POTION_RED, 0, DrawItem) }, + { ITEM_POTION_BLUE, ITEM_TRACKER_ITEM(ITEM_POTION_BLUE, 0, DrawItem) }, + { ITEM_MILK_BOTTLE, ITEM_TRACKER_ITEM(ITEM_MILK_BOTTLE, 0, DrawItem) }, + { ITEM_MILK_HALF, ITEM_TRACKER_ITEM(ITEM_MILK_HALF, 0, DrawItem) }, + { ITEM_LETTER_RUTO, ITEM_TRACKER_ITEM(ITEM_LETTER_RUTO, 0, DrawItem) }, - { ITEM_HOOKSHOT, ITEM_TRACKER_ITEM(ITEM_HOOKSHOT, 0, DrawItem) }, - { ITEM_LONGSHOT, ITEM_TRACKER_ITEM(ITEM_LONGSHOT, 0, DrawItem) }, + { ITEM_HOOKSHOT, ITEM_TRACKER_ITEM(ITEM_HOOKSHOT, 0, DrawItem) }, + { ITEM_LONGSHOT, ITEM_TRACKER_ITEM(ITEM_LONGSHOT, 0, DrawItem) }, - { ITEM_OCARINA_FAIRY, ITEM_TRACKER_ITEM(ITEM_OCARINA_FAIRY, 0, DrawItem) }, - { ITEM_OCARINA_TIME, ITEM_TRACKER_ITEM(ITEM_OCARINA_TIME, 0, DrawItem) }, + { ITEM_OCARINA_FAIRY, ITEM_TRACKER_ITEM(ITEM_OCARINA_FAIRY, 0, DrawItem) }, + { ITEM_OCARINA_TIME, ITEM_TRACKER_ITEM(ITEM_OCARINA_TIME, 0, DrawItem) }, - { ITEM_MAGIC_SMALL, ITEM_TRACKER_ITEM(ITEM_MAGIC_SMALL, 0, DrawItem) }, - { ITEM_MAGIC_LARGE, ITEM_TRACKER_ITEM(ITEM_MAGIC_LARGE, 0, DrawItem) }, + { ITEM_MAGIC_SMALL, ITEM_TRACKER_ITEM(ITEM_MAGIC_SMALL, 0, DrawItem) }, + { ITEM_MAGIC_LARGE, ITEM_TRACKER_ITEM(ITEM_MAGIC_LARGE, 0, DrawItem) }, - { ITEM_WALLET_ADULT, ITEM_TRACKER_ITEM(ITEM_WALLET_ADULT, 0, DrawItem) }, - { ITEM_WALLET_GIANT, ITEM_TRACKER_ITEM(ITEM_WALLET_GIANT, 0, DrawItem) }, + { ITEM_WALLET_ADULT, ITEM_TRACKER_ITEM(ITEM_WALLET_ADULT, 0, DrawItem) }, + { ITEM_WALLET_GIANT, ITEM_TRACKER_ITEM(ITEM_WALLET_GIANT, 0, DrawItem) }, - { ITEM_BRACELET, ITEM_TRACKER_ITEM(ITEM_BRACELET, 0, DrawItem) }, + { ITEM_BRACELET, ITEM_TRACKER_ITEM(ITEM_BRACELET, 0, DrawItem) }, { ITEM_GAUNTLETS_SILVER, ITEM_TRACKER_ITEM(ITEM_GAUNTLETS_SILVER, 0, DrawItem) }, - { ITEM_GAUNTLETS_GOLD, ITEM_TRACKER_ITEM(ITEM_GAUNTLETS_GOLD, 0, DrawItem) }, + { ITEM_GAUNTLETS_GOLD, ITEM_TRACKER_ITEM(ITEM_GAUNTLETS_GOLD, 0, DrawItem) }, - { ITEM_SCALE_SILVER, ITEM_TRACKER_ITEM(ITEM_SCALE_SILVER, 0, DrawItem) }, - { ITEM_SCALE_GOLDEN, ITEM_TRACKER_ITEM(ITEM_SCALE_GOLDEN, 0, DrawItem) }, + { ITEM_SCALE_SILVER, ITEM_TRACKER_ITEM(ITEM_SCALE_SILVER, 0, DrawItem) }, + { ITEM_SCALE_GOLDEN, ITEM_TRACKER_ITEM(ITEM_SCALE_GOLDEN, 0, DrawItem) }, - { ITEM_WEIRD_EGG, ITEM_TRACKER_ITEM(ITEM_WEIRD_EGG, 0, DrawItem) }, - { ITEM_CHICKEN, ITEM_TRACKER_ITEM(ITEM_CHICKEN, 0, DrawItem) }, - { ITEM_LETTER_ZELDA, ITEM_TRACKER_ITEM(ITEM_LETTER_ZELDA, 0, DrawItem) }, - { ITEM_MASK_KEATON, ITEM_TRACKER_ITEM(ITEM_MASK_KEATON, 0, DrawItem) }, - { ITEM_MASK_SKULL, ITEM_TRACKER_ITEM(ITEM_MASK_SKULL, 0, DrawItem) }, - { ITEM_MASK_SPOOKY, ITEM_TRACKER_ITEM(ITEM_MASK_SPOOKY, 0, DrawItem) }, - { ITEM_MASK_BUNNY, ITEM_TRACKER_ITEM(ITEM_MASK_BUNNY, 0, DrawItem) }, - { ITEM_MASK_GORON, ITEM_TRACKER_ITEM(ITEM_MASK_GORON, 0, DrawItem) }, - { ITEM_MASK_ZORA, ITEM_TRACKER_ITEM(ITEM_MASK_ZORA, 0, DrawItem) }, - { ITEM_MASK_GERUDO, ITEM_TRACKER_ITEM(ITEM_MASK_GERUDO, 0, DrawItem) }, - { ITEM_MASK_TRUTH, ITEM_TRACKER_ITEM(ITEM_MASK_TRUTH, 0, DrawItem) }, - { ITEM_SOLD_OUT, ITEM_TRACKER_ITEM(ITEM_SOLD_OUT, 0, DrawItem) }, + { ITEM_WEIRD_EGG, ITEM_TRACKER_ITEM(ITEM_WEIRD_EGG, 0, DrawItem) }, + { ITEM_CHICKEN, ITEM_TRACKER_ITEM(ITEM_CHICKEN, 0, DrawItem) }, + { ITEM_LETTER_ZELDA, ITEM_TRACKER_ITEM(ITEM_LETTER_ZELDA, 0, DrawItem) }, + { ITEM_MASK_KEATON, ITEM_TRACKER_ITEM(ITEM_MASK_KEATON, 0, DrawItem) }, + { ITEM_MASK_SKULL, ITEM_TRACKER_ITEM(ITEM_MASK_SKULL, 0, DrawItem) }, + { ITEM_MASK_SPOOKY, ITEM_TRACKER_ITEM(ITEM_MASK_SPOOKY, 0, DrawItem) }, + { ITEM_MASK_BUNNY, ITEM_TRACKER_ITEM(ITEM_MASK_BUNNY, 0, DrawItem) }, + { ITEM_MASK_GORON, ITEM_TRACKER_ITEM(ITEM_MASK_GORON, 0, DrawItem) }, + { ITEM_MASK_ZORA, ITEM_TRACKER_ITEM(ITEM_MASK_ZORA, 0, DrawItem) }, + { ITEM_MASK_GERUDO, ITEM_TRACKER_ITEM(ITEM_MASK_GERUDO, 0, DrawItem) }, + { ITEM_MASK_TRUTH, ITEM_TRACKER_ITEM(ITEM_MASK_TRUTH, 0, DrawItem) }, + { ITEM_SOLD_OUT, ITEM_TRACKER_ITEM(ITEM_SOLD_OUT, 0, DrawItem) }, - { ITEM_POCKET_EGG, ITEM_TRACKER_ITEM(ITEM_POCKET_EGG, 0, DrawItem) }, - { ITEM_POCKET_CUCCO, ITEM_TRACKER_ITEM(ITEM_POCKET_CUCCO, 0, DrawItem) }, - { ITEM_COJIRO, ITEM_TRACKER_ITEM(ITEM_COJIRO, 0, DrawItem) }, - { ITEM_ODD_MUSHROOM, ITEM_TRACKER_ITEM(ITEM_ODD_MUSHROOM, 0, DrawItem) }, - { ITEM_ODD_POTION, ITEM_TRACKER_ITEM(ITEM_ODD_POTION, 0, DrawItem) }, - { ITEM_SAW, ITEM_TRACKER_ITEM(ITEM_SAW, 0, DrawItem) }, - { ITEM_SWORD_BROKEN, ITEM_TRACKER_ITEM(ITEM_SWORD_BROKEN, 0, DrawItem) }, - { ITEM_PRESCRIPTION, ITEM_TRACKER_ITEM(ITEM_PRESCRIPTION, 0, DrawItem) }, - { ITEM_FROG, ITEM_TRACKER_ITEM(ITEM_FROG, 0, DrawItem) }, - { ITEM_EYEDROPS, ITEM_TRACKER_ITEM(ITEM_EYEDROPS, 0, DrawItem) }, - { ITEM_CLAIM_CHECK, ITEM_TRACKER_ITEM(ITEM_CLAIM_CHECK, 0, DrawItem) }, + { ITEM_POCKET_EGG, ITEM_TRACKER_ITEM(ITEM_POCKET_EGG, 0, DrawItem) }, + { ITEM_POCKET_CUCCO, ITEM_TRACKER_ITEM(ITEM_POCKET_CUCCO, 0, DrawItem) }, + { ITEM_COJIRO, ITEM_TRACKER_ITEM(ITEM_COJIRO, 0, DrawItem) }, + { ITEM_ODD_MUSHROOM, ITEM_TRACKER_ITEM(ITEM_ODD_MUSHROOM, 0, DrawItem) }, + { ITEM_ODD_POTION, ITEM_TRACKER_ITEM(ITEM_ODD_POTION, 0, DrawItem) }, + { ITEM_SAW, ITEM_TRACKER_ITEM(ITEM_SAW, 0, DrawItem) }, + { ITEM_SWORD_BROKEN, ITEM_TRACKER_ITEM(ITEM_SWORD_BROKEN, 0, DrawItem) }, + { ITEM_PRESCRIPTION, ITEM_TRACKER_ITEM(ITEM_PRESCRIPTION, 0, DrawItem) }, + { ITEM_FROG, ITEM_TRACKER_ITEM(ITEM_FROG, 0, DrawItem) }, + { ITEM_EYEDROPS, ITEM_TRACKER_ITEM(ITEM_EYEDROPS, 0, DrawItem) }, + { ITEM_CLAIM_CHECK, ITEM_TRACKER_ITEM(ITEM_CLAIM_CHECK, 0, DrawItem) }, }; std::vector buttonMap = { - BTN_A, - BTN_B, - BTN_CUP, - BTN_CDOWN, - BTN_CLEFT, - BTN_CRIGHT, - BTN_L, - BTN_Z, - BTN_R, - BTN_START, - BTN_DUP, - BTN_DDOWN, - BTN_DLEFT, - BTN_DRIGHT, + BTN_A, BTN_B, BTN_CUP, BTN_CDOWN, BTN_CLEFT, BTN_CRIGHT, BTN_L, + BTN_Z, BTN_R, BTN_START, BTN_DUP, BTN_DDOWN, BTN_DLEFT, BTN_DRIGHT, }; typedef enum { - ITEM_TRACKER_NUMBER_NONE, - ITEM_TRACKER_NUMBER_CURRENT_CAPACITY_ONLY, - ITEM_TRACKER_NUMBER_CURRENT_AMMO_ONLY, - ITEM_TRACKER_NUMBER_CAPACITY, - ITEM_TRACKER_NUMBER_AMMO, + ITEM_TRACKER_NUMBER_NONE, + ITEM_TRACKER_NUMBER_CURRENT_CAPACITY_ONLY, + ITEM_TRACKER_NUMBER_CURRENT_AMMO_ONLY, + ITEM_TRACKER_NUMBER_CAPACITY, + ITEM_TRACKER_NUMBER_AMMO, } ItemTrackerNumberOption; typedef enum { @@ -381,9 +365,9 @@ typedef enum { } ItemTrackerMinimalDisplayType; struct ItemTrackerNumbers { - int currentCapacity; - int maxCapacity; - int currentAmmo; + int currentCapacity; + int maxCapacity; + int currentAmmo; }; static ImVector itemTrackerNotes; @@ -448,8 +432,10 @@ ItemTrackerNumbers GetItemCurrentAndMax(ItemTrackerItem item) { break; case ITEM_WALLET_ADULT: case ITEM_WALLET_GIANT: - result.currentCapacity = IS_RANDO && !Flags_GetRandomizerInf(RAND_INF_HAS_WALLET) ? 0 : CUR_CAPACITY(UPG_WALLET); - result.maxCapacity = OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_INCLUDE_TYCOON_WALLET) ? 999 : 500; + result.currentCapacity = + IS_RANDO && !Flags_GetRandomizerInf(RAND_INF_HAS_WALLET) ? 0 : CUR_CAPACITY(UPG_WALLET); + result.maxCapacity = + OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_INCLUDE_TYCOON_WALLET) ? 999 : 500; result.currentAmmo = gSaveContext.rupees; break; case ITEM_BOMBCHU: @@ -529,7 +515,8 @@ void DrawItemCount(ItemTrackerItem item, bool hideMax) { int textSize = CVarGetInteger(CVAR_TRACKER_ITEM("TextSize"), 13); ItemTrackerNumbers currentAndMax = GetItemCurrentAndMax(item); ImVec2 p = ImGui::GetCursorScreenPos(); - int32_t trackerNumberDisplayMode = CVarGetInteger(CVAR_TRACKER_ITEM("ItemCountType"), ITEM_TRACKER_NUMBER_CURRENT_CAPACITY_ONLY); + int32_t trackerNumberDisplayMode = + CVarGetInteger(CVAR_TRACKER_ITEM("ItemCountType"), ITEM_TRACKER_NUMBER_CURRENT_CAPACITY_ONLY); int32_t trackerKeyNumberDisplayMode = CVarGetInteger(CVAR_TRACKER_ITEM("KeyCounts"), KEYS_COLLECTED_MAX); float textScalingFactor = static_cast(iconSize) / 36.0f; uint32_t actualItemId = INV_CONTENT(item.id); @@ -539,8 +526,11 @@ void DrawItemCount(ItemTrackerItem item, bool hideMax) { if ((actualItemId == ITEM_HOOKSHOT || actualItemId == ITEM_LONGSHOT) && hasItem) { // Calculate the scaled position for the text - ImVec2 textPos = ImVec2(p.x + (iconSize / 2) - (ImGui::CalcTextSize(item.id == ITEM_HOOKSHOT ? "H" : "L").x * - textScalingFactor / 2) + 8 * textScalingFactor, p.y - 22 * textScalingFactor); + ImVec2 textPos = + ImVec2(p.x + (iconSize / 2) - + (ImGui::CalcTextSize(item.id == ITEM_HOOKSHOT ? "H" : "L").x * textScalingFactor / 2) + + 8 * textScalingFactor, + p.y - 22 * textScalingFactor); ImGui::SetCursorScreenPos(textPos); ImGui::SetWindowFontScale(textScalingFactor); @@ -558,16 +548,19 @@ void DrawItemCount(ItemTrackerItem item, bool hideMax) { ImU32 currentColor = IM_COL_WHITE; ImU32 maxColor = IM_COL_GREEN; // "Collected / Max", "Current / Collected / Max", "Current / Max" - if (trackerKeyNumberDisplayMode == KEYS_CURRENT_COLLECTED_MAX || trackerKeyNumberDisplayMode == KEYS_CURRENT_MAX) { - currentString+= std::to_string(currentAndMax.currentAmmo); - currentString+= "/"; + if (trackerKeyNumberDisplayMode == KEYS_CURRENT_COLLECTED_MAX || + trackerKeyNumberDisplayMode == KEYS_CURRENT_MAX) { + currentString += std::to_string(currentAndMax.currentAmmo); + currentString += "/"; } - if (trackerKeyNumberDisplayMode == KEYS_COLLECTED_MAX || trackerKeyNumberDisplayMode == KEYS_CURRENT_COLLECTED_MAX) { - currentString+= std::to_string(currentAndMax.currentCapacity); - currentString+= "/"; + if (trackerKeyNumberDisplayMode == KEYS_COLLECTED_MAX || + trackerKeyNumberDisplayMode == KEYS_CURRENT_COLLECTED_MAX) { + currentString += std::to_string(currentAndMax.currentCapacity); + currentString += "/"; } - ImGui::SetCursorScreenPos(ImVec2(p.x + (iconSize / 2) - (ImGui::CalcTextSize((currentString + maxString).c_str()).x / 2), p.y - 14)); + ImGui::SetCursorScreenPos( + ImVec2(p.x + (iconSize / 2) - (ImGui::CalcTextSize((currentString + maxString).c_str()).x / 2), p.y - 14)); ImGui::PushStyleColor(ImGuiCol_Text, currentColor); ImGui::Text("%s", currentString.c_str()); ImGui::PopStyleColor(); @@ -575,26 +568,25 @@ void DrawItemCount(ItemTrackerItem item, bool hideMax) { ImGui::PushStyleColor(ImGuiCol_Text, maxColor); ImGui::Text("%s", maxString.c_str()); ImGui::PopStyleColor(); - } else if (currentAndMax.currentCapacity > 0 && trackerNumberDisplayMode != ITEM_TRACKER_NUMBER_NONE && IsValidSaveFile()) { + } else if (currentAndMax.currentCapacity > 0 && trackerNumberDisplayMode != ITEM_TRACKER_NUMBER_NONE && + IsValidSaveFile()) { std::string currentString = ""; std::string maxString = ""; ImU32 currentColor = IM_COL_WHITE; ImU32 maxColor = item.id == QUEST_SKULL_TOKEN ? IM_COL_RED : IM_COL_GREEN; bool shouldAlignToLeft = CVarGetInteger(CVAR_TRACKER_ITEM("ItemCountAlignLeft"), 0) && - trackerNumberDisplayMode != ITEM_TRACKER_NUMBER_CAPACITY && - trackerNumberDisplayMode != ITEM_TRACKER_NUMBER_AMMO; + trackerNumberDisplayMode != ITEM_TRACKER_NUMBER_CAPACITY && + trackerNumberDisplayMode != ITEM_TRACKER_NUMBER_AMMO; bool shouldDisplayAmmo = trackerNumberDisplayMode == ITEM_TRACKER_NUMBER_AMMO || - trackerNumberDisplayMode == ITEM_TRACKER_NUMBER_CURRENT_AMMO_ONLY || - // These items have a static capacity, so display ammo instead - item.id == ITEM_BOMBCHU || - item.id == ITEM_BEAN || - item.id == QUEST_SKULL_TOKEN || - item.id == ITEM_HEART_CONTAINER || - item.id == ITEM_HEART_PIECE; + trackerNumberDisplayMode == ITEM_TRACKER_NUMBER_CURRENT_AMMO_ONLY || + // These items have a static capacity, so display ammo instead + item.id == ITEM_BOMBCHU || item.id == ITEM_BEAN || item.id == QUEST_SKULL_TOKEN || + item.id == ITEM_HEART_CONTAINER || item.id == ITEM_HEART_PIECE; - bool shouldDisplayMax = !(trackerNumberDisplayMode == ITEM_TRACKER_NUMBER_CURRENT_CAPACITY_ONLY || trackerNumberDisplayMode == ITEM_TRACKER_NUMBER_CURRENT_AMMO_ONLY); + bool shouldDisplayMax = !(trackerNumberDisplayMode == ITEM_TRACKER_NUMBER_CURRENT_CAPACITY_ONLY || + trackerNumberDisplayMode == ITEM_TRACKER_NUMBER_CURRENT_AMMO_ONLY); if (shouldDisplayAmmo) { currentString = std::to_string(currentAndMax.currentAmmo); @@ -622,7 +614,9 @@ void DrawItemCount(ItemTrackerItem item, bool hideMax) { } } - float x = shouldAlignToLeft ? p.x : p.x + (iconSize / 2) - (ImGui::CalcTextSize((currentString + maxString).c_str()).x / 2); + float x = shouldAlignToLeft + ? p.x + : p.x + (iconSize / 2) - (ImGui::CalcTextSize((currentString + maxString).c_str()).x / 2); ImGui::SetCursorScreenPos(ImVec2(x, p.y - 14)); ImGui::PushStyleColor(ImGuiCol_Text, currentColor); @@ -637,11 +631,16 @@ void DrawItemCount(ItemTrackerItem item, bool hideMax) { std::string currentString = ""; std::string requiredString = ""; std::string maxString = ""; - uint8_t piecesRequired = (OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_TRIFORCE_HUNT_PIECES_REQUIRED) + 1); - uint8_t piecesTotal = (OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_TRIFORCE_HUNT_PIECES_TOTAL) + 1); - ImU32 currentColor = gSaveContext.ship.quest.data.randomizer.triforcePiecesCollected >= piecesRequired ? IM_COL_GREEN : IM_COL_WHITE; + uint8_t piecesRequired = + (OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_TRIFORCE_HUNT_PIECES_REQUIRED) + 1); + uint8_t piecesTotal = + (OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_TRIFORCE_HUNT_PIECES_TOTAL) + 1); + ImU32 currentColor = gSaveContext.ship.quest.data.randomizer.triforcePiecesCollected >= piecesRequired + ? IM_COL_GREEN + : IM_COL_WHITE; ImU32 maxColor = IM_COL_GREEN; - int32_t trackerTriforcePieceNumberDisplayMode = CVarGetInteger(CVAR_TRACKER_ITEM("TriforcePieceCounts"), TRIFORCE_PIECE_COLLECTED_REQUIRED_MAX); + int32_t trackerTriforcePieceNumberDisplayMode = + CVarGetInteger(CVAR_TRACKER_ITEM("TriforcePieceCounts"), TRIFORCE_PIECE_COLLECTED_REQUIRED_MAX); currentString += std::to_string(gSaveContext.ship.quest.data.randomizer.triforcePiecesCollected); currentString += "/"; @@ -672,7 +671,8 @@ void DrawItemCount(ItemTrackerItem item, bool hideMax) { void DrawEquip(ItemTrackerItem item) { bool hasEquip = HasEquipment(item); int iconSize = CVarGetInteger(CVAR_TRACKER_ITEM("IconSize"), 36); - ImGui::Image(Ship::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName(hasEquip && IsValidSaveFile() ? item.name : item.nameFaded), + ImGui::Image(Ship::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName( + hasEquip && IsValidSaveFile() ? item.name : item.nameFaded), ImVec2(iconSize, iconSize), ImVec2(0, 0), ImVec2(1, 1)); Tooltip(SohUtils::GetItemName(item.id).c_str()); @@ -682,7 +682,8 @@ void DrawQuest(ItemTrackerItem item) { bool hasQuestItem = HasQuestItem(item); int iconSize = CVarGetInteger(CVAR_TRACKER_ITEM("IconSize"), 36); ImGui::BeginGroup(); - ImGui::Image(Ship::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName(hasQuestItem && IsValidSaveFile() ? item.name : item.nameFaded), + ImGui::Image(Ship::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName( + hasQuestItem && IsValidSaveFile() ? item.name : item.nameFaded), ImVec2(iconSize, iconSize), ImVec2(0, 0), ImVec2(1, 1)); if (item.id == QUEST_SKULL_TOKEN) { @@ -729,7 +730,9 @@ void DrawItem(ItemTrackerItem item) { case ITEM_BRACELET: case ITEM_GAUNTLETS_SILVER: case ITEM_GAUNTLETS_GOLD: - actualItemId = CUR_UPG_VALUE(UPG_STRENGTH) == 3 ? ITEM_GAUNTLETS_GOLD : CUR_UPG_VALUE(UPG_STRENGTH) == 2 ? ITEM_GAUNTLETS_SILVER : ITEM_BRACELET; + actualItemId = CUR_UPG_VALUE(UPG_STRENGTH) == 3 ? ITEM_GAUNTLETS_GOLD + : CUR_UPG_VALUE(UPG_STRENGTH) == 2 ? ITEM_GAUNTLETS_SILVER + : ITEM_BRACELET; hasItem = CUR_UPG_VALUE(UPG_STRENGTH) > 0; break; case ITEM_SCALE_SILVER: @@ -788,8 +791,10 @@ void DrawItem(ItemTrackerItem item) { break; case RG_GANON_SOUL: actualItemId = item.id; - hasItem = OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_SHUFFLE_BOSS_SOULS) == RO_BOSS_SOULS_ON_PLUS_GANON ? - Flags_GetRandomizerInf(RAND_INF_GANON_SOUL) : true; + hasItem = OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_SHUFFLE_BOSS_SOULS) == + RO_BOSS_SOULS_ON_PLUS_GANON + ? Flags_GetRandomizerInf(RAND_INF_GANON_SOUL) + : true; itemName = "Ganon's Soul"; break; @@ -946,21 +951,25 @@ void DrawItem(ItemTrackerItem item) { break; } - if (GameInteractor::IsSaveLoaded() && (hasItem && item.id != actualItemId && actualItemTrackerItemMap.find(actualItemId) != actualItemTrackerItemMap.end())) { + if (GameInteractor::IsSaveLoaded() && + (hasItem && item.id != actualItemId && + actualItemTrackerItemMap.find(actualItemId) != actualItemTrackerItemMap.end())) { item = actualItemTrackerItemMap[actualItemId]; } - + ImGui::BeginGroup(); - ImGui::Image(Ship::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName(hasItem && IsValidSaveFile() ? item.name : item.nameFaded), + ImGui::Image(Ship::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName( + hasItem && IsValidSaveFile() ? item.name : item.nameFaded), ImVec2(iconSize, iconSize), ImVec2(0, 0), ImVec2(1, 1)); - + DrawItemCount(item, false); if (item.id >= RG_GOHMA_SOUL && item.id <= RG_GANON_SOUL) { ImVec2 p = ImGui::GetCursorScreenPos(); std::string bossName = itemTrackerBossShortNames[item.id]; - ImGui::SetCursorScreenPos(ImVec2(p.x + (iconSize / 2) - (ImGui::CalcTextSize(bossName.c_str()).x / 2), p.y - (iconSize + 13))); + ImGui::SetCursorScreenPos( + ImVec2(p.x + (iconSize / 2) - (ImGui::CalcTextSize(bossName.c_str()).x / 2), p.y - (iconSize + 13))); ImGui::PushStyleColor(ImGuiCol_Text, IM_COL_WHITE); ImGui::Text("%s", bossName.c_str()); ImGui::PopStyleColor(); @@ -969,7 +978,8 @@ void DrawItem(ItemTrackerItem item) { if (item.id >= RG_OCARINA_A_BUTTON && item.id <= RG_OCARINA_C_RIGHT_BUTTON) { ImVec2 p = ImGui::GetCursorScreenPos(); std::string ocarinaButtonName = itemTrackerOcarinaButtonShortNames[item.id]; - ImGui::SetCursorScreenPos(ImVec2(p.x + (iconSize / 2) - (ImGui::CalcTextSize(ocarinaButtonName.c_str()).x / 2), p.y - (iconSize + 13))); + ImGui::SetCursorScreenPos(ImVec2(p.x + (iconSize / 2) - (ImGui::CalcTextSize(ocarinaButtonName.c_str()).x / 2), + p.y - (iconSize + 13))); ImGui::PushStyleColor(ImGuiCol_Text, IM_COL_WHITE); ImGui::Text("%s", ocarinaButtonName.c_str()); ImGui::PopStyleColor(); @@ -978,7 +988,8 @@ void DrawItem(ItemTrackerItem item) { if (item.id >= RG_GUARD_HOUSE_KEY && item.id <= RG_FISHING_HOLE_KEY) { ImVec2 p = ImGui::GetCursorScreenPos(); std::string overworldKeyName = itemTrackerOverworldKeyShortNames[item.id]; - ImGui::SetCursorScreenPos(ImVec2(p.x + (iconSize / 2) - (ImGui::CalcTextSize(overworldKeyName.c_str()).x / 2), p.y - (iconSize + 13))); + ImGui::SetCursorScreenPos(ImVec2(p.x + (iconSize / 2) - (ImGui::CalcTextSize(overworldKeyName.c_str()).x / 2), + p.y - (iconSize + 13))); ImGui::PushStyleColor(ImGuiCol_Text, IM_COL_WHITE); ImGui::Text("%s", overworldKeyName.c_str()); ImGui::PopStyleColor(); @@ -994,15 +1005,19 @@ void DrawItem(ItemTrackerItem item) { } void DrawBottle(ItemTrackerItem item) { - uint32_t actualItemId = GameInteractor::IsSaveLoaded() ? (gSaveContext.inventory.items[SLOT(item.id) + item.data]) : false; + uint32_t actualItemId = + GameInteractor::IsSaveLoaded() ? (gSaveContext.inventory.items[SLOT(item.id) + item.data]) : false; bool hasItem = actualItemId != ITEM_NONE; - if (GameInteractor::IsSaveLoaded() && (hasItem && item.id != actualItemId && actualItemTrackerItemMap.find(actualItemId) != actualItemTrackerItemMap.end())) { + if (GameInteractor::IsSaveLoaded() && + (hasItem && item.id != actualItemId && + actualItemTrackerItemMap.find(actualItemId) != actualItemTrackerItemMap.end())) { item = actualItemTrackerItemMap[actualItemId]; } int iconSize = CVarGetInteger(CVAR_TRACKER_ITEM("IconSize"), 36); - ImGui::Image(Ship::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName(hasItem && IsValidSaveFile() ? item.name : item.nameFaded), + ImGui::Image(Ship::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName( + hasItem && IsValidSaveFile() ? item.name : item.nameFaded), ImVec2(iconSize, iconSize), ImVec2(0, 0), ImVec2(1, 1)); Tooltip(SohUtils::GetItemName(item.id).c_str()); @@ -1014,40 +1029,45 @@ void DrawDungeonItem(ItemTrackerItem item) { uint32_t bitMask = 1 << (item.id - ITEM_KEY_BOSS); // Bitset starts at ITEM_KEY_BOSS == 0. the rest are sequential int iconSize = CVarGetInteger(CVAR_TRACKER_ITEM("IconSize"), 36); bool hasItem = GameInteractor::IsSaveLoaded() ? (bitMask & gSaveContext.inventory.dungeonItems[item.data]) : false; - bool hasSmallKey = GameInteractor::IsSaveLoaded() ? ((gSaveContext.inventory.dungeonKeys[item.data]) >= 0) : false; + bool hasSmallKey = GameInteractor::IsSaveLoaded() ? ((gSaveContext.inventory.dungeonKeys[item.data]) >= 0) : false; ImGui::BeginGroup(); if (itemId == ITEM_KEY_SMALL) { - ImGui::Image(Ship::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName(hasSmallKey && IsValidSaveFile() ? item.name : item.nameFaded), + ImGui::Image(Ship::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName( + hasSmallKey && IsValidSaveFile() ? item.name : item.nameFaded), ImVec2(iconSize, iconSize), ImVec2(0, 0), ImVec2(1, 1)); - } - else { - ImGui::Image(Ship::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName(hasItem && IsValidSaveFile() ? item.name : item.nameFaded), + } else { + ImGui::Image(Ship::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName( + hasItem && IsValidSaveFile() ? item.name : item.nameFaded), ImVec2(iconSize, iconSize), ImVec2(0, 0), ImVec2(1, 1)); } - if (CheckTracker::IsAreaSpoiled(RandomizerCheckObjects::GetRCAreaBySceneID(static_cast(item.data))) && GameInteractor::IsSaveLoaded()) { + if (CheckTracker::IsAreaSpoiled(RandomizerCheckObjects::GetRCAreaBySceneID(static_cast(item.data))) && + GameInteractor::IsSaveLoaded()) { dungeonColor = (ResourceMgr_IsSceneMasterQuest(item.data) ? IM_COL_PURPLE : IM_COL_LIGHT_YELLOW); } if (itemId == ITEM_KEY_SMALL) { - DrawItemCount(item, !CheckTracker::IsAreaSpoiled(RandomizerCheckObjects::GetRCAreaBySceneID(static_cast(item.data)))); + DrawItemCount(item, !CheckTracker::IsAreaSpoiled( + RandomizerCheckObjects::GetRCAreaBySceneID(static_cast(item.data)))); ImVec2 p = ImGui::GetCursorScreenPos(); - // offset puts the text at the correct level. for some reason, if the save is loaded, the margin is 3 pixels higher only for small keys, so we use 16 then. Otherwise, 13 is where everything else is + // offset puts the text at the correct level. for some reason, if the save is loaded, the margin is 3 pixels + // higher only for small keys, so we use 16 then. Otherwise, 13 is where everything else is int offset = GameInteractor::IsSaveLoaded() ? 16 : 13; std::string dungeonName = itemTrackerDungeonShortNames[item.data]; - ImGui::SetCursorScreenPos(ImVec2(p.x + (iconSize / 2) - (ImGui::CalcTextSize(dungeonName.c_str()).x / 2), p.y - (iconSize + offset))); + ImGui::SetCursorScreenPos( + ImVec2(p.x + (iconSize / 2) - (ImGui::CalcTextSize(dungeonName.c_str()).x / 2), p.y - (iconSize + offset))); ImGui::PushStyleColor(ImGuiCol_Text, dungeonColor); ImGui::Text("%s", dungeonName.c_str()); ImGui::PopStyleColor(); } - if (itemId == ITEM_DUNGEON_MAP && - (item.data == SCENE_DEKU_TREE || item.data == SCENE_DODONGOS_CAVERN || item.data == SCENE_JABU_JABU || item.data == SCENE_ICE_CAVERN) - ) { + if (itemId == ITEM_DUNGEON_MAP && (item.data == SCENE_DEKU_TREE || item.data == SCENE_DODONGOS_CAVERN || + item.data == SCENE_JABU_JABU || item.data == SCENE_ICE_CAVERN)) { ImVec2 p = ImGui::GetCursorScreenPos(); std::string dungeonName = itemTrackerDungeonShortNames[item.data]; - ImGui::SetCursorScreenPos(ImVec2(p.x + (iconSize / 2) - (ImGui::CalcTextSize(dungeonName.c_str()).x / 2), p.y - (iconSize + 13))); + ImGui::SetCursorScreenPos( + ImVec2(p.x + (iconSize / 2) - (ImGui::CalcTextSize(dungeonName.c_str()).x / 2), p.y - (iconSize + 13))); ImGui::PushStyleColor(ImGuiCol_Text, dungeonColor); ImGui::Text("%s", dungeonName.c_str()); ImGui::PopStyleColor(); @@ -1062,7 +1082,8 @@ void DrawSong(ItemTrackerItem item) { ImVec2 p = ImGui::GetCursorScreenPos(); bool hasSong = HasSong(item); ImGui::SetCursorScreenPos(ImVec2(p.x + 6, p.y)); - ImGui::Image(Ship::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName(hasSong && IsValidSaveFile() ? item.name : item.nameFaded), + ImGui::Image(Ship::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName( + hasSong && IsValidSaveFile() ? item.name : item.nameFaded), ImVec2(iconSize / 1.5, iconSize), ImVec2(0, 0), ImVec2(1, 1)); Tooltip(SohUtils::GetQuestItemName(item.id).c_str()); } @@ -1083,22 +1104,24 @@ void DrawNotes(bool resizeable = false) { } return 0; } - static bool TrackerNotesInputTextMultiline(const char* label, ImVector* itemTrackerNotes, const ImVec2& size = ImVec2(0, 0), - ImGuiInputTextFlags flags = 0) { + static bool TrackerNotesInputTextMultiline(const char* label, ImVector* itemTrackerNotes, + const ImVec2& size = ImVec2(0, 0), ImGuiInputTextFlags flags = 0) { IM_ASSERT((flags & ImGuiInputTextFlags_CallbackResize) == 0); - return ImGui::InputTextMultiline(label, itemTrackerNotes->begin(), (size_t)itemTrackerNotes->size(), - size, flags | ImGuiInputTextFlags_CallbackResize, - ItemTrackerNotes::TrackerNotesResizeCallback, - (void*)itemTrackerNotes); + return ImGui::InputTextMultiline(label, itemTrackerNotes->begin(), (size_t)itemTrackerNotes->size(), size, + flags | ImGuiInputTextFlags_CallbackResize, + ItemTrackerNotes::TrackerNotesResizeCallback, (void*)itemTrackerNotes); } }; - ImVec2 size = resizeable ? ImVec2(-FLT_MIN, ImGui::GetContentRegionAvail().y) : ImVec2(((iconSize + iconSpacing) * 6) - 8, 200); + ImVec2 size = resizeable ? ImVec2(-FLT_MIN, ImGui::GetContentRegionAvail().y) + : ImVec2(((iconSize + iconSpacing) * 6) - 8, 200); if (GameInteractor::IsSaveLoaded()) { - if (ItemTrackerNotes::TrackerNotesInputTextMultiline("##ItemTrackerNotes", &itemTrackerNotes, size, ImGuiInputTextFlags_AllowTabInput)) { + if (ItemTrackerNotes::TrackerNotesInputTextMultiline("##ItemTrackerNotes", &itemTrackerNotes, size, + ImGuiInputTextFlags_AllowTabInput)) { notesNeedSave = true; notesIdleFrames = 0; } - if ((ImGui::IsItemDeactivatedAfterEdit() || (notesNeedSave && notesIdleFrames > notesMaxIdleFrames)) && IsValidSaveFile()) { + if ((ImGui::IsItemDeactivatedAfterEdit() || (notesNeedSave && notesIdleFrames > notesMaxIdleFrames)) && + IsValidSaveFile()) { notesNeedSave = false; SaveManager::Instance->SaveSection(gSaveContext.fileNum, itemTrackerSectionId, true); } @@ -1125,18 +1148,21 @@ void BeginFloatingWindows(std::string UniqueName, ImGuiWindowFlags flags = 0) { ImGuiWindowFlags windowFlags = flags; if (windowFlags == 0) { - windowFlags |= ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_NoFocusOnAppearing | ImGuiWindowFlags_NoResize; + windowFlags |= + ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_NoFocusOnAppearing | ImGuiWindowFlags_NoResize; } if (CVarGetInteger(CVAR_TRACKER_ITEM("WindowType"), TRACKER_WINDOW_FLOATING) == TRACKER_WINDOW_FLOATING) { ImGui::SetNextWindowViewport(ImGui::GetMainViewport()->ID); - windowFlags |= ImGuiWindowFlags_NoDocking | ImGuiWindowFlags_NoNav | ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_NoScrollWithMouse | ImGuiWindowFlags_NoScrollbar; + windowFlags |= ImGuiWindowFlags_NoDocking | ImGuiWindowFlags_NoNav | ImGuiWindowFlags_NoTitleBar | + ImGuiWindowFlags_NoScrollWithMouse | ImGuiWindowFlags_NoScrollbar; if (!CVarGetInteger(CVAR_TRACKER_ITEM("Draggable"), 0)) { windowFlags |= ImGuiWindowFlags_NoInputs | ImGuiWindowFlags_NoMove; } } - ImGui::PushStyleColor(ImGuiCol_WindowBg, VecFromRGBA8(CVarGetColor(CVAR_TRACKER_ITEM("BgColor.Value"), {0, 0, 0, 0}))); + ImGui::PushStyleColor(ImGuiCol_WindowBg, + VecFromRGBA8(CVarGetColor(CVAR_TRACKER_ITEM("BgColor.Value"), { 0, 0, 0, 0 }))); ImGui::PushStyleColor(ImGuiCol_Border, ImVec4(0, 0, 0, 0)); ImGui::PushStyleVar(ImGuiStyleVar_WindowRounding, 4.0f); ImGui::Begin(UniqueName.c_str(), nullptr, windowFlags); @@ -1155,12 +1181,14 @@ void EndFloatingWindows() { void DrawItemsInRows(std::vector items, int columns = 6) { int iconSize = CVarGetInteger(CVAR_TRACKER_ITEM("IconSize"), 36); int iconSpacing = CVarGetInteger(CVAR_TRACKER_ITEM("IconSpacing"), 12); - int topPadding = (CVarGetInteger(CVAR_TRACKER_ITEM("WindowType"), TRACKER_WINDOW_FLOATING) == TRACKER_WINDOW_WINDOW) ? 20 : 0; + int topPadding = + (CVarGetInteger(CVAR_TRACKER_ITEM("WindowType"), TRACKER_WINDOW_FLOATING) == TRACKER_WINDOW_WINDOW) ? 20 : 0; for (int i = 0; i < items.size(); i++) { int row = i / columns; int column = i % columns; - ImGui::SetCursorPos(ImVec2((column * (iconSize + iconSpacing) + 8), (row * (iconSize + iconSpacing)) + 8 + topPadding)); + ImGui::SetCursorPos( + ImVec2((column * (iconSize + iconSpacing) + 8), (row * (iconSize + iconSpacing)) + 8 + topPadding)); items[i].drawFunc(items[i]); } } @@ -1187,7 +1215,7 @@ void DrawItemsInACircle(std::vector items) { /** * GetDungeonItemsVector - * Loops over dungeons and creates vectors of items in the correct order + * Loops over dungeons and creates vectors of items in the correct order * to then call DrawItemsInRows */ std::vector GetDungeonItemsVector(std::vector dungeons, int columns = 6) { @@ -1197,7 +1225,8 @@ std::vector GetDungeonItemsVector(std::vector rowCount) rowCount = dungeons[i].items.size(); + if (dungeons[i].items.size() > rowCount) + rowCount = dungeons[i].items.size(); } for (int i = 0; i < rowCount; i++) { @@ -1210,7 +1239,8 @@ std::vector GetDungeonItemsVector(std::vector GetDungeonItemsVector(std::vector columns) { - std::vector nextDungeonItems = GetDungeonItemsVector(std::vector(dungeons.begin() + columns, dungeons.end()), columns); + std::vector nextDungeonItems = + GetDungeonItemsVector(std::vector(dungeons.begin() + columns, dungeons.end()), columns); dungeonItems.insert(dungeonItems.end(), nextDungeonItems.begin(), nextDungeonItems.end()); } @@ -1238,7 +1269,7 @@ std::vector GetDungeonItemsVector(std::vectorSaveData("personalNotes", std::string(std::begin(itemTrackerNotes), std::end(itemTrackerNotes)).c_str()); + SaveManager::Instance->SaveData("personalNotes", + std::string(std::begin(itemTrackerNotes), std::end(itemTrackerNotes)).c_str()); } void ItemTrackerLoadFile() { @@ -1428,51 +1489,73 @@ void ItemTrackerWindow::DrawElement() { int iconSpacing = CVarGetInteger(CVAR_TRACKER_ITEM("IconSpacing"), 12); int comboButton1Mask = buttonMap[CVarGetInteger(CVAR_TRACKER_ITEM("ComboButton1"), TRACKER_COMBO_BUTTON_L)]; int comboButton2Mask = buttonMap[CVarGetInteger(CVAR_TRACKER_ITEM("ComboButton2"), TRACKER_COMBO_BUTTON_R)]; - OSContPad* buttonsPressed = std::dynamic_pointer_cast(Ship::Context::GetInstance()->GetControlDeck())->GetPads(); - bool comboButtonsHeld = buttonsPressed != nullptr && buttonsPressed[0].button & comboButton1Mask && buttonsPressed[0].button & comboButton2Mask; - bool isPaused = CVarGetInteger(CVAR_TRACKER_ITEM("ShowOnlyPaused"), 0) == 0 || gPlayState != nullptr && gPlayState->pauseCtx.state > 0; + OSContPad* buttonsPressed = + std::dynamic_pointer_cast(Ship::Context::GetInstance()->GetControlDeck())->GetPads(); + bool comboButtonsHeld = buttonsPressed != nullptr && buttonsPressed[0].button & comboButton1Mask && + buttonsPressed[0].button & comboButton2Mask; + bool isPaused = CVarGetInteger(CVAR_TRACKER_ITEM("ShowOnlyPaused"), 0) == 0 || + gPlayState != nullptr && gPlayState->pauseCtx.state > 0; - if (CVarGetInteger(CVAR_TRACKER_ITEM("WindowType"), TRACKER_WINDOW_FLOATING) == TRACKER_WINDOW_WINDOW || isPaused && (CVarGetInteger(CVAR_TRACKER_ITEM("DisplayType.Main"), TRACKER_DISPLAY_ALWAYS) == TRACKER_DISPLAY_ALWAYS ? CVarGetInteger(CVAR_WINDOW("ItemTracker"), 0) : comboButtonsHeld)) { - if ( - (CVarGetInteger(CVAR_TRACKER_ITEM("DisplayType.Inventory"), SECTION_DISPLAY_MAIN_WINDOW) == SECTION_DISPLAY_MAIN_WINDOW) || - (CVarGetInteger(CVAR_TRACKER_ITEM("DisplayType.Equipment"), SECTION_DISPLAY_MAIN_WINDOW) == SECTION_DISPLAY_MAIN_WINDOW) || - (CVarGetInteger(CVAR_TRACKER_ITEM("DisplayType.Misc"), SECTION_DISPLAY_MAIN_WINDOW) == SECTION_DISPLAY_MAIN_WINDOW) || - (CVarGetInteger(CVAR_TRACKER_ITEM("DisplayType.DungeonRewards"), SECTION_DISPLAY_MAIN_WINDOW) == SECTION_DISPLAY_MAIN_WINDOW) || - (CVarGetInteger(CVAR_TRACKER_ITEM("DisplayType.Songs"), SECTION_DISPLAY_MAIN_WINDOW) == SECTION_DISPLAY_MAIN_WINDOW) || - (CVarGetInteger(CVAR_TRACKER_ITEM("DisplayType.DungeonItems"), SECTION_DISPLAY_HIDDEN) == SECTION_DISPLAY_MAIN_WINDOW) || - (CVarGetInteger(CVAR_TRACKER_ITEM("DisplayType.Greg"), SECTION_DISPLAY_EXTENDED_HIDDEN) == SECTION_DISPLAY_EXTENDED_MAIN_WINDOW) || - (CVarGetInteger(CVAR_TRACKER_ITEM("DisplayType.TriforcePieces"), SECTION_DISPLAY_HIDDEN) == SECTION_DISPLAY_MAIN_WINDOW) || - (CVarGetInteger(CVAR_TRACKER_ITEM("DisplayType.FishingPole"), SECTION_DISPLAY_EXTENDED_HIDDEN) == SECTION_DISPLAY_EXTENDED_MAIN_WINDOW) || - (CVarGetInteger(CVAR_TRACKER_ITEM("DisplayType.Notes"), SECTION_DISPLAY_HIDDEN) == SECTION_DISPLAY_MAIN_WINDOW) - ) { + if (CVarGetInteger(CVAR_TRACKER_ITEM("WindowType"), TRACKER_WINDOW_FLOATING) == TRACKER_WINDOW_WINDOW || + isPaused && + (CVarGetInteger(CVAR_TRACKER_ITEM("DisplayType.Main"), TRACKER_DISPLAY_ALWAYS) == TRACKER_DISPLAY_ALWAYS + ? CVarGetInteger(CVAR_WINDOW("ItemTracker"), 0) + : comboButtonsHeld)) { + if ((CVarGetInteger(CVAR_TRACKER_ITEM("DisplayType.Inventory"), SECTION_DISPLAY_MAIN_WINDOW) == + SECTION_DISPLAY_MAIN_WINDOW) || + (CVarGetInteger(CVAR_TRACKER_ITEM("DisplayType.Equipment"), SECTION_DISPLAY_MAIN_WINDOW) == + SECTION_DISPLAY_MAIN_WINDOW) || + (CVarGetInteger(CVAR_TRACKER_ITEM("DisplayType.Misc"), SECTION_DISPLAY_MAIN_WINDOW) == + SECTION_DISPLAY_MAIN_WINDOW) || + (CVarGetInteger(CVAR_TRACKER_ITEM("DisplayType.DungeonRewards"), SECTION_DISPLAY_MAIN_WINDOW) == + SECTION_DISPLAY_MAIN_WINDOW) || + (CVarGetInteger(CVAR_TRACKER_ITEM("DisplayType.Songs"), SECTION_DISPLAY_MAIN_WINDOW) == + SECTION_DISPLAY_MAIN_WINDOW) || + (CVarGetInteger(CVAR_TRACKER_ITEM("DisplayType.DungeonItems"), SECTION_DISPLAY_HIDDEN) == + SECTION_DISPLAY_MAIN_WINDOW) || + (CVarGetInteger(CVAR_TRACKER_ITEM("DisplayType.Greg"), SECTION_DISPLAY_EXTENDED_HIDDEN) == + SECTION_DISPLAY_EXTENDED_MAIN_WINDOW) || + (CVarGetInteger(CVAR_TRACKER_ITEM("DisplayType.TriforcePieces"), SECTION_DISPLAY_HIDDEN) == + SECTION_DISPLAY_MAIN_WINDOW) || + (CVarGetInteger(CVAR_TRACKER_ITEM("DisplayType.FishingPole"), SECTION_DISPLAY_EXTENDED_HIDDEN) == + SECTION_DISPLAY_EXTENDED_MAIN_WINDOW) || + (CVarGetInteger(CVAR_TRACKER_ITEM("DisplayType.Notes"), SECTION_DISPLAY_HIDDEN) == + SECTION_DISPLAY_MAIN_WINDOW)) { BeginFloatingWindows("Item Tracker##main window"); DrawItemsInRows(mainWindowItems, 6); - if (CVarGetInteger(CVAR_TRACKER_ITEM("DisplayType.Notes"), SECTION_DISPLAY_HIDDEN) == SECTION_DISPLAY_MAIN_WINDOW && CVarGetInteger(CVAR_TRACKER_ITEM("DisplayType.Main"), TRACKER_DISPLAY_ALWAYS) == TRACKER_DISPLAY_ALWAYS) { + if (CVarGetInteger(CVAR_TRACKER_ITEM("DisplayType.Notes"), SECTION_DISPLAY_HIDDEN) == + SECTION_DISPLAY_MAIN_WINDOW && + CVarGetInteger(CVAR_TRACKER_ITEM("DisplayType.Main"), TRACKER_DISPLAY_ALWAYS) == + TRACKER_DISPLAY_ALWAYS) { DrawNotes(); } EndFloatingWindows(); } - if (CVarGetInteger(CVAR_TRACKER_ITEM("DisplayType.Inventory"), SECTION_DISPLAY_MAIN_WINDOW) == SECTION_DISPLAY_SEPARATE) { + if (CVarGetInteger(CVAR_TRACKER_ITEM("DisplayType.Inventory"), SECTION_DISPLAY_MAIN_WINDOW) == + SECTION_DISPLAY_SEPARATE) { BeginFloatingWindows("Inventory Items Tracker"); DrawItemsInRows(inventoryItems); EndFloatingWindows(); } - if (CVarGetInteger(CVAR_TRACKER_ITEM("DisplayType.Equipment"), SECTION_DISPLAY_MAIN_WINDOW) == SECTION_DISPLAY_SEPARATE) { + if (CVarGetInteger(CVAR_TRACKER_ITEM("DisplayType.Equipment"), SECTION_DISPLAY_MAIN_WINDOW) == + SECTION_DISPLAY_SEPARATE) { BeginFloatingWindows("Equipment Items Tracker"); DrawItemsInRows(equipmentItems, 3); EndFloatingWindows(); } - if (CVarGetInteger(CVAR_TRACKER_ITEM("DisplayType.Misc"), SECTION_DISPLAY_MAIN_WINDOW) == SECTION_DISPLAY_SEPARATE) { + if (CVarGetInteger(CVAR_TRACKER_ITEM("DisplayType.Misc"), SECTION_DISPLAY_MAIN_WINDOW) == + SECTION_DISPLAY_SEPARATE) { BeginFloatingWindows("Misc Items Tracker"); DrawItemsInRows(miscItems, 4); EndFloatingWindows(); } - if (CVarGetInteger(CVAR_TRACKER_ITEM("DisplayType.DungeonRewards"), SECTION_DISPLAY_MAIN_WINDOW) == SECTION_DISPLAY_SEPARATE) { + if (CVarGetInteger(CVAR_TRACKER_ITEM("DisplayType.DungeonRewards"), SECTION_DISPLAY_MAIN_WINDOW) == + SECTION_DISPLAY_SEPARATE) { BeginFloatingWindows("Dungeon Rewards Tracker"); if (CVarGetInteger(CVAR_TRACKER_ITEM("DungeonRewardsLayout"), 0)) { ImGui::BeginGroup(); @@ -1487,13 +1570,15 @@ void ItemTrackerWindow::DrawElement() { EndFloatingWindows(); } - if (CVarGetInteger(CVAR_TRACKER_ITEM("DisplayType.Songs"), SECTION_DISPLAY_MAIN_WINDOW) == SECTION_DISPLAY_SEPARATE) { + if (CVarGetInteger(CVAR_TRACKER_ITEM("DisplayType.Songs"), SECTION_DISPLAY_MAIN_WINDOW) == + SECTION_DISPLAY_SEPARATE) { BeginFloatingWindows("Songs Tracker"); DrawItemsInRows(songItems); EndFloatingWindows(); } - if (CVarGetInteger(CVAR_TRACKER_ITEM("DisplayType.DungeonItems"), SECTION_DISPLAY_HIDDEN) == SECTION_DISPLAY_SEPARATE) { + if (CVarGetInteger(CVAR_TRACKER_ITEM("DisplayType.DungeonItems"), SECTION_DISPLAY_HIDDEN) == + SECTION_DISPLAY_SEPARATE) { BeginFloatingWindows("Dungeon Items Tracker"); if (CVarGetInteger(CVAR_TRACKER_ITEM("DungeonItems.Layout"), 1)) { if (CVarGetInteger(CVAR_TRACKER_ITEM("DungeonItems.DisplayMaps"), 1)) { @@ -1507,44 +1592,52 @@ void ItemTrackerWindow::DrawElement() { EndFloatingWindows(); } - if (CVarGetInteger(CVAR_TRACKER_ITEM("DisplayType.Greg"), SECTION_DISPLAY_EXTENDED_HIDDEN) == SECTION_DISPLAY_EXTENDED_SEPARATE) { + if (CVarGetInteger(CVAR_TRACKER_ITEM("DisplayType.Greg"), SECTION_DISPLAY_EXTENDED_HIDDEN) == + SECTION_DISPLAY_EXTENDED_SEPARATE) { BeginFloatingWindows("Greg Tracker"); DrawItemsInRows(gregItems); EndFloatingWindows(); } - if (CVarGetInteger(CVAR_TRACKER_ITEM("DisplayType.TriforcePieces"), SECTION_DISPLAY_HIDDEN) == SECTION_DISPLAY_SEPARATE) { + if (CVarGetInteger(CVAR_TRACKER_ITEM("DisplayType.TriforcePieces"), SECTION_DISPLAY_HIDDEN) == + SECTION_DISPLAY_SEPARATE) { BeginFloatingWindows("Triforce Piece Tracker"); DrawItemsInRows(triforcePieces); EndFloatingWindows(); } - if (CVarGetInteger(CVAR_TRACKER_ITEM("DisplayType.BossSouls"), SECTION_DISPLAY_HIDDEN) == SECTION_DISPLAY_SEPARATE) { + if (CVarGetInteger(CVAR_TRACKER_ITEM("DisplayType.BossSouls"), SECTION_DISPLAY_HIDDEN) == + SECTION_DISPLAY_SEPARATE) { BeginFloatingWindows("Boss Soul Tracker"); DrawItemsInRows(bossSoulItems); EndFloatingWindows(); } - if (CVarGetInteger(CVAR_TRACKER_ITEM("DisplayType.OcarinaButtons"), SECTION_DISPLAY_HIDDEN) == SECTION_DISPLAY_SEPARATE) { + if (CVarGetInteger(CVAR_TRACKER_ITEM("DisplayType.OcarinaButtons"), SECTION_DISPLAY_HIDDEN) == + SECTION_DISPLAY_SEPARATE) { BeginFloatingWindows("Ocarina Button Tracker"); DrawItemsInRows(ocarinaButtonItems); EndFloatingWindows(); } - if (CVarGetInteger(CVAR_TRACKER_ITEM("DisplayType.OverworldKeys"), SECTION_DISPLAY_HIDDEN) == SECTION_DISPLAY_SEPARATE) { + if (CVarGetInteger(CVAR_TRACKER_ITEM("DisplayType.OverworldKeys"), SECTION_DISPLAY_HIDDEN) == + SECTION_DISPLAY_SEPARATE) { BeginFloatingWindows("Overworld Key Tracker"); DrawItemsInRows(overworldKeyItems); EndFloatingWindows(); } - if (CVarGetInteger(CVAR_TRACKER_ITEM("DisplayType.FishingPole"), SECTION_DISPLAY_EXTENDED_HIDDEN) == SECTION_DISPLAY_EXTENDED_SEPARATE) { + if (CVarGetInteger(CVAR_TRACKER_ITEM("DisplayType.FishingPole"), SECTION_DISPLAY_EXTENDED_HIDDEN) == + SECTION_DISPLAY_EXTENDED_SEPARATE) { BeginFloatingWindows("Fishing Pole Tracker"); DrawItemsInRows(fishingPoleItems); EndFloatingWindows(); } - if (CVarGetInteger(CVAR_TRACKER_ITEM("DisplayType.Notes"), SECTION_DISPLAY_HIDDEN) == SECTION_DISPLAY_SEPARATE && CVarGetInteger(CVAR_TRACKER_ITEM("DisplayType.Main"), TRACKER_DISPLAY_ALWAYS) == TRACKER_DISPLAY_ALWAYS) { - ImGui::SetNextWindowSize(ImVec2(400,300), ImGuiCond_FirstUseEver); + if (CVarGetInteger(CVAR_TRACKER_ITEM("DisplayType.Notes"), SECTION_DISPLAY_HIDDEN) == + SECTION_DISPLAY_SEPARATE && + CVarGetInteger(CVAR_TRACKER_ITEM("DisplayType.Main"), TRACKER_DISPLAY_ALWAYS) == TRACKER_DISPLAY_ALWAYS) { + ImGui::SetNextWindowSize(ImVec2(400, 300), ImGuiCond_FirstUseEver); BeginFloatingWindows("Personal Notes", ImGuiWindowFlags_NoFocusOnAppearing); DrawNotes(true); EndFloatingWindows(); @@ -1561,22 +1654,52 @@ void ItemTrackerWindow::DrawElement() { } static std::unordered_map itemTrackerCapacityTrackOptions = { - { ITEM_TRACKER_NUMBER_NONE, "No Numbers" }, { ITEM_TRACKER_NUMBER_CURRENT_CAPACITY_ONLY, "Current Capacity" }, { ITEM_TRACKER_NUMBER_CURRENT_AMMO_ONLY, "Current Ammo" }, - { ITEM_TRACKER_NUMBER_CAPACITY, "Current Capacity / Max Capacity" }, { ITEM_TRACKER_NUMBER_AMMO, "Current Ammo / Current Capacity" },}; + { ITEM_TRACKER_NUMBER_NONE, "No Numbers" }, + { ITEM_TRACKER_NUMBER_CURRENT_CAPACITY_ONLY, "Current Capacity" }, + { ITEM_TRACKER_NUMBER_CURRENT_AMMO_ONLY, "Current Ammo" }, + { ITEM_TRACKER_NUMBER_CAPACITY, "Current Capacity / Max Capacity" }, + { ITEM_TRACKER_NUMBER_AMMO, "Current Ammo / Current Capacity" }, +}; static std::unordered_map itemTrackerKeyTrackOptions = { - { KEYS_COLLECTED_MAX, "Collected / Max" }, { KEYS_CURRENT_COLLECTED_MAX, "Current / Collected / Max" }, { KEYS_CURRENT_MAX, "Current / Max" },}; + { KEYS_COLLECTED_MAX, "Collected / Max" }, + { KEYS_CURRENT_COLLECTED_MAX, "Current / Collected / Max" }, + { KEYS_CURRENT_MAX, "Current / Max" }, +}; static std::unordered_map itemTrackerTriforcePieceTrackOptions = { - { TRIFORCE_PIECE_COLLECTED_REQUIRED, "Collected / Required" }, { TRIFORCE_PIECE_COLLECTED_REQUIRED_MAX, "Collected / Required / Max" },}; -static std::unordered_map windowTypes = {{ TRACKER_WINDOW_FLOATING, "Floating" }, { TRACKER_WINDOW_WINDOW, "Window" },}; -static std::unordered_map displayModes = {{ TRACKER_DISPLAY_ALWAYS, "Always" }, { TRACKER_DISPLAY_COMBO_BUTTON, "Combo Button Hold" },}; -static std::unordered_map buttons = {{ TRACKER_COMBO_BUTTON_A, "A" }, { TRACKER_COMBO_BUTTON_B, "B"}, { TRACKER_COMBO_BUTTON_C_UP, "C-Up"}, - { TRACKER_COMBO_BUTTON_C_DOWN, "C-Down" }, { TRACKER_COMBO_BUTTON_C_LEFT, "C-Left" }, { TRACKER_COMBO_BUTTON_C_RIGHT, "C-Right" }, { TRACKER_COMBO_BUTTON_L, "L" }, - { TRACKER_COMBO_BUTTON_Z, "Z" }, { TRACKER_COMBO_BUTTON_R, "R" }, { TRACKER_COMBO_BUTTON_START, "Start" }, { TRACKER_COMBO_BUTTON_D_UP, "D-Up" }, - { TRACKER_COMBO_BUTTON_D_DOWN, "D-Down" }, { TRACKER_COMBO_BUTTON_D_LEFT, "D-Left" }, { TRACKER_COMBO_BUTTON_D_RIGHT, "D-Right" },}; -static std::unordered_map displayTypes = {{ SECTION_DISPLAY_HIDDEN, "Hidden" }, { SECTION_DISPLAY_MAIN_WINDOW, "Main Window" }, { SECTION_DISPLAY_SEPARATE, "Separate" },}; -static std::unordered_map extendedDisplayTypes = {{ SECTION_DISPLAY_EXTENDED_HIDDEN, "Hidden" }, - { SECTION_DISPLAY_EXTENDED_MAIN_WINDOW, "Main Window" }, { SECTION_DISPLAY_EXTENDED_MISC_WINDOW, "Misc Window" }, { SECTION_DISPLAY_EXTENDED_SEPARATE, "Separate" },}; -static std::unordered_map minimalDisplayTypes = {{ SECTION_DISPLAY_MINIMAL_HIDDEN, "Hidden" }, { SECTION_DISPLAY_MINIMAL_SEPARATE, "Separate" }}; + { TRIFORCE_PIECE_COLLECTED_REQUIRED, "Collected / Required" }, + { TRIFORCE_PIECE_COLLECTED_REQUIRED_MAX, "Collected / Required / Max" }, +}; +static std::unordered_map windowTypes = { + { TRACKER_WINDOW_FLOATING, "Floating" }, + { TRACKER_WINDOW_WINDOW, "Window" }, +}; +static std::unordered_map displayModes = { + { TRACKER_DISPLAY_ALWAYS, "Always" }, + { TRACKER_DISPLAY_COMBO_BUTTON, "Combo Button Hold" }, +}; +static std::unordered_map buttons = { + { TRACKER_COMBO_BUTTON_A, "A" }, { TRACKER_COMBO_BUTTON_B, "B" }, + { TRACKER_COMBO_BUTTON_C_UP, "C-Up" }, { TRACKER_COMBO_BUTTON_C_DOWN, "C-Down" }, + { TRACKER_COMBO_BUTTON_C_LEFT, "C-Left" }, { TRACKER_COMBO_BUTTON_C_RIGHT, "C-Right" }, + { TRACKER_COMBO_BUTTON_L, "L" }, { TRACKER_COMBO_BUTTON_Z, "Z" }, + { TRACKER_COMBO_BUTTON_R, "R" }, { TRACKER_COMBO_BUTTON_START, "Start" }, + { TRACKER_COMBO_BUTTON_D_UP, "D-Up" }, { TRACKER_COMBO_BUTTON_D_DOWN, "D-Down" }, + { TRACKER_COMBO_BUTTON_D_LEFT, "D-Left" }, { TRACKER_COMBO_BUTTON_D_RIGHT, "D-Right" }, +}; +static std::unordered_map displayTypes = { + { SECTION_DISPLAY_HIDDEN, "Hidden" }, + { SECTION_DISPLAY_MAIN_WINDOW, "Main Window" }, + { SECTION_DISPLAY_SEPARATE, "Separate" }, +}; +static std::unordered_map extendedDisplayTypes = { + { SECTION_DISPLAY_EXTENDED_HIDDEN, "Hidden" }, + { SECTION_DISPLAY_EXTENDED_MAIN_WINDOW, "Main Window" }, + { SECTION_DISPLAY_EXTENDED_MISC_WINDOW, "Misc Window" }, + { SECTION_DISPLAY_EXTENDED_SEPARATE, "Separate" }, +}; +static std::unordered_map minimalDisplayTypes = { + { SECTION_DISPLAY_MINIMAL_HIDDEN, "Hidden" }, { SECTION_DISPLAY_MINIMAL_SEPARATE, "Separate" } +}; void ItemTrackerSettingsWindow::DrawElement() { ImGui::PushStyleVar(ImGuiStyleVar_CellPadding, { 8.0f, 8.0f }); @@ -1588,12 +1711,15 @@ void ItemTrackerSettingsWindow::DrawElement() { ImGui::TableNextColumn(); ImGui::PushItemWidth(ImGui::GetContentRegionAvail().x); CVarColorPicker("Background Color##gItemTrackerBgColor", CVAR_TRACKER_ITEM("BgColor"), { 0, 0, 0, 0 }, true, - ColorPickerRandomButton | ColorPickerResetButton, THEME_COLOR); + ColorPickerRandomButton | ColorPickerResetButton, THEME_COLOR); ImGui::PopItemWidth(); - if (CVarCombobox("Window Type", CVAR_TRACKER_ITEM("WindowType"), windowTypes, ComboboxOptions() - .DefaultIndex(TRACKER_WINDOW_FLOATING).ComponentAlignment(ComponentAlignments::Right) - .LabelPosition(LabelPositions::Far).Color(THEME_COLOR))) { + if (CVarCombobox("Window Type", CVAR_TRACKER_ITEM("WindowType"), windowTypes, + ComboboxOptions() + .DefaultIndex(TRACKER_WINDOW_FLOATING) + .ComponentAlignment(ComponentAlignments::Right) + .LabelPosition(LabelPositions::Far) + .Color(THEME_COLOR))) { shouldUpdateVectors = true; } @@ -1601,152 +1727,229 @@ void ItemTrackerSettingsWindow::DrawElement() { if (CVarCheckbox("Enable Dragging", CVAR_TRACKER_ITEM("Draggable"), CheckboxOptions().Color(THEME_COLOR))) { shouldUpdateVectors = true; } - if (CVarCheckbox("Only enable while paused", CVAR_TRACKER_ITEM("ShowOnlyPaused"), CheckboxOptions().Color(THEME_COLOR))) { + if (CVarCheckbox("Only enable while paused", CVAR_TRACKER_ITEM("ShowOnlyPaused"), + CheckboxOptions().Color(THEME_COLOR))) { shouldUpdateVectors = true; } - if (CVarCombobox("Display Mode", CVAR_TRACKER_ITEM("DisplayType.Main"), displayModes, ComboboxOptions() - .DefaultIndex(TRACKER_DISPLAY_ALWAYS).ComponentAlignment(ComponentAlignments::Right) - .LabelPosition(LabelPositions::Far).Color(THEME_COLOR))) { + if (CVarCombobox("Display Mode", CVAR_TRACKER_ITEM("DisplayType.Main"), displayModes, + ComboboxOptions() + .DefaultIndex(TRACKER_DISPLAY_ALWAYS) + .ComponentAlignment(ComponentAlignments::Right) + .LabelPosition(LabelPositions::Far) + .Color(THEME_COLOR))) { shouldUpdateVectors = true; } - if (CVarGetInteger(CVAR_TRACKER_ITEM("DisplayType.Main"), TRACKER_DISPLAY_ALWAYS) == TRACKER_DISPLAY_COMBO_BUTTON) { - if (CVarCombobox("Combo Button 1", CVAR_TRACKER_ITEM("ComboButton1"), buttons, ComboboxOptions() - .DefaultIndex(TRACKER_COMBO_BUTTON_L).ComponentAlignment(ComponentAlignments::Right) - .LabelPosition(LabelPositions::Far).Color(THEME_COLOR))) { + if (CVarGetInteger(CVAR_TRACKER_ITEM("DisplayType.Main"), TRACKER_DISPLAY_ALWAYS) == + TRACKER_DISPLAY_COMBO_BUTTON) { + if (CVarCombobox("Combo Button 1", CVAR_TRACKER_ITEM("ComboButton1"), buttons, + ComboboxOptions() + .DefaultIndex(TRACKER_COMBO_BUTTON_L) + .ComponentAlignment(ComponentAlignments::Right) + .LabelPosition(LabelPositions::Far) + .Color(THEME_COLOR))) { shouldUpdateVectors = true; } - if (CVarCombobox("Combo Button 2", CVAR_TRACKER_ITEM("ComboButton2"), buttons, ComboboxOptions() - .DefaultIndex(TRACKER_COMBO_BUTTON_R).ComponentAlignment(ComponentAlignments::Right) - .LabelPosition(LabelPositions::Far).Color(THEME_COLOR))) { + if (CVarCombobox("Combo Button 2", CVAR_TRACKER_ITEM("ComboButton2"), buttons, + ComboboxOptions() + .DefaultIndex(TRACKER_COMBO_BUTTON_R) + .ComponentAlignment(ComponentAlignments::Right) + .LabelPosition(LabelPositions::Far) + .Color(THEME_COLOR))) { shouldUpdateVectors = true; } } } ImGui::Separator(); - CVarSliderInt("Icon size : %dpx", CVAR_TRACKER_ITEM("IconSize"), IntSliderOptions().Min(25).Max(128).DefaultValue(36).Color(THEME_COLOR)); - CVarSliderInt("Icon margins : %dpx", CVAR_TRACKER_ITEM("IconSpacing"), IntSliderOptions().Min(-5).Max(50).DefaultValue(12).Color(THEME_COLOR)); - CVarSliderInt("Text size : %dpx", CVAR_TRACKER_ITEM("TextSize"), IntSliderOptions().Min(1).Max(30).DefaultValue(13).Color(THEME_COLOR)); - + CVarSliderInt("Icon size : %dpx", CVAR_TRACKER_ITEM("IconSize"), + IntSliderOptions().Min(25).Max(128).DefaultValue(36).Color(THEME_COLOR)); + CVarSliderInt("Icon margins : %dpx", CVAR_TRACKER_ITEM("IconSpacing"), + IntSliderOptions().Min(-5).Max(50).DefaultValue(12).Color(THEME_COLOR)); + CVarSliderInt("Text size : %dpx", CVAR_TRACKER_ITEM("TextSize"), + IntSliderOptions().Min(1).Max(30).DefaultValue(13).Color(THEME_COLOR)); + ImGui::NewLine(); - CVarCombobox("Ammo/Capacity Tracking", CVAR_TRACKER_ITEM("ItemCountType"), itemTrackerCapacityTrackOptions, ComboboxOptions() - .DefaultIndex(ITEM_TRACKER_NUMBER_CURRENT_CAPACITY_ONLY).ComponentAlignment(ComponentAlignments::Left) - .LabelPosition(LabelPositions::Above).Color(THEME_COLOR) - .Tooltip("Customize what the numbers under each item are tracking." - "\n\nNote: items without capacity upgrades will track ammo even in capacity mode")); - if (CVarGetInteger(CVAR_TRACKER_ITEM("ItemCountType"), ITEM_TRACKER_NUMBER_CURRENT_CAPACITY_ONLY) == ITEM_TRACKER_NUMBER_CURRENT_CAPACITY_ONLY || CVarGetInteger(CVAR_TRACKER_ITEM("ItemCountType"), ITEM_TRACKER_NUMBER_CURRENT_CAPACITY_ONLY) == ITEM_TRACKER_NUMBER_CURRENT_AMMO_ONLY) { - if (CVarCheckbox("Align count to left side", CVAR_TRACKER_ITEM("ItemCountAlignLeft"), CheckboxOptions().Color(THEME_COLOR))) { + CVarCombobox("Ammo/Capacity Tracking", CVAR_TRACKER_ITEM("ItemCountType"), itemTrackerCapacityTrackOptions, + ComboboxOptions() + .DefaultIndex(ITEM_TRACKER_NUMBER_CURRENT_CAPACITY_ONLY) + .ComponentAlignment(ComponentAlignments::Left) + .LabelPosition(LabelPositions::Above) + .Color(THEME_COLOR) + .Tooltip("Customize what the numbers under each item are tracking." + "\n\nNote: items without capacity upgrades will track ammo even in capacity mode")); + if (CVarGetInteger(CVAR_TRACKER_ITEM("ItemCountType"), ITEM_TRACKER_NUMBER_CURRENT_CAPACITY_ONLY) == + ITEM_TRACKER_NUMBER_CURRENT_CAPACITY_ONLY || + CVarGetInteger(CVAR_TRACKER_ITEM("ItemCountType"), ITEM_TRACKER_NUMBER_CURRENT_CAPACITY_ONLY) == + ITEM_TRACKER_NUMBER_CURRENT_AMMO_ONLY) { + if (CVarCheckbox("Align count to left side", CVAR_TRACKER_ITEM("ItemCountAlignLeft"), + CheckboxOptions().Color(THEME_COLOR))) { shouldUpdateVectors = true; } } - CVarCombobox("Key Count Tracking", CVAR_TRACKER_ITEM("KeyCounts"), itemTrackerKeyTrackOptions, ComboboxOptions() - .DefaultIndex(KEYS_COLLECTED_MAX).ComponentAlignment(ComponentAlignments::Left) - .LabelPosition(LabelPositions::Above).Color(THEME_COLOR) - .Tooltip("Customize what numbers are shown for key tracking.")); + CVarCombobox("Key Count Tracking", CVAR_TRACKER_ITEM("KeyCounts"), itemTrackerKeyTrackOptions, + ComboboxOptions() + .DefaultIndex(KEYS_COLLECTED_MAX) + .ComponentAlignment(ComponentAlignments::Left) + .LabelPosition(LabelPositions::Above) + .Color(THEME_COLOR) + .Tooltip("Customize what numbers are shown for key tracking.")); - CVarCombobox("Triforce Piece Count Tracking", CVAR_TRACKER_ITEM("TriforcePieceCounts"), itemTrackerTriforcePieceTrackOptions, ComboboxOptions() - .DefaultIndex(TRIFORCE_PIECE_COLLECTED_REQUIRED_MAX).ComponentAlignment(ComponentAlignments::Left) - .LabelPosition(LabelPositions::Above).Color(THEME_COLOR) - .Tooltip("Customize what numbers are shown for triforce piece tracking.")); + CVarCombobox("Triforce Piece Count Tracking", CVAR_TRACKER_ITEM("TriforcePieceCounts"), + itemTrackerTriforcePieceTrackOptions, + ComboboxOptions() + .DefaultIndex(TRIFORCE_PIECE_COLLECTED_REQUIRED_MAX) + .ComponentAlignment(ComponentAlignments::Left) + .LabelPosition(LabelPositions::Above) + .Color(THEME_COLOR) + .Tooltip("Customize what numbers are shown for triforce piece tracking.")); ImGui::TableNextColumn(); - if (CVarCombobox("Inventory", CVAR_TRACKER_ITEM("DisplayType.Inventory"), displayTypes, ComboboxOptions() - .DefaultIndex(SECTION_DISPLAY_MAIN_WINDOW).ComponentAlignment(ComponentAlignments::Right) - .LabelPosition(LabelPositions::Far).Color(THEME_COLOR))) { + if (CVarCombobox("Inventory", CVAR_TRACKER_ITEM("DisplayType.Inventory"), displayTypes, + ComboboxOptions() + .DefaultIndex(SECTION_DISPLAY_MAIN_WINDOW) + .ComponentAlignment(ComponentAlignments::Right) + .LabelPosition(LabelPositions::Far) + .Color(THEME_COLOR))) { shouldUpdateVectors = true; } - if (CVarCombobox("Equipment", CVAR_TRACKER_ITEM("DisplayType.Equipment"), displayTypes, ComboboxOptions() - .DefaultIndex(SECTION_DISPLAY_MAIN_WINDOW).ComponentAlignment(ComponentAlignments::Right) - .LabelPosition(LabelPositions::Far).Color(THEME_COLOR))) { + if (CVarCombobox("Equipment", CVAR_TRACKER_ITEM("DisplayType.Equipment"), displayTypes, + ComboboxOptions() + .DefaultIndex(SECTION_DISPLAY_MAIN_WINDOW) + .ComponentAlignment(ComponentAlignments::Right) + .LabelPosition(LabelPositions::Far) + .Color(THEME_COLOR))) { shouldUpdateVectors = true; } - if (CVarCombobox("Misc", CVAR_TRACKER_ITEM("DisplayType.Misc"), displayTypes, ComboboxOptions() - .DefaultIndex(SECTION_DISPLAY_MAIN_WINDOW).ComponentAlignment(ComponentAlignments::Right) - .LabelPosition(LabelPositions::Far).Color(THEME_COLOR))) { + if (CVarCombobox("Misc", CVAR_TRACKER_ITEM("DisplayType.Misc"), displayTypes, + ComboboxOptions() + .DefaultIndex(SECTION_DISPLAY_MAIN_WINDOW) + .ComponentAlignment(ComponentAlignments::Right) + .LabelPosition(LabelPositions::Far) + .Color(THEME_COLOR))) { shouldUpdateVectors = true; } - if (CVarCombobox("Dungeon Rewards", CVAR_TRACKER_ITEM("DisplayType.DungeonRewards"), displayTypes, ComboboxOptions() - .DefaultIndex(SECTION_DISPLAY_MAIN_WINDOW).ComponentAlignment(ComponentAlignments::Right) - .LabelPosition(LabelPositions::Far).Color(THEME_COLOR))) { + if (CVarCombobox("Dungeon Rewards", CVAR_TRACKER_ITEM("DisplayType.DungeonRewards"), displayTypes, + ComboboxOptions() + .DefaultIndex(SECTION_DISPLAY_MAIN_WINDOW) + .ComponentAlignment(ComponentAlignments::Right) + .LabelPosition(LabelPositions::Far) + .Color(THEME_COLOR))) { shouldUpdateVectors = true; } - if (CVarGetInteger(CVAR_TRACKER_ITEM("DisplayType.DungeonRewards"), SECTION_DISPLAY_MAIN_WINDOW) == SECTION_DISPLAY_SEPARATE) { + if (CVarGetInteger(CVAR_TRACKER_ITEM("DisplayType.DungeonRewards"), SECTION_DISPLAY_MAIN_WINDOW) == + SECTION_DISPLAY_SEPARATE) { if (CVarCheckbox("Circle display", CVAR_TRACKER_ITEM("DungeonRewardsLayout"))) { shouldUpdateVectors = true; } } - if (CVarCombobox("Songs", CVAR_TRACKER_ITEM("DisplayType.Songs"), displayTypes, ComboboxOptions() - .DefaultIndex(SECTION_DISPLAY_MAIN_WINDOW).ComponentAlignment(ComponentAlignments::Right) - .LabelPosition(LabelPositions::Far).Color(THEME_COLOR))) { + if (CVarCombobox("Songs", CVAR_TRACKER_ITEM("DisplayType.Songs"), displayTypes, + ComboboxOptions() + .DefaultIndex(SECTION_DISPLAY_MAIN_WINDOW) + .ComponentAlignment(ComponentAlignments::Right) + .LabelPosition(LabelPositions::Far) + .Color(THEME_COLOR))) { shouldUpdateVectors = true; } - if (CVarCombobox("Dungeon Items", CVAR_TRACKER_ITEM("DisplayType.DungeonItems"), displayTypes, ComboboxOptions() - .DefaultIndex(SECTION_DISPLAY_HIDDEN).ComponentAlignment(ComponentAlignments::Right) - .LabelPosition(LabelPositions::Far).Color(THEME_COLOR))) { + if (CVarCombobox("Dungeon Items", CVAR_TRACKER_ITEM("DisplayType.DungeonItems"), displayTypes, + ComboboxOptions() + .DefaultIndex(SECTION_DISPLAY_HIDDEN) + .ComponentAlignment(ComponentAlignments::Right) + .LabelPosition(LabelPositions::Far) + .Color(THEME_COLOR))) { shouldUpdateVectors = true; } - if (CVarGetInteger(CVAR_TRACKER_ITEM("DisplayType.DungeonItems"), SECTION_DISPLAY_HIDDEN) != SECTION_DISPLAY_HIDDEN) { - if (CVarGetInteger(CVAR_TRACKER_ITEM("DisplayType.DungeonItems"), SECTION_DISPLAY_HIDDEN) == SECTION_DISPLAY_SEPARATE) { - if (CVarCheckbox("Horizontal display", CVAR_TRACKER_ITEM("DungeonItems.Layout"), CheckboxOptions().DefaultValue(true).Color(THEME_COLOR))) { + if (CVarGetInteger(CVAR_TRACKER_ITEM("DisplayType.DungeonItems"), SECTION_DISPLAY_HIDDEN) != + SECTION_DISPLAY_HIDDEN) { + if (CVarGetInteger(CVAR_TRACKER_ITEM("DisplayType.DungeonItems"), SECTION_DISPLAY_HIDDEN) == + SECTION_DISPLAY_SEPARATE) { + if (CVarCheckbox("Horizontal display", CVAR_TRACKER_ITEM("DungeonItems.Layout"), + CheckboxOptions().DefaultValue(true).Color(THEME_COLOR))) { shouldUpdateVectors = true; } } - if (CVarCheckbox("Maps and compasses", CVAR_TRACKER_ITEM("DungeonItems.DisplayMaps"), CheckboxOptions().DefaultValue(true).Color(THEME_COLOR))) { + if (CVarCheckbox("Maps and compasses", CVAR_TRACKER_ITEM("DungeonItems.DisplayMaps"), + CheckboxOptions().DefaultValue(true).Color(THEME_COLOR))) { shouldUpdateVectors = true; } } - if (CVarCombobox("Greg", CVAR_TRACKER_ITEM("DisplayType.Greg"), extendedDisplayTypes, ComboboxOptions() - .DefaultIndex(SECTION_DISPLAY_EXTENDED_HIDDEN).ComponentAlignment(ComponentAlignments::Right) - .LabelPosition(LabelPositions::Far).Color(THEME_COLOR))) { + if (CVarCombobox("Greg", CVAR_TRACKER_ITEM("DisplayType.Greg"), extendedDisplayTypes, + ComboboxOptions() + .DefaultIndex(SECTION_DISPLAY_EXTENDED_HIDDEN) + .ComponentAlignment(ComponentAlignments::Right) + .LabelPosition(LabelPositions::Far) + .Color(THEME_COLOR))) { shouldUpdateVectors = true; } - if (CVarCombobox("Triforce Pieces", CVAR_TRACKER_ITEM("DisplayType.TriforcePieces"), displayTypes, ComboboxOptions() - .DefaultIndex(SECTION_DISPLAY_HIDDEN).ComponentAlignment(ComponentAlignments::Right) - .LabelPosition(LabelPositions::Far).Color(THEME_COLOR))) { + if (CVarCombobox("Triforce Pieces", CVAR_TRACKER_ITEM("DisplayType.TriforcePieces"), displayTypes, + ComboboxOptions() + .DefaultIndex(SECTION_DISPLAY_HIDDEN) + .ComponentAlignment(ComponentAlignments::Right) + .LabelPosition(LabelPositions::Far) + .Color(THEME_COLOR))) { shouldUpdateVectors = true; } - if (CVarCombobox("Boss Souls", CVAR_TRACKER_ITEM("DisplayType.BossSouls"), displayTypes, ComboboxOptions() - .DefaultIndex(SECTION_DISPLAY_HIDDEN).ComponentAlignment(ComponentAlignments::Right) - .LabelPosition(LabelPositions::Far).Color(THEME_COLOR))) { + if (CVarCombobox("Boss Souls", CVAR_TRACKER_ITEM("DisplayType.BossSouls"), displayTypes, + ComboboxOptions() + .DefaultIndex(SECTION_DISPLAY_HIDDEN) + .ComponentAlignment(ComponentAlignments::Right) + .LabelPosition(LabelPositions::Far) + .Color(THEME_COLOR))) { shouldUpdateVectors = true; } - if (CVarCombobox("Ocarina Buttons", CVAR_TRACKER_ITEM("DisplayType.OcarinaButtons"), displayTypes, ComboboxOptions() - .DefaultIndex(SECTION_DISPLAY_HIDDEN).ComponentAlignment(ComponentAlignments::Right) - .LabelPosition(LabelPositions::Far).Color(THEME_COLOR))) { + if (CVarCombobox("Ocarina Buttons", CVAR_TRACKER_ITEM("DisplayType.OcarinaButtons"), displayTypes, + ComboboxOptions() + .DefaultIndex(SECTION_DISPLAY_HIDDEN) + .ComponentAlignment(ComponentAlignments::Right) + .LabelPosition(LabelPositions::Far) + .Color(THEME_COLOR))) { shouldUpdateVectors = true; } - if (CVarCombobox("Overworld Keys", CVAR_TRACKER_ITEM("DisplayType.OverworldKeys"), displayTypes, ComboboxOptions() - .DefaultIndex(SECTION_DISPLAY_HIDDEN).ComponentAlignment(ComponentAlignments::Right) - .LabelPosition(LabelPositions::Far).Color(THEME_COLOR))) { + if (CVarCombobox("Overworld Keys", CVAR_TRACKER_ITEM("DisplayType.OverworldKeys"), displayTypes, + ComboboxOptions() + .DefaultIndex(SECTION_DISPLAY_HIDDEN) + .ComponentAlignment(ComponentAlignments::Right) + .LabelPosition(LabelPositions::Far) + .Color(THEME_COLOR))) { shouldUpdateVectors = true; } - if (CVarCombobox("Fishing Pole", CVAR_TRACKER_ITEM("DisplayType.FishingPole"), extendedDisplayTypes, ComboboxOptions() - .DefaultIndex(SECTION_DISPLAY_EXTENDED_HIDDEN).ComponentAlignment(ComponentAlignments::Right) - .LabelPosition(LabelPositions::Far).Color(THEME_COLOR))) { + if (CVarCombobox("Fishing Pole", CVAR_TRACKER_ITEM("DisplayType.FishingPole"), extendedDisplayTypes, + ComboboxOptions() + .DefaultIndex(SECTION_DISPLAY_EXTENDED_HIDDEN) + .ComponentAlignment(ComponentAlignments::Right) + .LabelPosition(LabelPositions::Far) + .Color(THEME_COLOR))) { shouldUpdateVectors = true; } - if (CVarCombobox("Total Checks", "gTrackers.ItemTracker.TotalChecks.DisplayType", minimalDisplayTypes, ComboboxOptions() - .DefaultIndex(SECTION_DISPLAY_MINIMAL_HIDDEN).ComponentAlignment(ComponentAlignments::Right) - .LabelPosition(LabelPositions::Far).Color(THEME_COLOR))) { + if (CVarCombobox("Total Checks", "gTrackers.ItemTracker.TotalChecks.DisplayType", minimalDisplayTypes, + ComboboxOptions() + .DefaultIndex(SECTION_DISPLAY_MINIMAL_HIDDEN) + .ComponentAlignment(ComponentAlignments::Right) + .LabelPosition(LabelPositions::Far) + .Color(THEME_COLOR))) { shouldUpdateVectors = true; } if (CVarGetInteger(CVAR_TRACKER_ITEM("DisplayType.Main"), TRACKER_DISPLAY_ALWAYS) == TRACKER_DISPLAY_ALWAYS) { - if (CVarCombobox("Personal notes", CVAR_TRACKER_ITEM("DisplayType.Notes"), displayTypes, ComboboxOptions() - .DefaultIndex(SECTION_DISPLAY_HIDDEN).ComponentAlignment(ComponentAlignments::Right) - .LabelPosition(LabelPositions::Far).Color(THEME_COLOR))) { + if (CVarCombobox("Personal notes", CVAR_TRACKER_ITEM("DisplayType.Notes"), displayTypes, + ComboboxOptions() + .DefaultIndex(SECTION_DISPLAY_HIDDEN) + .ComponentAlignment(ComponentAlignments::Right) + .LabelPosition(LabelPositions::Far) + .Color(THEME_COLOR))) { shouldUpdateVectors = true; } } - CVarCheckbox("Show Hookshot Identifiers", CVAR_TRACKER_ITEM("HookshotIdentifier"), CheckboxOptions() - .Tooltip("Shows an 'H' or an 'L' to more easiely distinguish between Hookshot and Longshot.").Color(THEME_COLOR)); + CVarCheckbox("Show Hookshot Identifiers", CVAR_TRACKER_ITEM("HookshotIdentifier"), + CheckboxOptions() + .Tooltip("Shows an 'H' or an 'L' to more easiely distinguish between Hookshot and Longshot.") + .Color(THEME_COLOR)); ImGui::PopStyleVar(1); ImGui::EndTable(); diff --git a/soh/soh/Enhancements/randomizer/randomizer_item_tracker.h b/soh/soh/Enhancements/randomizer/randomizer_item_tracker.h index 5405b1ea2..55f7b8974 100644 --- a/soh/soh/Enhancements/randomizer/randomizer_item_tracker.h +++ b/soh/soh/Enhancements/randomizer/randomizer_item_tracker.h @@ -19,15 +19,11 @@ bool HasSong(ItemTrackerItem); bool HasQuestItem(ItemTrackerItem); bool HasEquipment(ItemTrackerItem); -#define ITEM_TRACKER_ITEM(id, data, drawFunc) \ - { \ - id, #id, #id "_Faded", data, drawFunc \ - } +#define ITEM_TRACKER_ITEM(id, data, drawFunc) \ + { id, #id, #id "_Faded", data, drawFunc } -#define ITEM_TRACKER_ITEM_CUSTOM(id, name, nameFaded, data, drawFunc)\ - { \ - id, #name, #nameFaded "_Faded", data, drawFunc \ - } +#define ITEM_TRACKER_ITEM_CUSTOM(id, name, nameFaded, data, drawFunc) \ + { id, #name, #nameFaded "_Faded", data, drawFunc } typedef struct ItemTrackerDungeon { uint32_t id; @@ -39,9 +35,9 @@ class ItemTrackerSettingsWindow : public Ship::GuiWindow { using GuiWindow::GuiWindow; protected: - void InitElement() override {}; + void InitElement() override{}; void DrawElement() override; - void UpdateElement() override {}; + void UpdateElement() override{}; }; class ItemTrackerWindow : public Ship::GuiWindow { @@ -49,8 +45,8 @@ class ItemTrackerWindow : public Ship::GuiWindow { using GuiWindow::GuiWindow; void Draw() override; -protected: + protected: void InitElement() override; void DrawElement() override; - void UpdateElement() override {}; + void UpdateElement() override{}; }; \ No newline at end of file diff --git a/soh/soh/Enhancements/randomizer/savefile.cpp b/soh/soh/Enhancements/randomizer/savefile.cpp index 049b87f65..4753bb4b4 100644 --- a/soh/soh/Enhancements/randomizer/savefile.cpp +++ b/soh/soh/Enhancements/randomizer/savefile.cpp @@ -106,7 +106,6 @@ void GiveLinksPocketItem() { } } - void SetStartingItems() { if (Randomizer_GetSettingValue(RSK_STARTING_KOKIRI_SWORD)) Item_Give(NULL, ITEM_SWORD_KOKIRI); @@ -174,22 +173,22 @@ void SetStartingItems() { } if (Randomizer_GetSettingValue(RSK_KEYSANITY) == RO_DUNGEON_ITEM_LOC_STARTWITH) { - gSaveContext.inventory.dungeonKeys[SCENE_FOREST_TEMPLE] = FOREST_TEMPLE_SMALL_KEY_MAX; // Forest - gSaveContext.ship.stats.dungeonKeys[SCENE_FOREST_TEMPLE] = FOREST_TEMPLE_SMALL_KEY_MAX; // Forest - gSaveContext.inventory.dungeonKeys[SCENE_FIRE_TEMPLE] = FIRE_TEMPLE_SMALL_KEY_MAX; // Fire - gSaveContext.ship.stats.dungeonKeys[SCENE_FIRE_TEMPLE] = FIRE_TEMPLE_SMALL_KEY_MAX; // Fire - gSaveContext.inventory.dungeonKeys[SCENE_WATER_TEMPLE] = WATER_TEMPLE_SMALL_KEY_MAX; // Water - gSaveContext.ship.stats.dungeonKeys[SCENE_WATER_TEMPLE] = WATER_TEMPLE_SMALL_KEY_MAX; // Water - gSaveContext.inventory.dungeonKeys[SCENE_SPIRIT_TEMPLE] = SPIRIT_TEMPLE_SMALL_KEY_MAX; // Spirit - gSaveContext.ship.stats.dungeonKeys[SCENE_SPIRIT_TEMPLE] = SPIRIT_TEMPLE_SMALL_KEY_MAX; // Spirit - gSaveContext.inventory.dungeonKeys[SCENE_SHADOW_TEMPLE] = SHADOW_TEMPLE_SMALL_KEY_MAX; // Shadow - gSaveContext.ship.stats.dungeonKeys[SCENE_SHADOW_TEMPLE] = SHADOW_TEMPLE_SMALL_KEY_MAX; // Shadow - gSaveContext.inventory.dungeonKeys[SCENE_BOTTOM_OF_THE_WELL] = BOTTOM_OF_THE_WELL_SMALL_KEY_MAX; // BotW - gSaveContext.ship.stats.dungeonKeys[SCENE_BOTTOM_OF_THE_WELL] = BOTTOM_OF_THE_WELL_SMALL_KEY_MAX; // BotW + gSaveContext.inventory.dungeonKeys[SCENE_FOREST_TEMPLE] = FOREST_TEMPLE_SMALL_KEY_MAX; // Forest + gSaveContext.ship.stats.dungeonKeys[SCENE_FOREST_TEMPLE] = FOREST_TEMPLE_SMALL_KEY_MAX; // Forest + gSaveContext.inventory.dungeonKeys[SCENE_FIRE_TEMPLE] = FIRE_TEMPLE_SMALL_KEY_MAX; // Fire + gSaveContext.ship.stats.dungeonKeys[SCENE_FIRE_TEMPLE] = FIRE_TEMPLE_SMALL_KEY_MAX; // Fire + gSaveContext.inventory.dungeonKeys[SCENE_WATER_TEMPLE] = WATER_TEMPLE_SMALL_KEY_MAX; // Water + gSaveContext.ship.stats.dungeonKeys[SCENE_WATER_TEMPLE] = WATER_TEMPLE_SMALL_KEY_MAX; // Water + gSaveContext.inventory.dungeonKeys[SCENE_SPIRIT_TEMPLE] = SPIRIT_TEMPLE_SMALL_KEY_MAX; // Spirit + gSaveContext.ship.stats.dungeonKeys[SCENE_SPIRIT_TEMPLE] = SPIRIT_TEMPLE_SMALL_KEY_MAX; // Spirit + gSaveContext.inventory.dungeonKeys[SCENE_SHADOW_TEMPLE] = SHADOW_TEMPLE_SMALL_KEY_MAX; // Shadow + gSaveContext.ship.stats.dungeonKeys[SCENE_SHADOW_TEMPLE] = SHADOW_TEMPLE_SMALL_KEY_MAX; // Shadow + gSaveContext.inventory.dungeonKeys[SCENE_BOTTOM_OF_THE_WELL] = BOTTOM_OF_THE_WELL_SMALL_KEY_MAX; // BotW + gSaveContext.ship.stats.dungeonKeys[SCENE_BOTTOM_OF_THE_WELL] = BOTTOM_OF_THE_WELL_SMALL_KEY_MAX; // BotW gSaveContext.inventory.dungeonKeys[SCENE_GERUDO_TRAINING_GROUND] = GERUDO_TRAINING_GROUND_SMALL_KEY_MAX; // GTG gSaveContext.ship.stats.dungeonKeys[SCENE_GERUDO_TRAINING_GROUND] = GERUDO_TRAINING_GROUND_SMALL_KEY_MAX; // GTG - gSaveContext.inventory.dungeonKeys[SCENE_INSIDE_GANONS_CASTLE] = GANONS_CASTLE_SMALL_KEY_MAX; // Ganon - gSaveContext.ship.stats.dungeonKeys[SCENE_INSIDE_GANONS_CASTLE] = GANONS_CASTLE_SMALL_KEY_MAX; // Ganon + gSaveContext.inventory.dungeonKeys[SCENE_INSIDE_GANONS_CASTLE] = GANONS_CASTLE_SMALL_KEY_MAX; // Ganon + gSaveContext.ship.stats.dungeonKeys[SCENE_INSIDE_GANONS_CASTLE] = GANONS_CASTLE_SMALL_KEY_MAX; // Ganon } else if (Randomizer_GetSettingValue(RSK_KEYSANITY) == RO_DUNGEON_ITEM_LOC_VANILLA) { // Logic cannot handle vanilla key layout in some dungeons // this is because vanilla expects the dungeon major item to be @@ -203,11 +202,11 @@ void SetStartingItems() { } if (Randomizer_GetSettingValue(RSK_BOSS_KEYSANITY) == RO_DUNGEON_ITEM_LOC_STARTWITH) { - gSaveContext.inventory.dungeonItems[SCENE_FOREST_TEMPLE] |= 1; // Forest - gSaveContext.inventory.dungeonItems[SCENE_FIRE_TEMPLE] |= 1; // Fire - gSaveContext.inventory.dungeonItems[SCENE_WATER_TEMPLE] |= 1; // Water + gSaveContext.inventory.dungeonItems[SCENE_FOREST_TEMPLE] |= 1; // Forest + gSaveContext.inventory.dungeonItems[SCENE_FIRE_TEMPLE] |= 1; // Fire + gSaveContext.inventory.dungeonItems[SCENE_WATER_TEMPLE] |= 1; // Water gSaveContext.inventory.dungeonItems[SCENE_SPIRIT_TEMPLE] |= 1; // Spirit - gSaveContext.inventory.dungeonItems[SCENE_SHADOW_TEMPLE] |= 1; // Shadow + gSaveContext.inventory.dungeonItems[SCENE_SHADOW_TEMPLE] |= 1; // Shadow } if (Randomizer_GetSettingValue(RSK_GANONS_BOSS_KEY) == RO_GANON_BOSS_KEY_STARTWITH) { @@ -288,13 +287,9 @@ extern "C" void Randomizer_InitSaveFile() { gSaveContext.entranceIndex = -1; } - for (auto trialFlag : { EVENTCHKINF_COMPLETED_LIGHT_TRIAL, - EVENTCHKINF_COMPLETED_FOREST_TRIAL, - EVENTCHKINF_COMPLETED_FIRE_TRIAL, - EVENTCHKINF_COMPLETED_WATER_TRIAL, - EVENTCHKINF_COMPLETED_SPIRIT_TRIAL, - EVENTCHKINF_COMPLETED_SHADOW_TRIAL } - ) { + for (auto trialFlag : { EVENTCHKINF_COMPLETED_LIGHT_TRIAL, EVENTCHKINF_COMPLETED_FOREST_TRIAL, + EVENTCHKINF_COMPLETED_FIRE_TRIAL, EVENTCHKINF_COMPLETED_WATER_TRIAL, + EVENTCHKINF_COMPLETED_SPIRIT_TRIAL, EVENTCHKINF_COMPLETED_SHADOW_TRIAL }) { if (!OTRGlobals::Instance->gRandomizer->IsTrialRequired(trialFlag)) { Flags_SetEventChkInf(trialFlag); } diff --git a/soh/soh/Enhancements/randomizer/settings.cpp b/soh/soh/Enhancements/randomizer/settings.cpp index 8ade6a95a..c40f99168 100644 --- a/soh/soh/Enhancements/randomizer/settings.cpp +++ b/soh/soh/Enhancements/randomizer/settings.cpp @@ -13,7 +13,8 @@ namespace Rando { std::shared_ptr Settings::mInstance; -std::vector NumOpts(const int min, const int max, const int step = 1, const std::string& textBefore = {}, const std::string& textAfter = {}) { +std::vector NumOpts(const int min, const int max, const int step = 1, const std::string& textBefore = {}, + const std::string& textAfter = {}) { std::vector options; options.reserve((max - min) / step + 1); for (int i = min; i <= max; i += step) { @@ -24,7 +25,7 @@ std::vector NumOpts(const int min, const int max, const int step = std::vector MultiVecOpts(const std::vector>& optionsVector) { uint32_t totalSize = 0; - for (const auto& vector: optionsVector) { + for (const auto& vector : optionsVector) { totalSize += vector.size(); } std::vector options; @@ -37,11 +38,11 @@ std::vector MultiVecOpts(const std::vector return options; } -void Settings::HandleShopsanityPriceUI(){ +void Settings::HandleShopsanityPriceUI() { bool isTycoon = CVarGetInteger(CVAR_RANDOMIZER_SETTING("IncludeTycoonWallet"), RO_GENERIC_OFF); mOptions[RSK_SHOPSANITY].RemoveFlag(IMFLAG_SEPARATOR_BOTTOM); mOptions[RSK_SHOPSANITY_PRICES].Unhide(); - switch (CVarGetInteger(CVAR_RANDOMIZER_SETTING("ShopsanityPrices"), RO_PRICE_VANILLA)){ + switch (CVarGetInteger(CVAR_RANDOMIZER_SETTING("ShopsanityPrices"), RO_PRICE_VANILLA)) { case RO_PRICE_FIXED: mOptions[RSK_SHOPSANITY_PRICES_FIXED_PRICE].Unhide(); mOptions[RSK_SHOPSANITY_PRICES_RANGE_1].Hide(); @@ -51,7 +52,8 @@ void Settings::HandleShopsanityPriceUI(){ mOptions[RSK_SHOPSANITY_PRICES_ADULT_WALLET_WEIGHT].Hide(); mOptions[RSK_SHOPSANITY_PRICES_GIANT_WALLET_WEIGHT].Hide(); mOptions[RSK_SHOPSANITY_PRICES_TYCOON_WALLET_WEIGHT].Hide(); - if (isTycoon ? mOptions[RSK_SHOPSANITY_PRICES_FIXED_PRICE].GetOptionCount() == 501 : mOptions[RSK_SHOPSANITY_PRICES_FIXED_PRICE].GetOptionCount() == 1000) { + if (isTycoon ? mOptions[RSK_SHOPSANITY_PRICES_FIXED_PRICE].GetOptionCount() == 501 + : mOptions[RSK_SHOPSANITY_PRICES_FIXED_PRICE].GetOptionCount() == 1000) { mOptions[RSK_SHOPSANITY_PRICES_FIXED_PRICE].ChangeOptions(isTycoon ? NumOpts(0, 999) : NumOpts(0, 500)); } mOptions[RSK_SHOPSANITY_PRICES_AFFORDABLE].Hide(); @@ -65,9 +67,12 @@ void Settings::HandleShopsanityPriceUI(){ mOptions[RSK_SHOPSANITY_PRICES_ADULT_WALLET_WEIGHT].Hide(); mOptions[RSK_SHOPSANITY_PRICES_GIANT_WALLET_WEIGHT].Hide(); mOptions[RSK_SHOPSANITY_PRICES_TYCOON_WALLET_WEIGHT].Hide(); - if (isTycoon ? mOptions[RSK_SHOPSANITY_PRICES_RANGE_1].GetOptionCount() == 101 : mOptions[RSK_SHOPSANITY_PRICES_RANGE_1].GetOptionCount() == 200) { - mOptions[RSK_SHOPSANITY_PRICES_RANGE_1].ChangeOptions(isTycoon ? NumOpts(0, 995, 5) : NumOpts(0, 500, 5)); - mOptions[RSK_SHOPSANITY_PRICES_RANGE_2].ChangeOptions(isTycoon ? NumOpts(0, 995, 5) : NumOpts(0, 500, 5)); + if (isTycoon ? mOptions[RSK_SHOPSANITY_PRICES_RANGE_1].GetOptionCount() == 101 + : mOptions[RSK_SHOPSANITY_PRICES_RANGE_1].GetOptionCount() == 200) { + mOptions[RSK_SHOPSANITY_PRICES_RANGE_1].ChangeOptions(isTycoon ? NumOpts(0, 995, 5) + : NumOpts(0, 500, 5)); + mOptions[RSK_SHOPSANITY_PRICES_RANGE_2].ChangeOptions(isTycoon ? NumOpts(0, 995, 5) + : NumOpts(0, 500, 5)); } mOptions[RSK_SHOPSANITY_PRICES_AFFORDABLE].Unhide(); break; @@ -79,7 +84,7 @@ void Settings::HandleShopsanityPriceUI(){ mOptions[RSK_SHOPSANITY_PRICES_CHILD_WALLET_WEIGHT].Unhide(); mOptions[RSK_SHOPSANITY_PRICES_ADULT_WALLET_WEIGHT].Unhide(); mOptions[RSK_SHOPSANITY_PRICES_GIANT_WALLET_WEIGHT].Unhide(); - if (isTycoon){ + if (isTycoon) { mOptions[RSK_SHOPSANITY_PRICES_TYCOON_WALLET_WEIGHT].Unhide(); } else { mOptions[RSK_SHOPSANITY_PRICES_TYCOON_WALLET_WEIGHT].Hide(); @@ -335,211 +340,796 @@ void Settings::CreateOptions() { mExcludeLocationsOptionsAreas.reserve(RCAREA_INVALID); // the following are glitches and are currently disabled - // OPT_TRICK(RT_ACUTE_ANGLE_CLIP, RCQUEST_BOTH, RA_NONE, {Tricks::Tag::ADVANCED, Tricks::Tag::EXPERIMENTAL, Tricks::Tag::GLITCH}, "Acute angle clip", "Enables locations requiring jumpslash clips through walls which meet at an acute angle."); - // OPT_TRICK(RT_ADVANCED_CLIPS, RCQUEST_BOTH, RA_NONE, {Tricks::Tag::ADVANCED, Tricks::Tag::EXPERIMENTAL, Tricks::Tag::GLITCH}, "Advanced clips", "Enables locations requiring clips through walls and objects requiring precise jumps or other tricks."); - // OPT_TRICK(RT_BLANK_A, RCQUEST_BOTH, RA_NONE, {Tricks::Tag::ADVANCED, Tricks::Tag::EXPERIMENTAL, Tricks::Tag::GLITCH}, "Blank A", "Enables locations requiring blank A button; NOTE: this requires the 'Quick Putaway' restoration."); - // OPT_TRICK(RT_DOOM_JUMP, RCQUEST_BOTH, RA_NONE, {Tricks::Tag::ADVANCED, Tricks::Tag::EXPERIMENTAL, Tricks::Tag::GLITCH}, "Doom Jump", "Enables locations requiring doom jumps."); - // OPT_TRICK(RT_EPG, RCQUEST_BOTH, RA_NONE, {Tricks::Tag::ADVANCED, Tricks::Tag::EXPERIMENTAL, Tricks::Tag::GLITCH}, "EPG", "Enables locations requiring use of the Entrance Point Glitch."); - // OPT_TRICK(RT_EQUIP_SWAP, RCQUEST_BOTH, RA_NONE, {Tricks::Tag::ADVANCED, Tricks::Tag::EXPERIMENTAL, Tricks::Tag::GLITCH}, "Equip Swap", "Enables locations requiring use of equip swap; NOTE: this may expect the 'Allow cursor to be over any slot' enhancement to be turned off."); - // OPT_TRICK(RT_EQUIP_SWAP_EXPECTS_DINS, RCQUEST_BOTH, RA_NONE, {Tricks::Tag::ADVANCED, Tricks::Tag::EXPERIMENTAL, Tricks::Tag::GLITCH}, "Equip Swap Require's Din's Fire", "Enables locations requiring use of equip swap once Din's Fire is found."); - // OPT_TRICK(RT_FLAME_STORAGE, RCQUEST_BOTH, RA_NONE, {Tricks::Tag::ADVANCED, Tricks::Tag::EXPERIMENTAL, Tricks::Tag::GLITCH}, "Flame Storage", "Enables locations requiring flame storage."); - // OPT_TRICK(RT_GROUND_CLIP, RCQUEST_BOTH, RA_NONE, {Tricks::Tag::ADVANCED, Tricks::Tag::EXPERIMENTAL, Tricks::Tag::GLITCH}, "Ground Clip", "Enables locations requiring ground clips."); - // OPT_TRICK(RT_GROUND_JUMP, RCQUEST_BOTH, RA_NONE, {Tricks::Tag::ADVANCED, Tricks::Tag::EXPERIMENTAL, Tricks::Tag::GLITCH}, "Ground Jump", "Enables locations requiring ground jumps."); - // OPT_TRICK(RT_HESS, RCQUEST_BOTH, RA_NONE, {Tricks::Tag::ADVANCED, Tricks::Tag::EXPERIMENTAL, Tricks::Tag::GLITCH}, "HESS", "Enables locations requiring a Hyper Extended Super Slide."); - // OPT_TRICK(RT_HOOKSHOT_CLIP, RCQUEST_BOTH, RA_NONE, {Tricks::Tag::ADVANCED, Tricks::Tag::EXPERIMENTAL, Tricks::Tag::GLITCH}, "Hookshot Clip", "Enables locations requiring Hookshot clips."); - // OPT_TRICK(RT_HOOKSHOT_JUMP, RCQUEST_BOTH, RA_NONE, {Tricks::Tag::ADVANCED, Tricks::Tag::EXPERIMENTAL, Tricks::Tag::GLITCH}, "Hookshot Jump", "Enables locations requiring Hookshot jumps."); - // OPT_TRICK(RT_ISG, RCQUEST_BOTH, RA_NONE, {Tricks::Tag::ADVANCED, Tricks::Tag::EXPERIMENTAL, Tricks::Tag::GLITCH}, "ISG", "Enables locations requiring use of the infinite sword glitch."); + // OPT_TRICK(RT_ACUTE_ANGLE_CLIP, RCQUEST_BOTH, RA_NONE, {Tricks::Tag::ADVANCED, Tricks::Tag::EXPERIMENTAL, + // Tricks::Tag::GLITCH}, "Acute angle clip", "Enables locations requiring jumpslash clips through walls which meet + // at an acute angle."); OPT_TRICK(RT_ADVANCED_CLIPS, RCQUEST_BOTH, RA_NONE, {Tricks::Tag::ADVANCED, + // Tricks::Tag::EXPERIMENTAL, Tricks::Tag::GLITCH}, "Advanced clips", "Enables locations requiring clips through + // walls and objects requiring precise jumps or other tricks."); OPT_TRICK(RT_BLANK_A, RCQUEST_BOTH, RA_NONE, + // {Tricks::Tag::ADVANCED, Tricks::Tag::EXPERIMENTAL, Tricks::Tag::GLITCH}, "Blank A", "Enables locations requiring + // blank A button; NOTE: this requires the 'Quick Putaway' restoration."); OPT_TRICK(RT_DOOM_JUMP, RCQUEST_BOTH, + // RA_NONE, {Tricks::Tag::ADVANCED, Tricks::Tag::EXPERIMENTAL, Tricks::Tag::GLITCH}, "Doom Jump", "Enables locations + // requiring doom jumps."); OPT_TRICK(RT_EPG, RCQUEST_BOTH, RA_NONE, {Tricks::Tag::ADVANCED, + // Tricks::Tag::EXPERIMENTAL, Tricks::Tag::GLITCH}, "EPG", "Enables locations requiring use of the Entrance Point + // Glitch."); OPT_TRICK(RT_EQUIP_SWAP, RCQUEST_BOTH, RA_NONE, {Tricks::Tag::ADVANCED, Tricks::Tag::EXPERIMENTAL, + // Tricks::Tag::GLITCH}, "Equip Swap", "Enables locations requiring use of equip swap; NOTE: this may expect the + // 'Allow cursor to be over any slot' enhancement to be turned off."); OPT_TRICK(RT_EQUIP_SWAP_EXPECTS_DINS, + // RCQUEST_BOTH, RA_NONE, {Tricks::Tag::ADVANCED, Tricks::Tag::EXPERIMENTAL, Tricks::Tag::GLITCH}, "Equip Swap + // Require's Din's Fire", "Enables locations requiring use of equip swap once Din's Fire is found."); + // OPT_TRICK(RT_FLAME_STORAGE, RCQUEST_BOTH, RA_NONE, {Tricks::Tag::ADVANCED, Tricks::Tag::EXPERIMENTAL, + // Tricks::Tag::GLITCH}, "Flame Storage", "Enables locations requiring flame storage."); OPT_TRICK(RT_GROUND_CLIP, + // RCQUEST_BOTH, RA_NONE, {Tricks::Tag::ADVANCED, Tricks::Tag::EXPERIMENTAL, Tricks::Tag::GLITCH}, "Ground Clip", + // "Enables locations requiring ground clips."); OPT_TRICK(RT_GROUND_JUMP, RCQUEST_BOTH, RA_NONE, + // {Tricks::Tag::ADVANCED, Tricks::Tag::EXPERIMENTAL, Tricks::Tag::GLITCH}, "Ground Jump", "Enables locations + // requiring ground jumps."); OPT_TRICK(RT_HESS, RCQUEST_BOTH, RA_NONE, {Tricks::Tag::ADVANCED, + // Tricks::Tag::EXPERIMENTAL, Tricks::Tag::GLITCH}, "HESS", "Enables locations requiring a Hyper Extended Super + // Slide."); OPT_TRICK(RT_HOOKSHOT_CLIP, RCQUEST_BOTH, RA_NONE, {Tricks::Tag::ADVANCED, Tricks::Tag::EXPERIMENTAL, + // Tricks::Tag::GLITCH}, "Hookshot Clip", "Enables locations requiring Hookshot clips."); + // OPT_TRICK(RT_HOOKSHOT_JUMP, RCQUEST_BOTH, RA_NONE, {Tricks::Tag::ADVANCED, Tricks::Tag::EXPERIMENTAL, + // Tricks::Tag::GLITCH}, "Hookshot Jump", "Enables locations requiring Hookshot jumps."); OPT_TRICK(RT_ISG, + // RCQUEST_BOTH, RA_NONE, {Tricks::Tag::ADVANCED, Tricks::Tag::EXPERIMENTAL, Tricks::Tag::GLITCH}, "ISG", "Enables + // locations requiring use of the infinite sword glitch."); - OPT_TRICK(RT_VISIBLE_COLLISION, RCQUEST_BOTH, RA_NONE, {Tricks::Tag::NOVICE}, "Pass Through Visible One-Way Collision", "Allows climbing through the platform to reach Impa's House Back as adult with no items and going through the Kakariko Village Gate as child when coming from the Mountain Trail side."); - OPT_TRICK(RT_GROTTOS_WITHOUT_AGONY, RCQUEST_BOTH, RA_NONE, {Tricks::Tag::NOVICE}, "Hidden Grottos without Stone of Agony", "Allows entering hidden grottos without the Stone of Agony."); - OPT_TRICK(RT_FEWER_TUNIC_REQUIREMENTS, RCQUEST_BOTH, RA_NONE, {Tricks::Tag::INTERMEDIATE}, "Fewer Tunic Requirements", "Allows the following possible without Tunics:\n- Enter Water Temple. The area below the center pillar still requires Zora Tunic. Applies to MQ also.\n- Enter Fire Temple. Volvagia still requires Goron Tunic. Applies to MQ also, and includes child access to first floor with dungeon shuffle."); - OPT_TRICK(RT_RUSTED_SWITCHES, RCQUEST_BOTH, RA_NONE, {Tricks::Tag::NOVICE}, "Hammer Rusted Switches Through Walls", "Applies to:\n- Fire Temple Highest Goron Chest.\n- MQ Fire Temple Lizalfos Maze.\n- MQ Spirit Trial."); - OPT_TRICK(RT_FLAMING_CHESTS, RCQUEST_BOTH, RA_NONE, {Tricks::Tag::INTERMEDIATE}, "Flaming Chests", "The chests encircled in flames in Gerudo Training Ground and in Spirit Temple can be opened by running into the flames while Link is invincible after taking damage."); - // disabled for now, can't check for being able to use bunny hood & bunny hood speedup is currently completely decoupled from rando - // OPT_TRICK(RT_BUNNY_HOOD_JUMPS, RCQUEST_BOTH, RA_NONE, {Tricks::Tag::ADVANCED}, "Bunny Hood Jumps", "Allows reaching locations using Bunny Hood's extended jumps."); - OPT_TRICK(RT_DAMAGE_BOOST_SIMPLE, RCQUEST_BOTH, RA_NONE, {Tricks::Tag::ADVANCED, Tricks::Tag::EXPERIMENTAL}, "Simple damage boosts", "Allows damage boosts in order to reach further locations. Can be combined with \"Simple hover boosts\" for reaching far distances."); - OPT_TRICK(RT_HOVER_BOOST_SIMPLE, RCQUEST_BOTH, RA_NONE, {Tricks::Tag::ADVANCED, Tricks::Tag::EXPERIMENTAL}, "Simple hover boosts", "Allows equipping of hover boots when link is moving at high speeds to extend distance covered. Can be combined with \"Simple damage boosts\" for greater uses."); - OPT_TRICK(RT_BOMBCHU_BEEHIVES, RCQUEST_BOTH, RA_NONE, {Tricks::Tag::NOVICE}, "Bombchu Beehives", "Allows exploding beehives with Bombchus."); - OPT_TRICK(RT_BLUE_FIRE_MUD_WALLS, RCQUEST_BOTH, RA_NONE, {Tricks::Tag::NOVICE}, "Break Mud Walls with Blue Fire", "Use Blue Fire to break mud walls."); - OPT_TRICK(RT_KF_ADULT_GS, RCQUEST_BOTH, RA_KOKIRI_FOREST, {Tricks::Tag::NOVICE}, "Adult Kokiri Forest GS with Hover Boots", "Can be obtained without Hookshot by using the Hover Boots off of one of the roots."); - OPT_TRICK(RT_LW_BRIDGE, RCQUEST_BOTH, RA_THE_LOST_WOODS, {Tricks::Tag::EXPERT}, "Jump onto the Lost Woods Bridge as Adult with Nothing", "With very precise movement it's possible for adult to jump onto the bridge without needing Longshot, Hover Boots, or Bean."); - OPT_TRICK(RT_LW_MIDO_BACKFLIP, RCQUEST_BOTH, RA_THE_LOST_WOODS, {Tricks::Tag::NOVICE}, "Backflip over Mido as Adult", "With a specific position and angle, you can backflip over Mido."); - OPT_TRICK(RT_LW_GS_BEAN, RCQUEST_BOTH, RA_THE_LOST_WOODS, {Tricks::Tag::INTERMEDIATE}, "Lost Woods Adult GS without Bean", "You can collect the token with a precise Hookshot use, as long as you can kill the Skulltula somehow first. It can be killed using Longshot, Bow, Bombchus or Din's Fire."); - OPT_TRICK(RT_HC_STORMS_GS, RCQUEST_BOTH, RA_HYRULE_CASTLE, {Tricks::Tag::INTERMEDIATE}, "Hyrule Castle Storms Grotto GS with Just Boomerang", "With precise throws, the Boomerang alone can kill the Skulltula and collect the token, without first needing to blow up the wall."); - OPT_TRICK(RT_KAK_MAN_ON_ROOF, RCQUEST_BOTH, RA_KAKARIKO_VILLAGE, {Tricks::Tag::NOVICE}, "Man on Roof without Hookshot", "Can be reached by side-hopping off the watchtower as either age, or by jumping onto the potion shop's roof from the ledge as adult."); - OPT_TRICK(RT_KAK_TOWER_GS, RCQUEST_BOTH, RA_KAKARIKO_VILLAGE, {Tricks::Tag::INTERMEDIATE}, "Kakariko Tower GS with Jump Slash", "Climb the tower as high as you can without touching the Gold Skulltula, then let go and jump slash immediately. By jump-slashing from as low on the ladder as possible to still hit the Skulltula, this trick can be done without taking fall damage."); - OPT_TRICK(RT_KAK_ADULT_WINDMILL_POH, RCQUEST_BOTH, RA_KAKARIKO_VILLAGE, {Tricks::Tag::NOVICE}, "Windmill PoH as Adult with Nothing", "Can jump up to the spinning platform from below as adult."); - OPT_TRICK(RT_KAK_CHILD_WINDMILL_POH, RCQUEST_BOTH, RA_KAKARIKO_VILLAGE, {Tricks::Tag::EXTREME}, "Windmill PoH as Child with Precise Jump Slash", "Can jump up to the spinning platform from below as child with a precise jumpslash timed with the platforms rotation."); - OPT_TRICK(RT_KAK_ROOFTOP_GS, RCQUEST_BOTH, RA_KAKARIKO_VILLAGE, {Tricks::Tag::ADVANCED}, "Kakariko Rooftop GS with Hover Boots", "Take the Hover Boots from the entrance to Impa's House over to the rooftop of Skulltula House. From there, a precise Hover Boots backwalk with backflip can be used to get onto a hill above the side of the village. And then from there you can Hover onto Impa's rooftop to kill the Skulltula and backflip into the token."); - OPT_TRICK(RT_GY_POH, RCQUEST_BOTH, RA_THE_GRAVEYARD, {Tricks::Tag::INTERMEDIATE}, "Graveyard Freestanding PoH with Boomerang", "Using a precise moving setup you can obtain the Piece of Heart by having the Boomerang interact with it along the return path."); - OPT_TRICK(RT_GY_CHILD_DAMPE_RACE_POH, RCQUEST_BOTH, RA_THE_GRAVEYARD, {Tricks::Tag::NOVICE}, "Second Dampe Race as Child", "It is possible to complete the second dampe race as child in under a minute, but it is a strict time limit."); - OPT_TRICK(RT_GY_SHADOW_FIRE_ARROWS, RCQUEST_BOTH, RA_THE_GRAVEYARD, {Tricks::Tag::EXPERT}, "Shadow Temple Entry with Fire Arrows", "It is possible to light all of the torches to open the Shadow Temple entrance with just Fire Arrows, but you must be very quick, precise, and strategic with how you take your shots."); - OPT_TRICK(RT_DMT_SOIL_GS, RCQUEST_BOTH, RA_DEATH_MOUNTAIN_TRAIL, {Tricks::Tag::INTERMEDIATE}, "Death Mountain Trail Soil GS without Destroying Boulder", "Bugs will go into the soft soil even while the boulder is still blocking the entrance. Then, using a precise moving setup you can kill the Gold Skulltula and obtain the token by having the Boomerang interact with it along the return path."); - OPT_TRICK(RT_DMT_BOMBABLE, RCQUEST_BOTH, RA_DEATH_MOUNTAIN_TRAIL, {Tricks::Tag::INTERMEDIATE}, "Death Mountain Trail Chest with Strength", "Child Link can blow up the wall using a nearby bomb flower. You must backwalk with the flower and then quickly throw it toward the wall."); - OPT_TRICK(RT_DMT_HOOKSHOT_LOWER_GS, RCQUEST_BOTH, RA_DEATH_MOUNTAIN_TRAIL, {Tricks::Tag::INTERMEDIATE}, "Death Mountain Trail Lower Red Rock GS with Hookshot", "After killing the Skulltula, the token can be fished out of the rock without needing to destroy it, by using the Hookshot in the correct way."); - OPT_TRICK(RT_DMT_HOVERS_LOWER_GS, RCQUEST_BOTH, RA_DEATH_MOUNTAIN_TRAIL, {Tricks::Tag::ADVANCED}, "Death Mountain Trail Lower Red Rock GS with Hover Boots", "After killing the Skulltula, the token can be collected without needing to destroy the rock by backflipping down onto it with the Hover Boots. First use the Hover Boots to stand on a nearby fence, and go for the Skulltula Token from there."); - OPT_TRICK(RT_DMT_BEAN_LOWER_GS, RCQUEST_BOTH, RA_DEATH_MOUNTAIN_TRAIL, {Tricks::Tag::EXPERT}, "Death Mountain Trail Lower Red Rock GS with Magic Bean", "After killing the Skulltula, the token can be collected without needing to destroy the rock by jumping down onto it from the bean plant, midflight, with precise timing and positioning."); - OPT_TRICK(RT_DMT_JS_LOWER_GS, RCQUEST_BOTH, RA_DEATH_MOUNTAIN_TRAIL, {Tricks::Tag::INTERMEDIATE}, "Death Mountain Trail Lower Red Rock GS with Jump Slash", "After killing the Skulltula, the token can be collected without needing to destroy the rock by jump slashing from a precise angle."); - OPT_TRICK(RT_DMT_CLIMB_HOVERS, RCQUEST_BOTH, RA_DEATH_MOUNTAIN_TRAIL, {Tricks::Tag::ADVANCED}, "Death Mountain Trail Climb with Hover Boots", "It is possible to use the Hover Boots to bypass needing to destroy the boulders blocking the path to the top of Death Mountain."); - OPT_TRICK(RT_DMT_UPPER_GS, RCQUEST_BOTH, RA_DEATH_MOUNTAIN_TRAIL, {Tricks::Tag::NOVICE}, "Death Mountain Trail Upper Red Rock GS without Hammer", "After killing the Skulltula, the token can be collected by backflipping into the rock at the correct angle."); - // disabled for now, only applies when trade quest is not shuffled so there's a timer (currently not considered in logic) - // OPT_TRICK(RT_DMT_BOLERO_BIGGORON, RCQUEST_BOTH, RA_DEATH_MOUNTAIN_TRAIL, {Tricks::Tag::INTERMEDIATE}, "Deliver Eye Drops with Bolero of Fire", "Playing a warp song normally causes a trade item to spoil immediately, however, it is possible use Bolero to reach Biggoron and still deliver the Eye Drops before they spoil. If you do not wear the Goron Tunic, the heat timer inside the crater will override the trade item\'s timer. When you exit to Death Mountain Trail you will have one second to show the Eye Drops before they expire. You can get extra time to show the Eye Drops if you warp immediately upon receiving them. If you don't have many hearts, you may have to reset the heat timer by quickly dipping in and out of Darunia\'s chamber or quickly equipping and unequipping the Goron Tunic. This trick does not apply if \"Randomize Warp Song Destinations\" is enabled, or if the settings are such that trade items do not need to be delivered within a time limit."); - OPT_TRICK(RT_GC_POT, RCQUEST_BOTH, RA_GORON_CITY, {Tricks::Tag::ADVANCED}, "Goron City Spinning Pot PoH with Bombchu", "A Bombchu can be used to stop the spinning pot, but it can be quite finicky to get it to work."); - OPT_TRICK(RT_GC_POT_STRENGTH, RCQUEST_BOTH, RA_GORON_CITY, {Tricks::Tag::INTERMEDIATE}, "Goron City Spinning Pot PoH with Strength", "Allows for stopping the Goron City Spinning Pot using a Bomb Flower alone, requiring strength in lieu of inventory explosives."); - OPT_TRICK(RT_GC_ROLLING_STRENGTH, RCQUEST_BOTH, RA_GORON_CITY, {Tricks::Tag::INTERMEDIATE}, "Rolling Goron (Hot Rodder Goron) as Child with Strength", "Use the Bomb Flower on the stairs or near Medigoron. Timing is tight, especially without backwalking."); - OPT_TRICK(RT_GC_LEFTMOST, RCQUEST_BOTH, RA_GORON_CITY, {Tricks::Tag::ADVANCED}, "Goron City Maze Left Chest with Hover Boots", "A precise backwalk starting from on top of the crate and ending with a precisely-timed backflip can reach this chest without needing either the Hammer or Silver Gauntlets."); - OPT_TRICK(RT_GC_GROTTO, RCQUEST_BOTH, RA_GORON_CITY, {Tricks::Tag::ADVANCED}, "Goron City Grotto with Hookshot While Taking Damage", "It is possible to reach the Goron City Grotto by quickly using the Hookshot while in the midst of taking damage from the lava floor."); - OPT_TRICK(RT_GC_LINK_GORON_DINS, RCQUEST_BOTH, RA_GORON_CITY, {Tricks::Tag::NOVICE}, "Stop Link the Goron with Din\'s Fire", "The timing is quite awkward."); - OPT_TRICK(RT_DMC_HOVER_BEAN_POH, RCQUEST_BOTH, RA_DEATH_MOUNTAIN_CRATER, {Tricks::Tag::NOVICE}, "Crater\'s Bean PoH with Hover Boots", "Hover from the base of the bridge near Goron City and walk up the very steep slope."); - OPT_TRICK(RT_DMC_BOLERO_JUMP, RCQUEST_BOTH, RA_DEATH_MOUNTAIN_CRATER, {Tricks::Tag::EXTREME}, "Death Mountain Crater Jump to Bolero", "As Adult, using a shield to drop a pot while you have the perfect speed and position, the pot can push you that little extra distance you need to jump across the gap in the bridge."); - OPT_TRICK(RT_DMC_BOULDER_JS, RCQUEST_BOTH, RA_DEATH_MOUNTAIN_CRATER, {Tricks::Tag::NOVICE}, "Death Mountain Crater Upper to Lower with Hammer", "With the Hammer, you can jump slash the rock twice in the same jump in order to destroy it before you fall into the lava."); - OPT_TRICK(RT_DMC_BOULDER_SKIP, RCQUEST_BOTH, RA_DEATH_MOUNTAIN_CRATER, {Tricks::Tag::INTERMEDIATE}, "Death Mountain Crater Upper to Lower Boulder Skip", "As adult, With careful positioning, you can jump to the ledge where the boulder is, then use repeated ledge grabs to shimmy to a climbable ledge. This trick supersedes \"Death Mountain Crater Upper to Lower with Hammer\"."); - OPT_TRICK(RT_ZR_LOWER, RCQUEST_BOTH, RA_ZORAS_RIVER, {Tricks::Tag::INTERMEDIATE}, "Zora\'s River Lower Freestanding PoH as Adult with Nothing", "Adult can reach this PoH with a precise jump, no Hover Boots required."); - OPT_TRICK(RT_ZR_UPPER, RCQUEST_BOTH, RA_ZORAS_RIVER, {Tricks::Tag::INTERMEDIATE}, "Zora\'s River Upper Freestanding PoH as Adult with Nothing", "Adult can reach this PoH with a precise jump, no Hover Boots required."); - OPT_TRICK(RT_ZR_HOVERS, RCQUEST_BOTH, RA_ZORAS_RIVER, {Tricks::Tag::NOVICE}, "Zora\'s Domain Entry with Hover Boots", "Can hover behind the waterfall as adult."); - OPT_TRICK(RT_ZR_CUCCO, RCQUEST_BOTH, RA_ZORAS_RIVER, {Tricks::Tag::NOVICE}, "Zora\'s Domain Entry with Cucco", "You can fly behind the waterfall with a Cucco as child."); - OPT_TRICK(RT_ZD_KING_ZORA_SKIP, RCQUEST_BOTH, RA_ZORAS_DOMAIN, {Tricks::Tag::INTERMEDIATE}, "Skip King Zora as Adult with Nothing", "With a precise jump as adult, it is possible to get on the fence next to King Zora from the front to access Zora's Fountain."); - OPT_TRICK(RT_ZD_GS, RCQUEST_BOTH, RA_ZORAS_DOMAIN, {Tricks::Tag::INTERMEDIATE}, "Zora\'s Domain GS with No Additional Items", "A precise jump slash can kill the Skulltula and recoil back onto the top of the frozen waterfall. To kill it, the logic normally guarantees one of Hookshot, Bow, or Magic."); - OPT_TRICK(RT_ZF_GREAT_FAIRY_WITHOUT_EXPLOSIVES, RCQUEST_BOTH, RA_ZORAS_FOUNTAIN, {Tricks::Tag::NOVICE}, "Zora\'s Fountain Great Fairy Without Explosives", "It's possible to use silver gauntlets to pick up the silver rock and hammer to break the rock below it, allowing you to ledge grab the edge of the hole and get past the breakable wall (hammer can't break the wall itself)."); - OPT_TRICK(RT_LH_LAB_WALL_GS, RCQUEST_BOTH, RA_LAKE_HYLIA, {Tricks::Tag::NOVICE}, "Lake Hylia Lab Wall GS with Jump Slash", "The jump slash to actually collect the token is somewhat precise."); - OPT_TRICK(RT_LH_LAB_DIVING, RCQUEST_BOTH, RA_LAKE_HYLIA, {Tricks::Tag::NOVICE}, "Lake Hylia Lab Dive without Gold Scale", "Remove the Iron Boots in the midst of Hookshotting the underwater crate."); - OPT_TRICK(RT_LH_WATER_HOOKSHOT, RCQUEST_BOTH, RA_LAKE_HYLIA, {Tricks::Tag::INTERMEDIATE}, "Water Temple Entry without Iron Boots using Hookshot", "When entering Water Temple using Gold Scale instead of Iron Boots, the Longshot is usually used to be able to hit the switch and open the gate. But, by standing in a particular spot, the switch can be hit with only the reach of the Hookshot."); - OPT_TRICK(RT_GV_CRATE_HOVERS, RCQUEST_BOTH, RA_GERUDO_VALLEY, {Tricks::Tag::INTERMEDIATE}, "Gerudo Valley Crate PoH as Adult with Hover Boots", "From the far side of Gerudo Valley, a precise Hover Boots movement and jump-slash recoil can allow adult to reach the ledge with the crate PoH without needing Longshot. You will take fall damage."); - OPT_TRICK(RT_GF_KITCHEN, RCQUEST_BOTH, RA_GERUDO_FORTRESS, {Tricks::Tag::NOVICE}, "Thieves\' Hideout \"Kitchen\" with No Additional Items", "Allows passing through the kitchen by avoiding being seen by the guards. The logic normally guarantees Bow or Hookshot to stun them from a distance, or Hover Boots to cross the room without needing to deal with the guards."); - OPT_TRICK(RT_GF_JUMP, RCQUEST_BOTH, RA_GERUDO_FORTRESS, {Tricks::Tag::NOVICE}, "Gerudo\'s Fortress Ledge Jumps", "Adult can jump onto the top roof of the fortress without going through the interior of the hideout."); - OPT_TRICK(RT_GF_WARRIOR_WITH_DIFFICULT_WEAPON, RCQUEST_BOTH, RA_GERUDO_FORTRESS, {Tricks::Tag::NOVICE}, "Gerudo\'s Fortress Warriors with Difficult Weapons", "Warriors can be defeated with Slingshot or Bombchus."); - // disabled for now, can't check for being able to use bunny hood & bunny hood speedup is currently completely decoupled from rando - // OPT_TRICK(RT_HW_BUNNY_CROSSING, RCQUEST_BOTH, RA_HAUNTED_WASTELAND, {Tricks::Tag::NOVICE}, "Wasteland Crossing with Bunny Hood", "You can beat the quicksand by using the increased speed of the Bunny Hood. Note that jumping to the carpet merchant as child typically requires a fairly precise jump slash."); - OPT_TRICK(RT_HW_CROSSING, RCQUEST_BOTH, RA_HAUNTED_WASTELAND, {Tricks::Tag::INTERMEDIATE}, "Wasteland Crossing without Hover Boots or Longshot", "You can beat the quicksand by backwalking across it in a specific way. Note that jumping to the carpet merchant as child typically requires a fairly precise jump slash."); - OPT_TRICK(RT_LENS_HW, RCQUEST_BOTH, RA_HAUNTED_WASTELAND, {Tricks::Tag::INTERMEDIATE}, "Lensless Wasteland", "By memorizing the path, you can travel through the Wasteland without using the Lens of Truth to see the Poe. The equivalent trick for going in reverse through the Wasteland is \"Reverse Wasteland\"."); - OPT_TRICK(RT_HW_REVERSE, RCQUEST_BOTH, RA_HAUNTED_WASTELAND, {Tricks::Tag::INTERMEDIATE}, "Reverse Wasteland", "By memorizing the path, you can travel through the Wasteland in reverse. Note that jumping to the carpet merchant as child typically requires a fairly precise jump slash. The equivalent trick for going forward through the Wasteland is \"Lensless Wasteland\". To cross the river of sand with no additional items, be sure to also enable \"Wasteland Crossing without Hover Boots or Longshot\". Unless all overworld entrances are randomized, Child Link will not be expected to do anything at Gerudo's Fortress."); - OPT_TRICK(RT_COLOSSUS_GS, RCQUEST_BOTH, RA_DESERT_COLOSSUS, {Tricks::Tag::NOVICE}, "Colossus Hill GS with Hookshot", "Somewhat precise. If you kill enough Leevers you can get enough of a break to take some time to aim more carefully."); - OPT_TRICK(RT_DEKU_BASEMENT_GS, RCQUEST_VANILLA, RA_DEKU_TREE, {Tricks::Tag::NOVICE}, "Deku Tree Basement Vines GS with Jump Slash", "Can be defeated by doing a precise jump slash."); - OPT_TRICK(RT_DEKU_B1_SKIP, RCQUEST_BOTH, RA_DEKU_TREE, {Tricks::Tag::INTERMEDIATE}, "Deku Tree Basement without Slingshot", "A precise jump can be used to skip needing to use the Slingshot to go around B1 of the Deku Tree. If used with the \"Closed Forest\" setting, a Slingshot will not be guaranteed to exist somewhere inside the Forest. This trick applies to both Vanilla and Master Quest."); - OPT_TRICK(RT_DEKU_B1_BOW_WEBS, RCQUEST_VANILLA, RA_DEKU_TREE, {Tricks::Tag::NOVICE}, "Deku Tree Basement Web to Gohma with Bow", "All spider web walls in the Deku Tree basement can be burnt as adult with just a bow by shooting through torches. This trick only applies to the circular web leading to Gohma; the two vertical webs are always in logic. Backflip onto the chest near the torch at the bottom of the vine wall. With precise positioning you can shoot through the torch to the right edge of the circular web. This allows completion of adult Deku Tree with no fire source."); - OPT_TRICK(RT_DEKU_B1_BACKFLIP_OVER_SPIKED_LOG, RCQUEST_VANILLA, RA_DEKU_TREE, {Tricks::Tag::NOVICE}, "Deku Tree Basement Backflip over Spiked Log", "Allows backflipping over the spiked log in the Deku Tree basement in Vanilla. Only relevant if \"Shuffle Swim\" is enabled."); - OPT_TRICK(RT_DEKU_MQ_COMPASS_GS, RCQUEST_MQ, RA_DEKU_TREE, {Tricks::Tag::NOVICE}, "Deku Tree MQ Compass Room GS Boulders with Just Hammer", "Climb to the top of the vines, then let go and jump slash immediately to destroy the boulders using the Hammer, without needing to spawn a Song of Time block."); - OPT_TRICK(RT_DEKU_MQ_LOG, RCQUEST_MQ, RA_DEKU_TREE, {Tricks::Tag::NOVICE}, "Deku Tree MQ Roll Under the Spiked Log", "You can get past the spiked log by rolling to briefly shrink your hitbox. As adult, the timing is a bit more precise."); - OPT_TRICK(RT_DC_SCARECROW_GS, RCQUEST_VANILLA, RA_DODONGOS_CAVERN, {Tricks::Tag::NOVICE}, "Dodongo\'s Cavern Scarecrow GS with Armos Statue", "You can jump off an Armos Statue to reach the alcove with the Gold Skulltula. It takes quite a long time to pull the statue the entire way. The jump to the alcove can be a bit picky when done as child."); - OPT_TRICK(RT_DC_VINES_GS, RCQUEST_VANILLA, RA_DODONGOS_CAVERN, {Tricks::Tag::NOVICE}, "Dodongo\'s Cavern Vines GS from Below with Longshot", "The vines upon which this Skulltula rests are one-sided collision. You can use the Longshot to get it from below, by shooting it through the vines, bypassing the need to lower the staircase."); - OPT_TRICK(RT_DC_STAIRCASE, RCQUEST_VANILLA, RA_DODONGOS_CAVERN, {Tricks::Tag::NOVICE}, "Dodongo\'s Cavern Staircase with Bow", "The Bow can be used to knock down the stairs with two well-timed shots."); - OPT_TRICK(RT_DC_SLINGSHOT_SKIP, RCQUEST_VANILLA, RA_DODONGOS_CAVERN, {Tricks::Tag::EXPERT}, "Dodongo\'s Cavern Child Slingshot Skips", "With precise platforming, child can cross the platforms while the flame circles are there. When enabling this trick, it's recommended that you also enable the Adult variant: \"Dodongo's Cavern Spike Trap Room Jump without Hover Boots\"."); - OPT_TRICK(RT_DC_SCRUB_ROOM, RCQUEST_VANILLA, RA_DODONGOS_CAVERN, {Tricks::Tag::NOVICE}, "Dodongo\'s Cavern Two Scrub Room with Strength", "With help from a conveniently-positioned block, Adult can quickly carry a Bomb Flower over to destroy the mud wall blocking the room with two Deku Scrubs."); - OPT_TRICK(RT_DC_JUMP, RCQUEST_BOTH, RA_DODONGOS_CAVERN, {Tricks::Tag::NOVICE}, "Dodongo\'s Cavern Spike Trap Room Jump without Hover Boots", "The jump is Adult Link only. Applies to both Vanilla and MQ."); - OPT_TRICK(RT_DC_HAMMER_FLOOR, RCQUEST_BOTH, RA_DODONGOS_CAVERN, {Tricks::Tag::NOVICE}, "Dodongo\'s Cavern Smash the Boss Lobby Floor", "The bombable floor before King Dodongo can be destroyed with Hammer if hit in the very center. This is only relevant with Shuffle Boss Entrances or if Dodongo's Cavern is MQ and either variant of \"Dodongo's Cavern MQ Light the Eyes with Strength\" is on."); - OPT_TRICK(RT_DC_MQ_CHILD_BOMBS, RCQUEST_MQ, RA_DODONGOS_CAVERN, {Tricks::Tag::ADVANCED}, "Dodongo\'s Cavern MQ Early Bomb Bag Area as Child", "With a precise jump slash from above, you can reach the Bomb Bag area as only child without needing a Slingshot. You will take fall damage."); - OPT_TRICK(RT_DC_MQ_CHILD_EYES, RCQUEST_MQ, RA_DODONGOS_CAVERN, {Tricks::Tag::EXPERT}, "Dodongo\'s Cavern MQ Light the Eyes with Strength as Child", "If you move very quickly, it is possible to use the bomb flower at the top of the room to light the eyes. To perform this trick as child is significantly more difficult than adult. The player is also expected to complete the DC back area without explosives, including getting past the Armos wall to the switch for the boss door."); - OPT_TRICK(RT_DC_MQ_ADULT_EYES, RCQUEST_MQ, RA_DODONGOS_CAVERN, {Tricks::Tag::ADVANCED}, "Dodongo\'s Cavern MQ Light the Eyes with Strength as Adult", "If you move very quickly, it is possible to use the bomb flower at the top of the room to light the eyes."); - OPT_TRICK(RT_JABU_ALCOVE_JUMP_DIVE, RCQUEST_BOTH, RA_JABU_JABUS_BELLY, {Tricks::Tag::NOVICE}, "Jabu Underwater Alcove as Adult with Jump Dive", "Standing above the underwater tunnel leading to the scrub, jump down and swim through the tunnel. This allows adult to access the alcove with no Scale or Iron Boots. In Vanilla Jabu, this alcove has a business scrub. In MQ Jabu, it has the compass chest and a door switch for the main floor."); - OPT_TRICK(RT_JABU_BOSS_HOVER, RCQUEST_VANILLA, RA_JABU_JABUS_BELLY, {Tricks::Tag::INTERMEDIATE}, "Jabu Near Boss Room with Hover Boots", "A box for the blue switch can be carried over by backwalking with one while the elevator is at its peak. Alternatively, you can skip transporting a box by quickly rolling from the switch and opening the door before it closes. However, the timing for this is very tight."); - OPT_TRICK(RT_JABU_NEAR_BOSS_RANGED, RCQUEST_BOTH, RA_JABU_JABUS_BELLY, {Tricks::Tag::NOVICE}, "Jabu Near Boss Ceiling Switch/GS without Boomerang or Explosives", "Vanilla Jabu: From near the entrance into the room, you can hit the switch that opens the door to the boss room using a precisely-aimed use of the Slingshot, Bow, or Longshot. As well, if you climb to the top of the vines you can stand on the right edge of the platform and shoot around the glass. From this distance, even the Hookshot can reach the switch. This trick is only relevant if \"Shuffle Boss Entrances\" is enabled. MQ Jabu: A Gold Skulltula Token can be collected with the Hookshot or Longshot using the same methods as hitting the switch in Vanilla. This MQ trick is not currently relevant in logic."); - OPT_TRICK(RT_JABU_NEAR_BOSS_EXPLOSIVES, RCQUEST_VANILLA, RA_JABU_JABUS_BELLY, {Tricks::Tag::INTERMEDIATE}, "Jabu Near Boss Ceiling Switch with Explosives", "You can hit the switch that opens the door to the boss room using a precisely-aimed Bombchu. Also, using the Hover Boots, adult can throw a Bomb at the switch. This trick is only relevant if \"Shuffle Boss Entrances\" is enabled."); - OPT_TRICK(RT_LENS_JABU_MQ, RCQUEST_MQ, RA_JABU_JABUS_BELLY, {Tricks::Tag::NOVICE}, "Jabu MQ without Lens of Truth", "Removes the requirements for the Lens of Truth in Jabu MQ."); - OPT_TRICK(RT_JABU_MQ_RANG_JUMP, RCQUEST_MQ, RA_JABU_JABUS_BELLY, {Tricks::Tag::ADVANCED}, "Jabu MQ Compass Chest with Boomerang", "Boomerang can reach the cow switch to spawn the chest by targeting the cow, jumping off of the ledge where the chest spawns, and throwing the Boomerang in midair."); - OPT_TRICK(RT_JABU_MQ_SOT_GS, RCQUEST_MQ, RA_JABU_JABUS_BELLY, {Tricks::Tag::INTERMEDIATE}, "Jabu MQ Song of Time Block GS with Boomerang", "Allow the Boomerang to return to you through the Song of Time block to grab the token."); - OPT_TRICK(RT_LENS_BOTW, RCQUEST_VANILLA, RA_BOTTOM_OF_THE_WELL, {Tricks::Tag::NOVICE}, "Bottom of the Well without Lens of Truth", "Removes the requirements for the Lens of Truth in Bottom of the Well."); - OPT_TRICK(RT_BOTW_CHILD_DEADHAND, RCQUEST_BOTH, RA_BOTTOM_OF_THE_WELL, {Tricks::Tag::NOVICE}, "Child Dead Hand without Kokiri Sword", "Requires 9 sticks or 5 jump slashes."); - OPT_TRICK(RT_BOTW_BASEMENT, RCQUEST_VANILLA, RA_BOTTOM_OF_THE_WELL, {Tricks::Tag::NOVICE}, "Bottom of the Well Map Chest with Strength & Sticks", "The chest in the basement can be reached with strength by doing a jump slash with a lit stick to access the Bomb Flowers."); - OPT_TRICK(RT_BOTW_MQ_PITS, RCQUEST_MQ, RA_BOTTOM_OF_THE_WELL, {Tricks::Tag::NOVICE}, "Bottom of the Well MQ Jump Over the Pits", "While the pits in Bottom of the Well don't allow you to jump just by running straight at them, you can still get over them by side-hopping or backflipping across. With explosives, this allows you to access the central areas without Zelda's Lullaby. With Zelda's Lullaby, it allows you to access the west inner room without explosives."); - OPT_TRICK(RT_BOTW_MQ_DEADHAND_KEY, RCQUEST_MQ, RA_BOTTOM_OF_THE_WELL, {Tricks::Tag::NOVICE}, "Bottom of the Well MQ Dead Hand Freestanding Key with Boomerang", "Boomerang can fish the item out of the rubble without needing explosives to blow it up."); - OPT_TRICK(RT_FOREST_FIRST_GS, RCQUEST_VANILLA, RA_FOREST_TEMPLE, {Tricks::Tag::NOVICE}, "Forest Temple First Room GS with Difficult-to-Use Weapons", "Allows killing this Skulltula with Sword or Sticks by jump slashing it as you let go from the vines. You can avoid taking fall damage by recoiling onto the tree. Also allows killing it as Child with a Bomb throw. It's much more difficult to use a Bomb as child due to Child Link's shorter height."); - OPT_TRICK(RT_FOREST_OUTDOORS_EAST_GS, RCQUEST_VANILLA, RA_FOREST_TEMPLE, {Tricks::Tag::NOVICE}, "Forest Temple East Courtyard GS with Boomerang", "Precise Boomerang throws can allow child to kill the Skulltula and collect the token."); - OPT_TRICK(RT_FOREST_VINES, RCQUEST_BOTH, RA_FOREST_TEMPLE, {Tricks::Tag::NOVICE}, "Forest Temple East Courtyard Vines with Hookshot", "The vines in Forest Temple leading to where the well drain switch is in the standard form can be barely reached with just the Hookshot. Applies to MQ also."); - OPT_TRICK(RT_FOREST_OUTDOORS_LEDGE, RCQUEST_BOTH, RA_FOREST_TEMPLE, {Tricks::Tag::NOVICE}, "Forest Temple NE Outdoors Ledge with Hover Boots", "With precise Hover Boots movement you can fall down to this ledge from upper balconies. If done precisely enough, it is not necessary to take fall damage. In MQ, this skips a Longshot requirement. In Vanilla, this can skip a Hookshot requirement in entrance randomizer."); - OPT_TRICK(RT_FOREST_DOORFRAME, RCQUEST_BOTH, RA_FOREST_TEMPLE, {Tricks::Tag::ADVANCED}, "Forest Temple East Courtyard Door Frame with Hover Boots", "A precise Hover Boots movement from the upper balconies in this courtyard can be used to get on top of the door frame. Applies to both Vanilla and Master Quest. In Vanilla, from on top the door frame you can summon Pierre, allowing you to access the falling ceiling room early. In Master Quest, this allows you to obtain the GS on the door frame as adult without Hookshot or Song of Time."); - OPT_TRICK(RT_FOREST_OUTSIDE_BACKDOOR, RCQUEST_BOTH, RA_FOREST_TEMPLE, {Tricks::Tag::ADVANCED}, "Forest Temple Outside Backdoor with Jump Slash", "A jump slash recoil can be used to reach the ledge in the block puzzle room that leads to the west courtyard. This skips a potential Hover Boots requirement in Vanilla, and it can sometimes apply in MQ as well. This trick can be performed as both ages."); - OPT_TRICK(RT_FOREST_OUTDOORS_HEARTS_BOOMERANG, RCQUEST_BOTH, RA_FOREST_TEMPLE, {Tricks::Tag::NOVICE}, "Forest Temple Outside Hearts with Boomerang", "A well aimed boomerang from the water's edge can reach the hearts from ground level. If unable to swim, you can back away from the water while the boomerang is returning so the hearts land on the ground."); - OPT_TRICK(RT_FOREST_MQ_WELL_SWIM, RCQUEST_MQ, RA_FOREST_TEMPLE, {Tricks::Tag::ADVANCED}, "Swim Through Forest Temple MQ Well with Hookshot", "Shoot the vines in the well as low and as far to the right as possible, and then immediately swim under the ceiling to the right. This can only be required if Forest Temple is in its Master Quest form."); - OPT_TRICK(RT_FOREST_MQ_BLOCK_PUZZLE, RCQUEST_MQ, RA_FOREST_TEMPLE, {Tricks::Tag::NOVICE}, "Skip Forest Temple MQ Block Puzzle with Bombchu", "Send the Bombchu straight up the center of the wall directly to the left upon entering the room."); - //Child with hovers cannot do this from the lower floor, and most go to the upper floor which needs goron bracelet. Adult can do this with hammer and KSword, But child cannot. - OPT_TRICK(RT_FOREST_MQ_JS_HALLWAY_SWITCH, RCQUEST_MQ, RA_FOREST_TEMPLE, {Tricks::Tag::NOVICE}, "Forest Temple MQ Twisted Hallway Switch with Jump Slash", "The switch to twist the hallway can be hit with a jump slash through the glass block. To get in front of the switch, either use the Hover Boots or hit the shortcut switch at the top of the room and jump from the glass blocks that spawn. Sticks can be used as child, but the Kokiri Sword is too short to reach through the glass."); - OPT_TRICK(RT_FOREST_MQ_HOOKSHOT_HALLWAY_SWITCH, RCQUEST_MQ, RA_FOREST_TEMPLE, {Tricks::Tag::INTERMEDIATE}, "Forest Temple MQ Twisted Hallway Switch with Hookshot", "There's a very small gap between the glass block and the wall. Through that gap you can hookshot the target on the ceiling."); - OPT_TRICK(RT_FOREST_MQ_RANG_HALLWAY_SWITCH, RCQUEST_MQ, RA_FOREST_TEMPLE, {Tricks::Tag::INTERMEDIATE}, "Forest Temple MQ Twisted Hallway Switch with Boomerang", "The Boomerang can return to Link through walls, allowing child to hit the hallway switch. This can be used to allow adult to pass through later, or in conjunction with \"Forest Temple Outside Backdoor with Jump Slash\"."); - OPT_TRICK(RT_FIRE_BOSS_DOOR_JUMP, RCQUEST_BOTH, RA_FIRE_TEMPLE, {Tricks::Tag::NOVICE}, "Fire Temple Boss Door without Hover Boots or Pillar", "The Fire Temple Boss Door can be reached as adult with a precise jump. You must be touching the side wall of the room so that Link will grab the ledge from farther away than is normally possible."); - //Is also used in MQ logic, but has no practical effect there as of now - OPT_TRICK(RT_FIRE_SOT, RCQUEST_VANILLA, RA_FIRE_TEMPLE, {Tricks::Tag::INTERMEDIATE}, "Fire Temple Song of Time Room GS without Song of Time", "A precise jump can be used to reach this room."); - OPT_TRICK(RT_FIRE_STRENGTH, RCQUEST_VANILLA, RA_FIRE_TEMPLE, {Tricks::Tag::INTERMEDIATE}, "Fire Temple Climb without Strength", "A precise jump can be used to skip pushing the block."); - OPT_TRICK(RT_FIRE_SCARECROW, RCQUEST_VANILLA, RA_FIRE_TEMPLE, {Tricks::Tag::EXPERT}, "Fire Temple East Tower without Scarecrow\'s Song", "Also known as \"Pixelshot\". The Longshot can reach the target on the elevator itself, allowing you to skip needing to spawn the scarecrow."); - OPT_TRICK(RT_FIRE_FLAME_MAZE, RCQUEST_VANILLA, RA_FIRE_TEMPLE, {Tricks::Tag::INTERMEDIATE}, "Fire Temple Flame Wall Maze Skip", "If you move quickly you can sneak past the edge of a flame wall before it can rise up to block you. To do it without taking damage is more precise. Allows you to progress without needing either a Small Key or Hover Boots."); - OPT_TRICK(RT_FIRE_MQ_NEAR_BOSS, RCQUEST_MQ, RA_FIRE_TEMPLE, {Tricks::Tag::NOVICE}, "Fire Temple MQ Chest Near Boss without Breaking Crate", "The hitbox for the torch extends a bit outside of the crate. Shoot a flaming arrow at the side of the crate to light the torch without needing to get over there and break the crate."); - OPT_TRICK(RT_FIRE_MQ_BLOCKED_CHEST, RCQUEST_MQ, RA_FIRE_TEMPLE, {Tricks::Tag::INTERMEDIATE}, "Fire Temple MQ Big Lava Room Blocked Door without Hookshot", "There is a gap between the hitboxes of the flame wall in the big lava room. If you know where this gap is located, you can jump through it and skip needing to use the Hookshot. To do this without taking damage is more precise."); - OPT_TRICK(RT_FIRE_MQ_BK_CHEST, RCQUEST_MQ, RA_FIRE_TEMPLE, {Tricks::Tag::INTERMEDIATE}, "Fire Temple MQ Boss Key Chest without Bow", "It is possible to light both of the timed torches to unbar the door to the boss key chest's room with just Din's Fire if you move very quickly between the two torches. It is also possible to unbar the door with just Din's Fire by abusing an oversight in the way the game counts how many torches have been lit."); - OPT_TRICK(RT_FIRE_MQ_CLIMB, RCQUEST_MQ, RA_FIRE_TEMPLE, {Tricks::Tag::NOVICE}, "Fire Temple MQ Climb without Fire Source", "You can use the Hover Boots to hover around to the climbable wall, skipping the need to use a fire source and spawn a Hookshot target."); - OPT_TRICK(RT_FIRE_MQ_MAZE_SIDE_ROOM, RCQUEST_MQ, RA_FIRE_TEMPLE, {Tricks::Tag::NOVICE}, "Fire Temple MQ Lizalfos Maze Side Room without Box", "You can walk from the blue switch to the door and quickly open the door before the bars reclose. This skips needing to reach the upper sections of the maze to get a box to place on the switch."); - OPT_TRICK(RT_FIRE_MQ_MAZE_HOVERS, RCQUEST_MQ, RA_FIRE_TEMPLE, {Tricks::Tag::NOVICE}, "Fire Temple MQ Lower to Upper Lizalfos Maze with Hover Boots", "Use the Hover Boots off of a crate to climb to the upper maze without needing to spawn and use the Hookshot targets."); - OPT_TRICK(RT_FIRE_MQ_MAZE_JUMP, RCQUEST_MQ, RA_FIRE_TEMPLE, {Tricks::Tag::INTERMEDIATE}, "Fire Temple MQ Lower to Upper Lizalfos Maze with Precise Jump", "A precise jump off of a crate can be used to climb to the upper maze without needing to spawn and use the Hookshot targets. This trick supersedes both \"Fire Temple MQ Lower to Upper Lizalfos Maze with Hover Boots\" and \"Fire Temple MQ Lizalfos Maze Side Room without Box\"."); - OPT_TRICK(RT_FIRE_MQ_ABOVE_MAZE_GS, RCQUEST_MQ, RA_FIRE_TEMPLE, {Tricks::Tag::INTERMEDIATE}, "Fire Temple MQ Above Flame Wall Maze GS from Below with Longshot", "The floor of the room that contains this Skulltula is only solid from above. From the maze below, the Longshot can be shot through the ceiling to obtain the token with two fewer small keys than normal."); - OPT_TRICK(RT_FIRE_MQ_FLAME_MAZE, RCQUEST_MQ, RA_FIRE_TEMPLE, {Tricks::Tag::INTERMEDIATE}, "Fire Temple MQ Flame Wall Maze Skip", "If you move quickly you can sneak past the edge of a flame wall before it can rise up to block you. To do it without taking damage is more precise. Allows you to reach the side room GS without needing Song of Time or Hover Boots. If either of \"Fire Temple MQ Lower to Upper Lizalfos Maze with Hover Boots\" or \"with Precise Jump\" are enabled, this also allows you to progress deeper into the dungeon without Hookshot."); - OPT_TRICK(RT_WATER_LONGSHOT_TORCH, RCQUEST_VANILLA, RA_WATER_TEMPLE, {Tricks::Tag::NOVICE}, "Water Temple Torch Longshot", "Stand on the eastern side of the central pillar and longshot the torches on the bottom level. Swim through the corridor and float up to the top level. This allows access to this area and lower water levels without Iron Boots. The majority of the tricks that allow you to skip Iron Boots in the Water Temple are not going to be relevant unless this trick is first enabled."); - OPT_TRICK(RT_WATER_CRACKED_WALL_HOVERS, RCQUEST_VANILLA, RA_WATER_TEMPLE, {Tricks::Tag::NOVICE}, "Water Temple Cracked Wall with Hover Boots", "With a midair side-hop while wearing the Hover Boots, you can reach the cracked wall without needing to raise the water up to the middle level."); - OPT_TRICK(RT_WATER_CRACKED_WALL, RCQUEST_VANILLA, RA_WATER_TEMPLE, {Tricks::Tag::INTERMEDIATE}, "Water Temple Cracked Wall with No Additional Items", "A precise jump slash (among other methods) will get you to the cracked wall without needing the Hover Boots or to raise the water to the middle level. This trick supersedes \"Water Temple Cracked Wall with Hover Boots\"."); - OPT_TRICK(RT_WATER_BK_REGION, RCQUEST_VANILLA, RA_WATER_TEMPLE, {Tricks::Tag::INTERMEDIATE}, "Water Temple Boss Key Region with Hover Boots", "With precise Hover Boots movement it is possible to reach the boss key chest's region without needing the Longshot. It is not necessary to take damage from the spikes. The Gold Skulltula Token in the following room can also be obtained with just the Hover Boots."); - OPT_TRICK(RT_WATER_NORTH_BASEMENT_LEDGE_JUMP, RCQUEST_BOTH, RA_WATER_TEMPLE, {Tricks::Tag::INTERMEDIATE}, "Water Temple North Basement Ledge with Precise Jump", "In the northern basement there's a ledge from where, in Vanilla Water Temple, boulders roll out into the room. Normally to jump directly to this ledge logically requires the Hover Boots, but with precise jump, it can be done without them. This trick applies to both Vanilla and Master Quest."); - OPT_TRICK(RT_WATER_BK_JUMP_DIVE, RCQUEST_VANILLA, RA_WATER_TEMPLE, {Tricks::Tag::NOVICE}, "Water Temple Boss Key Jump Dive", "Stand on the very edge of the raised corridor leading from the push block room to the rolling boulder corridor. Face the Gold Skulltula on the waterfall and jump over the boulder corridor floor into the pool of water, swimming right once underwater. This allows access to the boss key room without Iron boots."); - //Also used in MQ logic, but won't be relevent unless a way to enter tower without irons exists (likely a clip + swim) - OPT_TRICK(RT_WATER_FW_CENTRAL_GS, RCQUEST_VANILLA, RA_WATER_TEMPLE, {Tricks::Tag::NOVICE}, "Water Temple Central Pillar GS with Farore\'s Wind", "If you set Farore's Wind inside the central pillar and then return to that warp point after raising the water to the highest level, you can obtain this Skulltula Token with Hookshot or Boomerang."); - OPT_TRICK(RT_WATER_IRONS_CENTRAL_GS, RCQUEST_VANILLA, RA_WATER_TEMPLE, {Tricks::Tag::NOVICE}, "Water Temple Central Pillar GS with Iron Boots", "After opening the middle water level door into the central pillar, the door will stay unbarred so long as you do not leave the room, even if you were to raise the water up to the highest level. With the Iron Boots to go through the door after the water has been raised, you can obtain the Skulltula Token with the Hookshot."); - OPT_TRICK(RT_WATER_CENTRAL_BOW, RCQUEST_VANILLA, RA_WATER_TEMPLE, {Tricks::Tag::ADVANCED}, "Water Temple Central Bow Target without Longshot or Hover Boots", "A very precise Bow shot can hit the eye switch from the floor above. Then, you can jump down into the hallway and make through it before the gate closes. It can also be done as child, using the Slingshot instead of the Bow."); - OPT_TRICK(RT_WATER_HOOKSHOT_FALLING_PLATFORM_GS, RCQUEST_VANILLA, RA_WATER_TEMPLE, {Tricks::Tag::NOVICE}, "Water Temple Falling Platform Room GS with Hookshot", "If you stand on the very edge of the platform, this Gold Skulltula can be obtained with only the Hookshot."); - OPT_TRICK(RT_WATER_RANG_FALLING_PLATFORM_GS, RCQUEST_VANILLA, RA_WATER_TEMPLE, {Tricks::Tag::INTERMEDIATE}, "Water Temple Falling Platform Room GS with Boomerang", "If you stand on the very edge of the platform, this Gold Skulltula can be obtained with only the Boomerang."); - OPT_TRICK(RT_WATER_RIVER_GS, RCQUEST_VANILLA, RA_WATER_TEMPLE, {Tricks::Tag::INTERMEDIATE}, "Water Temple River GS without Iron Boots", "Standing on the exposed ground toward the end of the river, a precise Longshot use can obtain the token. The Longshot cannot normally reach far enough to kill the Skulltula, however. You'll first have to find some other way of killing it."); - OPT_TRICK(RT_WATER_DRAGON_JUMP_DIVE, RCQUEST_BOTH, RA_WATER_TEMPLE, {Tricks::Tag::NOVICE}, "Water Temple Dragon Statue Jump Dive", "If you come into the dragon statue room from the serpent river, you can jump down from above and get into the tunnel without needing either Iron Boots or a Scale. This trick applies to both Vanilla and Master Quest. In Vanilla, you must shoot the switch from above with the Bow, and then quickly get through the tunnel before the gate closes."); - OPT_TRICK(RT_WATER_ADULT_DRAGON, RCQUEST_VANILLA, RA_WATER_TEMPLE, {Tricks::Tag::NOVICE}, "Water Temple Dragon Statue Switch from Above the Water as Adult", "Normally you need both Hookshot and Iron Boots to hit the switch and swim through the tunnel to get to the chest. But by hitting the switch from dry land, using one of Bombchus, Hookshot, or Bow, it is possible to skip one or both of those requirements. After the gate has been opened, besides just using the Iron Boots, a well-timed dive with at least the Silver Scale could be used to swim through the tunnel. If coming from the serpent river, a jump dive can also be used to get into the tunnel."); - OPT_TRICK(RT_WATER_CHILD_DRAGON, RCQUEST_VANILLA, RA_WATER_TEMPLE, {Tricks::Tag::ADVANCED}, "Water Temple Dragon Statue Switch from Above the Water as Child", "It is possible for child to hit the switch from dry land using one of Bombchus, Slingshot or Boomerang. Then, to get to the chest, child can dive through the tunnel using at least the Silver Scale. The timing and positioning of this dive needs to be perfect to actually make it under the gate, and it all needs to be done very quickly to be able to get through before the gate closes. Be sure to enable \"Water Temple Dragon Statue Switch from Above the Water as Adult\" for adult's variant of this trick."); - OPT_TRICK(RT_WATER_MQ_CENTRAL_PILLAR, RCQUEST_MQ, RA_WATER_TEMPLE, {Tricks::Tag::NOVICE}, "Water Temple MQ Central Pillar with Fire Arrows", "Slanted torches have misleading hitboxes. Whenever you see a slanted torch jutting out of the wall, you can expect most or all of its hitbox is actually on the other side that wall. This can make slanted torches very finicky to light when using arrows. The torches in the central pillar of MQ Water Temple are a particularly egregious example. Logic normally expects Din's Fire and Song of Time."); - OPT_TRICK(RT_WATER_MQ_LOCKED_GS, RCQUEST_MQ, RA_WATER_TEMPLE, {Tricks::Tag::NOVICE}, "Water Temple MQ North Basement GS without Small Key", "There is an invisible Hookshot target that can be used to get over the gate that blocks you from going to this Skulltula early, skipping a small key as well as needing Hovers or Scarecrow to reach the locked door."); - OPT_TRICK(RT_LENS_SHADOW, RCQUEST_VANILLA, RA_SHADOW_TEMPLE, {Tricks::Tag::NOVICE}, "Shadow Temple Stationary Objects without Lens of Truth", "Removes the requirements for the Lens of Truth in Shadow Temple for most areas in the dungeon except for crossing the moving platform in the huge pit room and for fighting Bongo Bongo."); - OPT_TRICK(RT_LENS_SHADOW_PLATFORM, RCQUEST_VANILLA, RA_SHADOW_TEMPLE, {Tricks::Tag::NOVICE}, "Shadow Temple Invisible Moving Platform without Lens of Truth", "Removes the requirements for the Lens of Truth in Shadow Temple to cross the invisible moving platform in the huge pit room in either direction."); - OPT_TRICK(RT_LENS_BONGO, RCQUEST_BOTH, RA_SHADOW_TEMPLE, {Tricks::Tag::NOVICE}, "Shadow Temple Bongo Bongo without Lens of Truth", "Bongo Bongo can be defeated without the use of Lens of Truth, as the hands give a pretty good idea of where the eye is."); - OPT_TRICK(RT_SHADOW_UMBRELLA, RCQUEST_BOTH, RA_SHADOW_TEMPLE, {Tricks::Tag::EXPERT}, "Shadow Temple Stone Umbrella Skip", "A very precise Hover Boots movement from off of the lower chest can get you on top of the crushing spikes without needing to pull the block. Applies to both Vanilla and Master Quest."); - OPT_TRICK(RT_SHADOW_UMBRELLA_GS, RCQUEST_BOTH, RA_SHADOW_TEMPLE, {Tricks::Tag::EXPERT}, "Shadow Temple Falling Spikes GS with Hover Boots", "After killing the Skulltula, a very precise Hover Boots movement from off of the lower chest can get you on top of the crushing spikes without needing to pull the block. From there, another very precise Hover Boots movement can be used to obtain the token without needing the Hookshot. Applies to both Vanilla and Master Quest. For obtaining the chests in this room with just Hover Boots, be sure to enable \"Shadow Temple Stone Umbrella Skip\"."); - OPT_TRICK(RT_SHADOW_FREESTANDING_KEY, RCQUEST_VANILLA, RA_SHADOW_TEMPLE, {Tricks::Tag::NOVICE}, "Shadow Temple Freestanding Key with Bombchu", "Release the Bombchu with good timing so that it explodes near the bottom of the pot."); - OPT_TRICK(RT_SHADOW_STATUE, RCQUEST_BOTH, RA_SHADOW_TEMPLE, {Tricks::Tag::INTERMEDIATE}, "Shadow Temple River Statue with Bombchu", "By sending a Bombchu around the edge of the gorge, you can knock down the statue without needing a Bow. Applies in both Vanilla and MQ Shadow."); - OPT_TRICK(RT_SHADOW_BONGO, RCQUEST_BOTH, RA_SHADOW_TEMPLE, {Tricks::Tag::INTERMEDIATE}, "Shadow Temple Bongo Bongo without projectiles", "Using precise sword slashes, Bongo Bongo can be defeated without using projectiles. This is only relevant in conjunction with Shadow Temple dungeon shortcuts or shuffled boss entrances."); - OPT_TRICK(RT_LENS_SHADOW_MQ, RCQUEST_MQ, RA_SHADOW_TEMPLE, {Tricks::Tag::NOVICE}, "Shadow Temple MQ Stationary Objects without Lens of Truth", "Removes the requirements for the Lens of Truth in Shadow Temple MQ for most areas in the dungeon. See \"Shadow Temple MQ Invisible Moving Platform without Lens of Truth\", \"Shadow Temple MQ Invisible Blades Silver Rupees without Lens of Truth\", \"Shadow Temple MQ 2nd Dead Hand without Lens of Truth\", and \"Shadow Temple Bongo Bongo without Lens of Truth\" for exceptions."); - OPT_TRICK(RT_LENS_SHADOW_MQ_INVISIBLE_BLADES, RCQUEST_MQ, RA_SHADOW_TEMPLE, {Tricks::Tag::NOVICE}, "Shadow Temple MQ Invisible Blades Silver Rupees without Lens of Truth", "Removes the requirement for the Lens of Truth or Nayru's Love in Shadow Temple MQ for the Invisible Blades room Silver Rupee collection."); - OPT_TRICK(RT_LENS_SHADOW_MQ_PLATFORM, RCQUEST_MQ, RA_SHADOW_TEMPLE, {Tricks::Tag::NOVICE}, "Shadow Temple MQ Invisible Moving Platform without Lens of Truth", "Removes the requirements for the Lens of Truth in Shadow Temple MQ to cross the invisible moving platform in the huge pit room in either direction."); - OPT_TRICK(RT_LENS_SHADOW_MQ_DEADHAND, RCQUEST_MQ, RA_SHADOW_TEMPLE, {Tricks::Tag::NOVICE}, "Shadow Temple MQ 2nd Dead Hand without Lens of Truth", "Dead Hand spawns in a random spot within the room. Having Lens removes the hassle of having to comb the room looking for his spawn location."); - OPT_TRICK(RT_SHADOW_MQ_GAP, RCQUEST_MQ, RA_SHADOW_TEMPLE, {Tricks::Tag::INTERMEDIATE}, "Shadow Temple MQ Truth Spinner Gap with Longshot", "You can Longshot a torch and jump-slash recoil onto the tongue. It works best if you Longshot the right torch from the left side of the room."); - OPT_TRICK(RT_SHADOW_MQ_INVISIBLE_BLADES, RCQUEST_MQ, RA_SHADOW_TEMPLE, {Tricks::Tag::INTERMEDIATE}, "Shadow Temple MQ Invisible Blades without Song of Time", "The Like Like can be used to boost you into the Silver Rupee or Recovery Hearts that normally require Song of Time. This cannot be performed on OHKO since the Like Like does not boost you high enough if you die."); - OPT_TRICK(RT_SHADOW_MQ_HUGE_PIT, RCQUEST_MQ, RA_SHADOW_TEMPLE, {Tricks::Tag::INTERMEDIATE}, "Shadow Temple MQ Lower Huge Pit without Fire Source", "Normally a frozen eye switch spawns some platforms that you can use to climb down, but there's actually a small piece of ground that you can stand on that you can just jump down to."); - OPT_TRICK(RT_SHADOW_MQ_WINDY_WALKWAY, RCQUEST_MQ, RA_SHADOW_TEMPLE, {Tricks::Tag::INTERMEDIATE}, "Shadow Temple MQ Windy Walkway Reverse without Hover Boots", "It is possible to jump from the alcove in the windy hallway to the middle platform. There are two methods: wait out the fan opposite the door and hold forward, or jump to the right to be pushed by the fan there towards the platform ledge. Note that jumps of this distance are inconsistent, but still possible."); - OPT_TRICK(RT_LENS_SPIRIT, RCQUEST_VANILLA, RA_SPIRIT_TEMPLE, {Tricks::Tag::NOVICE}, "Spirit Temple without Lens of Truth", "Removes the requirements for the Lens of Truth in Spirit Temple."); - OPT_TRICK(RT_SPIRIT_CHILD_CHU, RCQUEST_VANILLA, RA_SPIRIT_TEMPLE, {Tricks::Tag::NOVICE}, "Spirit Temple Child Side Bridge with Bombchu", "A carefully-timed Bombchu can hit the switch."); - OPT_TRICK(RT_SPIRIT_LOBBY_GS, RCQUEST_VANILLA, RA_SPIRIT_TEMPLE, {Tricks::Tag::NOVICE}, "Spirit Temple Main Room GS with Boomerang", "Standing on the highest part of the arm of the statue, a precise Boomerang throw can kill and obtain this Gold Skulltula. You must throw the Boomerang slightly off to the side so that it curves into the Skulltula, as aiming directly at it will clank off of the wall in front."); - OPT_TRICK(RT_SPIRIT_LOWER_ADULT_SWITCH, RCQUEST_VANILLA, RA_SPIRIT_TEMPLE, {Tricks::Tag::ADVANCED}, "Spirit Temple Lower Adult Switch with Bombs", "A bomb can be used to hit the switch on the ceiling, but it must be thrown from a particular distance away and with precise timing."); - OPT_TRICK(RT_SPIRIT_LOBBY_JUMP, RCQUEST_BOTH, RA_SPIRIT_TEMPLE, {Tricks::Tag::INTERMEDIATE}, "Spirit Temple Main Room Jump from Hands to Upper Ledges", "A precise jump to obtain the following as adult without needing one of Hover Boots, or Hookshot (in Vanilla) or Song of Time (in MQ): - Spirit Temple Statue Room Northeast Chest - Spirit Temple GS Lobby - Spirit Temple MQ Central Chamber Top Left Pot (Left) - Spirit Temple MQ Central Chamber Top Left Pot (Right)"); - // disabled since "Spirit Temple boss shortcuts" (pre-lowers the platform where you break the statues face) isn't a setting in ship - // OPT_TRICK(RT_SPIRIT_PLATFORM_HOOKSHOT, RCQUEST_VANILLA, RA_SPIRIT_TEMPLE, {Tricks::Tag::INTERMEDIATE}, "Spirit Temple Main Room Hookshot to Boss Platform", "Precise hookshot aiming at the platform chains can be used to reach the boss platform from the middle landings. Using a jump slash immediately after reaching a chain makes aiming more lenient. Relevant only when Spirit Temple boss shortcuts are on."); - OPT_TRICK(RT_SPIRIT_MAP_CHEST, RCQUEST_VANILLA, RA_SPIRIT_TEMPLE, {Tricks::Tag::NOVICE}, "Spirit Temple Map Chest with Bow", "To get a line of sight from the upper torch to the map chest torches, you must pull an Armos statue all the way up the stairs."); - OPT_TRICK(RT_SPIRIT_SUN_CHEST, RCQUEST_VANILLA, RA_SPIRIT_TEMPLE, {Tricks::Tag::ADVANCED}, "Spirit Temple Sun Block Room Chest with Bow", "Using the blocks in the room as platforms you can get lines of sight to all three torches. The timer on the torches is quite short so you must move quickly in order to light all three."); - OPT_TRICK(RT_SPIRIT_WALL, RCQUEST_VANILLA, RA_SPIRIT_TEMPLE, {Tricks::Tag::INTERMEDIATE}, "Spirit Temple Shifting Wall with No Additional Items", "Logic normally guarantees a way of dealing with both the Beamos and the Walltula before climbing the wall."); - OPT_TRICK(RT_LENS_SPIRIT_MQ, RCQUEST_MQ, RA_SPIRIT_TEMPLE, {Tricks::Tag::NOVICE}, "Spirit Temple MQ without Lens of Truth", "Removes the requirements for the Lens of Truth in Spirit Temple MQ."); - OPT_TRICK(RT_SPIRIT_MQ_SUN_BLOCK_SOT, RCQUEST_MQ, RA_SPIRIT_TEMPLE, {Tricks::Tag::INTERMEDIATE}, "Spirit Temple MQ Sun Block Room as Child without Song of Time", "While adult can easily jump directly to the switch that unbars the door to the sun block room, child Link cannot make the jump without spawning a Song of Time block to jump from. You can skip this by throwing the crate down onto the switch from above, which does unbar the door, however the crate immediately breaks, so you must move quickly to get through the door before it closes back up."); - OPT_TRICK(RT_SPIRIT_MQ_SUN_BLOCK_GS, RCQUEST_MQ, RA_SPIRIT_TEMPLE, {Tricks::Tag::INTERMEDIATE}, "Spirit Temple MQ Sun Block Room GS with Boomerang", "Throw the Boomerang in such a way that it curves through the side of the glass block to hit the Gold Skulltula."); - OPT_TRICK(RT_SPIRIT_MQ_LOWER_ADULT, RCQUEST_MQ, RA_SPIRIT_TEMPLE, {Tricks::Tag::INTERMEDIATE}, "Spirit Temple MQ Lower Adult without Fire Arrows", "By standing in a precise position it is possible to light two of the torches with a single use of Din\'s Fire. This saves enough time to be able to light all three torches with only Din\'s Fire."); - OPT_TRICK(RT_SPIRIT_MQ_FROZEN_EYE, RCQUEST_MQ, RA_SPIRIT_TEMPLE, {Tricks::Tag::NOVICE}, "Spirit Temple MQ Frozen Eye Switch without Fire", "You can melt the ice by shooting an arrow through a torch. The only way to find a line of sight for this shot is to first spawn a Song of Time block, and then stand on the very edge of it."); - OPT_TRICK(RT_ICE_BLOCK_GS, RCQUEST_VANILLA, RA_ICE_CAVERN, {Tricks::Tag::INTERMEDIATE}, "Ice Cavern Block Room GS with Hover Boots", "The Hover Boots can be used to get in front of the Skulltula to kill it with a jump slash. Then, the Hover Boots can again be used to obtain the Token, all without Hookshot or Boomerang."); - OPT_TRICK(RT_ICE_MQ_RED_ICE_GS, RCQUEST_MQ, RA_ICE_CAVERN, {Tricks::Tag::INTERMEDIATE}, "Ice Cavern MQ Red Ice GS without Song of Time", "If you side-hop into the perfect position, you can briefly stand on the platform with the red ice just long enough to dump some blue fire."); - OPT_TRICK(RT_ICE_MQ_SCARECROW, RCQUEST_MQ, RA_ICE_CAVERN, {Tricks::Tag::INTERMEDIATE}, "Ice Cavern MQ Scarecrow GS with No Additional Items", "As adult a precise jump can be used to reach this alcove."); - OPT_TRICK(RT_LENS_GTG, RCQUEST_VANILLA, RA_GERUDO_TRAINING_GROUND, {Tricks::Tag::NOVICE}, "Gerudo Training Ground without Lens of Truth", "Removes the requirements for the Lens of Truth in Gerudo Training Ground."); - OPT_TRICK(RT_GTG_WITHOUT_HOOKSHOT, RCQUEST_VANILLA, RA_GERUDO_TRAINING_GROUND, {Tricks::Tag::INTERMEDIATE}, "Gerudo Training Ground Left Side Silver Rupees without Hookshot", "After collecting the rest of the Silver Rupees in the room, you can reach the final Silver Rupee on the ceiling by being pulled up into it after getting grabbed by the Wallmaster. Then, you must also reach the exit of the room without the use of the Hookshot. If you move quickly you can sneak past the edge of a flame wall before it can rise up to block you. To do so without taking damage is more precise."); - OPT_TRICK(RT_GTG_FAKE_WALL, RCQUEST_BOTH, RA_GERUDO_TRAINING_GROUND, {Tricks::Tag::NOVICE}, "Reach Gerudo Training Ground Fake Wall Ledge with Hover Boots", "A precise Hover Boots use from the top of the chest can allow you to grab the ledge without needing the usual requirements. In Master Quest, this always skips a Song of Time requirement. In Vanilla, this skips a Hookshot requirement, but is only relevant if \"Gerudo Training Ground Left Side Silver Rupees without Hookshot\" is enabled."); - OPT_TRICK(RT_LENS_GTG_MQ, RCQUEST_MQ, RA_GERUDO_TRAINING_GROUND, {Tricks::Tag::NOVICE}, "Gerudo Training Ground MQ without Lens of Truth", "Removes the requirements for the Lens of Truth in Gerudo Training Ground MQ."); - OPT_TRICK(RT_GTG_MQ_WITH_HOOKSHOT, RCQUEST_MQ, RA_GERUDO_TRAINING_GROUND, {Tricks::Tag::NOVICE}, "Gerudo Training Ground MQ Left Side Silver Rupees with Hookshot", "The highest Silver Rupee can be obtained by hookshooting the target and then immediately jump slashing toward the Rupee."); - OPT_TRICK(RT_GTG_MQ_WIHTOUT_HOOKSHOT, RCQUEST_MQ, RA_GERUDO_TRAINING_GROUND, {Tricks::Tag::INTERMEDIATE}, "Gerudo Training Ground MQ Left Side Silver Rupees without Hookshot", "After collecting the rest of the Silver Rupees in the room, you can reach the final Silver Rupee on the ceiling by being pulled up into it after getting grabbed by the Wallmaster. The Wallmaster will not track you to directly underneath the rupee. You should take the last step to be under the rupee after the Wallmaster has begun its attempt to grab you. Also included with this trick is that fact that the switch that unbars the door to the final chest of GTG can be hit without a projectile, using a precise jump slash. This trick supersedes \"Gerudo Training Ground MQ Left Side Silver Rupees with Hookshot\"."); - OPT_TRICK(RT_LENS_GANON, RCQUEST_VANILLA, RA_GANONS_CASTLE, {Tricks::Tag::NOVICE}, "Ganon\'s Castle without Lens of Truth", "Removes the requirements for the Lens of Truth in Ganon's Castle."); - OPT_TRICK(RT_GANON_SPIRIT_TRIAL_HOOKSHOT, RCQUEST_VANILLA, RA_GANONS_CASTLE, {Tricks::Tag::NOVICE}, "Spirit Trial without Hookshot", "The highest rupee can be obtained as either age by performing a precise jump and a well-timed jumpslash off of an Armos."); - OPT_TRICK(RT_LENS_GANON_MQ, RCQUEST_MQ, RA_GANONS_CASTLE, {Tricks::Tag::NOVICE}, "Ganon\'s Castle MQ without Lens of Truth", "Removes the requirements for the Lens of Truth in Ganon's Castle MQ."); - OPT_TRICK(RT_GANON_MQ_FIRE_TRIAL, RCQUEST_MQ, RA_GANONS_CASTLE, {Tricks::Tag::ADVANCED}, "Fire Trial MQ with Hookshot", "It's possible to hook the target at the end of fire trial with just Hookshot, but it requires precise aim and perfect positioning. The main difficulty comes from getting on the very corner of the obelisk without falling into the lava."); - OPT_TRICK(RT_GANON_MQ_SHADOW_TRIAL, RCQUEST_MQ, RA_GANONS_CASTLE, {Tricks::Tag::NOVICE}, "Shadow Trial MQ Torch with Bow", "You can light the torch in this room without a fire source by shooting an arrow through the lit torch at the beginning of the room. Because the room is so dark and the unlit torch is so far away, it can be difficult to aim the shot correctly."); - OPT_TRICK(RT_GANON_MQ_LIGHT_TRIAL, RCQUEST_MQ, RA_GANONS_CASTLE, {Tricks::Tag::INTERMEDIATE}, "Light Trial MQ without Hookshot", "If you move quickly you can sneak past the edge of a flame wall before it can rise up to block you. In this case to do it without taking damage is especially precise."); + OPT_TRICK(RT_VISIBLE_COLLISION, RCQUEST_BOTH, RA_NONE, { Tricks::Tag::NOVICE }, + "Pass Through Visible One-Way Collision", + "Allows climbing through the platform to reach Impa's House Back as adult with no items and going " + "through the Kakariko Village Gate as child when coming from the Mountain Trail side."); + OPT_TRICK(RT_GROTTOS_WITHOUT_AGONY, RCQUEST_BOTH, RA_NONE, { Tricks::Tag::NOVICE }, + "Hidden Grottos without Stone of Agony", "Allows entering hidden grottos without the Stone of Agony."); + OPT_TRICK(RT_FEWER_TUNIC_REQUIREMENTS, RCQUEST_BOTH, RA_NONE, { Tricks::Tag::INTERMEDIATE }, + "Fewer Tunic Requirements", + "Allows the following possible without Tunics:\n- Enter Water Temple. The area below the center pillar " + "still requires Zora Tunic. Applies to MQ also.\n- Enter Fire Temple. Volvagia still requires Goron " + "Tunic. Applies to MQ also, and includes child access to first floor with dungeon shuffle."); + OPT_TRICK(RT_RUSTED_SWITCHES, RCQUEST_BOTH, RA_NONE, { Tricks::Tag::NOVICE }, + "Hammer Rusted Switches Through Walls", + "Applies to:\n- Fire Temple Highest Goron Chest.\n- MQ Fire Temple Lizalfos Maze.\n- MQ Spirit Trial."); + OPT_TRICK(RT_FLAMING_CHESTS, RCQUEST_BOTH, RA_NONE, { Tricks::Tag::INTERMEDIATE }, "Flaming Chests", + "The chests encircled in flames in Gerudo Training Ground and in Spirit Temple can be opened by running " + "into the flames while Link is invincible after taking damage."); + // disabled for now, can't check for being able to use bunny hood & bunny hood speedup is currently completely + // decoupled from rando OPT_TRICK(RT_BUNNY_HOOD_JUMPS, RCQUEST_BOTH, RA_NONE, {Tricks::Tag::ADVANCED}, "Bunny Hood + // Jumps", "Allows reaching locations using Bunny Hood's extended jumps."); + OPT_TRICK(RT_DAMAGE_BOOST_SIMPLE, RCQUEST_BOTH, RA_NONE, { Tricks::Tag::ADVANCED, Tricks::Tag::EXPERIMENTAL }, + "Simple damage boosts", + "Allows damage boosts in order to reach further locations. Can be combined with \"Simple hover boosts\" " + "for reaching far distances."); + OPT_TRICK(RT_HOVER_BOOST_SIMPLE, RCQUEST_BOTH, RA_NONE, { Tricks::Tag::ADVANCED, Tricks::Tag::EXPERIMENTAL }, + "Simple hover boosts", + "Allows equipping of hover boots when link is moving at high speeds to extend distance covered. Can be " + "combined with \"Simple damage boosts\" for greater uses."); + OPT_TRICK(RT_BOMBCHU_BEEHIVES, RCQUEST_BOTH, RA_NONE, { Tricks::Tag::NOVICE }, "Bombchu Beehives", + "Allows exploding beehives with Bombchus."); + OPT_TRICK(RT_BLUE_FIRE_MUD_WALLS, RCQUEST_BOTH, RA_NONE, { Tricks::Tag::NOVICE }, "Break Mud Walls with Blue Fire", + "Use Blue Fire to break mud walls."); + OPT_TRICK(RT_KF_ADULT_GS, RCQUEST_BOTH, RA_KOKIRI_FOREST, { Tricks::Tag::NOVICE }, + "Adult Kokiri Forest GS with Hover Boots", + "Can be obtained without Hookshot by using the Hover Boots off of one of the roots."); + OPT_TRICK(RT_LW_BRIDGE, RCQUEST_BOTH, RA_THE_LOST_WOODS, { Tricks::Tag::EXPERT }, + "Jump onto the Lost Woods Bridge as Adult with Nothing", + "With very precise movement it's possible for adult to jump onto the bridge without needing Longshot, " + "Hover Boots, or Bean."); + OPT_TRICK(RT_LW_MIDO_BACKFLIP, RCQUEST_BOTH, RA_THE_LOST_WOODS, { Tricks::Tag::NOVICE }, + "Backflip over Mido as Adult", "With a specific position and angle, you can backflip over Mido."); + OPT_TRICK(RT_LW_GS_BEAN, RCQUEST_BOTH, RA_THE_LOST_WOODS, { Tricks::Tag::INTERMEDIATE }, + "Lost Woods Adult GS without Bean", + "You can collect the token with a precise Hookshot use, as long as you can kill the Skulltula somehow " + "first. It can be killed using Longshot, Bow, Bombchus or Din's Fire."); + OPT_TRICK(RT_HC_STORMS_GS, RCQUEST_BOTH, RA_HYRULE_CASTLE, { Tricks::Tag::INTERMEDIATE }, + "Hyrule Castle Storms Grotto GS with Just Boomerang", + "With precise throws, the Boomerang alone can kill the Skulltula and collect the token, without first " + "needing to blow up the wall."); + OPT_TRICK(RT_KAK_MAN_ON_ROOF, RCQUEST_BOTH, RA_KAKARIKO_VILLAGE, { Tricks::Tag::NOVICE }, + "Man on Roof without Hookshot", + "Can be reached by side-hopping off the watchtower as either age, or by jumping onto the potion shop's " + "roof from the ledge as adult."); + OPT_TRICK(RT_KAK_TOWER_GS, RCQUEST_BOTH, RA_KAKARIKO_VILLAGE, { Tricks::Tag::INTERMEDIATE }, + "Kakariko Tower GS with Jump Slash", + "Climb the tower as high as you can without touching the Gold Skulltula, then let go and jump slash " + "immediately. By jump-slashing from as low on the ladder as possible to still hit the Skulltula, this " + "trick can be done without taking fall damage."); + OPT_TRICK(RT_KAK_ADULT_WINDMILL_POH, RCQUEST_BOTH, RA_KAKARIKO_VILLAGE, { Tricks::Tag::NOVICE }, + "Windmill PoH as Adult with Nothing", "Can jump up to the spinning platform from below as adult."); + OPT_TRICK(RT_KAK_CHILD_WINDMILL_POH, RCQUEST_BOTH, RA_KAKARIKO_VILLAGE, { Tricks::Tag::EXTREME }, + "Windmill PoH as Child with Precise Jump Slash", + "Can jump up to the spinning platform from below as child with a precise jumpslash timed with the " + "platforms rotation."); + OPT_TRICK( + RT_KAK_ROOFTOP_GS, RCQUEST_BOTH, RA_KAKARIKO_VILLAGE, { Tricks::Tag::ADVANCED }, + "Kakariko Rooftop GS with Hover Boots", + "Take the Hover Boots from the entrance to Impa's House over to the rooftop of Skulltula House. From there, a " + "precise Hover Boots backwalk with backflip can be used to get onto a hill above the side of the village. And " + "then from there you can Hover onto Impa's rooftop to kill the Skulltula and backflip into the token."); + OPT_TRICK(RT_GY_POH, RCQUEST_BOTH, RA_THE_GRAVEYARD, { Tricks::Tag::INTERMEDIATE }, + "Graveyard Freestanding PoH with Boomerang", + "Using a precise moving setup you can obtain the Piece of Heart by having the Boomerang interact with it " + "along the return path."); + OPT_TRICK( + RT_GY_CHILD_DAMPE_RACE_POH, RCQUEST_BOTH, RA_THE_GRAVEYARD, { Tricks::Tag::NOVICE }, + "Second Dampe Race as Child", + "It is possible to complete the second dampe race as child in under a minute, but it is a strict time limit."); + OPT_TRICK(RT_GY_SHADOW_FIRE_ARROWS, RCQUEST_BOTH, RA_THE_GRAVEYARD, { Tricks::Tag::EXPERT }, + "Shadow Temple Entry with Fire Arrows", + "It is possible to light all of the torches to open the Shadow Temple entrance with just Fire Arrows, " + "but you must be very quick, precise, and strategic with how you take your shots."); + OPT_TRICK(RT_DMT_SOIL_GS, RCQUEST_BOTH, RA_DEATH_MOUNTAIN_TRAIL, { Tricks::Tag::INTERMEDIATE }, + "Death Mountain Trail Soil GS without Destroying Boulder", + "Bugs will go into the soft soil even while the boulder is still blocking the entrance. Then, using a " + "precise moving setup you can kill the Gold Skulltula and obtain the token by having the Boomerang " + "interact with it along the return path."); + OPT_TRICK(RT_DMT_BOMBABLE, RCQUEST_BOTH, RA_DEATH_MOUNTAIN_TRAIL, { Tricks::Tag::INTERMEDIATE }, + "Death Mountain Trail Chest with Strength", + "Child Link can blow up the wall using a nearby bomb flower. You must backwalk with the flower and then " + "quickly throw it toward the wall."); + OPT_TRICK(RT_DMT_HOOKSHOT_LOWER_GS, RCQUEST_BOTH, RA_DEATH_MOUNTAIN_TRAIL, { Tricks::Tag::INTERMEDIATE }, + "Death Mountain Trail Lower Red Rock GS with Hookshot", + "After killing the Skulltula, the token can be fished out of the rock without needing to destroy it, by " + "using the Hookshot in the correct way."); + OPT_TRICK(RT_DMT_HOVERS_LOWER_GS, RCQUEST_BOTH, RA_DEATH_MOUNTAIN_TRAIL, { Tricks::Tag::ADVANCED }, + "Death Mountain Trail Lower Red Rock GS with Hover Boots", + "After killing the Skulltula, the token can be collected without needing to destroy the rock by " + "backflipping down onto it with the Hover Boots. First use the Hover Boots to stand on a nearby fence, " + "and go for the Skulltula Token from there."); + OPT_TRICK(RT_DMT_BEAN_LOWER_GS, RCQUEST_BOTH, RA_DEATH_MOUNTAIN_TRAIL, { Tricks::Tag::EXPERT }, + "Death Mountain Trail Lower Red Rock GS with Magic Bean", + "After killing the Skulltula, the token can be collected without needing to destroy the rock by jumping " + "down onto it from the bean plant, midflight, with precise timing and positioning."); + OPT_TRICK(RT_DMT_JS_LOWER_GS, RCQUEST_BOTH, RA_DEATH_MOUNTAIN_TRAIL, { Tricks::Tag::INTERMEDIATE }, + "Death Mountain Trail Lower Red Rock GS with Jump Slash", + "After killing the Skulltula, the token can be collected without needing to destroy the rock by jump " + "slashing from a precise angle."); + OPT_TRICK(RT_DMT_CLIMB_HOVERS, RCQUEST_BOTH, RA_DEATH_MOUNTAIN_TRAIL, { Tricks::Tag::ADVANCED }, + "Death Mountain Trail Climb with Hover Boots", + "It is possible to use the Hover Boots to bypass needing to destroy the boulders blocking the path to " + "the top of Death Mountain."); + OPT_TRICK( + RT_DMT_UPPER_GS, RCQUEST_BOTH, RA_DEATH_MOUNTAIN_TRAIL, { Tricks::Tag::NOVICE }, + "Death Mountain Trail Upper Red Rock GS without Hammer", + "After killing the Skulltula, the token can be collected by backflipping into the rock at the correct angle."); + // disabled for now, only applies when trade quest is not shuffled so there's a timer (currently not considered in + // logic) OPT_TRICK(RT_DMT_BOLERO_BIGGORON, RCQUEST_BOTH, RA_DEATH_MOUNTAIN_TRAIL, {Tricks::Tag::INTERMEDIATE}, + // "Deliver Eye Drops with Bolero of Fire", "Playing a warp song normally causes a trade item to spoil immediately, + // however, it is possible use Bolero to reach Biggoron and still deliver the Eye Drops before they spoil. If you do + // not wear the Goron Tunic, the heat timer inside the crater will override the trade item\'s timer. When you exit + // to Death Mountain Trail you will have one second to show the Eye Drops before they expire. You can get extra time + // to show the Eye Drops if you warp immediately upon receiving them. If you don't have many hearts, you may have to + // reset the heat timer by quickly dipping in and out of Darunia\'s chamber or quickly equipping and unequipping the + // Goron Tunic. This trick does not apply if \"Randomize Warp Song Destinations\" is enabled, or if the settings are + // such that trade items do not need to be delivered within a time limit."); + OPT_TRICK(RT_GC_POT, RCQUEST_BOTH, RA_GORON_CITY, { Tricks::Tag::ADVANCED }, + "Goron City Spinning Pot PoH with Bombchu", + "A Bombchu can be used to stop the spinning pot, but it can be quite finicky to get it to work."); + OPT_TRICK(RT_GC_POT_STRENGTH, RCQUEST_BOTH, RA_GORON_CITY, { Tricks::Tag::INTERMEDIATE }, + "Goron City Spinning Pot PoH with Strength", + "Allows for stopping the Goron City Spinning Pot using a Bomb Flower alone, requiring strength in lieu " + "of inventory explosives."); + OPT_TRICK(RT_GC_ROLLING_STRENGTH, RCQUEST_BOTH, RA_GORON_CITY, { Tricks::Tag::INTERMEDIATE }, + "Rolling Goron (Hot Rodder Goron) as Child with Strength", + "Use the Bomb Flower on the stairs or near Medigoron. Timing is tight, especially without backwalking."); + OPT_TRICK(RT_GC_LEFTMOST, RCQUEST_BOTH, RA_GORON_CITY, { Tricks::Tag::ADVANCED }, + "Goron City Maze Left Chest with Hover Boots", + "A precise backwalk starting from on top of the crate and ending with a precisely-timed backflip can " + "reach this chest without needing either the Hammer or Silver Gauntlets."); + OPT_TRICK(RT_GC_GROTTO, RCQUEST_BOTH, RA_GORON_CITY, { Tricks::Tag::ADVANCED }, + "Goron City Grotto with Hookshot While Taking Damage", + "It is possible to reach the Goron City Grotto by quickly using the Hookshot while in the midst of " + "taking damage from the lava floor."); + OPT_TRICK(RT_GC_LINK_GORON_DINS, RCQUEST_BOTH, RA_GORON_CITY, { Tricks::Tag::NOVICE }, + "Stop Link the Goron with Din\'s Fire", "The timing is quite awkward."); + OPT_TRICK(RT_DMC_HOVER_BEAN_POH, RCQUEST_BOTH, RA_DEATH_MOUNTAIN_CRATER, { Tricks::Tag::NOVICE }, + "Crater\'s Bean PoH with Hover Boots", + "Hover from the base of the bridge near Goron City and walk up the very steep slope."); + OPT_TRICK(RT_DMC_BOLERO_JUMP, RCQUEST_BOTH, RA_DEATH_MOUNTAIN_CRATER, { Tricks::Tag::EXTREME }, + "Death Mountain Crater Jump to Bolero", + "As Adult, using a shield to drop a pot while you have the perfect speed and position, the pot can push " + "you that little extra distance you need to jump across the gap in the bridge."); + OPT_TRICK(RT_DMC_BOULDER_JS, RCQUEST_BOTH, RA_DEATH_MOUNTAIN_CRATER, { Tricks::Tag::NOVICE }, + "Death Mountain Crater Upper to Lower with Hammer", + "With the Hammer, you can jump slash the rock twice in the same jump in order to destroy it before you " + "fall into the lava."); + OPT_TRICK(RT_DMC_BOULDER_SKIP, RCQUEST_BOTH, RA_DEATH_MOUNTAIN_CRATER, { Tricks::Tag::INTERMEDIATE }, + "Death Mountain Crater Upper to Lower Boulder Skip", + "As adult, With careful positioning, you can jump to the ledge where the boulder is, then use repeated " + "ledge grabs to shimmy to a climbable ledge. This trick supersedes \"Death Mountain Crater Upper to " + "Lower with Hammer\"."); + OPT_TRICK(RT_ZR_LOWER, RCQUEST_BOTH, RA_ZORAS_RIVER, { Tricks::Tag::INTERMEDIATE }, + "Zora\'s River Lower Freestanding PoH as Adult with Nothing", + "Adult can reach this PoH with a precise jump, no Hover Boots required."); + OPT_TRICK(RT_ZR_UPPER, RCQUEST_BOTH, RA_ZORAS_RIVER, { Tricks::Tag::INTERMEDIATE }, + "Zora\'s River Upper Freestanding PoH as Adult with Nothing", + "Adult can reach this PoH with a precise jump, no Hover Boots required."); + OPT_TRICK(RT_ZR_HOVERS, RCQUEST_BOTH, RA_ZORAS_RIVER, { Tricks::Tag::NOVICE }, + "Zora\'s Domain Entry with Hover Boots", "Can hover behind the waterfall as adult."); + OPT_TRICK(RT_ZR_CUCCO, RCQUEST_BOTH, RA_ZORAS_RIVER, { Tricks::Tag::NOVICE }, "Zora\'s Domain Entry with Cucco", + "You can fly behind the waterfall with a Cucco as child."); + OPT_TRICK(RT_ZD_KING_ZORA_SKIP, RCQUEST_BOTH, RA_ZORAS_DOMAIN, { Tricks::Tag::INTERMEDIATE }, + "Skip King Zora as Adult with Nothing", + "With a precise jump as adult, it is possible to get on the fence next to King Zora from the front to " + "access Zora's Fountain."); + OPT_TRICK(RT_ZD_GS, RCQUEST_BOTH, RA_ZORAS_DOMAIN, { Tricks::Tag::INTERMEDIATE }, + "Zora\'s Domain GS with No Additional Items", + "A precise jump slash can kill the Skulltula and recoil back onto the top of the frozen waterfall. To " + "kill it, the logic normally guarantees one of Hookshot, Bow, or Magic."); + OPT_TRICK(RT_ZF_GREAT_FAIRY_WITHOUT_EXPLOSIVES, RCQUEST_BOTH, RA_ZORAS_FOUNTAIN, { Tricks::Tag::NOVICE }, + "Zora\'s Fountain Great Fairy Without Explosives", + "It's possible to use silver gauntlets to pick up the silver rock and hammer to break the rock below it, " + "allowing you to ledge grab the edge of the hole and get past the breakable wall (hammer can't break the " + "wall itself)."); + OPT_TRICK(RT_LH_LAB_WALL_GS, RCQUEST_BOTH, RA_LAKE_HYLIA, { Tricks::Tag::NOVICE }, + "Lake Hylia Lab Wall GS with Jump Slash", + "The jump slash to actually collect the token is somewhat precise."); + OPT_TRICK(RT_LH_LAB_DIVING, RCQUEST_BOTH, RA_LAKE_HYLIA, { Tricks::Tag::NOVICE }, + "Lake Hylia Lab Dive without Gold Scale", + "Remove the Iron Boots in the midst of Hookshotting the underwater crate."); + OPT_TRICK(RT_LH_WATER_HOOKSHOT, RCQUEST_BOTH, RA_LAKE_HYLIA, { Tricks::Tag::INTERMEDIATE }, + "Water Temple Entry without Iron Boots using Hookshot", + "When entering Water Temple using Gold Scale instead of Iron Boots, the Longshot is usually used to be " + "able to hit the switch and open the gate. But, by standing in a particular spot, the switch can be hit " + "with only the reach of the Hookshot."); + OPT_TRICK(RT_GV_CRATE_HOVERS, RCQUEST_BOTH, RA_GERUDO_VALLEY, { Tricks::Tag::INTERMEDIATE }, + "Gerudo Valley Crate PoH as Adult with Hover Boots", + "From the far side of Gerudo Valley, a precise Hover Boots movement and jump-slash recoil can allow " + "adult to reach the ledge with the crate PoH without needing Longshot. You will take fall damage."); + OPT_TRICK(RT_GF_KITCHEN, RCQUEST_BOTH, RA_GERUDO_FORTRESS, { Tricks::Tag::NOVICE }, + "Thieves\' Hideout \"Kitchen\" with No Additional Items", + "Allows passing through the kitchen by avoiding being seen by the guards. The logic normally guarantees " + "Bow or Hookshot to stun them from a distance, or Hover Boots to cross the room without needing to deal " + "with the guards."); + OPT_TRICK(RT_GF_JUMP, RCQUEST_BOTH, RA_GERUDO_FORTRESS, { Tricks::Tag::NOVICE }, "Gerudo\'s Fortress Ledge Jumps", + "Adult can jump onto the top roof of the fortress without going through the interior of the hideout."); + OPT_TRICK(RT_GF_WARRIOR_WITH_DIFFICULT_WEAPON, RCQUEST_BOTH, RA_GERUDO_FORTRESS, { Tricks::Tag::NOVICE }, + "Gerudo\'s Fortress Warriors with Difficult Weapons", + "Warriors can be defeated with Slingshot or Bombchus."); + // disabled for now, can't check for being able to use bunny hood & bunny hood speedup is currently completely + // decoupled from rando OPT_TRICK(RT_HW_BUNNY_CROSSING, RCQUEST_BOTH, RA_HAUNTED_WASTELAND, {Tricks::Tag::NOVICE}, + // "Wasteland Crossing with Bunny Hood", "You can beat the quicksand by using the increased speed of the Bunny Hood. + // Note that jumping to the carpet merchant as child typically requires a fairly precise jump slash."); + OPT_TRICK(RT_HW_CROSSING, RCQUEST_BOTH, RA_HAUNTED_WASTELAND, { Tricks::Tag::INTERMEDIATE }, + "Wasteland Crossing without Hover Boots or Longshot", + "You can beat the quicksand by backwalking across it in a specific way. Note that jumping to the carpet " + "merchant as child typically requires a fairly precise jump slash."); + OPT_TRICK(RT_LENS_HW, RCQUEST_BOTH, RA_HAUNTED_WASTELAND, { Tricks::Tag::INTERMEDIATE }, "Lensless Wasteland", + "By memorizing the path, you can travel through the Wasteland without using the Lens of Truth to see the " + "Poe. The equivalent trick for going in reverse through the Wasteland is \"Reverse Wasteland\"."); + OPT_TRICK( + RT_HW_REVERSE, RCQUEST_BOTH, RA_HAUNTED_WASTELAND, { Tricks::Tag::INTERMEDIATE }, "Reverse Wasteland", + "By memorizing the path, you can travel through the Wasteland in reverse. Note that jumping to the carpet " + "merchant as child typically requires a fairly precise jump slash. The equivalent trick for going forward " + "through the Wasteland is \"Lensless Wasteland\". To cross the river of sand with no additional items, be sure " + "to also enable \"Wasteland Crossing without Hover Boots or Longshot\". Unless all overworld entrances are " + "randomized, Child Link will not be expected to do anything at Gerudo's Fortress."); + OPT_TRICK(RT_COLOSSUS_GS, RCQUEST_BOTH, RA_DESERT_COLOSSUS, { Tricks::Tag::NOVICE }, + "Colossus Hill GS with Hookshot", + "Somewhat precise. If you kill enough Leevers you can get enough of a break to take some time to aim " + "more carefully."); + OPT_TRICK(RT_DEKU_BASEMENT_GS, RCQUEST_VANILLA, RA_DEKU_TREE, { Tricks::Tag::NOVICE }, + "Deku Tree Basement Vines GS with Jump Slash", "Can be defeated by doing a precise jump slash."); + OPT_TRICK(RT_DEKU_B1_SKIP, RCQUEST_BOTH, RA_DEKU_TREE, { Tricks::Tag::INTERMEDIATE }, + "Deku Tree Basement without Slingshot", + "A precise jump can be used to skip needing to use the Slingshot to go around B1 of the Deku Tree. If " + "used with the \"Closed Forest\" setting, a Slingshot will not be guaranteed to exist somewhere inside " + "the Forest. This trick applies to both Vanilla and Master Quest."); + OPT_TRICK(RT_DEKU_B1_BOW_WEBS, RCQUEST_VANILLA, RA_DEKU_TREE, { Tricks::Tag::NOVICE }, + "Deku Tree Basement Web to Gohma with Bow", + "All spider web walls in the Deku Tree basement can be burnt as adult with just a bow by shooting " + "through torches. This trick only applies to the circular web leading to Gohma; the two vertical webs " + "are always in logic. Backflip onto the chest near the torch at the bottom of the vine wall. With " + "precise positioning you can shoot through the torch to the right edge of the circular web. This allows " + "completion of adult Deku Tree with no fire source."); + OPT_TRICK(RT_DEKU_B1_BACKFLIP_OVER_SPIKED_LOG, RCQUEST_VANILLA, RA_DEKU_TREE, { Tricks::Tag::NOVICE }, + "Deku Tree Basement Backflip over Spiked Log", + "Allows backflipping over the spiked log in the Deku Tree basement in Vanilla. Only relevant if " + "\"Shuffle Swim\" is enabled."); + OPT_TRICK(RT_DEKU_MQ_COMPASS_GS, RCQUEST_MQ, RA_DEKU_TREE, { Tricks::Tag::NOVICE }, + "Deku Tree MQ Compass Room GS Boulders with Just Hammer", + "Climb to the top of the vines, then let go and jump slash immediately to destroy the boulders using the " + "Hammer, without needing to spawn a Song of Time block."); + OPT_TRICK(RT_DEKU_MQ_LOG, RCQUEST_MQ, RA_DEKU_TREE, { Tricks::Tag::NOVICE }, + "Deku Tree MQ Roll Under the Spiked Log", + "You can get past the spiked log by rolling to briefly shrink your hitbox. As adult, the timing is a bit " + "more precise."); + OPT_TRICK(RT_DC_SCARECROW_GS, RCQUEST_VANILLA, RA_DODONGOS_CAVERN, { Tricks::Tag::NOVICE }, + "Dodongo\'s Cavern Scarecrow GS with Armos Statue", + "You can jump off an Armos Statue to reach the alcove with the Gold Skulltula. It takes quite a long " + "time to pull the statue the entire way. The jump to the alcove can be a bit picky when done as child."); + OPT_TRICK(RT_DC_VINES_GS, RCQUEST_VANILLA, RA_DODONGOS_CAVERN, { Tricks::Tag::NOVICE }, + "Dodongo\'s Cavern Vines GS from Below with Longshot", + "The vines upon which this Skulltula rests are one-sided collision. You can use the Longshot to get it " + "from below, by shooting it through the vines, bypassing the need to lower the staircase."); + OPT_TRICK(RT_DC_STAIRCASE, RCQUEST_VANILLA, RA_DODONGOS_CAVERN, { Tricks::Tag::NOVICE }, + "Dodongo\'s Cavern Staircase with Bow", + "The Bow can be used to knock down the stairs with two well-timed shots."); + OPT_TRICK(RT_DC_SLINGSHOT_SKIP, RCQUEST_VANILLA, RA_DODONGOS_CAVERN, { Tricks::Tag::EXPERT }, + "Dodongo\'s Cavern Child Slingshot Skips", + "With precise platforming, child can cross the platforms while the flame circles are there. When " + "enabling this trick, it's recommended that you also enable the Adult variant: \"Dodongo's Cavern Spike " + "Trap Room Jump without Hover Boots\"."); + OPT_TRICK(RT_DC_SCRUB_ROOM, RCQUEST_VANILLA, RA_DODONGOS_CAVERN, { Tricks::Tag::NOVICE }, + "Dodongo\'s Cavern Two Scrub Room with Strength", + "With help from a conveniently-positioned block, Adult can quickly carry a Bomb Flower over to destroy " + "the mud wall blocking the room with two Deku Scrubs."); + OPT_TRICK(RT_DC_JUMP, RCQUEST_BOTH, RA_DODONGOS_CAVERN, { Tricks::Tag::NOVICE }, + "Dodongo\'s Cavern Spike Trap Room Jump without Hover Boots", + "The jump is Adult Link only. Applies to both Vanilla and MQ."); + OPT_TRICK(RT_DC_HAMMER_FLOOR, RCQUEST_BOTH, RA_DODONGOS_CAVERN, { Tricks::Tag::NOVICE }, + "Dodongo\'s Cavern Smash the Boss Lobby Floor", + "The bombable floor before King Dodongo can be destroyed with Hammer if hit in the very center. This is " + "only relevant with Shuffle Boss Entrances or if Dodongo's Cavern is MQ and either variant of " + "\"Dodongo's Cavern MQ Light the Eyes with Strength\" is on."); + OPT_TRICK(RT_DC_MQ_CHILD_BOMBS, RCQUEST_MQ, RA_DODONGOS_CAVERN, { Tricks::Tag::ADVANCED }, + "Dodongo\'s Cavern MQ Early Bomb Bag Area as Child", + "With a precise jump slash from above, you can reach the Bomb Bag area as only child without needing a " + "Slingshot. You will take fall damage."); + OPT_TRICK(RT_DC_MQ_CHILD_EYES, RCQUEST_MQ, RA_DODONGOS_CAVERN, { Tricks::Tag::EXPERT }, + "Dodongo\'s Cavern MQ Light the Eyes with Strength as Child", + "If you move very quickly, it is possible to use the bomb flower at the top of the room to light the " + "eyes. To perform this trick as child is significantly more difficult than adult. The player is also " + "expected to complete the DC back area without explosives, including getting past the Armos wall to the " + "switch for the boss door."); + OPT_TRICK( + RT_DC_MQ_ADULT_EYES, RCQUEST_MQ, RA_DODONGOS_CAVERN, { Tricks::Tag::ADVANCED }, + "Dodongo\'s Cavern MQ Light the Eyes with Strength as Adult", + "If you move very quickly, it is possible to use the bomb flower at the top of the room to light the eyes."); + OPT_TRICK(RT_JABU_ALCOVE_JUMP_DIVE, RCQUEST_BOTH, RA_JABU_JABUS_BELLY, { Tricks::Tag::NOVICE }, + "Jabu Underwater Alcove as Adult with Jump Dive", + "Standing above the underwater tunnel leading to the scrub, jump down and swim through the tunnel. This " + "allows adult to access the alcove with no Scale or Iron Boots. In Vanilla Jabu, this alcove has a " + "business scrub. In MQ Jabu, it has the compass chest and a door switch for the main floor."); + OPT_TRICK(RT_JABU_BOSS_HOVER, RCQUEST_VANILLA, RA_JABU_JABUS_BELLY, { Tricks::Tag::INTERMEDIATE }, + "Jabu Near Boss Room with Hover Boots", + "A box for the blue switch can be carried over by backwalking with one while the elevator is at its " + "peak. Alternatively, you can skip transporting a box by quickly rolling from the switch and opening the " + "door before it closes. However, the timing for this is very tight."); + OPT_TRICK( + RT_JABU_NEAR_BOSS_RANGED, RCQUEST_BOTH, RA_JABU_JABUS_BELLY, { Tricks::Tag::NOVICE }, + "Jabu Near Boss Ceiling Switch/GS without Boomerang or Explosives", + "Vanilla Jabu: From near the entrance into the room, you can hit the switch that opens the door to the boss " + "room using a precisely-aimed use of the Slingshot, Bow, or Longshot. As well, if you climb to the top of the " + "vines you can stand on the right edge of the platform and shoot around the glass. From this distance, even " + "the Hookshot can reach the switch. This trick is only relevant if \"Shuffle Boss Entrances\" is enabled. MQ " + "Jabu: A Gold Skulltula Token can be collected with the Hookshot or Longshot using the same methods as hitting " + "the switch in Vanilla. This MQ trick is not currently relevant in logic."); + OPT_TRICK(RT_JABU_NEAR_BOSS_EXPLOSIVES, RCQUEST_VANILLA, RA_JABU_JABUS_BELLY, { Tricks::Tag::INTERMEDIATE }, + "Jabu Near Boss Ceiling Switch with Explosives", + "You can hit the switch that opens the door to the boss room using a precisely-aimed Bombchu. Also, " + "using the Hover Boots, adult can throw a Bomb at the switch. This trick is only relevant if \"Shuffle " + "Boss Entrances\" is enabled."); + OPT_TRICK(RT_LENS_JABU_MQ, RCQUEST_MQ, RA_JABU_JABUS_BELLY, { Tricks::Tag::NOVICE }, + "Jabu MQ without Lens of Truth", "Removes the requirements for the Lens of Truth in Jabu MQ."); + OPT_TRICK(RT_JABU_MQ_RANG_JUMP, RCQUEST_MQ, RA_JABU_JABUS_BELLY, { Tricks::Tag::ADVANCED }, + "Jabu MQ Compass Chest with Boomerang", + "Boomerang can reach the cow switch to spawn the chest by targeting the cow, jumping off of the ledge " + "where the chest spawns, and throwing the Boomerang in midair."); + OPT_TRICK(RT_JABU_MQ_SOT_GS, RCQUEST_MQ, RA_JABU_JABUS_BELLY, { Tricks::Tag::INTERMEDIATE }, + "Jabu MQ Song of Time Block GS with Boomerang", + "Allow the Boomerang to return to you through the Song of Time block to grab the token."); + OPT_TRICK(RT_LENS_BOTW, RCQUEST_VANILLA, RA_BOTTOM_OF_THE_WELL, { Tricks::Tag::NOVICE }, + "Bottom of the Well without Lens of Truth", + "Removes the requirements for the Lens of Truth in Bottom of the Well."); + OPT_TRICK(RT_BOTW_CHILD_DEADHAND, RCQUEST_BOTH, RA_BOTTOM_OF_THE_WELL, { Tricks::Tag::NOVICE }, + "Child Dead Hand without Kokiri Sword", "Requires 9 sticks or 5 jump slashes."); + OPT_TRICK(RT_BOTW_BASEMENT, RCQUEST_VANILLA, RA_BOTTOM_OF_THE_WELL, { Tricks::Tag::NOVICE }, + "Bottom of the Well Map Chest with Strength & Sticks", + "The chest in the basement can be reached with strength by doing a jump slash with a lit stick to access " + "the Bomb Flowers."); + OPT_TRICK(RT_BOTW_MQ_PITS, RCQUEST_MQ, RA_BOTTOM_OF_THE_WELL, { Tricks::Tag::NOVICE }, + "Bottom of the Well MQ Jump Over the Pits", + "While the pits in Bottom of the Well don't allow you to jump just by running straight at them, you can " + "still get over them by side-hopping or backflipping across. With explosives, this allows you to access " + "the central areas without Zelda's Lullaby. With Zelda's Lullaby, it allows you to access the west inner " + "room without explosives."); + OPT_TRICK(RT_BOTW_MQ_DEADHAND_KEY, RCQUEST_MQ, RA_BOTTOM_OF_THE_WELL, { Tricks::Tag::NOVICE }, + "Bottom of the Well MQ Dead Hand Freestanding Key with Boomerang", + "Boomerang can fish the item out of the rubble without needing explosives to blow it up."); + OPT_TRICK(RT_FOREST_FIRST_GS, RCQUEST_VANILLA, RA_FOREST_TEMPLE, { Tricks::Tag::NOVICE }, + "Forest Temple First Room GS with Difficult-to-Use Weapons", + "Allows killing this Skulltula with Sword or Sticks by jump slashing it as you let go from the vines. " + "You can avoid taking fall damage by recoiling onto the tree. Also allows killing it as Child with a " + "Bomb throw. It's much more difficult to use a Bomb as child due to Child Link's shorter height."); + OPT_TRICK(RT_FOREST_OUTDOORS_EAST_GS, RCQUEST_VANILLA, RA_FOREST_TEMPLE, { Tricks::Tag::NOVICE }, + "Forest Temple East Courtyard GS with Boomerang", + "Precise Boomerang throws can allow child to kill the Skulltula and collect the token."); + OPT_TRICK(RT_FOREST_VINES, RCQUEST_BOTH, RA_FOREST_TEMPLE, { Tricks::Tag::NOVICE }, + "Forest Temple East Courtyard Vines with Hookshot", + "The vines in Forest Temple leading to where the well drain switch is in the standard form can be barely " + "reached with just the Hookshot. Applies to MQ also."); + OPT_TRICK(RT_FOREST_OUTDOORS_LEDGE, RCQUEST_BOTH, RA_FOREST_TEMPLE, { Tricks::Tag::NOVICE }, + "Forest Temple NE Outdoors Ledge with Hover Boots", + "With precise Hover Boots movement you can fall down to this ledge from upper balconies. If done " + "precisely enough, it is not necessary to take fall damage. In MQ, this skips a Longshot requirement. In " + "Vanilla, this can skip a Hookshot requirement in entrance randomizer."); + OPT_TRICK(RT_FOREST_DOORFRAME, RCQUEST_BOTH, RA_FOREST_TEMPLE, { Tricks::Tag::ADVANCED }, + "Forest Temple East Courtyard Door Frame with Hover Boots", + "A precise Hover Boots movement from the upper balconies in this courtyard can be used to get on top of " + "the door frame. Applies to both Vanilla and Master Quest. In Vanilla, from on top the door frame you " + "can summon Pierre, allowing you to access the falling ceiling room early. In Master Quest, this allows " + "you to obtain the GS on the door frame as adult without Hookshot or Song of Time."); + OPT_TRICK(RT_FOREST_OUTSIDE_BACKDOOR, RCQUEST_BOTH, RA_FOREST_TEMPLE, { Tricks::Tag::ADVANCED }, + "Forest Temple Outside Backdoor with Jump Slash", + "A jump slash recoil can be used to reach the ledge in the block puzzle room that leads to the west " + "courtyard. This skips a potential Hover Boots requirement in Vanilla, and it can sometimes apply in MQ " + "as well. This trick can be performed as both ages."); + OPT_TRICK(RT_FOREST_OUTDOORS_HEARTS_BOOMERANG, RCQUEST_BOTH, RA_FOREST_TEMPLE, { Tricks::Tag::NOVICE }, + "Forest Temple Outside Hearts with Boomerang", + "A well aimed boomerang from the water's edge can reach the hearts from ground level. If unable to swim, " + "you can back away from the water while the boomerang is returning so the hearts land on the ground."); + OPT_TRICK(RT_FOREST_MQ_WELL_SWIM, RCQUEST_MQ, RA_FOREST_TEMPLE, { Tricks::Tag::ADVANCED }, + "Swim Through Forest Temple MQ Well with Hookshot", + "Shoot the vines in the well as low and as far to the right as possible, and then immediately swim under " + "the ceiling to the right. This can only be required if Forest Temple is in its Master Quest form."); + OPT_TRICK(RT_FOREST_MQ_BLOCK_PUZZLE, RCQUEST_MQ, RA_FOREST_TEMPLE, { Tricks::Tag::NOVICE }, + "Skip Forest Temple MQ Block Puzzle with Bombchu", + "Send the Bombchu straight up the center of the wall directly to the left upon entering the room."); + // Child with hovers cannot do this from the lower floor, and most go to the upper floor which needs goron bracelet. + // Adult can do this with hammer and KSword, But child cannot. + OPT_TRICK(RT_FOREST_MQ_JS_HALLWAY_SWITCH, RCQUEST_MQ, RA_FOREST_TEMPLE, { Tricks::Tag::NOVICE }, + "Forest Temple MQ Twisted Hallway Switch with Jump Slash", + "The switch to twist the hallway can be hit with a jump slash through the glass block. To get in front " + "of the switch, either use the Hover Boots or hit the shortcut switch at the top of the room and jump " + "from the glass blocks that spawn. Sticks can be used as child, but the Kokiri Sword is too short to " + "reach through the glass."); + OPT_TRICK(RT_FOREST_MQ_HOOKSHOT_HALLWAY_SWITCH, RCQUEST_MQ, RA_FOREST_TEMPLE, { Tricks::Tag::INTERMEDIATE }, + "Forest Temple MQ Twisted Hallway Switch with Hookshot", + "There's a very small gap between the glass block and the wall. Through that gap you can hookshot the " + "target on the ceiling."); + OPT_TRICK(RT_FOREST_MQ_RANG_HALLWAY_SWITCH, RCQUEST_MQ, RA_FOREST_TEMPLE, { Tricks::Tag::INTERMEDIATE }, + "Forest Temple MQ Twisted Hallway Switch with Boomerang", + "The Boomerang can return to Link through walls, allowing child to hit the hallway switch. This can be " + "used to allow adult to pass through later, or in conjunction with \"Forest Temple Outside Backdoor with " + "Jump Slash\"."); + OPT_TRICK(RT_FIRE_BOSS_DOOR_JUMP, RCQUEST_BOTH, RA_FIRE_TEMPLE, { Tricks::Tag::NOVICE }, + "Fire Temple Boss Door without Hover Boots or Pillar", + "The Fire Temple Boss Door can be reached as adult with a precise jump. You must be touching the side " + "wall of the room so that Link will grab the ledge from farther away than is normally possible."); + // Is also used in MQ logic, but has no practical effect there as of now + OPT_TRICK(RT_FIRE_SOT, RCQUEST_VANILLA, RA_FIRE_TEMPLE, { Tricks::Tag::INTERMEDIATE }, + "Fire Temple Song of Time Room GS without Song of Time", + "A precise jump can be used to reach this room."); + OPT_TRICK(RT_FIRE_STRENGTH, RCQUEST_VANILLA, RA_FIRE_TEMPLE, { Tricks::Tag::INTERMEDIATE }, + "Fire Temple Climb without Strength", "A precise jump can be used to skip pushing the block."); + OPT_TRICK(RT_FIRE_SCARECROW, RCQUEST_VANILLA, RA_FIRE_TEMPLE, { Tricks::Tag::EXPERT }, + "Fire Temple East Tower without Scarecrow\'s Song", + "Also known as \"Pixelshot\". The Longshot can reach the target on the elevator itself, allowing you to " + "skip needing to spawn the scarecrow."); + OPT_TRICK(RT_FIRE_FLAME_MAZE, RCQUEST_VANILLA, RA_FIRE_TEMPLE, { Tricks::Tag::INTERMEDIATE }, + "Fire Temple Flame Wall Maze Skip", + "If you move quickly you can sneak past the edge of a flame wall before it can rise up to block you. To " + "do it without taking damage is more precise. Allows you to progress without needing either a Small Key " + "or Hover Boots."); + OPT_TRICK(RT_FIRE_MQ_NEAR_BOSS, RCQUEST_MQ, RA_FIRE_TEMPLE, { Tricks::Tag::NOVICE }, + "Fire Temple MQ Chest Near Boss without Breaking Crate", + "The hitbox for the torch extends a bit outside of the crate. Shoot a flaming arrow at the side of the " + "crate to light the torch without needing to get over there and break the crate."); + OPT_TRICK(RT_FIRE_MQ_BLOCKED_CHEST, RCQUEST_MQ, RA_FIRE_TEMPLE, { Tricks::Tag::INTERMEDIATE }, + "Fire Temple MQ Big Lava Room Blocked Door without Hookshot", + "There is a gap between the hitboxes of the flame wall in the big lava room. If you know where this gap " + "is located, you can jump through it and skip needing to use the Hookshot. To do this without taking " + "damage is more precise."); + OPT_TRICK( + RT_FIRE_MQ_BK_CHEST, RCQUEST_MQ, RA_FIRE_TEMPLE, { Tricks::Tag::INTERMEDIATE }, + "Fire Temple MQ Boss Key Chest without Bow", + "It is possible to light both of the timed torches to unbar the door to the boss key chest's room with just " + "Din's Fire if you move very quickly between the two torches. It is also possible to unbar the door with just " + "Din's Fire by abusing an oversight in the way the game counts how many torches have been lit."); + OPT_TRICK(RT_FIRE_MQ_CLIMB, RCQUEST_MQ, RA_FIRE_TEMPLE, { Tricks::Tag::NOVICE }, + "Fire Temple MQ Climb without Fire Source", + "You can use the Hover Boots to hover around to the climbable wall, skipping the need to use a fire " + "source and spawn a Hookshot target."); + OPT_TRICK(RT_FIRE_MQ_MAZE_SIDE_ROOM, RCQUEST_MQ, RA_FIRE_TEMPLE, { Tricks::Tag::NOVICE }, + "Fire Temple MQ Lizalfos Maze Side Room without Box", + "You can walk from the blue switch to the door and quickly open the door before the bars reclose. This " + "skips needing to reach the upper sections of the maze to get a box to place on the switch."); + OPT_TRICK(RT_FIRE_MQ_MAZE_HOVERS, RCQUEST_MQ, RA_FIRE_TEMPLE, { Tricks::Tag::NOVICE }, + "Fire Temple MQ Lower to Upper Lizalfos Maze with Hover Boots", + "Use the Hover Boots off of a crate to climb to the upper maze without needing to spawn and use the " + "Hookshot targets."); + OPT_TRICK(RT_FIRE_MQ_MAZE_JUMP, RCQUEST_MQ, RA_FIRE_TEMPLE, { Tricks::Tag::INTERMEDIATE }, + "Fire Temple MQ Lower to Upper Lizalfos Maze with Precise Jump", + "A precise jump off of a crate can be used to climb to the upper maze without needing to spawn and use " + "the Hookshot targets. This trick supersedes both \"Fire Temple MQ Lower to Upper Lizalfos Maze with " + "Hover Boots\" and \"Fire Temple MQ Lizalfos Maze Side Room without Box\"."); + OPT_TRICK(RT_FIRE_MQ_ABOVE_MAZE_GS, RCQUEST_MQ, RA_FIRE_TEMPLE, { Tricks::Tag::INTERMEDIATE }, + "Fire Temple MQ Above Flame Wall Maze GS from Below with Longshot", + "The floor of the room that contains this Skulltula is only solid from above. From the maze below, the " + "Longshot can be shot through the ceiling to obtain the token with two fewer small keys than normal."); + OPT_TRICK( + RT_FIRE_MQ_FLAME_MAZE, RCQUEST_MQ, RA_FIRE_TEMPLE, { Tricks::Tag::INTERMEDIATE }, + "Fire Temple MQ Flame Wall Maze Skip", + "If you move quickly you can sneak past the edge of a flame wall before it can rise up to block you. To do it " + "without taking damage is more precise. Allows you to reach the side room GS without needing Song of Time or " + "Hover Boots. If either of \"Fire Temple MQ Lower to Upper Lizalfos Maze with Hover Boots\" or \"with Precise " + "Jump\" are enabled, this also allows you to progress deeper into the dungeon without Hookshot."); + OPT_TRICK(RT_WATER_LONGSHOT_TORCH, RCQUEST_VANILLA, RA_WATER_TEMPLE, { Tricks::Tag::NOVICE }, + "Water Temple Torch Longshot", + "Stand on the eastern side of the central pillar and longshot the torches on the bottom level. Swim " + "through the corridor and float up to the top level. This allows access to this area and lower water " + "levels without Iron Boots. The majority of the tricks that allow you to skip Iron Boots in the Water " + "Temple are not going to be relevant unless this trick is first enabled."); + OPT_TRICK(RT_WATER_CRACKED_WALL_HOVERS, RCQUEST_VANILLA, RA_WATER_TEMPLE, { Tricks::Tag::NOVICE }, + "Water Temple Cracked Wall with Hover Boots", + "With a midair side-hop while wearing the Hover Boots, you can reach the cracked wall without needing to " + "raise the water up to the middle level."); + OPT_TRICK(RT_WATER_CRACKED_WALL, RCQUEST_VANILLA, RA_WATER_TEMPLE, { Tricks::Tag::INTERMEDIATE }, + "Water Temple Cracked Wall with No Additional Items", + "A precise jump slash (among other methods) will get you to the cracked wall without needing the Hover " + "Boots or to raise the water to the middle level. This trick supersedes \"Water Temple Cracked Wall with " + "Hover Boots\"."); + OPT_TRICK(RT_WATER_BK_REGION, RCQUEST_VANILLA, RA_WATER_TEMPLE, { Tricks::Tag::INTERMEDIATE }, + "Water Temple Boss Key Region with Hover Boots", + "With precise Hover Boots movement it is possible to reach the boss key chest's region without needing " + "the Longshot. It is not necessary to take damage from the spikes. The Gold Skulltula Token in the " + "following room can also be obtained with just the Hover Boots."); + OPT_TRICK(RT_WATER_NORTH_BASEMENT_LEDGE_JUMP, RCQUEST_BOTH, RA_WATER_TEMPLE, { Tricks::Tag::INTERMEDIATE }, + "Water Temple North Basement Ledge with Precise Jump", + "In the northern basement there's a ledge from where, in Vanilla Water Temple, boulders roll out into " + "the room. Normally to jump directly to this ledge logically requires the Hover Boots, but with precise " + "jump, it can be done without them. This trick applies to both Vanilla and Master Quest."); + OPT_TRICK( + RT_WATER_BK_JUMP_DIVE, RCQUEST_VANILLA, RA_WATER_TEMPLE, { Tricks::Tag::NOVICE }, + "Water Temple Boss Key Jump Dive", + "Stand on the very edge of the raised corridor leading from the push block room to the rolling boulder " + "corridor. Face the Gold Skulltula on the waterfall and jump over the boulder corridor floor into the pool of " + "water, swimming right once underwater. This allows access to the boss key room without Iron boots."); + // Also used in MQ logic, but won't be relevent unless a way to enter tower without irons exists (likely a clip + + // swim) + OPT_TRICK(RT_WATER_FW_CENTRAL_GS, RCQUEST_VANILLA, RA_WATER_TEMPLE, { Tricks::Tag::NOVICE }, + "Water Temple Central Pillar GS with Farore\'s Wind", + "If you set Farore's Wind inside the central pillar and then return to that warp point after raising the " + "water to the highest level, you can obtain this Skulltula Token with Hookshot or Boomerang."); + OPT_TRICK( + RT_WATER_IRONS_CENTRAL_GS, RCQUEST_VANILLA, RA_WATER_TEMPLE, { Tricks::Tag::NOVICE }, + "Water Temple Central Pillar GS with Iron Boots", + "After opening the middle water level door into the central pillar, the door will stay unbarred so long as you " + "do not leave the room, even if you were to raise the water up to the highest level. With the Iron Boots to go " + "through the door after the water has been raised, you can obtain the Skulltula Token with the Hookshot."); + OPT_TRICK(RT_WATER_CENTRAL_BOW, RCQUEST_VANILLA, RA_WATER_TEMPLE, { Tricks::Tag::ADVANCED }, + "Water Temple Central Bow Target without Longshot or Hover Boots", + "A very precise Bow shot can hit the eye switch from the floor above. Then, you can jump down into the " + "hallway and make through it before the gate closes. It can also be done as child, using the Slingshot " + "instead of the Bow."); + OPT_TRICK( + RT_WATER_HOOKSHOT_FALLING_PLATFORM_GS, RCQUEST_VANILLA, RA_WATER_TEMPLE, { Tricks::Tag::NOVICE }, + "Water Temple Falling Platform Room GS with Hookshot", + "If you stand on the very edge of the platform, this Gold Skulltula can be obtained with only the Hookshot."); + OPT_TRICK( + RT_WATER_RANG_FALLING_PLATFORM_GS, RCQUEST_VANILLA, RA_WATER_TEMPLE, { Tricks::Tag::INTERMEDIATE }, + "Water Temple Falling Platform Room GS with Boomerang", + "If you stand on the very edge of the platform, this Gold Skulltula can be obtained with only the Boomerang."); + OPT_TRICK(RT_WATER_RIVER_GS, RCQUEST_VANILLA, RA_WATER_TEMPLE, { Tricks::Tag::INTERMEDIATE }, + "Water Temple River GS without Iron Boots", + "Standing on the exposed ground toward the end of the river, a precise Longshot use can obtain the " + "token. The Longshot cannot normally reach far enough to kill the Skulltula, however. You'll first have " + "to find some other way of killing it."); + OPT_TRICK(RT_WATER_DRAGON_JUMP_DIVE, RCQUEST_BOTH, RA_WATER_TEMPLE, { Tricks::Tag::NOVICE }, + "Water Temple Dragon Statue Jump Dive", + "If you come into the dragon statue room from the serpent river, you can jump down from above and get " + "into the tunnel without needing either Iron Boots or a Scale. This trick applies to both Vanilla and " + "Master Quest. In Vanilla, you must shoot the switch from above with the Bow, and then quickly get " + "through the tunnel before the gate closes."); + OPT_TRICK(RT_WATER_ADULT_DRAGON, RCQUEST_VANILLA, RA_WATER_TEMPLE, { Tricks::Tag::NOVICE }, + "Water Temple Dragon Statue Switch from Above the Water as Adult", + "Normally you need both Hookshot and Iron Boots to hit the switch and swim through the tunnel to get to " + "the chest. But by hitting the switch from dry land, using one of Bombchus, Hookshot, or Bow, it is " + "possible to skip one or both of those requirements. After the gate has been opened, besides just using " + "the Iron Boots, a well-timed dive with at least the Silver Scale could be used to swim through the " + "tunnel. If coming from the serpent river, a jump dive can also be used to get into the tunnel."); + OPT_TRICK(RT_WATER_CHILD_DRAGON, RCQUEST_VANILLA, RA_WATER_TEMPLE, { Tricks::Tag::ADVANCED }, + "Water Temple Dragon Statue Switch from Above the Water as Child", + "It is possible for child to hit the switch from dry land using one of Bombchus, Slingshot or Boomerang. " + "Then, to get to the chest, child can dive through the tunnel using at least the Silver Scale. The " + "timing and positioning of this dive needs to be perfect to actually make it under the gate, and it all " + "needs to be done very quickly to be able to get through before the gate closes. Be sure to enable " + "\"Water Temple Dragon Statue Switch from Above the Water as Adult\" for adult's variant of this trick."); + OPT_TRICK(RT_WATER_MQ_CENTRAL_PILLAR, RCQUEST_MQ, RA_WATER_TEMPLE, { Tricks::Tag::NOVICE }, + "Water Temple MQ Central Pillar with Fire Arrows", + "Slanted torches have misleading hitboxes. Whenever you see a slanted torch jutting out of the wall, you " + "can expect most or all of its hitbox is actually on the other side that wall. This can make slanted " + "torches very finicky to light when using arrows. The torches in the central pillar of MQ Water Temple " + "are a particularly egregious example. Logic normally expects Din's Fire and Song of Time."); + OPT_TRICK( + RT_WATER_MQ_LOCKED_GS, RCQUEST_MQ, RA_WATER_TEMPLE, { Tricks::Tag::NOVICE }, + "Water Temple MQ North Basement GS without Small Key", + "There is an invisible Hookshot target that can be used to get over the gate that blocks you from going to " + "this Skulltula early, skipping a small key as well as needing Hovers or Scarecrow to reach the locked door."); + OPT_TRICK(RT_LENS_SHADOW, RCQUEST_VANILLA, RA_SHADOW_TEMPLE, { Tricks::Tag::NOVICE }, + "Shadow Temple Stationary Objects without Lens of Truth", + "Removes the requirements for the Lens of Truth in Shadow Temple for most areas in the dungeon except " + "for crossing the moving platform in the huge pit room and for fighting Bongo Bongo."); + OPT_TRICK(RT_LENS_SHADOW_PLATFORM, RCQUEST_VANILLA, RA_SHADOW_TEMPLE, { Tricks::Tag::NOVICE }, + "Shadow Temple Invisible Moving Platform without Lens of Truth", + "Removes the requirements for the Lens of Truth in Shadow Temple to cross the invisible moving platform " + "in the huge pit room in either direction."); + OPT_TRICK(RT_LENS_BONGO, RCQUEST_BOTH, RA_SHADOW_TEMPLE, { Tricks::Tag::NOVICE }, + "Shadow Temple Bongo Bongo without Lens of Truth", + "Bongo Bongo can be defeated without the use of Lens of Truth, as the hands give a pretty good idea of " + "where the eye is."); + OPT_TRICK(RT_SHADOW_UMBRELLA, RCQUEST_BOTH, RA_SHADOW_TEMPLE, { Tricks::Tag::EXPERT }, + "Shadow Temple Stone Umbrella Skip", + "A very precise Hover Boots movement from off of the lower chest can get you on top of the crushing " + "spikes without needing to pull the block. Applies to both Vanilla and Master Quest."); + OPT_TRICK(RT_SHADOW_UMBRELLA_GS, RCQUEST_BOTH, RA_SHADOW_TEMPLE, { Tricks::Tag::EXPERT }, + "Shadow Temple Falling Spikes GS with Hover Boots", + "After killing the Skulltula, a very precise Hover Boots movement from off of the lower chest can get " + "you on top of the crushing spikes without needing to pull the block. From there, another very precise " + "Hover Boots movement can be used to obtain the token without needing the Hookshot. Applies to both " + "Vanilla and Master Quest. For obtaining the chests in this room with just Hover Boots, be sure to " + "enable \"Shadow Temple Stone Umbrella Skip\"."); + OPT_TRICK(RT_SHADOW_FREESTANDING_KEY, RCQUEST_VANILLA, RA_SHADOW_TEMPLE, { Tricks::Tag::NOVICE }, + "Shadow Temple Freestanding Key with Bombchu", + "Release the Bombchu with good timing so that it explodes near the bottom of the pot."); + OPT_TRICK(RT_SHADOW_STATUE, RCQUEST_BOTH, RA_SHADOW_TEMPLE, { Tricks::Tag::INTERMEDIATE }, + "Shadow Temple River Statue with Bombchu", + "By sending a Bombchu around the edge of the gorge, you can knock down the statue without needing a Bow. " + "Applies in both Vanilla and MQ Shadow."); + OPT_TRICK(RT_SHADOW_BONGO, RCQUEST_BOTH, RA_SHADOW_TEMPLE, { Tricks::Tag::INTERMEDIATE }, + "Shadow Temple Bongo Bongo without projectiles", + "Using precise sword slashes, Bongo Bongo can be defeated without using projectiles. This is only " + "relevant in conjunction with Shadow Temple dungeon shortcuts or shuffled boss entrances."); + OPT_TRICK(RT_LENS_SHADOW_MQ, RCQUEST_MQ, RA_SHADOW_TEMPLE, { Tricks::Tag::NOVICE }, + "Shadow Temple MQ Stationary Objects without Lens of Truth", + "Removes the requirements for the Lens of Truth in Shadow Temple MQ for most areas in the dungeon. See " + "\"Shadow Temple MQ Invisible Moving Platform without Lens of Truth\", \"Shadow Temple MQ Invisible " + "Blades Silver Rupees without Lens of Truth\", \"Shadow Temple MQ 2nd Dead Hand without Lens of Truth\", " + "and \"Shadow Temple Bongo Bongo without Lens of Truth\" for exceptions."); + OPT_TRICK(RT_LENS_SHADOW_MQ_INVISIBLE_BLADES, RCQUEST_MQ, RA_SHADOW_TEMPLE, { Tricks::Tag::NOVICE }, + "Shadow Temple MQ Invisible Blades Silver Rupees without Lens of Truth", + "Removes the requirement for the Lens of Truth or Nayru's Love in Shadow Temple MQ for the Invisible " + "Blades room Silver Rupee collection."); + OPT_TRICK(RT_LENS_SHADOW_MQ_PLATFORM, RCQUEST_MQ, RA_SHADOW_TEMPLE, { Tricks::Tag::NOVICE }, + "Shadow Temple MQ Invisible Moving Platform without Lens of Truth", + "Removes the requirements for the Lens of Truth in Shadow Temple MQ to cross the invisible moving " + "platform in the huge pit room in either direction."); + OPT_TRICK(RT_LENS_SHADOW_MQ_DEADHAND, RCQUEST_MQ, RA_SHADOW_TEMPLE, { Tricks::Tag::NOVICE }, + "Shadow Temple MQ 2nd Dead Hand without Lens of Truth", + "Dead Hand spawns in a random spot within the room. Having Lens removes the hassle of having to comb the " + "room looking for his spawn location."); + OPT_TRICK(RT_SHADOW_MQ_GAP, RCQUEST_MQ, RA_SHADOW_TEMPLE, { Tricks::Tag::INTERMEDIATE }, + "Shadow Temple MQ Truth Spinner Gap with Longshot", + "You can Longshot a torch and jump-slash recoil onto the tongue. It works best if you Longshot the right " + "torch from the left side of the room."); + OPT_TRICK( + RT_SHADOW_MQ_INVISIBLE_BLADES, RCQUEST_MQ, RA_SHADOW_TEMPLE, { Tricks::Tag::INTERMEDIATE }, + "Shadow Temple MQ Invisible Blades without Song of Time", + "The Like Like can be used to boost you into the Silver Rupee or Recovery Hearts that normally require Song of " + "Time. This cannot be performed on OHKO since the Like Like does not boost you high enough if you die."); + OPT_TRICK(RT_SHADOW_MQ_HUGE_PIT, RCQUEST_MQ, RA_SHADOW_TEMPLE, { Tricks::Tag::INTERMEDIATE }, + "Shadow Temple MQ Lower Huge Pit without Fire Source", + "Normally a frozen eye switch spawns some platforms that you can use to climb down, but there's actually " + "a small piece of ground that you can stand on that you can just jump down to."); + OPT_TRICK( + RT_SHADOW_MQ_WINDY_WALKWAY, RCQUEST_MQ, RA_SHADOW_TEMPLE, { Tricks::Tag::INTERMEDIATE }, + "Shadow Temple MQ Windy Walkway Reverse without Hover Boots", + "It is possible to jump from the alcove in the windy hallway to the middle platform. There are two methods: " + "wait out the fan opposite the door and hold forward, or jump to the right to be pushed by the fan there " + "towards the platform ledge. Note that jumps of this distance are inconsistent, but still possible."); + OPT_TRICK(RT_LENS_SPIRIT, RCQUEST_VANILLA, RA_SPIRIT_TEMPLE, { Tricks::Tag::NOVICE }, + "Spirit Temple without Lens of Truth", + "Removes the requirements for the Lens of Truth in Spirit Temple."); + OPT_TRICK(RT_SPIRIT_CHILD_CHU, RCQUEST_VANILLA, RA_SPIRIT_TEMPLE, { Tricks::Tag::NOVICE }, + "Spirit Temple Child Side Bridge with Bombchu", "A carefully-timed Bombchu can hit the switch."); + OPT_TRICK(RT_SPIRIT_LOBBY_GS, RCQUEST_VANILLA, RA_SPIRIT_TEMPLE, { Tricks::Tag::NOVICE }, + "Spirit Temple Main Room GS with Boomerang", + "Standing on the highest part of the arm of the statue, a precise Boomerang throw can kill and obtain " + "this Gold Skulltula. You must throw the Boomerang slightly off to the side so that it curves into the " + "Skulltula, as aiming directly at it will clank off of the wall in front."); + OPT_TRICK(RT_SPIRIT_LOWER_ADULT_SWITCH, RCQUEST_VANILLA, RA_SPIRIT_TEMPLE, { Tricks::Tag::ADVANCED }, + "Spirit Temple Lower Adult Switch with Bombs", + "A bomb can be used to hit the switch on the ceiling, but it must be thrown from a particular distance " + "away and with precise timing."); + OPT_TRICK( + RT_SPIRIT_LOBBY_JUMP, RCQUEST_BOTH, RA_SPIRIT_TEMPLE, { Tricks::Tag::INTERMEDIATE }, + "Spirit Temple Main Room Jump from Hands to Upper Ledges", + "A precise jump to obtain the following as adult without needing one of Hover Boots, or Hookshot (in Vanilla) " + "or Song of Time (in MQ): - Spirit Temple Statue Room Northeast Chest - Spirit Temple GS Lobby - Spirit Temple " + "MQ Central Chamber Top Left Pot (Left) - Spirit Temple MQ Central Chamber Top Left Pot (Right)"); + // disabled since "Spirit Temple boss shortcuts" (pre-lowers the platform where you break the statues face) isn't a + // setting in ship OPT_TRICK(RT_SPIRIT_PLATFORM_HOOKSHOT, RCQUEST_VANILLA, RA_SPIRIT_TEMPLE, + // {Tricks::Tag::INTERMEDIATE}, "Spirit Temple Main Room Hookshot to Boss Platform", "Precise hookshot aiming at the + // platform chains can be used to reach the boss platform from the middle landings. Using a jump slash immediately + // after reaching a chain makes aiming more lenient. Relevant only when Spirit Temple boss shortcuts are on."); + OPT_TRICK(RT_SPIRIT_MAP_CHEST, RCQUEST_VANILLA, RA_SPIRIT_TEMPLE, { Tricks::Tag::NOVICE }, + "Spirit Temple Map Chest with Bow", + "To get a line of sight from the upper torch to the map chest torches, you must pull an Armos statue all " + "the way up the stairs."); + OPT_TRICK(RT_SPIRIT_SUN_CHEST, RCQUEST_VANILLA, RA_SPIRIT_TEMPLE, { Tricks::Tag::ADVANCED }, + "Spirit Temple Sun Block Room Chest with Bow", + "Using the blocks in the room as platforms you can get lines of sight to all three torches. The timer on " + "the torches is quite short so you must move quickly in order to light all three."); + OPT_TRICK( + RT_SPIRIT_WALL, RCQUEST_VANILLA, RA_SPIRIT_TEMPLE, { Tricks::Tag::INTERMEDIATE }, + "Spirit Temple Shifting Wall with No Additional Items", + "Logic normally guarantees a way of dealing with both the Beamos and the Walltula before climbing the wall."); + OPT_TRICK(RT_LENS_SPIRIT_MQ, RCQUEST_MQ, RA_SPIRIT_TEMPLE, { Tricks::Tag::NOVICE }, + "Spirit Temple MQ without Lens of Truth", + "Removes the requirements for the Lens of Truth in Spirit Temple MQ."); + OPT_TRICK(RT_SPIRIT_MQ_SUN_BLOCK_SOT, RCQUEST_MQ, RA_SPIRIT_TEMPLE, { Tricks::Tag::INTERMEDIATE }, + "Spirit Temple MQ Sun Block Room as Child without Song of Time", + "While adult can easily jump directly to the switch that unbars the door to the sun block room, child " + "Link cannot make the jump without spawning a Song of Time block to jump from. You can skip this by " + "throwing the crate down onto the switch from above, which does unbar the door, however the crate " + "immediately breaks, so you must move quickly to get through the door before it closes back up."); + OPT_TRICK(RT_SPIRIT_MQ_SUN_BLOCK_GS, RCQUEST_MQ, RA_SPIRIT_TEMPLE, { Tricks::Tag::INTERMEDIATE }, + "Spirit Temple MQ Sun Block Room GS with Boomerang", + "Throw the Boomerang in such a way that it curves through the side of the glass block to hit the Gold " + "Skulltula."); + OPT_TRICK(RT_SPIRIT_MQ_LOWER_ADULT, RCQUEST_MQ, RA_SPIRIT_TEMPLE, { Tricks::Tag::INTERMEDIATE }, + "Spirit Temple MQ Lower Adult without Fire Arrows", + "By standing in a precise position it is possible to light two of the torches with a single use of " + "Din\'s Fire. This saves enough time to be able to light all three torches with only Din\'s Fire."); + OPT_TRICK(RT_SPIRIT_MQ_FROZEN_EYE, RCQUEST_MQ, RA_SPIRIT_TEMPLE, { Tricks::Tag::NOVICE }, + "Spirit Temple MQ Frozen Eye Switch without Fire", + "You can melt the ice by shooting an arrow through a torch. The only way to find a line of sight for " + "this shot is to first spawn a Song of Time block, and then stand on the very edge of it."); + OPT_TRICK(RT_ICE_BLOCK_GS, RCQUEST_VANILLA, RA_ICE_CAVERN, { Tricks::Tag::INTERMEDIATE }, + "Ice Cavern Block Room GS with Hover Boots", + "The Hover Boots can be used to get in front of the Skulltula to kill it with a jump slash. Then, the " + "Hover Boots can again be used to obtain the Token, all without Hookshot or Boomerang."); + OPT_TRICK(RT_ICE_MQ_RED_ICE_GS, RCQUEST_MQ, RA_ICE_CAVERN, { Tricks::Tag::INTERMEDIATE }, + "Ice Cavern MQ Red Ice GS without Song of Time", + "If you side-hop into the perfect position, you can briefly stand on the platform with the red ice just " + "long enough to dump some blue fire."); + OPT_TRICK(RT_ICE_MQ_SCARECROW, RCQUEST_MQ, RA_ICE_CAVERN, { Tricks::Tag::INTERMEDIATE }, + "Ice Cavern MQ Scarecrow GS with No Additional Items", + "As adult a precise jump can be used to reach this alcove."); + OPT_TRICK(RT_LENS_GTG, RCQUEST_VANILLA, RA_GERUDO_TRAINING_GROUND, { Tricks::Tag::NOVICE }, + "Gerudo Training Ground without Lens of Truth", + "Removes the requirements for the Lens of Truth in Gerudo Training Ground."); + OPT_TRICK(RT_GTG_WITHOUT_HOOKSHOT, RCQUEST_VANILLA, RA_GERUDO_TRAINING_GROUND, { Tricks::Tag::INTERMEDIATE }, + "Gerudo Training Ground Left Side Silver Rupees without Hookshot", + "After collecting the rest of the Silver Rupees in the room, you can reach the final Silver Rupee on the " + "ceiling by being pulled up into it after getting grabbed by the Wallmaster. Then, you must also reach " + "the exit of the room without the use of the Hookshot. If you move quickly you can sneak past the edge " + "of a flame wall before it can rise up to block you. To do so without taking damage is more precise."); + OPT_TRICK(RT_GTG_FAKE_WALL, RCQUEST_BOTH, RA_GERUDO_TRAINING_GROUND, { Tricks::Tag::NOVICE }, + "Reach Gerudo Training Ground Fake Wall Ledge with Hover Boots", + "A precise Hover Boots use from the top of the chest can allow you to grab the ledge without needing the " + "usual requirements. In Master Quest, this always skips a Song of Time requirement. In Vanilla, this " + "skips a Hookshot requirement, but is only relevant if \"Gerudo Training Ground Left Side Silver Rupees " + "without Hookshot\" is enabled."); + OPT_TRICK(RT_LENS_GTG_MQ, RCQUEST_MQ, RA_GERUDO_TRAINING_GROUND, { Tricks::Tag::NOVICE }, + "Gerudo Training Ground MQ without Lens of Truth", + "Removes the requirements for the Lens of Truth in Gerudo Training Ground MQ."); + OPT_TRICK(RT_GTG_MQ_WITH_HOOKSHOT, RCQUEST_MQ, RA_GERUDO_TRAINING_GROUND, { Tricks::Tag::NOVICE }, + "Gerudo Training Ground MQ Left Side Silver Rupees with Hookshot", + "The highest Silver Rupee can be obtained by hookshooting the target and then immediately jump slashing " + "toward the Rupee."); + OPT_TRICK(RT_GTG_MQ_WIHTOUT_HOOKSHOT, RCQUEST_MQ, RA_GERUDO_TRAINING_GROUND, { Tricks::Tag::INTERMEDIATE }, + "Gerudo Training Ground MQ Left Side Silver Rupees without Hookshot", + "After collecting the rest of the Silver Rupees in the room, you can reach the final Silver Rupee on the " + "ceiling by being pulled up into it after getting grabbed by the Wallmaster. The Wallmaster will not " + "track you to directly underneath the rupee. You should take the last step to be under the rupee after " + "the Wallmaster has begun its attempt to grab you. Also included with this trick is that fact that the " + "switch that unbars the door to the final chest of GTG can be hit without a projectile, using a precise " + "jump slash. This trick supersedes \"Gerudo Training Ground MQ Left Side Silver Rupees with Hookshot\"."); + OPT_TRICK(RT_LENS_GANON, RCQUEST_VANILLA, RA_GANONS_CASTLE, { Tricks::Tag::NOVICE }, + "Ganon\'s Castle without Lens of Truth", + "Removes the requirements for the Lens of Truth in Ganon's Castle."); + OPT_TRICK(RT_GANON_SPIRIT_TRIAL_HOOKSHOT, RCQUEST_VANILLA, RA_GANONS_CASTLE, { Tricks::Tag::NOVICE }, + "Spirit Trial without Hookshot", + "The highest rupee can be obtained as either age by performing a precise jump and a well-timed jumpslash " + "off of an Armos."); + OPT_TRICK(RT_LENS_GANON_MQ, RCQUEST_MQ, RA_GANONS_CASTLE, { Tricks::Tag::NOVICE }, + "Ganon\'s Castle MQ without Lens of Truth", + "Removes the requirements for the Lens of Truth in Ganon's Castle MQ."); + OPT_TRICK(RT_GANON_MQ_FIRE_TRIAL, RCQUEST_MQ, RA_GANONS_CASTLE, { Tricks::Tag::ADVANCED }, + "Fire Trial MQ with Hookshot", + "It's possible to hook the target at the end of fire trial with just Hookshot, but it requires precise " + "aim and perfect positioning. The main difficulty comes from getting on the very corner of the obelisk " + "without falling into the lava."); + OPT_TRICK(RT_GANON_MQ_SHADOW_TRIAL, RCQUEST_MQ, RA_GANONS_CASTLE, { Tricks::Tag::NOVICE }, + "Shadow Trial MQ Torch with Bow", + "You can light the torch in this room without a fire source by shooting an arrow through the lit torch " + "at the beginning of the room. Because the room is so dark and the unlit torch is so far away, it can be " + "difficult to aim the shot correctly."); + OPT_TRICK(RT_GANON_MQ_LIGHT_TRIAL, RCQUEST_MQ, RA_GANONS_CASTLE, { Tricks::Tag::INTERMEDIATE }, + "Light Trial MQ without Hookshot", + "If you move quickly you can sneak past the edge of a flame wall before it can rise up to block you. In " + "this case to do it without taking damage is especially precise."); mOptionGroups[RSG_LOGIC] = OptionGroup::SubGroup("Logic Options", { - &mOptions[RSK_LOGIC_RULES], - &mOptions[RSK_ALL_LOCATIONS_REACHABLE], - &mOptions[RSK_SKULLS_SUNS_SONG], - }); + &mOptions[RSK_LOGIC_RULES], + &mOptions[RSK_ALL_LOCATIONS_REACHABLE], + &mOptions[RSK_SKULLS_SUNS_SONG], + }); // TODO: Exclude Locations Menus mTricksByArea.clear(); std::vector tricksOption; @@ -554,563 +1144,586 @@ void Settings::CreateOptions() { } mOptionGroups[RSG_TRICKS] = OptionGroup::SubGroup("Logical Tricks", tricksOption); // TODO: Glitches - mOptionGroups[RSG_AREA_ACCESS_IMGUI] = OptionGroup::SubGroup("Area Access", { - &mOptions[RSK_FOREST], - &mOptions[RSK_KAK_GATE], - &mOptions[RSK_DOOR_OF_TIME], - &mOptions[RSK_ZORAS_FOUNTAIN], - &mOptions[RSK_SLEEPING_WATERFALL], - &mOptions[RSK_LOCK_OVERWORLD_DOORS], - }, WidgetContainerType::COLUMN); - mOptionGroups[RSG_WORLD_IMGUI] = OptionGroup::SubGroup("World Settings", { - &mOptions[RSK_STARTING_AGE], - &mOptions[RSK_GERUDO_FORTRESS], - &mOptions[RSK_RAINBOW_BRIDGE], - &mOptions[RSK_BRIDGE_OPTIONS], - &mOptions[RSK_RAINBOW_BRIDGE_STONE_COUNT], - &mOptions[RSK_RAINBOW_BRIDGE_MEDALLION_COUNT], - &mOptions[RSK_RAINBOW_BRIDGE_REWARD_COUNT], - &mOptions[RSK_RAINBOW_BRIDGE_DUNGEON_COUNT], - &mOptions[RSK_RAINBOW_BRIDGE_TOKEN_COUNT], - &mOptions[RSK_GANONS_TRIALS], - &mOptions[RSK_TRIAL_COUNT], - &mOptions[RSK_MQ_DUNGEON_RANDOM], - &mOptions[RSK_MQ_DUNGEON_COUNT], - &mOptions[RSK_MQ_DUNGEON_SET], - &mOptions[RSK_MQ_DEKU_TREE], - &mOptions[RSK_MQ_DODONGOS_CAVERN], - &mOptions[RSK_MQ_JABU_JABU], - &mOptions[RSK_MQ_FOREST_TEMPLE], - &mOptions[RSK_MQ_FIRE_TEMPLE], - &mOptions[RSK_MQ_WATER_TEMPLE], - &mOptions[RSK_MQ_SPIRIT_TEMPLE], - &mOptions[RSK_MQ_SHADOW_TEMPLE], - &mOptions[RSK_MQ_BOTTOM_OF_THE_WELL], - &mOptions[RSK_MQ_ICE_CAVERN], - &mOptions[RSK_MQ_GTG], - &mOptions[RSK_MQ_GANONS_CASTLE], - &mOptions[RSK_TRIFORCE_HUNT], - &mOptions[RSK_TRIFORCE_HUNT_PIECES_TOTAL], - &mOptions[RSK_TRIFORCE_HUNT_PIECES_REQUIRED] - }, WidgetContainerType::COLUMN); - mOptionGroups[RSG_SHUFFLE_ENTRANCES_IMGUI] = OptionGroup::SubGroup("Shuffle Entrances", { - &mOptions[RSK_SHUFFLE_DUNGEON_ENTRANCES], - &mOptions[RSK_SHUFFLE_BOSS_ENTRANCES], - &mOptions[RSK_SHUFFLE_OVERWORLD_ENTRANCES], - &mOptions[RSK_SHUFFLE_INTERIOR_ENTRANCES], - &mOptions[RSK_SHUFFLE_GROTTO_ENTRANCES], - &mOptions[RSK_SHUFFLE_OWL_DROPS], - &mOptions[RSK_SHUFFLE_WARP_SONGS], - &mOptions[RSK_SHUFFLE_OVERWORLD_SPAWNS], - &mOptions[RSK_DECOUPLED_ENTRANCES], - &mOptions[RSK_MIXED_ENTRANCE_POOLS], - &mOptions[RSK_MIX_DUNGEON_ENTRANCES], - &mOptions[RSK_MIX_BOSS_ENTRANCES], - &mOptions[RSK_MIX_OVERWORLD_ENTRANCES], - &mOptions[RSK_MIX_INTERIOR_ENTRANCES], - &mOptions[RSK_MIX_GROTTO_ENTRANCES] - }, WidgetContainerType::COLUMN); - mOptionGroups[RSG_WORLD_IMGUI_TABLE] = OptionGroup::SubGroup("World", { - &mOptionGroups[RSG_AREA_ACCESS_IMGUI], - &mOptionGroups[RSG_WORLD_IMGUI], - &mOptionGroups[RSG_SHUFFLE_ENTRANCES_IMGUI], - }, WidgetContainerType::TABLE); - mOptionGroups[RSG_SHUFFLE_ITEMS_IMGUI] = OptionGroup::SubGroup("Shuffle Items", { - &mOptions[RSK_SHUFFLE_SONGS], - &mOptions[RSK_SHUFFLE_TOKENS], - &mOptions[RSK_SKULLS_SUNS_SONG], - &mOptions[RSK_SHUFFLE_KOKIRI_SWORD], - &mOptions[RSK_SHUFFLE_MASTER_SWORD], - &mOptions[RSK_SHUFFLE_CHILD_WALLET], - &mOptions[RSK_INCLUDE_TYCOON_WALLET], - &mOptions[RSK_SHUFFLE_OCARINA], - &mOptions[RSK_SHUFFLE_OCARINA_BUTTONS], - &mOptions[RSK_SHUFFLE_SWIM], - &mOptions[RSK_SHUFFLE_WEIRD_EGG], - &mOptions[RSK_SHUFFLE_GERUDO_MEMBERSHIP_CARD], - &mOptions[RSK_SHUFFLE_FISHING_POLE], - &mOptions[RSK_SHUFFLE_DEKU_STICK_BAG], - &mOptions[RSK_SHUFFLE_DEKU_NUT_BAG], - &mOptions[RSK_SHUFFLE_FREESTANDING], - }, WidgetContainerType::COLUMN); - mOptionGroups[RSG_SHUFFLE_NPCS_IMGUI] = OptionGroup::SubGroup("Shuffle NPCs & Merchants", { - &mOptions[RSK_SHOPSANITY], - &mOptions[RSK_SHOPSANITY_COUNT], - &mOptions[RSK_SHOPSANITY_PRICES], - &mOptions[RSK_SHOPSANITY_PRICES_FIXED_PRICE], - &mOptions[RSK_SHOPSANITY_PRICES_RANGE_1], - &mOptions[RSK_SHOPSANITY_PRICES_RANGE_2], - &mOptions[RSK_SHOPSANITY_PRICES_NO_WALLET_WEIGHT], - &mOptions[RSK_SHOPSANITY_PRICES_CHILD_WALLET_WEIGHT], - &mOptions[RSK_SHOPSANITY_PRICES_ADULT_WALLET_WEIGHT], - &mOptions[RSK_SHOPSANITY_PRICES_GIANT_WALLET_WEIGHT], - &mOptions[RSK_SHOPSANITY_PRICES_TYCOON_WALLET_WEIGHT], - &mOptions[RSK_SHOPSANITY_PRICES_AFFORDABLE], - &mOptions[RSK_FISHSANITY], - &mOptions[RSK_FISHSANITY_POND_COUNT], - &mOptions[RSK_FISHSANITY_AGE_SPLIT], - &mOptions[RSK_SHUFFLE_SCRUBS], - &mOptions[RSK_SCRUBS_PRICES], - &mOptions[RSK_SCRUBS_PRICES_FIXED_PRICE], - &mOptions[RSK_SCRUBS_PRICES_RANGE_1], - &mOptions[RSK_SCRUBS_PRICES_RANGE_2], - &mOptions[RSK_SCRUBS_PRICES_NO_WALLET_WEIGHT], - &mOptions[RSK_SCRUBS_PRICES_CHILD_WALLET_WEIGHT], - &mOptions[RSK_SCRUBS_PRICES_ADULT_WALLET_WEIGHT], - &mOptions[RSK_SCRUBS_PRICES_GIANT_WALLET_WEIGHT], - &mOptions[RSK_SCRUBS_PRICES_TYCOON_WALLET_WEIGHT], - &mOptions[RSK_SCRUBS_PRICES_AFFORDABLE], - &mOptions[RSK_SHUFFLE_BEEHIVES], - &mOptions[RSK_SHUFFLE_COWS], - &mOptions[RSK_SHUFFLE_POTS], - &mOptions[RSK_SHUFFLE_CRATES], - &mOptions[RSK_SHUFFLE_MERCHANTS], - &mOptions[RSK_MERCHANT_PRICES], - &mOptions[RSK_MERCHANT_PRICES_FIXED_PRICE], - &mOptions[RSK_MERCHANT_PRICES_RANGE_1], - &mOptions[RSK_MERCHANT_PRICES_RANGE_2], - &mOptions[RSK_MERCHANT_PRICES_NO_WALLET_WEIGHT], - &mOptions[RSK_MERCHANT_PRICES_CHILD_WALLET_WEIGHT], - &mOptions[RSK_MERCHANT_PRICES_ADULT_WALLET_WEIGHT], - &mOptions[RSK_MERCHANT_PRICES_GIANT_WALLET_WEIGHT], - &mOptions[RSK_MERCHANT_PRICES_TYCOON_WALLET_WEIGHT], - &mOptions[RSK_MERCHANT_PRICES_AFFORDABLE], - &mOptions[RSK_SHUFFLE_FROG_SONG_RUPEES], - &mOptions[RSK_SHUFFLE_ADULT_TRADE], - &mOptions[RSK_SHUFFLE_100_GS_REWARD], - &mOptions[RSK_SHUFFLE_BOSS_SOULS], - &mOptions[RSK_SHUFFLE_FAIRIES], - &mOptions[RSK_SHUFFLE_GRASS], - }, WidgetContainerType::COLUMN); - mOptionGroups[RSG_SHUFFLE_DUNGEON_ITEMS_IMGUI] = OptionGroup::SubGroup("Shuffle Dungeon Items", { - &mOptions[RSK_SHUFFLE_DUNGEON_REWARDS], - &mOptions[RSK_SHUFFLE_MAPANDCOMPASS], - &mOptions[RSK_KEYSANITY], - &mOptions[RSK_GERUDO_KEYS], - &mOptions[RSK_BOSS_KEYSANITY], - &mOptions[RSK_GANONS_BOSS_KEY], - &mOptions[RSK_LACS_STONE_COUNT], - &mOptions[RSK_LACS_MEDALLION_COUNT], - &mOptions[RSK_LACS_DUNGEON_COUNT], - &mOptions[RSK_LACS_REWARD_COUNT], - &mOptions[RSK_LACS_TOKEN_COUNT], - &mOptions[RSK_LACS_OPTIONS], - &mOptions[RSK_KEYRINGS], - &mOptions[RSK_KEYRINGS_RANDOM_COUNT], - &mOptions[RSK_KEYRINGS_GERUDO_FORTRESS], - &mOptions[RSK_KEYRINGS_FOREST_TEMPLE], - &mOptions[RSK_KEYRINGS_FIRE_TEMPLE], - &mOptions[RSK_KEYRINGS_WATER_TEMPLE], - &mOptions[RSK_KEYRINGS_SPIRIT_TEMPLE], - &mOptions[RSK_KEYRINGS_SHADOW_TEMPLE], - &mOptions[RSK_KEYRINGS_BOTTOM_OF_THE_WELL], - &mOptions[RSK_KEYRINGS_GTG], - &mOptions[RSK_KEYRINGS_GANONS_CASTLE], - }, WidgetContainerType::COLUMN); - mOptionGroups[RSG_ITEMS_IMGUI_TABLE] = OptionGroup::SubGroup("Items", { - &mOptionGroups[RSG_SHUFFLE_ITEMS_IMGUI], - &mOptionGroups[RSG_SHUFFLE_NPCS_IMGUI], - &mOptionGroups[RSG_SHUFFLE_DUNGEON_ITEMS_IMGUI], - }, WidgetContainerType::TABLE); - mOptionGroups[RSG_TIMESAVERS_IMGUI] = OptionGroup::SubGroup("Timesavers", { - &mOptions[RSK_CUCCO_COUNT], - &mOptions[RSK_BIG_POE_COUNT], - &mOptions[RSK_SKIP_CHILD_ZELDA], - &mOptions[RSK_SKIP_EPONA_RACE], - &mOptions[RSK_COMPLETE_MASK_QUEST], - &mOptions[RSK_SKIP_SCARECROWS_SONG] - }, WidgetContainerType::COLUMN); - mOptionGroups[RSG_ITEM_POOL_HINTS_IMGUI] = OptionGroup::SubGroup("", { - &mOptions[RSK_ITEM_POOL], - &mOptions[RSK_ICE_TRAPS], - &mOptions[RSK_GOSSIP_STONE_HINTS], - &mOptions[RSK_HINT_CLARITY], - &mOptions[RSK_HINT_DISTRIBUTION], - }, WidgetContainerType::SECTION); - mOptionGroups[RSG_EXTRA_HINTS_IMGUI] = OptionGroup::SubGroup("Extra Hints", { - &mOptions[RSK_TOT_ALTAR_HINT], - &mOptions[RSK_GANONDORF_HINT], - &mOptions[RSK_SHEIK_LA_HINT], - &mOptions[RSK_DAMPES_DIARY_HINT], - &mOptions[RSK_GREG_HINT], - &mOptions[RSK_LOACH_HINT], - &mOptions[RSK_SARIA_HINT], - &mOptions[RSK_FROGS_HINT], - &mOptions[RSK_OOT_HINT], - &mOptions[RSK_BIGGORON_HINT], - &mOptions[RSK_BIG_POES_HINT], - &mOptions[RSK_CHICKENS_HINT], - &mOptions[RSK_MALON_HINT], - &mOptions[RSK_HBA_HINT], - &mOptions[RSK_FISHING_POLE_HINT], - &mOptions[RSK_WARP_SONG_HINTS], - &mOptions[RSK_SCRUB_TEXT_HINT], - &mOptions[RSK_MERCHANT_TEXT_HINT], - &mOptions[RSK_KAK_10_SKULLS_HINT], - &mOptions[RSK_KAK_20_SKULLS_HINT], - &mOptions[RSK_KAK_30_SKULLS_HINT], - &mOptions[RSK_KAK_40_SKULLS_HINT], - &mOptions[RSK_KAK_50_SKULLS_HINT], - &mOptions[RSK_KAK_100_SKULLS_HINT], - &mOptions[RSK_MASK_SHOP_HINT] - }, WidgetContainerType::SECTION, "This setting adds some hints at locations other than Gossip Stones."); - mOptionGroups[RSG_ITEM_POOL_HINTS_IMGUI_COLUMN] = OptionGroup::SubGroup("Item Pool & Hints", std::initializer_list{ - &mOptionGroups[RSG_ITEM_POOL_HINTS_IMGUI], - &mOptionGroups[RSG_EXTRA_HINTS_IMGUI], - }, WidgetContainerType::COLUMN); - mOptionGroups[RSG_ADDITIONAL_FEATURES_IMGUI] = OptionGroup::SubGroup("Additional Features", { - &mOptions[RSK_FULL_WALLETS], - &mOptions[RSK_BOMBCHU_BAG], - &mOptions[RSK_ENABLE_BOMBCHU_DROPS], - &mOptions[RSK_BLUE_FIRE_ARROWS], - &mOptions[RSK_SUNLIGHT_ARROWS], - &mOptions[RSK_INFINITE_UPGRADES], - &mOptions[RSK_SKELETON_KEY], - }, WidgetContainerType::COLUMN); - mOptionGroups[RSG_GAMEPLAY_IMGUI_TABLE] = OptionGroup::SubGroup("Gameplay", { - &mOptionGroups[RSG_TIMESAVERS_IMGUI], - &mOptionGroups[RSG_ITEM_POOL_HINTS_IMGUI_COLUMN], - &mOptionGroups[RSG_ADDITIONAL_FEATURES_IMGUI] - }, WidgetContainerType::TABLE); - mOptionGroups[RSG_STARTING_EQUIPMENT_IMGUI] = OptionGroup::SubGroup("Starting Equipment", { - &mOptions[RSK_LINKS_POCKET], - &mOptions[RSK_STARTING_KOKIRI_SWORD], - &mOptions[RSK_STARTING_MASTER_SWORD], - &mOptions[RSK_STARTING_DEKU_SHIELD] - }, WidgetContainerType::COLUMN); - mOptionGroups[RSG_STARTING_ITEMS_IMGUI] = OptionGroup::SubGroup("Starting Items", { - &mOptions[RSK_STARTING_OCARINA], - &mOptions[RSK_STARTING_STICKS], - &mOptions[RSK_STARTING_NUTS], - &mOptions[RSK_STARTING_SKULLTULA_TOKEN], - &mOptions[RSK_STARTING_HEARTS], - }, WidgetContainerType::COLUMN); - mOptionGroups[RSG_STARTING_NORMAL_SONGS_IMGUI] = OptionGroup::SubGroup("Normal Songs", { - &mOptions[RSK_STARTING_ZELDAS_LULLABY], - &mOptions[RSK_STARTING_EPONAS_SONG], - &mOptions[RSK_STARTING_SARIAS_SONG], - &mOptions[RSK_STARTING_SUNS_SONG], - &mOptions[RSK_STARTING_SONG_OF_TIME], - &mOptions[RSK_STARTING_SONG_OF_STORMS], - }, WidgetContainerType::SECTION); - mOptionGroups[RSG_STARTING_WARP_SONGS_IMGUI] = OptionGroup::SubGroup("Warp Songs", { - &mOptions[RSK_STARTING_MINUET_OF_FOREST], - &mOptions[RSK_STARTING_BOLERO_OF_FIRE], - &mOptions[RSK_STARTING_SERENADE_OF_WATER], - &mOptions[RSK_STARTING_REQUIEM_OF_SPIRIT], - &mOptions[RSK_STARTING_NOCTURNE_OF_SHADOW], - &mOptions[RSK_STARTING_PRELUDE_OF_LIGHT] - }, WidgetContainerType::SECTION); - mOptionGroups[RSG_STARTING_SONGS_IMGUI] = OptionGroup::SubGroup("Starting Songs", std::initializer_list({ - &mOptionGroups[RSG_STARTING_NORMAL_SONGS_IMGUI], - &mOptionGroups[RSG_STARTING_WARP_SONGS_IMGUI], - }), WidgetContainerType::COLUMN); - mOptionGroups[RSG_STARTING_INVENTORY_IMGUI_TABLE] = OptionGroup::SubGroup("Starting Inventory", { - &mOptionGroups[RSG_STARTING_EQUIPMENT_IMGUI], - &mOptionGroups[RSG_STARTING_ITEMS_IMGUI], - &mOptionGroups[RSG_STARTING_SONGS_IMGUI] - }, WidgetContainerType::TABLE); + mOptionGroups[RSG_AREA_ACCESS_IMGUI] = OptionGroup::SubGroup("Area Access", + { + &mOptions[RSK_FOREST], + &mOptions[RSK_KAK_GATE], + &mOptions[RSK_DOOR_OF_TIME], + &mOptions[RSK_ZORAS_FOUNTAIN], + &mOptions[RSK_SLEEPING_WATERFALL], + &mOptions[RSK_LOCK_OVERWORLD_DOORS], + }, + WidgetContainerType::COLUMN); + mOptionGroups[RSG_WORLD_IMGUI] = OptionGroup::SubGroup("World Settings", + { &mOptions[RSK_STARTING_AGE], + &mOptions[RSK_GERUDO_FORTRESS], + &mOptions[RSK_RAINBOW_BRIDGE], + &mOptions[RSK_BRIDGE_OPTIONS], + &mOptions[RSK_RAINBOW_BRIDGE_STONE_COUNT], + &mOptions[RSK_RAINBOW_BRIDGE_MEDALLION_COUNT], + &mOptions[RSK_RAINBOW_BRIDGE_REWARD_COUNT], + &mOptions[RSK_RAINBOW_BRIDGE_DUNGEON_COUNT], + &mOptions[RSK_RAINBOW_BRIDGE_TOKEN_COUNT], + &mOptions[RSK_GANONS_TRIALS], + &mOptions[RSK_TRIAL_COUNT], + &mOptions[RSK_MQ_DUNGEON_RANDOM], + &mOptions[RSK_MQ_DUNGEON_COUNT], + &mOptions[RSK_MQ_DUNGEON_SET], + &mOptions[RSK_MQ_DEKU_TREE], + &mOptions[RSK_MQ_DODONGOS_CAVERN], + &mOptions[RSK_MQ_JABU_JABU], + &mOptions[RSK_MQ_FOREST_TEMPLE], + &mOptions[RSK_MQ_FIRE_TEMPLE], + &mOptions[RSK_MQ_WATER_TEMPLE], + &mOptions[RSK_MQ_SPIRIT_TEMPLE], + &mOptions[RSK_MQ_SHADOW_TEMPLE], + &mOptions[RSK_MQ_BOTTOM_OF_THE_WELL], + &mOptions[RSK_MQ_ICE_CAVERN], + &mOptions[RSK_MQ_GTG], + &mOptions[RSK_MQ_GANONS_CASTLE], + &mOptions[RSK_TRIFORCE_HUNT], + &mOptions[RSK_TRIFORCE_HUNT_PIECES_TOTAL], + &mOptions[RSK_TRIFORCE_HUNT_PIECES_REQUIRED] }, + WidgetContainerType::COLUMN); + mOptionGroups[RSG_SHUFFLE_ENTRANCES_IMGUI] = OptionGroup::SubGroup( + "Shuffle Entrances", + { &mOptions[RSK_SHUFFLE_DUNGEON_ENTRANCES], &mOptions[RSK_SHUFFLE_BOSS_ENTRANCES], + &mOptions[RSK_SHUFFLE_OVERWORLD_ENTRANCES], &mOptions[RSK_SHUFFLE_INTERIOR_ENTRANCES], + &mOptions[RSK_SHUFFLE_GROTTO_ENTRANCES], &mOptions[RSK_SHUFFLE_OWL_DROPS], &mOptions[RSK_SHUFFLE_WARP_SONGS], + &mOptions[RSK_SHUFFLE_OVERWORLD_SPAWNS], &mOptions[RSK_DECOUPLED_ENTRANCES], + &mOptions[RSK_MIXED_ENTRANCE_POOLS], &mOptions[RSK_MIX_DUNGEON_ENTRANCES], &mOptions[RSK_MIX_BOSS_ENTRANCES], + &mOptions[RSK_MIX_OVERWORLD_ENTRANCES], &mOptions[RSK_MIX_INTERIOR_ENTRANCES], + &mOptions[RSK_MIX_GROTTO_ENTRANCES] }, + WidgetContainerType::COLUMN); + mOptionGroups[RSG_WORLD_IMGUI_TABLE] = OptionGroup::SubGroup("World", + { + &mOptionGroups[RSG_AREA_ACCESS_IMGUI], + &mOptionGroups[RSG_WORLD_IMGUI], + &mOptionGroups[RSG_SHUFFLE_ENTRANCES_IMGUI], + }, + WidgetContainerType::TABLE); + mOptionGroups[RSG_SHUFFLE_ITEMS_IMGUI] = OptionGroup::SubGroup("Shuffle Items", + { + &mOptions[RSK_SHUFFLE_SONGS], + &mOptions[RSK_SHUFFLE_TOKENS], + &mOptions[RSK_SKULLS_SUNS_SONG], + &mOptions[RSK_SHUFFLE_KOKIRI_SWORD], + &mOptions[RSK_SHUFFLE_MASTER_SWORD], + &mOptions[RSK_SHUFFLE_CHILD_WALLET], + &mOptions[RSK_INCLUDE_TYCOON_WALLET], + &mOptions[RSK_SHUFFLE_OCARINA], + &mOptions[RSK_SHUFFLE_OCARINA_BUTTONS], + &mOptions[RSK_SHUFFLE_SWIM], + &mOptions[RSK_SHUFFLE_WEIRD_EGG], + &mOptions[RSK_SHUFFLE_GERUDO_MEMBERSHIP_CARD], + &mOptions[RSK_SHUFFLE_FISHING_POLE], + &mOptions[RSK_SHUFFLE_DEKU_STICK_BAG], + &mOptions[RSK_SHUFFLE_DEKU_NUT_BAG], + &mOptions[RSK_SHUFFLE_FREESTANDING], + }, + WidgetContainerType::COLUMN); + mOptionGroups[RSG_SHUFFLE_NPCS_IMGUI] = + OptionGroup::SubGroup("Shuffle NPCs & Merchants", + { + &mOptions[RSK_SHOPSANITY], + &mOptions[RSK_SHOPSANITY_COUNT], + &mOptions[RSK_SHOPSANITY_PRICES], + &mOptions[RSK_SHOPSANITY_PRICES_FIXED_PRICE], + &mOptions[RSK_SHOPSANITY_PRICES_RANGE_1], + &mOptions[RSK_SHOPSANITY_PRICES_RANGE_2], + &mOptions[RSK_SHOPSANITY_PRICES_NO_WALLET_WEIGHT], + &mOptions[RSK_SHOPSANITY_PRICES_CHILD_WALLET_WEIGHT], + &mOptions[RSK_SHOPSANITY_PRICES_ADULT_WALLET_WEIGHT], + &mOptions[RSK_SHOPSANITY_PRICES_GIANT_WALLET_WEIGHT], + &mOptions[RSK_SHOPSANITY_PRICES_TYCOON_WALLET_WEIGHT], + &mOptions[RSK_SHOPSANITY_PRICES_AFFORDABLE], + &mOptions[RSK_FISHSANITY], + &mOptions[RSK_FISHSANITY_POND_COUNT], + &mOptions[RSK_FISHSANITY_AGE_SPLIT], + &mOptions[RSK_SHUFFLE_SCRUBS], + &mOptions[RSK_SCRUBS_PRICES], + &mOptions[RSK_SCRUBS_PRICES_FIXED_PRICE], + &mOptions[RSK_SCRUBS_PRICES_RANGE_1], + &mOptions[RSK_SCRUBS_PRICES_RANGE_2], + &mOptions[RSK_SCRUBS_PRICES_NO_WALLET_WEIGHT], + &mOptions[RSK_SCRUBS_PRICES_CHILD_WALLET_WEIGHT], + &mOptions[RSK_SCRUBS_PRICES_ADULT_WALLET_WEIGHT], + &mOptions[RSK_SCRUBS_PRICES_GIANT_WALLET_WEIGHT], + &mOptions[RSK_SCRUBS_PRICES_TYCOON_WALLET_WEIGHT], + &mOptions[RSK_SCRUBS_PRICES_AFFORDABLE], + &mOptions[RSK_SHUFFLE_BEEHIVES], + &mOptions[RSK_SHUFFLE_COWS], + &mOptions[RSK_SHUFFLE_POTS], + &mOptions[RSK_SHUFFLE_CRATES], + &mOptions[RSK_SHUFFLE_MERCHANTS], + &mOptions[RSK_MERCHANT_PRICES], + &mOptions[RSK_MERCHANT_PRICES_FIXED_PRICE], + &mOptions[RSK_MERCHANT_PRICES_RANGE_1], + &mOptions[RSK_MERCHANT_PRICES_RANGE_2], + &mOptions[RSK_MERCHANT_PRICES_NO_WALLET_WEIGHT], + &mOptions[RSK_MERCHANT_PRICES_CHILD_WALLET_WEIGHT], + &mOptions[RSK_MERCHANT_PRICES_ADULT_WALLET_WEIGHT], + &mOptions[RSK_MERCHANT_PRICES_GIANT_WALLET_WEIGHT], + &mOptions[RSK_MERCHANT_PRICES_TYCOON_WALLET_WEIGHT], + &mOptions[RSK_MERCHANT_PRICES_AFFORDABLE], + &mOptions[RSK_SHUFFLE_FROG_SONG_RUPEES], + &mOptions[RSK_SHUFFLE_ADULT_TRADE], + &mOptions[RSK_SHUFFLE_100_GS_REWARD], + &mOptions[RSK_SHUFFLE_BOSS_SOULS], + &mOptions[RSK_SHUFFLE_FAIRIES], + &mOptions[RSK_SHUFFLE_GRASS], + }, + WidgetContainerType::COLUMN); + mOptionGroups[RSG_SHUFFLE_DUNGEON_ITEMS_IMGUI] = + OptionGroup::SubGroup("Shuffle Dungeon Items", + { + &mOptions[RSK_SHUFFLE_DUNGEON_REWARDS], + &mOptions[RSK_SHUFFLE_MAPANDCOMPASS], + &mOptions[RSK_KEYSANITY], + &mOptions[RSK_GERUDO_KEYS], + &mOptions[RSK_BOSS_KEYSANITY], + &mOptions[RSK_GANONS_BOSS_KEY], + &mOptions[RSK_LACS_STONE_COUNT], + &mOptions[RSK_LACS_MEDALLION_COUNT], + &mOptions[RSK_LACS_DUNGEON_COUNT], + &mOptions[RSK_LACS_REWARD_COUNT], + &mOptions[RSK_LACS_TOKEN_COUNT], + &mOptions[RSK_LACS_OPTIONS], + &mOptions[RSK_KEYRINGS], + &mOptions[RSK_KEYRINGS_RANDOM_COUNT], + &mOptions[RSK_KEYRINGS_GERUDO_FORTRESS], + &mOptions[RSK_KEYRINGS_FOREST_TEMPLE], + &mOptions[RSK_KEYRINGS_FIRE_TEMPLE], + &mOptions[RSK_KEYRINGS_WATER_TEMPLE], + &mOptions[RSK_KEYRINGS_SPIRIT_TEMPLE], + &mOptions[RSK_KEYRINGS_SHADOW_TEMPLE], + &mOptions[RSK_KEYRINGS_BOTTOM_OF_THE_WELL], + &mOptions[RSK_KEYRINGS_GTG], + &mOptions[RSK_KEYRINGS_GANONS_CASTLE], + }, + WidgetContainerType::COLUMN); + mOptionGroups[RSG_ITEMS_IMGUI_TABLE] = OptionGroup::SubGroup("Items", + { + &mOptionGroups[RSG_SHUFFLE_ITEMS_IMGUI], + &mOptionGroups[RSG_SHUFFLE_NPCS_IMGUI], + &mOptionGroups[RSG_SHUFFLE_DUNGEON_ITEMS_IMGUI], + }, + WidgetContainerType::TABLE); + mOptionGroups[RSG_TIMESAVERS_IMGUI] = OptionGroup::SubGroup( + "Timesavers", + { &mOptions[RSK_CUCCO_COUNT], &mOptions[RSK_BIG_POE_COUNT], &mOptions[RSK_SKIP_CHILD_ZELDA], + &mOptions[RSK_SKIP_EPONA_RACE], &mOptions[RSK_COMPLETE_MASK_QUEST], &mOptions[RSK_SKIP_SCARECROWS_SONG] }, + WidgetContainerType::COLUMN); + mOptionGroups[RSG_ITEM_POOL_HINTS_IMGUI] = OptionGroup::SubGroup("", + { + &mOptions[RSK_ITEM_POOL], + &mOptions[RSK_ICE_TRAPS], + &mOptions[RSK_GOSSIP_STONE_HINTS], + &mOptions[RSK_HINT_CLARITY], + &mOptions[RSK_HINT_DISTRIBUTION], + }, + WidgetContainerType::SECTION); + mOptionGroups[RSG_EXTRA_HINTS_IMGUI] = OptionGroup::SubGroup( + "Extra Hints", + { &mOptions[RSK_TOT_ALTAR_HINT], &mOptions[RSK_GANONDORF_HINT], &mOptions[RSK_SHEIK_LA_HINT], + &mOptions[RSK_DAMPES_DIARY_HINT], &mOptions[RSK_GREG_HINT], &mOptions[RSK_LOACH_HINT], + &mOptions[RSK_SARIA_HINT], &mOptions[RSK_FROGS_HINT], &mOptions[RSK_OOT_HINT], + &mOptions[RSK_BIGGORON_HINT], &mOptions[RSK_BIG_POES_HINT], &mOptions[RSK_CHICKENS_HINT], + &mOptions[RSK_MALON_HINT], &mOptions[RSK_HBA_HINT], &mOptions[RSK_FISHING_POLE_HINT], + &mOptions[RSK_WARP_SONG_HINTS], &mOptions[RSK_SCRUB_TEXT_HINT], &mOptions[RSK_MERCHANT_TEXT_HINT], + &mOptions[RSK_KAK_10_SKULLS_HINT], &mOptions[RSK_KAK_20_SKULLS_HINT], &mOptions[RSK_KAK_30_SKULLS_HINT], + &mOptions[RSK_KAK_40_SKULLS_HINT], &mOptions[RSK_KAK_50_SKULLS_HINT], &mOptions[RSK_KAK_100_SKULLS_HINT], + &mOptions[RSK_MASK_SHOP_HINT] }, + WidgetContainerType::SECTION, "This setting adds some hints at locations other than Gossip Stones."); + mOptionGroups[RSG_ITEM_POOL_HINTS_IMGUI_COLUMN] = + OptionGroup::SubGroup("Item Pool & Hints", + std::initializer_list{ + &mOptionGroups[RSG_ITEM_POOL_HINTS_IMGUI], + &mOptionGroups[RSG_EXTRA_HINTS_IMGUI], + }, + WidgetContainerType::COLUMN); + mOptionGroups[RSG_ADDITIONAL_FEATURES_IMGUI] = OptionGroup::SubGroup("Additional Features", + { + &mOptions[RSK_FULL_WALLETS], + &mOptions[RSK_BOMBCHU_BAG], + &mOptions[RSK_ENABLE_BOMBCHU_DROPS], + &mOptions[RSK_BLUE_FIRE_ARROWS], + &mOptions[RSK_SUNLIGHT_ARROWS], + &mOptions[RSK_INFINITE_UPGRADES], + &mOptions[RSK_SKELETON_KEY], + }, + WidgetContainerType::COLUMN); + mOptionGroups[RSG_GAMEPLAY_IMGUI_TABLE] = + OptionGroup::SubGroup("Gameplay", + { &mOptionGroups[RSG_TIMESAVERS_IMGUI], &mOptionGroups[RSG_ITEM_POOL_HINTS_IMGUI_COLUMN], + &mOptionGroups[RSG_ADDITIONAL_FEATURES_IMGUI] }, + WidgetContainerType::TABLE); + mOptionGroups[RSG_STARTING_EQUIPMENT_IMGUI] = + OptionGroup::SubGroup("Starting Equipment", + { &mOptions[RSK_LINKS_POCKET], &mOptions[RSK_STARTING_KOKIRI_SWORD], + &mOptions[RSK_STARTING_MASTER_SWORD], &mOptions[RSK_STARTING_DEKU_SHIELD] }, + WidgetContainerType::COLUMN); + mOptionGroups[RSG_STARTING_ITEMS_IMGUI] = OptionGroup::SubGroup("Starting Items", + { + &mOptions[RSK_STARTING_OCARINA], + &mOptions[RSK_STARTING_STICKS], + &mOptions[RSK_STARTING_NUTS], + &mOptions[RSK_STARTING_SKULLTULA_TOKEN], + &mOptions[RSK_STARTING_HEARTS], + }, + WidgetContainerType::COLUMN); + mOptionGroups[RSG_STARTING_NORMAL_SONGS_IMGUI] = OptionGroup::SubGroup("Normal Songs", + { + &mOptions[RSK_STARTING_ZELDAS_LULLABY], + &mOptions[RSK_STARTING_EPONAS_SONG], + &mOptions[RSK_STARTING_SARIAS_SONG], + &mOptions[RSK_STARTING_SUNS_SONG], + &mOptions[RSK_STARTING_SONG_OF_TIME], + &mOptions[RSK_STARTING_SONG_OF_STORMS], + }, + WidgetContainerType::SECTION); + mOptionGroups[RSG_STARTING_WARP_SONGS_IMGUI] = + OptionGroup::SubGroup("Warp Songs", + { &mOptions[RSK_STARTING_MINUET_OF_FOREST], &mOptions[RSK_STARTING_BOLERO_OF_FIRE], + &mOptions[RSK_STARTING_SERENADE_OF_WATER], &mOptions[RSK_STARTING_REQUIEM_OF_SPIRIT], + &mOptions[RSK_STARTING_NOCTURNE_OF_SHADOW], &mOptions[RSK_STARTING_PRELUDE_OF_LIGHT] }, + WidgetContainerType::SECTION); + mOptionGroups[RSG_STARTING_SONGS_IMGUI] = OptionGroup::SubGroup("Starting Songs", + std::initializer_list({ + &mOptionGroups[RSG_STARTING_NORMAL_SONGS_IMGUI], + &mOptionGroups[RSG_STARTING_WARP_SONGS_IMGUI], + }), + WidgetContainerType::COLUMN); + mOptionGroups[RSG_STARTING_INVENTORY_IMGUI_TABLE] = + OptionGroup::SubGroup("Starting Inventory", + { &mOptionGroups[RSG_STARTING_EQUIPMENT_IMGUI], &mOptionGroups[RSG_STARTING_ITEMS_IMGUI], + &mOptionGroups[RSG_STARTING_SONGS_IMGUI] }, + WidgetContainerType::TABLE); mOptionGroups[RSG_OPEN] = OptionGroup("Open Settings", { - &mOptions[RSK_FOREST], - &mOptions[RSK_KAK_GATE], - &mOptions[RSK_DOOR_OF_TIME], - &mOptions[RSK_ZORAS_FOUNTAIN], - &mOptions[RSK_SLEEPING_WATERFALL], - &mOptions[RSK_LOCK_OVERWORLD_DOORS], - &mOptions[RSK_GERUDO_FORTRESS], - &mOptions[RSK_RAINBOW_BRIDGE], - &mOptions[RSK_RAINBOW_BRIDGE_STONE_COUNT], - &mOptions[RSK_RAINBOW_BRIDGE_MEDALLION_COUNT], - &mOptions[RSK_RAINBOW_BRIDGE_REWARD_COUNT], - &mOptions[RSK_RAINBOW_BRIDGE_DUNGEON_COUNT], - &mOptions[RSK_RAINBOW_BRIDGE_TOKEN_COUNT], - &mOptions[RSK_BRIDGE_OPTIONS], - &mOptions[RSK_GANONS_TRIALS], - &mOptions[RSK_TRIAL_COUNT], - }); + &mOptions[RSK_FOREST], + &mOptions[RSK_KAK_GATE], + &mOptions[RSK_DOOR_OF_TIME], + &mOptions[RSK_ZORAS_FOUNTAIN], + &mOptions[RSK_SLEEPING_WATERFALL], + &mOptions[RSK_LOCK_OVERWORLD_DOORS], + &mOptions[RSK_GERUDO_FORTRESS], + &mOptions[RSK_RAINBOW_BRIDGE], + &mOptions[RSK_RAINBOW_BRIDGE_STONE_COUNT], + &mOptions[RSK_RAINBOW_BRIDGE_MEDALLION_COUNT], + &mOptions[RSK_RAINBOW_BRIDGE_REWARD_COUNT], + &mOptions[RSK_RAINBOW_BRIDGE_DUNGEON_COUNT], + &mOptions[RSK_RAINBOW_BRIDGE_TOKEN_COUNT], + &mOptions[RSK_BRIDGE_OPTIONS], + &mOptions[RSK_GANONS_TRIALS], + &mOptions[RSK_TRIAL_COUNT], + }); mOptionGroups[RSG_WORLD] = OptionGroup("World Settings", { - &mOptions[RSK_STARTING_AGE], - &mOptions[RSK_SHUFFLE_ENTRANCES], - &mOptions[RSK_SHUFFLE_DUNGEON_ENTRANCES], - &mOptions[RSK_SHUFFLE_BOSS_ENTRANCES], - &mOptions[RSK_SHUFFLE_OVERWORLD_ENTRANCES], - &mOptions[RSK_SHUFFLE_INTERIOR_ENTRANCES], - &mOptions[RSK_SHUFFLE_GROTTO_ENTRANCES], - &mOptions[RSK_SHUFFLE_OWL_DROPS], - &mOptions[RSK_SHUFFLE_WARP_SONGS], - &mOptions[RSK_SHUFFLE_OVERWORLD_SPAWNS], - &mOptions[RSK_MIXED_ENTRANCE_POOLS], - &mOptions[RSK_MIX_DUNGEON_ENTRANCES], - &mOptions[RSK_MIX_BOSS_ENTRANCES], - &mOptions[RSK_MIX_OVERWORLD_ENTRANCES], - &mOptions[RSK_MIX_INTERIOR_ENTRANCES], - &mOptions[RSK_MIX_GROTTO_ENTRANCES], - &mOptions[RSK_DECOUPLED_ENTRANCES], - &mOptions[RSK_BOMBCHU_BAG], - &mOptions[RSK_ENABLE_BOMBCHU_DROPS], - &mOptions[RSK_TRIFORCE_HUNT], - &mOptions[RSK_TRIFORCE_HUNT_PIECES_TOTAL], - &mOptions[RSK_TRIFORCE_HUNT_PIECES_REQUIRED], - &mOptions[RSK_MQ_DUNGEON_RANDOM], - &mOptions[RSK_MQ_DUNGEON_COUNT], - &mOptions[RSK_MQ_DUNGEON_SET], - }); - mOptionGroups[RSG_SHUFFLE_DUNGEON_QUESTS] = OptionGroup::SubGroup("Shuffle Dungeon Quest", { - &mOptions[RSK_MQ_DEKU_TREE], - &mOptions[RSK_MQ_DODONGOS_CAVERN], - &mOptions[RSK_MQ_JABU_JABU], - &mOptions[RSK_MQ_FOREST_TEMPLE], - &mOptions[RSK_MQ_FIRE_TEMPLE], - &mOptions[RSK_MQ_WATER_TEMPLE], - &mOptions[RSK_MQ_SPIRIT_TEMPLE], - &mOptions[RSK_MQ_SHADOW_TEMPLE], - &mOptions[RSK_MQ_BOTTOM_OF_THE_WELL], - &mOptions[RSK_MQ_ICE_CAVERN], - &mOptions[RSK_MQ_GTG], - &mOptions[RSK_MQ_GANONS_CASTLE] - }); - mOptionGroups[RSG_SHUFFLE] = OptionGroup("Shuffle Settings", { - &mOptions[RSK_SHUFFLE_DUNGEON_REWARDS], - &mOptions[RSK_LINKS_POCKET], - &mOptions[RSK_SHUFFLE_SONGS], - &mOptions[RSK_SHOPSANITY], - &mOptions[RSK_SHOPSANITY_COUNT], - &mOptions[RSK_SHOPSANITY_PRICES], - &mOptions[RSK_SHOPSANITY_PRICES_FIXED_PRICE], - &mOptions[RSK_SHOPSANITY_PRICES_RANGE_1], - &mOptions[RSK_SHOPSANITY_PRICES_RANGE_2], - &mOptions[RSK_SHOPSANITY_PRICES_NO_WALLET_WEIGHT], - &mOptions[RSK_SHOPSANITY_PRICES_CHILD_WALLET_WEIGHT], - &mOptions[RSK_SHOPSANITY_PRICES_ADULT_WALLET_WEIGHT], - &mOptions[RSK_SHOPSANITY_PRICES_GIANT_WALLET_WEIGHT], - &mOptions[RSK_SHOPSANITY_PRICES_TYCOON_WALLET_WEIGHT], - &mOptions[RSK_SHOPSANITY_PRICES_AFFORDABLE], - &mOptions[RSK_FISHSANITY], - &mOptions[RSK_FISHSANITY_POND_COUNT], - &mOptions[RSK_FISHSANITY_AGE_SPLIT], - &mOptions[RSK_SHUFFLE_FISHING_POLE], - &mOptions[RSK_SHUFFLE_TOKENS], - &mOptions[RSK_SHUFFLE_SCRUBS], - &mOptions[RSK_SCRUBS_PRICES], - &mOptions[RSK_SCRUBS_PRICES_FIXED_PRICE], - &mOptions[RSK_SCRUBS_PRICES_RANGE_1], - &mOptions[RSK_SCRUBS_PRICES_RANGE_2], - &mOptions[RSK_SCRUBS_PRICES_NO_WALLET_WEIGHT], - &mOptions[RSK_SCRUBS_PRICES_CHILD_WALLET_WEIGHT], - &mOptions[RSK_SCRUBS_PRICES_ADULT_WALLET_WEIGHT], - &mOptions[RSK_SCRUBS_PRICES_GIANT_WALLET_WEIGHT], - &mOptions[RSK_SCRUBS_PRICES_TYCOON_WALLET_WEIGHT], - &mOptions[RSK_SCRUBS_PRICES_AFFORDABLE], - &mOptions[RSK_SHUFFLE_BEEHIVES], - &mOptions[RSK_SHUFFLE_COWS], - &mOptions[RSK_SHUFFLE_POTS], - &mOptions[RSK_SHUFFLE_CRATES], - &mOptions[RSK_SHUFFLE_KOKIRI_SWORD], - &mOptions[RSK_SHUFFLE_OCARINA], - &mOptions[RSK_SHUFFLE_OCARINA_BUTTONS], - &mOptions[RSK_SHUFFLE_SWIM], - &mOptions[RSK_SHUFFLE_WEIRD_EGG], - &mOptions[RSK_SHUFFLE_GERUDO_MEMBERSHIP_CARD], - &mOptions[RSK_SHUFFLE_MERCHANTS], - &mOptions[RSK_MERCHANT_PRICES], - &mOptions[RSK_MERCHANT_PRICES_FIXED_PRICE], - &mOptions[RSK_MERCHANT_PRICES_RANGE_1], - &mOptions[RSK_MERCHANT_PRICES_RANGE_2], - &mOptions[RSK_MERCHANT_PRICES_NO_WALLET_WEIGHT], - &mOptions[RSK_MERCHANT_PRICES_CHILD_WALLET_WEIGHT], - &mOptions[RSK_MERCHANT_PRICES_ADULT_WALLET_WEIGHT], - &mOptions[RSK_MERCHANT_PRICES_GIANT_WALLET_WEIGHT], - &mOptions[RSK_MERCHANT_PRICES_TYCOON_WALLET_WEIGHT], - &mOptions[RSK_MERCHANT_PRICES_AFFORDABLE], - &mOptions[RSK_SHUFFLE_FROG_SONG_RUPEES], - &mOptions[RSK_SHUFFLE_ADULT_TRADE], - &mOptions[RSK_SHUFFLE_CHEST_MINIGAME], - &mOptions[RSK_SHUFFLE_100_GS_REWARD], - &mOptions[RSK_SHUFFLE_BOSS_SOULS], - &mOptions[RSK_SHUFFLE_DEKU_STICK_BAG], - &mOptions[RSK_SHUFFLE_DEKU_NUT_BAG], - &mOptions[RSK_SHUFFLE_FREESTANDING], - &mOptions[RSK_SHUFFLE_FAIRIES], - }); - mOptionGroups[RSG_SHUFFLE_DUNGEON_ITEMS] = OptionGroup("Shuffle Dungeon Items", { - &mOptions[RSK_SHUFFLE_MAPANDCOMPASS], - &mOptions[RSK_KEYSANITY], - &mOptions[RSK_GERUDO_KEYS], - &mOptions[RSK_BOSS_KEYSANITY], - &mOptions[RSK_GANONS_BOSS_KEY], - &mOptions[RSK_LACS_STONE_COUNT], - &mOptions[RSK_LACS_MEDALLION_COUNT], - &mOptions[RSK_LACS_DUNGEON_COUNT], - &mOptions[RSK_LACS_REWARD_COUNT], - &mOptions[RSK_LACS_TOKEN_COUNT], - &mOptions[RSK_LACS_OPTIONS], - &mOptions[RSK_KEYRINGS], - &mOptions[RSK_KEYRINGS_RANDOM_COUNT], - &mOptions[RSK_KEYRINGS_GERUDO_FORTRESS], - &mOptions[RSK_KEYRINGS_FOREST_TEMPLE], - &mOptions[RSK_KEYRINGS_FIRE_TEMPLE], - &mOptions[RSK_KEYRINGS_WATER_TEMPLE], - &mOptions[RSK_KEYRINGS_SPIRIT_TEMPLE], - &mOptions[RSK_KEYRINGS_SHADOW_TEMPLE], - &mOptions[RSK_KEYRINGS_BOTTOM_OF_THE_WELL], - &mOptions[RSK_KEYRINGS_GTG], - &mOptions[RSK_KEYRINGS_GANONS_CASTLE], - }); - mOptionGroups[RSG_STARTING_ITEMS] = OptionGroup::SubGroup("Items", { - &mOptions[RSK_STARTING_OCARINA], - &mOptions[RSK_STARTING_KOKIRI_SWORD], - &mOptions[RSK_STARTING_DEKU_SHIELD] - }); - mOptionGroups[RSG_STARTING_SONGS] = OptionGroup::SubGroup("Ocarina Songs", { - &mOptions[RSK_STARTING_ZELDAS_LULLABY], - &mOptions[RSK_STARTING_EPONAS_SONG], - &mOptions[RSK_STARTING_SARIAS_SONG], - &mOptions[RSK_STARTING_SUNS_SONG], - &mOptions[RSK_STARTING_SONG_OF_TIME], - &mOptions[RSK_STARTING_SONG_OF_STORMS], - &mOptions[RSK_STARTING_SONG_OF_TIME], - &mOptions[RSK_STARTING_MINUET_OF_FOREST], - &mOptions[RSK_STARTING_BOLERO_OF_FIRE], - &mOptions[RSK_STARTING_SERENADE_OF_WATER], - &mOptions[RSK_STARTING_REQUIEM_OF_SPIRIT], - &mOptions[RSK_STARTING_NOCTURNE_OF_SHADOW], - &mOptions[RSK_STARTING_PRELUDE_OF_LIGHT], - }); + &mOptions[RSK_STARTING_AGE], + &mOptions[RSK_SHUFFLE_ENTRANCES], + &mOptions[RSK_SHUFFLE_DUNGEON_ENTRANCES], + &mOptions[RSK_SHUFFLE_BOSS_ENTRANCES], + &mOptions[RSK_SHUFFLE_OVERWORLD_ENTRANCES], + &mOptions[RSK_SHUFFLE_INTERIOR_ENTRANCES], + &mOptions[RSK_SHUFFLE_GROTTO_ENTRANCES], + &mOptions[RSK_SHUFFLE_OWL_DROPS], + &mOptions[RSK_SHUFFLE_WARP_SONGS], + &mOptions[RSK_SHUFFLE_OVERWORLD_SPAWNS], + &mOptions[RSK_MIXED_ENTRANCE_POOLS], + &mOptions[RSK_MIX_DUNGEON_ENTRANCES], + &mOptions[RSK_MIX_BOSS_ENTRANCES], + &mOptions[RSK_MIX_OVERWORLD_ENTRANCES], + &mOptions[RSK_MIX_INTERIOR_ENTRANCES], + &mOptions[RSK_MIX_GROTTO_ENTRANCES], + &mOptions[RSK_DECOUPLED_ENTRANCES], + &mOptions[RSK_BOMBCHU_BAG], + &mOptions[RSK_ENABLE_BOMBCHU_DROPS], + &mOptions[RSK_TRIFORCE_HUNT], + &mOptions[RSK_TRIFORCE_HUNT_PIECES_TOTAL], + &mOptions[RSK_TRIFORCE_HUNT_PIECES_REQUIRED], + &mOptions[RSK_MQ_DUNGEON_RANDOM], + &mOptions[RSK_MQ_DUNGEON_COUNT], + &mOptions[RSK_MQ_DUNGEON_SET], + }); + mOptionGroups[RSG_SHUFFLE_DUNGEON_QUESTS] = OptionGroup::SubGroup( + "Shuffle Dungeon Quest", + { &mOptions[RSK_MQ_DEKU_TREE], &mOptions[RSK_MQ_DODONGOS_CAVERN], &mOptions[RSK_MQ_JABU_JABU], + &mOptions[RSK_MQ_FOREST_TEMPLE], &mOptions[RSK_MQ_FIRE_TEMPLE], &mOptions[RSK_MQ_WATER_TEMPLE], + &mOptions[RSK_MQ_SPIRIT_TEMPLE], &mOptions[RSK_MQ_SHADOW_TEMPLE], &mOptions[RSK_MQ_BOTTOM_OF_THE_WELL], + &mOptions[RSK_MQ_ICE_CAVERN], &mOptions[RSK_MQ_GTG], &mOptions[RSK_MQ_GANONS_CASTLE] }); + mOptionGroups[RSG_SHUFFLE] = + OptionGroup("Shuffle Settings", { + &mOptions[RSK_SHUFFLE_DUNGEON_REWARDS], + &mOptions[RSK_LINKS_POCKET], + &mOptions[RSK_SHUFFLE_SONGS], + &mOptions[RSK_SHOPSANITY], + &mOptions[RSK_SHOPSANITY_COUNT], + &mOptions[RSK_SHOPSANITY_PRICES], + &mOptions[RSK_SHOPSANITY_PRICES_FIXED_PRICE], + &mOptions[RSK_SHOPSANITY_PRICES_RANGE_1], + &mOptions[RSK_SHOPSANITY_PRICES_RANGE_2], + &mOptions[RSK_SHOPSANITY_PRICES_NO_WALLET_WEIGHT], + &mOptions[RSK_SHOPSANITY_PRICES_CHILD_WALLET_WEIGHT], + &mOptions[RSK_SHOPSANITY_PRICES_ADULT_WALLET_WEIGHT], + &mOptions[RSK_SHOPSANITY_PRICES_GIANT_WALLET_WEIGHT], + &mOptions[RSK_SHOPSANITY_PRICES_TYCOON_WALLET_WEIGHT], + &mOptions[RSK_SHOPSANITY_PRICES_AFFORDABLE], + &mOptions[RSK_FISHSANITY], + &mOptions[RSK_FISHSANITY_POND_COUNT], + &mOptions[RSK_FISHSANITY_AGE_SPLIT], + &mOptions[RSK_SHUFFLE_FISHING_POLE], + &mOptions[RSK_SHUFFLE_TOKENS], + &mOptions[RSK_SHUFFLE_SCRUBS], + &mOptions[RSK_SCRUBS_PRICES], + &mOptions[RSK_SCRUBS_PRICES_FIXED_PRICE], + &mOptions[RSK_SCRUBS_PRICES_RANGE_1], + &mOptions[RSK_SCRUBS_PRICES_RANGE_2], + &mOptions[RSK_SCRUBS_PRICES_NO_WALLET_WEIGHT], + &mOptions[RSK_SCRUBS_PRICES_CHILD_WALLET_WEIGHT], + &mOptions[RSK_SCRUBS_PRICES_ADULT_WALLET_WEIGHT], + &mOptions[RSK_SCRUBS_PRICES_GIANT_WALLET_WEIGHT], + &mOptions[RSK_SCRUBS_PRICES_TYCOON_WALLET_WEIGHT], + &mOptions[RSK_SCRUBS_PRICES_AFFORDABLE], + &mOptions[RSK_SHUFFLE_BEEHIVES], + &mOptions[RSK_SHUFFLE_COWS], + &mOptions[RSK_SHUFFLE_POTS], + &mOptions[RSK_SHUFFLE_CRATES], + &mOptions[RSK_SHUFFLE_KOKIRI_SWORD], + &mOptions[RSK_SHUFFLE_OCARINA], + &mOptions[RSK_SHUFFLE_OCARINA_BUTTONS], + &mOptions[RSK_SHUFFLE_SWIM], + &mOptions[RSK_SHUFFLE_WEIRD_EGG], + &mOptions[RSK_SHUFFLE_GERUDO_MEMBERSHIP_CARD], + &mOptions[RSK_SHUFFLE_MERCHANTS], + &mOptions[RSK_MERCHANT_PRICES], + &mOptions[RSK_MERCHANT_PRICES_FIXED_PRICE], + &mOptions[RSK_MERCHANT_PRICES_RANGE_1], + &mOptions[RSK_MERCHANT_PRICES_RANGE_2], + &mOptions[RSK_MERCHANT_PRICES_NO_WALLET_WEIGHT], + &mOptions[RSK_MERCHANT_PRICES_CHILD_WALLET_WEIGHT], + &mOptions[RSK_MERCHANT_PRICES_ADULT_WALLET_WEIGHT], + &mOptions[RSK_MERCHANT_PRICES_GIANT_WALLET_WEIGHT], + &mOptions[RSK_MERCHANT_PRICES_TYCOON_WALLET_WEIGHT], + &mOptions[RSK_MERCHANT_PRICES_AFFORDABLE], + &mOptions[RSK_SHUFFLE_FROG_SONG_RUPEES], + &mOptions[RSK_SHUFFLE_ADULT_TRADE], + &mOptions[RSK_SHUFFLE_CHEST_MINIGAME], + &mOptions[RSK_SHUFFLE_100_GS_REWARD], + &mOptions[RSK_SHUFFLE_BOSS_SOULS], + &mOptions[RSK_SHUFFLE_DEKU_STICK_BAG], + &mOptions[RSK_SHUFFLE_DEKU_NUT_BAG], + &mOptions[RSK_SHUFFLE_FREESTANDING], + &mOptions[RSK_SHUFFLE_FAIRIES], + }); + mOptionGroups[RSG_SHUFFLE_DUNGEON_ITEMS] = + OptionGroup("Shuffle Dungeon Items", { + &mOptions[RSK_SHUFFLE_MAPANDCOMPASS], + &mOptions[RSK_KEYSANITY], + &mOptions[RSK_GERUDO_KEYS], + &mOptions[RSK_BOSS_KEYSANITY], + &mOptions[RSK_GANONS_BOSS_KEY], + &mOptions[RSK_LACS_STONE_COUNT], + &mOptions[RSK_LACS_MEDALLION_COUNT], + &mOptions[RSK_LACS_DUNGEON_COUNT], + &mOptions[RSK_LACS_REWARD_COUNT], + &mOptions[RSK_LACS_TOKEN_COUNT], + &mOptions[RSK_LACS_OPTIONS], + &mOptions[RSK_KEYRINGS], + &mOptions[RSK_KEYRINGS_RANDOM_COUNT], + &mOptions[RSK_KEYRINGS_GERUDO_FORTRESS], + &mOptions[RSK_KEYRINGS_FOREST_TEMPLE], + &mOptions[RSK_KEYRINGS_FIRE_TEMPLE], + &mOptions[RSK_KEYRINGS_WATER_TEMPLE], + &mOptions[RSK_KEYRINGS_SPIRIT_TEMPLE], + &mOptions[RSK_KEYRINGS_SHADOW_TEMPLE], + &mOptions[RSK_KEYRINGS_BOTTOM_OF_THE_WELL], + &mOptions[RSK_KEYRINGS_GTG], + &mOptions[RSK_KEYRINGS_GANONS_CASTLE], + }); + mOptionGroups[RSG_STARTING_ITEMS] = + OptionGroup::SubGroup("Items", { &mOptions[RSK_STARTING_OCARINA], &mOptions[RSK_STARTING_KOKIRI_SWORD], + &mOptions[RSK_STARTING_DEKU_SHIELD] }); + mOptionGroups[RSG_STARTING_SONGS] = + OptionGroup::SubGroup("Ocarina Songs", { + &mOptions[RSK_STARTING_ZELDAS_LULLABY], + &mOptions[RSK_STARTING_EPONAS_SONG], + &mOptions[RSK_STARTING_SARIAS_SONG], + &mOptions[RSK_STARTING_SUNS_SONG], + &mOptions[RSK_STARTING_SONG_OF_TIME], + &mOptions[RSK_STARTING_SONG_OF_STORMS], + &mOptions[RSK_STARTING_SONG_OF_TIME], + &mOptions[RSK_STARTING_MINUET_OF_FOREST], + &mOptions[RSK_STARTING_BOLERO_OF_FIRE], + &mOptions[RSK_STARTING_SERENADE_OF_WATER], + &mOptions[RSK_STARTING_REQUIEM_OF_SPIRIT], + &mOptions[RSK_STARTING_NOCTURNE_OF_SHADOW], + &mOptions[RSK_STARTING_PRELUDE_OF_LIGHT], + }); mOptionGroups[RSG_STARTING_OTHER] = OptionGroup::SubGroup("Other", { - &mOptions[RSK_STARTING_STICKS], - &mOptions[RSK_STARTING_NUTS], - &mOptions[RSK_FULL_WALLETS], - &mOptions[RSK_STARTING_SKULLTULA_TOKEN], - &mOptions[RSK_STARTING_HEARTS], - }); - mOptionGroups[RSG_STARTING_INVENTORY] = OptionGroup("Starting Inventory", { - &mOptionGroups[RSG_STARTING_ITEMS], - &mOptionGroups[RSG_STARTING_SONGS], - &mOptionGroups[RSG_STARTING_OTHER], - }, OptionGroupType::DEFAULT); + &mOptions[RSK_STARTING_STICKS], + &mOptions[RSK_STARTING_NUTS], + &mOptions[RSK_FULL_WALLETS], + &mOptions[RSK_STARTING_SKULLTULA_TOKEN], + &mOptions[RSK_STARTING_HEARTS], + }); + mOptionGroups[RSG_STARTING_INVENTORY] = OptionGroup("Starting Inventory", + { + &mOptionGroups[RSG_STARTING_ITEMS], + &mOptionGroups[RSG_STARTING_SONGS], + &mOptionGroups[RSG_STARTING_OTHER], + }, + OptionGroupType::DEFAULT); mOptionGroups[RSG_TIMESAVERS] = OptionGroup("Timesaver Settings", { - &mOptions[RSK_SKIP_CHILD_ZELDA], - &mOptions[RSK_SKIP_EPONA_RACE], - &mOptions[RSK_SKIP_SCARECROWS_SONG], - &mOptions[RSK_BIG_POE_COUNT], - &mOptions[RSK_CUCCO_COUNT], - &mOptions[RSK_COMPLETE_MASK_QUEST], - }); - mOptionGroups[RSG_MISC] = OptionGroup("Miscellaneous Settings", { - &mOptions[RSK_GOSSIP_STONE_HINTS], - &mOptions[RSK_HINT_CLARITY], - &mOptions[RSK_HINT_DISTRIBUTION], - &mOptions[RSK_TOT_ALTAR_HINT], - &mOptions[RSK_GANONDORF_HINT], - &mOptions[RSK_SHEIK_LA_HINT], - &mOptions[RSK_DAMPES_DIARY_HINT], - &mOptions[RSK_GREG_HINT], - &mOptions[RSK_LOACH_HINT], - &mOptions[RSK_SARIA_HINT], - &mOptions[RSK_FROGS_HINT], - &mOptions[RSK_OOT_HINT], - &mOptions[RSK_WARP_SONG_HINTS], - &mOptions[RSK_BIGGORON_HINT], - &mOptions[RSK_BIG_POES_HINT], - &mOptions[RSK_CHICKENS_HINT], - &mOptions[RSK_MALON_HINT], - &mOptions[RSK_HBA_HINT], - &mOptions[RSK_KAK_10_SKULLS_HINT], - &mOptions[RSK_KAK_20_SKULLS_HINT], - &mOptions[RSK_KAK_30_SKULLS_HINT], - &mOptions[RSK_KAK_40_SKULLS_HINT], - &mOptions[RSK_KAK_50_SKULLS_HINT], - &mOptions[RSK_KAK_100_SKULLS_HINT], - &mOptions[RSK_MASK_SHOP_HINT], - &mOptions[RSK_SCRUB_TEXT_HINT], - &mOptions[RSK_MERCHANT_TEXT_HINT], - &mOptions[RSK_FISHING_POLE_HINT], - // TODO: Compasses show Reward/WOTH, Maps show Dungeon Mode, Starting Time - &mOptions[RSK_DAMAGE_MULTIPLIER], - &mOptions[RSK_BLUE_FIRE_ARROWS], - &mOptions[RSK_SUNLIGHT_ARROWS], - &mOptions[RSK_INFINITE_UPGRADES], - &mOptions[RSK_SKELETON_KEY], - }); - mOptionGroups[RSG_ITEM_POOL] = OptionGroup("Item Pool Settings", std::initializer_list({ - &mOptions[RSK_ITEM_POOL], - &mOptions[RSK_ICE_TRAPS] - })); + &mOptions[RSK_SKIP_CHILD_ZELDA], + &mOptions[RSK_SKIP_EPONA_RACE], + &mOptions[RSK_SKIP_SCARECROWS_SONG], + &mOptions[RSK_BIG_POE_COUNT], + &mOptions[RSK_CUCCO_COUNT], + &mOptions[RSK_COMPLETE_MASK_QUEST], + }); + mOptionGroups[RSG_MISC] = OptionGroup("Miscellaneous Settings", + { + &mOptions[RSK_GOSSIP_STONE_HINTS], + &mOptions[RSK_HINT_CLARITY], + &mOptions[RSK_HINT_DISTRIBUTION], + &mOptions[RSK_TOT_ALTAR_HINT], + &mOptions[RSK_GANONDORF_HINT], + &mOptions[RSK_SHEIK_LA_HINT], + &mOptions[RSK_DAMPES_DIARY_HINT], + &mOptions[RSK_GREG_HINT], + &mOptions[RSK_LOACH_HINT], + &mOptions[RSK_SARIA_HINT], + &mOptions[RSK_FROGS_HINT], + &mOptions[RSK_OOT_HINT], + &mOptions[RSK_WARP_SONG_HINTS], + &mOptions[RSK_BIGGORON_HINT], + &mOptions[RSK_BIG_POES_HINT], + &mOptions[RSK_CHICKENS_HINT], + &mOptions[RSK_MALON_HINT], + &mOptions[RSK_HBA_HINT], + &mOptions[RSK_KAK_10_SKULLS_HINT], + &mOptions[RSK_KAK_20_SKULLS_HINT], + &mOptions[RSK_KAK_30_SKULLS_HINT], + &mOptions[RSK_KAK_40_SKULLS_HINT], + &mOptions[RSK_KAK_50_SKULLS_HINT], + &mOptions[RSK_KAK_100_SKULLS_HINT], + &mOptions[RSK_MASK_SHOP_HINT], + &mOptions[RSK_SCRUB_TEXT_HINT], + &mOptions[RSK_MERCHANT_TEXT_HINT], + &mOptions[RSK_FISHING_POLE_HINT], + // TODO: Compasses show Reward/WOTH, Maps show Dungeon Mode, Starting Time + &mOptions[RSK_DAMAGE_MULTIPLIER], + &mOptions[RSK_BLUE_FIRE_ARROWS], + &mOptions[RSK_SUNLIGHT_ARROWS], + &mOptions[RSK_INFINITE_UPGRADES], + &mOptions[RSK_SKELETON_KEY], + }); + mOptionGroups[RSG_ITEM_POOL] = OptionGroup( + "Item Pool Settings", std::initializer_list({ &mOptions[RSK_ITEM_POOL], &mOptions[RSK_ICE_TRAPS] })); // TODO: Progressive Goron Sword, Remove Double Defense - mOptionGroups[RSG_EXCLUDES_KOKIRI_FOREST] = OptionGroup::SubGroup("Kokiri Forest", mExcludeLocationsOptionsAreas[RCAREA_KOKIRI_FOREST]); - mOptionGroups[RSG_EXCLUDES_LOST_WOODS] = OptionGroup::SubGroup("Lost Woods", mExcludeLocationsOptionsAreas[RCAREA_LOST_WOODS]); - mOptionGroups[RSG_EXCLUDES_SACRED_FOREST_MEADOW] = OptionGroup::SubGroup("Sacred Forest Meadow", mExcludeLocationsOptionsAreas[RCAREA_SACRED_FOREST_MEADOW]); - mOptionGroups[RSG_EXCLUDES_DEKU_TREE] = OptionGroup::SubGroup("Deku Tree", mExcludeLocationsOptionsAreas[RCAREA_DEKU_TREE]); - mOptionGroups[RSG_EXCLUDES_FOREST_TEMPLE] = OptionGroup::SubGroup("Forest Temple", mExcludeLocationsOptionsAreas[RCAREA_FOREST_TEMPLE]); - mOptionGroups[RSG_EXCLUDES_KAKARIKO_VILLAGE] = OptionGroup::SubGroup("Kakariko Village", mExcludeLocationsOptionsAreas[RCAREA_KAKARIKO_VILLAGE]); - mOptionGroups[RSG_EXCLUDES_GRAVEYARD] = OptionGroup::SubGroup("Graveyard", mExcludeLocationsOptionsAreas[RCAREA_GRAVEYARD]); - mOptionGroups[RSG_EXCLUDES_BOTTOM_OF_THE_WELL] = OptionGroup::SubGroup("Bottom of the Well", mExcludeLocationsOptionsAreas[RCAREA_BOTTOM_OF_THE_WELL]); - mOptionGroups[RSG_EXCLUDES_SHADOW_TEMPLE] = OptionGroup::SubGroup("Shadow Temple", mExcludeLocationsOptionsAreas[RCAREA_SHADOW_TEMPLE]); - mOptionGroups[RSG_EXCLUDES_DEATH_MOUNTAIN_TRAIL] = OptionGroup::SubGroup("Death Mountain Trail", mExcludeLocationsOptionsAreas[RCAREA_DEATH_MOUNTAIN_TRAIL]); - mOptionGroups[RSG_EXCLUDES_DEATH_MOUNTAIN_CRATER] = OptionGroup::SubGroup("Death Mountain Crater", mExcludeLocationsOptionsAreas[RCAREA_DEATH_MOUNTAIN_CRATER]); - mOptionGroups[RSG_EXCLUDES_GORON_CITY] = OptionGroup::SubGroup("Goron City", mExcludeLocationsOptionsAreas[RCAREA_GORON_CITY]); - mOptionGroups[RSG_EXCLUDES_DODONGOS_CAVERN] = OptionGroup::SubGroup("Dodongo's Cavern", mExcludeLocationsOptionsAreas[RCAREA_DODONGOS_CAVERN]); - mOptionGroups[RSG_EXCLUDES_FIRE_TEMPLE] = OptionGroup::SubGroup("Fire Temple", mExcludeLocationsOptionsAreas[RCAREA_FIRE_TEMPLE]); - mOptionGroups[RSG_EXCLUDES_ZORAS_RIVER] = OptionGroup::SubGroup("Zora's River", mExcludeLocationsOptionsAreas[RCAREA_ZORAS_RIVER]); - mOptionGroups[RSG_EXCLUDES_ZORAS_DOMAIN] = OptionGroup::SubGroup("Zora's Domain", mExcludeLocationsOptionsAreas[RCAREA_ZORAS_DOMAIN]); - mOptionGroups[RSG_EXCLUDES_ZORAS_FOUNTAIN] = OptionGroup::SubGroup("Zora's Fountain", mExcludeLocationsOptionsAreas[RCAREA_ZORAS_FOUNTAIN]); - mOptionGroups[RSG_EXCLUDES_JABU_JABU] = OptionGroup::SubGroup("Jabu Jabu's Belly", mExcludeLocationsOptionsAreas[RCAREA_JABU_JABUS_BELLY]); - mOptionGroups[RSG_EXCLUDES_ICE_CAVERN] = OptionGroup::SubGroup("Ice Cavern", mExcludeLocationsOptionsAreas[RCAREA_ICE_CAVERN]); - mOptionGroups[RSG_EXCLUDES_HYRULE_FIELD] = OptionGroup::SubGroup("Hyrule Field", mExcludeLocationsOptionsAreas[RCAREA_HYRULE_FIELD]); - mOptionGroups[RSG_EXCLUDES_LON_LON_RANCH] = OptionGroup::SubGroup("Lon Lon Ranch", mExcludeLocationsOptionsAreas[RCAREA_LON_LON_RANCH]); - mOptionGroups[RSG_EXCLUDES_LAKE_HYLIA] = OptionGroup::SubGroup("Lake Hylia", mExcludeLocationsOptionsAreas[RCAREA_LAKE_HYLIA]); - mOptionGroups[RSG_EXCLUDES_WATER_TEMPLE] = OptionGroup::SubGroup("Water Temple", mExcludeLocationsOptionsAreas[RCAREA_WATER_TEMPLE]); - mOptionGroups[RSG_EXCLUDES_GERUDO_VALLEY] = OptionGroup::SubGroup("Gerudo Valley", mExcludeLocationsOptionsAreas[RCAREA_GERUDO_VALLEY]); - mOptionGroups[RSG_EXCLUDES_GERUDO_FORTRESS] = OptionGroup::SubGroup("Gerudo Fortress", mExcludeLocationsOptionsAreas[RCAREA_GERUDO_FORTRESS]); - mOptionGroups[RSG_EXCLUDES_HAUNTED_WASTELAND] = OptionGroup::SubGroup("Haunted Wasteland", mExcludeLocationsOptionsAreas[RCAREA_WASTELAND]); - mOptionGroups[RSG_EXCLUDES_DESERT_COLOSSUS] = OptionGroup::SubGroup("Desert Colossus", mExcludeLocationsOptionsAreas[RCAREA_DESERT_COLOSSUS]); - mOptionGroups[RSG_EXCLUDES_GERUDO_TRAINING_GROUND] = OptionGroup::SubGroup("Gerudo Training Ground", mExcludeLocationsOptionsAreas[RCAREA_GERUDO_TRAINING_GROUND]); - mOptionGroups[RSG_EXCLUDES_SPIRIT_TEMPLE] = OptionGroup::SubGroup("Spirit Temple", mExcludeLocationsOptionsAreas[RCAREA_SPIRIT_TEMPLE]); - mOptionGroups[RSG_EXCLUDES_HYRULE_CASTLE] = OptionGroup::SubGroup("Hyrule Castle", mExcludeLocationsOptionsAreas[RCAREA_HYRULE_CASTLE]); + mOptionGroups[RSG_EXCLUDES_KOKIRI_FOREST] = + OptionGroup::SubGroup("Kokiri Forest", mExcludeLocationsOptionsAreas[RCAREA_KOKIRI_FOREST]); + mOptionGroups[RSG_EXCLUDES_LOST_WOODS] = + OptionGroup::SubGroup("Lost Woods", mExcludeLocationsOptionsAreas[RCAREA_LOST_WOODS]); + mOptionGroups[RSG_EXCLUDES_SACRED_FOREST_MEADOW] = + OptionGroup::SubGroup("Sacred Forest Meadow", mExcludeLocationsOptionsAreas[RCAREA_SACRED_FOREST_MEADOW]); + mOptionGroups[RSG_EXCLUDES_DEKU_TREE] = + OptionGroup::SubGroup("Deku Tree", mExcludeLocationsOptionsAreas[RCAREA_DEKU_TREE]); + mOptionGroups[RSG_EXCLUDES_FOREST_TEMPLE] = + OptionGroup::SubGroup("Forest Temple", mExcludeLocationsOptionsAreas[RCAREA_FOREST_TEMPLE]); + mOptionGroups[RSG_EXCLUDES_KAKARIKO_VILLAGE] = + OptionGroup::SubGroup("Kakariko Village", mExcludeLocationsOptionsAreas[RCAREA_KAKARIKO_VILLAGE]); + mOptionGroups[RSG_EXCLUDES_GRAVEYARD] = + OptionGroup::SubGroup("Graveyard", mExcludeLocationsOptionsAreas[RCAREA_GRAVEYARD]); + mOptionGroups[RSG_EXCLUDES_BOTTOM_OF_THE_WELL] = + OptionGroup::SubGroup("Bottom of the Well", mExcludeLocationsOptionsAreas[RCAREA_BOTTOM_OF_THE_WELL]); + mOptionGroups[RSG_EXCLUDES_SHADOW_TEMPLE] = + OptionGroup::SubGroup("Shadow Temple", mExcludeLocationsOptionsAreas[RCAREA_SHADOW_TEMPLE]); + mOptionGroups[RSG_EXCLUDES_DEATH_MOUNTAIN_TRAIL] = + OptionGroup::SubGroup("Death Mountain Trail", mExcludeLocationsOptionsAreas[RCAREA_DEATH_MOUNTAIN_TRAIL]); + mOptionGroups[RSG_EXCLUDES_DEATH_MOUNTAIN_CRATER] = + OptionGroup::SubGroup("Death Mountain Crater", mExcludeLocationsOptionsAreas[RCAREA_DEATH_MOUNTAIN_CRATER]); + mOptionGroups[RSG_EXCLUDES_GORON_CITY] = + OptionGroup::SubGroup("Goron City", mExcludeLocationsOptionsAreas[RCAREA_GORON_CITY]); + mOptionGroups[RSG_EXCLUDES_DODONGOS_CAVERN] = + OptionGroup::SubGroup("Dodongo's Cavern", mExcludeLocationsOptionsAreas[RCAREA_DODONGOS_CAVERN]); + mOptionGroups[RSG_EXCLUDES_FIRE_TEMPLE] = + OptionGroup::SubGroup("Fire Temple", mExcludeLocationsOptionsAreas[RCAREA_FIRE_TEMPLE]); + mOptionGroups[RSG_EXCLUDES_ZORAS_RIVER] = + OptionGroup::SubGroup("Zora's River", mExcludeLocationsOptionsAreas[RCAREA_ZORAS_RIVER]); + mOptionGroups[RSG_EXCLUDES_ZORAS_DOMAIN] = + OptionGroup::SubGroup("Zora's Domain", mExcludeLocationsOptionsAreas[RCAREA_ZORAS_DOMAIN]); + mOptionGroups[RSG_EXCLUDES_ZORAS_FOUNTAIN] = + OptionGroup::SubGroup("Zora's Fountain", mExcludeLocationsOptionsAreas[RCAREA_ZORAS_FOUNTAIN]); + mOptionGroups[RSG_EXCLUDES_JABU_JABU] = + OptionGroup::SubGroup("Jabu Jabu's Belly", mExcludeLocationsOptionsAreas[RCAREA_JABU_JABUS_BELLY]); + mOptionGroups[RSG_EXCLUDES_ICE_CAVERN] = + OptionGroup::SubGroup("Ice Cavern", mExcludeLocationsOptionsAreas[RCAREA_ICE_CAVERN]); + mOptionGroups[RSG_EXCLUDES_HYRULE_FIELD] = + OptionGroup::SubGroup("Hyrule Field", mExcludeLocationsOptionsAreas[RCAREA_HYRULE_FIELD]); + mOptionGroups[RSG_EXCLUDES_LON_LON_RANCH] = + OptionGroup::SubGroup("Lon Lon Ranch", mExcludeLocationsOptionsAreas[RCAREA_LON_LON_RANCH]); + mOptionGroups[RSG_EXCLUDES_LAKE_HYLIA] = + OptionGroup::SubGroup("Lake Hylia", mExcludeLocationsOptionsAreas[RCAREA_LAKE_HYLIA]); + mOptionGroups[RSG_EXCLUDES_WATER_TEMPLE] = + OptionGroup::SubGroup("Water Temple", mExcludeLocationsOptionsAreas[RCAREA_WATER_TEMPLE]); + mOptionGroups[RSG_EXCLUDES_GERUDO_VALLEY] = + OptionGroup::SubGroup("Gerudo Valley", mExcludeLocationsOptionsAreas[RCAREA_GERUDO_VALLEY]); + mOptionGroups[RSG_EXCLUDES_GERUDO_FORTRESS] = + OptionGroup::SubGroup("Gerudo Fortress", mExcludeLocationsOptionsAreas[RCAREA_GERUDO_FORTRESS]); + mOptionGroups[RSG_EXCLUDES_HAUNTED_WASTELAND] = + OptionGroup::SubGroup("Haunted Wasteland", mExcludeLocationsOptionsAreas[RCAREA_WASTELAND]); + mOptionGroups[RSG_EXCLUDES_DESERT_COLOSSUS] = + OptionGroup::SubGroup("Desert Colossus", mExcludeLocationsOptionsAreas[RCAREA_DESERT_COLOSSUS]); + mOptionGroups[RSG_EXCLUDES_GERUDO_TRAINING_GROUND] = + OptionGroup::SubGroup("Gerudo Training Ground", mExcludeLocationsOptionsAreas[RCAREA_GERUDO_TRAINING_GROUND]); + mOptionGroups[RSG_EXCLUDES_SPIRIT_TEMPLE] = + OptionGroup::SubGroup("Spirit Temple", mExcludeLocationsOptionsAreas[RCAREA_SPIRIT_TEMPLE]); + mOptionGroups[RSG_EXCLUDES_HYRULE_CASTLE] = + OptionGroup::SubGroup("Hyrule Castle", mExcludeLocationsOptionsAreas[RCAREA_HYRULE_CASTLE]); mOptionGroups[RSG_EXCLUDES_MARKET] = OptionGroup::SubGroup("Market", mExcludeLocationsOptionsAreas[RCAREA_MARKET]); - mOptionGroups[RSG_EXCLUDES_GANONS_CASTLE] = OptionGroup::SubGroup("Ganon's Castle", mExcludeLocationsOptionsAreas[RCAREA_GANONS_CASTLE]); - mOptionGroups[RSG_EXCLUDES] = OptionGroup::SubGroup("Exclude Locations", { - &mOptionGroups[RSG_EXCLUDES_KOKIRI_FOREST], - &mOptionGroups[RSG_EXCLUDES_LOST_WOODS], - &mOptionGroups[RSG_EXCLUDES_SACRED_FOREST_MEADOW], - &mOptionGroups[RSG_EXCLUDES_DEKU_TREE], - &mOptionGroups[RSG_EXCLUDES_FOREST_TEMPLE], - &mOptionGroups[RSG_EXCLUDES_KAKARIKO_VILLAGE], - &mOptionGroups[RSG_EXCLUDES_GRAVEYARD], - &mOptionGroups[RSG_EXCLUDES_BOTTOM_OF_THE_WELL], - &mOptionGroups[RSG_EXCLUDES_SHADOW_TEMPLE], - &mOptionGroups[RSG_EXCLUDES_DEATH_MOUNTAIN_TRAIL], - &mOptionGroups[RSG_EXCLUDES_DEATH_MOUNTAIN_CRATER], - &mOptionGroups[RSG_EXCLUDES_GORON_CITY], - &mOptionGroups[RSG_EXCLUDES_DODONGOS_CAVERN], - &mOptionGroups[RSG_EXCLUDES_FIRE_TEMPLE], - &mOptionGroups[RSG_EXCLUDES_ZORAS_RIVER], - &mOptionGroups[RSG_EXCLUDES_ZORAS_DOMAIN], - &mOptionGroups[RSG_EXCLUDES_ZORAS_FOUNTAIN], - &mOptionGroups[RSG_EXCLUDES_JABU_JABU], - &mOptionGroups[RSG_EXCLUDES_ICE_CAVERN], - &mOptionGroups[RSG_EXCLUDES_HYRULE_FIELD], - &mOptionGroups[RSG_EXCLUDES_LON_LON_RANCH], - &mOptionGroups[RSG_EXCLUDES_LAKE_HYLIA], - &mOptionGroups[RSG_EXCLUDES_WATER_TEMPLE], - &mOptionGroups[RSG_EXCLUDES_GERUDO_VALLEY], - &mOptionGroups[RSG_EXCLUDES_GERUDO_FORTRESS], - &mOptionGroups[RSG_EXCLUDES_HAUNTED_WASTELAND], - &mOptionGroups[RSG_EXCLUDES_DESERT_COLOSSUS], - &mOptionGroups[RSG_EXCLUDES_GERUDO_TRAINING_GROUND], - &mOptionGroups[RSG_EXCLUDES_SPIRIT_TEMPLE], - &mOptionGroups[RSG_EXCLUDES_HYRULE_CASTLE], - &mOptionGroups[RSG_EXCLUDES_MARKET], - &mOptionGroups[RSG_EXCLUDES_GANONS_CASTLE], - }); - mOptionGroups[RSG_DETAILED_LOGIC] = OptionGroup("Detailed Logic Settings", { - &mOptionGroups[RSG_LOGIC], - &mOptionGroups[RSG_TRICKS], - &mOptionGroups[RSG_EXCLUDES] - }); + mOptionGroups[RSG_EXCLUDES_GANONS_CASTLE] = + OptionGroup::SubGroup("Ganon's Castle", mExcludeLocationsOptionsAreas[RCAREA_GANONS_CASTLE]); + mOptionGroups[RSG_EXCLUDES] = + OptionGroup::SubGroup("Exclude Locations", { + &mOptionGroups[RSG_EXCLUDES_KOKIRI_FOREST], + &mOptionGroups[RSG_EXCLUDES_LOST_WOODS], + &mOptionGroups[RSG_EXCLUDES_SACRED_FOREST_MEADOW], + &mOptionGroups[RSG_EXCLUDES_DEKU_TREE], + &mOptionGroups[RSG_EXCLUDES_FOREST_TEMPLE], + &mOptionGroups[RSG_EXCLUDES_KAKARIKO_VILLAGE], + &mOptionGroups[RSG_EXCLUDES_GRAVEYARD], + &mOptionGroups[RSG_EXCLUDES_BOTTOM_OF_THE_WELL], + &mOptionGroups[RSG_EXCLUDES_SHADOW_TEMPLE], + &mOptionGroups[RSG_EXCLUDES_DEATH_MOUNTAIN_TRAIL], + &mOptionGroups[RSG_EXCLUDES_DEATH_MOUNTAIN_CRATER], + &mOptionGroups[RSG_EXCLUDES_GORON_CITY], + &mOptionGroups[RSG_EXCLUDES_DODONGOS_CAVERN], + &mOptionGroups[RSG_EXCLUDES_FIRE_TEMPLE], + &mOptionGroups[RSG_EXCLUDES_ZORAS_RIVER], + &mOptionGroups[RSG_EXCLUDES_ZORAS_DOMAIN], + &mOptionGroups[RSG_EXCLUDES_ZORAS_FOUNTAIN], + &mOptionGroups[RSG_EXCLUDES_JABU_JABU], + &mOptionGroups[RSG_EXCLUDES_ICE_CAVERN], + &mOptionGroups[RSG_EXCLUDES_HYRULE_FIELD], + &mOptionGroups[RSG_EXCLUDES_LON_LON_RANCH], + &mOptionGroups[RSG_EXCLUDES_LAKE_HYLIA], + &mOptionGroups[RSG_EXCLUDES_WATER_TEMPLE], + &mOptionGroups[RSG_EXCLUDES_GERUDO_VALLEY], + &mOptionGroups[RSG_EXCLUDES_GERUDO_FORTRESS], + &mOptionGroups[RSG_EXCLUDES_HAUNTED_WASTELAND], + &mOptionGroups[RSG_EXCLUDES_DESERT_COLOSSUS], + &mOptionGroups[RSG_EXCLUDES_GERUDO_TRAINING_GROUND], + &mOptionGroups[RSG_EXCLUDES_SPIRIT_TEMPLE], + &mOptionGroups[RSG_EXCLUDES_HYRULE_CASTLE], + &mOptionGroups[RSG_EXCLUDES_MARKET], + &mOptionGroups[RSG_EXCLUDES_GANONS_CASTLE], + }); + mOptionGroups[RSG_DETAILED_LOGIC] = + OptionGroup("Detailed Logic Settings", + { &mOptionGroups[RSG_LOGIC], &mOptionGroups[RSG_TRICKS], &mOptionGroups[RSG_EXCLUDES] }); } -std::unordered_map Settings::PopulateOptionNameToEnum(){ +std::unordered_map Settings::PopulateOptionNameToEnum() { std::unordered_map output = {}; for (size_t count = 0; count < RSK_MAX; count++) { output[mOptions[count].GetName()] = static_cast(count); @@ -1127,8 +1740,8 @@ TrickOption& Settings::GetTrickOption(const RandomizerTrick key) { } void Context::ResetTrickOptions() { - for (int count = 0; count < RT_MAX; count++){ - mTrickOptions[count].Set(0); //RANDOTODO this can probably be done better + for (int count = 0; count < RT_MAX; count++) { + mTrickOptions[count].Set(0); // RANDOTODO this can probably be done better }; } @@ -1136,11 +1749,11 @@ const std::array& Settings::GetAllOptions() const { return mOptions; } -std::vector