/* ** Command & Conquer Renegade(tm) ** Copyright 2025 Electronic Arts Inc. ** ** This program is free software: you can redistribute it and/or modify ** it under the terms of the GNU General Public License as published by ** the Free Software Foundation, either version 3 of the License, or ** (at your option) any later version. ** ** This program is distributed in the hope that it will be useful, ** but WITHOUT ANY WARRANTY; without even the implied warranty of ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ** GNU General Public License for more details. ** ** You should have received a copy of the GNU General Public License ** along with this program. If not, see . */ /*********************************************************************************************** *** Confidential - Westwood Studios *** *********************************************************************************************** * * * Project Name : Commando * * * * $Archive:: /Commando/Code/wwnet/networkobjectmgr.cpp $* * * * $Author:: Tom_s $* * * * $Modtime:: 1/07/02 10:30a $* * * * $Revision:: 20 $* * * *---------------------------------------------------------------------------------------------* * Functions: * * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ #include "networkobjectmgr.h" #include "networkobject.h" //////////////////////////////////////////////////////////////// // Static member initialization //////////////////////////////////////////////////////////////// NetworkObjectMgrClass::OBJECT_LIST NetworkObjectMgrClass::_ObjectList; NetworkObjectMgrClass::OBJECT_LIST NetworkObjectMgrClass::_DeletePendingList; int NetworkObjectMgrClass::_NewDynamicID = NETID_DYNAMIC_OBJECT_MIN; int NetworkObjectMgrClass::_NewClientID = 0; bool NetworkObjectMgrClass::_IsLevelLoading = false; //////////////////////////////////////////////////////////////// // // Register_Object // //////////////////////////////////////////////////////////////// void NetworkObjectMgrClass::Register_Object (NetworkObjectClass *object) { int object_id = object->Get_Network_ID (); if (object_id != 0) { // // Check to ensure the object isn't already in the list // int index = 0; if (Find_Object (object_id, &index) == false) { // // Insert the object into the list // _ObjectList.Insert (index, object); } } return ; } //////////////////////////////////////////////////////////////// // // Unregister_Object // //////////////////////////////////////////////////////////////// void NetworkObjectMgrClass::Unregister_Object (NetworkObjectClass *object) { int object_id = object->Get_Network_ID (); if (object_id != 0) { // // Try to find the object in the list // int index = 0; if (Find_Object (object_id, &index)) { // // Remove the object from the list // _ObjectList.Delete (index); } } return ; } //////////////////////////////////////////////////////////////// // // Find_Object // //////////////////////////////////////////////////////////////// NetworkObjectClass * NetworkObjectMgrClass::Find_Object (int object_id) { NetworkObjectClass *object = NULL; // // Lookup the object in the sorted list // int index = 0; if (Find_Object (object_id, &index)) { object = _ObjectList[index]; } return object; } //////////////////////////////////////////////////////////////// // // Set_New_Dynamic_ID // //////////////////////////////////////////////////////////////// void NetworkObjectMgrClass::Set_New_Dynamic_ID (int id) { WWASSERT(id >= NETID_DYNAMIC_OBJECT_MIN && id <= NETID_DYNAMIC_OBJECT_MAX); _NewDynamicID = id; } //////////////////////////////////////////////////////////////// // // Get_New_Dynamic_ID // //////////////////////////////////////////////////////////////// int NetworkObjectMgrClass::Get_New_Dynamic_ID (void) { WWASSERT(_NewDynamicID >= NETID_DYNAMIC_OBJECT_MIN && _NewDynamicID < NETID_DYNAMIC_OBJECT_MAX); /* //TSS091001 NetworkObjectClass * p_object = Find_Object(_NewDynamicID); //WWASSERT(p_object == NULL); if (p_object != NULL) { int iii; iii = 111; } /**/ //TSS091201 NetworkObjectClass * p_object = Find_Object(_NewDynamicID); while (p_object != NULL) { /* WWDEBUG_SAY(("NetworkObjectMgrClass::Get_New_Dynamic_ID :skipping id %d (already in use)\n", _NewDynamicID)); */ _NewDynamicID++; p_object = Find_Object(_NewDynamicID); } return _NewDynamicID++; } //////////////////////////////////////////////////////////////// // // Get_Current_Dynamic_ID // //////////////////////////////////////////////////////////////// int NetworkObjectMgrClass::Get_Current_Dynamic_ID (void) { WWASSERT(_NewDynamicID >= NETID_DYNAMIC_OBJECT_MIN && _NewDynamicID <= NETID_DYNAMIC_OBJECT_MAX); return _NewDynamicID; } //////////////////////////////////////////////////////////////// // // Init_New_Client_ID // //////////////////////////////////////////////////////////////// void NetworkObjectMgrClass::Init_New_Client_ID (int client_id) { WWASSERT(client_id > 0); _NewClientID = NETID_CLIENT_OBJECT_MIN + (client_id - 1) * 100000; } //////////////////////////////////////////////////////////////// // // Get_New_Client_ID // //////////////////////////////////////////////////////////////// int NetworkObjectMgrClass::Get_New_Client_ID (void) { WWASSERT(_NewClientID >= NETID_CLIENT_OBJECT_MIN && _NewClientID < NETID_CLIENT_OBJECT_MAX); return _NewClientID++; } //////////////////////////////////////////////////////////////// // // Find_Object // //////////////////////////////////////////////////////////////// bool NetworkObjectMgrClass::Find_Object (int id_to_find, int *index) { WWASSERT(index != NULL); bool found = false; (*index) = 0; int min_index = 0; int max_index = _ObjectList.Count () - 1; // // Keep looping until we've closed the window of possiblity // bool keep_going = (max_index >= min_index); while (keep_going) { // // Calculate what slot we are currently looking at // int curr_index = min_index + ((max_index - min_index) / 2); int curr_id = _ObjectList[curr_index]->Get_Network_ID (); // // Did we find the right slot? // if (id_to_find == curr_id) { (*index) = curr_index; keep_going = false; found = true; } else { // // Stop if we've narrowed the window to one entry // keep_going = (max_index > min_index); // // Move the window to the appropriate side // of the test index. // if (id_to_find < curr_id) { max_index = curr_index - 1; (*index) = curr_index; } else { min_index = curr_index + 1; (*index) = curr_index + 1; } } } return found; } //////////////////////////////////////////////////////////////// // // Think // //////////////////////////////////////////////////////////////// void NetworkObjectMgrClass::Think (void) { // // Simply let each object think // for (int index = 0; index < _ObjectList.Count (); index ++) { WWASSERT(_ObjectList[index] != NULL); _ObjectList[index]->Network_Think (); } return ; } //////////////////////////////////////////////////////////////// // // Set_All_Delete_Pending // // This is for cleanup only. // //////////////////////////////////////////////////////////////// void NetworkObjectMgrClass::Set_All_Delete_Pending (void) { WWDEBUG_SAY(("NetworkObjectMgrClass::Set_All_Delete_Pending\n")); // // Mark all netobjects as delete pending // for (int index = 0; index < _ObjectList.Count (); index ++) { _ObjectList[index]->Set_Delete_Pending(); } return ; } //////////////////////////////////////////////////////////////// // // Delete_Pending // //////////////////////////////////////////////////////////////// void NetworkObjectMgrClass::Delete_Pending (void) { if (_IsLevelLoading) { return ; } //WWDEBUG_SAY(("NetworkObjectMgrClass::Delete_Pending\n")); // // Delete each object that is pending... // for (int index = 0; index < _DeletePendingList.Count (); index ++) { WWASSERT(_DeletePendingList[index] != NULL); if (_DeletePendingList[index]->Is_Delete_Pending ()) { _DeletePendingList[index]->Delete (); } } // if (_DeletePendingList.Count()) { // _DeletePendingList.Delete_All (); // } _DeletePendingList.Reset_Active(); // No need to resize the vector back to zero... return ; } //////////////////////////////////////////////////////////////// // // Delete_Client_Objects // //////////////////////////////////////////////////////////////// void NetworkObjectMgrClass::Delete_Client_Objects (int client_id) { WWASSERT(client_id > 0); // // Delete each object that belongs to the given client // for (int index = 0; index < _ObjectList.Count (); index ++) { WWASSERT(_ObjectList[index] != NULL); if (_ObjectList[index]->Belongs_To_Client (client_id)) { //TSS092301 _ObjectList[index]->Delete (); _ObjectList[index]->Set_Delete_Pending(); } } return ; } //////////////////////////////////////////////////////////////// // // Restore_Dirty_Bits // //////////////////////////////////////////////////////////////// void NetworkObjectMgrClass::Restore_Dirty_Bits (int client_id) { WWASSERT(client_id > 0); // // If a guy quits, we need to restore the dirty bits on each object so that // if he rejoins he will be told about stuff again. // For now I am going to use the topmost client id... // for (int index = 0; index < _ObjectList.Count (); index ++) { NetworkObjectClass * p_object = _ObjectList[index]; WWASSERT(p_object != NULL); BYTE generic_bits = p_object->Get_Object_Dirty_Bits(NetworkObjectClass::MAX_CLIENT_COUNT - 1);//TSS2001e p_object->Set_Object_Dirty_Bits(client_id, generic_bits); } return ; } //////////////////////////////////////////////////////////////// // // Register_Object_For_Deletion // //////////////////////////////////////////////////////////////// void NetworkObjectMgrClass::Register_Object_For_Deletion (NetworkObjectClass *object) { if (_DeletePendingList.ID (object) == -1) { _DeletePendingList.Add (object); } return ; } //////////////////////////////////////////////////////////////// // // Reset_Import_State_Counts // //////////////////////////////////////////////////////////////// void NetworkObjectMgrClass::Reset_Import_State_Counts(void) { for (int index = 0; index < _ObjectList.Count (); index ++) { NetworkObjectClass * p_object = _ObjectList[index]; WWASSERT(p_object != NULL); // // Reset its import state count // p_object->Reset_Import_State_Count(); } }