VadaVaka
2v2 - Printable Version

+- VadaVaka (https://vadavaka.com/forums)
+-- Forum: General Forums (https://vadavaka.com/forums/forumdisplay.php?fid=5)
+--- Forum: IT-Geeks Hang Out (https://vadavaka.com/forums/forumdisplay.php?fid=42)
+---- Forum: Programming (https://vadavaka.com/forums/forumdisplay.php?fid=27)
+---- Thread: 2v2 (/showthread.php?tid=3997)



2v2 - Pique - 06-05-2005

not sure if this is ricochet or programming but whatever

2v2 NOW WORKS!!!!!
There are still some obvious bugs as the scoreboard messes up a lot. The Teams dont get changed up until they lose. And the titles.txt needs some serious work. Also the map isn't great either, now i need to fix it up.

BUT TEAMPLAY IS NOW FUNCTIONABLE!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
MUHAHAHHAHAHAHHAHHAHHAHHA

Miagi is a godsend.

heres a screen for all you non-believers

haha what great news for my 300th post


2v2 - _Acid_Head_ - 06-05-2005

arena 2v2 pls thx


2v2 - Gragoon - 06-05-2005

hey man..thats cool

lets me think about clanwars again.....2on2 clanwars at least


2v2 - Miagi - 06-05-2005

Fixed the scoreboard. This is how in StartRound, I have it setup so that each round it resends the scoreboard instead of just sending wth a new match.

Fixed white disc by commenting out 'pPlayer->pev->team = 0;' located in movetospectator. That line removes people from their team ie. red or blue. They become white.

So when I commented that line out, the people who are waiting in spectate now keep their colors until assigned a new opponent. Looks better anyway:D

Here's the entire disc_arena.cpp

Code:
//=========== (C) Copyright 1999 Valve, L.L.C. All rights reserved. ===========
//
// The copyright to the contents herein is the property of Valve, L.L.C.
// The contents may be used and/or copied only with the written permission of
// Valve, L.L.C., or in accordance with the terms and conditions stipulated in
// the agreement/contract under which the contents have been supplied.
//
// Purpose: Handles the arena portion of discwar
//
// $Workfile:     $
// $Date:         $
//
//-----------------------------------------------------------------------------
// $Log: $
//
// $NoKeywords: $
//=============================================================================

#include "extdll.h"
#include "util.h"
#include "cbase.h"
#include "player.h"
#include "gamerules.h"
#include "weapons.h"
#include "discwar.h"
#include "disc_arena.h"
#include "disc_objects.h"

int g_iNextArenaGroupInfo = 0;

void ClientUserInfoChanged( edict_t *pEntity, char *infobuffer );
edict_t *EntSelectSpawnPoint( CBaseEntity *pPlayer );
void respawn(entvars_t* pev, BOOL fCopyCorpse);
extern int gmsgStartRnd;
extern int gmsgEndRnd;
extern int gmsgTeamInfo;
extern int g_iPlayersPerTeam;
extern int g_iMapTurnedOffArena;

CDiscArena *g_pArenaList[ MAX_ARENAS ];

char *g_szCountDownVox[6] =
{
    "die",
    "one",
    "two",
    "three",
    "four",
};

char *g_szTeamNames[3] =
{
    "",
    "red",
    "blue",
};

int InArenaMode()
{
    if ( g_iMapTurnedOffArena )
 return FALSE;

    if ( gpGlobals->maxClients == 1 || (CVAR_GET_FLOAT("rc_arena") == 0) )
 return FALSE;

    return TRUE;
}

LINK_ENTITY_TO_CLASS( disc_arena, CDiscArena );

// NOTE:
// We store queue position in pev->playerclass, so it's automatically pushed
// down to the client. The scoreboard uses pev->playerclass to display the
// positions of the players in the queue.
void CDiscArena::Spawn( void )
{
&nbsp;&nbsp;&nbsp;&nbsp;pev->groupinfo = 1 << (g_iNextArenaGroupInfo++);
&nbsp;&nbsp;&nbsp;&nbsp;Reset();

&nbsp;&nbsp;&nbsp;&nbsp;// Initialize
&nbsp;&nbsp;&nbsp;&nbsp;m_iMaxRounds = CVAR_GET_FLOAT("rc_rounds");
&nbsp;&nbsp;&nbsp;&nbsp;m_iPlayersPerTeam = g_iPlayersPerTeam;
&nbsp;&nbsp;&nbsp;&nbsp;SetThink( NULL );
}

void CDiscArena::Reset( void )
{
&nbsp;&nbsp;&nbsp;&nbsp;// Remove all clients in the queue
&nbsp;&nbsp;&nbsp;&nbsp;for ( int i = 1; i <= gpGlobals->maxClients; i++ )
&nbsp;&nbsp;&nbsp;&nbsp;{
 CBasePlayer *pPlayer = (CBasePlayer *)UTIL_PlayerByIndex( i );

 if (pPlayer &amp;&amp; (pPlayer->m_pCurrentArena == this) &amp;&amp; pPlayer->m_bHasDisconnected != TRUE )
 {
 &nbsp;&nbsp;&nbsp;&nbsp;RemoveClient( pPlayer );

 &nbsp;&nbsp;&nbsp;&nbsp;// Move her into spectator mode
 &nbsp;&nbsp;&nbsp;&nbsp;//MoveToSpectator( pPlayer );
 }
&nbsp;&nbsp;&nbsp;&nbsp;}

&nbsp;&nbsp;&nbsp;&nbsp;m_pPlayerQueue = NULL;
&nbsp;&nbsp;&nbsp;&nbsp;m_iPlayers = 0;
&nbsp;&nbsp;&nbsp;&nbsp;m_flTimeLimitOver = 0;
&nbsp;&nbsp;&nbsp;&nbsp;m_bShownTimeWarning = FALSE;
&nbsp;&nbsp;&nbsp;&nbsp;m_iArenaState = ARENA_WAITING_FOR_PLAYERS;
&nbsp;&nbsp;&nbsp;&nbsp;memset( m_hCombatants, 0, sizeof( m_hCombatants ) );

&nbsp;&nbsp;&nbsp;&nbsp;SetThink( NULL );
&nbsp;&nbsp;&nbsp;&nbsp;pev->nextthink = 0;
}

//-----------------------------------------------------------------------------
// Purpose: Start a battle. Spawn all the players, and begin the countdown.
//-----------------------------------------------------------------------------
void CDiscArena::StartBattle( void )
{
&nbsp;&nbsp;&nbsp;&nbsp;m_iCurrRound = 0;
&nbsp;&nbsp;&nbsp;&nbsp;m_iTeamOneScore = m_iTeamTwoScore = 0;

&nbsp;&nbsp;&nbsp;&nbsp;// First, set all players in this arena to "didn't play"
&nbsp;&nbsp;&nbsp;&nbsp;for ( int i = 1; i <= gpGlobals->maxClients; i++ )
&nbsp;&nbsp;&nbsp;&nbsp;{
 CBasePlayer *pPlayer = (CBasePlayer *)UTIL_PlayerByIndex( i );

 if (pPlayer &amp;&amp; (pPlayer->m_pCurrentArena == this) &amp;&amp; pPlayer->m_bHasDisconnected != TRUE )
 &nbsp;&nbsp;&nbsp;&nbsp;pPlayer->m_iLastGameResult = GAME_DIDNTPLAY;
&nbsp;&nbsp;&nbsp;&nbsp;}

&nbsp;&nbsp;&nbsp;&nbsp;// Get the players in the battle
&nbsp;&nbsp;&nbsp;&nbsp;for ( i = 0; i < (m_iPlayersPerTeam * 2); i++ )
&nbsp;&nbsp;&nbsp;&nbsp;{
 CBasePlayer *pCurr;

 // Check to see if this slot's already full
 if ( m_hCombatants[ i ] )
 {
 &nbsp;&nbsp;&nbsp;&nbsp;pCurr = (CBasePlayer*)(CBaseEntity*)m_hCombatants[ i ];
 }
 else
 {
 &nbsp;&nbsp;&nbsp;&nbsp;// Pop a new player from the queue
 &nbsp;&nbsp;&nbsp;&nbsp;pCurr = GetNextPlayer();
 &nbsp;&nbsp;&nbsp;&nbsp;if (!pCurr)
 &nbsp;&nbsp;&nbsp;&nbsp;{
   // Couldnt get enough players. Reset.
   Reset();
   return;
 &nbsp;&nbsp;&nbsp;&nbsp;}
 }

 // Set her team number
 if ( i < m_iPlayersPerTeam )
 &nbsp;&nbsp;&nbsp;&nbsp;pCurr->pev->team = 1;
 else
 &nbsp;&nbsp;&nbsp;&nbsp;pCurr->pev->team = 2;
 pCurr->pev->iuser4 = pCurr->pev->team;

 char sz[128];
 sprintf(sz, "Arena %d", pev->groupinfo );
 MESSAGE_BEGIN( MSG_ALL, gmsgTeamInfo );
 &nbsp;&nbsp;&nbsp;&nbsp;WRITE_BYTE( pCurr->entindex() );
 &nbsp;&nbsp;&nbsp;&nbsp;WRITE_STRING( sz );
 MESSAGE_END();

 // Add her to the list of combatants
 m_hCombatants[ i ] = pCurr;
 
 // Force her to update her clientinfo, so her colors match her team
 ClientUserInfoChanged( pCurr->edict(), g_engfuncs.pfnGetInfoKeyBuffer( pCurr->edict() ) );
&nbsp;&nbsp;&nbsp;&nbsp;}

&nbsp;&nbsp;&nbsp;&nbsp;// Start the first round
&nbsp;&nbsp;&nbsp;&nbsp;StartRound();
}

//-----------------------------------------------------------------------------
// Purpose: Start the next round in the match
//-----------------------------------------------------------------------------
void CDiscArena::StartRound( void )
{
&nbsp;&nbsp;&nbsp;&nbsp;m_iCurrRound++;
&nbsp;&nbsp;&nbsp;&nbsp;m_iSecondsTillStart = ARENA_TIME_PREBATTLE;
&nbsp;&nbsp;&nbsp;&nbsp;m_flTimeLimitOver = gpGlobals->time + ARENA_TIME_ROUNDLIMIT;

&nbsp;&nbsp;&nbsp;&nbsp;RestoreWorldObjects();

//miagi for 2v2

&nbsp;&nbsp;&nbsp;&nbsp;// Get the players in the battle
&nbsp;&nbsp;&nbsp;&nbsp;for ( int t = 0; t < (m_iPlayersPerTeam * 2); t++ )
&nbsp;&nbsp;&nbsp;&nbsp;{
 CBasePlayer *pCurr;

 // Check to see if this slot's already full
 if ( m_hCombatants[ t ] )
 {
 &nbsp;&nbsp;&nbsp;&nbsp;pCurr = (CBasePlayer*)(CBaseEntity*)m_hCombatants[ t ];
 }
 

 // Set scoreboard
 
 char sz[128];
 sprintf(sz, "Arena %d", pev->groupinfo );
 MESSAGE_BEGIN( MSG_ALL, gmsgTeamInfo );
 &nbsp;&nbsp;&nbsp;&nbsp;WRITE_BYTE( pCurr->entindex() );
 &nbsp;&nbsp;&nbsp;&nbsp;WRITE_STRING( sz );
 MESSAGE_END();

 // Add her to the list of combatants
 //m_hCombatants[ t ] = pCurr;
 
 // Force her to update her clientinfo, so her colors match her team
 //ClientUserInfoChanged( pCurr->edict(), g_engfuncs.pfnGetInfoKeyBuffer( pCurr->edict() ) );
&nbsp;&nbsp;&nbsp;&nbsp;}


//end miagi


&nbsp;&nbsp;&nbsp;&nbsp;// Tell the clients
&nbsp;&nbsp;&nbsp;&nbsp;for ( int iPlayerNum = 1; iPlayerNum <= gpGlobals->maxClients; iPlayerNum++ )
&nbsp;&nbsp;&nbsp;&nbsp;{
 CBasePlayer *pPlayer = (CBasePlayer *)UTIL_PlayerByIndex( iPlayerNum );

 if (pPlayer &amp;&amp; (pPlayer->pev->groupinfo &amp; pev->groupinfo) &amp;&amp; (pPlayer->m_bHasDisconnected != TRUE) )
 {
 &nbsp;&nbsp;&nbsp;&nbsp;MESSAGE_BEGIN( MSG_ONE, gmsgStartRnd, NULL, pPlayer->edict() );
   WRITE_BYTE( m_iCurrRound );
   WRITE_BYTE( m_iSecondsTillStart );
   WRITE_BYTE( (m_iPlayersPerTeam * 2) );

   // Send down all the players in the round
   for ( int j = 0; j < (m_iPlayersPerTeam * 2); j++ )
   {
   &nbsp;&nbsp;&nbsp;&nbsp;if (m_hCombatants[j])
     WRITE_SHORT( ((CBaseEntity*)m_hCombatants[j])->entindex() );
   }

 &nbsp;&nbsp;&nbsp;&nbsp;MESSAGE_END();

 &nbsp;&nbsp;&nbsp;&nbsp;
 }
&nbsp;&nbsp;&nbsp;&nbsp;}

&nbsp;&nbsp;&nbsp;&nbsp;// Spawn all the players in the round
&nbsp;&nbsp;&nbsp;&nbsp;for ( int i = 0; i < (m_iPlayersPerTeam * 2); i++ )
&nbsp;&nbsp;&nbsp;&nbsp;{
 CBasePlayer *pPlayer = ((CBasePlayer*)(CBaseEntity*)m_hCombatants[i]);

 if ( pPlayer )
 {
 &nbsp;&nbsp;&nbsp;&nbsp;// make sure the player's groupinfo is set the arena's groupinfo
 &nbsp;&nbsp;&nbsp;&nbsp;pPlayer->pev->groupinfo = pev->groupinfo;

 &nbsp;&nbsp;&nbsp;&nbsp;// is the player an observer?
 &nbsp;&nbsp;&nbsp;&nbsp;if ( pPlayer->IsObserver() )
 &nbsp;&nbsp;&nbsp;&nbsp;{
   SpawnCombatant( pPlayer );
 &nbsp;&nbsp;&nbsp;&nbsp;}

 &nbsp;&nbsp;&nbsp;&nbsp;// Remove any powerups
 &nbsp;&nbsp;&nbsp;&nbsp;pPlayer->RemoveAllPowerups();
 }
&nbsp;&nbsp;&nbsp;&nbsp;}

&nbsp;&nbsp;&nbsp;&nbsp;// Start counting down
&nbsp;&nbsp;&nbsp;&nbsp;m_iArenaState = ARENA_COUNTDOWN;
&nbsp;&nbsp;&nbsp;&nbsp;pev->nextthink = gpGlobals->time + 0.1;
&nbsp;&nbsp;&nbsp;&nbsp;SetThink( CountDownThink );
}

//-----------------------------------------------------------------------------
// Purpose: Make sure all the Combatants in the game a valid. Return FALSE if not.
//-----------------------------------------------------------------------------
int CDiscArena::ValidateCombatants( void )
{
&nbsp;&nbsp;&nbsp;&nbsp;for ( int i = 0; i < (m_iPlayersPerTeam * 2); i++ )
&nbsp;&nbsp;&nbsp;&nbsp;{
 CBasePlayer *pPlayer = ((CBasePlayer*)(CBaseEntity*)m_hCombatants[i]);

 if ( !pPlayer )
 &nbsp;&nbsp;&nbsp;&nbsp;return FALSE;
 if ( pPlayer->m_bHasDisconnected )
 &nbsp;&nbsp;&nbsp;&nbsp;return FALSE;
&nbsp;&nbsp;&nbsp;&nbsp;}
&nbsp;&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;return TRUE;
}

//-----------------------------------------------------------------------------
// Purpose: Restore all the world objects
//-----------------------------------------------------------------------------
void CDiscArena::RestoreWorldObjects( void )
{
&nbsp;&nbsp;&nbsp;&nbsp;CBaseEntity *pFunc = NULL;
&nbsp;&nbsp;&nbsp;&nbsp;while ((pFunc = UTIL_FindEntityByClassname( pFunc, "func_plat_toggleremove" )) != NULL)
&nbsp;&nbsp;&nbsp;&nbsp;{
 ((CPlatToggleRemove*)pFunc)->Reset();
&nbsp;&nbsp;&nbsp;&nbsp;}
&nbsp;&nbsp;&nbsp;&nbsp;while ((pFunc = UTIL_FindEntityByClassname( pFunc, "func_disctoggle" )) != NULL)
&nbsp;&nbsp;&nbsp;&nbsp;{
 ((CDiscTarget*)pFunc)->Reset();
&nbsp;&nbsp;&nbsp;&nbsp;}

&nbsp;&nbsp;&nbsp;&nbsp;// Disable powerups
&nbsp;&nbsp;&nbsp;&nbsp;while ((pFunc = UTIL_FindEntityByClassname( pFunc, "item_powerup" )) != NULL)
&nbsp;&nbsp;&nbsp;&nbsp;{
 ((CDiscwarPowerup*)pFunc)->Disable();
&nbsp;&nbsp;&nbsp;&nbsp;}
}

void CDiscArena::BattleThink( void )
{
&nbsp;&nbsp;&nbsp;&nbsp;if ( gpGlobals->time >= m_flTimeLimitOver - 1.0 )
&nbsp;&nbsp;&nbsp;&nbsp;{
 pev->nextthink = gpGlobals->time + 1.0;
 SetThink( TimeOver );
 return;
&nbsp;&nbsp;&nbsp;&nbsp;}

&nbsp;&nbsp;&nbsp;&nbsp;if ( !CheckBattleOver() )
&nbsp;&nbsp;&nbsp;&nbsp;{
 pev->nextthink = gpGlobals->time + 1.0;
&nbsp;&nbsp;&nbsp;&nbsp;}
}

//-----------------------------------------------------------------------------
// Purpose: Countdown to the round start
//-----------------------------------------------------------------------------
void CDiscArena::CountDownThink( void )
{
&nbsp;&nbsp;&nbsp;&nbsp;// Freeze everyone until there's 3 seconds to go
&nbsp;&nbsp;&nbsp;&nbsp;if ( m_iSecondsTillStart == 3 )
&nbsp;&nbsp;&nbsp;&nbsp;{
 for ( int i = 0; i < (m_iPlayersPerTeam * 2); i++ )
 {
 &nbsp;&nbsp;&nbsp;&nbsp;//.asm - white disc haxxx...
 &nbsp;&nbsp;&nbsp;&nbsp;// if the player is "dead" during countdown and they are not NULL
     

 &nbsp;&nbsp;&nbsp;&nbsp;CBasePlayer *pPlayer = ((CBasePlayer*)(CBaseEntity*)m_hCombatants[i]);

 &nbsp;&nbsp;&nbsp;&nbsp;if( m_hCombatants[i] != NULL &amp;&amp; !m_hCombatants[i]->IsAlive() )
           
 &nbsp;&nbsp;&nbsp;&nbsp;{
   //SpawnCombatant( pPlayer );
   pPlayer->Spawn();
   //Miagi Stop floaters
   pPlayer->StopObserver();
     

   //UTIL_ClientPrintAll( HUD_PRINTNOTIFY, "Spawned" );
 &nbsp;&nbsp;&nbsp;&nbsp;}
 &nbsp;&nbsp;&nbsp;&nbsp;// end hax

 &nbsp;&nbsp;&nbsp;&nbsp;if (m_hCombatants[i])
   ((CBaseEntity*)m_hCombatants[i])->pev->maxspeed = 320;
 }
&nbsp;&nbsp;&nbsp;&nbsp;}

&nbsp;&nbsp;&nbsp;&nbsp;m_iSecondsTillStart--;

&nbsp;&nbsp;&nbsp;&nbsp;// Play countdown VOX
&nbsp;&nbsp;&nbsp;&nbsp;if (m_iSecondsTillStart < 5)
&nbsp;&nbsp;&nbsp;&nbsp;{
 // Speech
 for ( int i = 0; i < (m_iPlayersPerTeam * 2); i++ )
 {
 &nbsp;&nbsp;&nbsp;&nbsp;if (m_hCombatants[i])
   ((CBasePlayer*)(CBaseEntity*)m_hCombatants[i])->ClientHearVox( g_szCountDownVox[ m_iSecondsTillStart ] );
 }
&nbsp;&nbsp;&nbsp;&nbsp;}

&nbsp;&nbsp;&nbsp;&nbsp;// Send the message to the clients in the arena
&nbsp;&nbsp;&nbsp;&nbsp;for ( int i = 1; i <= gpGlobals->maxClients; i++ )
&nbsp;&nbsp;&nbsp;&nbsp;{
 CBasePlayer *pPlayer = (CBasePlayer *)UTIL_PlayerByIndex( i );

 if (pPlayer &amp;&amp; (pPlayer->pev->groupinfo &amp; pev->groupinfo) &amp;&amp; pPlayer->m_bHasDisconnected != TRUE)
 {
 &nbsp;&nbsp;&nbsp;&nbsp;MESSAGE_BEGIN( MSG_ONE, gmsgStartRnd, NULL, pPlayer->edict() );
   WRITE_BYTE( m_iCurrRound );
   WRITE_BYTE( m_iSecondsTillStart );
   WRITE_BYTE( 0 );
 &nbsp;&nbsp;&nbsp;&nbsp;MESSAGE_END();
 }
&nbsp;&nbsp;&nbsp;&nbsp;}

&nbsp;&nbsp;&nbsp;&nbsp;if (m_iSecondsTillStart)
&nbsp;&nbsp;&nbsp;&nbsp;{
 pev->nextthink = gpGlobals->time + 1.0;
&nbsp;&nbsp;&nbsp;&nbsp;}
&nbsp;&nbsp;&nbsp;&nbsp;else
&nbsp;&nbsp;&nbsp;&nbsp;{
 m_iArenaState = ARENA_BATTLE_IN_PROGRESS;

 // Enable powerups
 CBaseEntity *pFunc = NULL;
 while ((pFunc = UTIL_FindEntityByClassname( pFunc, "item_powerup" )) != NULL)
 {
 &nbsp;&nbsp;&nbsp;&nbsp;((CDiscwarPowerup*)pFunc)->Enable();
 }

 pev->nextthink = gpGlobals->time + 1.0;
 SetThink( BattleThink );
&nbsp;&nbsp;&nbsp;&nbsp;}
}

//-----------------------------------------------------------------------------
// Purpose: A player in the battle has died. See if we need to restart the battle.
//-----------------------------------------------------------------------------
void CDiscArena::PlayerKilled( CBasePlayer *pPlayer )
{
&nbsp;&nbsp;&nbsp;&nbsp;// Check to see if the battle's over in 5 seconds
&nbsp;&nbsp;&nbsp;&nbsp;if ( m_iArenaState == ARENA_BATTLE_IN_PROGRESS || m_iArenaState == ARENA_COUNTDOWN )
&nbsp;&nbsp;&nbsp;&nbsp;{
 if ( !CheckBattleOver() )
 {
   //Play with this to see if white disc glitch can be fixed - desNotes
 &nbsp;&nbsp;&nbsp;&nbsp;pev->nextthink = gpGlobals->time + 0.5;
 &nbsp;&nbsp;&nbsp;&nbsp;SetThink( CheckOverThink );
 }
&nbsp;&nbsp;&nbsp;&nbsp;}
}

//-----------------------------------------------------------------------------
// Purpose: A player in the battle has respawned. Move them to observer mode.
//-----------------------------------------------------------------------------
void CDiscArena::PlayerRespawned( CBasePlayer *pPlayer )
{
&nbsp;&nbsp;&nbsp;&nbsp;if ( m_iArenaState == ARENA_BATTLE_IN_PROGRESS )
&nbsp;&nbsp;&nbsp;&nbsp;{
 // Move the player into Spectator mode
 MoveToSpectator( pPlayer );
&nbsp;&nbsp;&nbsp;&nbsp;}
&nbsp;&nbsp;&nbsp;&nbsp;else if ( m_iArenaState == ARENA_SHOWING_SCORES &amp;&amp; ( m_iTeamOneScore >= m_iMaxRounds || m_iTeamTwoScore >= m_iMaxRounds ) )
&nbsp;&nbsp;&nbsp;&nbsp;{
 // Battle is over. If there's only 2 players in the game, just respawn.
 // Otherwise, move to spectator.
 int iNumPlayers = 0;
 for ( int i = 1; i <= gpGlobals->maxClients; i++ )
 {
 &nbsp;&nbsp;&nbsp;&nbsp;CBasePlayer *pPlayer = (CBasePlayer *)UTIL_PlayerByIndex( i );
 &nbsp;&nbsp;&nbsp;&nbsp;if (pPlayer &amp;&amp; pPlayer->m_bHasDisconnected != TRUE)
   iNumPlayers++;
 }

 // Move the player into Spectator mode if there are more players
 if ( iNumPlayers > 2 )
 &nbsp;&nbsp;&nbsp;&nbsp;MoveToSpectator( pPlayer );
&nbsp;&nbsp;&nbsp;&nbsp;}
}

//-----------------------------------------------------------------------------
// Purpose: Move the player to a spectating position
//-----------------------------------------------------------------------------
void CDiscArena::MoveToSpectator( CBasePlayer *pPlayer )
{
&nbsp;&nbsp;&nbsp;&nbsp;// Find the spectator spawn position
&nbsp;&nbsp;&nbsp;&nbsp;CBaseEntity *pSpot = UTIL_FindEntityByClassname( NULL, "info_player_spectator");
&nbsp;&nbsp;&nbsp;&nbsp;if ( pSpot )
&nbsp;&nbsp;&nbsp;&nbsp;{
 pPlayer->StartObserver( pSpot->pev->origin, pSpot->pev->angles);
&nbsp;&nbsp;&nbsp;&nbsp;}
&nbsp;&nbsp;&nbsp;&nbsp;else
&nbsp;&nbsp;&nbsp;&nbsp;{
 // Find any spawn point
 edict_t *pentSpawnSpot = EntSelectSpawnPoint( pPlayer );
 pPlayer->StartObserver( VARS(pentSpawnSpot)->origin, VARS(pentSpawnSpot)->angles);
&nbsp;&nbsp;&nbsp;&nbsp;}
&nbsp;&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;//Miagi Causes white disc! This sets the team zero for people spectating
&nbsp;&nbsp;&nbsp;&nbsp;//pPlayer->pev->team = 0;

&nbsp;&nbsp;&nbsp;&nbsp;//pPlayer->Observer_SetMode( OBS_LOCKEDVIEW );
}

//-----------------------------------------------------------------------------
// Purpose: Battle is over.
//-----------------------------------------------------------------------------
void CDiscArena::BattleOver( void )
{
&nbsp;&nbsp;&nbsp;&nbsp;pev->nextthink = gpGlobals->time + 3;
&nbsp;&nbsp;&nbsp;&nbsp;SetThink( FinishedThink );

&nbsp;&nbsp;&nbsp;&nbsp;m_iSecondsTillStart = ARENA_TIME_VIEWSCORES;
&nbsp;&nbsp;&nbsp;&nbsp;m_iArenaState = ARENA_SHOWING_SCORES;

&nbsp;&nbsp;&nbsp;&nbsp;RestoreWorldObjects();
}

//-----------------------------------------------------------------------------
// Purpose: Round timelimit has been hit
//-----------------------------------------------------------------------------
void CDiscArena::TimeOver( void )
{
&nbsp;&nbsp;&nbsp;&nbsp;// Display the 10 second warning first
&nbsp;&nbsp;&nbsp;&nbsp;if ( !m_bShownTimeWarning )
&nbsp;&nbsp;&nbsp;&nbsp;{
 m_bShownTimeWarning = TRUE;

 for ( int i = 1; i <= gpGlobals->maxClients; i++ )
 {
 &nbsp;&nbsp;&nbsp;&nbsp;CBasePlayer *pPlayer = (CBasePlayer *)UTIL_PlayerByIndex( i );

 &nbsp;&nbsp;&nbsp;&nbsp;if (pPlayer &amp;&amp; (pPlayer->pev->groupinfo &amp; pev->groupinfo) &amp;&amp; pPlayer->m_bHasDisconnected != TRUE)
   ClientPrint( pPlayer->pev, HUD_PRINTCENTER, "#Time_Warning" );
 }

 pev->nextthink = gpGlobals->time + 10;
&nbsp;&nbsp;&nbsp;&nbsp;}
&nbsp;&nbsp;&nbsp;&nbsp;else
&nbsp;&nbsp;&nbsp;&nbsp;{
 for ( int i = 1; i <= gpGlobals->maxClients; i++ )
 {
 &nbsp;&nbsp;&nbsp;&nbsp;CBasePlayer *pPlayer = (CBasePlayer *)UTIL_PlayerByIndex( i );

 &nbsp;&nbsp;&nbsp;&nbsp;if (pPlayer &amp;&amp; (pPlayer->pev->groupinfo &amp; pev->groupinfo) &amp;&amp; (pPlayer->m_bHasDisconnected != TRUE) )
   ClientPrint( pPlayer->pev, HUD_PRINTCENTER, "#Time_Over" );
 }

 // Increment both scores to force the game to end
 m_iTeamOneScore++;
 m_iTeamTwoScore++;

 BattleOver();
&nbsp;&nbsp;&nbsp;&nbsp;}
}

bool CDiscArena::CheckBattleOver( void )
{
&nbsp;&nbsp;&nbsp;&nbsp;bool bTeamOneAlive = false;
&nbsp;&nbsp;&nbsp;&nbsp;bool bTeamTwoAlive = false;

&nbsp;&nbsp;&nbsp;&nbsp;// See if the battle is finished
&nbsp;&nbsp;&nbsp;&nbsp;for ( int i = 0; i < (m_iPlayersPerTeam * 2); i++ )
&nbsp;&nbsp;&nbsp;&nbsp;{
 if ( m_hCombatants[i] != NULL &amp;&amp; ((CBasePlayer*)(CBaseEntity*)m_hCombatants[i])->IsAlive() )
 {
 &nbsp;&nbsp;&nbsp;&nbsp;if ( ((CBaseEntity*)m_hCombatants[i])->pev->team == 1 )
   bTeamOneAlive = true;
 &nbsp;&nbsp;&nbsp;&nbsp;else if ( ((CBaseEntity*)m_hCombatants[i])->pev->team == 2 )
   bTeamTwoAlive = true;
 }
&nbsp;&nbsp;&nbsp;&nbsp;}

&nbsp;&nbsp;&nbsp;&nbsp;if ( !bTeamOneAlive || !bTeamTwoAlive )
&nbsp;&nbsp;&nbsp;&nbsp;{
 // Battle is finished.
 if (bTeamOneAlive)
 {
 &nbsp;&nbsp;&nbsp;&nbsp;m_iWinningTeam = 1;
 &nbsp;&nbsp;&nbsp;&nbsp;m_iTeamOneScore++;
 }
 else
 {
 &nbsp;&nbsp;&nbsp;&nbsp;m_iWinningTeam = 2;
 &nbsp;&nbsp;&nbsp;&nbsp;m_iTeamTwoScore++;
 }

 int iTeamInTheLead = 0;
 if ( m_iTeamOneScore > m_iTeamTwoScore )
 &nbsp;&nbsp;&nbsp;&nbsp;iTeamInTheLead = 1;
 else if ( m_iTeamOneScore < m_iTeamTwoScore )
 &nbsp;&nbsp;&nbsp;&nbsp;iTeamInTheLead = 2;

 // Send the message to the clients in the arena
 for ( int iPlayerNum = 1; iPlayerNum <= gpGlobals->maxClients; iPlayerNum++ )
 {
 &nbsp;&nbsp;&nbsp;&nbsp;CBasePlayer *pPlayer = (CBasePlayer*)UTIL_PlayerByIndex( iPlayerNum );

 &nbsp;&nbsp;&nbsp;&nbsp;if (pPlayer &amp;&amp; (pPlayer->pev->groupinfo &amp; pev->groupinfo) &amp;&amp; (pPlayer->m_bHasDisconnected != TRUE) )
 &nbsp;&nbsp;&nbsp;&nbsp;{
   MESSAGE_BEGIN( MSG_ONE, gmsgEndRnd, NULL, pPlayer->edict() );
   &nbsp;&nbsp;&nbsp;&nbsp;WRITE_BYTE( m_iCurrRound );
   &nbsp;&nbsp;&nbsp;&nbsp;WRITE_BYTE( 1 );
   &nbsp;&nbsp;&nbsp;&nbsp;WRITE_BYTE( m_iPlayersPerTeam );

   &nbsp;&nbsp;&nbsp;&nbsp;// Send down the winners of this round
   &nbsp;&nbsp;&nbsp;&nbsp;for (i = 0; i < (m_iPlayersPerTeam * 2); i++)
   &nbsp;&nbsp;&nbsp;&nbsp;{
     CBasePlayer *pPlayer = (CBasePlayer*)(CBaseEntity*)m_hCombatants[i];
     if ( !pPlayer || pPlayer->pev->team != m_iWinningTeam )
     &nbsp;&nbsp;&nbsp;&nbsp;continue;

     WRITE_SHORT( pPlayer->entindex() );
   &nbsp;&nbsp;&nbsp;&nbsp;}

   &nbsp;&nbsp;&nbsp;&nbsp;// Send down the team who's winning the battle now
   &nbsp;&nbsp;&nbsp;&nbsp;if ( iTeamInTheLead == 0 )
   &nbsp;&nbsp;&nbsp;&nbsp;{
     // It's a draw at the moment.
     // No need to send down player data.
     WRITE_BYTE( 0 );
   &nbsp;&nbsp;&nbsp;&nbsp;}
   &nbsp;&nbsp;&nbsp;&nbsp;else
   &nbsp;&nbsp;&nbsp;&nbsp;{
     WRITE_BYTE( m_iPlayersPerTeam );
     // Send down the winners of this round
     for (i = 0; i < (m_iPlayersPerTeam * 2); i++)
     {
     &nbsp;&nbsp;&nbsp;&nbsp;CBasePlayer *pPlayer = (CBasePlayer*)(CBaseEntity*)m_hCombatants[i];
     &nbsp;&nbsp;&nbsp;&nbsp;if ( !pPlayer || pPlayer->pev->team != iTeamInTheLead )
       continue;

     &nbsp;&nbsp;&nbsp;&nbsp;WRITE_SHORT( ((CBaseEntity*)m_hCombatants[i])->entindex() );
     }
   &nbsp;&nbsp;&nbsp;&nbsp;}

   &nbsp;&nbsp;&nbsp;&nbsp;// Send down the scores
   &nbsp;&nbsp;&nbsp;&nbsp;if ( iTeamInTheLead == 1 )
   &nbsp;&nbsp;&nbsp;&nbsp;{
     WRITE_BYTE( m_iTeamOneScore );
     WRITE_BYTE( m_iTeamTwoScore );
   &nbsp;&nbsp;&nbsp;&nbsp;}
   &nbsp;&nbsp;&nbsp;&nbsp;else
   &nbsp;&nbsp;&nbsp;&nbsp;{
     WRITE_BYTE( m_iTeamTwoScore );
     WRITE_BYTE( m_iTeamOneScore );
   &nbsp;&nbsp;&nbsp;&nbsp;}

   &nbsp;&nbsp;&nbsp;&nbsp;// Send down over or not
   &nbsp;&nbsp;&nbsp;&nbsp;if ( m_iTeamOneScore == m_iMaxRounds || m_iTeamTwoScore == m_iMaxRounds )
     WRITE_BYTE( 1 );
   &nbsp;&nbsp;&nbsp;&nbsp;else
     WRITE_BYTE( 0 );

   MESSAGE_END();
 &nbsp;&nbsp;&nbsp;&nbsp;}
 }

 BattleOver();
 return true;
&nbsp;&nbsp;&nbsp;&nbsp;}

&nbsp;&nbsp;&nbsp;&nbsp;return false;
}

//-----------------------------------------------------------------------------
// Purpose: Check to see if the Battle is over
//-----------------------------------------------------------------------------
void CDiscArena::CheckOverThink( void )
{
&nbsp;&nbsp;&nbsp;&nbsp;if ( !CheckBattleOver() )
&nbsp;&nbsp;&nbsp;&nbsp;{
 if ( m_iArenaState == ARENA_COUNTDOWN )
 {
 &nbsp;&nbsp;&nbsp;&nbsp;pev->nextthink = gpGlobals->time + 0.1;
 &nbsp;&nbsp;&nbsp;&nbsp;SetThink( CountDownThink );
 }
 else
 {
 &nbsp;&nbsp;&nbsp;&nbsp;pev->nextthink = gpGlobals->time + 0.1;
 &nbsp;&nbsp;&nbsp;&nbsp;SetThink( BattleThink );
 }
&nbsp;&nbsp;&nbsp;&nbsp;}
}

//-----------------------------------------------------------------------------
// Purpose: Show who won, and then restart the round
//-----------------------------------------------------------------------------
void CDiscArena::FinishedThink( void )
{
&nbsp;&nbsp;&nbsp;&nbsp;m_iSecondsTillStart--;

&nbsp;&nbsp;&nbsp;&nbsp;if (m_iSecondsTillStart)
&nbsp;&nbsp;&nbsp;&nbsp;{
 pev->nextthink = gpGlobals->time + 1.0;
&nbsp;&nbsp;&nbsp;&nbsp;}
&nbsp;&nbsp;&nbsp;&nbsp;else
&nbsp;&nbsp;&nbsp;&nbsp;{
 SetThink( NULL );

 // Tell the clients to remove the "Won" window
 for ( int i = 1; i <= gpGlobals->maxClients; i++ )
 {
 &nbsp;&nbsp;&nbsp;&nbsp;CBasePlayer *pPlayer = (CBasePlayer *)UTIL_PlayerByIndex( i );

 &nbsp;&nbsp;&nbsp;&nbsp;if (pPlayer &amp;&amp; (pPlayer->pev->groupinfo &amp; pev->groupinfo) &amp;&amp; pPlayer->m_bHasDisconnected != TRUE)
 &nbsp;&nbsp;&nbsp;&nbsp;{
   MESSAGE_BEGIN( MSG_ONE, gmsgEndRnd, NULL, pPlayer->edict() );
   &nbsp;&nbsp;&nbsp;&nbsp;WRITE_BYTE( m_iCurrRound );
   &nbsp;&nbsp;&nbsp;&nbsp;WRITE_BYTE( 0 );
   &nbsp;&nbsp;&nbsp;&nbsp;WRITE_BYTE( 0 );
   MESSAGE_END();
 &nbsp;&nbsp;&nbsp;&nbsp;}
 }

 // Round is over. See if the match is over too.
 if ( m_iTeamOneScore >= m_iMaxRounds || m_iTeamTwoScore >= m_iMaxRounds )
 {
 &nbsp;&nbsp;&nbsp;&nbsp;// Remove the losers from the combatants list
 &nbsp;&nbsp;&nbsp;&nbsp;for (int i = 0; i < (m_iPlayersPerTeam * 2); i++)
 &nbsp;&nbsp;&nbsp;&nbsp;{
   CBasePlayer *pPlayer = (CBasePlayer*)(CBaseEntity*)m_hCombatants[i];
   if (!pPlayer)
   &nbsp;&nbsp;&nbsp;&nbsp;continue;
   if ( pPlayer->pev->team == m_iWinningTeam )
   {
   &nbsp;&nbsp;&nbsp;&nbsp;pPlayer->m_iDeaths += 1;
   &nbsp;&nbsp;&nbsp;&nbsp;pPlayer->m_iLastGameResult = GAME_WON;
   &nbsp;&nbsp;&nbsp;&nbsp;continue;
   }

   pPlayer->m_iLastGameResult = GAME_LOST;
   m_hCombatants[i] = NULL;
 &nbsp;&nbsp;&nbsp;&nbsp;}

 &nbsp;&nbsp;&nbsp;&nbsp;// Then start the next Battle
 &nbsp;&nbsp;&nbsp;&nbsp;PostBattle();
 }
 else
 {
 &nbsp;&nbsp;&nbsp;&nbsp;// Start the next round
 &nbsp;&nbsp;&nbsp;&nbsp;StartRound();
 }
&nbsp;&nbsp;&nbsp;&nbsp;}
}

//-----------------------------------------------------------------------------
// Purpose: Spawn a player in this battle
//-----------------------------------------------------------------------------
void CDiscArena::SpawnCombatant( CBasePlayer *pPlayer )
{
&nbsp;&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;pPlayer->pev->groupinfo = pev->groupinfo;
&nbsp;&nbsp;&nbsp;&nbsp;// Spawn
&nbsp;&nbsp;&nbsp;&nbsp;g_pGameRules->GetPlayerSpawnSpot( pPlayer );

&nbsp;&nbsp;&nbsp;&nbsp;// Make sure she's out of spectator mode
&nbsp;&nbsp;&nbsp;&nbsp;pPlayer->StopObserver();

&nbsp;&nbsp;&nbsp;&nbsp;// Prevent movement for a couple of seconds
&nbsp;&nbsp;&nbsp;&nbsp;pPlayer->pev->maxspeed = 1;
}

//-----------------------------------------------------------------------------
// Purpose: Start a Battle
//-----------------------------------------------------------------------------
void CDiscArena::StartBattleThink( void )
{
&nbsp;&nbsp;&nbsp;&nbsp;StartBattle();
}

//-----------------------------------------------------------------------------
// Purpose: Prevent firing during prematch
//-----------------------------------------------------------------------------
bool CDiscArena::AllowedToFire( void )
{
&nbsp;&nbsp;&nbsp;&nbsp;return ( m_iArenaState == ARENA_BATTLE_IN_PROGRESS );
}

//-----------------------------------------------------------------------------
// Purpose: New client was added to the arena
//-----------------------------------------------------------------------------
void CDiscArena::AddClient( CBasePlayer *pPlayer, BOOL bCheckStart )
{
&nbsp;&nbsp;&nbsp;&nbsp;// Remove them from any arena they're currently in
&nbsp;&nbsp;&nbsp;&nbsp;if ( pPlayer->m_pCurrentArena != NULL )
 pPlayer->m_pCurrentArena->RemoveClient( pPlayer );

&nbsp;&nbsp;&nbsp;&nbsp;m_iPlayers++;

&nbsp;&nbsp;&nbsp;&nbsp;pPlayer->pev->groupinfo = pev->groupinfo;

&nbsp;&nbsp;&nbsp;&nbsp;// Add her to the queue
&nbsp;&nbsp;&nbsp;&nbsp;AddPlayerToQueue( pPlayer );
&nbsp;&nbsp;&nbsp;&nbsp;pPlayer->m_pCurrentArena = this;

&nbsp;&nbsp;&nbsp;&nbsp;// Only check a restart if the flag is set
&nbsp;&nbsp;&nbsp;&nbsp;if ( bCheckStart )
&nbsp;&nbsp;&nbsp;&nbsp;{
 // Start a game if there's none going, and we now have enough players
 // Allow starting of games if there aren't enough players, but there's more than 1 on the svr.
 //if ( (m_iPlayersPerTeam > 1) &amp;&amp; (m_iPlayers > 1) &amp;&amp; (m_iPlayers < (m_iPlayersPerTeam * 2)) )
 &nbsp;&nbsp;&nbsp;&nbsp;//m_iPlayersPerTeam = 1;
 // If we're in a battle, and the players-per-team isn't the map's setting, restart the battle
 if ( (m_iArenaState == ARENA_WAITING_FOR_PLAYERS) &amp;&amp; ( m_iPlayers >= (m_iPlayersPerTeam * 2) ) )
 {
 &nbsp;&nbsp;&nbsp;&nbsp;// Start a battle in a second to let the clients learn about this new player
 &nbsp;&nbsp;&nbsp;&nbsp;SetThink( StartBattleThink );
 &nbsp;&nbsp;&nbsp;&nbsp;pev->nextthink = gpGlobals->time + 1.0;
 }
 else
 {
 &nbsp;&nbsp;&nbsp;&nbsp;// Move her into spectator mode
 &nbsp;&nbsp;&nbsp;&nbsp;MoveToSpectator( pPlayer );
 }
&nbsp;&nbsp;&nbsp;&nbsp;}
}

//-----------------------------------------------------------------------------
// Purpose: Client was removed from the arena
//-----------------------------------------------------------------------------
void CDiscArena::RemoveClient( CBasePlayer *pPlayer )
{
&nbsp;&nbsp;&nbsp;&nbsp;m_iPlayers--;

&nbsp;&nbsp;&nbsp;&nbsp;pPlayer->pev->groupinfo = 0;
&nbsp;&nbsp;&nbsp;&nbsp;pPlayer->m_pCurrentArena = NULL;

&nbsp;&nbsp;&nbsp;&nbsp;// Is she in the current battle?
&nbsp;&nbsp;&nbsp;&nbsp;if ( pPlayer->pev->playerclass != 0 )
&nbsp;&nbsp;&nbsp;&nbsp;{
 // No, she's in the queue, so remove her.
 RemovePlayerFromQueue( pPlayer );
&nbsp;&nbsp;&nbsp;&nbsp;}
&nbsp;&nbsp;&nbsp;&nbsp;else if ( m_iArenaState != ARENA_WAITING_FOR_PLAYERS )
&nbsp;&nbsp;&nbsp;&nbsp;{
 // This team loses
 m_iWinningTeam = (pPlayer->pev->team == 1) ? 2 : 1;
 if ( m_iWinningTeam == 1 )
 &nbsp;&nbsp;&nbsp;&nbsp;m_iTeamOneScore = m_iMaxRounds - 1;  // -1 because we'll get 1 point for winning this round in CheckOverThink
 else
 &nbsp;&nbsp;&nbsp;&nbsp;m_iTeamTwoScore = m_iMaxRounds - 1;  // -1 because we'll get 1 point for winning this round in CheckOverThink

 // Find the player in the combatant list
 for ( int i = 0; i < (m_iPlayersPerTeam * 2); i++ )
 {
 &nbsp;&nbsp;&nbsp;&nbsp;// Check to see if this slot's already full
 &nbsp;&nbsp;&nbsp;&nbsp;if ( m_hCombatants[ i ] == pPlayer )
 &nbsp;&nbsp;&nbsp;&nbsp;{
   m_hCombatants[i] = NULL;
   break;
 &nbsp;&nbsp;&nbsp;&nbsp;}
 }

 CheckOverThink();
&nbsp;&nbsp;&nbsp;&nbsp;}
}

//-----------------------------------------------------------------------------
// Purpose: Add a player to the end of the queue
//-----------------------------------------------------------------------------
void CDiscArena::AddPlayerToQueue( CBasePlayer *pPlayer )
{
&nbsp;&nbsp;&nbsp;&nbsp;if ( !pPlayer )
 return;

&nbsp;&nbsp;&nbsp;&nbsp;if ( m_pPlayerQueue )
&nbsp;&nbsp;&nbsp;&nbsp;{
 CBasePlayer *pCurr = (CBasePlayer*)(CBaseEntity*)m_pPlayerQueue;
 while ( pCurr->m_pNextPlayer )
 {
 &nbsp;&nbsp;&nbsp;&nbsp;pCurr = (CBasePlayer*)(CBaseEntity*)pCurr->m_pNextPlayer;
 }

 pCurr->m_pNextPlayer = pPlayer;
 pPlayer->pev->playerclass = pCurr->pev->playerclass + 1;
&nbsp;&nbsp;&nbsp;&nbsp;}
&nbsp;&nbsp;&nbsp;&nbsp;else
&nbsp;&nbsp;&nbsp;&nbsp;{
 m_pPlayerQueue = pPlayer;
 pPlayer->pev->playerclass = 1;
&nbsp;&nbsp;&nbsp;&nbsp;}

&nbsp;&nbsp;&nbsp;&nbsp;pPlayer->m_pNextPlayer = NULL;
}

//-----------------------------------------------------------------------------
// Purpose: Remove a player from the queue
//-----------------------------------------------------------------------------
void CDiscArena::RemovePlayerFromQueue( CBasePlayer *pPlayer )
{
&nbsp;&nbsp;&nbsp;&nbsp;bool bFoundHer = false;

&nbsp;&nbsp;&nbsp;&nbsp;if ( !pPlayer )
 return;

&nbsp;&nbsp;&nbsp;&nbsp;CBasePlayer *pCurr = (CBasePlayer*)(CBaseEntity*)m_pPlayerQueue;
&nbsp;&nbsp;&nbsp;&nbsp;CBasePlayer *pPrev = NULL;
&nbsp;&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;while ( pCurr )
&nbsp;&nbsp;&nbsp;&nbsp;{
 if (pCurr == pPlayer )
 {
 &nbsp;&nbsp;&nbsp;&nbsp;bFoundHer = true;
 &nbsp;&nbsp;&nbsp;&nbsp;if (pPrev)
   pPrev->m_pNextPlayer = pCurr->m_pNextPlayer;
 &nbsp;&nbsp;&nbsp;&nbsp;else
   m_pPlayerQueue = pCurr->m_pNextPlayer;
 }
 else
 {
 &nbsp;&nbsp;&nbsp;&nbsp;pPrev = pCurr;

 &nbsp;&nbsp;&nbsp;&nbsp;// Adjust all the following player's queue positions
 &nbsp;&nbsp;&nbsp;&nbsp;if (bFoundHer)
   pCurr->pev->playerclass--;
 }

 pCurr = (CBasePlayer*)(CBaseEntity*)pCurr->m_pNextPlayer;
&nbsp;&nbsp;&nbsp;&nbsp;}

&nbsp;&nbsp;&nbsp;&nbsp;pPlayer->m_pNextPlayer = NULL;
&nbsp;&nbsp;&nbsp;&nbsp;pPlayer->pev->playerclass = 0;
}

//-----------------------------------------------------------------------------
// Purpose: Get the next player from the queue, and shuffle the rest up
//-----------------------------------------------------------------------------
CBasePlayer *CDiscArena::GetNextPlayer( void )
{
&nbsp;&nbsp;&nbsp;&nbsp;if ( m_pPlayerQueue == NULL )
 return NULL;

&nbsp;&nbsp;&nbsp;&nbsp;CBasePlayer *pCurr = (CBasePlayer*)(CBaseEntity*)m_pPlayerQueue;
&nbsp;&nbsp;&nbsp;&nbsp;RemovePlayerFromQueue( (CBasePlayer*)(CBaseEntity*)m_pPlayerQueue );

&nbsp;&nbsp;&nbsp;&nbsp;return pCurr;
}

//-----------------------------------------------------------------------------
// Returns TRUE if the Arena is full
int CDiscArena::IsFull( void )
{
&nbsp;&nbsp;&nbsp;&nbsp;if ( m_iPlayers < (m_iPlayersPerTeam * 2) )
 return FALSE;

&nbsp;&nbsp;&nbsp;&nbsp;return TRUE;
}

//-----------------------------------------------------------------------------
// Returns the first player in the Arena's queue, if any
CBasePlayer *CDiscArena::GetFirstSparePlayer( void )
{
&nbsp;&nbsp;&nbsp;&nbsp;if ( m_pPlayerQueue == NULL )
 return NULL;

&nbsp;&nbsp;&nbsp;&nbsp;return (CBasePlayer*)(CBaseEntity*)m_pPlayerQueue;
}

//-----------------------------------------------------------------------------
// Add a client to an Arena. Find the first arena that doesn't have two
// players in it, and add this player to that. If we find a third player
// Spectating another arena, grab them and add them to this player's arena.

//Modifying process to put new player in sepctate mode so reconnectors
//won't get to the front of the line - .asm 06/03/03
void AddClientToArena( CBasePlayer *pPlayer )
{
&nbsp;&nbsp;&nbsp;&nbsp;// First, find an arena for this player to be put into
&nbsp;&nbsp;&nbsp;&nbsp;for (int i = 0; i < MAX_ARENAS; i++)
&nbsp;&nbsp;&nbsp;&nbsp;{
 if ( g_pArenaList[i]->IsFull() == FALSE )
 {
 &nbsp;&nbsp;&nbsp;&nbsp;int iArenaNumber = i;

 &nbsp;&nbsp;&nbsp;&nbsp;g_pArenaList[iArenaNumber]->AddClient( pPlayer, TRUE );

 &nbsp;&nbsp;&nbsp;&nbsp;bool bFoundOne = TRUE;
 &nbsp;&nbsp;&nbsp;&nbsp;// Now, if this arena's not full, try to find more player to join her
 &nbsp;&nbsp;&nbsp;&nbsp;//Commented out - .asm 06/03/03
 /*&nbsp;&nbsp;&nbsp;&nbsp;while ( (g_pArenaList[iArenaNumber]->IsFull() == FALSE) &amp;&amp; bFoundOne )
 &nbsp;&nbsp;&nbsp;&nbsp;{
   bFoundOne = FALSE;

   // Cycle through all the arenas and find a spare player
   for (int j = 0; j < MAX_ARENAS; j++)
   {
   &nbsp;&nbsp;&nbsp;&nbsp;CBasePlayer *pSparePlayer = g_pArenaList[j]->GetFirstSparePlayer();
   &nbsp;&nbsp;&nbsp;&nbsp;if (pSparePlayer &amp;&amp; pSparePlayer != pPlayer)
   &nbsp;&nbsp;&nbsp;&nbsp;{
     g_pArenaList[j]->RemoveClient( pSparePlayer );
     g_pArenaList[iArenaNumber]->AddClient( pSparePlayer, TRUE );
     bFoundOne = TRUE;
     break;
   &nbsp;&nbsp;&nbsp;&nbsp;}
   }
 &nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;&nbsp;&nbsp;*/

 &nbsp;&nbsp;&nbsp;&nbsp;// If we couldn't find another player for this arena, just add them to an existing arena
 &nbsp;&nbsp;&nbsp;&nbsp;if ( g_pArenaList[iArenaNumber]->IsFull() == FALSE )
 &nbsp;&nbsp;&nbsp;&nbsp;{
   // Add to the first full arena
   for (int j = 0; j < MAX_ARENAS; j++)
   {
   &nbsp;&nbsp;&nbsp;&nbsp;if ( g_pArenaList[j]->IsFull() )
   &nbsp;&nbsp;&nbsp;&nbsp;{
     // Remove from current
     g_pArenaList[iArenaNumber]->RemoveClient( pPlayer );

     // Add to full one
     iArenaNumber = j;
     g_pArenaList[iArenaNumber]->AddClient( pPlayer, TRUE );
     break;
   &nbsp;&nbsp;&nbsp;&nbsp;}
   }
 &nbsp;&nbsp;&nbsp;&nbsp;}
 &nbsp;&nbsp;&nbsp;&nbsp;//Beginning of added code to prevent reconnectors - .asm 06/03/03
 &nbsp;&nbsp;&nbsp;&nbsp;else
 &nbsp;&nbsp;&nbsp;&nbsp;{
 bFoundOne = FALSE;

 // Cycle through all the arenas and find a spare player
 for (int j = 0; j < MAX_ARENAS; j++)
 {
 &nbsp;&nbsp;&nbsp;&nbsp;CBasePlayer *pSparePlayer = g_pArenaList[j]->GetFirstSparePlayer();
 &nbsp;&nbsp;&nbsp;&nbsp;if (pSparePlayer &amp;&amp; pSparePlayer != pPlayer)
 &nbsp;&nbsp;&nbsp;&nbsp;{
   g_pArenaList[j]->RemoveClient( pSparePlayer );
   g_pArenaList[iArenaNumber]->AddClient( pSparePlayer, TRUE );
   bFoundOne = TRUE;
   break;
 &nbsp;&nbsp;&nbsp;&nbsp;}
 }
&nbsp;&nbsp;&nbsp;&nbsp;}

 //End of added code to prevent reconnectors - .asm 06/03/03  


 &nbsp;&nbsp;&nbsp;&nbsp;//ALERT( at_console, "ADDED %s to Arena %d\n", STRING(pPlayer->pev->netname), iArenaNumber );
 &nbsp;&nbsp;&nbsp;&nbsp;return;
 }
&nbsp;&nbsp;&nbsp;&nbsp;}
}

//-----------------------------------------------------------------------------
// Put the specified group of players into the current arena
int AddPlayers( int iPlayers, int iArenaNum )
{
&nbsp;&nbsp;&nbsp;&nbsp;for ( int i = 1; i <= gpGlobals->maxClients; i++ )
&nbsp;&nbsp;&nbsp;&nbsp;{
 CBasePlayer *pPlayer = (CBasePlayer *)UTIL_PlayerByIndex( i );

 if (pPlayer &amp;&amp; (pPlayer->m_pCurrentArena == NULL) &amp;&amp; (pPlayer->m_bHasDisconnected != TRUE) )
 {
 &nbsp;&nbsp;&nbsp;&nbsp;if ( pPlayer->m_iLastGameResult != iPlayers )
   continue;

 &nbsp;&nbsp;&nbsp;&nbsp;g_pArenaList[iArenaNum]->AddClient( pPlayer, FALSE );
 &nbsp;&nbsp;&nbsp;&nbsp;if ( g_pArenaList[iArenaNum]->IsFull() )
   iArenaNum++;
 }
&nbsp;&nbsp;&nbsp;&nbsp;}

&nbsp;&nbsp;&nbsp;&nbsp;return iArenaNum;
}

//-----------------------------------------------------------------------------
// Take all the players not in battles and shuffle them into new groups
void ShufflePlayers( void )
{
&nbsp;&nbsp;&nbsp;&nbsp;int iArenaNum = 0;

&nbsp;&nbsp;&nbsp;&nbsp;// Reset all Arenas
&nbsp;&nbsp;&nbsp;&nbsp;for ( int i = 0; i < MAX_ARENAS; i++)
&nbsp;&nbsp;&nbsp;&nbsp;{
 g_pArenaList[i]->Reset();
&nbsp;&nbsp;&nbsp;&nbsp;}

&nbsp;&nbsp;&nbsp;&nbsp;// Play the winners off against the other winners first
&nbsp;&nbsp;&nbsp;&nbsp;iArenaNum = AddPlayers( GAME_WON, iArenaNum );
&nbsp;&nbsp;&nbsp;&nbsp;// First, add the players who didn't play at all
&nbsp;&nbsp;&nbsp;&nbsp;iArenaNum = AddPlayers( GAME_DIDNTPLAY, iArenaNum );
&nbsp;&nbsp;&nbsp;&nbsp;// Then add the losers
&nbsp;&nbsp;&nbsp;&nbsp;iArenaNum = AddPlayers( GAME_LOST, iArenaNum );

&nbsp;&nbsp;&nbsp;&nbsp;// Then tell all full arenas to start
&nbsp;&nbsp;&nbsp;&nbsp;for (i = 0; i < MAX_ARENAS; i++)
&nbsp;&nbsp;&nbsp;&nbsp;{
 if ( g_pArenaList[i]->IsFull() )
 {
 &nbsp;&nbsp;&nbsp;&nbsp;g_pArenaList[i]->StartBattle();
 }
 else
 {
 &nbsp;&nbsp;&nbsp;&nbsp;// If the arena has players in it, move them to the first full arena
 &nbsp;&nbsp;&nbsp;&nbsp;if ( g_pArenaList[i]->m_iPlayers != 0 )
 &nbsp;&nbsp;&nbsp;&nbsp;{
   for ( int j = 1; j <= gpGlobals->maxClients; j++ )
   {
   &nbsp;&nbsp;&nbsp;&nbsp;CBasePlayer *pPlayer = (CBasePlayer *)UTIL_PlayerByIndex( j );

   &nbsp;&nbsp;&nbsp;&nbsp;if (pPlayer &amp;&amp; (pPlayer->m_pCurrentArena == g_pArenaList[i]) &amp;&amp; (pPlayer->m_bHasDisconnected != TRUE) )
   &nbsp;&nbsp;&nbsp;&nbsp;{
     // Add to the first arena
     g_pArenaList[0]->AddClient( pPlayer, TRUE );

     pPlayer->m_iLastGameResult = GAME_DIDNTPLAY;
   &nbsp;&nbsp;&nbsp;&nbsp;}
   }
 &nbsp;&nbsp;&nbsp;&nbsp;}
 }
&nbsp;&nbsp;&nbsp;&nbsp;}

}

//-----------------------------------------------------------------------------
// The Battle is over. First, check to see if there are games going on in
// other arenas. If there are, these players go watch one of them for a bit.
// If all games finish in that time, shuffle all the players and start new
// games. Otherwise, shuffle all the players who aren't still playing, and
// start new games with them.
void CDiscArena::PostBattle( void )
{
&nbsp;&nbsp;&nbsp;&nbsp;int iOtherGame = -1;
&nbsp;&nbsp;&nbsp;&nbsp;// First, see if there are any other games going on in other arenas
&nbsp;&nbsp;&nbsp;&nbsp;for (int i = 0; i < MAX_ARENAS; i++)
&nbsp;&nbsp;&nbsp;&nbsp;{
 if ( g_pArenaList[i]->m_iArenaState != ARENA_WAITING_FOR_PLAYERS &amp;&amp; g_pArenaList[i] != this )
 {
 &nbsp;&nbsp;&nbsp;&nbsp;iOtherGame = i;
 &nbsp;&nbsp;&nbsp;&nbsp;break;
 }
&nbsp;&nbsp;&nbsp;&nbsp;}

&nbsp;&nbsp;&nbsp;&nbsp;// If there are no other games, just shuffle and start again
&nbsp;&nbsp;&nbsp;&nbsp;if ( iOtherGame == -1 )
&nbsp;&nbsp;&nbsp;&nbsp;{
 ShufflePlayers();
 return;
&nbsp;&nbsp;&nbsp;&nbsp;}

&nbsp;&nbsp;&nbsp;&nbsp;// There's another game going on. Move all the players from this arena to it to spectate.
&nbsp;&nbsp;&nbsp;&nbsp;for ( i = 1; i <= gpGlobals->maxClients; i++ )
&nbsp;&nbsp;&nbsp;&nbsp;{
 CBasePlayer *pPlayer = (CBasePlayer *)UTIL_PlayerByIndex( i );

 if (pPlayer &amp;&amp; (pPlayer->pev->groupinfo &amp; pev->groupinfo) &amp;&amp; (pPlayer->m_bHasDisconnected != TRUE) )
 {
 &nbsp;&nbsp;&nbsp;&nbsp;g_pArenaList[ iOtherGame ]->AddClient( (CBasePlayer*)pPlayer, TRUE );
 }
&nbsp;&nbsp;&nbsp;&nbsp;}

&nbsp;&nbsp;&nbsp;&nbsp;m_iArenaState = ARENA_WAITING_FOR_PLAYERS;
}



2v2 - Miagi - 06-05-2005

Oh and if anyone is interested in testing this for a awhile to see how it does with time here's the compiled mp.dll

I'll also be running this on my linux server.

The beta downloads can be found HERE


2v2 - Pique - 06-05-2005

arena now has a 2v2 option

http://pique.iown.org/ricoshit/rc_arena_tourny_2v2.rar

its the tourny map so there are no powerups


2v2 - Iluvatar - 06-08-2005

WoW thats great, nice job Miagi.

:)

Regards,

Ilu


2v2 - Reciprocity - 06-30-2005

i want to give this a shot.


2v2 - Knightmare - 07-05-2005

I will come back for this...


2v2 - Guest - 07-05-2005

1 question. Will your disk hit the player on your team?


2v2 - Miagi - 07-05-2005

Nope. I'll have to try to fix/reformat my linux box to get a bug free version for grits sometime.


2v2 - Pique - 07-05-2005

wouldn't that depend if FF is on? And im still wondering about teamplay now(i know its been awhile) that we can change models...