View difference between Paste ID: 6y1HdXy5 and
SHOW:
|
|
- or go back to the newest paste.
1 | - | |
1 | + | #include "CustomFiberThread.h" |
2 | #include "Scripting.h" | |
3 | #include "../ScriptHook/Log.h" | |
4 | ||
5 | #include <windows.h> | |
6 | #include <stdio.h> | |
7 | ||
8 | using namespace Scripting; | |
9 | ||
10 | // ASSEMBLY FUNCTIONS, MAYBE CAN NOT BE A CLASS FUNCTION | |
11 | ||
12 | __declspec( noinline ) u32 GTA4_GetHandleFromPed( CPool< void* >* pPool, void *Ped ) | |
13 | { | |
14 | _asm mov ecx, pPool; | |
15 | _asm mov eax, Ped; | |
16 | _asm sub eax, [ecx]; | |
17 | _asm cdq; | |
18 | _asm idiv dword ptr [ecx+12]; | |
19 | _asm mov edx, eax; | |
20 | _asm mov eax, [ecx+4]; | |
21 | _asm movzx eax, byte ptr [eax+edx]; | |
22 | _asm shl edx, 8; | |
23 | _asm add eax, edx; | |
24 | } | |
25 | ||
26 | // ASSEMBLY FUNCTIONS, MAYBE CAN NOT BE A CLASS FUNCTION | |
27 | ||
28 | RiotThread::RiotThread() | |
29 | { | |
30 | SetName( "RiotIV_050" ); | |
31 | } | |
32 | ||
33 | CPool< void* >* RiotThread::GetPedPoolNative() | |
34 | { | |
35 | // HACKHACK: Static address for GTAIV 1.0.6.0; DEPRECIATED!!! | |
36 | // return reinterpret_cast< CPool< void* >* >( *reinterpret_cast< DWORD* >( Game::GetBase() + 0x18A72BC ) ); | |
37 | ||
38 | return reinterpret_cast< CPool< void* >* >( *reinterpret_cast< DWORD* >( m_ulPedPoolBase ) ); | |
39 | } | |
40 | ||
41 | u32 RiotThread::GetPedCount() | |
42 | { | |
43 | if( GetPedPoolNative() == NULL ) return 0; | |
44 | ||
45 | return GetPedPoolNative()->Count(); | |
46 | } | |
47 | ||
48 | b8 RiotThread::GetPedByIndex( int idx, Ped *Out ) | |
49 | { | |
50 | if( !Out ) | |
51 | return false; | |
52 | ||
53 | Out->Set( 0 ); | |
54 | ||
55 | if( GetPedCount() == 0 ) | |
56 | return false; | |
57 | ||
58 | void *CurrentPedIdx = GetPedPoolNative()->at( idx ); | |
59 | ||
60 | if( CurrentPedIdx == NULL ) | |
61 | return false; | |
62 | ||
63 | Out->Set( GTA4_GetHandleFromPed( GetPedPoolNative(), CurrentPedIdx ) ); | |
64 | ||
65 | return ( Out->IsValid() && DoesCharExist( *Out ) ); | |
66 | } | |
67 | ||
68 | Scripting::Vector3 RiotThread::GetPedVector( Scripting::Ped *In ) | |
69 | { | |
70 | Vector3 Ret(0,0,0); | |
71 | Scripting::GetCharCoordinates( *In, &Ret.X, &Ret.Y, &Ret.Z ); | |
72 | return Ret; | |
73 | } | |
74 | ||
75 | Player RiotThread::GetPlayer() | |
76 | { | |
77 | Player playerIndex = ConvertIntToPlayerIndex(GetPlayerId()); | |
78 | return playerIndex; | |
79 | } | |
80 | ||
81 | Scripting::Ped RiotThread::GetPlayerPed() | |
82 | { | |
83 | Ped ped; | |
84 | GetPlayerChar( GetPlayer(), &ped ); | |
85 | return ped; | |
86 | } | |
87 | ||
88 | Scripting::eWeapon RiotThread::GetRandomWeapon() | |
89 | { | |
90 | srand( GetTickCount() ); | |
91 | ||
92 | return static_cast< eWeapon >( m_UsableWeaponry[ rand() % m_UsableWeaponry.size() ] ); | |
93 | } | |
94 | ||
95 | b8 RiotThread::IsPedPolice( Scripting::Ped ped ) | |
96 | { | |
97 | eModel CurrentModel; | |
98 | ||
99 | Scripting::GetCharModel( ped, &CurrentModel ); | |
100 | ||
101 | return ( | |
102 | ( CurrentModel == MODEL_M_Y_COP ) || | |
103 | ( CurrentModel == MODEL_M_Y_COP_TRAFFIC ) || | |
104 | ( CurrentModel == MODEL_M_M_FATCOP_01 ) || | |
105 | ( CurrentModel == MODEL_CS_MITCHCOP ) || | |
106 | ( CurrentModel == MODEL_M_Y_SWAT ) || | |
107 | ( CurrentModel == MODEL_M_M_FBI ) || | |
108 | ( CurrentModel == MODEL_M_Y_STROOPER ) ); | |
109 | } | |
110 | ||
111 | b8 RiotThread::ShouldRiot( Scripting::Ped ped ) | |
112 | { | |
113 | if( m_DontRiotHashes.empty() ) | |
114 | { | |
115 | return true; | |
116 | } | |
117 | ||
118 | for( size_t i = 0; i < m_DontRiotHashes.size(); i++ ) | |
119 | { | |
120 | if( IsCharModel( ped, static_cast< Scripting::eModel >( m_DontRiotHashes[ i ] ) ) ) | |
121 | { | |
122 | return false; | |
123 | } | |
124 | } | |
125 | ||
126 | return true; | |
127 | } | |
128 | ||
129 | b8 RiotThread::IsPedAllowedToRiot( Scripting::Ped ped ) | |
130 | { | |
131 | if( m_RiotHashes.empty() ) | |
132 | return true; | |
133 | ||
134 | for( size_t i = 0; i < m_RiotHashes.size(); i++ ) | |
135 | { | |
136 | if( IsCharModel( ped, static_cast< Scripting::eModel >( m_RiotHashes[ i ] ) ) ) | |
137 | { | |
138 | return true; | |
139 | } | |
140 | } | |
141 | ||
142 | return false; | |
143 | } | |
144 | ||
145 | b8 RiotThread::CausePedToRiot( Scripting::Ped LocalPed, Scripting::Ped RiotPed ) | |
146 | { | |
147 | // Check if ped exists | |
148 | if( DoesCharExist( RiotPed ) == false ) | |
149 | { | |
150 | return false; | |
151 | } | |
152 | ||
153 | // Check the model for status | |
154 | if( ShouldRiot( RiotPed ) == false || IsPedAllowedToRiot( RiotPed ) == false ) | |
155 | { | |
156 | if( IsPedAMissionPed( RiotPed ) ) | |
157 | { | |
158 | MarkCharAsNoLongerNeeded( &RiotPed ); | |
159 | } | |
160 | ||
161 | return false; | |
162 | } | |
163 | ||
164 | // If not "visible", delete them, not needed | |
165 | if( IsCharVisible( RiotPed ) == false ) | |
166 | { | |
167 | if( IsPedAMissionPed( RiotPed ) ) | |
168 | { | |
169 | MarkCharAsNoLongerNeeded( &RiotPed ); | |
170 | ||
171 | DeleteChar( &RiotPed ); | |
172 | } | |
173 | ||
174 | return false; | |
175 | } | |
176 | ||
177 | // If dead, fatally injured | |
178 | // if mission ped, unmark, stop | |
179 | if( IsCharDead( RiotPed ) || IsCharFatallyInjured( RiotPed ) ) | |
180 | { | |
181 | if( IsPedAMissionPed( RiotPed ) ) | |
182 | { | |
183 | MarkCharAsNoLongerNeeded( &RiotPed ); | |
184 | } | |
185 | ||
186 | return false; | |
187 | } | |
188 | ||
189 | // If cops rioting is disabled and ped is police, stop | |
190 | ||
191 | if( m_bCopsGoCrazy == false && IsPedPolice( RiotPed ) ) | |
192 | { | |
193 | if( IsPedAMissionPed( RiotPed ) ) | |
194 | { | |
195 | MarkCharAsNoLongerNeeded( &RiotPed ); | |
196 | } | |
197 | ||
198 | return false; | |
199 | } | |
200 | ||
201 | // If usable weaponry is available | |
202 | if( m_UsableWeaponry.size() > 0 ) | |
203 | { | |
204 | //if NOT police (already have weapons) | |
205 | if( IsPedPolice( RiotPed ) == false ) | |
206 | { | |
207 | //if have a gun already, and not police, stop | |
208 | if( Scripting::IsCharArmed( RiotPed, WEAPON_SLOT_MELEE ) | |
209 | || Scripting::IsCharArmed( RiotPed, WEAPON_SLOT_HANDGUN ) | |
210 | || Scripting::IsCharArmed( RiotPed, WEAPON_SLOT_HEAVY ) | |
211 | || Scripting::IsCharArmed( RiotPed, WEAPON_SLOT_RIFLE ) | |
212 | || Scripting::IsCharArmed( RiotPed, WEAPON_SLOT_SHOTGUN ) | |
213 | || Scripting::IsCharArmed( RiotPed, WEAPON_SLOT_SMG ) | |
214 | || Scripting::IsCharArmed( RiotPed, WEAPON_SLOT_SNIPER ) | |
215 | || Scripting::IsCharArmed( RiotPed, WEAPON_SLOT_THROWN ) ) | |
216 | { | |
217 | return false; | |
218 | } | |
219 | } | |
220 | } | |
221 | ||
222 | // Range checking to avoid crashes | |
223 | Scripting::Vector3 LocalVec = GetPedVector( &LocalPed ); | |
224 | Scripting::Vector3 PedVec = GetPedVector( &RiotPed ); | |
225 | ||
226 | if( PedVec.Distance( &LocalVec ) > m_fMaximumRange ) | |
227 | { | |
228 | // HACKHACK: If outside of maximum range mark as no longer needed... | |
229 | ||
230 | if( IsPedAMissionPed( RiotPed ) ) | |
231 | { | |
232 | MarkCharAsNoLongerNeeded( &RiotPed ); | |
233 | } | |
234 | ||
235 | return false; | |
236 | } | |
237 | ||
238 | if( IsPedAMissionPed( RiotPed ) == false ) | |
239 | { | |
240 | // Setup violent tendencies | |
241 | ||
242 | SetCharAsMissionChar( RiotPed ); | |
243 | ||
244 | SetCharAsEnemy( RiotPed, m_bTargetPlayer ); | |
245 | ||
246 | SetPedDiesWhenInjured( RiotPed, true ); | |
247 | ||
248 | AllowTargetWhenInjured( RiotPed, true ); | |
249 | ||
250 | SetCharWillMoveWhenInjured( RiotPed, true ); | |
251 | ||
252 | SetCharWillDoDrivebys( RiotPed, true ); | |
253 | ||
254 | SetCharWillUseCarsInCombat( RiotPed, m_bPedsUseCars ); | |
255 | ||
256 | SetPedWontAttackPlayerWithoutWantedLevel( RiotPed, 0 ); | |
257 | ||
258 | SetSenseRange( RiotPed, m_fMaximumRange ); | |
259 | ||
260 | SetCharAccuracy( RiotPed, 100 ); | |
261 | ||
262 | if( IsPedPolice( RiotPed ) == false ) | |
263 | { | |
264 | SetCharWantedByPolice( RiotPed, m_bPedsWanted ); | |
265 | ||
266 | SetCharRelationshipGroup( RiotPed, 8 ); | |
267 | ||
268 | // If weaponry available, give random weapon | |
269 | ||
270 | if( m_UsableWeaponry.size() > 0 ) | |
271 | { | |
272 | eWeapon RandomWeapon = GetRandomWeapon(); | |
273 | ||
274 | GiveWeaponToChar( RiotPed, RandomWeapon, ( RandomWeapon > 3 ) ? 9999 : 0, 0 ); | |
275 | ||
276 | SetCurrentCharWeapon( RiotPed, RandomWeapon, true ); | |
277 | ||
278 | BlockPedWeaponSwitching( RiotPed, true ); | |
279 | } | |
280 | else | |
281 | { | |
282 | // Melee if no weapons are set | |
283 | ||
284 | RemoveAllCharWeapons( RiotPed ); | |
285 | } | |
286 | } | |
287 | ||
288 | // Set attacking task | |
289 | ||
290 | TaskCombatHatedTargetsAroundChar( RiotPed, m_fMaximumRange ); | |
291 | ||
292 | SetCharKeepTask( RiotPed, true ); | |
293 | } | |
294 | ||
295 | return true; | |
296 | } | |
297 | ||
298 | void RiotThread::SpawnNewRioter( Ped LocalPed, Vector3 SpawnVector ) | |
299 | { | |
300 | Scripting::PrintStringWithLiteralStringNow( "STRING", "Spawning new riot ped", 3000, true ); | |
301 | ||
302 | srand( GetTickCount() ); | |
303 | ||
304 | eModel ModelSpawn = static_cast< eModel >( m_SpawnHashes[ rand() % m_SpawnHashes.size() ] ); | |
305 | ||
306 | RequestModel( ModelSpawn ); | |
307 | ||
308 | while( HasModelLoaded( ModelSpawn ) == false ) | |
309 | { | |
310 | Wait(10); | |
311 | } | |
312 | ||
313 | Ped OutPed; | |
314 | ||
315 | CreateChar( 2, ModelSpawn, SpawnVector.X, SpawnVector.Y, SpawnVector.Z, &OutPed, true ); | |
316 | ||
317 | if( OutPed.IsValid() ) | |
318 | { | |
319 | while( DoesCharExist( OutPed ) == false ) | |
320 | { | |
321 | Wait(10); | |
322 | } | |
323 | ||
324 | while( IsCharVisible( OutPed ) == false ) | |
325 | { | |
326 | Wait(10); | |
327 | } | |
328 | ||
329 | SetCharHealth( OutPed, 200 ); | |
330 | ||
331 | MarkCharAsNoLongerNeeded( &OutPed ); | |
332 | } | |
333 | } | |
334 | ||
335 | void RiotThread::SetupRelationships() | |
336 | { | |
337 | SetRelationship( 5, 8, 8 ); // Rioters hate themselves | |
338 | SetRelationship( 5, 8, 3 ); // Rioters hate police | |
339 | ||
340 | SetPlayerCanBeHassledByGangs( GetPlayer(), m_bTargetPlayer ); | |
341 | ||
342 | if( m_bTargetPlayer ) | |
343 | { | |
344 | SetRelationship( 5, 8, 0 ); // Rioters hate player (you) | |
345 | SetRelationship( 5, 0, 8 ); // Player hate rioters | |
346 | ||
347 | if( m_bCopsGoCrazy ) | |
348 | { | |
349 | SetRelationship( 5, 0, 3 ); //Cops hate player (you) | |
350 | } | |
351 | } | |
352 | else | |
353 | { | |
354 | SetRelationship( 1, 8, 0 ); // Rioters ignore player (you) | |
355 | SetRelationship( 1, 0, 8 ); // Player ignore rioters | |
356 | } | |
357 | ||
358 | if( m_bCopsGoCrazy ) | |
359 | { | |
360 | SetRelationship( 5, 3, 8 ); // Cops hate rioters | |
361 | } | |
362 | } | |
363 | ||
364 | std::vector< int > RiotThread::StringToIntList( const char *str ) | |
365 | { | |
366 | std::vector< int > ReturnVector; | |
367 | ||
368 | if( str == NULL ) | |
369 | { | |
370 | ReturnVector.clear(); | |
371 | ||
372 | return ReturnVector; | |
373 | } | |
374 | ||
375 | // | |
376 | ||
377 | char *pch = strtok( const_cast< char* >( str ), "," ); | |
378 | ||
379 | if( pch == NULL ) | |
380 | { | |
381 | ReturnVector.push_back( atoi( str ) ); | |
382 | } | |
383 | else | |
384 | { | |
385 | while( pch ) | |
386 | { | |
387 | ReturnVector.push_back( atoi( pch ) ); | |
388 | ||
389 | pch = strtok( 0, "," ); | |
390 | } | |
391 | } | |
392 | ||
393 | return ReturnVector; | |
394 | } | |
395 | ||
396 | void RiotThread::SetupSettingsFile() | |
397 | { | |
398 | Log::Debug( "Loading Settings..." ); | |
399 | ||
400 | m_pConfigService = ScriptHookManager::RequestService< IConfigService >( "Config" ); | |
401 | ||
402 | if( m_pConfigService ) | |
403 | { | |
404 | IConfig* Configuration = m_pConfigService->Create( IConfigService::ConfigTypeXml ); | |
405 | ||
406 | if( Configuration == NULL ) | |
407 | return; | |
408 | ||
409 | Configuration->Set( "RiotIV", "Enabled", "1" ); | |
410 | Configuration->Set( "RiotIV", "TargetPlayer", "0" ); | |
411 | Configuration->Set( "RiotIV", "CrazyCops", "1" ); | |
412 | Configuration->Set( "RiotIV", "PedsUseCars", "1" ); | |
413 | Configuration->Set( "RiotIV", "PedsWanted", "1" ); | |
414 | Configuration->Set( "RiotIV", "MadDrivers", "1" ); | |
415 | Configuration->Set( "RiotIV", "EmergencyServicesDisabled", "1" ); | |
416 | Configuration->Set( "RiotIV", "PedMultiplierEnforce", "NONE" ); | |
417 | Configuration->Set( "RiotIV", "UsableWeaponry", "4,5,7,9,10,11,12,13,14,15,16,17,18" ); | |
418 | Configuration->Set( "RiotIV", "DontRiotHashes", "" ); | |
419 | Configuration->Set( "RiotIV", "SpawnHashes", "1794146792" ); | |
420 | Configuration->Set( "RiotIV", "RiotHashes", "ANY" ); | |
421 | Configuration->Set( "RiotIV", "MaximumRange", "100.0" ); | |
422 | ||
423 | char *pszModulePath = GetModulePath(); | |
424 | ||
425 | if( pszModulePath == 0 || strlen( pszModulePath ) == 0 ) | |
426 | return; | |
427 | ||
428 | Log::Debug( "Module Path [%s]", pszModulePath ); | |
429 | ||
430 | char pszConfigPath[ MAX_PATH ] = { 0 }; | |
431 | ||
432 | strcat_s( pszConfigPath, MAX_PATH, GetModulePath() ); | |
433 | strcat_s( pszConfigPath, MAX_PATH, "Riot.xml" ); | |
434 | ||
435 | Log::Debug( "Loading configuration from [%s]", pszConfigPath ); | |
436 | ||
437 | WIN32_FIND_DATAA wfd; | |
438 | ||
439 | if ( FindFirstFileA( pszConfigPath, &wfd ) != INVALID_HANDLE_VALUE ) | |
440 | { | |
441 | Configuration->Load( pszConfigPath ); | |
442 | ||
443 | // HACKHACK: Save after we load to ensure any new values are inserted into the file for future loading | |
444 | Configuration->Save( pszConfigPath ); | |
445 | } | |
446 | else | |
447 | { | |
448 | Configuration->Save( pszConfigPath ); | |
449 | } | |
450 | ||
451 | m_bEnabled = ( Configuration->GetInteger( "RiotIV", "Enabled", 1 ) == 1 ); | |
452 | m_bTargetPlayer = ( Configuration->GetInteger( "RiotIV", "TargetPlayer", 0 ) == 1 ); | |
453 | m_bCopsGoCrazy = ( Configuration->GetInteger( "RiotIV", "CrazyCops", 0 ) == 1 ); | |
454 | m_bPedsUseCars = ( Configuration->GetInteger( "RiotIV", "PedsUseCars", 1 ) == 1 ); | |
455 | m_bPedsWanted = ( Configuration->GetInteger( "RiotIV", "PedsWanted", 0 ) == 1 ); | |
456 | m_bMadDrivers = ( Configuration->GetInteger( "RiotIV", "MadDrivers", 0 ) == 1 ); | |
457 | m_bEmergencyServicesDisabled = ( Configuration->GetInteger( "RiotIV", "EmergencyServicesDisabled", 0 ) == 1 ); | |
458 | m_fMaximumRange = Configuration->GetFloat( "RiotIV", "MaximumRange", 100.f ); | |
459 | ||
460 | CONST CHAR* PedMultiEnforce = Configuration->GetString( "RiotIV", "PedMultiplierEnforce" ); | |
461 | CONST CHAR* UsableWeapons = Configuration->GetString( "RiotIV", "UsableWeaponry" ); | |
462 | CONST CHAR* DontRiotHashes = Configuration->GetString( "RiotIV", "DontRiotHashes" ); | |
463 | CONST CHAR* RiotHashes = Configuration->GetString( "RiotIV", "RiotHashes" ); | |
464 | CONST CHAR* SpawnHashes = Configuration->GetString( "RiotIV", "SpawnHashes" ); | |
465 | ||
466 | m_UsableWeaponry = StringToIntList( UsableWeapons ); | |
467 | m_DontRiotHashes = StringToIntList( DontRiotHashes ); | |
468 | m_SpawnHashes = StringToIntList( SpawnHashes ); | |
469 | ||
470 | if( _stricmp( PedMultiEnforce, "NONE" ) == 0 ) | |
471 | { | |
472 | m_bForcePedMultiplier = false; | |
473 | } | |
474 | else | |
475 | { | |
476 | m_bForcePedMultiplier = true; | |
477 | ||
478 | m_fPedMultiplier = static_cast< f32 >( atof( PedMultiEnforce ) ); | |
479 | } | |
480 | ||
481 | if( _stricmp( RiotHashes, "ANY" ) == 0 ) | |
482 | { | |
483 | m_RiotHashes.clear(); | |
484 | } | |
485 | else | |
486 | { | |
487 | m_RiotHashes = StringToIntList( RiotHashes ); | |
488 | } | |
489 | ||
490 | Configuration->Release(); | |
491 | } | |
492 | else | |
493 | { | |
494 | Log::Debug( "Unable to load configuration service.." ); | |
495 | } | |
496 | } | |
497 | ||
498 | char* RiotThread::GetModulePath() | |
499 | { | |
500 | static char pszPath[ MAX_PATH ] = { 0 }; | |
501 | ||
502 | if( strlen( pszPath ) > 0 ) | |
503 | return pszPath; | |
504 | ||
505 | GetModuleFileNameA( m_hModule, pszPath, sizeof( pszPath ) ); | |
506 | ||
507 | u32 i = strlen( pszPath ); | |
508 | ||
509 | while( i > 0 && pszPath[i] != '\\' ) | |
510 | { | |
511 | i--; | |
512 | } | |
513 | ||
514 | pszPath[i] = 0; | |
515 | ||
516 | strcat_s( pszPath, MAX_PATH, "\\" ); | |
517 | ||
518 | return pszPath; | |
519 | } | |
520 | ||
521 | void RiotThread::UpdateCode() | |
522 | { | |
523 | HMODULE hMainModule = GetModuleHandleW( NULL ); | |
524 | ||
525 | Log::Debug( "Finding signiture..[0x%X][0x%X]", hMainModule, Game::GetBase() ); | |
526 | ||
527 | m_ulPedPoolBase = Code::FindAddress::DetectPattern( | |
528 | reinterpret_cast< unsigned long >( hMainModule ), 0xFFFFFF, | |
529 | ( BYTE* )"\x55\x8B\xEC\x83\xE4\xF0\x8B\x15\x00\x00\x00\x00\x81\xEC\xEC\x00\x00\x00", | |
530 | ( CHAR* )"xxxxxxxx????xxxxxx" ); | |
531 | ||
532 | if( m_ulPedPoolBase == NULL ) | |
533 | { | |
534 | Log::Fatal( "PedPoolBase not found...critical error" ); | |
535 | ||
536 | ExitProcess(0); | |
537 | } | |
538 | else | |
539 | { | |
540 | Log::Debug( "PedPoolBase 001 [0x%X]", m_ulPedPoolBase ); | |
541 | ||
542 | m_ulPedPoolBase += 8; | |
543 | ||
544 | Log::Debug( "PedPoolBase 002 [0x%X]", m_ulPedPoolBase ); | |
545 | ||
546 | m_ulPedPoolBase = *reinterpret_cast< unsigned long* >( m_ulPedPoolBase ); | |
547 | ||
548 | Log::Debug( "PedPoolBase FIN [0x%X]", m_ulPedPoolBase ); | |
549 | ||
550 | Log::Debug( "Address - Base = [0x%X]", m_ulPedPoolBase - reinterpret_cast< unsigned long >( hMainModule ) ); | |
551 | } | |
552 | } | |
553 | ||
554 | void RiotThread::RunScript() | |
555 | { | |
556 | SetupSettingsFile(); | |
557 | ||
558 | CreateKeyboard(); | |
559 | ||
560 | CreateMenu(); | |
561 | ||
562 | while( IsThreadAlive() ) | |
563 | { | |
564 | if( NetworkIsSessionStarted() == false ) | |
565 | { | |
566 | Ped LocalPed = GetPlayerPed(); | |
567 | ||
568 | if( LocalPed.IsValid() == false ) | |
569 | continue; | |
570 | ||
571 | Vector3 LocalVector = GetPedVector( &LocalPed ); | |
572 | ||
573 | if( m_bSpawnRandomPedNextFrame && m_SpawnHashes.size() ) | |
574 | { | |
575 | SpawnNewRioter( LocalPed, Vector3( LocalVector.X + 2.f, LocalVector.Y, LocalVector.Z ) ); | |
576 | ||
577 | m_bSpawnRandomPedNextFrame = false; | |
578 | } | |
579 | ||
580 | if( m_bForcePedMultiplier ) | |
581 | { | |
582 | SetPedDensityMultiplier( m_fPedMultiplier ); | |
583 | } | |
584 | ||
585 | SwitchMadDrivers( m_bMadDrivers ); | |
586 | ||
587 | AllowEmergencyServices( !m_bEmergencyServicesDisabled ); | |
588 | ||
589 | SetPoliceIgnorePlayer( GetPlayer(), m_bEmergencyServicesDisabled ); | |
590 | ||
591 | if( m_bEmergencyServicesDisabled ) | |
592 | { | |
593 | SetCharWantedByPolice( LocalPed, false ); | |
594 | ||
595 | ClearWantedLevel( GetPlayer() ); | |
596 | ||
597 | ClearAreaOfCops( LocalVector.X, LocalVector.Y, LocalVector.Z, m_fMaximumRange ); | |
598 | } | |
599 | ||
600 | if( m_bEnabled ) | |
601 | { | |
602 | AllowGangRelationshipsToBeChangedByNextCommand( true ); | |
603 | ||
604 | SetupRelationships(); | |
605 | ||
606 | for( u32 i = 0; i < GetPedCount(); i++ ) | |
607 | { | |
608 | Ped Index; | |
609 | ||
610 | Index.Set( 0 ); | |
611 | ||
612 | if( GetPedByIndex( i, &Index ) ) | |
613 | { | |
614 | if( Index.IsNull() ) | |
615 | continue; | |
616 | ||
617 | if( Index.Get() == LocalPed.Get() ) | |
618 | continue; | |
619 | ||
620 | if( CausePedToRiot( LocalPed, Index ) == false ) | |
621 | continue; | |
622 | } | |
623 | } | |
624 | } | |
625 | } | |
626 | ||
627 | Wait( 10 ); | |
628 | } | |
629 | } | |
630 | ||
631 | void RiotThread::OnStart() | |
632 | { | |
633 | m_pMenu = NULL; | |
634 | } | |
635 | ||
636 | void RiotThread::OnKill() | |
637 | { | |
638 | IKeyboardHookService *kbhService = ScriptHookManager::RequestService<IKeyboardHookService>( "KeyboardHook" ); | |
639 | ||
640 | kbhService->RemoveHandler( this ); | |
641 | ||
642 | if( m_pMenu ) | |
643 | { | |
644 | m_pMenu->Release(); | |
645 | m_pMenu = NULL; | |
646 | } | |
647 | ||
648 | ScriptThread::OnKill(); | |
649 | } | |
650 | ||
651 | void RiotThread::CreateKeyboard() | |
652 | { | |
653 | IKeyboardHookService *kbhService = ScriptHookManager::RequestService<IKeyboardHookService>( "KeyboardHook" ); | |
654 | ||
655 | kbhService->AddHandler( this ); | |
656 | } | |
657 | ||
658 | void RiotThread::CreateMenu() | |
659 | { | |
660 | IMenuService *menuService = ScriptHookManager::RequestService< IMenuService >( "Menu" ); | |
661 | ||
662 | m_pMenu = menuService->CreateMenu(); | |
663 | ||
664 | m_pMenu->SetTitle( "Riot mode" ); | |
665 | ||
666 | AddMenuItemCustom( 0, m_bEnabled ? "Disable Riot Mode" : "Enable Riot Mode" ); | |
667 | AddMenuItemCustom( 1, m_bTargetPlayer ? "Disable peds targetting player" : "Enable peds targetting player" ); | |
668 | AddMenuItemCustom( 2, m_bCopsGoCrazy ? "Disable cops rioting" : "Enable cops rioting" ); | |
669 | AddMenuItemCustom( 3, m_bPedsUseCars ? "Disable peds use cars in combat" : "Enable peds use cars in combat" ); | |
670 | AddMenuItemCustom( 4, m_bPedsWanted ? "Disable peds wanted" : "Enable peds wanted" ); | |
671 | AddMenuItemCustom( 5, m_bMadDrivers ? "Disable mad drivers" : "Enable mad drives" ); | |
672 | AddMenuItemCustom( 6, m_bEmergencyServicesDisabled ? "Enable emergancy services" : "Disable emergancy services" ); | |
673 | ||
674 | m_pMenu->SetEventHandler( this ); | |
675 | } | |
676 | ||
677 | void RiotThread::AddMenuItemCustom( int idx, char *pszFormat, ... ) | |
678 | { | |
679 | char FormattedBuffer[ 1024 ] = { 0 }; | |
680 | ||
681 | va_list va_alist; | |
682 | ||
683 | va_start( va_alist, pszFormat ); | |
684 | ||
685 | _vsnprintf( | |
686 | FormattedBuffer + strlen( FormattedBuffer ), | |
687 | sizeof( FormattedBuffer ) - strlen( FormattedBuffer ), | |
688 | pszFormat, va_alist ); | |
689 | ||
690 | va_end( va_alist ); | |
691 | ||
692 | m_pMenu->AddItem( idx, FormattedBuffer ); | |
693 | } | |
694 | ||
695 | void RiotThread::SetMenuItemCustom( int idx, char *pszFormat, ... ) | |
696 | { | |
697 | char FormattedBuffer[ 1024 ] = { 0 }; | |
698 | ||
699 | va_list va_alist; | |
700 | ||
701 | va_start( va_alist, pszFormat ); | |
702 | ||
703 | _vsnprintf( | |
704 | FormattedBuffer + strlen( FormattedBuffer ), | |
705 | sizeof( FormattedBuffer ) - strlen( FormattedBuffer ), | |
706 | pszFormat, va_alist ); | |
707 | ||
708 | va_end( va_alist ); | |
709 | ||
710 | m_pMenu->SetItem( idx, FormattedBuffer ); | |
711 | } | |
712 | ||
713 | void RiotThread::OnMenuSelectionChanged( IMenu *menu, u32 id ) | |
714 | { | |
715 | // None? | |
716 | } | |
717 | ||
718 | void RiotThread::OnMenuSelected( IMenu *menu, u32 id ) | |
719 | { | |
720 | switch( id ) | |
721 | { | |
722 | case 0: | |
723 | { | |
724 | m_bEnabled = !m_bEnabled; | |
725 | ||
726 | SetMenuItemCustom( 0, m_bEnabled ? "Disable Riot Mode" : "Enable Riot Mode" ); | |
727 | ||
728 | break; | |
729 | } | |
730 | case 1: | |
731 | { | |
732 | m_bTargetPlayer = !m_bTargetPlayer; | |
733 | ||
734 | SetMenuItemCustom( 1, m_bTargetPlayer ? "Disable peds targetting player" : "Enable peds targetting player" ); | |
735 | ||
736 | break; | |
737 | } | |
738 | case 2: | |
739 | { | |
740 | m_bCopsGoCrazy = !m_bCopsGoCrazy; | |
741 | ||
742 | SetMenuItemCustom( 2, m_bCopsGoCrazy ? "Disable cops rioting" : "Enable cops rioting" ); | |
743 | ||
744 | break; | |
745 | } | |
746 | case 3: | |
747 | { | |
748 | m_bPedsUseCars = !m_bPedsUseCars; | |
749 | ||
750 | SetMenuItemCustom( 3, m_bPedsUseCars ? "Disable peds use cars in combat" : "Enable peds use cars in combat" ); | |
751 | ||
752 | break; | |
753 | } | |
754 | case 4: | |
755 | { | |
756 | m_bPedsWanted = !m_bPedsWanted; | |
757 | ||
758 | SetMenuItemCustom( 4, m_bPedsWanted ? "Disable peds wanted" : "Enable peds wanted" ); | |
759 | ||
760 | break; | |
761 | } | |
762 | case 5: | |
763 | { | |
764 | m_bMadDrivers = !m_bMadDrivers; | |
765 | ||
766 | SetMenuItemCustom( 5, m_bMadDrivers ? "Disable mad drivers" : "Enable mad drives" ); | |
767 | ||
768 | break; | |
769 | } | |
770 | case 6: | |
771 | { | |
772 | m_bEmergencyServicesDisabled = !m_bEmergencyServicesDisabled; | |
773 | ||
774 | SetMenuItemCustom( 6, m_bEmergencyServicesDisabled ? "Enable emergancy services" : "Disable emergancy services" ); | |
775 | ||
776 | break; | |
777 | } | |
778 | } | |
779 | } | |
780 | ||
781 | void RiotThread::OnKeyboardHookEvent( const IKeyboardHookHandler::KeyEventArgs &args ) | |
782 | { | |
783 | if( args.VirtualKey == VK_INSERT && !args.WasKeyDownBefore ) | |
784 | { | |
785 | if( m_pMenu ) | |
786 | { | |
787 | m_pMenu->Show(); | |
788 | } | |
789 | } | |
790 | ||
791 | if( args.VirtualKey == VK_F3 && !args.WasKeyDownBefore ) | |
792 | { | |
793 | m_bSpawnRandomPedNextFrame = true; | |
794 | } | |
795 | } |