networkobjectmgr.cpp 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437
  1. /*
  2. ** Command & Conquer Renegade(tm)
  3. ** Copyright 2025 Electronic Arts Inc.
  4. **
  5. ** This program is free software: you can redistribute it and/or modify
  6. ** it under the terms of the GNU General Public License as published by
  7. ** the Free Software Foundation, either version 3 of the License, or
  8. ** (at your option) any later version.
  9. **
  10. ** This program is distributed in the hope that it will be useful,
  11. ** but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. ** GNU General Public License for more details.
  14. **
  15. ** You should have received a copy of the GNU General Public License
  16. ** along with this program. If not, see <http://www.gnu.org/licenses/>.
  17. */
  18. /***********************************************************************************************
  19. *** Confidential - Westwood Studios ***
  20. ***********************************************************************************************
  21. * *
  22. * Project Name : Commando *
  23. * *
  24. * $Archive:: /Commando/Code/wwnet/networkobjectmgr.cpp $*
  25. * *
  26. * $Author:: Tom_s $*
  27. * *
  28. * $Modtime:: 1/07/02 10:30a $*
  29. * *
  30. * $Revision:: 20 $*
  31. * *
  32. *---------------------------------------------------------------------------------------------*
  33. * Functions: *
  34. * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
  35. #include "networkobjectmgr.h"
  36. #include "networkobject.h"
  37. ////////////////////////////////////////////////////////////////
  38. // Static member initialization
  39. ////////////////////////////////////////////////////////////////
  40. NetworkObjectMgrClass::OBJECT_LIST NetworkObjectMgrClass::_ObjectList;
  41. NetworkObjectMgrClass::OBJECT_LIST NetworkObjectMgrClass::_DeletePendingList;
  42. int NetworkObjectMgrClass::_NewDynamicID = NETID_DYNAMIC_OBJECT_MIN;
  43. int NetworkObjectMgrClass::_NewClientID = 0;
  44. bool NetworkObjectMgrClass::_IsLevelLoading = false;
  45. ////////////////////////////////////////////////////////////////
  46. //
  47. // Register_Object
  48. //
  49. ////////////////////////////////////////////////////////////////
  50. void
  51. NetworkObjectMgrClass::Register_Object (NetworkObjectClass *object)
  52. {
  53. int object_id = object->Get_Network_ID ();
  54. if (object_id != 0) {
  55. //
  56. // Check to ensure the object isn't already in the list
  57. //
  58. int index = 0;
  59. if (Find_Object (object_id, &index) == false) {
  60. //
  61. // Insert the object into the list
  62. //
  63. _ObjectList.Insert (index, object);
  64. }
  65. }
  66. return ;
  67. }
  68. ////////////////////////////////////////////////////////////////
  69. //
  70. // Unregister_Object
  71. //
  72. ////////////////////////////////////////////////////////////////
  73. void
  74. NetworkObjectMgrClass::Unregister_Object (NetworkObjectClass *object)
  75. {
  76. int object_id = object->Get_Network_ID ();
  77. if (object_id != 0) {
  78. //
  79. // Try to find the object in the list
  80. //
  81. int index = 0;
  82. if (Find_Object (object_id, &index)) {
  83. //
  84. // Remove the object from the list
  85. //
  86. _ObjectList.Delete (index);
  87. }
  88. }
  89. return ;
  90. }
  91. ////////////////////////////////////////////////////////////////
  92. //
  93. // Find_Object
  94. //
  95. ////////////////////////////////////////////////////////////////
  96. NetworkObjectClass *
  97. NetworkObjectMgrClass::Find_Object (int object_id)
  98. {
  99. NetworkObjectClass *object = NULL;
  100. //
  101. // Lookup the object in the sorted list
  102. //
  103. int index = 0;
  104. if (Find_Object (object_id, &index)) {
  105. object = _ObjectList[index];
  106. }
  107. return object;
  108. }
  109. ////////////////////////////////////////////////////////////////
  110. //
  111. // Set_New_Dynamic_ID
  112. //
  113. ////////////////////////////////////////////////////////////////
  114. void
  115. NetworkObjectMgrClass::Set_New_Dynamic_ID (int id)
  116. {
  117. WWASSERT(id >= NETID_DYNAMIC_OBJECT_MIN && id <= NETID_DYNAMIC_OBJECT_MAX);
  118. _NewDynamicID = id;
  119. }
  120. ////////////////////////////////////////////////////////////////
  121. //
  122. // Get_New_Dynamic_ID
  123. //
  124. ////////////////////////////////////////////////////////////////
  125. int
  126. NetworkObjectMgrClass::Get_New_Dynamic_ID (void)
  127. {
  128. WWASSERT(_NewDynamicID >= NETID_DYNAMIC_OBJECT_MIN && _NewDynamicID < NETID_DYNAMIC_OBJECT_MAX);
  129. /*
  130. //TSS091001
  131. NetworkObjectClass * p_object = Find_Object(_NewDynamicID);
  132. //WWASSERT(p_object == NULL);
  133. if (p_object != NULL) {
  134. int iii;
  135. iii = 111;
  136. }
  137. /**/
  138. //TSS091201
  139. NetworkObjectClass * p_object = Find_Object(_NewDynamicID);
  140. while (p_object != NULL) {
  141. /*
  142. WWDEBUG_SAY(("NetworkObjectMgrClass::Get_New_Dynamic_ID :skipping id %d (already in use)\n",
  143. _NewDynamicID));
  144. */
  145. _NewDynamicID++;
  146. p_object = Find_Object(_NewDynamicID);
  147. }
  148. return _NewDynamicID++;
  149. }
  150. ////////////////////////////////////////////////////////////////
  151. //
  152. // Get_Current_Dynamic_ID
  153. //
  154. ////////////////////////////////////////////////////////////////
  155. int
  156. NetworkObjectMgrClass::Get_Current_Dynamic_ID (void)
  157. {
  158. WWASSERT(_NewDynamicID >= NETID_DYNAMIC_OBJECT_MIN && _NewDynamicID <= NETID_DYNAMIC_OBJECT_MAX);
  159. return _NewDynamicID;
  160. }
  161. ////////////////////////////////////////////////////////////////
  162. //
  163. // Init_New_Client_ID
  164. //
  165. ////////////////////////////////////////////////////////////////
  166. void
  167. NetworkObjectMgrClass::Init_New_Client_ID (int client_id)
  168. {
  169. WWASSERT(client_id > 0);
  170. _NewClientID = NETID_CLIENT_OBJECT_MIN + (client_id - 1) * 100000;
  171. }
  172. ////////////////////////////////////////////////////////////////
  173. //
  174. // Get_New_Client_ID
  175. //
  176. ////////////////////////////////////////////////////////////////
  177. int
  178. NetworkObjectMgrClass::Get_New_Client_ID (void)
  179. {
  180. WWASSERT(_NewClientID >= NETID_CLIENT_OBJECT_MIN && _NewClientID < NETID_CLIENT_OBJECT_MAX);
  181. return _NewClientID++;
  182. }
  183. ////////////////////////////////////////////////////////////////
  184. //
  185. // Find_Object
  186. //
  187. ////////////////////////////////////////////////////////////////
  188. bool
  189. NetworkObjectMgrClass::Find_Object (int id_to_find, int *index)
  190. {
  191. WWASSERT(index != NULL);
  192. bool found = false;
  193. (*index) = 0;
  194. int min_index = 0;
  195. int max_index = _ObjectList.Count () - 1;
  196. //
  197. // Keep looping until we've closed the window of possiblity
  198. //
  199. bool keep_going = (max_index >= min_index);
  200. while (keep_going) {
  201. //
  202. // Calculate what slot we are currently looking at
  203. //
  204. int curr_index = min_index + ((max_index - min_index) / 2);
  205. int curr_id = _ObjectList[curr_index]->Get_Network_ID ();
  206. //
  207. // Did we find the right slot?
  208. //
  209. if (id_to_find == curr_id) {
  210. (*index) = curr_index;
  211. keep_going = false;
  212. found = true;
  213. } else {
  214. //
  215. // Stop if we've narrowed the window to one entry
  216. //
  217. keep_going = (max_index > min_index);
  218. //
  219. // Move the window to the appropriate side
  220. // of the test index.
  221. //
  222. if (id_to_find < curr_id) {
  223. max_index = curr_index - 1;
  224. (*index) = curr_index;
  225. } else {
  226. min_index = curr_index + 1;
  227. (*index) = curr_index + 1;
  228. }
  229. }
  230. }
  231. return found;
  232. }
  233. ////////////////////////////////////////////////////////////////
  234. //
  235. // Think
  236. //
  237. ////////////////////////////////////////////////////////////////
  238. void
  239. NetworkObjectMgrClass::Think (void)
  240. {
  241. //
  242. // Simply let each object think
  243. //
  244. for (int index = 0; index < _ObjectList.Count (); index ++) {
  245. WWASSERT(_ObjectList[index] != NULL);
  246. _ObjectList[index]->Network_Think ();
  247. }
  248. return ;
  249. }
  250. ////////////////////////////////////////////////////////////////
  251. //
  252. // Set_All_Delete_Pending
  253. //
  254. // This is for cleanup only.
  255. //
  256. ////////////////////////////////////////////////////////////////
  257. void
  258. NetworkObjectMgrClass::Set_All_Delete_Pending (void)
  259. {
  260. WWDEBUG_SAY(("NetworkObjectMgrClass::Set_All_Delete_Pending\n"));
  261. //
  262. // Mark all netobjects as delete pending
  263. //
  264. for (int index = 0; index < _ObjectList.Count (); index ++) {
  265. _ObjectList[index]->Set_Delete_Pending();
  266. }
  267. return ;
  268. }
  269. ////////////////////////////////////////////////////////////////
  270. //
  271. // Delete_Pending
  272. //
  273. ////////////////////////////////////////////////////////////////
  274. void
  275. NetworkObjectMgrClass::Delete_Pending (void)
  276. {
  277. if (_IsLevelLoading) {
  278. return ;
  279. }
  280. //WWDEBUG_SAY(("NetworkObjectMgrClass::Delete_Pending\n"));
  281. //
  282. // Delete each object that is pending...
  283. //
  284. for (int index = 0; index < _DeletePendingList.Count (); index ++) {
  285. WWASSERT(_DeletePendingList[index] != NULL);
  286. if (_DeletePendingList[index]->Is_Delete_Pending ()) {
  287. _DeletePendingList[index]->Delete ();
  288. }
  289. }
  290. // if (_DeletePendingList.Count()) {
  291. // _DeletePendingList.Delete_All ();
  292. // }
  293. _DeletePendingList.Reset_Active(); // No need to resize the vector back to zero...
  294. return ;
  295. }
  296. ////////////////////////////////////////////////////////////////
  297. //
  298. // Delete_Client_Objects
  299. //
  300. ////////////////////////////////////////////////////////////////
  301. void
  302. NetworkObjectMgrClass::Delete_Client_Objects (int client_id)
  303. {
  304. WWASSERT(client_id > 0);
  305. //
  306. // Delete each object that belongs to the given client
  307. //
  308. for (int index = 0; index < _ObjectList.Count (); index ++) {
  309. WWASSERT(_ObjectList[index] != NULL);
  310. if (_ObjectList[index]->Belongs_To_Client (client_id)) {
  311. //TSS092301 _ObjectList[index]->Delete ();
  312. _ObjectList[index]->Set_Delete_Pending();
  313. }
  314. }
  315. return ;
  316. }
  317. ////////////////////////////////////////////////////////////////
  318. //
  319. // Restore_Dirty_Bits
  320. //
  321. ////////////////////////////////////////////////////////////////
  322. void
  323. NetworkObjectMgrClass::Restore_Dirty_Bits (int client_id)
  324. {
  325. WWASSERT(client_id > 0);
  326. //
  327. // If a guy quits, we need to restore the dirty bits on each object so that
  328. // if he rejoins he will be told about stuff again.
  329. // For now I am going to use the topmost client id...
  330. //
  331. for (int index = 0; index < _ObjectList.Count (); index ++) {
  332. NetworkObjectClass * p_object = _ObjectList[index];
  333. WWASSERT(p_object != NULL);
  334. BYTE generic_bits = p_object->Get_Object_Dirty_Bits(NetworkObjectClass::MAX_CLIENT_COUNT - 1);//TSS2001e
  335. p_object->Set_Object_Dirty_Bits(client_id, generic_bits);
  336. }
  337. return ;
  338. }
  339. ////////////////////////////////////////////////////////////////
  340. //
  341. // Register_Object_For_Deletion
  342. //
  343. ////////////////////////////////////////////////////////////////
  344. void
  345. NetworkObjectMgrClass::Register_Object_For_Deletion (NetworkObjectClass *object)
  346. {
  347. if (_DeletePendingList.ID (object) == -1) {
  348. _DeletePendingList.Add (object);
  349. }
  350. return ;
  351. }
  352. ////////////////////////////////////////////////////////////////
  353. //
  354. // Reset_Import_State_Counts
  355. //
  356. ////////////////////////////////////////////////////////////////
  357. void
  358. NetworkObjectMgrClass::Reset_Import_State_Counts(void)
  359. {
  360. for (int index = 0; index < _ObjectList.Count (); index ++) {
  361. NetworkObjectClass * p_object = _ObjectList[index];
  362. WWASSERT(p_object != NULL);
  363. //
  364. // Reset its import state count
  365. //
  366. p_object->Reset_Import_State_Count();
  367. }
  368. }