mirror of
https://github.com/HarbourMasters/Shipwright.git
synced 2025-08-22 06:13:45 -07:00
Merge branch 'develop' into region_scene
This commit is contained in:
commit
a520834981
295 changed files with 5973 additions and 5684 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,10 +2,11 @@ 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")
|
||||
|
||||
project(Ship VERSION 9.0.1 LANGUAGES C CXX)
|
||||
project(Ship VERSION 9.0.2 LANGUAGES C CXX)
|
||||
include(CMake/soh-cvars.cmake)
|
||||
include(CMake/lus-cvars.cmake)
|
||||
|
||||
|
|
|
@ -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
|
||||
}
|
|
@ -239,7 +239,7 @@
|
|||
<Texture Name="gGoldSkulltulaItemNameENGTex" OutName="gold_skulltula_item_name_eng" Format="ia4" Width="128" Height="16" Offset="0x3B000"/>
|
||||
<Texture Name="gPieceOfHeartItemNameENGTex" OutName="piece_of_heart_item_name_eng" Format="ia4" Width="128" Height="16" Offset="0x3B400"/>
|
||||
<Texture Name="gUnusedPieceOfHeartItemName2JPNTex" OutName="piece_of_heart_item_name_unused_jpn_2" Format="ia4" Width="128" Height="16" Offset="0x3B800"/>
|
||||
<Texture Name="gBigKeyItemNameENGTex" OutName="big_key_item_name_eng" Format="ia4" Width="128" Height="16" Offset="0x3BC00"/>
|
||||
<Texture Name="gUnusedBigKeyItemNameENGTex" OutName="big_key_item_name_eng" Format="ia4" Width="128" Height="16" Offset="0x3BC00"/>
|
||||
<Texture Name="gCompassItemNameENGTex" OutName="compass_item_name_eng" Format="ia4" Width="128" Height="16" Offset="0x3C000"/>
|
||||
<Texture Name="gDungeonMapItemNameENGTex" OutName="dungeon_map_item_name_eng" Format="ia4" Width="128" Height="16" Offset="0x3C400"/>
|
||||
<Texture Name="gUnusedBossKeyItemName12JPNTex" OutName="boss_key_item_name_unused_jpn_12" Format="ia4" Width="128" Height="16" Offset="0x3C800"/>
|
||||
|
|
|
@ -239,7 +239,7 @@
|
|||
<Texture Name="gGoldSkulltulaItemNameENGTex" OutName="gold_skulltula_item_name_eng" Format="ia4" Width="128" Height="16" Offset="0x3B000"/>
|
||||
<Texture Name="gPieceOfHeartItemNameENGTex" OutName="piece_of_heart_item_name_eng" Format="ia4" Width="128" Height="16" Offset="0x3B400"/>
|
||||
<Texture Name="gUnusedPieceOfHeartItemName2JPNTex" OutName="piece_of_heart_item_name_unused_jpn_2" Format="ia4" Width="128" Height="16" Offset="0x3B800"/>
|
||||
<Texture Name="gBigKeyItemNameENGTex" OutName="big_key_item_name_eng" Format="ia4" Width="128" Height="16" Offset="0x3BC00"/>
|
||||
<Texture Name="gUnusedBigKeyItemNameENGTex" OutName="big_key_item_name_eng" Format="ia4" Width="128" Height="16" Offset="0x3BC00"/>
|
||||
<Texture Name="gCompassItemNameENGTex" OutName="compass_item_name_eng" Format="ia4" Width="128" Height="16" Offset="0x3C000"/>
|
||||
<Texture Name="gDungeonMapItemNameENGTex" OutName="dungeon_map_item_name_eng" Format="ia4" Width="128" Height="16" Offset="0x3C400"/>
|
||||
<Texture Name="gUnusedBossKeyItemName12JPNTex" OutName="boss_key_item_name_unused_jpn_12" Format="ia4" Width="128" Height="16" Offset="0x3C800"/>
|
||||
|
|
|
@ -239,7 +239,7 @@
|
|||
<Texture Name="gGoldSkulltulaItemNameENGTex" OutName="gold_skulltula_item_name_eng" Format="ia4" Width="128" Height="16" Offset="0x3B000"/>
|
||||
<Texture Name="gPieceOfHeartItemNameENGTex" OutName="piece_of_heart_item_name_eng" Format="ia4" Width="128" Height="16" Offset="0x3B400"/>
|
||||
<Texture Name="gUnusedPieceOfHeartItemName2JPNTex" OutName="piece_of_heart_item_name_unused_jpn_2" Format="ia4" Width="128" Height="16" Offset="0x3B800"/>
|
||||
<Texture Name="gBigKeyItemNameENGTex" OutName="big_key_item_name_eng" Format="ia4" Width="128" Height="16" Offset="0x3BC00"/>
|
||||
<Texture Name="gUnusedBigKeyItemNameENGTex" OutName="big_key_item_name_eng" Format="ia4" Width="128" Height="16" Offset="0x3BC00"/>
|
||||
<Texture Name="gCompassItemNameENGTex" OutName="compass_item_name_eng" Format="ia4" Width="128" Height="16" Offset="0x3C000"/>
|
||||
<Texture Name="gDungeonMapItemNameENGTex" OutName="dungeon_map_item_name_eng" Format="ia4" Width="128" Height="16" Offset="0x3C400"/>
|
||||
<Texture Name="gUnusedBossKeyItemName12JPNTex" OutName="boss_key_item_name_unused_jpn_12" Format="ia4" Width="128" Height="16" Offset="0x3C800"/>
|
||||
|
|
|
@ -239,7 +239,7 @@
|
|||
<Texture Name="gGoldSkulltulaItemNameENGTex" OutName="gold_skulltula_item_name_eng" Format="ia4" Width="128" Height="16" Offset="0x3B000"/>
|
||||
<Texture Name="gPieceOfHeartItemNameENGTex" OutName="piece_of_heart_item_name_eng" Format="ia4" Width="128" Height="16" Offset="0x3B400"/>
|
||||
<Texture Name="gUnusedPieceOfHeartItemName2JPNTex" OutName="piece_of_heart_item_name_unused_jpn_2" Format="ia4" Width="128" Height="16" Offset="0x3B800"/>
|
||||
<Texture Name="gBigKeyItemNameENGTex" OutName="big_key_item_name_eng" Format="ia4" Width="128" Height="16" Offset="0x3BC00"/>
|
||||
<Texture Name="gUnusedBigKeyItemNameENGTex" OutName="big_key_item_name_eng" Format="ia4" Width="128" Height="16" Offset="0x3BC00"/>
|
||||
<Texture Name="gCompassItemNameENGTex" OutName="compass_item_name_eng" Format="ia4" Width="128" Height="16" Offset="0x3C000"/>
|
||||
<Texture Name="gDungeonMapItemNameENGTex" OutName="dungeon_map_item_name_eng" Format="ia4" Width="128" Height="16" Offset="0x3C400"/>
|
||||
<Texture Name="gUnusedBossKeyItemName12JPNTex" OutName="boss_key_item_name_unused_jpn_12" Format="ia4" Width="128" Height="16" Offset="0x3C800"/>
|
||||
|
|
|
@ -239,7 +239,7 @@
|
|||
<Texture Name="gGoldSkulltulaItemNameENGTex" OutName="gold_skulltula_item_name_eng" Format="ia4" Width="128" Height="16" Offset="0x3B000"/>
|
||||
<Texture Name="gPieceOfHeartItemNameENGTex" OutName="piece_of_heart_item_name_eng" Format="ia4" Width="128" Height="16" Offset="0x3B400"/>
|
||||
<Texture Name="gUnusedPieceOfHeartItemName2JPNTex" OutName="piece_of_heart_item_name_unused_jpn_2" Format="ia4" Width="128" Height="16" Offset="0x3B800"/>
|
||||
<Texture Name="gBigKeyItemNameENGTex" OutName="big_key_item_name_eng" Format="ia4" Width="128" Height="16" Offset="0x3BC00"/>
|
||||
<Texture Name="gUnusedBigKeyItemNameENGTex" OutName="big_key_item_name_eng" Format="ia4" Width="128" Height="16" Offset="0x3BC00"/>
|
||||
<Texture Name="gCompassItemNameENGTex" OutName="compass_item_name_eng" Format="ia4" Width="128" Height="16" Offset="0x3C000"/>
|
||||
<Texture Name="gDungeonMapItemNameENGTex" OutName="dungeon_map_item_name_eng" Format="ia4" Width="128" Height="16" Offset="0x3C400"/>
|
||||
<Texture Name="gUnusedBossKeyItemName12JPNTex" OutName="boss_key_item_name_unused_jpn_12" Format="ia4" Width="128" Height="16" Offset="0x3C800"/>
|
||||
|
|
|
@ -239,7 +239,7 @@
|
|||
<Texture Name="gGoldSkulltulaItemNameENGTex" OutName="gold_skulltula_item_name_eng" Format="ia4" Width="128" Height="16" Offset="0x3B000"/>
|
||||
<Texture Name="gPieceOfHeartItemNameENGTex" OutName="piece_of_heart_item_name_eng" Format="ia4" Width="128" Height="16" Offset="0x3B400"/>
|
||||
<Texture Name="gUnusedPieceOfHeartItemName2JPNTex" OutName="piece_of_heart_item_name_unused_jpn_2" Format="ia4" Width="128" Height="16" Offset="0x3B800"/>
|
||||
<Texture Name="gBigKeyItemNameENGTex" OutName="big_key_item_name_eng" Format="ia4" Width="128" Height="16" Offset="0x3BC00"/>
|
||||
<Texture Name="gUnusedBigKeyItemNameENGTex" OutName="big_key_item_name_eng" Format="ia4" Width="128" Height="16" Offset="0x3BC00"/>
|
||||
<Texture Name="gCompassItemNameENGTex" OutName="compass_item_name_eng" Format="ia4" Width="128" Height="16" Offset="0x3C000"/>
|
||||
<Texture Name="gDungeonMapItemNameENGTex" OutName="dungeon_map_item_name_eng" Format="ia4" Width="128" Height="16" Offset="0x3C400"/>
|
||||
<Texture Name="gUnusedBossKeyItemName12JPNTex" OutName="boss_key_item_name_unused_jpn_12" Format="ia4" Width="128" Height="16" Offset="0x3C800"/>
|
||||
|
|
|
@ -239,7 +239,7 @@
|
|||
<Texture Name="gGoldSkulltulaItemNameENGTex" OutName="gold_skulltula_item_name_eng" Format="ia4" Width="128" Height="16" Offset="0x3B000"/>
|
||||
<Texture Name="gPieceOfHeartItemNameENGTex" OutName="piece_of_heart_item_name_eng" Format="ia4" Width="128" Height="16" Offset="0x3B400"/>
|
||||
<Texture Name="gUnusedPieceOfHeartItemName2JPNTex" OutName="piece_of_heart_item_name_unused_jpn_2" Format="ia4" Width="128" Height="16" Offset="0x3B800"/>
|
||||
<Texture Name="gBigKeyItemNameENGTex" OutName="big_key_item_name_eng" Format="ia4" Width="128" Height="16" Offset="0x3BC00"/>
|
||||
<Texture Name="gUnusedBigKeyItemNameENGTex" OutName="big_key_item_name_eng" Format="ia4" Width="128" Height="16" Offset="0x3BC00"/>
|
||||
<Texture Name="gCompassItemNameENGTex" OutName="compass_item_name_eng" Format="ia4" Width="128" Height="16" Offset="0x3C000"/>
|
||||
<Texture Name="gDungeonMapItemNameENGTex" OutName="dungeon_map_item_name_eng" Format="ia4" Width="128" Height="16" Offset="0x3C400"/>
|
||||
<Texture Name="gUnusedBossKeyItemName12JPNTex" OutName="boss_key_item_name_unused_jpn_12" Format="ia4" Width="128" Height="16" Offset="0x3C800"/>
|
||||
|
|
|
@ -239,7 +239,7 @@
|
|||
<Texture Name="gGoldSkulltulaItemNameENGTex" OutName="gold_skulltula_item_name_eng" Format="ia4" Width="128" Height="16" Offset="0x3B000"/>
|
||||
<Texture Name="gPieceOfHeartItemNameENGTex" OutName="piece_of_heart_item_name_eng" Format="ia4" Width="128" Height="16" Offset="0x3B400"/>
|
||||
<Texture Name="gUnusedPieceOfHeartItemName2JPNTex" OutName="piece_of_heart_item_name_unused_jpn_2" Format="ia4" Width="128" Height="16" Offset="0x3B800"/>
|
||||
<Texture Name="gBigKeyItemNameENGTex" OutName="big_key_item_name_eng" Format="ia4" Width="128" Height="16" Offset="0x3BC00"/>
|
||||
<Texture Name="gUnusedBigKeyItemNameENGTex" OutName="big_key_item_name_eng" Format="ia4" Width="128" Height="16" Offset="0x3BC00"/>
|
||||
<Texture Name="gCompassItemNameENGTex" OutName="compass_item_name_eng" Format="ia4" Width="128" Height="16" Offset="0x3C000"/>
|
||||
<Texture Name="gDungeonMapItemNameENGTex" OutName="dungeon_map_item_name_eng" Format="ia4" Width="128" Height="16" Offset="0x3C400"/>
|
||||
<Texture Name="gUnusedBossKeyItemName12JPNTex" OutName="boss_key_item_name_unused_jpn_12" Format="ia4" Width="128" Height="16" Offset="0x3C800"/>
|
||||
|
|
|
@ -12,10 +12,9 @@ extern "C"
|
|||
|
||||
#include "luslog.h"
|
||||
#include <soh/Enhancements/item-tables/ItemTableTypes.h>
|
||||
#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
|
||||
|
@ -1044,6 +1043,7 @@ VecSph* OLib_Vec3fToVecSph(VecSph* dest, Vec3f* vec);
|
|||
VecSph* OLib_Vec3fToVecSphGeo(VecSph* arg0, Vec3f* arg1);
|
||||
VecSph* OLib_Vec3fDiffToVecSphGeo(VecSph* arg0, Vec3f* a, Vec3f* b);
|
||||
Vec3f* OLib_Vec3fDiffRad(Vec3f* dest, Vec3f* a, Vec3f* b);
|
||||
void OnePointCutscene_SetCsCamPoints(Camera* camera, s16 actionParameters, s16 initTimer, CutsceneCameraPoint* atPoints, CutsceneCameraPoint* eyePoints);
|
||||
s16 OnePointCutscene_Init(PlayState* play, s16 csId, s16 timer, Actor* actor, s16 camIdx);
|
||||
s16 OnePointCutscene_EndCutscene(PlayState* play, s16 camIdx);
|
||||
s32 OnePointCutscene_Attention(PlayState* play, Actor* actor);
|
||||
|
@ -1102,6 +1102,7 @@ void FrameAdvance_Init(FrameAdvanceContext* frameAdvCtx);
|
|||
s32 FrameAdvance_Update(FrameAdvanceContext* frameAdvCtx, Input* input);
|
||||
u8 PlayerGrounded(Player* player);
|
||||
void Player_SetBootData(PlayState* play, Player* player);
|
||||
void Player_StartAnimMovement(PlayState* play, Player* player, s32 flags);
|
||||
s32 Player_InBlockingCsMode(PlayState* play, Player* player);
|
||||
s32 Player_TryCsAction(PlayState* play, Actor* actor, s32 csAction);
|
||||
s32 Player_InCsMode(PlayState* play);
|
||||
|
@ -1376,7 +1377,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
|
||||
|
|
|
@ -260,9 +260,12 @@ typedef struct SkelAnime {
|
|||
/* 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.
|
||||
/* 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 moveFlags; // Flags used for animations that move the actor in worldspace.
|
||||
/* 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.
|
||||
|
|
|
@ -5,7 +5,6 @@
|
|||
#include "z64math.h"
|
||||
#include "z64audio.h"
|
||||
#include "soh/Enhancements/randomizer/randomizerTypes.h"
|
||||
#include "soh/Enhancements/randomizer/randomizer_inf.h"
|
||||
#include "soh/Enhancements/gameplaystats.h"
|
||||
#include "soh/Enhancements/randomizer/randomizer_entrance.h"
|
||||
#include "soh/Enhancements/boss-rush/BossRushTypes.h"
|
||||
|
|
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") });
|
42
soh/soh/Enhancements/ExtraModes/RupeeDash.cpp
Normal file
42
soh/soh/Enhancements/ExtraModes/RupeeDash.cpp
Normal file
|
@ -0,0 +1,42 @@
|
|||
#include <libultraship/bridge.h>
|
||||
#include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h"
|
||||
#include "soh/ShipInit.hpp"
|
||||
#include "functions.h"
|
||||
#include "macros.h"
|
||||
#include "variables.h"
|
||||
|
||||
extern "C" PlayState* gPlayState;
|
||||
|
||||
static constexpr int32_t CVAR_RUPEE_DASH_DEFAULT = 0;
|
||||
#define CVAR_RUPEE_DASH_NAME CVAR_ENHANCEMENT("RupeeDash")
|
||||
#define CVAR_RUPEE_DASH_VALUE CVarGetInteger(CVAR_RUPEE_DASH_NAME, CVAR_RUPEE_DASH_DEFAULT)
|
||||
|
||||
static constexpr int32_t CVAR_RUPEE_DASH_INTERVAL_DEFAULT = 5;
|
||||
#define CVAR_RUPEE_DASH_INTERVAL_NAME CVAR_ENHANCEMENT("RupeeDashInterval")
|
||||
#define CVAR_RUPEE_DASH_INTERVAL_TIME \
|
||||
CVarGetInteger(CVAR_RUPEE_DASH_INTERVAL_NAME, CVAR_RUPEE_DASH_INTERVAL_DEFAULT) * 20
|
||||
|
||||
void UpdateRupeeDash() {
|
||||
// Initialize Timer
|
||||
static uint16_t rupeeDashTimer = 0;
|
||||
|
||||
// Did time change by DashInterval?
|
||||
if (rupeeDashTimer < CVAR_RUPEE_DASH_INTERVAL_TIME) {
|
||||
rupeeDashTimer++;
|
||||
return;
|
||||
}
|
||||
|
||||
rupeeDashTimer = 0;
|
||||
if (gSaveContext.rupees > 0) {
|
||||
uint16_t walletSize = (CUR_UPG_VALUE(UPG_WALLET) + 1) * -1;
|
||||
Rupees_ChangeBy(walletSize);
|
||||
} else {
|
||||
Health_ChangeBy(gPlayState, -16);
|
||||
}
|
||||
}
|
||||
|
||||
void RegisterRupeeDash() {
|
||||
COND_HOOK(OnPlayerUpdate, CVAR_RUPEE_DASH_VALUE, UpdateRupeeDash);
|
||||
}
|
||||
|
||||
static RegisterShipInitFunc initFunc_RupeeDash(RegisterRupeeDash, { CVAR_RUPEE_DASH_NAME });
|
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("FixGrokenGiantsKnife"), 1), PRESET_ENTRY_S32(CVAR_ENHANCEMENT("FixMenuLR"), 1),
|
||||
PRESET_ENTRY_S32(CVAR_ENHANCEMENT("FixDungeonMinimapIcon"), 1),
|
||||
PRESET_ENTRY_S32(CVAR_ENHANCEMENT("TwoHandedIdle"), 1), PRESET_ENTRY_S32(CVAR_ENHANCEMENT("NaviTextFix"), 1),
|
||||
PRESET_ENTRY_S32(CVAR_ENHANCEMENT("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("FixGrokenGiantsKnife"), 1), PRESET_ENTRY_S32(CVAR_ENHANCEMENT("FixMenuLR"), 1),
|
||||
PRESET_ENTRY_S32(CVAR_ENHANCEMENT("FixDungeonMinimapIcon"), 1),
|
||||
PRESET_ENTRY_S32(CVAR_ENHANCEMENT("TwoHandedIdle"), 1), PRESET_ENTRY_S32(CVAR_ENHANCEMENT("NaviTextFix"), 1),
|
||||
PRESET_ENTRY_S32(CVAR_ENHANCEMENT("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("FixGrokenGiantsKnife"), 1),
|
||||
PRESET_ENTRY_S32(CVAR_ENHANCEMENT("FixMenuLR"), 1),
|
||||
PRESET_ENTRY_S32(CVAR_ENHANCEMENT("FixDungeonMinimapIcon"), 1),
|
||||
PRESET_ENTRY_S32(CVAR_ENHANCEMENT("TwoHandedIdle"), 1),
|
||||
PRESET_ENTRY_S32(CVAR_ENHANCEMENT("NaviTextFix"), 1),
|
||||
PRESET_ENTRY_S32(CVAR_ENHANCEMENT("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;
|
||||
}
|
||||
Ship::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesNextFrame();
|
||||
}
|
||||
ShipInit::Init("*");
|
||||
void PresetCheckboxStyle(const ImVec4& color) {
|
||||
ImGui::PushStyleColor(ImGuiCol_FrameBg, ImVec4(color.x, color.y, color.z, 1.0f));
|
||||
ImGui::PushStyleColor(ImGuiCol_FrameBgHovered, ImVec4(color.x, color.y, color.z, 0.8f));
|
||||
ImGui::PushStyleColor(ImGuiCol_FrameBgActive, ImVec4(color.x, color.y, color.z, 0.6f));
|
||||
ImGui::PushStyleColor(ImGuiCol_Border, ImVec4(0.0f, 0.0f, 0.0f, 0.3f));
|
||||
ImGui::PushStyleColor(ImGuiCol_CheckMark, ImVec4(1.0f, 1.0f, 1.0f, 0.7f));
|
||||
ImGui::PushStyleVar(ImGuiStyleVar_FrameRounding, 3.0f);
|
||||
ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, ImVec2(6.0f, 6.0f));
|
||||
ImGui::PushStyleVar(ImGuiStyleVar_FrameBorderSize, 5.0f);
|
||||
}
|
||||
|
||||
void DrawPresetSelector(PresetType presetTypeId) {
|
||||
const std::string presetTypeCvar = CVAR_GENERAL("SelectedPresets.") + std::to_string(presetTypeId);
|
||||
const PresetTypeDefinition presetTypeDef = presetTypes.at(presetTypeId);
|
||||
uint16_t selectedPresetId = CVarGetInteger(presetTypeCvar.c_str(), 0);
|
||||
if (selectedPresetId >= presetTypeDef.presets.size()) {
|
||||
selectedPresetId = 0;
|
||||
}
|
||||
const PresetDefinition selectedPresetDef = presetTypeDef.presets.at(selectedPresetId);
|
||||
std::string comboboxTooltip = "";
|
||||
for (auto iter = presetTypeDef.presets.begin(); iter != presetTypeDef.presets.end(); ++iter) {
|
||||
if (iter->first != 0)
|
||||
comboboxTooltip += "\n\n";
|
||||
comboboxTooltip += std::string(iter->second.label) + " - " + std::string(iter->second.description);
|
||||
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();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void DrawPresetSelector(std::vector<PresetSection> includeSections, std::string presetLoc, bool disabled) {
|
||||
std::vector<std::string> includedPresets;
|
||||
for (auto& [name, info] : presets) {
|
||||
for (auto& section : includeSections) {
|
||||
if (info.apply[section]) {
|
||||
includedPresets.push_back(name);
|
||||
}
|
||||
}
|
||||
}
|
||||
ImGui::Text("Presets");
|
||||
if (includedPresets.empty()) {
|
||||
ImGui::PushStyleColor(ImGuiCol_Text, UIWidgets::ColorValues.at(UIWidgets::Colors::Orange));
|
||||
ImGui::Text("No presets with rando options. Make some in Settings -> Presets");
|
||||
ImGui::PopStyleColor();
|
||||
return;
|
||||
}
|
||||
std::string selectorCvar = fmt::format(CVAR_GENERAL("{}SelectedPreset"), presetLoc);
|
||||
std::string currentIndex = CVarGetString(selectorCvar.c_str(), includedPresets[0].c_str());
|
||||
if (!presets.contains(currentIndex)) {
|
||||
currentIndex = *includedPresets.begin();
|
||||
CVarSetString(selectorCvar.c_str(), currentIndex.c_str());
|
||||
}
|
||||
UIWidgets::PushStyleCombobox(THEME_COLOR);
|
||||
if (ImGui::BeginCombo("##PresetsComboBox", selectedPresetDef.label)) {
|
||||
for (auto iter = presetTypeDef.presets.begin(); iter != presetTypeDef.presets.end(); ++iter) {
|
||||
if (ImGui::Selectable(iter->second.label, iter->first == selectedPresetId)) {
|
||||
CVarSetInteger(presetTypeCvar.c_str(), iter->first);
|
||||
if (ImGui::BeginCombo("##PresetsComboBox", currentIndex.c_str())) {
|
||||
for (auto iter = includedPresets.begin(); iter != includedPresets.end(); ++iter) {
|
||||
if (ImGui::Selectable(iter->c_str(), *iter == currentIndex)) {
|
||||
CVarSetString(selectorCvar.c_str(), iter->c_str());
|
||||
currentIndex = *iter;
|
||||
Ship::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesNextFrame();
|
||||
}
|
||||
}
|
||||
|
@ -65,18 +147,299 @@ 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 (!presets.empty()) {
|
||||
presets.clear();
|
||||
}
|
||||
if (fs::exists(presetFolder)) {
|
||||
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 });
|
25
soh/soh/Enhancements/RebottleBlueFire.cpp
Normal file
25
soh/soh/Enhancements/RebottleBlueFire.cpp
Normal file
|
@ -0,0 +1,25 @@
|
|||
#include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h"
|
||||
#include "soh/ShipInit.hpp"
|
||||
|
||||
extern "C" {
|
||||
#include "src/overlays/actors/ovl_En_Ice_Hono/z_en_ice_hono.h"
|
||||
void EnIceHono_CapturableFlame(EnIceHono* thisx, PlayState* play);
|
||||
u32 EnIceHono_InBottleRange(EnIceHono* thisx, PlayState* play);
|
||||
}
|
||||
|
||||
extern PlayState* gPlayState;
|
||||
|
||||
void OnEnIceHonoUpdate(void* actor) {
|
||||
EnIceHono* thisx = (EnIceHono*)actor;
|
||||
if (thisx->actionFunc != EnIceHono_CapturableFlame && EnIceHono_InBottleRange(thisx, gPlayState)) {
|
||||
// GI_MAX in this case allows the player to catch the actor in a bottle
|
||||
Actor_OfferGetItem(&thisx->actor, gPlayState, GI_MAX, 60.0f, 100.0f);
|
||||
}
|
||||
}
|
||||
|
||||
void RegisterRebottleBlueFire() {
|
||||
COND_ID_HOOK(OnActorUpdate, ACTOR_EN_ICE_HONO, CVarGetInteger(CVAR_ENHANCEMENT("RebottleBlueFire"), 0),
|
||||
OnEnIceHonoUpdate);
|
||||
}
|
||||
|
||||
static RegisterShipInitFunc initFunc(RegisterRebottleBlueFire, { CVAR_ENHANCEMENT("RebottleBlueFire") });
|
|
@ -1,6 +1,6 @@
|
|||
#include <libultraship/libultraship.h>
|
||||
|
||||
class TimeDisplayWindow : public Ship::GuiWindow {
|
||||
class TimeDisplayWindow final : public Ship::GuiWindow {
|
||||
public:
|
||||
using GuiWindow::GuiWindow;
|
||||
|
||||
|
|
110
soh/soh/Enhancements/TimeSavers/CrawlSpeed.cpp
Normal file
110
soh/soh/Enhancements/TimeSavers/CrawlSpeed.cpp
Normal file
|
@ -0,0 +1,110 @@
|
|||
#include <libultraship/bridge.h>
|
||||
#include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h"
|
||||
#include "soh/ShipInit.hpp"
|
||||
#include "global.h"
|
||||
|
||||
extern "C" {
|
||||
#include "functions.h"
|
||||
#include "objects/gameplay_keep/gameplay_keep.h"
|
||||
extern PlayState* gPlayState;
|
||||
}
|
||||
|
||||
#define CVAR_CRAWL_SPEED_NAME CVAR_ENHANCEMENT("CrawlSpeed")
|
||||
#define CVAR_CRAWL_SPEED_DEFAULT 1
|
||||
#define CVAR_CRAWL_SPEED_VALUE CVarGetInteger(CVAR_CRAWL_SPEED_NAME, CVAR_CRAWL_SPEED_DEFAULT)
|
||||
#define CVAR_GLITCH_AIDING_NAME CVAR_ENHANCEMENT("GlitchAidingCrawlspaces")
|
||||
#define CVAR_GLITCH_AIDING_DEFAULT 0
|
||||
#define CVAR_GLITCH_AIDING_VALUE CVarGetInteger(CVAR_GLITCH_AIDING_NAME, CVAR_GLITCH_AIDING_DEFAULT)
|
||||
|
||||
extern "C" void ExitCrawlspace(Player* player, PlayState* play) {
|
||||
LinkAnimationHeader* animExit = (LinkAnimationHeader*)gPlayerAnim_link_child_tunnel_end;
|
||||
LinkAnimationHeader* animEnter = (LinkAnimationHeader*)gPlayerAnim_link_child_tunnel_start;
|
||||
|
||||
if (player->linearVelocity > 0.0f) {
|
||||
// Leaving a crawlspace forwards
|
||||
player->actor.shape.rot.y = player->actor.wallYaw + 0x8000;
|
||||
LinkAnimation_Change(play, &player->skelAnime, animExit, ((CVAR_CRAWL_SPEED_VALUE + 1.0f) / 2.0f), 0.0f,
|
||||
Animation_GetLastFrame(animExit), ANIMMODE_ONCE, 0.0f);
|
||||
Player_StartAnimMovement(play, player, 0x9D);
|
||||
OnePointCutscene_Init(play, 9601, 999, NULL, MAIN_CAM);
|
||||
} else {
|
||||
// Leaving a crawlspace backwards
|
||||
player->actor.shape.rot.y = player->actor.wallYaw;
|
||||
LinkAnimation_Change(play, &player->skelAnime, animEnter, -1.0f * ((CVAR_CRAWL_SPEED_VALUE + 1.0f) / 2.0f),
|
||||
Animation_GetLastFrame(animEnter), 0.0f, ANIMMODE_ONCE, 0.0f);
|
||||
Player_StartAnimMovement(play, player, 0x9D);
|
||||
OnePointCutscene_Init(play, 9602, 999, NULL, MAIN_CAM);
|
||||
}
|
||||
}
|
||||
|
||||
extern "C" void ExitCrawlspaceCS(PlayState* play, Camera* csCam, int16_t actionParameters, int16_t initTimer,
|
||||
CutsceneCameraPoint* atPoints, CutsceneCameraPoint* eyePoints) {
|
||||
s16 camCrawlTemp = CVAR_CRAWL_SPEED_VALUE;
|
||||
s16 camCrawlTimer = initTimer / camCrawlTemp;
|
||||
|
||||
OnePointCutscene_SetCsCamPoints(csCam, actionParameters | 0x1000, camCrawlTimer, atPoints, eyePoints);
|
||||
}
|
||||
|
||||
extern "C" void EnterCrawlspace(Player* player, PlayState* play) {
|
||||
LinkAnimationHeader* anim = (LinkAnimationHeader*)gPlayerAnim_link_child_tunnel_start;
|
||||
|
||||
LinkAnimation_Change(play, &player->skelAnime, anim, ((CVAR_CRAWL_SPEED_VALUE + 1.0f) / 2.0f), 0.0f,
|
||||
Animation_GetLastFrame(anim), ANIMMODE_ONCE, 0.0f);
|
||||
}
|
||||
|
||||
extern "C" void IncreaseCrawlSpeed(Player* player, PlayState* play) {
|
||||
Input* sControlInput = &play->state.input[0];
|
||||
player->linearVelocity = sControlInput->rel.stick_y * 0.03f * CVAR_CRAWL_SPEED_VALUE;
|
||||
}
|
||||
|
||||
void CrawlSpeed_Register() {
|
||||
bool shouldRegister = CVAR_CRAWL_SPEED_VALUE > 1;
|
||||
|
||||
COND_VB_SHOULD(VB_CRAWL_SPEED_EXIT, shouldRegister, {
|
||||
Player* player = GET_PLAYER(gPlayState);
|
||||
bool excludeWellBackroom = (player->actor.world.pos.x > 950.0f) && (player->actor.world.pos.x < 1025.0f) &&
|
||||
(player->actor.world.pos.z > -1510.0f) && (player->actor.world.pos.z < -1490.0f) &&
|
||||
gPlayState->sceneNum == SCENE_BOTTOM_OF_THE_WELL;
|
||||
bool excludeGlitchAiding = CVAR_GLITCH_AIDING_VALUE;
|
||||
if (excludeGlitchAiding && excludeWellBackroom) {
|
||||
*should = true;
|
||||
} else {
|
||||
ExitCrawlspace(player, gPlayState);
|
||||
*should = false;
|
||||
}
|
||||
});
|
||||
|
||||
COND_VB_SHOULD(VB_CRAWL_SPEED_EXIT_CS, shouldRegister, {
|
||||
Player* player = GET_PLAYER(gPlayState);
|
||||
Camera* csCam = va_arg(args, Camera*);
|
||||
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) &&
|
||||
(player->actor.world.pos.z > -1510.0f) && (player->actor.world.pos.z < -1490.0f) &&
|
||||
gPlayState->sceneNum == SCENE_BOTTOM_OF_THE_WELL;
|
||||
bool excludeGlitchAiding = CVAR_GLITCH_AIDING_VALUE;
|
||||
if (excludeGlitchAiding && excludeWellBackroom) {
|
||||
*should = true;
|
||||
} else {
|
||||
ExitCrawlspaceCS(gPlayState, csCam, actionParameters, initTimer, atPoints, eyePoints);
|
||||
*should = false;
|
||||
}
|
||||
});
|
||||
|
||||
COND_VB_SHOULD(VB_CRAWL_SPEED_ENTER, shouldRegister, {
|
||||
Player* player = GET_PLAYER(gPlayState);
|
||||
EnterCrawlspace(player, gPlayState);
|
||||
*should = false;
|
||||
});
|
||||
|
||||
COND_VB_SHOULD(VB_CRAWL_SPEED_INCREASE, shouldRegister, {
|
||||
Player* player = GET_PLAYER(gPlayState);
|
||||
IncreaseCrawlSpeed(player, gPlayState);
|
||||
*should = false;
|
||||
});
|
||||
}
|
||||
|
||||
static RegisterShipInitFunc initSpeed(CrawlSpeed_Register, { CVAR_CRAWL_SPEED_NAME });
|
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;
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
#include <imgui.h>
|
||||
#include "AudioCollection.h"
|
||||
|
||||
class AudioEditor : public Ship::GuiWindow {
|
||||
class AudioEditor final : public Ship::GuiWindow {
|
||||
public:
|
||||
using GuiWindow::GuiWindow;
|
||||
|
||||
|
|
|
@ -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));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -151,7 +151,7 @@ void InputViewer::DrawElement() {
|
|||
}
|
||||
|
||||
ImVec2 mainPos = ImGui::GetWindowPos();
|
||||
ImVec2 size = ImGui::GetContentRegionAvail();
|
||||
ImVec2 size = ImGui::GetMainViewport()->WorkSize;
|
||||
|
||||
#ifdef __WIIU__
|
||||
const float scale = CVarGetFloat(CVAR_INPUT_VIEWER("Scale"), 1.0f) * 2.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);
|
||||
|
|
|
@ -17,7 +17,7 @@ typedef enum {
|
|||
STICK_MODE_ALWAYS_HIDDEN,
|
||||
} StickMode;
|
||||
|
||||
class InputViewer : public Ship::GuiWindow {
|
||||
class InputViewer final : public Ship::GuiWindow {
|
||||
public:
|
||||
using GuiWindow::GuiWindow;
|
||||
|
||||
|
@ -33,7 +33,7 @@ class InputViewer : public Ship::GuiWindow {
|
|||
void RenderButton(std::string btn, std::string btnOutline, int state, ImVec2 size, int outlineMode);
|
||||
};
|
||||
|
||||
class InputViewerSettingsWindow : public Ship::GuiWindow {
|
||||
class InputViewerSettingsWindow final : public Ship::GuiWindow {
|
||||
public:
|
||||
using GuiWindow::GuiWindow;
|
||||
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -17,7 +17,7 @@ typedef struct {
|
|||
N64ButtonMask defaultBtn;
|
||||
} CustomButtonMap;
|
||||
|
||||
class SohInputEditorWindow : public Ship::GuiWindow {
|
||||
class SohInputEditorWindow final : public Ship::GuiWindow {
|
||||
public:
|
||||
using GuiWindow::GuiWindow;
|
||||
~SohInputEditorWindow();
|
||||
|
|
|
@ -2376,10 +2376,12 @@ void CosmeticsEditorWindow::DrawElement() {
|
|||
.Step(0.01f)
|
||||
.Size(ImVec2(300.0f, 0.0f))
|
||||
.Color(THEME_COLOR));
|
||||
ImGui::BeginDisabled(CVarGetInteger(CVAR_SETTING("DisableChanges"), 0));
|
||||
UIWidgets::CVarCheckbox("Randomize All on New Scene", CVAR_COSMETIC("RandomizeAllOnNewScene"),
|
||||
UIWidgets::CheckboxOptions()
|
||||
.Color(THEME_COLOR)
|
||||
.Tooltip("Enables randomizing all unlocked cosmetics when you enter a new scene."));
|
||||
ImGui::EndDisabled();
|
||||
UIWidgets::CVarCheckbox(
|
||||
"Advanced Mode", CVAR_COSMETIC("AdvancedMode"),
|
||||
UIWidgets::CheckboxOptions()
|
||||
|
@ -2408,13 +2410,15 @@ void CosmeticsEditorWindow::DrawElement() {
|
|||
}
|
||||
}
|
||||
}
|
||||
ImGui::BeginDisabled(CVarGetInteger(CVAR_SETTING("DisableChanges"), 0));
|
||||
if (UIWidgets::Button("Randomize All", UIWidgets::ButtonOptions().Size(ImVec2(250.0f, 0.0f)).Color(THEME_COLOR))) {
|
||||
CosmeticsEditor_RandomizeAll();
|
||||
}
|
||||
ImGui::EndDisabled();
|
||||
|
||||
ImGui::SameLine();
|
||||
if (UIWidgets::Button("Reset All", UIWidgets::ButtonOptions().Size(ImVec2(250.0f, 0.0f)).Color(THEME_COLOR))) {
|
||||
CVarClearBlock("gCosmetics");
|
||||
ApplyOrResetCustomGfxPatches();
|
||||
CosmeticsEditor_ResetAll();
|
||||
}
|
||||
if (UIWidgets::Button("Lock All", UIWidgets::ButtonOptions().Size(ImVec2(250.0f, 0.0f)).Color(THEME_COLOR))) {
|
||||
for (auto& [id, cosmeticOption] : cosmeticOptions) {
|
||||
|
@ -2432,6 +2436,7 @@ void CosmeticsEditorWindow::DrawElement() {
|
|||
}
|
||||
}
|
||||
|
||||
ImGui::BeginDisabled(CVarGetInteger(CVAR_SETTING("DisableChanges"), 0));
|
||||
if (UIWidgets::Button("Rainbow All", UIWidgets::ButtonOptions().Size(ImVec2(250.0f, 0.0f)).Color(THEME_COLOR))) {
|
||||
for (auto& [id, cosmeticOption] : cosmeticOptions) {
|
||||
if (!CVarGetInteger(cosmeticOption.lockedCvar, 0) &&
|
||||
|
@ -2441,6 +2446,8 @@ void CosmeticsEditorWindow::DrawElement() {
|
|||
}
|
||||
}
|
||||
}
|
||||
ImGui::EndDisabled();
|
||||
|
||||
ImGui::SameLine();
|
||||
if (UIWidgets::Button("Un-Rainbow All", UIWidgets::ButtonOptions().Size(ImVec2(250.0f, 0.0f)).Color(THEME_COLOR))) {
|
||||
for (auto& [id, cosmeticOption] : cosmeticOptions) {
|
||||
|
@ -2470,6 +2477,7 @@ void CosmeticsEditorWindow::DrawElement() {
|
|||
|
||||
if (ImGui::BeginTabItem("Keys")) {
|
||||
|
||||
ImGui::BeginDisabled(CVarGetInteger(CVAR_SETTING("DisableChanges"), 0));
|
||||
UIWidgets::Separator(true, true, 2.0f, 2.0f);
|
||||
|
||||
if (UIWidgets::Button("Give all keys dungeon-specific colors",
|
||||
|
@ -2483,6 +2491,7 @@ void CosmeticsEditorWindow::DrawElement() {
|
|||
DrawCosmeticGroup(COSMETICS_GROUP_SMALL_KEYS);
|
||||
DrawCosmeticGroup(COSMETICS_GROUP_BOSS_KEYS);
|
||||
|
||||
ImGui::EndDisabled();
|
||||
ImGui::EndTabItem();
|
||||
}
|
||||
|
||||
|
|
|
@ -60,7 +60,7 @@ void CosmeticsEditor_ResetAll();
|
|||
void CosmeticsEditor_ResetGroup(CosmeticGroup group);
|
||||
void ApplyOrResetCustomGfxPatches(bool manualChange = true);
|
||||
|
||||
class CosmeticsEditorWindow : public Ship::GuiWindow {
|
||||
class CosmeticsEditorWindow final : public Ship::GuiWindow {
|
||||
public:
|
||||
using GuiWindow::GuiWindow;
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
@ -469,6 +469,27 @@ size_t CustomMessage::FindNEWLINE(std::string& str, size_t lastNewline) const {
|
|||
return newLine;
|
||||
}
|
||||
|
||||
bool CustomMessage::AddBreakString(std::string& str, size_t pos, std::string breakString) const {
|
||||
if (str[pos] == ' ' || str[pos] == '&') {
|
||||
str.replace(pos, 1, breakString);
|
||||
return false;
|
||||
} else {
|
||||
if (pos <= str.size() - 1) {
|
||||
// If the next char is a new textbox, it has priority, ignore whatever we are replacing it with
|
||||
if (str[pos + 1] == '^') {
|
||||
return false;
|
||||
// otherwise, if it is a line break or space, replace it
|
||||
} else if (str[pos + 1] == ' ' || str[pos + 1] == '&') {
|
||||
str.replace(pos + 1, 1, breakString);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
// otherwise insert after it
|
||||
str.insert(pos + 1, breakString);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
void CustomMessage::AutoFormatString(std::string& str) const {
|
||||
ReplaceAltarIcons(str);
|
||||
ReplaceColors(str);
|
||||
|
@ -481,7 +502,6 @@ void CustomMessage::AutoFormatString(std::string& str) const {
|
|||
while (lastNewline + lineLength < str.length() || yesNo != std::string::npos) {
|
||||
const size_t carrot = str.find('^', lastNewline);
|
||||
const size_t ampersand = str.find('&', lastNewline);
|
||||
const size_t lastSpace = str.rfind(' ', lastNewline + lineLength);
|
||||
size_t waitForInput = str.find(WAIT_FOR_INPUT()[0], lastNewline);
|
||||
size_t newLine = FindNEWLINE(str, lastNewline);
|
||||
if (carrot < waitForInput) {
|
||||
|
@ -513,13 +533,25 @@ void CustomMessage::AutoFormatString(std::string& str) const {
|
|||
lastNewline = waitForInput + 1;
|
||||
lineCount = 0;
|
||||
// some lines need to be split but don't have spaces, look for periods instead
|
||||
} else if (lastSpace == std::string::npos) {
|
||||
const size_t lastPeriod = str.rfind('.', lastNewline + lineLength);
|
||||
str.replace(lastPeriod, 1, ".&");
|
||||
lastNewline = lastPeriod + 2;
|
||||
} else {
|
||||
str.replace(lastSpace, 1, "&");
|
||||
lastNewline = lastSpace + 1;
|
||||
const size_t lastBreak =
|
||||
str.find_last_of(static_cast<std::string>(".,!?- "), lastNewline + lineLength);
|
||||
// if none exist or we go backwards, we look forward for a something and allow the overflow
|
||||
if (lastBreak == std::string::npos || lastBreak < lastNewline) {
|
||||
const size_t nextBreak = str.find_first_of(static_cast<std::string>(".,!?- &^"), lastNewline);
|
||||
if (str[nextBreak] == '^') {
|
||||
lastNewline = nextBreak + 1;
|
||||
lineCount = 0; // increments to 1 at the end
|
||||
} else if (str[nextBreak] == '&') {
|
||||
lastNewline = nextBreak + 1;
|
||||
} else {
|
||||
bool isAdded = AddBreakString(str, nextBreak, "&");
|
||||
lastNewline = nextBreak + 1 + isAdded;
|
||||
}
|
||||
} else {
|
||||
bool isAdded = AddBreakString(str, lastBreak, "&");
|
||||
lastNewline = lastBreak + 1 + isAdded;
|
||||
}
|
||||
}
|
||||
lineCount += 1;
|
||||
} else {
|
||||
|
@ -536,14 +568,23 @@ void CustomMessage::AutoFormatString(std::string& str) const {
|
|||
// or move the lastNewline cursor to the next line if a '^' is encountered.
|
||||
} else if (carrot < lastNewline + lineLength) {
|
||||
lastNewline = carrot + 1;
|
||||
// some lines need to be split but don't have spaces, look for periods instead
|
||||
} else if (lastSpace == std::string::npos) {
|
||||
const size_t lastPeriod = str.rfind('.', lastNewline + lineLength);
|
||||
str.replace(lastPeriod, 1, ".^" + colorText);
|
||||
lastNewline = lastPeriod + 2;
|
||||
// some lines need to be split but don't have spaces, look for punctuation instead
|
||||
} else {
|
||||
str.replace(lastSpace, 1, "^" + colorText);
|
||||
lastNewline = lastSpace + 1;
|
||||
const size_t lastBreak =
|
||||
str.find_last_of(static_cast<std::string>(".,!?- &"), lastNewline + lineLength);
|
||||
// if none exist or we go backwards, we look forward for a something and allow the overflow
|
||||
if (lastBreak == std::string::npos || lastBreak < lastNewline) {
|
||||
const size_t nextBreak = str.find_first_of(static_cast<std::string>(".,!?- &^"), lastNewline);
|
||||
if (str[nextBreak] == '^') {
|
||||
lastNewline = nextBreak + 1;
|
||||
} else {
|
||||
bool isAdded = AddBreakString(str, nextBreak, "^" + colorText);
|
||||
lastNewline = nextBreak + 1 + isAdded;
|
||||
}
|
||||
} else {
|
||||
bool isAdded = AddBreakString(str, lastBreak, "^" + colorText);
|
||||
lastNewline = lastBreak + 1 + isAdded;
|
||||
}
|
||||
}
|
||||
lineCount = 1;
|
||||
}
|
||||
|
|
|
@ -190,6 +190,17 @@ class CustomMessage {
|
|||
*/
|
||||
size_t FindNEWLINE(std::string& str, size_t lastNewline) const;
|
||||
|
||||
/**
|
||||
* @brief Inserts a string into another string, following the rules
|
||||
* of auto-format inserting new lines: spaces and & are replaced while
|
||||
* other chars are appended to.
|
||||
*
|
||||
* @param str the string we are inserting into
|
||||
* @param pos the position in the string to insert
|
||||
* @param breakString the string we are inserting
|
||||
*/
|
||||
bool AddBreakString(std::string& str, size_t pos, std::string breakString) const;
|
||||
|
||||
/**
|
||||
* @brief formats the string specifically to fit in OoT's
|
||||
* textboxes, and use it's formatting.
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -27,6 +27,7 @@ void MessageViewer::InitElement() {
|
|||
}
|
||||
|
||||
void MessageViewer::DrawElement() {
|
||||
ImGui::BeginDisabled(CVarGetInteger(CVAR_SETTING("DisableChanges"), 0));
|
||||
ImGui::Text("Table ID");
|
||||
ImGui::SameLine();
|
||||
PushStyleInput(THEME_COLOR);
|
||||
|
@ -78,6 +79,7 @@ void MessageViewer::DrawElement() {
|
|||
mDisplayCustomMessageClicked = true;
|
||||
}
|
||||
PopStyleButton();
|
||||
ImGui::EndDisabled();
|
||||
}
|
||||
|
||||
void MessageViewer::UpdateElement() {
|
||||
|
|
|
@ -25,7 +25,7 @@ void MessageDebug_DisplayCustomMessage(const char* customMessage);
|
|||
#ifdef __cplusplus
|
||||
}
|
||||
|
||||
class MessageViewer : public Ship::GuiWindow {
|
||||
class MessageViewer final : public Ship::GuiWindow {
|
||||
public:
|
||||
static inline const char* TABLE_ID = "MessageViewer";
|
||||
using GuiWindow::GuiWindow;
|
||||
|
|
|
@ -12,6 +12,7 @@ void SohConsoleWindow::UpdateElement() {
|
|||
}
|
||||
|
||||
void SohConsoleWindow::DrawElement() {
|
||||
ImGui::BeginDisabled(CVarGetInteger(CVAR_SETTING("DisableChanges"), 0));
|
||||
UIWidgets::PushStyleInput(THEME_COLOR);
|
||||
// Small font (13) to match hardcoded width values in the LUS window.. set large font after below TODO addressed
|
||||
ImGui::PushFont(OTRGlobals::Instance->fontMonoSmall);
|
||||
|
@ -27,4 +28,5 @@ void SohConsoleWindow::DrawElement() {
|
|||
|
||||
ImGui::PopFont();
|
||||
UIWidgets::PopStyleInput();
|
||||
ImGui::EndDisabled();
|
||||
}
|
||||
|
|
|
@ -10,7 +10,9 @@ void SohGfxDebuggerWindow::UpdateElement() {
|
|||
}
|
||||
|
||||
void SohGfxDebuggerWindow::DrawElement() {
|
||||
ImGui::BeginDisabled(CVarGetInteger(CVAR_SETTING("DisableChanges"), 0));
|
||||
ImGui::PushFont(OTRGlobals::Instance->fontMonoLarger);
|
||||
GfxDebuggerWindow::DrawElement();
|
||||
ImGui::PopFont();
|
||||
ImGui::EndDisabled();
|
||||
}
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
|
||||
#include <libultraship/libultraship.h>
|
||||
|
||||
class SohStatsWindow : public Ship::GuiWindow {
|
||||
class SohStatsWindow final : public Ship::GuiWindow {
|
||||
public:
|
||||
using GuiWindow::GuiWindow;
|
||||
~SohStatsWindow(){};
|
||||
|
|
|
@ -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;
|
||||
if (!CVarGetInteger(CVAR_ACTOR_NAME_TAGS("Enabled"), 0)) {
|
||||
return;
|
||||
}
|
||||
|
||||
NameTag_RegisterForActorWithOptions(actor, tag.c_str(), { .tag = DEBUG_ACTOR_NAMETAG_TAG });
|
||||
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() {
|
||||
|
@ -849,36 +866,65 @@ void ActorViewer_AddTagForAllActors() {
|
|||
}
|
||||
|
||||
void ActorViewerWindow::DrawElement() {
|
||||
static Actor* display;
|
||||
static Actor empty{};
|
||||
static Actor* fetch = NULL;
|
||||
ImGui::BeginDisabled(CVarGetInteger(CVAR_SETTING("DisableChanges"), 0));
|
||||
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();
|
||||
}
|
||||
lastSceneId = gPlayState->sceneNum;
|
||||
|
||||
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();
|
||||
}
|
||||
}
|
||||
ImGui::EndChild();
|
||||
|
||||
PushStyleCombobox(THEME_COLOR);
|
||||
if (ImGui::BeginCombo("Actor Type", acMapping[category])) {
|
||||
|
@ -892,21 +938,19 @@ void ActorViewerWindow::DrawElement() {
|
|||
ImGui::EndCombo();
|
||||
}
|
||||
|
||||
if (ImGui::BeginCombo("Actor", filler.c_str())) {
|
||||
if (gPlayState != nullptr && lastSceneId != gPlayState->sceneNum) {
|
||||
PopulateActorDropdown(category, list);
|
||||
lastSceneId = gPlayState->sceneNum;
|
||||
if (display == nullptr) {
|
||||
filler = "Please select";
|
||||
}
|
||||
|
||||
if (ImGui::BeginCombo("Actor", filler.c_str())) {
|
||||
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;
|
||||
}
|
||||
|
@ -917,6 +961,7 @@ void ActorViewerWindow::DrawElement() {
|
|||
|
||||
PushStyleHeader(THEME_COLOR);
|
||||
if (ImGui::TreeNode("Selected Actor")) {
|
||||
if (display != nullptr) {
|
||||
DrawGroupWithBorder(
|
||||
[&]() {
|
||||
ImGui::Text("Name: %s", ActorDB::Instance->RetrieveEntry(display->id).name.c_str());
|
||||
|
@ -924,6 +969,7 @@ void ActorViewerWindow::DrawElement() {
|
|||
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();
|
||||
|
@ -978,61 +1024,42 @@ void ActorViewerWindow::DrawElement() {
|
|||
},
|
||||
"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;
|
||||
}
|
||||
}
|
||||
|
||||
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",
|
||||
ButtonOptions()
|
||||
.Color(THEME_COLOR)
|
||||
.Tooltip("Grabs actor with target arrow above it. You might need C-Up for enemies"))) {
|
||||
Player* player = GET_PLAYER(gPlayState);
|
||||
fetch = player->talkActor;
|
||||
if (fetch != NULL) {
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1043,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
|
||||
if (!SohUtils::IsStringEmpty(searchString) && !actorSearchResults.empty()) {
|
||||
std::string preview =
|
||||
currentSelectedInDropdown == -1
|
||||
? "Please Select"
|
||||
: ActorDB::Instance->RetrieveEntry(actors[currentSelectedInDropdown]).desc;
|
||||
: 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();
|
||||
|
@ -1159,38 +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,11 +2,20 @@
|
|||
|
||||
#include <libultraship/libultraship.h>
|
||||
|
||||
class ActorViewerWindow : public Ship::GuiWindow {
|
||||
#include "z64actor.h"
|
||||
|
||||
#include <vector>
|
||||
|
||||
class ActorViewerWindow final : public Ship::GuiWindow {
|
||||
public:
|
||||
using GuiWindow::GuiWindow;
|
||||
|
||||
void DrawElement() override;
|
||||
void InitElement() override;
|
||||
void UpdateElement() override{};
|
||||
|
||||
private:
|
||||
Actor* display = nullptr;
|
||||
int category = ACTORCAT_SWITCH;
|
||||
std::vector<Actor*> list;
|
||||
};
|
||||
|
|
|
@ -20,7 +20,7 @@ extern "C" {
|
|||
extern PlayState* gPlayState;
|
||||
}
|
||||
|
||||
typedef enum ColRenderSetting { ColRenderDisabled, ColRenderSolid, ColRenderTransparent } ColRenderSetting;
|
||||
enum ColRenderSetting { ColRenderDisabled, ColRenderSolid, ColRenderTransparent };
|
||||
|
||||
static std::unordered_map<int32_t, const char*> ColRenderSettingNames = {
|
||||
{ ColRenderDisabled, "Disabled" },
|
||||
|
@ -58,6 +58,7 @@ using namespace UIWidgets;
|
|||
|
||||
// Draws the ImGui window for the collision viewer
|
||||
void ColViewerWindow::DrawElement() {
|
||||
ImGui::BeginDisabled(CVarGetInteger(CVAR_SETTING("DisableChanges"), 0));
|
||||
CheckboxOptions checkOpt = CheckboxOptions().Color(THEME_COLOR);
|
||||
ComboboxOptions comboOpt = ComboboxOptions().Color(THEME_COLOR);
|
||||
CVarCheckbox("Enabled", CVAR_DEVELOPER_TOOLS("ColViewer.Enabled"), checkOpt);
|
||||
|
@ -139,6 +140,7 @@ void ColViewerWindow::DrawElement() {
|
|||
UIWidgets::Tooltip(colorHelpText.c_str());
|
||||
}
|
||||
PopStyleHeader();
|
||||
ImGui::EndDisabled();
|
||||
}
|
||||
|
||||
// Calculates the normal for a triangle at the 3 specified points
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
typedef enum { COLVIEW_DISABLED, COLVIEW_SOLID, COLVIEW_TRANSPARENT } ColViewerRenderSetting;
|
||||
|
||||
#ifdef __cplusplus
|
||||
class ColViewerWindow : public Ship::GuiWindow {
|
||||
class ColViewerWindow final : public Ship::GuiWindow {
|
||||
public:
|
||||
using GuiWindow::GuiWindow;
|
||||
|
||||
|
|
|
@ -106,7 +106,7 @@ char z2ASCII(int code) {
|
|||
return char(ret);
|
||||
}
|
||||
|
||||
typedef enum MagicLevel { MAGIC_LEVEL_NONE, MAGIC_LEVEL_SINGLE, MAGIC_LEVEL_DOUBLE };
|
||||
enum MagicLevel { MAGIC_LEVEL_NONE, MAGIC_LEVEL_SINGLE, MAGIC_LEVEL_DOUBLE };
|
||||
|
||||
std::unordered_map<int8_t, const char*> magicLevelMap = {
|
||||
{ MAGIC_LEVEL_NONE, "None" },
|
||||
|
@ -114,7 +114,7 @@ std::unordered_map<int8_t, const char*> magicLevelMap = {
|
|||
{ MAGIC_LEVEL_DOUBLE, "Double" },
|
||||
};
|
||||
|
||||
typedef enum AudioOutput {
|
||||
enum AudioOutput {
|
||||
AUDIO_STEREO,
|
||||
AUDIO_MONO,
|
||||
AUDIO_HEADSET,
|
||||
|
@ -128,7 +128,7 @@ std::unordered_map<uint8_t, const char*> audioMap = {
|
|||
{ AUDIO_SURROUND, "Surround" },
|
||||
};
|
||||
|
||||
typedef enum ZTarget {
|
||||
enum ZTarget {
|
||||
Z_TARGET_SWITCH,
|
||||
Z_TARGET_HOLD,
|
||||
};
|
||||
|
@ -554,6 +554,10 @@ void DrawFlagTableArray16(const FlagTable& flagTable, uint16_t row, uint16_t& fl
|
|||
uint32_t bitMask = 1 << flagIndex;
|
||||
ImVec4 themeColor = ColorValues.at(THEME_COLOR);
|
||||
ImVec4 colorDark = { themeColor.x * 0.4f, themeColor.y * 0.4f, themeColor.z * 0.4f, themeColor.z };
|
||||
ImVec4& color = themeColor;
|
||||
if (!hasDescription) {
|
||||
color = colorDark;
|
||||
}
|
||||
PushStyleCheckbox(hasDescription ? themeColor : colorDark);
|
||||
ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, ImVec2(4.0f, 3.0f));
|
||||
bool flag = (flags & bitMask) != 0;
|
||||
|
@ -1665,6 +1669,7 @@ void ResetBaseOptions() {
|
|||
void SaveEditorWindow::DrawElement() {
|
||||
PushStyleTabs(THEME_COLOR);
|
||||
ImGui::PushFont(OTRGlobals::Instance->fontMonoLarger);
|
||||
ImGui::BeginDisabled(CVarGetInteger(CVAR_SETTING("DisableChanges"), 0));
|
||||
|
||||
if (ImGui::BeginTabBar("SaveContextTabBar", ImGuiTabBarFlags_NoCloseWithMiddleMouseButton)) {
|
||||
ResetBaseOptions();
|
||||
|
@ -1706,6 +1711,7 @@ void SaveEditorWindow::DrawElement() {
|
|||
ImGui::EndTabBar();
|
||||
}
|
||||
|
||||
ImGui::EndDisabled();
|
||||
ImGui::PopFont();
|
||||
PopStyleTabs();
|
||||
}
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -89,6 +89,7 @@ void PerformDisplayListSearch() {
|
|||
}
|
||||
|
||||
void DLViewerWindow::DrawElement() {
|
||||
ImGui::BeginDisabled(CVarGetInteger(CVAR_SETTING("DisableChanges"), 0));
|
||||
// Debounce the search field as listing otr files is expensive
|
||||
UIWidgets::PushStyleInput(THEME_COLOR);
|
||||
ImGui::PushFont(OTRGlobals::Instance->fontMonoLarger);
|
||||
|
@ -122,6 +123,7 @@ void DLViewerWindow::DrawElement() {
|
|||
|
||||
if (activeDisplayList == "") {
|
||||
ImGui::PopFont();
|
||||
ImGui::EndDisabled();
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -131,6 +133,8 @@ void DLViewerWindow::DrawElement() {
|
|||
|
||||
if (res->GetInitData()->Type != static_cast<uint32_t>(Fast::ResourceType::DisplayList)) {
|
||||
ImGui::Text("Resource type is not a Display List. Please choose another.");
|
||||
ImGui::PopFont();
|
||||
ImGui::EndDisabled();
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -325,13 +329,10 @@ void DLViewerWindow::DrawElement() {
|
|||
}
|
||||
ImGui::EndGroup();
|
||||
}
|
||||
} catch (const std::exception& e) {
|
||||
ImGui::Text("Error displaying DL instructions.");
|
||||
ImGui::PopFont();
|
||||
return;
|
||||
}
|
||||
} catch (const std::exception& e) { ImGui::Text("Error displaying DL instructions."); }
|
||||
|
||||
ImGui::PopFont();
|
||||
ImGui::EndDisabled();
|
||||
}
|
||||
|
||||
void DLViewerWindow::InitElement() {
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
#include <libultraship/libultraship.h>
|
||||
|
||||
class DLViewerWindow : public Ship::GuiWindow {
|
||||
class DLViewerWindow final : public Ship::GuiWindow {
|
||||
public:
|
||||
using GuiWindow::GuiWindow;
|
||||
|
||||
|
|
|
@ -77,6 +77,7 @@ void DrawHookRegisteringInfos(const char* hookName) {
|
|||
}
|
||||
|
||||
void HookDebuggerWindow::DrawElement() {
|
||||
ImGui::BeginDisabled(CVarGetInteger(CVAR_SETTING("DisableChanges"), 0));
|
||||
#ifndef __cpp_lib_source_location
|
||||
ImGui::TextColored(yellow, "Some features of the Hook Debugger are unavailable because SoH was compiled "
|
||||
"without \"<source_location>\" support "
|
||||
|
@ -93,6 +94,7 @@ void HookDebuggerWindow::DrawElement() {
|
|||
}
|
||||
|
||||
ImGui::PopFont();
|
||||
ImGui::EndDisabled();
|
||||
}
|
||||
|
||||
void HookDebuggerWindow::InitElement() {
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
#include <libultraship/libultraship.h>
|
||||
|
||||
class HookDebuggerWindow : public Ship::GuiWindow {
|
||||
class HookDebuggerWindow final : public Ship::GuiWindow {
|
||||
public:
|
||||
using GuiWindow::GuiWindow;
|
||||
|
||||
|
|
|
@ -154,6 +154,7 @@ void RegisterValueViewerHooks() {
|
|||
RegisterShipInitFunc initFunc(RegisterValueViewerHooks, { CVAR_NAME });
|
||||
|
||||
void ValueViewerWindow::DrawElement() {
|
||||
ImGui::BeginDisabled(CVarGetInteger(CVAR_SETTING("DisableChanges"), 0));
|
||||
UIWidgets::CVarCheckbox("Enable Printing", CVAR_NAME, UIWidgets::CheckboxOptions().Color(THEME_COLOR));
|
||||
|
||||
ImGui::BeginGroup();
|
||||
|
@ -275,6 +276,7 @@ void ValueViewerWindow::DrawElement() {
|
|||
}
|
||||
ImGui::EndGroup();
|
||||
}
|
||||
ImGui::EndDisabled();
|
||||
}
|
||||
|
||||
void ValueViewerWindow::InitElement() {
|
||||
|
|
|
@ -33,7 +33,7 @@ typedef struct {
|
|||
uint32_t y;
|
||||
} ValueTableElement;
|
||||
|
||||
class ValueViewerWindow : public Ship::GuiWindow {
|
||||
class ValueViewerWindow final : public Ship::GuiWindow {
|
||||
public:
|
||||
using GuiWindow::GuiWindow;
|
||||
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -15,18 +15,22 @@ DEFINE_HOOK(OnItemReceive, (GetItemEntry itemEntry));
|
|||
DEFINE_HOOK(OnSaleEnd, (GetItemEntry itemEntry));
|
||||
DEFINE_HOOK(OnTransitionEnd, (int16_t sceneNum));
|
||||
DEFINE_HOOK(OnSceneInit, (int16_t sceneNum));
|
||||
DEFINE_HOOK(AfterSceneCommands, (int16_t sceneNum));
|
||||
DEFINE_HOOK(OnSceneFlagSet, (int16_t sceneNum, int16_t flagType, int16_t flag));
|
||||
DEFINE_HOOK(OnSceneFlagUnset, (int16_t sceneNum, int16_t flagType, int16_t flag));
|
||||
DEFINE_HOOK(OnFlagSet, (int16_t flagType, int16_t flag));
|
||||
DEFINE_HOOK(OnFlagUnset, (int16_t flagType, int16_t flag));
|
||||
DEFINE_HOOK(OnSceneSpawnActors, ());
|
||||
DEFINE_HOOK(OnPlayerUpdate, ());
|
||||
DEFINE_HOOK(OnSetDoAction, (uint16_t action));
|
||||
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));
|
||||
|
|
|
@ -45,12 +45,18 @@ void GameInteractor_ExecuteOnTransitionEndHooks(int16_t sceneNum) {
|
|||
GameInteractor::Instance->ExecuteHooksForFilter<GameInteractor::OnTransitionEnd>(sceneNum);
|
||||
}
|
||||
|
||||
void GameInteractor_ExecuteOnSceneInitHooks(int16_t sceneNum) {
|
||||
void GameInteractor_ExecuteOnSceneInit(int16_t sceneNum) {
|
||||
GameInteractor::Instance->ExecuteHooks<GameInteractor::OnSceneInit>(sceneNum);
|
||||
GameInteractor::Instance->ExecuteHooksForID<GameInteractor::OnSceneInit>(sceneNum, sceneNum);
|
||||
GameInteractor::Instance->ExecuteHooksForFilter<GameInteractor::OnSceneInit>(sceneNum);
|
||||
}
|
||||
|
||||
void GameInteractor_ExecuteAfterSceneCommands(int16_t sceneNum) {
|
||||
GameInteractor::Instance->ExecuteHooks<GameInteractor::AfterSceneCommands>(sceneNum);
|
||||
GameInteractor::Instance->ExecuteHooksForID<GameInteractor::AfterSceneCommands>(sceneNum, sceneNum);
|
||||
GameInteractor::Instance->ExecuteHooksForFilter<GameInteractor::AfterSceneCommands>(sceneNum);
|
||||
}
|
||||
|
||||
void GameInteractor_ExecuteOnSceneFlagSet(int16_t sceneNum, int16_t flagType, int16_t flag) {
|
||||
GameInteractor::Instance->ExecuteHooks<GameInteractor::OnSceneFlagSet>(sceneNum, flagType, flag);
|
||||
GameInteractor::Instance->ExecuteHooksForFilter<GameInteractor::OnSceneFlagSet>(sceneNum, flagType, flag);
|
||||
|
@ -79,6 +85,10 @@ void GameInteractor_ExecuteOnPlayerUpdate() {
|
|||
GameInteractor::Instance->ExecuteHooks<GameInteractor::OnPlayerUpdate>();
|
||||
}
|
||||
|
||||
void GameInteractor_ExecuteOnSetDoAction(uint16_t action) {
|
||||
GameInteractor::Instance->ExecuteHooks<GameInteractor::OnSetDoAction>(action);
|
||||
}
|
||||
|
||||
void GameInteractor_ExecuteOnOcarinaSongAction() {
|
||||
GameInteractor::Instance->ExecuteHooks<GameInteractor::OnOcarinaSongAction>();
|
||||
}
|
||||
|
@ -98,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);
|
||||
|
@ -112,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);
|
||||
|
|
|
@ -18,17 +18,21 @@ void GameInteractor_ExecuteOnItemReceiveHooks(GetItemEntry itemEntry);
|
|||
void GameInteractor_ExecuteOnSaleEndHooks(GetItemEntry itemEntry);
|
||||
void GameInteractor_ExecuteOnTransitionEndHooks(int16_t sceneNum);
|
||||
void GameInteractor_ExecuteOnSceneInit(int16_t sceneNum);
|
||||
void GameInteractor_ExecuteAfterSceneCommands(int16_t sceneNum);
|
||||
void GameInteractor_ExecuteOnSceneFlagSet(int16_t sceneNum, int16_t flagType, int16_t flag);
|
||||
void GameInteractor_ExecuteOnSceneFlagUnset(int16_t sceneNum, int16_t flagType, int16_t flag);
|
||||
void GameInteractor_ExecuteOnFlagSet(int16_t flagType, int16_t flag);
|
||||
void GameInteractor_ExecuteOnFlagUnset(int16_t flagType, int16_t flag);
|
||||
void GameInteractor_ExecuteOnSceneSpawnActors();
|
||||
void GameInteractor_ExecuteOnPlayerUpdate();
|
||||
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))) ||
|
||||
|
@ -294,6 +302,51 @@ typedef enum {
|
|||
// - `*ObjKibako2`
|
||||
VB_CRATE_SETUP_DRAW,
|
||||
|
||||
// #### `result`
|
||||
// ```c
|
||||
// true
|
||||
// ```
|
||||
// #### `args`
|
||||
// - None
|
||||
VB_CRAWL_SPEED_ENTER,
|
||||
|
||||
// #### `result`
|
||||
// ```c
|
||||
// true
|
||||
// ```
|
||||
// #### `args`
|
||||
// - None
|
||||
VB_CRAWL_SPEED_EXIT,
|
||||
|
||||
// #### `result`
|
||||
// ```c
|
||||
// true
|
||||
// ```
|
||||
// #### `args`
|
||||
// - `*Camera`
|
||||
// - 'int16_t' (csId)
|
||||
// - 'int16_t' (actionParameters)
|
||||
// - 'int16_t' (initTimer)
|
||||
// - 'CutsceneCameraPoint*' (atPoints)
|
||||
// - 'CutsceneCameraPoint*' (eyePoints)
|
||||
VB_CRAWL_SPEED_EXIT_CS,
|
||||
|
||||
// #### `result`
|
||||
// ```c
|
||||
// true
|
||||
// ```
|
||||
// #### `args`
|
||||
// - 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)
|
||||
|
@ -425,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)
|
||||
|
@ -474,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
|
||||
|
@ -951,7 +1020,7 @@ typedef enum {
|
|||
// false
|
||||
// ```
|
||||
// #### `args`
|
||||
// - '*Fishing' (&this)
|
||||
// - '*Fishing'
|
||||
VB_GIVE_RANDO_GLITCH_FISHING_PRIZE,
|
||||
|
||||
// #### `result`
|
||||
|
@ -1358,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
|
||||
|
@ -1422,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
|
||||
|
@ -1663,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
|
||||
|
@ -1790,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
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
#include <libultraship/libultraship.h>
|
||||
|
||||
class GameplayStatsWindow : public Ship::GuiWindow {
|
||||
class GameplayStatsWindow final : public Ship::GuiWindow {
|
||||
public:
|
||||
using GuiWindow::GuiWindow;
|
||||
|
||||
|
|
|
@ -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,63 +134,6 @@ void RegisterOcarinaTimeTravel() {
|
|||
});
|
||||
}
|
||||
|
||||
void RegisterRupeeDash() {
|
||||
GameInteractor::Instance->RegisterGameHook<GameInteractor::OnPlayerUpdate>([]() {
|
||||
if (!CVarGetInteger(CVAR_ENHANCEMENT("RupeeDash"), 0)) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Initialize Timer
|
||||
static uint16_t rupeeDashTimer = 0;
|
||||
uint16_t rdmTime = CVarGetInteger(CVAR_ENHANCEMENT("RupeeDashInterval"), 5) * 20;
|
||||
|
||||
// Did time change by DashInterval?
|
||||
if (rupeeDashTimer >= rdmTime) {
|
||||
rupeeDashTimer = 0;
|
||||
if (gSaveContext.rupees > 0) {
|
||||
uint16_t walletSize = (CUR_UPG_VALUE(UPG_WALLET) + 1) * -1;
|
||||
Rupees_ChangeBy(walletSize);
|
||||
} else {
|
||||
Health_ChangeBy(gPlayState, -16);
|
||||
}
|
||||
} else {
|
||||
rupeeDashTimer++;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
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())
|
||||
|
@ -244,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 &&
|
||||
|
@ -1074,9 +957,6 @@ void InitMods() {
|
|||
TimeSavers_Register();
|
||||
RegisterTTS();
|
||||
RegisterOcarinaTimeTravel();
|
||||
RegisterDaytimeGoldSkultullas();
|
||||
RegisterRupeeDash();
|
||||
RegisterShadowTag();
|
||||
RegisterPermanentHeartLoss();
|
||||
RegisterDeleteFileOnDeath();
|
||||
RegisterHyperBosses();
|
||||
|
@ -1090,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');
|
||||
}),
|
||||
// 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();
|
||||
}
|
||||
|
||||
void NameTag_RegisterHooks() {
|
||||
static HOOK_ID gameStatUpdateHookID = 0;
|
||||
static HOOK_ID drawHookID = 0;
|
||||
static HOOK_ID playDestroyHookID = 0;
|
||||
static HOOK_ID actorDestroyHookID = 0;
|
||||
static bool sRegisteredHooks = false;
|
||||
|
||||
void NameTag_RegisterHooks() {
|
||||
if (sRegisteredHooks) {
|
||||
// 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,24 +205,24 @@ 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);
|
||||
}
|
||||
ValidateSphereZero(gals);
|
||||
}
|
||||
// process the region we just expanded to, to reduce looping
|
||||
ProcessRegion(exitRegion, gals, ignore, stopOnBeatable, addToPlaythrough);
|
||||
}
|
||||
|
||||
// If the exit is accessible and hasn't been added yet, add it to the pool
|
||||
// RANDOTODO do we want to add the region after the loop now, considering we
|
||||
// are processing the new region immediately. Maybe a reverse for loop in ProcessRegion?
|
||||
if (!exitRegion->addedToPool && exit.ConditionsMet()) {
|
||||
if (!exitRegion->addedToPool) {
|
||||
exitRegion->addedToPool = true;
|
||||
gals.regionPool.push_back(exit.GetConnectedRegionKey());
|
||||
}
|
||||
|
||||
// process the region we just expanded to, to reduce looping
|
||||
ProcessRegion(exitRegion, gals, ignore, stopOnBeatable, addToPlaythrough);
|
||||
}
|
||||
|
||||
if (addToPlaythrough) {
|
||||
// RANDOTODO Should this match the regular spheres?
|
||||
// Add shuffled entrances to the entrance playthrough
|
||||
|
@ -327,13 +319,12 @@ bool IsBeatableWithout(RandomizerCheck excludedCheck, bool replaceItem,
|
|||
auto ctx = Rando::Context::GetInstance();
|
||||
RandomizerGet copy = ctx->GetItemLocation(excludedCheck)->GetPlacedRandomizerGet(); // Copy out item
|
||||
ctx->GetItemLocation(excludedCheck)->SetPlacedItem(RG_NONE); // Write in empty item
|
||||
ctx->playthroughBeatable = false;
|
||||
logic->Reset();
|
||||
CheckBeatable(ignore);
|
||||
bool result = CheckBeatable(ignore);
|
||||
if (replaceItem) {
|
||||
ctx->GetItemLocation(excludedCheck)->SetPlacedItem(copy); // Immediately put item back
|
||||
}
|
||||
return ctx->playthroughBeatable;
|
||||
return result;
|
||||
}
|
||||
|
||||
// Reset non-Logic-class logic, and optionally apply the initial inventory
|
||||
|
@ -581,6 +572,7 @@ void GeneratePlaythrough() {
|
|||
// return if the seed is currently beatable or not
|
||||
bool CheckBeatable(RandomizerGet ignore /* = RG_NONE*/) {
|
||||
auto ctx = Rando::Context::GetInstance();
|
||||
ctx->playthroughBeatable = false;
|
||||
GetAccessibleLocationsStruct gals(0);
|
||||
ResetLogic(ctx, gals, true);
|
||||
do {
|
||||
|
@ -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
|
||||
|
||||
|
@ -929,10 +913,8 @@ static void AssumedFill(const std::vector<RandomizerGet>& items, const std::vect
|
|||
// If ALR is off, then we check beatability after placing the item.
|
||||
// If the game is beatable, then we can stop placing items with logic.
|
||||
if (!ctx->GetOption(RSK_ALL_LOCATIONS_REACHABLE)) {
|
||||
ctx->playthroughBeatable = false;
|
||||
logic->Reset();
|
||||
CheckBeatable();
|
||||
if (ctx->playthroughBeatable) {
|
||||
if (CheckBeatable()) {
|
||||
SPDLOG_DEBUG("Game beatable, now placing items randomly. " + std::to_string(itemsToPlace.size()) +
|
||||
" major items remaining.\n\n");
|
||||
FastFill(itemsToPlace, GetEmptyLocations(allowedLocations), true);
|
||||
|
|
|
@ -72,4 +72,4 @@ void GeneratePlaythrough();
|
|||
|
||||
bool CheckBeatable(RandomizerGet ignore = RG_NONE);
|
||||
|
||||
void ValidateEntrances(bool checkPoeCollectorAccess, bool checkOtherEntranceAccess);
|
||||
void ValidateEntrances(bool checkOtherEntranceAccess);
|
||||
|
|
|
@ -1458,257 +1458,258 @@ void StaticData::HintTable_Init() {
|
|||
---------------------------*/
|
||||
|
||||
hintTextTable[RHT_JUNK01] = HintText(CustomMessage("They say you must read the names of \"Special Deal\" shop items carefully.",
|
||||
/*german*/ TODO_TRANSLATE,
|
||||
/*german*/ "Man erzählt sich, dass man die \"Sonderangebote\" im Laden sorgfältig lesen sollte!",
|
||||
/*french*/ "Selon moi, les \"Offres spéciales\" sont parfois trompeuses... Lisez les attentivement!"));
|
||||
|
||||
hintTextTable[RHT_JUNK02] = HintText(CustomMessage("They say that Zelda is a poor leader.",
|
||||
/*german*/ TODO_TRANSLATE,
|
||||
/*german*/ "Man erzählt sich, dass Zelda eine schlechte Anführerin ist.",
|
||||
/*french*/ "Selon moi, Zelda ne ferait pas un bon monarque."));
|
||||
|
||||
hintTextTable[RHT_JUNK03] = HintText(CustomMessage("These hints can be quite useful. This is an exception.",
|
||||
/*german*/ TODO_TRANSLATE,
|
||||
/*german*/ "Die Hinweise können sehr nützlich sein. Dies ist eine Ausnahme.",
|
||||
/*french*/ "Ces indices sont très utiles, à l'exception de celui-ci."));
|
||||
|
||||
hintTextTable[RHT_JUNK04] = HintText(CustomMessage("They say that the Lizalfos in Dodongo's Cavern like to play in lava.",
|
||||
/*german*/ TODO_TRANSLATE,
|
||||
/*german*/ "Man erzählt sich, dass die Echsalfos in Dodongo's Cavern gerne in der Lava spielen.",
|
||||
/*french*/ "Selon moi, les Lézalfos de la Caverne Dodongo aiment patauger dans la lave."));
|
||||
|
||||
hintTextTable[RHT_JUNK05] = HintText(CustomMessage("They say that all the Zora drowned in Wind Waker.",
|
||||
/*german*/ TODO_TRANSLATE,
|
||||
/*german*/ "Man erzählt sich, dass alle Zoras in Wind Waker ertrunken sind.",
|
||||
/*french*/ "Selon moi, les Zoras se sont noyés dans Wind Waker."));
|
||||
|
||||
hintTextTable[RHT_JUNK06] = HintText(CustomMessage("If Gorons eat rocks, does that mean I'm in danger?",
|
||||
/*german*/ TODO_TRANSLATE,
|
||||
/*german*/ "Goronen essen doch Steine… heißt das, ich sollte mir Sorgen machen?",
|
||||
/*french*/ "Ne dis pas au Gorons que je suis ici. Ils mangent des roches, tu sais!"));
|
||||
|
||||
hintTextTable[RHT_JUNK07] = HintText(CustomMessage("'Member when Ganon was a blue pig?^I 'member.",
|
||||
/*german*/ TODO_TRANSLATE,
|
||||
/*german*/ "Erinnert ihr euch noch, als Ganon ein blauer Schwein war?^Ich erinnere mich!“",
|
||||
/*french*/ "Dans mon temps, Ganon était un cochon bleu...^Pff! Les jeunes de nos jours, et leur Ganondorf!"));
|
||||
|
||||
hintTextTable[RHT_JUNK08] = HintText(CustomMessage("One who does not have Triforce can't go in.",
|
||||
/*german*/ TODO_TRANSLATE,
|
||||
/*german*/ "Jemand, der nicht im Besitz der Triforce ist, kann nicht eintreten!",
|
||||
/*french*/ "Ceux sans Triforce doivent rebrousser chemin."));
|
||||
|
||||
hintTextTable[RHT_JUNK09] = HintText(CustomMessage("Save your future, end the Happy Mask Salesman.",
|
||||
/*german*/ TODO_TRANSLATE,
|
||||
/*german*/ "Man erzählt sich, dass der Maskenverkäufer aufgehalten werden muss, wenn man eine sichere Zukunft will.",
|
||||
/*french*/ "Selon moi, tu t'éviteras des jours de malheur si tu vaincs le vendeur de masques..."));
|
||||
|
||||
hintTextTable[RHT_JUNK10] = HintText(CustomMessage("Glitches are a pathway to many abilities some consider to be... Unnatural.",
|
||||
/*german*/ TODO_TRANSLATE,
|
||||
/*german*/ "Glitches sind ein Weg zu vielen Fähigkeiten, die manche als... unnatürlich betrachten.",
|
||||
/*french*/ "Les glitchs sont un moyen d'acquérir de nombreuses facultés considérées par certains comme... contraire "));
|
||||
|
||||
hintTextTable[RHT_JUNK11] = HintText(CustomMessage("I'm stoned. Get it?",
|
||||
/*german*/ TODO_TRANSLATE,
|
||||
/*french*/ "Allez, roche, papier, ciseau...&Roche."));
|
||||
/*german*/ "Ich bin stoned. Verstehst du?",
|
||||
/*french*/ "J'ai été pétrifié.&Tu as compris?"));
|
||||
|
||||
hintTextTable[RHT_JUNK12] = HintText(CustomMessage("Hoot! Hoot! Would you like me to repeat that?",
|
||||
/*german*/ TODO_TRANSLATE,
|
||||
/*german*/ "Sei willkommen! Soll ich meine Worte wiederholen?",
|
||||
/*french*/ "Hou hou! Veux-tu que je répète tout ça?"));
|
||||
|
||||
hintTextTable[RHT_JUNK13] = HintText(CustomMessage("Gorons are stupid. They eat rocks.",
|
||||
/*german*/ TODO_TRANSLATE,
|
||||
/*german*/ "Goronen sind dumm. Sie essen Felsen.",
|
||||
/*french*/ "Les Gorons sont des vraies têtes dures."));
|
||||
|
||||
hintTextTable[RHT_JUNK14] = HintText(CustomMessage("They say that Lon Lon Ranch prospered under Ingo.",
|
||||
/*german*/ TODO_TRANSLATE,
|
||||
/*german*/ "Man erzählt sich, dass Ingo der Lon-Lon-Farm zu neuem Glanz verholfen hat.",
|
||||
/*french*/ "Selon moi, le Ranch Lon Lon était plus prospère sous Ingo."));
|
||||
|
||||
hintTextTable[RHT_JUNK15] = HintText(CustomMessage("They say without the Lens of Truth, the Treasure Chest Mini-Game is a 1 out of 32 chance.^Good luck!",
|
||||
/*german*/ TODO_TRANSLATE,
|
||||
/*french*/ "Gagner la Chasse-aux-Trésors est 1 chance sur 32.^Bonne chance!"));
|
||||
/*german*/ "Man erzählt sich, dass du ohne das Auge der Wahrheit beim Schatzkisten-Minispiel nur eine 1-zu-32-Chance hast.^Na dann, viel Glück.",
|
||||
/*french*/ "Selon moi, les chances de gagner la Chasse-aux-Trésors sans Monocle de Vérité est de 1 chance sur 32.^Bonne chance!"));
|
||||
|
||||
hintTextTable[RHT_JUNK16] = HintText(CustomMessage("Use bombs wisely.",
|
||||
/*german*/ TODO_TRANSLATE,
|
||||
/*german*/ "Setze Bomben mit Bedacht ein.",
|
||||
/*french*/ "Utilise les bombes avec précaution."));
|
||||
|
||||
hintTextTable[RHT_JUNK17] = HintText(CustomMessage("They say that players who select the \"ON\" option for \"MOTION CONTROL\" are the real \"Zelda players!\"",
|
||||
/*german*/ TODO_TRANSLATE,
|
||||
/*german*/ "Man erzählt sich, dass Spieler, die die Option ‚BEWEGUNGSSTEUERUNG‘ auf ‚EIN‘ stellen, die wahren ‚Zelda-Spieler‘ sind.",
|
||||
/*french*/ "Selon moi, ceux qui utilisent les contrôles gyroscopiques sont les VRAIS joueurs."));
|
||||
|
||||
hintTextTable[RHT_JUNK18] = HintText(CustomMessage("L2P @.",
|
||||
/*german*/ TODO_TRANSLATE,
|
||||
/*german*/ "Lern zu spielen, @.",
|
||||
/*french*/ "Arrête de lire les indices et joue comme un grand, @."));
|
||||
|
||||
hintTextTable[RHT_JUNK19] = HintText(CustomMessage("I bet you'd like to have more bombs.",
|
||||
/*german*/ TODO_TRANSLATE,
|
||||
/*german*/ "Ich wette, du würdest jetzt gerne mehr Bomben haben.",
|
||||
/*french*/ "Je parie que tu veux plus de bombes."));
|
||||
|
||||
hintTextTable[RHT_JUNK20] = HintText(CustomMessage("When all else fails, use Fire.",
|
||||
/*german*/ TODO_TRANSLATE,
|
||||
/*german*/ "Wenn alles andere scheitert, benutze Feuer.",
|
||||
/*french*/ "Quand rien ne marche, utilise le feu."));
|
||||
|
||||
hintTextTable[RHT_JUNK21] = HintText(CustomMessage("Here's a hint, @. Don't be bad.",
|
||||
/*german*/ TODO_TRANSLATE,
|
||||
/*german*/ "Hier ein Tipp, @: Sei nicht so schlecht.",
|
||||
/*french*/ "Selon moi, la #Triforce# n'est pas dans le jeu... Duh!"));
|
||||
|
||||
hintTextTable[RHT_JUNK22] = HintText(CustomMessage("Game Over. Return of Ganon.",
|
||||
/*german*/ TODO_TRANSLATE,
|
||||
/*german*/ "Game Over. Die Rückkehr von Ganon.",
|
||||
/*french*/ "Partie terminée. RETour de Ganon."));
|
||||
|
||||
hintTextTable[RHT_JUNK23] = HintText(CustomMessage("May the way of the Hero lead to the Triforce.",
|
||||
/*german*/ TODO_TRANSLATE,
|
||||
/*german*/ "Möge der Weg des Helden zur Triforce führen.",
|
||||
/*french*/ "Que le chemin du héros te mène à la Triforce."));
|
||||
|
||||
hintTextTable[RHT_JUNK24] = HintText(CustomMessage("Can't find an item? Scan an Amiibo.",
|
||||
/*german*/ TODO_TRANSLATE,
|
||||
/*german*/ "Du kannst einen Gegenstand nicht finden? Scanne einen Amiibo.",
|
||||
/*french*/ "Tu cherches de quoi? Utilise un Amiibo!"));
|
||||
|
||||
hintTextTable[RHT_JUNK25] = HintText(CustomMessage("They say this game has just a few glitches.",
|
||||
/*german*/ TODO_TRANSLATE,
|
||||
/*german*/ "Man erzählt sich, dass dieses Spiel nur ein paar Glitches hat.",
|
||||
/*french*/ "Selon moi, ce jeu est complètement exempt de glitchs."));
|
||||
|
||||
hintTextTable[RHT_JUNK26] = HintText(CustomMessage("BRRING BRRING This is Ulrira. Wrong number?",
|
||||
/*german*/ TODO_TRANSLATE,
|
||||
/*german*/ "BRRING BRRING, hier ist Ulrira. Falsche Nummer.",
|
||||
/*french*/ "DRING DRING!! Pépé le Ramollo à l'appareil... Quoi? Faux numéro?"));
|
||||
|
||||
hintTextTable[RHT_JUNK27] = HintText(CustomMessage("Tingle Tingle Kooloo Limpah!",
|
||||
/*german*/ TODO_TRANSLATE,
|
||||
/*german*/ "Tingle Tingle Kuuluu-Limpah!",
|
||||
/*french*/ "Tingle! Tingle! Kooloolin... Pah!"));
|
||||
|
||||
hintTextTable[RHT_JUNK28] = HintText(CustomMessage("L is real 2401",
|
||||
/*german*/ TODO_TRANSLATE,
|
||||
/*german*/ "L is real 2401",
|
||||
/*french*/ "L is real 2401"));
|
||||
|
||||
hintTextTable[RHT_JUNK29] = HintText(CustomMessage("They say that Ganondorf will appear in the next Mario Tennis.",
|
||||
/*german*/ TODO_TRANSLATE,
|
||||
/*german*/ "Man erzählt sich, dass Ganondorf im nächsten Mario Tennis erscheinen wird.",
|
||||
/*french*/ "Selon moi, Ganondorf sera la nouvelle recrue dans Mario Tennis."));
|
||||
|
||||
hintTextTable[RHT_JUNK30] = HintText(CustomMessage("They say Medigoron sells the earliest Breath of the Wild demo.",
|
||||
/*german*/ TODO_TRANSLATE,
|
||||
/*german*/ "Man erzählt sich, dass Medigoron die früheste Breath of the Wild-Demo verkauft.",
|
||||
/*french*/ "Selon moi, Medigoron vend une démo de #Breath of the Wild#."));
|
||||
|
||||
hintTextTable[RHT_JUNK31] = HintText(CustomMessage("Can you move me? I don't get great service here.",
|
||||
/*german*/ TODO_TRANSLATE,
|
||||
/*german*/ "Kannst du mich bewegen? Der Service hier ist nicht gerade gut.",
|
||||
/*french*/ "Peux-tu me déplacer? J'ai pas une bonne réception ici."));
|
||||
|
||||
hintTextTable[RHT_JUNK32] = HintText(CustomMessage("They say if you use Strength on the truck, you can find Mew.",
|
||||
/*german*/ TODO_TRANSLATE,
|
||||
/*german*/ "Man erzählt sich, dass man mit Stärke am Truck Mew finden kann.",
|
||||
/*french*/ "Selon moi, #Mew# se trouve dessous le camion... Duh!"));
|
||||
|
||||
hintTextTable[RHT_JUNK33] = HintText(CustomMessage("I'm a helpful hint Gossip Stone!^See, I'm helping.",
|
||||
/*german*/ TODO_TRANSLATE,
|
||||
/*german*/ "Ich bin ein hilfreicher Stein!^Siehst du, ich helfe.",
|
||||
/*french*/ "Salut! Je suis une pierre de bons conseils!^Tiens, tu vois? J'aide bien, hein?"));
|
||||
|
||||
hintTextTable[RHT_JUNK34] = HintText(CustomMessage("Dear @, please come to the castle. I've baked a cake for you.&Yours truly, Princess Zelda.",
|
||||
/*german*/ TODO_TRANSLATE,
|
||||
/*german*/ "Lieber @, bitte komm ins Schloss. Ich habe einen Kuchen für dich gebacken. Mit freundlichen Grüßen,^Prinzessin Zelda.",
|
||||
/*french*/ "Mon très cher @:&Viens vite au château, je t'ai préparé&un délicieux gâteau...^À bientôt, Princesse Zelda"));
|
||||
|
||||
hintTextTable[RHT_JUNK35] = HintText(CustomMessage("They say all toasters toast toast.",
|
||||
/*german*/ TODO_TRANSLATE,
|
||||
/*german*/ "Man erzählt sich, dass alle Toaster Toast toasten.",
|
||||
/*french*/ "Selon moi, les grille-pains grillent du pain."));
|
||||
|
||||
hintTextTable[RHT_JUNK36] = HintText(CustomMessage("You thought it would be a useful hint, but it was me, junk hint!",
|
||||
/*german*/ TODO_TRANSLATE,
|
||||
/*german*/ "Du dachtest, es wäre ein nützlicher Hinweis, aber es war ich, der Müll-Hinweis.",
|
||||
/*french*/ "Tu t'attendais à un bon indice... Mais c'était moi, un mauvais indice!"));
|
||||
|
||||
hintTextTable[RHT_JUNK37] = HintText(CustomMessage("They say that quest guidance can be found at a talking rock.",
|
||||
/*german*/ TODO_TRANSLATE,
|
||||
/*german*/ "Man erzählt sich, dass man Quest-Hinweise bei einem sprechenden Stein finden kann.",
|
||||
/*french*/ "Selon moi, des #indices# se trouvent auprès d'une pierre parlante... Duh!"));
|
||||
|
||||
hintTextTable[RHT_JUNK38] = HintText(CustomMessage("They say that the final item you're looking for can be found somewhere in Hyrule.",
|
||||
/*german*/ TODO_TRANSLATE,
|
||||
/*german*/ "Man erzählt sich, dass das letzte Item, nach dem du suchst, irgendwo in Hyrule zu finden ist.",
|
||||
/*french*/ "Selon moi, le #dernier objet# se trouve quelque part dans Hyrule... Duh!"));
|
||||
|
||||
hintTextTable[RHT_JUNK39] = HintText(CustomMessage("Mweep.^Mweep.^Mweep.^Mweep.^Mweep.^Mweep.^Mweep.^Mweep.^Mweep.^Mweep.^Mweep.^Mweep.",
|
||||
/*german*/ TODO_TRANSLATE,
|
||||
/*german*/ "Mweep.^Mweep.^Mweep.^Mweep.^Mweep.^Mweep.^Mweep.^Mweep.^Mweep.^Mweep.^Mweep.^Mweep.",
|
||||
/*french*/ "Mwip.^Mwip.^Mwip.^Mwip.^Mwip.^Mwip.^Mwip.^Mwip.^Mwip.^Mwip.^Mwip.^Mwip."));
|
||||
|
||||
hintTextTable[RHT_JUNK40] = HintText(CustomMessage("They say that Barinade fears Deku Nuts.",
|
||||
/*german*/ TODO_TRANSLATE,
|
||||
/*german*/ "Man erzählt sich, dass Barinade Angst vor Deku-Nüssen hat.",
|
||||
/*french*/ "Selon moi, Barinade a la frousse des noix Mojo."));
|
||||
|
||||
hintTextTable[RHT_JUNK41] = HintText(CustomMessage("They say that Flare Dancers do not fear Goron-crafted blades.",
|
||||
/*german*/ TODO_TRANSLATE,
|
||||
/*german*/ "Man erzählt sich, dass Flammenderwische keine Angst vor von Goronen geschmiedeten Klingen haben.",
|
||||
/*french*/ "Selon moi, le danse-flamme n'a pas peur des armes de Goron."));
|
||||
|
||||
hintTextTable[RHT_JUNK42] = HintText(CustomMessage("They say that Morpha is easily trapped in a corner.",
|
||||
/*german*/ TODO_TRANSLATE,
|
||||
/*german*/ "Man erzählt sich, dass man Morpha ganz leicht in die Ecke drängen kann.",
|
||||
/*french*/ "Selon moi, Morpha est facilement coincé."));
|
||||
|
||||
hintTextTable[RHT_JUNK43] = HintText(CustomMessage("They say that Bongo Bongo really hates the cold.",
|
||||
/*german*/ TODO_TRANSLATE,
|
||||
/*german*/ "Man erzählt sich, dass Bongo Bongo die Kälte wirklich hasst.",
|
||||
/*french*/ "Selon moi, Bongo Bongo a facilement froid aux doigts."));
|
||||
|
||||
hintTextTable[RHT_JUNK44] = HintText(CustomMessage("They say that your sword is most powerful when you put it away.",
|
||||
/*german*/ TODO_TRANSLATE,
|
||||
/*german*/ "Man erzählt sich, dass dein Schwert am mächtigsten ist, wenn du es wegsteckst.",
|
||||
/*french*/ "Selon moi, ton épée est à pleine puissance quand tu la rengaines."));
|
||||
|
||||
hintTextTable[RHT_JUNK45] = HintText(CustomMessage("They say that bombing the hole Volvagia last flew into can be rewarding.",
|
||||
/*german*/ TODO_TRANSLATE,
|
||||
/*german*/ "Man erzählt sich, dass es sich lohnt, das Loch zu bombardieren, in das Volvagia zuletzt geflogen ist.",
|
||||
/*french*/ "Selon moi, le trou où se creuse Volvagia est vulnérable aux bombes."));
|
||||
|
||||
hintTextTable[RHT_JUNK46] = HintText(CustomMessage("They say that invisible ghosts can be exposed with Deku Nuts.",
|
||||
/*german*/ TODO_TRANSLATE,
|
||||
/*german*/ "Man erzählt sich, dass unsichtbare Geister mit Deku-Nüssen sichtbar gemacht werden können.",
|
||||
/*french*/ "Selon moi, des fantômes invisibles apparaissent avec des noix Mojo."));
|
||||
|
||||
hintTextTable[RHT_JUNK47] = HintText(CustomMessage("They say that the real Phantom Ganon is bright and loud.",
|
||||
/*german*/ TODO_TRANSLATE,
|
||||
/*german*/ "Man erzählt sich, dass der wahre Phantom-Ganon durch Helligkeit und Lärm auffällt.",
|
||||
/*french*/ "Selon moi, le vrai spectre de Ganon est clair et bruyant."));
|
||||
|
||||
hintTextTable[RHT_JUNK48] = HintText(CustomMessage("They say that walking backwards is very fast.",
|
||||
/*german*/ TODO_TRANSLATE,
|
||||
/*german*/ "Man erzählt sich, dass rückwärts laufen sehr schnell ist.",
|
||||
/*french*/ "Selon moi, tu fais marche arrière très rapidement pour un héros."));
|
||||
|
||||
hintTextTable[RHT_JUNK49] = HintText(CustomMessage("They say Ingo is not very good at planning ahead.",
|
||||
/*german*/ TODO_TRANSLATE,
|
||||
/*german*/ "Man erzählt sich, dass Ingo nicht besonders gut darin ist, vorauszuplanen.",
|
||||
/*french*/ "Selon moi, Ingo ne fait pas un très bon geôlier."));
|
||||
|
||||
hintTextTable[RHT_JUNK50] = HintText(CustomMessage("You found a spiritual Stone! By which I mean, I worship Nayru.",
|
||||
/*german*/ TODO_TRANSLATE,
|
||||
/*german*/ "Du hast einen heiligen Stein gefunden! Also... eigentlich heißt das nur, dass ich Nayru verehre.",
|
||||
/*french*/ "Vous avez trouvé une Pierre Ancestrale! En effet, je vénère la déesse Hylia."));
|
||||
|
||||
hintTextTable[RHT_JUNK51] = HintText(CustomMessage("Open your eyes.^Open your eyes.^Wake up, @.",
|
||||
/*german*/ TODO_TRANSLATE,
|
||||
/*german*/ "Öffne deine Augen.^Öffne deine Augen.^Wach auf, @.",
|
||||
/*french*/ "Réveille-toi...^Réveille-toi.^Ouvre les yeux, @."));
|
||||
|
||||
hintTextTable[RHT_JUNK52] = HintText(CustomMessage("They say that the Nocturne of Shadow can bring you very close to Ganon.",
|
||||
/*german*/ TODO_TRANSLATE,
|
||||
/*german*/ "Man erzählt sich, dass das Nocturne des Schattens dich Ganon sehr nahe bringen kann.",
|
||||
/*french*/ "Selon moi, le Nocturne de l'Ombre peut t'amener très près de Ganon."));
|
||||
|
||||
hintTextTable[RHT_JUNK53] = HintText(CustomMessage("They say that Twinrova always casts the same spell the first three times.",
|
||||
/*german*/ TODO_TRANSLATE,
|
||||
/*german*/ "Man erzählt sich, dass Twinrova die ersten drei Male immer denselben Zauber benutzt.",
|
||||
/*french*/ "Selon moi, le Duo Maléfique lance toujours les mêmes trois premiers sorts."));
|
||||
|
||||
hintTextTable[RHT_JUNK54] = HintText(CustomMessage("They say that the nightly builds may be unstable.",
|
||||
/*german*/ TODO_TRANSLATE,
|
||||
/*german*/ "Man erzählt sich, dass die \"nightly builds\" instabil sein könnten.",
|
||||
/*french*/ "Selon moi, les \"nightly builds\" peuvent être instables."));
|
||||
|
||||
hintTextTable[RHT_JUNK55] = HintText(CustomMessage("You're playing a Randomizer. I'm randomized!^Here's a random number: #4#.&Enjoy your Randomizer!",
|
||||
/*german*/ TODO_TRANSLATE,
|
||||
/*german*/ "Du spielst einen Randomizer. Ich bin randomisiert!^Hier ist eine zufällige Zahl: #4#.&Viel Spaß mit dem Randomizer!",
|
||||
/*french*/ "Tu joues à un randomizer. Je suis aléatoire!^Voici un nombre aléatoire: #4#.&Bonne partie!"));
|
||||
|
||||
hintTextTable[RHT_JUNK56] = HintText(CustomMessage("They say Ganondorf's bolts can be reflected with glass or steel.",
|
||||
/*german*/ TODO_TRANSLATE,
|
||||
/*german*/ "Man erzählt sich, dass man Ganondorfs Blitze mit Glas oder Stahl reflektieren kann.",
|
||||
/*french*/ "Selon moi, les éclairs de Ganon se reflètent sur l'acier et le verre."));
|
||||
|
||||
hintTextTable[RHT_JUNK57] = HintText(CustomMessage("They say Ganon's tail is vulnerable to nuts, arrows, swords, explosives, hammers...^...sticks, seeds, "
|
||||
"boomerangs...^...rods, shovels, iron balls, angry bees...",
|
||||
/*german*/ TODO_TRANSLATE,
|
||||
/*german*/ "Man erzählt sich, dass Ganons Schwanz verwundbar ist durch Nüsse, Pfeile, Schwerter...^...Sprengstoffe, Hämmer, "
|
||||
"Stöcke...^...Kerne, Bumerangs, Schaufeln, Eisenkugeln, wütende Bienen...",
|
||||
/*french*/ "Selon moi, la queue de Ganon est vulnérable aux noix, flèches, épées, bombes, marteaux...^...bâtons, "
|
||||
"graines, boomerangs...^...baguettes, pelles, boulets de fer, abeilles enragées..."));
|
||||
|
||||
hintTextTable[RHT_JUNK58] = HintText(CustomMessage("They say that you're wasting time reading this hint, but I disagree. Talk to me again!",
|
||||
/*german*/ TODO_TRANSLATE,
|
||||
/*german*/ "Man erzählt sich, dass du deine Zeit mit dem Lesen dieses Hinweises verschwendest, aber ich bin anderer Meinung. Sprich noch einmal mit mir.",
|
||||
/*french*/ "Selon moi... tu sais quoi? Parle-moi encore, et je te le dirai!"));
|
||||
|
||||
hintTextTable[RHT_JUNK59] = HintText(CustomMessage("They say Ganondorf knows where to find the instrument of his doom.",
|
||||
/*german*/ TODO_TRANSLATE,
|
||||
/*german*/ "Man erzählt sich, dass Ganondorf weiß, wo er das Instrument seines Untergangs finden kann.",
|
||||
/*french*/ "Selon moi, Ganondorf sait où il a caché son point faible."));
|
||||
|
||||
hintTextTable[RHT_JUNK60] = HintText(CustomMessage("I heard @ is pretty good at Zelda.",
|
||||
/*german*/ TODO_TRANSLATE,
|
||||
/*german*/ "Ich habe gehört, dass @ ziemlich gut in Zelda ist.",
|
||||
/*french*/ "Apparemment, @ est super bon à Zelda."));
|
||||
|
||||
hintTextTable[RHT_JUNK61] = HintText(CustomMessage("Hi @, we've been trying to reach you about your car's extended warranty. ",
|
||||
/*german*/ TODO_TRANSLATE,
|
||||
/*german*/ "Hallo @, wir haben versucht, dich wegen der erweiterten Garantie für dein Auto zu erreichen.",
|
||||
/*french*/ "Bonjour, @. Vous avez une voiture? Vous savez, nous offrons des assurances abordables..."));
|
||||
|
||||
hintTextTable[RHT_JUNK62] = HintText(CustomMessage("They say that it's actually possible to beat the running man.",
|
||||
/*german*/ TODO_TRANSLATE,
|
||||
/*german*/ "Man erzählt sich, dass es tatsächlich möglich ist, den Laufenden Mann zu besiegen.",
|
||||
/*french*/ "Selon moi, il est possible de battre le coureur.&Donc, tu prends ton arc, et..."));
|
||||
|
||||
hintTextTable[RHT_JUNK63] = HintText(CustomMessage("They say this hint makes more sense in other languages.",
|
||||
/*german*/ TODO_TRANSLATE,
|
||||
/*german*/ "Man erzählt sich, dass diese Hinweise besser übersetzt werden könnten… na ja, wer hätte das gedacht.",
|
||||
/*french*/ "Selon moi, ces indices auraient pu être mieux traduits... Duh!"));
|
||||
|
||||
// ^ Junk hints above are from 3drando
|
||||
|
@ -1717,39 +1718,36 @@ void StaticData::HintTable_Init() {
|
|||
// Please keep hints to stuff related to ship directly, or to Nintendo/Zelda related stuff.
|
||||
// And nothing that's super obscure that no one's going to understand.
|
||||
|
||||
#define HINT_TEXT_NEEDS_TRANSLATION_FR \
|
||||
"Erreur 0x69a504:&Traduction manquante^C'est de la faute à Purple Hato!&J'vous jure!"
|
||||
|
||||
hintTextTable[RHT_JUNK64] = HintText(CustomMessage("They say Greg is special.",
|
||||
/*german*/ TODO_TRANSLATE,
|
||||
/*german*/ "Man erzählt sich, dass Greg etwas Besonderes ist.",
|
||||
/*french*/ "Selon moi, Greg est spécial."));
|
||||
|
||||
hintTextTable[RHT_JUNK65] = HintText(CustomMessage("They say the longer the Goron's neck, the wiser they are.",
|
||||
/*german*/ TODO_TRANSLATE,
|
||||
/*german*/ "Man erzählt sich, dass ein Gorone umso weiser wird, je länger sein Hals ist.",
|
||||
/*french*/ "Selon moi, plus le cou des Gorons est long, plus ils sont sage." ));
|
||||
|
||||
hintTextTable[RHT_JUNK66] = HintText(CustomMessage("They say this ship is what all true gamers strive for.",
|
||||
/*german*/ TODO_TRANSLATE,
|
||||
/*german*/ "Man erzählt sich, dass dieses \"ship\" das ist, wonach alle echten Gamer streben.",
|
||||
/*french*/ "Selon moi, cette version du port est ce pour quoi luttent tous les vrais gamers."));
|
||||
|
||||
hintTextTable[RHT_JUNK67] = HintText(CustomMessage("They say that Glowsticks can be found in the Raveyard.",
|
||||
/*german*/ TODO_TRANSLATE,
|
||||
/*german*/ "Man erzählt sich, dass Leuchtstäbe auf dem Partyfriedhof zu finden sind.",
|
||||
/*french*/ "Selon moi, on peut trouver des Bâtons Lumineux sur le dancefloor du cimetière."));
|
||||
|
||||
hintTextTable[RHT_JUNK68] = HintText(CustomMessage("They say @'s uncle works for Nintendo.",
|
||||
/*german*/ TODO_TRANSLATE,
|
||||
/*german*/ "Man erzählt sich, dass @'s Onkel bei Nintendo arbeitet.",
|
||||
/*french*/ "Selon moi, l'oncle de @ travaille chez Nintendo."));
|
||||
|
||||
hintTextTable[RHT_JUNK69] = HintText(CustomMessage("They say pulling all gravestones in the graveyard leads to something magical.",
|
||||
/*german*/ TODO_TRANSLATE,
|
||||
/*german*/ "Man erzählt sich, dass das Ziehen aller Grabsteine auf dem Friedhof zu etwas Magischem führt.",
|
||||
/*french*/ "Selon moi, tirer toutes les tombes du Cimetière déclanche un truc magique."));
|
||||
|
||||
hintTextTable[RHT_JUNK70] = HintText(CustomMessage("They say holding L while pausing makes you win the game.",
|
||||
/*german*/ TODO_TRANSLATE,
|
||||
/*german*/ "Man erzählt sich, dass man das Spiel gewinnt, wenn man L gedrückt hält, während man pausiert.",
|
||||
/*french*/ "Selon moi, maintenir L pendant que vous appuyez sur START vous permet de terminer le jeu."));
|
||||
|
||||
hintTextTable[RHT_JUNK71] = HintText(CustomMessage("They say @'s body is ready.",
|
||||
/*german*/ TODO_TRANSLATE,
|
||||
/*german*/ "Man erzählt sich... nein weisst du was, ich hab keine lust mehr.",
|
||||
/*french*/ "Selon moi, ce junk hint ne se traduirait pas bien en français."));
|
||||
|
||||
/*--------------------------
|
||||
|
@ -2022,6 +2020,8 @@ void StaticData::HintTable_Init() {
|
|||
// /*spanish*/$sLos sabios aguardarán a que el héroe obtenga #[[d]] símbolo||s| de skulltula dorada#.^
|
||||
|
||||
hintTextTable[RHT_BRIDGE_GREG_HINT] = HintText(CustomMessage("$gThe awakened ones will await for the Hero to find #Greg#.^",
|
||||
/*german*/ "$gDie Erwachten werden darauf warten, dass der Held #Greg# findet.^",
|
||||
/*french*/ "$gLes êtres de sagesse attendront le héros muni de #Greg#.^",
|
||||
{QM_GREEN}));
|
||||
|
||||
|
||||
|
@ -2214,19 +2214,20 @@ void StaticData::HintTable_Init() {
|
|||
---------------------------*/
|
||||
|
||||
hintTextTable[RHT_GANONDORF_HINT_LA_ONLY] = HintText(CustomMessage("Ha ha ha... You'll never beat me by reflecting my lightning bolts and unleashing the arrows from #[[1]]#!",
|
||||
/*german*/ TODO_TRANSLATE,
|
||||
/*german*/ "Ha ha ha... Du wirst mich nie besiegen, indem du meine Blitze zurückschlägst und die Pfeile aus #[[1]]# entfesselts!",
|
||||
/*french*/ "Ha ha ha... Pauvre fou! Tu ne pourras jamais me vaincre sans les flèches que j'ai cachées dans #[[1]]#!",
|
||||
{QM_RED}));
|
||||
// /*spanish*/Ja, ja, ja... Nunca me derrotarás reflejando mis esferas de energía y desplegando la flecha de luz de #[[1]]#!
|
||||
|
||||
hintTextTable[RHT_GANONDORF_HINT_MS_ONLY] = HintText(CustomMessage("Ha ha ha... You'll never defeat me, drop a castle on me and finish me off with the sacred blade from #[[2]]#!",
|
||||
/*german*/ TODO_TRANSLATE,
|
||||
/*german*/ "Ha ha ha... Du wirst mich nie besiegen, wirf ein Schloss auf mich und beende mich mit dem heiligen Schwert von #[[2]]#!",
|
||||
/*french*/ "Ha ha ha... Pauvre fou! Tu ne pourras jamais me vaincre sans l'Épée de Légende cachée dans #[[2]]#!",
|
||||
{QM_RED}));
|
||||
|
||||
hintTextTable[RHT_GANONDORF_HINT_LA_AND_MS] = HintText(CustomMessage("Ha ha ha... You'll never beat me by reflecting my lightning bolts and unleashing the arrows from #[[1]]#!"
|
||||
"^And even if you do, you'll never find the legendary blade hidden in #[[2]]#!",
|
||||
/*german*/ TODO_TRANSLATE,
|
||||
/*german*/ "Ha ha ha... Du wirst mich nie besiegen, indem du meine Blitze zurückschlägst und die Pfeile aus #[[1]]# entfesselts!"
|
||||
"^Und selbst wenn du es tust, wirst du nie das legendäre Schwert finden, das in #[[2]]# versteckt ist!",
|
||||
/*french*/ "Ha ha ha... Pauvre fou! Tu ne pourras jamais me vaincre sans les flèches que j'ai cachées dans #[[1]]#!"
|
||||
"^Et même si tu les trouves, tu ne touveras jamais l'Épée de Légende cachée dans #[[2]]#!",
|
||||
{QM_RED, QM_RED}));
|
||||
|
@ -2234,34 +2235,38 @@ void StaticData::HintTable_Init() {
|
|||
// ^E incluso si lo haces, nunca encontrarás la espada legendaria escondida en #[[2]]#!
|
||||
|
||||
hintTextTable[RHT_SHEIK_HINT_LA_ONLY] = HintText(CustomMessage("I overheard Ganondorf say that he misplaced the #Light Arrows# in #[[1]]#.",
|
||||
/*german*/ TODO_TRANSLATE,
|
||||
/*german*/ "Ich habe Ganondorf sagen hören, dass er die #Lichtpfeile# in #[[1]]# verlegt hat.",
|
||||
/*french*/ "J'ai entendu dire que Ganondorf aurait caché les #Flèches de Lumière# dans #[[1]]#.",
|
||||
{QM_YELLOW, QM_RED}));
|
||||
|
||||
hintTextTable[RHT_DAMPE_DIARY] = HintText(CustomMessage("Whoever reads this, please enter #[[1]]#. I will let you have my #stretching, shrinking keepsake#.^I'm waiting for you.&--Dampé",
|
||||
/*german*/ "Wer immer dies liest, der möge folgenden Ort aufsuchen: #[[1]]#. Ihm gebe ich meinen #dehnenden, schrumpfenden Schatz#.^Ich warte!&Boris", //RANDOTODO color in whatever refers to the hookshot
|
||||
/*german*/ "Wer immer dies liest, der möge folgenden Ort aufsuchen: #[[1]]#. Ihm gebe ich meinen #dehnenden, schrumpfenden Schatz#.^Ich warte!&Boris",
|
||||
/*french*/ "Toi qui lit ce journal, rends-toi dans #[[1]]#. Et peut-être auras-tu droit à mon précieux #trésor#.^Je t'attends...&--Igor",
|
||||
{QM_RED, QM_RED}));
|
||||
|
||||
hintTextTable[RHT_GREG_HINT] = HintText(CustomMessage("By the way, if you're interested, I saw the shiniest #Green Rupee# somewhere in #[[1]]#.^It's said to have #mysterious powers#...^But then, it could just be another regular rupee.&Oh well.",
|
||||
/*german*/ TODO_TRANSLATE,
|
||||
/*french*/ "Au fait, si ça t'intéresse, j'ai aperçu le plus éclatant des #Rubis Verts# quelque part à #[[1]]#. On dit qu'il possède des pouvoirs mystérieux... Mais bon, ça pourrait juste être un autre rubis ordinaire.",//RANDOTODO color in mysterious powers
|
||||
/*german*/ "Übrigens, falls es dich interessiert, ich habe irgendwo in #[[1]]# den glänzendsten #Grünen Rubinen# gesehen.^Es soll #mysteriöse Kräfte# haben...^Aber na ja, es könnte auch einfach nur ein normaler Rubin sein. Tja",
|
||||
/*french*/ "Au fait, si ça t'intéresse, j'ai aperçu le plus éclatant des #Rubis Verts# quelque part à #[[1]]#.^On dit qu'il possède des #pouvoirs mystérieux#...^Mais bon, ça pourrait juste être un autre rubis ordinaire.",
|
||||
{QM_GREEN, QM_RED, QM_RED}));
|
||||
|
||||
hintTextTable[RHT_SARIA_TALK_HINT] = HintText(CustomMessage("Did you feel the #surge of magic# recently? A mysterious bird told me it came from #[[1]]#.^You should check that place out, @!",
|
||||
/*german*/ TODO_TRANSLATE,
|
||||
/*french*/ "As-tu récemment ressenti une vague de #puissance magique#? Un mystérieux hibou m'a dit qu'elle provenait du #[[1]]#. Tu devrais aller y jeter un coup d'oeil, @!",
|
||||
/*german*/ "Hast du kürzlich den #Magieschub# gespürt? Ein geheimnisvoller Vogel hat mir erzählt, dass er aus #[[1]]# kam.^Du solltest dir diesen Ort mal ansehen, @!",
|
||||
/*french*/ "As-tu récemment ressenti une vague de #puissance magique#? Un mystérieux hibou m'a dit qu'elle provenait du #[[1]]#.^Tu devrais aller y jeter un coup d'oeil, @!",
|
||||
{QM_GREEN, QM_RED}));
|
||||
|
||||
hintTextTable[RHT_SARIA_SONG_HINT] = HintText(CustomMessage("Did you feel the #surge of magic# recently? A mysterious bird told me it came from #[[1]]#.^You should check that place out, @!\x0B",
|
||||
/*german*/ TODO_TRANSLATE,
|
||||
/*french*/ "As-tu récemment ressenti une vague de #puissance magique#? Un mystérieux hibou m'a dit qu'elle provenait du #[[1]]#. Tu devrais aller y jeter un coup d'oeil, @!\x0B",
|
||||
/*german*/ "Hast du kürzlich den #Magieschub# gespürt? Ein geheimnisvoller Vogel hat mir erzählt, dass er aus #[[1]]# kam.^Du solltest dir diesen Ort mal ansehen, @!\x0B",
|
||||
/*french*/ "As-tu récemment ressenti une vague de #puissance magique#? Un mystérieux hibou m'a dit qu'elle provenait du #[[1]]#.^Tu devrais aller y jeter un coup d'oeil, @!\x0B",
|
||||
{QM_GREEN, QM_RED}, {}, TEXTBOX_TYPE_BLUE));
|
||||
|
||||
hintTextTable[RHT_LOACH_HINT] = HintText(CustomMessage("What?^You wanna know about the&%rHyrule Loach%w?^It's a big fish, but it's so rare that I'll give my %g[[1]]%w to anyone who catches it. Seriously!",
|
||||
/*german*/ "Was?^Du willst was über den&%rHyrule-Schleicher%w wissen?^Das ist ein riesiger Fisch, aber&so selten, dass ich jedem mein&%g[[1]]%w gebe, der ihn fängt.&Im Ernst."
|
||||
/*french*/ "Quoi?&Tu veux en savoir plus sur le&%rBrochet d'Hyrule%w?^C'est un gros poisson, mais il&est si rare que je donne&%g[[1]]%w&à celui qui l'attrape.^Ouais, j'suis sérieux!",
|
||||
{QM_RED}));
|
||||
|
||||
hintTextTable[RHT_FISHING_POLE_HINT] = HintText(CustomMessage("^If I remember correctly, I lost it somewhere in #[[1]]#...&Let me know if you find it!",
|
||||
/*german*/ "Wenn ich mich recht erinnere,&hab ich es irgendwo in #[[1]]#&verloren...&Sag mir Bescheid, wenn du es findest."
|
||||
/*french*/ "Si je me souviens bien, il me&semble que je l'ai perdue&quelque part dans&#[[1]]#...^Fais-moi signe si jamais&tu la trouves!",
|
||||
{QM_RED}));
|
||||
|
||||
/*--------------------------
|
||||
|
@ -2277,44 +2282,84 @@ void StaticData::HintTable_Init() {
|
|||
| STATIC LOCATION HINTS |
|
||||
---------------------------*/
|
||||
|
||||
/*--------------------------
|
||||
| STATIC LOCATION HINTS |
|
||||
---------------------------*/
|
||||
|
||||
hintTextTable[RHT_HBA_HINT_SIGN] = HintText(CustomMessage("#Horseback Archery# Range Prizes:&1000: #[[1]]#&1500: #[[2]]#^@'s Record: #" + CustomMessage::POINTS(HS_HORSE_ARCHERY) + "#",
|
||||
/*german*/ "#Bogenschießen zu Pferde#&Schießstandpreise:&1000: #[[1]]#&1500: #[[2]]#^@'s Record: #" + CustomMessage::POINTS(HS_HORSE_ARCHERY) + "#",
|
||||
/*french*/ "Récompenses de l'#Archerie Montée#:&1000: #[[1]]#&1500: #[[2]]#^Record de @: #" + CustomMessage::POINTS(HS_HORSE_ARCHERY) + "#",
|
||||
{QM_RED, QM_GREEN, QM_GREEN, QM_GREEN}, {}, TEXTBOX_TYPE_WOODEN));
|
||||
|
||||
hintTextTable[RHT_HBA_HINT_NOT_ON_HORSE] = HintText(CustomMessage("Hey, rookie!&Come back on your #horse# and take on then #Horseback Archery# challenge!^"
|
||||
hintTextTable[RHT_HBA_HINT_NOT_ON_HORSE] = HintText(CustomMessage("Hey, rookie!&Come back on your #horse# and take on the #Horseback Archery# challenge!^"
|
||||
"Impress me with a high score of 1000 to win a #[[1]]# or score 1500 for #[[2]]#!",
|
||||
/*german*/ "Hey, Neuling!&Komm mit deinem #Pferd# zurück und stell dich der #Pferdebogenschießen#-Herausforderung!^"
|
||||
"Beeindruck mich mit 1000 Punkten und gewinne #[[1]]#! Oder hol dir 1500 Punkte für #[[2]]#!",
|
||||
/*french*/ "Hé, l'nouveau!&Reviens avec ton #cheval# et essaie notre #Terrain d'Archerie Montée#^"
|
||||
"Impressionne-moi avec un score de 1000 pour gagner #[[1]]# ou atteins 1500 pour #[[2]]#!",
|
||||
{QM_RED, QM_RED, QM_GREEN, QM_GREEN}));
|
||||
|
||||
hintTextTable[RHT_HBA_HINT_INITIAL] = HintText(CustomMessage("Hey, rookie!&Want to take on the #Horseback Archery# challenge?^"
|
||||
"Impress me with a high score of 1000 to win a #[[1]]# or score 1500 for #[[2]]#!\x0B",
|
||||
/*german*/ "Hey, Neuling!&Willst du dich der #Pferdebogenschießen#-Herausforderung stellen?^"
|
||||
"Zeig, was du drauf hast - hol 1000 Punkte für #[[1]]#! Oder knack die 1500 und kassier #[[2]]#!\x0B",
|
||||
/*french*/ "Hé, l'nouveau!&Tu veux essayer notre #Terrain d'Archerie Montée#^"
|
||||
"Impressionne-moi avec un score de 1000 pour gagner #[[1]]# ou atteins 1500 pour #[[2]]#!\x0B",
|
||||
{QM_RED, QM_GREEN, QM_GREEN}));
|
||||
|
||||
hintTextTable[RHT_HBA_HINT_HAVE_1000] = HintText(CustomMessage("Hey, newcomer!&Want to take on the #Horseback Archery# challenge?^"
|
||||
"Prove yourself to be a horsemaster by scoring 1500 points to win #[[2]]#!\x0B",
|
||||
/*german*/ "Hey, Neuling!&Willst du dich der #Pferdebogenschießen#-Herausforderung stellen?^"
|
||||
"Beweise dein Können als Reitmeister - hol 1500 Punkte und gewinne #[[2]]#!\x0B",
|
||||
/*french*/ "Hé, l'nouveau!&Tu veux essayer notre #Terrain d'Archerie Montée#^"
|
||||
"Prouve que tu es un véritable cavalier en obtenant 1500 points pour gagner #[[2]]#!\x0B",
|
||||
{QM_RED, QM_GREEN}));
|
||||
|
||||
hintTextTable[RHT_MALON_HINT_HOW_IS_EPONA] = HintText(CustomMessage("@! You should come back with Epona and try to beat my time on the #Obstacle Course#!^"
|
||||
"If you beat my time, I'll give you my favourite #cow# Elsie and her toy #[[1]]#!",
|
||||
/*german*/ "@! Du solltest mit Epona zurückkommen und versuchen, meine Zeit im #Hindernisparcours# zu schlagen!^"
|
||||
"Wenn du meine Zeit schlägst, gebe ich dir meine #Lieblingskuh# Elsie und ihr Spielzeug #[[1]]#!",
|
||||
/*french*/ "@! Tu devrais revenir avec Epona et essayer de battre mon temps sur le #Parcours d'Obstacles#!^"
|
||||
"Si tu bats mon temps, je te donnerai ma vache préférée, Elsie, ainsi que son jouet #[[1]]#!",
|
||||
{QM_RED, QM_BLUE, QM_GREEN}));
|
||||
|
||||
hintTextTable[RHT_MALON_HINT_OBSTICLE_COURSE] = HintText(CustomMessage("How about trying the #Obstacle Course?# If you beat my time I'll let you keep my favourite #cow# Elsie and her toy #[[1]]#!^"
|
||||
"Challenge the #Obstacle Course?#&\x1B&#Let's go&No thanks#",
|
||||
/*german*/ "Wie wärs mit dem #Hindernisparcours#? Wenn du meine Zeit schlägst, lasse ich dir meine #LieblingsKuh# Elsie und ihr Spielzeug #[[1]]#!^"
|
||||
"Herausforderung: #Hindernisparcours?#&\x1B&#Los geht's!&nein, danke#",
|
||||
/*french*/ "Que dirais-tu d'essayer le #Parcours d'Obstacles#? Si tu bats mon temps, je te donnerai ma vache préférée, Elsie, et son jouet #[[1]]#!^"
|
||||
"Tenter le #Parcours d'Obstacles#?&\x1B&#Allons-y&Non merci#",
|
||||
{QM_RED, QM_BLUE, QM_GREEN, QM_RED, QM_GREEN}));
|
||||
|
||||
hintTextTable[RHT_MALON_HINT_TURNING_EVIL] = HintText(CustomMessage("@? Is that you? ^If I ran the ranch, I'd build an #Obstacle Course#, and whoever gets the best time would win a #cow#!^"
|
||||
"Elsie loves sharing her #[[1]]# with new people, It'll be fun!^...But Ingo won't let me...",
|
||||
/*german*/ "@? Bist du das? ^Wenn ich die Ranch leiten würde, würde ich einen #Hindernisparcours# bauen, und wer die beste Zeit schafft, gewinnt eine #Kuh#!^"
|
||||
"Elsie liebt es, ihr #[[1]]# mit neuen Leuten zu teilen. Es wird Spaß machen^...Aber Ingo lässt mich nicht",
|
||||
/*french*/ "@? C'est toi?^Si je dirigeais le ranch, je construirais un #Parcours d'Obstacles#, et celui qui obtiendrait le meilleur temps gagnerait une #vache#!^"
|
||||
"Elsie adore partager son #[[1]]# avec de nouvelles personnes, ce serait amusant!^... Mais Ingo ne me laisse pas faire...",
|
||||
{QM_RED, QM_BLUE, QM_GREEN}));
|
||||
|
||||
hintTextTable[RHT_MALON_HINT_INGO_TEMPTED] = HintText(CustomMessage("@! You should come back in the morning and try to beat my time on the #Obstacle Course#!^"
|
||||
"If you beat my time, I'll give you my favourite #cow# Elsie and her toy #[[1]]#!",
|
||||
/*german*/ "@! Du solltest morgens zurückkommen und versuchen, meine Zeit im #Hindernisparcours# zu schlagen!^"
|
||||
"Wenn du meine Zeit schlägst, gebe ich dir meine #Lieblingskuh# Elsie und ihr Spielzeug #[[1]]#!",
|
||||
/*french*/ "@! Tu devrais revenir le matin et essayer de battre mon temps sur le #Parcours d'Obstacles#!^"
|
||||
"Si tu bats mon temps, je te donnerai ma vache préférée, Elsie, ainsi que son jouet #[[1]]#!",
|
||||
{QM_RED, QM_BLUE, QM_GREEN}));
|
||||
|
||||
hintTextTable[RHT_CHICKENS_HINT] = HintText(CustomMessage("You! Please!&Bring my Cucco's back to my pen!&I'll give you my #[[1]]#!",
|
||||
/*german*/ "Du! Bitte!&Bring meine Hühner zurück in ihren&Stall! Ich gebe dir meine #[[1]]#!",
|
||||
/*french*/ "Mes Cocottes sont perdues!&Dépose toutes les cocottes dans cet enclos!&Je te donnerai #[[1]]#!",
|
||||
{QM_GREEN}));
|
||||
|
||||
hintTextTable[RHT_BIG_POES_HINT] = HintText(CustomMessage("You have #\x1E\x01 Poe Points#! Reach 1000 and you'll get a #[[1]]#!",
|
||||
/*german*/ "Du hast #\x1E\x01 Nachtschwärmer-Punkte#! Erreiche 1000 und du bekommst ein #[[1]]#!",
|
||||
/*french*/ "Tu as #\x1E\x01 Points d'Âme#! Atteins 1000 et tu recevras #[[1]]#!",
|
||||
{QM_YELLOW, QM_GREEN}));
|
||||
|
||||
hintTextTable[RHT_BIGGORON_HINT] = HintText(CustomMessage("Arrrrrre you here to claim my finest #[[1]]#? Shoooooow me your #Claim Check#.",
|
||||
/*german*/ "Arrrrr, bist du hier, um mein feinsten #[[1]]# zu beanspruchen? Zeig mir deinen #Zertifikat#!",
|
||||
/*french*/ "Eeeeeees-tu ici pour réclaaaaaamer mon plus beau #[[1]]#? Moooooontre-moi ton #Certificat#.",
|
||||
{QM_GREEN, QM_RED}));
|
||||
|
||||
hintTextTable[RHT_FROGS_HINT] = HintText(CustomMessage("Some frogs holding #[[1]]# are looking at you from underwater...",
|
||||
|
@ -2323,6 +2368,8 @@ void StaticData::HintTable_Init() {
|
|||
{QM_GREEN}));
|
||||
|
||||
hintTextTable[RHT_OOT_HINT] = HintText(CustomMessage("Bring the #Spiritual Stones# to the past so you can receive #[[1]]# from Zelda and learn #[[2]]#!",
|
||||
/*german*/ "Bringe die #Spirituellen Steine# in die Vergangenheit, damit du #[[1]]# von Zelda erhältst und #[[2]]#! lernst",
|
||||
/*french*/ "Amène les #Pierres Spirituelles# dans le passé et Zelda te donnera #[[1]]# et t'apprendra #[[2]]# !",
|
||||
{QM_BLUE, QM_GREEN, QM_GREEN}));
|
||||
|
||||
hintTextTable[RHT_SKULLS_HINT] = HintText(CustomMessage("Yeaaarrgh! I'm cursed!!^Please save me by destroying #[[d]] Spiders of the Curse# and I will give you my #[[1]]#!",
|
||||
|
@ -2332,6 +2379,10 @@ void StaticData::HintTable_Init() {
|
|||
|
||||
hintTextTable[RHT_MASK_SHOP_HINT] = HintText(CustomMessage("Some young scrubs in the #Deku Theatre# love seeing Masks!^"
|
||||
"They'll give you #[[1]]# if you show them the #Skull Mask#, and #[[2]]# if you show them the #Mask of Truth#!",
|
||||
/*german*/ "Ein paar junge Gören in der #Waldbühne# lieben es, Masken zu sehen!^"
|
||||
"Sie geben dir #[[1]]#, wenn du ihnen die #Schädel-Maske# zeigst, und #[[2]]#, wenn du ihnen die #Maske des Wissens# zeigst!",
|
||||
/*french*/ "De jeunes Pestes Mojo qui se trouvent dans le #Théâtre Mojo# adorent voir des masques !^"
|
||||
"Elles te donneront #[[1]]# si tu leur montres le #Masque de Mort#, et #[[2]]# si tu leur montres le #Masque de Vérité#.",
|
||||
{QM_GREEN, QM_GREEN, QM_RED, QM_GREEN, QM_RED}));
|
||||
|
||||
/*--------------------------
|
||||
|
@ -2339,33 +2390,34 @@ void StaticData::HintTable_Init() {
|
|||
---------------------------*/
|
||||
|
||||
hintTextTable[RHT_GANON_JOKE01] = HintText(CustomMessage("Oh! It's @.&I was expecting someone called Sheik.&Do you know what happened to them?",
|
||||
/*german*/ TODO_TRANSLATE,
|
||||
/*german*/ "Oh! Da ist @.&Ich hatte eigentlich jemanden namens&Sheik erwartet. Weißt du, was mit&ihnen passiert ist?",
|
||||
/*french*/ "Ah, c'est @.&J'attendais un certain Sheik.&Tu sais ce qui lui est arrivé?"));
|
||||
// /*spanish*/¡Oh! Pero si es @.&Estaba esperando a alguien llamado Sheik. ¿Sabes qué puede haberle pasado?
|
||||
|
||||
hintTextTable[RHT_GANON_JOKE02] = HintText(CustomMessage("I knew I shouldn't have put the key on the other side of my door.",
|
||||
/*german*/ TODO_TRANSLATE,
|
||||
/*german*/ "Ich wusste, dass ich den Schlüssel nicht auf der anderen Seite meiner Tür legen sollte.",
|
||||
/*french*/ "J'aurais dû garder la clé ici. Hélas..."));
|
||||
// /*spanish*/Sabía que no tendría que haber dejado la llave al otro lado de la puerta.
|
||||
|
||||
hintTextTable[RHT_GANON_JOKE03] = HintText(CustomMessage("Looks like it's time for a round of tennis.",
|
||||
/*german*/ TODO_TRANSLATE,
|
||||
/*german*/ "Sieht so aus, als wäre es Zeit für eine Runde Tennis.",
|
||||
/*french*/ "C'est l'heure de jouer au tennis."));
|
||||
// /*spanish*/Parece que es hora de una pachanga de tenis.
|
||||
|
||||
hintTextTable[RHT_GANON_JOKE04] = HintText(CustomMessage("You'll never deflect my bolts of energy with your sword, then shoot me with those Light Arrows you happen to have.",
|
||||
/*german*/ TODO_TRANSLATE,
|
||||
/*german*/ "Du wirst meine Energiestrahlen nie mit deinem Schwert abwehren und mich dann mit den Lichtpfeilen beschießen, die du zufällig hast.",
|
||||
/*french*/ "Ne perds pas ton temps à frapper mes éclairs d'énergie avec ton épée et me tirer avec tes flèches de Lumière!"));
|
||||
// /*spanish*/Nunca reflejarás mis esferas de energía con tu espada, para después dispararme con las flechas de luz que tendrás.
|
||||
|
||||
hintTextTable[RHT_GANON_JOKE05] = HintText(CustomMessage("Why did I leave my trident back in the desert?",
|
||||
/*german*/ TODO_TRANSLATE,
|
||||
/*german*/ "Warum habe ich meinen Dreizack wieder in der Wüste gelassen?",
|
||||
/*french*/ "Sale bêtise... Et j'ai oublié mon trident dans le désert!"));
|
||||
// /*spanish*/Santa Hylia... ¿Por qué me habré dejado el tridente en el desierto?
|
||||
|
||||
hintTextTable[RHT_GANON_JOKE06] = HintText(CustomMessage("Zelda is probably going to do something stupid, like send you back to your own timeline.^So this is "
|
||||
"quite meaningless. Do you really want to save this moron?",
|
||||
/*german*/ TODO_TRANSLATE,
|
||||
/*german*/ "Zelda wird wahrscheinlich wieder etwas Dummes tun, wie dich zurück in deine eigene Timeline schicken "
|
||||
"^Das ist also ziemlich bedeutungslos. Willst du wirklich diese Idiotin retten?",
|
||||
/*french*/ "Même si je suis vaincu... Zelda te renverra dans ton ère, et je reviendrai conquérir!^Telle est la "
|
||||
"prophécie d'Hyrule Historia!"));
|
||||
// /*spanish*/Seguro que Zelda trata de hacer alguna tontería, como enviarte de vuelta a tu línea temporal.^No tiene
|
||||
|
@ -2373,30 +2425,31 @@ void StaticData::HintTable_Init() {
|
|||
|
||||
hintTextTable[RHT_GANON_JOKE07] = HintText(CustomMessage("What about Zelda makes you think&she'd be a better ruler than I?^I saved Lon Lon Ranch,&fed the "
|
||||
"hungry,&and my castle floats.",
|
||||
/*german*/ TODO_TRANSLATE,
|
||||
/*german*/ "Was an Zelda lässt dich glauben&sie wäre eine bessere&Herrscherin als ich?^Ich rettete die Lon Lon Ranch,&fütterte die Hungrigen"
|
||||
"&und mein Schloss schwebt.",
|
||||
/*french*/ "Zelda ne sera jamais un meilleur monarque que moi!^J'ai un château volant, mes sujets sont des belles "
|
||||
"amazones... et mes Moblins sont clairement plus puissants que jamais!"));
|
||||
// /*spanish*/¿Qué te hace pensar que Zelda gobierna mejor que yo?^Yo he salvado el Rancho Lon Lon,&he alimentado a
|
||||
// los hambrientos&y hasta hago que mi castillo flote.
|
||||
|
||||
hintTextTable[RHT_GANON_JOKE08] = HintText(CustomMessage("I've learned this spell,&it's really neat,&I'll keep it later&for your treat!",
|
||||
/*german*/ TODO_TRANSLATE,
|
||||
/*german*/ "Ich hab' diesen Zauber gelernt,&er ist wirklich ziemlich fein,&ich heb' ihn auf für später,&und dann soll er dein Geschenk sein!",
|
||||
/*french*/ "Gamin, ton destin achève,&sous mon sort tu périras!&Cette partie ne fut pas brève,&et cette mort, tu subiras!"));
|
||||
// /*spanish*/Veamos ahora que harás,&la batalla ha de comenzar,&te enviaré de una vez al más allá,&¿listo para
|
||||
// afrontar la verdad?
|
||||
|
||||
hintTextTable[RHT_GANON_JOKE09] = HintText(CustomMessage("Many tricks are up my sleeve,&to save yourself&you'd better leave!",
|
||||
/*german*/ TODO_TRANSLATE,
|
||||
/*german*/ "Viele Tricks hab' ich im Gepäck,&und um dich zu retten,&solltest du lieber weg.",
|
||||
/*french*/ "Sale petit garnement,&tu fais erreur!&C'est maintenant que marque&ta dernière heure!"));
|
||||
// /*spanish*/¿No osarás a mí enfrentarte?&Rimas aparte,&¡voy a matarte!
|
||||
|
||||
hintTextTable[RHT_GANON_JOKE10] = HintText(CustomMessage("After what you did to Koholint Island, how can you call me the bad guy?",
|
||||
/*german*/ TODO_TRANSLATE,
|
||||
/*german*/ "Nach dem, was du auf Insel Cocolint getan hast, wie kannst du mich da den Bösewicht nennen?",
|
||||
/*french*/ "J'admire ce que tu as fait à l'Île Koholint... Toi et moi, nous devrions faire équipe!"));
|
||||
// /*spanish*/Después de lo que le hiciste a la Isla Koholint, ¿cómo te atreves a llamarme malvado?
|
||||
|
||||
hintTextTable[RHT_GANON_JOKE11] = HintText(CustomMessage("Today, let's begin down&'The Hero is Defeated' timeline.",
|
||||
/*german*/ TODO_TRANSLATE,
|
||||
/*german*/ "Heute beginnen wir in der&‚Der Held ist besiegt‘-Timeline",
|
||||
/*french*/ "Si tu me vaincs, Hyrule sera englouti... mais si tu meurs, on aura A Link to the Past, le meilleur opus "
|
||||
"de la série!"));
|
||||
// /*spanish*/Hoy daremos lugar a la línea temporal del Héroe Derrotado.&¡Prepárate para el culmen de esta saga!
|
||||
|
@ -2410,15 +2463,17 @@ void StaticData::HintTable_Init() {
|
|||
/*french*/ "tes poches"));
|
||||
// /*spanish*/tu bolsillo
|
||||
|
||||
hintTextTable[RHT_ISOLATED_PLACE] = HintText(CustomMessage("an Isolated Place"));
|
||||
hintTextTable[RHT_ISOLATED_PLACE] = HintText(CustomMessage("an Isolated Place",
|
||||
/*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--;
|
||||
}
|
||||
|
|
|
@ -16,7 +16,7 @@ extern "C" {
|
|||
#include "soh/Enhancements/randomizer/item.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
class PlandomizerWindow : public Ship::GuiWindow {
|
||||
class PlandomizerWindow final : public Ship::GuiWindow {
|
||||
public:
|
||||
using GuiWindow::GuiWindow;
|
||||
|
||||
|
|
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) {
|
||||
|
@ -535,6 +535,8 @@ void Rando::StaticData::RegisterCrateLocations() {
|
|||
locationTable[RC_SPIRIT_TEMPLE_BEFORE_CHILD_CLIMB_SMALL_CRATE_2] = Location::SmallCrate(RC_SPIRIT_TEMPLE_BEFORE_CHILD_CLIMB_SMALL_CRATE_2, RCQUEST_VANILLA, RCAREA_SPIRIT_TEMPLE, SCENE_SPIRIT_TEMPLE, TWO_ACTOR_PARAMS(-1151, -939), "Before Child Climb Small Crate 2", RHT_CRATE_SPIRIT_TEMPLE, RG_DEKU_NUTS_5, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SPIRIT_TEMPLE_BEFORE_CHILD_CLIMB_SMALL_CRATE_2));
|
||||
locationTable[RC_JABU_JABUS_BELLY_MQ_TRIPLE_HALLWAY_SMALL_CRATE_1] = Location::SmallCrate(RC_JABU_JABUS_BELLY_MQ_TRIPLE_HALLWAY_SMALL_CRATE_1, RCQUEST_MQ, RCAREA_JABU_JABUS_BELLY, SCENE_JABU_JABU, TWO_ACTOR_PARAMS(-512, -4592), "MQ Triple Hallway Small Crate 1", RHT_CRATE_JABU_JABU, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_JABU_JABUS_BELLY_MQ_TRIPLE_HALLWAY_SMALL_CRATE_1));
|
||||
locationTable[RC_JABU_JABUS_BELLY_MQ_TRIPLE_HALLWAY_SMALL_CRATE_2] = Location::SmallCrate(RC_JABU_JABUS_BELLY_MQ_TRIPLE_HALLWAY_SMALL_CRATE_2, RCQUEST_MQ, RCAREA_JABU_JABUS_BELLY, SCENE_JABU_JABU, TWO_ACTOR_PARAMS(-666, -4671), "MQ Triple Hallway Small Crate 2", RHT_CRATE_JABU_JABU, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_JABU_JABUS_BELLY_MQ_TRIPLE_HALLWAY_SMALL_CRATE_2));
|
||||
locationTable[RC_JABU_JABUS_BELLY_MQ_JIGGLIES_SMALL_CRATE_1] = Location::SmallCrate(RC_JABU_JABUS_BELLY_MQ_JIGGLIES_SMALL_CRATE_1, RCQUEST_MQ, RCAREA_JABU_JABUS_BELLY, SCENE_JABU_JABU, TWO_ACTOR_PARAMS(-1381, -2115), "MQ Jigglies Small Crate 1", RHT_CRATE_JABU_JABU, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_JABU_JABUS_BELLY_MQ_JIGGLIES_SMALL_CRATE_1));
|
||||
locationTable[RC_JABU_JABUS_BELLY_MQ_JIGGLIES_SMALL_CRATE_2] = Location::SmallCrate(RC_JABU_JABUS_BELLY_MQ_JIGGLIES_SMALL_CRATE_2, RCQUEST_MQ, RCAREA_JABU_JABUS_BELLY, SCENE_JABU_JABU, TWO_ACTOR_PARAMS(-1341, -2116), "MQ Jigglies Small Crate 2", RHT_CRATE_JABU_JABU, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_JABU_JABUS_BELLY_MQ_JIGGLIES_SMALL_CRATE_2));
|
||||
locationTable[RC_FOREST_TEMPLE_MQ_FROZEN_EYE_SWITCH_SMALL_CRATE_1] = Location::SmallCrate(RC_FOREST_TEMPLE_MQ_FROZEN_EYE_SWITCH_SMALL_CRATE_1, RCQUEST_MQ, RCAREA_FOREST_TEMPLE, SCENE_FOREST_TEMPLE, TWO_ACTOR_PARAMS(1599, -1322), "MQ Frozen Eye Switch Small Crate 1", RHT_CRATE_FOREST_TEMPLE, RG_GREEN_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_FOREST_TEMPLE_MQ_FROZEN_EYE_SWITCH_SMALL_CRATE_1));
|
||||
locationTable[RC_FOREST_TEMPLE_MQ_FROZEN_EYE_SWITCH_SMALL_CRATE_2] = Location::SmallCrate(RC_FOREST_TEMPLE_MQ_FROZEN_EYE_SWITCH_SMALL_CRATE_2, RCQUEST_MQ, RCAREA_FOREST_TEMPLE, SCENE_FOREST_TEMPLE, TWO_ACTOR_PARAMS(2364, -873), "MQ Frozen Eye Switch Small Crate 2", RHT_CRATE_FOREST_TEMPLE, RG_ARROWS_5, SpoilerCollectionCheck::RandomizerInf(RAND_INF_FOREST_TEMPLE_MQ_FROZEN_EYE_SWITCH_SMALL_CRATE_2));
|
||||
locationTable[RC_FOREST_TEMPLE_MQ_FROZEN_EYE_SWITCH_SMALL_CRATE_3] = Location::SmallCrate(RC_FOREST_TEMPLE_MQ_FROZEN_EYE_SWITCH_SMALL_CRATE_3, RCQUEST_MQ, RCAREA_FOREST_TEMPLE, SCENE_FOREST_TEMPLE, TWO_ACTOR_PARAMS(2312, -874), "MQ Frozen Eye Switch Small Crate 3", RHT_CRATE_FOREST_TEMPLE, RG_ARROWS_5, SpoilerCollectionCheck::RandomizerInf(RAND_INF_FOREST_TEMPLE_MQ_FROZEN_EYE_SWITCH_SMALL_CRATE_3));
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
#include <z64.h>
|
||||
#include "soh/Enhancements/item-tables/ItemTableTypes.h"
|
||||
#include "randomizer_inf.h"
|
||||
#include "randomizerTypes.h"
|
||||
|
||||
typedef struct FairyIdentity {
|
||||
RandomizerInf randomizerInf;
|
||||
|
|
|
@ -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) {
|
||||
|
@ -497,7 +497,7 @@ void Rando::StaticData::RegisterGrassLocations() {
|
|||
locationTable[RC_JABU_JABUS_BELLY_MQ_BASEMENT_GRASS_1] = Location::Grass(RC_JABU_JABUS_BELLY_MQ_BASEMENT_GRASS_1, RCQUEST_MQ, RCAREA_JABU_JABUS_BELLY, SCENE_JABU_JABU, TWO_ACTOR_PARAMS(-91, -2815), "MQ Basement Grass 1", RHT_JABU_JABUS_BELLY_GRASS, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_JABU_JABUS_BELLY_MQ_BASEMENT_GRASS_1));
|
||||
locationTable[RC_JABU_JABUS_BELLY_MQ_BASEMENT_GRASS_2] = Location::Grass(RC_JABU_JABUS_BELLY_MQ_BASEMENT_GRASS_2, RCQUEST_MQ, RCAREA_JABU_JABUS_BELLY, SCENE_JABU_JABU, TWO_ACTOR_PARAMS(231, -3575), "MQ Basement Grass 2", RHT_JABU_JABUS_BELLY_GRASS, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_JABU_JABUS_BELLY_MQ_BASEMENT_GRASS_2));
|
||||
locationTable[RC_JABU_JABUS_BELLY_MQ_BASEMENT_GRASS_3] = Location::Grass(RC_JABU_JABUS_BELLY_MQ_BASEMENT_GRASS_3, RCQUEST_MQ, RCAREA_JABU_JABUS_BELLY, SCENE_JABU_JABU, TWO_ACTOR_PARAMS(305, -3481), "MQ Basement Grass 3", RHT_JABU_JABUS_BELLY_GRASS, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_JABU_JABUS_BELLY_MQ_BASEMENT_GRASS_3));
|
||||
locationTable[RC_JABU_JABUS_BELLY_MQ_WIGGLERS_GRASS] = Location::Grass(RC_JABU_JABUS_BELLY_MQ_WIGGLERS_GRASS, RCQUEST_MQ, RCAREA_JABU_JABUS_BELLY, SCENE_JABU_JABU, TWO_ACTOR_PARAMS(-1089, -1489), "MQ Wigglers Grass", RHT_JABU_JABUS_BELLY_GRASS, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_JABU_JABUS_BELLY_MQ_WIGGLERS_GRASS));
|
||||
locationTable[RC_JABU_JABUS_BELLY_MQ_JIGGLIES_GRASS] = Location::Grass(RC_JABU_JABUS_BELLY_MQ_JIGGLIES_GRASS, RCQUEST_MQ, RCAREA_JABU_JABUS_BELLY, SCENE_JABU_JABU, TWO_ACTOR_PARAMS(-1089, -1489), "MQ Jigglies Grass", RHT_JABU_JABUS_BELLY_GRASS, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_JABU_JABUS_BELLY_MQ_JIGGLIES_GRASS));
|
||||
locationTable[RC_JABU_JABUS_BELLY_MQ_FALLING_LIKE_LIKE_GRASS] = Location::Grass(RC_JABU_JABUS_BELLY_MQ_FALLING_LIKE_LIKE_GRASS, RCQUEST_MQ, RCAREA_JABU_JABUS_BELLY, SCENE_JABU_JABU, TWO_ACTOR_PARAMS(652, -5687), "MQ Like Like Grass", RHT_JABU_JABUS_BELLY_GRASS, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_JABU_JABUS_BELLY_MQ_FALLING_LIKE_LIKE_GRASS));
|
||||
locationTable[RC_JABU_JABUS_BELLY_MQ_BASEMENT_BOOMERANG_GRASS] = Location::Grass(RC_JABU_JABUS_BELLY_MQ_BASEMENT_BOOMERANG_GRASS, RCQUEST_MQ, RCAREA_JABU_JABUS_BELLY, SCENE_JABU_JABU, TWO_ACTOR_PARAMS(1228, -2647), "MQ Basement Boomerang Grass", RHT_JABU_JABUS_BELLY_GRASS, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_JABU_JABUS_BELLY_MQ_BASEMENT_BOOMERANG_GRASS));
|
||||
locationTable[RC_JABU_JABUS_BELLY_MQ_AFTER_BIG_OCTO_GRASS_1] = Location::Grass(RC_JABU_JABUS_BELLY_MQ_AFTER_BIG_OCTO_GRASS_1, RCQUEST_MQ, RCAREA_JABU_JABUS_BELLY, SCENE_JABU_JABU, TWO_ACTOR_PARAMS(-1360, -3606), "MQ After Big Octo Grass 1", RHT_JABU_JABUS_BELLY_GRASS, RG_BLUE_RUPEE, SpoilerCollectionCheck::RandomizerInf(RAND_INF_JABU_JABUS_BELLY_MQ_AFTER_BIG_OCTO_GRASS_1));
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -180,6 +180,8 @@ void Context::GenerateLocationPool() {
|
|||
location.GetRandomizerCheck() == RC_HF_DEKU_SCRUB_GROTTO)) ||
|
||||
(location.GetRCType() == RCTYPE_ADULT_TRADE && mOptions[RSK_SHUFFLE_ADULT_TRADE].Is(RO_GENERIC_OFF)) ||
|
||||
(location.GetRCType() == RCTYPE_COW && mOptions[RSK_SHUFFLE_COWS].Is(RO_GENERIC_OFF)) ||
|
||||
(location.GetRandomizerCheck() == RC_LH_HYRULE_LOACH &&
|
||||
mOptions[RSK_FISHSANITY].IsNot(RO_FISHSANITY_HYRULE_LOACH)) ||
|
||||
(location.GetRCType() == RCTYPE_FISH && !mFishsanity->GetFishLocationIncluded(&location)) ||
|
||||
(location.GetRCType() == RCTYPE_POT && mOptions[RSK_SHUFFLE_POTS].Is(RO_SHUFFLE_POTS_OFF)) ||
|
||||
(location.GetRCType() == RCTYPE_GRASS && mOptions[RSK_SHUFFLE_GRASS].Is(RO_SHUFFLE_GRASS_OFF)) ||
|
||||
|
@ -200,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);
|
||||
|
|
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