VadaVaka

Full Version: 2v2
You're currently viewing a stripped down version of our content. View the full version with proper formatting.
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
arena 2v2 pls thx
hey man..thats cool

lets me think about clanwars again.....2on2 clanwars at least
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;
}
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
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
WoW thats great, nice job Miagi.

:)

Regards,

Ilu
i want to give this a shot.
I will come back for this...

Guest

1 question. Will your disk hit the player on your team?
Nope. I'll have to try to fix/reformat my linux box to get a bug free version for grits sometime.
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...