This repository has been archived on 2025-02-27. You can view files and clone it, but cannot push or open issues or pull requests.
CnC_Renegade/Code/Commando/player.cpp

1105 lines
28 KiB
C++
Raw Permalink Normal View History

/*
** 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 <http://www.gnu.org/licenses/>.
*/
/***********************************************************************************************
*** 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 <string.h>
#include <stdio.h>
#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;
}