Clone of UAS2 @ https://github.com/drudgedance/uas2

WorldManager.cpp 22KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723
  1. /*
  2. * This file is part of UAS2.
  3. *
  4. * UAS2 is free software; you can redistribute it and/or modify
  5. * it under the terms of the GNU General Public License as published by
  6. * the Free Software Foundation; either version 2 of the License, or
  7. * (at your option) any later version.
  8. *
  9. * UAS2 is distributed in the hope that it will be useful,
  10. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. * GNU General Public License for more details.
  13. * You should have received a copy of the GNU General Public License
  14. * along with UASv1; if not, write to the Free Software
  15. * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  16. */
  17. /**
  18. * @file WorldManager.cpp
  19. * Encapsulates basic world functionality. Maintains client and object lists.
  20. * Loads world objects and populates/depopulates landblock object lists.
  21. * Also controls when and which objects' Create Packets are sent to the client.
  22. * @see ReceiveAllObjectsInLandBlock() - encapsulates the functionality to create the objects within a given avatar's landblock.
  23. * @see ReceiveAllObjectsInFocus() - encapsulates funtionality to create tthe objects with the area of a given avatar's landblock.
  24. * @see LandBlocksWithin() - determines which landblocks are in the area of a given avatar's landblock.
  25. */
  26. //TODO: When a landblock is disabled, the important information should be saved to disk. Important
  27. // information being things like corpses.
  28. //Your location is Landblock: a5b4002b, X: 133.4, Y: 51.5, Z: 52.0, H: 184.8
  29. //Your location is Landblock: a5b30030, X: 127.6, Y: 169.9, Z: 55.9, H: 184.8
  30. #define RADAR_RADIUS 120
  31. #include "MasterServer.h"
  32. #include "WorldManager.h"
  33. #include "Client.h"
  34. #include "cModels.h"
  35. #include "cMagicModels.h"
  36. //Initialize static members
  37. //=============================================================
  38. DWORD cWorldManager::m_dwGUIDCycle_Avatar;
  39. DWORD cWorldManager::m_dwGUIDCycle_Object;
  40. std::list< DWORD > cWorldManager::m_lstUnusedAvatarGUIDs;
  41. std::list< DWORD > cWorldManager::m_lstUnusedObjectGUIDs;
  42. std::vector<ConfirmPanel> cWorldManager::m_lstConfirmsPending;
  43. DWORD cWorldManager::m_dwConfirmSequence;
  44. char cWorldManager::g_szAccessFile[MAX_PATH+20];
  45. cLandBlock *cLandBlock::m_lpcHashTable[510];
  46. WORD wTmpMoveCounter;
  47. //=============================================================
  48. /**
  49. * Loads the initial world objects
  50. *
  51. * This function is called when the server is started.
  52. */
  53. void cWorldManager::Load( )
  54. {
  55. cDatabase::InitializeAvatarGUIDs( m_dwGUIDCycle_Avatar );
  56. cDatabase::InitializeObjectGUIDs( m_dwGUIDCycle_Object );
  57. cLandBlock::Hash_Load( );
  58. cWorldManager::m_dwConfirmSequence = 0x00000000;
  59. // UpdateConsole( " --------------------------------------------------------------------------\r\n\r\n" );
  60. UpdateConsole( " Starting to load the world:\r\n\r\n" );
  61. cDatabase::LoadModelList( );
  62. // UpdateConsole( "\r\n Model list has been loaded.\r\n\r\n");
  63. cMasterServer::LoadItemModels( );
  64. UpdateConsole( "\r\n Item model loading complete.\r\n\r\n" );
  65. cMasterServer::LoadWorldModels( );
  66. UpdateConsole( "\r\n World model loading complete.\r\n\r\n" );
  67. cMasterServer::LoadSpellModels( );
  68. UpdateConsole( "\r\n Spell model loading complete.\r\n\r\n" );
  69. cMasterServer::LoadSpells( );
  70. UpdateConsole( "\r\n Spell loading complete.\r\n\r\n" );
  71. cMasterServer::LoadSpellComps( );
  72. UpdateConsole( "\r\n Spell component loading complete.\r\n\r\n" );
  73. cMasterServer::LoadWorldObjects( );
  74. UpdateConsole( "\r\n World objects loading complete.\r\n\r\n" );
  75. cMasterServer::LoadWorldObjects2( );
  76. UpdateConsole( "\r\n Merchant sign loading complete.\r\n\r\n" );
  77. cMasterServer::LoadHousing( );
  78. UpdateConsole( "\r\n Housing object loading complete.\r\n\r\n" );
  79. cMasterServer::LoadCovenants( );
  80. UpdateConsole( "\r\n Covenant crystal loading complete.\r\n\r\n" );
  81. cMasterServer::LoadHooks( );
  82. UpdateConsole( "\r\n Housing hooks loading complete.\r\n\r\n" );
  83. cMasterServer::LoadStorage( );
  84. UpdateConsole( "\r\n Housing storage loading complete.\r\n\r\n" );
  85. cMasterServer::LoadDoors( );
  86. UpdateConsole( "\r\n Door loading completed.\r\n\r\n" );
  87. cMasterServer::LoadChests( );
  88. UpdateConsole( "\r\n Chest loading complete.\r\n\r\n" );
  89. cMasterServer::LoadLifestones( );
  90. UpdateConsole( "\r\n Lifestone loading complete.\r\n\r\n" );
  91. cMasterServer::LoadPortals( );
  92. UpdateConsole( "\r\n Portal loading complete.\r\n\r\n" );
  93. cMasterServer::LoadAltars( );
  94. UpdateConsole( "\r\n Altar loading complete.\r\n\r\n" );
  95. cMasterServer::LoadNPCModels( );
  96. UpdateConsole( "\r\n NPC model loading complete.\r\n\r\n" );
  97. cMasterServer::LoadMonsterModels( );
  98. UpdateConsole( "\r\n Monster model loading complete.\r\n\r\n" );
  99. cMasterServer::LoadNPCs( );
  100. UpdateConsole( "\r\n NPC loading complete.\r\n\r\n" );
  101. cMasterServer::LoadGroundSpawns( );
  102. UpdateConsole( "\r\n Ground spawn loading complete.\r\n\r\n" );
  103. cMasterServer::LoadMonsters( );
  104. UpdateConsole( "\r\n Monster loading complete.\r\n\r\n" );
  105. UpdateConsole( " World loading complete!\r\n\r\n" );
  106. }
  107. void cWorldManager::Unload( )
  108. {
  109. cLandBlock::Hash_Unload( );
  110. }
  111. /**
  112. * Handles the processing for when an avatar moves.
  113. *
  114. * This function is called whenever an avatar moves. The function checks whether the avatar
  115. * has moved into a new landblock and populates/depopulates landblocks appropriately.
  116. * The function also sends the movement animation to all clients within focus.
  117. *
  118. * @param *pcClient - A pointer to the client whose avatar is being teleported.
  119. * @param &NewLoc - The address of the cLocation struct value that represents the location to which the avatar is being teleported.
  120. * @param wAnim - The numeric value of the animation to play.
  121. * @param flPlay - The speed at which to play the gievn animation.
  122. *
  123. * @return BOOL - A boolean value representing whether the avatar's landblock has not changed.
  124. */
  125. BOOL cWorldManager::MoveAvatar( cClient *pcClient, cLocation& NewLoc, WORD wAnim, float flPlaySpeed )
  126. {
  127. WORD wOldLB = HIWORD( pcClient->m_pcAvatar->m_Location.m_dwLandBlock );
  128. WORD wNewLB = HIWORD( NewLoc.m_dwLandBlock );
  129. WORD wO_LB = LOWORD( pcClient->m_pcAvatar->m_Location.m_dwLandBlock );
  130. WORD wN_LB = LOWORD( NewLoc.m_dwLandBlock );
  131. cLandBlock *pcNewLB = cLandBlock::Hash_New( wNewLB );
  132. SimpleAI::ExecuteActions( );
  133. /*
  134. #ifdef _DEBUG
  135. char szPacketA[120];
  136. sprintf( szPacketA, "Move: LB: %08x X: %f Y: %f Z: %f H1: %f U1: %f U2: %f H2: %f",NewLoc.m_dwLandBlock,NewLoc.m_flX, NewLoc.m_flY,NewLoc.m_flZ,NewLoc.m_flA,NewLoc.m_flB, NewLoc.m_flC,NewLoc.m_flW);
  137. cMasterServer::ServerMessage( ColorBlue,pcClient,(char *)szPacketA);
  138. #endif
  139. */
  140. cLocation OldLoc = pcClient->m_pcAvatar->m_Location;
  141. pcClient->m_pcAvatar->SetLocation( NewLoc );
  142. if ( wOldLB != wNewLB )
  143. {
  144. cLandBlock *pcOldLB = cLandBlock::Hash_Find( wOldLB );
  145. if ( !pcOldLB )
  146. return FALSE;
  147. WORD wLBUnFocus[9];
  148. WORD wLBFocus[9];
  149. cMessage cmLogin;
  150. // Must be signed to allow for negatives.
  151. short sDiffX = HIBYTE( wNewLB ) - HIBYTE( wOldLB );
  152. short sDiffY = LOBYTE( wNewLB ) - LOBYTE( wOldLB );
  153. cMessage cmCreate = pcClient->m_pcAvatar->CreatePacket( );
  154. BYTE bChangeSize = 0;
  155. *((DWORD *)&MSG_00000002[4]) = pcClient->m_pcAvatar->GetGUID( );
  156. cmLogin.CannedData( MSG_00000002, sizeof( MSG_00000002 ) );
  157. if ( sDiffY )
  158. {
  159. wLBFocus[0] = wNewLB + sDiffY * 2;
  160. wLBFocus[1] = wLBFocus[0] - 0x0100;
  161. wLBFocus[2] = wLBFocus[0] + 0x0100;
  162. wLBFocus[3] = wLBFocus[0] - 0x0200;
  163. wLBFocus[4] = wLBFocus[0] + 0x0200;
  164. wLBUnFocus[0] = wOldLB - sDiffY * 2;
  165. wLBUnFocus[1] = wLBUnFocus[0] - 0x0100;
  166. wLBUnFocus[2] = wLBUnFocus[0] + 0x0100;
  167. wLBUnFocus[3] = wLBUnFocus[0] - 0x0200;
  168. wLBUnFocus[4] = wLBUnFocus[0] + 0x0200;
  169. bChangeSize = 5;
  170. }
  171. if ( sDiffX )
  172. {
  173. if ( !bChangeSize )
  174. {
  175. wLBFocus[0] = wNewLB + sDiffX * 0x0200;
  176. wLBFocus[1] = wLBFocus[0] - 1;
  177. wLBFocus[2] = wLBFocus[0] + 1;
  178. wLBFocus[3] = wLBFocus[0] - 2;
  179. wLBFocus[4] = wLBFocus[0] + 2;
  180. wLBUnFocus[0] = wOldLB - sDiffX * 0x0200;
  181. wLBUnFocus[1] = wLBUnFocus[0] - 1;
  182. wLBUnFocus[2] = wLBUnFocus[0] + 1;
  183. wLBUnFocus[3] = wLBUnFocus[0] - 2;
  184. wLBUnFocus[4] = wLBUnFocus[0] + 2;
  185. bChangeSize = 5;
  186. }
  187. else
  188. {
  189. wLBFocus[5] = wNewLB + sDiffX * 0x0200;
  190. wLBFocus[6] = wLBFocus[5] - 1;
  191. wLBFocus[7] = wLBFocus[5] + 1;
  192. wLBUnFocus[5] = wOldLB - sDiffX * 0x0200;
  193. wLBUnFocus[6] = wLBUnFocus[5] - 1;
  194. wLBUnFocus[7] = wLBUnFocus[5] + 1;
  195. if ( sDiffY > 0 )
  196. {
  197. wLBFocus[8] = wLBFocus[5] - 2;
  198. wLBUnFocus[8] = wLBUnFocus[5] + 2;
  199. }
  200. else
  201. {
  202. wLBFocus[8] = wLBFocus[5] + 2;
  203. wLBUnFocus[8] = wLBUnFocus[5] - 2;
  204. }
  205. bChangeSize = 9;
  206. }
  207. }
  208. cLandBlock *pcRemFocus;
  209. cLandBlock *pcAddFocus;
  210. for ( int i = 0; i < bChangeSize; ++i )
  211. {
  212. pcRemFocus = cLandBlock::Hash_Find( wLBUnFocus[i] );
  213. pcAddFocus = cLandBlock::Hash_New( wLBFocus[i] );
  214. AddFocus( pcAddFocus, pcClient );
  215. if ( pcRemFocus )
  216. RemFocus( pcRemFocus, pcClient );
  217. //ReceiveAllObjectsInLandBlock( pcClient, pcAddFocus );
  218. ReceiveAllObjectsInFocus( pcClient, pcAddFocus );
  219. SendToAllInLandBlock( pcAddFocus, cmCreate, 3 );
  220. SendToAllInLandBlock( pcAddFocus, cmLogin, 3 );
  221. }
  222. // Guaranteed to happen for any kind of movement.
  223. AddClient( pcNewLB, pcClient );
  224. AddFocus( pcOldLB, pcClient );
  225. RemFocus( pcNewLB, pcClient );
  226. RemClient( pcOldLB, pcClient );
  227. }
  228. // if (( wOldLB == wNewLB ) && (HIBYTE(wO_LB) != HIBYTE( wN_LB)))
  229. if (( wOldLB == wNewLB ) && (wTmpMoveCounter > 60))
  230. {
  231. ReceiveAllObjectsInFocus( pcClient, pcNewLB );
  232. wTmpMoveCounter = 0;
  233. }
  234. if ( wAnim )
  235. SendToOthersInFocus( pcNewLB, pcClient, pcClient->m_pcAvatar->Animation( wAnim, flPlaySpeed ), 3 );
  236. SendToAllInFocus( pcNewLB, pcClient->m_pcAvatar->LocationPacket( ), 3 );
  237. wTmpMoveCounter = wTmpMoveCounter + 1 ;
  238. if ( cObject *CollisionPortal = GetCollisionPortal( OldLoc, NewLoc ) )
  239. CollisionPortal->Action( pcClient );
  240. return TRUE;
  241. }
  242. /**
  243. * Handles the processing for when an avatar is teleported
  244. *
  245. * This function is called whenever an avatar is teleported.
  246. *
  247. * @param *pcClient - A pointer to the client whose avatar is being teleported.
  248. * @param &NewLoc - The address of the cLocation struct value that represents the location to which the avatar is being teleported.
  249. *
  250. * @return BOOL - A boolean value representing whether the avatar's landblock has not changed.
  251. */
  252. BOOL cWorldManager::TeleportAvatar( cClient *pcClient, cLocation& NewLoc )
  253. {
  254. WORD wOldLB = HIWORD( pcClient->m_pcAvatar->m_Location.m_dwLandBlock );
  255. cLandBlock *pcOldLB = cLandBlock::Hash_Find( wOldLB );
  256. cLocation OldLoc = pcClient->m_pcAvatar->m_Location;
  257. if ( !pcOldLB )
  258. return FALSE;
  259. pcClient->m_pcAvatar->m_wPortalCount += 2;
  260. pcClient->m_pcAvatar->SetLocation( NewLoc );
  261. SendToAllInFocus( pcOldLB, pcClient->m_pcAvatar->LocationPacket( ), 3 );
  262. pcClient->m_pcAvatar->SetLocation( OldLoc );
  263. if ( !RemoveClient( pcClient, FALSE, FALSE ) )
  264. return FALSE;
  265. pcClient->m_pcAvatar->SetLocation( NewLoc );
  266. return TRUE;
  267. }
  268. /**
  269. * Handles the processing for when a client is removed from the server.
  270. *
  271. * This function is called whenever an avatar removed from the server
  272. *
  273. * @param *pcClient - A pointer to the client whose avatar is being removed.
  274. * @param fRemoveAvatar - A value representing whether the avatar should be removed.
  275. * @param fDeleteavatar - A value representing whether the avatar object should be deleted from working memory.
  276. *
  277. * @return BOOL - A boolean value representing whether the avatar is located in a known landblock.
  278. */
  279. BOOL cWorldManager::RemoveClient( cClient *pcClient, BOOL fRemoveAvatar, BOOL fDeleteAvatar )
  280. {
  281. WORD wLBs[25];
  282. WORD wLandBlock = HIWORD( pcClient->m_pcAvatar->m_Location.m_dwLandBlock );
  283. cLandBlock *pcLB = cLandBlock::Hash_Find( wLandBlock );
  284. if ( !pcLB )
  285. return FALSE;
  286. if ( pcClient->m_pcAvatar )
  287. {
  288. if ( fRemoveAvatar )
  289. {
  290. char szIP[32];
  291. cMasterServer::FormatIP_Port( pcClient->m_saSockAddr, szIP );
  292. UpdateConsole( " World Server disconnection:\r\n"
  293. " User: %s\r\n"
  294. " Avatar: %s\r\n"
  295. " IP: %s\r\n", pcClient->m_szAccountName, pcClient->m_pcAvatar->m_strName.c_str(), szIP);
  296. RemoveAvatar( pcClient, pcLB, 0x011B );
  297. //Karki
  298. cMasterServer::m_UserCount--;
  299. cMasterServer::ServerMessage( ColorMagenta, NULL, "%s has left %s. %d client(s) connected.", pcClient->m_pcAvatar->Name( ), cMasterServer::m_szServerName, cMasterServer::m_UserCount);
  300. //EndKarki
  301. }
  302. if ( fDeleteAvatar )
  303. SAFEDELETE( pcClient->m_pcAvatar )
  304. }
  305. RemClient( pcLB, pcClient );
  306. LandBlocksWithin( 2, wLandBlock, wLBs );
  307. for ( int i = 0; i < 24; ++i )
  308. {
  309. pcLB = cLandBlock::Hash_Find( wLBs[i] );
  310. if ( pcLB )
  311. RemFocus( pcLB, pcClient );
  312. }
  313. return TRUE;
  314. }
  315. /**
  316. * Handles the processing for when a client is added to the server.
  317. *
  318. * This function is called whenever an avatar is added to the server.
  319. *
  320. * @param *pcClient - A pointer to the client whose avatar is being added.
  321. * @param fSpawnAvatar - A value representing whether the avatar should be spawned.
  322. */
  323. BOOL cWorldManager::AddClient( cClient *pcClient, BOOL fSpawnAvatar )
  324. {
  325. WORD wLBs[25];
  326. WORD wLandBlock = HIWORD( pcClient->m_pcAvatar->m_Location.m_dwLandBlock );
  327. cLandBlock *pcLB = cLandBlock::Hash_New( wLandBlock );
  328. AddClient( pcLB, pcClient );
  329. LandBlocksWithin( 2, wLandBlock, wLBs );
  330. cLandBlock *pcFLB;
  331. for ( int i = 0; i < 24; ++i )
  332. {
  333. pcFLB = cLandBlock::Hash_New( wLBs[i] );
  334. AddFocus( pcFLB, pcClient );
  335. }
  336. if ( fSpawnAvatar )
  337. SpawnAvatar( pcClient, pcLB );
  338. return TRUE;
  339. }
  340. /**
  341. * Handles the processing of objects within an avatar's landblock.
  342. *
  343. * Sends the client the create messages of all objects within the specified landblock.
  344. * This is accomplished by iterating through all the clients within the landblock and sending
  345. * their Create Packets (excluding that packet for the client receiving them) and then
  346. * iterating through all the other objects and sending their Create Packets.
  347. *
  348. * @param *pcClient - A pointer to the client whose avatar should receive the packets.
  349. * @param *pcLB - The landblock in which the given avatar resides.
  350. */
  351. void cWorldManager::ReceiveAllObjectsInLandBlock( cClient *pcClient, cLandBlock *pcLB )
  352. {
  353. //Iterate through all the clients within the landblock
  354. for ( iterClient_lst itClient = pcLB->m_lstClients.begin( ); itClient != pcLB->m_lstClients.end( ); ++itClient )
  355. {
  356. //Exclude the pcClient
  357. if ( pcClient != *itClient )
  358. {
  359. cMessage cmLogin;
  360. *((DWORD *)&MSG_00000002[4]) = (*itClient)->m_pcAvatar->GetGUID( );
  361. cmLogin.CannedData( MSG_00000002, sizeof( MSG_00000002 ) );
  362. /*BOOL fContinue;
  363. do
  364. {
  365. cMessage cmChildren = ( *itClient )->m_pcAvatar->CreateChildren( fContinue );
  366. if( fContinue )
  367. pcClient->AddPacket( WORLD_SERVER, cmChildren, 3 );
  368. } while ( fContinue );*/
  369. ( *itClient )->m_pcAvatar->CreateChildren( pcClient );
  370. pcClient->AddPacket( WORLD_SERVER, (*itClient)->m_pcAvatar->CreatePacket( ), 3 );
  371. pcClient->AddPacket( WORLD_SERVER, cmLogin, 3 );
  372. }
  373. }
  374. //Iterate through all the objects within the landblock
  375. for ( iterObject_lst itObject = pcLB->m_lstObjects.begin( ); itObject != pcLB->m_lstObjects.end( ); ++itObject )
  376. {
  377. pcClient->AddPacket( WORLD_SERVER, (*itObject)->CreatePacket( ), 3 );
  378. }
  379. }
  380. /**
  381. * Sends the client the Create Messages for all of the objects within the focus range of the specified landblock.
  382. *
  383. * Iterates through the landblocks within a specified range of the avatar's current landblock.
  384. * A call is made to LandBlocksWithin() to determine which landblocks lie within the specified range.
  385. * For each landblock with the range, a call to ReceiveAllObjectsInLandBlock() is made.
  386. *
  387. * @param *pcClient - A pointer to the client whose avatar should referenced.
  388. * @param *pcLB - The landblock in which the given avatar resides.
  389. */
  390. void cWorldManager::ReceiveAllObjectsInFocus( cClient *pcClient, cLandBlock *pcLB )
  391. {
  392. WORD wLBs[25];
  393. LandBlocksWithin( 2, pcLB->m_wLandBlock, wLBs );
  394. // Receive all the objects in the landblock itself first.
  395. ReceiveAllObjectsInLandBlock( pcClient, pcLB );
  396. for ( int i = 0; i < 24; ++i )
  397. {
  398. pcLB = cLandBlock::Hash_Find( wLBs[i] );
  399. if ( pcLB )
  400. {
  401. //cMasterServer::LoadSpawns(pcLB->m_wLandBlock);
  402. ReceiveAllObjectsInLandBlock( pcClient, pcLB );
  403. }
  404. }
  405. }
  406. /**
  407. * Adds an object to object list of the landblock in which it is located.
  408. *
  409. * @param *pcObject - A pointer to the object to add.
  410. * @param fSpawnObject - A value representing whether the object should be spawned.
  411. */
  412. BOOL cWorldManager::AddObject( cObject *pcObject, BOOL fSpawnObject )
  413. {
  414. //Find the object's landblock
  415. WORD wLandBlock = HIWORD( pcObject->m_Location.m_dwLandBlock );
  416. cLandBlock *pcLB = cLandBlock::Hash_Find( wLandBlock );
  417. if ( !pcLB )
  418. pcLB = cLandBlock::Hash_New( wLandBlock );
  419. AddObject( pcLB, pcObject );
  420. if ( fSpawnObject )
  421. SpawnObject( pcObject, pcLB );
  422. return TRUE;
  423. }
  424. /**
  425. * Removes an object to object list of the landblock in which it is located.
  426. *
  427. * @param *pcObject - A pointer to the object to remove.
  428. * @param fRemoveObject - A value representing whether the object should be removed.
  429. * @param fDeleteObject - A value representing whether the object should be deleted from working memory.
  430. */
  431. BOOL cWorldManager::RemoveObject( cObject *pcObject, BOOL fRemoveObject, BOOL fDeleteObject )
  432. {
  433. WORD wLandBlock = HIWORD( pcObject->m_Location.m_dwLandBlock );
  434. cLandBlock *pcLB = cLandBlock::Hash_Find( wLandBlock );
  435. if ( !pcLB )
  436. return FALSE;
  437. RemObject( pcLB, pcObject );
  438. if ( fRemoveObject )
  439. RemoveObject( pcObject, pcLB );
  440. if ( fDeleteObject )
  441. SAFEDELETE( pcObject )
  442. return TRUE;
  443. }
  444. //// Object changes Landblock location
  445. /**
  446. * Adds an object to object list of the landblock in which it is located.
  447. *
  448. * Used for when an object changes landblock location.
  449. *
  450. * @param *pcObject - A pointer to the object to add.
  451. */
  452. BOOL cWorldManager::MoveAddObject( cObject *pcObject )
  453. {
  454. WORD wLandBlock = HIWORD( pcObject->m_Location.m_dwLandBlock );
  455. cLandBlock *pcLB = cLandBlock::Hash_Find( wLandBlock );
  456. if ( !pcLB )
  457. pcLB = cLandBlock::Hash_New( wLandBlock );
  458. AddObject( pcLB, pcObject );
  459. return TRUE;
  460. }
  461. /**
  462. * Removes an object from the object list of the landblock in which it is located.
  463. *
  464. * Used for when an object changes landblock location.
  465. *
  466. * @param *pcObject - A pointer to the object to remove.
  467. *
  468. * @return BOOL - A boolean value representing whether the object is located in a known landblock.
  469. */
  470. BOOL cWorldManager::MoveRemObject( cObject *pcObject )
  471. {
  472. WORD wLandBlock = HIWORD( pcObject->m_Location.m_dwLandBlock );
  473. cLandBlock *pcLB = cLandBlock::Hash_Find( wLandBlock );
  474. if ( !pcLB )
  475. return FALSE;
  476. RemObject( pcLB, pcObject );
  477. return TRUE;
  478. }
  479. //////////////////////////////////////////////////////
  480. /**
  481. * Removes all object from the object list of all the landblocks.
  482. *
  483. * This is accomplished by iterating through each landblock, for each landblock iterating through each object,
  484. * and deleting the objects as they are iterated through.
  485. */
  486. void cWorldManager::RemoveAllObjects()
  487. {
  488. for ( int i = 0; i < 510; ++i )
  489. {
  490. cLandBlock *pcLB = cLandBlock::m_lpcHashTable[i];
  491. while ( pcLB )
  492. {
  493. for ( iterObject_lst itObject = pcLB->m_lstObjects.begin( ); itObject != pcLB->m_lstObjects.end( ); )
  494. {
  495. if( !(*itObject)->IsStatic( ) )
  496. {
  497. RemoveObject( (*itObject), pcLB );
  498. SAFEDELETE( *itObject );
  499. itObject = pcLB->m_lstObjects.erase( itObject );
  500. }
  501. else
  502. ++itObject;
  503. }
  504. pcLB = pcLB->m_pcNext;
  505. }
  506. }
  507. }
  508. /**
  509. * Takes a center landblock and returns the landblocks around it.
  510. */
  511. void cWorldManager::LandBlocksWithin( BYTE bDistance, WORD wCenterLB, WORD *pwStore )
  512. {
  513. static WORD i = 0;
  514. WORD wDiameter = 2 * bDistance + 1;
  515. pwStore[i++] = wCenterLB + bDistance + (0x0100 * bDistance);
  516. int j = 1, k = -1;
  517. while ( 1 )
  518. {
  519. if ( j++ >= wDiameter )
  520. {
  521. if ( k == -1 )
  522. {
  523. k = -0x0100;
  524. j = 1;
  525. continue;
  526. }
  527. else if ( k == -0x0100 )
  528. {
  529. k = 1;
  530. j = 1;
  531. continue;
  532. }
  533. else if ( k == 1 )
  534. {
  535. k = 0x0100;
  536. j = 2;
  537. continue;
  538. }
  539. else
  540. break;
  541. }
  542. pwStore[i++] = pwStore[i-1] + k;
  543. }
  544. if ( bDistance > 1 )
  545. LandBlocksWithin( --bDistance, wCenterLB, pwStore );
  546. else
  547. {
  548. pwStore[i] = wCenterLB;
  549. i = 0;
  550. }
  551. }
  552. void cWorldManager::AddPendingConfirm(DWORD sequence, DWORD type, std::string szText, DWORD senderGUID, DWORD receiptGUID)
  553. {
  554. ConfirmPanel aConfirmPanel;
  555. aConfirmPanel.m_dwSequence = sequence;
  556. aConfirmPanel.m_dwType = type;
  557. aConfirmPanel.m_szText = szText;
  558. aConfirmPanel.m_dwSenderGUID = senderGUID;
  559. aConfirmPanel.m_dwReceiptGUID = receiptGUID;
  560. m_lstConfirmsPending.push_back(aConfirmPanel);
  561. }
  562. void cWorldManager::FindPendingConfirm( DWORD dwSeq, DWORD dwReply )
  563. {
  564. for( cWorldManager::iterConfirmPanel_lst itConfirmPanel = m_lstConfirmsPending.begin(); itConfirmPanel != m_lstConfirmsPending.end(); ++itConfirmPanel )
  565. {
  566. if ( itConfirmPanel->m_dwSequence == dwSeq )
  567. {
  568. cClient *pcSendClient = cClient::FindClient( itConfirmPanel->m_dwSenderGUID );
  569. cClient *pcRecvClient = cClient::FindClient( itConfirmPanel->m_dwReceiptGUID );
  570. switch (itConfirmPanel->m_dwType)
  571. {
  572. case 1:
  573. {
  574. pcRecvClient->m_pcAvatar->SwearAllegiance(itConfirmPanel->m_szText, dwReply, itConfirmPanel->m_dwSenderGUID);
  575. break;
  576. }
  577. case 2:
  578. {
  579. break;
  580. }
  581. case 3:
  582. {
  583. break;
  584. }
  585. case 4:
  586. {
  587. pcRecvClient->m_pcAvatar->FellowshipRecruitRecv(itConfirmPanel->m_szText, dwReply, itConfirmPanel->m_dwReceiptGUID);
  588. pcSendClient->m_pcAvatar->FellowshipRecruitSend(itConfirmPanel->m_szText, dwReply, itConfirmPanel->m_dwSenderGUID);
  589. break;
  590. }
  591. case 5:
  592. {
  593. break;
  594. }
  595. }
  596. m_lstConfirmsPending.erase(itConfirmPanel);
  597. break; // the "itConfirmPanel" iterator is now invalid; must break
  598. }
  599. }
  600. }