Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include "CustomFiberThread.h"
- #include "Scripting.h"
- #include "../ScriptHook/Log.h"
- #include <windows.h>
- #include <stdio.h>
- using namespace Scripting;
- // ASSEMBLY FUNCTIONS, MAYBE CAN NOT BE A CLASS FUNCTION
- __declspec( noinline ) u32 GTA4_GetHandleFromPed( CPool< void* >* pPool, void *Ped )
- {
- _asm mov ecx, pPool;
- _asm mov eax, Ped;
- _asm sub eax, [ecx];
- _asm cdq;
- _asm idiv dword ptr [ecx+12];
- _asm mov edx, eax;
- _asm mov eax, [ecx+4];
- _asm movzx eax, byte ptr [eax+edx];
- _asm shl edx, 8;
- _asm add eax, edx;
- }
- // ASSEMBLY FUNCTIONS, MAYBE CAN NOT BE A CLASS FUNCTION
- RiotThread::RiotThread()
- {
- SetName( "RiotIV_050" );
- }
- CPool< void* >* RiotThread::GetPedPoolNative()
- {
- // HACKHACK: Static address for GTAIV 1.0.6.0; DEPRECIATED!!!
- // return reinterpret_cast< CPool< void* >* >( *reinterpret_cast< DWORD* >( Game::GetBase() + 0x18A72BC ) );
- return reinterpret_cast< CPool< void* >* >( *reinterpret_cast< DWORD* >( m_ulPedPoolBase ) );
- }
- u32 RiotThread::GetPedCount()
- {
- if( GetPedPoolNative() == NULL ) return 0;
- return GetPedPoolNative()->Count();
- }
- b8 RiotThread::GetPedByIndex( int idx, Ped *Out )
- {
- if( !Out )
- return false;
- Out->Set( 0 );
- if( GetPedCount() == 0 )
- return false;
- void *CurrentPedIdx = GetPedPoolNative()->at( idx );
- if( CurrentPedIdx == NULL )
- return false;
- Out->Set( GTA4_GetHandleFromPed( GetPedPoolNative(), CurrentPedIdx ) );
- return ( Out->IsValid() && DoesCharExist( *Out ) );
- }
- Scripting::Vector3 RiotThread::GetPedVector( Scripting::Ped *In )
- {
- Vector3 Ret(0,0,0);
- Scripting::GetCharCoordinates( *In, &Ret.X, &Ret.Y, &Ret.Z );
- return Ret;
- }
- Player RiotThread::GetPlayer()
- {
- Player playerIndex = ConvertIntToPlayerIndex(GetPlayerId());
- return playerIndex;
- }
- Scripting::Ped RiotThread::GetPlayerPed()
- {
- Ped ped;
- GetPlayerChar( GetPlayer(), &ped );
- return ped;
- }
- Scripting::eWeapon RiotThread::GetRandomWeapon()
- {
- srand( GetTickCount() );
- return static_cast< eWeapon >( m_UsableWeaponry[ rand() % m_UsableWeaponry.size() ] );
- }
- b8 RiotThread::IsPedPolice( Scripting::Ped ped )
- {
- eModel CurrentModel;
- Scripting::GetCharModel( ped, &CurrentModel );
- return (
- ( CurrentModel == MODEL_M_Y_COP ) ||
- ( CurrentModel == MODEL_M_Y_COP_TRAFFIC ) ||
- ( CurrentModel == MODEL_M_M_FATCOP_01 ) ||
- ( CurrentModel == MODEL_CS_MITCHCOP ) ||
- ( CurrentModel == MODEL_M_Y_SWAT ) ||
- ( CurrentModel == MODEL_M_M_FBI ) ||
- ( CurrentModel == MODEL_M_Y_STROOPER ) );
- }
- b8 RiotThread::ShouldRiot( Scripting::Ped ped )
- {
- if( m_DontRiotHashes.empty() )
- {
- return true;
- }
- for( size_t i = 0; i < m_DontRiotHashes.size(); i++ )
- {
- if( IsCharModel( ped, static_cast< Scripting::eModel >( m_DontRiotHashes[ i ] ) ) )
- {
- return false;
- }
- }
- return true;
- }
- b8 RiotThread::IsPedAllowedToRiot( Scripting::Ped ped )
- {
- if( m_RiotHashes.empty() )
- return true;
- for( size_t i = 0; i < m_RiotHashes.size(); i++ )
- {
- if( IsCharModel( ped, static_cast< Scripting::eModel >( m_RiotHashes[ i ] ) ) )
- {
- return true;
- }
- }
- return false;
- }
- b8 RiotThread::CausePedToRiot( Scripting::Ped LocalPed, Scripting::Ped RiotPed )
- {
- // Check if ped exists
- if( DoesCharExist( RiotPed ) == false )
- {
- return false;
- }
- // Check the model for status
- if( ShouldRiot( RiotPed ) == false || IsPedAllowedToRiot( RiotPed ) == false )
- {
- if( IsPedAMissionPed( RiotPed ) )
- {
- MarkCharAsNoLongerNeeded( &RiotPed );
- }
- return false;
- }
- // If not "visible", delete them, not needed
- if( IsCharVisible( RiotPed ) == false )
- {
- if( IsPedAMissionPed( RiotPed ) )
- {
- MarkCharAsNoLongerNeeded( &RiotPed );
- DeleteChar( &RiotPed );
- }
- return false;
- }
- // If dead, fatally injured
- // if mission ped, unmark, stop
- if( IsCharDead( RiotPed ) || IsCharFatallyInjured( RiotPed ) )
- {
- if( IsPedAMissionPed( RiotPed ) )
- {
- MarkCharAsNoLongerNeeded( &RiotPed );
- }
- return false;
- }
- // If cops rioting is disabled and ped is police, stop
- if( m_bCopsGoCrazy == false && IsPedPolice( RiotPed ) )
- {
- if( IsPedAMissionPed( RiotPed ) )
- {
- MarkCharAsNoLongerNeeded( &RiotPed );
- }
- return false;
- }
- // If usable weaponry is available
- if( m_UsableWeaponry.size() > 0 )
- {
- //if NOT police (already have weapons)
- if( IsPedPolice( RiotPed ) == false )
- {
- //if have a gun already, and not police, stop
- if( Scripting::IsCharArmed( RiotPed, WEAPON_SLOT_MELEE )
- || Scripting::IsCharArmed( RiotPed, WEAPON_SLOT_HANDGUN )
- || Scripting::IsCharArmed( RiotPed, WEAPON_SLOT_HEAVY )
- || Scripting::IsCharArmed( RiotPed, WEAPON_SLOT_RIFLE )
- || Scripting::IsCharArmed( RiotPed, WEAPON_SLOT_SHOTGUN )
- || Scripting::IsCharArmed( RiotPed, WEAPON_SLOT_SMG )
- || Scripting::IsCharArmed( RiotPed, WEAPON_SLOT_SNIPER )
- || Scripting::IsCharArmed( RiotPed, WEAPON_SLOT_THROWN ) )
- {
- return false;
- }
- }
- }
- // Range checking to avoid crashes
- Scripting::Vector3 LocalVec = GetPedVector( &LocalPed );
- Scripting::Vector3 PedVec = GetPedVector( &RiotPed );
- if( PedVec.Distance( &LocalVec ) > m_fMaximumRange )
- {
- // HACKHACK: If outside of maximum range mark as no longer needed...
- if( IsPedAMissionPed( RiotPed ) )
- {
- MarkCharAsNoLongerNeeded( &RiotPed );
- }
- return false;
- }
- if( IsPedAMissionPed( RiotPed ) == false )
- {
- // Setup violent tendencies
- SetCharAsMissionChar( RiotPed );
- SetCharAsEnemy( RiotPed, m_bTargetPlayer );
- SetPedDiesWhenInjured( RiotPed, true );
- AllowTargetWhenInjured( RiotPed, true );
- SetCharWillMoveWhenInjured( RiotPed, true );
- SetCharWillDoDrivebys( RiotPed, true );
- SetCharWillUseCarsInCombat( RiotPed, m_bPedsUseCars );
- SetPedWontAttackPlayerWithoutWantedLevel( RiotPed, 0 );
- SetSenseRange( RiotPed, m_fMaximumRange );
- SetCharAccuracy( RiotPed, 100 );
- if( IsPedPolice( RiotPed ) == false )
- {
- SetCharWantedByPolice( RiotPed, m_bPedsWanted );
- SetCharRelationshipGroup( RiotPed, 8 );
- // If weaponry available, give random weapon
- if( m_UsableWeaponry.size() > 0 )
- {
- eWeapon RandomWeapon = GetRandomWeapon();
- GiveWeaponToChar( RiotPed, RandomWeapon, ( RandomWeapon > 3 ) ? 9999 : 0, 0 );
- SetCurrentCharWeapon( RiotPed, RandomWeapon, true );
- BlockPedWeaponSwitching( RiotPed, true );
- }
- else
- {
- // Melee if no weapons are set
- RemoveAllCharWeapons( RiotPed );
- }
- }
- // Set attacking task
- TaskCombatHatedTargetsAroundChar( RiotPed, m_fMaximumRange );
- SetCharKeepTask( RiotPed, true );
- }
- return true;
- }
- void RiotThread::SpawnNewRioter( Ped LocalPed, Vector3 SpawnVector )
- {
- Scripting::PrintStringWithLiteralStringNow( "STRING", "Spawning new riot ped", 3000, true );
- srand( GetTickCount() );
- eModel ModelSpawn = static_cast< eModel >( m_SpawnHashes[ rand() % m_SpawnHashes.size() ] );
- RequestModel( ModelSpawn );
- while( HasModelLoaded( ModelSpawn ) == false )
- {
- Wait(10);
- }
- Ped OutPed;
- CreateChar( 2, ModelSpawn, SpawnVector.X, SpawnVector.Y, SpawnVector.Z, &OutPed, true );
- if( OutPed.IsValid() )
- {
- while( DoesCharExist( OutPed ) == false )
- {
- Wait(10);
- }
- while( IsCharVisible( OutPed ) == false )
- {
- Wait(10);
- }
- SetCharHealth( OutPed, 200 );
- MarkCharAsNoLongerNeeded( &OutPed );
- }
- }
- void RiotThread::SetupRelationships()
- {
- SetRelationship( 5, 8, 8 ); // Rioters hate themselves
- SetRelationship( 5, 8, 3 ); // Rioters hate police
- SetPlayerCanBeHassledByGangs( GetPlayer(), m_bTargetPlayer );
- if( m_bTargetPlayer )
- {
- SetRelationship( 5, 8, 0 ); // Rioters hate player (you)
- SetRelationship( 5, 0, 8 ); // Player hate rioters
- if( m_bCopsGoCrazy )
- {
- SetRelationship( 5, 0, 3 ); //Cops hate player (you)
- }
- }
- else
- {
- SetRelationship( 1, 8, 0 ); // Rioters ignore player (you)
- SetRelationship( 1, 0, 8 ); // Player ignore rioters
- }
- if( m_bCopsGoCrazy )
- {
- SetRelationship( 5, 3, 8 ); // Cops hate rioters
- }
- }
- std::vector< int > RiotThread::StringToIntList( const char *str )
- {
- std::vector< int > ReturnVector;
- if( str == NULL )
- {
- ReturnVector.clear();
- return ReturnVector;
- }
- //
- char *pch = strtok( const_cast< char* >( str ), "," );
- if( pch == NULL )
- {
- ReturnVector.push_back( atoi( str ) );
- }
- else
- {
- while( pch )
- {
- ReturnVector.push_back( atoi( pch ) );
- pch = strtok( 0, "," );
- }
- }
- return ReturnVector;
- }
- void RiotThread::SetupSettingsFile()
- {
- Log::Debug( "Loading Settings..." );
- m_pConfigService = ScriptHookManager::RequestService< IConfigService >( "Config" );
- if( m_pConfigService )
- {
- IConfig* Configuration = m_pConfigService->Create( IConfigService::ConfigTypeXml );
- if( Configuration == NULL )
- return;
- Configuration->Set( "RiotIV", "Enabled", "1" );
- Configuration->Set( "RiotIV", "TargetPlayer", "0" );
- Configuration->Set( "RiotIV", "CrazyCops", "1" );
- Configuration->Set( "RiotIV", "PedsUseCars", "1" );
- Configuration->Set( "RiotIV", "PedsWanted", "1" );
- Configuration->Set( "RiotIV", "MadDrivers", "1" );
- Configuration->Set( "RiotIV", "EmergencyServicesDisabled", "1" );
- Configuration->Set( "RiotIV", "PedMultiplierEnforce", "NONE" );
- Configuration->Set( "RiotIV", "UsableWeaponry", "4,5,7,9,10,11,12,13,14,15,16,17,18" );
- Configuration->Set( "RiotIV", "DontRiotHashes", "" );
- Configuration->Set( "RiotIV", "SpawnHashes", "1794146792" );
- Configuration->Set( "RiotIV", "RiotHashes", "ANY" );
- Configuration->Set( "RiotIV", "MaximumRange", "100.0" );
- char *pszModulePath = GetModulePath();
- if( pszModulePath == 0 || strlen( pszModulePath ) == 0 )
- return;
- Log::Debug( "Module Path [%s]", pszModulePath );
- char pszConfigPath[ MAX_PATH ] = { 0 };
- strcat_s( pszConfigPath, MAX_PATH, GetModulePath() );
- strcat_s( pszConfigPath, MAX_PATH, "Riot.xml" );
- Log::Debug( "Loading configuration from [%s]", pszConfigPath );
- WIN32_FIND_DATAA wfd;
- if ( FindFirstFileA( pszConfigPath, &wfd ) != INVALID_HANDLE_VALUE )
- {
- Configuration->Load( pszConfigPath );
- // HACKHACK: Save after we load to ensure any new values are inserted into the file for future loading
- Configuration->Save( pszConfigPath );
- }
- else
- {
- Configuration->Save( pszConfigPath );
- }
- m_bEnabled = ( Configuration->GetInteger( "RiotIV", "Enabled", 1 ) == 1 );
- m_bTargetPlayer = ( Configuration->GetInteger( "RiotIV", "TargetPlayer", 0 ) == 1 );
- m_bCopsGoCrazy = ( Configuration->GetInteger( "RiotIV", "CrazyCops", 0 ) == 1 );
- m_bPedsUseCars = ( Configuration->GetInteger( "RiotIV", "PedsUseCars", 1 ) == 1 );
- m_bPedsWanted = ( Configuration->GetInteger( "RiotIV", "PedsWanted", 0 ) == 1 );
- m_bMadDrivers = ( Configuration->GetInteger( "RiotIV", "MadDrivers", 0 ) == 1 );
- m_bEmergencyServicesDisabled = ( Configuration->GetInteger( "RiotIV", "EmergencyServicesDisabled", 0 ) == 1 );
- m_fMaximumRange = Configuration->GetFloat( "RiotIV", "MaximumRange", 100.f );
- CONST CHAR* PedMultiEnforce = Configuration->GetString( "RiotIV", "PedMultiplierEnforce" );
- CONST CHAR* UsableWeapons = Configuration->GetString( "RiotIV", "UsableWeaponry" );
- CONST CHAR* DontRiotHashes = Configuration->GetString( "RiotIV", "DontRiotHashes" );
- CONST CHAR* RiotHashes = Configuration->GetString( "RiotIV", "RiotHashes" );
- CONST CHAR* SpawnHashes = Configuration->GetString( "RiotIV", "SpawnHashes" );
- m_UsableWeaponry = StringToIntList( UsableWeapons );
- m_DontRiotHashes = StringToIntList( DontRiotHashes );
- m_SpawnHashes = StringToIntList( SpawnHashes );
- if( _stricmp( PedMultiEnforce, "NONE" ) == 0 )
- {
- m_bForcePedMultiplier = false;
- }
- else
- {
- m_bForcePedMultiplier = true;
- m_fPedMultiplier = static_cast< f32 >( atof( PedMultiEnforce ) );
- }
- if( _stricmp( RiotHashes, "ANY" ) == 0 )
- {
- m_RiotHashes.clear();
- }
- else
- {
- m_RiotHashes = StringToIntList( RiotHashes );
- }
- Configuration->Release();
- }
- else
- {
- Log::Debug( "Unable to load configuration service.." );
- }
- }
- char* RiotThread::GetModulePath()
- {
- static char pszPath[ MAX_PATH ] = { 0 };
- if( strlen( pszPath ) > 0 )
- return pszPath;
- GetModuleFileNameA( m_hModule, pszPath, sizeof( pszPath ) );
- u32 i = strlen( pszPath );
- while( i > 0 && pszPath[i] != '\\' )
- {
- i--;
- }
- pszPath[i] = 0;
- strcat_s( pszPath, MAX_PATH, "\\" );
- return pszPath;
- }
- void RiotThread::UpdateCode()
- {
- HMODULE hMainModule = GetModuleHandleW( NULL );
- Log::Debug( "Finding signiture..[0x%X][0x%X]", hMainModule, Game::GetBase() );
- m_ulPedPoolBase = Code::FindAddress::DetectPattern(
- reinterpret_cast< unsigned long >( hMainModule ), 0xFFFFFF,
- ( BYTE* )"\x55\x8B\xEC\x83\xE4\xF0\x8B\x15\x00\x00\x00\x00\x81\xEC\xEC\x00\x00\x00",
- ( CHAR* )"xxxxxxxx????xxxxxx" );
- if( m_ulPedPoolBase == NULL )
- {
- Log::Fatal( "PedPoolBase not found...critical error" );
- ExitProcess(0);
- }
- else
- {
- Log::Debug( "PedPoolBase 001 [0x%X]", m_ulPedPoolBase );
- m_ulPedPoolBase += 8;
- Log::Debug( "PedPoolBase 002 [0x%X]", m_ulPedPoolBase );
- m_ulPedPoolBase = *reinterpret_cast< unsigned long* >( m_ulPedPoolBase );
- Log::Debug( "PedPoolBase FIN [0x%X]", m_ulPedPoolBase );
- Log::Debug( "Address - Base = [0x%X]", m_ulPedPoolBase - reinterpret_cast< unsigned long >( hMainModule ) );
- }
- }
- void RiotThread::RunScript()
- {
- SetupSettingsFile();
- CreateKeyboard();
- CreateMenu();
- while( IsThreadAlive() )
- {
- if( NetworkIsSessionStarted() == false )
- {
- Ped LocalPed = GetPlayerPed();
- if( LocalPed.IsValid() == false )
- continue;
- Vector3 LocalVector = GetPedVector( &LocalPed );
- if( m_bSpawnRandomPedNextFrame && m_SpawnHashes.size() )
- {
- SpawnNewRioter( LocalPed, Vector3( LocalVector.X + 2.f, LocalVector.Y, LocalVector.Z ) );
- m_bSpawnRandomPedNextFrame = false;
- }
- if( m_bForcePedMultiplier )
- {
- SetPedDensityMultiplier( m_fPedMultiplier );
- }
- SwitchMadDrivers( m_bMadDrivers );
- AllowEmergencyServices( !m_bEmergencyServicesDisabled );
- SetPoliceIgnorePlayer( GetPlayer(), m_bEmergencyServicesDisabled );
- if( m_bEmergencyServicesDisabled )
- {
- SetCharWantedByPolice( LocalPed, false );
- ClearWantedLevel( GetPlayer() );
- ClearAreaOfCops( LocalVector.X, LocalVector.Y, LocalVector.Z, m_fMaximumRange );
- }
- if( m_bEnabled )
- {
- AllowGangRelationshipsToBeChangedByNextCommand( true );
- SetupRelationships();
- for( u32 i = 0; i < GetPedCount(); i++ )
- {
- Ped Index;
- Index.Set( 0 );
- if( GetPedByIndex( i, &Index ) )
- {
- if( Index.IsNull() )
- continue;
- if( Index.Get() == LocalPed.Get() )
- continue;
- if( CausePedToRiot( LocalPed, Index ) == false )
- continue;
- }
- }
- }
- }
- Wait( 10 );
- }
- }
- void RiotThread::OnStart()
- {
- m_pMenu = NULL;
- }
- void RiotThread::OnKill()
- {
- IKeyboardHookService *kbhService = ScriptHookManager::RequestService<IKeyboardHookService>( "KeyboardHook" );
- kbhService->RemoveHandler( this );
- if( m_pMenu )
- {
- m_pMenu->Release();
- m_pMenu = NULL;
- }
- ScriptThread::OnKill();
- }
- void RiotThread::CreateKeyboard()
- {
- IKeyboardHookService *kbhService = ScriptHookManager::RequestService<IKeyboardHookService>( "KeyboardHook" );
- kbhService->AddHandler( this );
- }
- void RiotThread::CreateMenu()
- {
- IMenuService *menuService = ScriptHookManager::RequestService< IMenuService >( "Menu" );
- m_pMenu = menuService->CreateMenu();
- m_pMenu->SetTitle( "Riot mode" );
- AddMenuItemCustom( 0, m_bEnabled ? "Disable Riot Mode" : "Enable Riot Mode" );
- AddMenuItemCustom( 1, m_bTargetPlayer ? "Disable peds targetting player" : "Enable peds targetting player" );
- AddMenuItemCustom( 2, m_bCopsGoCrazy ? "Disable cops rioting" : "Enable cops rioting" );
- AddMenuItemCustom( 3, m_bPedsUseCars ? "Disable peds use cars in combat" : "Enable peds use cars in combat" );
- AddMenuItemCustom( 4, m_bPedsWanted ? "Disable peds wanted" : "Enable peds wanted" );
- AddMenuItemCustom( 5, m_bMadDrivers ? "Disable mad drivers" : "Enable mad drives" );
- AddMenuItemCustom( 6, m_bEmergencyServicesDisabled ? "Enable emergancy services" : "Disable emergancy services" );
- m_pMenu->SetEventHandler( this );
- }
- void RiotThread::AddMenuItemCustom( int idx, char *pszFormat, ... )
- {
- char FormattedBuffer[ 1024 ] = { 0 };
- va_list va_alist;
- va_start( va_alist, pszFormat );
- _vsnprintf(
- FormattedBuffer + strlen( FormattedBuffer ),
- sizeof( FormattedBuffer ) - strlen( FormattedBuffer ),
- pszFormat, va_alist );
- va_end( va_alist );
- m_pMenu->AddItem( idx, FormattedBuffer );
- }
- void RiotThread::SetMenuItemCustom( int idx, char *pszFormat, ... )
- {
- char FormattedBuffer[ 1024 ] = { 0 };
- va_list va_alist;
- va_start( va_alist, pszFormat );
- _vsnprintf(
- FormattedBuffer + strlen( FormattedBuffer ),
- sizeof( FormattedBuffer ) - strlen( FormattedBuffer ),
- pszFormat, va_alist );
- va_end( va_alist );
- m_pMenu->SetItem( idx, FormattedBuffer );
- }
- void RiotThread::OnMenuSelectionChanged( IMenu *menu, u32 id )
- {
- // None?
- }
- void RiotThread::OnMenuSelected( IMenu *menu, u32 id )
- {
- switch( id )
- {
- case 0:
- {
- m_bEnabled = !m_bEnabled;
- SetMenuItemCustom( 0, m_bEnabled ? "Disable Riot Mode" : "Enable Riot Mode" );
- break;
- }
- case 1:
- {
- m_bTargetPlayer = !m_bTargetPlayer;
- SetMenuItemCustom( 1, m_bTargetPlayer ? "Disable peds targetting player" : "Enable peds targetting player" );
- break;
- }
- case 2:
- {
- m_bCopsGoCrazy = !m_bCopsGoCrazy;
- SetMenuItemCustom( 2, m_bCopsGoCrazy ? "Disable cops rioting" : "Enable cops rioting" );
- break;
- }
- case 3:
- {
- m_bPedsUseCars = !m_bPedsUseCars;
- SetMenuItemCustom( 3, m_bPedsUseCars ? "Disable peds use cars in combat" : "Enable peds use cars in combat" );
- break;
- }
- case 4:
- {
- m_bPedsWanted = !m_bPedsWanted;
- SetMenuItemCustom( 4, m_bPedsWanted ? "Disable peds wanted" : "Enable peds wanted" );
- break;
- }
- case 5:
- {
- m_bMadDrivers = !m_bMadDrivers;
- SetMenuItemCustom( 5, m_bMadDrivers ? "Disable mad drivers" : "Enable mad drives" );
- break;
- }
- case 6:
- {
- m_bEmergencyServicesDisabled = !m_bEmergencyServicesDisabled;
- SetMenuItemCustom( 6, m_bEmergencyServicesDisabled ? "Enable emergancy services" : "Disable emergancy services" );
- break;
- }
- }
- }
- void RiotThread::OnKeyboardHookEvent( const IKeyboardHookHandler::KeyEventArgs &args )
- {
- if( args.VirtualKey == VK_INSERT && !args.WasKeyDownBefore )
- {
- if( m_pMenu )
- {
- m_pMenu->Show();
- }
- }
- if( args.VirtualKey == VK_F3 && !args.WasKeyDownBefore )
- {
- m_bSpawnRandomPedNextFrame = true;
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement