├── .github └── workflows │ └── msbuild.yml ├── .gitignore ├── .gitmodules ├── CHANGELOG.md ├── GTAVMenuExample.sln ├── GTAVMenuExample ├── Constants.hpp ├── DllMain.cpp ├── GTAVMenuExample.vcxproj ├── GTAVMenuExample.vcxproj.filters ├── ImageDimensions.cpp ├── ImageDimensions.hpp ├── MenuExampleMenu.cpp ├── MenuExampleScript.cpp ├── MenuExampleScript.hpp ├── MenuTexture.cpp ├── MenuTexture.hpp ├── Script.cpp ├── Script.hpp ├── ScriptMenu.hpp └── Util │ ├── Logger.cpp │ ├── Logger.hpp │ ├── Paths.cpp │ ├── Paths.hpp │ ├── UI.cpp │ └── UI.hpp ├── GTAV_dir ├── GTAVMenuExample │ ├── img │ │ ├── 86coupe.jpg │ │ ├── ae86.png │ │ ├── blista.png │ │ ├── custom_background.png │ │ ├── custom_background2.png │ │ ├── cw2020.jpg │ │ └── nisgtrr32.png │ └── settings_menu.ini └── README.md ├── LICENSE ├── MenuCompare.png ├── README.md └── thirdparty └── ScriptHookV_SDK ├── inc ├── enums.h ├── main.h ├── nativeCaller.h ├── natives.h └── types.h ├── lib └── ScriptHookV.lib └── readme.txt /.github/workflows/msbuild.yml: -------------------------------------------------------------------------------- 1 | name: MSBuild 2 | 3 | on: 4 | push: 5 | branches: [ "master" ] 6 | pull_request: 7 | branches: [ "master" ] 8 | 9 | env: 10 | # Path to the solution file relative to the root of the project. 11 | SOLUTION_FILE_PATH: ./GTAVMenuExample.sln 12 | 13 | # Configuration type to build. 14 | # You can convert this to a build matrix if you need coverage of multiple configuration types. 15 | # https://docs.github.com/actions/learn-github-actions/managing-complex-workflows#using-a-build-matrix 16 | BUILD_CONFIGURATION: Release 17 | 18 | permissions: 19 | contents: read 20 | 21 | jobs: 22 | build: 23 | runs-on: windows-latest 24 | 25 | steps: 26 | - uses: actions/checkout@v3 27 | with: 28 | submodules: recursive 29 | 30 | - name: Add MSBuild to PATH 31 | uses: microsoft/setup-msbuild@v1.0.2 32 | 33 | - name: Build 34 | working-directory: ${{env.GITHUB_WORKSPACE}} 35 | # Add additional options to the MSBuild command line here (like platform or verbosity level). 36 | # See https://docs.microsoft.com/visualstudio/msbuild/msbuild-command-line-reference 37 | run: msbuild /m /p:Configuration=${{env.BUILD_CONFIGURATION}} ${{env.SOLUTION_FILE_PATH}} /p:Platform=x64 38 | 39 | - name: Copy build result to stage dir 40 | run: | 41 | cp GTAVMenuExample/bin/GTAVMenuExample.asi GTAV_dir/GTAVMenuExample.asi 42 | cp GTAVMenuExample/bin/GTAVMenuExample.pdb GTAV_dir/GTAVMenuExample.pdb 43 | - name: Upload a Build Artifact 44 | uses: actions/upload-artifact@v3.1.0 45 | with: 46 | # Artifact name 47 | name: GTAVMenuExample-${{ github.sha }} 48 | path: | 49 | GTAV_dir/ 50 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | ## Ignore Visual Studio temporary files, build results, and 2 | ## files generated by popular Visual Studio add-ons. 3 | ## 4 | ## Get latest from https://github.com/github/gitignore/blob/main/VisualStudio.gitignore 5 | 6 | # User-specific files 7 | *.rsuser 8 | *.suo 9 | *.user 10 | *.userosscache 11 | *.sln.docstates 12 | 13 | # User-specific files (MonoDevelop/Xamarin Studio) 14 | *.userprefs 15 | 16 | # Mono auto generated files 17 | mono_crash.* 18 | 19 | # Build results 20 | [Dd]ebug/ 21 | [Dd]ebugPublic/ 22 | [Rr]elease/ 23 | [Rr]eleases/ 24 | x64/ 25 | x86/ 26 | [Ww][Ii][Nn]32/ 27 | [Aa][Rr][Mm]/ 28 | [Aa][Rr][Mm]64/ 29 | bld/ 30 | [Bb]in/ 31 | [Oo]bj/ 32 | [Ll]og/ 33 | [Ll]ogs/ 34 | 35 | # Visual Studio 2015/2017 cache/options directory 36 | .vs/ 37 | # Uncomment if you have tasks that create the project's static files in wwwroot 38 | #wwwroot/ 39 | 40 | # Visual Studio 2017 auto generated files 41 | Generated\ Files/ 42 | 43 | # MSTest test Results 44 | [Tt]est[Rr]esult*/ 45 | [Bb]uild[Ll]og.* 46 | 47 | # NUnit 48 | *.VisualState.xml 49 | TestResult.xml 50 | nunit-*.xml 51 | 52 | # Build Results of an ATL Project 53 | [Dd]ebugPS/ 54 | [Rr]eleasePS/ 55 | dlldata.c 56 | 57 | # Benchmark Results 58 | BenchmarkDotNet.Artifacts/ 59 | 60 | # .NET Core 61 | project.lock.json 62 | project.fragment.lock.json 63 | artifacts/ 64 | 65 | # ASP.NET Scaffolding 66 | ScaffoldingReadMe.txt 67 | 68 | # StyleCop 69 | StyleCopReport.xml 70 | 71 | # Files built by Visual Studio 72 | *_i.c 73 | *_p.c 74 | *_h.h 75 | *.ilk 76 | *.meta 77 | *.obj 78 | *.iobj 79 | *.pch 80 | *.pdb 81 | *.ipdb 82 | *.pgc 83 | *.pgd 84 | *.rsp 85 | *.sbr 86 | *.tlb 87 | *.tli 88 | *.tlh 89 | *.tmp 90 | *.tmp_proj 91 | *_wpftmp.csproj 92 | *.log 93 | *.tlog 94 | *.vspscc 95 | *.vssscc 96 | .builds 97 | *.pidb 98 | *.svclog 99 | *.scc 100 | 101 | # Chutzpah Test files 102 | _Chutzpah* 103 | 104 | # Visual C++ cache files 105 | ipch/ 106 | *.aps 107 | *.ncb 108 | *.opendb 109 | *.opensdf 110 | *.sdf 111 | *.cachefile 112 | *.VC.db 113 | *.VC.VC.opendb 114 | 115 | # Visual Studio profiler 116 | *.psess 117 | *.vsp 118 | *.vspx 119 | *.sap 120 | 121 | # Visual Studio Trace Files 122 | *.e2e 123 | 124 | # TFS 2012 Local Workspace 125 | $tf/ 126 | 127 | # Guidance Automation Toolkit 128 | *.gpState 129 | 130 | # ReSharper is a .NET coding add-in 131 | _ReSharper*/ 132 | *.[Rr]e[Ss]harper 133 | *.DotSettings.user 134 | 135 | # TeamCity is a build add-in 136 | _TeamCity* 137 | 138 | # DotCover is a Code Coverage Tool 139 | *.dotCover 140 | 141 | # AxoCover is a Code Coverage Tool 142 | .axoCover/* 143 | !.axoCover/settings.json 144 | 145 | # Coverlet is a free, cross platform Code Coverage Tool 146 | coverage*.json 147 | coverage*.xml 148 | coverage*.info 149 | 150 | # Visual Studio code coverage results 151 | *.coverage 152 | *.coveragexml 153 | 154 | # NCrunch 155 | _NCrunch_* 156 | .*crunch*.local.xml 157 | nCrunchTemp_* 158 | 159 | # MightyMoose 160 | *.mm.* 161 | AutoTest.Net/ 162 | 163 | # Web workbench (sass) 164 | .sass-cache/ 165 | 166 | # Installshield output folder 167 | [Ee]xpress/ 168 | 169 | # DocProject is a documentation generator add-in 170 | DocProject/buildhelp/ 171 | DocProject/Help/*.HxT 172 | DocProject/Help/*.HxC 173 | DocProject/Help/*.hhc 174 | DocProject/Help/*.hhk 175 | DocProject/Help/*.hhp 176 | DocProject/Help/Html2 177 | DocProject/Help/html 178 | 179 | # Click-Once directory 180 | publish/ 181 | 182 | # Publish Web Output 183 | *.[Pp]ublish.xml 184 | *.azurePubxml 185 | # Note: Comment the next line if you want to checkin your web deploy settings, 186 | # but database connection strings (with potential passwords) will be unencrypted 187 | *.pubxml 188 | *.publishproj 189 | 190 | # Microsoft Azure Web App publish settings. Comment the next line if you want to 191 | # checkin your Azure Web App publish settings, but sensitive information contained 192 | # in these scripts will be unencrypted 193 | PublishScripts/ 194 | 195 | # NuGet Packages 196 | *.nupkg 197 | # NuGet Symbol Packages 198 | *.snupkg 199 | # The packages folder can be ignored because of Package Restore 200 | **/[Pp]ackages/* 201 | # except build/, which is used as an MSBuild target. 202 | !**/[Pp]ackages/build/ 203 | # Uncomment if necessary however generally it will be regenerated when needed 204 | #!**/[Pp]ackages/repositories.config 205 | # NuGet v3's project.json files produces more ignorable files 206 | *.nuget.props 207 | *.nuget.targets 208 | 209 | # Microsoft Azure Build Output 210 | csx/ 211 | *.build.csdef 212 | 213 | # Microsoft Azure Emulator 214 | ecf/ 215 | rcf/ 216 | 217 | # Windows Store app package directories and files 218 | AppPackages/ 219 | BundleArtifacts/ 220 | Package.StoreAssociation.xml 221 | _pkginfo.txt 222 | *.appx 223 | *.appxbundle 224 | *.appxupload 225 | 226 | # Visual Studio cache files 227 | # files ending in .cache can be ignored 228 | *.[Cc]ache 229 | # but keep track of directories ending in .cache 230 | !?*.[Cc]ache/ 231 | 232 | # Others 233 | ClientBin/ 234 | ~$* 235 | *~ 236 | *.dbmdl 237 | *.dbproj.schemaview 238 | *.jfm 239 | *.pfx 240 | *.publishsettings 241 | orleans.codegen.cs 242 | 243 | # Including strong name files can present a security risk 244 | # (https://github.com/github/gitignore/pull/2483#issue-259490424) 245 | #*.snk 246 | 247 | # Since there are multiple workflows, uncomment next line to ignore bower_components 248 | # (https://github.com/github/gitignore/pull/1529#issuecomment-104372622) 249 | #bower_components/ 250 | 251 | # RIA/Silverlight projects 252 | Generated_Code/ 253 | 254 | # Backup & report files from converting an old project file 255 | # to a newer Visual Studio version. Backup files are not needed, 256 | # because we have git ;-) 257 | _UpgradeReport_Files/ 258 | Backup*/ 259 | UpgradeLog*.XML 260 | UpgradeLog*.htm 261 | ServiceFabricBackup/ 262 | *.rptproj.bak 263 | 264 | # SQL Server files 265 | *.mdf 266 | *.ldf 267 | *.ndf 268 | 269 | # Business Intelligence projects 270 | *.rdl.data 271 | *.bim.layout 272 | *.bim_*.settings 273 | *.rptproj.rsuser 274 | *- [Bb]ackup.rdl 275 | *- [Bb]ackup ([0-9]).rdl 276 | *- [Bb]ackup ([0-9][0-9]).rdl 277 | 278 | # Microsoft Fakes 279 | FakesAssemblies/ 280 | 281 | # GhostDoc plugin setting file 282 | *.GhostDoc.xml 283 | 284 | # Node.js Tools for Visual Studio 285 | .ntvs_analysis.dat 286 | node_modules/ 287 | 288 | # Visual Studio 6 build log 289 | *.plg 290 | 291 | # Visual Studio 6 workspace options file 292 | *.opt 293 | 294 | # Visual Studio 6 auto-generated workspace file (contains which files were open etc.) 295 | *.vbw 296 | 297 | # Visual Studio 6 auto-generated project file (contains which files were open etc.) 298 | *.vbp 299 | 300 | # Visual Studio 6 workspace and project file (working project files containing files to include in project) 301 | *.dsw 302 | *.dsp 303 | 304 | # Visual Studio 6 technical files 305 | *.ncb 306 | *.aps 307 | 308 | # Visual Studio LightSwitch build output 309 | **/*.HTMLClient/GeneratedArtifacts 310 | **/*.DesktopClient/GeneratedArtifacts 311 | **/*.DesktopClient/ModelManifest.xml 312 | **/*.Server/GeneratedArtifacts 313 | **/*.Server/ModelManifest.xml 314 | _Pvt_Extensions 315 | 316 | # Paket dependency manager 317 | .paket/paket.exe 318 | paket-files/ 319 | 320 | # FAKE - F# Make 321 | .fake/ 322 | 323 | # CodeRush personal settings 324 | .cr/personal 325 | 326 | # Python Tools for Visual Studio (PTVS) 327 | __pycache__/ 328 | *.pyc 329 | 330 | # Cake - Uncomment if you are using it 331 | # tools/** 332 | # !tools/packages.config 333 | 334 | # Tabs Studio 335 | *.tss 336 | 337 | # Telerik's JustMock configuration file 338 | *.jmconfig 339 | 340 | # BizTalk build output 341 | *.btp.cs 342 | *.btm.cs 343 | *.odx.cs 344 | *.xsd.cs 345 | 346 | # OpenCover UI analysis results 347 | OpenCover/ 348 | 349 | # Azure Stream Analytics local run output 350 | ASALocalRun/ 351 | 352 | # MSBuild Binary and Structured Log 353 | *.binlog 354 | 355 | # NVidia Nsight GPU debugger configuration file 356 | *.nvuser 357 | 358 | # MFractors (Xamarin productivity tool) working folder 359 | .mfractor/ 360 | 361 | # Local History for Visual Studio 362 | .localhistory/ 363 | 364 | # Visual Studio History (VSHistory) files 365 | .vshistory/ 366 | 367 | # BeatPulse healthcheck temp database 368 | healthchecksdb 369 | 370 | # Backup folder for Package Reference Convert tool in Visual Studio 2017 371 | MigrationBackup/ 372 | 373 | # Ionide (cross platform F# VS Code tools) working folder 374 | .ionide/ 375 | 376 | # Fody - auto-generated XML schema 377 | FodyWeavers.xsd 378 | 379 | # VS Code files for those working on multiple tools 380 | .vscode/* 381 | !.vscode/settings.json 382 | !.vscode/tasks.json 383 | !.vscode/launch.json 384 | !.vscode/extensions.json 385 | *.code-workspace 386 | 387 | # Local History for Visual Studio Code 388 | .history/ 389 | 390 | # Windows Installer files from build outputs 391 | *.cab 392 | *.msi 393 | *.msix 394 | *.msm 395 | *.msp 396 | 397 | # JetBrains Rider 398 | *.sln.iml 399 | -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "thirdparty/GTAVMenuBase"] 2 | path = thirdparty/GTAVMenuBase 3 | url = https://github.com/E66666666/GTAVMenuBase.git 4 | [submodule "thirdparty/simpleini"] 5 | path = thirdparty/simpleini 6 | url = https://github.com/brofield/simpleini 7 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Changelog 2 | 3 | Commits should be fine to read, but this is here anyway for the larger changes that need more than 50 characters to explain. 4 | 5 | ## 2.0 6 | 7 | Basically a full rewrite, based on how my new scripts use the menu and their general structure. 8 | 9 | The underlaying menu is still one and the same horrible mess, but the pretty wrapper around it makes 10 | usage a lot more user (or, developer: me)-friendly. For one, gone are the days where one needs to 11 | define a submenu name, a function that implements it, and the call to run it, while also calling 12 | the required methods. It's all in the wrapper now. 13 | 14 | The script instance that's passed there allows the menu to interact with the core mod logic 15 | in a defined manner (public methods), so no more throwing around globals and loose functions. 16 | 17 | Loose functions still exist in the "called by DllMain stuff", but that should be mostly limited to 18 | initialization and grabbing the script instance handles. Oh yeah, splitting things up allows 19 | to create multiple instances, for example a "script" that works for all NPCs. 20 | 21 | ## 1.0 22 | 23 | Initial publish. Based on the proof-ish of concept made for VStancer to have *some* UI, as before 24 | that my scripts were just .ini based and the user was expected to dig around in there using Notepad. 25 | -------------------------------------------------------------------------------- /GTAVMenuExample.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio Version 17 4 | VisualStudioVersion = 17.3.32804.467 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "GTAVMenuExample", "GTAVMenuExample\GTAVMenuExample.vcxproj", "{71D4C2A8-9E78-47A8-A2B7-3FB2DE014D27}" 7 | EndProject 8 | Global 9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 10 | Debug|x64 = Debug|x64 11 | Release|x64 = Release|x64 12 | EndGlobalSection 13 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 14 | {71D4C2A8-9E78-47A8-A2B7-3FB2DE014D27}.Debug|x64.ActiveCfg = Debug|x64 15 | {71D4C2A8-9E78-47A8-A2B7-3FB2DE014D27}.Debug|x64.Build.0 = Debug|x64 16 | {71D4C2A8-9E78-47A8-A2B7-3FB2DE014D27}.Release|x64.ActiveCfg = Release|x64 17 | {71D4C2A8-9E78-47A8-A2B7-3FB2DE014D27}.Release|x64.Build.0 = Release|x64 18 | EndGlobalSection 19 | GlobalSection(SolutionProperties) = preSolution 20 | HideSolutionNode = FALSE 21 | EndGlobalSection 22 | GlobalSection(ExtensibilityGlobals) = postSolution 23 | SolutionGuid = {762324C6-E280-45CA-BEE2-2C7BC056AE62} 24 | EndGlobalSection 25 | EndGlobal 26 | -------------------------------------------------------------------------------- /GTAVMenuExample/Constants.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #define STR_HELPER(x) #x 3 | #define STR(x) STR_HELPER(x) 4 | 5 | #define VERSION_MAJOR 2 6 | #define VERSION_MINOR 0 7 | #define VERSION_PATCH 0 8 | 9 | namespace Constants { 10 | static const char* const ScriptName = "Menu Example"; 11 | static const char* const NotificationPrefix = "~b~Menu Example~w~"; 12 | static const char* const DisplayVersion = "v" STR(VERSION_MAJOR) "." STR(VERSION_MINOR) "." STR(VERSION_PATCH); 13 | 14 | // This can probably be renamed to "authorFolder" 15 | // This is to create %localappdata%/ikt/GTAVMenuExample if for some reason 16 | // the GTA V folder is not read/writeable for the script. 17 | static const char* const iktFolder = "ikt"; 18 | static const char* const ScriptFolder = "GTAVMenuExample"; 19 | } 20 | -------------------------------------------------------------------------------- /GTAVMenuExample/DllMain.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * DllMain.cpp hosts the DllMain function, which is the entry point for the DLL. 3 | * Initialization happens here. 4 | * In this example, it initializes the logger and paths, and registers the main 5 | * script function to ScriptHookV using scriptRegister. 6 | */ 7 | 8 | #include "Script.hpp" 9 | #include "Constants.hpp" 10 | #include "Util/Logger.hpp" 11 | #include "Util/Paths.hpp" 12 | 13 | #include 14 | #include 15 | 16 | namespace fs = std::filesystem; 17 | 18 | /* 19 | * As the game is often installed in a default directory, like 20 | * C:\Program Files (x86)\Steam\steamapps\common\Grand Theft Auto V 21 | * Windows permissions may not allow scripts to write there. 22 | * This function detects if that happens and copies the files it needs to 23 | * %localappdata%\{author}\{scriptname}. 24 | * 25 | * Use Paths::GetModPath() to ensure the relocated path is used, instead of the 26 | * GTA V directory. 27 | */ 28 | void initializePaths(HMODULE hInstance) { 29 | Paths::SetOurModuleHandle(hInstance); 30 | 31 | auto localAppDataPath = Paths::GetLocalAppDataPath(); 32 | auto localAppDataModPath = localAppDataPath / Constants::iktFolder / Constants::ScriptFolder; 33 | auto originalModPath = Paths::GetModuleFolder(hInstance) / Constants::ScriptFolder; 34 | Paths::SetModPath(originalModPath); 35 | 36 | bool useAltModPath = false; 37 | if (fs::exists(localAppDataModPath)) { 38 | useAltModPath = true; 39 | } 40 | 41 | fs::path modPath; 42 | fs::path logFile; 43 | 44 | // Use LocalAppData if it already exists. 45 | if (useAltModPath) { 46 | modPath = localAppDataModPath; 47 | logFile = localAppDataModPath / (Paths::GetModuleNameWithoutExtension(hInstance) + ".log"); 48 | } 49 | else { 50 | modPath = originalModPath; 51 | logFile = modPath / (Paths::GetModuleNameWithoutExtension(hInstance) + ".log"); 52 | } 53 | 54 | Paths::SetModPath(modPath); 55 | 56 | if (!fs::is_directory(modPath) || !fs::exists(modPath)) { 57 | fs::create_directories(modPath); 58 | } 59 | 60 | g_Logger.SetFile(logFile.string()); 61 | g_Logger.Clear(); 62 | 63 | if (g_Logger.Error()) { 64 | modPath = localAppDataModPath; 65 | logFile = localAppDataModPath / (Paths::GetModuleNameWithoutExtension(hInstance) + ".log"); 66 | fs::create_directories(modPath); 67 | 68 | Paths::SetModPath(modPath); 69 | g_Logger.SetFile(logFile.string()); 70 | 71 | fs::copy(originalModPath, localAppDataModPath, 72 | fs::copy_options::update_existing | fs::copy_options::recursive); 73 | 74 | std::vector messages; 75 | 76 | // Fix perms 77 | for (auto& path : fs::recursive_directory_iterator(localAppDataModPath)) { 78 | try { 79 | fs::permissions(path, fs::perms::all); 80 | } 81 | catch (std::exception& e) { 82 | messages.push_back( 83 | std::format("Failed to set permissions on [{}]: {}", 84 | path.path().string(), e.what())); 85 | } 86 | } 87 | 88 | g_Logger.ClearError(); 89 | g_Logger.Clear(); 90 | 91 | LOG(WARN, "Copied to [{}] from [{}] due to read/write issues.", 92 | modPath.string(), originalModPath.string()); 93 | 94 | if (!messages.empty()) { 95 | LOG(WARN, "Encountered issues while updating permissions:"); 96 | for (const auto& message : messages) { 97 | LOG(WARN, "{}", message); 98 | } 99 | } 100 | } 101 | } 102 | 103 | BOOL APIENTRY DllMain(HMODULE hInstance, DWORD reason, LPVOID lpReserved) { 104 | switch (reason) { 105 | case DLL_PROCESS_ATTACH: { 106 | g_Logger.SetMinLevel(DEBUG); 107 | initializePaths(hInstance); 108 | LOG(INFO, "{} {} (built {} {})", Constants::ScriptName, Constants::DisplayVersion, __DATE__, __TIME__); 109 | LOG(INFO, "Data path: {}", Paths::GetModPath().string()); 110 | 111 | scriptRegister(hInstance, MenuExample::ScriptMain); 112 | LOG(INFO, "Script registered"); 113 | break; 114 | } 115 | case DLL_PROCESS_DETACH: { 116 | scriptUnregister(hInstance); 117 | break; 118 | } 119 | default: { 120 | break; 121 | } 122 | } 123 | return TRUE; 124 | } 125 | -------------------------------------------------------------------------------- /GTAVMenuExample/GTAVMenuExample.vcxproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Debug 6 | x64 7 | 8 | 9 | Release 10 | x64 11 | 12 | 13 | 14 | {71D4C2A8-9E78-47A8-A2B7-3FB2DE014D27} 15 | InversePower 16 | 10.0 17 | GTAVMenuExample 18 | 19 | 20 | 21 | DynamicLibrary 22 | true 23 | v143 24 | NotSet 25 | true 26 | 27 | 28 | DynamicLibrary 29 | false 30 | v143 31 | NotSet 32 | true 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | bin\dbg\ 49 | obj\dbg\ 50 | .asi 51 | false 52 | 53 | 54 | .asi 55 | bin\ 56 | obj\ 57 | false 58 | 59 | 60 | 61 | Level3 62 | MaxSpeed 63 | 64 | 65 | true 66 | MultiThreaded 67 | true 68 | Fast 69 | WIN32_LEAN_AND_MEAN;NOMINMAX;NOGDI;%(PreprocessorDefinitions) 70 | ProgramDatabase 71 | Default 72 | $(SolutionDir)thirdparty\ScriptHookV_SDK;$(SolutionDir)thirdparty;$(SolutionDir)thirdparty\GTAVMenuBase\ 73 | stdcpp20 74 | 75 | 76 | DebugFull 77 | true 78 | true 79 | 80 | 81 | 82 | copy /b $(ProjectDir)DllMain.cpp +,, 83 | 84 | 85 | 86 | 87 | WIN32_LEAN_AND_MEAN;NOMINMAX;NOGDI;%(PreprocessorDefinitions) 88 | Async 89 | MultiThreaded 90 | true 91 | Fast 92 | Level3 93 | $(SolutionDir)thirdparty\ScriptHookV_SDK;$(SolutionDir)thirdparty;$(SolutionDir)thirdparty\GTAVMenuBase\ 94 | stdcpp20 95 | 96 | 97 | DebugFull 98 | Windows 99 | true 100 | true 101 | 102 | 103 | 104 | copy /b $(ProjectDir)DllMain.cpp +,, 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 | 148 | 149 | 150 | 151 | 152 | 153 | 154 | 155 | 156 | 157 | 158 | 159 | 160 | 161 | 162 | -------------------------------------------------------------------------------- /GTAVMenuExample/GTAVMenuExample.vcxproj.filters: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | Util 8 | 9 | 10 | Util 11 | 12 | 13 | Util 14 | 15 | 16 | 17 | 18 | 19 | Util 20 | 21 | 22 | ThirdParty\GTAVMenuBase 23 | 24 | 25 | ThirdParty\GTAVMenuBase 26 | 27 | 28 | ThirdParty\GTAVMenuBase 29 | 30 | 31 | ThirdParty\GTAVMenuBase 32 | 33 | 34 | ThirdParty\GTAVMenuBase 35 | 36 | 37 | ThirdParty\GTAVMenuBase 38 | 39 | 40 | 41 | 42 | 43 | Util 44 | 45 | 46 | Util 47 | 48 | 49 | Util 50 | 51 | 52 | 53 | 54 | 55 | 56 | Util 57 | 58 | 59 | ThirdParty\GTAVMenuBase 60 | 61 | 62 | ThirdParty\GTAVMenuBase 63 | 64 | 65 | ThirdParty\GTAVMenuBase 66 | 67 | 68 | ThirdParty\GTAVMenuBase 69 | 70 | 71 | ThirdParty\GTAVMenuBase 72 | 73 | 74 | ThirdParty\GTAVMenuBase 75 | 76 | 77 | ThirdParty\GTAVMenuBase 78 | 79 | 80 | ThirdParty\GTAVMenuBase 81 | 82 | 83 | ThirdParty\ScriptHookV\inc 84 | 85 | 86 | ThirdParty\ScriptHookV\inc 87 | 88 | 89 | ThirdParty\ScriptHookV\inc 90 | 91 | 92 | ThirdParty\ScriptHookV\inc 93 | 94 | 95 | ThirdParty\ScriptHookV\inc 96 | 97 | 98 | ThirdParty\simpleini 99 | 100 | 101 | 102 | 103 | {2d981cd8-6f7d-42dd-bf15-44aebcda936b} 104 | 105 | 106 | {12bfb7cd-0fb3-4dc1-9bdf-2f6b97605338} 107 | 108 | 109 | {01012e73-37b7-4874-b66a-9390e9a83264} 110 | 111 | 112 | {26d64db9-1573-4132-9638-76079dc911c5} 113 | 114 | 115 | {5a4685d5-4339-4375-a79e-f3a511b574a9} 116 | 117 | 118 | {f8c9a988-6205-4f4d-876e-0ea2849a9866} 119 | 120 | 121 | {6e54d8dd-e89f-4fb9-8ecc-af8f4e3bd69a} 122 | 123 | 124 | {b456ee42-7020-4fb5-8bea-49dbdfee208a} 125 | 126 | 127 | 128 | 129 | ThirdParty\ScriptHookV\lib 130 | 131 | 132 | 133 | 134 | Info 135 | 136 | 137 | Info 138 | 139 | 140 | Info 141 | 142 | 143 | -------------------------------------------------------------------------------- /GTAVMenuExample/ImageDimensions.cpp: -------------------------------------------------------------------------------- 1 | #include "ImageDimensions.hpp" 2 | #include "Util/Logger.hpp" 3 | #include 4 | #include 5 | 6 | namespace fs = std::filesystem; 7 | 8 | namespace ImageDimensions { 9 | std::optional getPNGDimensions(const std::string& file); 10 | std::optional getJPGDimensions(const std::string& file); 11 | } 12 | 13 | namespace { 14 | std::string to_lower(std::string data) { 15 | std::transform(data.begin(), data.end(), data.begin(), ::tolower); 16 | return data; 17 | } 18 | } 19 | 20 | std::optional ImageDimensions::GetIMGDimensions(const std::string& file) { 21 | auto ext = to_lower(fs::path(file).extension().string()); 22 | if (ext == ".png") 23 | return getPNGDimensions(file); 24 | if (ext == ".jpg" || ext == ".jpeg") 25 | return getJPGDimensions(file); 26 | return {}; 27 | } 28 | 29 | std::optional ImageDimensions::getPNGDimensions(const std::string& file) { 30 | const uint64_t pngSig = 0x89504E470D0A1A0A; 31 | 32 | std::ifstream img(file, std::ios::binary); 33 | 34 | if (!img.good()) { 35 | LOG(ERROR, "[IMG]: {} failed to open", file); 36 | return {}; 37 | } 38 | 39 | uint64_t imgSig = 0x0; 40 | 41 | img.seekg(0); 42 | img.read((char*)&imgSig, sizeof(uint64_t)); 43 | 44 | imgSig = _byteswap_uint64(imgSig); 45 | 46 | if (imgSig == pngSig) { 47 | uint32_t w, h; 48 | 49 | img.seekg(16); 50 | img.read((char*)&w, 4); 51 | img.read((char*)&h, 4); 52 | 53 | return ImageDimensions::SImageDimensions{ 54 | .Width = _byteswap_ulong(w), 55 | .Height = _byteswap_ulong(h) 56 | }; 57 | } 58 | 59 | LOG(ERROR, "[IMG]: {} not a PNG file, sig: 0x{:16X}", file, imgSig); 60 | return {}; 61 | } 62 | 63 | //https://stackoverflow.com/questions/17847171/c-library-for-getting-the-jpeg-image-size 64 | std::optional ImageDimensions::getJPGDimensions(const std::string& file) { 65 | ImageDimensions::SImageDimensions dims{}; 66 | FILE* image = nullptr; 67 | 68 | errno_t err = fopen_s(&image, file.c_str(), "rb"); // open JPEG image file 69 | if (!image || err) { 70 | return {}; 71 | } 72 | fseek(image, 0, SEEK_END); 73 | int size = ftell(image); 74 | fseek(image, 0, SEEK_SET); 75 | unsigned char* data = (unsigned char*)malloc(size); 76 | fread(data, 1, size, image); 77 | /* verify valid JPEG header */ 78 | int i = 0; 79 | if (data[i] == 0xFF && data[i + 1] == 0xD8 && data[i + 2] == 0xFF && data[i + 3] == 0xE0) { 80 | i += 4; 81 | /* Check for null terminated JFIF */ 82 | if (data[i + 2] == 'J' && data[i + 3] == 'F' && data[i + 4] == 'I' && data[i + 5] == 'F' && data[i + 6] == 0x00) { 83 | while (i < size) { 84 | i++; 85 | if (data[i] == 0xFF) { 86 | if (data[i + 1] == 0xC0) { 87 | dims.Width = data[i + 7] * 256 + data[i + 8]; 88 | dims.Height = data[i + 5] * 256 + data[i + 6]; 89 | break; 90 | } 91 | } 92 | } 93 | } 94 | else { 95 | fclose(image); 96 | return {}; 97 | } 98 | } 99 | else { 100 | fclose(image); 101 | return {}; 102 | } 103 | fclose(image); 104 | return dims; 105 | } 106 | -------------------------------------------------------------------------------- /GTAVMenuExample/ImageDimensions.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | 6 | namespace ImageDimensions { 7 | struct SImageDimensions { 8 | uint32_t Width; 9 | uint32_t Height; 10 | }; 11 | 12 | std::optional GetIMGDimensions(const std::string& file); 13 | } 14 | -------------------------------------------------------------------------------- /GTAVMenuExample/MenuExampleMenu.cpp: -------------------------------------------------------------------------------- 1 | #include "ScriptMenu.hpp" 2 | #include "Constants.hpp" 3 | #include "MenuExampleScript.hpp" 4 | #include "MenuTexture.hpp" 5 | #include "Script.hpp" 6 | 7 | #include "Util/Logger.hpp" 8 | #include "Util/Paths.hpp" 9 | #include "Util/UI.hpp" 10 | 11 | #include 12 | 13 | namespace { 14 | // A few state variables for demoing the menu 15 | bool checkBoxStatus = false; 16 | float someFloat = 0.0f; 17 | int someInt = 0; 18 | int intStep = 1; 19 | int stringsPos = 0; 20 | int stepChoice = 0; 21 | int numberOfOptions = 16; 22 | 23 | // Choice of step size to demonstrate variable precision display 24 | const std::vector floatSteps = { 25 | 1.0f, 26 | 0.1f, 27 | 0.01f, 28 | 0.001f, 29 | 0.0001f, 30 | 0.00001f, 31 | 0.000001f, 32 | }; 33 | 34 | // Random words to go through in the menu 35 | const std::vector strings = { 36 | "Hello", 37 | "World!", 38 | }; 39 | } 40 | 41 | /* 42 | * This function builds the menu's submenus, and the submenus are passed into the CScriptMenu constructor. 43 | * While this provides a cleaner way to define the menu, dynamically created submenu are not possible. 44 | * CScriptMenu would need to be changed to allow adding and removing submenus on-the-fly. 45 | */ 46 | std::vector::CSubmenu> MenuExample::BuildMenu() { 47 | std::vector::CSubmenu> submenus; 48 | submenus.emplace_back("mainmenu", 49 | [](NativeMenu::Menu& mbCtx, CMenuExampleScript& context) { 50 | // Title and Subtitle are required on each submenu. 51 | mbCtx.Title(Constants::ScriptName); 52 | mbCtx.Subtitle(std::string("~b~") + Constants::DisplayVersion); 53 | 54 | // This is a normal option. It'll return true when "select" is presed. 55 | if (mbCtx.Option("Click me!", { "This will log something to " + Paths::GetModuleNameWithoutExtension(Paths::GetOurModuleHandle()) + ".log" })) { 56 | UI::Notify("Check the log file!"); 57 | LOG(INFO, "\"Click me!\" was selected!"); 58 | } 59 | 60 | // This will open a submenu with the name "submenu" 61 | mbCtx.MenuOption("Option demos", "submenu", { "This submenu demonstrates usage of some options." }); 62 | mbCtx.MenuOption("Variable size demo", "varmenu", { "This submenu demonstrates how items can be added or removed dynamically." }); 63 | mbCtx.MenuOption("Title demo", "titlemenu", { "Showcase different title drawing options." }); 64 | mbCtx.MenuOption("Image demo", "imagemenu", { "Showcase OptionPlus image arguments." }); 65 | mbCtx.MenuOption("Script context demo", "scriptcontextmenu", { "Showcase interaction with separate \"game script\" from the menu implementation." }); 66 | 67 | // Showing a non-scrolling aligned item is also possible, if the vector only contains one element. 68 | int nothing = 0; 69 | mbCtx.StringArray("Version", { Constants::DisplayVersion }, nothing, 70 | { "Thanks for checking out this menu!", "Author: ikt" }); 71 | }); 72 | 73 | submenus.emplace_back("submenu", 74 | [](NativeMenu::Menu& mbCtx, CMenuExampleScript& context) { 75 | mbCtx.Title("Option demos"); 76 | mbCtx.Subtitle(""); 77 | 78 | mbCtx.BoolOption("BoolOption", checkBoxStatus, { std::string("Boolean is ") + (checkBoxStatus ? "checked" : "not checked") + "." }); 79 | mbCtx.IntOption("IntOption step size", intStep, 1, 100, 1, { "Change the step size for IntOption below" }); 80 | mbCtx.IntOption("IntOption", someInt, -100, 100, intStep, { "Stepsize: " + std::to_string(intStep) }); 81 | mbCtx.FloatArray("FloatOption step size", floatSteps, stepChoice, { "Change the step size for FloatOption below.", 82 | "Note: this option uses FloatArray." }); 83 | mbCtx.FloatOption("FloatOption", someFloat, -100.0f, 100.0f, floatSteps[stepChoice], { "Try holding left/right, things should speed up." }); 84 | mbCtx.StringArray("StringArray", strings, stringsPos, { "You can also show different strings" }); 85 | 86 | mbCtx.Option("Option/Details", 87 | { "You can put arbitarily long texts in the details. Word wrapping happens automatically.", 88 | "Vector elements are newlines." }); 89 | 90 | // Some extra information can be shown on the right of the the menu. 91 | std::vector extraInfo = { 92 | "OptionPlus", 93 | "This box supports images, in-game sprites and texts. ", 94 | "Longer texts can be used without problems, this box splits the lines " 95 | "by itself. As with the details, a new vector element inserts a newline." 96 | }; 97 | mbCtx.OptionPlus("OptionPlus", extraInfo, nullptr, 98 | []() { 99 | UI::Notify("You pressed RIGHT on an OptionPlus"); 100 | }, 101 | []() { 102 | UI::Notify("You pressed LEFT on an OptionPlus"); 103 | }, 104 | "OptionPlus extras", 105 | { "This box also manages string splitting for width." }); 106 | }); 107 | 108 | submenus.emplace_back("varmenu", 109 | [](NativeMenu::Menu& mbCtx, CMenuExampleScript& context) { 110 | mbCtx.Title("Variable size"); 111 | mbCtx.Subtitle(""); 112 | 113 | mbCtx.IntOption("Options #", numberOfOptions, 1, 999, 1, { "Increase or decrease the amount of items." }); 114 | 115 | for (int i = 0; i < numberOfOptions; i++) { 116 | int display = i + 1; 117 | mbCtx.IntOption("Option number", display, display, display, 0, { "This option was automatically generated." }); 118 | } 119 | }); 120 | 121 | submenus.emplace_back("titlemenu", 122 | [](NativeMenu::Menu& mbCtx, CMenuExampleScript& context) { 123 | mbCtx.Title("Title demo"); 124 | mbCtx.Subtitle(""); 125 | 126 | mbCtx.MenuOption("Los Santos Customs background", "title_lscmenu", { "Internal sprites as background." }); 127 | mbCtx.MenuOption("Custom background", "title_pngmenu", { "External textures as background." }); 128 | mbCtx.MenuOption("Custom background 2", "title_pngmenu2", { "External textures as background. Colored footer." }); 129 | 130 | mbCtx.MenuOption("Long title text", "longtitlemenu", 131 | { "Automatically fit and resize long titles. Works for up to 2 lines of text after processing." }); 132 | }); 133 | 134 | 135 | submenus.emplace_back("title_lscmenu", 136 | [](NativeMenu::Menu& mbCtx, CMenuExampleScript& context) { 137 | mbCtx.Title("", "shopui_title_carmod", "shopui_title_carmod"); 138 | mbCtx.Subtitle("Sprite background"); 139 | mbCtx.Option("Option"); 140 | }); 141 | 142 | submenus.emplace_back("title_pngmenu", 143 | [](NativeMenu::Menu& mbCtx, CMenuExampleScript& context) { 144 | const auto& textures = MenuTexture::GetTextures(); 145 | auto foundTexture = textures.find("custom_background"); 146 | if (foundTexture != textures.end()) { 147 | mbCtx.Title("", foundTexture->second.Handle); 148 | } 149 | else { 150 | mbCtx.Title("custom_background not found"); 151 | } 152 | mbCtx.Subtitle("Custom background"); 153 | mbCtx.Option("Option"); 154 | }); 155 | 156 | submenus.emplace_back("title_pngmenu2", 157 | [](NativeMenu::Menu& mbCtx, CMenuExampleScript& context) { 158 | const auto& textures = MenuTexture::GetTextures(); 159 | auto foundTexture = textures.find("custom_background2"); 160 | if (foundTexture != textures.end()) { 161 | mbCtx.Title("", foundTexture->second.Handle); 162 | } 163 | else { 164 | mbCtx.Title("custom_background2 not found"); 165 | } 166 | mbCtx.Subtitle("Custom background"); 167 | mbCtx.Option("Option"); 168 | mbCtx.Footer({ 173, 236, 173, 255 }); 169 | }); 170 | 171 | submenus.emplace_back("longtitlemenu", 172 | [](NativeMenu::Menu& mbCtx, CMenuExampleScript& context) { 173 | mbCtx.Title("Further Adventures in Finance and Felony"); 174 | mbCtx.Subtitle("Long title text"); 175 | mbCtx.Option("Option"); 176 | }); 177 | 178 | 179 | submenus.emplace_back("imagemenu", 180 | [](NativeMenu::Menu& mbCtx, CMenuExampleScript& context) { 181 | mbCtx.Title("Images"); 182 | mbCtx.Subtitle("Image demo"); 183 | 184 | { 185 | std::vector extras; 186 | // The OptionPlus interprets a specifically formatted string to display game textures/sprites. 187 | // !SPR:{dictionary} {name} W{width}H{height} 188 | // Or, filled in: 189 | // !SPR:dock_default seashark W512H256 190 | // for the seashark in the dock_default txd, with hardcoded size 512x1080. 191 | extras.push_back(std::format("{}{} {} W{}H{}", 192 | mbCtx.SpritePrefix, "dock_default", "seashark", 193 | 512, 256)); 194 | mbCtx.OptionPlus("Game texture", extras, nullptr, nullptr, nullptr, "Sprite", { "OptionPlus box with sprite." }); 195 | } 196 | 197 | for (const auto& [fileName, texture] : MenuTexture::GetTextures()) { 198 | std::vector extras; 199 | // The OptionPlus interprets a specifically formatted string to display images. 200 | // !IMG:{texture_handle}W{width}H{height} 201 | // Or, filled in: 202 | // !IMG:20W1920H1080 203 | // for an image with texture handle 20, size 1920x1080. 204 | extras.push_back(std::format("{}{}W{}H{}", 205 | mbCtx.ImagePrefix, texture.Handle, 206 | texture.Width, texture.Height)); 207 | extras.push_back(texture.Filename); 208 | mbCtx.OptionPlus(texture.Filename, extras, nullptr, nullptr, nullptr, "Image", { "OptionPlus box with custom texture." }); 209 | } 210 | }); 211 | 212 | submenus.emplace_back("scriptcontextmenu", 213 | [](NativeMenu::Menu& mbCtx, CMenuExampleScript& context) { 214 | mbCtx.Title("Script Context"); 215 | mbCtx.Subtitle("ScriptContext demo"); 216 | 217 | // Here we can show stuff that the "core script" updates, 218 | // independently of the menu. 219 | // Notice how the menu doesn't need to include any natives. 220 | 221 | int nothing = 0; 222 | mbCtx.StringArray("Player health", { context.GetPlayerHealth() }, nothing); 223 | 224 | mbCtx.StringArray("Player vehicle", { context.GetPlayerVehicleName() }, nothing); 225 | 226 | mbCtx.StringArray("Distance traveled", { context.GetDistanceTraveled() }, nothing); 227 | 228 | // This option only appears if the player is in a vehicle. 229 | if (context.IsPlayerInVehicle()) { 230 | // This is triggered when pressing "Enter" 231 | if (mbCtx.Option("Randomize player vehicle color")) { 232 | context.ChangePlayerVehicleColor(); 233 | } 234 | } 235 | }); 236 | 237 | return submenus; 238 | } 239 | -------------------------------------------------------------------------------- /GTAVMenuExample/MenuExampleScript.cpp: -------------------------------------------------------------------------------- 1 | #include "MenuExampleScript.hpp" 2 | 3 | #include 4 | #include 5 | 6 | void CMenuExampleScript::Tick() { 7 | // Core script logic 8 | mDistance += ENTITY::GET_ENTITY_SPEED(PLAYER::PLAYER_PED_ID()) * MISC::GET_FRAME_TIME(); 9 | } 10 | 11 | std::string CMenuExampleScript::GetPlayerHealth() { 12 | int health = ENTITY::GET_ENTITY_HEALTH(PLAYER::PLAYER_PED_ID()); 13 | 14 | return std::format("{}", health); 15 | } 16 | 17 | std::string CMenuExampleScript::GetPlayerVehicleName() { 18 | Vehicle playerVehicle = PED::GET_VEHICLE_PED_IS_IN(PLAYER::PLAYER_PED_ID(), false); 19 | if (ENTITY::DOES_ENTITY_EXIST(playerVehicle)) { 20 | Hash model = ENTITY::GET_ENTITY_MODEL(playerVehicle); 21 | std::string makeName = HUD::GET_FILENAME_FOR_AUDIO_CONVERSATION(VEHICLE::GET_MAKE_NAME_FROM_VEHICLE_MODEL(model)); 22 | std::string modelName = HUD::GET_FILENAME_FOR_AUDIO_CONVERSATION(VEHICLE::GET_DISPLAY_NAME_FROM_VEHICLE_MODEL(model)); 23 | return std::format("{} {}", makeName, modelName); 24 | } 25 | else { 26 | return "No vehicle"; 27 | } 28 | } 29 | 30 | std::string CMenuExampleScript::GetDistanceTraveled() { 31 | return std::format("{:.0f} meters", mDistance); 32 | } 33 | 34 | bool CMenuExampleScript::IsPlayerInVehicle() { 35 | Vehicle playerVehicle = PED::GET_VEHICLE_PED_IS_IN(PLAYER::PLAYER_PED_ID(), false); 36 | return ENTITY::DOES_ENTITY_EXIST(playerVehicle); 37 | } 38 | 39 | void CMenuExampleScript::ChangePlayerVehicleColor() { 40 | Vehicle playerVehicle = PED::GET_VEHICLE_PED_IS_IN(PLAYER::PLAYER_PED_ID(), false); 41 | if (ENTITY::DOES_ENTITY_EXIST(playerVehicle)) { 42 | VEHICLE::SET_VEHICLE_COLOUR_COMBINATION(playerVehicle, 43 | MISC::GET_RANDOM_INT_IN_RANGE(0, 44 | VEHICLE::GET_NUMBER_OF_VEHICLE_COLOURS(playerVehicle) 45 | ) 46 | ); 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /GTAVMenuExample/MenuExampleScript.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | 4 | /* 5 | * The class for the "script" that runs. 6 | * This may serve as the core logic of the script. 7 | * For example, doing something with the player or world every tick. 8 | */ 9 | class CMenuExampleScript { 10 | public: 11 | CMenuExampleScript() = default; 12 | ~CMenuExampleScript() = default; 13 | void Tick(); 14 | 15 | std::string GetPlayerHealth(); 16 | std::string GetPlayerVehicleName(); 17 | std::string GetDistanceTraveled(); 18 | 19 | bool IsPlayerInVehicle(); 20 | void ChangePlayerVehicleColor(); 21 | private: 22 | float mDistance{ 0.0f }; 23 | }; 24 | -------------------------------------------------------------------------------- /GTAVMenuExample/MenuTexture.cpp: -------------------------------------------------------------------------------- 1 | #include "MenuTexture.hpp" 2 | #include "ImageDimensions.hpp" 3 | #include "Util/Logger.hpp" 4 | #include "Util/Paths.hpp" 5 | 6 | #include 7 | #include 8 | 9 | namespace fs = std::filesystem; 10 | 11 | namespace { 12 | std::map textures; 13 | } 14 | 15 | const std::map& MenuTexture::GetTextures() { 16 | return textures; 17 | } 18 | 19 | void MenuTexture::UpdateTextures() { 20 | auto imgPath = Paths::GetModPath() / "img"; 21 | LOG(INFO, "Loading images in {}", imgPath.string()); 22 | 23 | for (auto& file : fs::directory_iterator(imgPath)) { 24 | std::string fileName = file.path().string(); 25 | auto stem = file.path().stem().string(); 26 | LOG(INFO, "Loading {}", fileName); 27 | LOG(INFO, " Stem: {}", stem); 28 | 29 | if (textures.find(stem) != textures.end()) { 30 | LOG(INFO, " Skip: Image already registered"); 31 | continue; 32 | } 33 | 34 | auto dims = ImageDimensions::GetIMGDimensions(fileName); 35 | if (!dims) { 36 | LOG(ERROR, " Skip: Failed to get image size"); 37 | continue; 38 | } 39 | 40 | int handle = createTexture(fileName.c_str()); 41 | 42 | auto result = textures.emplace( 43 | stem, 44 | SMenuTexture(fileName, handle, dims->Width, dims->Height)); 45 | 46 | if (result.second) { 47 | LOG(INFO, " Emplaced {} with id [{}]", stem, result.first->second.Handle); 48 | } 49 | else { 50 | LOG(ERROR, " Failed to emplace {}", stem); 51 | } 52 | } 53 | std::vector filesToErase; 54 | for (const auto& [stem, texture] : textures) { 55 | if (!fs::exists(texture.Filename)) { 56 | filesToErase.push_back(stem); 57 | LOG(INFO, "Removing stale file handle {} / {}", stem, texture.Filename); 58 | } 59 | } 60 | for (const auto& file : filesToErase) { 61 | textures.erase(file); 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /GTAVMenuExample/MenuTexture.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | 6 | /* 7 | * To demonstrate the menu image stuff, a struct with 8 | * some image information is made. 9 | * The menu requires the texture handle ScriptHookV generates for the image itself, 10 | * and the width and height to properly set the aspect ratio. 11 | */ 12 | struct SMenuTexture { 13 | SMenuTexture(const std::string& filename, int handle, int width, int height) 14 | : Filename(filename) 15 | , Handle(handle) 16 | , Width(width) 17 | , Height(height) { 18 | } 19 | 20 | std::string Filename; 21 | int Handle = -1; 22 | int Width = 480; 23 | int Height = 270; 24 | }; 25 | 26 | namespace MenuTexture { 27 | const std::map& GetTextures(); 28 | void UpdateTextures(); 29 | } 30 | -------------------------------------------------------------------------------- /GTAVMenuExample/Script.cpp: -------------------------------------------------------------------------------- 1 | #include "Script.hpp" 2 | #include "MenuTexture.hpp" 3 | #include "ScriptMenu.hpp" 4 | #include "Util/Logger.hpp" 5 | #include "Util/Paths.hpp" 6 | #include "Util/UI.hpp" 7 | 8 | #include 9 | 10 | namespace { 11 | std::shared_ptr coreScript; 12 | std::unique_ptr> scriptMenu; 13 | 14 | bool initialized = false; 15 | } 16 | 17 | // These functions are only called in Script.cpp so don't need to be exposed. 18 | namespace MenuExample { 19 | void scriptInit(); 20 | void scriptTick(); 21 | } 22 | 23 | // ScriptHookV calls ScriptMain when loading a save, 24 | // so it can happen multiple times in a game session. 25 | void MenuExample::ScriptMain() { 26 | // This check exists to prevent global objects from being 27 | // initialized multiple times. 28 | if (!initialized) { 29 | LOG(INFO, "Script started"); 30 | scriptInit(); 31 | initialized = true; 32 | } 33 | else { 34 | LOG(INFO, "Script restarted"); 35 | } 36 | 37 | scriptTick(); 38 | } 39 | 40 | void MenuExample::scriptInit() { 41 | const auto settingsMenuPath = Paths::GetModPath() / "settings_menu.ini"; 42 | 43 | coreScript = std::make_shared(); 44 | 45 | // The menu being initialized. Note the passed settings, 46 | // the onInit and onExit lambdas and finally BuildMenu being called. 47 | scriptMenu = std::make_unique>(settingsMenuPath.string(), 48 | []() { 49 | LOG(INFO, "Menu opened"); 50 | // When the menu is opened, functions can be called. 51 | // In this case, the images in the example folder are refreshed. 52 | MenuTexture::UpdateTextures(); 53 | }, 54 | []() { 55 | LOG(INFO, "Menu closed"); 56 | // When the menu is closed, functions can be called. 57 | // In this case, a notification is shown. 58 | UI::Notify("Menu was closed"); 59 | }, 60 | // The menu is built and submenus are passed into the CScriptMenu object. 61 | // See MenuExampleMenu.cpp for the actual implementation. 62 | BuildMenu() 63 | ); 64 | } 65 | 66 | // This function starts the infinite loop that updates the script instance and menu, every game tick. 67 | // It keeps running forever, until ScriptHookV restarts or stops the script. 68 | void MenuExample::scriptTick() { 69 | while (true) { 70 | coreScript->Tick(); 71 | scriptMenu->Tick(*coreScript); 72 | WAIT(0); 73 | } 74 | } 75 | -------------------------------------------------------------------------------- /GTAVMenuExample/Script.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "MenuExampleScript.hpp" 3 | #include "ScriptMenu.hpp" 4 | 5 | /* 6 | * Script.hpp exposes functions to initialize and manage the script. 7 | */ 8 | namespace MenuExample { 9 | // ScriptHookV calls this when starting the script. 10 | void ScriptMain(); 11 | 12 | /* 13 | * BuildMenu builds the menu with its options and submenus. 14 | * This function is declared here, so Script.cpp can call it 15 | * The implementation is in MenuExampleMenu.cpp 16 | */ 17 | std::vector::CSubmenu> BuildMenu(); 18 | } 19 | -------------------------------------------------------------------------------- /GTAVMenuExample/ScriptMenu.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | 6 | /* 7 | * This class calls boilerplate functions of the menu. 8 | * The main script only needs to call Tick() to fully update the menu. 9 | * This way the menu can be used in a more OOP way than the original 10 | * design (or lack thereof) initially allowed. 11 | */ 12 | template 13 | class CScriptMenu 14 | { 15 | public: 16 | /* 17 | * The Submenu class represents an actual "menu": e.g. the main menu is also a "sub"-menu. 18 | * Within a Submenu body, the NativeMenu object functions (Title, Subtitle, Option, etc) 19 | * can be called from the "mbCtx" (menubase context). 20 | * Using the scriptContext, public methods of the script can be called - to retrieve the 21 | * player ped, or whatever else is needed for the menu to interact with it. 22 | */ 23 | class CSubmenu { 24 | public: 25 | // Submenu added by name, useful for most purposes (as submenu). 26 | CSubmenu(std::string name, 27 | std::function menuBody) 28 | : mName(std::move(name)) 29 | , mBody(std::move(menuBody)) 30 | , mPred(nullptr) { 31 | } 32 | 33 | // Submenu added by predicate, useful for interaction-ish activation, 34 | // e.g. game context: When near a car, set predicate to true. 35 | CSubmenu(std::function predicate, 36 | std::function menuBody) 37 | : mName() // unused 38 | , mBody(std::move(menuBody)) 39 | , mPred(std::move(predicate)) { 40 | } 41 | 42 | // Called by CSubmenu for all submenus 43 | void Update(NativeMenu::Menu& mbCtx, T& scriptContext) { 44 | if (mPred && mPred(mbCtx)) { 45 | mBody(mbCtx, scriptContext); 46 | return; 47 | } 48 | 49 | if (mbCtx.CurrentMenu(mName)) 50 | mBody(mbCtx, scriptContext); 51 | } 52 | private: 53 | std::string mName; 54 | std::function mBody; 55 | std::function mPred; 56 | }; 57 | 58 | // The actual menu. Has its own settings and 59 | // can call stuff when opened or closed. 60 | CScriptMenu(std::string settingsFile, 61 | std::function onInit, 62 | std::function onExit, 63 | std::vector submenus) 64 | : mSettingsFile(std::move(settingsFile)) 65 | , mSubmenus(std::move(submenus)) { 66 | mMenuBase.RegisterOnMain([this, onInit]() { 67 | mMenuBase.ReadSettings(); 68 | onInit(); 69 | }); 70 | mMenuBase.RegisterOnExit(std::move(onExit)); 71 | mMenuBase.SetFiles(mSettingsFile); 72 | mMenuBase.Initialize(); 73 | mMenuBase.ReadSettings(); 74 | } 75 | 76 | // Call Tick() for the menu instance every game tick. 77 | void Tick(T& scriptContext) { 78 | mMenuBase.CheckKeys(); 79 | 80 | for (auto& submenu : mSubmenus) { 81 | submenu.Update(mMenuBase, scriptContext); 82 | } 83 | 84 | mMenuBase.EndMenu(); 85 | } 86 | 87 | private: 88 | std::string mSettingsFile; 89 | NativeMenu::Menu mMenuBase; 90 | std::vector mSubmenus; 91 | }; 92 | -------------------------------------------------------------------------------- /GTAVMenuExample/Util/Logger.cpp: -------------------------------------------------------------------------------- 1 | #include "Logger.hpp" 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | Logger g_Logger; 9 | 10 | namespace { 11 | constexpr const char* const levelStrings[] = { 12 | " DEBUG ", 13 | " INFO ", 14 | "WARNING", 15 | " ERROR ", 16 | " FATAL " 17 | }; 18 | } 19 | 20 | Logger::Logger() = default; 21 | 22 | void Logger::SetFile(const std::string& fileName) { 23 | file = fileName; 24 | } 25 | 26 | void Logger::SetMinLevel(LogLevel level) { 27 | minLevel = level; 28 | } 29 | 30 | void Logger::Clear() const { 31 | std::ofstream logFile(file, std::ofstream::out | std::ofstream::trunc); 32 | logFile.close(); 33 | if (logFile.fail()) 34 | mError = true; 35 | } 36 | 37 | bool Logger::Error() { 38 | return mError; 39 | } 40 | 41 | void Logger::ClearError() { 42 | mError = false; 43 | } 44 | 45 | void Logger::write(LogLevel level, const std::string& txt) const { 46 | #ifndef _DEBUG 47 | if (level < minLevel) return; 48 | #endif 49 | std::ofstream logFile(file, std::ios_base::out | std::ios_base::app); 50 | 51 | const auto now = std::chrono::system_clock::now().time_since_epoch(); 52 | logFile << std::format("[{:%H:%M:%S}] [{}] {}\n", 53 | std::chrono::duration_cast(now), 54 | levelText(level), 55 | txt); 56 | 57 | logFile.close(); 58 | if (logFile.fail()) 59 | mError = true; 60 | } 61 | 62 | std::string Logger::levelText(LogLevel level) const { 63 | if (level > 4 || level < 0) { 64 | return " UNK "; 65 | } 66 | 67 | return levelStrings[level]; 68 | } 69 | -------------------------------------------------------------------------------- /GTAVMenuExample/Util/Logger.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | #include 4 | 5 | #define LOG(level, fmt, ...) \ 6 | g_Logger.Write(level, fmt, __VA_ARGS__) 7 | 8 | enum LogLevel { 9 | DEBUG, 10 | INFO, 11 | WARN, 12 | ERROR, 13 | FATAL, 14 | }; 15 | 16 | class Logger { 17 | 18 | public: 19 | Logger(); 20 | void SetFile(const std::string& fileName); 21 | void SetMinLevel(LogLevel level); 22 | void Clear() const; 23 | bool Error(); 24 | void ClearError(); 25 | 26 | template 27 | void Write(LogLevel level, std::string_view fmt, Args&&... args) const { 28 | try { 29 | write(level, std::vformat(fmt, std::make_format_args(args...))); 30 | } 31 | catch (const std::exception& ex) { 32 | write(ERROR, std::format("Failed to format: [{}], {}", fmt, ex.what())); 33 | } 34 | } 35 | 36 | private: 37 | std::string levelText(LogLevel level) const; 38 | void write(LogLevel, const std::string& txt) const; 39 | 40 | mutable bool mError = false; 41 | std::string file = ""; 42 | LogLevel minLevel = INFO; 43 | }; 44 | 45 | extern Logger g_Logger; 46 | -------------------------------------------------------------------------------- /GTAVMenuExample/Util/Paths.cpp: -------------------------------------------------------------------------------- 1 | #include "Paths.hpp" 2 | 3 | #include 4 | 5 | namespace { 6 | HMODULE ourModule; 7 | std::filesystem::path modPath; 8 | std::filesystem::path initialModPath; 9 | bool modPathChangedThisRun = false; 10 | } 11 | 12 | std::filesystem::path Paths::GetLocalAppDataPath() { 13 | std::filesystem::path fsPath; 14 | PWSTR path = NULL; 15 | HRESULT result = SHGetKnownFolderPath(FOLDERID_LocalAppData, 0, NULL, &path); 16 | 17 | if (path != NULL) { 18 | fsPath = std::filesystem::path(path); 19 | } 20 | 21 | CoTaskMemFree(path); 22 | 23 | return fsPath; 24 | } 25 | 26 | void Paths::SetModPath(std::filesystem::path path) { 27 | if (initialModPath.empty()) { 28 | initialModPath = path; 29 | } 30 | modPath = path; 31 | } 32 | 33 | std::filesystem::path Paths::GetModPath() { 34 | return modPath; 35 | } 36 | 37 | std::filesystem::path Paths::GetInitialModPath() { 38 | return initialModPath; 39 | } 40 | 41 | void Paths::SetModPathChanged() { 42 | modPathChangedThisRun = true; 43 | } 44 | 45 | bool Paths::GetModPathChanged() { 46 | return modPathChangedThisRun; 47 | } 48 | 49 | std::filesystem::path Paths::GetRunningExecutablePath() { 50 | char fileName[MAX_PATH]; 51 | GetModuleFileNameA(nullptr, fileName, MAX_PATH); 52 | return fileName; 53 | } 54 | 55 | std::filesystem::path Paths::GetModuleFolder(const HMODULE module) { 56 | char fileName[MAX_PATH]; 57 | GetModuleFileNameA(module, fileName, MAX_PATH); 58 | 59 | std::string currentPath = fileName; 60 | return currentPath.substr(0, currentPath.find_last_of("\\")); 61 | } 62 | 63 | std::string Paths::GetModuleName(const HMODULE module) { 64 | char fileName[MAX_PATH]; 65 | GetModuleFileNameA(module, fileName, MAX_PATH); 66 | 67 | std::string fullPath = fileName; 68 | 69 | size_t lastIndex = fullPath.find_last_of("\\") + 1; 70 | return fullPath.substr(lastIndex, fullPath.length() - lastIndex); 71 | } 72 | 73 | std::string Paths::GetModuleNameWithoutExtension(const HMODULE module) { 74 | const std::string fileNameWithExtension = GetModuleName(module); 75 | 76 | size_t lastIndex = fileNameWithExtension.find_last_of("."); 77 | if (lastIndex == -1) { 78 | return fileNameWithExtension; 79 | } 80 | 81 | return fileNameWithExtension.substr(0, lastIndex); 82 | } 83 | 84 | 85 | void Paths::SetOurModuleHandle(const HMODULE module) { 86 | ourModule = module; 87 | } 88 | 89 | HMODULE Paths::GetOurModuleHandle() { 90 | return ourModule; 91 | } 92 | 93 | std::wstring Paths::GetDocumentsFolder() { 94 | PWSTR path; 95 | SHGetKnownFolderPath(FOLDERID_Documents, KF_FLAG_DEFAULT, NULL, &path); 96 | std::wstring strPath(path); 97 | CoTaskMemFree(path); 98 | 99 | return strPath; 100 | } 101 | -------------------------------------------------------------------------------- /GTAVMenuExample/Util/Paths.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | #include 4 | #include 5 | 6 | namespace Paths { 7 | std::filesystem::path GetLocalAppDataPath(); 8 | 9 | void SetModPath(std::filesystem::path path); 10 | std::filesystem::path GetModPath(); 11 | std::filesystem::path GetInitialModPath(); 12 | 13 | void SetModPathChanged(); 14 | bool GetModPathChanged(); 15 | 16 | std::filesystem::path GetRunningExecutablePath(); 17 | 18 | std::filesystem::path GetModuleFolder(HMODULE module); 19 | std::string GetModuleName(HMODULE module); 20 | std::string GetModuleNameWithoutExtension(HMODULE module); 21 | 22 | void SetOurModuleHandle(HMODULE module); 23 | HMODULE GetOurModuleHandle(); 24 | 25 | std::wstring GetDocumentsFolder(); 26 | } 27 | -------------------------------------------------------------------------------- /GTAVMenuExample/Util/UI.cpp: -------------------------------------------------------------------------------- 1 | #include "UI.hpp" 2 | 3 | #include 4 | 5 | namespace { 6 | int notificationHandle = 0; 7 | } 8 | 9 | void UI::Notify(const std::string& message) { 10 | Notify(message, true); 11 | } 12 | 13 | void UI::Notify(const std::string& message, bool removePrevious) { 14 | int* prevNotification = nullptr; 15 | if (removePrevious) { 16 | prevNotification = ¬ificationHandle; 17 | } 18 | 19 | if (prevNotification != nullptr && *prevNotification != 0) { 20 | HUD::THEFEED_REMOVE_ITEM(*prevNotification); 21 | } 22 | HUD::BEGIN_TEXT_COMMAND_THEFEED_POST("STRING"); 23 | 24 | HUD::ADD_TEXT_COMPONENT_SUBSTRING_PLAYER_NAME(message.c_str()); 25 | 26 | int id = HUD::END_TEXT_COMMAND_THEFEED_POST_TICKER(false, false); 27 | if (prevNotification != nullptr) { 28 | *prevNotification = id; 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /GTAVMenuExample/Util/UI.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | #include 4 | #include 5 | 6 | namespace UI { 7 | void Notify(const std::string& message); 8 | void Notify(const std::string& message, bool removePrevious); 9 | } 10 | 11 | -------------------------------------------------------------------------------- /GTAV_dir/GTAVMenuExample/img/86coupe.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ikt32/GTAVMenuExample/d1ef6a8cf393144c3805717ad3b3c7e9c92215de/GTAV_dir/GTAVMenuExample/img/86coupe.jpg -------------------------------------------------------------------------------- /GTAV_dir/GTAVMenuExample/img/ae86.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ikt32/GTAVMenuExample/d1ef6a8cf393144c3805717ad3b3c7e9c92215de/GTAV_dir/GTAVMenuExample/img/ae86.png -------------------------------------------------------------------------------- /GTAV_dir/GTAVMenuExample/img/blista.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ikt32/GTAVMenuExample/d1ef6a8cf393144c3805717ad3b3c7e9c92215de/GTAV_dir/GTAVMenuExample/img/blista.png -------------------------------------------------------------------------------- /GTAV_dir/GTAVMenuExample/img/custom_background.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ikt32/GTAVMenuExample/d1ef6a8cf393144c3805717ad3b3c7e9c92215de/GTAV_dir/GTAVMenuExample/img/custom_background.png -------------------------------------------------------------------------------- /GTAV_dir/GTAVMenuExample/img/custom_background2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ikt32/GTAVMenuExample/d1ef6a8cf393144c3805717ad3b3c7e9c92215de/GTAV_dir/GTAVMenuExample/img/custom_background2.png -------------------------------------------------------------------------------- /GTAV_dir/GTAVMenuExample/img/cw2020.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ikt32/GTAVMenuExample/d1ef6a8cf393144c3805717ad3b3c7e9c92215de/GTAV_dir/GTAVMenuExample/img/cw2020.jpg -------------------------------------------------------------------------------- /GTAV_dir/GTAVMenuExample/img/nisgtrr32.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ikt32/GTAVMenuExample/d1ef6a8cf393144c3805717ad3b3c7e9c92215de/GTAV_dir/GTAVMenuExample/img/nisgtrr32.png -------------------------------------------------------------------------------- /GTAV_dir/GTAVMenuExample/settings_menu.ini: -------------------------------------------------------------------------------- 1 | [MENU] 2 | MenuKey = F6 3 | MenuUp = UP 4 | MenuDown = DOWN 5 | MenuLeft = LEFT 6 | MenuRight = RIGHT 7 | MenuSelect = RETURN 8 | MenuCancel = BACKSPACE 9 | MenuX = 0.000000 10 | MenuY = 0.000000 11 | ControllerButton1 = -1 12 | ControllerButton2 = -1 13 | CheatString = menuexample 14 | 15 | [Title Text] 16 | Red =255 17 | Green =255 18 | Blue =255 19 | Alpha =255 20 | Font =1 21 | 22 | [Title Rect] 23 | Red =255 24 | Green =255 25 | Blue =255 26 | Alpha =255 27 | 28 | [Scroller] 29 | Red = 255 30 | Green = 255 31 | Blue = 255 32 | Alpha =255 33 | 34 | [Options Text] 35 | Red =255 36 | Green =255 37 | Blue =255 38 | Alpha =255 39 | Font =0 40 | 41 | [Options Rect] 42 | Red = 0 43 | Green = 0 44 | Blue = 0 45 | Alpha = 255 46 | 47 | [Navigation] 48 | Smooth Scrolling = true 49 | Smooth Factor = 0.00001 50 | -------------------------------------------------------------------------------- /GTAV_dir/README.md: -------------------------------------------------------------------------------- 1 | Instructions 2 | ------------ 3 | 4 | The GTAVMenuExample/ folder and the compiled GTAVMenuExample.asi go in the 5 | root GTA V folder. A GTAVMenuExample.log is generated on load and some 6 | actions. 7 | 8 | In the img/ folder, images can be placed which are picked up by the 9 | `"imagemenu"` submenu. Currently jpg and png images are supported. 10 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2022 ikt 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /MenuCompare.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ikt32/GTAVMenuExample/d1ef6a8cf393144c3805717ad3b3c7e9c92215de/MenuCompare.png -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # GTAVMenuExample 2 | 3 | [![Build status](https://github.com/E66666666/GTAVMenuExample/actions/workflows/msbuild.yml/badge.svg)](https://github.com/E66666666/GTAVMenuExample/actions) 4 | 5 | Example script of how to use [GTAVMenuBase](https://github.com/E66666666/GTAVMenuBase). 6 | 7 | ![Comparison](MenuCompare.png) 8 | 9 | ## Building 10 | 11 | * [ScriptHookV SDK by Alexander Blade](http://www.dev-c.com/gtav/scripthookv/) 12 | * [GTAVMenuBase](https://github.com/E66666666/GTAVMenuBase) 13 | * [simpleini](https://github.com/brofield/simpleini) 14 | 15 | GTAVMenuBase and simpleini are added as submodule in the `thirdparty` directory. 16 | Note that GTAVMenuBase depends on simpleini (but doesn't do anything to get it, so your project has to) 17 | and expects the directory containing the `simpleini/` directory to be in the include directories, 18 | such that `#include ` works. 19 | 20 | Similarly, it expects the `ScriptHookV_SDK/` directory to be in the include directories, 21 | such that `#include ` works. 22 | 23 | The ScriptHookV SDK is in the project repository itself, in `thirdparty/ScriptHookV_SDK`. 24 | The `natives.h` files is generated by [Dot.'s Native DB](https://nativedb.dotindustries.dev/natives), 25 | and is newer than the one included by Alexander Blades' SDK with corrected namespaces. 26 | 27 | Once cloned, the project should just build with 28 | 29 | * Visual Studio 2022 (17.2 or newer) 30 | * Visual Studio 2019 (16.11.14 or newer) (v142 build tools, /std:c++20) 31 | 32 | ## Usage 33 | 34 | v2.0.0 of the example is completely rewritten to how my newer scripts use it. A few general concepts: 35 | 36 | * Generally, things should be more neatly divided and less of a complete mess. 37 | * `CScriptMenu` wraps the `NativeMenu::Menu` and calls boilerplate menu code to initialize and check controls. 38 | * `CScriptMenu::CSubmenu` represents a single "menu page". 39 | * There is a "script instance" object that can be passed for the menu page to use. 40 | 41 | I recommend the following order to get a general grasp of how this example works: 42 | 43 | 1. `DllMain.cpp` - Dll entrypoint and some setup stuff 44 | 2. `Script.cpp/hpp` - Script initialization 45 | 3. `MenuExampleScript.cpp/hpp` - The 'core' logic of the 'script' part which interacts with the game world. 46 | 4. `MenuExampleMenu.cpp` - The menu implementation. 47 | 48 | Plenty of comments have been left in the source code files to figure out what the heck everything actually does. 49 | 50 | Feel free to use this as a base project, it lends itself pretty well for most purposes and can be easily 51 | extended for multiple instances (for NPCs, etc.). 52 | 53 | \- ikt 54 | -------------------------------------------------------------------------------- /thirdparty/ScriptHookV_SDK/inc/enums.h: -------------------------------------------------------------------------------- 1 | /* 2 | THIS FILE IS A PART OF GTA V SCRIPT HOOK SDK 3 | http://dev-c.com 4 | (C) Alexander Blade 2015-2016 5 | */ 6 | 7 | #pragma once 8 | 9 | #include 10 | 11 | enum eAudioFlag 12 | { 13 | AudioFlagActivateSwitchWheelAudio, 14 | AudioFlagAllowCutsceneOverScreenFade, 15 | AudioFlagAllowForceRadioAfterRetune, 16 | AudioFlagAllowPainAndAmbientSpeechToPlayDuringCutscene, 17 | AudioFlagAllowPlayerAIOnMission, 18 | AudioFlagAllowPoliceScannerWhenPlayerHasNoControl, 19 | AudioFlagAllowRadioDuringSwitch, 20 | AudioFlagAllowRadioOverScreenFade, 21 | AudioFlagAllowScoreAndRadio, 22 | AudioFlagAllowScriptedSpeechInSlowMo, 23 | AudioFlagAvoidMissionCompleteDelay, 24 | AudioFlagDisableAbortConversationForDeathAndInjury, 25 | AudioFlagDisableAbortConversationForRagdoll, 26 | AudioFlagDisableBarks, 27 | AudioFlagDisableFlightMusic, 28 | AudioFlagDisableReplayScriptStreamRecording, 29 | AudioFlagEnableHeadsetBeep, 30 | AudioFlagForceConversationInterrupt, 31 | AudioFlagForceSeamlessRadioSwitch, 32 | AudioFlagForceSniperAudio, 33 | AudioFlagFrontendRadioDisabled, 34 | AudioFlagHoldMissionCompleteWhenPrepared, 35 | AudioFlagIsDirectorModeActive, 36 | AudioFlagIsPlayerOnMissionForSpeech, 37 | AudioFlagListenerReverbDisabled, 38 | AudioFlagLoadMPData, 39 | AudioFlagMobileRadioInGame, 40 | AudioFlagOnlyAllowScriptTriggerPoliceScanner, 41 | AudioFlagPlayMenuMusic, 42 | AudioFlagPoliceScannerDisabled, 43 | AudioFlagScriptedConvListenerMaySpeak, 44 | AudioFlagSpeechDucksScore, 45 | AudioFlagSuppressPlayerScubaBreathing, 46 | AudioFlagWantedMusicDisabled, 47 | AudioFlagWantedMusicOnMission 48 | }; 49 | 50 | enum eBlipColor 51 | { 52 | BlipColorWhite = 0, 53 | BlipColorRed = 1, 54 | BlipColorGreen = 2, 55 | BlipColorBlue = 3, 56 | BlipColorYellow = 66, 57 | }; 58 | 59 | enum eBlipSprite 60 | { 61 | BlipSpriteStandard = 1, 62 | BlipSpriteBigBlip = 2, 63 | BlipSpritePoliceOfficer = 3, 64 | BlipSpritePoliceArea = 4, 65 | BlipSpriteSquare = 5, 66 | BlipSpritePlayer = 6, 67 | BlipSpriteNorth = 7, 68 | BlipSpriteWaypoint = 8, 69 | BlipSpriteBigCircle = 9, 70 | BlipSpriteBigCircleOutline = 10, 71 | BlipSpriteArrowUpOutlined = 11, 72 | BlipSpriteArrowDownOutlined = 12, 73 | BlipSpriteArrowUp = 13, 74 | BlipSpriteArrowDown = 14, 75 | BlipSpritePoliceHelicopterAnimated = 15, 76 | BlipSpriteJet = 16, 77 | BlipSpriteNumber1 = 17, 78 | BlipSpriteNumber2 = 18, 79 | BlipSpriteNumber3 = 19, 80 | BlipSpriteNumber4 = 20, 81 | BlipSpriteNumber5 = 21, 82 | BlipSpriteNumber6 = 22, 83 | BlipSpriteNumber7 = 23, 84 | BlipSpriteNumber8 = 24, 85 | BlipSpriteNumber9 = 25, 86 | BlipSpriteNumber10 = 26, 87 | BlipSpriteGTAOCrew = 27, 88 | BlipSpriteGTAOFriendly = 28, 89 | BlipSpriteLift = 36, 90 | BlipSpriteRaceFinish = 38, 91 | BlipSpriteSafehouse = 40, 92 | BlipSpritePoliceOfficer2 = 41, 93 | BlipSpritePoliceCarDot = 42, 94 | BlipSpritePoliceHelicopter = 43, 95 | BlipSpriteChatBubble = 47, 96 | BlipSpriteGarage2 = 50, 97 | BlipSpriteDrugs = 51, 98 | BlipSpriteStore = 52, 99 | BlipSpritePoliceCar = 56, 100 | BlipSpritePolicePlayer = 58, 101 | BlipSpritePoliceStation = 60, 102 | BlipSpriteHospital = 61, 103 | BlipSpriteHelicopter = 64, 104 | BlipSpriteStrangersAndFreaks = 65, 105 | BlipSpriteArmoredTruck = 66, 106 | BlipSpriteTowTruck = 68, 107 | BlipSpriteBarber = 71, 108 | BlipSpriteLosSantosCustoms = 72, 109 | BlipSpriteClothes = 73, 110 | BlipSpriteTattooParlor = 75, 111 | BlipSpriteSimeon = 76, 112 | BlipSpriteLester = 77, 113 | BlipSpriteMichael = 78, 114 | BlipSpriteTrevor = 79, 115 | BlipSpriteRampage = 84, 116 | BlipSpriteVinewoodTours = 85, 117 | BlipSpriteLamar = 86, 118 | BlipSpriteFranklin = 88, 119 | BlipSpriteChinese = 89, 120 | BlipSpriteAirport = 90, 121 | BlipSpriteBar = 93, 122 | BlipSpriteBaseJump = 94, 123 | BlipSpriteCarWash = 100, 124 | BlipSpriteComedyClub = 102, 125 | BlipSpriteDart = 103, 126 | BlipSpriteFIB = 106, 127 | BlipSpriteDollarSign = 108, 128 | BlipSpriteGolf = 109, 129 | BlipSpriteAmmuNation = 110, 130 | BlipSpriteExile = 112, 131 | BlipSpriteShootingRange = 119, 132 | BlipSpriteSolomon = 120, 133 | BlipSpriteStripClub = 121, 134 | BlipSpriteTennis = 122, 135 | BlipSpriteTriathlon = 126, 136 | BlipSpriteOffRoadRaceFinish = 127, 137 | BlipSpriteKey = 134, 138 | BlipSpriteMovieTheater = 135, 139 | BlipSpriteMusic = 136, 140 | BlipSpriteMarijuana = 140, 141 | BlipSpriteHunting = 141, 142 | BlipSpriteArmsTraffickingGround = 147, 143 | BlipSpriteNigel = 149, 144 | BlipSpriteAssaultRifle = 150, 145 | BlipSpriteBat = 151, 146 | BlipSpriteGrenade = 152, 147 | BlipSpriteHealth = 153, 148 | BlipSpriteKnife = 154, 149 | BlipSpriteMolotov = 155, 150 | BlipSpritePistol = 156, 151 | BlipSpriteRPG = 157, 152 | BlipSpriteShotgun = 158, 153 | BlipSpriteSMG = 159, 154 | BlipSpriteSniper = 160, 155 | BlipSpriteSonicWave = 161, 156 | BlipSpritePointOfInterest = 162, 157 | BlipSpriteGTAOPassive = 163, 158 | BlipSpriteGTAOUsingMenu = 164, 159 | BlipSpriteLink = 171, 160 | BlipSpriteMinigun = 173, 161 | BlipSpriteGrenadeLauncher = 174, 162 | BlipSpriteArmor = 175, 163 | BlipSpriteCastle = 176, 164 | BlipSpriteCamera = 184, 165 | BlipSpriteHandcuffs = 188, 166 | BlipSpriteYoga = 197, 167 | BlipSpriteCab = 198, 168 | BlipSpriteNumber11 = 199, 169 | BlipSpriteNumber12 = 200, 170 | BlipSpriteNumber13 = 201, 171 | BlipSpriteNumber14 = 202, 172 | BlipSpriteNumber15 = 203, 173 | BlipSpriteNumber16 = 204, 174 | BlipSpriteShrink = 205, 175 | BlipSpriteEpsilon = 206, 176 | BlipSpritePersonalVehicleCar = 225, 177 | BlipSpritePersonalVehicleBike = 226, 178 | BlipSpriteCustody = 237, 179 | BlipSpriteArmsTraffickingAir = 251, 180 | BlipSpriteFairground = 266, 181 | BlipSpritePropertyManagement = 267, 182 | BlipSpriteAltruist = 269, 183 | BlipSpriteEnemy = 270, 184 | BlipSpriteChop = 273, 185 | BlipSpriteDead = 274, 186 | BlipSpriteHooker = 279, 187 | BlipSpriteFriend = 280, 188 | BlipSpriteBountyHit = 303, 189 | BlipSpriteGTAOMission = 304, 190 | BlipSpriteGTAOSurvival = 305, 191 | BlipSpriteCrateDrop = 306, 192 | BlipSpritePlaneDrop = 307, 193 | BlipSpriteSub = 308, 194 | BlipSpriteRace = 309, 195 | BlipSpriteDeathmatch = 310, 196 | BlipSpriteArmWrestling = 311, 197 | BlipSpriteAmmuNationShootingRange = 313, 198 | BlipSpriteRaceAir = 314, 199 | BlipSpriteRaceCar = 315, 200 | BlipSpriteRaceSea = 316, 201 | BlipSpriteGarbageTruck = 318, 202 | BlipSpriteSafehouseForSale = 350, 203 | BlipSpritePackage = 351, 204 | BlipSpriteMartinMadrazo = 352, 205 | BlipSpriteEnemyHelicopter = 353, 206 | BlipSpriteBoost = 354, 207 | BlipSpriteDevin = 355, 208 | BlipSpriteMarina = 356, 209 | BlipSpriteGarage = 357, 210 | BlipSpriteGolfFlag = 358, 211 | BlipSpriteHangar = 359, 212 | BlipSpriteHelipad = 360, 213 | BlipSpriteJerryCan = 361, 214 | BlipSpriteMasks = 362, 215 | BlipSpriteHeistSetup = 363, 216 | BlipSpriteIncapacitated = 364, 217 | BlipSpritePickupSpawn = 365, 218 | BlipSpriteBoilerSuit = 366, 219 | BlipSpriteCompleted = 367, 220 | BlipSpriteRockets = 368, 221 | BlipSpriteGarageForSale = 369, 222 | BlipSpriteHelipadForSale = 370, 223 | BlipSpriteMarinaForSale = 371, 224 | BlipSpriteHangarForSale = 372, 225 | BlipSpriteBusiness = 374, 226 | BlipSpriteBusinessForSale = 375, 227 | BlipSpriteRaceBike = 376, 228 | BlipSpriteParachute = 377, 229 | BlipSpriteTeamDeathmatch = 378, 230 | BlipSpriteRaceFoot = 379, 231 | BlipSpriteVehicleDeathmatch = 380, 232 | BlipSpriteBarry = 381, 233 | BlipSpriteDom = 382, 234 | BlipSpriteMaryAnn = 383, 235 | BlipSpriteCletus = 384, 236 | BlipSpriteJosh = 385, 237 | BlipSpriteMinute = 386, 238 | BlipSpriteOmega = 387, 239 | BlipSpriteTonya = 388, 240 | BlipSpritePaparazzo = 389, 241 | BlipSpriteCrosshair = 390, 242 | BlipSpriteCreator = 398, 243 | BlipSpriteCreatorDirection = 399, 244 | BlipSpriteAbigail = 400, 245 | BlipSpriteBlimp = 401, 246 | BlipSpriteRepair = 402, 247 | BlipSpriteTestosterone = 403, 248 | BlipSpriteDinghy = 404, 249 | BlipSpriteFanatic = 405, 250 | BlipSpriteInformation = 407, 251 | BlipSpriteCaptureBriefcase = 408, 252 | BlipSpriteLastTeamStanding = 409, 253 | BlipSpriteBoat = 410, 254 | BlipSpriteCaptureHouse = 411, 255 | BlipSpriteJerryCan2 = 415, 256 | BlipSpriteRP = 416, 257 | BlipSpriteGTAOPlayerSafehouse = 417, 258 | BlipSpriteGTAOPlayerSafehouseDead = 418, 259 | BlipSpriteCaptureAmericanFlag = 419, 260 | BlipSpriteCaptureFlag = 420, 261 | BlipSpriteTank = 421, 262 | BlipSpriteHelicopterAnimated = 422, 263 | BlipSpritePlane = 423, 264 | BlipSpritePlayerNoColor = 425, 265 | BlipSpriteGunCar = 426, 266 | BlipSpriteSpeedboat = 427, 267 | BlipSpriteHeist = 428, 268 | BlipSpriteStopwatch = 430, 269 | BlipSpriteDollarSignCircled = 431, 270 | BlipSpriteCrosshair2 = 432, 271 | BlipSpriteDollarSignSquared = 434, 272 | }; 273 | 274 | enum eCameraShake 275 | { 276 | CameraShakeHand = 0, 277 | CameraShakeSmallExplosion, 278 | CameraShakeMediumExplosion, 279 | CameraShakeLargeExplosion, 280 | CameraShakeJolt, 281 | CameraShakeVibrate, 282 | CameraShakeRoadVibration, 283 | CameraShakeDrunk, 284 | CameraShakeSkyDiving, 285 | CameraShakeFamilyDrugTrip, 286 | CameraShakeDeathFail 287 | }; 288 | 289 | enum eControl 290 | { 291 | ControlNextCamera = 0, 292 | ControlLookLeftRight = 1, 293 | ControlLookUpDown = 2, 294 | ControlLookUpOnly = 3, 295 | ControlLookDownOnly = 4, 296 | ControlLookLeftOnly = 5, 297 | ControlLookRightOnly = 6, 298 | ControlCinematicSlowMo = 7, 299 | ControlFlyUpDown = 8, 300 | ControlFlyLeftRight = 9, 301 | ControlScriptedFlyZUp = 10, 302 | ControlScriptedFlyZDown = 11, 303 | ControlWeaponWheelUpDown = 12, 304 | ControlWeaponWheelLeftRight = 13, 305 | ControlWeaponWheelNext = 14, 306 | ControlWeaponWheelPrev = 15, 307 | ControlSelectNextWeapon = 16, 308 | ControlSelectPrevWeapon = 17, 309 | ControlSkipCutscene = 18, 310 | ControlCharacterWheel = 19, 311 | ControlMultiplayerInfo = 20, 312 | ControlSprint = 21, 313 | ControlJump = 22, 314 | ControlEnter = 23, 315 | ControlAttack = 24, 316 | ControlAim = 25, 317 | ControlLookBehind = 26, 318 | ControlPhone = 27, 319 | ControlSpecialAbility = 28, 320 | ControlSpecialAbilitySecondary = 29, 321 | ControlMoveLeftRight = 30, 322 | ControlMoveUpDown = 31, 323 | ControlMoveUpOnly = 32, 324 | ControlMoveDownOnly = 33, 325 | ControlMoveLeftOnly = 34, 326 | ControlMoveRightOnly = 35, 327 | ControlDuck = 36, 328 | ControlSelectWeapon = 37, 329 | ControlPickup = 38, 330 | ControlSniperZoom = 39, 331 | ControlSniperZoomInOnly = 40, 332 | ControlSniperZoomOutOnly = 41, 333 | ControlSniperZoomInSecondary = 42, 334 | ControlSniperZoomOutSecondary = 43, 335 | ControlCover = 44, 336 | ControlReload = 45, 337 | ControlTalk = 46, 338 | ControlDetonate = 47, 339 | ControlHUDSpecial = 48, 340 | ControlArrest = 49, 341 | ControlAccurateAim = 50, 342 | ControlContext = 51, 343 | ControlContextSecondary = 52, 344 | ControlWeaponSpecial = 53, 345 | ControlWeaponSpecial2 = 54, 346 | ControlDive = 55, 347 | ControlDropWeapon = 56, 348 | ControlDropAmmo = 57, 349 | ControlThrowGrenade = 58, 350 | ControlVehicleMoveLeftRight = 59, 351 | ControlVehicleMoveUpDown = 60, 352 | ControlVehicleMoveUpOnly = 61, 353 | ControlVehicleMoveDownOnly = 62, 354 | ControlVehicleMoveLeftOnly = 63, 355 | ControlVehicleMoveRightOnly = 64, 356 | ControlVehicleSpecial = 65, 357 | ControlVehicleGunLeftRight = 66, 358 | ControlVehicleGunUpDown = 67, 359 | ControlVehicleAim = 68, 360 | ControlVehicleAttack = 69, 361 | ControlVehicleAttack2 = 70, 362 | ControlVehicleAccelerate = 71, 363 | ControlVehicleBrake = 72, 364 | ControlVehicleDuck = 73, 365 | ControlVehicleHeadlight = 74, 366 | ControlVehicleExit = 75, 367 | ControlVehicleHandbrake = 76, 368 | ControlVehicleHotwireLeft = 77, 369 | ControlVehicleHotwireRight = 78, 370 | ControlVehicleLookBehind = 79, 371 | ControlVehicleCinCam = 80, 372 | ControlVehicleNextRadio = 81, 373 | ControlVehiclePrevRadio = 82, 374 | ControlVehicleNextRadioTrack = 83, 375 | ControlVehiclePrevRadioTrack = 84, 376 | ControlVehicleRadioWheel = 85, 377 | ControlVehicleHorn = 86, 378 | ControlVehicleFlyThrottleUp = 87, 379 | ControlVehicleFlyThrottleDown = 88, 380 | ControlVehicleFlyYawLeft = 89, 381 | ControlVehicleFlyYawRight = 90, 382 | ControlVehiclePassengerAim = 91, 383 | ControlVehiclePassengerAttack = 92, 384 | ControlVehicleSpecialAbilityFranklin = 93, 385 | ControlVehicleStuntUpDown = 94, 386 | ControlVehicleCinematicUpDown = 95, 387 | ControlVehicleCinematicUpOnly = 96, 388 | ControlVehicleCinematicDownOnly = 97, 389 | ControlVehicleCinematicLeftRight = 98, 390 | ControlVehicleSelectNextWeapon = 99, 391 | ControlVehicleSelectPrevWeapon = 100, 392 | ControlVehicleRoof = 101, 393 | ControlVehicleJump = 102, 394 | ControlVehicleGrapplingHook = 103, 395 | ControlVehicleShuffle = 104, 396 | ControlVehicleDropProjectile = 105, 397 | ControlVehicleMouseControlOverride = 106, 398 | ControlVehicleFlyRollLeftRight = 107, 399 | ControlVehicleFlyRollLeftOnly = 108, 400 | ControlVehicleFlyRollRightOnly = 109, 401 | ControlVehicleFlyPitchUpDown = 110, 402 | ControlVehicleFlyPitchUpOnly = 111, 403 | ControlVehicleFlyPitchDownOnly = 112, 404 | ControlVehicleFlyUnderCarriage = 113, 405 | ControlVehicleFlyAttack = 114, 406 | ControlVehicleFlySelectNextWeapon = 115, 407 | ControlVehicleFlySelectPrevWeapon = 116, 408 | ControlVehicleFlySelectTargetLeft = 117, 409 | ControlVehicleFlySelectTargetRight = 118, 410 | ControlVehicleFlyVerticalFlightMode = 119, 411 | ControlVehicleFlyDuck = 120, 412 | ControlVehicleFlyAttackCamera = 121, 413 | ControlVehicleFlyMouseControlOverride = 122, 414 | ControlVehicleSubTurnLeftRight = 123, 415 | ControlVehicleSubTurnLeftOnly = 124, 416 | ControlVehicleSubTurnRightOnly = 125, 417 | ControlVehicleSubPitchUpDown = 126, 418 | ControlVehicleSubPitchUpOnly = 127, 419 | ControlVehicleSubPitchDownOnly = 128, 420 | ControlVehicleSubThrottleUp = 129, 421 | ControlVehicleSubThrottleDown = 130, 422 | ControlVehicleSubAscend = 131, 423 | ControlVehicleSubDescend = 132, 424 | ControlVehicleSubTurnHardLeft = 133, 425 | ControlVehicleSubTurnHardRight = 134, 426 | ControlVehicleSubMouseControlOverride = 135, 427 | ControlVehiclePushbikePedal = 136, 428 | ControlVehiclePushbikeSprint = 137, 429 | ControlVehiclePushbikeFrontBrake = 138, 430 | ControlVehiclePushbikeRearBrake = 139, 431 | ControlMeleeAttackLight = 140, 432 | ControlMeleeAttackHeavy = 141, 433 | ControlMeleeAttackAlternate = 142, 434 | ControlMeleeBlock = 143, 435 | ControlParachuteDeploy = 144, 436 | ControlParachuteDetach = 145, 437 | ControlParachuteTurnLeftRight = 146, 438 | ControlParachuteTurnLeftOnly = 147, 439 | ControlParachuteTurnRightOnly = 148, 440 | ControlParachutePitchUpDown = 149, 441 | ControlParachutePitchUpOnly = 150, 442 | ControlParachutePitchDownOnly = 151, 443 | ControlParachuteBrakeLeft = 152, 444 | ControlParachuteBrakeRight = 153, 445 | ControlParachuteSmoke = 154, 446 | ControlParachutePrecisionLanding = 155, 447 | ControlMap = 156, 448 | ControlSelectWeaponUnarmed = 157, 449 | ControlSelectWeaponMelee = 158, 450 | ControlSelectWeaponHandgun = 159, 451 | ControlSelectWeaponShotgun = 160, 452 | ControlSelectWeaponSmg = 161, 453 | ControlSelectWeaponAutoRifle = 162, 454 | ControlSelectWeaponSniper = 163, 455 | ControlSelectWeaponHeavy = 164, 456 | ControlSelectWeaponSpecial = 165, 457 | ControlSelectCharacterMichael = 166, 458 | ControlSelectCharacterFranklin = 167, 459 | ControlSelectCharacterTrevor = 168, 460 | ControlSelectCharacterMultiplayer = 169, 461 | ControlSaveReplayClip = 170, 462 | ControlSpecialAbilityPC = 171, 463 | ControlPhoneUp = 172, 464 | ControlPhoneDown = 173, 465 | ControlPhoneLeft = 174, 466 | ControlPhoneRight = 175, 467 | ControlPhoneSelect = 176, 468 | ControlPhoneCancel = 177, 469 | ControlPhoneOption = 178, 470 | ControlPhoneExtraOption = 179, 471 | ControlPhoneScrollForward = 180, 472 | ControlPhoneScrollBackward = 181, 473 | ControlPhoneCameraFocusLock = 182, 474 | ControlPhoneCameraGrid = 183, 475 | ControlPhoneCameraSelfie = 184, 476 | ControlPhoneCameraDOF = 185, 477 | ControlPhoneCameraExpression = 186, 478 | ControlFrontendDown = 187, 479 | ControlFrontendUp = 188, 480 | ControlFrontendLeft = 189, 481 | ControlFrontendRight = 190, 482 | ControlFrontendRdown = 191, 483 | ControlFrontendRup = 192, 484 | ControlFrontendRleft = 193, 485 | ControlFrontendRright = 194, 486 | ControlFrontendAxisX = 195, 487 | ControlFrontendAxisY = 196, 488 | ControlFrontendRightAxisX = 197, 489 | ControlFrontendRightAxisY = 198, 490 | ControlFrontendPause = 199, 491 | ControlFrontendPauseAlternate = 200, 492 | ControlFrontendAccept = 201, 493 | ControlFrontendCancel = 202, 494 | ControlFrontendX = 203, 495 | ControlFrontendY = 204, 496 | ControlFrontendLb = 205, 497 | ControlFrontendRb = 206, 498 | ControlFrontendLt = 207, 499 | ControlFrontendRt = 208, 500 | ControlFrontendLs = 209, 501 | ControlFrontendRs = 210, 502 | ControlFrontendLeaderboard = 211, 503 | ControlFrontendSocialClub = 212, 504 | ControlFrontendSocialClubSecondary = 213, 505 | ControlFrontendDelete = 214, 506 | ControlFrontendEndscreenAccept = 215, 507 | ControlFrontendEndscreenExpand = 216, 508 | ControlFrontendSelect = 217, 509 | ControlScriptLeftAxisX = 218, 510 | ControlScriptLeftAxisY = 219, 511 | ControlScriptRightAxisX = 220, 512 | ControlScriptRightAxisY = 221, 513 | ControlScriptRUp = 222, 514 | ControlScriptRDown = 223, 515 | ControlScriptRLeft = 224, 516 | ControlScriptRRight = 225, 517 | ControlScriptLB = 226, 518 | ControlScriptRB = 227, 519 | ControlScriptLT = 228, 520 | ControlScriptRT = 229, 521 | ControlScriptLS = 230, 522 | ControlScriptRS = 231, 523 | ControlScriptPadUp = 232, 524 | ControlScriptPadDown = 233, 525 | ControlScriptPadLeft = 234, 526 | ControlScriptPadRight = 235, 527 | ControlScriptSelect = 236, 528 | ControlCursorAccept = 237, 529 | ControlCursorCancel = 238, 530 | ControlCursorX = 239, 531 | ControlCursorY = 240, 532 | ControlCursorScrollUp = 241, 533 | ControlCursorScrollDown = 242, 534 | ControlEnterCheatCode = 243, 535 | ControlInteractionMenu = 244, 536 | ControlMpTextChatAll = 245, 537 | ControlMpTextChatTeam = 246, 538 | ControlMpTextChatFriends = 247, 539 | ControlMpTextChatCrew = 248, 540 | ControlPushToTalk = 249, 541 | ControlCreatorLS = 250, 542 | ControlCreatorRS = 251, 543 | ControlCreatorLT = 252, 544 | ControlCreatorRT = 253, 545 | ControlCreatorMenuToggle = 254, 546 | ControlCreatorAccept = 255, 547 | ControlCreatorDelete = 256, 548 | ControlAttack2 = 257, 549 | ControlRappelJump = 258, 550 | ControlRappelLongJump = 259, 551 | ControlRappelSmashWindow = 260, 552 | ControlPrevWeapon = 261, 553 | ControlNextWeapon = 262, 554 | ControlMeleeAttack1 = 263, 555 | ControlMeleeAttack2 = 264, 556 | ControlWhistle = 265, 557 | ControlMoveLeft = 266, 558 | ControlMoveRight = 267, 559 | ControlMoveUp = 268, 560 | ControlMoveDown = 269, 561 | ControlLookLeft = 270, 562 | ControlLookRight = 271, 563 | ControlLookUp = 272, 564 | ControlLookDown = 273, 565 | ControlSniperZoomIn = 274, 566 | ControlSniperZoomOut = 275, 567 | ControlSniperZoomInAlternate = 276, 568 | ControlSniperZoomOutAlternate = 277, 569 | ControlVehicleMoveLeft = 278, 570 | ControlVehicleMoveRight = 279, 571 | ControlVehicleMoveUp = 280, 572 | ControlVehicleMoveDown = 281, 573 | ControlVehicleGunLeft = 282, 574 | ControlVehicleGunRight = 283, 575 | ControlVehicleGunUp = 284, 576 | ControlVehicleGunDown = 285, 577 | ControlVehicleLookLeft = 286, 578 | ControlVehicleLookRight = 287, 579 | ControlReplayStartStopRecording = 288, 580 | ControlReplayStartStopRecordingSecondary = 289, 581 | ControlScaledLookLeftRight = 290, 582 | ControlScaledLookUpDown = 291, 583 | ControlScaledLookUpOnly = 292, 584 | ControlScaledLookDownOnly = 293, 585 | ControlScaledLookLeftOnly = 294, 586 | ControlScaledLookRightOnly = 295, 587 | ControlReplayMarkerDelete = 296, 588 | ControlReplayClipDelete = 297, 589 | ControlReplayPause = 298, 590 | ControlReplayRewind = 299, 591 | ControlReplayFfwd = 300, 592 | ControlReplayNewmarker = 301, 593 | ControlReplayRecord = 302, 594 | ControlReplayScreenshot = 303, 595 | ControlReplayHidehud = 304, 596 | ControlReplayStartpoint = 305, 597 | ControlReplayEndpoint = 306, 598 | ControlReplayAdvance = 307, 599 | ControlReplayBack = 308, 600 | ControlReplayTools = 309, 601 | ControlReplayRestart = 310, 602 | ControlReplayShowhotkey = 311, 603 | ControlReplayCycleMarkerLeft = 312, 604 | ControlReplayCycleMarkerRight = 313, 605 | ControlReplayFOVIncrease = 314, 606 | ControlReplayFOVDecrease = 315, 607 | ControlReplayCameraUp = 316, 608 | ControlReplayCameraDown = 317, 609 | ControlReplaySave = 318, 610 | ControlReplayToggletime = 319, 611 | ControlReplayToggletips = 320, 612 | ControlReplayPreview = 321, 613 | ControlReplayToggleTimeline = 322, 614 | ControlReplayTimelinePickupClip = 323, 615 | ControlReplayTimelineDuplicateClip = 324, 616 | ControlReplayTimelinePlaceClip = 325, 617 | ControlReplayCtrl = 326, 618 | ControlReplayTimelineSave = 327, 619 | ControlReplayPreviewAudio = 328, 620 | ControlVehicleDriveLook = 329, 621 | ControlVehicleDriveLook2 = 330, 622 | ControlVehicleFlyAttack2 = 331, 623 | ControlRadioWheelUpDown = 332, 624 | ControlRadioWheelLeftRight = 333, 625 | ControlVehicleSlowMoUpDown = 334, 626 | ControlVehicleSlowMoUpOnly = 335, 627 | ControlVehicleSlowMoDownOnly = 336, 628 | ControlMapPointOfInterest = 337, 629 | }; 630 | 631 | enum eRadioStation 632 | { 633 | RadioStationLosSantosRockRadio, 634 | RadioStationNonStopPopFM, 635 | RadioStationLosSantos, 636 | RadioStationChannelX, 637 | RadioStationWestCoastTalkRadio, 638 | RadioStationRebelRadio, 639 | RadioStationSoulwaxFM, 640 | RadioStationEastLosFM, 641 | RadioStationWestCoastClassics, 642 | RadioStationTheBlueArk, 643 | RadioStationWorldWideFM, 644 | RadioStationFlyloFM, 645 | RadioStationTheLowdown, 646 | RadioStationTheLab, 647 | RadioStationMirrorPark, 648 | RadioStationSpace, 649 | RadioStationVinewoodBoulevardRadio, 650 | }; 651 | 652 | enum eWindowTitle 653 | { 654 | CELL_EMAIL_BOD, 655 | CELL_EMAIL_BODE, 656 | CELL_EMAIL_BODF, 657 | CELL_EMAIL_SOD, 658 | CELL_EMAIL_SODE, 659 | CELL_EMAIL_SODF, 660 | CELL_EMASH_BOD, 661 | CELL_EMASH_BODE, 662 | CELL_EMASH_BODF, 663 | CELL_EMASH_SOD, 664 | CELL_EMASH_SODE, 665 | CELL_EMASH_SODF, 666 | FMMC_KEY_TIP10, 667 | FMMC_KEY_TIP12, 668 | FMMC_KEY_TIP12F, 669 | FMMC_KEY_TIP12N, 670 | FMMC_KEY_TIP8, 671 | FMMC_KEY_TIP8F, 672 | FMMC_KEY_TIP8FS, 673 | FMMC_KEY_TIP8S, 674 | FMMC_KEY_TIP9, 675 | FMMC_KEY_TIP9F, 676 | FMMC_KEY_TIP9N, 677 | PM_NAME_CHALL, 678 | }; 679 | 680 | enum eGender 681 | { 682 | GenderMale, 683 | GenderFemale 684 | }; 685 | 686 | enum eDrivingStyle 687 | { 688 | DrivingStyleNormal = 0xC00AB, 689 | DrivingStyleIgnoreLights = 0x2C0025, 690 | DrivingStyleSometimesOvertakeTraffic = 5, 691 | DrivingStyleRushed = 0x400C0025, 692 | DrivingStyleAvoidTraffic = 0xC0024, 693 | DrivingStyleAvoidTrafficExtremely = 6 694 | }; 695 | 696 | enum eBone 697 | { 698 | SKEL_ROOT = 0x0, 699 | SKEL_Pelvis = 0x2e28, 700 | SKEL_L_Thigh = 0xe39f, 701 | SKEL_L_Calf = 0xf9bb, 702 | SKEL_L_Foot = 0x3779, 703 | SKEL_L_Toe0 = 0x83c, 704 | IK_L_Foot = 0xfedd, 705 | PH_L_Foot = 0xe175, 706 | MH_L_Knee = 0xb3fe, 707 | SKEL_R_Thigh = 0xca72, 708 | SKEL_R_Calf = 0x9000, 709 | SKEL_R_Foot = 0xcc4d, 710 | SKEL_R_Toe0 = 0x512d, 711 | IK_R_Foot = 0x8aae, 712 | PH_R_Foot = 0x60e6, 713 | MH_R_Knee = 0x3fcf, 714 | RB_L_ThighRoll = 0x5c57, 715 | RB_R_ThighRoll = 0x192a, 716 | SKEL_Spine_Root = 0xe0fd, 717 | SKEL_Spine0 = 0x5c01, 718 | SKEL_Spine1 = 0x60f0, 719 | SKEL_Spine2 = 0x60f1, 720 | SKEL_Spine3 = 0x60f2, 721 | SKEL_L_Clavicle = 0xfcd9, 722 | SKEL_L_UpperArm = 0xb1c5, 723 | SKEL_L_Forearm = 0xeeeb, 724 | SKEL_L_Hand = 0x49d9, 725 | SKEL_L_Finger00 = 0x67f2, 726 | SKEL_L_Finger01 = 0xff9, 727 | SKEL_L_Finger02 = 0xffa, 728 | SKEL_L_Finger10 = 0x67f3, 729 | SKEL_L_Finger11 = 0x1049, 730 | SKEL_L_Finger12 = 0x104a, 731 | SKEL_L_Finger20 = 0x67f4, 732 | SKEL_L_Finger21 = 0x1059, 733 | SKEL_L_Finger22 = 0x105a, 734 | SKEL_L_Finger30 = 0x67f5, 735 | SKEL_L_Finger31 = 0x1029, 736 | SKEL_L_Finger32 = 0x102a, 737 | SKEL_L_Finger40 = 0x67f6, 738 | SKEL_L_Finger41 = 0x1039, 739 | SKEL_L_Finger42 = 0x103a, 740 | PH_L_Hand = 0xeb95, 741 | IK_L_Hand = 0x8cbd, 742 | RB_L_ForeArmRoll = 0xee4f, 743 | RB_L_ArmRoll = 0x1470, 744 | MH_L_Elbow = 0x58b7, 745 | SKEL_R_Clavicle = 0x29d2, 746 | SKEL_R_UpperArm = 0x9d4d, 747 | SKEL_R_Forearm = 0x6e5c, 748 | SKEL_R_Hand = 0xdead, 749 | SKEL_R_Finger00 = 0xe5f2, 750 | SKEL_R_Finger01 = 0xfa10, 751 | SKEL_R_Finger02 = 0xfa11, 752 | SKEL_R_Finger10 = 0xe5f3, 753 | SKEL_R_Finger11 = 0xfa60, 754 | SKEL_R_Finger12 = 0xfa61, 755 | SKEL_R_Finger20 = 0xe5f4, 756 | SKEL_R_Finger21 = 0xfa70, 757 | SKEL_R_Finger22 = 0xfa71, 758 | SKEL_R_Finger30 = 0xe5f5, 759 | SKEL_R_Finger31 = 0xfa40, 760 | SKEL_R_Finger32 = 0xfa41, 761 | SKEL_R_Finger40 = 0xe5f6, 762 | SKEL_R_Finger41 = 0xfa50, 763 | SKEL_R_Finger42 = 0xfa51, 764 | PH_R_Hand = 0x6f06, 765 | IK_R_Hand = 0x188e, 766 | RB_R_ForeArmRoll = 0xab22, 767 | RB_R_ArmRoll = 0x90ff, 768 | MH_R_Elbow = 0xbb0, 769 | SKEL_Neck_1 = 0x9995, 770 | SKEL_Head = 0x796e, 771 | IK_Head = 0x322c, 772 | FACIAL_facialRoot = 0xfe2c, 773 | FB_L_Brow_Out_000 = 0xe3db, 774 | FB_L_Lid_Upper_000 = 0xb2b6, 775 | FB_L_Eye_000 = 0x62ac, 776 | FB_L_CheekBone_000 = 0x542e, 777 | FB_L_Lip_Corner_000 = 0x74ac, 778 | FB_R_Lid_Upper_000 = 0xaa10, 779 | FB_R_Eye_000 = 0x6b52, 780 | FB_R_CheekBone_000 = 0x4b88, 781 | FB_R_Brow_Out_000 = 0x54c, 782 | FB_R_Lip_Corner_000 = 0x2ba6, 783 | FB_Brow_Centre_000 = 0x9149, 784 | FB_UpperLipRoot_000 = 0x4ed2, 785 | FB_UpperLip_000 = 0xf18f, 786 | FB_L_Lip_Top_000 = 0x4f37, 787 | FB_R_Lip_Top_000 = 0x4537, 788 | FB_Jaw_000 = 0xb4a0, 789 | FB_LowerLipRoot_000 = 0x4324, 790 | FB_LowerLip_000 = 0x508f, 791 | FB_L_Lip_Bot_000 = 0xb93b, 792 | FB_R_Lip_Bot_000 = 0xc33b, 793 | FB_Tongue_000 = 0xb987, 794 | RB_Neck_1 = 0x8b93, 795 | IK_Root = 0xdd1c 796 | }; 797 | 798 | enum eFiringPattern : DWORD 799 | { 800 | FiringPatternFullAuto = 0xC6EE6B4C, 801 | FiringPatternBurstFire = 0xD6FF6D61, 802 | FiringPatternBurstInCover = 0x026321F1, 803 | FiringPatternBurstFireDriveby = 0xD31265F2, 804 | FiringPatternFromGround = 0x2264E5D6, 805 | FiringPatternDelayFireByOneSec = 0x7A845691, 806 | FiringPatternSingleShot = 0x5D60E4E0, 807 | FiringPatternBurstFirePistol = 0xA018DB8A, 808 | FiringPatternBurstFireSMG = 0xD10DADEE, 809 | FiringPatternBurstFireRifle = 0x9C74B406, 810 | FiringPatternBurstFireMG = 0xB573C5B4, 811 | FiringPatternBurstFirePumpShotGun = 0x00BAC39B, 812 | FiringPatternBurstFireHeli = 0x914E786F, 813 | FiringPatternBurstFireMicro = 0x42EF03FD, 814 | FiringPatternBurstFireBursts = 0x42EF03FD, 815 | FiringPatternBurstFireTank = 0xE2CA3A71 816 | }; 817 | 818 | enum eFont 819 | { 820 | FontChaletLondon = 0, 821 | FontHouseScript = 1, 822 | FontMonospace = 2, 823 | FontChaletComprimeCologne = 4, 824 | FontPricedown = 7 825 | }; 826 | 827 | enum eVehicleColor 828 | { 829 | VehicleColorMetallicBlack = 0, 830 | VehicleColorMetallicGraphiteBlack = 1, 831 | VehicleColorMetallicBlackSteel = 2, 832 | VehicleColorMetallicDarkSilver = 3, 833 | VehicleColorMetallicSilver = 4, 834 | VehicleColorMetallicBlueSilver = 5, 835 | VehicleColorMetallicSteelGray = 6, 836 | VehicleColorMetallicShadowSilver = 7, 837 | VehicleColorMetallicStoneSilver = 8, 838 | VehicleColorMetallicMidnightSilver = 9, 839 | VehicleColorMetallicGunMetal = 10, 840 | VehicleColorMetallicAnthraciteGray = 11, 841 | VehicleColorMatteBlack = 12, 842 | VehicleColorMatteGray = 13, 843 | VehicleColorMatteLightGray = 14, 844 | VehicleColorUtilBlack = 15, 845 | VehicleColorUtilBlackPoly = 16, 846 | VehicleColorUtilDarksilver = 17, 847 | VehicleColorUtilSilver = 18, 848 | VehicleColorUtilGunMetal = 19, 849 | VehicleColorUtilShadowSilver = 20, 850 | VehicleColorWornBlack = 21, 851 | VehicleColorWornGraphite = 22, 852 | VehicleColorWornSilverGray = 23, 853 | VehicleColorWornSilver = 24, 854 | VehicleColorWornBlueSilver = 25, 855 | VehicleColorWornShadowSilver = 26, 856 | VehicleColorMetallicRed = 27, 857 | VehicleColorMetallicTorinoRed = 28, 858 | VehicleColorMetallicFormulaRed = 29, 859 | VehicleColorMetallicBlazeRed = 30, 860 | VehicleColorMetallicGracefulRed = 31, 861 | VehicleColorMetallicGarnetRed = 32, 862 | VehicleColorMetallicDesertRed = 33, 863 | VehicleColorMetallicCabernetRed = 34, 864 | VehicleColorMetallicCandyRed = 35, 865 | VehicleColorMetallicSunriseOrange = 36, 866 | VehicleColorMetallicClassicGold = 37, 867 | VehicleColorMetallicOrange = 38, 868 | VehicleColorMatteRed = 39, 869 | VehicleColorMatteDarkRed = 40, 870 | VehicleColorMatteOrange = 41, 871 | VehicleColorMatteYellow = 42, 872 | VehicleColorUtilRed = 43, 873 | VehicleColorUtilBrightRed = 44, 874 | VehicleColorUtilGarnetRed = 45, 875 | VehicleColorWornRed = 46, 876 | VehicleColorWornGoldenRed = 47, 877 | VehicleColorWornDarkRed = 48, 878 | VehicleColorMetallicDarkGreen = 49, 879 | VehicleColorMetallicRacingGreen = 50, 880 | VehicleColorMetallicSeaGreen = 51, 881 | VehicleColorMetallicOliveGreen = 52, 882 | VehicleColorMetallicGreen = 53, 883 | VehicleColorMetallicGasolineBlueGreen = 54, 884 | VehicleColorMatteLimeGreen = 55, 885 | VehicleColorUtilDarkGreen = 56, 886 | VehicleColorUtilGreen = 57, 887 | VehicleColorWornDarkGreen = 58, 888 | VehicleColorWornGreen = 59, 889 | VehicleColorWornSeaWash = 60, 890 | VehicleColorMetallicMidnightBlue = 61, 891 | VehicleColorMetallicDarkBlue = 62, 892 | VehicleColorMetallicSaxonyBlue = 63, 893 | VehicleColorMetallicBlue = 64, 894 | VehicleColorMetallicMarinerBlue = 65, 895 | VehicleColorMetallicHarborBlue = 66, 896 | VehicleColorMetallicDiamondBlue = 67, 897 | VehicleColorMetallicSurfBlue = 68, 898 | VehicleColorMetallicNauticalBlue = 69, 899 | VehicleColorMetallicBrightBlue = 70, 900 | VehicleColorMetallicPurpleBlue = 71, 901 | VehicleColorMetallicSpinnakerBlue = 72, 902 | VehicleColorMetallicUltraBlue = 73, 903 | VehicleColorUtilDarkBlue = 75, 904 | VehicleColorUtilMidnightBlue = 76, 905 | VehicleColorUtilBlue = 77, 906 | VehicleColorUtilSeaFoamBlue = 78, 907 | VehicleColorUtilLightningBlue = 79, 908 | VehicleColorUtilMauiBluePoly = 80, 909 | VehicleColorUtilBrightBlue = 81, 910 | VehicleColorMatteDarkBlue = 82, 911 | VehicleColorMatteBlue = 83, 912 | VehicleColorMatteMidnightBlue = 84, 913 | VehicleColorWornDarkBlue = 85, 914 | VehicleColorWornBlue = 86, 915 | VehicleColorWornLightBlue = 87, 916 | VehicleColorMetallicTaxiYellow = 88, 917 | VehicleColorMetallicRaceYellow = 89, 918 | VehicleColorMetallicBronze = 90, 919 | VehicleColorMetallicYellowBird = 91, 920 | VehicleColorMetallicLime = 92, 921 | VehicleColorMetallicChampagne = 93, 922 | VehicleColorMetallicPuebloBeige = 94, 923 | VehicleColorMetallicDarkIvory = 95, 924 | VehicleColorMetallicChocoBrown = 96, 925 | VehicleColorMetallicGoldenBrown = 97, 926 | VehicleColorMetallicLightBrown = 98, 927 | VehicleColorMetallicStrawBeige = 99, 928 | VehicleColorMetallicMossBrown = 100, 929 | VehicleColorMetallicBistonBrown = 101, 930 | VehicleColorMetallicBeechwood = 102, 931 | VehicleColorMetallicDarkBeechwood = 103, 932 | VehicleColorMetallicChocoOrange = 104, 933 | VehicleColorMetallicBeachSand = 105, 934 | VehicleColorMetallicSunBleechedSand = 106, 935 | VehicleColorMetallicCream = 107, 936 | VehicleColorUtilBrown = 108, 937 | VehicleColorUtilMediumBrown = 109, 938 | VehicleColorUtilLightBrown = 110, 939 | VehicleColorMetallicWhite = 111, 940 | VehicleColorMetallicFrostWhite = 112, 941 | VehicleColorWornHoneyBeige = 113, 942 | VehicleColorWornBrown = 114, 943 | VehicleColorWornDarkBrown = 115, 944 | VehicleColorWornStrawBeige = 116, 945 | VehicleColorBrushedSteel = 117, 946 | VehicleColorBrushedBlackSteel = 118, 947 | VehicleColorBrushedAluminium = 119, 948 | VehicleColorChrome = 120, 949 | VehicleColorWornOffWhite = 121, 950 | VehicleColorUtilOffWhite = 122, 951 | VehicleColorWornOrange = 123, 952 | VehicleColorWornLightOrange = 124, 953 | VehicleColorMetallicSecuricorGreen = 125, 954 | VehicleColorWornTaxiYellow = 126, 955 | VehicleColorPoliceCarBlue = 127, 956 | VehicleColorMatteGreen = 128, 957 | VehicleColorMatteBrown = 129, 958 | VehicleColorMatteWhite = 131, 959 | VehicleColorWornWhite = 132, 960 | VehicleColorWornOliveArmyGreen = 133, 961 | VehicleColorPureWhite = 134, 962 | VehicleColorHotPink = 135, 963 | VehicleColorSalmonpink = 136, 964 | VehicleColorMetallicVermillionPink = 137, 965 | VehicleColorOrange = 138, 966 | VehicleColorGreen = 139, 967 | VehicleColorBlue = 140, 968 | VehicleColorMettalicBlackBlue = 141, 969 | VehicleColorMetallicBlackPurple = 142, 970 | VehicleColorMetallicBlackRed = 143, 971 | VehicleColorHunterGreen = 144, 972 | VehicleColorMetallicPurple = 145, 973 | VehicleColorMetaillicVDarkBlue = 146, 974 | VehicleColorModshopBlack1 = 147, 975 | VehicleColorMattePurple = 148, 976 | VehicleColorMatteDarkPurple = 149, 977 | VehicleColorMetallicLavaRed = 150, 978 | VehicleColorMatteForestGreen = 151, 979 | VehicleColorMatteOliveDrab = 152, 980 | VehicleColorMatteDesertBrown = 153, 981 | VehicleColorMatteDesertTan = 154, 982 | VehicleColorMatteFoliageGreen = 155, 983 | VehicleColorDefaultAlloyColor = 156, 984 | VehicleColorEpsilonBlue = 157, 985 | VehicleColorPureGold = 158, 986 | VehicleColorBrushedGold = 159, 987 | }; 988 | 989 | enum eVehicleDoor 990 | { 991 | VehicleDoorFrontLeftDoor = 0, 992 | VehicleDoorFrontRightDoor = 1, 993 | VehicleDoorBackLeftDoor = 2, 994 | VehicleDoorBackRightDoor = 3, 995 | VehicleDoorHood = 4, 996 | VehicleDoorTrunk = 5, 997 | VehicleDoorTrunk2 = 6, 998 | }; 999 | 1000 | enum eVehicleLockStatus 1001 | { 1002 | VehicleLockStatusNone = 0, 1003 | VehicleLockStatusUnlocked = 1, 1004 | VehicleLockStatusLocked = 2, 1005 | VehicleLockStatusLockedForPlayer = 3, 1006 | VehicleLockStatusStickPlayerInside = 4, 1007 | VehicleLockStatusCanBeBrokenInto = 7, 1008 | VehicleLockStatusCanBeBrokenIntoPersist = 8, 1009 | VehicleLockStatusCannotBeTriedToEnter = 10 1010 | }; 1011 | 1012 | enum eVehicleLandingGear 1013 | { 1014 | VehicleLandingGearDeployed = 0, 1015 | VehicleLandingGearClosing = 1, 1016 | VehicleLandingGearOpening = 2, 1017 | VehicleLandingGearRetracted = 3, 1018 | }; 1019 | 1020 | enum eVehicleMod 1021 | { 1022 | VehicleModSpoilers = 0, 1023 | VehicleModFrontBumper = 1, 1024 | VehicleModRearBumper = 2, 1025 | VehicleModSideSkirt = 3, 1026 | VehicleModExhaust = 4, 1027 | VehicleModFrame = 5, 1028 | VehicleModGrille = 6, 1029 | VehicleModHood = 7, 1030 | VehicleModFender = 8, 1031 | VehicleModRightFender = 9, 1032 | VehicleModRoof = 10, 1033 | VehicleModEngine = 11, 1034 | VehicleModBrakes = 12, 1035 | VehicleModTransmission = 13, 1036 | VehicleModHorns = 14, 1037 | VehicleModSuspension = 15, 1038 | VehicleModArmor = 16, 1039 | VehicleModFrontWheels = 23, 1040 | VehicleModBackWheels = 24 // only for motocycles 1041 | }; 1042 | 1043 | enum eVehicleNeonLight 1044 | { 1045 | VehicleNeonLightLeft = 0, 1046 | VehicleNeonLightRight = 1, 1047 | VehicleNeonLightFront = 2, 1048 | VehicleNeonLightBack = 3, 1049 | }; 1050 | 1051 | enum eVehicleRoofState 1052 | { 1053 | VehicleRoofStateClosed, 1054 | VehicleRoofStateOpening, 1055 | VehicleRoofStateOpened, 1056 | VehicleRoofStateClosing, 1057 | }; 1058 | 1059 | enum eVehicleSeat 1060 | { 1061 | VehicleSeatNone = -3, 1062 | VehicleSeatAny = -2, 1063 | VehicleSeatDriver = -1, 1064 | VehicleSeatPassenger = 0, 1065 | VehicleSeatLeftFront = -1, 1066 | VehicleSeatRightFront = 0, 1067 | VehicleSeatLeftRear = 1, 1068 | VehicleSeatRightRear = 2, 1069 | }; 1070 | 1071 | enum eVehicleToggleMod 1072 | { 1073 | VehicleToggleModTurbo = 18, 1074 | VehicleToggleModTireSmoke = 20, 1075 | VehicleToggleModXenonHeadlights = 22 1076 | }; 1077 | 1078 | enum eVehicleWheelType 1079 | { 1080 | VehicleWheelTypeSport = 0, 1081 | VehicleWheelTypeMuscle = 1, 1082 | VehicleWheelTypeLowrider = 2, 1083 | VehicleWheelTypeSUV = 3, 1084 | VehicleWheelTypeOffroad = 4, 1085 | VehicleWheelTypeTuner = 5, 1086 | VehicleWheelTypeBikeWheels = 6, 1087 | VehicleWheelTypeHighEnd = 7 1088 | }; 1089 | 1090 | enum eVehicleWindow 1091 | { 1092 | VehicleWindowFrontRight = 1, 1093 | VehicleWindowFrontLeft = 0, 1094 | VehicleWindowBackRight = 3, 1095 | VehicleWindowBackLeft = 2 1096 | }; 1097 | 1098 | enum eVehicleWindowTint 1099 | { 1100 | VehicleWindowTintNone = 0, 1101 | VehicleWindowTintPureBlack = 1, 1102 | VehicleWindowTintDarkSmoke = 2, 1103 | VehicleWindowTintLightSmoke = 3, 1104 | VehicleWindowTintStock = 4, 1105 | VehicleWindowTintLimo = 5, 1106 | VehicleWindowTintGreen = 6 1107 | }; 1108 | 1109 | enum eNumberPlateMounting 1110 | { 1111 | NumberPlateMountingFrontAndRear = 0, 1112 | NumberPlateMountingFront = 1, 1113 | NumberPlateMountingRear = 2, 1114 | NumberPlateMountingNone = 3, 1115 | }; 1116 | 1117 | enum eNumberPlateType 1118 | { 1119 | NumberPlateTypeBlueOnWhite1 = 0, 1120 | NumberPlateTypeYellowOnBlack = 1, 1121 | NumberPlateTypeYellowOnBlue = 2, 1122 | NumberPlateTypeBlueOnWhite2 = 3, 1123 | NumberPlateTypeBlueOnWhite3 = 4, 1124 | NumberPlateTypeNorthYankton = 5, 1125 | }; 1126 | 1127 | enum eVehicleClass 1128 | { 1129 | VehicleClassCompacts = 0, 1130 | VehicleClassSedans = 1, 1131 | VehicleClassSUVs = 2, 1132 | VehicleClassCoupes = 3, 1133 | VehicleClassMuscle = 4, 1134 | VehicleClassSportsClassics = 5, 1135 | VehicleClassSports = 6, 1136 | VehicleClassSuper = 7, 1137 | VehicleClassMotorcycles = 8, 1138 | VehicleClassOffRoad = 9, 1139 | VehicleClassIndustrial = 10, 1140 | VehicleClassUtility = 11, 1141 | VehicleClassVans = 12, 1142 | VehicleClassCycles = 13, 1143 | VehicleClassBoats = 14, 1144 | VehicleClassHelicopters = 15, 1145 | VehicleClassPlanes = 16, 1146 | VehicleClassService = 17, 1147 | VehicleClassEmergency = 18, 1148 | VehicleClassMilitary = 19, 1149 | VehicleClassCommercial = 20, 1150 | VehicleClassTrains = 21, 1151 | }; 1152 | 1153 | enum eExplosionType 1154 | { 1155 | ExplosionTypeGrenade = 0, 1156 | ExplosionTypeGrenadeL = 1, 1157 | ExplosionTypeStickyBomb = 2, 1158 | ExplosionTypeMolotov = 3, 1159 | ExplosionTypeRocket = 4, 1160 | ExplosionTypeTankShell = 5, 1161 | ExplosionTypeHiOctane = 6, 1162 | ExplosionTypeCar = 7, 1163 | ExplosionTypePlane = 8, 1164 | ExplosionTypePetrolPump = 9, 1165 | ExplosionTypeBike = 10, 1166 | ExplosionTypeSteam = 11, 1167 | ExplosionTypeFlame = 12, 1168 | ExplosionTypeWaterHydrant = 13, 1169 | ExplosionTypeGasCanister = 14, 1170 | ExplosionTypeBoat = 15, 1171 | ExplosionTypeShipDestroy = 16, 1172 | ExplosionTypeTruck = 17, 1173 | ExplosionTypeBullet = 18, 1174 | ExplosionTypeSmokeGL = 19, 1175 | ExplosionTypeSmokeG = 20, 1176 | ExplosionTypeBZGas = 21, 1177 | ExplosionTypeFlare = 22, 1178 | ExplosionTypeGasCanister2 = 23, 1179 | ExplosionTypeExtinguisher = 24, 1180 | ExplosionTypeProgramAR = 25, 1181 | ExplosionTypeTrain = 26, 1182 | ExplosionTypeBarrel = 27, 1183 | ExplosionTypePropane = 28, 1184 | ExplosionTypeBlimp = 29, 1185 | ExplosionTypeFlameExplode = 30, 1186 | ExplosionTypeTanker = 31, 1187 | ExplosionTypePlaneRocket = 32, 1188 | ExplosionTypeVehicleBullet = 33, 1189 | ExplosionTypeGasTank = 34, 1190 | ExplosionTypeFireWork = 35, 1191 | ExplosionTypeSnowBall = 36, 1192 | ExplosionTypeProxMine = 37, 1193 | ExplosionTypeValkyrie = 38 1194 | }; 1195 | 1196 | enum eIntersectFlags 1197 | { 1198 | IntersectFlagsEverything = -1, 1199 | IntersectFlagsMap = 1, 1200 | IntersectFlagsMissionEntities = 2, 1201 | IntersectFlagsPeds1 = 12, // 4 and 8 both seem to be peds 1202 | IntersectFlagsObjects = 16, 1203 | IntersectFlagsUnk1 = 32, 1204 | IntersectFlagsUnk2 = 64, 1205 | IntersectFlagsUnk3 = 128, 1206 | IntersectFlagsVegetation = 256, 1207 | IntersectFlagsUnk4 = 512 1208 | }; 1209 | 1210 | enum eMarkerType 1211 | { 1212 | MarkerTypeUpsideDownCone = 0, 1213 | MarkerTypeVerticalCylinder = 1, 1214 | MarkerTypeThickChevronUp = 2, 1215 | MarkerTypeThinChevronUp = 3, 1216 | MarkerTypeCheckeredFlagRect = 4, 1217 | MarkerTypeCheckeredFlagCircle = 5, 1218 | MarkerTypeVerticleCircle = 6, 1219 | MarkerTypePlaneModel = 7, 1220 | MarkerTypeLostMCDark = 8, 1221 | MarkerTypeLostMCLight = 9, 1222 | MarkerTypeNumber0 = 10, 1223 | MarkerTypeNumber1 = 11, 1224 | MarkerTypeNumber2 = 12, 1225 | MarkerTypeNumber3 = 13, 1226 | MarkerTypeNumber4 = 14, 1227 | MarkerTypeNumber5 = 15, 1228 | MarkerTypeNumber6 = 16, 1229 | MarkerTypeNumber7 = 17, 1230 | MarkerTypeNumber8 = 18, 1231 | MarkerTypeNumber9 = 19, 1232 | MarkerTypeChevronUpx1 = 20, 1233 | MarkerTypeChevronUpx2 = 21, 1234 | MarkerTypeChevronUpx3 = 22, 1235 | MarkerTypeHorizontalCircleFat = 23, 1236 | MarkerTypeReplayIcon = 24, 1237 | MarkerTypeHorizontalCircleSkinny = 25, 1238 | MarkerTypeHorizontalCircleSkinny_Arrow = 26, 1239 | MarkerTypeHorizontalSplitArrowCircle = 27, 1240 | MarkerTypeDebugSphere = 28 1241 | }; 1242 | 1243 | enum eRelationship 1244 | { 1245 | RelationshipHate = 5, 1246 | RelationshipDislike = 4, 1247 | RelationshipNeutral = 3, 1248 | RelationshipLike = 2, 1249 | RelationshipRespect = 1, 1250 | RelationshipCompanion = 0, 1251 | RelationshipPedestrians = 255 // or neutral 1252 | }; 1253 | 1254 | enum eRopeType 1255 | { 1256 | RopeTypeNormal = 4, 1257 | }; 1258 | 1259 | enum eWeapon : DWORD 1260 | { 1261 | WeaponKnife = 0x99B507EA, 1262 | WeaponNightstick = 0x678B81B1, 1263 | WeaponHammer = 0x4E875F73, 1264 | WeaponBat = 0x958A4A8F, 1265 | WeaponGolfClub = 0x440E4788, 1266 | WeaponCrowbar = 0x84BD7BFD, 1267 | WeaponPistol = 0x1B06D571, 1268 | WeaponCombatPistol = 0x5EF9FEC4, 1269 | WeaponAPPistol = 0x22D8FE39, 1270 | WeaponPistol50 = 0x99AEEB3B, 1271 | WeaponMicroSMG = 0x13532244, 1272 | WeaponSMG = 0x2BE6766B, 1273 | WeaponAssaultSMG = 0xEFE7E2DF, 1274 | WeaponCombatPDW = 0x0A3D4D34, 1275 | WeaponAssaultRifle = 0xBFEFFF6D, 1276 | WeaponCarbineRifle = 0x83BF0278, 1277 | WeaponAdvancedRifle = 0xAF113F99, 1278 | WeaponMG = 0x9D07F764, 1279 | WeaponCombatMG = 0x7FD62962, 1280 | WeaponPumpShotgun = 0x1D073A89, 1281 | WeaponSawnOffShotgun = 0x7846A318, 1282 | WeaponAssaultShotgun = 0xE284C527, 1283 | WeaponBullpupShotgun = 0x9D61E50F, 1284 | WeaponStunGun = 0x3656C8C1, 1285 | WeaponSniperRifle = 0x5FC3C11, 1286 | WeaponHeavySniper = 0xC472FE2, 1287 | WeaponGrenadeLauncher = 0xA284510B, 1288 | WeaponGrenadeLauncherSmoke = 0x4DD2DC56, 1289 | WeaponRPG = 0xB1CA77B1, 1290 | WeaponMinigun = 0x42BF8A85, 1291 | WeaponGrenade = 0x93E220BD, 1292 | WeaponStickyBomb = 0x2C3731D9, 1293 | WeaponSmokeGrenade = 0xFDBC8A50, 1294 | WeaponBZGas = 0xA0973D5E, 1295 | WeaponMolotov = 0x24B17070, 1296 | WeaponFireExtinguisher = 0x60EC506, 1297 | WeaponPetrolCan = 0x34A67B97, 1298 | WeaponSNSPistol = 0xBFD21232, 1299 | WeaponSpecialCarbine = 0xC0A3098D, 1300 | WeaponHeavyPistol = 0xD205520E, 1301 | WeaponBullpupRifle = 0x7F229F94, 1302 | WeaponHomingLauncher = 0x63AB0442, 1303 | WeaponProximityMine = 0xAB564B93, 1304 | WeaponSnowball = 0x787F0BB, 1305 | WeaponVintagePistol = 0x83839C4, 1306 | WeaponDagger = 0x92A27487, 1307 | WeaponFirework = 0x7F7497E5, 1308 | WeaponMusket = 0xA89CB99E, 1309 | WeaponMarksmanRifle = 0xC734385A, 1310 | WeaponHeavyShotgun = 0x3AABBBAA, 1311 | WeaponGusenberg = 0x61012683, 1312 | WeaponHatchet = 0xF9DCBF2D, 1313 | WeaponRailgun = 0x6D544C99, 1314 | WeaponUnarmed = 0xA2719263 1315 | }; 1316 | 1317 | enum eWeaponGroup : DWORD 1318 | { 1319 | WeaponGroupUnarmed = 0xA00FC1E4, 1320 | WeaponGroupMelee = 0xD49321D4, 1321 | WeaponGroupPistol = 0x18D5FA97, 1322 | WeaponGroupSMG = 0xC6E9A5C5, 1323 | WeaponGroupAssaultRifle = 0xC7D15052, 1324 | WeaponGroupMG = 0x451B04BC, 1325 | WeaponGroupShotgun = 0x33431399, 1326 | WeaponGroupSniper = 0xB7BBD827, 1327 | WeaponGroupHeavy = 0xA27A4F9F, 1328 | WeaponGroupThrown = 0x5C4C5883, 1329 | WeaponGroupPetrolCan = 0x5F1BE07C 1330 | }; 1331 | 1332 | enum eWeaponTint 1333 | { 1334 | WeaponTintNormal = 0, 1335 | WeaponTintGreen = 1, 1336 | WeaponTintGold = 2, 1337 | WeaponTintPink = 3, 1338 | WeaponTintArmy = 4, 1339 | WeaponTintLSPD = 5, 1340 | WeaponTintOrange = 6, 1341 | WeaponTintPlatinum = 7 1342 | }; 1343 | 1344 | enum ePickupType : DWORD 1345 | { 1346 | PickupTypeCustomScript = 0x2C014CA6, 1347 | PickupTypeVehicleCustomScript = 0xA5B8CAA9, 1348 | PickupTypeParachute = 0x6773257D, 1349 | PickupTypePortablePackage = 0x80AB931C, 1350 | PickupTypePortableCrateUnfixed = 0x6E717A95, 1351 | 1352 | PickupTypeHealth = 0x8F707C18, 1353 | PickupTypeHealthSnack = 0x1CD2CF66, 1354 | PickupTypeArmour = 0x4BFB42D1, 1355 | 1356 | PickupTypeMoneyCase = 0xCE6FDD6B, 1357 | PickupTypeMoneySecurityCase = 0xDE78F17E, 1358 | PickupTypeMoneyVariable = 0xFE18F3AF, 1359 | PickupTypeMoneyMedBag = 0x14568F28, 1360 | PickupTypeMoneyPurse = 0x1E9A99F8, 1361 | PickupTypeMoneyDepBag = 0x20893292, 1362 | PickupTypeMoneyWallet = 0x5DE0AD3E, 1363 | PickupTypeMoneyPaperBag = 0x711D02A4, 1364 | 1365 | PickupTypeWeaponPistol = 0xF9AFB48F, 1366 | PickupTypeWeaponCombatPistol = 0x8967B4F3, 1367 | PickupTypeWeaponAPPistol = 0x3B662889, 1368 | PickupTypeWeaponSNSPistol = 0xC5B72713, 1369 | PickupTypeWeaponHeavyPistol = 0x9CF13918, 1370 | PickupTypeWeaponMicroSMG = 0x1D9588D3, 1371 | PickupTypeWeaponSMG = 0x3A4C2AD2, 1372 | PickupTypeWeaponMG = 0x85CAA9B1, 1373 | PickupTypeWeaponCombatMG = 0xB2930A14, 1374 | PickupTypeWeaponAssaultRifle = 0xF33C83B0, 1375 | PickupTypeWeaponCarbineRifle = 0xDF711959, 1376 | PickupTypeWeaponAdvancedRifle = 0xB2B5325E, 1377 | PickupTypeWeaponSpecialCarbine = 0x968339D, 1378 | PickupTypeWeaponBullpupRifle = 0x815D66E8, 1379 | PickupTypeWeaponPumpShotgun = 0xA9355DCD, 1380 | PickupTypeWeaponSawnoffShotgun = 0x96B412A3, 1381 | PickupTypeWeaponAssaultShotgun = 0x9299C95B, 1382 | PickupTypeWeaponSniperRifle = 0xFE2A352C, 1383 | PickupTypeWeaponHeavySniper = 0x693583AD, 1384 | PickupTypeWeaponGrenadeLauncher = 0x2E764125, 1385 | PickupTypeWeaponRPG = 0x4D36C349, 1386 | PickupTypeWeaponMinigun = 0x2F36B434, 1387 | PickupTypeWeaponGrenade = 0x5E0683A1, 1388 | PickupTypeWeaponStickyBomb = 0x7C119D58, 1389 | PickupTypeWeaponSmokeGrenade = 0x1CD604C7, 1390 | PickupTypeWeaponMolotov = 0x2DD30479, 1391 | PickupTypeWeaponPetrolCan = 0xC69DE3FF, 1392 | PickupTypeWeaponKnife = 0x278D8734, 1393 | PickupTypeWeaponNightstick = 0x5EA16D74, 1394 | PickupTypeWeaponBat = 0x81EE601E, 1395 | PickupTypeWeaponCrowbar = 0x872DC888, 1396 | PickupTypeWeaponGolfclub = 0x88EAACA7, 1397 | PickupTypeWeaponBottle = 0xFA51ABF5, 1398 | 1399 | PickupTypeVehicleWeaponPistol = 0xA54AE7B7, 1400 | PickupTypeVehicleWeaponCombatPistol = 0xD0AACEF7, 1401 | PickupTypeVehicleWeaponAPPistol = 0xCC8B3905, 1402 | PickupTypeVehicleWeaponMicroSMG = 0xB86AEE5B, 1403 | PickupTypeVehicleWeaponSawnoffShotgun = 0x2E071B5A, 1404 | PickupTypeVehicleWeaponGrenade = 0xA717F898, 1405 | PickupTypeVehicleWeaponSmokeGrenade = 0x65A7D8E9, 1406 | PickupTypeVehicleWeaponStickyBomb = 0x2C804FE3, 1407 | PickupTypeVehicleWeaponMolotov = 0x84D676D4, 1408 | PickupTypeVehicleHealth = 0x98D79EF, 1409 | 1410 | PickupTypeAmmoPistol = 0x20796A82, 1411 | PickupTypeAmmoSMG = 0x116FC4E6, 1412 | PickupTypeAmmoMG = 0xDE58E0B3, 1413 | PickupTypeAmmoRifle = 0xE4BD2FC6, 1414 | PickupTypeAmmoShotgun = 0x77F3F2DD, 1415 | PickupTypeAmmoSniper = 0xC02CF125, 1416 | PickupTypeAmmoGrenadeLauncher = 0x881AB0A8, 1417 | PickupTypeAmmoRPG = 0x84837FD7, 1418 | PickupTypeAmmoMinigun = 0xF25A01B9, 1419 | PickupTypeAmmoMissileMP = 0xF99E15D0, 1420 | PickupTypeAmmoBulletMP = 0x550447A9, 1421 | PickupTypeAmmoGrenadeLauncherMP = 0xA421A532 1422 | }; 1423 | 1424 | enum eHudComponent 1425 | { 1426 | HudComponentMain = 0, 1427 | HudComponentWantedStars, 1428 | HudComponentWeaponIcon, 1429 | HudComponentCash, 1430 | HudComponentMpCash, 1431 | HudComponentMpMessage, 1432 | HudComponentVehicleName, 1433 | HudComponentAreaName, 1434 | HudComponentUnused, 1435 | HudComponentStreetName, 1436 | HudComponentHelpText, 1437 | HudComponentFloatingHelpText1, 1438 | HudComponentFloatingHelpText2, 1439 | HudComponentCashChange, 1440 | HudComponentReticle, 1441 | HudComponentSubtitleText, 1442 | HudComponentRadioStationsWheel, 1443 | HudComponentSaving, 1444 | HudComponentGameStreamUnused, 1445 | HudComponentWeaponWheel, 1446 | HudComponentWeaponWheelStats, 1447 | HudComponentDrugsPurse01, 1448 | HudComponentDrugsPurse02, 1449 | HudComponentDrugsPurse03, 1450 | HudComponentDrugsPurse04, 1451 | HudComponentMpTagCashFromBank, 1452 | HudComponentMpTagPackages, 1453 | HudComponentMpTagCuffKeys, 1454 | HudComponentMpTagDownloadData, 1455 | HudComponentMpTagIfPedFollowing, 1456 | HudComponentMpTagKeyCard, 1457 | HudComponentMpTagRandomObject, 1458 | HudComponentMpTagRemoteControl, 1459 | HudComponentMpTagCashFromSafe, 1460 | HudComponentMpTagWeaponsPackage, 1461 | HudComponentMpTagKeys, 1462 | HudComponentMpVehicle, 1463 | HudComponentMpVehicleHeli, 1464 | HudComponentMpVehiclePlane, 1465 | HudComponentPlayerSwitchAlert, 1466 | HudComponentMpRankBar, 1467 | HudComponentDirectorMode, 1468 | HudComponentReplayController, 1469 | HudComponentReplayMouse, 1470 | HudComponentReplayHeader, 1471 | HudComponentReplayOptions, 1472 | HudComponentReplayHelpText, 1473 | HudComponentReplayMiscText, 1474 | HudComponentReplayTopLine, 1475 | HudComponentReplayBottomLine, 1476 | HudComponentReplayLeftBar, 1477 | HudComponentReplayTimer 1478 | }; 1479 | 1480 | -------------------------------------------------------------------------------- /thirdparty/ScriptHookV_SDK/inc/main.h: -------------------------------------------------------------------------------- 1 | /* 2 | THIS FILE IS A PART OF GTA V SCRIPT HOOK SDK 3 | http://dev-c.com 4 | (C) Alexander Blade 2015-2016 5 | */ 6 | 7 | #pragma once 8 | 9 | #include 10 | 11 | #define IMPORT __declspec(dllimport) 12 | 13 | /* textures */ 14 | 15 | // Create texture 16 | // texFileName - texture file name, it's best to specify full texture path and use PNG textures 17 | // returns internal texture id 18 | // Texture deletion is performed automatically when game reloads scripts 19 | // Can be called only in the same thread as natives 20 | 21 | IMPORT int createTexture(const char *texFileName); 22 | 23 | // Draw texture 24 | // id - texture id recieved from createTexture() 25 | // index - each texture can have up to 64 different instances on screen at one time 26 | // level - draw level, being used in global draw order, texture instance with least level draws first 27 | // time - how much time (ms) texture instance will stay on screen, the amount of time should be enough 28 | // for it to stay on screen until the next corresponding drawTexture() call 29 | // sizeX,Y - size in screen space, should be in the range from 0.0 to 1.0, e.g setting this to 0.2 means that 30 | // texture instance will take 20% of the screen space 31 | // centerX,Y - center position in texture space, e.g. 0.5 means real texture center 32 | // posX,Y - position in screen space, [0.0, 0.0] - top left corner, [1.0, 1.0] - bottom right, 33 | // texture instance is positioned according to it's center 34 | // rotation - should be in the range from 0.0 to 1.0 35 | // screenHeightScaleFactor - screen aspect ratio, used for texture size correction, you can get it using natives 36 | // r,g,b,a - color, should be in the range from 0.0 to 1.0 37 | // 38 | // Texture instance draw parameters are updated each time script performs corresponding call to drawTexture() 39 | // You should always check your textures layout for 16:9, 16:10 and 4:3 screen aspects, for ex. in 1280x720, 40 | // 1440x900 and 1024x768 screen resolutions, use windowed mode for this 41 | // Can be called only in the same thread as natives 42 | 43 | IMPORT void drawTexture(int id, int index, int level, int time, 44 | float sizeX, float sizeY, float centerX, float centerY, 45 | float posX, float posY, float rotation, float screenHeightScaleFactor, 46 | float r, float g, float b, float a); 47 | 48 | // IDXGISwapChain::Present callback 49 | // Called right before the actual Present method call, render test calls don't trigger callbacks 50 | // When the game uses DX10 it actually uses DX11 with DX10 feature level 51 | // Remember that you can't call natives inside 52 | // void OnPresent(IDXGISwapChain *swapChain); 53 | typedef void(*PresentCallback)(void *); 54 | 55 | // Register IDXGISwapChain::Present callback 56 | // must be called on dll attach 57 | IMPORT void presentCallbackRegister(PresentCallback cb); 58 | 59 | // Unregister IDXGISwapChain::Present callback 60 | // must be called on dll detach 61 | IMPORT void presentCallbackUnregister(PresentCallback cb); 62 | 63 | /* keyboard */ 64 | 65 | // DWORD key, WORD repeats, BYTE scanCode, BOOL isExtended, BOOL isWithAlt, BOOL wasDownBefore, BOOL isUpNow 66 | typedef void(*KeyboardHandler)(DWORD, WORD, BYTE, BOOL, BOOL, BOOL, BOOL); 67 | 68 | // Register keyboard handler 69 | // must be called on dll attach 70 | IMPORT void keyboardHandlerRegister(KeyboardHandler handler); 71 | 72 | // Unregister keyboard handler 73 | // must be called on dll detach 74 | IMPORT void keyboardHandlerUnregister(KeyboardHandler handler); 75 | 76 | /* scripts */ 77 | 78 | IMPORT void scriptWait(DWORD time); 79 | IMPORT void scriptRegister(HMODULE module, void(*LP_SCRIPT_MAIN)()); 80 | IMPORT void scriptRegisterAdditionalThread(HMODULE module, void(*LP_SCRIPT_MAIN)()); 81 | IMPORT void scriptUnregister(HMODULE module); 82 | IMPORT void scriptUnregister(void(*LP_SCRIPT_MAIN)()); // deprecated 83 | 84 | IMPORT void nativeInit(UINT64 hash); 85 | IMPORT void nativePush64(UINT64 val); 86 | IMPORT PUINT64 nativeCall(); 87 | 88 | static void WAIT(DWORD time) { scriptWait(time); } 89 | static void TERMINATE() { WAIT(MAXDWORD); } 90 | 91 | // Returns pointer to global variable 92 | // make sure that you check game version before accessing globals because 93 | // ids may differ between patches 94 | IMPORT UINT64 *getGlobalPtr(int globalId); 95 | 96 | /* world */ 97 | 98 | // Get entities from internal pools 99 | // return value represents filled array elements count 100 | // can be called only in the same thread as natives 101 | IMPORT int worldGetAllVehicles(int *arr, int arrSize); 102 | IMPORT int worldGetAllPeds(int *arr, int arrSize); 103 | IMPORT int worldGetAllObjects(int *arr, int arrSize); 104 | IMPORT int worldGetAllPickups(int *arr, int arrSize); 105 | 106 | /* misc */ 107 | 108 | // Returns base object pointer using it's script handle 109 | // make sure that you check game version before accessing object fields because 110 | // offsets may differ between patches 111 | IMPORT BYTE *getScriptHandleBaseAddress(int handle); 112 | 113 | enum eGameVersion : int 114 | { 115 | VER_1_0_335_2_STEAM, 116 | VER_1_0_335_2_NOSTEAM, 117 | 118 | VER_1_0_350_1_STEAM, 119 | VER_1_0_350_2_NOSTEAM, 120 | 121 | VER_1_0_372_2_STEAM, 122 | VER_1_0_372_2_NOSTEAM, 123 | 124 | VER_1_0_393_2_STEAM, 125 | VER_1_0_393_2_NOSTEAM, 126 | 127 | VER_1_0_393_4_STEAM, 128 | VER_1_0_393_4_NOSTEAM, 129 | 130 | VER_1_0_463_1_STEAM, 131 | VER_1_0_463_1_NOSTEAM, 132 | 133 | VER_1_0_505_2_STEAM, 134 | VER_1_0_505_2_NOSTEAM, 135 | 136 | VER_1_0_573_1_STEAM, 137 | VER_1_0_573_1_NOSTEAM, 138 | 139 | VER_1_0_617_1_STEAM, 140 | VER_1_0_617_1_NOSTEAM, 141 | 142 | VER_SIZE, 143 | VER_UNK = -1 144 | }; 145 | 146 | IMPORT eGameVersion getGameVersion(); 147 | -------------------------------------------------------------------------------- /thirdparty/ScriptHookV_SDK/inc/nativeCaller.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "main.h" 4 | #include 5 | 6 | template 7 | static inline void nativePush(T val) 8 | { 9 | static_assert(sizeof(T) <= sizeof(UINT64), "Type is too large"); 10 | UINT64 val64 = 0; 11 | *reinterpret_cast(&val64) = val; 12 | nativePush64(val64); 13 | } 14 | 15 | template 16 | static inline R invoke(UINT64 hash) 17 | { 18 | nativeInit(hash); 19 | return *reinterpret_cast(nativeCall()); 20 | } 21 | 22 | template 23 | static inline R invoke(UINT64 hash, Args&& ... args) 24 | { 25 | nativeInit(hash); 26 | 27 | (nativePush(std::forward(args)), ...); 28 | 29 | return *reinterpret_cast(nativeCall()); 30 | } 31 | -------------------------------------------------------------------------------- /thirdparty/ScriptHookV_SDK/inc/types.h: -------------------------------------------------------------------------------- 1 | /* 2 | THIS FILE IS A PART OF GTA V SCRIPT HOOK SDK 3 | http://dev-c.com 4 | (C) Alexander Blade 2015 5 | */ 6 | 7 | #pragma once 8 | 9 | #include 10 | #include 11 | 12 | 13 | typedef DWORD Void; 14 | typedef DWORD Any; 15 | typedef DWORD uint; 16 | typedef DWORD Hash; 17 | typedef int Entity; 18 | typedef int Player; 19 | typedef int FireId; 20 | typedef int Ped; 21 | typedef int Vehicle; 22 | typedef int Cam; 23 | typedef int CarGenerator; 24 | typedef int Group; 25 | typedef int Train; 26 | typedef int Pickup; 27 | typedef int Object; 28 | typedef int Weapon; 29 | typedef int Interior; 30 | typedef int Blip; 31 | typedef int Texture; 32 | typedef int TextureDict; 33 | typedef int CoverPoint; 34 | typedef int Camera; 35 | typedef int TaskSequence; 36 | typedef int ColourIndex; 37 | typedef int Sphere; 38 | typedef int ScrHandle; 39 | 40 | #pragma warning(push) 41 | #pragma warning(disable : 4324) 42 | struct Vector2 { 43 | alignas(8) float x; 44 | alignas(8) float y; 45 | }; 46 | 47 | 48 | struct Vector3 { 49 | alignas(8) float x; 50 | alignas(8) float y; 51 | alignas(8) float z; 52 | }; 53 | 54 | struct Vector4 { 55 | alignas(8) float x; 56 | alignas(8) float y; 57 | alignas(8) float z; 58 | alignas(8) float w; 59 | }; 60 | #pragma warning(pop) 61 | -------------------------------------------------------------------------------- /thirdparty/ScriptHookV_SDK/lib/ScriptHookV.lib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ikt32/GTAVMenuExample/d1ef6a8cf393144c3805717ad3b3c7e9c92215de/thirdparty/ScriptHookV_SDK/lib/ScriptHookV.lib -------------------------------------------------------------------------------- /thirdparty/ScriptHookV_SDK/readme.txt: -------------------------------------------------------------------------------- 1 | ; THIS ARCHIVE REDISTRIBUTION IS NOT ALLOWED, USE THE FOLLOWING LINK INSTEAD 2 | ; http://www.dev-c.com/gtav/scripthookv/ 3 | 4 | 5 | SCRIPT HOOK V SDK 6 | 7 | v1.0.617.1a 8 | 9 | 1. General concept 10 | The main concept is that your compiled script plugin depends only on ScriptHookV.dll, 11 | so when the game updates the only thing that user must do in order to make your 12 | script working again is to update script hook runtime (i.e. ScriptHookV.dll). 13 | 14 | 2. Changes 15 | v1.0.617.1a 16 | - added ability to access pickup pool 17 | - added ability to get base object pointer using script handle 18 | v1.0.393.4a 19 | - added ability to create more objects 20 | - added ability to access entity pools (see features) 21 | - added enums (see enums.h) 22 | v1.0.393.4 23 | - added support of the latest patch 1.0.393.4 24 | v1.0.393.2 25 | - added support of the latest patch 1.0.393.2 26 | v1.0.372.2a 27 | - added support of the latest patch 1.0.372.2 28 | - added direct x hook (see textures section of main.h) 29 | - added ability to access script global variables 30 | v1.0.350.2 31 | - added support of the latest patches 1.0.350.1/2 32 | this patch changes native function hashes, however it doesn't affect SDK 33 | because script hook performs hash-to-hash translation in runtime, so 34 | we will be using original PC hashes all the time. 35 | - added ability to reload scripts in runtime 36 | - added keyboard hook 37 | 38 | 3. Features 39 | Runtime asi script reloading: 40 | In order to use this feature you must create empty file called "ScriptHookV.dev" 41 | in you game's main dir. While being ingame press CTRL + R, beep sound will tell 42 | you that all loaded scripts are fully unloaded and you can replace your *.asi, 43 | press CTRL + R again to load the scripts, triple beep will indicate that 44 | everything is loaded. You must have the call to scriptUnregister() SDK func in 45 | your plugin's DllMain in order reloading feature to work correctly, see 46 | NativeTrainer\main.cpp for more details. 47 | Script reloading can be applied only to the *.asi plugins which were loaded 48 | normally, i.e. using asi loader when the game was started. Script reloading is 49 | performed by script hook and not by asi loader. 50 | 51 | Keyboard hook: 52 | You must use keyboard hook instead of GetKeyState/GetAsyncKeyState WIN API funcs, 53 | because it guarantees that all key presses will be handled correctly. Keyboard 54 | handler must be registered/unregistered in DllMain of your plugin using SDK funcs 55 | keyboardHandlerRegister/keyboardHandlerUnregister, see NativeTrainer\main.cpp for 56 | more details. 57 | Example of using keyboard hook can be found in NativeTrainer\keyboard.cpp, the 58 | trainer script is using keyboard.cpp provided functions, your projects should do 59 | the same. 60 | 61 | DirectX hook: 62 | Provides an ability to use custom textures, see createTexture/drawTexture funcs 63 | in main.h, full description is provided there as well, you can call them only in 64 | the same thread as natives. 65 | If you need to draw something using DX API directly then you need to use callback 66 | for IDXGISwapChain::Present method. Callback must be registered/unregistered in 67 | DllMain of your plugin using presentCallbackRegister/presentCallbackUnregister. 68 | Example of using textures can be found in NativeSpeedo\script.cpp file. 69 | 70 | Entity pools: 71 | All entities that game currently uses are stored in pools, each type of entity 72 | has a separate pool. Using SDK funcs worldGetAllVehicles/Peds/Objects you can 73 | access any entity you need. 74 | While accessing these pools you should remember that lots of entities are being 75 | created not by scripts, so scripts have no full control over that entities and 76 | for ex. if you want to prevent entity from deletion by the engine or delete it 77 | by yourself you will need to gain script control over it via setting this entity 78 | as mission entity. Entities which are not set as mission ones can be deleted by 79 | the engine at any time, so you must not reuse handles of these entities between 80 | engine ticks (i.e. WAIT calls). 81 | Original scripts follow the same rules as written above while using the natives 82 | which access entities from the world, for ex. GET_PED_NEARBY_VEHICLES and 83 | GET_PED_NEARBY_PEDS. See these natives as well: IS_ENTITY_A_MISSION_ENTITY, 84 | SET_ENTITY_AS_MISSION_ENTITY. 85 | Example of using entity pools can be found in Pools\script.cpp file. 86 | 87 | 88 | 4. Compilation 89 | All samples here are being compiled using MSVC 2013, you may also use MSVC 2010 90 | with the same *.vcxproj files but this will require changing the platfrom toolset 91 | in project settings. 92 | 93 | 5. Native declarations 94 | You can always get the newest version of natives.h from NATIVEDB: 95 | http://www.dev-c.com/nativedb/ 96 | 97 | 6. Terms of use 98 | - You are allowed to use this SDK only for writing scripts intended to work offline. 99 | - You are not allowed to redistribute ScriptHookV.dll with your script plugins, 100 | provide the link to the latest runtime instead: 101 | http://www.dev-c.com/gtav/scripthookv/ 102 | 103 | 7. Samples 104 | There are few samples included - NativeTrainer and NativeSpeedo, for more details 105 | see NativeTrainer\script.cpp and NativeSpeedo\script.cpp, also an example that shows 106 | how to use entity pools can be found in Pools\script.cpp. 107 | 108 | (C) Alexander Blade 2015-2016 109 | --------------------------------------------------------------------------------