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.
342 lines
10 KiB
342 lines
10 KiB
//========= Copyright © 1996-2005, Valve Corporation, All rights reserved. ============// |
|
// |
|
// Purpose: Team management class. Contains all the details for a specific team |
|
// |
|
// $NoKeywords: $ |
|
//=============================================================================// |
|
#include "cbase.h" |
|
#include "team.h" |
|
#include "player.h" |
|
#include "team_spawnpoint.h" |
|
|
|
// memdbgon must be the last include file in a .cpp file!!! |
|
#include "tier0/memdbgon.h" |
|
|
|
CUtlVector< CTeam * > g_Teams; |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: SendProxy that converts the Team's player UtlVector to entindexes |
|
//----------------------------------------------------------------------------- |
|
void SendProxy_PlayerList( const SendProp *pProp, const void *pStruct, const void *pData, DVariant *pOut, int iElement, int objectID ) |
|
{ |
|
CTeam *pTeam = (CTeam*)pData; |
|
|
|
// If this assertion fails, then SendProxyArrayLength_PlayerArray must have failed. |
|
Assert( iElement < pTeam->m_aPlayers.Count() ); |
|
|
|
CBasePlayer *pPlayer = pTeam->m_aPlayers[iElement]; |
|
pOut->m_Int = pPlayer->entindex(); |
|
} |
|
|
|
|
|
int SendProxyArrayLength_PlayerArray( const void *pStruct, int objectID ) |
|
{ |
|
CTeam *pTeam = (CTeam*)pStruct; |
|
return pTeam->m_aPlayers.Count(); |
|
} |
|
|
|
|
|
// Datatable |
|
IMPLEMENT_SERVERCLASS_ST_NOBASE(CTeam, DT_Team) |
|
SendPropInt( SENDINFO(m_iTeamNum), 5 ), |
|
SendPropInt( SENDINFO(m_iScore), 0 ), |
|
SendPropInt( SENDINFO(m_iRoundsWon), 8 ), |
|
SendPropString( SENDINFO( m_szTeamname ) ), |
|
|
|
SendPropArray2( |
|
SendProxyArrayLength_PlayerArray, |
|
SendPropInt("player_array_element", 0, 4, 10, SPROP_UNSIGNED, SendProxy_PlayerList), |
|
MAX_PLAYERS, |
|
0, |
|
"player_array" |
|
) |
|
END_SEND_TABLE() |
|
|
|
LINK_ENTITY_TO_CLASS( team_manager, CTeam ); |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: Get a pointer to the specified team manager |
|
//----------------------------------------------------------------------------- |
|
CTeam *GetGlobalTeam( int iIndex ) |
|
{ |
|
if ( iIndex < 0 || iIndex >= GetNumberOfTeams() ) |
|
return NULL; |
|
|
|
return g_Teams[ iIndex ]; |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: Get the number of team managers |
|
//----------------------------------------------------------------------------- |
|
int GetNumberOfTeams( void ) |
|
{ |
|
return g_Teams.Count(); |
|
} |
|
|
|
const char* GetTeamName( int iTeam ) |
|
{ |
|
CTeam *pTeam = GetGlobalTeam( iTeam ); |
|
if ( pTeam ) |
|
{ |
|
return pTeam->GetName(); |
|
} |
|
else |
|
{ |
|
return "UNKNOWN TEAM"; |
|
} |
|
} |
|
|
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: Needed because this is an entity, but should never be used |
|
//----------------------------------------------------------------------------- |
|
CTeam::CTeam( void ) |
|
{ |
|
memset( m_szTeamname.GetForModify(), 0, sizeof(m_szTeamname) ); |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: |
|
//----------------------------------------------------------------------------- |
|
CTeam::~CTeam( void ) |
|
{ |
|
m_aSpawnPoints.Purge(); |
|
m_aPlayers.Purge(); |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: Called every frame |
|
//----------------------------------------------------------------------------- |
|
void CTeam::Think( void ) |
|
{ |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: Teams are always transmitted to clients |
|
//----------------------------------------------------------------------------- |
|
int CTeam::UpdateTransmitState() |
|
{ |
|
return SetTransmitState( FL_EDICT_ALWAYS ); |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Visibility/scanners |
|
//----------------------------------------------------------------------------- |
|
int CTeam::ShouldTransmitToPlayer( CBasePlayer* pRecipient, CBaseEntity* pEntity ) |
|
{ |
|
// Always transmit the observer target to players |
|
if ( pRecipient && pRecipient->IsObserver() && pRecipient->GetObserverTarget() == pEntity ) |
|
return FL_EDICT_ALWAYS; |
|
|
|
return FL_EDICT_PVSCHECK; |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Initialization |
|
//----------------------------------------------------------------------------- |
|
void CTeam::Init( const char *pName, int iNumber ) |
|
{ |
|
InitializeSpawnpoints(); |
|
InitializePlayers(); |
|
|
|
m_iScore = 0; |
|
|
|
Q_strncpy( m_szTeamname.GetForModify(), pName, MAX_TEAM_NAME_LENGTH ); |
|
m_iTeamNum = iNumber; |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// DATA HANDLING |
|
//----------------------------------------------------------------------------- |
|
int CTeam::GetTeamNumber( void ) const |
|
{ |
|
return m_iTeamNum; |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: Get the team's name |
|
//----------------------------------------------------------------------------- |
|
const char *CTeam::GetName( void ) |
|
{ |
|
return m_szTeamname; |
|
} |
|
|
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: Update the player's client data |
|
//----------------------------------------------------------------------------- |
|
void CTeam::UpdateClientData( CBasePlayer *pPlayer ) |
|
{ |
|
} |
|
|
|
//------------------------------------------------------------------------------------------------------------------ |
|
// SPAWNPOINTS |
|
//----------------------------------------------------------------------------- |
|
// Purpose: |
|
//----------------------------------------------------------------------------- |
|
void CTeam::InitializeSpawnpoints( void ) |
|
{ |
|
m_iLastSpawn = 0; |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: |
|
//----------------------------------------------------------------------------- |
|
void CTeam::AddSpawnpoint( CTeamSpawnPoint *pSpawnpoint ) |
|
{ |
|
m_aSpawnPoints.AddToTail( pSpawnpoint ); |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: |
|
//----------------------------------------------------------------------------- |
|
void CTeam::RemoveSpawnpoint( CTeamSpawnPoint *pSpawnpoint ) |
|
{ |
|
for (int i = 0; i < m_aSpawnPoints.Count(); i++ ) |
|
{ |
|
if ( m_aSpawnPoints[i] == pSpawnpoint ) |
|
{ |
|
m_aSpawnPoints.Remove( i ); |
|
return; |
|
} |
|
} |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: Spawn the player at one of this team's spawnpoints. Return true if successful. |
|
//----------------------------------------------------------------------------- |
|
CBaseEntity *CTeam::SpawnPlayer( CBasePlayer *pPlayer ) |
|
{ |
|
if ( m_aSpawnPoints.Count() == 0 ) |
|
return NULL; |
|
|
|
// Randomize the start spot |
|
int iSpawn = m_iLastSpawn + random->RandomInt( 1,3 ); |
|
if ( iSpawn >= m_aSpawnPoints.Count() ) |
|
iSpawn -= m_aSpawnPoints.Count(); |
|
int iStartingSpawn = iSpawn; |
|
|
|
// Now loop through the spawnpoints and pick one |
|
int loopCount = 0; |
|
do |
|
{ |
|
if ( iSpawn >= m_aSpawnPoints.Count() ) |
|
{ |
|
++loopCount; |
|
iSpawn = 0; |
|
} |
|
|
|
// check if pSpot is valid, and that the player is on the right team |
|
if ( (loopCount > 3) || m_aSpawnPoints[iSpawn]->IsValid( pPlayer ) ) |
|
{ |
|
// DevMsg( 1, "player: spawning at (%s)\n", STRING(m_aSpawnPoints[iSpawn]->m_iName) ); |
|
m_aSpawnPoints[iSpawn]->m_OnPlayerSpawn.FireOutput( pPlayer, m_aSpawnPoints[iSpawn] ); |
|
|
|
m_iLastSpawn = iSpawn; |
|
return m_aSpawnPoints[iSpawn]; |
|
} |
|
|
|
iSpawn++; |
|
} while ( iSpawn != iStartingSpawn ); // loop if we're not back to the start |
|
|
|
return NULL; |
|
} |
|
|
|
//------------------------------------------------------------------------------------------------------------------ |
|
// PLAYERS |
|
//----------------------------------------------------------------------------- |
|
// Purpose: |
|
//----------------------------------------------------------------------------- |
|
void CTeam::InitializePlayers( void ) |
|
{ |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: Add the specified player to this team. Remove them from their current team, if any. |
|
//----------------------------------------------------------------------------- |
|
void CTeam::AddPlayer( CBasePlayer *pPlayer ) |
|
{ |
|
m_aPlayers.AddToTail( pPlayer ); |
|
NetworkStateChanged(); |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: Remove this player from the team |
|
//----------------------------------------------------------------------------- |
|
void CTeam::RemovePlayer( CBasePlayer *pPlayer ) |
|
{ |
|
m_aPlayers.FindAndRemove( pPlayer ); |
|
NetworkStateChanged(); |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: Return the number of players in this team. |
|
//----------------------------------------------------------------------------- |
|
int CTeam::GetNumPlayers( void ) |
|
{ |
|
return m_aPlayers.Count(); |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: Get a specific player |
|
//----------------------------------------------------------------------------- |
|
CBasePlayer *CTeam::GetPlayer( int iIndex ) |
|
{ |
|
Assert( iIndex >= 0 && iIndex < m_aPlayers.Count() ); |
|
return m_aPlayers[ iIndex ]; |
|
} |
|
|
|
//------------------------------------------------------------------------------------------------------------------ |
|
// SCORING |
|
//----------------------------------------------------------------------------- |
|
// Purpose: Add / Remove score for this team |
|
//----------------------------------------------------------------------------- |
|
void CTeam::AddScore( int iScore ) |
|
{ |
|
m_iScore += iScore; |
|
} |
|
|
|
void CTeam::SetScore( int iScore ) |
|
{ |
|
m_iScore = iScore; |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: Get this team's score |
|
//----------------------------------------------------------------------------- |
|
int CTeam::GetScore( void ) |
|
{ |
|
return m_iScore; |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: |
|
//----------------------------------------------------------------------------- |
|
void CTeam::ResetScores( void ) |
|
{ |
|
SetScore(0); |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: |
|
//----------------------------------------------------------------------------- |
|
void CTeam::AwardAchievement( int iAchievement ) |
|
{ |
|
Assert( iAchievement >= 0 && iAchievement < 255 ); // must fit in short |
|
|
|
CRecipientFilter filter; |
|
|
|
int iNumPlayers = GetNumPlayers(); |
|
|
|
for ( int i=0;i<iNumPlayers;i++ ) |
|
{ |
|
if ( GetPlayer(i) ) |
|
{ |
|
filter.AddRecipient( GetPlayer(i) ); |
|
} |
|
} |
|
|
|
UserMessageBegin( filter, "AchievementEvent" ); |
|
WRITE_SHORT( iAchievement ); |
|
MessageEnd(); |
|
}
|
|
|