├── .gitignore ├── Trap.asi ├── lib └── bass.lib ├── include ├── gender │ ├── gender.c │ ├── umlaut_g.h │ ├── nam_dict.txt │ └── readme_g.txt ├── credits.hh ├── weaponstats.hh ├── map.hh ├── blips.hh ├── particles.hh ├── respawns.hh ├── handling.hh ├── fades.hh ├── generalsettings.hh ├── timecycle.hh ├── riot.hh ├── plates.hh ├── util │ ├── dyom │ │ ├── tts │ │ │ ├── TTSBackend.hh │ │ │ ├── TikTokSinging.hh │ │ │ ├── StreamlabsPolly.hh │ │ │ └── TikTok.hh │ │ ├── StubSession.hh │ │ ├── Translation.hh │ │ ├── TTS.hh │ │ ├── Internet.hh │ │ └── DYOMFileFormat.hh │ ├── loader.hh │ ├── text.hh │ └── scrpt.hh ├── pickups.hh ├── wanted.hh ├── animations.hh ├── CMath.hh ├── cutscenes.hh ├── weapons.hh ├── gxt.hh ├── ped.hh ├── autosave.hh ├── cgen.hh ├── logger.hh ├── cheats.hh ├── injector │ ├── utility.hpp │ ├── calling.hpp │ ├── assembly.hpp │ └── gvm │ │ └── translator.hpp ├── clothes.hh ├── heli.hh ├── dyom.hh ├── config.hh ├── sounds.hh ├── colours.hh ├── objects.hh ├── hooks.hh ├── traffic.hh ├── weapon_patterns.hh ├── missions.hh └── base.hh ├── src ├── util │ ├── loader.cc │ ├── scrpt.cc │ ├── HSL.hh │ └── text.cc ├── fades.cc ├── generalsettings.cc ├── map.cc ├── respawns.cc ├── particles.cc ├── credits.cc ├── plates.cc ├── logger.cc ├── wanted.cc ├── blips.cc ├── animations.cc ├── cheats.cc ├── cgen.cc ├── config.cc ├── main.cc ├── heli.cc ├── objects.cc ├── handling.cc ├── riot.cc └── weaponstats.cc ├── .github └── workflows │ └── main.yml ├── CMakePresets.json ├── CMakeLists.txt ├── data └── Weapon_Patterns.txt ├── .clang-format └── CONTRIBUTING.md /.gitignore: -------------------------------------------------------------------------------- 1 | .ccls 2 | .ccls-cache 3 | bin/ 4 | bin_rel/ -------------------------------------------------------------------------------- /Trap.asi: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Parik27/SA.Rainbomizer/HEAD/Trap.asi -------------------------------------------------------------------------------- /lib/bass.lib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Parik27/SA.Rainbomizer/HEAD/lib/bass.lib -------------------------------------------------------------------------------- /include/gender/gender.c: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Parik27/SA.Rainbomizer/HEAD/include/gender/gender.c -------------------------------------------------------------------------------- /include/gender/umlaut_g.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Parik27/SA.Rainbomizer/HEAD/include/gender/umlaut_g.h -------------------------------------------------------------------------------- /include/gender/nam_dict.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Parik27/SA.Rainbomizer/HEAD/include/gender/nam_dict.txt -------------------------------------------------------------------------------- /include/gender/readme_g.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Parik27/SA.Rainbomizer/HEAD/include/gender/readme_g.txt -------------------------------------------------------------------------------- /include/credits.hh: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | struct CreditsExtender 4 | { 5 | static void Initialise (); 6 | }; 7 | -------------------------------------------------------------------------------- /include/weaponstats.hh: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | class WeaponStatsRandomizer 4 | { 5 | static WeaponStatsRandomizer *mInstance; 6 | 7 | WeaponStatsRandomizer () {} 8 | 9 | static void DestroyInstance (); 10 | 11 | public: 12 | static WeaponStatsRandomizer *GetInstance (); 13 | 14 | void Initialise (); 15 | }; 16 | -------------------------------------------------------------------------------- /include/map.hh: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | class MapRandomizer 4 | { 5 | static MapRandomizer *mInstance; 6 | 7 | MapRandomizer (){}; 8 | static void DestroyInstance (); 9 | 10 | public: 11 | /// Returns the static instance for MapRandomizer. 12 | static MapRandomizer *GetInstance (); 13 | 14 | /// Initialises Hooks/etc. 15 | void Initialise (); 16 | }; 17 | -------------------------------------------------------------------------------- /include/blips.hh: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | class BlipRandomizer 4 | { 5 | static BlipRandomizer *mInstance; 6 | 7 | BlipRandomizer (){}; 8 | static void DestroyInstance (); 9 | 10 | public: 11 | /// Returns the static instance for BlipRandomizer. 12 | static BlipRandomizer *GetInstance (); 13 | 14 | /// Initialises Hooks/etc. 15 | void Initialise (); 16 | }; 17 | -------------------------------------------------------------------------------- /include/particles.hh: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | class ParticleRandomizer 4 | { 5 | static ParticleRandomizer *mInstance; 6 | 7 | ParticleRandomizer (){}; 8 | static void DestroyInstance (); 9 | 10 | public: 11 | /// Returns the static instance for ParticleRandomizer. 12 | static ParticleRandomizer *GetInstance (); 13 | 14 | /// Initialises Hooks/etc. 15 | void Initialise (); 16 | }; 17 | -------------------------------------------------------------------------------- /include/respawns.hh: -------------------------------------------------------------------------------- 1 | 2 | #pragma once 3 | 4 | class RespawnPointRandomizer 5 | { 6 | static RespawnPointRandomizer *mInstance; 7 | 8 | RespawnPointRandomizer (){}; 9 | static void DestroyInstance (); 10 | 11 | public: 12 | /// Returns the static instance for RespawnPointRandomizer. 13 | static RespawnPointRandomizer *GetInstance (); 14 | 15 | /// Initialises Hooks/etc. 16 | void Initialise (); 17 | }; 18 | -------------------------------------------------------------------------------- /include/handling.hh: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | struct tHandlingData; 4 | 5 | class HandlingRandomizer 6 | { 7 | static HandlingRandomizer *mInstance; 8 | 9 | tHandlingData *data; 10 | 11 | HandlingRandomizer (){}; 12 | static void DestroyInstance (); 13 | 14 | public: 15 | /// Returns the static instance for HandlingRandomizer. 16 | static HandlingRandomizer *GetInstance (); 17 | 18 | /// Initialises Hooks/etc. 19 | void Initialise (); 20 | }; 21 | -------------------------------------------------------------------------------- /include/fades.hh: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | 6 | class FadesManager 7 | { 8 | 9 | static auto & 10 | GetFadeCallbacks () 11 | { 12 | static std::vector> mFadeCallbacks; 13 | return mFadeCallbacks; 14 | } 15 | 16 | public: 17 | static void HandleFades (); 18 | static void Initialise (); 19 | static void 20 | AddFadeCallback (std::function function) 21 | { 22 | Initialise (); 23 | GetFadeCallbacks ().push_back (function); 24 | }; 25 | }; 26 | -------------------------------------------------------------------------------- /include/generalsettings.hh: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | class GeneralSettings 4 | { 5 | static GeneralSettings *mInstance; 6 | 7 | GeneralSettings (){}; 8 | static void DestroyInstance (); 9 | 10 | public: 11 | static GeneralSettings *GetInstance (); 12 | 13 | static inline struct Config 14 | { 15 | int Seed = -1; 16 | bool Unprotect = true; 17 | int AutoSaveSlot = 8; 18 | bool ModifyCredits = true; 19 | 20 | Config () {} 21 | } m_Config; 22 | 23 | /// Initialises Hooks/etc. 24 | void Initialise (); 25 | }; 26 | -------------------------------------------------------------------------------- /include/timecycle.hh: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | class TimeCycleRandomizer 4 | { 5 | static TimeCycleRandomizer *mInstance; 6 | 7 | TimeCycleRandomizer (){}; 8 | static void DestroyInstance (); 9 | 10 | public: 11 | /// Returns the static instance for TimeCycleRandomizer. 12 | static TimeCycleRandomizer *GetInstance (); 13 | 14 | static inline struct Config 15 | { 16 | bool RandomizeTimeCycle; 17 | bool ChangeOnFade; 18 | bool RandomizeWeather; 19 | int RandomTimecycleOdds; 20 | } m_Config; 21 | 22 | /// Initialises Hooks/etc. 23 | void Initialise (); 24 | }; 25 | -------------------------------------------------------------------------------- /include/riot.hh: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | class RiotRandomizer 4 | { 5 | static RiotRandomizer *mInstance; 6 | 7 | RiotRandomizer (){}; 8 | static void DestroyInstance (); 9 | 10 | public: 11 | /// Returns the static instance for RiotRandomizer. 12 | static RiotRandomizer *GetInstance (); 13 | 14 | static inline struct Config 15 | { 16 | bool RandomizeRiots; 17 | bool RandomizeTrafficLights; 18 | } m_Config; 19 | 20 | inline static char previousZone[8]; 21 | inline static bool riotModeRandomized = false; 22 | 23 | /// Initialises Hooks/etc. 24 | void Initialise (); 25 | }; 26 | -------------------------------------------------------------------------------- /include/plates.hh: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | struct CText; 4 | 5 | const char *__fastcall GetNewCustomPlateText (void *thisInfo, void *edx); 6 | void GetNewPlateText (char *buf, int len); 7 | void __fastcall InitialiseText (CText *text, void *edx, char a2); 8 | 9 | class LicensePlateRandomizer 10 | { 11 | static LicensePlateRandomizer *mInstance; 12 | 13 | LicensePlateRandomizer (){}; 14 | static void DestroyInstance (); 15 | 16 | public: 17 | /// Returns the static instance for LicensePlateRandomizer. 18 | static LicensePlateRandomizer *GetInstance (); 19 | 20 | /// Initialises Hooks/etc. 21 | void Initialise (); 22 | }; 23 | -------------------------------------------------------------------------------- /include/util/dyom/tts/TTSBackend.hh: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | 7 | enum Gender 8 | { 9 | GENDER_M, 10 | GENDER_F, 11 | GENDER_U 12 | }; 13 | 14 | struct Voice 15 | { 16 | std::string Name; 17 | std::string Country; 18 | int Gender; 19 | }; 20 | 21 | class TTSBackend 22 | { 23 | public: 24 | virtual HSTREAM GetSoundStream (const std::string &text, 25 | const std::string &voice, void **data) 26 | = 0; 27 | 28 | virtual std::vector GetVoices () = 0; 29 | virtual void FreeData (void *data){}; 30 | }; 31 | -------------------------------------------------------------------------------- /include/pickups.hh: -------------------------------------------------------------------------------- 1 | 2 | #pragma once 3 | #include 4 | #include 5 | 6 | class PickupsRandomizer 7 | { 8 | static PickupsRandomizer *mInstance; 9 | 10 | PickupsRandomizer (){}; 11 | static void DestroyInstance (); 12 | 13 | public: 14 | /// Returns the static instance for PickupsRandomizer. 15 | static PickupsRandomizer *GetInstance (); 16 | 17 | static inline struct Config 18 | { 19 | bool RandomizeDeadPed; 20 | bool ReplaceWithWeaponsOnly; 21 | bool MoneyFromPickups; 22 | bool RandomizeCollectables; 23 | 24 | bool SkipChecks; 25 | } m_Config; 26 | 27 | /// Initialises Hooks/etc. 28 | void Initialise (); 29 | }; 30 | -------------------------------------------------------------------------------- /include/wanted.hh: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | class WantedLevelRandomizer 4 | { 5 | static WantedLevelRandomizer *mInstance; 6 | 7 | static inline struct Config 8 | { 9 | bool RandomizeMission = true; 10 | bool RandomizeChaos; 11 | 12 | Config () {} 13 | } m_Config; 14 | 15 | WantedLevelRandomizer (){}; 16 | static void DestroyInstance (); 17 | 18 | static float mNextChaosPoints; 19 | 20 | public: 21 | /// Returns the static instance for WantedLevelRandomizer. 22 | static WantedLevelRandomizer *GetInstance (); 23 | 24 | /// Randomizes Chaos Points 25 | void RandomizeChaosPoints (); 26 | 27 | /// Initialises Hooks/etc. 28 | void Initialise (); 29 | }; 30 | -------------------------------------------------------------------------------- /src/util/loader.cc: -------------------------------------------------------------------------------- 1 | #include "util/loader.hh" 2 | #include "functions.hh" 3 | 4 | /*******************************************************/ 5 | int 6 | StreamingManager::GetRandomLoadedVehicle () 7 | { 8 | return CStreaming::ms_nVehiclesLoaded->PickRandomCar (false, false); 9 | } 10 | 11 | /*******************************************************/ 12 | eLoadError 13 | StreamingManager::AttemptToLoadVehicle (int model) 14 | { 15 | eLoadError error = ERR_ALREADY_LOADED; 16 | const int TRIES = 1; 17 | 18 | for (int i = 0; ms_aInfoForModel[model].m_nLoadState != 1; i++) 19 | { 20 | CStreaming::RequestModel (model, 0); 21 | CStreaming::LoadAllRequestedModels (false); 22 | 23 | error = ERR_LOADED; 24 | if (i >= TRIES) 25 | { 26 | return ERR_FAILED; 27 | } 28 | } 29 | 30 | return error; 31 | } 32 | -------------------------------------------------------------------------------- /include/animations.hh: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | struct CAnimationStyleDescriptor; 6 | 7 | class AnimationRandomizer 8 | { 9 | std::vector mAnimAssocDefs; 10 | static AnimationRandomizer * mInstance; 11 | 12 | static CAnimationStyleDescriptor *AddAnimAssocDefinition (const char *, 13 | const char *, int, 14 | unsigned int, 15 | void *); 16 | 17 | static void RandomizeAnimAssocDefs (); 18 | 19 | AnimationRandomizer (){}; 20 | static void DestroyInstance (); 21 | 22 | public: 23 | /// Returns the static instance for AnimationRandomizer. 24 | static AnimationRandomizer *GetInstance (); 25 | 26 | /// Initialises Hooks/etc. 27 | void Initialise (); 28 | }; 29 | -------------------------------------------------------------------------------- /src/fades.cc: -------------------------------------------------------------------------------- 1 | #include "fades.hh" 2 | #include "base.hh" 3 | #include "functions.hh" 4 | #include "injector/calling.hpp" 5 | 6 | /*******************************************************/ 7 | void 8 | FadesManager::HandleFades () 9 | { 10 | static int prevFadeValue = -1; 11 | int fadeValue = injector::ReadMemory (0xC3EFAB); 12 | 13 | if (prevFadeValue != fadeValue && fadeValue == 255) 14 | { 15 | for (const auto &i : GetFadeCallbacks ()) 16 | i (); 17 | } 18 | 19 | prevFadeValue = fadeValue; 20 | 21 | HookManager::CallOriginal, 0x53EB9D> (); 22 | } 23 | 24 | /*******************************************************/ 25 | void 26 | FadesManager::Initialise () 27 | { 28 | static bool bInitialised = false; 29 | if (std::exchange (bInitialised, true)) 30 | return; 31 | 32 | RegisterHooks ({{HOOK_CALL, 0x53EB9D, (void *) HandleFades}}); 33 | } 34 | -------------------------------------------------------------------------------- /.github/workflows/main.yml: -------------------------------------------------------------------------------- 1 | name: Build 2 | 3 | on: [push] 4 | 5 | jobs: 6 | build: 7 | 8 | runs-on: windows-latest 9 | 10 | steps: 11 | - uses: actions/checkout@v1 12 | - name: Setup 13 | uses: ilammy/msvc-dev-cmd@v1.5.0 14 | with: 15 | arch: x86 16 | 17 | - name: Compile 18 | run: | 19 | mkdir bin 20 | cd bin 21 | cmake -G "NMake Makefiles" -DCMAKE_BUILD_TYPE=Release ../ 22 | nmake 23 | mkdir output 24 | mkdir output/rainbomizer 25 | mkdir output/scripts 26 | cp rainbomizer.asi output/scripts/SA.Rainbomizer.asi 27 | cp ../config.toml output/rainbomizer/ 28 | cp ../FAQ.md output/rainbomizer/FAQ.txt 29 | cp -r ../data output/rainbomizer/data/ 30 | cp ../README.md output/readme.txt 31 | 32 | - name: Upload 33 | uses: actions/upload-artifact@v1 34 | with: 35 | name: "SA.Rainbomizer" 36 | path: bin/output 37 | 38 | -------------------------------------------------------------------------------- /include/CMath.hh: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | template struct Vector2_t 4 | { 5 | T x; 6 | T y; 7 | }; 8 | 9 | template struct Vector3_t : public Vector2_t 10 | { 11 | T z; 12 | 13 | inline Vector3_t & 14 | operator+= (const Vector3_t &rhs) 15 | { 16 | this->x += rhs.x; 17 | this->y += rhs.y; 18 | this->z += rhs.z; 19 | 20 | return *this; 21 | } 22 | 23 | inline friend Vector3_t 24 | operator+ (Vector3_t lhs, const Vector3_t &rhs) 25 | { 26 | lhs += rhs; 27 | return lhs; 28 | } 29 | 30 | inline Vector3_t & 31 | operator-= (const Vector3_t &rhs) 32 | { 33 | this->x -= rhs.x; 34 | this->y -= rhs.y; 35 | this->z -= rhs.z; 36 | 37 | return *this; 38 | } 39 | 40 | inline friend Vector3_t 41 | operator- (Vector3_t lhs, const Vector3_t &rhs) 42 | { 43 | lhs -= rhs; 44 | return lhs; 45 | } 46 | }; 47 | 48 | typedef Vector3_t Vector3; 49 | -------------------------------------------------------------------------------- /include/cutscenes.hh: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | 7 | struct COffset 8 | { 9 | float x; 10 | float y; 11 | float z; 12 | }; 13 | 14 | class CutsceneRandomizer 15 | { 16 | static CutsceneRandomizer *mInstance; 17 | 18 | std::vector> mModels; 19 | 20 | std::string mLastModel; 21 | 22 | CutsceneRandomizer (){}; 23 | static void DestroyInstance (); 24 | 25 | public: 26 | int originalLevel; 27 | COffset offset; 28 | 29 | static inline struct Config 30 | { 31 | bool RandomizeModels; 32 | bool NoBrokenJaws; 33 | bool RandomizeLocation; 34 | bool RandomizeCutsceneToPlay; 35 | } m_Config; 36 | 37 | /// Returns the static instance for CutsceneRandomizer. 38 | static CutsceneRandomizer *GetInstance (); 39 | 40 | char *GetRandomModel (std::string model); 41 | 42 | COffset GetRandomOffset (float x, float y, float z); 43 | 44 | /// Initialises Hooks/etc. 45 | void Initialise (); 46 | }; 47 | -------------------------------------------------------------------------------- /include/util/dyom/StubSession.hh: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | // clang-format off 4 | class DyomStubSession 5 | { 6 | 7 | public: 8 | bool StartsAutomatically () { return false; } 9 | bool EndsAutomatically () { return false; } 10 | // legitimate is true if and only if the mission pass text was displayed by dyom. 11 | void ReportMissionPass (bool legitimate = false) { } 12 | void ReportMissionSkip () { } 13 | void ReportStartSkip () { } 14 | void ReportRetry () { } 15 | void ProcessTimer () { } 16 | bool IsRunning () { return false; } 17 | int GetTimeLeft () { return 0; } 18 | bool IsRestoringFromCrash () { return false; } 19 | void ReportObjective (const std::string &original, const std::string &translated) { } 20 | void BackupObjectiveTexts (std::string objectives[100]) {} 21 | void RestoreObjectiveTexts (std::string objectives[100]) {} 22 | void ReportMissionStart (const std::string &html, const std::string &url) {} 23 | bool ShouldSkipMission (const std::string &url) { return false; } 24 | void ReportMissionUnplayable (const std::string &url) {} 25 | }; 26 | // clang-format on 27 | -------------------------------------------------------------------------------- /include/util/loader.hh: -------------------------------------------------------------------------------- 1 | /* 2 | Rainbomizer - A (probably fun) Grand Theft Auto San Andreas Mod that 3 | randomizes stuff 4 | Copyright (C) 2019 - Parik 5 | 6 | This program is free software: you can redistribute it and/or modify 7 | it under the terms of the GNU General Public License as published by 8 | the Free Software Foundation, either version 3 of the License, or 9 | (at your option) any later version. 10 | 11 | This program is distributed in the hope that it will be useful, 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | GNU General Public License for more details. 15 | 16 | You should have received a copy of the GNU General Public License 17 | along with this program. If not, see . 18 | 19 | */ 20 | 21 | #pragma once 22 | 23 | enum eLoadError 24 | { 25 | ERR_ALREADY_LOADED, 26 | ERR_LOADED, 27 | ERR_FAILED 28 | }; 29 | 30 | class StreamingManager 31 | { 32 | public: 33 | static int GetRandomLoadedVehicle (); 34 | static eLoadError AttemptToLoadVehicle (int model); 35 | }; 36 | -------------------------------------------------------------------------------- /include/weapons.hh: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include "weapon_patterns.hh" 8 | 9 | int *GetWeaponInfo (int weaponId, char skill); 10 | 11 | class WeaponRandomizer 12 | { 13 | static WeaponRandomizer * mInstance; 14 | static inline std::vector mWeaponPatterns; 15 | 16 | WeaponRandomizer (){}; 17 | static void DestroyInstance (); 18 | 19 | public: 20 | /// Returns the static instance for WeaponRandomizer. 21 | static WeaponRandomizer *GetInstance (); 22 | 23 | static inline struct Config 24 | { 25 | bool RandomizePlayerWeapons; 26 | bool SkipChecks; 27 | } m_Config; 28 | 29 | int GetRandomWeapon (CPed *ped, int weapon, bool isPickup); 30 | void CachePatterns (); 31 | 32 | static inline int playerWeaponID = -1; 33 | static inline int dealerWeaponID = random (22, 38); 34 | static inline bool forceWeapon = false; 35 | static inline bool firstPartFinaleCActive = false; 36 | 37 | /// Initialises Hooks/etc. 38 | void Initialise (); 39 | void InitialiseCache (); 40 | }; 41 | -------------------------------------------------------------------------------- /CMakePresets.json: -------------------------------------------------------------------------------- 1 | { 2 | "version": 2, 3 | "configurePresets": [ 4 | { 5 | "name": "release", 6 | "displayName": "Release", 7 | "generator": "NMake Makefiles", 8 | "binaryDir": "${sourceDir}/build/${presetName}", 9 | "architecture": { 10 | "value": "Win32", 11 | "strategy": "external" 12 | }, 13 | "cacheVariables": { 14 | "CMAKE_BUILD_TYPE": "Release" 15 | }, 16 | "vendor": { 17 | "microsoft.com/VisualStudioSettings/CMake/1.0": { 18 | "hostOS": [ "Windows" ] 19 | } 20 | } 21 | }, 22 | { 23 | "name": "debug", 24 | "displayName": "Debug", 25 | "generator": "NMake Makefiles", 26 | "binaryDir": "${sourceDir}/build/${presetName}", 27 | "architecture": { 28 | "value": "Win32", 29 | "strategy": "external" 30 | }, 31 | "cacheVariables": { 32 | "CMAKE_BUILD_TYPE": "Debug" 33 | }, 34 | "vendor": { 35 | "microsoft.com/VisualStudioSettings/CMake/1.0": { 36 | "hostOS": [ "Windows" ] 37 | } 38 | } 39 | } 40 | ], 41 | "buildPresets": [ 42 | { 43 | "name": "release", 44 | "configurePreset": "release" 45 | }, 46 | { 47 | "name": "debug", 48 | "configurePreset": "debug" 49 | } 50 | ] 51 | } -------------------------------------------------------------------------------- /include/gxt.hh: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | struct CText; 4 | 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | 11 | class GxtRandomizer 12 | { 13 | static GxtRandomizer *mInstance; 14 | 15 | inline static std::unordered_map> 16 | m_StringTable; 17 | 18 | static char *__fastcall GetTextHook (CText *text, void *edx, char *key); 19 | 20 | void ReadDatEntry (std::istream &i, uint32_t crc32); 21 | void ReadKeyTable (std::istream &i); 22 | void ReadStringTable (std::istream &i, uint32_t); 23 | bool InitialiseStringTable (); 24 | void AddGxtFile (std::istream &i); 25 | 26 | GxtRandomizer (){}; 27 | static void DestroyInstance (); 28 | 29 | public: 30 | static inline struct Config 31 | { 32 | int MinTime; 33 | int MaxTime; 34 | } m_Config; 35 | 36 | inline static char lastZone[8]; 37 | inline static char *randomZoneText; 38 | 39 | inline static char lastCar[8]; 40 | inline static char *randomCarText; 41 | 42 | /// Returns the static instance for GxtRandomizer. 43 | static GxtRandomizer *GetInstance (); 44 | 45 | /// Initialises Hooks/etc. 46 | void Initialise (); 47 | }; 48 | -------------------------------------------------------------------------------- /CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # rainbomizer 2 | cmake_minimum_required(VERSION 3.1.5) 3 | project(rainbomizer) 4 | 5 | # C++20 6 | if (MSVC_VERSION GREATER_EQUAL "1900") 7 | set(CMAKE_MSVC_RUNTIME_LIBRARY "MultiThreaded$<$:Debug>") 8 | # Because CMAKE_MSVC_RUNTIME_LIBRARY doesn't work for whatever reason 9 | set(CompilerFlags 10 | CMAKE_CXX_FLAGS 11 | CMAKE_CXX_FLAGS_DEBUG 12 | CMAKE_CXX_FLAGS_RELEASE 13 | CMAKE_C_FLAGS 14 | CMAKE_C_FLAGS_DEBUG 15 | CMAKE_C_FLAGS_RELEASE 16 | ) 17 | foreach(CompilerFlag ${CompilerFlags}) 18 | string(REPLACE "/MD" "/MT" ${CompilerFlag} "${${CompilerFlag}}") 19 | endforeach() 20 | endif() 21 | 22 | set (CMAKE_CXX_STANDARD 17) 23 | 24 | # Sources 25 | include_directories(include) 26 | file(GLOB SOURCES include/gender/*.c src/*.cc src/util/*.cc src/util/dyom/*.cc) 27 | 28 | add_library("rainbomizer" SHARED ${SOURCES}) 29 | 30 | # Properties 31 | target_link_directories("rainbomizer" PUBLIC lib/) 32 | set_target_properties("rainbomizer" PROPERTIES SUFFIX ".asi") 33 | target_link_libraries("rainbomizer" PUBLIC dbghelp wininet bass) 34 | target_compile_definitions("rainbomizer" PUBLIC NOMINMAX) 35 | 36 | if (CMAKE_CXX_COMPILER_ID STREQUAL "GNU") 37 | 38 | else() 39 | target_compile_features("rainbomizer" PRIVATE cxx_auto_type) 40 | endif() 41 | -------------------------------------------------------------------------------- /src/generalsettings.cc: -------------------------------------------------------------------------------- 1 | #include "generalsettings.hh" 2 | #include "config.hh" 3 | #include "base.hh" 4 | #include 5 | #include "logger.hh" 6 | #include "functions.hh" 7 | 8 | GeneralSettings *GeneralSettings::mInstance = nullptr; 9 | 10 | /*******************************************************/ 11 | void 12 | GeneralSettings::Initialise () 13 | { 14 | if (!ConfigManager::ReadConfig ( 15 | "EnableRainbomizer", std::pair ("Seed", &m_Config.Seed), 16 | std::pair ("Unprotect", &m_Config.Unprotect), 17 | std::pair ("AutosaveSlot", &m_Config.AutoSaveSlot), 18 | std::pair ("ModifyCredits", &m_Config.ModifyCredits))) 19 | return; 20 | 21 | Logger::GetLogger ()->LogMessage ("Initialising Rainbomizer..."); 22 | } 23 | 24 | /*******************************************************/ 25 | void 26 | GeneralSettings::DestroyInstance () 27 | { 28 | if (GeneralSettings::mInstance) 29 | delete GeneralSettings::mInstance; 30 | } 31 | 32 | /*******************************************************/ 33 | GeneralSettings * 34 | GeneralSettings::GetInstance () 35 | { 36 | if (!GeneralSettings::mInstance) 37 | { 38 | GeneralSettings::mInstance = new GeneralSettings (); 39 | atexit (&GeneralSettings::DestroyInstance); 40 | } 41 | return GeneralSettings::mInstance; 42 | } -------------------------------------------------------------------------------- /include/util/text.hh: -------------------------------------------------------------------------------- 1 | /* 2 | Rainbomizer - A (probably fun) Grand Theft Auto San Andreas Mod that 3 | randomizes stuff 4 | Copyright (C) 2019 - Parik 5 | 6 | This program is free software: you can redistribute it and/or modify 7 | it under the terms of the GNU General Public License as published by 8 | the Free Software Foundation, either version 3 of the License, or 9 | (at your option) any later version. 10 | 11 | This program is distributed in the hope that it will be useful, 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | GNU General Public License for more details. 15 | 16 | You should have received a copy of the GNU General Public License 17 | along with this program. If not, see . 18 | 19 | */ 20 | 21 | #include 22 | #include 23 | #include 24 | 25 | struct CText; 26 | struct CKeyArray; 27 | 28 | class GxtManager 29 | { 30 | static std::vector> mData; 31 | static void Update (CKeyArray &array); 32 | static std::string mRandomWordData; 33 | 34 | public: 35 | static void Initialise (CText *text); 36 | static const char *GetText (std::string key); 37 | static const char *GetRandomWord (); 38 | }; 39 | -------------------------------------------------------------------------------- /include/util/dyom/Translation.hh: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | 7 | #include 8 | #include 9 | 10 | #include "DYOMFileFormat.hh" 11 | #include "Internet.hh" 12 | 13 | /* Based on some of the code by captain_n00by/met-nikita 14 | https://github.com/Parik27/SA.Rainbomizer/pull/170 15 | */ 16 | class DyomTranslator 17 | { 18 | InternetUtils internet; 19 | std::string translationQueue; 20 | int queueCounter = 0; 21 | bool didTranslate = false; 22 | std::vector translationOut; 23 | 24 | void ProcessDidTranslate (std::string translated); 25 | 26 | public: 27 | DyomTranslator (const std::string &translationChain = ""); 28 | ~DyomTranslator () { internet.Close (); } 29 | 30 | void FixupGxtTokens (std::string &text); 31 | static void DecodeSpecialChars (std::string &text); 32 | 33 | std::string TranslateText (const std::string &text); 34 | void TranslateDyomFile (DYOM::DYOMFileStructure &file); 35 | 36 | // Queue based translation 37 | void DoTranslate (); 38 | void EnqueueTranslation (std::string &text); 39 | 40 | bool 41 | GetDidTranslate () 42 | { 43 | return didTranslate; 44 | } 45 | 46 | std::vector mTranslationChain; 47 | }; 48 | -------------------------------------------------------------------------------- /include/ped.hh: -------------------------------------------------------------------------------- 1 | 2 | #pragma once 3 | #include "functions.hh" 4 | #include 5 | #include 6 | #include 7 | 8 | class PedRandomizer 9 | { 10 | static PedRandomizer *mInstance; 11 | 12 | PedRandomizer (){}; 13 | static void DestroyInstance (); 14 | 15 | static uint32_t GetRandomModelIndex (uint32_t originalIdx); 16 | 17 | static void __fastcall RandomizePedModelIndex (CEntity *entity, void *, 18 | uint32_t index); 19 | static int ChooseRandomPedToLoad (); 20 | static void RandomizeSpecialModels (int slot, const char *modelName, 21 | int flags); 22 | 23 | public: 24 | /// Returns the static instance for PedRandomizer. 25 | static PedRandomizer *GetInstance (); 26 | 27 | static inline struct Config 28 | { 29 | bool RandomizeGenericModels; 30 | bool RandomizeCops; 31 | bool RandomizeGangMembers; 32 | bool RandomizeSpecialModels; 33 | bool IncludeNSFWModels; 34 | 35 | int ForcedPed; 36 | std::string ForcedSpecial; 37 | } m_Config; 38 | 39 | /// Initialises Hooks/etc. 40 | void Initialise (); 41 | 42 | inline static std::vector specialModels{}; 43 | static bool IsSpecialModel (int model); 44 | static bool IsModelValidPedModel (int model); 45 | static inline bool isSkinSelect = false; 46 | }; 47 | -------------------------------------------------------------------------------- /include/autosave.hh: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | const int ORIGINAL_DATA_SIZE = 5; 6 | class AutoSave 7 | { 8 | static AutoSave *mInstance; 9 | 10 | bool m_shouldSave = false; 11 | 12 | char m_original_data[ORIGINAL_DATA_SIZE]; 13 | 14 | float mDrawPosX = -1; 15 | float mDrawPosY = -1; 16 | 17 | float mDisplayDrawPosX = 0; 18 | float mDisplayDrawPosY = 0; 19 | 20 | int mLastSave = 0; 21 | 22 | void DrawMessage (const char *text); 23 | void HandleTransitions (float &counter, const float &target); 24 | 25 | AutoSave (){}; 26 | static void DestroyInstance (); 27 | 28 | public: 29 | bool mSaveVehicleCoords = false; 30 | 31 | /// Returns the static instance for AutoSave. 32 | static AutoSave *GetInstance (); 33 | 34 | /// Draws the autosave message 35 | void DrawAutosaveMessage (); 36 | 37 | bool 38 | ShouldSave () 39 | { 40 | return m_shouldSave; 41 | }; 42 | 43 | void SetShouldSave (bool shouldSave); 44 | 45 | /// Initialises Hooks/etc. 46 | void Initialise (); 47 | 48 | void 49 | SetDrawXY (float x, float y) 50 | { 51 | x = (x == -1) ? mDrawPosX : x; 52 | y = (y == -1) ? mDrawPosY : y; 53 | 54 | if (this->mDrawPosX == -1 || this->mDrawPosY == -1) 55 | { 56 | this->mDisplayDrawPosX = x; 57 | this->mDisplayDrawPosY = y; 58 | } 59 | 60 | this->mDrawPosX = x; 61 | this->mDrawPosY = y; 62 | } 63 | 64 | void InstallHooks (); 65 | void RevertHooks (); 66 | 67 | bool IsMissionGlobalVariable (int global_var); 68 | }; 69 | -------------------------------------------------------------------------------- /include/cgen.hh: -------------------------------------------------------------------------------- 1 | /* 2 | Rainbomizer - A (probably fun) Grand Theft Auto San Andreas Mod that 3 | randomizes stuff 4 | Copyright (C) 2019 - Parik 5 | 6 | This program is free software: you can redistribute it and/or modify 7 | it under the terms of the GNU General Public License as published by 8 | the Free Software Foundation, either version 3 of the License, or 9 | (at your option) any later version. 10 | 11 | This program is distributed in the hope that it will be useful, 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | GNU General Public License for more details. 15 | 16 | You should have received a copy of the GNU General Public License 17 | along with this program. If not, see . 18 | 19 | */ 20 | 21 | #pragma once 22 | 23 | struct CCarGenerator; 24 | 25 | // Hooks 26 | void __fastcall RandomizeFixedSpawn (CCarGenerator *gen); 27 | int __fastcall RandomizeRandomSpawn (void *group, void *edx, char a2, char a3); 28 | 29 | class ParkedCarRandomizer 30 | { 31 | static ParkedCarRandomizer *mInstance; 32 | 33 | ParkedCarRandomizer (){}; 34 | static void DestroyInstance (); 35 | 36 | public: 37 | /// Returns the static instance for ParkedCarRandomizer. 38 | static ParkedCarRandomizer *GetInstance (); 39 | 40 | static inline struct Config 41 | { 42 | bool RandomizeFixedSpawns; 43 | bool RandomizeRandomSpawns; 44 | bool UseSameType; 45 | } m_Config; 46 | 47 | /// Initialises Hooks/etc. 48 | void Initialise (); 49 | }; 50 | -------------------------------------------------------------------------------- /include/logger.hh: -------------------------------------------------------------------------------- 1 | /* 2 | Rainbomizer - A (probably fun) Grand Theft Auto San Andreas Mod that 3 | randomizes stuff 4 | Copyright (C) 2019 - Parik 5 | 6 | This program is free software: you can redistribute it and/or modify 7 | it under the terms of the GNU General Public License as published by 8 | the Free Software Foundation, either version 3 of the License, or 9 | (at your option) any later version. 10 | 11 | This program is distributed in the hope that it will be useful, 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | GNU General Public License for more details. 15 | 16 | You should have received a copy of the GNU General Public License 17 | along with this program. If not, see . 18 | 19 | */ 20 | 21 | #pragma once 22 | 23 | #include 24 | 25 | class Logger 26 | { 27 | FILE * mFile; 28 | static std::string mFileName; 29 | static Logger * mInstance; 30 | 31 | Logger (); 32 | ~Logger (); 33 | static void DestroyLogger (); 34 | 35 | public: 36 | /// Returns the static instance for Logger. 37 | static Logger *GetLogger (); 38 | 39 | /// Sets the file name for the logger (only if it's not already created) 40 | void 41 | SetFileName (std::string name) 42 | { 43 | mFileName = name; 44 | } 45 | 46 | /// Gets the current file name for the logger 47 | std::string 48 | GetFileName () 49 | { 50 | return mFileName; 51 | } 52 | 53 | /// Logs a message to the logger 54 | void LogMessage (std::string message); 55 | }; 56 | -------------------------------------------------------------------------------- /include/util/dyom/tts/TikTokSinging.hh: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "TikTok.hh" 4 | #include 5 | #include "functions.hh" 6 | 7 | class TikTokSinging : public TikTokTTS 8 | { 9 | public: 10 | auto & 11 | GetSingingVoicesList () 12 | { 13 | const static std::map> voices 14 | = {{ 15 | "singing_male", 16 | {{"en_male_sing_deep_jingle"}, 17 | {"en_male_sing_funny_it_goes_up"}, 18 | {"en_male_m03_lobby"}, 19 | {"en_male_m03_sunshine_soon"}, 20 | {"en_male_m2_xhxs_m03_silly"}, 21 | {"en_male_sing_funny_thanksgiving"}}, 22 | }, 23 | 24 | { 25 | "singing_female", 26 | {{"en_female_f08_salut_damour"}, 27 | {"en_female_f08_warmy_breeze"}, 28 | {"en_female_ht_f08_glorious"}, 29 | {"en_female_ht_f08_wonderful_world"}, 30 | {"en_female_ht_f08_halloween"}, 31 | {"en_female_ht_f08_newyear"}, 32 | {"en_female_f08_twinkle"}}, 33 | }}; 34 | 35 | return voices; 36 | } 37 | 38 | virtual HSTREAM 39 | GetSoundStream (const std::string &text, const std::string &voice, 40 | void **data) override 41 | { 42 | return TikTokTTS::GetSoundStream ( 43 | text, GetRandomElement (GetSingingVoicesList ().at (voice)), data); 44 | } 45 | 46 | virtual std::vector 47 | GetVoices () override 48 | { 49 | return {{"singing_male", "GB", GENDER_M}, 50 | {"singing_female", "GB", GENDER_F}}; 51 | } 52 | }; 53 | -------------------------------------------------------------------------------- /include/cheats.hh: -------------------------------------------------------------------------------- 1 | /* 2 | Rainbomizer - A (probably fun) Grand Theft Auto San Andreas Mod that 3 | randomizes stuff 4 | Copyright (C) 2019 - Parik 5 | 6 | This program is free software: you can redistribute it and/or modify 7 | it under the terms of the GNU General Public License as published by 8 | the Free Software Foundation, either version 3 of the License, or 9 | (at your option) any later version. 10 | 11 | This program is distributed in the hope that it will be useful, 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | GNU General Public License for more details. 15 | 16 | You should have received a copy of the GNU General Public License 17 | along with this program. If not, see . 18 | 19 | */ 20 | 21 | #pragma once 22 | 23 | struct CText; 24 | const char *__fastcall RandomizeHashesAfterCheatActivated (CText *text, 25 | void * edx, 26 | char * key); 27 | 28 | class CheatRandomizer 29 | { 30 | static CheatRandomizer *mInstance; 31 | 32 | int mTimer = 0; 33 | 34 | CheatRandomizer (){}; 35 | static void DestroyInstance (); 36 | 37 | public: 38 | static inline struct Config 39 | { 40 | bool EasterEgg; 41 | } m_Config; 42 | /// Returns the static instance for CheatRandomizer. 43 | static CheatRandomizer *GetInstance (); 44 | 45 | /// Initialises Hooks/etc. 46 | void Initialise (); 47 | 48 | /// Randomizes the Cheat Hash table 49 | void RandomizeCheatHashes (); 50 | 51 | /// Should activate a cheat 52 | bool ShouldActivate (); 53 | }; 54 | -------------------------------------------------------------------------------- /include/injector/utility.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Injectors - Utility / Helpers 3 | * 4 | * Copyright (C) 2014 LINK/2012 5 | * 6 | * This software is provided 'as-is', without any express or implied 7 | * warranty. In no event will the authors be held liable for any damages 8 | * arising from the use of this software. 9 | * 10 | * Permission is granted to anyone to use this software for any purpose, 11 | * including commercial applications, and to alter it and redistribute it 12 | * freely, subject to the following restrictions: 13 | * 14 | * 1. The origin of this software must not be misrepresented; you must not 15 | * claim that you wrote the original software. If you use this software 16 | * in a product, an acknowledgment in the product documentation would be 17 | * appreciated but is not required. 18 | * 19 | * 2. Altered source versions must be plainly marked as such, and must not be 20 | * misrepresented as being the original software. 21 | * 22 | * 3. This notice may not be removed or altered from any source 23 | * distribution. 24 | * 25 | */ 26 | #pragma once 27 | 28 | namespace injector 29 | { 30 | template 31 | T return_value() 32 | { 33 | return value; 34 | } 35 | 36 | template 37 | void* force_ptr(const T& fun) 38 | { 39 | auto ptr = fun; 40 | return *(void**)&ptr; 41 | } 42 | 43 | 44 | // Helper structure to help calling back what was there before a hook 45 | // e.g. hb.fun = MakeCALL(0x0, raw_ptr(my_hook)); 46 | template 47 | struct hook_back 48 | { 49 | typedef FuncType func_type; 50 | 51 | func_type fun; 52 | 53 | hook_back() : fun(nullptr) 54 | {} 55 | }; 56 | }; 57 | -------------------------------------------------------------------------------- /include/clothes.hh: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | 7 | class ClothesRandomizer 8 | { 9 | static ClothesRandomizer * mInstance; 10 | std::vector> mClothes[18]; 11 | 12 | bool mInitialised = false; 13 | 14 | ClothesRandomizer (){}; 15 | static void DestroyInstance (); 16 | 17 | void InitialiseClothes (); 18 | 19 | static void FixChangingClothes (int modelId, uint32_t *newClothes, 20 | uint32_t *oldClothes, bool CutscenePlayer); 21 | 22 | static int __fastcall FixAnimCrash (uint32_t *anim, void *edx, int arg0, 23 | int animGroup); 24 | 25 | static void RandomizePlayerClothes (); 26 | static void RandomizePlayerModel (); 27 | static void HandleClothesChange (); 28 | 29 | public: 30 | /// Returns the static instance for ClothesRandomizer. 31 | static ClothesRandomizer *GetInstance (); 32 | 33 | static inline struct Config 34 | { 35 | bool RandomizePlayerModel; 36 | bool RandomizePlayerClothing; 37 | 38 | int OddsOfNewModel; 39 | 40 | bool IncludeNSFWModels; 41 | bool RandomizePlayerOnce; 42 | 43 | int ForcedModel; 44 | std::string ForcedSpecial; 45 | } m_Config; 46 | 47 | std::pair GetRandomCRCForComponent (int componentId); 48 | 49 | static inline struct RandomizeOnceData 50 | { 51 | bool Initialised = false; 52 | 53 | bool isClothes; 54 | std::vector> RandomClothes; 55 | int ChosenModel; 56 | std::string SpecialModel; 57 | 58 | RandomizeOnceData (){}; 59 | 60 | } m_RandomizeOnceInfo; 61 | 62 | /// Initialises Hooks/etc. 63 | void Initialise (); 64 | }; 65 | -------------------------------------------------------------------------------- /src/map.cc: -------------------------------------------------------------------------------- 1 | #include "map.hh" 2 | #include 3 | #include "logger.hh" 4 | #include "functions.hh" 5 | #include "util/scrpt.hh" 6 | #include "config.hh" 7 | 8 | MapRandomizer *MapRandomizer::mInstance = nullptr; 9 | 10 | std::unordered_map tags 11 | = {{1490, "tag_01"}, {1524, "tag_front"}, {1525, "tag_kilo"}, 12 | {1526, "tag_rifa"}, {1527, "tag_rollin"}, {1528, "tag_seville"}, 13 | {1529, "tag_temple"}, {1530, "tag_vagos"}, {1531, "tag_azteca"}}; 14 | 15 | /*******************************************************/ 16 | CEntity * 17 | RandomizeObjectInstance (CFileObjectInstance *inst, const char *modelName) 18 | { 19 | if ((inst->modelId >= 1524 && inst->modelId <= 1531) 20 | || inst->modelId == 1490) 21 | { 22 | int randomTag = GetRandomElement (tags).first; 23 | inst->modelId = randomTag; 24 | modelName = tags[randomTag]; 25 | } 26 | return CallAndReturn (inst, modelName); 27 | } 28 | 29 | /*******************************************************/ 30 | void 31 | MapRandomizer::Initialise () 32 | { 33 | if (!ConfigManager::ReadConfig ("MapRandomizer")) 34 | return; 35 | 36 | RegisterHooks ({{HOOK_CALL, 0x5386E3, (void *) RandomizeObjectInstance}}); 37 | 38 | Logger::GetLogger ()->LogMessage ("Intialised MapRandomizer"); 39 | } 40 | 41 | /*******************************************************/ 42 | void 43 | MapRandomizer::DestroyInstance () 44 | { 45 | if (MapRandomizer::mInstance) 46 | delete MapRandomizer::mInstance; 47 | } 48 | 49 | /*******************************************************/ 50 | MapRandomizer * 51 | MapRandomizer::GetInstance () 52 | { 53 | if (!MapRandomizer::mInstance) 54 | { 55 | MapRandomizer::mInstance = new MapRandomizer (); 56 | atexit (&MapRandomizer::DestroyInstance); 57 | } 58 | return MapRandomizer::mInstance; 59 | } 60 | -------------------------------------------------------------------------------- /src/respawns.cc: -------------------------------------------------------------------------------- 1 | #include "respawns.hh" 2 | #include 3 | #include "logger.hh" 4 | #include "functions.hh" 5 | #include "util/scrpt.hh" 6 | #include "config.hh" 7 | 8 | RespawnPointRandomizer *RespawnPointRandomizer::mInstance = nullptr; 9 | 10 | /*******************************************************/ 11 | void 12 | RandomizeRespawnPoint (float x, float y, float z, RwV3d *a4, float *a5) 13 | { 14 | a4->x = randomFloat (-3000.0, 3000.0); 15 | a4->y = randomFloat (-3000.0, 3000.0); 16 | 17 | Scrpt::CallOpcode (0x4E4, "refresh_game_renderer", a4->x, a4->y); 18 | Scrpt::CallOpcode (0x3CB, "set_render_origin", a4->x, a4->y, 20); 19 | Scrpt::CallOpcode (0x15f, "set_pos", a4->x, a4->y, 20, 0, 0, 0); 20 | 21 | a4->z = CWorld::FindGroundZedForCoord (a4->x, a4->y); 22 | 23 | *a5 = randomFloat (0, 360); 24 | } 25 | 26 | /*******************************************************/ 27 | void 28 | RespawnPointRandomizer::Initialise () 29 | { 30 | if (!ConfigManager::ReadConfig ("RespawnPointRandomizer")) 31 | return; 32 | 33 | RegisterHooks ({{HOOK_CALL, 0x44331B, (void *) &RandomizeRespawnPoint}, 34 | {HOOK_CALL, 0x4435C6, (void *) &RandomizeRespawnPoint}, 35 | {HOOK_CALL, 0x442F70, (void *) &RandomizeRespawnPoint}}); 36 | Logger::GetLogger ()->LogMessage ("Intialised RespawnPointRandomizer"); 37 | } 38 | 39 | /*******************************************************/ 40 | void 41 | RespawnPointRandomizer::DestroyInstance () 42 | { 43 | if (RespawnPointRandomizer::mInstance) 44 | delete RespawnPointRandomizer::mInstance; 45 | } 46 | 47 | /*******************************************************/ 48 | RespawnPointRandomizer * 49 | RespawnPointRandomizer::GetInstance () 50 | { 51 | if (!RespawnPointRandomizer::mInstance) 52 | { 53 | RespawnPointRandomizer::mInstance = new RespawnPointRandomizer (); 54 | atexit (&RespawnPointRandomizer::DestroyInstance); 55 | } 56 | return RespawnPointRandomizer::mInstance; 57 | } 58 | -------------------------------------------------------------------------------- /include/heli.hh: -------------------------------------------------------------------------------- 1 | /* 2 | Rainbomizer - A (probably fun) Grand Theft Auto San Andreas Mod that 3 | randomizes stuff 4 | Copyright (C) 2019 - Parik 5 | 6 | This program is free software: you can redistribute it and/or modify 7 | it under the terms of the GNU General Public License as published by 8 | the Free Software Foundation, either version 3 of the License, or 9 | (at your option) any later version. 10 | 11 | This program is distributed in the hope that it will be useful, 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | GNU General Public License for more details. 15 | 16 | You should have received a copy of the GNU General Public License 17 | along with this program. If not, see . 18 | 19 | */ 20 | 21 | #pragma once 22 | 23 | struct CHeli; 24 | struct _EXCEPTION_POINTERS; 25 | 26 | int GetRandomHeliID (); 27 | void RandomizeHelisOnUnload (); 28 | void TurnOnRandomization (int model, int flags); 29 | 30 | class PoliceHeliRandomizer 31 | { 32 | static PoliceHeliRandomizer *mInstance; 33 | 34 | int mPoliceHeli; 35 | int mVCNHeli; 36 | bool mRandomizationEnabled = true; 37 | 38 | PoliceHeliRandomizer (){}; 39 | static void DestroyInstance (); 40 | 41 | public: 42 | /// Returns the static instance for PoliceHeliRandomizer. 43 | static PoliceHeliRandomizer *GetInstance (); 44 | 45 | /// Initialises Hooks/etc. 46 | void Initialise (); 47 | 48 | int 49 | GetPoliceHeli () 50 | { 51 | return mPoliceHeli; 52 | } 53 | int 54 | GetVCNHeli () 55 | { 56 | return mVCNHeli; 57 | } 58 | 59 | static void ExceptionHandlerCallback (_EXCEPTION_POINTERS *ep); 60 | 61 | void UnloadHelis (); 62 | void RandomizeHelis (bool disableRandomization = true); 63 | void UpdatePatches (); 64 | 65 | void 66 | SetRandomizationEnabled (bool enabled = true) 67 | { 68 | mRandomizationEnabled = enabled; 69 | } 70 | }; 71 | -------------------------------------------------------------------------------- /src/particles.cc: -------------------------------------------------------------------------------- 1 | #include "particles.hh" 2 | #include 3 | #include "logger.hh" 4 | #include "base.hh" 5 | #include "functions.hh" 6 | #include "injector/calling.hpp" 7 | #include "config.hh" 8 | 9 | ParticleRandomizer *ParticleRandomizer::mInstance = nullptr; 10 | 11 | /*******************************************************/ 12 | FxSystemBP_c *__fastcall RandomizeParticles (FxManager_c *thisManager, 13 | void *edx, char *name) 14 | { 15 | int particle = random (thisManager->SystemBlueprints.count - 1); 16 | FxSystemBP_c *randomParticle = thisManager->SystemBlueprints.last; 17 | FxSystemBP_c *originalParticle 18 | = injector::thiscall::call ( 19 | 0x4A9360, thisManager, name); 20 | 21 | std::string particle_name = name; 22 | if (particle_name == "heli_dust" || particle_name == "prt_cardebris" 23 | || particle_name == "gunsmoke") 24 | return originalParticle; 25 | 26 | while (particle--) 27 | randomParticle = randomParticle->m_link.prev; 28 | 29 | return randomParticle; 30 | } 31 | 32 | /*******************************************************/ 33 | void 34 | ParticleRandomizer::Initialise () 35 | { 36 | if (!ConfigManager::ReadConfig ("ParticleRandomizer")) 37 | return; 38 | 39 | RegisterHooks ({{HOOK_CALL, 0x4A9BF9, (void *) RandomizeParticles}}); 40 | Logger::GetLogger ()->LogMessage ("Intialised ParticleRandomizer"); 41 | } 42 | 43 | /*******************************************************/ 44 | void 45 | ParticleRandomizer::DestroyInstance () 46 | { 47 | if (ParticleRandomizer::mInstance) 48 | delete ParticleRandomizer::mInstance; 49 | } 50 | 51 | /*******************************************************/ 52 | ParticleRandomizer * 53 | ParticleRandomizer::GetInstance () 54 | { 55 | if (!ParticleRandomizer::mInstance) 56 | { 57 | ParticleRandomizer::mInstance = new ParticleRandomizer (); 58 | atexit (&ParticleRandomizer::DestroyInstance); 59 | } 60 | return ParticleRandomizer::mInstance; 61 | } 62 | -------------------------------------------------------------------------------- /include/dyom.hh: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | #include 4 | #include 5 | #include "util/dyom/Internet.hh" 6 | 7 | struct CRunningScript; 8 | 9 | class DyomRandomizer 10 | { 11 | static DyomRandomizer *mInstance; 12 | 13 | DyomRandomizer (){}; 14 | static void DestroyInstance (); 15 | 16 | InternetUtils internet; 17 | 18 | void SaveMission (const std::vector &data); 19 | bool ParseMission (const std::string &url); 20 | 21 | bool GetRandomEntryFromPage (std::string page, std::string &out); 22 | int GetTotalNumberOfDYOMMissionPages (std::string list); 23 | int GetTotalNumberOfDYOMMissions (std::string list); 24 | void DownloadRandomMission (const std::string &list); 25 | void DownloadRandomMission (); 26 | 27 | int prevObjectiveForSubtitles = -1; 28 | bool enableExternalSubtitles = false; 29 | std::string storedObjectives[100]; 30 | std::string originalName; 31 | 32 | bool inhibitEditorScript = false; 33 | 34 | public: 35 | static inline struct Config 36 | { 37 | bool EnglishOnly; 38 | bool AutoTranslateToEnglish; 39 | bool EnableTextToSpeech; 40 | bool RandomSpawn; 41 | bool RandomTime; 42 | bool RandomWeather; 43 | bool SpeedUpLongTTSTexts; 44 | std::string TranslationChain; 45 | double OverrideTTSVolume; 46 | std::string ForcedMissionID; 47 | std::string OverrideSearchURL; 48 | 49 | int IncrementPassCounterKey; 50 | int IncrementSkipCounterKey; 51 | int DecrementPassCounterKey; 52 | int DecrementSkipCounterKey; 53 | 54 | bool AutoReset; 55 | } m_Config; 56 | 57 | CRunningScript *mDyomScript = nullptr; 58 | 59 | void HandleExternalSubtitles (); 60 | void HandleAutoplay (CRunningScript* scr); 61 | 62 | void HandleScript (CRunningScript *scr); 63 | void HandleDyomScript (CRunningScript *scr); 64 | 65 | static bool mEnabled; 66 | 67 | /// Returns the static instance for DyomRandomizer. 68 | static DyomRandomizer *GetInstance (); 69 | 70 | /// Initialises Hooks/etc. 71 | void Initialise (); 72 | }; 73 | -------------------------------------------------------------------------------- /include/config.hh: -------------------------------------------------------------------------------- 1 | /* 2 | Rainbomizer - A (probably fun) Grand Theft Auto San Andreas Mod that 3 | randomizes stuff 4 | Copyright (C) 2019 - Parik 5 | 6 | This program is free software: you can redistribute it and/or modify 7 | it under the terms of the GNU General Public License as published by 8 | the Free Software Foundation, either version 3 of the License, or 9 | (at your option) any later version. 10 | 11 | This program is distributed in the hope that it will be useful, 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | GNU General Public License for more details. 15 | 16 | You should have received a copy of the GNU General Public License 17 | along with this program. If not, see . 18 | 19 | */ 20 | 21 | #pragma once 22 | 23 | #include 24 | #include 25 | #include 26 | #include 27 | #include 28 | #include 29 | #include 30 | #include 31 | 32 | namespace cpptoml { 33 | class table; 34 | } // namespace cpptoml 35 | 36 | /*******************************************************/ 37 | class ConfigManager 38 | { 39 | std::shared_ptr m_pDefaultConfig; 40 | std::shared_ptr m_pConfig; 41 | 42 | ConfigManager (){}; 43 | 44 | void WriteDefaultConfig (const std::string &file); 45 | std::shared_ptr ParseDefaultConfig (); 46 | 47 | template 48 | void ReadValue (const std::string &tableName, const std::string &key, 49 | T &out); 50 | 51 | bool GetIsEnabled (const std::string &name); 52 | 53 | public: 54 | /// Returns the static instance for ConfigManager. 55 | static ConfigManager *GetInstance (); 56 | 57 | /// Initialises 58 | ConfigManager (const std::string &file = "config.toml"); 59 | 60 | template 61 | static bool 62 | ReadConfig (const std::string &table, Args... params) 63 | { 64 | if (!GetInstance ()->GetIsEnabled (table)) 65 | return false; 66 | 67 | (GetInstance ()->ReadValue (table, params.first, *params.second), ...); 68 | return true; 69 | } 70 | }; 71 | -------------------------------------------------------------------------------- /src/credits.cc: -------------------------------------------------------------------------------- 1 | #include "credits.hh" 2 | #include 3 | #include "base.hh" 4 | #include "injector/calling.hpp" 5 | #include 6 | #include "config.hh" 7 | #include "generalsettings.hh" 8 | 9 | std::vector lead_devs = {"Parik", "123robot", "GTA_Madman"}; 10 | 11 | std::vector concept = {"NABN00B", "MrMateczko", "Veigar"}; 12 | 13 | std::vector contribs = {"iguana", "SpeedyFolf", "SRewo"}; 14 | 15 | std::vector beta_testers 16 | = {"Fryterp23", "Hugo_One", "Lordmau5", "Riekelt", "Waris"}; 17 | 18 | /*******************************************************/ 19 | void 20 | PrintCreditText (float scaleX, float scaleY, const char *text, int *position, 21 | float currentOffset, char bHighlighted) 22 | { 23 | using f 24 | = injector::cstd; 25 | HookManager::CallOriginal (scaleX, scaleY, text, position, 26 | currentOffset, bHighlighted); 27 | } 28 | 29 | /*******************************************************/ 30 | void 31 | PrintGroup (const std::vector &list, std::string title, 32 | int *position, float currentOffset) 33 | { 34 | PrintCreditText (1.1, 1.1, title.c_str (), position, currentOffset, 1); 35 | for (auto i : list) 36 | { 37 | PrintCreditText (1.1, 1.1, i.c_str (), position, currentOffset, 0); 38 | } 39 | 40 | *position += 37.5; 41 | } 42 | 43 | /*******************************************************/ 44 | void 45 | PrintCredits (float scaleX, float scaleY, char *text, int *position, 46 | float currentOffset, char bHighlighted) 47 | { 48 | PrintCreditText (1.6, 1.6, "RAINBOMIZER", position, currentOffset, 1); 49 | *position += 37.5; 50 | 51 | PrintGroup (lead_devs, "Lead Developers", position, currentOffset); 52 | PrintGroup (concept, "Original Concept", position, currentOffset); 53 | PrintGroup (contribs, "Additional Contributors", position, currentOffset); 54 | PrintGroup (beta_testers, "Beta Testers", position, currentOffset); 55 | 56 | PrintCreditText (1.6, 1.6, text, position, currentOffset, bHighlighted); 57 | } 58 | 59 | /*******************************************************/ 60 | void 61 | CreditsExtender::Initialise () 62 | { 63 | if (GeneralSettings::m_Config.ModifyCredits) 64 | RegisterHooks ({{HOOK_CALL, 0x5A88AC, (void *) PrintCredits}}); 65 | } 66 | -------------------------------------------------------------------------------- /src/plates.cc: -------------------------------------------------------------------------------- 1 | #include "plates.hh" 2 | #include 3 | #include "base.hh" 4 | #include "logger.hh" 5 | #include 6 | #include "util/text.hh" 7 | #include "functions.hh" 8 | #include 9 | #include "config.hh" 10 | 11 | LicensePlateRandomizer *LicensePlateRandomizer::mInstance = nullptr; 12 | 13 | /*******************************************************/ 14 | const char *__fastcall GetNewCustomPlateText (void *thisInfo, void *edx) 15 | { 16 | return GxtManager::GetRandomWord (); 17 | } 18 | 19 | /*******************************************************/ 20 | void __fastcall InitialiseText (CText *text, void *edx, char a2) 21 | { 22 | text->Load (a2); 23 | GxtManager::Initialise (text); 24 | } 25 | 26 | /*******************************************************/ 27 | void 28 | GenerateNewText (char *buf) 29 | { 30 | memset (buf, 0, 8); 31 | 32 | const char *word = GxtManager::GetRandomWord (); 33 | int length = strlen (word); 34 | 35 | strncpy (buf, word, std::min (length, 8)); 36 | } 37 | 38 | /*******************************************************/ 39 | void 40 | GetNewPlateText (char *buf, int len) 41 | { 42 | GenerateNewText (buf); 43 | } 44 | 45 | /*******************************************************/ 46 | void 47 | LicensePlateRandomizer::Initialise () 48 | { 49 | if (!ConfigManager::ReadConfig ("LicensePlateRandomizer")) 50 | return; 51 | 52 | Logger::GetLogger ()->LogMessage ("Intialised LicensePlateRandomizer"); 53 | RegisterHooks ({{HOOK_CALL, 0x6D10FB, (void *) &GetNewCustomPlateText}, 54 | {HOOK_CALL, 0x4C9484, (void *) &GetNewPlateText}, 55 | {HOOK_CALL, 0x468E9A, (void *) &InitialiseText}, 56 | {HOOK_CALL, 0x618E97, (void *) &InitialiseText}, 57 | {HOOK_CALL, 0x5BA167, (void *) &InitialiseText}}); 58 | } 59 | 60 | /*******************************************************/ 61 | void 62 | LicensePlateRandomizer::DestroyInstance () 63 | { 64 | if (LicensePlateRandomizer::mInstance) 65 | delete LicensePlateRandomizer::mInstance; 66 | } 67 | 68 | /*******************************************************/ 69 | LicensePlateRandomizer * 70 | LicensePlateRandomizer::GetInstance () 71 | { 72 | if (!LicensePlateRandomizer::mInstance) 73 | { 74 | LicensePlateRandomizer::mInstance = new LicensePlateRandomizer (); 75 | atexit (&LicensePlateRandomizer::DestroyInstance); 76 | } 77 | return LicensePlateRandomizer::mInstance; 78 | } 79 | -------------------------------------------------------------------------------- /include/sounds.hh: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | struct SoundPair 6 | { 7 | int id; 8 | std::string name; 9 | }; 10 | 11 | struct SlotSoundPair 12 | { 13 | int oldSound = -1; 14 | int newSound = -1; 15 | }; 16 | 17 | #pragma once 18 | 19 | struct CAudioEngine; 20 | struct CText; 21 | struct CAEMp3BankLoader; 22 | 23 | void __fastcall RandomizeAudioLoad (CAudioEngine *audio, void *edx, 24 | unsigned char slot, int id); 25 | char *__fastcall CorrectSubtitles (CText *TheText, void *edx, char *key); 26 | char *__fastcall RemoveSubtitlesHook (CText *TheText, void *edx, char *key); 27 | char __fastcall InitialiseLoopedSoundList (CAEMp3BankLoader *thisLoader); 28 | 29 | class SoundRandomizer 30 | { 31 | static SoundRandomizer *mInstance; 32 | 33 | std::vector mSoundTable; 34 | std::vector mLoopedSounds; 35 | std::unordered_map mPreviousPairs; 36 | SlotSoundPair slots[5]; 37 | std::string mPrevOverridenText; 38 | std::string mPrevOverridenKey; 39 | 40 | void InitaliseSoundTable (); 41 | 42 | SoundRandomizer (){}; 43 | static void DestroyInstance (); 44 | 45 | public: 46 | static inline struct Config 47 | { 48 | bool RandomizeMissionLines; 49 | bool MatchSubtitles; 50 | bool RandomizePedSpeech; 51 | bool RandomizeGenericSfx; 52 | int ForcedAudioLine; 53 | } m_Config; 54 | 55 | /// Returns the static instance for SoundRandomizer. 56 | static SoundRandomizer *GetInstance (); 57 | 58 | /// Initialises Hooks/etc. 59 | void Initialise (); 60 | 61 | /// Returns a random sound pair 62 | SoundPair GetRandomPair (int &index, int slot, int id); 63 | 64 | /// Returns random pair map 65 | std::unordered_map &GetPreviousPairs (); 66 | 67 | /// Returns sound pair by array index 68 | SoundPair GetPairByIndex (int index); 69 | 70 | /// Returns sound pair by ID 71 | bool IsSoundLooped (int id); 72 | 73 | /// Returns sound pair by ID 74 | SoundPair GetPairByID (int id); 75 | 76 | const std::string &GetPreviousOverridenText (); 77 | const std::string &GetPreviousOverridenKey (); 78 | 79 | void SetPreviousOverridenText (const std::string &key, 80 | const std::string &text); 81 | 82 | friend char __fastcall InitialiseLoopedSoundList ( 83 | CAEMp3BankLoader *thisLoader); 84 | }; 85 | -------------------------------------------------------------------------------- /data/Weapon_Patterns.txt: -------------------------------------------------------------------------------- 1 | #Thread Original Weapon Ped Melee Pistols Shotguns SMG Assault Rifles Rifles Heavy Weapons Projectiles Sprayables Gadgets Pickup? Flags 2 | sweet1 spraycan 0 N N N N N N N N N N N 3 | crash1 fire_ex -1 N N N N N N N N N N Y 4 | crash1 molotov -1 N N N N N N Y Y N N Y projectilecheck+explosive 5 | la1fin2 camera 0 N N N N N N N N N N N 6 | bcrash1 camera -1 N N N N N N N N N N Y 7 | bcrash1 camera 0 N N N N N N N N N N N 8 | truth2 flame 0 N N N N N N Y Y N N N flame 9 | truth2 flame -1 N N N N N N Y Y N N Y flame 10 | truth2 rocketla 0 N N Y Y Y Y Y Y N N N longrange 11 | truth2 rocketla -1 N N Y Y Y Y Y Y N N Y longrange 12 | syn6 rocketla -1 N N Y Y Y Y Y Y N N Y longrange 13 | des3 rocketla -1 N N Y Y Y Y Y Y N N Y longrange 14 | desert9 gun_para -1 N N N N N N N N N N Y 15 | desert9 gun_para -1 N N N N N N N N N N N 16 | desert9 satchel 0 N N N N N N N Y N N N explosive+noflame 17 | heist1 camera -1 N N N N N N N N N N Y 18 | heist9 gun_para -1 N N N N N N N N N N Y 19 | heist9 satchel -1 N N N N N N Y Y N N Y explosive 20 | heist9 teargas 0 N N N N N N N Y N N N projectilecheck 21 | heist9 nvgoggles 0 N N N N N N N N N Y N goggles 22 | heist9 knifecur 0 Y Y Y Y Y Y Y N Y N N 23 | heist9 mp5lng 0 Y Y Y Y Y Y Y N Y N N 24 | syn5 sniper 0 N N Y Y Y Y Y Y N N N longrange 25 | desert5 gun_para 0 N N N N N N N N N N N 26 | syn1 camera 0 N N N N N N N N N N N 27 | heist2 gun_para 0 N N N N N N N N N N N 28 | mansio1 gun_para -1 N N N N N N N N N N N 29 | cat4 satchel 0 N N N N N N Y Y N N N explosive 30 | drugs4 ak47 0 N Y Y Y Y Y Y Y N N N uselessproj 31 | finaleb nvgoggles 0 N N N N N N N N N Y N goggles 32 | finaleb fire_ex -1 N N N N N N N N N N Y 33 | finalec micro_uzi 0 N Y Y Y Y Y Y N N N N candriveby 34 | drugs1 micro_uzi 0 N Y Y Y Y Y Y N N N N candriveby 35 | casino9 colt45 0 N Y Y Y Y Y Y Y N N N uselessproj 36 | shrange colt45 -1 N Y Y Y Y Y Y N N N N noexplosives+noflame+nofps 37 | shrange micro_uzi -1 N Y Y Y Y Y Y N N N N noexplosives+noflame+nofps 38 | shrange chromegun -1 N Y Y Y Y Y Y N N N N noexplosives+noflame+nofps 39 | shrange ak47 -1 N Y Y Y Y Y Y N N N N noexplosives+noflame+nofps 40 | zero1 minigun 0 N N Y Y Y Y Y N N N N longrange+noexplosives 41 | heist5 minigun 0 N N Y N Y N Y N N N N longrange 42 | wuzi5 minigun 0 N Y Y Y Y Y Y Y N N N uselessproj 43 | sweet2 colt45 0 Y Y Y Y Y Y Y Y Y Y N 44 | maf4 micro_uzi 0 N Y Y Y N N N N N N N dualwield 45 | des10 micro_uzi 0 N Y Y Y N N N N N N N dualwield 46 | blood mp5lng 0 N N N Y N N N N N N N 47 | music3 camera -1 N N N N N N N N N Y N goggles 48 | smoke3 tec9 -1 N Y Y Y Y Y Y Y Y N N 49 | casino9 colt45 24 N Y Y Y Y Y Y Y Y N N 50 | pool2 poolcue 0 Y N N N N N N N N Y N -------------------------------------------------------------------------------- /include/colours.hh: -------------------------------------------------------------------------------- 1 | /* 2 | Rainbomizer - A (probably fun) Grand Theft Auto San Andreas Mod that 3 | randomizes stuff 4 | Copyright (C) 2019 - Parik 5 | 6 | This program is free software: you can redistribute it and/or modify 7 | it under the terms of the GNU General Public License as published by 8 | the Free Software Foundation, either version 3 of the License, or 9 | (at your option) any later version. 10 | 11 | This program is distributed in the hope that it will be useful, 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | GNU General Public License for more details. 15 | 16 | You should have received a copy of the GNU General Public License 17 | along with this program. If not, see . 18 | 19 | */ 20 | 21 | #pragma once 22 | 23 | #include 24 | #include 25 | 26 | // Hooks 27 | // - Select car colour 28 | // - Initialise car colour tables 29 | 30 | // Hooked Functions 31 | 32 | struct CRGBA; 33 | struct CRunningScript; 34 | 35 | void __fastcall RandomizeVehicleColour (void *info, void *edx, uint8_t *prim, 36 | uint8_t *secn, uint8_t *tert, 37 | uint8_t *quat, int variation); 38 | void __fastcall RandomizeScriptVehicleColours (CRunningScript *scr, void *edx, 39 | short count); 40 | template int RandomizeColourTables (); 41 | 42 | CRGBA GetRainbowColour (int offset = 0); 43 | 44 | class ColourRandomizer 45 | { 46 | static ColourRandomizer *mInstance; 47 | 48 | ColourRandomizer (){}; 49 | static void DestroyInstance (); 50 | 51 | public: 52 | static inline struct Config 53 | { 54 | bool RandomizeCarCols; 55 | bool ChangeCarColsFade; 56 | bool RandomizeMarkers; 57 | bool RandomizeText; 58 | bool RandomizeWeaponSprites; 59 | bool OldColourRandomization; 60 | 61 | bool RandomizeLights; 62 | bool ConsistentLights; 63 | bool RandomizeClouds; 64 | bool RandomizeStars; 65 | bool RandomizeRainbows; 66 | bool RandomizeFireLight; 67 | bool ChangeOnFade; 68 | 69 | bool RainbowHueCycle; 70 | 71 | bool RandomizeFades; 72 | bool CrazyMode; 73 | } m_Config; 74 | 75 | inline static std::uint32_t HudRandomizerSeed = 0; 76 | 77 | /// Returns the static instance for CarColRandomizer. 78 | static ColourRandomizer *GetInstance (); 79 | 80 | void Initialise (); 81 | 82 | struct Pattern 83 | { 84 | int ID; 85 | int colours[3]; 86 | }; 87 | }; 88 | 89 | CRGBA *__fastcall RandomizeColours (CRGBA *thisCol, void *edx, uint8_t r, 90 | uint8_t g, uint8_t b, uint8_t a); 91 | -------------------------------------------------------------------------------- /include/util/dyom/TTS.hh: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | 12 | #include "Internet.hh" 13 | #include "tts/TTSBackend.hh" 14 | 15 | class DyomRandomizerTTS 16 | { 17 | 18 | struct SpeakerVoice 19 | { 20 | std::string Voice; 21 | int Pitch; 22 | TTSBackend *Backend; 23 | bool RemoveSpeakerName; 24 | }; 25 | 26 | struct StreamEntry 27 | { 28 | enum 29 | { 30 | FREE, 31 | REQUESTED, 32 | LOADED, 33 | PLAYING 34 | } state; 35 | 36 | int objective; 37 | bool shouldPlay; 38 | HSTREAM sound; 39 | std::string text; 40 | SpeakerVoice speaker; 41 | void *data; 42 | 43 | StreamEntry (const std::string &text, SpeakerVoice &speaker, 44 | int objective) 45 | : objective (objective), text (text), speaker (speaker) 46 | { 47 | state = REQUESTED; 48 | } 49 | 50 | bool ProcessFSM (DyomRandomizerTTS &tts); 51 | }; 52 | 53 | struct QueueEntry 54 | { 55 | std::string text; 56 | SpeakerVoice speaker; 57 | int objective; 58 | bool play; 59 | }; 60 | 61 | bool areAnySoundsLoading; 62 | bool areAnySoundsPlaying; 63 | std::mutex queueMutex; 64 | std::vector streams; 65 | std::vector swearFilter; 66 | std::vector queue; 67 | std::array voices; 68 | bool voicesInitialised = false; 69 | 70 | InternetUtils internet; 71 | 72 | std::string GuessObjectiveSpeaker (const char *text); 73 | void RemoveSpeakerName (std::string &str); 74 | 75 | void ProcessStreams (); 76 | void ProcessQueue (); 77 | void CleanupStreams (); 78 | void ProcessTTS (); 79 | 80 | void ReadSwearFilterFile (); 81 | 82 | void LoadEntry (StreamEntry &entry); 83 | void EnqueueObjective (int objective, bool play); 84 | 85 | std::thread workerThread; 86 | bool running = false; 87 | bool reset = false; 88 | 89 | void BuildObjectiveSpeakerMap (); 90 | 91 | public: 92 | DyomRandomizerTTS (); 93 | ~DyomRandomizerTTS (); 94 | 95 | void SetDuration (int duration); 96 | 97 | std::string GetRandomVoice (); 98 | 99 | bool 100 | IsBusy () 101 | { 102 | return areAnySoundsLoading || areAnySoundsPlaying; 103 | } 104 | 105 | void Reset (); 106 | void PlayObjectiveSound (); 107 | }; 108 | -------------------------------------------------------------------------------- /include/objects.hh: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | class ObjectsRandomizer 6 | { 7 | static ObjectsRandomizer *mInstance; 8 | 9 | ObjectsRandomizer (){}; 10 | static void DestroyInstance (); 11 | 12 | public: 13 | /// Returns the static instance for ObjectsRandomizer. 14 | static ObjectsRandomizer *GetInstance (); 15 | 16 | /// Initialises Hooks/etc. 17 | void Initialise (); 18 | 19 | static inline std::vector goodObjects 20 | = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 21 | 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 22 | 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 43, 23 | 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 24 | 57, 58, 59, 60, 61, 62, 63, 66, 67, 68, 69, 70, 71, 25 | 72, 73, 76, 77, 78, 90, 93, 94, 95, 104, 105, 106, 107, 26 | 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 27 | 121, 123, 124, 126, 130, 135, 139, 140, 141, 142, 143, 144, 145, 28 | 146, 147, 148, 149, 150, 151, 152, 153, 155, 156, 157, 158, 160, 29 | 162, 164, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 30 | 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 31 | 190, 191, 192, 193, 194, 196, 197, 198, 199, 200, 201, 202, 203, 32 | 208, 209, 210, 211, 212, 214, 215, 216, 219, 220, 221, 222, 223, 33 | 224, 226, 227, 228, 229, 230, 231, 232, 233, 237, 238, 243, 244, 34 | 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, 256, 261, 35 | 262, 263, 264, 265, 266, 267, 268, 270, 271, 272, 273, 274, 275, 36 | 276, 277, 278, 279, 280, 281, 282, 283, 284, 285, 286, 287, 288, 37 | 290, 292, 293, 294, 295, 296, 297, 298, 300, 301, 302, 303, 304, 38 | 307, 312, 313, 315, 316, 317, 318, 319, 320, 321, 322, 323, 324, 39 | 325, 326, 327, 328, 329, 330, 331, 332, 335, 336, 337, 338, 339, 40 | 340, 341, 342, 343, 344, 345, 346, 347, 348, 349, 350, 351, 352, 41 | 353, 354, 355, 356, 357, 358, 359, 360, 361, 362, 363, 364, 365, 42 | 366, 367, 368, 369, 370, 371, 372, 373, 374, 375, 376, 377, 378, 43 | 379, 380, 381, 382, 383, 384, 385, 386, 387}; 44 | 45 | static inline std::vector destructibleObjects 46 | = {44, 66, 69, 70, 123, 139, 140, 145, 147, 158, 160, 162, 47 | 166, 168, 170, 173, 175, 176, 177, 179, 188, 189, 191, 192, 48 | 193, 198, 200, 201, 202, 209, 216, 224, 230, 231, 232, 233, 49 | 238, 261, 265, 273, 276, 277, 279, 298, 312, 316, 320, 321, 50 | 322, 323, 324, 325, 326, 329, 330, 386}; 51 | 52 | static inline std::vector objectsToIgnore 53 | = {44, 87, 88, 89, 159, 161, 222, 227, 239, 240, 241, 54 | 242, 305, 306, 307, 314, 333, 334, 336, 347}; 55 | 56 | static inline bool modifyObject = false; 57 | }; 58 | -------------------------------------------------------------------------------- /src/util/scrpt.cc: -------------------------------------------------------------------------------- 1 | #include "util/scrpt.hh" 2 | 3 | /*******************************************************/ 4 | void 5 | Scrpt::Append (const void *bytes, int size) 6 | { 7 | if (offset + size >= 128) 8 | return; 9 | memcpy (this->data + offset, bytes, size); 10 | 11 | this->offset += size; 12 | } 13 | 14 | /*******************************************************/ 15 | unsigned char * 16 | Scrpt::CreateNop (unsigned char *dst, int size) 17 | { 18 | if (size > 4) 19 | { 20 | Scrpt opcode = Scrpt (0x661); 21 | unsigned char typeId = 0xE; 22 | unsigned char length = size - 4; 23 | 24 | opcode.Append (&typeId, 1); 25 | opcode.Append (&length, 1); 26 | 27 | memcpy (dst, opcode.GetData (), opcode.offset); 28 | } 29 | else 30 | { 31 | Scrpt opcode = Scrpt (0x0); 32 | memcpy (dst, opcode.GetData (), opcode.offset); 33 | } 34 | 35 | return dst + size; 36 | } 37 | 38 | /*******************************************************/ 39 | unsigned char * 40 | Scrpt::CreateNop (unsigned char *dst, int start, int end) 41 | { 42 | return CreateNop (dst + start, end - start); 43 | } 44 | 45 | /*******************************************************/ 46 | Scrpt::~Scrpt () { delete[] data; } 47 | 48 | /*******************************************************/ 49 | Scrpt::Scrpt (short opcodeId) 50 | { 51 | this->data = new unsigned char[128]; 52 | this->offset = 0; 53 | 54 | Append (&opcodeId, sizeof (short)); 55 | } 56 | 57 | /*******************************************************/ 58 | void 59 | Scrpt::operator<< (const char *str) 60 | { 61 | unsigned char typeId = 0xE; 62 | unsigned char len = strlen (str); 63 | 64 | Append (&typeId, 1); 65 | Append (&len, 1); 66 | 67 | Append (str, len); 68 | } 69 | 70 | /*******************************************************/ 71 | void 72 | Scrpt::operator<< (int *ptr) 73 | { 74 | *this << LocalVar (this->savedParams.size ()); 75 | this->savedParams.push_back (ptr); 76 | } 77 | 78 | /*******************************************************/ 79 | void 80 | Scrpt::StoreParameters (CRunningScript *scr) 81 | { 82 | int j = 0; 83 | for (auto i : savedParams) 84 | *i = scr->m_aLocalVars[j++]; 85 | } 86 | 87 | /*******************************************************/ 88 | #define operator(ID, TYPE) \ 89 | void Scrpt::operator<< (TYPE n) \ 90 | { \ 91 | unsigned char typeId = ID; \ 92 | Append (&typeId, 1); \ 93 | Append (&n, sizeof (TYPE)); \ 94 | } 95 | 96 | operator(4, char); 97 | operator(1, int); 98 | operator(2, short); 99 | operator(6, float); 100 | operator(2, GlobalVar); 101 | operator(3, LocalVar); 102 | -------------------------------------------------------------------------------- /include/util/scrpt.hh: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include "base.hh" 4 | #include "functions.hh" 5 | #include 6 | #include 7 | 8 | struct GlobalVar 9 | { 10 | short val; 11 | GlobalVar (short val) { this->val = val * 4; } 12 | }; 13 | struct LocalVar 14 | { 15 | short val; 16 | LocalVar (short val) { this->val = val; } 17 | }; 18 | 19 | /*******************************************************/ 20 | class Scrpt 21 | { 22 | unsigned char * data; 23 | int offset; 24 | std::vector savedParams; 25 | 26 | void Append (const void *bytes, int size); 27 | 28 | public: 29 | Scrpt (short opcodeId); 30 | ~Scrpt (); 31 | 32 | unsigned char * 33 | GetData () 34 | { 35 | return data; 36 | }; 37 | 38 | void operator<< (char n); 39 | void operator<< (int n); 40 | void operator<< (short n); 41 | void operator<< (float n); 42 | void operator<< (GlobalVar n); 43 | void operator<< (LocalVar n); 44 | void operator<< (int *n); 45 | void operator<< (const char *str); 46 | 47 | void StoreParameters (CRunningScript *scr); 48 | 49 | /*******************************************************/ 50 | template 51 | void 52 | Pack (T value) 53 | { 54 | operator<< (value); 55 | } 56 | 57 | /*******************************************************/ 58 | template 59 | void 60 | Pack (First first, Rest... rest) 61 | { 62 | Pack (first); 63 | Pack (rest...); 64 | } 65 | 66 | void 67 | Pack () 68 | { 69 | } 70 | 71 | /*******************************************************/ 72 | template 73 | static unsigned char * 74 | CreateOpcode (short opcodeId, const char *name, unsigned char *dst, 75 | Args... args) 76 | { 77 | Scrpt opcode = Scrpt (opcodeId); 78 | opcode.Pack (args...); 79 | 80 | memcpy (dst, opcode.GetData (), opcode.offset); 81 | return dst + opcode.offset; 82 | } 83 | 84 | static unsigned char *CreateNop (unsigned char *dst, int size); 85 | static unsigned char *CreateNop (unsigned char *dst, int start, int end); 86 | 87 | /*******************************************************/ 88 | template 89 | static void 90 | CallOpcode (short opcodeId, const char *name, Args... args) 91 | { 92 | CRunningScript scr; 93 | scr.Init (); 94 | 95 | Scrpt opcode = Scrpt (opcodeId); 96 | opcode.Pack (args...); 97 | 98 | scr.m_pBaseIP = opcode.GetData (); 99 | scr.m_pCurrentIP = scr.m_pBaseIP; 100 | 101 | static std::unique_ptr originalScriptParams (new int[10]); 102 | memcpy (originalScriptParams.get (), ScriptParams, 10 * sizeof (int)); 103 | 104 | scr.ProcessOneCommand (); 105 | opcode.StoreParameters (&scr); 106 | 107 | memcpy (ScriptParams, originalScriptParams.get (), 10 * sizeof (int)); 108 | } 109 | }; 110 | -------------------------------------------------------------------------------- /src/logger.cc: -------------------------------------------------------------------------------- 1 | /* 2 | Rainbomizer - A (probably fun) Grand Theft Auto San Andreas Mod that 3 | randomizes stuff 4 | Copyright (C) 2019 - Parik 5 | 6 | This program is free software: you can redistribute it and/or modify 7 | it under the terms of the GNU General Public License as published by 8 | the Free Software Foundation, either version 3 of the License, or 9 | (at your option) any later version. 10 | 11 | This program is distributed in the hope that it will be useful, 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | GNU General Public License for more details. 15 | 16 | You should have received a copy of the GNU General Public License 17 | along with this program. If not, see . 18 | 19 | */ 20 | 21 | #include "logger.hh" 22 | #include 23 | #include 24 | #include "base.hh" 25 | 26 | Logger * Logger::mInstance = nullptr; 27 | std::string Logger::mFileName = ""; 28 | 29 | #ifndef NDEBUG 30 | #define RAINBOMIZER_BUILD "Debug Build: " __DATE__ " " __TIME__ 31 | #else 32 | #define RAINBOMIZER_BUILD "Build v3.2" 33 | #endif 34 | 35 | /*******************************************************/ 36 | std::string 37 | GetTimeNow () 38 | { 39 | time_t currentTime; 40 | char str[256]; 41 | 42 | time (¤tTime); 43 | 44 | auto tm = std::localtime (¤tTime); 45 | sprintf (str, "%02d-%02d-%04d", tm->tm_mday, tm->tm_mon + 1, 46 | 1900 + tm->tm_year); 47 | 48 | return str; 49 | } 50 | 51 | /*******************************************************/ 52 | Logger::Logger () 53 | { 54 | 55 | mFile = OpenRainbomizerFile (GetTimeNow () + ".txt", "a+", "logs/"); 56 | 57 | if (!mFile) 58 | return; 59 | 60 | // Print initial message/time 61 | fprintf (mFile, "===========================================\n"); 62 | fprintf (mFile, "%d\n", (int) time (NULL)); 63 | fprintf (mFile, "Rainbomizer Build: %s \n", RAINBOMIZER_BUILD); 64 | fprintf (mFile, "===========================================\n"); 65 | } 66 | 67 | /*******************************************************/ 68 | Logger::~Logger () 69 | { 70 | if (mFile) 71 | fclose (mFile); 72 | } 73 | 74 | /*******************************************************/ 75 | void 76 | Logger::DestroyLogger () 77 | { 78 | if (Logger::mInstance) 79 | delete Logger::mInstance; 80 | } 81 | 82 | /*******************************************************/ 83 | Logger * 84 | Logger::GetLogger () 85 | { 86 | if (!Logger::mInstance) 87 | { 88 | Logger::mInstance = new Logger (); 89 | atexit (&Logger::DestroyLogger); 90 | } 91 | return Logger::mInstance; 92 | } 93 | 94 | /*******************************************************/ 95 | void 96 | Logger::LogMessage (std::string message) 97 | { 98 | if (!mFile) 99 | return; 100 | 101 | fprintf (mFile, "[%d]: %s\n", (int) time (NULL), message.c_str ()); 102 | fflush (mFile); 103 | } 104 | -------------------------------------------------------------------------------- /include/hooks.hh: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | namespace Rainbomizer { 6 | 7 | template class FunctionCb 8 | { 9 | public: 10 | uintptr_t address = 0; 11 | 12 | template 13 | Ret 14 | Call (Args... args) 15 | { 16 | if constexpr (Method) 17 | return reinterpret_cast (address) ( 18 | args...); 19 | else 20 | return reinterpret_cast (address) ( 21 | args...); 22 | } 23 | 24 | template 25 | Ret 26 | operator() (Args... args) 27 | { 28 | if (address != 0) 29 | return Call (args...); 30 | } 31 | 32 | explicit operator bool () const { return address != 0; } 33 | 34 | void 35 | SetAddress (uint32_t addr) 36 | { 37 | address = addr; 38 | } 39 | }; 40 | 41 | class HookType 42 | { 43 | public: 44 | struct CALL 45 | { 46 | static uintptr_t 47 | Hook (uintptr_t src, uintptr_t dest) 48 | { 49 | uintptr_t orig = injector::GetBranchDestination (src).as_int (); 50 | injector::MakeCALL (src, dest); 51 | 52 | return orig; 53 | } 54 | }; 55 | 56 | struct JMP 57 | { 58 | static uintptr_t 59 | Hook (uintptr_t src, uintptr_t dest) 60 | { 61 | std::uint32_t orig = injector::GetBranchDestination (src).as_int (); 62 | injector::MakeJMP (src, dest); 63 | 64 | return orig; 65 | } 66 | }; 67 | }; 68 | 69 | class HooksManager 70 | { 71 | private: 72 | template 73 | static Ret 74 | Trampoline (Args... args) 75 | { 76 | return Cb (Orig, args...); 77 | } 78 | 79 | template 80 | struct RegisterHookClass; 81 | 82 | template 84 | struct RegisterHookClass 85 | { 86 | template 87 | static void 88 | Register () 89 | { 90 | static OrigType origType; 91 | origType.SetAddress (HookType::Hook ( 92 | addr, std::uintptr_t (Trampoline))); 93 | } 94 | }; 95 | 96 | public: 97 | template 98 | static void 99 | Add () 100 | { 101 | (..., RegisterHookClass::template Register ()); 103 | } 104 | 105 | template 106 | static void 107 | Add () 108 | { 109 | (..., RegisterHookClass::template Register ()); 111 | } 112 | }; 113 | 114 | } // namespace Rainbomizer 115 | -------------------------------------------------------------------------------- /src/wanted.cc: -------------------------------------------------------------------------------- 1 | #include "wanted.hh" 2 | #include 3 | #include "logger.hh" 4 | #include "base.hh" 5 | #include "config.hh" 6 | #include "functions.hh" 7 | #include "injector/calling.hpp" 8 | #include 9 | 10 | WantedLevelRandomizer *WantedLevelRandomizer::mInstance = nullptr; 11 | float WantedLevelRandomizer::mNextChaosPoints = 0; 12 | 13 | /*******************************************************/ 14 | bool 15 | RandomizeChaosIncrement () 16 | { 17 | WantedLevelRandomizer::GetInstance ()->RandomizeChaosPoints (); 18 | return HookManager::CallOriginalAndReturn, 19 | 0x56218E> (false); 20 | } 21 | 22 | /*******************************************************/ 23 | void __fastcall RandomizeMissionWantedLevel (CRunningScript *scr, void *edx, 24 | short count) 25 | { 26 | scr->CollectParameters (count); 27 | if (ScriptParams[1] != 0) 28 | { 29 | bool greater = (bool) random (1); 30 | if (!greater) 31 | ScriptParams[1] = random (1, ScriptParams[1]); 32 | else 33 | ScriptParams[1] = random (ScriptParams[1], 6); 34 | } 35 | } 36 | 37 | /*******************************************************/ 38 | void 39 | WantedLevelRandomizer::RandomizeChaosPoints () 40 | { 41 | mNextChaosPoints = int (randomNormal (0.016, 0.1) * 3000); 42 | } 43 | 44 | /*******************************************************/ 45 | void 46 | WantedLevelRandomizer::Initialise () 47 | { 48 | if (!ConfigManager::ReadConfig ("WantedLevelRandomizer", 49 | std::pair ("RandomizeMissionWantedLevels", 50 | &m_Config.RandomizeMission), 51 | std::pair ("RandomizeChaosPoints", 52 | &m_Config.RandomizeChaos))) 53 | return; 54 | 55 | for (auto ref : 56 | {0x5621BB, 0x5621CA, 0x5621D9, 0x5621E5, 0x5621F1, 0x5621FD, 0x562209, 57 | 0x562215, 0x562221, 0x56222D, 0x562239, 0x562245, 0x562251}) 58 | { 59 | injector::WriteMemory (ref + 2, &mNextChaosPoints); 60 | } 61 | 62 | if (m_Config.RandomizeChaos) 63 | RegisterHooks ( 64 | {{HOOK_CALL, 0x56218E, (void *) RandomizeChaosIncrement}}); 65 | 66 | if (m_Config.RandomizeMission) 67 | RegisterHooks ( 68 | {{HOOK_CALL, 0x4699BF, (void *) RandomizeMissionWantedLevel}, 69 | {HOOK_CALL, 0x4699EC, (void *) RandomizeMissionWantedLevel}}); 70 | Logger::GetLogger ()->LogMessage ("Intialised WantedLevelRandomizer"); 71 | } 72 | 73 | /*******************************************************/ 74 | 75 | /*******************************************************/ 76 | void 77 | WantedLevelRandomizer::DestroyInstance () 78 | { 79 | if (WantedLevelRandomizer::mInstance) 80 | delete WantedLevelRandomizer::mInstance; 81 | } 82 | 83 | /*******************************************************/ 84 | WantedLevelRandomizer * 85 | WantedLevelRandomizer::GetInstance () 86 | { 87 | if (!WantedLevelRandomizer::mInstance) 88 | { 89 | WantedLevelRandomizer::mInstance = new WantedLevelRandomizer (); 90 | atexit (&WantedLevelRandomizer::DestroyInstance); 91 | } 92 | return WantedLevelRandomizer::mInstance; 93 | } 94 | -------------------------------------------------------------------------------- /src/blips.cc: -------------------------------------------------------------------------------- 1 | #include "blips.hh" 2 | #include 3 | #include "logger.hh" 4 | #include "injector/calling.hpp" 5 | #include "base.hh" 6 | #include "functions.hh" 7 | #include "config.hh" 8 | #include "fades.hh" 9 | 10 | BlipRandomizer *BlipRandomizer::mInstance = nullptr; 11 | static int northIcon = random (2, 63); 12 | 13 | /*******************************************************/ 14 | void 15 | RandomizeBlipSprite (int blipHandle, char spriteId) 16 | { 17 | spriteId = random (2, 63); 18 | injector::cstd::call (0x583D70, blipHandle, spriteId); 19 | } 20 | 21 | /*******************************************************/ 22 | void 23 | RandomizeBlipsOnStart () 24 | { 25 | injector::cstd::call (0x5D53C0); 26 | 27 | int radarTrace = 0xBA86F0 + 0x24; 28 | for (int i = 0; i < 175; i++) 29 | { 30 | if (injector::ReadMemory (radarTrace) > 0) 31 | injector::WriteMemory (radarTrace, random (2, 63)); 32 | radarTrace += 40; 33 | } 34 | northIcon = random (2, 63); 35 | } 36 | 37 | /*******************************************************/ 38 | void 39 | FixLegendCrash (float x, float y, char *text) 40 | { 41 | if (int (text) < 0x2000) 42 | text = (char *) "Boohoo"; 43 | 44 | HookManager::CallOriginal, 45 | 0x582DEE> (x, y, text); 46 | } 47 | 48 | /*******************************************************/ 49 | void 50 | RandomizeNorthIcon (int iconID, float x, float y, uint8_t alpha) 51 | { 52 | iconID = northIcon; 53 | injector::cstd::call (0x585FF0, iconID, 54 | x, y, alpha); 55 | } 56 | 57 | /*******************************************************/ 58 | int 59 | DisplayBlipsInInteriors (int a1, char a2) 60 | { 61 | return 1; 62 | } 63 | 64 | /*******************************************************/ 65 | void 66 | BlipRandomizer::Initialise () 67 | { 68 | if (!ConfigManager::ReadConfig ("BlipRandomizer")) 69 | return; 70 | 71 | Logger::GetLogger ()->LogMessage ("Intialised BlipRandomizer"); 72 | RegisterHooks ({ 73 | {HOOK_CALL, 0x5D1948, (void *) RandomizeBlipsOnStart}, 74 | {HOOK_CALL, 0x582DEE, (void *) FixLegendCrash}, 75 | {HOOK_CALL, 0x588188, (void *) RandomizeNorthIcon}, 76 | {HOOK_JUMP, 0x583B40, (void *) DisplayBlipsInInteriors}, 77 | }); 78 | for (auto i : {0x444403, 0x47F7FE, 0x48BCA8, 0x48DBE1, 0x5775DD}) 79 | injector::MakeCALL (i, (void *) RandomizeBlipSprite); 80 | 81 | FadesManager::AddFadeCallback ([] { northIcon = random (2, 63); }); 82 | } 83 | 84 | /*******************************************************/ 85 | void 86 | BlipRandomizer::DestroyInstance () 87 | { 88 | if (BlipRandomizer::mInstance) 89 | delete BlipRandomizer::mInstance; 90 | } 91 | 92 | /*******************************************************/ 93 | BlipRandomizer * 94 | BlipRandomizer::GetInstance () 95 | { 96 | if (!BlipRandomizer::mInstance) 97 | { 98 | BlipRandomizer::mInstance = new BlipRandomizer (); 99 | atexit (&BlipRandomizer::DestroyInstance); 100 | } 101 | return BlipRandomizer::mInstance; 102 | } 103 | -------------------------------------------------------------------------------- /src/util/HSL.hh: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "CMath.hh" 4 | #include 5 | #include 6 | 7 | namespace Rainbomizer { 8 | 9 | struct CARGB 10 | { 11 | union 12 | { 13 | struct 14 | { 15 | unsigned char b; 16 | unsigned char g; 17 | unsigned char r; 18 | unsigned char a; 19 | }; 20 | int colour; 21 | }; 22 | 23 | CARGB (unsigned char a, unsigned char r, unsigned char g, unsigned char b) 24 | { 25 | this->a = a; 26 | this->r = r; 27 | this->g = g; 28 | this->b = b; 29 | } 30 | 31 | CARGB () = default; 32 | 33 | bool 34 | operator== (const CARGB &rhs) const 35 | { 36 | return rhs.colour == this->colour; 37 | } 38 | bool 39 | operator!= (const CARGB &rhs) const 40 | { 41 | return !(rhs == *this); 42 | } 43 | }; 44 | 45 | struct ColorFloat 46 | { 47 | float r; 48 | float g; 49 | float b; 50 | 51 | ColorFloat () = default; 52 | 53 | ColorFloat (float r, float g, float b) : r (r), g (g), b (b) {} 54 | 55 | ColorFloat (const CARGB &argb) 56 | { 57 | r = argb.r / 255.0f; 58 | g = argb.g / 255.0f; 59 | b = argb.b / 255.0f; 60 | } 61 | 62 | CARGB 63 | ToARGB () 64 | { 65 | return CARGB{255, static_cast (r * 255), 66 | static_cast (g * 255), 67 | static_cast (b * 255)}; 68 | } 69 | }; 70 | 71 | struct HSL 72 | { 73 | float h; 74 | float s; 75 | float l; 76 | 77 | HSL () = default; 78 | 79 | HSL (float h, float s, float l) : h (h), s (s), l (l){}; 80 | 81 | HSL (const ColorFloat &input) 82 | { 83 | float R = input.r; 84 | float G = input.g; 85 | float B = input.b; 86 | 87 | float Xmax = std::max ({R, G, B}); 88 | float Xmin = std::min ({R, G, B}); 89 | float C = Xmax - Xmin; 90 | 91 | this->l = (Xmax + Xmin) / 2; 92 | if (C == 0) 93 | this->h = 0; 94 | else if (fabs (Xmax - R) < 0.01) 95 | this->h = 60 * (0 + ((G - B) / C)); 96 | else if (fabs (Xmax - G) < 0.01) 97 | this->h = 60 * (2 + ((B - R) / C)); 98 | else if (fabs (Xmax - B) < 0.01) 99 | this->h = 60 * (4 + ((R - G) / C)); 100 | 101 | if (this->l == 0 || this->l == 1) 102 | this->s = 0; 103 | else 104 | this->s = C / (1 - (fabs (2 * Xmax - C - 1))); 105 | } 106 | 107 | ColorFloat 108 | ToColorFloat () const 109 | { 110 | auto f = [this] (float n) { 111 | float k = fmod ((n + (this->h / 30)), 12); 112 | float a = this->s * std::min (this->l, 1 - this->l); 113 | float f 114 | = this->l 115 | - a 116 | * std::max (-1.0f, 117 | std::min (k - 3, std::min (9 - k, 1.0f))); 118 | return f; 119 | }; 120 | 121 | return ColorFloat{f (0), f (8), f (4)}; 122 | } 123 | 124 | CARGB 125 | ToARGB () const { return ToColorFloat ().ToARGB (); } 126 | 127 | operator CARGB () const { return ToARGB (); } 128 | 129 | operator ColorFloat () const { return ToColorFloat (); } 130 | }; 131 | } // namespace Rainbomizer 132 | -------------------------------------------------------------------------------- /include/util/dyom/Internet.hh: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | class InternetUtils 10 | { 11 | HANDLE session; 12 | HINTERNET internet; 13 | 14 | public: 15 | 16 | class Request 17 | { 18 | HANDLE handle; 19 | 20 | public: 21 | /*******************************************************/ 22 | std::string 23 | GetString () 24 | { 25 | std::vector output; 26 | GetResponse (output); 27 | 28 | return std::string (output.begin (), output.end ()).c_str (); 29 | } 30 | 31 | /*******************************************************/ 32 | bool 33 | GetResponse (std::vector &out) 34 | { 35 | DWORD dwSize = 16000; 36 | DWORD dwDownloaded; 37 | 38 | auto lpszData = new TCHAR[dwSize + 1]; 39 | 40 | for (;;) 41 | { 42 | if (!InternetReadFile (handle, lpszData, dwSize, 43 | &dwDownloaded)) 44 | break; 45 | 46 | if (dwDownloaded == 0) 47 | break; 48 | 49 | out.insert (out.end (), lpszData, lpszData + dwDownloaded); 50 | } 51 | 52 | delete[] lpszData; 53 | 54 | return true; 55 | } 56 | 57 | Request (HANDLE handle) : handle (handle) {} 58 | ~Request () { InternetCloseHandle (handle); } 59 | }; 60 | 61 | void 62 | Open (const std::string &domain) 63 | { 64 | internet = InternetOpen ("123robot", INTERNET_OPEN_TYPE_PRECONFIG, NULL, 65 | NULL, 0); 66 | 67 | if (!internet) 68 | throw std::runtime_error ( 69 | "Failed to connect to the internet!. Error Code: " 70 | + std::to_string (GetLastError ())); 71 | 72 | session = InternetConnect (internet, domain.c_str (), 73 | INTERNET_DEFAULT_HTTPS_PORT, NULL, NULL, 74 | INTERNET_SERVICE_HTTP, 0, 0); 75 | 76 | if (!session) 77 | throw std::runtime_error ( 78 | "Failed to connect to the DWOM website!. Error Code: " 79 | + std::to_string (GetLastError ())); 80 | } 81 | 82 | void Close () 83 | { 84 | CloseHandle (session); 85 | CloseHandle (internet); 86 | } 87 | 88 | /*******************************************************/ 89 | Request 90 | Get (const std::string &file) 91 | { 92 | HANDLE request = HttpOpenRequest (session, "GET", file.c_str (), NULL, 93 | NULL, NULL, INTERNET_FLAG_SECURE, 0); 94 | HttpSendRequest (request, NULL, 0, NULL, 0); 95 | 96 | return request; 97 | } 98 | 99 | /*******************************************************/ 100 | Request 101 | Post (const std::string &url, const std::string &headers, 102 | const std::string &data) 103 | { 104 | HANDLE request = HttpOpenRequest (session, "POST", url.c_str (), NULL, 105 | NULL, NULL, INTERNET_FLAG_SECURE, 0); 106 | HttpSendRequest (request, headers.c_str (), headers.length (), 107 | (char *) data.c_str (), data.length ()); 108 | 109 | return request; 110 | } 111 | }; 112 | -------------------------------------------------------------------------------- /include/traffic.hh: -------------------------------------------------------------------------------- 1 | /* 2 | Rainbomizer - A (probably fun) Grand Theft Auto San Andreas Mod that 3 | randomizes stuff 4 | Copyright (C) 2019 - Parik 5 | 6 | This program is free software: you can redistribute it and/or modify 7 | it under the terms of the GNU General Public License as published by 8 | the Free Software Foundation, either version 3 of the License, or 9 | (at your option) any later version. 10 | 11 | This program is distributed in the hope that it will be useful, 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | GNU General Public License for more details. 15 | 16 | You should have received a copy of the GNU General Public License 17 | along with this program. If not, see . 18 | 19 | */ 20 | 21 | #pragma once 22 | 23 | #include "base.hh" 24 | #include 25 | 26 | struct cVehicleParams; 27 | struct CAEVehicleAudioEntity; 28 | struct CPed; 29 | struct CVehicle; 30 | 31 | // Hooked Functions 32 | int RandomizePoliceCars (); 33 | int RandomizeTrafficCars (int *type); 34 | int RandomizeCarToLoad (); 35 | void FixEmptyPoliceCars (uint8_t *vehicle, char a3); 36 | void *RandomizeCarPeds (int type, int model, float *pos, bool unk); 37 | void *__fastcall FixCopCrash (CPed *ped, void *edx, int type); 38 | void __fastcall FixFreightTrainCrash (CAEVehicleAudioEntity *audio, void *edx, 39 | cVehicleParams *vehicle_params); 40 | void __fastcall PlaceOnRoadFix (CVehicle *vehicle, void *edx); 41 | int ChoosePoliceVehicleBasedOnModel (int model); 42 | template 43 | void *__fastcall RandomizeRoadblocks (CVehicle *vehicle, void *edx, int model, 44 | char createdBy, 45 | char setupSuspensionLines); 46 | 47 | /// Randomizes cars that spawn in traffic including the police cars 48 | class TrafficRandomizer 49 | { 50 | bool mInitialVehiclesLoaded = false; 51 | static TrafficRandomizer *mInstance; 52 | 53 | unsigned char mOriginalData[5]; 54 | 55 | TrafficRandomizer (){}; 56 | static void DestroyInstance (); 57 | 58 | void FixTrainSpawns (); 59 | 60 | public: 61 | std::deque mMostRecentSpawnedVehicles; 62 | std::deque mMostRecentLoadedVehicles; 63 | int mForcedCar = 0; 64 | 65 | static inline struct Config 66 | { 67 | int ForcedVehicleID; 68 | 69 | bool Trains; 70 | bool Boats; 71 | bool Aircraft; 72 | bool Cars; 73 | bool Bikes; 74 | bool Trailers; 75 | 76 | int DefaultModel; 77 | } m_Config; 78 | 79 | /// Initialises Hooks/etc. 80 | void Initialise (); 81 | 82 | void Install6AF420_Hook (); 83 | void Revert6AF420_Hook (); 84 | 85 | bool IsVehicleAllowed (int model); 86 | 87 | void MakeRCsEnterable (); 88 | 89 | /// Exception Handling 90 | static void ExceptionHandlerCallback (_EXCEPTION_POINTERS *ep); 91 | 92 | /// Sets an overridden car for always spawning in traffic 93 | void 94 | SetForcedRandomCar (int car) 95 | { 96 | mForcedCar = car; 97 | }; 98 | 99 | /// Gets instance for TrafficRandomizer 100 | static TrafficRandomizer *GetInstance (); 101 | 102 | friend int RandomizeTrafficCars (int *type); 103 | friend int RandomizeCarToLoad (); 104 | friend int RandomizePoliceCars (); 105 | friend void LoadRandomVehiclesAtStart (); 106 | }; 107 | -------------------------------------------------------------------------------- /src/animations.cc: -------------------------------------------------------------------------------- 1 | #include "animations.hh" 2 | #include 3 | #include "logger.hh" 4 | #include "base.hh" 5 | #include "functions.hh" 6 | #include "injector/calling.hpp" 7 | #include "fades.hh" 8 | #include "config.hh" 9 | 10 | AnimationRandomizer *AnimationRandomizer::mInstance = nullptr; 11 | 12 | /*******************************************************/ 13 | CAnimBlendAssocGroup * 14 | GetRandomGroup (int anim) 15 | { 16 | std::vector mValidGroups; 17 | for (int i = 0; i < CAnimBlendAssocGroup::ms_numAnimAssocDefinitions; i++) 18 | { 19 | auto &group = CAnimBlendAssocGroup::ms_aAnimAssocGroups[i]; 20 | if (group.pAnimBlock && group.pAnimBlock->bLoaded 21 | && group.iNumAnimations >= anim) 22 | mValidGroups.push_back (i); 23 | } 24 | 25 | return &CAnimBlendAssocGroup::ms_aAnimAssocGroups[mValidGroups[random ( 26 | mValidGroups.size () - 1)]]; 27 | } 28 | 29 | /*******************************************************/ 30 | CAnimBlendAssociation *__fastcall RandomizeAnimation ( 31 | CAnimBlendAssocGroup *group, void *edx, int animation) 32 | { 33 | int newAnim = random (group->iNumAnimations - 1) + group->iIDOffset; 34 | return group->CopyAnimation (newAnim); 35 | } 36 | 37 | /*******************************************************/ 38 | CAnimationStyleDescriptor * 39 | AnimationRandomizer::AddAnimAssocDefinition (const char *p1, const char *p2, 40 | int p3, unsigned int p4, void *p5) 41 | { 42 | auto desc = HookManager::CallOriginalAndReturn< 43 | injector::cstd, 45 | 0x5BC99C> ([] () { return nullptr; }, p1, p2, p3, p4, p5); 46 | 47 | GetInstance ()->mAnimAssocDefs.push_back (desc); 48 | return desc; 49 | } 50 | 51 | /*******************************************************/ 52 | void 53 | AnimationRandomizer::RandomizeAnimAssocDefs () 54 | { 55 | auto &defs = GetInstance ()->mAnimAssocDefs; 56 | for (auto def : defs) 57 | { 58 | for (int i = 0; i < def->animsCount; i++) 59 | { 60 | CAnimationStyleDescriptor *def2 61 | = defs[random (defs.size () - 1)]; 62 | std::swap (def->animNames[i], def2->animNames[i]); 63 | } 64 | } 65 | } 66 | 67 | /*******************************************************/ 68 | void 69 | AnimationRandomizer::Initialise () 70 | { 71 | if (!ConfigManager::ReadConfig ("AnimationRandomizer")) 72 | return; 73 | 74 | RegisterHooks ({{HOOK_CALL, 0x5BC99C, (void *) AddAnimAssocDefinition}}); 75 | FadesManager::AddFadeCallback (RandomizeAnimAssocDefs); 76 | 77 | RegisterHooks ({{HOOK_CALL, 0x4D3AB7, (void *) RandomizeAnimation}, 78 | {HOOK_CALL, 0x4D3A55, (void *) RandomizeAnimation}, 79 | {HOOK_CALL, 0x4D3B47, (void *) RandomizeAnimation}}); 80 | Logger::GetLogger ()->LogMessage ("Intialised AnimationRandomizer"); 81 | } 82 | 83 | /*******************************************************/ 84 | void 85 | AnimationRandomizer::DestroyInstance () 86 | { 87 | if (AnimationRandomizer::mInstance) 88 | delete AnimationRandomizer::mInstance; 89 | } 90 | 91 | /*******************************************************/ 92 | AnimationRandomizer * 93 | AnimationRandomizer::GetInstance () 94 | { 95 | if (!AnimationRandomizer::mInstance) 96 | { 97 | AnimationRandomizer::mInstance = new AnimationRandomizer (); 98 | atexit (&AnimationRandomizer::DestroyInstance); 99 | } 100 | return AnimationRandomizer::mInstance; 101 | } 102 | -------------------------------------------------------------------------------- /src/cheats.cc: -------------------------------------------------------------------------------- 1 | /* 2 | Rainbomizer - A (probably fun) Grand Theft Auto San Andreas Mod that 3 | randomizes stuff 4 | Copyright (C) 2019 - Parik 5 | 6 | This program is free software: you can redistribute it and/or modify 7 | it under the terms of the GNU General Public License as published by 8 | the Free Software Foundation, either version 3 of the License, or 9 | (at your option) any later version. 10 | 11 | This program is distributed in the hope that it will be useful, 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | GNU General Public License for more details. 15 | 16 | You should have received a copy of the GNU General Public License 17 | along with this program. If not, see . 18 | 19 | */ 20 | 21 | #include "cheats.hh" 22 | #include 23 | #include "logger.hh" 24 | #include "base.hh" 25 | #include "functions.hh" 26 | #include 27 | #include "config.hh" 28 | 29 | CheatRandomizer *CheatRandomizer::mInstance = nullptr; 30 | 31 | std::string chits[] = {"Chit Activated", "Cabbage", "Giant Pizza Activated", 32 | "Beep Boop Boop Beep"}; 33 | 34 | /*******************************************************/ 35 | const char *__fastcall RandomizeHashesAfterCheatActivated (CText *text, 36 | void *edx, char *key) 37 | { 38 | CheatRandomizer::GetInstance ()->RandomizeCheatHashes (); 39 | 40 | if (CheatRandomizer::m_Config.EasterEgg) 41 | { 42 | int chits_len = sizeof (chits) / sizeof (chits[0]); 43 | const char *chit = chits[random (chits_len - 1)].c_str (); 44 | 45 | return chit; 46 | } 47 | 48 | return text->Get (key); 49 | } 50 | 51 | /*******************************************************/ 52 | void 53 | CheatRandomizer::Initialise () 54 | { 55 | if (!ConfigManager::ReadConfig ("CheatRandomizer", 56 | std::pair ("EnableEasterEgg", 57 | &m_Config.EasterEgg))) 58 | return; 59 | 60 | Logger::GetLogger ()->LogMessage ("Intialised CheatRandomizer"); 61 | RegisterHooks ( 62 | {{HOOK_CALL, 0x43854D, (void *) &RandomizeHashesAfterCheatActivated}}); 63 | 64 | RandomizeCheatHashes (); 65 | } 66 | 67 | /*******************************************************/ 68 | void 69 | CheatRandomizer::DestroyInstance () 70 | { 71 | if (CheatRandomizer::mInstance) 72 | delete CheatRandomizer::mInstance; 73 | } 74 | 75 | /*******************************************************/ 76 | bool 77 | CheatRandomizer::ShouldActivate () 78 | { 79 | int currentTime = time (NULL); 80 | if (mTimer == 0) 81 | { 82 | mTimer = currentTime; 83 | return false; 84 | } 85 | if (mTimer + 20 < currentTime) 86 | { 87 | mTimer = currentTime; 88 | return true; 89 | } 90 | 91 | return false; 92 | } 93 | 94 | /*******************************************************/ 95 | void 96 | CheatRandomizer::RandomizeCheatHashes () 97 | { 98 | const int CHEAT_HASH_COUNT = 92; 99 | 100 | unsigned int *aCheatHashKeys = (unsigned int *) 0x8A5CC8; 101 | for (int i = 0; i < CHEAT_HASH_COUNT; i++) 102 | { 103 | int temp = aCheatHashKeys[i]; 104 | int swap = random (CHEAT_HASH_COUNT - 1); 105 | 106 | aCheatHashKeys[i] = aCheatHashKeys[swap]; 107 | aCheatHashKeys[swap] = temp; 108 | } 109 | } 110 | 111 | /*******************************************************/ 112 | CheatRandomizer * 113 | CheatRandomizer::GetInstance () 114 | { 115 | if (!CheatRandomizer::mInstance) 116 | { 117 | CheatRandomizer::mInstance = new CheatRandomizer (); 118 | atexit (&CheatRandomizer::DestroyInstance); 119 | } 120 | return CheatRandomizer::mInstance; 121 | } 122 | -------------------------------------------------------------------------------- /src/cgen.cc: -------------------------------------------------------------------------------- 1 | /* 2 | Rainbomizer - A (probably fun) Grand Theft Auto San Andreas Mod that 3 | randomizes stuff 4 | Copyright (C) 2019 - Parik 5 | 6 | This program is free software: you can redistribute it and/or modify 7 | it under the terms of the GNU General Public License as published by 8 | the Free Software Foundation, either version 3 of the License, or 9 | (at your option) any later version. 10 | 11 | This program is distributed in the hope that it will be useful, 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | GNU General Public License for more details. 15 | 16 | You should have received a copy of the GNU General Public License 17 | along with this program. If not, see . 18 | 19 | */ 20 | 21 | #include "cgen.hh" 22 | #include 23 | #include "logger.hh" 24 | #include "base.hh" 25 | #include "functions.hh" 26 | #include "traffic.hh" 27 | #include "config.hh" 28 | #include "scm.hh" 29 | #include 30 | 31 | ParkedCarRandomizer *ParkedCarRandomizer::mInstance = nullptr; 32 | 33 | /*******************************************************/ 34 | void 35 | ParkedCarRandomizer::Initialise () 36 | { 37 | if (!ConfigManager::ReadConfig ( 38 | "ParkedCarRandomizer", 39 | std::pair ("RandomizeFixedSpawns", &m_Config.RandomizeFixedSpawns), 40 | std::pair ("RandomizeRandomSpawns", 41 | &m_Config.RandomizeRandomSpawns), 42 | std::pair ("RandomizeToSameType", &m_Config.UseSameType))) 43 | return; 44 | 45 | if (m_Config.RandomizeRandomSpawns) 46 | RegisterHooks ({{HOOK_CALL, 0x6F3583, (void *) &RandomizeRandomSpawn}}); 47 | 48 | if (m_Config.RandomizeFixedSpawns) 49 | RegisterHooks ({{HOOK_CALL, 0x6F3EC1, (void *) &RandomizeFixedSpawn}}); 50 | 51 | Logger::GetLogger ()->LogMessage ("Intialised ParkedCarRandomizer"); 52 | } 53 | 54 | /*******************************************************/ 55 | void 56 | ParkedCarRandomizer::DestroyInstance () 57 | { 58 | if (ParkedCarRandomizer::mInstance) 59 | delete ParkedCarRandomizer::mInstance; 60 | } 61 | 62 | /*******************************************************/ 63 | ParkedCarRandomizer * 64 | ParkedCarRandomizer::GetInstance () 65 | { 66 | if (!ParkedCarRandomizer::mInstance) 67 | { 68 | ParkedCarRandomizer::mInstance = new ParkedCarRandomizer (); 69 | atexit (&ParkedCarRandomizer::DestroyInstance); 70 | } 71 | return ParkedCarRandomizer::mInstance; 72 | } 73 | 74 | /*******************************************************/ 75 | int 76 | GetRandomCarOfType (int originalCar) 77 | { 78 | for (auto &i : ScriptVehicleRandomizer::carTypes) 79 | { 80 | if (std::find (i.begin (), i.end (), originalCar) != i.end ()) 81 | { 82 | return GetRandomElement (i); 83 | } 84 | } 85 | return random (400, 611); 86 | } 87 | 88 | /*******************************************************/ 89 | /* This function hooks the CheckForBlockage function of a car generator 90 | to change the model index of a car generator. */ 91 | /*******************************************************/ 92 | void __fastcall RandomizeFixedSpawn (CCarGenerator *gen) 93 | { 94 | auto oldModel = gen->m_nModelId; 95 | 96 | if (!ParkedCarRandomizer::m_Config.UseSameType) 97 | gen->m_nModelId = random (400, 611); 98 | else 99 | gen->m_nModelId = GetRandomCarOfType (oldModel); 100 | 101 | gen->DoInternalProcessing (); 102 | gen->m_nModelId = oldModel; 103 | } 104 | 105 | /*******************************************************/ 106 | /* This function is supposed to return a random car based on the ones 107 | defined in the zone. It is redirected to the random traffic function */ 108 | /*******************************************************/ 109 | int __fastcall RandomizeRandomSpawn (void *group, void *edx, char a2, char a3) 110 | { 111 | return RandomizeTrafficCars (nullptr); 112 | } 113 | -------------------------------------------------------------------------------- /.clang-format: -------------------------------------------------------------------------------- 1 | # Copyright (C) 2015 Free Software Foundation, Inc. 2 | # 3 | # This program is free software; you can redistribute it and/or modify 4 | # it under the terms of the GNU General Public License as published by 5 | # the Free Software Foundation; either version 3 of the License, or 6 | # (at your option) any later version. 7 | # 8 | # This program is distributed in the hope that it will be useful, 9 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | # GNU General Public License for more details. 12 | # 13 | # You should have received a copy of the GNU General Public License 14 | # along with this program. If not, see . 15 | 16 | # clang-format 3.8+ (Mon Nov 16) is required 17 | # 18 | # To utilize the tool to lines just touched by a patch, use 19 | # clang-format-diff.py script, which can be downloaded here: 20 | # https://llvm.org/svn/llvm-project/cfe/trunk/tools/clang-format/clang-format-diff.py 21 | 22 | --- 23 | Language: Cpp 24 | AccessModifierOffset: -4 25 | AlwaysBreakAfterDefinitionReturnType: All 26 | BinPackArguments: true 27 | BinPackParameters: true 28 | BraceWrapping: 29 | AfterClass: true 30 | AfterControlStatement: true 31 | AfterEnum: true 32 | AfterFunction: true 33 | AfterNamespace: false 34 | AfterObjCDeclaration: true 35 | AfterStruct: true 36 | AfterUnion: true 37 | BeforeCatch: true 38 | BeforeElse: true 39 | IndentBraces: true 40 | BreakBeforeBinaryOperators: All 41 | BreakBeforeBraces: Custom 42 | BreakBeforeTernaryOperators: true 43 | ColumnLimit: 80 44 | ConstructorInitializerIndentWidth: 4 45 | ContinuationIndentWidth: 4 46 | IndentWidth: 4 47 | ForEachMacros: [ 48 | 'FOR_ALL_BB_FN', 49 | 'FOR_ALL_EH_REGION', 50 | 'FOR_ALL_EH_REGION_AT', 51 | 'FOR_ALL_EH_REGION_FN', 52 | 'FOR_ALL_INHERITED_FIELDS', 53 | 'FOR_ALL_PREDICATES', 54 | 'FOR_BB_BETWEEN', 55 | 'FOR_BB_INSNS', 56 | 'FOR_BB_INSNS_REVERSE', 57 | 'FOR_BB_INSNS_REVERSE_SAFE', 58 | 'FOR_BB_INSNS_SAFE', 59 | 'FOR_BODY', 60 | 'FOR_COND', 61 | 'FOR_EACH_AGGR_INIT_EXPR_ARG', 62 | 'FOR_EACH_ALIAS', 63 | 'FOR_EACH_ALLOCNO', 64 | 'FOR_EACH_ALLOCNO_OBJECT', 65 | 'FOR_EACH_ARTIFICIAL_DEF', 66 | 'FOR_EACH_ARTIFICIAL_USE', 67 | 'FOR_EACH_BB_FN', 68 | 'FOR_EACH_BB_REVERSE_FN', 69 | 'FOR_EACH_BIT_IN_MINMAX_SET', 70 | 'FOR_EACH_CALL_EXPR_ARG', 71 | 'FOR_EACH_CLONE', 72 | 'FOR_EACH_CONST_CALL_EXPR_ARG', 73 | 'FOR_EACH_CONSTRUCTOR_ELT', 74 | 'FOR_EACH_CONSTRUCTOR_VALUE', 75 | 'FOR_EACH_COPY', 76 | 'FOR_EACH_DEF', 77 | 'FOR_EACH_DEFINED_FUNCTION', 78 | 'FOR_EACH_DEFINED_SYMBOL', 79 | 'FOR_EACH_DEFINED_VARIABLE', 80 | 'FOR_EACH_DEP', 81 | 'FOR_EACH_EDGE', 82 | 'FOR_EACH_EXPR', 83 | 'FOR_EACH_EXPR_1', 84 | 'FOR_EACH_FUNCTION', 85 | 'FOREACH_FUNCTION_ARGS', 86 | 'FOREACH_FUNCTION_ARGS_PTR', 87 | 'FOR_EACH_FUNCTION_WITH_GIMPLE_BODY', 88 | 'FOR_EACH_HASH_TABLE_ELEMENT', 89 | 'FOR_EACH_IMM_USE_FAST', 90 | 'FOR_EACH_IMM_USE_ON_STMT', 91 | 'FOR_EACH_IMM_USE_STMT', 92 | 'FOR_EACH_INSN', 93 | 'FOR_EACH_INSN_1', 94 | 'FOR_EACH_INSN_DEF', 95 | 'FOR_EACH_INSN_EQ_USE', 96 | 'FOR_EACH_INSN_INFO_DEF', 97 | 'FOR_EACH_INSN_INFO_EQ_USE', 98 | 'FOR_EACH_INSN_INFO_MW', 99 | 'FOR_EACH_INSN_INFO_USE', 100 | 'FOR_EACH_INSN_USE', 101 | 'FOR_EACH_LOCAL_DECL', 102 | 'FOR_EACH_LOOP', 103 | 'FOR_EACH_LOOP_FN', 104 | 'FOR_EACH_OBJECT', 105 | 'FOR_EACH_OBJECT_CONFLICT', 106 | 'FOR_EACH_PHI_ARG', 107 | 'FOR_EACH_PHI_OR_STMT_DEF', 108 | 'FOR_EACH_PHI_OR_STMT_USE', 109 | 'FOR_EACH_PREF', 110 | 'FOR_EACH_SCALAR', 111 | 'FOR_EACH_SSA_DEF_OPERAND', 112 | 'FOR_EACH_SSA_TREE_OPERAND', 113 | 'FOR_EACH_SSA_USE_OPERAND', 114 | 'FOR_EACH_STATIC_INITIALIZER', 115 | 'FOR_EACH_SUBRTX', 116 | 'FOR_EACH_SUBRTX_PTR', 117 | 'FOR_EACH_SUBRTX_VAR', 118 | 'FOR_EACH_SUCC', 119 | 'FOR_EACH_SUCC_1', 120 | 'FOR_EACH_SYMBOL', 121 | 'FOR_EACH_VARIABLE', 122 | 'FOR_EACH_VEC_ELT', 123 | 'FOR_EACH_VEC_ELT_FROM', 124 | 'FOR_EACH_VEC_ELT_REVERSE', 125 | 'FOR_EACH_VEC_SAFE_ELT', 126 | 'FOR_EACH_VEC_SAFE_ELT_REVERSE', 127 | 'FOR_EXPR', 128 | 'FOR_INIT_STMT', 129 | 'FOR_SCOPE' 130 | ] 131 | IndentCaseLabels: false 132 | NamespaceIndentation: None 133 | PenaltyBreakBeforeFirstCallParameter: 100 134 | PointerAlignment: Right 135 | SortIncludes: false 136 | SpaceAfterCStyleCast: true 137 | SpaceBeforeParens: Always 138 | SpacesBeforeTrailingComments: 1 139 | UseTab: Never 140 | AlignConsecutiveDeclarations: true 141 | AlignConsecutiveAssignments: true 142 | AlignEscapedNewlines: Right 143 | AllowShortCaseLabelsOnASingleLine: true 144 | 145 | -------------------------------------------------------------------------------- /include/util/dyom/tts/StreamlabsPolly.hh: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "TTSBackend.hh" 4 | #include "util/dyom/Internet.hh" 5 | 6 | #include 7 | #include 8 | #include 9 | 10 | class StreamlabsPolly : public TTSBackend 11 | { 12 | InternetUtils internet; 13 | 14 | static std::string 15 | EncodeURL (const std::string &s) 16 | { 17 | const std::string safe_characters = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefgh" 18 | "ijklmnopqrstuvwxyz0123456789-._~"; 19 | std::ostringstream oss; 20 | for (auto c : s) 21 | { 22 | if (safe_characters.find (c) != std::string::npos) 23 | oss << c; 24 | else 25 | oss << '%' << std::setfill ('0') << std::setw (2) 26 | << std::uppercase << std::hex << (0xff & c); 27 | } 28 | return oss.str (); 29 | } 30 | 31 | std::string 32 | GetSoundURL (const std::string &text, const std::string &voice) 33 | { 34 | auto res 35 | = internet 36 | .Post ("/polly/speak", 37 | "Content-Type: application/x-www-form-urlencoded\r\n" 38 | "Referer: https://streamlabs.com", 39 | "service=Polly&voice=" + voice 40 | + "&text=" + EncodeURL (text)) 41 | .GetString (); 42 | 43 | auto start = res.find ("\"speak_url\"") + 13; 44 | auto end = res.find ("\"", start); 45 | 46 | auto url = res.substr (start, end - start); 47 | return std::regex_replace (url, std::regex ("\\\\/"), "/"); 48 | } 49 | 50 | public: 51 | virtual HSTREAM 52 | GetSoundStream (const std::string &text, const std::string &voice, 53 | void **data) 54 | { 55 | auto url = GetSoundURL (text, voice); 56 | auto stream 57 | = BASS_StreamCreateURL (url.c_str (), 0, BASS_STREAM_DECODE, 0, 0); 58 | return stream; 59 | } 60 | 61 | virtual std::vector 62 | GetVoices () 63 | { 64 | return std::vector{{ 65 | {"Brian", "GB", GENDER_M}, {"Amy", "GB", GENDER_F}, 66 | {"Emma", "GB", GENDER_F}, {"Geraint", "GB-WLS", GENDER_M}, 67 | {"Russell", "AU", GENDER_M}, {"Nicole", "AU", GENDER_F}, 68 | {"Joey", "US", GENDER_M}, {"Justin", "US", GENDER_M}, 69 | {"Matthew", "US", GENDER_M}, {"Ivy", "US", GENDER_F}, 70 | {"Joanna", "US", GENDER_F}, {"Kendra", "US", GENDER_F}, 71 | {"Kimberly", "US", GENDER_F}, {"Salli", "US", GENDER_F}, 72 | {"Raveena", "IN", GENDER_F}, {"Zeina", "ARAB", GENDER_F}, 73 | {"Zhiyu", "CN", GENDER_F}, {"Mads", "DK", GENDER_M}, 74 | {"Naja", "DK", GENDER_F}, {"Ruben", "NL", GENDER_M}, 75 | {"Lotte", "NL", GENDER_F}, {"Mathieu", "FR", GENDER_M}, 76 | {"Celine", "FR", GENDER_F}, {"Lea", "FR", GENDER_F}, 77 | {"Chantal", "CA", GENDER_F}, {"Hans", "DE", GENDER_M}, 78 | {"Marlene", "DE", GENDER_F}, {"Vicki", "DE", GENDER_F}, 79 | {"Aditi", "IN", GENDER_F}, {"Karl", "IS", GENDER_M}, 80 | {"Dora", "IS", GENDER_F}, {"Giorgio", "IT", GENDER_M}, 81 | {"Carla", "IT", GENDER_F}, {"Bianca", "IT", GENDER_F}, 82 | {"Takumi", "JP", GENDER_M}, {"Mizuki", "JP", GENDER_F}, 83 | {"Seoyeon", "KR", GENDER_F}, {"Liv", "NO", GENDER_F}, 84 | {"Jacek", "PL", GENDER_M}, {"Jan", "PL", GENDER_M}, 85 | {"Ewa", "PL", GENDER_F}, {"Maja", "PL", GENDER_F}, 86 | {"Ricardo", "BR", GENDER_M}, {"Camila", "BR", GENDER_F}, 87 | {"Vitoria", "BR", GENDER_F}, {"Cristiano", "PT", GENDER_M}, 88 | {"Ines", "PT", GENDER_F}, {"Carmen", "RO", GENDER_F}, 89 | {"Maxim", "RU", GENDER_M}, {"Tatyana", "RU", GENDER_F}, 90 | {"Enrique", "ES", GENDER_M}, {"Conchita", "ES", GENDER_F}, 91 | {"Lucia", "ES", GENDER_F}, {"Mia", "MX", GENDER_F}, 92 | {"Miguel", "US", GENDER_M}, {"Lupe", "US", GENDER_F}, 93 | {"Penelope", "US", GENDER_F}, {"Astrid", "SE", GENDER_F}, 94 | {"Filiz", "TR", GENDER_M}, {"Gwyneth", "GB-WLS", GENDER_F}, 95 | }}; 96 | } 97 | 98 | StreamlabsPolly () { internet.Open ("streamlabs.com"); } 99 | 100 | ~StreamlabsPolly () { internet.Close (); } 101 | }; 102 | -------------------------------------------------------------------------------- /src/util/text.cc: -------------------------------------------------------------------------------- 1 | #include "util/text.hh" 2 | #include "functions.hh" 3 | #include "injector/injector.hpp" 4 | #include 5 | 6 | const char *tables[] = { 7 | "INTRO1", "DUAL", "SHTR", "GRAV", "OTB", "POOL", "LOWR", 8 | "ZERO2", "INTRO2", "SWEET1", "SWEET1B", "SWEET3", "SWEET2", "SWEET4", 9 | "SWEET5", "SWEET6", "SWEET7", "CRASH2", "CRASH1", "CRASH3", "RYDER1", 10 | "RYDER3", "RYDER2", "SMOKE1", "SMOKE2", "SMOKE3", "SMOKE4", "STRAP1", 11 | "STRAP2", "STRAP3", "STRAP4", "RACETOR", "CESAR1", "LAFIN1", "LAFIN2", 12 | "BCRASH1", "CAT", "BCESAR2", "TRU1", "TRU2", "BCESAR4", "GARAGE1", 13 | "GARAGE2", "VALET1", "SCRASH2", "WUZI1", "FARLIE4", "FARLIE5", "WUZI2", 14 | "WUZI4", "SYN1", "SYN2", "SYN3", "SYN4", "SYN6", "SYN7", 15 | "SYN5", "FARLIE2", "FARLIE3", "STEAL1", "STEAL2", "STEAL4", "STEAL5", 16 | "DS", "ZERO1", "ZERO4", "TORENO1", "TORENO2", "DSERT3", "DSERT4", 17 | "DSERT6", "DSERT9", "DSERT8", "DSERT10", "DSERT5", "CASINO1", "CASINO2", 18 | "CASINO3", "CASINO7", "CASINO4", "CASINO5", "CASINO6", "CASINO9", "CASIN10", 19 | "VCR1", "VCR2", "DOC2", "HEIST1", "HEIST3", "HEIST2", "HEIST4", 20 | "HEIST5", "HEIST9", "MAN_1", "MAN_2", "MAN_3", "MAN_5", "GROVE1", 21 | "GROVE2", "RIOT1", "RIOT2", "RIOT4", "GYM", "TRUCK", "QUARRY", 22 | "BOAT", "BS", "TAXI1", "AMBULAE", "FIRETRK", "COPCAR", "BURGLAR", 23 | "FTRAIN", "PIMP", "BLOOD", "KICKSTT", "BCOU", "STUNT"}; 24 | 25 | typedef std::pair keyPair; // for less writing :P 26 | 27 | /*******************************************************/ 28 | struct Comp 29 | { 30 | bool 31 | operator() (keyPair p, size_t s) const 32 | { 33 | return p.first < s; 34 | } 35 | bool 36 | operator() (size_t s, keyPair p) const 37 | { 38 | return s < p.first; 39 | } 40 | }; 41 | 42 | /*******************************************************/ 43 | void 44 | GxtManager::Update (CKeyArray &array) 45 | { 46 | for (int i = 0; i < array.size; i++) 47 | mData.push_back ( 48 | std::make_pair (array.data[i].hash, array.data[i].pos)); 49 | } 50 | 51 | /*******************************************************/ 52 | const char * 53 | GxtManager::GetRandomWord () 54 | { 55 | const char *str = mData[random (mData.size () - 1)].second.data (); 56 | int length = strlen (str); 57 | 58 | int phrase_start = 0; 59 | for (phrase_start = random (length - 1); phrase_start >= 0; phrase_start--) 60 | { 61 | if (str[phrase_start] == ' ' || str[phrase_start] == '~') 62 | { 63 | phrase_start = phrase_start + 1; 64 | break; 65 | } 66 | } 67 | 68 | int phrase_end = phrase_start; 69 | int last_checkpoint = -1; 70 | for (; phrase_end - phrase_start <= 8; phrase_end++) 71 | { 72 | if (str[phrase_end] == ' ' || str[phrase_end] == '~') 73 | { 74 | last_checkpoint = phrase_end - 1; 75 | } 76 | if (phrase_end == length) 77 | { 78 | last_checkpoint = phrase_end - 1; 79 | break; 80 | } 81 | } 82 | if (last_checkpoint == -1) 83 | last_checkpoint = phrase_end; 84 | 85 | mRandomWordData 86 | = std::string (str + phrase_start, last_checkpoint - phrase_start + 1); 87 | 88 | return mRandomWordData.data (); 89 | } 90 | 91 | /*******************************************************/ 92 | const char * 93 | GxtManager::GetText (std::string key) 94 | { 95 | unsigned int hash = CKeyGen::GetUppercaseKey (key.c_str ()); 96 | 97 | auto iter = std::lower_bound (mData.begin (), mData.end (), hash, Comp ()); 98 | if (iter != mData.end () && hash == (*iter).first) 99 | return (*iter).second.data (); 100 | return ""; 101 | } 102 | 103 | /*******************************************************/ 104 | void 105 | GxtManager::Initialise (CText *text) 106 | { 107 | if (mData.size () > 0) 108 | return; 109 | 110 | Update (text->tKeyMain); 111 | for (int i = 0; i < sizeof (tables) / 4; i++) 112 | { 113 | text->LoadMissionText (tables[i]); 114 | Update (text->tKeyMission); 115 | } 116 | 117 | std::sort (std::begin (mData), std::end (mData)); 118 | } 119 | 120 | std::vector GxtManager::mData; 121 | std::string GxtManager::mRandomWordData; 122 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contributing to Rainbomizer 2 | 3 | This file contains the guidelines for contributing to Rainbomizer. 4 | All issues and pull-requests should follow these guidelines before they can be considered or merged into the main repository. 5 | 6 | ## Issues 7 | 8 | Issues are methods to improve the project by informing the developers of bugs, or suggestions of new features. 9 | 10 | - Any crash reports should contain the Rainbomizer log file. (rainbomizer.log.txt found in the same directory as the Rainbomizer ASI). 11 | - It is recommended, but not required, to also attach a minidump from Ultimate ASI Loader, found in the CrashLogs directory in the main GTA SA directory. 12 | 13 | - New feature requests should contain a concise description of what the new feature should be. You should also make sure that the feature 14 | hasn't already been requested or been worked-on. 15 | 16 | - Feature requests should be relevant to improving upon existing, or adding new randomization aspects. Any feature requests that aren't 17 | relevant to the randomizing nature of the mod will be ignored. 18 | 19 | ## Pull Requests 20 | 21 | Pull requests are direct ways to contribute to Rainbomizer. Pull requests include implementing new features, bug-fixes or other improvements 22 | made directly to the code. Pull requests are highly appreciated, but they must follow the following guidelines if they are to be merged into the main repository. 23 | 24 | - All code should be formatted using clang-format using the .clang-format file provided in the main repository. 25 | This includes the following conventions. 26 | - There should be a break after the return type of the function unless it is followed by a calling convention specification (eg. __fastcall) 27 | 28 | ```cpp 29 | int 30 | function (..) 31 | ``` 32 | 33 | - The indent width should be 4 characters. 34 | - Columns **must not** exceed 80 characters. 35 | - All parentheses must have a space preceding them. `function_call (a + b)` instead of `function_call(a+b)` 36 | - Pointers are right aligned. i.e `int *int_pointer` instead of `int* int_pointer` 37 | - There should be a line-break before all braces. 38 | 39 | ```cpp 40 | if(...) 41 | { 42 | ... 43 | } 44 | else 45 | { 46 | ... 47 | } 48 | ``` 49 | 50 | This rule is not applicable to namespace declarations 51 | 52 | - Use a singleton model for all randomizer classes. They should have a static instance that can be retrieved by a function. 53 | - See traffic.cc and traffic.hh for examples. Store any variables related to the randomizer in that class. 54 | - Avoid using global variables. 55 | 56 | - All function or class definitions should be divided by a comment containing 55 asterisks. 57 | ```cpp 58 | /*******************************************************/ 59 | void 60 | function (...) 61 | { 62 | ... 63 | } 64 | 65 | /*******************************************************/ 66 | void 67 | function2 (...) 68 | { 69 | ... 70 | } 71 | ``` 72 | 73 | - Use the provided RegisterHooks functions for hooks wherever possible. 74 | 75 | - To call the original function, use the `HookManager::CallOriginal`. (Note: This only works for hooks created with RegisterHooks) 76 | functions provided. This is to increase compatibillity with other mods. 77 | - To resolve conflicts, it might also be nececssary to use the 78 | RegisterDelayedHooks or RegisterDelayedFunctions methods. 79 | 80 | - Do **not** use any compiler specific extensions that are not a part of the ISO C++ standard. At the very least, the code should be made 81 | compatible with both the MSVC and GCC compilers. 82 | 83 | - Unless absolutely necessary, do **not** use inline-ASM for the implementations of any hooks. If you have to use inline-ASM, 84 | make it compatible with both MSVC and GCC. 85 | 86 | Using inline-asm makes the code compiler-specific and more-importantly, makes the code unreadable. In most cases, inline-ASM can be 87 | replaced by equivalent C++ code, or replaced with simple hooks. 88 | 89 | ```cpp 90 | // Replaced code 91 | mov eax, CommandsExecuted 92 | inc dword ptr [eax] 93 | ``` 94 | For example, this example code from scrlog can simply be rewritten in C++ as: 95 | ```cpp 96 | CommandsExecuted++; 97 | ``` 98 | 99 | - All include statements except includes from the standard library should be included in the source file and not the header file. 100 | This speeds up compile time and is a good practise in general. 101 | 102 | -------------------------------------------------------------------------------- /include/injector/calling.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Injectors - Function Calls Using Variadic Templates 3 | * 4 | * Copyright (C) 2014 LINK/2012 5 | * 6 | * This software is provided 'as-is', without any express or implied 7 | * warranty. In no event will the authors be held liable for any damages 8 | * arising from the use of this software. 9 | * 10 | * Permission is granted to anyone to use this software for any purpose, 11 | * including commercial applications, and to alter it and redistribute it 12 | * freely, subject to the following restrictions: 13 | * 14 | * 1. The origin of this software must not be misrepresented; you must not 15 | * claim that you wrote the original software. If you use this software 16 | * in a product, an acknowledgment in the product documentation would be 17 | * appreciated but is not required. 18 | * 19 | * 2. Altered source versions must be plainly marked as such, and must not be 20 | * misrepresented as being the original software. 21 | * 22 | * 3. This notice may not be removed or altered from any source 23 | * distribution. 24 | * 25 | */ 26 | #pragma once 27 | #include "injector.hpp" 28 | #include 29 | #include 30 | 31 | #if __cplusplus >= 201103L || _MSC_VER >= 1800 // MSVC 2013 32 | #else 33 | #error "This feature is not supported on this compiler" 34 | #endif 35 | 36 | namespace injector 37 | { 38 | template 39 | struct cstd; 40 | 41 | template 42 | struct cstd 43 | { 44 | typedef Ret result_type; 45 | 46 | // Call function at @p returning @Ret with args @Args 47 | static Ret call(memory_pointer_tr p, Args... a) 48 | { 49 | auto fn = (Ret(*)(Args...)) p.get(); 50 | return fn(std::forward(a)...); 51 | } 52 | 53 | template // Uses lazy pointer 54 | static Ret call(Args... a) 55 | { 56 | return call(lazy_pointer::get(), std::forward(a)...); 57 | } 58 | }; 59 | 60 | template 61 | struct stdcall; 62 | 63 | template 64 | struct stdcall 65 | { 66 | typedef Ret result_type; 67 | 68 | // Call function at @p returning @Ret with args @Args 69 | static Ret call(memory_pointer_tr p, Args... a) 70 | { 71 | auto fn = (Ret(__stdcall *)(Args...)) p.get(); 72 | return fn(std::forward(a)...); 73 | } 74 | 75 | template // Uses lazy pointer 76 | static Ret call(Args... a) 77 | { 78 | return call(lazy_pointer::get(), std::forward(a)...); 79 | } 80 | }; 81 | 82 | template 83 | struct fastcall; 84 | 85 | template 86 | struct fastcall 87 | { 88 | typedef Ret result_type; 89 | 90 | // Call function at @p returning @Ret with args @Args 91 | static Ret call(memory_pointer_tr p, Args... a) 92 | { 93 | auto fn = (Ret(__fastcall *)(Args...)) p.get();; 94 | return fn(std::forward(a)...); 95 | } 96 | 97 | template // Uses lazy pointer 98 | static Ret call(Args... a) 99 | { 100 | return call(lazy_pointer::get(), std::forward(a)...); 101 | } 102 | }; 103 | 104 | template 105 | struct thiscall; 106 | 107 | template 108 | struct thiscall 109 | { 110 | typedef Ret result_type; 111 | 112 | // Call function at @p returning @Ret with args @Args 113 | static Ret call(memory_pointer_tr p, Args... a) 114 | { 115 | auto fn = (Ret(__thiscall *)(Args...)) p.get(); 116 | return fn(std::forward(a)...); 117 | } 118 | 119 | // Call function at the index @i from the vtable of the object @a[0] 120 | template 121 | static Ret vtbl(Args... a) 122 | { 123 | auto obj = raw_ptr(std::get<0>(std::forward_as_tuple(a...))); 124 | auto p = raw_ptr( (*obj.template get()) [i] ); 125 | return call(p, std::forward(a)...); 126 | } 127 | 128 | template // Uses lazy pointer 129 | static Ret call(Args... a) 130 | { 131 | return call(lazy_pointer::get(), std::forward(a)...); 132 | } 133 | }; 134 | } 135 | 136 | -------------------------------------------------------------------------------- /src/config.cc: -------------------------------------------------------------------------------- 1 | /* 2 | Rainbomizer - A (probably fun) Grand Theft Auto San Andreas Mod that 3 | randomizes stuff 4 | Copyright (C) 2019 - Parik 5 | 6 | This program is free software: you can redistribute it and/or modify 7 | it under the terms of the GNU General Public License as published by 8 | the Free Software Foundation, either version 3 of the License, or 9 | (at your option) any later version. 10 | 11 | This program is distributed in the hope that it will be useful, 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | GNU General Public License for more details. 15 | 16 | You should have received a copy of the GNU General Public License 17 | along with this program. If not, see . 18 | 19 | */ 20 | 21 | #include 22 | #define CPPTOML_NO_RTTI 23 | 24 | #include 25 | #include "config.hh" 26 | #include "cpptoml/cpptoml.h" 27 | #include 28 | #include "logger.hh" 29 | #include "config_default.hh" 30 | #include 31 | #include 32 | #include "base.hh" 33 | 34 | /*******************************************************/ 35 | bool 36 | DoesFileExist (const std::string &file) 37 | { 38 | FILE *f = OpenRainbomizerFile (file, "r"); 39 | if (f) 40 | { 41 | fclose (f); 42 | return true; 43 | } 44 | return false; 45 | } 46 | 47 | /*******************************************************/ 48 | void 49 | ConfigManager::WriteDefaultConfig (const std::string &file) 50 | { 51 | FILE *f = OpenRainbomizerFile (file.c_str (), "wb"); 52 | if (f) 53 | { 54 | fwrite (config_toml, sizeof (config_toml) - 1, 1, f); 55 | fclose (f); 56 | } 57 | } 58 | 59 | /*******************************************************/ 60 | std::shared_ptr 61 | ConfigManager::ParseDefaultConfig () 62 | { 63 | // Read the default config file 64 | auto stream = std::istringstream (config_toml); 65 | 66 | cpptoml::parser p{stream}; 67 | return p.parse (); 68 | } 69 | 70 | /*******************************************************/ 71 | ConfigManager::ConfigManager (const std::string &file) 72 | { 73 | Logger::GetLogger ()->LogMessage (GetRainbomizerFileName (file)); 74 | m_pDefaultConfig = ParseDefaultConfig (); 75 | try 76 | { 77 | m_pConfig = cpptoml::parse_file (GetRainbomizerFileName (file)); 78 | } 79 | catch (const std::exception &e) 80 | { 81 | Logger::GetLogger ()->LogMessage (e.what ()); 82 | 83 | if (!DoesFileExist (file)) 84 | WriteDefaultConfig (file); 85 | 86 | m_pConfig = m_pDefaultConfig; 87 | } 88 | } 89 | 90 | /*******************************************************/ 91 | ConfigManager * 92 | ConfigManager::GetInstance () 93 | { 94 | static ConfigManager mgr ("config.toml"); 95 | return &mgr; 96 | } 97 | 98 | /*******************************************************/ 99 | bool 100 | ConfigManager::GetIsEnabled (const std::string &name) 101 | { 102 | // Finds "name" key in the main table. Also allows an "Enabled" key in the 103 | // table for the randomizer/whatever. 104 | 105 | // Example: 106 | // TrafficRandomizer = true 107 | // ColourRandomizer = false 108 | // [ColourRandomizer] 109 | // Enabled = true 110 | 111 | // Will be parsed as TrafficRandomizer and ColourRandomizer enabled. 112 | // Enabled key takes precedence over main table key. 113 | 114 | bool enabled = true; 115 | ReadValue ("Randomizers", name, enabled); 116 | ReadValue (name, "Enabled", enabled); 117 | 118 | // Logger::GetLogger ()->LogMessage (name + ": " 119 | // + std::to_string (enabled)); 120 | 121 | return enabled; 122 | } 123 | 124 | template 125 | void 126 | ConfigManager::ReadValue (const std::string &tableName, const std::string &key, 127 | T &out) 128 | { 129 | auto table = m_pConfig->get_table (tableName); 130 | auto defTable = m_pDefaultConfig->get_table (tableName); 131 | if (table) 132 | out = table->get_as (key).value_or ( 133 | (defTable) ? defTable->get_as (key).value_or (out) : out); 134 | } 135 | 136 | #define READ_VALUE_ADD_TYPE(type) \ 137 | template void ConfigManager::ReadValue ( \ 138 | const std::string &tableName, const std::string &key, type &out); 139 | 140 | READ_VALUE_ADD_TYPE (bool) 141 | READ_VALUE_ADD_TYPE (int) 142 | READ_VALUE_ADD_TYPE (double) 143 | READ_VALUE_ADD_TYPE (std::string) 144 | -------------------------------------------------------------------------------- /src/main.cc: -------------------------------------------------------------------------------- 1 | /* 2 | Rainbomizer - A (probably fun) Grand Theft Auto San Andreas Mod that 3 | randomizes stuff 4 | Copyright (C) 2019 - Parik 5 | 6 | This program is free software: you can redistribute it and/or modify 7 | it under the terms of the GNU General Public License as published by 8 | the Free Software Foundation, either version 3 of the License, or 9 | (at your option) any later version. 10 | 11 | This program is distributed in the hope that it will be useful, 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | GNU General Public License for more details. 15 | 16 | You should have received a copy of the GNU General Public License 17 | along with this program. If not, see . 18 | 19 | */ 20 | 21 | #include "base.hh" 22 | #include "gxt.hh" 23 | #include "logger.hh" 24 | #include "traffic.hh" 25 | #include "colours.hh" 26 | #include "heli.hh" 27 | #include "cgen.hh" 28 | #include 29 | #include "scm.hh" 30 | #include "sounds.hh" 31 | #include "cheats.hh" 32 | #include "plates.hh" 33 | #include "handling.hh" 34 | #include "weapons.hh" 35 | #include "config.hh" 36 | #include "autosave.hh" 37 | #include "pickups.hh" 38 | #include "missions.hh" 39 | #include "objects.hh" 40 | #include "cutscenes.hh" 41 | #include "particles.hh" 42 | #include "blips.hh" 43 | #include "credits.hh" 44 | #include "weaponstats.hh" 45 | #include "clothes.hh" 46 | #include "wanted.hh" 47 | #include "respawns.hh" 48 | #include "dyom.hh" 49 | #include "animations.hh" 50 | #include "ped.hh" 51 | #include "timecycle.hh" 52 | #include "riot.hh" 53 | #include "map.hh" 54 | #include "generalsettings.hh" 55 | 56 | /////////////////////////////////////////////// 57 | // _ ____ _____ _ _ // 58 | // / |___ \|___ / _ __ ___ | |__ ___ | |_ // 59 | // | | __) | |_ \| '__/ _ \| '_ \ / _ \| __| // 60 | // | |/ __/ ___) | | | (_) | |_) | (_) | |_ // 61 | // |_|_____|____/|_| \___/|_.__/ \___/ \__| // 62 | /////////////////////////////////////////////// 63 | // Visit his Twitch Channel - https://www.twitch.tv/123robot 64 | 65 | class Rainbomizer 66 | { 67 | public: 68 | /*******************************************************/ 69 | Rainbomizer () 70 | { 71 | if (!ConfigManager::ReadConfig ("EnableRainbomizer")) 72 | return; 73 | 74 | GeneralSettings::GetInstance ()->Initialise (); 75 | 76 | // Unprotect if required 77 | if (GeneralSettings::m_Config.Unprotect) 78 | UnProtectInstance (); 79 | 80 | auto logger = Logger::GetLogger (); 81 | 82 | ExceptionManager::GetExceptionManager ()->RegisterExceptionManager (); 83 | logger->LogMessage ("Registered Exception Manager"); 84 | 85 | if (!VerifyGameVersion ()) 86 | return; 87 | 88 | HookManager::GetInstance ()->Initialise (); 89 | 90 | TrafficRandomizer::GetInstance ()->Initialise (); 91 | ColourRandomizer::GetInstance ()->Initialise (); 92 | TimeCycleRandomizer::GetInstance ()->Initialise (); 93 | ParkedCarRandomizer::GetInstance ()->Initialise (); 94 | PoliceHeliRandomizer::GetInstance ()->Initialise (); 95 | ScriptVehicleRandomizer::GetInstance ()->Initialise (); 96 | LicensePlateRandomizer::GetInstance ()->Initialise (); 97 | SoundRandomizer::GetInstance ()->Initialise (); 98 | HandlingRandomizer::GetInstance ()->Initialise (); 99 | CheatRandomizer::GetInstance ()->Initialise (); 100 | WeaponRandomizer::GetInstance ()->Initialise (); 101 | PickupsRandomizer::GetInstance ()->Initialise (); 102 | MissionRandomizer::GetInstance ()->Initialise (); 103 | ObjectsRandomizer::GetInstance ()->Initialise (); 104 | CutsceneRandomizer::GetInstance ()->Initialise (); 105 | ParticleRandomizer::GetInstance ()->Initialise (); 106 | BlipRandomizer::GetInstance ()->Initialise (); 107 | WeaponStatsRandomizer::GetInstance ()->Initialise (); 108 | ClothesRandomizer::GetInstance ()->Initialise (); 109 | WantedLevelRandomizer::GetInstance ()->Initialise (); 110 | RespawnPointRandomizer::GetInstance ()->Initialise (); 111 | DyomRandomizer::GetInstance ()->Initialise (); 112 | RiotRandomizer::GetInstance ()->Initialise (); 113 | AnimationRandomizer::GetInstance ()->Initialise (); 114 | GxtRandomizer::GetInstance ()->Initialise (); 115 | PedRandomizer::GetInstance ()->Initialise (); 116 | MapRandomizer::GetInstance ()->Initialise (); 117 | 118 | CreditsExtender::Initialise (); 119 | 120 | AutoSave::GetInstance ()->Initialise (); 121 | } 122 | 123 | } rainbow; 124 | -------------------------------------------------------------------------------- /src/heli.cc: -------------------------------------------------------------------------------- 1 | /* 2 | Rainbomizer - A (probably fun) Grand Theft Auto San Andreas Mod that 3 | randomizes stuff 4 | Copyright (C) 2019 - Parik 5 | 6 | This program is free software: you can redistribute it and/or modify 7 | it under the terms of the GNU General Public License as published by 8 | the Free Software Foundation, either version 3 of the License, or 9 | (at your option) any later version. 10 | 11 | This program is distributed in the hope that it will be useful, 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | GNU General Public License for more details. 15 | 16 | You should have received a copy of the GNU General Public License 17 | along with this program. If not, see . 18 | 19 | */ 20 | 21 | #include "heli.hh" 22 | #include 23 | #include "logger.hh" 24 | #include "functions.hh" 25 | #include "base.hh" 26 | #include "injector/injector.hpp" 27 | #include "config.hh" 28 | 29 | PoliceHeliRandomizer *PoliceHeliRandomizer::mInstance = nullptr; 30 | 31 | /*******************************************************/ 32 | int 33 | GetRandomHeliID () 34 | { 35 | int HeliIDs[] = {548, 425, 417, 487, 488, 497, 563, 447, 469, 501, 465}; 36 | return HeliIDs[random (sizeof (HeliIDs) / 4 - 1)]; 37 | } 38 | 39 | /*******************************************************/ 40 | void 41 | RandomizeHelisOnUnload () 42 | { 43 | PoliceHeliRandomizer::GetInstance ()->UnloadHelis (); 44 | PoliceHeliRandomizer::GetInstance ()->RandomizeHelis (); 45 | } 46 | 47 | /*******************************************************/ 48 | void 49 | PoliceHeliRandomizer::UnloadHelis () 50 | { 51 | CStreaming::SetIsDeletable (mVCNHeli); 52 | CStreaming::SetIsDeletable (mPoliceHeli); 53 | } 54 | 55 | /*******************************************************/ 56 | void 57 | PoliceHeliRandomizer::Initialise () 58 | { 59 | if (!ConfigManager::ReadConfig ("PoliceHeliRandomizer")) 60 | return; 61 | 62 | RegisterHooks ({{HOOK_CALL, 0x40B88B, (void *) &RandomizeHelisOnUnload}, 63 | {HOOK_CALL, 0x40B845, (void *) &TurnOnRandomization}}); 64 | 65 | ExceptionManager::GetExceptionManager ()->RegisterHandler ( 66 | &PoliceHeliRandomizer::ExceptionHandlerCallback); 67 | 68 | RandomizeHelis (); 69 | Logger::GetLogger ()->LogMessage ("Intialised PoliceHeliRandomizer"); 70 | } 71 | 72 | /*******************************************************/ 73 | void 74 | TurnOnRandomization (int model, int flags) 75 | { 76 | PoliceHeliRandomizer::GetInstance ()->SetRandomizationEnabled (); 77 | CStreaming::RequestModel (model, flags); 78 | } 79 | 80 | /*******************************************************/ 81 | void 82 | PoliceHeliRandomizer::RandomizeHelis (bool disableRandomization) 83 | { 84 | if (mRandomizationEnabled) 85 | { 86 | mVCNHeli = GetRandomHeliID (); 87 | mPoliceHeli = GetRandomHeliID (); 88 | UpdatePatches (); 89 | } 90 | 91 | if (disableRandomization) 92 | mRandomizationEnabled = false; 93 | } 94 | 95 | /*******************************************************/ 96 | void 97 | PoliceHeliRandomizer::UpdatePatches () 98 | { 99 | injector::WriteMemory (0x6C79CF, mPoliceHeli); 100 | injector::WriteMemory (0x6C658A, mPoliceHeli); 101 | injector::WriteMemory (0x40B841, mPoliceHeli); 102 | 103 | injector::WriteMemory (0x6C7A5F, mVCNHeli); 104 | injector::WriteMemory (0x6C6562, mVCNHeli); 105 | injector::WriteMemory (0x40B86C, mVCNHeli); 106 | 107 | injector::WriteMemory (0x6C7A96 + 2, 108 | &ms_aInfoForModel[mPoliceHeli].m_nLoadState); 109 | 110 | injector::WriteMemory (0x6C7AF0, &ms_aInfoForModel[mVCNHeli].m_nLoadState); 111 | } 112 | 113 | /*******************************************************/ 114 | void 115 | PoliceHeliRandomizer::DestroyInstance () 116 | { 117 | if (PoliceHeliRandomizer::mInstance) 118 | delete PoliceHeliRandomizer::mInstance; 119 | } 120 | 121 | /*******************************************************/ 122 | void 123 | PoliceHeliRandomizer::ExceptionHandlerCallback (_EXCEPTION_POINTERS *ep) 124 | { 125 | auto inst = GetInstance (); 126 | Logger::GetLogger ()->LogMessage ("Helicopters (VCN, Police): " 127 | + std::to_string (inst->mVCNHeli) + ", " 128 | + std::to_string (inst->mPoliceHeli)); 129 | } 130 | 131 | /*******************************************************/ 132 | PoliceHeliRandomizer * 133 | PoliceHeliRandomizer::GetInstance () 134 | { 135 | if (!PoliceHeliRandomizer::mInstance) 136 | { 137 | PoliceHeliRandomizer::mInstance = new PoliceHeliRandomizer (); 138 | atexit (&PoliceHeliRandomizer::DestroyInstance); 139 | } 140 | return PoliceHeliRandomizer::mInstance; 141 | } 142 | -------------------------------------------------------------------------------- /src/objects.cc: -------------------------------------------------------------------------------- 1 | #include "objects.hh" 2 | #include 3 | #include "logger.hh" 4 | #include "base.hh" 5 | #include "functions.hh" 6 | #include "config.hh" 7 | 8 | ObjectsRandomizer *ObjectsRandomizer::mInstance = nullptr; 9 | 10 | /*******************************************************/ 11 | void __fastcall RandomizeObjectIndices (CRunningScript *script, void *edx, 12 | short count) 13 | { 14 | script->CollectParameters (count); 15 | if (ScriptParams[0] < 0) 16 | { 17 | int tempObjectCheck = -(ScriptParams[0]); 18 | std::vector badObjects 19 | = ObjectsRandomizer::GetInstance ()->objectsToIgnore; 20 | 21 | // Check list of objects we don't want to change 22 | if (std::find (badObjects.begin (), badObjects.end (), 23 | tempObjectCheck) 24 | == badObjects.end ()) 25 | { 26 | std::vector objectsToUse; 27 | 28 | // Checks if should use generic good object list or 29 | // destructible list 30 | if (tempObjectCheck == 75 || tempObjectCheck == 123 31 | || tempObjectCheck == 198 || tempObjectCheck == 298 32 | || (tempObjectCheck == 140 33 | && (CRunningScripts::CheckForRunningScript ( 34 | "drugs3") 35 | || CRunningScripts::CheckForRunningScript ( 36 | "ryder2")))) 37 | { 38 | objectsToUse = ObjectsRandomizer::GetInstance () 39 | ->destructibleObjects; 40 | ObjectsRandomizer::modifyObject = true; 41 | } 42 | else 43 | { 44 | objectsToUse = ObjectsRandomizer::GetInstance () 45 | ->goodObjects; 46 | } 47 | 48 | // Adds original object to list if not present 49 | if (std::find (objectsToUse.begin (), objectsToUse.end (), 50 | tempObjectCheck) 51 | == badObjects.end ()) 52 | { 53 | objectsToUse.push_back (tempObjectCheck); 54 | } 55 | 56 | // Selects random object from the final vector 57 | ScriptParams[0] = -(GetRandomElement (objectsToUse)); 58 | } 59 | // ScriptParams[0] = -random (*((int *) 0xA44B6C)); // Original code 60 | } 61 | } 62 | 63 | // Directly modifies the data of the created object to change its properties. 64 | // Values still need to be worked out. 65 | /*******************************************************/ 66 | CObject * 67 | ChangeObjectData (int modelId) 68 | { 69 | CObject *obj = CObject::Create (modelId); 70 | if (ObjectsRandomizer::modifyObject) 71 | { 72 | // obj->m_pObjectInfo->m_fMass = 50.0f; 73 | //obj->m_pObjectInfo->m_fTurnMass = 150.0f; 74 | // obj->m_pObjectInfo->m_fAirResistance = 0.99f; 75 | //obj->m_pObjectInfo->m_fElasticity = 0.0f; 76 | // obj->m_pObjectInfo->m_fUprootLimit = 350.0f; 77 | //obj->m_pObjectInfo->m_fColDamageMultiplier = 5.0f; 78 | 79 | obj->m_pObjectInfo->m_bColDamageEffect = 200; 80 | obj->m_pObjectInfo->m_fSmashMultiplier = 1.0f; 81 | obj->m_pObjectInfo->m_vBreakVelocity = {0.0f, 0.0f, 0.1f}; 82 | obj->m_pObjectInfo->m_fBreakVelocityRand = 0.07f; 83 | obj->m_pObjectInfo->m_dwGunBreakMode = 2; 84 | obj->m_pObjectInfo->m_dwSparksOnImpact = 0; 85 | obj->m_fHealth = 1.0f; 86 | ObjectsRandomizer::modifyObject = false; 87 | } 88 | return obj; 89 | } 90 | 91 | /*******************************************************/ 92 | void 93 | ObjectsRandomizer::Initialise () 94 | { 95 | if (!ConfigManager::ReadConfig ("ObjectRandomizer")) 96 | return; 97 | 98 | RegisterHooks ({{HOOK_CALL, 0x469773, (void *) RandomizeObjectIndices}/*, 99 | {HOOK_CALL, 0x46979B, (void *) ChangeObjectData}*/}); 100 | Logger::GetLogger ()->LogMessage ("Intialised ObjectsRandomizer"); 101 | } 102 | 103 | /*******************************************************/ 104 | void 105 | ObjectsRandomizer::DestroyInstance () 106 | { 107 | if (ObjectsRandomizer::mInstance) 108 | delete ObjectsRandomizer::mInstance; 109 | } 110 | 111 | /*******************************************************/ 112 | ObjectsRandomizer * 113 | ObjectsRandomizer::GetInstance () 114 | { 115 | if (!ObjectsRandomizer::mInstance) 116 | { 117 | ObjectsRandomizer::mInstance = new ObjectsRandomizer (); 118 | atexit (&ObjectsRandomizer::DestroyInstance); 119 | } 120 | return ObjectsRandomizer::mInstance; 121 | } 122 | -------------------------------------------------------------------------------- /src/handling.cc: -------------------------------------------------------------------------------- 1 | /* 2 | Rainbomizer - A (probably fun) Grand Theft Auto San Andreas Mod that 3 | randomizes stuff 4 | Copyright (C) 2019 - Parik 5 | 6 | This program is free software: you can redistribute it and/or modify 7 | it under the terms of the GNU General Public License as published by 8 | the Free Software Foundation, either version 3 of the License, or 9 | (at your option) any later version. 10 | 11 | This program is distributed in the hope that it will be useful, 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | GNU General Public License for more details. 15 | 16 | You should have received a copy of the GNU General Public License 17 | along with this program. If not, see . 18 | 19 | */ 20 | 21 | #include "handling.hh" 22 | #include 23 | #include "logger.hh" 24 | #include "functions.hh" 25 | #include "base.hh" 26 | #include "config.hh" 27 | #include "injector/injector.hpp" 28 | 29 | #include 30 | 31 | HandlingRandomizer *HandlingRandomizer::mInstance = nullptr; 32 | 33 | const int NUM_HANDLINGS = 209; 34 | static tHandlingData *s_Handlings 35 | = reinterpret_cast (0xC2B9DC); 36 | 37 | /*******************************************************/ 38 | tHandlingData * 39 | GetRandomHandling (CVehicle *vehicle) 40 | { 41 | static std::map data; 42 | 43 | tHandlingData *handling = &data[vehicle]; 44 | if (vehicle->m_pHandling == handling) 45 | return handling; 46 | 47 | memcpy (handling, vehicle->m_pHandling, sizeof (tHandlingData)); 48 | 49 | #define ADD_RANDOMIZED_FIELD(fieldName) \ 50 | handling->fieldName = s_Handlings[random (NUM_HANDLINGS)].fieldName 51 | 52 | // ADD_RANDOMIZED_FIELD (index); 53 | ADD_RANDOMIZED_FIELD (fMass); 54 | ADD_RANDOMIZED_FIELD (field_8); 55 | ADD_RANDOMIZED_FIELD (fTurnMass); 56 | ADD_RANDOMIZED_FIELD (fDragMult); 57 | ADD_RANDOMIZED_FIELD (centreOfMass); 58 | ADD_RANDOMIZED_FIELD (nPercentSubmerged); 59 | ADD_RANDOMIZED_FIELD (field_21); 60 | ADD_RANDOMIZED_FIELD (field_22); 61 | ADD_RANDOMIZED_FIELD (field_23); 62 | ADD_RANDOMIZED_FIELD (fBuoyancyConstant); 63 | ADD_RANDOMIZED_FIELD (fTractionMultiplier); 64 | ADD_RANDOMIZED_FIELD (transmissionData); 65 | ADD_RANDOMIZED_FIELD (fBrakeDeceleration); 66 | ADD_RANDOMIZED_FIELD (fBrakeBias); 67 | ADD_RANDOMIZED_FIELD (bABS); 68 | ADD_RANDOMIZED_FIELD (field_9D); 69 | ADD_RANDOMIZED_FIELD (field_9E); 70 | ADD_RANDOMIZED_FIELD (field_9F); 71 | ADD_RANDOMIZED_FIELD (fSteeringLock); 72 | ADD_RANDOMIZED_FIELD (fTractionLoss); 73 | ADD_RANDOMIZED_FIELD (fTractionBias); 74 | ADD_RANDOMIZED_FIELD (fSuspensionForceLevel); 75 | ADD_RANDOMIZED_FIELD (fSuspensionDampingLevel); 76 | ADD_RANDOMIZED_FIELD (fSuspensionHighSpdComDamp); 77 | ADD_RANDOMIZED_FIELD (fSuspensionUpperLimit); 78 | ADD_RANDOMIZED_FIELD (fSuspensionLowerLimit); 79 | ADD_RANDOMIZED_FIELD (fSuspensionBiasBetweenFrontAndRear); 80 | ADD_RANDOMIZED_FIELD (fSuspensionAntiDiveMultiplier); 81 | ADD_RANDOMIZED_FIELD (fCollisionDamageMultiplier); 82 | ADD_RANDOMIZED_FIELD (modelFlags); 83 | ADD_RANDOMIZED_FIELD (handlingFlags); 84 | ADD_RANDOMIZED_FIELD (fSeatOffsetDistance); 85 | ADD_RANDOMIZED_FIELD (nMonetaryValue); 86 | ADD_RANDOMIZED_FIELD (frontLights); 87 | ADD_RANDOMIZED_FIELD (rearLights); 88 | // ADD_RANDOMIZED_FIELD (animGroup); 89 | ADD_RANDOMIZED_FIELD (field_DF); 90 | 91 | return handling; 92 | } 93 | 94 | /*******************************************************/ 95 | void __fastcall RandomizeHandling (CVehicle *vehicle, void *edx, CPed *ped) 96 | { 97 | if (!CModelInfo::IsBoatModel (vehicle->m_nModelIndex) 98 | && !CModelInfo::IsHeliModel (vehicle->m_nModelIndex) 99 | && !CModelInfo::IsPlaneModel (vehicle->m_nModelIndex) 100 | && !CModelInfo::IsTrainModel (vehicle->m_nModelIndex)) 101 | { 102 | vehicle->m_pHandling = GetRandomHandling (vehicle); 103 | } 104 | vehicle->SetDriver (ped); 105 | } 106 | 107 | /*******************************************************/ 108 | void 109 | HandlingRandomizer::Initialise () 110 | { 111 | if (!ConfigManager::ReadConfig ("HandlingRandomizer")) 112 | return; 113 | 114 | RegisterHooks ({{HOOK_CALL, 0x64BB57, (void *) &RandomizeHandling}}); 115 | Logger::GetLogger ()->LogMessage ("Intialised HandlingRandomizer"); 116 | } 117 | 118 | /*******************************************************/ 119 | void 120 | HandlingRandomizer::DestroyInstance () 121 | { 122 | if (HandlingRandomizer::mInstance) 123 | delete HandlingRandomizer::mInstance; 124 | } 125 | 126 | /*******************************************************/ 127 | HandlingRandomizer * 128 | HandlingRandomizer::GetInstance () 129 | { 130 | if (!HandlingRandomizer::mInstance) 131 | { 132 | HandlingRandomizer::mInstance = new HandlingRandomizer (); 133 | atexit (&HandlingRandomizer::DestroyInstance); 134 | } 135 | return HandlingRandomizer::mInstance; 136 | } 137 | -------------------------------------------------------------------------------- /include/util/dyom/DYOMFileFormat.hh: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | namespace DYOM { 9 | struct DYOMFileStructure 10 | { 11 | private: 12 | template 13 | void ReadWriteInternal (T &file, F1 byte, F2 str); 14 | 15 | public: 16 | // Header 17 | int32_t g_DYOM_FILE_VERSION; 18 | std::string g_HEADERSTRINGS[6]; 19 | 20 | // Dyom Block 21 | uint32_t g_DYOM_OBJECTIVE_COUNT = 0; 22 | uint32_t g_DYOM_ACTOR_COUNT = 0; 23 | uint32_t g_DYOM_CAR_COUNT = 0; 24 | uint32_t g_DYOM_PICKUP_COUNT = 0; 25 | uint32_t g_DYOM_OBJECT_COUNT = 0; 26 | uint32_t g_DYOM_TIMELIMIT = 0; 27 | uint32_t g_DYOM_TIMEOFDAY = 0; 28 | uint32_t g_DYOM_WEATHER = 0; 29 | uint32_t g_DYOM_MINWANTEDLEVEL = 0; 30 | uint32_t g_DYOM_MAXWANTEDLEVEL = 0; 31 | uint32_t g_DYOM_PROPERTIES = 0; 32 | 33 | // Player Block 34 | float g_DYOM_PLAYER_LOCATION_X = 0; 35 | float g_DYOM_PLAYER_LOCATION_Y = 0; 36 | float g_DYOM_PLAYER_LOCATION_Z = 0; 37 | float g_DYOM_PLAYER_LOCATION_A = 0; 38 | uint32_t g_DYOM_PLAYER_INTERIOR = 0; 39 | uint32_t g_DYOM_PLAYER_MODEL = 0; 40 | uint32_t g_DYOM_PLAYER_WEAPON = 0; 41 | uint32_t g_DYOM_PLAYER_AMMO = 0; 42 | uint32_t g_DYOM_PLAYER_HEALTH = 0; 43 | 44 | // Objective Block 45 | float g_DYOM_OBJECTIVE_LOCATION_X[100] = {}; 46 | float g_DYOM_OBJECTIVE_LOCATION_Y[100] = {}; 47 | float g_DYOM_OBJECTIVE_LOCATION_Z[100] = {}; 48 | float g_DYOM_OBJECTIVE_LOCATION_A[100] = {}; 49 | uint32_t g_DYOM_OBJECTIVE_INTERIOR[100] = {}; 50 | uint32_t g_DYOM_OBJECTIVE_TYPE[100] = {}; 51 | int32_t g_DYOM_OBJECTIVE_MODEL[100] = {}; 52 | uint32_t g_DYOM_OBJECTIVE_DATA[100] = {}; 53 | uint32_t g_DYOM_OBJECTIVE_AMMO[100] = {}; 54 | uint32_t g_DYOM_OBJECTIVE_MARKERCOLOR[100] = {}; 55 | uint32_t g_DYOM_OBJECTIVE_PROPERTIES[100] = {}; 56 | uint32_t g_DYOM_OBJECTIVE_HEALTH[100] = {}; 57 | uint32_t g_DYOM_OBJECTIVE_ACCURACY[100] = {}; 58 | uint32_t g_DYOM_OBJECTIVE_TIMELIMIT[100] = {}; 59 | uint32_t g_DYOM_OBJECTIVE_ANIMATION[100] = {}; 60 | float g_DYOM_OBJECTIVE_DISTANCE[100] = {}; 61 | std::string g_TEXTOBJECTIVES[100] = {}; 62 | 63 | // Actor Block 64 | uint32_t g_DYOM_ACTOR_MODEL[100] = {}; 65 | uint32_t g_DYOM_ACTOR_GANG[100] = {}; 66 | float g_DYOM_ACTOR_LOCATION_X[100] = {}; 67 | float g_DYOM_ACTOR_LOCATION_Y[100] = {}; 68 | float g_DYOM_ACTOR_LOCATION_Z[100] = {}; 69 | float g_DYOM_ACTOR_LOCATION_A[100] = {}; 70 | uint32_t g_DYOM_ACTOR_INTERIOR[100] = {}; 71 | uint32_t g_DYOM_ACTOR_WEAPON[100] = {}; 72 | uint32_t g_DYOM_ACTOR_AMMO[100] = {}; 73 | uint32_t g_DYOM_ACTOR_PROPERTIES[100] = {}; 74 | uint32_t g_DYOM_ACTOR_HEALTH[100] = {}; 75 | uint32_t g_DYOM_ACTOR_ACCURACY[100] = {}; 76 | uint32_t g_DYOM_ACTOR_SPAWNWITH[100] = {}; 77 | uint32_t g_DYOM_ACTOR_HIDEWITH[100] = {}; 78 | uint32_t g_DYOM_ACTOR_MUSTLIVE[100] = {}; 79 | uint32_t g_DYOM_ACTOR_ANIMATION[100] = {}; 80 | float g_DYOM_ACTOR_DISTANCE[100] = {}; 81 | 82 | // Car Block 83 | uint32_t g_DYOM_CAR_MODEL[50] = {}; 84 | uint32_t g_DYOM_CAR_COLOR1[50] = {}; 85 | uint32_t g_DYOM_CAR_COLOR2[50] = {}; 86 | float g_DYOM_CAR_LOCATION_X[50] = {}; 87 | float g_DYOM_CAR_LOCATION_Y[50] = {}; 88 | float g_DYOM_CAR_LOCATION_Z[50] = {}; 89 | float g_DYOM_CAR_LOCATION_A[50] = {}; 90 | uint32_t g_DYOM_CAR_INTERIOR[50] = {}; 91 | uint32_t g_DYOM_CAR_HEALTH[50] = {}; 92 | uint32_t g_DYOM_CAR_PROPERTIES[50] = {}; 93 | uint32_t g_DYOM_CAR_SPAWNWITH[50] = {}; 94 | uint32_t g_DYOM_CAR_HIDEWITH[50] = {}; 95 | uint32_t g_DYOM_CAR_MUSTLIVE[50] = {}; 96 | 97 | // Pickup Block 98 | uint32_t g_DYOM_PICKUP_MODEL[50] = {}; 99 | uint32_t g_DYOM_PICKUP_AMMO[50] = {}; 100 | uint32_t g_DYOM_PICKUP_MODE[50] = {}; 101 | float g_DYOM_PICKUP_LOCATION_X[50] = {}; 102 | float g_DYOM_PICKUP_LOCATION_Y[50] = {}; 103 | float g_DYOM_PICKUP_LOCATION_Z[50] = {}; 104 | uint32_t g_DYOM_PICKUP_SPAWNWITH[50] = {}; 105 | uint32_t g_DYOM_PICKUP_HIDEWITH[50] = {}; 106 | 107 | // Object Block 108 | uint32_t g_DYOM_OBJECT_MODEL[100] = {}; 109 | float g_DYOM_OBJECT_LOCATION_X[100] = {}; 110 | float g_DYOM_OBJECT_LOCATION_Y[100] = {}; 111 | float g_DYOM_OBJECT_LOCATION_Z[100] = {}; 112 | float g_DYOM_OBJECT_LOCATION_RX[100] = {}; 113 | float g_DYOM_OBJECT_LOCATION_RY[100] = {}; 114 | float g_DYOM_OBJECT_LOCATION_RZ[100] = {}; 115 | uint32_t g_DYOM_OBJECT_INTERIOR[100] = {}; 116 | uint32_t g_DYOM_OBJECT_SPAWNWITH[100] = {}; 117 | uint32_t g_DYOM_OBJECT_HIDEWITH[100] = {}; 118 | 119 | // Routepoints Block 120 | uint8_t g_8277[1600] = {}; 121 | uint8_t g_8677[1600] = {}; 122 | uint8_t g_9077[1600] = {}; 123 | uint8_t g_9477[1600] = {}; 124 | 125 | void Save (std::ostream &file); 126 | void Read (std::istream &file); 127 | 128 | void Read (const std::string &file); 129 | void Save (const std::string &file); 130 | 131 | void Read (const std::vector &bytes); 132 | }; 133 | }; // namespace DYOM 134 | -------------------------------------------------------------------------------- /include/weapon_patterns.hh: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include "functions.hh" 9 | #include "logger.hh" 10 | 11 | static std::vector> weapon_slots 12 | = {{0, 1}, // Fist Slot 0 13 | {2, 3, 4, 5, 6, 7, 8, 9}, // Melee Slot 1 14 | {22, 23, 24}, // Pistol Slot 2 15 | {25, 26, 27}, // Shotgun Slot 3 16 | {28, 29, 32}, // SMG Slot 4 17 | {30, 31}, // Assault Rifle Slot 5 18 | {33, 34}, // Rifle Slot 6 19 | {35, 36, 37, 38}, // Heavy Weapons Slot 7 20 | {16, 17, 18, 39}, // Projectiles Slot 8 21 | {41, 42, 43}, // Spray / Camera Slot 9 22 | {10, 11, 12, 13, 14, 15}, // Gift Slot 10 23 | {44, 45, 46}, // Wearable Slots 11 24 | {40}}; // Detonator Slot 12 25 | 26 | static const std::vector additional_pickups = {1240, 1242, 1247, 1241}; 27 | 28 | /*******************************************************/ 29 | /* Class to handle a single weapon pattern. */ 30 | /*******************************************************/ 31 | class WeaponPattern 32 | { 33 | struct WeaponTypes 34 | { 35 | bool Melee : 1; 36 | bool Pistol : 1; 37 | bool Shotgun : 1; 38 | bool SMG : 1; 39 | bool Assault : 1; 40 | bool Rifle : 1; 41 | bool Heavy : 1; 42 | bool Projectile : 1; 43 | bool Spray : 1; 44 | bool Gadget : 1; 45 | 46 | bool GetValue (uint32_t type); 47 | 48 | } mAllowedTypes; 49 | 50 | struct 51 | { 52 | bool Extra : 1; 53 | bool Explosive : 1; 54 | bool NoExplode : 1; 55 | bool Flame : 1; 56 | bool NoFlame : 1; 57 | bool NoUselessProj : 1; 58 | bool LongRange : 1; 59 | bool Goggles : 1; 60 | bool DualWield : 1; 61 | bool CanDriveby : 1; 62 | bool ProjectileCheck : 1; 63 | bool NoFPSAiming : 1; 64 | } mFlags; 65 | 66 | uint32_t m_nPedType = 0; 67 | uint32_t m_nOriginalWeapon = 0; 68 | 69 | std::string m_szThread = ""; 70 | 71 | bool m_bPickup = false; 72 | bool m_bCached = false; 73 | std::vector m_aCache; 74 | 75 | public: 76 | std::unordered_map weaponIDs 77 | = {{"fist", 0}, {"brassknuckle", 1}, {"golfclub", 2}, 78 | {"nitestick", 3}, {"knifecur", 4}, {"bat", 5}, 79 | {"shovel", 6}, {"poolcue", 7}, {"katana", 8}, 80 | {"chnsaw", 9}, {"gun_dildo1", 10}, {"gun_dildo2", 11}, 81 | {"gun_vibe1", 12}, {"gun_vibe2", 13}, {"flowera", 14}, 82 | {"gun_cane", 15}, {"grenade", 16}, {"teargas", 17}, 83 | {"molotov", 18}, {"colt45", 22}, {"silenced", 23}, 84 | {"desert_eagle", 24}, {"chromegun", 25}, {"sawnoff", 26}, 85 | {"shotgspa", 27}, {"micro_uzi", 28}, {"mp5lng", 29}, 86 | {"ak47", 30}, {"m4", 31}, {"tec9", 32}, 87 | {"cuntgun", 33}, {"sniper", 34}, {"rocketla", 35}, 88 | {"heatseek", 36}, {"flame", 37}, {"minigun", 38}, 89 | {"satchel", 39}, {"bomb", 40}, {"spraycan", 41}, 90 | {"fire_ex", 42}, {"camera", 43}, {"nvgoggles", 44}, 91 | {"irgoggles", 45}, {"gun_para", 46}}; 92 | 93 | /*******************************************************/ 94 | void 95 | SetAllowedTypes (WeaponTypes types) 96 | { 97 | m_bCached = false; 98 | mAllowedTypes = types; 99 | } 100 | void 101 | SetOriginalWeapon (char *weapon) 102 | { 103 | m_bCached = false; 104 | m_nOriginalWeapon = weaponIDs[weapon]; 105 | } 106 | void 107 | SetPedType (int ped) 108 | { 109 | m_bCached = false; 110 | m_nPedType = ped; 111 | } 112 | uint32_t 113 | GetPedType () const 114 | { 115 | return m_nPedType; 116 | } 117 | void 118 | SetPickup (char pickup) 119 | { 120 | m_bCached = false; 121 | if (pickup == 'Y') 122 | m_bPickup = true; 123 | else 124 | m_bPickup = false; 125 | } 126 | 127 | bool 128 | GetPickup () const 129 | { 130 | return m_bPickup; 131 | } 132 | 133 | void 134 | SetThreadName (char threadName[64]) 135 | { 136 | m_bCached = false; 137 | m_szThread = threadName; 138 | } 139 | 140 | std::string 141 | GetThreadName () const 142 | { 143 | return m_szThread; 144 | } 145 | 146 | uint32_t 147 | GetOriginalWeapon () const 148 | { 149 | return m_nOriginalWeapon; 150 | } 151 | 152 | // Returns if a weapon matches a certain pattern 153 | bool DoesWeaponMatchPattern (int weaponID); 154 | void Cache (); 155 | 156 | uint32_t GetRandom (); 157 | 158 | // Reads a flag string in the format "flag=value" or "flag" for just bools 159 | void ReadFlag (const std::string &flag); 160 | 161 | // Reads a list of flags delimited by a '+' 162 | void ParseFlags (const std::string &flags); 163 | 164 | bool MatchWeapon (int weaponID, int ped, bool pickup); 165 | 166 | WeaponPattern () 167 | : mFlags{false, false, false, false, false, false, 168 | false, false, false, false, false} 169 | { 170 | } 171 | }; 172 | -------------------------------------------------------------------------------- /include/missions.hh: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | 11 | struct CRunningScript; 12 | 13 | const int OPCODE_REPLACE_MISSION = 0x1096; // custom opcode used in race scripts 14 | 15 | struct CitiesInfo 16 | { 17 | int citiesUnlocked; 18 | bool SFBarriers; 19 | bool LVBarriers; 20 | int maxWanted; 21 | }; 22 | 23 | struct MissionStatus 24 | { 25 | unsigned char data[102]; 26 | 27 | unsigned char & 28 | operator[] (int index) 29 | { 30 | return data[index - 11]; 31 | } 32 | }; 33 | 34 | struct MissionRandomizerSaveStructure 35 | { 36 | char signature[12] = "RAINBOMIZER"; 37 | unsigned int randomSeed; 38 | MissionStatus missionStatus; 39 | 40 | MissionRandomizerSaveStructure & 41 | operator= (const MissionRandomizerSaveStructure &rhs) 42 | { 43 | if (this == &rhs) 44 | return *this; 45 | 46 | memcpy (this, &rhs, sizeof (MissionRandomizerSaveStructure)); 47 | 48 | return *this; 49 | } 50 | }; 51 | 52 | class MissionRandomizer 53 | { 54 | static MissionRandomizer *mInstance; 55 | 56 | static inline struct Config 57 | { 58 | int ForcedMissionID; 59 | 60 | bool RandomizeOnce = true; 61 | std::string RandomizeOnceSeed; 62 | int MissionSeedHash = 0; 63 | bool ForcedRandomizeOnceSeed = false; 64 | 65 | bool PreserveMomentum = true; 66 | bool DisableMainSCMCheck = false; 67 | 68 | Config () {} 69 | } m_Config; 70 | 71 | MissionRandomizer (){}; 72 | static void DestroyInstance (); 73 | 74 | int mPrevOffset = 0; 75 | unsigned char *mOriginalBaseIP = nullptr; 76 | bool mScriptReplaced = false; 77 | unsigned char *mTempMissionData = nullptr; 78 | int * mLocalVariables = nullptr; 79 | CitiesInfo mCityInfo; 80 | bool mScriptByPass = false; 81 | 82 | MissionRandomizerSaveStructure mSaveInfo; 83 | std::unordered_map> mShuffledOrder; 84 | 85 | void ApplyMissionSpecificFixes (unsigned char *data); 86 | void ApplyMissionFailFixes (); 87 | void TeleportPlayerAfterMission (); 88 | int GetCorrectedMissionNo (); 89 | void StoreCityInfo (CitiesInfo &out); 90 | void RestoreCityInfo (const CitiesInfo &info); 91 | int GetStatusForTwoPartMissions (int index); 92 | void HandleGoSubAlternativeForMission (int index); 93 | 94 | int GetCorrectedMissionStatusIndex (int index); 95 | 96 | void HandleReturnOpcode (CRunningScript *scr, short opcode); 97 | void HandleGoSubOpcode (CRunningScript *scr, short &opcode); 98 | void HandleStoreCarOpcode (CRunningScript *scr, short opcode); 99 | void HandleReplaceMissionOpcode (CRunningScript *scr, short opcode); 100 | void HandleEndThreadOpcode (CRunningScript *scr, short opcode); 101 | void HandleOverrideRestartOpcode (CRunningScript *scr, short opcode); 102 | 103 | bool VerifyMainSCM (); 104 | 105 | void InstallCheat (void *func, uint32_t hash); 106 | 107 | public: 108 | CRunningScript * mRandomizedScript = nullptr; 109 | int mRandomizedMissionNumber = -1; 110 | int mOriginalMissionNumber = -1; 111 | bool mStoreNextMission = false; 112 | int mCurrentCitiesUnlocked = 0; 113 | int mContinuedMission = -1; 114 | int mSkipNextMission = -1; 115 | std::pair mCorrectedMissionStatus = {-1, -1}; 116 | static inline bool mKeyPressOpcode = false; 117 | 118 | /// Returns the static instance for MissionRandomizer. 119 | static MissionRandomizer *GetInstance (); 120 | 121 | /// Initialises Hooks/etc. 122 | void Initialise (); 123 | 124 | /// Checks if the mission script should jump 125 | bool ShouldJump (CRunningScript *src); 126 | 127 | /// Applies Mission Specific Fixes (start) 128 | void ApplyMissionStartSpecificFixes (unsigned char *data); 129 | 130 | /// Sets continued mission 131 | void 132 | SetContinuedMission (int mission) 133 | { 134 | this->mContinuedMission = mission; 135 | } 136 | 137 | /// Sets the randomizer to skip the next mission with this index 138 | void 139 | SetSkippedMission (int mission) 140 | { 141 | this->mSkipNextMission = mission; 142 | } 143 | 144 | /// Sets the randomizer to use a different mission status 145 | void 146 | SetCorrectedMissionStatusIndex (int mission, int newStatus) 147 | { 148 | this->mCorrectedMissionStatus = {mission, newStatus}; 149 | } 150 | 151 | /// Returns a random mission 152 | int GetRandomMission (int originalMission); 153 | 154 | /// Jumps the script to the original offset 155 | void MoveScriptToOriginalOffset (CRunningScript *src); 156 | 157 | /// Unlocks the cities based on the mission number 158 | void UnlockCitiesBasedOnMissionID (int missionId); 159 | void SetGangTerritoriesForMission (int index); 160 | void SetRiotModeForMission (int index); 161 | 162 | void TeleportPlayerBeforeMission (); 163 | 164 | /// Reset save data 165 | void ResetSaveData (); 166 | void InitShuffledMissionOrder (); 167 | 168 | void 169 | SetScriptByPass (bool status = true) 170 | { 171 | mScriptByPass = status; 172 | } 173 | 174 | void Load (); 175 | void Save (); 176 | }; 177 | -------------------------------------------------------------------------------- /src/riot.cc: -------------------------------------------------------------------------------- 1 | #include "riot.hh" 2 | #include 3 | #include "logger.hh" 4 | #include "base.hh" 5 | #include "functions.hh" 6 | #include "injector/calling.hpp" 7 | #include "config.hh" 8 | #include 9 | 10 | RiotRandomizer *RiotRandomizer::mInstance = nullptr; 11 | 12 | static bool greenLightCheat = false; 13 | static char lightResult = 0; 14 | static int randomTimeInterval = 0; 15 | static float currentTimeSinceLightChange = 0.0f; 16 | static float timeOfLastChange = 0.0f; 17 | 18 | /*******************************************************/ 19 | char 20 | TimeToSwitchLight () 21 | { 22 | if (!greenLightCheat && injector::ReadMemory (0x969130 + 30)) 23 | { 24 | greenLightCheat = true; 25 | lightResult = random (0, 2); 26 | currentTimeSinceLightChange = 0.0f; 27 | timeOfLastChange = 0.0f; 28 | randomTimeInterval = 0.0f; 29 | } 30 | else if (greenLightCheat && !injector::ReadMemory (0x969130 + 30)) 31 | greenLightCheat = false; 32 | if (greenLightCheat) 33 | return lightResult; 34 | 35 | if ((int) currentTimeSinceLightChange >= randomTimeInterval) 36 | { 37 | lightResult = random (0, 2); 38 | randomTimeInterval = random (100, 6000); 39 | timeOfLastChange = clock (); 40 | } 41 | 42 | currentTimeSinceLightChange = clock () - timeOfLastChange; 43 | 44 | return lightResult; 45 | } 46 | 47 | /*******************************************************/ 48 | CZone * 49 | CheckNewZone (CVector *point, char checkType) 50 | { 51 | CZone * currentZone = CallAndReturn (point, checkType); 52 | CVector playerPos = FindPlayerCoors (); 53 | if ((int) playerPos.x != (int) point->x 54 | && (int) playerPos.y != (int) point->y 55 | && (int) playerPos.z != (int) point->z) 56 | return currentZone; 57 | 58 | if (std::string (currentZone->m_szTextKey) 59 | != std::string (RiotRandomizer::previousZone)) 60 | { 61 | if (ConfigManager::ReadConfig ("RiotRandomizer") 62 | && RiotRandomizer::m_Config.RandomizeRiots) 63 | { 64 | // Memory address storing if end-game riots are enabled 65 | int gbLARiots = 0xB72958; 66 | 67 | // Memory address storing if riot cheat is enabled 68 | // Checked before randomizing riot and written to in order 69 | // to enable it 70 | int riotCheatActive = 0x969130 + 69; 71 | 72 | // Check if riots already enabled separate from randomizer 73 | // Doesn't take effect in these cases for simplicity 74 | if (!injector::ReadMemory (gbLARiots) 75 | && !injector::ReadMemory (riotCheatActive)) 76 | RiotRandomizer::riotModeRandomized = false; 77 | 78 | if (!injector::ReadMemory (gbLARiots) 79 | && !injector::ReadMemory (riotCheatActive) 80 | && !RiotRandomizer::riotModeRandomized 81 | && random (1000) > 985 82 | && !ScriptSpace[1870]) 83 | { 84 | RiotRandomizer::riotModeRandomized = true; 85 | injector::WriteMemory (riotCheatActive, 1); 86 | } 87 | else if (!injector::ReadMemory (gbLARiots) 88 | && RiotRandomizer::riotModeRandomized 89 | && random (1000) > 600) 90 | { 91 | RiotRandomizer::riotModeRandomized = false; 92 | injector::WriteMemory (riotCheatActive, 0); 93 | } 94 | } 95 | } 96 | 97 | for (int i = 0; i < 8; i++) 98 | { 99 | RiotRandomizer::previousZone[i] = currentZone->m_szTextKey[i]; 100 | } 101 | return currentZone; 102 | } 103 | 104 | /*******************************************************/ 105 | void 106 | RiotRandomizer::Initialise () 107 | { 108 | RegisterHooks ({{HOOK_CALL, 0x572407, (void *) &CheckNewZone}}); 109 | 110 | if (!ConfigManager::ReadConfig ( 111 | "RiotRandomizer", 112 | std::pair ("RandomizeRiots", &m_Config.RandomizeRiots), 113 | std::pair ("RandomizeTrafficLights", 114 | &m_Config.RandomizeTrafficLights))) 115 | return; 116 | 117 | if (m_Config.RandomizeTrafficLights) 118 | { 119 | for (int address : {0x49DB6D, 0x49DB5F, 0x49D6EC, 0x49D862, 120 | 0x49D9E3, 0x49D6D4, 0x49D84A, 0x49D9CD}) 121 | { 122 | injector::MakeCALL (address, (void *) &TimeToSwitchLight); 123 | } 124 | } 125 | 126 | Logger::GetLogger ()->LogMessage ("Intialised RiotRandomizer"); 127 | } 128 | 129 | /*******************************************************/ 130 | void 131 | RiotRandomizer::DestroyInstance () 132 | { 133 | if (RiotRandomizer::mInstance) 134 | delete RiotRandomizer::mInstance; 135 | } 136 | 137 | /*******************************************************/ 138 | RiotRandomizer * 139 | RiotRandomizer::GetInstance () 140 | { 141 | if (!RiotRandomizer::mInstance) 142 | { 143 | RiotRandomizer::mInstance = new RiotRandomizer (); 144 | atexit (&RiotRandomizer::DestroyInstance); 145 | } 146 | return RiotRandomizer::mInstance; 147 | } 148 | -------------------------------------------------------------------------------- /src/weaponstats.cc: -------------------------------------------------------------------------------- 1 | #include "weaponstats.hh" 2 | #include "functions.hh" 3 | #include 4 | #include 5 | #include "injector/injector.hpp" 6 | #include "logger.hh" 7 | #include "base.hh" 8 | #include "config.hh" 9 | 10 | WeaponStatsRandomizer *WeaponStatsRandomizer::mInstance = nullptr; 11 | // Hex flags used to define weapon properties. Values provided in comments 12 | // define single property. Every other value is combination of that properties. 13 | 14 | // 0x1- aim anywhere, 0x2 - aim with arm, 0x4 - 1st person, 0x8 - no auto aim 15 | int aimFlag[] = {0x1, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8}; 16 | 17 | // 0x0 - none, 0x10 - can only aim while moving, 0x20 - can shoot while moving 18 | int movementFlag[] = {0x0, 0x10, 0x20, 0x30}; 19 | 20 | // 0x0 -regular, 0x100 -throw, 0x200 - cant jump with weapon, 0x400 - continous 21 | // fire, 0x800 - dual-wield 22 | int otherFlag[] = {0x0, 0x200, 0x400, 0x600, 0x800, 0xA00, 0xC00, 0xE00}; 23 | 24 | // 0x0 - none, 0x1000 - reload, 0x2000 - can shoot while crouching, 0x4000 - 25 | // reload to start, 0x8000 - long reload 26 | int reloadFlag[] = {0x0, 0x2000, 0x3000, 0x4000, 0x5000, 0x6000, 0x8000, 27 | 0x9000, 0xA000, 0xB000, 0xC000, 0xD000, 0xE000, 0xF000}; 28 | 29 | /*******************************************************/ 30 | int __fastcall RandomizeStats (int *address, int weaponid) 31 | { 32 | CPed *player = FindPlayerPed (); 33 | 34 | if (address < (int *) player || address > (int *) (player + 0x764) 35 | || (weaponid <= 46 && weaponid >= 40) || weaponid == 36 36 | || weaponid == 37 || weaponid < 22) 37 | return 0; 38 | 39 | int weaponids[] = {weaponid, 0, 0, 0}; 40 | 41 | /* Get weapon ids for all skill levels. */ 42 | if (weaponid + 25 >= 47 && weaponid + 25 <= 57) 43 | { 44 | weaponids[1] = weaponid + 25; 45 | weaponids[2] = weaponid + 36; 46 | weaponids[3] = weaponid + 47; 47 | } 48 | 49 | short quality = random (100); 50 | 51 | short ammoClip; 52 | short damage; 53 | float accuracy; 54 | float moveSpeed; 55 | float range; 56 | unsigned int properties; 57 | 58 | if (weaponid == 18 || weaponid == 16 || weaponid == 39 || weaponid == 17) 59 | properties = 0x100; 60 | 61 | else if (weaponid == 35 || weaponid == 36) 62 | properties = 0x48214; 63 | 64 | else if (weaponid == 38) 65 | properties = 0x238; 66 | // randomize SMG properties in the way which they can be used with jetpack 67 | else if (weaponid == 28 || weaponid == 29 || weaponid == 32) 68 | properties = aimFlag[1] + movementFlag[random (3)] 69 | + otherFlag[random (7)] + reloadFlag[2]; 70 | else 71 | properties = aimFlag[random (6)] + movementFlag[random (3)] 72 | + otherFlag[random (7)] + reloadFlag[random (13)]; 73 | 74 | if (quality < 10) 75 | { 76 | ammoClip = random (1, 15); 77 | damage = random (1, 25); 78 | accuracy = randomFloat (0.1, 0.5); 79 | moveSpeed = randomFloat (0, 1.5); 80 | range = randomFloat (10, 30); 81 | } 82 | else if (quality < 85) 83 | { 84 | ammoClip = random (1, 30); 85 | damage = random (1, 50); 86 | accuracy = randomFloat (0.1, 0.75); 87 | moveSpeed = randomFloat (0.5, 2); 88 | range = randomFloat (20, 50); 89 | } 90 | else if (quality < 95) 91 | { 92 | ammoClip = random (30, 50); 93 | damage = random (10, 75); 94 | accuracy = randomFloat (0.25, 1); 95 | moveSpeed = randomFloat (1, 2.5); 96 | range = randomFloat (20, 75); 97 | } 98 | else 99 | { 100 | ammoClip = random (50, 100); 101 | damage = random (20, 150); 102 | accuracy = randomFloat (1, 2); 103 | moveSpeed = randomFloat (1.5, 3); 104 | range = randomFloat (20, 150); 105 | } 106 | 107 | float animValues[] = {randomFloat (0, 0.70f), randomFloat (0, 0.70f), 108 | randomFloat (0, 1.2f)}; 109 | 110 | std::sort (animValues, animValues + 3, std::greater ()); 111 | 112 | for (int id : weaponids) 113 | { 114 | if (id == 0) 115 | break; 116 | 117 | aWeaponInfos[id].m_nFlags = properties; 118 | aWeaponInfos[id].m_nAmmoClipSize = ammoClip; 119 | aWeaponInfos[id].m_nDamage = damage; 120 | aWeaponInfos[id].m_fAccuracy = accuracy; 121 | aWeaponInfos[id].m_fSpeed = moveSpeed; 122 | aWeaponInfos[id].m_fTargetingRange = range; 123 | aWeaponInfos[id].m_fFiringRange = range; 124 | // aWeaponInfos[id].m_fAnimLoopStart = animValues[2]; 125 | // aWeaponInfos[id].m_fAnimFrameFire = animValues[1]; 126 | // aWeaponInfos[id].m_fAnimLoopEnd = animValues[0]; 127 | // aWeaponInfos[id].m_fAnim2LoopStart = animValues[2]; 128 | // aWeaponInfos[id].m_fAnim2FrameFire = animValues[1]; 129 | // aWeaponInfos[id].m_fAnim2LoopEnd = animValues[0]; 130 | } 131 | 132 | return 0; 133 | } 134 | 135 | /*******************************************************/ 136 | void 137 | WeaponStatsRandomizer::Initialise () 138 | { 139 | if (!ConfigManager::ReadConfig ("WeaponStatsRandomizer")) 140 | return; 141 | 142 | RegisterHooks ({{HOOK_CALL, 0x73B4C8, (void *) &RandomizeStats}}); 143 | 144 | Logger::GetLogger ()->LogMessage ("Intialised WeaponStatsRandomizer"); 145 | } 146 | 147 | /*******************************************************/ 148 | WeaponStatsRandomizer * 149 | WeaponStatsRandomizer::GetInstance () 150 | { 151 | 152 | if (!WeaponStatsRandomizer::mInstance) 153 | { 154 | WeaponStatsRandomizer::mInstance = new WeaponStatsRandomizer (); 155 | atexit (&WeaponStatsRandomizer::DestroyInstance); 156 | } 157 | 158 | return WeaponStatsRandomizer::mInstance; 159 | } 160 | 161 | /*******************************************************/ 162 | void 163 | WeaponStatsRandomizer::DestroyInstance () 164 | { 165 | if (WeaponStatsRandomizer::mInstance) 166 | delete WeaponStatsRandomizer::mInstance; 167 | } 168 | -------------------------------------------------------------------------------- /include/injector/assembly.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Injectors - Useful Assembly Stuff 3 | * 4 | * Copyright (C) 2012-2014 LINK/2012 5 | * 6 | * This software is provided 'as-is', without any express or implied 7 | * warranty. In no event will the authors be held liable for any damages 8 | * arising from the use of this software. 9 | * 10 | * Permission is granted to anyone to use this software for any purpose, 11 | * including commercial applications, and to alter it and redistribute it 12 | * freely, subject to the following restrictions: 13 | * 14 | * 1. The origin of this software must not be misrepresented; you must not 15 | * claim that you wrote the original software. If you use this software 16 | * in a product, an acknowledgment in the product documentation would be 17 | * appreciated but is not required. 18 | * 19 | * 2. Altered source versions must be plainly marked as such, and must not be 20 | * misrepresented as being the original software. 21 | * 22 | * 3. This notice may not be removed or altered from any source 23 | * distribution. 24 | * 25 | */ 26 | #pragma once 27 | 28 | // This header is very restrict about compiler and architecture 29 | #ifndef _MSC_VER // MSVC is much more flexible when we're talking about inline assembly 30 | #error Cannot use this header in another compiler other than MSVC 31 | #endif 32 | #ifndef _M_IX86 33 | #error Supported only in x86 34 | #endif 35 | 36 | // 37 | #include "injector.hpp" 38 | 39 | namespace injector 40 | { 41 | struct reg_pack 42 | { 43 | // The ordering is very important, don't change 44 | // The first field is the last to be pushed and first to be poped 45 | 46 | // PUSHAD/POPAD -- must be the lastest fields (because of esp) 47 | union 48 | { 49 | uint32_t arr[8]; 50 | struct { uint32_t edi, esi, ebp, esp, ebx, edx, ecx, eax; }; 51 | }; 52 | 53 | // PUSHFD / POPFD 54 | uint32_t ef; 55 | 56 | enum reg_name { 57 | reg_edi, reg_esi, reg_ebp, reg_esp, reg_ebx, reg_edx, reg_ecx, reg_eax 58 | }; 59 | 60 | enum ef_flag { 61 | carry_flag = 0, parity_flag = 2, adjust_flag = 4, zero_flag = 6, sign_flag = 7, 62 | direction_flag = 10, overflow_flag = 11 63 | }; 64 | 65 | uint32_t& operator[](size_t i) 66 | { return this->arr[i]; } 67 | const uint32_t& operator[](size_t i) const 68 | { return this->arr[i]; } 69 | 70 | template // bit starts from 0, use ef_flag enum 71 | bool flag() 72 | { 73 | return (this->ef & (1 << bit)) != 0; 74 | } 75 | 76 | bool jnb() 77 | { 78 | return flag() == false; 79 | } 80 | }; 81 | 82 | // Lowest level stuff (actual assembly) goes on the following namespace 83 | // PRIVATE! Skip this, not interesting for you. 84 | namespace injector_asm 85 | { 86 | // Wrapper functor, so the assembly can use some templating 87 | template 88 | struct wrapper 89 | { 90 | static void call(reg_pack* regs) 91 | { 92 | T fun; fun(*regs); 93 | } 94 | }; 95 | 96 | // Constructs a reg_pack and calls the wrapper functor 97 | template // where W is of type wrapper 98 | inline void __declspec(naked) make_reg_pack_and_call() 99 | { 100 | _asm 101 | { 102 | // Construct the reg_pack structure on the stack 103 | pushfd // Pushes EFLAGS to reg_pack 104 | pushad // Pushes general purposes registers to reg_pack 105 | add dword ptr[esp+12], 8 // Add 4 to reg_pack::esp 'cuz of our return pointer, let it be as before this func is called 106 | 107 | // Call wrapper sending reg_pack as parameter 108 | push esp 109 | call W::call 110 | add esp, 4 111 | 112 | // Destructs the reg_pack from the stack 113 | sub dword ptr[esp+12], 8 // Fix reg_pack::esp before popping it (doesn't make a difference though) (+4 because eflags) 114 | popad 115 | popfd // Warning: Do not use any instruction that changes EFLAGS after this (-> sub affects EF!! <-) 116 | 117 | // Back to normal flow 118 | ret 119 | } 120 | } 121 | }; 122 | 123 | 124 | /* 125 | * MakeInline 126 | * Makes inline assembly (but not assembly, an actual functor of type FuncT) at address 127 | */ 128 | template 129 | void MakeInline(memory_pointer_tr at) 130 | { 131 | typedef injector_asm::wrapper functor; 132 | if(false) functor::call(nullptr); // To instantiate the template, if not done _asm will fail 133 | MakeCALL(at, injector_asm::make_reg_pack_and_call); 134 | } 135 | 136 | /* 137 | * MakeInline 138 | * Same as above, but it NOPs everything between at and end (exclusive), then performs MakeInline 139 | */ 140 | template 141 | void MakeInline(memory_pointer_tr at, memory_pointer_tr end) 142 | { 143 | MakeRangedNOP(at, end); 144 | MakeInline(at); 145 | } 146 | 147 | /* 148 | * MakeInline 149 | * Same as above, but (at,end) are template parameters. 150 | * On this case the functor can be passed as argument since there will be one func instance for each at,end not just for each FuncT 151 | */ 152 | template 153 | void MakeInline(FuncT func) 154 | { 155 | static std::unique_ptr static_func; 156 | static_func.reset(new FuncT(std::move(func))); 157 | 158 | // Encapsulates the call to static_func 159 | struct Caps 160 | { 161 | void operator()(reg_pack& regs) 162 | { (*static_func)(regs); } 163 | }; 164 | 165 | // Does the actual MakeInline 166 | return MakeInline(lazy_pointer::get(), lazy_pointer::get()); 167 | } 168 | 169 | /* 170 | * MakeInline 171 | * Same as above, but (end) is calculated by the length of a call instruction 172 | */ 173 | template 174 | void MakeInline(FuncT func) 175 | { 176 | return MakeInline(func); 177 | } 178 | }; 179 | -------------------------------------------------------------------------------- /include/util/dyom/tts/TikTok.hh: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "TTSBackend.hh" 4 | #include "util/dyom/Internet.hh" 5 | 6 | #include 7 | #include 8 | #include 9 | 10 | #include 11 | #include 12 | 13 | class TikTokTTS : public TTSBackend 14 | { 15 | InternetUtils internet; 16 | 17 | public: 18 | virtual std::string * 19 | DecodeAPIResponse (const std::string &res) 20 | { 21 | nlohmann::json j = nlohmann::json::parse (res); 22 | auto success = j["success"].get (); 23 | 24 | if (!success) 25 | throw std::runtime_error (j["error"].get ()); 26 | 27 | auto data_b64 = j["data"].get (); 28 | std::string *data = new std::string (base64::from_base64 (data_b64)); 29 | 30 | return data; 31 | } 32 | 33 | virtual HSTREAM 34 | GetSoundStream (const std::string &text, const std::string &voice, 35 | void **data) 36 | { 37 | auto res 38 | = internet 39 | .Post ("/api/generation", "Content-Type: application/json", 40 | nlohmann::json{ 41 | {"text", text}, 42 | {"voice", voice}, 43 | } 44 | .dump ()) 45 | .GetString (); 46 | try 47 | { 48 | std::string *strData = DecodeAPIResponse (res); 49 | auto stream = BASS_StreamCreateFile (TRUE, strData->data (), 0, 50 | strData->size (), 51 | BASS_STREAM_DECODE); 52 | 53 | *data = strData; 54 | return stream; 55 | } 56 | catch (std::exception &e) 57 | { 58 | Logger::GetLogger ()->LogMessage ( 59 | "Tiktok TTS generation failed"); 60 | Logger::GetLogger ()->LogMessage (e.what ()); 61 | } 62 | catch (...) 63 | { 64 | Logger::GetLogger ()->LogMessage ( 65 | "Tiktok TTS generation failed"); 66 | } 67 | 68 | return 0; 69 | } 70 | 71 | virtual std::vector 72 | GetVoices () 73 | { 74 | return std::vector{{ 75 | {"en_male_jomboy", "GB", GENDER_M}, 76 | {"en_us_002", "US", GENDER_F}, 77 | {"en_male_funny", "GB", GENDER_M}, 78 | {"es_mx_002", "GB", GENDER_M}, 79 | {"en_female_samc", "US", GENDER_F}, 80 | {"en_us_ghostface", "US", GENDER_M}, 81 | {"en_female_makeup", "US", GENDER_F}, 82 | {"en_male_cody", "US", GENDER_M}, 83 | {"en_male_grinch", "US", GENDER_M}, 84 | {"en_female_richgirl", "US", GENDER_F}, 85 | {"en_male_narration", "US", GENDER_M}, 86 | {"en_us_006", "US", GENDER_M}, 87 | {"en_uk_001", "GB", GENDER_M}, 88 | {"en_male_deadpool", "US", GENDER_M}, 89 | {"en_au_001", "AU", GENDER_M}, 90 | {"en_uk_003", "GB", GENDER_M}, 91 | {"en_male_ashmagic", "GB", GENDER_M}, 92 | {"en_male_jarvis", "GB", GENDER_M}, 93 | {"en_male_ukneighbor", "GB", GENDER_M}, 94 | {"en_male_olantekkers", "GB", GENDER_M}, 95 | {"en_female_shenna", "GB", GENDER_F}, 96 | {"en_male_ukbutler", "GB", GENDER_M}, 97 | {"en_male_trevor", "GB", GENDER_M}, 98 | {"en_female_pansino", "GB", GENDER_F}, 99 | {"en_male_m03_classical", "GB", GENDER_M}, 100 | {"en_male_cupid", "GB", GENDER_M}, 101 | {"en_female_betty", "GB", GENDER_F}, 102 | {"en_male_m2_xhxs_m03_christmas", "GB", GENDER_M}, 103 | {"en_female_grandma", "GB", GENDER_F}, 104 | {"en_male_santa_narration", "GB", GENDER_M}, 105 | {"en_male_santa_effect", "GB", GENDER_M}, 106 | {"en_male_wizard", "GB", GENDER_M}, 107 | {"en_female_emotional", "GB", GENDER_F}, 108 | {"en_us_009", "US", GENDER_M}, 109 | {"en_us_007", "US", GENDER_M}, 110 | {"en_au_002", "AU", GENDER_M}, 111 | {"en_us_010", "US", GENDER_M}, 112 | {"en_us_chewbacca", "US", GENDER_M}, 113 | {"en_us_ghostface", "US", GENDER_M}, 114 | {"en_us_stitch", "US", GENDER_M}, 115 | {"en_us_c3po", "US", GENDER_M}, 116 | {"en_us_rocket", "US", GENDER_M}, 117 | {"en_us_stormtrooper", "US", GENDER_M}, 118 | {"en_male_ghosthost", "US", GENDER_M}, 119 | {"en_female_madam_leota", "US", GENDER_F}, 120 | {"fr_001", "FR", GENDER_M}, 121 | {"fr_002", "FR", GENDER_M}, 122 | {"es_002", "ES", GENDER_M}, 123 | {"es_mx_002", "MX", GENDER_M}, 124 | {"br_001", "BR", GENDER_F}, 125 | {"br_003", "BR", GENDER_F}, 126 | {"br_004", "BR", GENDER_F}, 127 | {"br_005", "BR", GENDER_M}, 128 | {"bp_female_ivete", "BR", GENDER_F}, 129 | {"bp_female_ludmilla", "BR", GENDER_F}, 130 | {"pt_female_lhays", "PT", GENDER_F}, 131 | {"pt_female_laizza", "PT", GENDER_F}, 132 | {"pt_male_bueno", "PT", GENDER_M}, 133 | {"de_001", "DE", GENDER_F}, 134 | {"de_002", "DE", GENDER_M}, 135 | {"id_001", "IN", GENDER_F}, 136 | {"jp_001", "JP", GENDER_F}, 137 | {"jp_003", "JP", GENDER_F}, 138 | {"jp_005", "JP", GENDER_F}, 139 | {"jp_006", "JP", GENDER_M}, 140 | {"jp_female_fujicochan", "JP", GENDER_F}, 141 | {"jp_female_hasegawariona", "JP", GENDER_F}, 142 | {"jp_male_keiichinakano", "JP", GENDER_M}, 143 | {"jp_female_oomaeaika", "JP", GENDER_F}, 144 | {"jp_male_yujinchigusa", "JP", GENDER_M}, 145 | {"jp_female_shirou", "JP", GENDER_F}, 146 | {"jp_male_tamawakazuki", "JP", GENDER_M}, 147 | {"jp_female_kaorishoji", "JP", GENDER_F}, 148 | {"jp_female_yagishaki", "JP", GENDER_F}, 149 | {"jp_male_hikakin", "JP", GENDER_M}, 150 | {"jp_female_rei", "JP", GENDER_F}, 151 | {"jp_male_shuichiro", "JP", GENDER_M}, 152 | {"jp_male_matsudake", "JP", GENDER_M}, 153 | {"jp_female_machikoriiita", "JP", GENDER_F}, 154 | {"jp_male_matsuo", "JP", GENDER_M}, 155 | {"jp_male_osada", "JP", GENDER_M}, 156 | {"kr_002", "KR", GENDER_M}, 157 | {"kr_003", "KR", GENDER_F}, 158 | {"kr_004", "KR", GENDER_M}, 159 | {"BV074_streaming", "NO", GENDER_F}, 160 | {"BV075_streaming", "NO", GENDER_M}, 161 | }}; 162 | } 163 | 164 | void 165 | FreeData (void *data) 166 | { 167 | delete (std::string *) data; 168 | } 169 | 170 | TikTokTTS () { internet.Open ("tiktok-tts.weilnet.workers.dev"); } 171 | 172 | ~TikTokTTS () { internet.Close (); } 173 | }; 174 | -------------------------------------------------------------------------------- /include/base.hh: -------------------------------------------------------------------------------- 1 | /* 2 | Rainbomizer - A (probably fun) Grand Theft Auto San Andreas Mod that 3 | randomizes stuff 4 | Copyright (C) 2019 - Parik 5 | 6 | This program is free software: you can redistribute it and/or modify 7 | it under the terms of the GNU General Public License as published by 8 | the Free Software Foundation, either version 3 of the License, or 9 | (at your option) any later version. 10 | 11 | This program is distributed in the hope that it will be useful, 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | GNU General Public License for more details. 15 | 16 | You should have received a copy of the GNU General Public License 17 | along with this program. If not, see . 18 | 19 | */ 20 | 21 | #pragma once 22 | 23 | /* Base - contains classes for setting up hooks */ 24 | #include 25 | #include 26 | #include 27 | #include 28 | #include 29 | #include 30 | 31 | enum eHookType 32 | { 33 | HOOK_JUMP, 34 | HOOK_CALL 35 | }; 36 | 37 | struct HookProperties 38 | { 39 | eHookType type; 40 | uintptr_t src; 41 | void * dest; 42 | }; 43 | 44 | struct GamePathA 45 | { 46 | char _path[160 + 1]; 47 | char _temp_path[160 + 1]; 48 | 49 | GamePathA (); 50 | }; 51 | 52 | char * GetGameDirRelativePathA (const char *subpath); 53 | std::string GetRainbomizerFileName (std::string name, std::string subdirs = ""); 54 | FILE * OpenRainbomizerFile (std::string name, std::string mode, 55 | std::string subdirs = ""); 56 | FILE * GetRainbomizerDataFile (const std::string &name, 57 | const std::string &mode = "r"); 58 | 59 | bool VerifyGameVersion (); 60 | 61 | /*******************************************************/ 62 | class HookManager 63 | { 64 | static int InstallDelayedHooks (); 65 | 66 | static HookManager * mInstance; 67 | std::unordered_map mHooks; 68 | std::vector mDelayedHooks; 69 | std::vector> mDelayedFuncs; 70 | 71 | HookManager (){}; 72 | static void DestroyInstance (); 73 | 74 | public: 75 | /// Returns the static instance for HookManager. 76 | static HookManager *GetInstance (); 77 | 78 | /// Initialises Hooks/etc. 79 | void Initialise (); 80 | 81 | /// Creates hooks based on HookProperties 82 | void RegisterHooks (std::vector hooks); 83 | void RegisterDelayedFunction (std::function func); 84 | void RegisterDelayedHooks (std::vector hooks); 85 | 86 | static int GetOriginalCall (int call); 87 | 88 | template 89 | static void 90 | CallOriginal (Args... args) 91 | { 92 | static int branch = GetOriginalCall (addr); 93 | if (branch) 94 | T::call (branch, args...); 95 | } 96 | 97 | template 98 | static auto 99 | CallOriginalAndReturn (std::function fallback, 100 | Args... args) 101 | { 102 | static int branch = GetOriginalCall (addr); 103 | if (branch) 104 | return T::call (branch, args...); 105 | return fallback (); 106 | } 107 | 108 | template 109 | static auto 110 | CallOriginalAndReturn (typename T::result_type fallback, Args... args) 111 | { 112 | int branch = GetOriginalCall (addr); 113 | if (branch) 114 | return T::call (branch, args...); 115 | return fallback; 116 | } 117 | }; 118 | 119 | void RegisterHooks (std::vector hooks); 120 | void RegisterDelayedFunction (std::function func); 121 | void RegisterDelayedHooks (std::vector hooks); 122 | 123 | /// Unprotects the entire module 124 | void UnProtectInstance (); 125 | 126 | struct _EXCEPTION_POINTERS; 127 | 128 | class ExceptionManager 129 | { 130 | static ExceptionManager *mManager; 131 | static long __stdcall RunExceptionHandler (_EXCEPTION_POINTERS *ep); 132 | 133 | ExceptionManager (){}; 134 | std::vector> 135 | mExceptionHandlers; 136 | 137 | static void DestroyExceptionManager (); 138 | 139 | public: 140 | /// Registers a new Exception Handler. These are executed in order in a case 141 | /// of a crash 142 | void 143 | RegisterHandler (std::function handler); 144 | 145 | /// Initiates the Exception Manager 146 | void RegisterExceptionManager (); 147 | 148 | /// Returns/Creates the Exception Manager 149 | static ExceptionManager *GetExceptionManager (); 150 | }; 151 | 152 | /*******************************************************/ 153 | constexpr char 154 | NormaliseChar (const char c) 155 | { 156 | if (c >= 'A' && c <= 'Z') 157 | return c + ('a' - 'A'); 158 | 159 | else if (c == '\\') 160 | return '/'; 161 | 162 | return c; 163 | } 164 | 165 | /*******************************************************/ 166 | template 167 | void 168 | Call (Args... args) 169 | { 170 | reinterpret_cast (address) (args...); 171 | } 172 | 173 | /*******************************************************/ 174 | template 175 | Ret 176 | CallAndReturn (Args... args) 177 | { 178 | return reinterpret_cast (address) (args...); 179 | } 180 | 181 | /*******************************************************/ 182 | template 183 | void 184 | CallMethod (C _this, Args... args) 185 | { 186 | reinterpret_cast (address) (_this, 187 | args...); 188 | } 189 | 190 | /*******************************************************/ 191 | template 192 | Ret 193 | CallMethodAndReturn (C _this, Args... args) 194 | { 195 | return reinterpret_cast ( 196 | address) (_this, args...); 197 | } 198 | 199 | /*******************************************************/ 200 | template 201 | void 202 | CallVirtualMethod (C _this, Args... args) 203 | { 204 | reinterpret_cast ( 205 | (*reinterpret_cast (_this))[tableIndex]) (_this, args...); 206 | } 207 | 208 | /*******************************************************/ 209 | template 210 | Ret 211 | CallVirtualMethodAndReturn (C _this, Args... args) 212 | { 213 | return reinterpret_cast ( 214 | (*reinterpret_cast (_this))[tableIndex]) (_this, args...); 215 | } -------------------------------------------------------------------------------- /include/injector/gvm/translator.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Injectors - Address Translation Management 3 | * 4 | * Copyright (C) 2014 LINK/2012 5 | * 6 | * This software is provided 'as-is', without any express or implied 7 | * warranty. In no event will the authors be held liable for any damages 8 | * arising from the use of this software. 9 | * 10 | * Permission is granted to anyone to use this software for any purpose, 11 | * including commercial applications, and to alter it and redistribute it 12 | * freely, subject to the following restrictions: 13 | * 14 | * 1. The origin of this software must not be misrepresented; you must not 15 | * claim that you wrote the original software. If you use this software 16 | * in a product, an acknowledgment in the product documentation would be 17 | * appreciated but is not required. 18 | * 19 | * 2. Altered source versions must be plainly marked as such, and must not be 20 | * misrepresented as being the original software. 21 | * 22 | * 3. This notice may not be removed or altered from any source 23 | * distribution. 24 | * 25 | */ 26 | #pragma once 27 | 28 | #if !defined(INJECTOR_GVM_HAS_TRANSLATOR) 29 | #error Missing INJECTOR_GVM_HAS_TRANSLATOR on compiler definitions 30 | #endif 31 | 32 | /* 33 | * This is a quick solution for address translations if you're too lazy to implement a proper address_manager::translator by yourself 34 | * So, just call address_translator_manager::singleton().translate(p) from your address_manager::translator and that's it. 35 | * It'll translate addresses based on 'address_translator' objects, when one gets constructed it turns into a possible translator. 36 | * At the constructor of your derived 'address_translator' make the map object to have [addr_to_translate] = translated_addr; 37 | * There's also the virtual method 'fallback' that will get called when the translation wasn't possible, you can do some fallback stuff here 38 | * (such as return the pointer as is or output a error message) 39 | */ 40 | 41 | #include "../injector.hpp" 42 | #include 43 | #include 44 | #include 45 | 46 | namespace injector 47 | { 48 | /* 49 | * address_translator 50 | * Base for an address translator 51 | */ 52 | class address_translator 53 | { 54 | private: 55 | bool enabled; 56 | void add(); 57 | void remove(); 58 | 59 | protected: 60 | friend class address_translator_manager; 61 | std::map map; 62 | 63 | public: 64 | address_translator() : enabled(true) 65 | { 66 | // Must have bounds filled with min ptr and max ptr to have search working properly 67 | map.insert(std::make_pair(raw_ptr(0x00000000u), raw_ptr(0x00000000u))); 68 | map.insert(std::make_pair(raw_ptr(0xffffffffu), raw_ptr(0xffffffffu))); 69 | add(); 70 | } 71 | 72 | ~address_translator() 73 | { 74 | remove(); 75 | } 76 | 77 | virtual void* fallback(void*) const 78 | { 79 | return nullptr; 80 | } 81 | 82 | 83 | // Enables or disables this translator 84 | void enable(bool enable_it) 85 | { 86 | if(enable_it) this->enable(); 87 | else this->disable(); 88 | } 89 | 90 | // Enables this translator 91 | void enable() 92 | { 93 | this->enabled = true; 94 | } 95 | 96 | // Disables this translator 97 | void disable() 98 | { 99 | this->enabled = false; 100 | } 101 | 102 | // Checks if this translator is enabled 103 | bool is_enabled() const 104 | { 105 | return enabled; 106 | } 107 | }; 108 | 109 | /* 110 | * address_translator_manager 111 | * Manages the address_translator objects 112 | */ 113 | class address_translator_manager 114 | { 115 | protected: 116 | friend class address_manager; 117 | friend class address_translator; 118 | 119 | std::list translators; 120 | 121 | void add(const address_translator& t) 122 | { 123 | translators.push_front(&t); 124 | } 125 | 126 | void remove(const address_translator& t) 127 | { 128 | translators.remove(&t); 129 | } 130 | 131 | public: 132 | // Translates the address p 133 | void* translator(void* p); 134 | 135 | // Singleton object 136 | static address_translator_manager& singleton() 137 | { 138 | static address_translator_manager mgr; 139 | return mgr; 140 | } 141 | }; 142 | 143 | 144 | 145 | inline void* address_translator_manager::translator(void* p_) 146 | { 147 | static const size_t max_ptr_dist = 7; 148 | 149 | // Tries to find an address in a translator map 150 | auto try_map = [](const std::map& map, memory_pointer_raw p) -> memory_pointer_raw 151 | { 152 | memory_pointer_raw result = nullptr; 153 | 154 | // Find first element in the map that is greater than or equal to p 155 | auto it = map.lower_bound(p); 156 | if(it != map.end()) 157 | { 158 | // If it's not exactly the address, get back one position on the table 159 | if(it->first != p) --it; 160 | 161 | auto diff = (p - it->first).as_int(); // What's the difference between p and that address? 162 | if(diff <= max_ptr_dist) // Could we live with this difference in hands? 163 | result = it->second + raw_ptr(diff); // Yes, we can! 164 | } 165 | 166 | return result; 167 | }; 168 | 169 | 170 | // 171 | memory_pointer_raw result = nullptr; 172 | 173 | // Try to find translation for this pointer 174 | auto& mgr = address_translator_manager::singleton().translators; 175 | for(auto it = mgr.begin(); result == nullptr && it != mgr.end(); ++it) 176 | { 177 | auto& t = **it; 178 | if(t.is_enabled()) result = try_map(t.map, p_); 179 | } 180 | 181 | // If we couldn't translate the address, notify and try to fallback 182 | if(result.is_null()) 183 | { 184 | for(auto it = mgr.begin(); result == nullptr && it != mgr.end(); ++it) 185 | { 186 | auto& t = **it; 187 | if(t.is_enabled()) result = t.fallback(p_); 188 | } 189 | } 190 | 191 | return result.get(); 192 | } 193 | 194 | inline void address_translator::add() 195 | { 196 | address_translator_manager::singleton().add(*this); 197 | } 198 | 199 | inline void address_translator::remove() 200 | { 201 | address_translator_manager::singleton().remove(*this); 202 | } 203 | } 204 | --------------------------------------------------------------------------------