fork download
  1. /*****************************************************************************
  2. *
  3. * PROJECT: Multi Theft Auto v1.0
  4. * LICENSE: See LICENSE in the top level directory
  5. * FILE: multiplayer_sa/CPopulationSA.cpp
  6. * PURPOSE: Ped world population class
  7. * DEVELOPERS: Ed Lyons <eai@opencoding.net>
  8. * Christian Myhre Lundheim <>
  9. * Cecill Etheredge <ijsf@gmx.net>
  10. *
  11. * Multi Theft Auto is available from http://w...content-available-to-author-only...o.com/
  12. *
  13. *****************************************************************************/
  14.  
  15. #include "StdInc.h"
  16.  
  17. using std::list;
  18.  
  19. CPedSAInterface * pPedStorage;
  20. CVehicleSAInterface * pVehicleStorage;
  21. CObjectSAInterface * pObjectStorage;
  22.  
  23. CPopulationSA * pSingleton;
  24. DWORD pedVtable;
  25.  
  26. VOID HOOK_EndOf_CPopulation__Add();
  27. VOID HOOK_CPopulation__RemovePed();
  28.  
  29. VOID HOOK_CVehicle__Add();
  30. VOID HOOK_CVehicle__Remove();
  31.  
  32. VOID HOOK_CObject__Add();
  33. VOID HOOK_CObject__Remove();
  34.  
  35. CivilianAddHandler * m_pCivilianAddHandler;
  36. CivilianRemoveHandler * m_pCivilianRemoveHandler;
  37. VehicleAddHandler * m_pVehicleAddHandler;
  38. VehicleRemoveHandler * m_pVehicleRemoveHandler;
  39. ObjectAddHandler * m_pObjectAddHandler;
  40. ObjectRemoveHandler * m_pObjectRemoveHandler;
  41.  
  42. CPopulationSA::CPopulationSA()
  43. {
  44. dwPedCount = 0;
  45. dwVehicleCount = 0;
  46. dwObjectCount = 0;
  47.  
  48. HookInstall(HOOKPOS_EndOf_CPopulation__Add, (DWORD)HOOK_EndOf_CPopulation__Add, 6);
  49. HookInstall(HOOKPOS_CPopulation__RemovePed, (DWORD)HOOK_CPopulation__RemovePed, 6);
  50.  
  51. #if HOOKPOS_CVehicle__Add != 0x00000000
  52. HookInstall(HOOKPOS_CVehicle__Add, (DWORD)HOOK_CVehicle__Add, 6);
  53. #endif
  54. #if HOOKPOS_CVehicle__Remove != 0x00000000
  55. HookInstall(HOOKPOS_CVehicle__Remove, (DWORD)HOOK_CVehicle__Remove, 6);
  56. #endif
  57. #if HOOKPOS_CObject__Add != 0x00000000
  58. HookInstall(HOOKPOS_CObject__Add, (DWORD)HOOK_CObject__Add, 6);
  59. #endif
  60. #if HOOKPOS_CObject__Remove != 0x00000000
  61. HookInstall(HOOKPOS_CObject__Remove, (DWORD)HOOK_CObject__Remove, 6);
  62. #endif
  63.  
  64. pSingleton = this;
  65. m_pCivilianRemoveHandler = NULL;
  66. m_pCivilianAddHandler = NULL;
  67. m_pObjectAddHandler = NULL;
  68. m_pObjectRemoveHandler = NULL;
  69. m_pVehicleAddHandler = NULL;
  70. m_pVehicleRemoveHandler = NULL;
  71. }
  72.  
  73. VOID CPopulationSA::AddPed ( CCivilianPed * ped )
  74. {
  75. CCivilianPedSA* pPedSA = dynamic_cast < CCivilianPedSA* > ( ped );
  76. if ( !pPedSA ) return;
  77.  
  78. CEntitySAInterface* pPedSAInterface = pPedSA->GetInterface ();
  79.  
  80. list < CCivilianPedSA* > ::iterator iter;
  81. for ( iter = peds.begin (); iter != peds.end (); ++iter )
  82. {
  83. if ( (*iter)->GetInterface() == pPedSAInterface )
  84. {
  85. return;
  86. }
  87. }
  88.  
  89. peds.push_back ( pPedSA );
  90. dwPedCount ++;
  91. }
  92.  
  93. VOID CPopulationSA::AddVehicle(CVehicle * vehicle)
  94. {
  95. CVehicleSA* pVehicleSA = dynamic_cast < CVehicleSA* > (vehicle);
  96. if (!pVehicleSA) return;
  97.  
  98. CEntitySAInterface* pVehicleSAInterface = pVehicleSA->GetInterface();
  99.  
  100. list < CVehicleSA* > ::iterator iter;
  101. for (iter = vehicles.begin(); iter != vehicles.end(); ++iter)
  102. {
  103. if ((*iter)->GetInterface() == pVehicleSAInterface)
  104. {
  105. return;
  106. }
  107. }
  108.  
  109. vehicles.push_back(pVehicleSA);
  110. dwVehicleCount++;
  111. }
  112.  
  113. VOID CPopulationSA::AddObject(CObject * object)
  114. {
  115. CObjectSA* pObjectSA = dynamic_cast < CObjectSA* > (object);
  116. if (!pObjectSA) return;
  117.  
  118. CEntitySAInterface* pObjectSAInterface = pObjectSA->GetInterface();
  119.  
  120. list < CObjectSA* > ::iterator iter;
  121. for (iter = objects.begin(); iter != objects.end(); ++iter)
  122. {
  123. if ((*iter)->GetInterface() == pObjectSAInterface)
  124. {
  125. return;
  126. }
  127. }
  128.  
  129. objects.push_back(pObjectSA);
  130. dwObjectCount++;
  131. }
  132.  
  133. VOID CPopulationSA::AddPed ( CPedSAInterface * ped )
  134. {
  135. list < CCivilianPedSA* > ::iterator iter;
  136. for ( iter = peds.begin (); iter != peds.end (); ++iter )
  137. {
  138. if ( (*iter)->GetInterface() == ped )
  139. {
  140. return;
  141. }
  142. }
  143.  
  144. //_asm int 3
  145. CCivilianPedSA * pedSA = dynamic_cast < CCivilianPedSA* > ( pGameInterface->GetPools()->AddCivilianPed((DWORD *)ped ) );
  146. if ( !pedSA ) return;
  147.  
  148. //char szDebug[255] = {'\0'};
  149. DWORD dwPedInterface = (DWORD)pedSA->GetInterface();
  150. //sprintf ( szDebug, "Civ ped added (%d) (0x%X -> 0x%X)\n", dwPedCount+1, ped, dwPedInterface);
  151. //OutputDebugString ( szDebug );
  152.  
  153. if ( m_pCivilianAddHandler )
  154. m_pCivilianAddHandler ( pedSA );
  155.  
  156. peds.push_back (pedSA);
  157. dwPedCount ++;
  158. }
  159.  
  160. VOID CPopulationSA::AddVehicle(CVehicleSAInterface * vehicle)
  161. {
  162. list < CVehicleSA* > ::iterator iter;
  163. for (iter = vehicles.begin(); iter != vehicles.end(); ++iter)
  164. {
  165. if ((*iter)->GetInterface() == vehicle)
  166. {
  167. return;
  168. }
  169. }
  170.  
  171. //_asm int 3
  172. CVehicleSA * vehicleSA = dynamic_cast < CVehicleSA* > (pGameInterface->GetPools()->AddVehicle((DWORD *)vehicle));
  173. if (!vehicleSA) return;
  174.  
  175. //char szDebug[255] = { '\0' };
  176. DWORD dwVehicleInterface = (DWORD)vehicleSA->GetInterface();
  177. //sprintf(szDebug, "Vehicle added (%d) (0x%X -> 0x%X)\n", dwVehicleCount + 1, vehicle, dwVehicleInterface);
  178. //OutputDebugString ( szDebug );
  179.  
  180. if (m_pVehicleAddHandler)
  181. m_pVehicleAddHandler(vehicleSA);
  182.  
  183. vehicles.push_back(vehicleSA);
  184. dwVehicleCount++;
  185. }
  186.  
  187. VOID CPopulationSA::AddObject(CObjectSAInterface * object)
  188. {
  189. list < CObjectSA* > ::iterator iter;
  190. for (iter = objects.begin(); iter != objects.end(); ++iter)
  191. {
  192. if ((*iter)->GetInterface() == object)
  193. {
  194. return;
  195. }
  196. }
  197.  
  198. //_asm int 3
  199. CObjectSA * ObjectSA = dynamic_cast < CObjectSA* > (pGameInterface->GetPools()->AddBuilding(object->m_nModelIndex));
  200. if (!ObjectSA) return;
  201.  
  202. //char szDebug[255] = { '\0' };
  203. DWORD dwObjectInterface = (DWORD)ObjectSA->GetInterface();
  204. //sprintf(szDebug, "Object added (%d) (0x%X -> 0x%X)\n", dwObjectCount + 1, object, dwObjectInterface);
  205. //OutputDebugString ( szDebug );
  206.  
  207. if (m_pObjectAddHandler)
  208. m_pObjectAddHandler(ObjectSA);
  209.  
  210. objects.push_back(ObjectSA);
  211. dwObjectCount++;
  212. }
  213.  
  214. VOID CPopulationSA::RemovePed ( CCivilianPed * ped )
  215. {
  216. if ( !ped ) return;
  217.  
  218. CCivilianPedSA* pPedSA = dynamic_cast < CCivilianPedSA* > ( ped );
  219. if ( !pPedSA ) return;
  220.  
  221. ped->SetDoNotRemoveFromGameWhenDeleted ( true );
  222. pGameInterface->GetPools()->RemovePed ( (CPed*)ped );
  223. if ( !peds.empty () ) peds.remove ( pPedSA );
  224. dwPedCount--;
  225. }
  226.  
  227. VOID CPopulationSA::RemoveVehicle(CVehicle * vehicle)
  228. {
  229. if (!vehicle) return;
  230.  
  231. CVehicleSA* pVehicleSA = dynamic_cast < CVehicleSA* > (vehicle);
  232. if (!pVehicleSA) return;
  233.  
  234. vehicle->SetDoNotRemoveFromGameWhenDeleted(true);
  235. pGameInterface->GetPools()->RemoveVehicle((CVehicle*)vehicle);
  236. if (!vehicles.empty()) vehicles.remove(pVehicleSA);
  237. dwVehicleCount--;
  238. }
  239.  
  240. VOID CPopulationSA::RemoveObject(CObject * object)
  241. {
  242. if (!object) return;
  243.  
  244. CObjectSA* pObjectSA = dynamic_cast < CObjectSA* > (object);
  245. if (!pObjectSA) return;
  246.  
  247. object->SetDoNotRemoveFromGameWhenDeleted(true);
  248. pGameInterface->GetPools()->RemoveObject((CObject*)object);
  249. if (!objects.empty()) objects.remove(pObjectSA);
  250. dwObjectCount--;
  251. }
  252.  
  253. VOID CPopulationSA::RemovePed ( CPedSAInterface * ped )
  254. {
  255. list < CCivilianPedSA* > ::iterator iter;
  256. for ( iter = peds.begin (); iter != peds.end (); ++iter )
  257. {
  258. if ( (*iter)->GetInterface() == ped )
  259. {
  260. //char szDebug[255] = {'\0'};
  261. //sprintf ( szDebug, "Civ ped removed (%d)\n", dwPedCount - 1);
  262. pGameInterface->GetPools()->RemovePed ( (CPed *)(CCivilianPed *)(*iter), false );
  263. //OutputDebugString ( szDebug );
  264.  
  265. if ( m_pCivilianRemoveHandler )
  266. m_pCivilianRemoveHandler ( (*iter) );
  267.  
  268. peds.erase ( iter );
  269. dwPedCount--;
  270. return;
  271. }
  272. }
  273. //OutputDebugString ( "Tried to remove Civ Ped, but Civ Ped not found!\n" );
  274. }
  275.  
  276. VOID CPopulationSA::RemoveVehicle(CVehicleSAInterface * vehicle)
  277. {
  278. list < CVehicleSA* > ::iterator iter;
  279. for (iter = vehicles.begin(); iter != vehicles.end(); ++iter)
  280. {
  281. if ((*iter)->GetInterface() == vehicle)
  282. {
  283. //char szDebug[255] = {'\0'};
  284. //sprintf ( szDebug, "Civ ped removed (%d)\n", dwPedCount - 1);
  285. pGameInterface->GetPools()->RemoveVehicle((CVehicle*)(*iter), false);
  286. //OutputDebugString ( szDebug );
  287.  
  288. if (m_pVehicleRemoveHandler)
  289. m_pVehicleRemoveHandler((*iter));
  290.  
  291. vehicles.erase(iter);
  292. dwVehicleCount--;
  293. return;
  294. }
  295. }
  296. //OutputDebugString ( "Tried to remove Civ Ped, but Civ Ped not found!\n" );
  297. }
  298.  
  299. VOID CPopulationSA::RemoveObject(CObjectSAInterface * object)
  300. {
  301. list < CObjectSA* > ::iterator iter;
  302. for (iter = objects.begin(); iter != objects.end(); ++iter)
  303. {
  304. if ((*iter)->GetInterface() == object)
  305. {
  306. //char szDebug[255] = {'\0'};
  307. //sprintf ( szDebug, "Civ ped removed (%d)\n", dwPedCount - 1);
  308. pGameInterface->GetPools()->RemoveObject((CObject*)(*iter), false);
  309. //OutputDebugString ( szDebug );
  310.  
  311. if (m_pObjectRemoveHandler)
  312. m_pObjectRemoveHandler((*iter));
  313.  
  314. objects.erase(iter);
  315. dwObjectCount--;
  316. return;
  317. }
  318. }
  319. //OutputDebugString ( "Tried to remove Civ Ped, but Civ Ped not found!\n" );
  320. }
  321.  
  322. DWORD CPopulationSA::GetPedCount ( )
  323. {
  324. return dwPedCount;
  325. }
  326.  
  327. DWORD CPopulationSA::GetVehicleCount()
  328. {
  329. return dwVehicleCount;
  330. }
  331.  
  332. DWORD CPopulationSA::GetObjectCount()
  333. {
  334. return dwObjectCount;
  335. }
  336.  
  337. CCivilianPed * CPopulationSA::GetFirstPed ()
  338. {
  339. if ( peds.size () > 0 )
  340. {
  341. pedIter = peds.begin ();
  342. return *peds.begin ();
  343. }
  344. else
  345. {
  346. return NULL;
  347. }
  348. }
  349.  
  350. CVehicle * CPopulationSA::GetFirstVehicle()
  351. {
  352. if (vehicles.size() > 0)
  353. {
  354. vehIter = vehicles.begin();
  355. return *vehicles.begin();
  356. }
  357. else
  358. {
  359. return NULL;
  360. }
  361. }
  362.  
  363. CObject * CPopulationSA::GetFirstObject()
  364. {
  365. if (objects.size() > 0)
  366. {
  367. objectIter = objects.begin();
  368. return *objects.begin();
  369. }
  370. else
  371. {
  372. return NULL;
  373. }
  374. }
  375.  
  376. CCivilianPed * CPopulationSA::GetNextPed ()
  377. {
  378. ++( pedIter );
  379. if ( pedIter != peds.end () )
  380. {
  381. return *pedIter;
  382. }
  383. else
  384. {
  385. return NULL;
  386. }
  387. }
  388.  
  389. CVehicle * CPopulationSA::GetNextVehicle()
  390. {
  391. ++(vehIter);
  392. if (vehIter != vehicles.end())
  393. {
  394. return *vehIter;
  395. }
  396. else
  397. {
  398. return NULL;
  399. }
  400. }
  401.  
  402. CObject * CPopulationSA::GetNextObject()
  403. {
  404. ++(objectIter);
  405. if (objectIter != objects.end())
  406. {
  407. return *objectIter;
  408. }
  409. else
  410. {
  411. return NULL;
  412. }
  413. }
  414.  
  415. void CPopulationSA::SetCivilianAddHandler ( CivilianAddHandler * pCivilianAddHandler )
  416. {
  417. m_pCivilianAddHandler = pCivilianAddHandler;
  418. }
  419.  
  420. void CPopulationSA::SetCivilianRemoveHandler ( CivilianRemoveHandler * pCivilianRemoveHandler )
  421. {
  422. m_pCivilianRemoveHandler = pCivilianRemoveHandler;
  423. }
  424.  
  425. void CPopulationSA::SetObjectAddHandler(ObjectAddHandler * pObjectAddHandler)
  426. {
  427. m_pObjectAddHandler = pObjectAddHandler;
  428. }
  429.  
  430. void CPopulationSA::SetObjectRemoveHandler(ObjectRemoveHandler * pObjectRemoveHandler)
  431. {
  432. m_pObjectRemoveHandler = pObjectRemoveHandler;
  433. }
  434.  
  435. void CPopulationSA::SetVehicleAddHandler(VehicleAddHandler * pVehicleAddHandler)
  436. {
  437. m_pVehicleAddHandler = pVehicleAddHandler;
  438. }
  439.  
  440. void CPopulationSA::SetVehicleRemoveHandler(VehicleRemoveHandler * pVehicleRemoveHandler)
  441. {
  442. m_pVehicleRemoveHandler = pVehicleRemoveHandler;
  443. }
  444.  
  445. VOID _declspec(naked) HOOK_EndOf_CPopulation__Add()
  446. {
  447. _asm
  448. {
  449. mov pPedStorage, eax
  450. pushad
  451. }
  452.  
  453. pSingleton->AddPed ( pPedStorage );
  454.  
  455. _asm
  456. {
  457. popad
  458. add esp, 0x3C
  459. retn
  460. }
  461. }
  462.  
  463. VOID _declspec(naked) HOOK_CPopulation__RemovePed()
  464. {
  465. /*
  466.   00610F20 /$ 56 PUSH ESI
  467.   00610F21 |. 8B7424 08 MOV ESI,DWORD PTR SS:[ESP+8]
  468.   00610F25 |. 56 PUSH ESI
  469.   */
  470.  
  471. _asm
  472. {
  473.  
  474. push esi
  475. mov esi, [esp+8]
  476. push esi
  477. mov pPedStorage, esi
  478. mov ecx, [esi]
  479. mov pedVtable, ecx
  480. pushad
  481. }
  482.  
  483. if ( pedVtable == VTBL_CPlayerPed )
  484. {
  485. _asm
  486. {
  487. popad
  488. pop esi
  489. pop esi
  490. retn
  491. }
  492. }
  493.  
  494. pSingleton->RemovePed(pPedStorage);
  495.  
  496. _asm
  497. {
  498. popad
  499. mov ecx, HOOKPOS_CPopulation__RemovePed
  500. add ecx, 6
  501. jmp ecx
  502. }
  503. }
  504.  
  505. //I really just copied the ASM code, probably will crash
  506. VOID _declspec(naked) HOOK_CVehicle__Add()
  507. {
  508. _asm
  509. {
  510. mov pVehicleStorage, eax
  511. pushad
  512. }
  513.  
  514. pSingleton->AddVehicle(pVehicleStorage);
  515.  
  516. _asm
  517. {
  518. popad
  519. add esp, 0x3C
  520. retn
  521. }
  522. }
  523.  
  524. VOID _declspec(naked) HOOK_CVehicle__Remove()
  525. {
  526. #pragma warning ("Put ASM shit here just like in HOOK_EndOf_CPopulation__Add() to make it work")
  527. pSingleton->RemoveVehicle(pVehicleStorage);
  528. }
  529.  
  530. VOID _declspec(naked) HOOK_CObject__Add()
  531. {
  532. _asm
  533. {
  534. mov pObjectStorage, eax
  535. pushad
  536. }
  537.  
  538. pSingleton->AddObject(pObjectStorage);
  539.  
  540. _asm
  541. {
  542. popad
  543. add esp, 0x3C
  544. retn
  545. }
  546. }
  547. VOID _declspec(naked) HOOK_CObject__Remove()
  548. {
  549. pSingleton->RemoveObject(pObjectStorage);
  550. }
Compilation error #stdin compilation error #stdout 0s 0KB
stdin
Standard input is empty
compilation info
prog.cpp:15:20: fatal error: StdInc.h: No such file or directory
 #include "StdInc.h"
                    ^
compilation terminated.
stdout
Standard output is empty