mirror of
https://github.com/HarbourMasters/Shipwright.git
synced 2025-08-22 14:23:44 -07:00
Merge branch 'develop' into hook-mod-rupee-dash
This commit is contained in:
commit
7ccc5ff85d
246 changed files with 3090 additions and 1963 deletions
|
@ -1,7 +1,5 @@
|
|||
set(CVAR_VSYNC_ENABLED "${CVAR_PREFIX_SETTING}.VsyncEnabled" CACHE STRING "")
|
||||
set(CVAR_Z_FIGHTING_MODE "${CVAR_PREFIX_SETTING}.ZFightingMode" CACHE STRING "")
|
||||
set(CVAR_NEW_FILE_DROPPED "${CVAR_PREFIX_GENERAL}.NewFileDropped" CACHE STRING "")
|
||||
set(CVAR_DROPPED_FILE "${CVAR_PREFIX_GENERAL}.DroppedFile" CACHE STRING "")
|
||||
set(CVAR_INTERNAL_RESOLUTION "${CVAR_PREFIX_SETTING}.InternalResolution" CACHE STRING "")
|
||||
set(CVAR_MSAA_VALUE "${CVAR_PREFIX_SETTING}.MSAAValue" CACHE STRING "")
|
||||
set(CVAR_SDL_WINDOWED_FULLSCREEN "${CVAR_PREFIX_SETTING}.SdlWindowedFullscreen" CACHE STRING "")
|
||||
|
|
|
@ -2,6 +2,7 @@ cmake_minimum_required(VERSION 3.26.0 FATAL_ERROR)
|
|||
|
||||
set(CMAKE_SYSTEM_VERSION 10.0 CACHE STRING "" FORCE)
|
||||
set(CMAKE_CXX_STANDARD 20 CACHE STRING "The C++ standard to use")
|
||||
set(CMAKE_C_STANDARD 23 CACHE STRING "The C standard to use")
|
||||
|
||||
set(CMAKE_OSX_DEPLOYMENT_TARGET "10.15" CACHE STRING "Minimum OS X deployment version")
|
||||
|
||||
|
|
|
@ -1 +1 @@
|
|||
Subproject commit ffc062cbf44ce8dc07ac9fc0185224010bd78cc5
|
||||
Subproject commit 6a3f6cd327b99f617b623e5b9a3afeae460aac2b
|
|
@ -39,7 +39,7 @@ $files = Get-ChildItem -Path $basePath\soh -Recurse -File `
|
|||
| Where-Object { ($_.Extension -eq '.c' -or $_.Extension -eq '.cpp' -or `
|
||||
(($_.Extension -eq '.h' -or $_.Extension -eq '.hpp') -and `
|
||||
(-not ($_.FullName -like "*\soh\src\*" -or $_.FullName -like "*\soh\include\*")))) -and `
|
||||
(-not ($_.FullName -like "*\soh\assets\*")) }
|
||||
(-not ($_.FullName -like "*\soh\assets\*" -or $_.FullName -like "*\soh\build\*")) }
|
||||
|
||||
for ($i = 0; $i -lt $files.Length; $i++) {
|
||||
$file = $files[$i]
|
||||
|
|
|
@ -4,6 +4,7 @@ set(CMAKE_SYSTEM_VERSION 10.0 CACHE STRING "" FORCE)
|
|||
|
||||
project(soh LANGUAGES C CXX)
|
||||
set(CMAKE_CXX_STANDARD 20 CACHE STRING "The C++ standard to use")
|
||||
set(CMAKE_C_STANDARD 23 CACHE STRING "The C standard to use")
|
||||
|
||||
if (CMAKE_SYSTEM_NAME STREQUAL "Darwin")
|
||||
enable_language(OBJCXX)
|
||||
|
@ -511,10 +512,10 @@ if (CMAKE_CXX_COMPILER_ID MATCHES "GNU|Clang|AppleClang")
|
|||
-Wno-parentheses
|
||||
-Wno-narrowing
|
||||
-Wno-missing-braces
|
||||
-Wno-int-conversion
|
||||
$<$<COMPILE_LANGUAGE:C>:
|
||||
-Werror-implicit-function-declaration
|
||||
-Wno-incompatible-pointer-types
|
||||
-Wno-int-conversion
|
||||
>
|
||||
$<$<COMPILE_LANGUAGE:CXX>:-fpermissive>
|
||||
$<$<COMPILE_LANGUAGE:CXX>:
|
||||
|
@ -587,11 +588,11 @@ if (CMAKE_CXX_COMPILER_ID MATCHES "GNU|Clang|AppleClang")
|
|||
-Wno-parentheses
|
||||
-Wno-narrowing
|
||||
-Wno-missing-braces
|
||||
-Wno-int-conversion
|
||||
-Wno-implicit-int
|
||||
$<$<COMPILE_LANGUAGE:C>:
|
||||
-Werror-implicit-function-declaration
|
||||
-Wno-implicit-int
|
||||
-Wno-incompatible-pointer-types
|
||||
-Wno-int-conversion
|
||||
>
|
||||
$<$<COMPILE_LANGUAGE:CXX>:-fpermissive>
|
||||
$<$<COMPILE_LANGUAGE:CXX>:-Wno-deprecated-enum-enum-conversion>
|
||||
|
|
11
soh/assets/custom/presets/Main Default.json
Normal file
11
soh/assets/custom/presets/Main Default.json
Normal file
|
@ -0,0 +1,11 @@
|
|||
{
|
||||
"blocks": {
|
||||
"enhancements": {
|
||||
"gCheats": null,
|
||||
"gEnhancements": null,
|
||||
"gRandoEnhancements": null
|
||||
}
|
||||
},
|
||||
"presetName": "Main Default",
|
||||
"isBuiltIn": true
|
||||
}
|
56
soh/assets/custom/presets/Main Enhanced.json
Normal file
56
soh/assets/custom/presets/Main Enhanced.json
Normal file
|
@ -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
|
||||
}
|
135
soh/assets/custom/presets/Main Randomizer.json
Normal file
135
soh/assets/custom/presets/Main Randomizer.json
Normal file
|
@ -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
|
||||
}
|
56
soh/assets/custom/presets/Main Vanilla+.json
Normal file
56
soh/assets/custom/presets/Main Vanilla+.json
Normal file
|
@ -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
|
||||
}
|
69
soh/assets/custom/presets/Rando Advanced.json
Normal file
69
soh/assets/custom/presets/Rando Advanced.json
Normal file
|
@ -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
|
||||
}
|
51
soh/assets/custom/presets/Rando Beginner.json
Normal file
51
soh/assets/custom/presets/Rando Beginner.json
Normal file
|
@ -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
|
||||
}
|
9
soh/assets/custom/presets/Rando Default.json
Normal file
9
soh/assets/custom/presets/Rando Default.json
Normal file
|
@ -0,0 +1,9 @@
|
|||
{
|
||||
"blocks": {
|
||||
"rando": {
|
||||
"gRandoSettings": null
|
||||
}
|
||||
},
|
||||
"presetName": "Rando Default",
|
||||
"isBuiltIn": true
|
||||
}
|
80
soh/assets/custom/presets/Rando Hell Mode.json
Normal file
80
soh/assets/custom/presets/Rando Hell Mode.json
Normal file
|
@ -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
|
||||
}
|
63
soh/assets/custom/presets/Rando Standard.json
Normal file
63
soh/assets/custom/presets/Rando Standard.json
Normal file
|
@ -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
|
||||
}
|
|
@ -15,7 +15,7 @@ extern "C"
|
|||
#include <soh/Enhancements/randomizer/randomizer_inf.h>
|
||||
|
||||
#if defined(INCLUDE_GAME_PRINTF) && defined(_DEBUG)
|
||||
#define osSyncPrintf(fmt, ...) lusprintf(__FILE__, __LINE__, 0, fmt, __VA_ARGS__)
|
||||
#define osSyncPrintf(fmt, ...) lusprintf(__FILE__, __LINE__, 0, fmt, ##__VA_ARGS__)
|
||||
#else
|
||||
#define osSyncPrintf(fmt, ...) osSyncPrintfUnused(fmt, ##__VA_ARGS__)
|
||||
#endif
|
||||
|
@ -1378,7 +1378,7 @@ void func_800AA0B4();
|
|||
void func_800AA0F0(void);
|
||||
u32 func_800AA148();
|
||||
void func_800AA15C();
|
||||
void func_800AA16C();
|
||||
void Rumble_ClearRequests();
|
||||
void func_800AA178(u32);
|
||||
View* View_New(GraphicsContext* gfxCtx);
|
||||
void View_Free(View* view);
|
||||
|
|
|
@ -544,7 +544,7 @@ typedef enum {
|
|||
LANGUAGE_MAX
|
||||
} Language;
|
||||
|
||||
#define TODO_TRANSLATE "__Translate_This__"
|
||||
#define TODO_TRANSLATE "TranslateThis"
|
||||
|
||||
// TODO get these properties from the textures themselves
|
||||
#define FONT_CHAR_TEX_WIDTH 16
|
||||
|
|
|
@ -245,27 +245,30 @@ typedef void (*PostCurveLimbDraw)(struct PlayState* play, SkelAnimeCurve* skelCu
|
|||
typedef s32 (*AnimUpdateFunc)();
|
||||
|
||||
typedef struct SkelAnime {
|
||||
/* 0x00 */ u8 limbCount; // Number of limbs in the skeleton
|
||||
/* 0x01 */ u8 mode; // See `AnimationMode`
|
||||
/* 0x02 */ u8 dListCount; // Number of display lists in a flexible skeleton
|
||||
/* 0x03 */ s8 taper; // Tapering to use when morphing between animations. Only used by Door_Warp1.
|
||||
/* 0x04 */ void** skeleton; // An array of pointers to limbs. Can be StandardLimb, LodLimb, or SkinLimb.
|
||||
/* 0x08 */ void* animation; // Can be an AnimationHeader or LinkAnimationHeader.
|
||||
/* 0x0C */ f32 startFrame; // In mode ANIMMODE_LOOP_PARTIAL*, start of partial loop.
|
||||
/* 0x10 */ f32 endFrame; // In mode ANIMMODE_ONCE*, Update returns true when curFrame is equal to this. In mode ANIMMODE_LOOP_PARTIAL*, end of partial loop.
|
||||
/* 0x14 */ f32 animLength; // Total number of frames in the current animation.
|
||||
/* 0x18 */ f32 curFrame; // Current frame in the animation
|
||||
/* 0x1C */ f32 playSpeed; // Multiplied by R_UPDATE_RATE / 3 to get the animation's frame rate.
|
||||
/* 0x00 */ u8 limbCount; // Number of limbs in the skeleton
|
||||
/* 0x01 */ u8 mode; // See `AnimationMode`
|
||||
/* 0x02 */ u8 dListCount; // Number of display lists in a flexible skeleton
|
||||
/* 0x03 */ s8 taper; // Tapering to use when morphing between animations. Only used by Door_Warp1.
|
||||
/* 0x04 */ void** skeleton; // An array of pointers to limbs. Can be StandardLimb, LodLimb, or SkinLimb.
|
||||
/* 0x08 */ void* animation; // Can be an AnimationHeader or LinkAnimationHeader.
|
||||
/* 0x0C */ f32 startFrame; // In mode ANIMMODE_LOOP_PARTIAL*, start of partial loop.
|
||||
/* 0x10 */ f32 endFrame; // In mode ANIMMODE_ONCE*, Update returns true when curFrame is equal to this. In mode ANIMMODE_LOOP_PARTIAL*, end of partial loop.
|
||||
/* 0x14 */ f32 animLength; // Total number of frames in the current animation.
|
||||
/* 0x18 */ f32 curFrame; // Current frame in the animation
|
||||
/* 0x1C */ f32 playSpeed; // Multiplied by R_UPDATE_RATE / 3 to get the animation's frame rate.
|
||||
/* 0x20 */ Vec3s* jointTable; // Current translation of model and rotations of all limbs
|
||||
/* 0x24 */ Vec3s* morphTable; // Table of values used to morph between animations
|
||||
/* 0x28 */ f32 morphWeight; // Weight of the current animation morph as a fraction in [0,1]
|
||||
/* 0x2C */ f32 morphRate; // Reciprocal of the number of frames in the morph
|
||||
/* 0x30 */ s32 (*update)(); // Can be Loop, Partial loop, Play once, Morph, or Tapered morph. Link only has Loop, Play once, and Morph.
|
||||
/* 0x34 */ s8 initFlags; // Flags used when initializing Link's skeleton
|
||||
/* 0x35 */ u8 moveFlags; // Flags used for animations that move the actor in worldspace.
|
||||
/* 0x36 */ s16 prevRot; // Previous rotation in worldspace.
|
||||
/* 0x38 */ Vec3s prevTransl; // Previous modelspace translation.
|
||||
/* 0x3E */ Vec3s baseTransl; // Base modelspace translation.
|
||||
/* 0x28 */ f32 morphWeight; // Weight of the current animation morph as a fraction in [0,1]
|
||||
/* 0x2C */ f32 morphRate; // Reciprocal of the number of frames in the morph
|
||||
/* 0x30 */ union {
|
||||
s32 (*normal)(struct SkelAnime*); // Can be Loop, Partial loop, Play once, Morph, or Tapered morph
|
||||
s32 (*link)(struct PlayState*, struct SkelAnime*); // Can be Loop, Play once, or Morph
|
||||
} update;
|
||||
/* 0x34 */ s8 initFlags; // Flags used when initializing Link's skeleton
|
||||
/* 0x35 */ u8 movementFlags; // Flags used for animations that move the actor in worldspace.
|
||||
/* 0x36 */ s16 prevRot; // Previous rotation in worldspace.
|
||||
/* 0x38 */ Vec3s prevTransl; // Previous modelspace translation.
|
||||
/* 0x3E */ Vec3s baseTransl; // Base modelspace translation.
|
||||
SkeletonHeader* skeletonHeader;
|
||||
} SkelAnime; // size = 0x44
|
||||
|
||||
|
|
48
soh/soh/Enhancements/DampeFire.cpp
Normal file
48
soh/soh/Enhancements/DampeFire.cpp
Normal file
|
@ -0,0 +1,48 @@
|
|||
#include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h"
|
||||
#include "soh/ShipInit.hpp"
|
||||
#include "soh/Enhancements/enhancementTypes.h"
|
||||
|
||||
extern "C" {
|
||||
extern PlayState* gPlayState;
|
||||
#include "src/overlays/actors/ovl_En_Po_Relay/z_en_po_relay.h"
|
||||
}
|
||||
|
||||
void RegisterDampeFire() {
|
||||
COND_VB_SHOULD(VB_DAMPE_DROP_FLAME, CVarGetInteger(CVAR_ENHANCEMENT("DampeDropRate"), DAMPE_NORMAL) != DAMPE_NORMAL,
|
||||
{
|
||||
double chance;
|
||||
int cooldown = 9;
|
||||
switch (CVarGetInteger(CVAR_ENHANCEMENT("DampeDropRate"), DAMPE_NORMAL)) {
|
||||
case DAMPE_NONE:
|
||||
*should = false;
|
||||
return;
|
||||
default:
|
||||
case DAMPE_NORMAL:
|
||||
return;
|
||||
case DAMPE_JALAPENO:
|
||||
chance = 0.03;
|
||||
break;
|
||||
case DAMPE_CHIPOTLE:
|
||||
chance = 0.1;
|
||||
break;
|
||||
case DAMPE_SCOTCH_BONNET:
|
||||
chance = 0.2;
|
||||
break;
|
||||
case DAMPE_GHOST_PEPPER:
|
||||
chance = 0.5;
|
||||
cooldown = 4;
|
||||
break;
|
||||
case DAMPE_INFERNO:
|
||||
*should = true;
|
||||
return;
|
||||
}
|
||||
|
||||
EnPoRelay* actor = va_arg(args, EnPoRelay*);
|
||||
if (actor->actionTimer > cooldown) {
|
||||
actor->actionTimer = cooldown;
|
||||
}
|
||||
*should = actor->actionTimer == 0 && Rand_ZeroOne() < chance;
|
||||
});
|
||||
}
|
||||
|
||||
static RegisterShipInitFunc initFunc(RegisterDampeFire, { CVAR_ENHANCEMENT("DampeDropRate") });
|
50
soh/soh/Enhancements/ExtraModes/ShadowTag.cpp
Normal file
50
soh/soh/Enhancements/ExtraModes/ShadowTag.cpp
Normal file
|
@ -0,0 +1,50 @@
|
|||
#include <libultraship/bridge.h>
|
||||
#include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h"
|
||||
#include "soh/ShipInit.hpp"
|
||||
#include "functions.h"
|
||||
|
||||
extern "C" PlayState* gPlayState;
|
||||
|
||||
static constexpr int32_t CVAR_SHADOW_TAG_DEFAULT = 0;
|
||||
#define CVAR_SHADOW_TAG_NAME CVAR_ENHANCEMENT("ShadowTag")
|
||||
#define CVAR_SHADOW_TAG_VALUE CVarGetInteger(CVAR_SHADOW_TAG_NAME, CVAR_SHADOW_TAG_DEFAULT)
|
||||
|
||||
static bool shouldSpawn = false;
|
||||
static uint16_t delayTimer = 60;
|
||||
|
||||
static constexpr s8 ROOM_GREEN_POE = 16;
|
||||
static constexpr s8 ROOM_BLUE_POE = 13;
|
||||
static constexpr s8 ROOM_RED_POE = 12;
|
||||
|
||||
void OnPlayerUpdateShadowTag() {
|
||||
if (gPlayState->sceneNum == SCENE_FOREST_TEMPLE) {
|
||||
switch (gPlayState->roomCtx.curRoom.num) {
|
||||
case ROOM_GREEN_POE:
|
||||
case ROOM_BLUE_POE:
|
||||
case ROOM_RED_POE:
|
||||
return;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (shouldSpawn && (delayTimer <= 0)) {
|
||||
Actor_Spawn(&gPlayState->actorCtx, gPlayState, ACTOR_EN_WALLMAS, 0, 0, 0, 0, 0, 0, 3, false);
|
||||
shouldSpawn = false;
|
||||
} else {
|
||||
delayTimer--;
|
||||
}
|
||||
}
|
||||
|
||||
void ResetShadowTagSpawnTimer() {
|
||||
shouldSpawn = true;
|
||||
delayTimer = 60;
|
||||
}
|
||||
|
||||
void RegisterShadowTag() {
|
||||
COND_HOOK(OnPlayerUpdate, CVAR_SHADOW_TAG_VALUE, OnPlayerUpdateShadowTag);
|
||||
COND_HOOK(OnSceneSpawnActors, true, []() { ResetShadowTagSpawnTimer(); });
|
||||
COND_HOOK(OnSceneInit, true, [](int16_t) { ResetShadowTagSpawnTimer(); });
|
||||
}
|
||||
|
||||
static RegisterShipInitFunc initFunc_ShadowTag(RegisterShadowTag, { CVAR_SHADOW_TAG_NAME });
|
|
@ -61,8 +61,8 @@ std::vector<AltTrapType> getEnabledAddTraps() {
|
|||
};
|
||||
|
||||
static void RollRandomTrap(uint32_t seed) {
|
||||
uint32_t finalSeed =
|
||||
seed + (IS_RANDO ? Rando::Context::GetInstance()->GetSeed() : gSaveContext.ship.stats.fileCreatedAt);
|
||||
uint32_t finalSeed = seed + (IS_RANDO ? Rando::Context::GetInstance()->GetSeed()
|
||||
: static_cast<uint32_t>(gSaveContext.ship.stats.fileCreatedAt));
|
||||
Random_Init(finalSeed);
|
||||
|
||||
roll = RandomElement(getEnabledAddTraps());
|
||||
|
@ -126,12 +126,12 @@ static void OnPlayerUpdate() {
|
|||
Play_TriggerRespawn(gPlayState);
|
||||
break;
|
||||
case ADD_AMMO_TRAP:
|
||||
AMMO(ITEM_STICK) = AMMO(ITEM_STICK) * 0.5;
|
||||
AMMO(ITEM_NUT) = AMMO(ITEM_NUT) * 0.5;
|
||||
AMMO(ITEM_SLINGSHOT) = AMMO(ITEM_SLINGSHOT) * 0.5;
|
||||
AMMO(ITEM_BOW) = AMMO(ITEM_BOW) * 0.5;
|
||||
AMMO(ITEM_BOMB) = AMMO(ITEM_BOMB) * 0.5;
|
||||
AMMO(ITEM_BOMBCHU) = AMMO(ITEM_BOMBCHU) * 0.5;
|
||||
AMMO(ITEM_STICK) = static_cast<int8_t>(floor(AMMO(ITEM_STICK) * 0.5f));
|
||||
AMMO(ITEM_NUT) = static_cast<int8_t>(floor(AMMO(ITEM_NUT) * 0.5f));
|
||||
AMMO(ITEM_SLINGSHOT) = static_cast<int8_t>(floor(AMMO(ITEM_SLINGSHOT) * 0.5f));
|
||||
AMMO(ITEM_BOW) = static_cast<int8_t>(floor(AMMO(ITEM_BOW) * 0.5f));
|
||||
AMMO(ITEM_BOMB) = static_cast<int8_t>(floor(AMMO(ITEM_BOMB) * 0.5f));
|
||||
AMMO(ITEM_BOMBCHU) = static_cast<int8_t>(floor(AMMO(ITEM_BOMBCHU) * 0.5f));
|
||||
Audio_PlaySoundGeneral(NA_SE_VO_FR_SMILE_0, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale,
|
||||
&gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb);
|
||||
break;
|
||||
|
|
|
@ -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"), 0),
|
||||
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"), 0),
|
||||
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"), 0),
|
||||
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"), 0),
|
||||
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 } },
|
||||
} } }
|
||||
};
|
|
@ -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 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;
|
||||
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);
|
||||
}
|
||||
|
||||
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;
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
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);
|
||||
}
|
||||
|
||||
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 (selectedPresetId != 0) {
|
||||
applyPreset(selectedPresetDef.entries);
|
||||
}
|
||||
CVarSetInteger(presetTypeCvar.c_str(), selectedPresetId);
|
||||
Ship::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesNextFrame();
|
||||
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"];
|
||||
}
|
||||
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;
|
||||
}
|
||||
}
|
||||
} 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);
|
||||
}
|
||||
}
|
||||
|
||||
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);
|
||||
|
|
|
@ -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 = {});
|
||||
|
|
70
soh/soh/Enhancements/QoL/DaytimeGS.cpp
Normal file
70
soh/soh/Enhancements/QoL/DaytimeGS.cpp
Normal file
|
@ -0,0 +1,70 @@
|
|||
#include <libultraship/bridge.h>
|
||||
#include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h"
|
||||
#include "soh/ShipInit.hpp"
|
||||
#include "functions.h"
|
||||
#include "macros.h"
|
||||
|
||||
extern "C" {
|
||||
extern PlayState* gPlayState;
|
||||
extern SaveContext gSaveContext;
|
||||
}
|
||||
|
||||
static constexpr int32_t CVAR_DAYTIME_GS_DEFAULT = 0;
|
||||
#define CVAR_DAYTIME_GS_NAME CVAR_ENHANCEMENT("NightGSAlwaysSpawn")
|
||||
#define CVAR_DAYTIME_GS_VALUE CVarGetInteger(CVAR_DAYTIME_GS_NAME, CVAR_DAYTIME_GS_DEFAULT)
|
||||
|
||||
struct DayTimeGoldSkulltulas {
|
||||
uint16_t scene;
|
||||
uint16_t room;
|
||||
bool forChild;
|
||||
std::vector<ActorEntry> actorEntries;
|
||||
};
|
||||
|
||||
using DayTimeGoldSkulltulasList = std::vector<DayTimeGoldSkulltulas>;
|
||||
|
||||
void OnSpawnNighttimeGoldSkulltula() {
|
||||
// Gold Skulltulas that are not part of the scene actor list during the day
|
||||
// Actor values copied from the night time scene actor list
|
||||
static const DayTimeGoldSkulltulasList dayTimeGoldSkulltulas = {
|
||||
// Graveyard
|
||||
{ SCENE_GRAVEYARD, 1, true, { { ACTOR_EN_SW, { 156, 315, 795 }, { 16384, -32768, 0 }, -20096 } } },
|
||||
// ZF
|
||||
{ SCENE_ZORAS_FOUNTAIN, 0, true, { { ACTOR_EN_SW, { -1891, 187, 1911 }, { 16384, 18022, 0 }, -19964 } } },
|
||||
// GF
|
||||
{ SCENE_GERUDOS_FORTRESS, 0, false, { { ACTOR_EN_SW, { 1598, 999, -2008 }, { 16384, -16384, 0 }, -19198 } } },
|
||||
{ SCENE_GERUDOS_FORTRESS, 1, false, { { ACTOR_EN_SW, { 3377, 1734, -4935 }, { 16384, 0, 0 }, -19199 } } },
|
||||
// Kak
|
||||
{ SCENE_KAKARIKO_VILLAGE, 0, false, { { ACTOR_EN_SW, { -18, 540, 1800 }, { 0, -32768, 0 }, -20160 } } },
|
||||
{ SCENE_KAKARIKO_VILLAGE,
|
||||
0,
|
||||
true,
|
||||
{ { ACTOR_EN_SW, { -465, 377, -888 }, { 0, 28217, 0 }, -20222 },
|
||||
{ ACTOR_EN_SW, { 5, 686, -171 }, { 0, -32768, 0 }, -20220 },
|
||||
{ ACTOR_EN_SW, { 324, 270, 905 }, { 16384, 0, 0 }, -20216 },
|
||||
{ ACTOR_EN_SW, { -602, 120, 1120 }, { 16384, 0, 0 }, -20208 } } },
|
||||
// LLR
|
||||
{ SCENE_LON_LON_RANCH,
|
||||
0,
|
||||
true,
|
||||
{ { ACTOR_EN_SW, { -2344, 180, 672 }, { 16384, 22938, 0 }, -29695 },
|
||||
{ ACTOR_EN_SW, { 808, 48, 326 }, { 16384, 0, 0 }, -29694 },
|
||||
{ ACTOR_EN_SW, { 997, 286, -2698 }, { 16384, -16384, 0 }, -29692 } } },
|
||||
};
|
||||
|
||||
for (const auto& dayTimeGS : dayTimeGoldSkulltulas) {
|
||||
if (IS_DAY && dayTimeGS.forChild == LINK_IS_CHILD && dayTimeGS.scene == gPlayState->sceneNum &&
|
||||
dayTimeGS.room == gPlayState->roomCtx.curRoom.num) {
|
||||
for (const auto& actorEntry : dayTimeGS.actorEntries) {
|
||||
Actor_Spawn(&gPlayState->actorCtx, gPlayState, actorEntry.id, actorEntry.pos.x, actorEntry.pos.y,
|
||||
actorEntry.pos.z, actorEntry.rot.x, actorEntry.rot.y, actorEntry.rot.z, actorEntry.params,
|
||||
false);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void RegisterDaytimeGoldSkultullas() {
|
||||
COND_HOOK(OnSceneSpawnActors, CVAR_DAYTIME_GS_VALUE, OnSpawnNighttimeGoldSkulltula);
|
||||
}
|
||||
|
||||
static RegisterShipInitFunc initFunc_DaytimeGoldSkulltulas(RegisterDaytimeGoldSkultullas, { CVAR_DAYTIME_GS_NAME });
|
|
@ -77,9 +77,9 @@ void CrawlSpeed_Register() {
|
|||
COND_VB_SHOULD(VB_CRAWL_SPEED_EXIT_CS, shouldRegister, {
|
||||
Player* player = GET_PLAYER(gPlayState);
|
||||
Camera* csCam = va_arg(args, Camera*);
|
||||
s16 csId = va_arg(args, s16);
|
||||
s16 actionParameters = va_arg(args, s16);
|
||||
s16 initTimer = va_arg(args, s16);
|
||||
s16 csId = static_cast<s16>(va_arg(args, int));
|
||||
s16 actionParameters = static_cast<s16>(va_arg(args, int));
|
||||
s16 initTimer = static_cast<s16>(va_arg(args, int));
|
||||
CutsceneCameraPoint* atPoints = va_arg(args, CutsceneCameraPoint*);
|
||||
CutsceneCameraPoint* eyePoints = va_arg(args, CutsceneCameraPoint*);
|
||||
bool excludeWellBackroom = (player->actor.world.pos.x > 950.0f) && (player->actor.world.pos.x < 1025.0f) &&
|
||||
|
|
13
soh/soh/Enhancements/TimeSavers/FasterBeanSkulltula.cpp
Normal file
13
soh/soh/Enhancements/TimeSavers/FasterBeanSkulltula.cpp
Normal file
|
@ -0,0 +1,13 @@
|
|||
#include "soh/Enhancements/game-interactor/GameInteractor.h"
|
||||
#include "soh/ShipInit.hpp"
|
||||
|
||||
extern "C" {
|
||||
#include "z64save.h"
|
||||
}
|
||||
|
||||
void RegisterFasterBeanSkulltula() {
|
||||
COND_VB_SHOULD(VB_SPAWN_BEAN_SKULLTULA, CVarGetInteger(CVAR_ENHANCEMENT("FasterBeanSkull"), 0),
|
||||
{ *should = true; });
|
||||
}
|
||||
|
||||
static RegisterShipInitFunc initFunc(RegisterFasterBeanSkulltula, { CVAR_ENHANCEMENT("FasterBeanSkull") });
|
19
soh/soh/Enhancements/TimeSavers/FasterBottleEmpty.cpp
Normal file
19
soh/soh/Enhancements/TimeSavers/FasterBottleEmpty.cpp
Normal file
|
@ -0,0 +1,19 @@
|
|||
#include "soh/Enhancements/game-interactor/GameInteractor.h"
|
||||
#include "soh/ShipInit.hpp"
|
||||
|
||||
extern "C" {
|
||||
#include "z64save.h"
|
||||
}
|
||||
|
||||
void RegisterFasterEmptyBottle() {
|
||||
COND_VB_SHOULD(VB_EMPTYING_BOTTLE, CVarGetInteger(CVAR_ENHANCEMENT("FasterBottleEmpty"), 0), {
|
||||
Player* player = va_arg(args, Player*);
|
||||
if (player->skelAnime.curFrame <= 60.0f) {
|
||||
player->skelAnime.playSpeed = 3.0f;
|
||||
} else {
|
||||
player->skelAnime.playSpeed = 1.0f;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
static RegisterShipInitFunc initFunc(RegisterFasterEmptyBottle, { CVAR_ENHANCEMENT("FasterBottleEmpty") });
|
|
@ -41,7 +41,7 @@ void FasterHeavyBlockLift_Register() {
|
|||
LinkAnimationHeader* anim = va_arg(args, LinkAnimationHeader*);
|
||||
|
||||
// Same actor is used for small and large silver rocks, use actor params to identify large ones
|
||||
bool isLargeSilverRock = interactActorId == ACTOR_EN_ISHI && interactRangeActor->params & 1 == 1;
|
||||
bool isLargeSilverRock = (interactActorId == ACTOR_EN_ISHI) && ((interactRangeActor->params & 1) == 1);
|
||||
if (CVarGetInteger(CVAR_ENHANCEMENT("FasterHeavyBlockLift"), 0) &&
|
||||
(isLargeSilverRock || interactActorId == ACTOR_BG_HEAVY_BLOCK)) {
|
||||
*should = false;
|
||||
|
|
|
@ -265,6 +265,9 @@ void Draw_SfxTab(const std::string& tabId, SeqType type, const std::string& tabN
|
|||
}
|
||||
}
|
||||
|
||||
auto playingFromMenu = CVarGetInteger(CVAR_AUDIO("Playing"), 0);
|
||||
auto currentBGM = func_800FA0B4(SEQ_PLAYER_BGM_MAIN);
|
||||
|
||||
// Longest text in Audio Editor
|
||||
ImVec2 columnSize = ImGui::CalcTextSize("Navi - Look/Hey/Watchout (Target Enemy)");
|
||||
ImGui::BeginTable(tabId.c_str(), 3, ImGuiTableFlags_SizingFixedFit);
|
||||
|
@ -291,10 +294,13 @@ void Draw_SfxTab(const std::string& tabId, SeqType type, const std::string& tabN
|
|||
const std::string lockedButton = ICON_FA_LOCK + hiddenKey;
|
||||
const std::string unlockedButton = ICON_FA_UNLOCK + hiddenKey;
|
||||
const int currentValue = CVarGetInteger(cvarKey.c_str(), defaultValue);
|
||||
const bool isCurrentlyPlaying = currentValue == playingFromMenu || seqData.sequenceId == currentBGM;
|
||||
|
||||
ImGui::TableNextRow();
|
||||
ImGui::TableNextColumn();
|
||||
ImGui::Text("%s", seqData.label.c_str());
|
||||
ImGui::TextColored(
|
||||
UIWidgets::ColorValues.at(isCurrentlyPlaying ? UIWidgets::Colors::Yellow : UIWidgets::Colors::White), "%s",
|
||||
seqData.label.c_str());
|
||||
ImGui::TableNextColumn();
|
||||
ImGui::PushItemWidth(-FLT_MIN);
|
||||
const int initialValue = map.contains(currentValue) ? currentValue : defaultValue;
|
||||
|
|
|
@ -111,7 +111,7 @@ const char* BossRush_GetSettingChoiceName(u8 optionIndex, u8 choiceIndex, u8 lan
|
|||
}
|
||||
|
||||
u8 BossRush_GetSettingOptionsAmount(u8 optionIndex) {
|
||||
return BossRushOptions[optionIndex].choices.size();
|
||||
return static_cast<u8>(BossRushOptions[optionIndex].choices.size());
|
||||
}
|
||||
|
||||
void BossRush_SpawnBlueWarps(PlayState* play) {
|
||||
|
@ -311,7 +311,8 @@ void BossRush_HandleCompleteBoss(PlayState* play) {
|
|||
play->sceneNum == SCENE_GANON_BOSS) {
|
||||
gSaveContext.ship.stats.playTimer += 2;
|
||||
gSaveContext.ship.stats.gameComplete = 1;
|
||||
gSaveContext.ship.stats.itemTimestamp[TIMESTAMP_BOSSRUSH_FINISH] = GAMEPLAYSTAT_TOTAL_TIME;
|
||||
gSaveContext.ship.stats.itemTimestamp[TIMESTAMP_BOSSRUSH_FINISH] =
|
||||
static_cast<uint32_t>(GAMEPLAYSTAT_TOTAL_TIME);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -49,14 +49,14 @@ void InputViewer::RenderButton(std::string btnTexture, std::string btnOutlineTex
|
|||
if (outlineMode == BUTTON_OUTLINE_ALWAYS_SHOWN || (outlineMode == BUTTON_OUTLINE_NOT_PRESSED && !state) ||
|
||||
(outlineMode == BUTTON_OUTLINE_PRESSED && state)) {
|
||||
ImGui::Image(Ship::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName(btnOutlineTexture), size,
|
||||
ImVec2(0, 0), ImVec2(1.0f, 1.0f), ImVec4(255, 255, 255, 255));
|
||||
ImVec2(0, 0), ImVec2(1.0f, 1.0f));
|
||||
}
|
||||
// Render button if pressed
|
||||
if (state) {
|
||||
ImGui::SetCursorPos(pos);
|
||||
ImGui::SetNextItemAllowOverlap();
|
||||
ImGui::Image(Ship::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName(btnTexture), size,
|
||||
ImVec2(0, 0), ImVec2(1.0f, 1.0f), ImVec4(255, 255, 255, 255));
|
||||
ImVec2(0, 0), ImVec2(1.0f, 1.0f));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -201,7 +201,7 @@ void InputViewer::DrawElement() {
|
|||
// Background
|
||||
ImGui::Image(
|
||||
Ship::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName("Input-Viewer-Background"),
|
||||
scaledBGSize, ImVec2(0, 0), ImVec2(1.0f, 1.0f), ImVec4(255, 255, 255, 255));
|
||||
scaledBGSize, ImVec2(0, 0), ImVec2(1.0f, 1.0f));
|
||||
}
|
||||
|
||||
// A/B
|
||||
|
@ -345,14 +345,14 @@ void InputViewer::DrawElement() {
|
|||
// Analog Stick
|
||||
const int analogOutlineMode =
|
||||
CVarGetInteger(CVAR_INPUT_VIEWER("AnalogStick.OutlineMode"), STICK_MODE_ALWAYS_SHOWN);
|
||||
const float maxStickDistance = CVarGetInteger(CVAR_INPUT_VIEWER("AnalogStick.Movement"), 12);
|
||||
const int32_t maxStickDistance = CVarGetInteger(CVAR_INPUT_VIEWER("AnalogStick.Movement"), 12);
|
||||
if (analogOutlineMode == STICK_MODE_ALWAYS_SHOWN ||
|
||||
(analogOutlineMode == STICK_MODE_HIDDEN_IN_DEADZONE && !analogStickIsInDeadzone)) {
|
||||
ImGui::SetNextItemAllowOverlap();
|
||||
ImGui::SetCursorPos(aPos);
|
||||
ImGui::Image(
|
||||
Ship::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName("Analog-Stick Outline"),
|
||||
scaledBGSize, ImVec2(0, 0), ImVec2(1.0f, 1.0f), ImVec4(255, 255, 255, 255));
|
||||
scaledBGSize, ImVec2(0, 0), ImVec2(1.0f, 1.0f));
|
||||
}
|
||||
const int analogStickMode =
|
||||
CVarGetInteger(CVAR_INPUT_VIEWER("AnalogStick.VisibilityMode"), STICK_MODE_ALWAYS_SHOWN);
|
||||
|
@ -363,11 +363,11 @@ void InputViewer::DrawElement() {
|
|||
ImVec2(aPos.x + maxStickDistance * ((float)(pads[0].stick_x) / MAX_AXIS_RANGE) * scale,
|
||||
aPos.y - maxStickDistance * ((float)(pads[0].stick_y) / MAX_AXIS_RANGE) * scale));
|
||||
ImGui::Image(Ship::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName("Analog-Stick"),
|
||||
scaledBGSize, ImVec2(0, 0), ImVec2(1.0f, 1.0f), ImVec4(255, 255, 255, 255));
|
||||
scaledBGSize, ImVec2(0, 0), ImVec2(1.0f, 1.0f));
|
||||
}
|
||||
|
||||
// Right Stick
|
||||
const float maxRightStickDistance = CVarGetInteger(CVAR_INPUT_VIEWER("RightStick.Movement"), 7);
|
||||
const int32_t maxRightStickDistance = CVarGetInteger(CVAR_INPUT_VIEWER("RightStick.Movement"), 7);
|
||||
const int rightOutlineMode =
|
||||
CVarGetInteger(CVAR_INPUT_VIEWER("RightStick.OutlineMode"), STICK_MODE_ALWAYS_HIDDEN);
|
||||
if (rightOutlineMode == STICK_MODE_ALWAYS_SHOWN ||
|
||||
|
@ -376,7 +376,7 @@ void InputViewer::DrawElement() {
|
|||
ImGui::SetCursorPos(aPos);
|
||||
ImGui::Image(
|
||||
Ship::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName("Right-Stick Outline"),
|
||||
scaledBGSize, ImVec2(0, 0), ImVec2(1.0f, 1.0f), ImVec4(255, 255, 255, 255));
|
||||
scaledBGSize, ImVec2(0, 0), ImVec2(1.0f, 1.0f));
|
||||
}
|
||||
const int rightStickMode =
|
||||
CVarGetInteger(CVAR_INPUT_VIEWER("RightStick.VisibilityMode"), STICK_MODE_ALWAYS_HIDDEN);
|
||||
|
@ -387,7 +387,7 @@ void InputViewer::DrawElement() {
|
|||
ImVec2(aPos.x + maxRightStickDistance * ((float)(pads[0].right_stick_x) / MAX_AXIS_RANGE) * scale,
|
||||
aPos.y - maxRightStickDistance * ((float)(pads[0].right_stick_y) / MAX_AXIS_RANGE) * scale));
|
||||
ImGui::Image(Ship::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName("Right-Stick"),
|
||||
scaledBGSize, ImVec2(0, 0), ImVec2(1.0f, 1.0f), ImVec4(255, 255, 255, 255));
|
||||
scaledBGSize, ImVec2(0, 0), ImVec2(1.0f, 1.0f));
|
||||
}
|
||||
|
||||
// Analog stick angle text
|
||||
|
@ -401,7 +401,7 @@ void InputViewer::DrawElement() {
|
|||
ImGui::PushFont(ImGui::GetFont());
|
||||
|
||||
// Calculate polar R coordinate from X and Y angles, squared to avoid sqrt
|
||||
const float rSquared = pads[0].stick_x * pads[0].stick_x + pads[0].stick_y * pads[0].stick_y;
|
||||
const int32_t rSquared = pads[0].stick_x * pads[0].stick_x + pads[0].stick_y * pads[0].stick_y;
|
||||
|
||||
// ESS range
|
||||
const int range1Min = CVarGetInteger(CVAR_INPUT_VIEWER("AnalogAngles.Range1.Min"), 8);
|
||||
|
|
|
@ -50,8 +50,8 @@ void Mouse_HandleFirstPerson(Player* player) {
|
|||
: 1;
|
||||
s8 invertYAxisMulti = CVarGetInteger(CVAR_SETTING("Controls.InvertAimingYAxis"), 1) ? 1 : -1;
|
||||
if (MOUSE_ENABLED) {
|
||||
player->actor.focus.rot.y -= mouseCoordRel.x * 6.0f * xAxisMulti * invertXAxisMulti;
|
||||
player->actor.focus.rot.x += mouseCoordRel.y * 6.0f * yAxisMulti * invertYAxisMulti;
|
||||
player->actor.focus.rot.y -= static_cast<int16_t>(mouseCoordRel.x * 6.0f * xAxisMulti * invertXAxisMulti);
|
||||
player->actor.focus.rot.x += static_cast<int16_t>(mouseCoordRel.y * 6.0f * yAxisMulti * invertYAxisMulti);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -59,7 +59,7 @@ void Mouse_RecenterCursor() {
|
|||
u32 width = GetWindow()->GetWidth();
|
||||
u32 height = GetWindow()->GetHeight();
|
||||
if (MOUSE_ENABLED) {
|
||||
GetWindow()->SetMousePos({ (s32)(width / 2), (s32)(height / 2) });
|
||||
GetWindow()->SetMousePos({ static_cast<s32>(width / 2), static_cast<s32>(height / 2) });
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -67,8 +67,8 @@ void Mouse_HandleShield(f32* sp50, f32* sp54) {
|
|||
if (MOUSE_ENABLED) {
|
||||
s32 width = GetWindow()->GetWidth();
|
||||
s32 height = GetWindow()->GetHeight();
|
||||
f32 xBound = 7200 / ((f32)width / 2);
|
||||
f32 yBound = 6000 / ((f32)height / 2);
|
||||
f32 xBound = 7200 / (width / 2.0f);
|
||||
f32 yBound = 6000 / (height / 2.0f);
|
||||
*sp50 +=
|
||||
(mouseCoord.x - (width / 2)) * xBound * (CVarGetInteger(CVAR_ENHANCEMENT("MirroredWorld"), 0) ? 1 : -1);
|
||||
*sp54 += (mouseCoord.y - (height / 2)) * yBound;
|
||||
|
@ -78,8 +78,8 @@ void Mouse_HandleShield(f32* sp50, f32* sp54) {
|
|||
}
|
||||
|
||||
static s8 iterMouse = 0;
|
||||
static f32 mouseQuickspinX[5] = {};
|
||||
static f32 mouseQuickspinY[5] = {};
|
||||
static s32 mouseQuickspinX[5] = {};
|
||||
static s32 mouseQuickspinY[5] = {};
|
||||
static u8 quickspinCount = 0;
|
||||
|
||||
void Mouse_UpdateQuickspinCount() {
|
||||
|
@ -102,9 +102,9 @@ bool Mouse_HandleQuickspin(bool* should, s8* iter2, s8* sp3C) {
|
|||
|
||||
for (i = 0; i < 4; i++, iter2++) {
|
||||
// Calculating angles as per z_lib.c:func_80077D10()
|
||||
f32 relY = mouseQuickspinY[i + 1] - mouseQuickspinY[i];
|
||||
f32 relX = mouseQuickspinX[i + 1] - mouseQuickspinX[i];
|
||||
s16 aTan = Math_Atan2S(relY, -relX);
|
||||
s32 relY = mouseQuickspinY[i + 1] - mouseQuickspinY[i];
|
||||
s32 relX = mouseQuickspinX[i + 1] - mouseQuickspinX[i];
|
||||
s16 aTan = Math_Atan2S((f32)relY, (f32)-relX);
|
||||
iterMouse = (u16)(aTan + 0x2000) >> 9; // See z_player.c:Player_ProcessControlStick()
|
||||
if ((*iter2 = iterMouse) < 0) {
|
||||
return *should = false;
|
||||
|
|
|
@ -642,10 +642,14 @@ void SohInputEditorWindow::DrawStickSection(uint8_t port, uint8_t stick, int32_t
|
|||
|
||||
ImGui::SameLine();
|
||||
ImGui::BeginGroup();
|
||||
DrawStickDirectionLine(ICON_FA_ARROW_UP, port, stick, Ship::UP, color);
|
||||
DrawStickDirectionLine(ICON_FA_ARROW_DOWN, port, stick, Ship::DOWN, color);
|
||||
DrawStickDirectionLine(ICON_FA_ARROW_LEFT, port, stick, Ship::LEFT, color);
|
||||
DrawStickDirectionLine(ICON_FA_ARROW_RIGHT, port, stick, Ship::RIGHT, color);
|
||||
DrawStickDirectionLine(StringHelper::Sprintf("%s##%d", ICON_FA_ARROW_UP, stick).c_str(), port, stick, Ship::UP,
|
||||
color);
|
||||
DrawStickDirectionLine(StringHelper::Sprintf("%s##%d", ICON_FA_ARROW_DOWN, stick).c_str(), port, stick, Ship::DOWN,
|
||||
color);
|
||||
DrawStickDirectionLine(StringHelper::Sprintf("%s##%d", ICON_FA_ARROW_LEFT, stick).c_str(), port, stick, Ship::LEFT,
|
||||
color);
|
||||
DrawStickDirectionLine(StringHelper::Sprintf("%s##%d", ICON_FA_ARROW_RIGHT, stick).c_str(), port, stick,
|
||||
Ship::RIGHT, color);
|
||||
ImGui::EndGroup();
|
||||
ImGui::SetNextItemOpen(true, ImGuiCond_Once);
|
||||
if (ImGui::TreeNode(StringHelper::Sprintf("Analog Stick Options##%d", id).c_str())) {
|
||||
|
@ -1335,12 +1339,12 @@ void SohInputEditorWindow::DrawOcarinaControlPanel() {
|
|||
|
||||
ImGui::AlignTextToFramePadding();
|
||||
ImGui::BulletText("Disable song detection");
|
||||
DrawButtonLine(ICON_FA_BAN, 0, BTN_CUSTOM_OCARINA_DISABLE_SONGS);
|
||||
DrawButtonLine(ICON_FA_BAN "##DisableSongDetection", 0, BTN_CUSTOM_OCARINA_DISABLE_SONGS);
|
||||
|
||||
ImGui::AlignTextToFramePadding();
|
||||
ImGui::BulletText("Pitch");
|
||||
DrawButtonLine(ICON_FA_ARROW_UP, 0, BTN_CUSTOM_OCARINA_PITCH_UP);
|
||||
DrawButtonLine(ICON_FA_ARROW_DOWN, 0, BTN_CUSTOM_OCARINA_PITCH_DOWN);
|
||||
DrawButtonLine(ICON_FA_ARROW_UP "##Pitch", 0, BTN_CUSTOM_OCARINA_PITCH_UP);
|
||||
DrawButtonLine(ICON_FA_ARROW_DOWN "##Pitch", 0, BTN_CUSTOM_OCARINA_PITCH_DOWN);
|
||||
|
||||
if (!CVarGetInteger(CVAR_SETTING("CustomOcarina.Enabled"), 0)) {
|
||||
ImGui::EndDisabled();
|
||||
|
|
|
@ -155,12 +155,12 @@ const std::string CustomMessage::GetFrench(MessageFormat format) const {
|
|||
}
|
||||
|
||||
const std::string CustomMessage::GetForCurrentLanguage(MessageFormat format) const {
|
||||
return GetForLanguage(((Language)gSaveContext.language == LANGUAGE_JPN) ? LANGUAGE_ENG : gSaveContext.language,
|
||||
format);
|
||||
return GetForLanguage(
|
||||
((Language)gSaveContext.language == LANGUAGE_JPN) ? LANGUAGE_ENG : (Language)gSaveContext.language, format);
|
||||
}
|
||||
|
||||
const std::string CustomMessage::GetForLanguage(uint8_t language, MessageFormat format) const {
|
||||
std::string output = messages[language] != TODO_TRANSLATE ? messages[language] : messages[LANGUAGE_ENG];
|
||||
std::string output = !messages[language].starts_with(TODO_TRANSLATE) ? messages[language] : messages[LANGUAGE_ENG];
|
||||
ProcessMessageFormat(output, format);
|
||||
return output;
|
||||
}
|
||||
|
|
|
@ -162,6 +162,7 @@ typedef enum {
|
|||
TEXT_ANJU_THANKS_FOR_FINDING_MY_CUCCOS = 0x503B,
|
||||
TEXT_ANJU_ROUND_THEM_UP_OR_YOULL_PAY = 0x503C,
|
||||
TEXT_ANJU_DONT_TEASE_MY_CUCCOS = 0x503D,
|
||||
TEXT_BIG_POE_COLLECTED_RANDO = 0x5090,
|
||||
TEXT_HBA_NOT_ON_HORSE = 0x603F,
|
||||
TEXT_HBA_INITIAL_EXPLAINATION = 0x6040,
|
||||
TEXT_HBA_WANT_TO_TRY_AGAIN_YES_NO = 0x6041,
|
||||
|
|
|
@ -5,7 +5,9 @@
|
|||
#include "soh/ActorDB.h"
|
||||
#include "soh/Enhancements/game-interactor/GameInteractor.h"
|
||||
#include "soh/Enhancements/nametag.h"
|
||||
#include "soh/ShipInit.hpp"
|
||||
|
||||
#include <algorithm>
|
||||
#include <array>
|
||||
#include <bit>
|
||||
#include <map>
|
||||
|
@ -13,8 +15,10 @@
|
|||
#include <string>
|
||||
#include <libultraship/bridge.h>
|
||||
#include <libultraship/libultraship.h>
|
||||
#include <spdlog/fmt/fmt.h>
|
||||
#include "soh/OTRGlobals.h"
|
||||
#include "soh/cvar_prefixes.h"
|
||||
#include "soh/ObjectExtension/ActorListIndex.h"
|
||||
|
||||
extern "C" {
|
||||
#include <z64.h>
|
||||
|
@ -31,6 +35,10 @@ extern PlayState* gPlayState;
|
|||
#define DEKUNUTS_FLOWER 10
|
||||
#define DEBUG_ACTOR_NAMETAG_TAG "debug_actor_viewer"
|
||||
|
||||
#define CVAR_ACTOR_NAME_TAGS(val) CVAR_DEVELOPER_TOOLS("ActorViewer.NameTags." val)
|
||||
#define CVAR_ACTOR_NAME_TAGS_ENABLED_NAME CVAR_ACTOR_NAME_TAGS("Enabled")
|
||||
#define CVAR_ACTOR_NAME_TAGS_ENABLED CVarGetInteger(CVAR_ACTOR_NAME_TAGS("Enabled"), 0)
|
||||
|
||||
typedef struct {
|
||||
u16 id;
|
||||
u16 params;
|
||||
|
@ -38,13 +46,6 @@ typedef struct {
|
|||
Vec3s rot;
|
||||
} ActorInfo;
|
||||
|
||||
typedef enum {
|
||||
LIST,
|
||||
TARGET,
|
||||
HELD,
|
||||
INTERACT,
|
||||
} RetrievalMethod;
|
||||
|
||||
std::array<const char*, 12> acMapping = {
|
||||
"Switch", "Background (Prop type 1)",
|
||||
"Player", "Bomb",
|
||||
|
@ -67,6 +68,10 @@ const std::string GetActorDescription(u16 id) {
|
|||
return ActorDB::Instance->RetrieveEntry(id).entry.valid ? ActorDB::Instance->RetrieveEntry(id).entry.desc : "???";
|
||||
}
|
||||
|
||||
const std::string GetActorDebugName(u16 id) {
|
||||
return ActorDB::Instance->RetrieveEntry(id).entry.valid ? ActorDB::Instance->RetrieveEntry(id).entry.name : "???";
|
||||
}
|
||||
|
||||
template <typename T> void DrawGroupWithBorder(T&& drawFunc, std::string section) {
|
||||
// First group encapsulates the inner portion and border
|
||||
ImGui::BeginChild(std::string("##" + section).c_str(), ImVec2(0, 0),
|
||||
|
@ -812,25 +817,37 @@ std::vector<u16> GetActorsWithDescriptionContainingString(std::string s) {
|
|||
}
|
||||
|
||||
void ActorViewer_AddTagForActor(Actor* actor) {
|
||||
int val = CVarGetInteger(CVAR_DEVELOPER_TOOLS("ActorViewer.NameTags"), ACTORVIEWER_NAMETAGS_NONE);
|
||||
auto entry = ActorDB::Instance->RetrieveEntry(actor->id);
|
||||
std::string tag;
|
||||
|
||||
if (val > 0 && entry.entry.valid) {
|
||||
switch (val) {
|
||||
case ACTORVIEWER_NAMETAGS_DESC:
|
||||
tag = entry.desc;
|
||||
break;
|
||||
case ACTORVIEWER_NAMETAGS_NAME:
|
||||
tag = entry.name;
|
||||
break;
|
||||
case ACTORVIEWER_NAMETAGS_BOTH:
|
||||
tag = entry.name + '\n' + entry.desc;
|
||||
break;
|
||||
}
|
||||
|
||||
NameTag_RegisterForActorWithOptions(actor, tag.c_str(), { .tag = DEBUG_ACTOR_NAMETAG_TAG });
|
||||
if (!CVarGetInteger(CVAR_ACTOR_NAME_TAGS("Enabled"), 0)) {
|
||||
return;
|
||||
}
|
||||
|
||||
std::vector<std::string> parts;
|
||||
|
||||
if (CVarGetInteger(CVAR_ACTOR_NAME_TAGS("DisplayID"), 0)) {
|
||||
parts.push_back(GetActorDebugName(actor->id));
|
||||
}
|
||||
if (CVarGetInteger(CVAR_ACTOR_NAME_TAGS("DisplayDescription"), 0)) {
|
||||
parts.push_back(GetActorDescription(actor->id));
|
||||
}
|
||||
if (CVarGetInteger(CVAR_ACTOR_NAME_TAGS("DisplayCategory"), 0)) {
|
||||
parts.push_back(acMapping[actor->category]);
|
||||
}
|
||||
if (CVarGetInteger(CVAR_ACTOR_NAME_TAGS("DisplayParams"), 0)) {
|
||||
parts.push_back(fmt::format("0x{:04X} ({})", (u16)actor->params, actor->params));
|
||||
}
|
||||
|
||||
std::string tag = "";
|
||||
for (size_t i = 0; i < parts.size(); i++) {
|
||||
if (i != 0) {
|
||||
tag += "\n";
|
||||
}
|
||||
tag += parts.at(i);
|
||||
}
|
||||
|
||||
bool withZBuffer = CVarGetInteger(CVAR_ACTOR_NAME_TAGS("WithZBuffer"), 0);
|
||||
|
||||
NameTag_RegisterForActorWithOptions(actor, tag.c_str(),
|
||||
{ .tag = DEBUG_ACTOR_NAMETAG_TAG, .noZBuffer = !withZBuffer });
|
||||
}
|
||||
|
||||
void ActorViewer_AddTagForAllActors() {
|
||||
|
@ -850,36 +867,64 @@ void ActorViewer_AddTagForAllActors() {
|
|||
|
||||
void ActorViewerWindow::DrawElement() {
|
||||
ImGui::BeginDisabled(CVarGetInteger(CVAR_SETTING("DisableChanges"), 0));
|
||||
static Actor* display;
|
||||
static Actor empty{};
|
||||
static Actor* fetch = NULL;
|
||||
static ActorInfo newActor = { 0, 0, { 0, 0, 0 }, { 0, 0, 0 } };
|
||||
static bool needs_reset = false;
|
||||
static ImU16 one = 1;
|
||||
static int actor;
|
||||
static int category = 0;
|
||||
static RetrievalMethod rm;
|
||||
static std::string filler = "Please select";
|
||||
static std::vector<Actor*> list;
|
||||
static u16 lastSceneId = 0;
|
||||
static std::string searchString = "";
|
||||
static s16 currentSelectedInDropdown;
|
||||
static std::vector<u16> actors;
|
||||
static s16 currentSelectedInDropdown = -1;
|
||||
static std::vector<u16> actorSearchResults;
|
||||
|
||||
if (gPlayState != nullptr) {
|
||||
needs_reset = lastSceneId != gPlayState->sceneNum;
|
||||
if (needs_reset) {
|
||||
display = ∅
|
||||
fetch = nullptr;
|
||||
actor = category = 0;
|
||||
filler = "Please Select";
|
||||
list.clear();
|
||||
needs_reset = false;
|
||||
searchString = "";
|
||||
currentSelectedInDropdown = -1;
|
||||
actors.clear();
|
||||
if (ImGui::BeginChild("options", ImVec2(0, 0), ImGuiChildFlags_Border | ImGuiChildFlags_AutoResizeY)) {
|
||||
bool toggled = false;
|
||||
bool optionChange = false;
|
||||
|
||||
ImGui::SeparatorText("Options");
|
||||
|
||||
toggled = UIWidgets::CVarCheckbox("Actor Name Tags", CVAR_ACTOR_NAME_TAGS("Enabled"),
|
||||
{ { .tooltip = "Adds \"name tags\" above actors for identification" } });
|
||||
|
||||
ImGui::SameLine();
|
||||
|
||||
UIWidgets::Button("Display Items", { { .tooltip = "Click to add display items on the name tags" } });
|
||||
|
||||
if (ImGui::BeginPopupContextItem(nullptr, ImGuiPopupFlags_MouseButtonLeft | ImGuiPopupFlags_NoReopen)) {
|
||||
optionChange |= UIWidgets::CVarCheckbox("ID", CVAR_ACTOR_NAME_TAGS("DisplayID"));
|
||||
optionChange |= UIWidgets::CVarCheckbox("Description", CVAR_ACTOR_NAME_TAGS("DisplayDescription"));
|
||||
optionChange |= UIWidgets::CVarCheckbox("Category", CVAR_ACTOR_NAME_TAGS("DisplayCategory"));
|
||||
optionChange |= UIWidgets::CVarCheckbox("Params", CVAR_ACTOR_NAME_TAGS("DisplayParams"));
|
||||
|
||||
ImGui::EndPopup();
|
||||
}
|
||||
|
||||
optionChange |= UIWidgets::CVarCheckbox(
|
||||
"Name tags with Z-Buffer", CVAR_ACTOR_NAME_TAGS("WithZBuffer"),
|
||||
{ { .tooltip = "Allow name tags to be obstructed when behind geometry and actors" } });
|
||||
|
||||
if (toggled || optionChange) {
|
||||
bool tagsEnabled = CVarGetInteger(CVAR_ACTOR_NAME_TAGS("Enabled"), 0);
|
||||
bool noOptionsEnabled = !CVarGetInteger(CVAR_ACTOR_NAME_TAGS("DisplayID"), 0) &&
|
||||
!CVarGetInteger(CVAR_ACTOR_NAME_TAGS("DisplayDescription"), 0) &&
|
||||
!CVarGetInteger(CVAR_ACTOR_NAME_TAGS("DisplayCategory"), 0) &&
|
||||
!CVarGetInteger(CVAR_ACTOR_NAME_TAGS("DisplayParams"), 0);
|
||||
|
||||
// Save the user an extra click and prevent adding "empty" tags by enabling,
|
||||
// disabling, or setting an option based on what changed
|
||||
if (tagsEnabled && noOptionsEnabled) {
|
||||
if (toggled) {
|
||||
CVarSetInteger(CVAR_ACTOR_NAME_TAGS("DisplayID"), 1);
|
||||
} else {
|
||||
CVarSetInteger(CVAR_ACTOR_NAME_TAGS("Enabled"), 0);
|
||||
}
|
||||
} else if (optionChange && !tagsEnabled && !noOptionsEnabled) {
|
||||
CVarSetInteger(CVAR_ACTOR_NAME_TAGS("Enabled"), 1);
|
||||
}
|
||||
|
||||
NameTag_RemoveAllByTag(DEBUG_ACTOR_NAMETAG_TAG);
|
||||
ActorViewer_AddTagForAllActors();
|
||||
}
|
||||
}
|
||||
lastSceneId = gPlayState->sceneNum;
|
||||
ImGui::EndChild();
|
||||
|
||||
PushStyleCombobox(THEME_COLOR);
|
||||
if (ImGui::BeginCombo("Actor Type", acMapping[category])) {
|
||||
|
@ -893,21 +938,19 @@ void ActorViewerWindow::DrawElement() {
|
|||
ImGui::EndCombo();
|
||||
}
|
||||
|
||||
if (display == nullptr) {
|
||||
filler = "Please select";
|
||||
}
|
||||
|
||||
if (ImGui::BeginCombo("Actor", filler.c_str())) {
|
||||
if (gPlayState != nullptr && lastSceneId != gPlayState->sceneNum) {
|
||||
PopulateActorDropdown(category, list);
|
||||
lastSceneId = gPlayState->sceneNum;
|
||||
}
|
||||
for (int i = 0; i < list.size(); i++) {
|
||||
std::string label = std::to_string(i) + ": " + ActorDB::Instance->RetrieveEntry(list[i]->id).name;
|
||||
std::string description = GetActorDescription(list[i]->id);
|
||||
if (description != "")
|
||||
label += " (" + description + ")";
|
||||
|
||||
if (ImGui::Selectable(label.c_str())) {
|
||||
rm = LIST;
|
||||
if (ImGui::Selectable(label.c_str(), list[i] == display)) {
|
||||
display = list[i];
|
||||
actor = i;
|
||||
filler = label;
|
||||
break;
|
||||
}
|
||||
|
@ -918,87 +961,76 @@ void ActorViewerWindow::DrawElement() {
|
|||
|
||||
PushStyleHeader(THEME_COLOR);
|
||||
if (ImGui::TreeNode("Selected Actor")) {
|
||||
DrawGroupWithBorder(
|
||||
[&]() {
|
||||
ImGui::Text("Name: %s", ActorDB::Instance->RetrieveEntry(display->id).name.c_str());
|
||||
ImGui::Text("Description: %s", GetActorDescription(display->id).c_str());
|
||||
ImGui::Text("Category: %s", acMapping[display->category]);
|
||||
ImGui::Text("ID: %d", display->id);
|
||||
ImGui::Text("Parameters: %d", display->params);
|
||||
},
|
||||
"Selected Actor");
|
||||
ImGui::SameLine();
|
||||
ImGui::PushItemWidth(ImGui::GetFontSize() * 6);
|
||||
if (display != nullptr) {
|
||||
DrawGroupWithBorder(
|
||||
[&]() {
|
||||
ImGui::Text("Name: %s", ActorDB::Instance->RetrieveEntry(display->id).name.c_str());
|
||||
ImGui::Text("Description: %s", GetActorDescription(display->id).c_str());
|
||||
ImGui::Text("Category: %s", acMapping[display->category]);
|
||||
ImGui::Text("ID: %d", display->id);
|
||||
ImGui::Text("Parameters: %d", display->params);
|
||||
ImGui::Text("Actor List Index: %d", GetActorListIndex(display));
|
||||
},
|
||||
"Selected Actor");
|
||||
ImGui::SameLine();
|
||||
ImGui::PushItemWidth(ImGui::GetFontSize() * 6);
|
||||
|
||||
DrawGroupWithBorder(
|
||||
[&]() {
|
||||
ImGui::PushItemWidth(ImGui::GetFontSize() * 6);
|
||||
DrawGroupWithBorder(
|
||||
[&]() {
|
||||
ImGui::PushItemWidth(ImGui::GetFontSize() * 6);
|
||||
PushStyleInput(THEME_COLOR);
|
||||
ImGui::Text("Actor Position");
|
||||
ImGui::InputScalar("X##CurPos", ImGuiDataType_Float, &display->world.pos.x);
|
||||
ImGui::InputScalar("Y##CurPos", ImGuiDataType_Float, &display->world.pos.y);
|
||||
ImGui::InputScalar("Z##CurPos", ImGuiDataType_Float, &display->world.pos.z);
|
||||
ImGui::PopItemWidth();
|
||||
PopStyleInput();
|
||||
},
|
||||
"Actor Position");
|
||||
ImGui::SameLine();
|
||||
DrawGroupWithBorder(
|
||||
[&]() {
|
||||
PushStyleInput(THEME_COLOR);
|
||||
ImGui::PushItemWidth(ImGui::GetFontSize() * 6);
|
||||
ImGui::Text("Actor Rotation");
|
||||
ImGui::InputScalar("X##CurRot", ImGuiDataType_S16, &display->world.rot.x);
|
||||
ImGui::InputScalar("Y##CurRot", ImGuiDataType_S16, &display->world.rot.y);
|
||||
ImGui::InputScalar("Z##CurRot", ImGuiDataType_S16, &display->world.rot.z);
|
||||
ImGui::PopItemWidth();
|
||||
PopStyleInput();
|
||||
},
|
||||
"Actor Rotation");
|
||||
|
||||
if (display->category == ACTORCAT_BOSS || display->category == ACTORCAT_ENEMY) {
|
||||
PushStyleInput(THEME_COLOR);
|
||||
ImGui::Text("Actor Position");
|
||||
ImGui::InputScalar("X##CurPos", ImGuiDataType_Float, &display->world.pos.x);
|
||||
ImGui::InputScalar("Y##CurPos", ImGuiDataType_Float, &display->world.pos.y);
|
||||
ImGui::InputScalar("Z##CurPos", ImGuiDataType_Float, &display->world.pos.z);
|
||||
ImGui::PopItemWidth();
|
||||
ImGui::InputScalar("Enemy Health", ImGuiDataType_U8, &display->colChkInfo.health);
|
||||
PopStyleInput();
|
||||
},
|
||||
"Actor Position");
|
||||
ImGui::SameLine();
|
||||
DrawGroupWithBorder(
|
||||
[&]() {
|
||||
PushStyleInput(THEME_COLOR);
|
||||
ImGui::PushItemWidth(ImGui::GetFontSize() * 6);
|
||||
ImGui::Text("Actor Rotation");
|
||||
ImGui::InputScalar("X##CurRot", ImGuiDataType_S16, &display->world.rot.x);
|
||||
ImGui::InputScalar("Y##CurRot", ImGuiDataType_S16, &display->world.rot.y);
|
||||
ImGui::InputScalar("Z##CurRot", ImGuiDataType_S16, &display->world.rot.z);
|
||||
ImGui::PopItemWidth();
|
||||
PopStyleInput();
|
||||
},
|
||||
"Actor Rotation");
|
||||
|
||||
if (display->category == ACTORCAT_BOSS || display->category == ACTORCAT_ENEMY) {
|
||||
PushStyleInput(THEME_COLOR);
|
||||
ImGui::InputScalar("Enemy Health", ImGuiDataType_U8, &display->colChkInfo.health);
|
||||
PopStyleInput();
|
||||
UIWidgets::InsertHelpHoverText("Some actors might not use this!");
|
||||
}
|
||||
|
||||
DrawGroupWithBorder(
|
||||
[&]() {
|
||||
ImGui::Text("flags");
|
||||
UIWidgets::DrawFlagArray32("flags", display->flags);
|
||||
},
|
||||
"flags");
|
||||
|
||||
ImGui::SameLine();
|
||||
|
||||
DrawGroupWithBorder(
|
||||
[&]() {
|
||||
ImGui::Text("bgCheckFlags");
|
||||
UIWidgets::DrawFlagArray16("bgCheckFlags", display->bgCheckFlags);
|
||||
},
|
||||
"bgCheckFlags");
|
||||
|
||||
if (Button("Refresh", ButtonOptions().Color(THEME_COLOR))) {
|
||||
PopulateActorDropdown(category, list);
|
||||
switch (rm) {
|
||||
case INTERACT:
|
||||
case HELD:
|
||||
case TARGET:
|
||||
display = fetch;
|
||||
break;
|
||||
case LIST:
|
||||
display = list[actor];
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
UIWidgets::InsertHelpHoverText("Some actors might not use this!");
|
||||
}
|
||||
}
|
||||
|
||||
if (Button("Go to Actor", ButtonOptions().Color(THEME_COLOR))) {
|
||||
Player* player = GET_PLAYER(gPlayState);
|
||||
Math_Vec3f_Copy(&player->actor.world.pos, &display->world.pos);
|
||||
Math_Vec3f_Copy(&player->actor.home.pos, &player->actor.world.pos);
|
||||
DrawGroupWithBorder(
|
||||
[&]() {
|
||||
ImGui::Text("flags");
|
||||
UIWidgets::DrawFlagArray32("flags", display->flags);
|
||||
},
|
||||
"flags");
|
||||
|
||||
ImGui::SameLine();
|
||||
|
||||
DrawGroupWithBorder(
|
||||
[&]() {
|
||||
ImGui::Text("bgCheckFlags");
|
||||
UIWidgets::DrawFlagArray16("bgCheckFlags", display->bgCheckFlags);
|
||||
},
|
||||
"bgCheckFlags");
|
||||
|
||||
if (Button("Go to Actor", ButtonOptions().Color(THEME_COLOR))) {
|
||||
Player* player = GET_PLAYER(gPlayState);
|
||||
Math_Vec3f_Copy(&player->actor.world.pos, &display->world.pos);
|
||||
Math_Vec3f_Copy(&player->actor.home.pos, &player->actor.world.pos);
|
||||
}
|
||||
} else {
|
||||
ImGui::Text("Select an actor to display information.");
|
||||
}
|
||||
|
||||
if (Button("Fetch from Target",
|
||||
|
@ -1006,34 +1038,28 @@ void ActorViewerWindow::DrawElement() {
|
|||
.Color(THEME_COLOR)
|
||||
.Tooltip("Grabs actor with target arrow above it. You might need C-Up for enemies"))) {
|
||||
Player* player = GET_PLAYER(gPlayState);
|
||||
fetch = player->talkActor;
|
||||
if (fetch != NULL) {
|
||||
display = fetch;
|
||||
category = fetch->category;
|
||||
if (player->talkActor != NULL) {
|
||||
display = player->talkActor;
|
||||
category = display->category;
|
||||
PopulateActorDropdown(category, list);
|
||||
rm = TARGET;
|
||||
}
|
||||
}
|
||||
if (Button("Fetch from Held",
|
||||
ButtonOptions().Color(THEME_COLOR).Tooltip("Grabs actor that Link is holding"))) {
|
||||
Player* player = GET_PLAYER(gPlayState);
|
||||
fetch = player->heldActor;
|
||||
if (fetch != NULL) {
|
||||
display = fetch;
|
||||
category = fetch->category;
|
||||
if (player->heldActor != NULL) {
|
||||
display = player->heldActor;
|
||||
category = display->category;
|
||||
PopulateActorDropdown(category, list);
|
||||
rm = HELD;
|
||||
}
|
||||
}
|
||||
if (Button("Fetch from Interaction",
|
||||
ButtonOptions().Color(THEME_COLOR).Tooltip("Grabs actor from \"interaction range\""))) {
|
||||
Player* player = GET_PLAYER(gPlayState);
|
||||
fetch = player->interactRangeActor;
|
||||
if (fetch != NULL) {
|
||||
display = fetch;
|
||||
category = fetch->category;
|
||||
if (player->interactRangeActor != NULL) {
|
||||
display = player->interactRangeActor;
|
||||
category = display->category;
|
||||
PopulateActorDropdown(category, list);
|
||||
rm = INTERACT;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1044,21 +1070,22 @@ void ActorViewerWindow::DrawElement() {
|
|||
// ImGui::PushItemWidth(ImGui::GetFontSize() * 10);
|
||||
|
||||
if (InputString("Search Actor", &searchString, InputOptions().Color(THEME_COLOR))) {
|
||||
actors = GetActorsWithDescriptionContainingString(searchString);
|
||||
actorSearchResults = GetActorsWithDescriptionContainingString(searchString);
|
||||
currentSelectedInDropdown = -1;
|
||||
}
|
||||
|
||||
if (!SohUtils::IsStringEmpty(searchString) && !actors.empty()) {
|
||||
std::string preview = currentSelectedInDropdown == -1
|
||||
? "Please Select"
|
||||
: ActorDB::Instance->RetrieveEntry(actors[currentSelectedInDropdown]).desc;
|
||||
if (!SohUtils::IsStringEmpty(searchString) && !actorSearchResults.empty()) {
|
||||
std::string preview =
|
||||
currentSelectedInDropdown == -1
|
||||
? "Please Select"
|
||||
: ActorDB::Instance->RetrieveEntry(actorSearchResults[currentSelectedInDropdown]).desc;
|
||||
PushStyleCombobox(THEME_COLOR);
|
||||
if (ImGui::BeginCombo("Results", preview.c_str())) {
|
||||
for (u8 i = 0; i < actors.size(); i++) {
|
||||
if (ImGui::Selectable(ActorDB::Instance->RetrieveEntry(actors[i]).desc.c_str(),
|
||||
for (u8 i = 0; i < actorSearchResults.size(); i++) {
|
||||
if (ImGui::Selectable(ActorDB::Instance->RetrieveEntry(actorSearchResults[i]).desc.c_str(),
|
||||
i == currentSelectedInDropdown)) {
|
||||
currentSelectedInDropdown = i;
|
||||
newActor.id = actors[i];
|
||||
newActor.id = actorSearchResults[i];
|
||||
}
|
||||
}
|
||||
ImGui::EndCombo();
|
||||
|
@ -1160,39 +1187,45 @@ void ActorViewerWindow::DrawElement() {
|
|||
ImGui::TreePop();
|
||||
}
|
||||
PopStyleHeader();
|
||||
|
||||
static std::unordered_map<int32_t, const char*> nameTagOptions = {
|
||||
{ 0, "None" },
|
||||
{ 1, "Short Description" },
|
||||
{ 2, "Actor ID" },
|
||||
{ 3, "Both" },
|
||||
};
|
||||
|
||||
if (CVarCombobox(
|
||||
"Actor Name Tags", CVAR_DEVELOPER_TOOLS("ActorViewer.NameTags"), nameTagOptions,
|
||||
ComboboxOptions().Color(THEME_COLOR).Tooltip("Adds \"name tags\" above actors for identification"))) {
|
||||
NameTag_RemoveAllByTag(DEBUG_ACTOR_NAMETAG_TAG);
|
||||
ActorViewer_AddTagForAllActors();
|
||||
}
|
||||
} else {
|
||||
ImGui::Text("Global Context needed for actor info!");
|
||||
if (needs_reset) {
|
||||
fetch = nullptr;
|
||||
actor = category = 0;
|
||||
filler = "Please Select";
|
||||
list.clear();
|
||||
needs_reset = false;
|
||||
searchString = "";
|
||||
currentSelectedInDropdown = -1;
|
||||
actors.clear();
|
||||
}
|
||||
}
|
||||
ImGui::EndDisabled();
|
||||
}
|
||||
|
||||
void ActorViewerWindow::InitElement() {
|
||||
GameInteractor::Instance->RegisterGameHook<GameInteractor::OnActorInit>([](void* refActor) {
|
||||
GameInteractor::Instance->RegisterGameHook<GameInteractor::OnActorSpawn>([this](void* refActor) {
|
||||
Actor* actor = static_cast<Actor*>(refActor);
|
||||
ActorViewer_AddTagForActor(actor);
|
||||
|
||||
// Reload actor list if the new actor belongs to the selected category
|
||||
if (category == actor->category) {
|
||||
PopulateActorDropdown(actor->category, list);
|
||||
}
|
||||
});
|
||||
|
||||
GameInteractor::Instance->RegisterGameHook<GameInteractor::OnActorDestroy>([this](void* refActor) {
|
||||
Actor* actor = static_cast<Actor*>(refActor);
|
||||
|
||||
// If the actor belongs to the selected category, we need to manually remove it, as it has not been removed from
|
||||
// the global actor array yet
|
||||
if (category == actor->category) {
|
||||
list.erase(std::remove(list.begin(), list.end(), actor), list.end());
|
||||
}
|
||||
if (display == actor) {
|
||||
display = nullptr;
|
||||
}
|
||||
});
|
||||
|
||||
GameInteractor::Instance->RegisterGameHook<GameInteractor::OnSceneInit>([this](int16_t sceneNum) {
|
||||
display = nullptr;
|
||||
category = ACTORCAT_SWITCH;
|
||||
list.clear();
|
||||
});
|
||||
}
|
||||
|
||||
void ActorViewer_RegisterNameTagHooks() {
|
||||
COND_HOOK(OnActorInit, CVAR_ACTOR_NAME_TAGS_ENABLED,
|
||||
[](void* actor) { ActorViewer_AddTagForActor(static_cast<Actor*>(actor)); });
|
||||
}
|
||||
|
||||
RegisterShipInitFunc nametagInit(ActorViewer_RegisterNameTagHooks, { CVAR_ACTOR_NAME_TAGS_ENABLED_NAME });
|
||||
|
|
|
@ -2,6 +2,10 @@
|
|||
|
||||
#include <libultraship/libultraship.h>
|
||||
|
||||
#include "z64actor.h"
|
||||
|
||||
#include <vector>
|
||||
|
||||
class ActorViewerWindow final : public Ship::GuiWindow {
|
||||
public:
|
||||
using GuiWindow::GuiWindow;
|
||||
|
@ -9,4 +13,9 @@ class ActorViewerWindow final : public Ship::GuiWindow {
|
|||
void DrawElement() override;
|
||||
void InitElement() override;
|
||||
void UpdateElement() override{};
|
||||
|
||||
private:
|
||||
Actor* display = nullptr;
|
||||
int category = ACTORCAT_SWITCH;
|
||||
std::vector<Actor*> list;
|
||||
};
|
||||
|
|
|
@ -87,6 +87,16 @@ typedef enum {
|
|||
DAMAGE_OHKO
|
||||
} DamageMultType;
|
||||
|
||||
typedef enum {
|
||||
DAMPE_NONE,
|
||||
DAMPE_NORMAL,
|
||||
DAMPE_JALAPENO,
|
||||
DAMPE_CHIPOTLE,
|
||||
DAMPE_SCOTCH_BONNET,
|
||||
DAMPE_GHOST_PEPPER,
|
||||
DAMPE_INFERNO,
|
||||
} DampeDropRate;
|
||||
|
||||
typedef enum {
|
||||
DEKU_STICK_NORMAL,
|
||||
DEKU_STICK_UNBREAKABLE,
|
||||
|
|
|
@ -27,8 +27,10 @@ DEFINE_HOOK(OnOcarinaSongAction, ());
|
|||
DEFINE_HOOK(OnCuccoOrChickenHatch, ());
|
||||
DEFINE_HOOK(OnShopSlotChange, (uint8_t cursorIndex, int16_t price));
|
||||
DEFINE_HOOK(OnActorInit, (void* actor));
|
||||
DEFINE_HOOK(OnActorSpawn, (void* actor));
|
||||
DEFINE_HOOK(OnActorUpdate, (void* actor));
|
||||
DEFINE_HOOK(OnActorKill, (void* actor));
|
||||
DEFINE_HOOK(OnActorDestroy, (void* actor));
|
||||
DEFINE_HOOK(OnEnemyDefeat, (void* actor));
|
||||
DEFINE_HOOK(OnBossDefeat, (void* actor));
|
||||
DEFINE_HOOK(OnTimestamp, (u8 item));
|
||||
|
|
|
@ -108,6 +108,13 @@ void GameInteractor_ExecuteOnActorInit(void* actor) {
|
|||
GameInteractor::Instance->ExecuteHooksForFilter<GameInteractor::OnActorInit>(actor);
|
||||
}
|
||||
|
||||
void GameInteractor_ExecuteOnActorSpawn(void* actor) {
|
||||
GameInteractor::Instance->ExecuteHooks<GameInteractor::OnActorSpawn>(actor);
|
||||
GameInteractor::Instance->ExecuteHooksForID<GameInteractor::OnActorSpawn>(((Actor*)actor)->id, actor);
|
||||
GameInteractor::Instance->ExecuteHooksForPtr<GameInteractor::OnActorSpawn>((uintptr_t)actor, actor);
|
||||
GameInteractor::Instance->ExecuteHooksForFilter<GameInteractor::OnActorSpawn>(actor);
|
||||
}
|
||||
|
||||
void GameInteractor_ExecuteOnActorUpdate(void* actor) {
|
||||
GameInteractor::Instance->ExecuteHooks<GameInteractor::OnActorUpdate>(actor);
|
||||
GameInteractor::Instance->ExecuteHooksForID<GameInteractor::OnActorUpdate>(((Actor*)actor)->id, actor);
|
||||
|
@ -122,6 +129,13 @@ void GameInteractor_ExecuteOnActorKill(void* actor) {
|
|||
GameInteractor::Instance->ExecuteHooksForFilter<GameInteractor::OnActorKill>(actor);
|
||||
}
|
||||
|
||||
void GameInteractor_ExecuteOnActorDestroy(void* actor) {
|
||||
GameInteractor::Instance->ExecuteHooks<GameInteractor::OnActorDestroy>(actor);
|
||||
GameInteractor::Instance->ExecuteHooksForID<GameInteractor::OnActorDestroy>(((Actor*)actor)->id, actor);
|
||||
GameInteractor::Instance->ExecuteHooksForPtr<GameInteractor::OnActorDestroy>((uintptr_t)actor, actor);
|
||||
GameInteractor::Instance->ExecuteHooksForFilter<GameInteractor::OnActorDestroy>(actor);
|
||||
}
|
||||
|
||||
void GameInteractor_ExecuteOnEnemyDefeat(void* actor) {
|
||||
GameInteractor::Instance->ExecuteHooks<GameInteractor::OnEnemyDefeat>(actor);
|
||||
GameInteractor::Instance->ExecuteHooksForID<GameInteractor::OnEnemyDefeat>(((Actor*)actor)->id, actor);
|
||||
|
|
|
@ -29,8 +29,10 @@ void GameInteractor_ExecuteOnSetDoAction(uint16_t action);
|
|||
void GameInteractor_ExecuteOnOcarinaSongAction();
|
||||
void GameInteractor_ExecuteOnCuccoOrChickenHatch();
|
||||
void GameInteractor_ExecuteOnActorInit(void* actor);
|
||||
void GameInteractor_ExecuteOnActorSpawn(void* actor);
|
||||
void GameInteractor_ExecuteOnActorUpdate(void* actor);
|
||||
void GameInteractor_ExecuteOnActorKill(void* actor);
|
||||
void GameInteractor_ExecuteOnActorDestroy(void* actor);
|
||||
void GameInteractor_ExecuteOnEnemyDefeat(void* actor);
|
||||
void GameInteractor_ExecuteOnBossDefeat(void* actor);
|
||||
void GameInteractor_ExecuteOnTimestamp(u8 item);
|
||||
|
|
|
@ -112,7 +112,7 @@ void GameInteractor::RawAction::FreezePlayer() {
|
|||
void GameInteractor::RawAction::BurnPlayer() {
|
||||
Player* player = GET_PLAYER(gPlayState);
|
||||
for (int i = 0; i < 18; i++) {
|
||||
player->bodyFlameTimers[i] = Rand_S16Offset(0, 200);
|
||||
player->bodyFlameTimers[i] = static_cast<uint8_t>(Rand_S16Offset(0, 200));
|
||||
}
|
||||
player->bodyIsBurning = true;
|
||||
func_80837C0C(gPlayState, player, 0, 0, 0, 0, 0);
|
||||
|
@ -559,7 +559,7 @@ void GameInteractor::RawAction::SetRandomWind(bool active) {
|
|||
GameInteractor::State::RandomWindActive = 0;
|
||||
GameInteractor::State::RandomWindSecondsSinceLastDirectionChange = 0;
|
||||
player->pushedSpeed = 0.0f;
|
||||
player->pushedYaw = 0.0f;
|
||||
player->pushedYaw = 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -617,7 +617,7 @@ GameInteractionEffectQueryResult GameInteractor::RawAction::SpawnEnemyWithOffset
|
|||
}
|
||||
|
||||
// Generate point in random angle with a radius.
|
||||
float angle = Random(0, 2 * M_PI);
|
||||
float angle = static_cast<float>(RandomDouble() * 2 * M_PI);
|
||||
float radius = 150;
|
||||
float posXOffset = radius * cos(angle);
|
||||
float posZOffset = radius * sin(angle);
|
||||
|
|
|
@ -228,6 +228,14 @@ typedef enum {
|
|||
// - `*Actor` (interactRangeActor)
|
||||
VB_BOTTLE_ACTOR,
|
||||
|
||||
// #### `result`
|
||||
// ```c
|
||||
// true
|
||||
// ```
|
||||
// #### `args`
|
||||
// - `*EnPoField`
|
||||
VB_BOTTLE_BIG_POE,
|
||||
|
||||
// #### `result`
|
||||
// ```c
|
||||
// ((this->actor.params == DNS_TYPE_HEART_PIECE) && (Flags_GetItemGetInf(ITEMGETINF_DEKU_SCRUB_HEART_PIECE))) ||
|
||||
|
@ -331,6 +339,14 @@ typedef enum {
|
|||
// - None
|
||||
VB_CRAWL_SPEED_INCREASE,
|
||||
|
||||
// #### `result`
|
||||
// ```c
|
||||
// this->actionTimer == 0 && Rand_ZeroOne() < 0.03f
|
||||
// ```
|
||||
// #### `args`
|
||||
// - `*EnPoRelay`
|
||||
VB_DAMPE_DROP_FLAME,
|
||||
|
||||
// #### `result`
|
||||
// ```c
|
||||
// !Flags_GetItemGetInf(ITEMGETINF_1C)
|
||||
|
@ -462,6 +478,14 @@ typedef enum {
|
|||
// - `*int16_t` (item id)
|
||||
VB_DRAW_AMMO_COUNT,
|
||||
|
||||
// #### `result`
|
||||
// ```c
|
||||
// true
|
||||
// ```
|
||||
// #### `args`
|
||||
// - Player*
|
||||
VB_EMPTYING_BOTTLE,
|
||||
|
||||
// #### `result`
|
||||
// ```c
|
||||
// (Message_GetState(&play->msgCtx) == TEXT_STATE_EVENT) && Message_ShouldAdvance(play)
|
||||
|
@ -511,6 +535,14 @@ typedef enum {
|
|||
// - `*BgHeavyBlock`
|
||||
VB_FREEZE_LINK_FOR_BLOCK_THROW,
|
||||
|
||||
// #### `result`
|
||||
// ```c
|
||||
// true
|
||||
// ```
|
||||
// #### `args`
|
||||
// - None
|
||||
VB_FREEZE_LINK_FOR_FOREST_PILLARS,
|
||||
|
||||
// #### `result`
|
||||
// ```c
|
||||
// true
|
||||
|
@ -1395,6 +1427,14 @@ typedef enum {
|
|||
// - `*BgTreemouth`
|
||||
VB_PLAY_DEKU_TREE_INTRO_CS,
|
||||
|
||||
// #### `result`
|
||||
// ```c
|
||||
// true
|
||||
// ```
|
||||
// #### `args`
|
||||
// - `*DemoKekkai`
|
||||
VB_PLAY_DISPEL_BARRIER_CS,
|
||||
|
||||
// #### `result`
|
||||
// ```c
|
||||
// true
|
||||
|
@ -1459,6 +1499,15 @@ typedef enum {
|
|||
// - None
|
||||
VB_PLAY_FIRE_ARROW_CS,
|
||||
|
||||
// #### `result`
|
||||
// ```c
|
||||
// true
|
||||
// ```
|
||||
// #### `args`
|
||||
// - `*EnHeishi2`
|
||||
// - `bool` (clearCamera - true if the code clears a sub-camera, false otherwise)
|
||||
VB_PLAY_GATE_OPENING_OR_CLOSING_CS,
|
||||
|
||||
// #### `result`
|
||||
// ```c
|
||||
// true
|
||||
|
@ -1700,6 +1749,14 @@ typedef enum {
|
|||
// - `*EnRu1`
|
||||
VB_RUTO_WANT_TO_BE_TOSSED_TO_SAPPHIRE,
|
||||
|
||||
// #### `result`
|
||||
// ```c
|
||||
// true
|
||||
// ```
|
||||
// #### `args`
|
||||
// - `*EnGb`
|
||||
VB_SELL_POES_TO_POE_COLLECTOR,
|
||||
|
||||
// #### `result`
|
||||
// ```c
|
||||
// true
|
||||
|
@ -1827,6 +1884,14 @@ typedef enum {
|
|||
// - `*ObjBean`
|
||||
VB_SPAWN_BEAN_STALK_FAIRIES,
|
||||
|
||||
// #### `result`
|
||||
// ```c
|
||||
// this->timer >= 60
|
||||
// ```
|
||||
// #### `args`
|
||||
// - `None`
|
||||
VB_SPAWN_BEAN_SKULLTULA,
|
||||
|
||||
// #### `result`
|
||||
// ```c
|
||||
// true
|
||||
|
|
|
@ -12,7 +12,6 @@
|
|||
#include "soh/Enhancements/randomizer/3drando/random.hpp"
|
||||
#include "soh/Enhancements/cosmetics/authenticGfxPatches.h"
|
||||
#include <soh/Enhancements/item-tables/ItemTableManager.h>
|
||||
#include "soh/Enhancements/nametag.h"
|
||||
#include "soh/Enhancements/timesaver_hook_handlers.h"
|
||||
#include "soh/Enhancements/TimeSavers/TimeSavers.h"
|
||||
#include "soh/Enhancements/randomizer/hook_handlers.h"
|
||||
|
@ -135,38 +134,6 @@ void RegisterOcarinaTimeTravel() {
|
|||
});
|
||||
}
|
||||
|
||||
void RegisterShadowTag() {
|
||||
static bool shouldSpawn = false;
|
||||
static uint16_t delayTimer = 60;
|
||||
|
||||
GameInteractor::Instance->RegisterGameHook<GameInteractor::OnPlayerUpdate>([]() {
|
||||
if (!CVarGetInteger(CVAR_ENHANCEMENT("ShadowTag"), 0)) {
|
||||
return;
|
||||
}
|
||||
if (gPlayState->sceneNum == SCENE_FOREST_TEMPLE && // Forest Temple Scene
|
||||
gPlayState->roomCtx.curRoom.num == 16 || // Green Poe Room
|
||||
gPlayState->roomCtx.curRoom.num == 13 || // Blue Poe Room
|
||||
gPlayState->roomCtx.curRoom.num == 12) { // Red Poe Room
|
||||
return;
|
||||
} else {
|
||||
if (shouldSpawn && (delayTimer <= 0)) {
|
||||
Actor_Spawn(&gPlayState->actorCtx, gPlayState, ACTOR_EN_WALLMAS, 0, 0, 0, 0, 0, 0, 3, false);
|
||||
shouldSpawn = false;
|
||||
} else {
|
||||
delayTimer--;
|
||||
}
|
||||
}
|
||||
});
|
||||
GameInteractor::Instance->RegisterGameHook<GameInteractor::OnSceneSpawnActors>([]() {
|
||||
shouldSpawn = true;
|
||||
delayTimer = 60;
|
||||
});
|
||||
GameInteractor::Instance->RegisterGameHook<GameInteractor::OnSceneInit>([](int16_t sceneNum) {
|
||||
shouldSpawn = true;
|
||||
delayTimer = 60;
|
||||
});
|
||||
}
|
||||
|
||||
static bool hasAffectedHealth = false;
|
||||
void UpdatePermanentHeartLossState() {
|
||||
if (!GameInteractor::IsSaveLoaded())
|
||||
|
@ -219,65 +186,6 @@ void RegisterDeleteFileOnDeath() {
|
|||
});
|
||||
}
|
||||
|
||||
struct DayTimeGoldSkulltulas {
|
||||
uint16_t scene;
|
||||
uint16_t room;
|
||||
bool forChild;
|
||||
std::vector<ActorEntry> actorEntries;
|
||||
};
|
||||
|
||||
using DayTimeGoldSkulltulasList = std::vector<DayTimeGoldSkulltulas>;
|
||||
|
||||
void RegisterDaytimeGoldSkultullas() {
|
||||
GameInteractor::Instance->RegisterGameHook<GameInteractor::OnSceneSpawnActors>([]() {
|
||||
if (!CVarGetInteger(CVAR_ENHANCEMENT("NightGSAlwaysSpawn"), 0)) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Gold Skulltulas that are not part of the scene actor list during the day
|
||||
// Actor values copied from the night time scene actor list
|
||||
static const DayTimeGoldSkulltulasList dayTimeGoldSkulltulas = {
|
||||
// Graveyard
|
||||
{ SCENE_GRAVEYARD, 1, true, { { ACTOR_EN_SW, { 156, 315, 795 }, { 16384, -32768, 0 }, -20096 } } },
|
||||
// ZF
|
||||
{ SCENE_ZORAS_FOUNTAIN, 0, true, { { ACTOR_EN_SW, { -1891, 187, 1911 }, { 16384, 18022, 0 }, -19964 } } },
|
||||
// GF
|
||||
{ SCENE_GERUDOS_FORTRESS,
|
||||
0,
|
||||
false,
|
||||
{ { ACTOR_EN_SW, { 1598, 999, -2008 }, { 16384, -16384, 0 }, -19198 } } },
|
||||
{ SCENE_GERUDOS_FORTRESS, 1, false, { { ACTOR_EN_SW, { 3377, 1734, -4935 }, { 16384, 0, 0 }, -19199 } } },
|
||||
// Kak
|
||||
{ SCENE_KAKARIKO_VILLAGE, 0, false, { { ACTOR_EN_SW, { -18, 540, 1800 }, { 0, -32768, 0 }, -20160 } } },
|
||||
{ SCENE_KAKARIKO_VILLAGE,
|
||||
0,
|
||||
true,
|
||||
{ { ACTOR_EN_SW, { -465, 377, -888 }, { 0, 28217, 0 }, -20222 },
|
||||
{ ACTOR_EN_SW, { 5, 686, -171 }, { 0, -32768, 0 }, -20220 },
|
||||
{ ACTOR_EN_SW, { 324, 270, 905 }, { 16384, 0, 0 }, -20216 },
|
||||
{ ACTOR_EN_SW, { -602, 120, 1120 }, { 16384, 0, 0 }, -20208 } } },
|
||||
// LLR
|
||||
{ SCENE_LON_LON_RANCH,
|
||||
0,
|
||||
true,
|
||||
{ { ACTOR_EN_SW, { -2344, 180, 672 }, { 16384, 22938, 0 }, -29695 },
|
||||
{ ACTOR_EN_SW, { 808, 48, 326 }, { 16384, 0, 0 }, -29694 },
|
||||
{ ACTOR_EN_SW, { 997, 286, -2698 }, { 16384, -16384, 0 }, -29692 } } },
|
||||
};
|
||||
|
||||
for (const auto& dayTimeGS : dayTimeGoldSkulltulas) {
|
||||
if (IS_DAY && dayTimeGS.forChild == LINK_IS_CHILD && dayTimeGS.scene == gPlayState->sceneNum &&
|
||||
dayTimeGS.room == gPlayState->roomCtx.curRoom.num) {
|
||||
for (const auto& actorEntry : dayTimeGS.actorEntries) {
|
||||
Actor_Spawn(&gPlayState->actorCtx, gPlayState, actorEntry.id, actorEntry.pos.x, actorEntry.pos.y,
|
||||
actorEntry.pos.z, actorEntry.rot.x, actorEntry.rot.y, actorEntry.rot.z,
|
||||
actorEntry.params, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
bool IsHyperBossesActive() {
|
||||
return CVarGetInteger(CVAR_ENHANCEMENT("HyperBosses"), 0) ||
|
||||
(IS_BOSS_RUSH &&
|
||||
|
@ -1049,8 +957,6 @@ void InitMods() {
|
|||
TimeSavers_Register();
|
||||
RegisterTTS();
|
||||
RegisterOcarinaTimeTravel();
|
||||
RegisterDaytimeGoldSkultullas();
|
||||
RegisterShadowTag();
|
||||
RegisterPermanentHeartLoss();
|
||||
RegisterDeleteFileOnDeath();
|
||||
RegisterHyperBosses();
|
||||
|
@ -1064,7 +970,6 @@ void InitMods() {
|
|||
RegisterRandomizedEnemySizes();
|
||||
RegisterOpenAllHours();
|
||||
RegisterToTMedallions();
|
||||
NameTag_RegisterHooks();
|
||||
RegisterFloorSwitchesHook();
|
||||
RegisterPatchHandHandler();
|
||||
RegisterHurtContainerModeHandler();
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
#include "soh/frame_interpolation.h"
|
||||
#include "soh/Enhancements/custom-message/CustomMessageInterfaceAddon.h"
|
||||
#include "soh/Enhancements/game-interactor/GameInteractor.h"
|
||||
#include "soh/OTRGlobals.h"
|
||||
#include "soh/ShipUtils.h"
|
||||
|
||||
extern "C" {
|
||||
#include "z64.h"
|
||||
|
@ -26,12 +26,16 @@ typedef struct {
|
|||
int16_t height; // Textbox height
|
||||
int16_t width; // Textbox width
|
||||
int16_t yOffset; // Addition Y offset
|
||||
uint8_t noZBuffer; // Allow rendering over geometry
|
||||
Mtx* mtx; // Allocated Mtx for rendering
|
||||
Vtx* vtx; // Allocated Vtx for rendering
|
||||
} NameTag;
|
||||
|
||||
static std::vector<NameTag> nameTags;
|
||||
static std::vector<Gfx> nameTagDl;
|
||||
static bool sMirrorWorldActive = false;
|
||||
|
||||
void NameTag_RegisterHooks();
|
||||
|
||||
void FreeNameTag(NameTag* nameTag) {
|
||||
if (nameTag->vtx != nullptr) {
|
||||
|
@ -51,14 +55,14 @@ void DrawNameTag(PlayState* play, const NameTag* nameTag) {
|
|||
}
|
||||
|
||||
// Name tag is too far away to meaningfully read, don't bother rendering it
|
||||
if (nameTag->actor->xyzDistToPlayerSq > 200000.0f) {
|
||||
if (nameTag->actor->xyzDistToPlayerSq > 440000.0f) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Fade out name tags that are far away
|
||||
float alpha = 1.0f;
|
||||
if (nameTag->actor->xyzDistToPlayerSq > 160000.0f) {
|
||||
alpha = (200000.0f - nameTag->actor->xyzDistToPlayerSq) / 40000.0f;
|
||||
if (nameTag->actor->xyzDistToPlayerSq > 360000.0f) {
|
||||
alpha = (440000.0f - nameTag->actor->xyzDistToPlayerSq) / 80000.0f;
|
||||
}
|
||||
|
||||
float scale = 75.0f / 100.f;
|
||||
|
@ -79,7 +83,7 @@ void DrawNameTag(PlayState* play, const NameTag* nameTag) {
|
|||
textColor = CVarGetColor(CVAR_COSMETIC("HUD.NameTagActorText.Value"), textColor);
|
||||
}
|
||||
|
||||
FrameInterpolation_RecordOpenChild(nameTag->actor, 10);
|
||||
FrameInterpolation_RecordOpenChild(nameTag->actor, 0);
|
||||
|
||||
// Prefer the highest between world position and focus position if targetable
|
||||
float posY = nameTag->actor->world.pos.y;
|
||||
|
@ -92,7 +96,7 @@ void DrawNameTag(PlayState* play, const NameTag* nameTag) {
|
|||
// Set position, billboard effect, scale (with mirror mode), then center nametag
|
||||
Matrix_Translate(nameTag->actor->world.pos.x, posY, nameTag->actor->world.pos.z, MTXMODE_NEW);
|
||||
Matrix_ReplaceRotation(&play->billboardMtxF);
|
||||
Matrix_Scale(scale * (CVarGetInteger(CVAR_ENHANCEMENT("MirroredWorld"), 0) ? -1 : 1), -scale, 1.0f, MTXMODE_APPLY);
|
||||
Matrix_Scale(scale * (sMirrorWorldActive ? -1.0f : 1.0f), -scale, 1.0f, MTXMODE_APPLY);
|
||||
Matrix_Translate(-(float)nameTag->width / 2, -nameTag->height, 0, MTXMODE_APPLY);
|
||||
Matrix_ToMtx(nameTag->mtx, (char*)__FILE__, __LINE__);
|
||||
|
||||
|
@ -154,15 +158,27 @@ void DrawNameTags() {
|
|||
OPEN_DISPS(gPlayState->state.gfxCtx);
|
||||
|
||||
// Setup before rendering name tags
|
||||
Gfx_SetupDL_38Xlu(gPlayState->state.gfxCtx);
|
||||
nameTagDl.push_back(gsDPSetAlphaDither(G_AD_DISABLE));
|
||||
nameTagDl.push_back(gsSPClearGeometryMode(G_SHADE));
|
||||
POLY_XLU_DISP = Gfx_SetupDL_39(POLY_XLU_DISP);
|
||||
|
||||
nameTagDl.push_back(gsDPSetAlphaCompare(G_AC_NONE));
|
||||
nameTagDl.push_back(
|
||||
gsDPSetCombineLERP(0, 0, 0, PRIMITIVE, TEXEL0, 0, PRIMITIVE, 0, 0, 0, 0, PRIMITIVE, TEXEL0, 0, PRIMITIVE, 0));
|
||||
|
||||
bool zbufferEnabled = false;
|
||||
|
||||
// Add all the name tags
|
||||
for (const auto& nameTag : nameTags) {
|
||||
// Toggle ZBuffer mode based on last state and next tag
|
||||
if (zbufferEnabled == nameTag.noZBuffer) {
|
||||
if (nameTag.noZBuffer) {
|
||||
nameTagDl.push_back(gsSPClearGeometryMode(G_ZBUFFER));
|
||||
zbufferEnabled = false;
|
||||
} else {
|
||||
nameTagDl.push_back(gsSPSetGeometryMode(G_ZBUFFER));
|
||||
zbufferEnabled = true;
|
||||
}
|
||||
}
|
||||
|
||||
DrawNameTag(gPlayState, &nameTag);
|
||||
}
|
||||
|
||||
|
@ -189,22 +205,22 @@ void UpdateNameTags() {
|
|||
|
||||
return aDistToCamera > bDistToCamera;
|
||||
});
|
||||
|
||||
sMirrorWorldActive = CVarGetInteger(CVAR_ENHANCEMENT("MirroredWorld"), 0);
|
||||
}
|
||||
|
||||
extern "C" void NameTag_RegisterForActorWithOptions(Actor* actor, const char* text, NameTagOptions options) {
|
||||
std::string processedText = std::string(Interface_ReplaceSpecialCharacters((char*)text));
|
||||
|
||||
// Strip out unsupported characters
|
||||
processedText.erase(std::remove_if(processedText.begin(), processedText.end(),
|
||||
[](const char& c) {
|
||||
// 172 is max supported texture for the in-game font system,
|
||||
// and filter anything less than a space but not the newline or nul
|
||||
// characters
|
||||
return (unsigned char)c > 172 || (c < ' ' && c != '\n' && c != '\0');
|
||||
}),
|
||||
processedText.end());
|
||||
// 172 is max supported texture for the in-game font system,
|
||||
// and filter anything less than a space but not the newline or nul characters
|
||||
processedText.erase(
|
||||
std::remove_if(processedText.begin(), processedText.end(),
|
||||
[](const char& c) { return (uint8_t)c > 172 || (c < ' ' && c != '\n' && c != '\0'); }),
|
||||
processedText.end());
|
||||
|
||||
int16_t numChar = processedText.length();
|
||||
size_t numChar = processedText.length();
|
||||
int16_t numLines = 1;
|
||||
int16_t offsetX = 0;
|
||||
int16_t maxOffsetX = 0;
|
||||
|
@ -213,7 +229,7 @@ extern "C" void NameTag_RegisterForActorWithOptions(Actor* actor, const char* te
|
|||
Vtx* vertices = (Vtx*)calloc(sizeof(Vtx[4]), numChar + 1);
|
||||
|
||||
// Set all the char vtx first to get the total size for the textbox
|
||||
for (int16_t i = 0; i < numChar; i++) {
|
||||
for (size_t i = 0; i < numChar; i++) {
|
||||
if (processedText[i] == '\n') {
|
||||
offsetX = 0;
|
||||
numLines++;
|
||||
|
@ -249,10 +265,13 @@ extern "C" void NameTag_RegisterForActorWithOptions(Actor* actor, const char* te
|
|||
nameTag.height = height;
|
||||
nameTag.width = width;
|
||||
nameTag.yOffset = options.yOffset;
|
||||
nameTag.noZBuffer = options.noZBuffer;
|
||||
nameTag.mtx = new Mtx();
|
||||
nameTag.vtx = vertices;
|
||||
|
||||
nameTags.push_back(nameTag);
|
||||
|
||||
NameTag_RegisterHooks();
|
||||
}
|
||||
|
||||
extern "C" void NameTag_RegisterForActor(Actor* actor, const char* text) {
|
||||
|
@ -268,6 +287,8 @@ extern "C" void NameTag_RemoveAllForActor(Actor* actor) {
|
|||
it++;
|
||||
}
|
||||
}
|
||||
|
||||
NameTag_RegisterHooks();
|
||||
}
|
||||
|
||||
extern "C" void NameTag_RemoveAllByTag(const char* tag) {
|
||||
|
@ -279,6 +300,8 @@ extern "C" void NameTag_RemoveAllByTag(const char* tag) {
|
|||
it++;
|
||||
}
|
||||
}
|
||||
|
||||
NameTag_RegisterHooks();
|
||||
}
|
||||
|
||||
void RemoveAllNameTags() {
|
||||
|
@ -287,23 +310,49 @@ void RemoveAllNameTags() {
|
|||
}
|
||||
|
||||
nameTags.clear();
|
||||
|
||||
NameTag_RegisterHooks();
|
||||
}
|
||||
|
||||
static bool sRegisteredHooks = false;
|
||||
|
||||
void NameTag_RegisterHooks() {
|
||||
if (sRegisteredHooks) {
|
||||
static HOOK_ID gameStatUpdateHookID = 0;
|
||||
static HOOK_ID drawHookID = 0;
|
||||
static HOOK_ID playDestroyHookID = 0;
|
||||
static HOOK_ID actorDestroyHookID = 0;
|
||||
static bool sRegisteredHooks = false;
|
||||
|
||||
// Hooks already (un)registered based on nametags
|
||||
if ((nameTags.size() > 0) == sRegisteredHooks) {
|
||||
return;
|
||||
}
|
||||
|
||||
GameInteractor::Instance->UnregisterGameHook<GameInteractor::OnGameFrameUpdate>(gameStatUpdateHookID);
|
||||
GameInteractor::Instance->UnregisterGameHook<GameInteractor::OnPlayDrawEnd>(drawHookID);
|
||||
GameInteractor::Instance->UnregisterGameHook<GameInteractor::OnPlayDestroy>(playDestroyHookID);
|
||||
GameInteractor::Instance->UnregisterGameHook<GameInteractor::OnActorDestroy>(actorDestroyHookID);
|
||||
gameStatUpdateHookID = 0;
|
||||
drawHookID = 0;
|
||||
playDestroyHookID = 0;
|
||||
actorDestroyHookID = 0;
|
||||
sRegisteredHooks = false;
|
||||
|
||||
if (nameTags.size() == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
sRegisteredHooks = true;
|
||||
|
||||
// Reorder tags every frame to mimic depth rendering
|
||||
GameInteractor::Instance->RegisterGameHook<GameInteractor::OnGameFrameUpdate>([]() { UpdateNameTags(); });
|
||||
gameStatUpdateHookID =
|
||||
GameInteractor::Instance->RegisterGameHook<GameInteractor::OnGameFrameUpdate>(UpdateNameTags);
|
||||
|
||||
// Render name tags at the end of player draw to avoid overflowing the display buffers
|
||||
GameInteractor::Instance->RegisterGameHook<GameInteractor::OnPlayDrawEnd>([]() { DrawNameTags(); });
|
||||
// Render name tags at the end of the Play World drawing
|
||||
drawHookID = GameInteractor::Instance->RegisterGameHook<GameInteractor::OnPlayDrawEnd>(DrawNameTags);
|
||||
|
||||
// Remove all name tags on play state destroy as all actors are removed anyways
|
||||
GameInteractor::Instance->RegisterGameHook<GameInteractor::OnPlayDestroy>([]() { RemoveAllNameTags(); });
|
||||
playDestroyHookID = GameInteractor::Instance->RegisterGameHook<GameInteractor::OnPlayDestroy>(RemoveAllNameTags);
|
||||
|
||||
// Remove all name tags for actor on destroy
|
||||
actorDestroyHookID = GameInteractor::Instance->RegisterGameHook<GameInteractor::OnActorDestroy>(
|
||||
[](void* actor) { NameTag_RemoveAllForActor((Actor*)actor); });
|
||||
}
|
||||
|
|
|
@ -1,11 +1,16 @@
|
|||
#ifndef _NAMETAG_H_
|
||||
#define _NAMETAG_H_
|
||||
#include <z64.h>
|
||||
#ifndef NAMETAG_H
|
||||
#define NAMETAG_H
|
||||
|
||||
#include <libultraship/color.h>
|
||||
#include <libultraship/libultra.h>
|
||||
|
||||
struct Actor;
|
||||
|
||||
typedef struct {
|
||||
const char* tag; // Tag identifier to filter/remove multiple tags
|
||||
int16_t yOffset; // Additional Y offset to apply for the name tag
|
||||
Color_RGBA8 textColor; // Text color override. Global color is used if alpha is 0
|
||||
uint8_t noZBuffer; // Allow rendering over geometry
|
||||
} NameTagOptions;
|
||||
|
||||
// Register required hooks for nametags on startup
|
||||
|
@ -28,4 +33,4 @@ void NameTag_RemoveAllByTag(const char* tag);
|
|||
}
|
||||
#endif
|
||||
|
||||
#endif // _NAMETAG_H_
|
||||
#endif // NAMETAG_H
|
||||
|
|
|
@ -159,11 +159,6 @@ static void ValidateOtherEntrance(GetAccessibleLocationsStruct& gals) {
|
|||
ApplyStartingInventory(); // RANDOTODO when proper ammo logic is done, this could be moved to the start
|
||||
}
|
||||
}
|
||||
// If we are not shuffling the guard house, add the key so we can properly check for poe merchant access
|
||||
if (gals.validatedStartingRegion && gals.foundTempleOfTime &&
|
||||
ctx->GetOption(RSK_SHUFFLE_INTERIOR_ENTRANCES).Is(RO_INTERIOR_ENTRANCE_SHUFFLE_OFF)) {
|
||||
Rando::StaticData::RetrieveItem(RG_GUARD_HOUSE_KEY).ApplyEffect();
|
||||
}
|
||||
}
|
||||
|
||||
// Apply all items that are necessary for checking all location access
|
||||
|
@ -180,10 +175,7 @@ static void ApplyAllAdvancmentItems() {
|
|||
static void ValidateSphereZero(GetAccessibleLocationsStruct& gals) {
|
||||
auto ctx = Rando::Context::GetInstance();
|
||||
// Condition for verifying everything required for sphere 0, expanding search to all locations
|
||||
if ((!logic->AreCheckingBigPoes || logic->CanEmptyBigPoes) && gals.validatedStartingRegion &&
|
||||
gals.foundTempleOfTime && gals.haveTimeAccess) {
|
||||
// stop checking for big poes
|
||||
logic->AreCheckingBigPoes = false;
|
||||
if (gals.validatedStartingRegion && gals.foundTempleOfTime && gals.haveTimeAccess) {
|
||||
// Apply all items that are necessary for checking all location access
|
||||
ApplyAllAdvancmentItems();
|
||||
// Reset access as the non-starting age
|
||||
|
@ -213,7 +205,7 @@ void ProcessExits(Region* region, GetAccessibleLocationsStruct& gals, Randomizer
|
|||
// Update Time of Day Access for the exit
|
||||
if (UpdateToDAccess(&exit, exitRegion)) {
|
||||
gals.logicUpdated = true;
|
||||
if (!gals.sphereZeroComplete || logic->AreCheckingBigPoes) {
|
||||
if (!gals.sphereZeroComplete) {
|
||||
if (!gals.foundTempleOfTime || !gals.validatedStartingRegion) {
|
||||
ValidateOtherEntrance(gals);
|
||||
}
|
||||
|
@ -596,15 +588,12 @@ bool CheckBeatable(RandomizerGet ignore /* = RG_NONE*/) {
|
|||
}
|
||||
|
||||
// Check if the currently randomised set of entrances is a valid game map.
|
||||
void ValidateEntrances(bool checkPoeCollectorAccess, bool checkOtherEntranceAccess) {
|
||||
void ValidateEntrances(bool checkOtherEntranceAccess) {
|
||||
auto ctx = Rando::Context::GetInstance();
|
||||
GetAccessibleLocationsStruct gals(0);
|
||||
ResetLogic(ctx, gals, !checkOtherEntranceAccess);
|
||||
|
||||
ctx->allLocationsReachable = false;
|
||||
if (checkPoeCollectorAccess) {
|
||||
logic->AreCheckingBigPoes = true;
|
||||
}
|
||||
|
||||
if (checkOtherEntranceAccess) {
|
||||
gals.foundTempleOfTime = false;
|
||||
|
@ -620,11 +609,6 @@ void ValidateEntrances(bool checkPoeCollectorAccess, bool checkOtherEntranceAcce
|
|||
RegionTable(RR_ROOT)->adultNight = true;
|
||||
RegionTable(RR_ROOT)->childDay = true;
|
||||
RegionTable(RR_ROOT)->adultDay = true;
|
||||
} else if (checkPoeCollectorAccess) {
|
||||
// If we are not shuffling the guard house, add the key so we can properly check for poe merchant access
|
||||
if (ctx->GetOption(RSK_SHUFFLE_INTERIOR_ENTRANCES).Is(RO_INTERIOR_ENTRANCE_SHUFFLE_OFF)) {
|
||||
Rando::StaticData::RetrieveItem(RG_GUARD_HOUSE_KEY).ApplyEffect();
|
||||
}
|
||||
} else {
|
||||
ApplyAllAdvancmentItems();
|
||||
}
|
||||
|
@ -710,11 +694,11 @@ static void PareDownPlaythrough() {
|
|||
auto ctx = Rando::Context::GetInstance();
|
||||
std::vector<RandomizerCheck> toAddBackItem;
|
||||
// Start at sphere before Ganon's and count down
|
||||
for (int i = ctx->playthroughLocations.size() - 2; i >= 0; i--) {
|
||||
for (int32_t i = static_cast<int32_t>(ctx->playthroughLocations.size()) - 2; i >= 0; i--) {
|
||||
// Check each item location in sphere
|
||||
std::vector<int> erasableIndices;
|
||||
std::vector<RandomizerCheck> sphere = ctx->playthroughLocations.at(i);
|
||||
for (int j = sphere.size() - 1; j >= 0; j--) {
|
||||
for (int32_t j = static_cast<int32_t>(sphere.size()) - 1; j >= 0; j--) {
|
||||
RandomizerCheck loc = sphere.at(j);
|
||||
RandomizerGet locGet = ctx->GetItemLocation(loc)->GetPlacedRandomizerGet(); // Copy out item
|
||||
|
||||
|
|
|
@ -72,4 +72,4 @@ void GeneratePlaythrough();
|
|||
|
||||
bool CheckBeatable(RandomizerGet ignore = RG_NONE);
|
||||
|
||||
void ValidateEntrances(bool checkPoeCollectorAccess, bool checkOtherEntranceAccess);
|
||||
void ValidateEntrances(bool checkOtherEntranceAccess);
|
||||
|
|
|
@ -2467,13 +2467,13 @@ void StaticData::HintTable_Init() {
|
|||
/*german*/ "ein abgelegener Ort",
|
||||
/*french*/ "un lieu isolé"));
|
||||
|
||||
hintTextTable[RHT_DUNGEON_ORDINARY] = HintText(CustomMessage(" It's ordinary.",
|
||||
/*german*/ "&Sieht aus wie immer.",
|
||||
/*french*/ "&Elle vous semble %rordinaire%w."));
|
||||
hintTextTable[RHT_DUNGEON_ORDINARY] = HintText(CustomMessage("&It's %gordinary%w.",
|
||||
/*german*/ "&Sieht aus %gwie immer%w.",
|
||||
/*french*/ "&Elle vous semble %gordinaire%w."));
|
||||
|
||||
hintTextTable[RHT_DUNGEON_MASTERFUL] = HintText(CustomMessage(" It's masterful!",
|
||||
/*german*/ "&Man kann darauf die Worte&%r\"Master Quest\"%w entziffern...",
|
||||
/*french*/ "&Étrange... les mots %r\"Master&Quest\"%w sont gravés dessus."));
|
||||
hintTextTable[RHT_DUNGEON_MASTERFUL] = HintText(CustomMessage("&It's %rmasterful%w!",
|
||||
/*german*/ "&Man kann darauf die Worte %r\"Master_Quest\"%w entziffern...",
|
||||
/*french*/ "&Étrange... les mots %r\"Master_Quest\"%w sont gravés dessus."));
|
||||
|
||||
// clang-format on
|
||||
}
|
||||
|
|
|
@ -40,7 +40,7 @@ const CustomMessage& HintText::GetObscure() const {
|
|||
return obscureText.size() > 0 ? RandomElement(obscureText) : clearText;
|
||||
}
|
||||
|
||||
const CustomMessage& HintText::GetObscure(uint8_t selection) const {
|
||||
const CustomMessage& HintText::GetObscure(size_t selection) const {
|
||||
if (obscureText.size() > selection) {
|
||||
return obscureText[selection];
|
||||
} else if (obscureText.size() > 0) {
|
||||
|
@ -53,7 +53,7 @@ const CustomMessage& HintText::GetAmbiguous() const {
|
|||
return ambiguousText.size() > 0 ? RandomElement(ambiguousText) : clearText;
|
||||
}
|
||||
|
||||
const CustomMessage& HintText::GetAmbiguous(uint8_t selection) const {
|
||||
const CustomMessage& HintText::GetAmbiguous(size_t selection) const {
|
||||
if (ambiguousText.size() > selection) {
|
||||
return ambiguousText[selection];
|
||||
} else if (ambiguousText.size() > 0) {
|
||||
|
@ -62,15 +62,15 @@ const CustomMessage& HintText::GetAmbiguous(uint8_t selection) const {
|
|||
return clearText;
|
||||
}
|
||||
|
||||
uint8_t HintText::GetAmbiguousSize() const {
|
||||
size_t HintText::GetAmbiguousSize() const {
|
||||
return ambiguousText.size();
|
||||
}
|
||||
|
||||
uint8_t HintText::GetObscureSize() const {
|
||||
size_t HintText::GetObscureSize() const {
|
||||
return obscureText.size();
|
||||
}
|
||||
|
||||
const CustomMessage& HintText::GetHintMessage(uint8_t selection) const {
|
||||
const CustomMessage& HintText::GetHintMessage(size_t selection) const {
|
||||
auto ctx = Rando::Context::GetInstance();
|
||||
if (ctx->GetOption(RSK_HINT_CLARITY).Is(RO_HINT_CLARITY_OBSCURE)) {
|
||||
return GetObscure(selection);
|
||||
|
@ -273,8 +273,8 @@ std::vector<std::pair<RandomizerCheck, std::function<bool()>>> conditionalAlways
|
|||
std::make_pair(RC_MARKET_10_BIG_POES,
|
||||
[]() {
|
||||
auto ctx = Rando::Context::GetInstance();
|
||||
return ctx->GetOption(RSK_BIG_POE_COUNT).Get() >= 3 && !ctx->GetOption(RSK_BIG_POES_HINT);
|
||||
}), // Remember, the option's value being 3 means 4 are required
|
||||
return ctx->GetOption(RSK_BIG_POE_COUNT).Get() > 3 && !ctx->GetOption(RSK_BIG_POES_HINT);
|
||||
}),
|
||||
std::make_pair(RC_DEKU_THEATER_MASK_OF_TRUTH,
|
||||
[]() {
|
||||
auto ctx = Rando::Context::GetInstance();
|
||||
|
@ -598,7 +598,7 @@ static void DistributeHints(std::vector<uint8_t>& selected, size_t stoneCount,
|
|||
}
|
||||
// if stones are left, assign junk to every remaining stone as a fallback.
|
||||
if (stoneCount > 0) {
|
||||
selected[selected.size() - 1] += stoneCount;
|
||||
selected[static_cast<uint8_t>(selected.size()) - 1] += static_cast<uint8_t>(stoneCount);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -37,12 +37,12 @@ class HintText {
|
|||
std::vector<CustomMessage> obscureText_ = {});
|
||||
const CustomMessage& GetClear() const;
|
||||
const CustomMessage& GetObscure() const;
|
||||
const CustomMessage& GetObscure(uint8_t selection) const;
|
||||
const CustomMessage& GetObscure(size_t selection) const;
|
||||
const CustomMessage& GetAmbiguous() const;
|
||||
const CustomMessage& GetAmbiguous(uint8_t selection) const;
|
||||
uint8_t GetAmbiguousSize() const;
|
||||
uint8_t GetObscureSize() const;
|
||||
const CustomMessage& GetHintMessage(uint8_t selection = 0) const;
|
||||
const CustomMessage& GetAmbiguous(size_t selection) const;
|
||||
size_t GetAmbiguousSize() const;
|
||||
size_t GetObscureSize() const;
|
||||
const CustomMessage& GetHintMessage(size_t selection = 0) const;
|
||||
const CustomMessage GetMessageCopy() const;
|
||||
bool operator==(const HintText& right) const;
|
||||
bool operator!=(const HintText& right) const;
|
||||
|
|
|
@ -325,7 +325,7 @@ RandomizerGet GetJunkItem() {
|
|||
return RandomElement(JunkPoolItems);
|
||||
}
|
||||
// Ice Trap is the last item in JunkPoolItems, so subtract 1 to never hit that index
|
||||
uint8_t idx = Random(0, JunkPoolItems.size() - 1);
|
||||
uint8_t idx = Random(0, static_cast<uint32_t>(JunkPoolItems.size()) - 1);
|
||||
return JunkPoolItems[idx];
|
||||
}
|
||||
|
||||
|
|
|
@ -27,7 +27,7 @@ bool GenerateRandomizer(std::set<RandomizerCheck> excludedLocations, std::set<Ra
|
|||
ResetPerformanceTimers();
|
||||
StartPerformanceTimer(PT_WHOLE_SEED);
|
||||
|
||||
srand(time(NULL));
|
||||
srand(static_cast<uint32_t>(time(NULL)));
|
||||
// if a blank seed was entered, make a random one
|
||||
if (seedInput.empty()) {
|
||||
seedInput = std::to_string(rand() % 0xFFFFFFFF);
|
||||
|
@ -35,7 +35,7 @@ bool GenerateRandomizer(std::set<RandomizerCheck> excludedLocations, std::set<Ra
|
|||
int count;
|
||||
try {
|
||||
count = std::stoi(seedInput.substr(18), nullptr);
|
||||
} catch (std::invalid_argument& e) { count = 1; } catch (std::out_of_range& e) {
|
||||
} catch (std::invalid_argument&) { count = 1; } catch (std::out_of_range&) {
|
||||
count = 1;
|
||||
}
|
||||
Playthrough::Playthrough_Repeat(excludedLocations, enabledTricks, count);
|
||||
|
|
|
@ -14,8 +14,7 @@ void Random_Init(uint32_t seed) {
|
|||
generator = boost::random::mt19937{ seed };
|
||||
}
|
||||
|
||||
// Returns a random integer in range [min, max-1]
|
||||
uint32_t Random(int min, int max) {
|
||||
void Random_InitSeed() {
|
||||
if (!init) {
|
||||
// No seed given, get a random number from device to seed
|
||||
#if !defined(__SWITCH__) && !defined(__WIIU__)
|
||||
|
@ -25,11 +24,16 @@ uint32_t Random(int min, int max) {
|
|||
#endif
|
||||
Random_Init(seed);
|
||||
}
|
||||
}
|
||||
|
||||
// Returns a random unsigned integer in range [min, max-1]
|
||||
uint32_t Random(uint32_t min, uint32_t max) {
|
||||
Random_InitSeed();
|
||||
boost::random::uniform_int_distribution<uint32_t> distribution(min, max - 1);
|
||||
return distribution(generator);
|
||||
}
|
||||
|
||||
// Returns a random floating point number in [0.0, 1.0]
|
||||
// Returns a random floating point number in [0.0, 1.0)
|
||||
double RandomDouble() {
|
||||
boost::random::uniform_real_distribution<double> distribution(0.0, 1.0);
|
||||
return distribution(generator);
|
||||
|
|
|
@ -8,12 +8,12 @@
|
|||
#include <set>
|
||||
|
||||
void Random_Init(uint32_t seed);
|
||||
uint32_t Random(int min, int max);
|
||||
uint32_t Random(uint32_t min, uint32_t max);
|
||||
double RandomDouble();
|
||||
|
||||
// Get a random element from a vector or array
|
||||
template <typename T> T RandomElement(std::vector<T>& vector, bool erase) {
|
||||
const auto idx = Random(0, vector.size());
|
||||
const auto idx = Random(0, static_cast<uint32_t>(vector.size()));
|
||||
const T selected = vector[idx];
|
||||
if (erase) {
|
||||
vector.erase(vector.begin() + idx);
|
||||
|
@ -21,17 +21,17 @@ template <typename T> T RandomElement(std::vector<T>& vector, bool erase) {
|
|||
return selected;
|
||||
}
|
||||
template <typename Container> auto& RandomElement(Container& container) {
|
||||
return container[Random(0, std::size(container))];
|
||||
return container[Random(0, static_cast<uint32_t>(std::size(container)))];
|
||||
}
|
||||
template <typename Container> const auto& RandomElement(const Container& container) {
|
||||
return container[Random(0, std::size(container))];
|
||||
return container[Random(0, static_cast<uint32_t>(std::size(container)))];
|
||||
}
|
||||
|
||||
template <typename T> const T RandomElementFromSet(const std::set<T>& set) {
|
||||
if (set.size() == 1) {
|
||||
return *set.begin();
|
||||
}
|
||||
uint32_t rand = Random(0, set.size());
|
||||
uint32_t rand = Random(0, static_cast<uint32_t>(set.size()));
|
||||
auto it = set.begin();
|
||||
for (uint32_t i = 0; i < rand; i++) {
|
||||
it++;
|
||||
|
@ -43,12 +43,12 @@ template <typename T> const T RandomElementFromSet(const std::set<T>& set) {
|
|||
// Shuffle items within a vector or array
|
||||
// RANDOTODO There's probably a more efficient way to do what this does.
|
||||
template <typename T> void Shuffle(std::vector<T>& vector) {
|
||||
for (std::size_t i = 0; i + 1 < vector.size(); i++) {
|
||||
std::swap(vector[i], vector[Random(i, vector.size())]);
|
||||
for (size_t i = 0; i + 1 < vector.size(); i++) {
|
||||
std::swap(vector[i], vector[Random(static_cast<uint32_t>(i), static_cast<uint32_t>(vector.size()))]);
|
||||
}
|
||||
}
|
||||
template <typename T, std::size_t size> void Shuffle(std::array<T, size>& arr) {
|
||||
for (std::size_t i = 0; i + 1 < arr.size(); i++) {
|
||||
std::swap(arr[i], arr[Random(i, arr.size())]);
|
||||
template <typename T, size_t size> void Shuffle(std::array<T, size>& arr) {
|
||||
for (size_t i = 0; i + 1 < arr.size(); i++) {
|
||||
std::swap(arr[i], arr[Random(static_cast<uint32_t>(i), static_cast<uint32_t>(arr.size()))]);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -115,7 +115,7 @@ uint16_t GetPriceFromSettings(Rando::Location* loc, PriceSettingsStruct priceSet
|
|||
if (random < ShopPriceProbability[i]) {
|
||||
// The randomly generated value has surpassed the total probability up to this point, so this is the
|
||||
// generated price i in range [0, 59], output in range [0, 295] in increments of 5
|
||||
return i * 5;
|
||||
return static_cast<uint16_t>(i) * 5;
|
||||
}
|
||||
}
|
||||
return 150;
|
||||
|
@ -196,7 +196,8 @@ uint16_t GetCheapBalancedPrice() {
|
|||
double random = RandomDouble();
|
||||
for (size_t i = 0; i < CheapPriceProbability.size(); i++) {
|
||||
if (random < CheapPriceProbability[i]) {
|
||||
return i * 5; // i in range [0, 19], output in range [0, 95] in increments of 5
|
||||
// i in range [0, 19], output in range [0, 95] in increments of 5
|
||||
return static_cast<uint16_t>(i) * 5;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
|
|
|
@ -632,7 +632,7 @@ void PlandomizerLoadSpoilerLog(std::string logFile) {
|
|||
PlandomizerAddToItemList(plandomizerRandoRetrieveItem(RG_SOLD_OUT));
|
||||
}
|
||||
}
|
||||
} catch (nlohmann::json::parse_error& e) {
|
||||
} catch (nlohmann::json::parse_error&) {
|
||||
Notification::Emit({ .message = "Invalid Spoiler Log Format", .remainingTime = 10.0f });
|
||||
}
|
||||
}
|
||||
|
@ -967,7 +967,7 @@ void PlandomizerDrawOptions() {
|
|||
}
|
||||
ImGui::TableNextColumn();
|
||||
|
||||
size_t index = 0;
|
||||
int32_t index = 0;
|
||||
PlandoPushImageButtonStyle();
|
||||
for (auto& hash : plandoHash) {
|
||||
ImGui::PushID(index);
|
||||
|
@ -995,7 +995,7 @@ void PlandomizerDrawOptions() {
|
|||
ImGui::PopStyleVar();
|
||||
if (downRet) {
|
||||
if (hash == 0) {
|
||||
hash = gSeedTextures.size() - 1;
|
||||
hash = static_cast<int32_t>(gSeedTextures.size()) - 1;
|
||||
} else {
|
||||
hash--;
|
||||
}
|
||||
|
|
137
soh/soh/Enhancements/randomizer/ShuffleBeehives.cpp
Normal file
137
soh/soh/Enhancements/randomizer/ShuffleBeehives.cpp
Normal file
|
@ -0,0 +1,137 @@
|
|||
#include <soh/OTRGlobals.h>
|
||||
#include "static_data.h"
|
||||
|
||||
extern "C" {
|
||||
#include "src/overlays/actors/ovl_Obj_Comb/z_obj_comb.h"
|
||||
extern PlayState* gPlayState;
|
||||
}
|
||||
|
||||
extern void EnItem00_DrawRandomizedItem(EnItem00* enItem00, PlayState* play);
|
||||
|
||||
void ObjComb_RandomizerChooseItemDrop(ObjComb* objComb, PlayState* play) {
|
||||
s16 params = objComb->actor.params & 0x1F;
|
||||
|
||||
if (Rando::Context::GetInstance()->GetOption(RSK_SHUFFLE_BEEHIVES).Get() &&
|
||||
!Flags_GetRandomizerInf(objComb->beehiveIdentity.randomizerInf)) {
|
||||
EnItem00* item00 = (EnItem00*)Item_DropCollectible2(play, &objComb->actor.world.pos, ITEM00_SOH_DUMMY);
|
||||
item00->randoInf = objComb->beehiveIdentity.randomizerInf;
|
||||
item00->itemEntry =
|
||||
OTRGlobals::Instance->gRandomizer->GetItemFromKnownCheck(objComb->beehiveIdentity.randomizerCheck, GI_NONE);
|
||||
item00->actor.draw = (ActorFunc)EnItem00_DrawRandomizedItem;
|
||||
return;
|
||||
}
|
||||
|
||||
if ((params > 0) || (params < 0x1A)) {
|
||||
if (params == 6) {
|
||||
if (Flags_GetCollectible(play, (objComb->actor.params >> 8) & 0x3F)) {
|
||||
params = -1;
|
||||
} else {
|
||||
params = (params | (((objComb->actor.params >> 8) & 0x3F) << 8));
|
||||
}
|
||||
} else if (Rand_ZeroOne() < 0.5f) {
|
||||
params = -1;
|
||||
}
|
||||
if (params >= 0 && !CVarGetInteger(CVAR_ENHANCEMENT("NoRandomDrops"), 0)) {
|
||||
Item_DropCollectible(play, &objComb->actor.world.pos, params);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ObjComb_RandomizerWait(ObjComb* objComb, PlayState* play) {
|
||||
s32 dmgFlags;
|
||||
|
||||
objComb->unk_1B0 -= 50;
|
||||
if (Rando::Context::GetInstance()->GetOption(RSK_SHUFFLE_BEEHIVES).Get() &&
|
||||
!Flags_GetRandomizerInf(objComb->beehiveIdentity.randomizerInf)) {
|
||||
if (objComb->unk_1B0 <= -5000) {
|
||||
objComb->unk_1B0 = 1500;
|
||||
}
|
||||
} else if (objComb->unk_1B0 < 0) {
|
||||
objComb->unk_1B0 = 0;
|
||||
}
|
||||
|
||||
if ((objComb->collider.base.acFlags & AC_HIT) != 0) {
|
||||
objComb->collider.base.acFlags &= ~AC_HIT;
|
||||
dmgFlags = objComb->collider.elements[0].info.acHitInfo->toucher.dmgFlags;
|
||||
if (dmgFlags & 0x4001F866) {
|
||||
objComb->unk_1B0 = 1500;
|
||||
} else {
|
||||
ObjComb_Break(objComb, play);
|
||||
ObjComb_RandomizerChooseItemDrop(objComb, play);
|
||||
Actor_Kill(&objComb->actor);
|
||||
}
|
||||
} else {
|
||||
CollisionCheck_SetAC(play, &play->colChkCtx, &objComb->collider.base);
|
||||
}
|
||||
|
||||
if (objComb->actor.update != NULL) {
|
||||
CollisionCheck_SetOC(play, &play->colChkCtx, &objComb->collider.base);
|
||||
}
|
||||
}
|
||||
|
||||
void ObjComb_RandomizerInit(void* actor) {
|
||||
ObjComb* objComb = static_cast<ObjComb*>(actor);
|
||||
s16 respawnData = gSaveContext.respawn[RESPAWN_MODE_RETURN].data & ((1 << 8) - 1);
|
||||
objComb->beehiveIdentity = OTRGlobals::Instance->gRandomizer->IdentifyBeehive(
|
||||
gPlayState->sceneNum, (s16)objComb->actor.world.pos.x, respawnData);
|
||||
objComb->actionFunc = (ObjCombActionFunc)ObjComb_RandomizerWait;
|
||||
}
|
||||
|
||||
void ObjComb_RandomizerUpdate(void* actor) {
|
||||
ObjComb* combActor = reinterpret_cast<ObjComb*>(actor);
|
||||
combActor->actor.shape.rot.x =
|
||||
static_cast<int16_t>(Math_SinS(combActor->unk_1B2)) * CLAMP_MIN(combActor->unk_1B0, 0) +
|
||||
combActor->actor.home.rot.x;
|
||||
}
|
||||
|
||||
void RegisterShuffleBeehives() {
|
||||
bool shouldRegister = IS_RANDO && Rando::Context::GetInstance()->GetOption(RSK_SHUFFLE_BEEHIVES).Get();
|
||||
|
||||
COND_ID_HOOK(OnActorInit, ACTOR_OBJ_COMB, shouldRegister, ObjComb_RandomizerInit);
|
||||
COND_ID_HOOK(OnActorUpdate, ACTOR_OBJ_COMB, shouldRegister, ObjComb_RandomizerUpdate);
|
||||
}
|
||||
|
||||
static RegisterShipInitFunc initFunc(RegisterShuffleBeehives, { "IS_RANDO" });
|
||||
|
||||
void Rando::StaticData::RegisterBeehiveLocations() {
|
||||
static bool registered = false;
|
||||
if (registered)
|
||||
return;
|
||||
registered = true;
|
||||
// clang-format off
|
||||
locationTable[RC_KF_STORMS_GROTTO_BEEHIVE_LEFT] = Location::Base(RC_KF_STORMS_GROTTO_BEEHIVE_LEFT, RCQUEST_BOTH, RCTYPE_BEEHIVE, RCAREA_KOKIRI_FOREST, ACTOR_OBJ_COMB, SCENE_GROTTOS, TWO_ACTOR_PARAMS(-144, 0x2C), "Storms Grotto Beehive Left", RHT_BEEHIVE_CHEST_GROTTO, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_BEEHIVE_KF_STORMS_GROTTO_LEFT));
|
||||
locationTable[RC_KF_STORMS_GROTTO_BEEHIVE_RIGHT] = Location::Base(RC_KF_STORMS_GROTTO_BEEHIVE_RIGHT, RCQUEST_BOTH, RCTYPE_BEEHIVE, RCAREA_KOKIRI_FOREST, ACTOR_OBJ_COMB, SCENE_GROTTOS, TWO_ACTOR_PARAMS(121, 0x2C), "Storms Grotto Beehive Right", RHT_BEEHIVE_CHEST_GROTTO, RG_RED_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_BEEHIVE_KF_STORMS_GROTTO_RIGHT));
|
||||
locationTable[RC_LW_NEAR_SHORTCUTS_GROTTO_BEEHIVE_LEFT] = Location::Base(RC_LW_NEAR_SHORTCUTS_GROTTO_BEEHIVE_LEFT, RCQUEST_BOTH, RCTYPE_BEEHIVE, RCAREA_LOST_WOODS, ACTOR_OBJ_COMB, SCENE_GROTTOS, TWO_ACTOR_PARAMS(-144, 0x14), "Tunnel Grotto Beehive Left", RHT_BEEHIVE_CHEST_GROTTO, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_BEEHIVE_LW_NEAR_SHORTCUTS_GROTTO_LEFT));
|
||||
locationTable[RC_LW_NEAR_SHORTCUTS_GROTTO_BEEHIVE_RIGHT] = Location::Base(RC_LW_NEAR_SHORTCUTS_GROTTO_BEEHIVE_RIGHT, RCQUEST_BOTH, RCTYPE_BEEHIVE, RCAREA_LOST_WOODS, ACTOR_OBJ_COMB, SCENE_GROTTOS, TWO_ACTOR_PARAMS(121, 0x14), "Tunnel Grotto Beehive Right", RHT_BEEHIVE_CHEST_GROTTO, RG_RED_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_BEEHIVE_LW_NEAR_SHORTCUTS_GROTTO_RIGHT));
|
||||
locationTable[RC_LW_DEKU_SCRUB_GROTTO_BEEHIVE] = Location::Base(RC_LW_DEKU_SCRUB_GROTTO_BEEHIVE, RCQUEST_BOTH, RCTYPE_BEEHIVE, RCAREA_LOST_WOODS, ACTOR_OBJ_COMB, SCENE_GROTTOS, TWO_ACTOR_PARAMS(747, 0xF5), "Deku Scrub Grotto Beehive", RHT_BEEHIVE_SCRUB_PAIR_GROTTO, RG_RED_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_BEEHIVE_LW_DEKU_SCRUB_GROTTO));
|
||||
locationTable[RC_SFM_STORMS_GROTTO_BEEHIVE] = Location::Base(RC_SFM_STORMS_GROTTO_BEEHIVE, RCQUEST_BOTH, RCTYPE_BEEHIVE, RCAREA_SACRED_FOREST_MEADOW, ACTOR_OBJ_COMB, SCENE_GROTTOS, TWO_ACTOR_PARAMS(2262, 0xEE), "Deku Scrub Grotto Beehive", RHT_BEEHIVE_SCRUB_PAIR_GROTTO, RG_RED_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_BEEHIVE_SFM_STORMS_GROTTO));
|
||||
locationTable[RC_HF_NEAR_MARKET_GROTTO_BEEHIVE_LEFT] = Location::Base(RC_HF_NEAR_MARKET_GROTTO_BEEHIVE_LEFT, RCQUEST_BOTH, RCTYPE_BEEHIVE, RCAREA_HYRULE_FIELD, ACTOR_OBJ_COMB, SCENE_GROTTOS, TWO_ACTOR_PARAMS(-144, 0x00), "Near Market Grotto Beehive Left", RHT_BEEHIVE_CHEST_GROTTO, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_BEEHIVE_HF_NEAR_MARKET_GROTTO_LEFT));
|
||||
locationTable[RC_HF_NEAR_MARKET_GROTTO_BEEHIVE_RIGHT] = Location::Base(RC_HF_NEAR_MARKET_GROTTO_BEEHIVE_RIGHT, RCQUEST_BOTH, RCTYPE_BEEHIVE, RCAREA_HYRULE_FIELD, ACTOR_OBJ_COMB, SCENE_GROTTOS, TWO_ACTOR_PARAMS(121, 0x00), "Near Market Grotto Beehive Right", RHT_BEEHIVE_CHEST_GROTTO, RG_RED_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_BEEHIVE_HF_NEAR_MARKET_GROTTO_RIGHT));
|
||||
locationTable[RC_HF_OPEN_GROTTO_BEEHIVE_LEFT] = Location::Base(RC_HF_OPEN_GROTTO_BEEHIVE_LEFT, RCQUEST_BOTH, RCTYPE_BEEHIVE, RCAREA_HYRULE_FIELD, ACTOR_OBJ_COMB, SCENE_GROTTOS, TWO_ACTOR_PARAMS(-144, 0x03), "Open Grotto Beehive Left", RHT_BEEHIVE_CHEST_GROTTO, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_BEEHIVE_HF_OPEN_GROTTO_LEFT));
|
||||
locationTable[RC_HF_OPEN_GROTTO_BEEHIVE_RIGHT] = Location::Base(RC_HF_OPEN_GROTTO_BEEHIVE_RIGHT, RCQUEST_BOTH, RCTYPE_BEEHIVE, RCAREA_HYRULE_FIELD, ACTOR_OBJ_COMB, SCENE_GROTTOS, TWO_ACTOR_PARAMS(121, 0x03), "Open Grotto Beehive Right", RHT_BEEHIVE_CHEST_GROTTO, RG_RED_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_BEEHIVE_HF_OPEN_GROTTO_RIGHT));
|
||||
locationTable[RC_HF_SOUTHEAST_GROTTO_BEEHIVE_LEFT] = Location::Base(RC_HF_SOUTHEAST_GROTTO_BEEHIVE_LEFT, RCQUEST_BOTH, RCTYPE_BEEHIVE, RCAREA_HYRULE_FIELD, ACTOR_OBJ_COMB, SCENE_GROTTOS, TWO_ACTOR_PARAMS(-144, 0x22), "Southeast Grotto Beehive Left", RHT_BEEHIVE_CHEST_GROTTO, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_BEEHIVE_HF_SOUTHEAST_GROTTO_LEFT));
|
||||
locationTable[RC_HF_SOUTHEAST_GROTTO_BEEHIVE_RIGHT] = Location::Base(RC_HF_SOUTHEAST_GROTTO_BEEHIVE_RIGHT, RCQUEST_BOTH, RCTYPE_BEEHIVE, RCAREA_HYRULE_FIELD, ACTOR_OBJ_COMB, SCENE_GROTTOS, TWO_ACTOR_PARAMS(121, 0x22), "Southeast Grotto Beehive Right", RHT_BEEHIVE_CHEST_GROTTO, RG_RED_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_BEEHIVE_HF_SOUTHEAST_GROTTO_RIGHT));
|
||||
locationTable[RC_HF_INSIDE_FENCE_GROTTO_BEEHIVE] = Location::Base(RC_HF_INSIDE_FENCE_GROTTO_BEEHIVE, RCQUEST_BOTH, RCTYPE_BEEHIVE, RCAREA_HYRULE_FIELD, ACTOR_OBJ_COMB, SCENE_GROTTOS, TWO_ACTOR_PARAMS(1410, 0xE6), "Deku Scrub Grotto Beehive", RHT_BEEHIVE_LONELY_SCRUB_GROTTO, RG_RED_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_BEEHIVE_HF_INSIDE_FENCE_GROTTO));
|
||||
locationTable[RC_LLR_GROTTO_BEEHIVE] = Location::Base(RC_LLR_GROTTO_BEEHIVE, RCQUEST_BOTH, RCTYPE_BEEHIVE, RCAREA_LON_LON_RANCH, ACTOR_OBJ_COMB, SCENE_GROTTOS, TWO_ACTOR_PARAMS(5144, 0xFC), "Deku Scrub Grotto Beehive", RHT_BEEHIVE_SCRUB_TRIO_GROTTO, RG_RED_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_BEEHIVE_LLR_GROTTO));
|
||||
locationTable[RC_KAK_OPEN_GROTTO_BEEHIVE_LEFT] = Location::Base(RC_KAK_OPEN_GROTTO_BEEHIVE_LEFT, RCQUEST_BOTH, RCTYPE_BEEHIVE, RCAREA_KAKARIKO_VILLAGE, ACTOR_OBJ_COMB, SCENE_GROTTOS, TWO_ACTOR_PARAMS(-144, 0x28), "Open Grotto Beehive Left", RHT_BEEHIVE_CHEST_GROTTO, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_BEEHIVE_KAK_OPEN_GROTTO_LEFT));
|
||||
locationTable[RC_KAK_OPEN_GROTTO_BEEHIVE_RIGHT] = Location::Base(RC_KAK_OPEN_GROTTO_BEEHIVE_RIGHT, RCQUEST_BOTH, RCTYPE_BEEHIVE, RCAREA_KAKARIKO_VILLAGE, ACTOR_OBJ_COMB, SCENE_GROTTOS, TWO_ACTOR_PARAMS(121, 0x28), "Open Grotto Beehive Right", RHT_BEEHIVE_CHEST_GROTTO, RG_RED_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_BEEHIVE_KAK_OPEN_GROTTO_RIGHT));
|
||||
locationTable[RC_DMT_COW_GROTTO_BEEHIVE] = Location::Base(RC_DMT_COW_GROTTO_BEEHIVE, RCQUEST_BOTH, RCTYPE_BEEHIVE, RCAREA_DEATH_MOUNTAIN_TRAIL, ACTOR_OBJ_COMB, SCENE_GROTTOS, TWO_ACTOR_PARAMS(2617, 0xF8), "Cow Grotto Beehive", RHT_BEEHIVE_COW_GROTTO, RG_RED_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_BEEHIVE_DMT_COW_GROTTO));
|
||||
locationTable[RC_DMT_STORMS_GROTTO_BEEHIVE_LEFT] = Location::Base(RC_DMT_STORMS_GROTTO_BEEHIVE_LEFT, RCQUEST_BOTH, RCTYPE_BEEHIVE, RCAREA_DEATH_MOUNTAIN_TRAIL, ACTOR_OBJ_COMB, SCENE_GROTTOS, TWO_ACTOR_PARAMS(-144, 0x57), "Storms Grotto Beehive Left", RHT_BEEHIVE_CHEST_GROTTO, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_BEEHIVE_DMT_STORMS_GROTTO_LEFT));
|
||||
locationTable[RC_DMT_STORMS_GROTTO_BEEHIVE_RIGHT] = Location::Base(RC_DMT_STORMS_GROTTO_BEEHIVE_RIGHT, RCQUEST_BOTH, RCTYPE_BEEHIVE, RCAREA_DEATH_MOUNTAIN_TRAIL, ACTOR_OBJ_COMB, SCENE_GROTTOS, TWO_ACTOR_PARAMS(121, 0x57), "Storms Grotto Beehive Right", RHT_BEEHIVE_CHEST_GROTTO, RG_RED_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_BEEHIVE_DMT_STORMS_GROTTO_RIGHT));
|
||||
locationTable[RC_GC_GROTTO_BEEHIVE] = Location::Base(RC_GC_GROTTO_BEEHIVE, RCQUEST_BOTH, RCTYPE_BEEHIVE, RCAREA_GORON_CITY, ACTOR_OBJ_COMB, SCENE_GROTTOS, TWO_ACTOR_PARAMS(5144, 0xFB), "Grotto Beehive", RHT_BEEHIVE_SCRUB_TRIO_GROTTO, RG_RED_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_BEEHIVE_GC_GROTTO));
|
||||
locationTable[RC_DMC_UPPER_GROTTO_BEEHIVE_LEFT] = Location::Base(RC_DMC_UPPER_GROTTO_BEEHIVE_LEFT, RCQUEST_BOTH, RCTYPE_BEEHIVE, RCAREA_DEATH_MOUNTAIN_CRATER, ACTOR_OBJ_COMB, SCENE_GROTTOS, TWO_ACTOR_PARAMS(-144, 0x7A), "Upper Grotto Beehive Left", RHT_BEEHIVE_CHEST_GROTTO, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_BEEHIVE_DMC_UPPER_GROTTO_LEFT));
|
||||
locationTable[RC_DMC_UPPER_GROTTO_BEEHIVE_RIGHT] = Location::Base(RC_DMC_UPPER_GROTTO_BEEHIVE_RIGHT, RCQUEST_BOTH, RCTYPE_BEEHIVE, RCAREA_DEATH_MOUNTAIN_CRATER, ACTOR_OBJ_COMB, SCENE_GROTTOS, TWO_ACTOR_PARAMS(121, 0x7A), "Upper Grotto Beehive Right", RHT_BEEHIVE_CHEST_GROTTO, RG_RED_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_BEEHIVE_DMC_UPPER_GROTTO_RIGHT));
|
||||
locationTable[RC_DMC_HAMMER_GROTTO_BEEHIVE] = Location::Base(RC_DMC_HAMMER_GROTTO_BEEHIVE, RCQUEST_BOTH, RCTYPE_BEEHIVE, RCAREA_DEATH_MOUNTAIN_CRATER, ACTOR_OBJ_COMB, SCENE_GROTTOS, TWO_ACTOR_PARAMS(5144, 0xF9), "Hammer Grotto Beehive", RHT_BEEHIVE_SCRUB_TRIO_GROTTO, RG_RED_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_BEEHIVE_DMC_HAMMER_GROTTO));
|
||||
locationTable[RC_ZR_OPEN_GROTTO_BEEHIVE_LEFT] = Location::Base(RC_ZR_OPEN_GROTTO_BEEHIVE_LEFT, RCQUEST_BOTH, RCTYPE_BEEHIVE, RCAREA_ZORAS_RIVER, ACTOR_OBJ_COMB, SCENE_GROTTOS, TWO_ACTOR_PARAMS(-144, 0x29), "Open Grotto Beehive Left", RHT_BEEHIVE_CHEST_GROTTO, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_BEEHIVE_ZR_OPEN_GROTTO_LEFT));
|
||||
locationTable[RC_ZR_OPEN_GROTTO_BEEHIVE_RIGHT] = Location::Base(RC_ZR_OPEN_GROTTO_BEEHIVE_RIGHT, RCQUEST_BOTH, RCTYPE_BEEHIVE, RCAREA_ZORAS_RIVER, ACTOR_OBJ_COMB, SCENE_GROTTOS, TWO_ACTOR_PARAMS(121, 0x29), "Open Grotto Beehive Right", RHT_BEEHIVE_CHEST_GROTTO, RG_RED_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_BEEHIVE_ZR_OPEN_GROTTO_RIGHT));
|
||||
locationTable[RC_ZR_STORMS_GROTTO_BEEHIVE] = Location::Base(RC_ZR_STORMS_GROTTO_BEEHIVE, RCQUEST_BOTH, RCTYPE_BEEHIVE, RCAREA_ZORAS_RIVER, ACTOR_OBJ_COMB, SCENE_GROTTOS, TWO_ACTOR_PARAMS(2262, 0xEB), "Storms Grotto Beehive", RHT_BEEHIVE_SCRUB_PAIR_GROTTO, RG_RED_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_BEEHIVE_ZR_STORMS_GROTTO));
|
||||
locationTable[RC_ZD_IN_FRONT_OF_KING_ZORA_BEEHIVE_LEFT] = Location::Base(RC_ZD_IN_FRONT_OF_KING_ZORA_BEEHIVE_LEFT, RCQUEST_BOTH, RCTYPE_BEEHIVE, ACTOR_OBJ_COMB, SCENE_ZORAS_DOMAIN, TWO_ACTOR_PARAMS(382, 0x00), "In Front of King Zora Beehive Left", RHT_BEEHIVE_IN_FRONT_OF_KING_ZORA, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_BEEHIVE_ZD_IN_FRONT_OF_KING_ZORA_LEFT));
|
||||
locationTable[RC_ZD_IN_FRONT_OF_KING_ZORA_BEEHIVE_RIGHT] = Location::Base(RC_ZD_IN_FRONT_OF_KING_ZORA_BEEHIVE_RIGHT, RCQUEST_BOTH, RCTYPE_BEEHIVE, ACTOR_OBJ_COMB, SCENE_ZORAS_DOMAIN, TWO_ACTOR_PARAMS(948, 0x00), "In Front of King Zora Beehive Right", RHT_BEEHIVE_IN_FRONT_OF_KING_ZORA, RG_RED_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_BEEHIVE_ZD_IN_FRONT_OF_KING_ZORA_RIGHT));
|
||||
locationTable[RC_ZD_BEHIND_KING_ZORA_BEEHIVE] = Location::Base(RC_ZD_BEHIND_KING_ZORA_BEEHIVE, RCQUEST_BOTH, RCTYPE_BEEHIVE, ACTOR_OBJ_COMB, SCENE_ZORAS_DOMAIN, TWO_ACTOR_PARAMS(701, 0x00), "Behind King Zora Beehive", RHT_BEEHIVE_BEHIND_KING_ZORA, RG_RED_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_BEEHIVE_ZD_BEHIND_KING_ZORA));
|
||||
locationTable[RC_LH_GROTTO_BEEHIVE] = Location::Base(RC_LH_GROTTO_BEEHIVE, RCQUEST_BOTH, RCTYPE_BEEHIVE, RCAREA_LAKE_HYLIA, ACTOR_OBJ_COMB, SCENE_GROTTOS, TWO_ACTOR_PARAMS(5144, 0xEF), "Deku Scrub Grotto Beehive", RHT_BEEHIVE_SCRUB_TRIO_GROTTO, RG_RED_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_BEEHIVE_LH_GROTTO));
|
||||
locationTable[RC_GV_DEKU_SCRUB_GROTTO_BEEHIVE] = Location::Base(RC_GV_DEKU_SCRUB_GROTTO_BEEHIVE, RCQUEST_BOTH, RCTYPE_BEEHIVE, RCAREA_GERUDO_VALLEY, ACTOR_OBJ_COMB, SCENE_GROTTOS, TWO_ACTOR_PARAMS(2262, 0xF0), "Deku Scrub Grotto Beehive", RHT_BEEHIVE_SCRUB_PAIR_GROTTO, RG_RED_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_BEEHIVE_GV_DEKU_SCRUB_GROTTO));
|
||||
locationTable[RC_COLOSSUS_GROTTO_BEEHIVE] = Location::Base(RC_COLOSSUS_GROTTO_BEEHIVE, RCQUEST_BOTH, RCTYPE_BEEHIVE, RCAREA_DESERT_COLOSSUS, ACTOR_OBJ_COMB, SCENE_GROTTOS, TWO_ACTOR_PARAMS(2262, 0xFD), "Deku Scrub Grotto Beehive", RHT_BEEHIVE_SCRUB_PAIR_GROTTO, RG_RED_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_BEEHIVE_COLOSSUS_GROTTO));
|
||||
// clang-format-on
|
||||
}
|
||||
|
||||
static RegisterShipInitFunc registerFunc(Rando::StaticData::RegisterBeehiveLocations);
|
|
@ -19,7 +19,7 @@ void EnCow_MoveForRandomizer(EnCow* enCow, PlayState* play) {
|
|||
// Move left cow in lon lon tower
|
||||
enCow->actor.world.pos.x = -229.0f;
|
||||
enCow->actor.world.pos.z = 157.0f;
|
||||
enCow->actor.shape.rot.y = 15783.0f;
|
||||
enCow->actor.shape.rot.y = 15783;
|
||||
moved = true;
|
||||
} else if (play->sceneNum == SCENE_STABLE && enCow->actor.world.pos.x == -3 && enCow->actor.world.pos.z == -254) {
|
||||
// Move right cow in lon lon stable
|
||||
|
@ -39,7 +39,8 @@ void RegisterShuffleCows() {
|
|||
COND_VB_SHOULD(VB_GIVE_ITEM_FROM_COW, shouldRegister, {
|
||||
EnCow* enCow = va_arg(args, EnCow*);
|
||||
CowIdentity cowIdentity = OTRGlobals::Instance->gRandomizer->IdentifyCow(
|
||||
gPlayState->sceneNum, enCow->actor.world.pos.x, enCow->actor.world.pos.z);
|
||||
gPlayState->sceneNum, static_cast<int32_t>(enCow->actor.world.pos.x),
|
||||
static_cast<int32_t>(enCow->actor.world.pos.z));
|
||||
// Has this cow already rewarded an item?
|
||||
if (!Flags_GetRandomizerInf(cowIdentity.randomizerInf)) {
|
||||
Flags_SetRandomizerInf(cowIdentity.randomizerInf);
|
||||
|
@ -75,7 +76,6 @@ void Rando::StaticData::RegisterCowLocations() {
|
|||
locationTable[RC_DMT_COW_GROTTO_COW] = Location::Base(RC_DMT_COW_GROTTO_COW, RCQUEST_BOTH, RCTYPE_COW, RCAREA_DEATH_MOUNTAIN_TRAIL, ACTOR_EN_COW, SCENE_GROTTOS, TWO_ACTOR_PARAMS(2444, -471), "Cow Grotto Cow", RHT_DMT_COW_GROTTO_COW, RG_MILK, SpoilerCollectionCheck::RandomizerInf(RAND_INF_COWS_MILKED_DMT_COW_GROTTO_COW));
|
||||
locationTable[RC_GV_COW] = Location::Base(RC_GV_COW, RCQUEST_BOTH, RCTYPE_COW, ACTOR_EN_COW, SCENE_GERUDO_VALLEY, 0x00, "Cow", RHT_GV_COW, RG_MILK, SpoilerCollectionCheck::RandomizerInf(RAND_INF_COWS_MILKED_GV_COW));
|
||||
locationTable[RC_JABU_JABUS_BELLY_MQ_COW] = Location::Base(RC_JABU_JABUS_BELLY_MQ_COW, RCQUEST_MQ, RCTYPE_COW, ACTOR_EN_COW, SCENE_JABU_JABU, 0x00, "MQ Cow", RHT_JABU_JABUS_BELLY_MQ_COW, RG_MILK, SpoilerCollectionCheck::RandomizerInf(RAND_INF_COWS_MILKED_JABU_JABUS_BELLY_MQ_COW));
|
||||
|
||||
// clang-format-on
|
||||
}
|
||||
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
#include "static_data.h"
|
||||
#include <libultraship/libultra.h>
|
||||
#include "global.h"
|
||||
#include "soh/ResourceManagerHelpers.h"
|
||||
|
||||
extern "C" {
|
||||
#include "variables.h"
|
||||
|
@ -11,7 +12,6 @@ extern "C" {
|
|||
#include "overlays/actors/ovl_Obj_Kibako/z_obj_kibako.h"
|
||||
#include "objects/gameplay_dangeon_keep/gameplay_dangeon_keep.h"
|
||||
#include "soh/Enhancements/enhancementTypes.h"
|
||||
#include "soh/ResourceManagerHelpers.h"
|
||||
extern PlayState* gPlayState;
|
||||
}
|
||||
|
||||
|
@ -195,7 +195,7 @@ void ObjKibako2_RandomizerSpawnCollectible(ObjKibako2* crateActor, PlayState* pl
|
|||
item00->actor.draw = (ActorFunc)EnItem00_DrawRandomizedItem;
|
||||
item00->actor.velocity.y = 8.0f;
|
||||
item00->actor.speedXZ = 2.0f;
|
||||
item00->actor.world.rot.y = Rand_CenteredFloat(65536.0f);
|
||||
item00->actor.world.rot.y = static_cast<int16_t>(Rand_CenteredFloat(65536.0f));
|
||||
}
|
||||
|
||||
void ObjKibako_RandomizerSpawnCollectible(ObjKibako* smallCrateActor, PlayState* play) {
|
||||
|
@ -206,7 +206,7 @@ void ObjKibako_RandomizerSpawnCollectible(ObjKibako* smallCrateActor, PlayState*
|
|||
item00->actor.draw = (ActorFunc)EnItem00_DrawRandomizedItem;
|
||||
item00->actor.velocity.y = 8.0f;
|
||||
item00->actor.speedXZ = 2.0f;
|
||||
item00->actor.world.rot.y = Rand_CenteredFloat(65536.0f);
|
||||
item00->actor.world.rot.y = static_cast<int16_t>(Rand_CenteredFloat(65536.0f));
|
||||
}
|
||||
|
||||
void ObjKibako2_RandomizerInit(void* actorRef) {
|
||||
|
|
|
@ -117,7 +117,7 @@ void EnKusa_RandomizerSpawnCollectible(EnKusa* grassActor, PlayState* play) {
|
|||
item00->actor.draw = (ActorFunc)EnItem00_DrawRandomizedItem;
|
||||
item00->actor.velocity.y = 8.0f;
|
||||
item00->actor.speedXZ = 2.0f;
|
||||
item00->actor.world.rot.y = Rand_CenteredFloat(65536.0f);
|
||||
item00->actor.world.rot.y = static_cast<int16_t>(Rand_CenteredFloat(65536.0f));
|
||||
}
|
||||
|
||||
void EnKusa_RandomizerInit(void* actorRef) {
|
||||
|
|
|
@ -48,7 +48,7 @@ void ObjTsubo_RandomizerSpawnCollectible(ObjTsubo* potActor, PlayState* play) {
|
|||
item00->actor.draw = (ActorFunc)EnItem00_DrawRandomizedItem;
|
||||
item00->actor.velocity.y = 8.0f;
|
||||
item00->actor.speedXZ = 2.0f;
|
||||
item00->actor.world.rot.y = Rand_CenteredFloat(65536.0f);
|
||||
item00->actor.world.rot.y = static_cast<int16_t>(Rand_CenteredFloat(65536.0f));
|
||||
}
|
||||
|
||||
void ObjTsubo_RandomizerInit(void* actorRef) {
|
||||
|
|
|
@ -202,7 +202,6 @@ void Context::GenerateLocationPool() {
|
|||
mOptions[RSK_SHUFFLE_FREESTANDING].Is(RO_SHUFFLE_FREESTANDING_DUNGEONS)) ||
|
||||
(location.GetRCType() == RCTYPE_POT && mOptions[RSK_SHUFFLE_POTS].Is(RO_SHUFFLE_POTS_DUNGEONS)) ||
|
||||
(location.GetRCType() == RCTYPE_GRASS && mOptions[RSK_SHUFFLE_GRASS].Is(RO_SHUFFLE_GRASS_DUNGEONS)) ||
|
||||
(location.GetRCType() == RCTYPE_POT && mOptions[RSK_SHUFFLE_POTS].Is(RO_SHUFFLE_POTS_DUNGEONS)) ||
|
||||
(location.GetRCType() == RCTYPE_CRATE && mOptions[RSK_SHUFFLE_CRATES].Is(RO_SHUFFLE_CRATES_DUNGEONS)) ||
|
||||
(location.GetRCType() == RCTYPE_NLCRATE &&
|
||||
mOptions[RSK_SHUFFLE_CRATES].Is(RO_SHUFFLE_CRATES_DUNGEONS) &&
|
||||
|
|
|
@ -597,7 +597,7 @@ extern "C" s32 OverrideLimbDrawBarinade(PlayState* play, s32 limbIndex, Gfx** dL
|
|||
(uintptr_t)Gfx_TwoTexScroll(play->state.gfxCtx, 0, 0, 0, 8, 16, 1, 0,
|
||||
(play->gameplayFrames * -2) % 64, 16, 16));
|
||||
gDPSetEnvColor(POLY_OPA_DISP++, 0, 0, 0, 200);
|
||||
Matrix_RotateX(-M_PI / 2, MTXMODE_APPLY);
|
||||
Matrix_RotateX(-M_PIf / 2.0f, MTXMODE_APPLY);
|
||||
} else if ((limbIndex >= 10) && (limbIndex < 20)) {
|
||||
rot->x -= 0x4000;
|
||||
*dList = NULL;
|
||||
|
@ -1097,7 +1097,7 @@ extern "C" void Randomizer_DrawBronzeScale(PlayState* play, GetItemEntry* getIte
|
|||
gSPSegment(POLY_XLU_DISP++, 0x08,
|
||||
(uintptr_t)Gfx_TwoTexScroll(play->state.gfxCtx, 0, 1 * (play->state.frames * 2),
|
||||
-1 * (play->state.frames * 2), 64, 64, 1, 1 * (play->state.frames * 4),
|
||||
1 * -(play->state.frames * 4), 32, 32));
|
||||
-1 * (play->state.frames * 4), 32, 32));
|
||||
|
||||
gSPMatrix(POLY_XLU_DISP++, Matrix_NewMtx(play->state.gfxCtx, (char*)__FILE__, __LINE__),
|
||||
G_MTX_MODELVIEW | G_MTX_LOAD);
|
||||
|
@ -1116,7 +1116,7 @@ extern "C" void Randomizer_DrawFishingPoleGI(PlayState* play, GetItemEntry* getI
|
|||
|
||||
// Draw rod
|
||||
Gfx_SetupDL_25Opa(play->state.gfxCtx);
|
||||
Matrix_Scale(0.2, 0.2, 0.2, MTXMODE_APPLY);
|
||||
Matrix_Scale(0.2f, 0.2f, 0.2f, MTXMODE_APPLY);
|
||||
gSPMatrix(POLY_OPA_DISP++, Matrix_NewMtx(play->state.gfxCtx, (char*)__FILE__, __LINE__),
|
||||
G_MTX_MODELVIEW | G_MTX_LOAD);
|
||||
gSPDisplayList(POLY_OPA_DISP++, (Gfx*)gFishingPoleGiDL);
|
||||
|
@ -1126,8 +1126,8 @@ extern "C" void Randomizer_DrawFishingPoleGI(PlayState* play, GetItemEntry* getI
|
|||
Matrix_Scale(5.0f, 5.0f, 5.0f, MTXMODE_APPLY);
|
||||
pos = { 0.0f, -25.5f, -4.0f };
|
||||
Matrix_Translate(pos.x, pos.y, pos.z, MTXMODE_APPLY);
|
||||
Matrix_RotateZ(-M_PI_2, MTXMODE_APPLY);
|
||||
Matrix_RotateY(-M_PI_2 - 0.2f, MTXMODE_APPLY);
|
||||
Matrix_RotateZ(-M_PI_2f, MTXMODE_APPLY);
|
||||
Matrix_RotateY(-M_PI_2f - 0.2f, MTXMODE_APPLY);
|
||||
Matrix_Scale(0.006f, 0.006f, 0.006f, MTXMODE_APPLY);
|
||||
Gfx_SetupDL_25Opa(play->state.gfxCtx);
|
||||
gSPMatrix(POLY_OPA_DISP++, Matrix_NewMtx(play->state.gfxCtx, (char*)__FILE__, __LINE__),
|
||||
|
@ -1140,7 +1140,7 @@ extern "C" void Randomizer_DrawFishingPoleGI(PlayState* play, GetItemEntry* getI
|
|||
gSPMatrix(POLY_OPA_DISP++, Matrix_NewMtx(play->state.gfxCtx, (char*)__FILE__, __LINE__),
|
||||
G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
|
||||
gSPDisplayList(POLY_OPA_DISP++, (Gfx*)gFishingLureHookDL);
|
||||
Matrix_RotateZ(M_PI_2, MTXMODE_APPLY);
|
||||
Matrix_RotateZ(M_PI_2f, MTXMODE_APPLY);
|
||||
gSPMatrix(POLY_OPA_DISP++, Matrix_NewMtx(play->state.gfxCtx, (char*)__FILE__, __LINE__),
|
||||
G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
|
||||
gSPDisplayList(POLY_OPA_DISP++, (Gfx*)gFishingLureHookDL);
|
||||
|
@ -1149,7 +1149,7 @@ extern "C" void Randomizer_DrawFishingPoleGI(PlayState* play, GetItemEntry* getI
|
|||
gSPMatrix(POLY_OPA_DISP++, Matrix_NewMtx(play->state.gfxCtx, (char*)__FILE__, __LINE__),
|
||||
G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
|
||||
gSPDisplayList(POLY_OPA_DISP++, (Gfx*)gFishingLureHookDL);
|
||||
Matrix_RotateZ(M_PI / 2, MTXMODE_APPLY);
|
||||
Matrix_RotateZ(M_PIf / 2.0f, MTXMODE_APPLY);
|
||||
gSPMatrix(POLY_OPA_DISP++, Matrix_NewMtx(play->state.gfxCtx, (char*)__FILE__, __LINE__),
|
||||
G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
|
||||
gSPDisplayList(POLY_OPA_DISP++, (Gfx*)gFishingLureHookDL);
|
||||
|
|
|
@ -441,12 +441,6 @@ static bool ValidateWorld(Entrance* entrancePlaced) {
|
|||
type = entrancePlaced->GetType();
|
||||
}
|
||||
|
||||
bool checkPoeCollectorAccess =
|
||||
(ctx->GetOption(RSK_SHUFFLE_OVERWORLD_ENTRANCES) ||
|
||||
ctx->GetOption(RSK_SHUFFLE_INTERIOR_ENTRANCES).Is(RO_INTERIOR_ENTRANCE_SHUFFLE_ALL)) &&
|
||||
(entrancePlaced == nullptr || ctx->GetOption(RSK_MIXED_ENTRANCE_POOLS) || type == EntranceType::Interior ||
|
||||
type == EntranceType::SpecialInterior || type == EntranceType::Overworld || type == EntranceType::Spawn ||
|
||||
type == EntranceType::WarpSong || type == EntranceType::OwlDrop);
|
||||
bool checkOtherEntranceAccess =
|
||||
(ctx->GetOption(RSK_SHUFFLE_OVERWORLD_ENTRANCES) ||
|
||||
ctx->GetOption(RSK_SHUFFLE_INTERIOR_ENTRANCES).Is(RO_INTERIOR_ENTRANCE_SHUFFLE_ALL) ||
|
||||
|
@ -459,7 +453,7 @@ static bool ValidateWorld(Entrance* entrancePlaced) {
|
|||
// Conditions will be checked during the search and any that fail will be figured out
|
||||
// afterwards
|
||||
ctx->GetLogic()->Reset();
|
||||
ValidateEntrances(checkPoeCollectorAccess, checkOtherEntranceAccess);
|
||||
ValidateEntrances(checkOtherEntranceAccess);
|
||||
|
||||
if (!ctx->GetOption(RSK_DECOUPLED_ENTRANCES)) {
|
||||
// Unless entrances are decoupled, we don't want the player to end up through certain entrances as the wrong age
|
||||
|
@ -544,15 +538,6 @@ static bool ValidateWorld(Entrance* entrancePlaced) {
|
|||
}
|
||||
}
|
||||
|
||||
// The Big Poe shop should always be accessible as adult without the need to use any bottles
|
||||
// This is important to ensure that players can never lock their only bottles by filling them with Big Poes they
|
||||
// can't sell
|
||||
if (checkPoeCollectorAccess) {
|
||||
if (!RegionTable(RR_MARKET_GUARD_HOUSE)->Adult()) {
|
||||
SPDLOG_DEBUG("Big Poe Shop access is not guarenteed as adult\n");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
SPDLOG_DEBUG("All Locations NOT REACHABLE\n");
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -90,7 +90,7 @@ class Entrance {
|
|||
Entrance* reverse = nullptr;
|
||||
Entrance* assumed = nullptr;
|
||||
Entrance* replacement = nullptr;
|
||||
int16_t index = 0xFFFF;
|
||||
int16_t index = -1;
|
||||
bool shuffled = false;
|
||||
bool primary = false;
|
||||
bool addedToPool = false;
|
||||
|
|
|
@ -136,8 +136,9 @@ Fishsanity::GetFishingPondLocations(FishsanityOptionsSource optionsSource) {
|
|||
}
|
||||
// NOTE: This only works because we can assume activeFish is already sorted; changes that break this assumption will
|
||||
// also break this
|
||||
FilterAndEraseFromPool(remainingFish,
|
||||
[&](uint32_t loc) { return std::binary_search(activeFish.begin(), activeFish.end(), loc); });
|
||||
FilterAndEraseFromPool(remainingFish, [&](RandomizerCheck loc) {
|
||||
return std::binary_search(activeFish.begin(), activeFish.end(), loc);
|
||||
});
|
||||
|
||||
return std::make_pair(activeFish, remainingFish);
|
||||
}
|
||||
|
|
|
@ -174,8 +174,8 @@ void Hint::NamesChosen() {
|
|||
auto ctx = Rando::Context::GetInstance();
|
||||
std::vector<uint8_t> namesTemp = {};
|
||||
bool saveNames = false;
|
||||
uint8_t numMessages = GetNumberOfMessages();
|
||||
for (uint8_t c = 0; c < numMessages; c++) {
|
||||
size_t numMessages = GetNumberOfMessages();
|
||||
for (size_t c = 0; c < numMessages; c++) {
|
||||
uint8_t selection = GetRandomHintTextEntry(GetHintText(c));
|
||||
if (selection > 0) {
|
||||
saveNames = true;
|
||||
|
@ -187,7 +187,7 @@ void Hint::NamesChosen() {
|
|||
}
|
||||
|
||||
if (hintType == HINT_TYPE_ITEM || hintType == HINT_TYPE_ITEM_AREA) {
|
||||
for (uint8_t c = 0; c < locations.size(); c++) {
|
||||
for (size_t c = 0; c < locations.size(); c++) {
|
||||
namesTemp = {};
|
||||
saveNames = false;
|
||||
uint8_t selection = GetRandomHintTextEntry(GetItemHintText(c));
|
||||
|
@ -218,7 +218,7 @@ void Hint::NamesChosen() {
|
|||
}
|
||||
}
|
||||
|
||||
uint8_t Hint::GetNumberOfMessages() const {
|
||||
size_t Hint::GetNumberOfMessages() const {
|
||||
size_t numMessages = std::max(messages.size(), hintKeys.size());
|
||||
if (StaticData::staticHintInfoMap.contains(ownKey)) {
|
||||
numMessages = std::max(StaticData::staticHintInfoMap[ownKey].hintKeys.size(), numMessages);
|
||||
|
@ -231,14 +231,14 @@ uint8_t Hint::GetNumberOfMessages() const {
|
|||
|
||||
const std::vector<std::string> Hint::GetAllMessageStrings(MessageFormat format) const {
|
||||
std::vector<std::string> hintMessages = {};
|
||||
uint8_t numMessages = GetNumberOfMessages();
|
||||
for (int c = 0; c < numMessages; c++) {
|
||||
size_t numMessages = GetNumberOfMessages();
|
||||
for (size_t c = 0; c < numMessages; c++) {
|
||||
hintMessages.push_back(GetHintMessage(format, c).GetForCurrentLanguage(format));
|
||||
}
|
||||
return hintMessages;
|
||||
}
|
||||
|
||||
const HintText Hint::GetHintText(uint8_t id) const {
|
||||
const HintText Hint::GetHintText(size_t id) const {
|
||||
auto ctx = Rando::Context::GetInstance();
|
||||
if (hintKeys.size() > id) {
|
||||
return StaticData::hintTextTable[hintKeys[id]];
|
||||
|
@ -283,11 +283,11 @@ const HintText Hint::GetHintText(uint8_t id) const {
|
|||
}
|
||||
}
|
||||
|
||||
const CustomMessage Hint::GetHintMessage(MessageFormat format, uint8_t id) const {
|
||||
const CustomMessage Hint::GetHintMessage(MessageFormat format, size_t id) const {
|
||||
auto ctx = Rando::Context::GetInstance();
|
||||
CustomMessage hintText = CustomMessage("");
|
||||
|
||||
uint8_t chosenMessage = 0;
|
||||
size_t chosenMessage = 0;
|
||||
if (hintTextsChosen.size() > id) {
|
||||
chosenMessage = id;
|
||||
}
|
||||
|
|
|
@ -23,10 +23,10 @@ class Hint {
|
|||
void FillGapsInData();
|
||||
void SetLocationsAsHinted() const;
|
||||
void NamesChosen();
|
||||
uint8_t GetNumberOfMessages() const;
|
||||
size_t GetNumberOfMessages() const;
|
||||
const std::vector<std::string> GetAllMessageStrings(MessageFormat format = MF_AUTO_FORMAT) const;
|
||||
const CustomMessage GetHintMessage(MessageFormat format = MF_AUTO_FORMAT, uint8_t id = 0) const;
|
||||
const HintText GetHintText(uint8_t id = 0) const;
|
||||
const CustomMessage GetHintMessage(MessageFormat format = MF_AUTO_FORMAT, size_t id = 0) const;
|
||||
const HintText GetHintText(size_t id = 0) const;
|
||||
oJson toJSON();
|
||||
void logHint(oJson& jsonData);
|
||||
const HintText GetItemHintText(uint8_t slot, bool mysterious = false) const;
|
||||
|
|
|
@ -29,6 +29,7 @@ extern "C" {
|
|||
#include "src/overlays/actors/ovl_En_Shopnuts/z_en_shopnuts.h"
|
||||
#include "src/overlays/actors/ovl_En_Dns/z_en_dns.h"
|
||||
#include "src/overlays/actors/ovl_En_Gb/z_en_gb.h"
|
||||
#include "src/overlays/actors/ovl_En_Po_Field/z_en_po_field.h"
|
||||
#include "src/overlays/actors/ovl_Item_B_Heart/z_item_b_heart.h"
|
||||
#include "src/overlays/actors/ovl_En_Ko/z_en_ko.h"
|
||||
#include "src/overlays/actors/ovl_En_Mk/z_en_mk.h"
|
||||
|
@ -43,7 +44,6 @@ extern "C" {
|
|||
#include "src/overlays/actors/ovl_En_Box/z_en_box.h"
|
||||
#include "src/overlays/actors/ovl_En_Skj/z_en_skj.h"
|
||||
#include "src/overlays/actors/ovl_En_Hy/z_en_hy.h"
|
||||
#include "src/overlays/actors/ovl_Obj_Comb/z_obj_comb.h"
|
||||
#include "src/overlays/actors/ovl_En_Bom_Bowl_Pit/z_en_bom_bowl_pit.h"
|
||||
#include "src/overlays/actors/ovl_En_Ge1/z_en_ge1.h"
|
||||
#include "src/overlays/actors/ovl_En_Ds/z_en_ds.h"
|
||||
|
@ -328,7 +328,7 @@ void RandomizerOnPlayerUpdateForRCQueueHandler() {
|
|||
(getItemEntry.getItemCategory == ITEM_CATEGORY_JUNK ||
|
||||
getItemEntry.getItemCategory == ITEM_CATEGORY_SKULLTULA_TOKEN ||
|
||||
getItemEntry.getItemCategory == ITEM_CATEGORY_LESSER))))) {
|
||||
Item_DropCollectible(gPlayState, &spawnPos, ITEM00_SOH_GIVE_ITEM_ENTRY | 0x8000);
|
||||
Item_DropCollectible(gPlayState, &spawnPos, static_cast<int16_t>(ITEM00_SOH_GIVE_ITEM_ENTRY | 0x8000));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1013,7 +1013,7 @@ void RandomizerOnVanillaBehaviorHandler(GIVanillaBehavior id, bool* should, va_l
|
|||
if (item00->itemEntry.getItemId == GI_SWORD_BGS) {
|
||||
gSaveContext.bgsFlag = true;
|
||||
}
|
||||
Item_Give(gPlayState, item00->itemEntry.itemId);
|
||||
Item_Give(gPlayState, static_cast<uint8_t>(item00->itemEntry.itemId));
|
||||
} else if (item00->itemEntry.modIndex == MOD_RANDOMIZER) {
|
||||
if (item00->itemEntry.getItemId == RG_ICE_TRAP) {
|
||||
gSaveContext.ship.pendingIceTrapCount++;
|
||||
|
@ -1080,12 +1080,35 @@ void RandomizerOnVanillaBehaviorHandler(GIVanillaBehavior id, bool* should, va_l
|
|||
*should = false;
|
||||
break;
|
||||
}
|
||||
case VB_BOTTLE_BIG_POE: {
|
||||
EnPoField* enPoe = va_arg(args, EnPoField*);
|
||||
enPoe->actor.textId = 0x5090;
|
||||
Flags_SetSwitch(gPlayState, enPoe->actor.params & 0xFF);
|
||||
HIGH_SCORE(HS_POE_POINTS) += 100;
|
||||
if (HIGH_SCORE(HS_POE_POINTS) > 1100) {
|
||||
HIGH_SCORE(HS_POE_POINTS) = 1100;
|
||||
}
|
||||
*should = false;
|
||||
break;
|
||||
}
|
||||
case VB_SELL_POES_TO_POE_COLLECTOR: {
|
||||
if (!Flags_GetRandomizerInf(RAND_INF_10_BIG_POES) && HIGH_SCORE(HS_POE_POINTS) >= 1000) {
|
||||
EnGb* enGb = va_arg(args, EnGb*);
|
||||
enGb->textId = 0x70F8;
|
||||
Message_ContinueTextbox(gPlayState, enGb->textId);
|
||||
enGb->actionFunc = func_80A2FB40;
|
||||
*should = false;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case VB_GIVE_ITEM_FROM_POE_COLLECTOR: {
|
||||
EnGb* enGb = va_arg(args, EnGb*);
|
||||
if (!Flags_GetRandomizerInf(RAND_INF_10_BIG_POES)) {
|
||||
Flags_SetInfTable(INFTABLE_SPOKE_TO_POE_COLLECTOR_IN_RUINED_MARKET);
|
||||
Flags_SetRandomizerInf(RAND_INF_10_BIG_POES);
|
||||
enGb->textId = 0x70F5;
|
||||
enGb->dyna.actor.parent = NULL;
|
||||
enGb->actionFunc = func_80A2FC0C;
|
||||
enGb->actionFunc = func_80A2F83C;
|
||||
*should = false;
|
||||
}
|
||||
break;
|
||||
|
@ -1832,65 +1855,6 @@ void EnDns_RandomizerPurchase(EnDns* enDns) {
|
|||
Flags_SetRandomizerInf(enDns->sohScrubIdentity.randomizerInf);
|
||||
}
|
||||
|
||||
void ObjComb_RandomizerChooseItemDrop(ObjComb* objComb, PlayState* play) {
|
||||
s16 params = objComb->actor.params & 0x1F;
|
||||
|
||||
if (RAND_GET_OPTION(RSK_SHUFFLE_BEEHIVES) && !Flags_GetRandomizerInf(objComb->beehiveIdentity.randomizerInf)) {
|
||||
EnItem00* item00 = (EnItem00*)Item_DropCollectible2(play, &objComb->actor.world.pos, ITEM00_SOH_DUMMY);
|
||||
item00->randoInf = objComb->beehiveIdentity.randomizerInf;
|
||||
item00->itemEntry =
|
||||
OTRGlobals::Instance->gRandomizer->GetItemFromKnownCheck(objComb->beehiveIdentity.randomizerCheck, GI_NONE);
|
||||
item00->actor.draw = (ActorFunc)EnItem00_DrawRandomizedItem;
|
||||
return;
|
||||
}
|
||||
|
||||
if ((params > 0) || (params < 0x1A)) {
|
||||
if (params == 6) {
|
||||
if (Flags_GetCollectible(play, (objComb->actor.params >> 8) & 0x3F)) {
|
||||
params = -1;
|
||||
} else {
|
||||
params = (params | (((objComb->actor.params >> 8) & 0x3F) << 8));
|
||||
}
|
||||
} else if (Rand_ZeroOne() < 0.5f) {
|
||||
params = -1;
|
||||
}
|
||||
if (params >= 0 && !CVarGetInteger(CVAR_ENHANCEMENT("NoRandomDrops"), 0)) {
|
||||
Item_DropCollectible(play, &objComb->actor.world.pos, params);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ObjComb_RandomizerWait(ObjComb* objComb, PlayState* play) {
|
||||
s32 dmgFlags;
|
||||
|
||||
objComb->unk_1B0 -= 50;
|
||||
if (RAND_GET_OPTION(RSK_SHUFFLE_BEEHIVES) && !Flags_GetRandomizerInf(objComb->beehiveIdentity.randomizerInf)) {
|
||||
if (objComb->unk_1B0 <= -5000) {
|
||||
objComb->unk_1B0 = 1500;
|
||||
}
|
||||
} else if (objComb->unk_1B0 < 0) {
|
||||
objComb->unk_1B0 = 0;
|
||||
}
|
||||
|
||||
if ((objComb->collider.base.acFlags & AC_HIT) != 0) {
|
||||
objComb->collider.base.acFlags &= ~AC_HIT;
|
||||
dmgFlags = objComb->collider.elements[0].info.acHitInfo->toucher.dmgFlags;
|
||||
if (dmgFlags & 0x4001F866) {
|
||||
objComb->unk_1B0 = 1500;
|
||||
} else {
|
||||
ObjComb_Break(objComb, play);
|
||||
ObjComb_RandomizerChooseItemDrop(objComb, play);
|
||||
Actor_Kill(&objComb->actor);
|
||||
}
|
||||
} else {
|
||||
CollisionCheck_SetAC(play, &play->colChkCtx, &objComb->collider.base);
|
||||
}
|
||||
|
||||
if (objComb->actor.update != NULL) {
|
||||
CollisionCheck_SetOC(play, &play->colChkCtx, &objComb->collider.base);
|
||||
}
|
||||
}
|
||||
|
||||
void RandomizerOnActorInitHandler(void* actorRef) {
|
||||
Actor* actor = static_cast<Actor*>(actorRef);
|
||||
|
||||
|
@ -1983,14 +1947,6 @@ void RandomizerOnActorInitHandler(void* actorRef) {
|
|||
}
|
||||
}
|
||||
|
||||
if (actor->id == ACTOR_OBJ_COMB) {
|
||||
ObjComb* objComb = static_cast<ObjComb*>(actorRef);
|
||||
s16 respawnData = gSaveContext.respawn[RESPAWN_MODE_RETURN].data & ((1 << 8) - 1);
|
||||
objComb->beehiveIdentity = OTRGlobals::Instance->gRandomizer->IdentifyBeehive(
|
||||
gPlayState->sceneNum, (s16)actor->world.pos.x, respawnData);
|
||||
objComb->actionFunc = (ObjCombActionFunc)ObjComb_RandomizerWait;
|
||||
}
|
||||
|
||||
if (actor->id == ACTOR_EN_EX_ITEM) {
|
||||
EnExItem* enExItem = static_cast<EnExItem*>(actorRef);
|
||||
|
||||
|
@ -2137,27 +2093,27 @@ void RandomizerOnActorInitHandler(void* actorRef) {
|
|||
|
||||
void RandomizerOnGameFrameUpdateHandler() {
|
||||
if (Flags_GetRandomizerInf(RAND_INF_HAS_INFINITE_QUIVER)) {
|
||||
AMMO(ITEM_BOW) = CUR_CAPACITY(UPG_QUIVER);
|
||||
AMMO(ITEM_BOW) = static_cast<int8_t>(CUR_CAPACITY(UPG_QUIVER));
|
||||
}
|
||||
|
||||
if (Flags_GetRandomizerInf(RAND_INF_HAS_INFINITE_BOMB_BAG)) {
|
||||
AMMO(ITEM_BOMB) = CUR_CAPACITY(UPG_BOMB_BAG);
|
||||
AMMO(ITEM_BOMB) = static_cast<int8_t>(CUR_CAPACITY(UPG_BOMB_BAG));
|
||||
}
|
||||
|
||||
if (Flags_GetRandomizerInf(RAND_INF_HAS_INFINITE_BULLET_BAG)) {
|
||||
AMMO(ITEM_SLINGSHOT) = CUR_CAPACITY(UPG_BULLET_BAG);
|
||||
AMMO(ITEM_SLINGSHOT) = static_cast<int8_t>(CUR_CAPACITY(UPG_BULLET_BAG));
|
||||
}
|
||||
|
||||
if (Flags_GetRandomizerInf(RAND_INF_HAS_INFINITE_STICK_UPGRADE)) {
|
||||
AMMO(ITEM_STICK) = CUR_CAPACITY(UPG_STICKS);
|
||||
AMMO(ITEM_STICK) = static_cast<int8_t>(CUR_CAPACITY(UPG_STICKS));
|
||||
}
|
||||
|
||||
if (Flags_GetRandomizerInf(RAND_INF_HAS_INFINITE_NUT_UPGRADE)) {
|
||||
AMMO(ITEM_NUT) = CUR_CAPACITY(UPG_NUTS);
|
||||
AMMO(ITEM_NUT) = static_cast<int8_t>(CUR_CAPACITY(UPG_NUTS));
|
||||
}
|
||||
|
||||
if (Flags_GetRandomizerInf(RAND_INF_HAS_INFINITE_MAGIC_METER)) {
|
||||
gSaveContext.magic = gSaveContext.magicCapacity;
|
||||
gSaveContext.magic = static_cast<int8_t>(gSaveContext.magicCapacity);
|
||||
}
|
||||
|
||||
if (Flags_GetRandomizerInf(RAND_INF_HAS_INFINITE_BOMBCHUS)) {
|
||||
|
@ -2165,7 +2121,7 @@ void RandomizerOnGameFrameUpdateHandler() {
|
|||
}
|
||||
|
||||
if (Flags_GetRandomizerInf(RAND_INF_HAS_INFINITE_MONEY)) {
|
||||
gSaveContext.rupees = CUR_CAPACITY(UPG_WALLET);
|
||||
gSaveContext.rupees = static_cast<int8_t>(CUR_CAPACITY(UPG_WALLET));
|
||||
}
|
||||
|
||||
if (!Flags_GetRandomizerInf(RAND_INF_HAS_WALLET)) {
|
||||
|
@ -2199,12 +2155,6 @@ void RandomizerOnActorUpdateHandler(void* refActor) {
|
|||
actor->params == 0x000F) { // Warp Song particles
|
||||
Entrance_SetWarpSongEntrance();
|
||||
}
|
||||
|
||||
if (actor->id == ACTOR_OBJ_COMB) {
|
||||
ObjComb* combActor = reinterpret_cast<ObjComb*>(actor);
|
||||
combActor->actor.shape.rot.x =
|
||||
Math_SinS(combActor->unk_1B2) * CLAMP_MIN(combActor->unk_1B0, 0) + combActor->actor.home.rot.x;
|
||||
}
|
||||
}
|
||||
|
||||
// from z_player.c
|
||||
|
@ -2216,29 +2166,29 @@ typedef struct {
|
|||
// special respawns used when voided out without swim to prevent infinite loops
|
||||
std::map<s32, SpecialRespawnInfo> swimSpecialRespawnInfo = {
|
||||
{ ENTR_ZORAS_RIVER_3, // hf to zr in water
|
||||
{ { -1455.443, -20, 1384.826 }, 28761 } },
|
||||
{ { -1455.443f, -20.0f, 1384.826f }, 28761 } },
|
||||
{ ENTR_HYRULE_FIELD_14, // zr to hf in water
|
||||
{ { 5730.209, -20, 3725.911 }, -20025 } },
|
||||
{ { 5730.209f, -20.0f, 3725.911f }, -20025 } },
|
||||
{ ENTR_LOST_WOODS_UNDERWATER_SHORTCUT, // zr to lw
|
||||
{ { 1978.718, -36.908, -855 }, -16384 } },
|
||||
{ { 1978.718f, -36.908f, -855.0f }, -16384 } },
|
||||
{ ENTR_ZORAS_RIVER_UNDERWATER_SHORTCUT, // lw to zr
|
||||
{ { 4082.366, 860.442, -1018.949 }, -32768 } },
|
||||
{ { 4082.366f, 860.442f, -1018.949f }, -32768 } },
|
||||
{ ENTR_LAKE_HYLIA_RIVER_EXIT, // gv to lh
|
||||
{ { -3276.416, -1033, 2908.421 }, 11228 } },
|
||||
{ { -3276.416f, -1033.0f, 2908.421f }, 11228 } },
|
||||
{ ENTR_WATER_TEMPLE_ENTRANCE, // lh to water temple
|
||||
{ { -182, 780, 759.5 }, -32768 } },
|
||||
{ { -182.0f, 780.0f, 759.5f }, -32768 } },
|
||||
{ ENTR_LAKE_HYLIA_OUTSIDE_TEMPLE, // water temple to lh
|
||||
{ { -955.028, -1306.9, 6768.954 }, -32768 } },
|
||||
{ { -955.028f, -1306.9f, 6768.954f }, -32768 } },
|
||||
{ ENTR_ZORAS_DOMAIN_UNDERWATER_SHORTCUT, // lh to zd
|
||||
{ { -109.86, 11.396, -9.933 }, -29131 } },
|
||||
{ { -109.86f, 11.396f, -9.933f }, -29131 } },
|
||||
{ ENTR_LAKE_HYLIA_UNDERWATER_SHORTCUT, // zd to lh
|
||||
{ { -912, -1326.967, 3391 }, 0 } },
|
||||
{ { -912.0f, -1326.967f, 3391.0f }, 0 } },
|
||||
{ ENTR_GERUDO_VALLEY_1, // caught by gerudos as child
|
||||
{ { -424, -2051, -74 }, 16384 } },
|
||||
{ { -424.0f, -2051.0f, -74.0f }, 16384 } },
|
||||
{ ENTR_HYRULE_FIELD_ON_BRIDGE_SPAWN, // mk to hf (can be a problem when it then turns night)
|
||||
{ { 0, 0, 1100 }, 0 } },
|
||||
{ { 0.0f, 0.0f, 1100.0f }, 0 } },
|
||||
{ ENTR_ZORAS_FOUNTAIN_JABU_JABU_BLUE_WARP, // jabu blue warp to zf
|
||||
{ { -1580, 150, 1670 }, 8000 } },
|
||||
{ { -1580.0f, 150.0f, 1670.0f }, 8000 } },
|
||||
};
|
||||
|
||||
f32 triforcePieceScale;
|
||||
|
@ -2298,8 +2248,8 @@ void RandomizerOnSceneSpawnActorsHandler() {
|
|||
switch (gPlayState->sceneNum) {
|
||||
case SCENE_TEMPLE_OF_TIME:
|
||||
if (gPlayState->roomCtx.curRoom.num == 1) {
|
||||
Actor_Spawn(&gPlayState->actorCtx, gPlayState, ACTOR_EN_XC, -104, -40, 2382, 0, 0x8000, 0,
|
||||
SHEIK_TYPE_RANDO, false);
|
||||
Actor_Spawn(&gPlayState->actorCtx, gPlayState, ACTOR_EN_XC, -104, -40, 2382, 0,
|
||||
static_cast<int16_t>(0x8000), 0, SHEIK_TYPE_RANDO, false);
|
||||
}
|
||||
break;
|
||||
case SCENE_INSIDE_GANONS_CASTLE:
|
||||
|
|
|
@ -10,9 +10,10 @@
|
|||
#include "soh/Enhancements/debugger/performanceTimer.h"
|
||||
|
||||
#include <fstream>
|
||||
#include <soh/OTRGlobals.h>
|
||||
|
||||
#include "3drando/shops.hpp"
|
||||
extern "C" {
|
||||
extern SaveContext gSaveContext;
|
||||
extern PlayState* gPlayState;
|
||||
}
|
||||
|
||||
|
@ -45,17 +46,71 @@ bool LocationAccess::ConditionsMet(Region* parentRegion, bool calculatingAvailab
|
|||
conditionsMet = true;
|
||||
}
|
||||
|
||||
return conditionsMet &&
|
||||
(calculatingAvailableChecks || CanBuy()); // TODO: run CanBuy when price is known due to settings
|
||||
return conditionsMet && CanBuy(calculatingAvailableChecks);
|
||||
}
|
||||
|
||||
bool LocationAccess::CanBuy() const {
|
||||
return CanBuyAnother(location);
|
||||
static uint16_t GetMinimumPrice(const Rando::Location* loc) {
|
||||
extern PriceSettingsStruct shopsanityPrices;
|
||||
extern PriceSettingsStruct scrubPrices;
|
||||
extern PriceSettingsStruct merchantPrices;
|
||||
PriceSettingsStruct priceSettings = loc->GetRCType() == RCTYPE_SHOP ? shopsanityPrices
|
||||
: loc->GetRCType() == RCTYPE_SCRUB ? scrubPrices
|
||||
: merchantPrices;
|
||||
|
||||
auto ctx = Rando::Context::GetInstance();
|
||||
switch (ctx->GetOption(priceSettings.main).Get()) {
|
||||
case RO_PRICE_VANILLA:
|
||||
return loc->GetVanillaPrice();
|
||||
case RO_PRICE_CHEAP_BALANCED:
|
||||
return 0;
|
||||
case RO_PRICE_BALANCED:
|
||||
return 0;
|
||||
case RO_PRICE_FIXED:
|
||||
return ctx->GetOption(priceSettings.fixedPrice).Get() * 5;
|
||||
case RO_PRICE_RANGE: {
|
||||
uint16_t range1 = ctx->GetOption(priceSettings.range1).Get() * 5;
|
||||
uint16_t range2 = ctx->GetOption(priceSettings.range1).Get() * 5;
|
||||
return range1 < range2 ? range1 : range2;
|
||||
}
|
||||
case RO_PRICE_SET_BY_WALLET: {
|
||||
if (ctx->GetOption(priceSettings.noWallet).Get()) {
|
||||
return 0;
|
||||
} else if (ctx->GetOption(priceSettings.childWallet).Get()) {
|
||||
return 1;
|
||||
} else if (ctx->GetOption(priceSettings.adultWallet).Get()) {
|
||||
return 100;
|
||||
} else if (ctx->GetOption(priceSettings.giantWallet).Get()) {
|
||||
return 201;
|
||||
} else {
|
||||
return 501;
|
||||
}
|
||||
}
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
bool LocationAccess::CanBuy(bool calculatingAvailableChecks) const {
|
||||
const auto& loc = Rando::StaticData::GetLocation(location);
|
||||
const auto& itemLoc = OTRGlobals::Instance->gRandoContext->GetItemLocation(location);
|
||||
|
||||
if (loc->GetRCType() == RCTYPE_SHOP || loc->GetRCType() == RCTYPE_SCRUB || loc->GetRCType() == RCTYPE_MERCHANT) {
|
||||
// Checks should only be identified while playing
|
||||
if (calculatingAvailableChecks && itemLoc->GetCheckStatus() != RCSHOW_IDENTIFIED) {
|
||||
return CanBuyAnother(GetMinimumPrice(loc));
|
||||
} else {
|
||||
return CanBuyAnother(itemLoc->GetPrice());
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CanBuyAnother(RandomizerCheck rc) {
|
||||
uint16_t price = ctx->GetItemLocation(rc)->GetPrice();
|
||||
return CanBuyAnother(ctx->GetItemLocation(rc)->GetPrice());
|
||||
}
|
||||
|
||||
bool CanBuyAnother(uint16_t price) {
|
||||
if (price > 500) {
|
||||
return logic->HasItem(RG_TYCOON_WALLET);
|
||||
} else if (price > 200) {
|
||||
|
@ -275,7 +330,7 @@ bool BeanPlanted(const RandomizerRegion region) {
|
|||
if (gPlayState != nullptr && gPlayState->sceneNum == sceneID) {
|
||||
swch = gPlayState->actorCtx.flags.swch;
|
||||
} else if (sceneID != SCENE_ID_MAX) {
|
||||
swch = gSaveContext.sceneFlags[sceneID].swch;
|
||||
swch = Rando::Context::GetInstance()->GetLogic()->GetSaveContext()->sceneFlags[sceneID].swch;
|
||||
} else {
|
||||
swch = 0;
|
||||
}
|
||||
|
@ -312,7 +367,7 @@ void RegionTable_Init() {
|
|||
logic = ctx->GetLogic(); // RANDOTODO do not hardcode, instead allow accepting a Logic class somehow
|
||||
grottoEvents = {
|
||||
EventAccess(&logic->GossipStoneFairy, [] { return logic->CallGossipFairy(); }),
|
||||
EventAccess(&logic->ButterflyFairy, [] { return logic->ButterflyFairy || (logic->CanUse(RG_STICKS)); }),
|
||||
EventAccess(&logic->ButterflyFairy, [] { return logic->CanUse(RG_STICKS); }),
|
||||
EventAccess(&logic->BugShrub, [] { return logic->CanCutShrubs(); }),
|
||||
EventAccess(&logic->LoneFish, [] { return true; }),
|
||||
};
|
||||
|
@ -324,9 +379,6 @@ void RegionTable_Init() {
|
|||
areaTable[RR_ROOT] = Region("Root", "", {RA_LINKS_POCKET}, NO_DAY_NIGHT_CYCLE, {
|
||||
//Events
|
||||
EventAccess(&logic->KakarikoVillageGateOpen, []{return ctx->GetOption(RSK_KAK_GATE).Is(RO_KAK_GATE_OPEN);}),
|
||||
//The big poes bottle softlock safety check does not account for the guard house lock if the guard house is not shuffled, so the key is needed before we can safely allow bottle use in logic
|
||||
//RANDOTODO a setting that lets you drink/dump big poes so we don't need this logic
|
||||
EventAccess(&logic->CouldEmptyBigPoes, []{return !ctx->GetOption(RSK_SHUFFLE_INTERIOR_ENTRANCES).Is(RO_INTERIOR_ENTRANCE_SHUFFLE_OFF) || logic->CanOpenOverworldDoor(RG_GUARD_HOUSE_KEY);}),
|
||||
}, {
|
||||
//Locations
|
||||
LOCATION(RC_LINKS_POCKET, true),
|
||||
|
@ -480,17 +532,17 @@ std::string CleanCheckConditionString(std::string condition) {
|
|||
}
|
||||
|
||||
namespace Regions {
|
||||
const auto GetAllRegions() {
|
||||
auto GetAllRegions() {
|
||||
static const size_t regionCount = RR_MAX - (RR_NONE + 1);
|
||||
|
||||
static std::array<RandomizerRegion, regionCount> allRegions = {};
|
||||
|
||||
static bool intialized = false;
|
||||
if (!intialized) {
|
||||
static bool initialized = false;
|
||||
if (!initialized) {
|
||||
for (size_t i = 0; i < regionCount; i++) {
|
||||
allRegions[i] = (RandomizerRegion)((RR_NONE + 1) + i);
|
||||
}
|
||||
intialized = true;
|
||||
initialized = true;
|
||||
}
|
||||
|
||||
return allRegions;
|
||||
|
@ -629,7 +681,7 @@ std::vector<Rando::Entrance*> GetShuffleableEntrances(Rando::EntranceType type,
|
|||
|
||||
Rando::Entrance* GetEntrance(RandomizerRegion source, RandomizerRegion destination) {
|
||||
for (auto& exit : RegionTable(source)->exits) {
|
||||
if (exit.GetConnectedRegionKey() == destination) {
|
||||
if (exit.GetOriginalConnectedRegionKey() == destination) {
|
||||
return &exit;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -100,9 +100,10 @@ class LocationAccess {
|
|||
std::string condition_str;
|
||||
|
||||
// Makes sure shop locations are buyable
|
||||
bool CanBuy() const;
|
||||
bool CanBuy(bool calculatingAvailableChecks) const;
|
||||
};
|
||||
|
||||
bool CanBuyAnother(uint16_t price);
|
||||
bool CanBuyAnother(RandomizerCheck rc);
|
||||
|
||||
namespace Rando {
|
||||
|
|
|
@ -25,7 +25,6 @@ void RegionTable_Init_BottomOfTheWell() {
|
|||
}, {
|
||||
//Locations
|
||||
LOCATION(RC_BOTTOM_OF_THE_WELL_FRONT_CENTER_BOMBABLE_CHEST, logic->HasExplosives()),
|
||||
LOCATION(RC_BOTTOM_OF_THE_WELL_FREESTANDING_KEY, (logic->HasItem(RG_BRONZE_SCALE) || logic->LoweredWaterInsideBotw) && logic->CanUse(RG_STICKS) || logic->CanUse(RG_DINS_FIRE)),
|
||||
LOCATION(RC_BOTTOM_OF_THE_WELL_UNDERWATER_FRONT_CHEST, logic->LoweredWaterInsideBotw),
|
||||
LOCATION(RC_BOTTOM_OF_THE_WELL_UNDERWATER_LEFT_CHEST, logic->LoweredWaterInsideBotw),
|
||||
LOCATION(RC_BOTTOM_OF_THE_WELL_NEAR_ENTRANCE_POT_1, logic->CanBreakPots()),
|
||||
|
|
|
@ -445,7 +445,7 @@ void RegionTable_Init_DekuTree() {
|
|||
|
||||
areaTable[RR_DEKU_TREE_BOSS_ROOM] = Region("Deku Tree Boss Room", "Deku Tree", {}, NO_DAY_NIGHT_CYCLE, {
|
||||
// Events
|
||||
EventAccess(&logic->DekuTreeClear, []{return logic->DekuTreeClear || logic->CanKillEnemy(RE_GOHMA);}),
|
||||
EventAccess(&logic->DekuTreeClear, []{return logic->CanKillEnemy(RE_GOHMA);}),
|
||||
}, {
|
||||
// Locations
|
||||
LOCATION(RC_QUEEN_GOHMA, logic->DekuTreeClear),
|
||||
|
|
|
@ -567,7 +567,7 @@ void RegionTable_Init_DodongosCavern() {
|
|||
|
||||
areaTable[RR_DODONGOS_CAVERN_BOSS_ROOM] = Region("Dodongos Cavern Boss Room", "Dodongos Cavern", {}, NO_DAY_NIGHT_CYCLE, {
|
||||
// Events
|
||||
EventAccess(&logic->DodongosCavernClear, []{return logic->DodongosCavernClear || (Here(RR_DODONGOS_CAVERN_BOSS_ROOM, []{return logic->HasExplosives() || (logic->CanUse(RG_MEGATON_HAMMER) && ctx->GetTrickOption(RT_DC_HAMMER_FLOOR));}) && logic->CanKillEnemy(RE_KING_DODONGO)); /*todo add chu kill to tricks*/}),
|
||||
EventAccess(&logic->DodongosCavernClear, []{return Here(RR_DODONGOS_CAVERN_BOSS_ROOM, []{return logic->HasExplosives() || (logic->CanUse(RG_MEGATON_HAMMER) && ctx->GetTrickOption(RT_DC_HAMMER_FLOOR));}) && logic->CanKillEnemy(RE_KING_DODONGO); /*todo add chu kill to tricks*/}),
|
||||
}, {
|
||||
// Locations
|
||||
LOCATION(RC_DODONGOS_CAVERN_BOSS_ROOM_CHEST, true),
|
||||
|
|
|
@ -20,14 +20,14 @@ void RegionTable_Init_FireTemple() {
|
|||
//Exits
|
||||
Entrance(RR_FIRE_TEMPLE_ENTRYWAY, []{return true;}),
|
||||
Entrance(RR_FIRE_TEMPLE_NEAR_BOSS_ROOM, []{return logic->FireTimer() >= 24;}),
|
||||
Entrance(RR_FIRE_TEMPLE_LOOP_ENEMIES, []{return Here(RR_FIRE_TEMPLE_FIRST_ROOM, []{return logic->CanUse(RG_MEGATON_HAMMER);}) && (logic->SmallKeys(RR_FIRE_TEMPLE, 8) || !logic->IsKeysanity);}),
|
||||
Entrance(RR_FIRE_TEMPLE_LOOP_ENEMIES, []{return Here(RR_FIRE_TEMPLE_FIRST_ROOM, []{return logic->CanUse(RG_MEGATON_HAMMER);}) && (logic->SmallKeys(RR_FIRE_TEMPLE, 8) || !logic->IsFireLoopLocked);}),
|
||||
Entrance(RR_FIRE_TEMPLE_LOOP_EXIT, []{return true;}),
|
||||
Entrance(RR_FIRE_TEMPLE_BIG_LAVA_ROOM, []{return logic->SmallKeys(RR_FIRE_TEMPLE, 2) && logic->FireTimer() >= 24;}),
|
||||
});
|
||||
|
||||
areaTable[RR_FIRE_TEMPLE_NEAR_BOSS_ROOM] = Region("Fire Temple Near Boss Room", "Fire Temple", {RA_FIRE_TEMPLE}, NO_DAY_NIGHT_CYCLE, {
|
||||
//Events
|
||||
EventAccess(&logic->FairyPot, []{return logic->FairyPot || (logic->CanUse(RG_HOVER_BOOTS) || logic->CanUse(RG_HOOKSHOT));}),
|
||||
EventAccess(&logic->FairyPot, []{return logic->CanUse(RG_HOVER_BOOTS) || logic->CanUse(RG_HOOKSHOT);}),
|
||||
}, {
|
||||
//Locations
|
||||
LOCATION(RC_FIRE_TEMPLE_NEAR_BOSS_CHEST, true),
|
||||
|
@ -43,7 +43,7 @@ void RegionTable_Init_FireTemple() {
|
|||
|
||||
areaTable[RR_FIRE_TEMPLE_LOOP_ENEMIES] = Region("Fire Temple Loop Enemies", "Fire Temple", {RA_FIRE_TEMPLE}, NO_DAY_NIGHT_CYCLE, {}, {}, {
|
||||
//Exits
|
||||
Entrance(RR_FIRE_TEMPLE_FIRST_ROOM, []{return logic->SmallKeys(RR_FIRE_TEMPLE, 8) || !logic->IsKeysanity;}),
|
||||
Entrance(RR_FIRE_TEMPLE_FIRST_ROOM, []{return logic->SmallKeys(RR_FIRE_TEMPLE, 8) || !logic->IsFireLoopLocked;}),
|
||||
Entrance(RR_FIRE_TEMPLE_LOOP_TILES, []{return Here(RR_FIRE_TEMPLE_LOOP_ENEMIES, []{return logic->CanKillEnemy(RE_TORCH_SLUG) && logic->CanKillEnemy(RE_FIRE_KEESE);});}),
|
||||
});
|
||||
|
||||
|
@ -67,7 +67,7 @@ void RegionTable_Init_FireTemple() {
|
|||
|
||||
areaTable[RR_FIRE_TEMPLE_LOOP_HAMMER_SWITCH] = Region("Fire Temple Loop Hammer Switch", "Fire Temple", {RA_FIRE_TEMPLE}, NO_DAY_NIGHT_CYCLE, {
|
||||
//Events
|
||||
EventAccess(&logic->FireLoopSwitch, []{return logic->FireLoopSwitch || logic->CanUse(RG_MEGATON_HAMMER);}),
|
||||
EventAccess(&logic->FireLoopSwitch, []{return logic->CanUse(RG_MEGATON_HAMMER);}),
|
||||
}, {}, {
|
||||
//Exits
|
||||
Entrance(RR_FIRE_TEMPLE_LOOP_FLARE_DANCER, []{return true;}),
|
||||
|
@ -745,7 +745,7 @@ void RegionTable_Init_FireTemple() {
|
|||
|
||||
areaTable[RR_FIRE_TEMPLE_BOSS_ROOM] = Region("Fire Temple Boss Room", "Fire Temple", {}, NO_DAY_NIGHT_CYCLE, {
|
||||
// Events
|
||||
EventAccess(&logic->FireTempleClear, []{return logic->FireTempleClear || (logic->FireTimer() >= 64 && logic->CanKillEnemy(RE_VOLVAGIA));}),
|
||||
EventAccess(&logic->FireTempleClear, []{return logic->FireTimer() >= 64 && logic->CanKillEnemy(RE_VOLVAGIA);}),
|
||||
}, {
|
||||
// Locations
|
||||
LOCATION(RC_FIRE_TEMPLE_VOLVAGIA_HEART, logic->FireTempleClear),
|
||||
|
|
|
@ -34,7 +34,7 @@ void RegionTable_Init_ForestTemple() {
|
|||
|
||||
areaTable[RR_FOREST_TEMPLE_LOBBY] = Region("Forest Temple Lobby", "Forest Temple", {RA_FOREST_TEMPLE}, NO_DAY_NIGHT_CYCLE, {
|
||||
//Events
|
||||
EventAccess(&logic->ForestTempleMeg, []{return logic->ForestTempleMeg || (logic->ForestTempleJoelle && logic->ForestTempleBeth && logic->ForestTempleAmy && logic->CanUse(RG_FAIRY_BOW));}),
|
||||
EventAccess(&logic->ForestTempleMeg, []{return logic->ForestTempleJoelle && logic->ForestTempleBeth && logic->ForestTempleAmy && logic->CanUse(RG_FAIRY_BOW);}),
|
||||
}, {
|
||||
//Locations
|
||||
LOCATION(RC_FOREST_TEMPLE_GS_LOBBY, logic->HookshotOrBoomerang()),
|
||||
|
@ -203,7 +203,7 @@ void RegionTable_Init_ForestTemple() {
|
|||
|
||||
areaTable[RR_FOREST_TEMPLE_RED_POE_ROOM] = Region("Forest Temple Red Poe Room", "Forest Temple", {RA_FOREST_TEMPLE}, NO_DAY_NIGHT_CYCLE, {
|
||||
//Events
|
||||
EventAccess(&logic->ForestTempleJoelle, []{return logic->ForestTempleJoelle || logic->CanUse(RG_FAIRY_BOW);}),
|
||||
EventAccess(&logic->ForestTempleJoelle, []{return logic->CanUse(RG_FAIRY_BOW);}),
|
||||
}, {
|
||||
//Locations
|
||||
LOCATION(RC_FOREST_TEMPLE_RED_POE_CHEST, logic->ForestTempleJoelle),
|
||||
|
@ -228,7 +228,7 @@ void RegionTable_Init_ForestTemple() {
|
|||
|
||||
areaTable[RR_FOREST_TEMPLE_BLUE_POE_ROOM] = Region("Forest Temple Blue Poe Room", "Forest Temple", {RA_FOREST_TEMPLE}, NO_DAY_NIGHT_CYCLE, {
|
||||
//Events
|
||||
EventAccess(&logic->ForestTempleBeth, []{return logic->ForestTempleBeth || logic->CanUse(RG_FAIRY_BOW);}),
|
||||
EventAccess(&logic->ForestTempleBeth, []{return logic->CanUse(RG_FAIRY_BOW);}),
|
||||
}, {
|
||||
//Locations
|
||||
LOCATION(RC_FOREST_TEMPLE_BLUE_POE_CHEST, logic->ForestTempleBeth),
|
||||
|
@ -274,7 +274,7 @@ void RegionTable_Init_ForestTemple() {
|
|||
|
||||
areaTable[RR_FOREST_TEMPLE_GREEN_POE_ROOM] = Region("Forest Temple Green Poe Room", "Forest Temple", {RA_FOREST_TEMPLE}, NO_DAY_NIGHT_CYCLE, {
|
||||
//Events
|
||||
EventAccess(&logic->ForestTempleAmy, []{return logic->ForestTempleAmy || logic->CanUse(RG_FAIRY_BOW);}),
|
||||
EventAccess(&logic->ForestTempleAmy, []{return logic->CanUse(RG_FAIRY_BOW);}),
|
||||
}, {
|
||||
//Locations
|
||||
LOCATION(RC_FOREST_TEMPLE_GREEN_POE_POT_1, logic->CanBreakPots()),
|
||||
|
@ -608,7 +608,7 @@ void RegionTable_Init_ForestTemple() {
|
|||
|
||||
areaTable[RR_FOREST_TEMPLE_BOSS_ROOM] = Region("Forest Temple Boss Room", "Forest Temple", {}, NO_DAY_NIGHT_CYCLE, {
|
||||
// Events
|
||||
EventAccess(&logic->ForestTempleClear, []{return logic->ForestTempleClear || logic->CanKillEnemy(RE_PHANTOM_GANON);}),
|
||||
EventAccess(&logic->ForestTempleClear, []{return logic->CanKillEnemy(RE_PHANTOM_GANON);}),
|
||||
}, {
|
||||
// Locations
|
||||
LOCATION(RC_FOREST_TEMPLE_PHANTOM_GANON_HEART, logic->ForestTempleClear),
|
||||
|
|
|
@ -80,7 +80,7 @@ void RegionTable_Init_GanonsCastle() {
|
|||
areaTable[RR_GANONS_CASTLE_WATER_TRIAL] = Region("Ganon's Castle Water Trial", "Ganon's Castle", {RA_GANONS_CASTLE}, NO_DAY_NIGHT_CYCLE, {
|
||||
//Events
|
||||
EventAccess(&logic->BlueFireAccess, []{return true;}),
|
||||
EventAccess(&logic->FairyPot, []{return logic->FairyPot || (logic->BlueFire() && logic->CanKillEnemy(RE_FREEZARD));}),
|
||||
EventAccess(&logic->FairyPot, []{return logic->BlueFire() && logic->CanKillEnemy(RE_FREEZARD);}),
|
||||
EventAccess(&logic->WaterTrialClear, []{return logic->BlueFire() && logic->IsAdult && logic->CanUse(RG_MEGATON_HAMMER) && logic->CanUse(RG_LIGHT_ARROWS);}),
|
||||
}, {
|
||||
//Locations
|
||||
|
@ -109,7 +109,7 @@ void RegionTable_Init_GanonsCastle() {
|
|||
|
||||
areaTable[RR_GANONS_CASTLE_SPIRIT_TRIAL] = Region("Ganon's Castle Spirit Trial", "Ganon's Castle", {RA_GANONS_CASTLE}, NO_DAY_NIGHT_CYCLE, {
|
||||
//Events
|
||||
EventAccess(&logic->NutPot, []{return logic->NutPot || (((ctx->GetTrickOption(RT_GANON_SPIRIT_TRIAL_HOOKSHOT) && logic->CanJumpslashExceptHammer()) || logic->CanUse(RG_HOOKSHOT)) && logic->CanUse(RG_BOMBCHU_5) && logic->CanUse(RG_FAIRY_BOW) && (logic->CanUse(RG_MIRROR_SHIELD) || (ctx->GetOption(RSK_SUNLIGHT_ARROWS) && logic->CanUse(RG_LIGHT_ARROWS))));}),
|
||||
EventAccess(&logic->NutPot, []{return ((ctx->GetTrickOption(RT_GANON_SPIRIT_TRIAL_HOOKSHOT) && logic->CanJumpslashExceptHammer()) || logic->CanUse(RG_HOOKSHOT)) && logic->CanUse(RG_BOMBCHU_5) && logic->CanUse(RG_FAIRY_BOW) && (logic->CanUse(RG_MIRROR_SHIELD) || (ctx->GetOption(RSK_SUNLIGHT_ARROWS) && logic->CanUse(RG_LIGHT_ARROWS)));}),
|
||||
EventAccess(&logic->SpiritTrialClear, []{return logic->CanUse(RG_LIGHT_ARROWS) && (logic->CanUse(RG_MIRROR_SHIELD) || ctx->GetOption(RSK_SUNLIGHT_ARROWS)) && logic->CanUse(RG_BOMBCHU_5) && ((ctx->GetTrickOption(RT_GANON_SPIRIT_TRIAL_HOOKSHOT) && logic->CanJumpslashExceptHammer()) || logic->CanUse(RG_HOOKSHOT));}),
|
||||
}, {
|
||||
//Locations
|
||||
|
|
|
@ -361,7 +361,7 @@ void RegionTable_Init_JabuJabusBelly() {
|
|||
|
||||
areaTable[RR_JABU_JABUS_BELLY_BOSS_ROOM] = Region("Jabu Jabus Belly Boss Room", "Jabu Jabus Belly", {}, NO_DAY_NIGHT_CYCLE, {
|
||||
// Events //todo: add pot kill trick
|
||||
EventAccess(&logic->JabuJabusBellyClear, []{return logic->JabuJabusBellyClear || logic->CanKillEnemy(RE_BARINADE);}),
|
||||
EventAccess(&logic->JabuJabusBellyClear, []{return logic->CanKillEnemy(RE_BARINADE);}),
|
||||
}, {
|
||||
// Locations
|
||||
LOCATION(RC_JABU_JABUS_BELLY_BARINADE_POT_1, logic->CanBreakPots()),
|
||||
|
|
|
@ -408,7 +408,7 @@ void RegionTable_Init_ShadowTemple() {
|
|||
|
||||
areaTable[RR_SHADOW_TEMPLE_BOSS_ROOM] = Region("Shadow Temple Boss Room", "Shadow Temple", {}, NO_DAY_NIGHT_CYCLE, {
|
||||
// Events
|
||||
EventAccess(&logic->ShadowTempleClear, []{return logic->ShadowTempleClear || logic->CanKillEnemy(RE_BONGO_BONGO);}),
|
||||
EventAccess(&logic->ShadowTempleClear, []{return logic->CanKillEnemy(RE_BONGO_BONGO);}),
|
||||
}, {
|
||||
// Locations
|
||||
LOCATION(RC_SHADOW_TEMPLE_BONGO_BONGO_HEART, logic->ShadowTempleClear),
|
||||
|
|
|
@ -556,7 +556,7 @@ void RegionTable_Init_SpiritTemple() {
|
|||
|
||||
areaTable[RR_SPIRIT_TEMPLE_BOSS_ROOM] = Region("Spirit Temple Boss Room", "Spirit Temple", {}, NO_DAY_NIGHT_CYCLE, {
|
||||
// Events
|
||||
EventAccess(&logic->SpiritTempleClear, []{return logic->SpiritTempleClear || logic->CanKillEnemy(RE_TWINROVA);}),
|
||||
EventAccess(&logic->SpiritTempleClear, []{return logic->CanKillEnemy(RE_TWINROVA);}),
|
||||
}, {
|
||||
// Locations
|
||||
LOCATION(RC_SPIRIT_TEMPLE_TWINROVA_HEART, logic->SpiritTempleClear),
|
||||
|
|
|
@ -40,7 +40,7 @@ void RegionTable_Init_WaterTemple() {
|
|||
|
||||
areaTable[RR_WATER_TEMPLE_EAST_LOWER] = Region("Water Temple East Lower", "Water Temple", {RA_WATER_TEMPLE}, NO_DAY_NIGHT_CYCLE, {
|
||||
//Events
|
||||
EventAccess(&logic->CanWaterTempleLowFromHigh, []{return logic->CanWaterTempleLowFromHigh || logic->CanUse(RG_ZELDAS_LULLABY);}),
|
||||
EventAccess(&logic->CanWaterTempleLowFromHigh, []{return logic->CanUse(RG_ZELDAS_LULLABY);}),
|
||||
}, {
|
||||
//Locations
|
||||
LOCATION(RC_WATER_TEMPLE_TORCH_POT_1, logic->CanBreakPots() && (logic->CanWaterTempleLowFromHigh || (logic->CanUse(RG_HOOKSHOT) && logic->CanUse(RG_IRON_BOOTS)))),
|
||||
|
@ -165,7 +165,7 @@ void RegionTable_Init_WaterTemple() {
|
|||
|
||||
areaTable[RR_WATER_TEMPLE_CENTRAL_PILLAR_UPPER] = Region("Water Temple Central Pillar Upper", "Water Temple", {RA_WATER_TEMPLE}, NO_DAY_NIGHT_CYCLE, {
|
||||
//Events
|
||||
EventAccess(&logic->CanWaterTempleMiddle, []{return logic->CanWaterTempleMiddle || logic->CanUse(RG_ZELDAS_LULLABY);}),
|
||||
EventAccess(&logic->CanWaterTempleMiddle, []{return logic->CanUse(RG_ZELDAS_LULLABY);}),
|
||||
}, {
|
||||
//Locations
|
||||
LOCATION(RC_WATER_TEMPLE_GS_CENTRAL_PILLAR, logic->CanUse(RG_LONGSHOT) || (((ctx->GetTrickOption(RT_WATER_FW_CENTRAL_GS) && logic->CanUse(RG_FARORES_WIND) && (logic->CanUse(RG_FAIRY_BOW) || logic->CanUse(RG_DINS_FIRE) || logic->SmallKeys(RR_WATER_TEMPLE, 5))) || (ctx->GetTrickOption(RT_WATER_IRONS_CENTRAL_GS) && logic->CanUse(RG_IRON_BOOTS) && ((logic->CanUse(RG_HOOKSHOT) && logic->CanUse(RG_FAIRY_BOW)) || (logic->CanUse(RG_DINS_FIRE))))) && logic->CanWaterTempleHigh && logic->HookshotOrBoomerang())),
|
||||
|
@ -202,7 +202,7 @@ void RegionTable_Init_WaterTemple() {
|
|||
|
||||
areaTable[RR_WATER_TEMPLE_HIGH_WATER] = Region("Water Temple High Water", "Water Temple", {RA_WATER_TEMPLE}, NO_DAY_NIGHT_CYCLE, {
|
||||
//Events
|
||||
EventAccess(&logic->CanWaterTempleHigh, []{return logic->CanWaterTempleHigh || logic->CanUse(RG_ZELDAS_LULLABY);}),
|
||||
EventAccess(&logic->CanWaterTempleHigh, []{return logic->CanUse(RG_ZELDAS_LULLABY);}),
|
||||
}, {}, {
|
||||
//Exits
|
||||
Entrance(RR_WATER_TEMPLE_LOBBY, []{return true;}),
|
||||
|
@ -658,7 +658,7 @@ void RegionTable_Init_WaterTemple() {
|
|||
|
||||
areaTable[RR_WATER_TEMPLE_MQ_DRAGON_ROOM_ALCOVE] = Region("Water Temple MQ Dragon Room Alcove", "Water Temple", {RA_WATER_TEMPLE}, NO_DAY_NIGHT_CYCLE, {
|
||||
//Events
|
||||
EventAccess(&logic->MQWaterDragonTorches, []{return true;}),
|
||||
EventAccess(&logic->MQWaterDragonTorches, []{return logic->HasFireSource();}),
|
||||
},
|
||||
{
|
||||
//Locations
|
||||
|
@ -848,7 +848,7 @@ void RegionTable_Init_WaterTemple() {
|
|||
|
||||
areaTable[RR_WATER_TEMPLE_BOSS_ROOM] = Region("Water Temple Boss Room", "Water Temple", {}, NO_DAY_NIGHT_CYCLE, {
|
||||
// Events
|
||||
EventAccess(&logic->WaterTempleClear, []{return logic->WaterTempleClear || logic->CanKillEnemy(RE_MORPHA);}),
|
||||
EventAccess(&logic->WaterTempleClear, []{return logic->CanKillEnemy(RE_MORPHA);}),
|
||||
}, {
|
||||
// Locations
|
||||
LOCATION(RC_WATER_TEMPLE_MORPHA_HEART, logic->WaterTempleClear),
|
||||
|
|
|
@ -14,7 +14,7 @@ void RegionTable_Init_GerudoFortress() {
|
|||
//Events
|
||||
EventAccess(&logic->CarpenterRescue, []{return logic->CanFinishGerudoFortress();}),
|
||||
EventAccess(&logic->GF_GateOpen, []{return logic->IsAdult && logic->HasItem(RG_GERUDO_MEMBERSHIP_CARD);}),
|
||||
EventAccess(&logic->GtG_GateOpen, []{return logic->GtG_GateOpen || (logic->IsAdult && logic->HasItem(RG_GERUDO_MEMBERSHIP_CARD) && logic->HasItem(RG_CHILD_WALLET));}),
|
||||
EventAccess(&logic->GtG_GateOpen, []{return logic->IsAdult && logic->HasItem(RG_GERUDO_MEMBERSHIP_CARD) && logic->HasItem(RG_CHILD_WALLET);}),
|
||||
}, {
|
||||
//Locations
|
||||
LOCATION(RC_GF_CHEST, logic->CanUse(RG_HOVER_BOOTS) || (logic->IsAdult && logic->CanUse(RG_SCARECROW)) || logic->CanUse(RG_LONGSHOT)),
|
||||
|
|
|
@ -17,7 +17,7 @@ void RegionTable_Init_CastleGrounds() {
|
|||
areaTable[RR_HYRULE_CASTLE_GROUNDS] = Region("Hyrule Castle Grounds", "Castle Grounds", {RA_HYRULE_CASTLE}, DAY_NIGHT_CYCLE, {
|
||||
//Events
|
||||
EventAccess(&logic->GossipStoneFairy, []{return logic->CallGossipFairy();}),
|
||||
EventAccess(&logic->ButterflyFairy, []{return logic->ButterflyFairy || logic->CanUse(RG_STICKS);}),
|
||||
EventAccess(&logic->ButterflyFairy, []{return logic->CanUse(RG_STICKS);}),
|
||||
EventAccess(&logic->BugRock, []{return true;}),
|
||||
}, {
|
||||
//Locations
|
||||
|
|
|
@ -14,7 +14,7 @@ void RegionTable_Init_DeathMountainCrater() {
|
|||
|
||||
areaTable[RR_DMC_UPPER_LOCAL] = Region("DMC Upper Local", "Death Mountain Crater", {RA_DEATH_MOUNTAIN_CRATER}, NO_DAY_NIGHT_CYCLE, {
|
||||
//Events
|
||||
EventAccess(&logic->GossipStoneFairy, []{return logic->GossipStoneFairy || (logic->HasExplosives() && logic->CallGossipFairyExceptSuns() && (logic->FireTimer() >= 16 || logic->Hearts() >= 3));}),
|
||||
EventAccess(&logic->GossipStoneFairy, []{return logic->HasExplosives() && logic->CallGossipFairyExceptSuns() && (logic->FireTimer() >= 16 || logic->Hearts() >= 3);}),
|
||||
}, {
|
||||
//Locations
|
||||
LOCATION(RC_DMC_WALL_FREESTANDING_POH, logic->FireTimer() >= 16 || logic->Hearts() >= 3),
|
||||
|
|
|
@ -33,7 +33,7 @@ void RegionTable_Init_DeathMountainTrail() {
|
|||
areaTable[RR_DEATH_MOUNTAIN_SUMMIT] = Region("Death Mountain Summit", "Death Mountain", {RA_DEATH_MOUNTAIN_TRAIL}, DAY_NIGHT_CYCLE, {
|
||||
//Events
|
||||
EventAccess(&logic->GossipStoneFairy, []{return logic->CallGossipFairy();}),
|
||||
EventAccess(&logic->BugRock, []{return logic->BugRock || logic->IsChild;}),
|
||||
EventAccess(&logic->BugRock, []{return logic->IsChild;}),
|
||||
}, {
|
||||
//Locations
|
||||
LOCATION(RC_DMT_TRADE_BROKEN_SWORD, logic->IsAdult && logic->CanUse(RG_BROKEN_SWORD)),
|
||||
|
|
|
@ -7,7 +7,7 @@ void RegionTable_Init_DesertColossus() {
|
|||
// clang-format off
|
||||
areaTable[RR_DESERT_COLOSSUS] = Region("Desert Colossus", "Desert Colossus", {RA_DESERT_COLOSSUS}, DAY_NIGHT_CYCLE, {
|
||||
//Events
|
||||
EventAccess(&logic->FairyPond, []{return logic->FairyPond || logic->CanUse(RG_SONG_OF_STORMS);}),
|
||||
EventAccess(&logic->FairyPond, []{return logic->CanUse(RG_SONG_OF_STORMS);}),
|
||||
EventAccess(&logic->BugRock, []{return true;}),
|
||||
}, {
|
||||
//Locations
|
||||
|
|
|
@ -7,7 +7,7 @@ void RegionTable_Init_GerudoValley() {
|
|||
// clang-format off
|
||||
areaTable[RR_GERUDO_VALLEY] = Region("Gerudo Valley", "Gerudo Valley", {RA_GERUDO_VALLEY}, DAY_NIGHT_CYCLE, {
|
||||
//Events
|
||||
EventAccess(&logic->BugRock, []{return logic->BugRock || logic->IsChild;}),
|
||||
EventAccess(&logic->BugRock, []{return logic->IsChild;}),
|
||||
}, {
|
||||
//Locations
|
||||
LOCATION(RC_GV_GS_SMALL_BRIDGE, logic->IsChild && logic->HookshotOrBoomerang() && logic->CanGetNightTimeGS()),
|
||||
|
|
|
@ -8,12 +8,12 @@ void RegionTable_Init_GoronCity() {
|
|||
areaTable[RR_GORON_CITY] = Region("Goron City", "Goron City", {RA_GORON_CITY}, NO_DAY_NIGHT_CYCLE, {
|
||||
//Events
|
||||
EventAccess(&logic->GossipStoneFairy, []{return logic->CallGossipFairyExceptSuns();}),
|
||||
EventAccess(&logic->StickPot, []{return logic->StickPot || logic->IsChild;}),
|
||||
EventAccess(&logic->BugRock, []{return logic->BugRock || (logic->BlastOrSmash() || logic->CanUse(RG_SILVER_GAUNTLETS));}),
|
||||
EventAccess(&logic->GoronCityChildFire, []{return logic->GoronCityChildFire || (logic->IsChild && logic->CanUse(RG_DINS_FIRE));}),
|
||||
EventAccess(&logic->GCWoodsWarpOpen, []{return logic->GCWoodsWarpOpen || (logic->BlastOrSmash() || logic->CanUse(RG_DINS_FIRE) || logic->CanUse(RG_FAIRY_BOW) || logic->HasItem(RG_GORONS_BRACELET) || logic->GoronCityChildFire);}),
|
||||
EventAccess(&logic->GCDaruniasDoorOpenChild, []{return logic->GCDaruniasDoorOpenChild || (logic->IsChild && logic->CanUse(RG_ZELDAS_LULLABY));}),
|
||||
EventAccess(&logic->StopGCRollingGoronAsAdult, []{return logic->StopGCRollingGoronAsAdult || (logic->IsAdult && (logic->HasItem(RG_GORONS_BRACELET) || logic->HasExplosives() || logic->CanUse(RG_FAIRY_BOW) || (ctx->GetTrickOption(RT_GC_LINK_GORON_DINS) && logic->CanUse(RG_DINS_FIRE))));}),
|
||||
EventAccess(&logic->StickPot, []{return logic->IsChild;}),
|
||||
EventAccess(&logic->BugRock, []{return logic->BlastOrSmash() || logic->CanUse(RG_SILVER_GAUNTLETS);}),
|
||||
EventAccess(&logic->GoronCityChildFire, []{return logic->IsChild && logic->CanUse(RG_DINS_FIRE);}),
|
||||
EventAccess(&logic->GCWoodsWarpOpen, []{return logic->BlastOrSmash() || logic->CanUse(RG_DINS_FIRE) || logic->CanUse(RG_FAIRY_BOW) || logic->HasItem(RG_GORONS_BRACELET) || logic->GoronCityChildFire;}),
|
||||
EventAccess(&logic->GCDaruniasDoorOpenChild, []{return logic->IsChild && logic->CanUse(RG_ZELDAS_LULLABY);}),
|
||||
EventAccess(&logic->StopGCRollingGoronAsAdult, []{return logic->IsAdult && (logic->HasItem(RG_GORONS_BRACELET) || logic->HasExplosives() || logic->CanUse(RG_FAIRY_BOW) || (ctx->GetTrickOption(RT_GC_LINK_GORON_DINS) && logic->CanUse(RG_DINS_FIRE)));}),
|
||||
}, {
|
||||
//Locations
|
||||
LOCATION(RC_GC_MAZE_LEFT_CHEST, logic->CanUse(RG_MEGATON_HAMMER) || logic->CanUse(RG_SILVER_GAUNTLETS) || (ctx->GetTrickOption(RT_GC_LEFTMOST) && logic->HasExplosives() && logic->CanUse(RG_HOVER_BOOTS))),
|
||||
|
@ -58,7 +58,7 @@ void RegionTable_Init_GoronCity() {
|
|||
|
||||
areaTable[RR_GC_WOODS_WARP] = Region("GC Woods Warp", "Goron City", {RA_GORON_CITY}, NO_DAY_NIGHT_CYCLE, {
|
||||
//Events
|
||||
EventAccess(&logic->GCWoodsWarpOpen, []{return logic->GCWoodsWarpOpen || (logic->BlastOrSmash() || logic->CanUse(RG_DINS_FIRE));}),
|
||||
EventAccess(&logic->GCWoodsWarpOpen, []{return logic->BlastOrSmash() || logic->CanUse(RG_DINS_FIRE);}),
|
||||
}, {}, {
|
||||
//Exits
|
||||
Entrance(RR_GORON_CITY, []{return logic->CanLeaveForest() && logic->GCWoodsWarpOpen;}),
|
||||
|
@ -67,7 +67,7 @@ void RegionTable_Init_GoronCity() {
|
|||
|
||||
areaTable[RR_GC_DARUNIAS_CHAMBER] = Region("GC Darunias Chamber", "Goron City", {RA_GORON_CITY}, NO_DAY_NIGHT_CYCLE, {
|
||||
//Events
|
||||
EventAccess(&logic->GoronCityChildFire, []{return logic->GoronCityChildFire || (logic->IsChild && logic->CanUse(RG_STICKS));}),
|
||||
EventAccess(&logic->GoronCityChildFire, []{return logic->IsChild && logic->CanUse(RG_STICKS);}),
|
||||
}, {
|
||||
//Locations
|
||||
LOCATION(RC_GC_DARUNIAS_JOY, logic->IsChild && logic->CanUse(RG_SARIAS_SONG)),
|
||||
|
|
|
@ -7,7 +7,7 @@ void RegionTable_Init_Graveyard() {
|
|||
// clang-format off
|
||||
areaTable[RR_THE_GRAVEYARD] = Region("The Graveyard", "The Graveyard", {RA_THE_GRAVEYARD}, NO_DAY_NIGHT_CYCLE, {
|
||||
//Events
|
||||
EventAccess(&logic->ButterflyFairy, []{return logic->ButterflyFairy || (logic->CanUse(RG_STICKS) && logic->AtDay);}),
|
||||
EventAccess(&logic->ButterflyFairy, []{return logic->CanUse(RG_STICKS) && logic->AtDay;}),
|
||||
EventAccess(&logic->BeanPlantFairy, []{return logic->IsChild && logic->CanUse(RG_MAGIC_BEAN) && logic->CanUse(RG_SONG_OF_STORMS);}),
|
||||
EventAccess(&logic->BugRock, []{return true;}),
|
||||
}, {
|
||||
|
@ -88,7 +88,7 @@ void RegionTable_Init_Graveyard() {
|
|||
areaTable[RR_GRAVEYARD_DAMPES_GRAVE] = Region("Graveyard Dampes Grave", "Windmill and Dampes Grave", {}, NO_DAY_NIGHT_CYCLE, {
|
||||
//Events
|
||||
EventAccess(&logic->NutPot, []{return true;}),
|
||||
EventAccess(&logic->DampesWindmillAccess, []{return logic->DampesWindmillAccess || (logic->IsAdult && logic->CanUse(RG_SONG_OF_TIME));}),
|
||||
EventAccess(&logic->DampesWindmillAccess, []{return logic->IsAdult && logic->CanUse(RG_SONG_OF_TIME);}),
|
||||
}, {
|
||||
//Locations
|
||||
LOCATION(RC_GRAVEYARD_HOOKSHOT_CHEST, true),
|
||||
|
|
|
@ -66,7 +66,7 @@ void RegionTable_Init_Kakariko() {
|
|||
Entrance(RR_KAK_WINDMILL, []{return logic->CanOpenOverworldDoor(RG_WINDMILL_KEY);}),
|
||||
Entrance(RR_KAK_BAZAAR, []{return logic->IsAdult && logic->AtDay && logic->CanOpenOverworldDoor(RG_KAK_BAZAAR_KEY);}),
|
||||
Entrance(RR_KAK_SHOOTING_GALLERY, []{return logic->IsAdult && logic->AtDay && logic->CanOpenOverworldDoor(RG_KAK_SHOOTING_GALLERY_KEY);}),
|
||||
Entrance(RR_KAK_WELL, []{return logic->IsAdult || logic->DrainWell || logic->CanUse(RG_IRON_BOOTS);}),
|
||||
Entrance(RR_KAK_WELL, []{return logic->IsAdult || logic->DrainWell || logic->CanUse(RG_IRON_BOOTS) || (ctx->GetTrickOption(RT_BOTTOM_OF_THE_WELL_NAVI_DIVE) && logic->IsChild && logic->HasItem(RG_BRONZE_SCALE) && logic->CanJumpslash());}),
|
||||
Entrance(RR_KAK_POTION_SHOP_FRONT, []{return (logic->AtDay || logic->IsChild) && logic->CanOpenOverworldDoor(RG_KAK_POTION_SHOP_KEY);}),
|
||||
Entrance(RR_KAK_REDEAD_GROTTO, []{return logic->CanOpenBombGrotto();}),
|
||||
Entrance(RR_KAK_IMPAS_LEDGE, []{return (logic->IsChild && logic->AtDay) || (logic->IsAdult && ctx->GetTrickOption(RT_VISIBLE_COLLISION));}),
|
||||
|
@ -166,7 +166,7 @@ void RegionTable_Init_Kakariko() {
|
|||
|
||||
areaTable[RR_KAK_WINDMILL] = Region("Kak Windmill", "Windmill and Dampes Grave", {}, NO_DAY_NIGHT_CYCLE, {
|
||||
//Events
|
||||
EventAccess(&logic->DrainWell, []{return logic->DrainWell || (logic->IsChild && logic->CanUse(RG_SONG_OF_STORMS));}),
|
||||
EventAccess(&logic->DrainWell, []{return logic->IsChild && logic->CanUse(RG_SONG_OF_STORMS);}),
|
||||
}, {
|
||||
//Locations
|
||||
LOCATION(RC_KAK_WINDMILL_FREESTANDING_POH, logic->CanUse(RG_BOOMERANG) || logic->DampesWindmillAccess || (logic->IsAdult && ctx->GetTrickOption(RT_KAK_ADULT_WINDMILL_POH)) || (logic->IsChild && logic->CanJumpslashExceptHammer() && ctx->GetTrickOption(RT_KAK_CHILD_WINDMILL_POH))),
|
||||
|
|
|
@ -9,7 +9,7 @@ void RegionTable_Init_KokiriForest() {
|
|||
//Events
|
||||
EventAccess(&logic->BeanPlantFairy, []{return logic->IsChild && logic->CanUse(RG_MAGIC_BEAN) && logic->CanUse(RG_SONG_OF_STORMS);}),
|
||||
EventAccess(&logic->GossipStoneFairy, []{return logic->CallGossipFairyExceptSuns();}),
|
||||
EventAccess(&logic->ShowedMidoSwordAndShield, []{return logic->ShowedMidoSwordAndShield || (logic->IsChild && logic->CanUse(RG_KOKIRI_SWORD) && logic->CanUse(RG_DEKU_SHIELD));}),
|
||||
EventAccess(&logic->ShowedMidoSwordAndShield, []{return logic->IsChild && logic->CanUse(RG_KOKIRI_SWORD) && logic->CanUse(RG_DEKU_SHIELD);}),
|
||||
}, {
|
||||
//Locations
|
||||
LOCATION(RC_KF_KOKIRI_SWORD_CHEST, logic->IsChild),
|
||||
|
@ -93,7 +93,7 @@ void RegionTable_Init_KokiriForest() {
|
|||
//Events
|
||||
EventAccess(&logic->DekuBabaSticks, []{return logic->CanGetDekuBabaSticks();}),
|
||||
EventAccess(&logic->DekuBabaNuts, []{return logic->CanGetDekuBabaNuts();}),
|
||||
EventAccess(&logic->ShowedMidoSwordAndShield, []{return logic->ShowedMidoSwordAndShield || (logic->IsChild && logic->CanUse(RG_KOKIRI_SWORD) && logic->CanUse(RG_DEKU_SHIELD));}),
|
||||
EventAccess(&logic->ShowedMidoSwordAndShield, []{return logic->IsChild && logic->CanUse(RG_KOKIRI_SWORD) && logic->CanUse(RG_DEKU_SHIELD);}),
|
||||
}, {
|
||||
//Locations
|
||||
LOCATION(RC_KF_DEKU_TREE_LEFT_GOSSIP_STONE_FAIRY, logic->CallGossipFairyExceptSuns()),
|
||||
|
|
|
@ -9,10 +9,10 @@ void RegionTable_Init_LakeHylia() {
|
|||
//Events
|
||||
EventAccess(&logic->GossipStoneFairy, []{return logic->CallGossipFairy();}),
|
||||
EventAccess(&logic->BeanPlantFairy, []{return logic->IsChild && logic->CanUse(RG_MAGIC_BEAN) && logic->CanUse(RG_SONG_OF_STORMS);}),
|
||||
EventAccess(&logic->ButterflyFairy, []{return logic->ButterflyFairy || logic->CanUse(RG_STICKS);}),
|
||||
EventAccess(&logic->BugShrub, []{return logic->BugShrub || (logic->IsChild && logic->CanCutShrubs());}),
|
||||
EventAccess(&logic->ChildScarecrow, []{return logic->ChildScarecrow || (logic->IsChild && logic->HasItem(RG_FAIRY_OCARINA) && logic->OcarinaButtons() >= 2);}),
|
||||
EventAccess(&logic->AdultScarecrow, []{return logic->AdultScarecrow || (logic->IsAdult && logic->HasItem(RG_FAIRY_OCARINA) && logic->OcarinaButtons() >= 2);}),
|
||||
EventAccess(&logic->ButterflyFairy, []{return logic->CanUse(RG_STICKS);}),
|
||||
EventAccess(&logic->BugShrub, []{return logic->IsChild && logic->CanCutShrubs();}),
|
||||
EventAccess(&logic->ChildScarecrow, []{return logic->IsChild && logic->HasItem(RG_FAIRY_OCARINA) && logic->OcarinaButtons() >= 2;}),
|
||||
EventAccess(&logic->AdultScarecrow, []{return logic->IsAdult && logic->HasItem(RG_FAIRY_OCARINA) && logic->OcarinaButtons() >= 2;}),
|
||||
}, {
|
||||
//Locations
|
||||
LOCATION(RC_LH_UNDERWATER_ITEM, logic->IsChild && logic->HasItem(RG_SILVER_SCALE)),
|
||||
|
|
|
@ -7,8 +7,8 @@ void RegionTable_Init_LonLonRanch() {
|
|||
// clang-format off
|
||||
areaTable[RR_LON_LON_RANCH] = Region("Lon Lon Ranch", "Lon Lon Ranch", {RA_LON_LON_RANCH}, NO_DAY_NIGHT_CYCLE, {
|
||||
//Events
|
||||
EventAccess(&logic->FreedEpona, []{return logic->FreedEpona || ((logic->HasItem(RG_CHILD_WALLET) || ctx->GetOption(RSK_SKIP_EPONA_RACE)) && logic->CanUse(RG_EPONAS_SONG) && logic->IsAdult && logic->AtDay);}),
|
||||
EventAccess(&logic->LinksCow, []{return logic->LinksCow || (logic->HasItem(RG_CHILD_WALLET) && logic->CanUse(RG_EPONAS_SONG) && logic->IsAdult && logic->AtDay);}),
|
||||
EventAccess(&logic->FreedEpona, []{return (logic->HasItem(RG_CHILD_WALLET) || ctx->GetOption(RSK_SKIP_EPONA_RACE)) && logic->CanUse(RG_EPONAS_SONG) && logic->IsAdult && logic->AtDay;}),
|
||||
EventAccess(&logic->LinksCow, []{return logic->HasItem(RG_CHILD_WALLET) && logic->CanUse(RG_EPONAS_SONG) && logic->IsAdult && logic->AtDay;}),
|
||||
}, {
|
||||
//Locations
|
||||
LOCATION(RC_SONG_FROM_MALON, logic->IsChild && logic->HasItem(RG_ZELDAS_LETTER) && logic->HasItem(RG_FAIRY_OCARINA) && logic->AtDay),
|
||||
|
|
|
@ -57,14 +57,14 @@ void RegionTable_Init_LostWoods() {
|
|||
Entrance(RR_LW_FOREST_EXIT, []{return true;}),
|
||||
Entrance(RR_GC_WOODS_WARP, []{return true;}),
|
||||
Entrance(RR_LW_BRIDGE, []{return logic->CanLeaveForest() && ((logic->IsAdult && (CanPlantBean(RR_THE_LOST_WOODS) || ctx->GetTrickOption(RT_LW_BRIDGE))) || logic->CanUse(RG_HOVER_BOOTS) || logic->CanUse(RG_LONGSHOT));}),
|
||||
Entrance(RR_ZORAS_RIVER, []{return logic->CanLeaveForest() && (logic->HasItem(RG_SILVER_SCALE) || logic->CanUse(RG_IRON_BOOTS));}),
|
||||
Entrance(RR_ZORAS_RIVER, []{return logic->CanLeaveForest() && (logic->HasItem(RG_SILVER_SCALE) || logic->CanUse(RG_IRON_BOOTS) || (ctx->GetTrickOption(RT_BOTTOM_OF_THE_WELL_NAVI_DIVE) && logic->IsChild && logic->HasItem(RG_BRONZE_SCALE) && logic->CanJumpslash()));}),
|
||||
Entrance(RR_LW_BEYOND_MIDO, []{return logic->IsChild || logic->CanUse(RG_SARIAS_SONG) || ctx->GetTrickOption(RT_LW_MIDO_BACKFLIP);}),
|
||||
Entrance(RR_LW_NEAR_SHORTCUTS_GROTTO, []{return Here(RR_THE_LOST_WOODS, []{return logic->BlastOrSmash();});}),
|
||||
});
|
||||
|
||||
areaTable[RR_LW_BEYOND_MIDO] = Region("LW Beyond Mido", "Lost Woods", {RA_THE_LOST_WOODS}, NO_DAY_NIGHT_CYCLE, {
|
||||
//Events
|
||||
EventAccess(&logic->ButterflyFairy, []{return logic->ButterflyFairy || logic->CanUse(RG_STICKS);}),
|
||||
EventAccess(&logic->ButterflyFairy, []{return logic->CanUse(RG_STICKS);}),
|
||||
}, {
|
||||
//Locations
|
||||
LOCATION(RC_LW_DEKU_SCRUB_NEAR_DEKU_THEATER_RIGHT, logic->IsChild && logic->CanStunDeku()),
|
||||
|
|
|
@ -54,7 +54,7 @@ void RegionTable_Init_Market() {
|
|||
EventAccess(&logic->CanEmptyBigPoes, []{return logic->IsAdult;}),
|
||||
}, {
|
||||
//Locations
|
||||
LOCATION(RC_MARKET_10_BIG_POES, logic->IsAdult && (logic->BigPoeKill || logic->BigPoes > ctx->GetOption(RSK_BIG_POE_COUNT).Get())),
|
||||
LOCATION(RC_MARKET_10_BIG_POES, logic->IsAdult && (logic->BigPoeKill || logic->BigPoes >= ctx->GetOption(RSK_BIG_POE_COUNT).Get())),
|
||||
LOCATION(RC_MARKET_GS_GUARD_HOUSE, logic->IsChild),
|
||||
LOCATION(RC_MK_GUARD_HOUSE_CHILD_POT_1, logic->IsChild && logic->CanBreakPots()),
|
||||
LOCATION(RC_MK_GUARD_HOUSE_CHILD_POT_2, logic->IsChild && logic->CanBreakPots()),
|
||||
|
@ -138,8 +138,8 @@ void RegionTable_Init_Market() {
|
|||
|
||||
areaTable[RR_MARKET_MASK_SHOP] = Region("Market Mask Shop", "Market Mask Shop", {}, NO_DAY_NIGHT_CYCLE, {
|
||||
//Events
|
||||
EventAccess(&logic->SkullMask, []{return logic->SkullMask || (logic->HasItem(RG_ZELDAS_LETTER) && (ctx->GetOption(RSK_COMPLETE_MASK_QUEST) || ChildCanAccess(RR_KAKARIKO_VILLAGE)));}), //RANDOTODO Complete mask quest does not need this location, so should be tied to link's pocket
|
||||
EventAccess(&logic->MaskOfTruth, []{return logic->MaskOfTruth || (logic->SkullMask && (ctx->GetOption(RSK_COMPLETE_MASK_QUEST) || (ChildCanAccess(RR_THE_LOST_WOODS) && logic->CanUse(RG_SARIAS_SONG) && RegionTable(RR_THE_GRAVEYARD)->childDay && ChildCanAccess(RR_HYRULE_FIELD) && logic->StoneCount() == 3)));}),
|
||||
EventAccess(&logic->SkullMask, []{return logic->HasItem(RG_ZELDAS_LETTER) && (ctx->GetOption(RSK_COMPLETE_MASK_QUEST) || ChildCanAccess(RR_KAKARIKO_VILLAGE));}), //RANDOTODO Complete mask quest does not need this location, so should be tied to link's pocket
|
||||
EventAccess(&logic->MaskOfTruth, []{return logic->SkullMask && (ctx->GetOption(RSK_COMPLETE_MASK_QUEST) || (ChildCanAccess(RR_THE_LOST_WOODS) && logic->CanUse(RG_SARIAS_SONG) && RegionTable(RR_THE_GRAVEYARD)->childDay && ChildCanAccess(RR_HYRULE_FIELD) && logic->StoneCount() == 3));}),
|
||||
}, {
|
||||
//Locations
|
||||
LOCATION(RC_MASK_SHOP_HINT, true),
|
||||
|
|
|
@ -9,10 +9,10 @@ void RegionTable_Init_ZorasDomain() {
|
|||
//Events
|
||||
EventAccess(&logic->GossipStoneFairy, []{return logic->CallGossipFairyExceptSuns();}),
|
||||
EventAccess(&logic->NutPot, []{return true;}),
|
||||
EventAccess(&logic->StickPot, []{return logic->StickPot || logic->IsChild;}),
|
||||
EventAccess(&logic->FishGroup, []{return logic->FishGroup || logic->IsChild;}),
|
||||
EventAccess(&logic->KingZoraThawed, []{return logic->KingZoraThawed || (logic->IsAdult && logic->BlueFire());}),
|
||||
EventAccess(&logic->DeliverLetter, []{return logic->DeliverLetter || (logic->CanUse(RG_RUTOS_LETTER) && logic->IsChild && ctx->GetOption(RSK_ZORAS_FOUNTAIN).IsNot(RO_ZF_OPEN));}),
|
||||
EventAccess(&logic->StickPot, []{return logic->IsChild;}),
|
||||
EventAccess(&logic->FishGroup, []{return logic->IsChild;}),
|
||||
EventAccess(&logic->KingZoraThawed, []{return logic->IsAdult && logic->BlueFire();}),
|
||||
EventAccess(&logic->DeliverLetter, []{return logic->CanUse(RG_RUTOS_LETTER) && logic->IsChild && ctx->GetOption(RSK_ZORAS_FOUNTAIN).IsNot(RO_ZF_OPEN);}),
|
||||
}, {
|
||||
//Locations
|
||||
LOCATION(RC_ZD_DIVING_MINIGAME, logic->HasItem(RG_BRONZE_SCALE) && logic->HasItem(RG_CHILD_WALLET) && logic->IsChild),
|
||||
|
|
|
@ -8,7 +8,7 @@ void RegionTable_Init_ZorasFountain() {
|
|||
areaTable[RR_ZORAS_FOUNTAIN] = Region("Zoras Fountain", "Zoras Fountain", {RA_ZORAS_FOUNTAIN}, NO_DAY_NIGHT_CYCLE, {
|
||||
//Events
|
||||
EventAccess(&logic->GossipStoneFairy, []{return logic->CallGossipFairyExceptSuns();}),
|
||||
EventAccess(&logic->ButterflyFairy, []{return logic->ButterflyFairy || (logic->CanUse(RG_STICKS) && logic->AtDay);}),
|
||||
EventAccess(&logic->ButterflyFairy, []{return logic->CanUse(RG_STICKS) && logic->AtDay;}),
|
||||
}, {
|
||||
//Locations
|
||||
LOCATION(RC_ZF_GS_TREE, logic->IsChild),
|
||||
|
|
|
@ -30,8 +30,8 @@ void RegionTable_Init_ZoraRiver() {
|
|||
//Events
|
||||
EventAccess(&logic->GossipStoneFairy, []{return logic->CallGossipFairy();}),
|
||||
EventAccess(&logic->BeanPlantFairy, []{return logic->IsChild && logic->CanUse(RG_MAGIC_BEAN) && logic->CanUse(RG_SONG_OF_STORMS);}),
|
||||
EventAccess(&logic->ButterflyFairy, []{return logic->ButterflyFairy || logic->CanUse(RG_STICKS);}),
|
||||
EventAccess(&logic->BugShrub, []{return logic->BugShrub || logic->CanCutShrubs();}),
|
||||
EventAccess(&logic->ButterflyFairy, []{return logic->CanUse(RG_STICKS);}),
|
||||
EventAccess(&logic->BugShrub, []{return logic->CanCutShrubs();}),
|
||||
}, {
|
||||
//Locations
|
||||
LOCATION(RC_ZR_MAGIC_BEAN_SALESMAN, logic->HasItem(RG_CHILD_WALLET) && logic->IsChild),
|
||||
|
|
|
@ -842,40 +842,6 @@ void Rando::StaticData::InitLocationTable() {
|
|||
locationTable[RC_SONG_FROM_OCARINA_OF_TIME] = Location::Base(RC_SONG_FROM_OCARINA_OF_TIME, RCQUEST_BOTH, RCTYPE_SONG_LOCATION, ACTOR_ID_MAX, SCENE_HYRULE_FIELD, 0x00, "Song from Ocarina of Time", "Song from Ocarina of Time", RHT_SONG_FROM_OCARINA_OF_TIME, RG_SONG_OF_TIME, SpoilerCollectionCheck::EventChkInf(EVENTCHKINF_LEARNED_SONG_OF_TIME), true);
|
||||
locationTable[RC_SONG_FROM_WINDMILL] = Location::Base(RC_SONG_FROM_WINDMILL, RCQUEST_BOTH, RCTYPE_SONG_LOCATION, RCAREA_KAKARIKO_VILLAGE, ACTOR_ID_MAX, SCENE_WINDMILL_AND_DAMPES_GRAVE, 0x00, "Song from Windmill", "Song from Windmill", RHT_SONG_FROM_WINDMILL, RG_SONG_OF_STORMS, SpoilerCollectionCheck::EventChkInf(EVENTCHKINF_LEARNED_SONG_OF_STORMS), true);
|
||||
|
||||
//Beehives
|
||||
locationTable[RC_KF_STORMS_GROTTO_BEEHIVE_LEFT] = Location::Base(RC_KF_STORMS_GROTTO_BEEHIVE_LEFT, RCQUEST_BOTH, RCTYPE_BEEHIVE, RCAREA_KOKIRI_FOREST, ACTOR_OBJ_COMB, SCENE_GROTTOS, TWO_ACTOR_PARAMS(-144, 0x2C), "Storms Grotto Beehive Left", RHT_BEEHIVE_CHEST_GROTTO, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_BEEHIVE_KF_STORMS_GROTTO_LEFT));
|
||||
locationTable[RC_KF_STORMS_GROTTO_BEEHIVE_RIGHT] = Location::Base(RC_KF_STORMS_GROTTO_BEEHIVE_RIGHT, RCQUEST_BOTH, RCTYPE_BEEHIVE, RCAREA_KOKIRI_FOREST, ACTOR_OBJ_COMB, SCENE_GROTTOS, TWO_ACTOR_PARAMS(121, 0x2C), "Storms Grotto Beehive Right", RHT_BEEHIVE_CHEST_GROTTO, RG_RED_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_BEEHIVE_KF_STORMS_GROTTO_RIGHT));
|
||||
locationTable[RC_LW_NEAR_SHORTCUTS_GROTTO_BEEHIVE_LEFT] = Location::Base(RC_LW_NEAR_SHORTCUTS_GROTTO_BEEHIVE_LEFT, RCQUEST_BOTH, RCTYPE_BEEHIVE, RCAREA_LOST_WOODS, ACTOR_OBJ_COMB, SCENE_GROTTOS, TWO_ACTOR_PARAMS(-144, 0x14), "Tunnel Grotto Beehive Left", RHT_BEEHIVE_CHEST_GROTTO, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_BEEHIVE_LW_NEAR_SHORTCUTS_GROTTO_LEFT));
|
||||
locationTable[RC_LW_NEAR_SHORTCUTS_GROTTO_BEEHIVE_RIGHT] = Location::Base(RC_LW_NEAR_SHORTCUTS_GROTTO_BEEHIVE_RIGHT, RCQUEST_BOTH, RCTYPE_BEEHIVE, RCAREA_LOST_WOODS, ACTOR_OBJ_COMB, SCENE_GROTTOS, TWO_ACTOR_PARAMS(121, 0x14), "Tunnel Grotto Beehive Right", RHT_BEEHIVE_CHEST_GROTTO, RG_RED_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_BEEHIVE_LW_NEAR_SHORTCUTS_GROTTO_RIGHT));
|
||||
locationTable[RC_LW_DEKU_SCRUB_GROTTO_BEEHIVE] = Location::Base(RC_LW_DEKU_SCRUB_GROTTO_BEEHIVE, RCQUEST_BOTH, RCTYPE_BEEHIVE, RCAREA_LOST_WOODS, ACTOR_OBJ_COMB, SCENE_GROTTOS, TWO_ACTOR_PARAMS(747, 0xF5), "Deku Scrub Grotto Beehive", RHT_BEEHIVE_SCRUB_PAIR_GROTTO, RG_RED_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_BEEHIVE_LW_DEKU_SCRUB_GROTTO));
|
||||
locationTable[RC_SFM_STORMS_GROTTO_BEEHIVE] = Location::Base(RC_SFM_STORMS_GROTTO_BEEHIVE, RCQUEST_BOTH, RCTYPE_BEEHIVE, RCAREA_SACRED_FOREST_MEADOW, ACTOR_OBJ_COMB, SCENE_GROTTOS, TWO_ACTOR_PARAMS(2262, 0xEE), "Deku Scrub Grotto Beehive", RHT_BEEHIVE_SCRUB_PAIR_GROTTO, RG_RED_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_BEEHIVE_SFM_STORMS_GROTTO));
|
||||
locationTable[RC_HF_NEAR_MARKET_GROTTO_BEEHIVE_LEFT] = Location::Base(RC_HF_NEAR_MARKET_GROTTO_BEEHIVE_LEFT, RCQUEST_BOTH, RCTYPE_BEEHIVE, RCAREA_HYRULE_FIELD, ACTOR_OBJ_COMB, SCENE_GROTTOS, TWO_ACTOR_PARAMS(-144, 0x00), "Near Market Grotto Beehive Left", RHT_BEEHIVE_CHEST_GROTTO, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_BEEHIVE_HF_NEAR_MARKET_GROTTO_LEFT));
|
||||
locationTable[RC_HF_NEAR_MARKET_GROTTO_BEEHIVE_RIGHT] = Location::Base(RC_HF_NEAR_MARKET_GROTTO_BEEHIVE_RIGHT, RCQUEST_BOTH, RCTYPE_BEEHIVE, RCAREA_HYRULE_FIELD, ACTOR_OBJ_COMB, SCENE_GROTTOS, TWO_ACTOR_PARAMS(121, 0x00), "Near Market Grotto Beehive Right", RHT_BEEHIVE_CHEST_GROTTO, RG_RED_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_BEEHIVE_HF_NEAR_MARKET_GROTTO_RIGHT));
|
||||
locationTable[RC_HF_OPEN_GROTTO_BEEHIVE_LEFT] = Location::Base(RC_HF_OPEN_GROTTO_BEEHIVE_LEFT, RCQUEST_BOTH, RCTYPE_BEEHIVE, RCAREA_HYRULE_FIELD, ACTOR_OBJ_COMB, SCENE_GROTTOS, TWO_ACTOR_PARAMS(-144, 0x03), "Open Grotto Beehive Left", RHT_BEEHIVE_CHEST_GROTTO, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_BEEHIVE_HF_OPEN_GROTTO_LEFT));
|
||||
locationTable[RC_HF_OPEN_GROTTO_BEEHIVE_RIGHT] = Location::Base(RC_HF_OPEN_GROTTO_BEEHIVE_RIGHT, RCQUEST_BOTH, RCTYPE_BEEHIVE, RCAREA_HYRULE_FIELD, ACTOR_OBJ_COMB, SCENE_GROTTOS, TWO_ACTOR_PARAMS(121, 0x03), "Open Grotto Beehive Right", RHT_BEEHIVE_CHEST_GROTTO, RG_RED_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_BEEHIVE_HF_OPEN_GROTTO_RIGHT));
|
||||
locationTable[RC_HF_SOUTHEAST_GROTTO_BEEHIVE_LEFT] = Location::Base(RC_HF_SOUTHEAST_GROTTO_BEEHIVE_LEFT, RCQUEST_BOTH, RCTYPE_BEEHIVE, RCAREA_HYRULE_FIELD, ACTOR_OBJ_COMB, SCENE_GROTTOS, TWO_ACTOR_PARAMS(-144, 0x22), "Southeast Grotto Beehive Left", RHT_BEEHIVE_CHEST_GROTTO, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_BEEHIVE_HF_SOUTHEAST_GROTTO_LEFT));
|
||||
locationTable[RC_HF_SOUTHEAST_GROTTO_BEEHIVE_RIGHT] = Location::Base(RC_HF_SOUTHEAST_GROTTO_BEEHIVE_RIGHT, RCQUEST_BOTH, RCTYPE_BEEHIVE, RCAREA_HYRULE_FIELD, ACTOR_OBJ_COMB, SCENE_GROTTOS, TWO_ACTOR_PARAMS(121, 0x22), "Southeast Grotto Beehive Right", RHT_BEEHIVE_CHEST_GROTTO, RG_RED_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_BEEHIVE_HF_SOUTHEAST_GROTTO_RIGHT));
|
||||
locationTable[RC_HF_INSIDE_FENCE_GROTTO_BEEHIVE] = Location::Base(RC_HF_INSIDE_FENCE_GROTTO_BEEHIVE, RCQUEST_BOTH, RCTYPE_BEEHIVE, RCAREA_HYRULE_FIELD, ACTOR_OBJ_COMB, SCENE_GROTTOS, TWO_ACTOR_PARAMS(1410, 0xE6), "Deku Scrub Grotto Beehive", RHT_BEEHIVE_LONELY_SCRUB_GROTTO, RG_RED_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_BEEHIVE_HF_INSIDE_FENCE_GROTTO));
|
||||
locationTable[RC_LLR_GROTTO_BEEHIVE] = Location::Base(RC_LLR_GROTTO_BEEHIVE, RCQUEST_BOTH, RCTYPE_BEEHIVE, RCAREA_LON_LON_RANCH, ACTOR_OBJ_COMB, SCENE_GROTTOS, TWO_ACTOR_PARAMS(5144, 0xFC), "Deku Scrub Grotto Beehive", RHT_BEEHIVE_SCRUB_TRIO_GROTTO, RG_RED_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_BEEHIVE_LLR_GROTTO));
|
||||
locationTable[RC_KAK_OPEN_GROTTO_BEEHIVE_LEFT] = Location::Base(RC_KAK_OPEN_GROTTO_BEEHIVE_LEFT, RCQUEST_BOTH, RCTYPE_BEEHIVE, RCAREA_KAKARIKO_VILLAGE, ACTOR_OBJ_COMB, SCENE_GROTTOS, TWO_ACTOR_PARAMS(-144, 0x28), "Open Grotto Beehive Left", RHT_BEEHIVE_CHEST_GROTTO, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_BEEHIVE_KAK_OPEN_GROTTO_LEFT));
|
||||
locationTable[RC_KAK_OPEN_GROTTO_BEEHIVE_RIGHT] = Location::Base(RC_KAK_OPEN_GROTTO_BEEHIVE_RIGHT, RCQUEST_BOTH, RCTYPE_BEEHIVE, RCAREA_KAKARIKO_VILLAGE, ACTOR_OBJ_COMB, SCENE_GROTTOS, TWO_ACTOR_PARAMS(121, 0x28), "Open Grotto Beehive Right", RHT_BEEHIVE_CHEST_GROTTO, RG_RED_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_BEEHIVE_KAK_OPEN_GROTTO_RIGHT));
|
||||
locationTable[RC_DMT_COW_GROTTO_BEEHIVE] = Location::Base(RC_DMT_COW_GROTTO_BEEHIVE, RCQUEST_BOTH, RCTYPE_BEEHIVE, RCAREA_DEATH_MOUNTAIN_TRAIL, ACTOR_OBJ_COMB, SCENE_GROTTOS, TWO_ACTOR_PARAMS(2617, 0xF8), "Cow Grotto Beehive", RHT_BEEHIVE_COW_GROTTO, RG_RED_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_BEEHIVE_DMT_COW_GROTTO));
|
||||
locationTable[RC_DMT_STORMS_GROTTO_BEEHIVE_LEFT] = Location::Base(RC_DMT_STORMS_GROTTO_BEEHIVE_LEFT, RCQUEST_BOTH, RCTYPE_BEEHIVE, RCAREA_DEATH_MOUNTAIN_TRAIL, ACTOR_OBJ_COMB, SCENE_GROTTOS, TWO_ACTOR_PARAMS(-144, 0x57), "Storms Grotto Beehive Left", RHT_BEEHIVE_CHEST_GROTTO, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_BEEHIVE_DMT_STORMS_GROTTO_LEFT));
|
||||
locationTable[RC_DMT_STORMS_GROTTO_BEEHIVE_RIGHT] = Location::Base(RC_DMT_STORMS_GROTTO_BEEHIVE_RIGHT, RCQUEST_BOTH, RCTYPE_BEEHIVE, RCAREA_DEATH_MOUNTAIN_TRAIL, ACTOR_OBJ_COMB, SCENE_GROTTOS, TWO_ACTOR_PARAMS(121, 0x57), "Storms Grotto Beehive Right", RHT_BEEHIVE_CHEST_GROTTO, RG_RED_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_BEEHIVE_DMT_STORMS_GROTTO_RIGHT));
|
||||
locationTable[RC_GC_GROTTO_BEEHIVE] = Location::Base(RC_GC_GROTTO_BEEHIVE, RCQUEST_BOTH, RCTYPE_BEEHIVE, RCAREA_GORON_CITY, ACTOR_OBJ_COMB, SCENE_GROTTOS, TWO_ACTOR_PARAMS(5144, 0xFB), "Grotto Beehive", RHT_BEEHIVE_SCRUB_TRIO_GROTTO, RG_RED_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_BEEHIVE_GC_GROTTO));
|
||||
locationTable[RC_DMC_UPPER_GROTTO_BEEHIVE_LEFT] = Location::Base(RC_DMC_UPPER_GROTTO_BEEHIVE_LEFT, RCQUEST_BOTH, RCTYPE_BEEHIVE, RCAREA_DEATH_MOUNTAIN_CRATER, ACTOR_OBJ_COMB, SCENE_GROTTOS, TWO_ACTOR_PARAMS(-144, 0x7A), "Upper Grotto Beehive Left", RHT_BEEHIVE_CHEST_GROTTO, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_BEEHIVE_DMC_UPPER_GROTTO_LEFT));
|
||||
locationTable[RC_DMC_UPPER_GROTTO_BEEHIVE_RIGHT] = Location::Base(RC_DMC_UPPER_GROTTO_BEEHIVE_RIGHT, RCQUEST_BOTH, RCTYPE_BEEHIVE, RCAREA_DEATH_MOUNTAIN_CRATER, ACTOR_OBJ_COMB, SCENE_GROTTOS, TWO_ACTOR_PARAMS(121, 0x7A), "Upper Grotto Beehive Right", RHT_BEEHIVE_CHEST_GROTTO, RG_RED_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_BEEHIVE_DMC_UPPER_GROTTO_RIGHT));
|
||||
locationTable[RC_DMC_HAMMER_GROTTO_BEEHIVE] = Location::Base(RC_DMC_HAMMER_GROTTO_BEEHIVE, RCQUEST_BOTH, RCTYPE_BEEHIVE, RCAREA_DEATH_MOUNTAIN_CRATER, ACTOR_OBJ_COMB, SCENE_GROTTOS, TWO_ACTOR_PARAMS(5144, 0xF9), "Hammer Grotto Beehive", RHT_BEEHIVE_SCRUB_TRIO_GROTTO, RG_RED_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_BEEHIVE_DMC_HAMMER_GROTTO));
|
||||
locationTable[RC_ZR_OPEN_GROTTO_BEEHIVE_LEFT] = Location::Base(RC_ZR_OPEN_GROTTO_BEEHIVE_LEFT, RCQUEST_BOTH, RCTYPE_BEEHIVE, RCAREA_ZORAS_RIVER, ACTOR_OBJ_COMB, SCENE_GROTTOS, TWO_ACTOR_PARAMS(-144, 0x29), "Open Grotto Beehive Left", RHT_BEEHIVE_CHEST_GROTTO, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_BEEHIVE_ZR_OPEN_GROTTO_LEFT));
|
||||
locationTable[RC_ZR_OPEN_GROTTO_BEEHIVE_RIGHT] = Location::Base(RC_ZR_OPEN_GROTTO_BEEHIVE_RIGHT, RCQUEST_BOTH, RCTYPE_BEEHIVE, RCAREA_ZORAS_RIVER, ACTOR_OBJ_COMB, SCENE_GROTTOS, TWO_ACTOR_PARAMS(121, 0x29), "Open Grotto Beehive Right", RHT_BEEHIVE_CHEST_GROTTO, RG_RED_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_BEEHIVE_ZR_OPEN_GROTTO_RIGHT));
|
||||
locationTable[RC_ZR_STORMS_GROTTO_BEEHIVE] = Location::Base(RC_ZR_STORMS_GROTTO_BEEHIVE, RCQUEST_BOTH, RCTYPE_BEEHIVE, RCAREA_ZORAS_RIVER, ACTOR_OBJ_COMB, SCENE_GROTTOS, TWO_ACTOR_PARAMS(2262, 0xEB), "Storms Grotto Beehive", RHT_BEEHIVE_SCRUB_PAIR_GROTTO, RG_RED_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_BEEHIVE_ZR_STORMS_GROTTO));
|
||||
locationTable[RC_ZD_IN_FRONT_OF_KING_ZORA_BEEHIVE_LEFT] = Location::Base(RC_ZD_IN_FRONT_OF_KING_ZORA_BEEHIVE_LEFT, RCQUEST_BOTH, RCTYPE_BEEHIVE, ACTOR_OBJ_COMB, SCENE_ZORAS_DOMAIN, TWO_ACTOR_PARAMS(382, 0x00), "In Front of King Zora Beehive Left", RHT_BEEHIVE_IN_FRONT_OF_KING_ZORA, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_BEEHIVE_ZD_IN_FRONT_OF_KING_ZORA_LEFT));
|
||||
locationTable[RC_ZD_IN_FRONT_OF_KING_ZORA_BEEHIVE_RIGHT] = Location::Base(RC_ZD_IN_FRONT_OF_KING_ZORA_BEEHIVE_RIGHT, RCQUEST_BOTH, RCTYPE_BEEHIVE, ACTOR_OBJ_COMB, SCENE_ZORAS_DOMAIN, TWO_ACTOR_PARAMS(948, 0x00), "In Front of King Zora Beehive Right", RHT_BEEHIVE_IN_FRONT_OF_KING_ZORA, RG_RED_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_BEEHIVE_ZD_IN_FRONT_OF_KING_ZORA_RIGHT));
|
||||
locationTable[RC_ZD_BEHIND_KING_ZORA_BEEHIVE] = Location::Base(RC_ZD_BEHIND_KING_ZORA_BEEHIVE, RCQUEST_BOTH, RCTYPE_BEEHIVE, ACTOR_OBJ_COMB, SCENE_ZORAS_DOMAIN, TWO_ACTOR_PARAMS(701, 0x00), "Behind King Zora Beehive", RHT_BEEHIVE_BEHIND_KING_ZORA, RG_RED_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_BEEHIVE_ZD_BEHIND_KING_ZORA));
|
||||
locationTable[RC_LH_GROTTO_BEEHIVE] = Location::Base(RC_LH_GROTTO_BEEHIVE, RCQUEST_BOTH, RCTYPE_BEEHIVE, RCAREA_LAKE_HYLIA, ACTOR_OBJ_COMB, SCENE_GROTTOS, TWO_ACTOR_PARAMS(5144, 0xEF), "Deku Scrub Grotto Beehive", RHT_BEEHIVE_SCRUB_TRIO_GROTTO, RG_RED_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_BEEHIVE_LH_GROTTO));
|
||||
locationTable[RC_GV_DEKU_SCRUB_GROTTO_BEEHIVE] = Location::Base(RC_GV_DEKU_SCRUB_GROTTO_BEEHIVE, RCQUEST_BOTH, RCTYPE_BEEHIVE, RCAREA_GERUDO_VALLEY, ACTOR_OBJ_COMB, SCENE_GROTTOS, TWO_ACTOR_PARAMS(2262, 0xF0), "Deku Scrub Grotto Beehive", RHT_BEEHIVE_SCRUB_PAIR_GROTTO, RG_RED_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_BEEHIVE_GV_DEKU_SCRUB_GROTTO));
|
||||
locationTable[RC_COLOSSUS_GROTTO_BEEHIVE] = Location::Base(RC_COLOSSUS_GROTTO_BEEHIVE, RCQUEST_BOTH, RCTYPE_BEEHIVE, RCAREA_DESERT_COLOSSUS, ACTOR_OBJ_COMB, SCENE_GROTTOS, TWO_ACTOR_PARAMS(2262, 0xFD), "Deku Scrub Grotto Beehive", RHT_BEEHIVE_SCRUB_PAIR_GROTTO, RG_RED_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_BEEHIVE_COLOSSUS_GROTTO));
|
||||
|
||||
/*-------------------------------
|
||||
--- SHOPS ---
|
||||
8 6 2 4
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue