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.
356 lines
8.2 KiB
356 lines
8.2 KiB
//++ BulliT |
|
|
|
#include "extdll.h" |
|
#include "util.h" |
|
#include "cbase.h" |
|
#include "player.h" |
|
#include "weapons.h" |
|
#include "gamerules.h" |
|
|
|
#include "aggamerules.h" |
|
#include "agglobal.h" |
|
#include "agarena.h" |
|
|
|
////////////////////////////////////////////////////////////////////// |
|
// Construction/Destruction |
|
////////////////////////////////////////////////////////////////////// |
|
|
|
extern int gmsgCountdown; |
|
|
|
AgArena::AgArena() |
|
{ |
|
m_fMatchStart = 0.0; |
|
m_fNextCountdown = 0.0; |
|
m_fNextSay = 0.0; |
|
m_Player1 = NULL; |
|
m_Player2 = NULL; |
|
m_Status = Waiting; |
|
} |
|
|
|
AgArena::~AgArena() |
|
{ |
|
|
|
} |
|
|
|
|
|
void AgArena::Think() |
|
{ |
|
if (!g_pGameRules) |
|
return; |
|
|
|
if (Playing == m_Status) |
|
{ |
|
CBasePlayer* pPlayer1 = GetPlayer1(); |
|
CBasePlayer* pPlayer2 = GetPlayer2(); |
|
|
|
if( !pPlayer1 || ( pPlayer1 && !pPlayer1->IsAlive() ) || !pPlayer2 || ( pPlayer2 && !pPlayer2->IsAlive() ) ) |
|
{ |
|
m_Status = PlayerDied; |
|
m_fNextCountdown = gpGlobals->time + 3.0; //Let the effect of him dying play for 3 seconds |
|
|
|
if (pPlayer1) |
|
pPlayer1->SetIngame(false); //Cant respawn |
|
if (pPlayer2) |
|
pPlayer2->SetIngame(false); //Cant respawn |
|
} |
|
} |
|
else |
|
{ |
|
//We only update status once every second. |
|
if (m_fNextCountdown > gpGlobals->time) |
|
return; |
|
m_fNextCountdown = gpGlobals->time + 1.0; |
|
|
|
//Handle the status |
|
if (Waiting == m_Status) |
|
{ |
|
//Get new arena players. |
|
if (!GetPlayer1()) |
|
{ |
|
//Get one from top of list. |
|
if (0 != m_lstWaitList.size()) |
|
{ |
|
m_Player1 = AgPlayerByIndex(m_lstWaitList.front()); |
|
m_lstWaitList.pop_front(); |
|
} |
|
} |
|
|
|
if (!GetPlayer2()) |
|
{ |
|
//Get one from top of list. |
|
if (0 != m_lstWaitList.size()) |
|
{ |
|
m_Player2 = AgPlayerByIndex(m_lstWaitList.front()); |
|
m_lstWaitList.pop_front(); |
|
} |
|
} |
|
|
|
if (GetPlayer1() && GetPlayer2()) |
|
{ |
|
m_Status = Countdown; |
|
m_fMatchStart = gpGlobals->time + 5.0; |
|
m_fNextCountdown = gpGlobals->time + 2.0; |
|
} |
|
|
|
|
|
//Write waiting message |
|
#ifdef AG_NO_CLIENT_DLL |
|
if (0 != m_sWinner.size()) |
|
{ |
|
AgString s; |
|
s = "Last match won by " + m_sWinner; |
|
AgSay(NULL,s.c_str(),NULL,10,0.4,0.1,2); |
|
m_sWinner = ""; |
|
} |
|
AgSay(NULL,"Waiting for players to get ready!\n",&m_fNextSay,2,0.4,0.5); |
|
#else |
|
MESSAGE_BEGIN( MSG_ALL, gmsgCountdown); |
|
WRITE_BYTE( 50 ); |
|
WRITE_BYTE( 1 ); |
|
WRITE_STRING( m_sWinner.c_str() ); |
|
WRITE_STRING( "" ); |
|
MESSAGE_END(); |
|
#endif |
|
} |
|
else if (Countdown == m_Status) |
|
{ |
|
if (!GetPlayer1() || !GetPlayer2()) |
|
{ |
|
m_Status = Waiting; //Someone left in middle of countdown. Go back to waiting. |
|
return; |
|
} |
|
|
|
if (m_fMatchStart < gpGlobals->time) |
|
{ |
|
//Clear out the map |
|
AgResetMap(); |
|
|
|
GetPlayer1()->SetIngame(true); |
|
GetPlayer2()->SetIngame(true); |
|
g_pGameRules->m_ScoreCache.UpdateScore(GetPlayer1()); |
|
g_pGameRules->m_ScoreCache.UpdateScore(GetPlayer2()); |
|
|
|
m_Status = Spawning; |
|
m_sWinner = ""; |
|
|
|
//Time to start playing. |
|
if (GetPlayer1()->IsSpectator()) |
|
{ |
|
GetPlayer1()->Spectate_Stop(); |
|
} |
|
else |
|
GetPlayer1()->RespawnMatch(); |
|
|
|
if (GetPlayer2()->IsSpectator()) |
|
{ |
|
GetPlayer2()->Spectate_Stop(); |
|
} |
|
else |
|
GetPlayer2()->RespawnMatch(); |
|
|
|
m_Status = Playing; |
|
|
|
#ifndef AG_NO_CLIENT_DLL |
|
//Stop countdown |
|
MESSAGE_BEGIN( MSG_ALL, gmsgCountdown); |
|
WRITE_BYTE( -1 ); |
|
WRITE_BYTE( 0 ); |
|
WRITE_STRING( "" ); |
|
WRITE_STRING( "" ); |
|
MESSAGE_END(); |
|
#endif |
|
} |
|
else |
|
{ |
|
//Write countdown message. |
|
#ifdef AG_NO_CLIENT_DLL |
|
char szMatchStart[128]; |
|
sprintf(szMatchStart,"Match %s vs %s in %d seconds!\n",GetPlayer1()->GetName(),GetPlayer2()->GetName(),(int)(m_fMatchStart - gpGlobals->time)); |
|
AgSay(NULL,szMatchStart,&m_fNextSay,1,0.3,0.5); |
|
#else |
|
MESSAGE_BEGIN( MSG_ALL, gmsgCountdown); |
|
WRITE_BYTE( (int)(m_fMatchStart - gpGlobals->time) ); |
|
WRITE_BYTE( 1 ); |
|
WRITE_STRING( GetPlayer1()->GetName() ); |
|
WRITE_STRING( GetPlayer2()->GetName() ); |
|
MESSAGE_END(); |
|
#endif |
|
} |
|
} |
|
else if (PlayerDied == m_Status) |
|
{ |
|
CBasePlayer* pPlayer1 = GetPlayer1(); |
|
CBasePlayer* pPlayer2 = GetPlayer2(); |
|
|
|
m_Status = Waiting; |
|
m_sWinner = ""; |
|
|
|
if (pPlayer1 && !pPlayer1->IsAlive()) |
|
{ |
|
if(!pPlayer1->IsSpectator()) |
|
{ |
|
pPlayer1->Spectate_Start(false); |
|
pPlayer1->Spectate_Follow(m_Player2,OBS_IN_EYE); |
|
} |
|
m_lstWaitList.push_back(pPlayer1->entindex()); |
|
pPlayer1->SetIngame(false); |
|
m_Player1 = NULL; |
|
|
|
if (pPlayer2) |
|
{ |
|
pPlayer2->SetIngame(false); |
|
if (pPlayer2->IsAlive()) |
|
m_sWinner = pPlayer2->GetName(); |
|
} |
|
} |
|
|
|
if (pPlayer2 && !pPlayer2->IsAlive()) |
|
{ |
|
if(!pPlayer2->IsSpectator()) |
|
{ |
|
pPlayer2->Spectate_Start(false); |
|
pPlayer2->Spectate_Follow(m_Player1,OBS_IN_EYE); |
|
} |
|
m_lstWaitList.push_back(pPlayer2->entindex()); |
|
pPlayer2->SetIngame(false); |
|
m_Player2 = NULL; |
|
if (pPlayer1) |
|
{ |
|
pPlayer1->SetIngame(false); |
|
if (pPlayer1->IsAlive()) |
|
m_sWinner = pPlayer1->GetName(); |
|
} |
|
} |
|
|
|
//Stop sounds. |
|
for ( int i = 1; i <= gpGlobals->maxClients; i++ ) |
|
{ |
|
CBasePlayer* pPlayerLoop = AgPlayerByIndex(i); |
|
if (pPlayerLoop) |
|
{ |
|
CLIENT_COMMAND(pPlayerLoop->edict(),"stopsound\n"); |
|
} |
|
} |
|
} |
|
} |
|
} |
|
|
|
void AgArena::Add(CBasePlayer* pPlayer) |
|
{ |
|
if (GetPlayer1() == pPlayer || GetPlayer2() == pPlayer) |
|
return; |
|
|
|
if (0 == m_lstWaitList.size()) |
|
{ |
|
m_lstWaitList.push_back(pPlayer->entindex()); |
|
} |
|
else |
|
{ |
|
AgWaitList::iterator itrWaitlist = find(m_lstWaitList.begin(),m_lstWaitList.end(),pPlayer->entindex()); |
|
if (itrWaitlist == m_lstWaitList.end()) |
|
m_lstWaitList.push_back(pPlayer->entindex()); |
|
} |
|
} |
|
|
|
void AgArena::Remove(CBasePlayer* pPlayer) |
|
{ |
|
if (GetPlayer1() == pPlayer) |
|
{ |
|
m_Player1 = NULL; |
|
} |
|
else if (GetPlayer2() == pPlayer) |
|
{ |
|
m_Player2 = NULL; |
|
} |
|
else if (0 != m_lstWaitList.size()) |
|
{ |
|
AgWaitList::iterator itrWaitlist = find(m_lstWaitList.begin(),m_lstWaitList.end(),pPlayer->entindex()); |
|
if (itrWaitlist == m_lstWaitList.end()) |
|
m_lstWaitList.erase(itrWaitlist); |
|
//m_lstWaitList.remove(pPlayer->entindex()); |
|
} |
|
} |
|
|
|
void AgArena::Ready(CBasePlayer* pPlayer) |
|
{ |
|
ASSERT(NULL != pPlayer); |
|
if (!pPlayer) |
|
return; |
|
ASSERT(NULL != pPlayer->pev); |
|
if (!pPlayer->pev) |
|
return; |
|
|
|
if (Countdown != m_Status) |
|
{ |
|
Add(pPlayer); |
|
ClientPrint( pPlayer->pev, HUD_PRINTCONSOLE, "Changed mode to READY.\n"); |
|
} |
|
else |
|
{ |
|
ClientPrint( pPlayer->pev, HUD_PRINTCONSOLE, "Can not change ready state at this point.\n"); |
|
} |
|
} |
|
|
|
void AgArena::NotReady(CBasePlayer* pPlayer) |
|
{ |
|
ASSERT(NULL != pPlayer); |
|
if (!pPlayer) |
|
return; |
|
ASSERT(NULL != pPlayer->pev); |
|
if (!pPlayer->pev) |
|
return; |
|
|
|
if (Countdown != m_Status) |
|
{ |
|
pPlayer->SetIngame(false); |
|
if(!pPlayer->IsSpectator()) |
|
{ |
|
pPlayer->Spectate_Start(false); |
|
} |
|
Remove(pPlayer); |
|
ClientPrint( pPlayer->pev, HUD_PRINTCONSOLE, "Changed mode to NOT READY.\n"); |
|
} |
|
else |
|
{ |
|
ClientPrint( pPlayer->pev, HUD_PRINTCONSOLE, "Can not change ready state at this point.\n"); |
|
} |
|
} |
|
|
|
void AgArena::ClientConnected(CBasePlayer* pPlayer) |
|
{ |
|
ASSERT(NULL != pPlayer); |
|
if (!pPlayer) |
|
return; |
|
ASSERT(NULL != pPlayer->pev); |
|
if (!pPlayer->pev) |
|
return; |
|
|
|
//Set status |
|
pPlayer->SetIngame(false); |
|
|
|
if (!pPlayer->IsProxy()) |
|
Add(pPlayer); |
|
} |
|
|
|
|
|
void AgArena::ClientDisconnected(CBasePlayer* pPlayer) |
|
{ |
|
ASSERT(NULL != pPlayer); |
|
if (!pPlayer) |
|
return; |
|
ASSERT(NULL != pPlayer->pev); |
|
if (!pPlayer->pev) |
|
return; |
|
|
|
//Set status |
|
pPlayer->SetIngame(false); |
|
|
|
//Just blank if active in arena. |
|
//This will put the status into waiting mode within a second. |
|
if (!pPlayer->IsProxy()) |
|
Remove(pPlayer); |
|
} |
|
|
|
|
|
//-- Martin Webrant |
|
|
|
|