You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
482 lines
14 KiB
482 lines
14 KiB
//========= Copyright Valve Corporation, All rights reserved. ============// |
|
// |
|
//============================================================================= |
|
#include "cbase.h" |
|
#include "tf_team.h" |
|
#include "entitylist.h" |
|
#include "util.h" |
|
#include "tf_obj.h" |
|
#include "tf_gamerules.h" |
|
|
|
// memdbgon must be the last include file in a .cpp file!!! |
|
#include "tier0/memdbgon.h" |
|
|
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: SendProxy that converts the UtlVector list of objects to entindexes, where it's reassembled on the client |
|
//----------------------------------------------------------------------------- |
|
void SendProxy_TeamObjectList( const SendProp *pProp, const void *pStruct, const void *pData, DVariant *pOut, int iElement, int objectID ) |
|
{ |
|
CTFTeam *pTeam = (CTFTeam*)pStruct; |
|
|
|
Assert( iElement < pTeam->GetNumObjects() ); |
|
|
|
CBaseObject *pObject = pTeam->GetObject(iElement); |
|
|
|
EHANDLE hObject; |
|
hObject = pObject; |
|
|
|
SendProxy_EHandleToInt( pProp, pStruct, &hObject, pOut, iElement, objectID ); |
|
} |
|
|
|
int SendProxyArrayLength_TeamObjects( const void *pStruct, int objectID ) |
|
{ |
|
CTFTeam *pTeam = (CTFTeam*)pStruct; |
|
int iObjects = pTeam->GetNumObjects(); |
|
return iObjects; |
|
} |
|
|
|
//============================================================================= |
|
// |
|
// TF Team tables. |
|
// |
|
IMPLEMENT_SERVERCLASS_ST( CTFTeam, DT_TFTeam ) |
|
|
|
SendPropInt( SENDINFO( m_nFlagCaptures ), 8 ), |
|
SendPropInt( SENDINFO( m_iRole ), 4, SPROP_UNSIGNED ), |
|
|
|
SendPropArray2( |
|
SendProxyArrayLength_TeamObjects, |
|
SendPropInt( "team_object_array_element", 0, SIZEOF_IGNORE, NUM_NETWORKED_EHANDLE_BITS, SPROP_UNSIGNED, SendProxy_TeamObjectList ), |
|
MAX_PLAYERS * MAX_OBJECTS_PER_PLAYER, |
|
0, |
|
"team_object_array" |
|
), |
|
|
|
SendPropEHandle( SENDINFO( m_hLeader ) ), |
|
|
|
END_SEND_TABLE() |
|
|
|
|
|
LINK_ENTITY_TO_CLASS( tf_team, CTFTeam ); |
|
|
|
//============================================================================= |
|
// |
|
// TF Team Manager Functions. |
|
// |
|
CTFTeamManager s_TFTeamManager; |
|
|
|
CTFTeamManager *TFTeamMgr() |
|
{ |
|
return &s_TFTeamManager; |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: |
|
//----------------------------------------------------------------------------- |
|
CTFTeamManager::CTFTeamManager() |
|
{ |
|
m_UndefinedTeamColor.r = 255; |
|
m_UndefinedTeamColor.g = 255; |
|
m_UndefinedTeamColor.b = 255; |
|
m_UndefinedTeamColor.a = 0; |
|
|
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: |
|
//----------------------------------------------------------------------------- |
|
bool CTFTeamManager::Init( void ) |
|
{ |
|
// Clear the list. |
|
Shutdown(); |
|
|
|
// Create the team list. |
|
for ( int iTeam = 0; iTeam < TF_TEAM_COUNT; ++iTeam ) |
|
{ |
|
COMPILE_TIME_ASSERT( TF_TEAM_COUNT == ARRAYSIZE( g_aTeamNames ) ); |
|
COMPILE_TIME_ASSERT( TF_TEAM_COUNT == ARRAYSIZE( g_aTeamColors ) ); |
|
int index = Create( g_aTeamNames[iTeam], g_aTeamColors[iTeam] ); |
|
Assert( index == iTeam ); |
|
if ( index != iTeam ) |
|
return false; |
|
} |
|
|
|
return true; |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: |
|
//----------------------------------------------------------------------------- |
|
void CTFTeamManager::Shutdown( void ) |
|
{ |
|
// Note, don't delete each team since they are in the gEntList and will |
|
// automatically be deleted from there, instead. |
|
g_Teams.Purge(); |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: |
|
//----------------------------------------------------------------------------- |
|
int CTFTeamManager::Create( const char *pName, color32 color ) |
|
{ |
|
CTeam *pTeam = static_cast<CTeam*>( CreateEntityByName( "tf_team" ) ); |
|
if ( pTeam ) |
|
{ |
|
// Add the team to the global list of teams. |
|
int iTeam = g_Teams.AddToTail( pTeam ); |
|
|
|
// Initialize the team. |
|
pTeam->Init( pName, iTeam ); |
|
pTeam->NetworkProp()->SetUpdateInterval( 0.75f ); |
|
|
|
// Set the team color. |
|
CTFTeam *pTFTeam = static_cast<CTFTeam*>( pTeam ); |
|
pTFTeam->SetColor( color ); |
|
|
|
return iTeam; |
|
} |
|
|
|
// Error. |
|
return -1; |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: |
|
//----------------------------------------------------------------------------- |
|
int CTFTeamManager::GetFlagCaptures( int iTeam ) |
|
{ |
|
if ( !IsValidTeam( iTeam ) ) |
|
return -1; |
|
|
|
CTFTeam *pTeam = GetGlobalTFTeam( iTeam ); |
|
if ( !pTeam ) |
|
return -1; |
|
|
|
return pTeam->GetFlagCaptures(); |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: |
|
//----------------------------------------------------------------------------- |
|
void CTFTeamManager::IncrementFlagCaptures( int iTeam ) |
|
{ |
|
if ( !IsValidTeam( iTeam ) ) |
|
return; |
|
|
|
CTFTeam *pTeam = GetGlobalTFTeam( iTeam ); |
|
if ( !pTeam ) |
|
return; |
|
|
|
pTeam->IncrementFlagCaptures(); |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: |
|
//----------------------------------------------------------------------------- |
|
void CTFTeamManager::AddTeamScore( int iTeam, int iScoreToAdd ) |
|
{ |
|
if ( !IsValidTeam( iTeam ) ) |
|
return; |
|
|
|
CTeam *pTeam = GetGlobalTeam( iTeam ); |
|
if ( !pTeam ) |
|
return; |
|
|
|
pTeam->AddScore( iScoreToAdd ); |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: |
|
//----------------------------------------------------------------------------- |
|
bool CTFTeamManager::IsValidTeam( int iTeam ) |
|
{ |
|
if ( ( iTeam >= 0 ) && ( iTeam < g_Teams.Count() ) ) |
|
return true; |
|
|
|
return false; |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: |
|
//----------------------------------------------------------------------------- |
|
int CTFTeamManager::GetTeamCount( void ) |
|
{ |
|
return g_Teams.Count(); |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: |
|
//----------------------------------------------------------------------------- |
|
CTFTeam *CTFTeamManager::GetTeam( int iTeam ) |
|
{ |
|
Assert( ( iTeam >= 0 ) && ( iTeam < g_Teams.Count() ) ); |
|
if ( IsValidTeam( iTeam ) ) |
|
{ |
|
return static_cast<CTFTeam*>( g_Teams[iTeam] ); |
|
} |
|
|
|
return NULL; |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: |
|
//----------------------------------------------------------------------------- |
|
CTFTeam *CTFTeamManager::GetSpectatorTeam() |
|
{ |
|
return GetTeam( 0 ); |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: |
|
//----------------------------------------------------------------------------- |
|
color32 CTFTeamManager::GetUndefinedTeamColor( void ) |
|
{ |
|
return m_UndefinedTeamColor; |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: Sends a message to the center of the player's screen. |
|
//----------------------------------------------------------------------------- |
|
void CTFTeamManager::PlayerCenterPrint( CBasePlayer *pPlayer, const char *msg_name, const char *param1, const char *param2, const char *param3, const char *param4 ) |
|
{ |
|
ClientPrint( pPlayer, HUD_PRINTCENTER, msg_name, param1, param2, param3, param4 ); |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: Sends a message to the center of the given teams screen. |
|
//----------------------------------------------------------------------------- |
|
void CTFTeamManager::TeamCenterPrint( int iTeam, const char *msg_name, const char *param1, const char *param2, const char *param3, const char *param4 ) |
|
{ |
|
CTeamRecipientFilter filter( iTeam, true ); |
|
UTIL_ClientPrintFilter( filter, HUD_PRINTCENTER, msg_name, param1, param2, param3, param4 ); |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: Sends a message to the center of the player's teams screen (minus |
|
// the player). |
|
//----------------------------------------------------------------------------- |
|
void CTFTeamManager::PlayerTeamCenterPrint( CBasePlayer *pPlayer, const char *msg_name, const char *param1, const char *param2, const char *param3, const char *param4 ) |
|
{ |
|
CTeamRecipientFilter filter( pPlayer->GetTeamNumber(), true ); |
|
filter.RemoveRecipient( pPlayer ); |
|
UTIL_ClientPrintFilter( filter, HUD_PRINTCENTER, msg_name, param1, param2, param3, param4 ); |
|
} |
|
|
|
//============================================================================= |
|
// |
|
// TF Team Functions. |
|
// |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: Constructor. |
|
//----------------------------------------------------------------------------- |
|
CTFTeam::CTFTeam() |
|
{ |
|
m_TeamColor.r = 0; |
|
m_TeamColor.g = 0; |
|
m_TeamColor.b = 0; |
|
m_TeamColor.a = 0; |
|
|
|
m_nFlagCaptures = 0; |
|
m_nTotalFlagCaptures = 0; |
|
m_flTotalSecondsKOTHPointOwned = 0.f; |
|
m_flTotalPLRTrackPercentTraveled = 0.f; |
|
|
|
m_hLeader = NULL; |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: |
|
//----------------------------------------------------------------------------- |
|
void CTFTeam::SetColor( color32 color ) |
|
{ |
|
m_TeamColor = color; |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: |
|
//----------------------------------------------------------------------------- |
|
color32 CTFTeam::GetColor( void ) |
|
{ |
|
return m_TeamColor; |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: |
|
// Input: pPlayer - print to just that client, NULL = all clients |
|
//----------------------------------------------------------------------------- |
|
void CTFTeam::ShowScore( CBasePlayer *pPlayer ) |
|
{ |
|
if ( pPlayer ) |
|
{ |
|
ClientPrint( pPlayer, HUD_PRINTNOTIFY, UTIL_VarArgs( "Team %s: %d\n", GetName(), GetScore() ) ); |
|
} |
|
else |
|
{ |
|
UTIL_ClientPrintAll( HUD_PRINTNOTIFY, UTIL_VarArgs( "Team %s: %d\n", GetName(), GetScore() ) ); |
|
} |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// OBJECTS |
|
//----------------------------------------------------------------------------- |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: Add the specified object to this team. |
|
//----------------------------------------------------------------------------- |
|
void CTFTeam::AddObject( CBaseObject *pObject ) |
|
{ |
|
TRACE_OBJECT( UTIL_VarArgs( "%0.2f CTFTeam::AddObject adding object %p:%s to team %s\n", gpGlobals->curtime, |
|
pObject, pObject->GetClassname(), GetName() ) ); |
|
|
|
bool alreadyInList = IsObjectOnTeam( pObject ); |
|
Assert( !alreadyInList ); |
|
if ( !alreadyInList ) |
|
{ |
|
m_aObjects.AddToTail( pObject ); |
|
} |
|
|
|
NetworkStateChanged(); |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Returns true if the object is in the team's list of objects |
|
//----------------------------------------------------------------------------- |
|
bool CTFTeam::IsObjectOnTeam( CBaseObject *pObject ) const |
|
{ |
|
return ( m_aObjects.Find( pObject ) != -1 ); |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: Remove this object from the team |
|
// Removes all references from all sublists as well |
|
//----------------------------------------------------------------------------- |
|
void CTFTeam::RemoveObject( CBaseObject *pObject ) |
|
{ |
|
if ( m_aObjects.Count() <= 0 ) |
|
return; |
|
|
|
if ( m_aObjects.Find( pObject ) != -1 ) |
|
{ |
|
TRACE_OBJECT( UTIL_VarArgs( "%0.2f CTFTeam::RemoveObject removing %p:%s from %s\n", gpGlobals->curtime, |
|
pObject, pObject->GetClassname(), GetName() ) ); |
|
|
|
m_aObjects.FindAndRemove( pObject ); |
|
} |
|
else |
|
{ |
|
TRACE_OBJECT( UTIL_VarArgs( "%0.2f CTFTeam::RemoveObject couldn't remove %p:%s from %s\n", gpGlobals->curtime, |
|
pObject, pObject->GetClassname(), GetName() ) ); |
|
} |
|
|
|
NetworkStateChanged(); |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: |
|
//----------------------------------------------------------------------------- |
|
int CTFTeam::GetNumObjects( int iObjectType ) |
|
{ |
|
// Asking for a count of a specific object type? |
|
if ( iObjectType > 0 ) |
|
{ |
|
int iCount = 0; |
|
for ( int i = 0; i < GetNumObjects(); i++ ) |
|
{ |
|
CBaseObject *pObject = GetObject(i); |
|
if ( pObject && pObject->GetType() == iObjectType ) |
|
{ |
|
iCount++; |
|
} |
|
} |
|
return iCount; |
|
} |
|
|
|
return m_aObjects.Count(); |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: |
|
//----------------------------------------------------------------------------- |
|
CBaseObject *CTFTeam::GetObject( int num ) |
|
{ |
|
Assert( num >= 0 && num < m_aObjects.Count() ); |
|
return m_aObjects[ num ]; |
|
} |
|
|
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: Get a pointer to the specified TF team |
|
//----------------------------------------------------------------------------- |
|
CTFTeam *GetGlobalTFTeam( int iIndex ) |
|
{ |
|
if ( iIndex < 0 || iIndex >= GetNumberOfTeams() ) |
|
return NULL; |
|
|
|
return ( dynamic_cast< CTFTeam* >( g_Teams[iIndex] ) ); |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Set the team leader |
|
//----------------------------------------------------------------------------- |
|
bool CTFTeam::SetTeamLeader( CBasePlayer *pPlayer ) |
|
{ |
|
Assert ( pPlayer ); |
|
|
|
// player must be on this team |
|
if ( m_aPlayers.Find(pPlayer) == m_aPlayers.InvalidIndex() ) |
|
{ |
|
Assert( !"can't set a player as leader of a team he's not on" ); |
|
return false; |
|
} |
|
|
|
m_hLeader = pPlayer; |
|
|
|
return true; |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: Get Leader |
|
//----------------------------------------------------------------------------- |
|
CBasePlayer *CTFTeam::GetTeamLeader( void ) |
|
{ |
|
return m_hLeader.Get(); |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: Add the specified player to this team. Remove them from their current team, if any. |
|
//----------------------------------------------------------------------------- |
|
void CTFTeam::AddPlayer( CBasePlayer *pPlayer ) |
|
{ |
|
BaseClass::AddPlayer( pPlayer ); |
|
|
|
if ( GetTeamLeader() == NULL ) |
|
{ |
|
SetTeamLeader( pPlayer ); |
|
} |
|
|
|
TFGameRules()->TeamPlayerCountChanged( this ); |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: Remove this player from the team |
|
//----------------------------------------------------------------------------- |
|
void CTFTeam::RemovePlayer( CBasePlayer *pPlayer ) |
|
{ |
|
BaseClass::RemovePlayer( pPlayer ); |
|
|
|
if ( pPlayer == m_hLeader.Get() ) |
|
{ |
|
m_hLeader = NULL; |
|
|
|
if ( m_aPlayers.Count() > 0 ) |
|
{ |
|
// pick a new leader randomly |
|
int iLeader = random->RandomInt( 0, m_aPlayers.Count()-1 ); |
|
SetTeamLeader( m_aPlayers.Element(iLeader) ); |
|
} |
|
} |
|
|
|
TFGameRules()->TeamPlayerCountChanged( this ); |
|
} |