/* ** 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/Commando/team.cpp $* * * * $Author:: Tom_s $* * * * $Modtime:: 2/05/02 11:22a $* * * * $Revision:: 58 $* * * *---------------------------------------------------------------------------------------------* * Functions: * * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ #include "team.h" #include #include "teammanager.h" #include "miscutil.h" #include "cnetwork.h" #include "playermanager.h" #include "gamedata.h" #include "wwdebug.h" #include "useroptions.h" #include "playertype.h" #include "colors.h" #include "networkobjectfactory.h" #include "netclassids.h" #include "gameobjmanager.h" #include "translatedb.h" #include "string_ids.h" #include "multihud.h" #include "apppackettypes.h" #include "devoptions.h" #include "gamespyadmin.h" DECLARE_NETWORKOBJECT_FACTORY(cTeam, NETCLASSID_TEAM); //------------------------------------------------------------------------------------ cTeam::cTeam(void) { Reset(); Set_App_Packet_Type(APPPACKETTYPE_TEAM); cTeamManager::Add(this); } //------------------------------------------------------------------------------------ cTeam::~cTeam(void) { //WWDEBUG_SAY(("* Destroying team object %d (%s)\n", TeamNumber, Name)); } //------------------------------------------------------------------------------------ void cTeam::Init(int team_number)//, WideStringClass & name) { WWASSERT(team_number >= 0 && team_number < MAX_TEAMS); WWASSERT(cNetwork::I_Am_Server()); //WWDEBUG_SAY(("* Adding team object %d (%s)\n", team_number, name)); Set_Object_Dirty_Bit(NetworkObjectClass::BIT_CREATION, true); /* // // This doesn't work because at this point we are not yet a client // if (cNetwork::I_Am_Client()) { // // Turn off for self // Set_Object_Dirty_Bit(cNetwork::Get_My_Id(), NetworkObjectClass::BIT_CREATION, false); } /**/ TeamNumber = team_number; Init_Team_Name(); // // Special-case the IDs because this code is executed before loading, // and in loading the dynamic range is reset. // if (TeamNumber == PLAYERTYPE_NOD) { Set_Network_ID(NETID_NOD_TEAM); } else { WWASSERT(TeamNumber == PLAYERTYPE_GDI); Set_Network_ID(NETID_GDI_TEAM); } } //------------------------------------------------------------------------------------ void cTeam::Init_Team_Name(void) { if (TeamNumber == PLAYERTYPE_NOD) { Name = TRANSLATION(IDS_MP_TEAMNAME_MISSIONS_TEAM_0); } else { WWASSERT(TeamNumber == PLAYERTYPE_GDI); Name = TRANSLATION(IDS_MP_TEAMNAME_MISSIONS_TEAM_1); } } //------------------------------------------------------------------------------------ void cTeam::Reset(void) { Kills = 0; Deaths = 0; Score = 0; Money = 0; Set_Object_Dirty_Bit(NetworkObjectClass::BIT_RARE, true); } //------------------------------------------------------------------------------------ void cTeam::Set_Kills(int new_kills) { WWASSERT(cNetwork::I_Am_Only_Client()); WWASSERT(new_kills >= 0); Kills = new_kills; Set_Object_Dirty_Bit(NetworkObjectClass::BIT_RARE, true); } //------------------------------------------------------------------------------------ void cTeam::Set_Deaths(int new_deaths) { WWASSERT(cNetwork::I_Am_Only_Client()); WWASSERT(new_deaths >= 0); Deaths = new_deaths; Set_Object_Dirty_Bit(NetworkObjectClass::BIT_RARE, true); } //------------------------------------------------------------------------------------ void cTeam::Set_Score(float new_score) { //WWASSERT(cNetwork::I_Am_Only_Client()); Score = new_score; Set_Object_Dirty_Bit(NetworkObjectClass::BIT_OCCASIONAL, true); } //------------------------------------------------------------------------------------ int cTeam::Tally_Size(void) const { // // For the sake of simplicity/at the cost of efficiency, we calculate // team size, rather than storing and maintaining it. // To remind you of this I use "tally" instead of "get". // return cPlayerManager::Tally_Team_Size(TeamNumber); } //------------------------------------------------------------------------------------ void cTeam::Increment_Kills(void) { if (!CombatManager::Is_Gameplay_Permitted()) { return; } WWASSERT(cNetwork::I_Am_Server()); Kills++; Set_Object_Dirty_Bit(NetworkObjectClass::BIT_RARE, true); } //------------------------------------------------------------------------------------ void cTeam::Increment_Deaths(void) { if (!CombatManager::Is_Gameplay_Permitted()) { return; } WWASSERT(cNetwork::I_Am_Server()); Deaths++; Set_Object_Dirty_Bit(NetworkObjectClass::BIT_RARE, true); } //------------------------------------------------------------------------------------ void cTeam::Increment_Score(float increment) { if (!CombatManager::Is_Gameplay_Permitted()) { return; } WWASSERT(cNetwork::I_Am_Server()); Score += increment; Set_Object_Dirty_Bit(NetworkObjectClass::BIT_OCCASIONAL, true); } //------------------------------------------------------------------------------------ float cTeam::Get_Kill_To_Death_Ratio(void) const { // // If Deaths = 0, return -1; // float ktd = -1; if (Deaths > 0) { ktd = Kills / (float) Deaths; } return ktd; } //------------------------------------------------------------------------------------ void cTeam::Get_Team_String(int rank, WideStringClass & string) const { // // Compose a string description of a team's stats for display // string.Format(L""); WWASSERT(PTheGameData != NULL); //bool is_verbose = The_Game()->IsIntermission.Get() || MultiHUDClass::Get_Verbose_Lists(); bool is_verbose = //force_verbose || The_Game()->IsIntermission.Is_True() || //MultiHUDClass::Get_Verbose_Lists(); (MultiHUDClass::Get_Playerlist_Format() == PLAYERLIST_FORMAT_FULL); WideStringClass substring; // // Num Players // substring.Format(L"%-2d ", Tally_Size()); string += substring; /* // // Standing // if (is_verbose) { substring.Format(L" %2d. ", rank); string += substring; } */ // // Name // //GAMESPY //substring.Format(L"%-11s", Name); if (cGameSpyAdmin::Is_Gamespy_Game()) { substring.Format(L"%-36s", Name); } else { substring.Format(L"%-11s", Name); } string += substring; // // Kills // if (is_verbose) { substring.Format(L"%-8d", Kills); string += substring; } // // Deaths // if (is_verbose) { substring.Format(L"%-8d", Deaths); string += substring; } // // Kill to Death ratio // if (is_verbose) { float ktd = Get_Kill_To_Death_Ratio(); if (ktd >= 0) { substring.Format(L"%-8.1f", ktd); } else { substring.Format(L"%-8s", "-"); } string += substring; } /**/ // // Money // WWASSERT(PTheGameData != NULL); if ((The_Game()->Is_Cnc() || The_Game()->Is_Skirmish()) && is_verbose) { #ifdef WWDEBUG bool show = cDevOptions::ShowMoney.Is_True() || #else bool show = #endif // WWDEBUG cNetwork::I_Am_Only_Server() || (cNetwork::I_Am_Client() && cNetwork::Get_My_Player_Object() != NULL && (cNetwork::Get_My_Team_Number() == TeamNumber)); if (show) { substring.Format(L"%-8d", Tally_Money()); } else { substring.Format(L"%-8s", "-"); } string += substring; } /**/ // // Score // substring.Format(L"%-8d", (int) Score); string += substring; } //------------------------------------------------------------------------------------ Vector3 cTeam::Get_Color(void) const { return Get_Color_For_Team(TeamNumber); } //------------------------------------------------------------------------------------ int cTeam::Tally_Money(void) const { int tally = 0; for ( SLNode * player_node = cPlayerManager::Get_Player_Object_List()->Head(); player_node != NULL; player_node = player_node->Next ()) { cPlayer * p_player = player_node->Data(); WWASSERT(p_player != NULL); if (p_player->Get_Is_Active().Is_True() && p_player->Get_Player_Type() == TeamNumber) { tally += (int) p_player->Get_Money(); } } return tally; } //------------------------------------------------------------------------------------ void cTeam::Export_Creation(BitStreamClass &packet) { NetworkObjectClass::Export_Creation (packet); packet.Add(TeamNumber); //packet.Add_Wide_Terminated_String(Name);//XXX } //------------------------------------------------------------------------------------ void cTeam::Import_Creation(BitStreamClass &packet) { NetworkObjectClass::Import_Creation(packet); packet.Get(TeamNumber); //packet.Get_Wide_Terminated_String(Name, sizeof(Name)); //packet.Get_Wide_Terminated_String(Name.Get_Buffer(256), 256); Init_Team_Name(); WWASSERT(cNetwork::I_Am_Only_Client()); } //------------------------------------------------------------------------------------ void cTeam::Export_Rare(BitStreamClass &packet) { packet.Add(Kills); packet.Add(Deaths); //packet.Add(Score); ////packet.Add(Money); } //------------------------------------------------------------------------------------ void cTeam::Import_Rare(BitStreamClass &packet) { int placeholder = 0; //float float_placeholder = 0; Set_Kills( packet.Get(placeholder)); Set_Deaths( packet.Get(placeholder)); //Set_Score( packet.Get(float_placeholder)); ////Set_Money( packet.Get(placeholder)); } //------------------------------------------------------------------------------------ void cTeam::Export_Occasional(BitStreamClass &packet) { packet.Add(Score); //packet.Add(Money); } //------------------------------------------------------------------------------------ void cTeam::Import_Occasional(BitStreamClass &packet) { //int placeholder = 0; float float_placeholder = 0; Set_Score( packet.Get(float_placeholder)); //Set_Money( packet.Get(placeholder)); } //------------------------------------------------------------------------------------ void cTeam::Export_Frequent(BitStreamClass &packet) { } //------------------------------------------------------------------------------------ void cTeam::Import_Frequent(BitStreamClass &packet) { } //FlagCaps = 0; //FlagLosses = 0;