/* ** 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/player.cpp $* * * * $Author:: Steve_t $* * * * $Modtime:: 10/17/02 11:04a $* * * * $Revision:: 146 $* * * *---------------------------------------------------------------------------------------------* * Functions: * * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ #include "player.h" #include #include #include "playermanager.h" #include "teammanager.h" #include "wwdebug.h" #include "miscutil.h" #include "cnetwork.h" #include "textdisplay.h" #include "WWAudio.H" #include "gamedata.h" #include "wwdebug.h" #include "chunkio.h" #include "useroptions.h" #include "smartgameobj.h" #include "playertype.h" #include "translatedb.h" #include "string_ids.h" #include "devoptions.h" #include "colors.h" #include "persistfactory.h" #include "combatchunkid.h" #include "networkobjectfactory.h" #include "gameobjmanager.h" #include "gametype.h" #include "multihud.h" #include "apppackettypes.h" #include "messagewindow.h" #include "playerkill.h" #include "consolemode.h" #include "gamespyadmin.h" DECLARE_NETWORKOBJECT_FACTORY(cPlayer, NETCLASSID_PLAYER); // // Class statics // const int cPlayer::INVALID_ID = -1000; //------------------------------------------------------------------------------------ cPlayer::cPlayer(void) : ClanID(0), WOLPoints(0) { //WWDEBUG_SAY(("cPlayer::cPlayer\n")); Id = INVALID_ID; LadderPoints = 0; Kills = 0; Deaths = 0; Rung = 0; WolRank = -1; IpAddress = 0; Fps = 0; LastUpdateTimeMs = 0; DamageScaleFactor = 100; Ping = -1; FastSortKey = 0; NumWolGames = 0; Reset_Join_Time(); Reset_Total_Time(); Set_Is_In_Game(true); Set_Is_Waiting_For_Intermission(false); Set_App_Packet_Type(APPPACKETTYPE_PLAYER); Set_GameSpy_Auth_State(GAMESPY_AUTH_STATE_INITIAL); Set_GameSpy_Kick_State(GAMESPY_KICK_STATE_INITIAL); cPlayerManager::Add(this); } //------------------------------------------------------------------------------------ cPlayer::~cPlayer(void) { //WWDEBUG_SAY(("* Destroying player object for client %d (%s)\n", Id, Name)); //WWDEBUG_SAY(("cPlayer::~cPlayer\n")); cPlayerManager::Remove(this); } //------------------------------------------------------------------------------------ void cPlayer::Delete(void) { delete this; } //------------------------------------------------------------------------------------ void cPlayer::Init(void) { WWASSERT(cNetwork::I_Am_Server()); Set_Object_Dirty_Bit(NetworkObjectClass::BIT_CREATION, true); } //----------------------------------------------------------------------------- enum { CHUNKID_VARIABLES = 12374, CHUNKID_PARENT, MICROCHUNK_ID = 1, MICROCHUNK_NAME, MICROCHUNK_PLAYERTYPE, MICROCHUNK_KILLS, MICROCHUNK_DEATHS, XXXMICROCHUNK_SCORE, MICROCHUNK_NUMLIVES, MICROCHUNK_TEAMNUMBER, MICROCHUNK_REMAP_POINTER, }; //----------------------------------------------------------------------------- bool cPlayer::Save(ChunkSaveClass & csave) { csave.Begin_Chunk(CHUNKID_PARENT); PlayerDataClass::Save( csave ); csave.End_Chunk(); csave.Begin_Chunk(CHUNKID_VARIABLES); WRITE_MICRO_CHUNK(csave, MICROCHUNK_ID, Id); WRITE_MICRO_CHUNK_WIDESTRING(csave, MICROCHUNK_NAME, Name); WRITE_MICRO_CHUNK(csave, MICROCHUNK_KILLS, Kills()); WRITE_MICRO_CHUNK(csave, MICROCHUNK_DEATHS, Deaths()); WRITE_MICRO_CHUNK(csave, MICROCHUNK_TEAMNUMBER, PlayerType()); void * old_ptr = this; WRITE_MICRO_CHUNK(csave, MICROCHUNK_REMAP_POINTER, old_ptr); csave.End_Chunk(); return true; } //----------------------------------------------------------------------------- bool cPlayer::Load(ChunkLoadClass &cload) { void * old_ptr = NULL; while (cload.Open_Chunk()) { switch(cload.Cur_Chunk_ID()) { case CHUNKID_PARENT: PlayerDataClass::Load( cload ); break; case CHUNKID_VARIABLES: while (cload.Open_Micro_Chunk()) { switch(cload.Cur_Micro_Chunk_ID()) { READ_MICRO_CHUNK(cload, MICROCHUNK_ID, Id); READ_MICRO_CHUNK_WIDESTRING(cload, MICROCHUNK_NAME, Name); READ_SAFE_MICRO_CHUNK(cload, MICROCHUNK_KILLS, Kills,int); READ_SAFE_MICRO_CHUNK(cload, MICROCHUNK_DEATHS, Deaths, int); READ_SAFE_MICRO_CHUNK(cload, MICROCHUNK_TEAMNUMBER, PlayerType, int); READ_MICRO_CHUNK(cload, MICROCHUNK_REMAP_POINTER, old_ptr); default: Debug_Say(( "Unrecognized cPlayer Variable chunkID\n" )); break; } cload.Close_Micro_Chunk(); } break; default: Debug_Say(( "Unrecognized cPlayer chunkID\n" )); break; } cload.Close_Chunk(); } if ( old_ptr != NULL ) { SaveLoadSystemClass::Register_Pointer(old_ptr, this); } return true; } //------------------------------------------------------------------------------------ void cPlayer::On_Create(void) { WWASSERT(cNetwork::I_Am_Client()); // // Don't show a join message unless: // - It's MP // - I am rendering // - It's not about me // - His join came after my join (the server will send you existing // players before your own). // if (!IS_MISSION && cPlayerManager::Is_Player_Present(cNetwork::Get_My_Id())) { WWASSERT(CombatManager::Get_Message_Window() != NULL); if (cNetwork::Show_Welcome_Message(Name)) { switch (PlayerType()) { case PLAYERTYPE_RENEGADE: { WideStringClass widestring; widestring.Format( L"%s, %s.\n", TRANSLATION(IDS_MP_WELCOME_RENEGADE), Name); // // Display the message... // CombatManager::Get_Message_Window ()->Add_Message (widestring, Vector3 (0.7F, 0.7F, 0.7F)); break; } case PLAYERTYPE_NOD: case PLAYERTYPE_GDI: { WideStringClass widestring; WWASSERT(PTheGameData != NULL); if (The_Game()->IsTeamChangingAllowed.Is_True()) { widestring.Format( L"%s, %s.\n", TRANSLATION(IDS_MP_WELCOME_RENEGADE), Name); } else { widestring.Format( L"%s, %s, %s %s %s.\n", TRANSLATION(IDS_MP_WELCOME_RENEGADE), Name, TRANSLATION(IDS_MP_TO), The_Game()->Get_Team_Word(), cTeamManager::Get_Team_Name(PlayerType)); } // // Display the message... // CombatManager::Get_Message_Window ()->Add_Message (widestring, Vector3 (0.7F, 0.7F, 0.7F)); break; } default: DIE; } } else { switch (PlayerType()) { case PLAYERTYPE_MUTANT: case PLAYERTYPE_NEUTRAL: break; case PLAYERTYPE_RENEGADE: { WideStringClass widestring; widestring.Format( L"%s %s\n", Name, TRANSLATION(IDS_MP_RENEGADE_JOINS)); // // Display the message... // CombatManager::Get_Message_Window ()->Add_Message (widestring, Vector3 (0.7F, 0.7F, 0.7F)); break; } case PLAYERTYPE_NOD: case PLAYERTYPE_GDI: { WideStringClass widestring; WWASSERT(PTheGameData != NULL); if (The_Game()->IsTeamChangingAllowed.Is_True()) { widestring.Format( L"%s %s\n", Name, TRANSLATION(IDS_MP_RENEGADE_JOINS)); } else { widestring.Format( L"%s %s %s %s\n", Name, TRANSLATION(IDS_MP_TEAMPLAYER_JOINS), The_Game()->Get_Team_Word(), cTeamManager::Get_Team_Name(PlayerType)); } // // Display the message... // Vector3 color(0.7F, 0.7F, 0.7F); CombatManager::Get_Message_Window ()->Add_Message (widestring, color); break; } default: DIE; } } } } //------------------------------------------------------------------------------------ void cPlayer::On_Destroy(void) { if (cNetwork::I_Am_Client() && GameModeManager::Find("Combat")->Is_Active() && The_Game() != NULL && The_Game()->Is_Cnc()) { WideStringClass message; message.Format( L"%s %s\n", Name, TRANSLATION(IDS_MP_PLAYER_LEFT_GAME)); // // Display the message... // CombatManager::Get_Message_Window ()->Add_Message (message, Vector3 (0.7F, 0.7F, 0.7F)); } } //------------------------------------------------------------------------------------ void cPlayer::Mark_As_Modified(void) { Set_Object_Dirty_Bit(NetworkObjectClass::BIT_RARE, true); } //------------------------------------------------------------------------------------ void cPlayer::Set_Id(int id) { Id = id; Set_Object_Dirty_Bit(NetworkObjectClass::BIT_RARE, true); } //------------------------------------------------------------------------------------ void cPlayer::Set_Name(const WideStringClass & name) { Name = name; Set_Object_Dirty_Bit(NetworkObjectClass::BIT_RARE, true); } //------------------------------------------------------------------------------------ void cPlayer::Set_Player_Type(int type) { WWASSERT(type >= PLAYERTYPE_FIRST && type <= PLAYERTYPE_LAST); PlayerType = type; Set_Object_Dirty_Bit(NetworkObjectClass::BIT_RARE, true); } //----------------------------------------------------------------------------- bool cPlayer::Is_Team_Player(void) { return PlayerType == PLAYERTYPE_NOD || PlayerType == PLAYERTYPE_GDI; } //------------------------------------------------------------------------------------ void cPlayer::Reset_Player(void) { // // Call base class // PlayerDataClass::Reset_Player(); Set_Ladder_Points(0); Set_Kills(0); Set_Deaths(0); Reset_Join_Time(); Reset_Total_Time(); Set_Object_Dirty_Bit(NetworkObjectClass::BIT_RARE, true); } //------------------------------------------------------------------------------------ Vector3 cPlayer::Get_Color(void) const { switch (PlayerType()) { case PLAYERTYPE_NEUTRAL: return COLOR_NEUTRAL; break; case PLAYERTYPE_RENEGADE: return COLOR_RENEGADE; break; case PLAYERTYPE_NOD: return Get_Color_For_Team(PLAYERTYPE_NOD); break; case PLAYERTYPE_GDI: return Get_Color_For_Team(PLAYERTYPE_GDI); break; default: // //TSS110101 //This crashed the server in the beta test. //I don't know how we got here. //Try making it non-fatal. // //DIE; return COLOR_NEUTRAL; // avoid compiler warning } } //------------------------------------------------------------------------------------ void cPlayer::Get_Player_String(int rank, WideStringClass & string, bool force_verbose) { // // Compose a string description of a player's stats for display // #pragma message("TODO: (TSS) Examine all wide string %s formatting for errors...") string.Format(L""); WWASSERT(The_Game() != NULL); bool is_verbose = force_verbose || The_Game()->IsIntermission.Is_True() || //MultiHUDClass::Get_Verbose_Lists(); (MultiHUDClass::Get_Playerlist_Format() == PLAYERLIST_FORMAT_FULL); WideStringClass substring(0, true); // // Standing // //XXX substring.Format(L" %2d. ", rank); substring.Format(L" %2d. ", (int) Get_Rung()); string += substring; // // Name // // GAMESPY /* if (IsActive.Is_True()) { substring.Format(L"%-11s", Name); } else { substring.Format(L"%-9s##", Name); } */ if (cGameSpyAdmin::Is_Gamespy_Game()) { substring.Format(L"%-34s", Name); } else { substring.Format(L"%-9s", Name); } if (IsActive.Is_True()) { substring += L" "; } else { substring += L"##"; } string += substring; if (IsInGame.Is_False()) { // // Don't show all the other details, just show "RELOADING" // substring.Format(L"%s", TRANSLATION(IDS_MP_LOADING)); string += substring; return; } // // Kills // if (is_verbose) { substring.Format(L"%-8d", Get_Kills()); string += substring; } // // Deaths // if (is_verbose) { substring.Format(L"%-8d", Get_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. // Do not show other team's 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() == (int) PlayerType)); if (show) { substring.Format(L"%-8d", (int) Get_Money()); } else { substring.Format(L"%-8s", "-"); } string += substring; } // // Score // substring.Format(L"%-8d", (int) Get_Score()); string += substring; // // Ladder Points // if (force_verbose && The_Game()->IsLaddered.Is_True()) { substring.Format(L"%-8d", Get_Ladder_Points()); string += substring; } // // WOL rank // if (GameModeManager::Find("WOL")->Is_Active() && is_verbose) { if ((int)WolRank == -1) { substring.Format(L"%-8s", L" -"); } else { substring.Format(L"%-8d", (int)WolRank); } string += substring; } #ifdef WWDEBUG // // Ping // if (cDevOptions::ShowPing.Is_True()) { /* int ping = Get_Avg_Ping(); if (ping >= 0) { substring.Format(L"%-8d", ping); } else { substring.Format(L"%-8s", L""); } */ int ping = Get_Ping(); if (ping >= 0) { substring.Format(L"%-8d", ping); } else { substring.Format(L"%-8s", L""); } string += substring; } // // Player Id // if (cDevOptions::ShowId.Is_True()) { substring.Format(L"%-8d", Id); string += substring; } // // Fps // if (cNetwork::I_Am_Server() && cDevOptions::ShowClientFps.Is_True()) { substring.Format(L"%-8d", Fps); string += substring; } // // GameSpy auth. state // if (cNetwork::I_Am_Server() && cGameSpyAdmin::Is_Gamespy_Game() && cDevOptions::ShowGameSpyAuthState.Is_True()) { WideStringClass wide_string; wide_string.Convert_From(cGameSpyAuthMgr::Describe_Auth_State(GameSpyAuthState)); substring.Format(L"%-12s", wide_string); string += substring; } // // IP Address // if (cNetwork::I_Am_Server() && cDevOptions::ShowIpAddresses.Is_True()) { WideStringClass wide_ip; wide_ip.Convert_From(cNetUtil::Address_To_String(IpAddress)); substring.Format(L"%-30s", wide_ip); string += substring; } #endif // WWDEBUG if (force_verbose) { // // Logged player list has no color so we need to show Nod/GDI // //substring.Format(L" T%d", (int) PlayerType); if (PlayerType == PLAYERTYPE_NOD) { substring.Format(L" %s", TRANSLATION(IDS_MP_TEAMNAME_MISSIONS_TEAM_0)); } else { substring.Format(L" %s", TRANSLATION(IDS_MP_TEAMNAME_MISSIONS_TEAM_1)); } string += substring; } } //------------------------------------------------------------------------------------ void cPlayer::Set_Score(float score) { // // Call base class // PlayerDataClass::Set_Score(score); Set_Object_Dirty_Bit(NetworkObjectClass::BIT_OCCASIONAL, true); } //------------------------------------------------------------------------------------ void cPlayer::Increment_Score(float add) { if (!CombatManager::Is_Gameplay_Permitted()) { return; } // // Call base class // PlayerDataClass::Increment_Score(add); // // If this player is on a team, increment the team score // if (Is_Team_Player()) { cTeam * p_team = cTeamManager::Find_Team(Get_Player_Type()); WWASSERT(p_team != NULL); p_team->Increment_Score(add); } Set_Object_Dirty_Bit(NetworkObjectClass::BIT_OCCASIONAL, true); } //------------------------------------------------------------------------------------ void cPlayer::Set_Money(float money) { // // Call base class // PlayerDataClass::Set_Money(money); Set_Object_Dirty_Bit(NetworkObjectClass::BIT_OCCASIONAL, true); } //------------------------------------------------------------------------------------ void cPlayer::Increment_Money(float add) { if (!CombatManager::Is_Gameplay_Permitted()) { return; } // // Call base class // PlayerDataClass::Increment_Money(add); /* // // If this player is on a team, increment the team money // if (Is_Team_Player()) { cTeam * p_team = cTeamManager::Find_Team(Get_Player_Type()); WWASSERT(p_team != NULL); p_team->Increment_Money(add); } */ Set_Object_Dirty_Bit(NetworkObjectClass::BIT_OCCASIONAL, true); } //------------------------------------------------------------------------------------ void cPlayer::Set_Ladder_Points(int points) { LadderPoints = points; Set_Object_Dirty_Bit(NetworkObjectClass::BIT_RARE, true); } //------------------------------------------------------------------------------------ void cPlayer::Set_Kills(int new_kills) { WWASSERT(new_kills >= 0); Kills = new_kills; Set_Object_Dirty_Bit(NetworkObjectClass::BIT_OCCASIONAL, true); } //------------------------------------------------------------------------------------ void cPlayer::Set_Deaths(int new_deaths) { WWASSERT(new_deaths >= 0); Deaths = new_deaths; Set_Object_Dirty_Bit(NetworkObjectClass::BIT_OCCASIONAL, true); } //------------------------------------------------------------------------------------ void cPlayer::Set_Wol_Rank(int wol_rank) { WWASSERT(wol_rank >= -1); WolRank = wol_rank; Set_Object_Dirty_Bit(NetworkObjectClass::BIT_RARE, true); } //------------------------------------------------------------------------------------ void cPlayer::Set_Rung(int rung) { WWASSERT(rung >= 0); Rung = rung; } //------------------------------------------------------------------------------------ void cPlayer::Set_Damage_Scale_Factor(int factor) { WWASSERT(factor >= 0 && factor <= 100); DamageScaleFactor = factor; Set_Object_Dirty_Bit(NetworkObjectClass::BIT_RARE, true); } //------------------------------------------------------------------------------------ void cPlayer::Reset_Join_Time(void) { JoinTimeMs = TIMEGETTIME(); } //------------------------------------------------------------------------------------ void cPlayer::Increment_Total_Time(void) { TotalTimeMs += (TIMEGETTIME() - JoinTimeMs); } //------------------------------------------------------------------------------------ void cPlayer::Reset_Total_Time(void) { TotalTimeMs = 0; } //------------------------------------------------------------------------------------ void cPlayer::Set_Ip_Address(ULONG ip_address) { WWASSERT(ip_address != 0); WWDEBUG_SAY(("cPlayer::Set_Ip_Address to %s\n", cNetUtil::Address_To_String(ip_address))); IpAddress = ip_address; } //------------------------------------------------------------------------------------ void cPlayer::Set_Fps(int fps) { WWASSERT(fps >= 0); Fps = fps; } //------------------------------------------------------------------------------------ void cPlayer::Set_Last_Update_Time_Ms(DWORD time_ms) { LastUpdateTimeMs = time_ms; } //------------------------------------------------------------------------------------ float cPlayer::Get_Kill_To_Death_Ratio(void) const { // // If Deaths = 0, return -1; // float ktd = -1; if ((int) Deaths > 0) { ktd = ((int) Kills) / (float) ((int)Deaths); } return ktd; } //------------------------------------------------------------------------------------ void cPlayer::Increment_Kills(void) { if (!CombatManager::Is_Gameplay_Permitted()) { return; } WWASSERT(cNetwork::I_Am_Server()); Set_Kills((int)Kills + 1); } //------------------------------------------------------------------------------------ void cPlayer::Increment_Deaths(void) { if (!CombatManager::Is_Gameplay_Permitted()) { return; } WWASSERT(cNetwork::I_Am_Server()); Set_Deaths((int)Deaths + 1); } /* //------------------------------------------------------------------------------------ int cPlayer::Get_Avg_Ping(void) const { // // If you are a server this method will return the player's S->C ping. // If you are a client this method will return your own C->S ping, and // -1 for anyone else. // int ping = -1; if (cNetwork::I_Am_Server()) { if (Id > 0) { cRemoteHost * p_rhost = cNetwork::Get_Server_Rhost(Id); WWASSERT(p_rhost != NULL); ping = p_rhost->Get_Average_Internal_Pingtime_Ms(); } } else if (Id == cNetwork::Get_My_Id()) { WWASSERT(cNetwork::I_Am_Only_Client()); cRemoteHost * p_rhost = cNetwork::Get_Client_Rhost(); if (p_rhost != NULL) { // // It can be NULL as you are quitting // ping = p_rhost->Get_Average_Internal_Pingtime_Ms(); } } return ping; } */ //------------------------------------------------------------------------------------ int cPlayer::Get_Ping(void) { // // Update the ping if we are the server. // if (cNetwork::I_Am_Server() && Id > 0) { cRemoteHost * p_rhost = cNetwork::Get_Server_Rhost(Id); if (p_rhost != NULL) { Ping = p_rhost->Get_Average_Internal_Pingtime_Ms(); } } return Ping; } //------------------------------------------------------------------------------------ void cPlayer::Export_Creation(BitStreamClass &packet) { NetworkObjectClass::Export_Creation(packet); packet.Add_Wide_Terminated_String(Name); } //------------------------------------------------------------------------------------ void cPlayer::Import_Creation(BitStreamClass &packet) { NetworkObjectClass::Import_Creation(packet); WWASSERT(cNetwork::I_Am_Only_Client()); packet.Get_Wide_Terminated_String(Name.Get_Buffer(256), 256); } //------------------------------------------------------------------------------------ void cPlayer::Export_Rare(BitStreamClass &packet) { packet.Add(Id); packet.Add((int)LadderPoints); packet.Add((int)PlayerType); packet.Add(DamageScaleFactor); packet.Add(Get_Ping()); packet.Add(IsInGame.Get()); packet.Add(Invulnerable.Get()); packet.Add(IsActive.Get()); packet.Add((int)WolRank); packet.Add(NumWolGames); //WWDEBUG_SAY(("cPlayer::Export_Rare NumWolGames = %d\n", NumWolGames)); } //------------------------------------------------------------------------------------ void cPlayer::Import_Rare(BitStreamClass &packet) { int int_placeholder = 0; Set_Id( packet.Get(int_placeholder)); Set_Ladder_Points( packet.Get(int_placeholder)); Set_Player_Type( packet.Get(int_placeholder)); Set_Damage_Scale_Factor( packet.Get(int_placeholder)); Set_Ping( packet.Get(int_placeholder)); bool bool_placeholder = false; Set_Is_In_Game( packet.Get(bool_placeholder)); Invulnerable.Set( packet.Get(bool_placeholder)); Set_Is_Active( packet.Get(bool_placeholder)); WolRank = packet.Get(int_placeholder); NumWolGames = packet.Get(int_placeholder); } //------------------------------------------------------------------------------------ void cPlayer::Export_Occasional(BitStreamClass &packet) { // // Call the base class // PlayerDataClass::Export_Occasional(packet); packet.Add((int)Kills); packet.Add((int)Deaths); } //------------------------------------------------------------------------------------ void cPlayer::Import_Occasional(BitStreamClass &packet) { // // Call the base class // PlayerDataClass::Import_Occasional(packet); int int_placeholder = 0; Set_Kills( packet.Get(int_placeholder)); Set_Deaths( packet.Get(int_placeholder)); } //------------------------------------------------------------------------------------ void cPlayer::Set_Is_In_Game(bool state) { IsInGame.Set(state); Set_Object_Dirty_Bit(NetworkObjectClass::BIT_RARE, true); } //------------------------------------------------------------------------------------ void cPlayer::Set_Is_Waiting_For_Intermission(bool state) { IsWaitingForIntermission.Set(state); } //------------------------------------------------------------------------------------ void cPlayer::Set_Is_Active(bool flag) { if (flag != IsActive.Get()) { if (cNetwork::I_Am_Client()) { if (flag == true) { On_Create(); cPlayerManager::Activated(this); } else { On_Destroy(); cPlayerManager::Deactivated(this); } } if (IsActive.Is_False()) { // // Anyone who leaves will need to be reauthenticated next tim ethey attempt // to join. // Set_GameSpy_Auth_State(GAMESPY_AUTH_STATE_INITIAL); Set_GameSpy_Kick_State(GAMESPY_KICK_STATE_INITIAL); } IsActive.Set(flag); Set_Object_Dirty_Bit(NetworkObjectClass::BIT_RARE, true); } } //------------------------------------------------------------------------------------ bool cPlayer::Is_Alive_And_Kicking(void) const { // // Abbreviates those players who are human, loaded, and active. // return Is_Human() && IsInGame.Is_True() && IsActive.Is_True(); } //------------------------------------------------------------------------------------ void cPlayer::Set_Num_Wol_Games(int num_games) { NumWolGames = num_games; //WWDEBUG_SAY(("Set_Num_Wol_Games NumWolGames = %d\n", NumWolGames)); Set_Object_Dirty_Bit(NetworkObjectClass::BIT_RARE, true); } //------------------------------------------------------------------------------------ void cPlayer::Set_GameSpy_Auth_State(GAMESPY_AUTH_STATE_ENUM state) { if (state != GameSpyAuthState) { GameSpyAuthState = state; GameSpyAuthStateEntryTimeMs = TIMEGETTIME(); } } //------------------------------------------------------------------------------------ void cPlayer::Set_GameSpy_Auth_State_Entry_Time_Ms(DWORD time_ms) { GameSpyAuthStateEntryTimeMs = time_ms; } //------------------------------------------------------------------------------------ void cPlayer::Set_GameSpy_Challenge_String(StringClass & challenge_string) { WWASSERT(!challenge_string.Is_Empty()); GameSpyChallengeString = challenge_string; } //------------------------------------------------------------------------------------ void cPlayer::Set_GameSpy_Hash_Id(StringClass & hash_id) { WWASSERT(!hash_id.Is_Empty()); GameSpyHashId = hash_id; } //------------------------------------------------------------------------------------ void cPlayer::Set_GameSpy_Kick_State(GAMESPY_KICK_STATE_ENUM state) { if (state != GameSpyKickState) { GameSpyKickState = state; GameSpyKickStateEntryTimeMs = TIMEGETTIME(); } } //------------------------------------------------------------------------------------ void cPlayer::Set_GameSpy_Kick_State_Entry_Time_Ms(DWORD time_ms) { GameSpyKickStateEntryTimeMs = time_ms; }