summaryrefslogtreecommitdiff
path: root/soh
diff options
context:
space:
mode:
authorMalkierian <malkierian@gmail.com>2025-05-23 14:57:49 -0700
committerGitHub <noreply@github.com>2025-05-23 14:57:49 -0700
commit99c3fa600672c656dc39d2eb5efaff1b7ff8041c (patch)
treeea3851f56e3ffe042ccd90fcfd7000e2f5b9ae12 /soh
parent3a069e621eed36a3c9fd801e87567f4fb13b1c31 (diff)
Preset Manager (#5459)
* Add presets sidebar, proof of concept row-based listing. * Complete and unify section check/x drawing. * Add error state to InputString, and corresponding members and builders to InputOptions. Implement saving and loading of preset files. * Implement `Config::SetBlock()`. Implement Apply. Implement Delete. Some json structure changes. * Apply `CVarClear()` calls in CVar-prefixed widget functions. * Comment out satellite preset pickers for now. * clang * Fix ButtonOptions initializer list. * I hate clang... * Loop new preset checkbox creation. Restore auto-resizing to new preset popup. Remove errant BeginDisabled in randomizer (merge artifact?). * Add BlockInfo struct to make array with all info for each block. Setup loops for all other same-ish situations (applying presets, setting up columns, etc) based on blockInfo. * Save tracker windows info for later restoration. Lay the groundwork for said restoration. * Complete tracker window restoration on preset application. * Fix RadioButtonsOptions builder parameter type. Add race lockout to new and apply buttons. * Revert application of CVarClear on UIWidgets widgets (need to preserve manually-set default states). * Remove enhancements satellite picker. Swap randomizer satellite picker to use the manager presets, only displays presets with randomizer section included. Move built-in presets to the asset archive, and remove delete button on them. Remove PresetEntries.cpp. * Fix locations and tricks tabs not updating live when applying preset with new system. * Apply RandoGenerating lockout to rando preset Apply button. * Fix new presets not being properly filtered in satellite selectors. * Fix currently selected presets getting deleted still being selected in satellite selectors. * Change BigPoeTargetCount in preset files to 1.
Diffstat (limited to 'soh')
-rw-r--r--soh/assets/custom/presets/Main Default.json11
-rw-r--r--soh/assets/custom/presets/Main Enhanced.json56
-rw-r--r--soh/assets/custom/presets/Main Randomizer.json135
-rw-r--r--soh/assets/custom/presets/Main Vanilla+.json56
-rw-r--r--soh/assets/custom/presets/Rando Advanced.json69
-rw-r--r--soh/assets/custom/presets/Rando Beginner.json51
-rw-r--r--soh/assets/custom/presets/Rando Default.json9
-rw-r--r--soh/assets/custom/presets/Rando Hell Mode.json80
-rw-r--r--soh/assets/custom/presets/Rando Standard.json63
-rw-r--r--soh/soh/Enhancements/Presets/PresetEntries.cpp650
-rw-r--r--soh/soh/Enhancements/Presets/Presets.cpp468
-rw-r--r--soh/soh/Enhancements/Presets/Presets.h62
-rw-r--r--soh/soh/Enhancements/randomizer/randomizer.cpp74
-rw-r--r--soh/soh/Enhancements/randomizer/randomizer_check_tracker.cpp18
-rw-r--r--soh/soh/Enhancements/randomizer/randomizer_check_tracker.h1
-rw-r--r--soh/soh/Enhancements/randomizer/randomizer_entrance_tracker.cpp18
-rw-r--r--soh/soh/Enhancements/randomizer/randomizer_entrance_tracker.h1
-rw-r--r--soh/soh/Enhancements/randomizer/randomizer_item_tracker.cpp26
-rw-r--r--soh/soh/Enhancements/randomizer/randomizer_item_tracker.h17
-rw-r--r--soh/soh/Enhancements/randomizer/randomizer_settings_window.h1
-rw-r--r--soh/soh/SohGui/SohMenu.h7
-rw-r--r--soh/soh/SohGui/SohMenuEnhancements.cpp67
-rw-r--r--soh/soh/SohGui/SohMenuNetwork.cpp1
-rw-r--r--soh/soh/SohGui/SohMenuRandomizer.cpp2
-rw-r--r--soh/soh/SohGui/SohMenuSettings.cpp1
-rw-r--r--soh/soh/SohGui/UIWidgets.cpp28
-rw-r--r--soh/soh/SohGui/UIWidgets.hpp31
27 files changed, 1114 insertions, 889 deletions
diff --git a/soh/assets/custom/presets/Main Default.json b/soh/assets/custom/presets/Main Default.json
new file mode 100644
index 000000000..7d87c3d95
--- /dev/null
+++ b/soh/assets/custom/presets/Main Default.json
@@ -0,0 +1,11 @@
+{
+ "blocks": {
+ "enhancements": {
+ "gCheats": null,
+ "gEnhancements": null,
+ "gRandoEnhancements": null
+ }
+ },
+ "presetName": "Main Default",
+ "isBuiltIn": true
+} \ No newline at end of file
diff --git a/soh/assets/custom/presets/Main Enhanced.json b/soh/assets/custom/presets/Main Enhanced.json
new file mode 100644
index 000000000..026a78de7
--- /dev/null
+++ b/soh/assets/custom/presets/Main Enhanced.json
@@ -0,0 +1,56 @@
+{
+ "blocks": {
+ "enhancements": {
+ "gCheats": null,
+ "gEnhancements": {
+ "AssignableTunicsAndBoots": 1,
+ "Autosave": 1,
+ "BetterOwl": 1,
+ "CreditsFix": 1,
+ "CustomizeFrogsOcarinaGame": 1,
+ "DekuNutUpgradeFix": 1,
+ "DisableLOD": 1,
+ "DpadEquips": 1,
+ "DpadNoDropOcarinaInput": 1,
+ "DynamicWalletIcon": 1,
+ "EnemySpawnsOverWaterboxes": 1,
+ "FasterRupeeAccumulator": 1,
+ "FixBrokenGiantsKnife": 1,
+ "FixDaruniaDanceSpeed": 1,
+ "FixDungeonMinimapIcon": 1,
+ "FixEyesOpenWhileSleeping": 1,
+ "FixFloorSwitches": 1,
+ "FixHammerHand": 1,
+ "FixMenuLR": 1,
+ "FixSawSoftlock": 1,
+ "FixTexturesOOB": 1,
+ "FixVineFall": 1,
+ "FixZoraHintDialogue": 1,
+ "FrogsModifyFailTime": 2,
+ "GerudoWarriorClothingFix": 1,
+ "GravediggingTourFix": 1,
+ "InjectItemCounts": {
+ "GoldSkulltula": 1,
+ "HeartContainer": 1,
+ "HeartPiece": 1
+ },
+ "NaviTextFix": 1,
+ "PulsateBossIcon": 1,
+ "RedGanonBlood": 1,
+ "RememberMapToggleState": 1,
+ "SceneSpecificDirtPathFix": 1,
+ "SilverRupeeJingleExtend": 1,
+ "SkipSaveConfirmation": 1,
+ "SkipText": 1,
+ "TextSpeed": 5,
+ "TimeFlowFileSelect": 1,
+ "TwoHandedIdle": 1,
+ "VisualAgony": 1,
+ "WidescreenActorCulling": 1
+ },
+ "gRandoEnhancements": null
+ }
+ },
+ "presetName": "Main Enhanced",
+ "isBuiltIn": true
+} \ No newline at end of file
diff --git a/soh/assets/custom/presets/Main Randomizer.json b/soh/assets/custom/presets/Main Randomizer.json
new file mode 100644
index 000000000..59c24e982
--- /dev/null
+++ b/soh/assets/custom/presets/Main Randomizer.json
@@ -0,0 +1,135 @@
+{
+ "blocks": {
+ "enhancements": {
+ "gCheats": {
+ "EasyFrameAdvance": 1
+ },
+ "gEnhancements": {
+ "AdultMasks": 1,
+ "AssignableTunicsAndBoots": 1,
+ "Autosave": 1,
+ "BetterAmmoRendering": 1,
+ "BetterBombchuShopping": 1,
+ "BetterFarore": 1,
+ "BetterOwl": 1,
+ "BombchusOOB": 1,
+ "ClimbSpeed": 3,
+ "CrawlSpeed": 2,
+ "CreditsFix": 1,
+ "CustomizeFishing": 1,
+ "CustomizeFrogsOcarinaGame": 1,
+ "CustomizeOcarinaGame": 1,
+ "DampeAllNight": 1,
+ "DampeWin": 1,
+ "DayGravePull": 1,
+ "DekuNutUpgradeFix": 1,
+ "DisableCritWiggle": 1,
+ "DisableFirstPersonChus": 1,
+ "DisableLOD": 1,
+ "DpadEquips": 1,
+ "DpadNoDropOcarinaInput": 1,
+ "DynamicWalletIcon": 1,
+ "EarlyEyeballFrog": 1,
+ "EnemySpawnsOverWaterboxes": 1,
+ "EquipmentCanBeRemoved": 1,
+ "ExtendedCullingExcludeGlitchActors": 1,
+ "FastBoomerang": 1,
+ "FastChests": 1,
+ "FastDrops": 1,
+ "FastFarores": 1,
+ "FastOcarinaPlayback": 1,
+ "FasterBlockPush": 5,
+ "FasterHeavyBlockLift": 1,
+ "FasterRupeeAccumulator": 1,
+ "FileSelectMoreInfo": 1,
+ "FishNeverEscape": 1,
+ "FixBrokenGiantsKnife": 1,
+ "FixDaruniaDanceSpeed": 1,
+ "FixDungeonMinimapIcon": 1,
+ "FixFloorSwitches": 1,
+ "FixHammerHand": 1,
+ "FixMenuLR": 1,
+ "FixSawSoftlock": 1,
+ "FixTexturesOOB": 1,
+ "FixVineFall": 1,
+ "FixZoraHintDialogue": 1,
+ "ForgeTime": 0,
+ "FrogsModifyFailTime": 2,
+ "GerudoWarriorClothingFix": 1,
+ "GoronPot": 1,
+ "GravediggingTourFix": 1,
+ "GuaranteeFishingBite": 1,
+ "HoverFishing": 1,
+ "IncludeHeldInputsBufferWindow": 1,
+ "InjectItemCounts": {
+ "GoldSkulltula": 1,
+ "HeartContainer": 1,
+ "HeartPiece": 1
+ },
+ "InstantPutaway": 1,
+ "InstantScarecrow": 1,
+ "MMBunnyHood": 1,
+ "MarketSneak": 1,
+ "MaskSelect": 1,
+ "MinimumFishWeightAdult": 6,
+ "MinimumFishWeightChild": 3,
+ "MweepSpeed": 5.0,
+ "N64WeirdFrames": 1,
+ "NaviTextFix": 1,
+ "NewDrops": 1,
+ "NoInputForCredits": 1,
+ "NutsExplodeBombs": 1,
+ "OcarinaGame": {
+ "StartingNotes": 5
+ },
+ "PauseMenuAnimatedLink": 1,
+ "PauseWarp": 1,
+ "PersistentMasks": 1,
+ "PulsateBossIcon": 1,
+ "QuickBongoKill": 1,
+ "QuickPutaway": 1,
+ "QuitFishingAtDoor": 1,
+ "RedGanonBlood": 1,
+ "RememberMapToggleState": 1,
+ "SceneSpecificDirtPathFix": 1,
+ "SeparateArrows": 1,
+ "ShowDoorLocksOnBothSides": 1,
+ "SilverRupeeJingleExtend": 1,
+ "SkipArrowAnimation": 1,
+ "SkipSaveConfirmation": 1,
+ "SkipSwimDeepEndAnim": 1,
+ "SkipText": 1,
+ "SlowTextSpeed": 5,
+ "SwordToggle": 1,
+ "TextSpeed": 5,
+ "TimeFlowFileSelect": 1,
+ "TimeSavers": {
+ "DisableTitleCard": 1,
+ "SkipChildStealth": 1,
+ "SkipCutscene": {
+ "BossIntro": 1,
+ "Entrances": 1,
+ "Intro": 1,
+ "LearnSong": 1,
+ "OnePoint": 1,
+ "QuickBossDeaths": 1,
+ "Story": 1
+ },
+ "SkipForcedDialog": 3,
+ "SkipMiscInteractions": 1,
+ "SkipOwlInteractions": 1,
+ "SkipTowerEscape": 1,
+ "SleepingWaterfall": 1
+ },
+ "ToTMedallionsColors": 1,
+ "ToggleStrength": 1,
+ "TwoHandedIdle": 1,
+ "VisualAgony": 1,
+ "WidescreenActorCulling": 1
+ },
+ "gRandoEnhancements": null
+ }
+ },
+ "presetName": "Main Randomizer",
+ "isBuiltIn": true
+} \ No newline at end of file
diff --git a/soh/assets/custom/presets/Main Vanilla+.json b/soh/assets/custom/presets/Main Vanilla+.json
new file mode 100644
index 000000000..0f6c1741a
--- /dev/null
+++ b/soh/assets/custom/presets/Main Vanilla+.json
@@ -0,0 +1,56 @@
+{
+ "blocks": {
+ "enhancements": {
+ "gCheats": null,
+ "gEnhancements": {
+ "AssignableTunicsAndBoots": 1,
+ "Autosave": 1,
+ "BetterOwl": 1,
+ "CreditsFix": 1,
+ "CustomizeFrogsOcarinaGame": 1,
+ "DekuNutUpgradeFix": 1,
+ "DisableLOD": 1,
+ "DpadEquips": 1,
+ "DpadNoDropOcarinaInput": 1,
+ "DynamicWalletIcon": 1,
+ "EnemySpawnsOverWaterboxes": 1,
+ "FasterRupeeAccumulator": 1,
+ "FixBrokenGiantsKnife": 1,
+ "FixDaruniaDanceSpeed": 1,
+ "FixDungeonMinimapIcon": 1,
+ "FixEyesOpenWhileSleeping": 1,
+ "FixFloorSwitches": 1,
+ "FixHammerHand": 1,
+ "FixMenuLR": 1,
+ "FixSawSoftlock": 1,
+ "FixTexturesOOB": 1,
+ "FixVineFall": 1,
+ "FixZoraHintDialogue": 1,
+ "FrogsModifyFailTime": 2,
+ "GerudoWarriorClothingFix": 1,
+ "GravediggingTourFix": 1,
+ "InjectItemCounts": {
+ "GoldSkulltula": 1,
+ "HeartContainer": 1,
+ "HeartPiece": 1
+ },
+ "NaviTextFix": 1,
+ "PulsateBossIcon": 1,
+ "RedGanonBlood": 1,
+ "RememberMapToggleState": 1,
+ "SceneSpecificDirtPathFix": 1,
+ "SilverRupeeJingleExtend": 1,
+ "SkipSaveConfirmation": 1,
+ "SkipText": 1,
+ "TextSpeed": 5,
+ "TimeFlowFileSelect": 1,
+ "TwoHandedIdle": 1,
+ "VisualAgony": 1,
+ "WidescreenActorCulling": 1
+ },
+ "gRandoEnhancements": null
+ }
+ },
+ "presetName": "Main Vanilla+",
+ "isBuiltIn": true
+} \ No newline at end of file
diff --git a/soh/assets/custom/presets/Rando Advanced.json b/soh/assets/custom/presets/Rando Advanced.json
new file mode 100644
index 000000000..4042c0688
--- /dev/null
+++ b/soh/assets/custom/presets/Rando Advanced.json
@@ -0,0 +1,69 @@
+{
+ "blocks": {
+ "rando": {
+ "gRandoSettings": {
+ "40GSHint": 1,
+ "50GSHint": 1,
+ "BigPoeTargetCount": 1,
+ "BlueFireArrows": 1,
+ "BombchuBag": 1,
+ "BossKeysanity": 5,
+ "ClosedForest": 2,
+ "CompleteMaskQuest": 1,
+ "CuccosToReturn": 1,
+ "DampeHint": 1,
+ "DoorOfTime": 2,
+ "EnableBombchuDrops": 1,
+ "FortressCarpenters": 1,
+ "FrogsHint": 1,
+ "FullWallets": 1,
+ "GanonTrial": 0,
+ "GerudoKeys": 3,
+ "GregHint": 1,
+ "HBAHint": 1,
+ "IncludeTycoonWallet": 1,
+ "KakarikoGate": 1,
+ "Keysanity": 5,
+ "LacsRewardCount": 8,
+ "MalonHint": 1,
+ "MerchantText": 1,
+ "RainbowBridge": 7,
+ "SariaHint": 1,
+ "ScrubsFixedPrice": 2,
+ "ScrubsPrices": 3,
+ "SheikLAHint": 0,
+ "Shopsanity": 1,
+ "ShopsanityCount": 7,
+ "ShopsanityPrices": 2,
+ "ShuffleAdultTrade": 1,
+ "ShuffleBossEntrances": 2,
+ "ShuffleCows": 1,
+ "ShuffleDekuNutBag": 1,
+ "ShuffleDekuStickBag": 1,
+ "ShuffleDungeonsEntrances": 2,
+ "ShuffleFrogSongRupees": 1,
+ "ShuffleGanonBossKey": 9,
+ "ShuffleGerudoToken": 1,
+ "ShuffleKeyRings": 2,
+ "ShuffleKeyRingsRandomCount": 4,
+ "ShuffleKokiriSword": 1,
+ "ShuffleMasterSword": 1,
+ "ShuffleMerchants": 3,
+ "ShuffleOcarinas": 1,
+ "ShuffleOverworldSpawns": 1,
+ "ShuffleScrubs": 2,
+ "ShuffleSongs": 2,
+ "ShuffleSwim": 1,
+ "ShuffleTokens": 3,
+ "SkipChildZelda": 1,
+ "SkipEponaRace": 1,
+ "SkipScarecrowsSong": 1,
+ "StartingAge": 2,
+ "StartingMapsCompasses": 0,
+ "SunlightArrows": 1
+ }
+ }
+ },
+ "presetName": "Rando Advanced",
+ "isBuiltIn": true
+} \ No newline at end of file
diff --git a/soh/assets/custom/presets/Rando Beginner.json b/soh/assets/custom/presets/Rando Beginner.json
new file mode 100644
index 000000000..595734fe0
--- /dev/null
+++ b/soh/assets/custom/presets/Rando Beginner.json
@@ -0,0 +1,51 @@
+{
+ "blocks": {
+ "rando": {
+ "gRandoSettings": {
+ "10GSHint": 1,
+ "20GSHint": 1,
+ "30GSHint": 1,
+ "40GSHint": 1,
+ "50GSHint": 1,
+ "BigPoeTargetCount": 1,
+ "BiggoronHint": 1,
+ "BlueFireArrows": 1,
+ "BossKeysanity": 2,
+ "ClosedForest": 2,
+ "CompleteMaskQuest": 1,
+ "CuccosToReturn": 1,
+ "DampeHint": 1,
+ "DoorOfTime": 2,
+ "EnableBombchuDrops": 1,
+ "ExcludedLocations": "147,148,233,323,",
+ "FortressCarpenters": 1,
+ "FrogsHint": 1,
+ "FullWallets": 1,
+ "GanonTrial": 0,
+ "GregHint": 1,
+ "HBAHint": 1,
+ "IncludeTycoonWallet": 1,
+ "KakarikoGate": 1,
+ "Keysanity": 2,
+ "LacsRewardCount": 6,
+ "MalonHint": 1,
+ "MerchantText": 1,
+ "RainbowBridge": 7,
+ "SariaHint": 1,
+ "SheikLAHint": 0,
+ "ShuffleGanonBossKey": 9,
+ "ShuffleOcarinas": 1,
+ "SkipChildZelda": 1,
+ "SkipEponaRace": 1,
+ "SkipScarecrowsSong": 1,
+ "StartingKokiriSword": 1,
+ "StartingMapsCompasses": 0,
+ "StartingOcarina": 1,
+ "SunlightArrows": 1,
+ "ZorasFountain": 1
+ }
+ }
+ },
+ "presetName": "Rando Beginner",
+ "isBuiltIn": true
+} \ No newline at end of file
diff --git a/soh/assets/custom/presets/Rando Default.json b/soh/assets/custom/presets/Rando Default.json
new file mode 100644
index 000000000..f5c5818e9
--- /dev/null
+++ b/soh/assets/custom/presets/Rando Default.json
@@ -0,0 +1,9 @@
+{
+ "blocks": {
+ "rando": {
+ "gRandoSettings": null
+ }
+ },
+ "presetName": "Rando Default",
+ "isBuiltIn": true
+} \ No newline at end of file
diff --git a/soh/assets/custom/presets/Rando Hell Mode.json b/soh/assets/custom/presets/Rando Hell Mode.json
new file mode 100644
index 000000000..d42727127
--- /dev/null
+++ b/soh/assets/custom/presets/Rando Hell Mode.json
@@ -0,0 +1,80 @@
+{
+ "blocks": {
+ "rando": {
+ "gRandoSettings": {
+ "BigPoeTargetCount": 1,
+ "BlueFireArrows": 1,
+ "BombchuBag": 1,
+ "BossKeysanity": 5,
+ "ClosedForest": 2,
+ "CuccosToReturn": 1,
+ "DecoupleEntrances": 1,
+ "DoorOfTime": 2,
+ "EnableBombchuDrops": 1,
+ "Fishsanity": 4,
+ "FishsanityAgeSplit": 1,
+ "FishsanityPondCount": 17,
+ "GerudoKeys": 3,
+ "IncludeTycoonWallet": 1,
+ "KakarikoGate": 1,
+ "Keysanity": 5,
+ "LacsRewardCount": 10,
+ "LacsRewardOptions": 1,
+ "LockOverworldDoors": 1,
+ "MixBosses": 1,
+ "MixDungeons": 1,
+ "MixGrottos": 1,
+ "MixInteriors": 1,
+ "MixOverworld": 1,
+ "MixedEntrances": 1,
+ "RainbowBridge": 7,
+ "ScrubsPrices": 2,
+ "Shopsanity": 1,
+ "ShopsanityCount": 7,
+ "ShopsanityPrices": 2,
+ "Shuffle100GSReward": 1,
+ "ShuffleAdultTrade": 1,
+ "ShuffleBeehives": 1,
+ "ShuffleBossEntrances": 2,
+ "ShuffleBossSouls": 2,
+ "ShuffleChildWallet": 1,
+ "ShuffleCows": 1,
+ "ShuffleCrates": 3,
+ "ShuffleDekuNutBag": 1,
+ "ShuffleDekuStickBag": 1,
+ "ShuffleDungeonsEntrances": 2,
+ "ShuffleFairies": 1,
+ "ShuffleFishingPole": 1,
+ "ShuffleFreestanding": 3,
+ "ShuffleFrogSongRupees": 1,
+ "ShuffleGanonBossKey": 9,
+ "ShuffleGerudoToken": 1,
+ "ShuffleGrass": 3,
+ "ShuffleGrottosEntrances": 1,
+ "ShuffleInteriorsEntrances": 2,
+ "ShuffleKokiriSword": 1,
+ "ShuffleMasterSword": 1,
+ "ShuffleMerchants": 3,
+ "ShuffleOcarinaButtons": 1,
+ "ShuffleOcarinas": 1,
+ "ShuffleOverworldEntrances": 1,
+ "ShuffleOverworldSpawns": 1,
+ "ShuffleOwlDrops": 1,
+ "ShufflePots": 3,
+ "ShuffleScrubs": 2,
+ "ShuffleSongs": 2,
+ "ShuffleSwim": 1,
+ "ShuffleTokens": 3,
+ "ShuffleWarpSongs": 1,
+ "ShuffleWeirdEgg": 1,
+ "SkipEponaRace": 1,
+ "StartingAge": 2,
+ "StartingHearts": 0,
+ "StartingMapsCompasses": 5,
+ "SunlightArrows": 1
+ }
+ }
+ },
+ "presetName": "Rando Hell Mode",
+ "isBuiltIn": true
+} \ No newline at end of file
diff --git a/soh/assets/custom/presets/Rando Standard.json b/soh/assets/custom/presets/Rando Standard.json
new file mode 100644
index 000000000..ad91912de
--- /dev/null
+++ b/soh/assets/custom/presets/Rando Standard.json
@@ -0,0 +1,63 @@
+{
+ "blocks": {
+ "rando": {
+ "gRandoSettings": {
+ "10GSHint": 1,
+ "20GSHint": 1,
+ "30GSHint": 1,
+ "40GSHint": 1,
+ "50GSHint": 1,
+ "BigPoeTargetCount": 1,
+ "BiggoronHint": 1,
+ "BlueFireArrows": 1,
+ "BombchuBag": 1,
+ "BossKeysanity": 2,
+ "ClosedForest": 2,
+ "CompleteMaskQuest": 1,
+ "CuccosToReturn": 1,
+ "DampeHint": 1,
+ "DoorOfTime": 2,
+ "EnableBombchuDrops": 1,
+ "FortressCarpenters": 1,
+ "FrogsHint": 1,
+ "FullWallets": 1,
+ "GanonTrial": 0,
+ "GregHint": 1,
+ "HBAHint": 1,
+ "IncludeTycoonWallet": 1,
+ "KakarikoGate": 1,
+ "Keysanity": 5,
+ "LacsRewardCount": 7,
+ "MalonHint": 1,
+ "MerchantText": 1,
+ "RainbowBridge": 7,
+ "SariaHint": 1,
+ "ScrubsFixedPrice": 2,
+ "ScrubsPrices": 3,
+ "SheikLAHint": 0,
+ "Shopsanity": 1,
+ "ShopsanityCount": 4,
+ "ShopsanityPrices": 2,
+ "ShuffleGanonBossKey": 9,
+ "ShuffleGerudoToken": 1,
+ "ShuffleKeyRings": 2,
+ "ShuffleKeyRingsRandomCount": 8,
+ "ShuffleKokiriSword": 1,
+ "ShuffleMerchants": 1,
+ "ShuffleOcarinas": 1,
+ "ShuffleScrubs": 2,
+ "ShuffleSongs": 2,
+ "ShuffleTokens": 3,
+ "SkipChildZelda": 1,
+ "SkipEponaRace": 1,
+ "SkipScarecrowsSong": 1,
+ "StartingMapsCompasses": 0,
+ "StartingOcarina": 1,
+ "SunlightArrows": 1,
+ "ZorasFountain": 1
+ }
+ }
+ },
+ "presetName": "Rando Standard",
+ "isBuiltIn": true
+} \ No newline at end of file
diff --git a/soh/soh/Enhancements/Presets/PresetEntries.cpp b/soh/soh/Enhancements/Presets/PresetEntries.cpp
deleted file mode 100644
index d94323d08..000000000
--- a/soh/soh/Enhancements/Presets/PresetEntries.cpp
+++ /dev/null
@@ -1,650 +0,0 @@
-#include "Presets.h"
-#include <map>
-#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 }
-
-// TODO: Ideally everything in this file will come from one/many JSON files
-
-// Enhancement presets
-const std::vector<PresetEntry> vanillaPlusPresetEntries = {
- // Quality of Life
- PRESET_ENTRY_S32(CVAR_ENHANCEMENT("Autosave"), 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("BetterOwl"), 1),
-
- // Skips & Speed-ups
- 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("TimeFlowFileSelect"), 1),
- PRESET_ENTRY_S32(CVAR_ENHANCEMENT("WidescreenActorCulling"), 1),
-
- // Items
- PRESET_ENTRY_S32(CVAR_ENHANCEMENT("DpadEquips"), 1),
- PRESET_ENTRY_S32(CVAR_ENHANCEMENT("AssignableTunicsAndBoots"), 1),
- PRESET_ENTRY_S32(CVAR_ENHANCEMENT("DpadNoDropOcarinaInput"), 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("EnemySpawnsOverWaterboxes"), 1),
- PRESET_ENTRY_S32(CVAR_ENHANCEMENT("FixSawSoftlock"), 1), PRESET_ENTRY_S32(CVAR_ENHANCEMENT("DekuNutUpgradeFix"), 1),
- PRESET_ENTRY_S32(CVAR_ENHANCEMENT("FixBrokenGiantsKnife"), 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("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),
-
- // Difficulty
- // NONE
-
- // Minigames
- PRESET_ENTRY_S32(CVAR_ENHANCEMENT("CustomizeFrogsOcarinaGame"), 1),
- PRESET_ENTRY_S32(CVAR_ENHANCEMENT("FrogsModifyFailTime"), 2),
-
- // Extra Modes
- // NONE
-
- // Cheats
- // NONE
-};
-
-const std::vector<PresetEntry> enhancedPresetEntries = {
- // Quality of Life
- 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("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("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("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("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("BetterAmmoRendering"), 1),
- PRESET_ENTRY_S32(CVAR_ENHANCEMENT("TimeFlowFileSelect"), 1),
- PRESET_ENTRY_S32(CVAR_ENHANCEMENT("WidescreenActorCulling"), 1),
- PRESET_ENTRY_S32(CVAR_ENHANCEMENT("ExtendedCullingExcludeGlitchActors"), 1),
-
- // Items
- PRESET_ENTRY_S32(CVAR_ENHANCEMENT("DpadEquips"), 1),
- PRESET_ENTRY_S32(CVAR_ENHANCEMENT("AssignableTunicsAndBoots"), 1),
- 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("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),
-
- // 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("EnemySpawnsOverWaterboxes"), 1),
- PRESET_ENTRY_S32(CVAR_ENHANCEMENT("FixSawSoftlock"), 1), PRESET_ENTRY_S32(CVAR_ENHANCEMENT("DekuNutUpgradeFix"), 1),
- PRESET_ENTRY_S32(CVAR_ENHANCEMENT("FixBrokenGiantsKnife"), 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("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),
-
- // Difficulty
- PRESET_ENTRY_S32(CVAR_ENHANCEMENT("EnableBombchuDrops"), 1), PRESET_ENTRY_S32(CVAR_ENHANCEMENT("DampeWin"), 1),
-
- // Minigames
- PRESET_ENTRY_S32(CVAR_ENHANCEMENT("CustomizeFrogsOcarinaGame"), 1),
- PRESET_ENTRY_S32(CVAR_ENHANCEMENT("FrogsModifyFailTime"), 2),
- PRESET_ENTRY_S32(CVAR_ENHANCEMENT("CustomizeOcarinaGame"), 1),
- PRESET_ENTRY_S32(CVAR_ENHANCEMENT("OcarinaGame.StartingNotes"), 5),
- PRESET_ENTRY_S32(CVAR_ENHANCEMENT("CustomizeFishing"), 1),
- PRESET_ENTRY_S32(CVAR_ENHANCEMENT("GuaranteeFishingBite"), 1),
- PRESET_ENTRY_S32(CVAR_ENHANCEMENT("FishNeverEscape"), 1),
-
- // Extra Modes
- // NONE
-
- // Cheats
- // NONE
-};
-
-const std::vector<PresetEntry> randomizerPresetEntries = {
- // Quality of Life
- PRESET_ENTRY_S32(CVAR_ENHANCEMENT("Autosave"), 1),
- PRESET_ENTRY_S32(CVAR_ENHANCEMENT("DayGravePull"), 1),
- PRESET_ENTRY_S32(CVAR_ENHANCEMENT("DampeAllNight"), 1),
- PRESET_ENTRY_S32(CVAR_ENHANCEMENT("MarketSneak"), 1),
- PRESET_ENTRY_S32(CVAR_ENHANCEMENT("PauseWarp"), 1),
- PRESET_ENTRY_S32(CVAR_ENHANCEMENT("NoInputForCredits"), 1),
- PRESET_ENTRY_S32(CVAR_ENHANCEMENT("IncludeHeldInputsBufferWindow"), 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("TimeSavers.SleepingWaterfall"), 1),
-
- // Skips & Speed-ups
- PRESET_ENTRY_S32(CVAR_ENHANCEMENT("TimeSavers.SkipCutscene.Intro"), 1),
- PRESET_ENTRY_S32(CVAR_ENHANCEMENT("TimeSavers.SkipCutscene.Entrances"), 1),
- PRESET_ENTRY_S32(CVAR_ENHANCEMENT("TimeSavers.SkipCutscene.Story"), 1),
- PRESET_ENTRY_S32(CVAR_ENHANCEMENT("TimeSavers.SkipCutscene.LearnSong"), 1),
- PRESET_ENTRY_S32(CVAR_ENHANCEMENT("TimeSavers.SkipCutscene.BossIntro"), 1),
- PRESET_ENTRY_S32(CVAR_ENHANCEMENT("TimeSavers.SkipCutscene.QuickBossDeaths"), 1),
- PRESET_ENTRY_S32(CVAR_ENHANCEMENT("TimeSavers.SkipCutscene.OnePoint"), 1),
- PRESET_ENTRY_S32(CVAR_ENHANCEMENT("TimeSavers.SkipOwlInteractions"), 1),
- PRESET_ENTRY_S32(CVAR_ENHANCEMENT("TimeSavers.SkipMiscInteractions"), 1),
- PRESET_ENTRY_S32(CVAR_ENHANCEMENT("TimeSavers.DisableTitleCard"), 1),
- PRESET_ENTRY_S32(CVAR_ENHANCEMENT("FastDrops"), 1),
- PRESET_ENTRY_S32(CVAR_ENHANCEMENT("TimeSavers.SkipForcedDialog"), FORCED_DIALOG_SKIP_ALL),
- 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("FastChests"), 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("TimeSavers.SkipChildStealth"), 1),
- PRESET_ENTRY_S32(CVAR_ENHANCEMENT("TimeSavers.SkipTowerEscape"), 1),
- PRESET_ENTRY_S32(CVAR_ENHANCEMENT("InstantScarecrow"), 1),
- PRESET_ENTRY_S32(CVAR_ENHANCEMENT("FasterRupeeAccumulator"), 1),
- PRESET_ENTRY_S32(CVAR_ENHANCEMENT("SkipSaveConfirmation"), 1),
- PRESET_ENTRY_S32(CVAR_ENHANCEMENT("ForgeTime"), 0),
-
- // Graphics
- 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("FileSelectMoreInfo"), 1),
- PRESET_ENTRY_S32(CVAR_ENHANCEMENT("BetterAmmoRendering"), 1),
- PRESET_ENTRY_S32(CVAR_ENHANCEMENT("TimeFlowFileSelect"), 1),
- PRESET_ENTRY_S32(CVAR_ENHANCEMENT("WidescreenActorCulling"), 1),
- PRESET_ENTRY_S32(CVAR_ENHANCEMENT("ExtendedCullingExcludeGlitchActors"), 1),
-
- // Items
- PRESET_ENTRY_S32(CVAR_ENHANCEMENT("DpadEquips"), 1),
- PRESET_ENTRY_S32(CVAR_ENHANCEMENT("AssignableTunicsAndBoots"), 1),
- PRESET_ENTRY_S32(CVAR_ENHANCEMENT("EquipmentCanBeRemoved"), 1),
- PRESET_ENTRY_S32(CVAR_ENHANCEMENT("ToggleStrength"), 1),
- PRESET_ENTRY_S32(CVAR_ENHANCEMENT("SwordToggle"), SWORD_TOGGLE_CHILD),
- 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("AdultMasks"), 1),
- PRESET_ENTRY_S32(CVAR_ENHANCEMENT("PersistentMasks"), 1),
- PRESET_ENTRY_S32(CVAR_ENHANCEMENT("MaskSelect"), 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),
-
- // 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("EnemySpawnsOverWaterboxes"), 1),
- PRESET_ENTRY_S32(CVAR_ENHANCEMENT("FixSawSoftlock"), 1),
- PRESET_ENTRY_S32(CVAR_ENHANCEMENT("DekuNutUpgradeFix"), 1),
- PRESET_ENTRY_S32(CVAR_ENHANCEMENT("FixBrokenGiantsKnife"), 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("GerudoWarriorClothingFix"), 1),
- PRESET_ENTRY_S32(CVAR_ENHANCEMENT("FixTexturesOOB"), 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),
-
- // Difficulty
- PRESET_ENTRY_S32(CVAR_ENHANCEMENT("GoronPot"), 1),
- PRESET_ENTRY_S32(CVAR_ENHANCEMENT("DampeWin"), 1),
-
- // Minigames
- PRESET_ENTRY_S32(CVAR_ENHANCEMENT("CustomizeFrogsOcarinaGame"), 1),
- PRESET_ENTRY_S32(CVAR_ENHANCEMENT("FrogsModifyFailTime"), 2),
- PRESET_ENTRY_S32(CVAR_ENHANCEMENT("CustomizeOcarinaGame"), 1),
- PRESET_ENTRY_S32(CVAR_ENHANCEMENT("OcarinaGame.StartingNotes"), 5),
- PRESET_ENTRY_S32(CVAR_ENHANCEMENT("CustomizeFishing"), 1),
- PRESET_ENTRY_S32(CVAR_ENHANCEMENT("GuaranteeFishingBite"), 1),
- PRESET_ENTRY_S32(CVAR_ENHANCEMENT("FishNeverEscape"), 1),
- PRESET_ENTRY_S32(CVAR_ENHANCEMENT("MinimumFishWeightChild"), 3),
- PRESET_ENTRY_S32(CVAR_ENHANCEMENT("MinimumFishWeightAdult"), 6),
-
- // Extra Modes
- // NONE
-
- // Cheats
- PRESET_ENTRY_S32(CVAR_CHEAT("EasyFrameAdvance"), 1),
-};
-
-// Randomizer presets
-const std::vector<PresetEntry> randomizerBeginnerPresetEntries = {
- // World tab
- PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("ClosedForest"), RO_CLOSED_FOREST_OFF),
- PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("KakarikoGate"), 1),
- PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("DoorOfTime"), 2),
- PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("ZorasFountain"), 1),
- PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("RainbowBridge"), RO_BRIDGE_GREG),
- PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("GanonTrial"), RO_GANONS_TRIALS_SKIP),
- PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("FortressCarpenters"), 1),
-
- // Items tab
- PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("IncludeTycoonWallet"), 1),
- PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("ShuffleOcarinas"), 1),
- PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("StartingMapsCompasses"), RO_DUNGEON_ITEM_LOC_STARTWITH),
- PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("Keysanity"), RO_DUNGEON_ITEM_LOC_OWN_DUNGEON),
- PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("BossKeysanity"), RO_DUNGEON_ITEM_LOC_OWN_DUNGEON),
- PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("ShuffleGanonBossKey"), RO_GANON_BOSS_KEY_LACS_REWARDS),
- PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("LacsRewardCount"), 6),
-
- // Gamplay tab
- PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("CuccosToReturn"), 1),
- PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("BigPoeTargetCount"), 1),
- PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("SkipChildZelda"), 1),
- PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("SkipEponaRace"), 1),
- PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("CompleteMaskQuest"), 1),
- 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("SariaHint"), 1),
- PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("FrogsHint"), 1),
- PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("BiggoronHint"), 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("10GSHint"), 1),
- PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("20GSHint"), 1),
- PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("30GSHint"), 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("EnableBombchuDrops"), 1),
- PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("BlueFireArrows"), 1),
- PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("SunlightArrows"), 1),
-
- // Locations tab
- PRESET_ENTRY_STRING(CVAR_RANDOMIZER_SETTING("ExcludedLocations"), "147,148,233,323,"),
-
- // Tricks/Glitches tab
- // NONE
-
- // Starting inventory tab
- PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("StartingKokiriSword"), RO_STARTING_OCARINA_FAIRY),
- PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("StartingOcarina"), RO_STARTING_OCARINA_FAIRY),
-};
-
-const std::vector<PresetEntry> randomizerStandardPresetEntries = {
- // World tab
- PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("ClosedForest"), RO_CLOSED_FOREST_OFF),
- PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("KakarikoGate"), 1),
- PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("DoorOfTime"), 2),
- PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("ZorasFountain"), 1),
- PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("RainbowBridge"), RO_BRIDGE_GREG),
- PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("GanonTrial"), RO_GANONS_TRIALS_SKIP),
- PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("FortressCarpenters"), 1),
-
- // Items tab
- PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("ShuffleSongs"), RO_SONG_SHUFFLE_ANYWHERE),
- PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("ShuffleTokens"), RO_TOKENSANITY_ALL),
- PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("ShuffleKokiriSword"), 1),
- PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("IncludeTycoonWallet"), 1),
- PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("ShuffleOcarinas"), 1),
- PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("ShuffleGerudoToken"), 1),
- PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("Shopsanity"), RO_SHOPSANITY_SPECIFIC_COUNT),
- PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("ShopsanityCount"), 4),
- PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("ShopsanityPrices"), RO_PRICE_BALANCED),
- PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("ShuffleScrubs"), RO_SCRUBS_ALL),
- PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("ScrubsPrices"), RO_PRICE_FIXED),
- PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("ScrubsFixedPrice"), 2),
- PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("ShuffleMerchants"), RO_SHUFFLE_MERCHANTS_BEANS_ONLY),
- PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("StartingMapsCompasses"), RO_DUNGEON_ITEM_LOC_STARTWITH),
- PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("Keysanity"), RO_DUNGEON_ITEM_LOC_ANYWHERE),
- PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("BossKeysanity"), RO_DUNGEON_ITEM_LOC_OWN_DUNGEON),
- PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("ShuffleGanonBossKey"), RO_GANON_BOSS_KEY_LACS_REWARDS),
- PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("LacsRewardCount"), 7),
- PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("ShuffleKeyRings"), RO_KEYRINGS_COUNT),
- PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("ShuffleKeyRingsRandomCount"), 8),
-
- // Gamplay tab
- PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("CuccosToReturn"), 1),
- PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("BigPoeTargetCount"), 1),
- PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("SkipChildZelda"), 1),
- PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("SkipEponaRace"), 1),
- PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("CompleteMaskQuest"), 1),
- 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("SariaHint"), 1),
- PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("FrogsHint"), 1),
- PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("BiggoronHint"), 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("10GSHint"), 1),
- PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("20GSHint"), 1),
- PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("30GSHint"), 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),
- PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("EnableBombchuDrops"), 1),
- PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("BlueFireArrows"), 1),
- PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("SunlightArrows"), 1),
-
- // Locations tab
- // NONE
-
- // Tricks/Glitches tab
- // NONE
-
- // Starting inventory tab
- PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("StartingOcarina"), RO_STARTING_OCARINA_FAIRY),
-};
-
-const std::vector<PresetEntry> randomizerAdvancedPresetEntries = {
- // World tab
- PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("ClosedForest"), RO_CLOSED_FOREST_OFF),
- PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("KakarikoGate"), 1),
- PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("DoorOfTime"), 2),
- PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("RainbowBridge"), RO_BRIDGE_GREG),
- PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("StartingAge"), RO_AGE_RANDOM),
- PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("GanonTrial"), RO_GANONS_TRIALS_SKIP),
- PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("FortressCarpenters"), 1),
- PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("ShuffleDungeonsEntrances"), RO_DUNGEON_ENTRANCE_SHUFFLE_ON_PLUS_GANON),
- PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("ShuffleBossEntrances"), RO_BOSS_ROOM_ENTRANCE_SHUFFLE_FULL),
- PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("ShuffleOverworldSpawns"), 1),
-
- // Items tab
- PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("ShuffleSongs"), RO_SONG_SHUFFLE_ANYWHERE),
- PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("ShuffleTokens"), RO_TOKENSANITY_ALL),
- PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("ShuffleKokiriSword"), 1),
- PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("ShuffleMasterSword"), 1),
- PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("IncludeTycoonWallet"), 1),
- PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("ShuffleOcarinas"), 1),
- PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("ShuffleSwim"), 1),
- PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("ShuffleGerudoToken"), 1),
- PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("ShuffleDekuNutBag"), 1),
- PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("ShuffleDekuStickBag"), 1),
- PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("Shopsanity"), RO_SHOPSANITY_SPECIFIC_COUNT),
- PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("ShopsanityCount"), 7),
- PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("ShopsanityPrices"), RO_PRICE_BALANCED),
- PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("ShuffleScrubs"), RO_SCRUBS_ALL),
- PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("ScrubsPrices"), RO_PRICE_FIXED),
- PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("ScrubsFixedPrice"), 2),
- PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("ShuffleCows"), 1),
- PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("ShuffleMerchants"), RO_SHUFFLE_MERCHANTS_ALL),
- PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("ShuffleFrogSongRupees"), 1),
- PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("ShuffleAdultTrade"), 1),
- PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("StartingMapsCompasses"), RO_DUNGEON_ITEM_LOC_STARTWITH),
- PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("Keysanity"), RO_DUNGEON_ITEM_LOC_ANYWHERE),
- PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("GerudoKeys"), RO_GERUDO_KEYS_ANYWHERE),
- PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("BossKeysanity"), RO_DUNGEON_ITEM_LOC_ANYWHERE),
- PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("ShuffleGanonBossKey"), RO_GANON_BOSS_KEY_LACS_REWARDS),
- PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("LacsRewardCount"), 8),
- PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("ShuffleKeyRings"), RO_KEYRINGS_COUNT),
- PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("ShuffleKeyRingsRandomCount"), 4),
-
- // Gamplay tab
- PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("CuccosToReturn"), 1),
- PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("BigPoeTargetCount"), 1),
- PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("SkipChildZelda"), 1),
- PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("SkipEponaRace"), 1),
- PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("CompleteMaskQuest"), 1),
- 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("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("MerchantText"), 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),
- PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("EnableBombchuDrops"), 1),
- PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("BlueFireArrows"), 1),
- PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("SunlightArrows"), 1),
-
- // Locations tab
- // NONE
-
- // Tricks/Glitches tab
- // NONE
-
- // Starting inventory tab
- // NONE
-};
-
-const std::vector<PresetEntry> hellModePresetEntries = {
- // World tab
- PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("ClosedForest"), RO_CLOSED_FOREST_OFF),
- PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("KakarikoGate"), 1),
- PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("DoorOfTime"), 2),
- PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("LockOverworldDoors"), 1),
- PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("RainbowBridge"), RO_BRIDGE_GREG),
- PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("StartingAge"), RO_AGE_RANDOM),
- PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("ShuffleDungeonsEntrances"), RO_DUNGEON_ENTRANCE_SHUFFLE_ON_PLUS_GANON),
- PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("ShuffleBossEntrances"), RO_BOSS_ROOM_ENTRANCE_SHUFFLE_FULL),
- PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("ShuffleOverworldEntrances"), 1),
- PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("ShuffleInteriorsEntrances"), RO_INTERIOR_ENTRANCE_SHUFFLE_ALL),
- PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("ShuffleGrottosEntrances"), 1),
- PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("ShuffleOwlDrops"), 1),
- PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("ShuffleWarpSongs"), 1),
- PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("ShuffleOverworldSpawns"), 1),
- PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("MixedEntrances"), 1),
- PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("MixDungeons"), 1),
- PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("MixBosses"), 1),
- PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("MixOverworld"), 1),
- PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("MixInteriors"), 1),
- PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("MixGrottos"), 1),
- PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("DecoupleEntrances"), 1),
-
- // Items tab
- PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("ShuffleSongs"), RO_SONG_SHUFFLE_ANYWHERE),
- PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("ShuffleTokens"), RO_TOKENSANITY_ALL),
- PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("ShuffleKokiriSword"), 1),
- PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("ShuffleMasterSword"), 1),
- PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("ShuffleChildWallet"), 1),
- PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("IncludeTycoonWallet"), 1),
- PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("ShuffleOcarinas"), 1),
- PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("ShuffleOcarinaButtons"), 1),
- PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("ShuffleSwim"), 1),
- PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("ShuffleWeirdEgg"), 1),
- PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("ShuffleGerudoToken"), 1),
- PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("ShuffleFishingPole"), 1),
- PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("ShuffleDekuNutBag"), 1),
- PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("ShuffleDekuStickBag"), 1),
- PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("ShuffleFreestanding"), RO_SHUFFLE_FREESTANDING_ALL),
- PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("Shopsanity"), RO_SHOPSANITY_SPECIFIC_COUNT),
- PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("ShopsanityCount"), 7),
- PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("ShopsanityPrices"), RO_PRICE_BALANCED),
- PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("Fishsanity"), RO_FISHSANITY_BOTH),
- PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("FishsanityPondCount"), 17),
- PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("FishsanityAgeSplit"), 1),
- PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("ShuffleScrubs"), RO_SCRUBS_ALL),
- PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("ScrubsPrices"), RO_PRICE_BALANCED),
- PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("ShuffleBeehives"), 1),
- PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("ShuffleCows"), 1),
- PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("ShufflePots"), RO_SHUFFLE_POTS_ALL),
- PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("ShuffleCrates"), RO_SHUFFLE_CRATES_ALL),
- PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("ShuffleMerchants"), RO_SHUFFLE_MERCHANTS_ALL),
- PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("ShuffleFrogSongRupees"), 1),
- PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("ShuffleAdultTrade"), 1),
- PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("Shuffle100GSReward"), 1),
- PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("ShuffleBossSouls"), 2),
- PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("ShuffleFairies"), 1),
- PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("ShuffleGrass"), RO_SHUFFLE_GRASS_ALL),
- PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("StartingMapsCompasses"), RO_DUNGEON_ITEM_LOC_ANYWHERE),
- PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("Keysanity"), RO_DUNGEON_ITEM_LOC_ANYWHERE),
- PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("GerudoKeys"), RO_GERUDO_KEYS_ANYWHERE),
- PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("BossKeysanity"), RO_DUNGEON_ITEM_LOC_ANYWHERE),
- PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("ShuffleGanonBossKey"), RO_GANON_BOSS_KEY_LACS_REWARDS),
- PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("LacsRewardCount"), 10),
- PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("LacsRewardOptions"), RO_LACS_GREG_REWARD),
-
- // Gamplay tab
- PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("CuccosToReturn"), 1),
- PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("BigPoeTargetCount"), 1),
- PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("SkipEponaRace"), 1),
- PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("BombchuBag"), 1),
- PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("EnableBombchuDrops"), 1),
- PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("BlueFireArrows"), 1),
- PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("SunlightArrows"), 1),
-
- // Locations tab
- // NONE
-
- // Tricks/Glitches tab
- // NONE
-
- // Starting inventory tab
- PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("StartingHearts"), 0),
-};
-
-const std::map<PresetType, PresetTypeDefinition> presetTypes = {
- { PRESET_TYPE_ENHANCEMENTS,
- { { CVAR_PREFIX_ENHANCEMENT, CVAR_PREFIX_CHEAT },
- {
- { ENHANCEMENT_PRESET_DEFAULT,
- {
- "Default",
- "Reset all options to their default values.",
- {},
- } },
- { ENHANCEMENT_PRESET_VANILLA_PLUS,
- {
- "Vanilla Plus",
- "Adds some quality of life features, but don't alter gameplay and aims to "
- "preserve the authentic experience. Recommended for a first playthrough of OoT.",
- vanillaPlusPresetEntries,
- } },
- { ENHANCEMENT_PRESET_ENHANCED,
- { "Enhanced",
- "The \"Vanilla Plus\" preset, but with more quality of life enhancements that might alter gameplay "
- "slightly. Recommended for returning players going through the vanilla game again.",
- enhancedPresetEntries } },
- { ENHANCEMENT_PRESET_RANDOMIZER,
- { "Randomizer",
- "A baseline set of enhancements for playing randomizer. Includes many quality of life options and "
- "options to speed up gameplay.",
- randomizerPresetEntries } },
- } } },
- { PRESET_TYPE_RANDOMIZER,
- { { CVAR_PREFIX_RANDOMIZER_SETTING, CVAR_PREFIX_RANDOMIZER_ENHANCEMENT },
- {
- { RANDOMIZER_PRESET_DEFAULT,
- {
- "Default",
- "Reset all options to their default values.",
- {},
- } },
- { RANDOMIZER_PRESET_BEGINNER,
- {
- "Beginner",
- "A simpler set of options and shuffled items meant for players new to the randomizer. ",
- randomizerBeginnerPresetEntries,
- } },
- { RANDOMIZER_PRESET_STANDARD,
- {
- "Standard",
- "A set of options meant as a baseline for both newer and experienced randomizer players.",
- randomizerStandardPresetEntries,
- } },
- { RANDOMIZER_PRESET_ADVANCED,
- {
- "Advanced",
- "Includes many more shuffled items and introduces some entrance shuffle options. Meant for advanced "
- "randomizer players.",
- randomizerAdvancedPresetEntries,
- } },
- { RANDOMIZER_PRESET_HELL_MODE,
- { "Hell Mode",
- "Every location randomized, all entrance settings enabled, but still using glitchless logic. Expect "
- "pain.",
- hellModePresetEntries } },
- } } }
-};
diff --git a/soh/soh/Enhancements/Presets/Presets.cpp b/soh/soh/Enhancements/Presets/Presets.cpp
index cef3f8362..b5c364251 100644
--- a/soh/soh/Enhancements/Presets/Presets.cpp
+++ b/soh/soh/Enhancements/Presets/Presets.cpp
@@ -1,63 +1,145 @@
#include "Presets.h"
#include <variant>
#include <string>
-#include <cstdint>
-#include <libultraship/bridge.h>
+#include <fstream>
+#include <config/Config.h>
+#include <libultraship/classes.h>
+#include <nlohmann/json.hpp>
#include <libultraship/libultraship.h>
+#include <Json.h>
+#include "soh/OTRGlobals.h"
#include "soh/SohGui/MenuTypes.h"
#include "soh/SohGui/SohMenu.h"
#include "soh/SohGui/SohGui.hpp"
+#include "soh/Enhancements/randomizer/randomizer_settings_window.h"
+#include "soh/Enhancements/randomizer/randomizer_check_tracker.h"
+#include "soh/Enhancements/randomizer/randomizer_entrance_tracker.h"
+#include "soh/Enhancements/randomizer/randomizer_item_tracker.h"
-std::string FormatLocations(std::vector<RandomizerCheck> locs) {
- std::string locString = "";
- for (auto loc : locs) {
- locString += std::to_string(loc) + ",";
- }
- return locString;
+namespace fs = std::filesystem;
+
+namespace SohGui {
+extern std::shared_ptr<SohMenu> mSohMenu;
+extern std::shared_ptr<RandomizerSettingsWindow> mRandomizerSettingsWindow;
+} // namespace SohGui
+
+struct PresetInfo {
+ nlohmann::json presetValues;
+ std::string fileName;
+ bool apply[PRESET_SECTION_MAX];
+ bool isBuiltIn = false;
+};
+
+struct BlockInfo {
+ std::vector<std::string> sections;
+ const char* icon;
+ std::string names[2];
+};
+
+static std::map<std::string, PresetInfo> presets;
+static std::string presetFolder;
+
+void BlankButton() {
+ ImGui::PushStyleColor(ImGuiCol_Button, { 0, 0, 0, 0 });
+ ImGui::PushStyleColor(ImGuiCol_ButtonHovered, { 0, 0, 0, 0 });
+ ImGui::PushStyleColor(ImGuiCol_ButtonActive, { 0, 0, 0, 0 });
+ ImGui::PushStyleColor(ImGuiCol_Border, { 0, 0, 0, 0 });
+ ImGui::PushStyleVar(ImGuiStyleVar_FrameRounding, 3.0f);
+ ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, ImVec2(8.0f, 8.0f));
+ ImGui::PushStyleVar(ImGuiStyleVar_FrameBorderSize, 5.0f);
+}
+
+void PresetCheckboxStyle(const ImVec4& color) {
+ ImGui::PushStyleColor(ImGuiCol_FrameBg, ImVec4(color.x, color.y, color.z, 1.0f));
+ ImGui::PushStyleColor(ImGuiCol_FrameBgHovered, ImVec4(color.x, color.y, color.z, 0.8f));
+ ImGui::PushStyleColor(ImGuiCol_FrameBgActive, ImVec4(color.x, color.y, color.z, 0.6f));
+ ImGui::PushStyleColor(ImGuiCol_Border, ImVec4(0.0f, 0.0f, 0.0f, 0.3f));
+ ImGui::PushStyleColor(ImGuiCol_CheckMark, ImVec4(1.0f, 1.0f, 1.0f, 0.7f));
+ ImGui::PushStyleVar(ImGuiStyleVar_FrameRounding, 3.0f);
+ ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, ImVec2(6.0f, 6.0f));
+ ImGui::PushStyleVar(ImGuiStyleVar_FrameBorderSize, 5.0f);
}
-void applyPreset(std::vector<PresetEntry> entries) {
- for (auto& [cvar, type, value] : entries) {
- switch (type) {
- case PRESET_ENTRY_TYPE_S32:
- CVarSetInteger(cvar, std::get<int32_t>(value));
- break;
- case PRESET_ENTRY_TYPE_FLOAT:
- CVarSetFloat(cvar, std::get<float>(value));
- break;
- case PRESET_ENTRY_TYPE_STRING:
- CVarSetString(cvar, std::get<const char*>(value));
- break;
- case PRESET_ENTRY_TYPE_CPP_STRING:
- CVarSetString(cvar, std::get<std::string>(value).c_str());
- break;
+static BlockInfo blockInfo[PRESET_SECTION_MAX] = {
+ { { CVAR_PREFIX_SETTING, CVAR_PREFIX_WINDOW }, ICON_FA_COG, { "Settings", "settings" } },
+ { { CVAR_PREFIX_ENHANCEMENT, CVAR_PREFIX_RANDOMIZER_ENHANCEMENT, CVAR_PREFIX_CHEAT },
+ ICON_FA_PLUS_CIRCLE,
+ { "Enhancements", "enhancements" } },
+ { { CVAR_PREFIX_AUDIO }, ICON_FA_MUSIC, { "Audio", "audio" } },
+ { { CVAR_PREFIX_COSMETIC }, ICON_FA_PAINT_BRUSH, { "Cosmetics", "cosmetics" } },
+ { { CVAR_PREFIX_RANDOMIZER_SETTING }, ICON_FA_RANDOM, { "Rando Settings", "rando" } },
+ { { CVAR_PREFIX_TRACKER }, ICON_FA_MAP, { "Trackers", "trackers" } },
+ { { CVAR_PREFIX_REMOTE }, ICON_FA_WIFI, { "Network", "network" } },
+};
+
+std::string FormatPresetPath(std::string name) {
+ return fmt::format("{}/{}.json", presetFolder, name);
+}
+
+void applyPreset(std::string presetName, std::vector<PresetSection> includeSections) {
+ auto& info = presets[presetName];
+ for (int i = PRESET_SECTION_SETTINGS; i < PRESET_SECTION_MAX; i++) {
+ if (info.apply[i] && info.presetValues["blocks"].contains(blockInfo[i].names[1])) {
+ if (!includeSections.empty() &&
+ std::find(includeSections.begin(), includeSections.end(), i) == includeSections.end()) {
+ continue;
+ }
+ if (i == PRESET_SECTION_TRACKERS) {
+ ItemTracker_LoadFromPreset(info.presetValues["blocks"][blockInfo[i].names[1]]["windows"]);
+ if (info.presetValues["blocks"][blockInfo[i].names[1]]["windows"].contains("Check Tracker")) {
+ CheckTracker::CheckTracker_LoadFromPreset(
+ info.presetValues["blocks"][blockInfo[i].names[1]]["windows"]["Check Tracker"]);
+ }
+ if (info.presetValues["blocks"][blockInfo[i].names[1]]["windows"].contains("Entrance Tracker")) {
+ EntranceTracker_LoadFromPreset(
+ info.presetValues["blocks"][blockInfo[i].names[1]]["windows"]["Entrance Tracker"]);
+ }
+ }
+ auto section = info.presetValues["blocks"][blockInfo[i].names[1]];
+ for (auto& item : section.items()) {
+ if (section[item.key()].is_null()) {
+ CVarClearBlock(item.key().c_str());
+ } else {
+ Ship::Context::GetInstance()->GetConfig()->SetBlock(fmt::format("{}.{}", "CVars", item.key()),
+ item.value());
+ Ship::Context::GetInstance()->GetConsoleVariables()->Load();
+ }
+ }
+ if (i == PRESET_SECTION_RANDOMIZER) {
+ SohGui::mRandomizerSettingsWindow->SetNeedsUpdate();
+ }
}
- Ship::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesNextFrame();
}
- ShipInit::Init("*");
}
-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()) {
- 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";
- comboboxTooltip += std::string(iter->second.label) + " - " + std::string(iter->second.description);
+void DrawPresetSelector(std::vector<PresetSection> includeSections, std::string presetLoc, bool disabled) {
+ std::vector<std::string> includedPresets;
+ for (auto& [name, info] : presets) {
+ for (auto& section : includeSections) {
+ if (info.apply[section]) {
+ includedPresets.push_back(name);
+ }
+ }
}
-
ImGui::Text("Presets");
+ if (includedPresets.empty()) {
+ ImGui::PushStyleColor(ImGuiCol_Text, UIWidgets::ColorValues.at(UIWidgets::Colors::Orange));
+ ImGui::Text("No presets with rando options. Make some in Settings -> Presets");
+ ImGui::PopStyleColor();
+ return;
+ }
+ std::string selectorCvar = fmt::format(CVAR_GENERAL("{}SelectedPreset"), presetLoc);
+ std::string currentIndex = CVarGetString(selectorCvar.c_str(), includedPresets[0].c_str());
+ if (!presets.contains(currentIndex)) {
+ currentIndex = *includedPresets.begin();
+ CVarSetString(selectorCvar.c_str(), currentIndex.c_str());
+ }
UIWidgets::PushStyleCombobox(THEME_COLOR);
- if (ImGui::BeginCombo("##PresetsComboBox", selectedPresetDef.label)) {
- 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);
+ if (ImGui::BeginCombo("##PresetsComboBox", currentIndex.c_str())) {
+ for (auto iter = includedPresets.begin(); iter != includedPresets.end(); ++iter) {
+ if (ImGui::Selectable(iter->c_str(), *iter == currentIndex)) {
+ CVarSetString(selectorCvar.c_str(), iter->c_str());
+ currentIndex = *iter;
Ship::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesNextFrame();
}
}
@@ -65,18 +147,300 @@ void DrawPresetSelector(PresetType presetTypeId) {
ImGui::EndCombo();
}
UIWidgets::PopStyleCombobox();
- UIWidgets::Tooltip(comboboxTooltip.c_str());
+ // UIWidgets::Tooltip(comboboxTooltip.c_str());
UIWidgets::PushStyleButton(THEME_COLOR);
- if (ImGui::Button(("Apply Preset##" + presetTypeCvar).c_str())) {
- for (const char* block : presetTypeDef.blocksToClear) {
- CVarClearBlock(block);
+ if (UIWidgets::Button(
+ ("Apply Preset##" + selectorCvar).c_str(),
+ UIWidgets::ButtonOptions({ { .disabled = disabled } }).Color(THEME_COLOR).Size(UIWidgets::Sizes::Inline))) {
+ applyPreset(currentIndex, includeSections);
+ }
+ UIWidgets::PopStyleButton();
+}
+
+void DrawSectionCheck(const std::string& name, bool empty, bool* pointer, std::string section) {
+ ImGui::AlignTextToFramePadding();
+ if (empty) {
+ ImGui::PushStyleColor(ImGuiCol_Text, { 1.0f, 0.0f, 0.0f, 0.7f });
+ BlankButton();
+ ImGui::BeginDisabled();
+ ImGui::Button((ICON_FA_TIMES + std::string("##") + name + section).c_str());
+ ImGui::EndDisabled();
+ UIWidgets::PopStyleButton();
+ ImGui::PopStyleColor();
+ } else {
+ ImGui::PushFont(OTRGlobals::Instance->fontMono);
+ ImGui::SetCursorPosY(ImGui::GetCursorPosY() + (ImGui::GetStyle().FramePadding.y));
+ UIWidgets::Checkbox(("##" + name + section).c_str(), pointer,
+ { .defaultValue = true, .padding = { 6.0f, 6.0f }, .color = THEME_COLOR });
+ ImGui::PopFont();
+ }
+}
+
+void ParsePreset(nlohmann::json& json, std::string name) {
+ try {
+ presets[json["presetName"]].presetValues = json;
+ presets[json["presetName"]].fileName = name;
+ if (json.contains("isBuiltIn")) {
+ presets[json["presetName"]].isBuiltIn = json["isBuiltIn"];
}
- if (selectedPresetId != 0) {
- applyPreset(selectedPresetDef.entries);
+ for (int i = 0; i < PRESET_SECTION_MAX; i++) {
+ if (presets[json["presetName"]].presetValues["blocks"].contains(blockInfo[i].names[1])) {
+ presets[json["presetName"]].apply[i] = true;
+ }
}
- CVarSetInteger(presetTypeCvar.c_str(), selectedPresetId);
- Ship::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesNextFrame();
+ } catch (...) {}
+}
+
+void LoadPresets() {
+ if (!fs::exists(presetFolder)) {
+ return;
+ }
+ if (!presets.empty()) {
+ presets.clear();
+ }
+ for (auto const& preset : fs::directory_iterator(presetFolder)) {
+ std::ifstream ifs(preset.path());
+
+ auto json = nlohmann::json::parse(ifs);
+ if (!json.contains("presetName")) {
+ spdlog::error(fmt::format("Attempted to load file {} as a preset, but was not a preset file.",
+ preset.path().filename().string()));
+ } else {
+ ParsePreset(json, preset.path().filename().stem().string());
+ }
+ ifs.close();
+ }
+ auto initData = std::make_shared<Ship::ResourceInitData>();
+ initData->Format = RESOURCE_FORMAT_BINARY;
+ initData->Type = static_cast<uint32_t>(Ship::ResourceType::Json);
+ initData->ResourceVersion = 0;
+ std::string folder = "presets/*";
+ auto builtIns = Ship::Context::GetInstance()->GetResourceManager()->GetArchiveManager()->ListFiles(folder);
+ size_t start = std::string(folder).size() - 1;
+ for (size_t i = 0; i < builtIns->size(); i++) {
+ std::string filePath = builtIns->at(i);
+ auto json = std::static_pointer_cast<Ship::Json>(
+ Ship::Context::GetInstance()->GetResourceManager()->LoadResource(filePath, true, initData));
+
+ std::string fileName = filePath.substr(start, filePath.size() - start - 5); // 5 for length of ".json"
+ ParsePreset(json->Data, fileName);
}
- UIWidgets::PopStyleButton();
}
+
+void SavePreset(std::string& presetName) {
+ if (!fs::exists(presetFolder)) {
+ fs::create_directory(presetFolder);
+ }
+ presets[presetName].presetValues["presetName"] = presetName;
+ std::ofstream file(
+ fmt::format("{}/{}.json", Ship::Context::GetInstance()->LocateFileAcrossAppDirs("presets"), presetName));
+ file << presets[presetName].presetValues.dump(4);
+ file.close();
+ LoadPresets();
+}
+
+static std::string newPresetName;
+static bool saveSection[PRESET_SECTION_MAX];
+
+void DrawNewPresetPopup() {
+ bool nameExists = presets.contains(newPresetName);
+ UIWidgets::InputString("Preset Name", &newPresetName,
+ UIWidgets::InputOptions()
+ .Color(THEME_COLOR)
+ .Size({ 200, 40 })
+ .ComponentAlignment(UIWidgets::ComponentAlignments::Right)
+ .LabelPosition(UIWidgets::LabelPositions::Near)
+ .ErrorText("Preset name already exists")
+ .HasError(nameExists));
+ nameExists = presets.contains(newPresetName);
+ bool noneSelected = true;
+ for (int i = PRESET_SECTION_SETTINGS; i < PRESET_SECTION_MAX; i++) {
+ if (saveSection[i]) {
+ noneSelected = false;
+ break;
+ }
+ }
+ const char* disabledTooltip =
+ (newPresetName.empty() ? "Preset name is empty"
+ : (noneSelected ? "No sections selected" : "Preset name already exists"));
+ for (int i = PRESET_SECTION_SETTINGS; i < PRESET_SECTION_MAX; i++) {
+ UIWidgets::Checkbox(fmt::format("Save {}", blockInfo[i].names[0]).c_str(), &saveSection[i],
+ UIWidgets::CheckboxOptions().Color(THEME_COLOR).Padding({ 6.0f, 6.0f }));
+ }
+ if (UIWidgets::Button(
+ "Save", UIWidgets::ButtonOptions({ { .disabled = (nameExists || noneSelected || newPresetName.empty()),
+ .disabledTooltip = disabledTooltip } })
+ .Padding({ 6.0f, 6.0f })
+ .Color(THEME_COLOR))) {
+ presets[newPresetName] = {};
+ auto config = Ship::Context::GetInstance()->GetConfig()->GetNestedJson();
+ for (int i = PRESET_SECTION_SETTINGS; i < PRESET_SECTION_MAX; i++) {
+ if (saveSection[i]) {
+ for (int j = 0; j < blockInfo[i].sections.size(); j++) {
+ presets[newPresetName].presetValues["blocks"][blockInfo[i].names[1]][blockInfo[i].sections[j]] =
+ config["CVars"][blockInfo[i].sections[j]];
+ }
+ }
+ }
+ if (saveSection[PRESET_SECTION_TRACKERS]) {
+ for (auto id : itemTrackerWindowIDs) {
+ auto window = ImGui::FindWindowByName(id);
+ if (window != nullptr) {
+ auto size = window->Size;
+ auto pos = window->Pos;
+ presets[newPresetName].presetValues["blocks"][blockInfo[PRESET_SECTION_TRACKERS].names[1]]
+ ["windows"][id]["size"]["width"] = size.x;
+ presets[newPresetName].presetValues["blocks"][blockInfo[PRESET_SECTION_TRACKERS].names[1]]
+ ["windows"][id]["size"]["height"] = size.y;
+ presets[newPresetName].presetValues["blocks"][blockInfo[PRESET_SECTION_TRACKERS].names[1]]
+ ["windows"][id]["pos"]["x"] = pos.x;
+ presets[newPresetName].presetValues["blocks"][blockInfo[PRESET_SECTION_TRACKERS].names[1]]
+ ["windows"][id]["pos"]["y"] = pos.y;
+ }
+ }
+
+ auto window = ImGui::FindWindowByName("Entrance Tracker");
+ if (window != nullptr) {
+ auto size = window->Size;
+ auto pos = window->Pos;
+ presets[newPresetName].presetValues["blocks"][blockInfo[PRESET_SECTION_TRACKERS].names[1]]["windows"]
+ ["Entrance Tracker"]["size"]["width"] = size.x;
+ presets[newPresetName].presetValues["blocks"][blockInfo[PRESET_SECTION_TRACKERS].names[1]]["windows"]
+ ["Entrance Tracker"]["size"]["height"] = size.y;
+ presets[newPresetName].presetValues["blocks"][blockInfo[PRESET_SECTION_TRACKERS].names[1]]["windows"]
+ ["Entrance Tracker"]["pos"]["x"] = pos.x;
+ presets[newPresetName].presetValues["blocks"][blockInfo[PRESET_SECTION_TRACKERS].names[1]]["windows"]
+ ["Entrance Tracker"]["pos"]["y"] = pos.y;
+ }
+
+ window = ImGui::FindWindowByName("Check Tracker");
+ if (window != nullptr) {
+ auto size = window->Size;
+ auto pos = window->Pos;
+ presets[newPresetName].presetValues["blocks"][blockInfo[PRESET_SECTION_TRACKERS].names[1]]["windows"]
+ ["Check Tracker"]["size"]["width"] = size.x;
+ presets[newPresetName].presetValues["blocks"][blockInfo[PRESET_SECTION_TRACKERS].names[1]]["windows"]
+ ["Check Tracker"]["size"]["height"] = size.y;
+ presets[newPresetName].presetValues["blocks"][blockInfo[PRESET_SECTION_TRACKERS].names[1]]["windows"]
+ ["Check Tracker"]["pos"]["x"] = pos.x;
+ presets[newPresetName].presetValues["blocks"][blockInfo[PRESET_SECTION_TRACKERS].names[1]]["windows"]
+ ["Check Tracker"]["pos"]["y"] = pos.y;
+ }
+ }
+ presets[newPresetName].fileName = newPresetName;
+ std::fill_n(presets[newPresetName].apply, PRESET_SECTION_MAX, true);
+ SavePreset(newPresetName);
+ newPresetName = "";
+ ImGui::CloseCurrentPopup();
+ }
+ if (UIWidgets::Button("Cancel", UIWidgets::ButtonOptions().Padding({ 6.0f, 6.0f }).Color(THEME_COLOR))) {
+ ImGui::CloseCurrentPopup();
+ }
+ ImGui::EndPopup();
+}
+
+void PresetsCustomWidget(WidgetInfo& info) {
+ ImGui::PushFont(OTRGlobals::Instance->fontMonoLargest);
+ if (UIWidgets::Button("New Preset", UIWidgets::ButtonOptions(
+ { { .disabled = (CVarGetInteger(CVAR_SETTING("DisableChanges"), 0) != 0),
+ .disabledTooltip = "Disabled because of race lockout" } })
+ .Size(UIWidgets::Sizes::Inline)
+ .Color(THEME_COLOR))) {
+ ImGui::OpenPopup("newPreset");
+ }
+ if (ImGui::BeginPopup("newPreset", ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_NoResize |
+ ImGuiWindowFlags_NoMove | ImGuiWindowFlags_NoScrollbar |
+ ImGuiWindowFlags_NoSavedSettings | ImGuiWindowFlags_NoTitleBar)) {
+ DrawNewPresetPopup();
+ }
+ ImGui::SameLine();
+ UIWidgets::CVarCheckbox("Hide built-in presets", CVAR_GENERAL("HideBuiltInPresets"),
+ UIWidgets::CheckboxOptions().Color(THEME_COLOR));
+ bool hideBuiltIn = CVarGetInteger(CVAR_GENERAL("HideBuiltInPresets"), 0);
+ UIWidgets::PushStyleTabs(THEME_COLOR);
+ if (ImGui::BeginTable("PresetWidgetTable", PRESET_SECTION_MAX + 3)) {
+ ImGui::TableSetupColumn("Name", ImGuiTableColumnFlags_WidthFixed, 250);
+ for (int i = PRESET_SECTION_SETTINGS; i < PRESET_SECTION_MAX; i++) {
+ ImGui::TableSetupColumn(blockInfo[i].names[0].c_str());
+ }
+ ImGui::TableSetupColumn("Apply", ImGuiTableColumnFlags_WidthFixed,
+ ImGui::CalcTextSize("Apply").x + ImGui::GetStyle().FramePadding.x * 2);
+ ImGui::TableSetupColumn("Delete", ImGuiTableColumnFlags_WidthFixed,
+ ImGui::CalcTextSize("Delete").x + ImGui::GetStyle().FramePadding.x * 2);
+ BlankButton();
+ ImGui::TableNextRow();
+ ImGui::TableNextColumn();
+ for (int i = PRESET_SECTION_SETTINGS; i < PRESET_SECTION_MAX; i++) {
+ ImGui::TableNextColumn();
+ ImGui::Button(fmt::format("{}##header{}", blockInfo[i].icon, blockInfo[i].names[1]).c_str());
+ UIWidgets::Tooltip(blockInfo[i].names[0].c_str());
+ }
+ UIWidgets::PopStyleButton();
+
+ if (presets.empty()) {
+ ImGui::TableNextRow();
+ ImGui::TableNextColumn();
+ ImGui::AlignTextToFramePadding();
+ ImGui::Text("No presets found.");
+ ImGui::EndTable();
+ UIWidgets::PopStyleTabs();
+ ImGui::PopFont();
+ return;
+ }
+ for (auto& [name, info] : presets) {
+ if (hideBuiltIn && info.isBuiltIn) {
+ continue;
+ }
+ ImGui::TableNextRow();
+ ImGui::TableNextColumn();
+ ImGui::AlignTextToFramePadding();
+ ImGui::Text(name.c_str());
+ for (int i = PRESET_SECTION_SETTINGS; i < PRESET_SECTION_MAX; i++) {
+ ImGui::TableNextColumn();
+ DrawSectionCheck(name, !info.presetValues["blocks"].contains(blockInfo[i].names[1]), &info.apply[i],
+ blockInfo[i].names[1]);
+ }
+ ImGui::TableNextColumn();
+ UIWidgets::PushStyleButton(THEME_COLOR);
+ if (UIWidgets::Button(
+ ("Apply##" + name).c_str(),
+ UIWidgets::ButtonOptions({ { .disabled = (CVarGetInteger(CVAR_SETTING("DisableChanges"), 0) != 0),
+ .disabledTooltip = "Disabled because of race lockout" } })
+ .Padding({ 6.0f, 6.0f }))) {
+ applyPreset(name);
+ }
+ UIWidgets::PopStyleButton();
+ ImGui::TableNextColumn();
+ UIWidgets::PushStyleButton(THEME_COLOR);
+ if (!info.isBuiltIn) {
+ if (UIWidgets::Button(("Delete##" + name).c_str(),
+ UIWidgets::ButtonOptions().Padding({ 6.0f, 6.0f }))) {
+ auto path = FormatPresetPath(info.fileName);
+ if (fs::exists(path)) {
+ fs::remove(path);
+ }
+ presets.erase(name);
+ UIWidgets::PopStyleButton();
+ break;
+ }
+ }
+ UIWidgets::PopStyleButton();
+ }
+
+ ImGui::EndTable();
+ }
+ ImGui::PopFont();
+ UIWidgets::PopStyleTabs();
+}
+
+void RegisterPresetsWidgets() {
+ SohGui::mSohMenu->AddSidebarEntry("Settings", "Presets", 1);
+ WidgetPath path = { "Settings", "Presets", SECTION_COLUMN_1 };
+ SohGui::mSohMenu->AddWidget(path, "PresetsWidget", WIDGET_CUSTOM).CustomFunction(PresetsCustomWidget);
+ presetFolder = Ship::Context::GetInstance()->GetPathRelativeToAppDirectory("presets");
+ std::fill_n(saveSection, PRESET_SECTION_MAX, true);
+ LoadPresets();
+}
+
+static RegisterMenuInitFunc initFunc(RegisterPresetsWidgets);
diff --git a/soh/soh/Enhancements/Presets/Presets.h b/soh/soh/Enhancements/Presets/Presets.h
index 898bc9cc9..5edb265a3 100644
--- a/soh/soh/Enhancements/Presets/Presets.h
+++ b/soh/soh/Enhancements/Presets/Presets.h
@@ -2,57 +2,17 @@
#include <string>
#include <vector>
-#include <variant>
-#include "soh/OTRGlobals.h"
-enum PresetEntryType {
- PRESET_ENTRY_TYPE_S32,
- PRESET_ENTRY_TYPE_FLOAT,
- PRESET_ENTRY_TYPE_STRING,
- PRESET_ENTRY_TYPE_CPP_STRING,
+enum PresetSection {
+ PRESET_SECTION_SETTINGS,
+ PRESET_SECTION_ENHANCEMENTS,
+ PRESET_SECTION_AUDIO,
+ PRESET_SECTION_COSMETICS,
+ PRESET_SECTION_RANDOMIZER,
+ PRESET_SECTION_TRACKERS,
+ PRESET_SECTION_NETWORK,
+ PRESET_SECTION_MAX,
};
-enum PresetType {
- PRESET_TYPE_ENHANCEMENTS,
- PRESET_TYPE_RANDOMIZER,
-};
-
-enum EnhancementPreset {
- ENHANCEMENT_PRESET_DEFAULT,
- ENHANCEMENT_PRESET_VANILLA_PLUS,
- ENHANCEMENT_PRESET_ENHANCED,
- ENHANCEMENT_PRESET_RANDOMIZER,
-};
-
-enum RandomizerPreset {
- RANDOMIZER_PRESET_DEFAULT,
- RANDOMIZER_PRESET_BEGINNER,
- RANDOMIZER_PRESET_STANDARD,
- RANDOMIZER_PRESET_ADVANCED,
- RANDOMIZER_PRESET_HELL_MODE,
-};
-
-typedef struct PresetEntry {
- const char* cvar;
- PresetEntryType type;
- std::variant<int32_t, float, const char*, std::string> value;
-} PresetEntry;
-
-std::string FormatLocations(std::vector<RandomizerCheck> locs);
-
-void DrawPresetSelector(PresetType presetType);
-void clearCvars(std::vector<const char*> cvarsToClear);
-void applyPreset(std::vector<PresetEntry> entries);
-
-typedef struct PresetDefinition {
- const char* label;
- const char* description;
- std::vector<PresetEntry> entries;
-} PresetDefinition;
-
-typedef struct PresetTypeDefinition {
- std::vector<const char*> blocksToClear;
- std::map<uint16_t, PresetDefinition> presets;
-} PresetTypeDefinition;
-
-extern const std::map<PresetType, PresetTypeDefinition> presetTypes;
+void DrawPresetSelector(std::vector<PresetSection> includeSections, std::string currentIndex, bool disabled);
+void applyPreset(std::string presetName, std::vector<PresetSection> includeSections = {});
diff --git a/soh/soh/Enhancements/randomizer/randomizer.cpp b/soh/soh/Enhancements/randomizer/randomizer.cpp
index 104dfd435..f7279ff80 100644
--- a/soh/soh/Enhancements/randomizer/randomizer.cpp
+++ b/soh/soh/Enhancements/randomizer/randomizer.cpp
@@ -26,6 +26,7 @@
#include <tuple>
#include <functional>
#include "draw.h"
+#include "soh/OTRGlobals.h"
#include "soh/SohGui/UIWidgets.hpp"
#include "static_data.h"
#include "soh/Enhancements/game-interactor/GameInteractor.h"
@@ -3643,14 +3644,8 @@ bool GenerateRandomizer(std::string seed /*= ""*/) {
return false;
}
-static const std::unordered_map<int32_t, const char*> randomizerPresetList = {
- { RANDOMIZER_PRESET_DEFAULT, "Default" },
- { RANDOMIZER_PRESET_BEGINNER, "Beginner" },
- { RANDOMIZER_PRESET_STANDARD, "Standard" },
- { RANDOMIZER_PRESET_ADVANCED, "Advanced" },
- { RANDOMIZER_PRESET_HELL_MODE, "Hell Mode" }
-};
-static int32_t randomizerPresetSelected = RANDOMIZER_PRESET_DEFAULT;
+static bool locationsTabOpen = false;
+static bool tricksTabOpen = false;
void RandomizerSettingsWindow::DrawElement() {
auto ctx = Rando::Context::GetInstance();
@@ -3658,53 +3653,12 @@ void RandomizerSettingsWindow::DrawElement() {
generated = 0;
randoThread.join();
}
- static bool locationsTabOpen = false;
- static bool tricksTabOpen = false;
- 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";
- 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))) {
- 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 (randomizerPresetSelected >= presetTypeDef.presets.size()) {
- randomizerPresetSelected = 0;
- }
- const PresetDefinition selectedPresetDef = presetTypeDef.presets.at(randomizerPresetSelected);
- for (const char* block : presetTypeDef.blocksToClear) {
- CVarClearBlock(block);
- }
- if (randomizerPresetSelected != 0) {
- applyPreset(selectedPresetDef.entries);
- }
- CVarSetInteger(presetTypeCvar.c_str(), randomizerPresetSelected);
- Ship::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesNextFrame();
- mSettings->UpdateOptionProperties();
- // force excluded location list and trick list update if tab is open.
- locationsTabOpen = false;
- tricksTabOpen = false;
- }
- ImGui::EndDisabled();
+ bool generating = CVarGetInteger(CVAR_GENERAL("RandoGenerating"), 0);
+ bool disableEditingRandoSettings = generating || CVarGetInteger(CVAR_GENERAL("OnFileSelectNameEntry"), 0);
- UIWidgets::Spacer(0);
+ DrawPresetSelector({ PRESET_SECTION_RANDOMIZER }, "Randomizer", generating);
+
+ // UIWidgets::Spacer(0);
UIWidgets::CVarCheckbox("Manual seed entry", CVAR_RANDOMIZER_SETTING("ManualSeedEntry"),
UIWidgets::CheckboxOptions().Color(THEME_COLOR));
if (CVarGetInteger(CVAR_RANDOMIZER_SETTING("ManualSeedEntry"), 0)) {
@@ -3754,10 +3708,6 @@ void RandomizerSettingsWindow::DrawElement() {
ImGui::Text("Spoiler File: %s", spoilerfilepath.c_str());
}
- // RANDOTODO settings presets
- // std::string presetfilepath = CVarGetString(CVAR_RANDOMIZER_SETTING("LoadedPreset"), "");
- // ImGui::Text("Settings File: %s", presetfilepath.c_str());
-
UIWidgets::Separator(true, true, 0.f, 0.f);
ImGuiWindow* window = ImGui::GetCurrentWindow();
@@ -4367,9 +4317,17 @@ void RandomizerSettingsWindow::DrawElement() {
UIWidgets::PopStyleTabs();
}
+void RandomizerSettingsWindow::SetNeedsUpdate() {
+ mNeedsUpdate = true;
+}
+
void RandomizerSettingsWindow::UpdateElement() {
if (mNeedsUpdate) {
+ RandomizerCheckObjects::UpdateImGuiVisibility();
mSettings->UpdateOptionProperties();
+ locationsTabOpen = false;
+ tricksTabOpen = false;
+ mNeedsUpdate = false;
}
}
diff --git a/soh/soh/Enhancements/randomizer/randomizer_check_tracker.cpp b/soh/soh/Enhancements/randomizer/randomizer_check_tracker.cpp
index c919e4c6c..52b977032 100644
--- a/soh/soh/Enhancements/randomizer/randomizer_check_tracker.cpp
+++ b/soh/soh/Enhancements/randomizer/randomizer_check_tracker.cpp
@@ -91,6 +91,10 @@ bool previousShowHidden = false;
bool hideShopUnshuffledChecks = false;
bool alwaysShowGS = false;
+static bool presetLoaded = false;
+static ImVec2 presetPos;
+static ImVec2 presetSize;
+
std::map<uint32_t, RandomizerCheck> startingShopItem = {
{ SCENE_KOKIRI_SHOP, RC_KF_SHOP_ITEM_1 },
{ SCENE_BAZAAR, RC_MARKET_BAZAAR_ITEM_1 },
@@ -979,7 +983,13 @@ void CheckTrackerWindow::DrawElement() {
}
}
- ImGui::SetNextWindowSize(ImVec2(400, 540), ImGuiCond_FirstUseEver);
+ if (presetLoaded) {
+ ImGui::SetNextWindowSize(presetSize);
+ ImGui::SetNextWindowPos(presetPos);
+ presetLoaded = false;
+ } else {
+ ImGui::SetNextWindowSize(ImVec2(400, 540), ImGuiCond_FirstUseEver);
+ }
BeginFloatWindows("Check Tracker", mIsVisible, ImGuiWindowFlags_NoScrollbar);
if (!GameInteractor::IsSaveLoaded() || !initialized) {
@@ -2000,6 +2010,12 @@ void RecalculateAvailableChecks() {
GetPerformanceTimer(PT_RECALCULATE_AVAILABLE_CHECKS).count());
}
+void CheckTracker_LoadFromPreset(nlohmann::json info) {
+ presetLoaded = true;
+ presetPos = { info["pos"]["x"], info["pos"]["y"] };
+ presetSize = { info["size"]["width"], info["size"]["height"] };
+}
+
void CheckTrackerWindow::Draw() {
if (!IsVisible()) {
return;
diff --git a/soh/soh/Enhancements/randomizer/randomizer_check_tracker.h b/soh/soh/Enhancements/randomizer/randomizer_check_tracker.h
index 7636ab063..695899bab 100644
--- a/soh/soh/Enhancements/randomizer/randomizer_check_tracker.h
+++ b/soh/soh/Enhancements/randomizer/randomizer_check_tracker.h
@@ -62,4 +62,5 @@ void UpdateAllAreas();
void RecalculateAllAreaTotals();
void SpoilAreaFromCheck(RandomizerCheck rc);
void RecalculateAvailableChecks();
+void CheckTracker_LoadFromPreset(nlohmann::json info);
} // namespace CheckTracker
diff --git a/soh/soh/Enhancements/randomizer/randomizer_entrance_tracker.cpp b/soh/soh/Enhancements/randomizer/randomizer_entrance_tracker.cpp
index eaa928705..1a635f58e 100644
--- a/soh/soh/Enhancements/randomizer/randomizer_entrance_tracker.cpp
+++ b/soh/soh/Enhancements/randomizer/randomizer_entrance_tracker.cpp
@@ -39,6 +39,10 @@ static s16 lastEntranceIndex = -1;
static s16 currentGrottoId = -1;
static s16 lastSceneOrEntranceDetected = -1;
+static bool presetLoaded = false;
+static ImVec2 presetPos;
+static ImVec2 presetSize;
+
static std::string spoilerEntranceGroupNames[] = {
"Spawns/Warp Songs/Owls",
"Kokiri Forest",
@@ -445,6 +449,12 @@ const EntranceData* GetEntranceData(s16 index) {
return nullptr;
}
+void EntranceTracker_LoadFromPreset(nlohmann::json info) {
+ presetLoaded = true;
+ presetPos = { info["pos"]["x"], info["pos"]["y"] };
+ presetSize = { info["size"]["width"], info["size"]["height"] };
+}
+
// 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
@@ -757,7 +767,13 @@ void EntranceTrackerWindow::Draw() {
}
void EntranceTrackerWindow::DrawElement() {
- ImGui::SetNextWindowSize(ImVec2(600, 375), ImGuiCond_FirstUseEver);
+ if (presetLoaded) {
+ ImGui::SetNextWindowSize(presetSize);
+ ImGui::SetNextWindowPos(presetPos);
+ presetLoaded = false;
+ } else {
+ ImGui::SetNextWindowSize(ImVec2(600, 375), ImGuiCond_FirstUseEver);
+ }
if (!ImGui::Begin("Entrance Tracker", &mIsVisible, ImGuiWindowFlags_NoFocusOnAppearing)) {
ImGui::End();
diff --git a/soh/soh/Enhancements/randomizer/randomizer_entrance_tracker.h b/soh/soh/Enhancements/randomizer/randomizer_entrance_tracker.h
index 4ee33ef62..2d2f7143c 100644
--- a/soh/soh/Enhancements/randomizer/randomizer_entrance_tracker.h
+++ b/soh/soh/Enhancements/randomizer/randomizer_entrance_tracker.h
@@ -90,6 +90,7 @@ void InitEntranceTrackingData();
s16 GetLastEntranceOverride();
s16 GetCurrentGrottoId();
const EntranceData* GetEntranceData(s16);
+void EntranceTracker_LoadFromPreset(nlohmann::json info);
class EntranceTrackerSettingsWindow final : public Ship::GuiWindow {
public:
diff --git a/soh/soh/Enhancements/randomizer/randomizer_item_tracker.cpp b/soh/soh/Enhancements/randomizer/randomizer_item_tracker.cpp
index bd26b1d44..6284d7121 100644
--- a/soh/soh/Enhancements/randomizer/randomizer_item_tracker.cpp
+++ b/soh/soh/Enhancements/randomizer/randomizer_item_tracker.cpp
@@ -375,6 +375,10 @@ uint32_t notesIdleFrames = 0;
bool notesNeedSave = false;
const uint32_t notesMaxIdleFrames = 40; // two seconds of game time, since OnGameFrameUpdate is used to tick
+static bool presetLoaded = false;
+static std::unordered_map<std::string, ImVec2> presetPos;
+static std::unordered_map<std::string, ImVec2> presetSize;
+
void ItemTrackerOnFrame() {
if (notesNeedSave && notesIdleFrames <= notesMaxIdleFrames) {
notesIdleFrames++;
@@ -398,6 +402,16 @@ bool HasEquipment(ItemTrackerItem item) {
return GameInteractor::IsSaveLoaded() ? (item.data & gSaveContext.inventory.equipment) : false;
}
+void ItemTracker_LoadFromPreset(nlohmann::json trackerInfo) {
+ presetLoaded = true;
+ for (auto window : itemTrackerWindowIDs) {
+ if (trackerInfo.contains(window)) {
+ presetPos[window] = { trackerInfo[window]["pos"]["x"], trackerInfo[window]["pos"]["y"] };
+ presetSize[window] = { trackerInfo[window]["size"]["width"], trackerInfo[window]["size"]["height"] };
+ }
+ }
+}
+
ItemTrackerNumbers GetItemCurrentAndMax(ItemTrackerItem item) {
ItemTrackerNumbers result;
result.currentCapacity = 0;
@@ -1171,6 +1185,12 @@ void BeginFloatingWindows(std::string UniqueName, ImGuiWindowFlags flags = 0) {
ImGui::PushStyleColor(ImGuiCol_WindowBg, color);
ImGui::PushStyleColor(ImGuiCol_Border, ImVec4(0, 0, 0, 0));
ImGui::PushStyleVar(ImGuiStyleVar_WindowRounding, 4.0f);
+ if (presetLoaded && presetPos.contains(UniqueName)) {
+ ImGui::SetNextWindowSize(presetSize[UniqueName]);
+ ImGui::SetNextWindowPos(presetPos[UniqueName]);
+ presetSize.erase(UniqueName);
+ presetPos.erase(UniqueName);
+ }
ImGui::Begin(UniqueName.c_str(), nullptr, windowFlags);
}
void EndFloatingWindows() {
@@ -1525,7 +1545,7 @@ void ItemTrackerWindow::DrawElement() {
SECTION_DISPLAY_EXTENDED_MAIN_WINDOW) ||
(CVarGetInteger(CVAR_TRACKER_ITEM("DisplayType.Notes"), SECTION_DISPLAY_HIDDEN) ==
SECTION_DISPLAY_MAIN_WINDOW)) {
- BeginFloatingWindows("Item Tracker##main window");
+ BeginFloatingWindows("Item Tracker");
DrawItemsInRows(mainWindowItems, 6);
if (CVarGetInteger(CVAR_TRACKER_ITEM("DisplayType.Notes"), SECTION_DISPLAY_HIDDEN) ==
@@ -1659,6 +1679,10 @@ void ItemTrackerWindow::DrawElement() {
EndFloatingWindows();
}
}
+ if (presetLoaded) {
+ shouldUpdateVectors = true;
+ presetLoaded = false;
+ }
}
static std::unordered_map<int32_t, const char*> itemTrackerCapacityTrackOptions = {
diff --git a/soh/soh/Enhancements/randomizer/randomizer_item_tracker.h b/soh/soh/Enhancements/randomizer/randomizer_item_tracker.h
index 7175baeab..85a2b63a0 100644
--- a/soh/soh/Enhancements/randomizer/randomizer_item_tracker.h
+++ b/soh/soh/Enhancements/randomizer/randomizer_item_tracker.h
@@ -25,6 +25,23 @@ bool HasEquipment(ItemTrackerItem);
#define ITEM_TRACKER_ITEM_CUSTOM(id, name, nameFaded, data, drawFunc) \
{ id, #name, #nameFaded "_Faded", data, drawFunc }
+static std::vector<const char*> itemTrackerWindowIDs = { "Item Tracker",
+ "Inventory Items Tracker",
+ "Equipment Items Tracker",
+ "Misc Items Tracker",
+ "Dungeon Rewards Tracker",
+ "Songs Tracker",
+ "Dungeon Items Tracker",
+ "Greg Tracker",
+ "Triforce Piece Tracker",
+ "Boss Soul Tracker",
+ "Ocarina Button Tracker",
+ "Overworld Key Tracker",
+ "Fishing Pole Tracker",
+ "Personal Notes",
+ "Total Checks" };
+void ItemTracker_LoadFromPreset(nlohmann::json trackerInfo);
+
typedef struct ItemTrackerDungeon {
uint32_t id;
std::vector<uint32_t> items;
diff --git a/soh/soh/Enhancements/randomizer/randomizer_settings_window.h b/soh/soh/Enhancements/randomizer/randomizer_settings_window.h
index bf1a2a740..87d830e38 100644
--- a/soh/soh/Enhancements/randomizer/randomizer_settings_window.h
+++ b/soh/soh/Enhancements/randomizer/randomizer_settings_window.h
@@ -13,6 +13,7 @@ class RandomizerSettingsWindow final : public Ship::GuiWindow {
void InitElement() override;
void DrawElement() override;
void UpdateElement() override;
+ void SetNeedsUpdate();
private:
bool mNeedsUpdate = false;
diff --git a/soh/soh/SohGui/SohMenu.h b/soh/soh/SohGui/SohMenu.h
index 1de142299..c3c3f4fd1 100644
--- a/soh/soh/SohGui/SohMenu.h
+++ b/soh/soh/SohGui/SohMenu.h
@@ -193,13 +193,6 @@ static const std::unordered_map<int32_t, const char*> bootSequenceLabels = {
{ BOOTSEQUENCE_FILESELECT, "File Select" },
};
-static const std::unordered_map<int32_t, const char*> enhancementPresetList = {
- { ENHANCEMENT_PRESET_DEFAULT, "Default" },
- { ENHANCEMENT_PRESET_VANILLA_PLUS, "Vanilla Plus" },
- { ENHANCEMENT_PRESET_ENHANCED, "Enhanced" },
- { ENHANCEMENT_PRESET_RANDOMIZER, "Randomizer" },
-};
-
class SohMenu : public Ship::Menu {
public:
SohMenu(const std::string& consoleVariable, const std::string& name);
diff --git a/soh/soh/SohGui/SohMenuEnhancements.cpp b/soh/soh/SohGui/SohMenuEnhancements.cpp
index 4785da238..4aaf1fb67 100644
--- a/soh/soh/SohGui/SohMenuEnhancements.cpp
+++ b/soh/soh/SohGui/SohMenuEnhancements.cpp
@@ -4,11 +4,9 @@
#include <soh/OTRGlobals.h>
#include <soh/Enhancements/cosmetics/authenticGfxPatches.h>
#include <soh/Enhancements/enemyrandomizer.h>
-#include <soh/Enhancements/Presets/Presets.h>
#include <soh/Enhancements/TimeDisplay/TimeDisplay.h>
static std::string comboboxTooltip = "";
-static int32_t enhancementPresetSelected = ENHANCEMENT_PRESET_DEFAULT;
bool isBetaQuestEnabled = false;
static std::unordered_map<int32_t, const char*> bunnyHoodEffectMap = {
{ BUNNY_HOOD_VANILLA, "Vanilla" },
@@ -34,51 +32,8 @@ void SohMenu::AddMenuEnhancements() {
// Add Enhancements Menu
AddMenuEntry("Enhancements", CVAR_SETTING("Menu.EnhancementsSidebarSection"));
- // Enhancements
- WidgetPath path = { "Enhancements", "Presets", SECTION_COLUMN_1 };
- AddSidebarEntry("Enhancements", path.sidebarName, 3);
-
- const PresetTypeDefinition presetTypeDef = presetTypes.at(PRESET_TYPE_ENHANCEMENTS);
- 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);
- }
- AddWidget(path, "Enhancement Presets", WIDGET_SEPARATOR_TEXT);
- AddWidget(path, "Select Preset", WIDGET_COMBOBOX)
- .ValuePointer(&enhancementPresetSelected)
- .Callback([](WidgetInfo& info) {
- const std::string presetTypeCvar =
- CVAR_GENERAL("SelectedPresets.") + std::to_string(PRESET_TYPE_ENHANCEMENTS);
- CVarSetInteger(presetTypeCvar.c_str(), *std::get<int32_t*>(info.valuePointer));
- })
- .Options(ComboboxOptions()
- .ComboMap(enhancementPresetList)
- .DefaultIndex(ENHANCEMENT_PRESET_DEFAULT)
- .Tooltip(comboboxTooltip.c_str()));
- AddWidget(path, "Apply Preset##Enhancemnts", WIDGET_BUTTON)
- .Options(ButtonOptions().Size(UIWidgets::Sizes::Inline))
- .Callback([](WidgetInfo& info) {
- const std::string presetTypeCvar =
- CVAR_GENERAL("SelectedPresets.") + std::to_string(PRESET_TYPE_ENHANCEMENTS);
- const PresetTypeDefinition presetTypeDef = presetTypes.at(PRESET_TYPE_ENHANCEMENTS);
- uint16_t selectedPresetId = CVarGetInteger(presetTypeCvar.c_str(), 0);
- if (selectedPresetId >= presetTypeDef.presets.size()) {
- selectedPresetId = 0;
- }
- const PresetDefinition selectedPresetDef = presetTypeDef.presets.at(selectedPresetId);
- for (const char* block : presetTypeDef.blocksToClear) {
- CVarClearBlock(block);
- }
- if (selectedPresetId != 0) {
- applyPreset(selectedPresetDef.entries);
- }
- CVarSetInteger(presetTypeCvar.c_str(), selectedPresetId);
- Ship::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesNextFrame();
- });
-
// Quality of Life
- path.sidebarName = "Quality of Life";
+ WidgetPath path = { "Enhancements", "Quality of Life", SECTION_COLUMN_1 };
AddSidebarEntry("Enhancements", path.sidebarName, 3);
path.column = SECTION_COLUMN_1;
@@ -289,16 +244,16 @@ void SohMenu::AddMenuEnhancements() {
.SameLine(true)
.Options(ButtonOptions().Size(Sizes::Inline))
.Callback([](WidgetInfo& info) {
- CVarSetInteger(CVAR_ENHANCEMENT("TimeSavers.SkipCutscene.Intro"), false);
- CVarSetInteger(CVAR_ENHANCEMENT("TimeSavers.SkipCutscene.Entrances"), false);
- CVarSetInteger(CVAR_ENHANCEMENT("TimeSavers.SkipCutscene.Story"), false);
- CVarSetInteger(CVAR_ENHANCEMENT("TimeSavers.SkipCutscene.LearnSong"), false);
- CVarSetInteger(CVAR_ENHANCEMENT("TimeSavers.SkipCutscene.BossIntro"), false);
- CVarSetInteger(CVAR_ENHANCEMENT("TimeSavers.SkipCutscene.QuickBossDeaths"), false);
- CVarSetInteger(CVAR_ENHANCEMENT("TimeSavers.SkipCutscene.OnePoint"), false);
- CVarSetInteger(CVAR_ENHANCEMENT("TimeSavers.SkipOwlInteractions"), false);
- CVarSetInteger(CVAR_ENHANCEMENT("TimeSavers.SkipMiscInteractions"), false);
- CVarSetInteger(CVAR_ENHANCEMENT("TimeSavers.DisableTitleCard"), false);
+ CVarClear(CVAR_ENHANCEMENT("TimeSavers.SkipCutscene.Intro"));
+ CVarClear(CVAR_ENHANCEMENT("TimeSavers.SkipCutscene.Entrances"));
+ CVarClear(CVAR_ENHANCEMENT("TimeSavers.SkipCutscene.Story"));
+ CVarClear(CVAR_ENHANCEMENT("TimeSavers.SkipCutscene.LearnSong"));
+ CVarClear(CVAR_ENHANCEMENT("TimeSavers.SkipCutscene.BossIntro"));
+ CVarClear(CVAR_ENHANCEMENT("TimeSavers.SkipCutscene.QuickBossDeaths"));
+ CVarClear(CVAR_ENHANCEMENT("TimeSavers.SkipCutscene.OnePoint"));
+ CVarClear(CVAR_ENHANCEMENT("TimeSavers.SkipOwlInteractions"));
+ CVarClear(CVAR_ENHANCEMENT("TimeSavers.SkipMiscInteractions"));
+ CVarClear(CVAR_ENHANCEMENT("TimeSavers.DisableTitleCard"));
Ship::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesNextFrame();
});
diff --git a/soh/soh/SohGui/SohMenuNetwork.cpp b/soh/soh/SohGui/SohMenuNetwork.cpp
index 637c78285..bb6004288 100644
--- a/soh/soh/SohGui/SohMenuNetwork.cpp
+++ b/soh/soh/SohGui/SohMenuNetwork.cpp
@@ -3,6 +3,7 @@
#include <soh/Notification/Notification.h>
#include <soh/Network/Network.h>
#include "SohGui.hpp"
+#include "soh/OTRGlobals.h"
#include <soh/Network/Sail/Sail.h>
#include <soh/Network/CrowdControl/CrowdControl.h>
diff --git a/soh/soh/SohGui/SohMenuRandomizer.cpp b/soh/soh/SohGui/SohMenuRandomizer.cpp
index 8f4e6e43b..b95a8049c 100644
--- a/soh/soh/SohGui/SohMenuRandomizer.cpp
+++ b/soh/soh/SohGui/SohMenuRandomizer.cpp
@@ -1,5 +1,5 @@
#include "SohMenu.h"
-#include <macros.h>
+#include "soh/OTRGlobals.h"
namespace SohGui {
diff --git a/soh/soh/SohGui/SohMenuSettings.cpp b/soh/soh/SohGui/SohMenuSettings.cpp
index 909c647bd..23bee56dc 100644
--- a/soh/soh/SohGui/SohMenuSettings.cpp
+++ b/soh/soh/SohGui/SohMenuSettings.cpp
@@ -1,5 +1,6 @@
#include "SohMenu.h"
#include "soh/Notification/Notification.h"
+#include "soh/OTRGlobals.h"
#include <soh/GameVersions.h>
#include "soh/ResourceManagerHelpers.h"
#include "UIWidgets.hpp"
diff --git a/soh/soh/SohGui/UIWidgets.cpp b/soh/soh/SohGui/UIWidgets.cpp
index 3c4e91147..774407583 100644
--- a/soh/soh/SohGui/UIWidgets.cpp
+++ b/soh/soh/SohGui/UIWidgets.cpp
@@ -204,19 +204,19 @@ bool WindowButton(const char* label, const char* cvarName, std::shared_ptr<Ship:
return dirty;
}
-void PushStyleCheckbox(const ImVec4& color) {
+void PushStyleCheckbox(const ImVec4& color, ImVec2 padding) {
ImGui::PushStyleColor(ImGuiCol_FrameBg, ImVec4(color.x, color.y, color.z, 1.0f));
ImGui::PushStyleColor(ImGuiCol_FrameBgHovered, ImVec4(color.x, color.y, color.z, 0.8f));
ImGui::PushStyleColor(ImGuiCol_FrameBgActive, ImVec4(color.x, color.y, color.z, 0.6f));
ImGui::PushStyleColor(ImGuiCol_Border, ImVec4(0.0f, 0.0f, 0.0f, 0.3f));
ImGui::PushStyleColor(ImGuiCol_CheckMark, ImVec4(1.0f, 1.0f, 1.0f, 0.7f));
ImGui::PushStyleVar(ImGuiStyleVar_FrameRounding, 3.0f);
- ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, ImVec2(10.0f, 6.0f));
+ ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, padding);
ImGui::PushStyleVar(ImGuiStyleVar_FrameBorderSize, 5.0f);
}
-void PushStyleCheckbox(Colors color) {
- PushStyleCheckbox(ColorValues.at(color));
+void PushStyleCheckbox(Colors color, ImVec2 padding) {
+ PushStyleCheckbox(ColorValues.at(color), padding);
}
void PopStyleCheckbox() {
@@ -297,6 +297,7 @@ bool Checkbox(const char* _label, bool* value, const CheckboxOptions& options) {
const char* label = labelStr.c_str();
+ PushStyleCheckbox(options.color, options.padding);
ImGuiContext& g = *GImGui;
const ImGuiStyle& style = g.Style;
const ImGuiID id = window->GetID(label);
@@ -317,6 +318,7 @@ bool Checkbox(const char* _label, bool* value, const CheckboxOptions& options) {
ImGui::ItemSize(total_bb, style.FramePadding.y);
if (!ImGui::ItemAdd(total_bb, id)) {
+ PopStyleCheckbox();
ImGui::EndDisabled();
return false;
}
@@ -326,14 +328,13 @@ bool Checkbox(const char* _label, bool* value, const CheckboxOptions& options) {
*value = !(*value);
ImGui::MarkItemEdited(id);
}
- PushStyleCheckbox(options.color);
ImVec2 checkPos = pos;
ImVec2 labelPos = pos;
if (options.labelPosition == LabelPositions::Above) {
checkPos.y += label_size.y + (style.ItemInnerSpacing.y * 2.0f);
} else {
// Center with checkbox automatically
- labelPos.y += ImGui::CalcTextSize("g").y / 8;
+ labelPos.y += ImGui::GetStyle().FramePadding.y;
}
if (options.alignment == ComponentAlignments::Right) {
checkPos.x = total_bb.Max.x - square_sz;
@@ -762,6 +763,9 @@ bool InputString(const char* label, std::string* value, const InputOptions& opti
ImGui::BeginGroup();
ImGui::BeginDisabled(options.disabled);
PushStyleInput(options.color);
+ if (options.hasError) {
+ ImGui::PushStyleColor(ImGuiCol_Border, ColorValues.at(Colors::Red));
+ }
float width = (options.size == ImVec2(0, 0)) ? ImGui::GetContentRegionAvail().x : options.size.x;
if (options.alignment == ComponentAlignments::Left) {
if (options.labelPosition == LabelPositions::Above) {
@@ -787,11 +791,17 @@ bool InputString(const char* label, std::string* value, const InputOptions& opti
ImGui::SameLine(17.0f);
ImGui::TextColored(ImVec4(1.0f, 1.0f, 1.0f, 0.4f), "%s", options.placeholder.c_str());
}
+ if (options.hasError) {
+ ImGui::PopStyleColor();
+ }
PopStyleInput();
ImGui::EndDisabled();
ImGui::EndGroup();
- if (options.disabled && ImGui::IsItemHovered(ImGuiHoveredFlags_AllowWhenDisabled) &&
- !Ship_IsCStringEmpty(options.disabledTooltip)) {
+ if (options.hasError && ImGui::IsItemHovered(ImGuiHoveredFlags_AllowWhenDisabled) &&
+ !Ship_IsCStringEmpty(options.errorText)) {
+ ImGui::SetTooltip("%s", WrappedText(options.errorText).c_str());
+ } else if (options.disabled && ImGui::IsItemHovered(ImGuiHoveredFlags_AllowWhenDisabled) &&
+ !Ship_IsCStringEmpty(options.disabledTooltip)) {
ImGui::SetTooltip("%s", WrappedText(options.disabledTooltip).c_str());
} else if (ImGui::IsItemHovered(ImGuiHoveredFlags_AllowWhenDisabled) && !Ship_IsCStringEmpty(options.tooltip)) {
ImGui::SetTooltip("%s", WrappedText(options.tooltip).c_str());
@@ -1018,7 +1028,7 @@ bool CVarRadioButton(const char* text, const char* cvarName, int32_t id, const R
std::string make_invisible = "##" + std::string(text) + std::string(cvarName);
bool ret = false;
- int val = CVarGetInteger(cvarName, 0);
+ int val = CVarGetInteger(cvarName, options.defaultIndex);
PushStyleCheckbox(options.color);
if (ImGui::RadioButton(make_invisible.c_str(), id == val)) {
CVarSetInteger(cvarName, id);
diff --git a/soh/soh/SohGui/UIWidgets.hpp b/soh/soh/SohGui/UIWidgets.hpp
index 0008b4cfa..caf2e912b 100644
--- a/soh/soh/SohGui/UIWidgets.hpp
+++ b/soh/soh/SohGui/UIWidgets.hpp
@@ -194,6 +194,7 @@ struct CheckboxOptions : WidgetOptions {
bool defaultValue = false; // Only applicable to CVarCheckbox
ComponentAlignments alignment = ComponentAlignments::Left;
LabelPositions labelPosition = LabelPositions::Near;
+ ImVec2 padding = ImVec2(10.0f, 8.0f);
Colors color = Colors::LightBlue;
CheckboxOptions& DefaultValue(bool defaultValue_) {
@@ -220,6 +221,10 @@ struct CheckboxOptions : WidgetOptions {
WidgetOptions::disabledTooltip = disabledTooltip_;
return *this;
}
+ CheckboxOptions& Padding(ImVec2 padding_) {
+ padding = padding_;
+ return *this;
+ }
};
struct ComboboxOptions : WidgetOptions {
@@ -394,6 +399,7 @@ struct FloatSliderOptions : WidgetOptions {
struct RadioButtonsOptions : WidgetOptions {
std::unordered_map<int32_t, const char*> buttonMap;
+ int32_t defaultIndex = 0;
Colors color = Colors::LightBlue;
RadioButtonsOptions& ButtonMap(std::unordered_map<int32_t, const char*> buttonMap_) {
@@ -408,6 +414,10 @@ struct RadioButtonsOptions : WidgetOptions {
color = color_;
return *this;
}
+ RadioButtonsOptions& DefaultIndex(int32_t defaultIndex_) {
+ defaultIndex = defaultIndex_;
+ return *this;
+ }
};
struct InputOptions : WidgetOptions {
@@ -420,6 +430,8 @@ struct InputOptions : WidgetOptions {
std::string defaultValue = "";
bool secret = false;
ImGuiInputFlags addedFlags = 0;
+ bool hasError = false;
+ const char* errorText = "";
InputOptions& Tooltip(const char* tooltip_) {
WidgetOptions::tooltip = tooltip_;
@@ -454,6 +466,11 @@ struct InputOptions : WidgetOptions {
return *this;
}
+ InputOptions& ComponentAlignment(ComponentAlignments alignment_) {
+ alignment = alignment_;
+ return *this;
+ }
+
InputOptions& DefaultValue(std::string defaultValue_) {
defaultValue = defaultValue_;
return *this;
@@ -463,6 +480,16 @@ struct InputOptions : WidgetOptions {
secret = secret_;
return *this;
}
+
+ InputOptions& HasError(bool error_ = false) {
+ hasError = error_;
+ return *this;
+ }
+
+ InputOptions& ErrorText(const char* errorText_) {
+ errorText = errorText_;
+ return *this;
+ }
};
void PushStyleMenu(const ImVec4& color);
@@ -482,8 +509,8 @@ bool Button(const char* label, const ButtonOptions& options = {});
bool WindowButton(const char* label, const char* cvarName, std::shared_ptr<Ship::GuiWindow> windowPtr,
const WindowButtonOptions& options = {});
-void PushStyleCheckbox(const ImVec4& color);
-void PushStyleCheckbox(Colors color = Colors::LightBlue);
+void PushStyleCheckbox(const ImVec4& color, ImVec2 padding = ImVec2(10.0f, 6.0f));
+void PushStyleCheckbox(Colors color = Colors::LightBlue, ImVec2 padding = ImVec2(10.0f, 6.0f));
void PopStyleCheckbox();
void RenderText(ImVec2 pos, const char* text, const char* text_end, bool hide_text_after_hash);
bool Checkbox(const char* label, bool* v, const CheckboxOptions& options = {});