Wavelength Logo
tl.jpg (2351 bytes) blank.gif (837 bytes) tr.jpg (2446 bytes)
blank.gif (837 bytes)
Counterstrike Gameplay, Part 1 by Gooseman
and Pink
blank.gif (837 bytes)
Ok, first of all, this tutorial is 90% Gooseman and 10% me (Pink), he just sent me the bit of code that reset the rounds, I'm gonna comment his code, and explain what each part does. So.. Here we go!.

First of all, Open multiplay_gamerules.cpp, and go to the CHalfLifeMultiplay :: Think() function, just click on Think on the wizard.
Lets see what he did...

void CHalfLifeMultiplay :: Think ( void )
{
 ///// Check game rules /////
 
 if ( g_fGameOver )   // someone else quit the game already
 {
  if ( m_flIntermissionEndTime < gpGlobals->time )
  {
   if ( m_iEndIntermissionButtonHit  // check that someone has pressed a key, or the max intermission time is over
    || ((m_flIntermissionEndTime + MAX_INTERMISSION_TIME) < gpGlobals->time) ) 
    ChangeLevel(); // intermission is over
  }
  return;
 }

 float flTimeLimit = timelimit.value * 60;
 float flFragLimit = fraglimit.value;
 
 if ( flTimeLimit != 0 && gpGlobals->time >= flTimeLimit )
 {
  GoToIntermission();
  return;
 }
 /*Gooseman's Stuff*/
 
 /*
 I belive this bit is when the time is over, and the teams are tied
 thats why he sets m_iCTWin = 3, m_iCTWin is the variable that handles wich team
 won the round, it goes like this:

 m_iCTWin = 1; // The Counter-Terrorists Won
 m_iCTWin = 2; // The Terrorist Won
 m_iCTWin = 3; // The teams tied.
 */

 if (gpGlobals->time > m_flRoundTime + 385.0 ) // here he checks if the 6 minutes limit for the round are over.
 { 
  m_iCTWin = 3; // Teams are Tied
  m_flRestartRoundTime = gpGlobals->time + 5.0; // Next round starts in 5 seconds
  m_flRoundTime = gpGlobals->time + 60; // 1 more minute (Suddent Dead?)
 }

 if ( (m_flRestartRoundTime != 0.0) && (m_flRestartRoundTime <= gpGlobals->time) ) // Time is Up!
  RestartRound(); // Restart Round!
 
 /*End of Gooseman's Stuff*/
}

Ok, that was easy, now lets go to the RestartRound function, where all the exciting stuff happens.
 
First off all, you got to add the RestartRound function to the CHalfLifeMultiplay class definition, so, open up teamplay_gamerules.h, and add it to the Class definition around line 60. also you got to add all the new variables, so lets take a look:

Right now to get a Time Based round system we need:

float m_flRestartRoundTime; // Variable to store the time when the next round is going to start
virtual void RestartRound ( void ); // Function for restarting the round
float m_flRoundTime; // Variable to store how long the round is going to last

void CHalfLifeMultiplay :: RestartRound( void ) 
{
 // Clear the kicktable
 for (int i = 0; i <= 19; i++)
 m_iKickTable [i] = 0;

 /*
 Ok, I'm going to comment out this part, this is all the hostage checking, respawning and money award
 code, I'm still going to explain what it does, but right now we just want to restart the round
 when the time is over

 // Update accounts based on number of hostages remaining.. SUB_Remove these hostage entities.
 CBaseEntity* hostage = NULL; 
 CHostage* temp;

 hostage = (CBaseMonster*) UTIL_FindEntityByClassname(NULL, "hostage_entity"); // Here we search for the "hostage_entity" entity, that would be the hostage dudes.
 while (hostage != NULL)   
 {
  if (hostage->pev->solid != SOLID_NOT) // If they're alive (?), we check what team won, so we can
            // reward them.
  {
   if (m_iCTWin == 2) // terrorists won // Terrorist won
    m_iAccountTerrorist += 400; // give 400$ for each hostage alive
   else if (m_iCTWin == 1) // CT Won 
    m_iAccountCT += 400; //  It is Pay Day (sorry, playing too much Dungeon Keeper 2 =)

   if (hostage->pev->deadflag == DEAD_DEAD) // If the hostage is dead
    hostage->pev->deadflag = DEAD_RESPAWNABLE; // Make it respawnable
  }
  temp = (CHostage*) hostage;
  temp->RePosition(); // Respawn the Hostage
  hostage = (CBaseMonster*) UTIL_FindEntityByClassname(hostage, "hostage_entity");
 }

 // Give the losing team a charity bonus.. that way, they can get back in the game..
 if (m_iCTWin == 2) // Terrorist Won
  m_iAccountCT += 800; // Give the CT some money
 else if (m_iCTWin == 1) // CT Won
  m_iAccountTerrorist += 800; // Give the bad guys some money.

 //Update CT account based on number of hostages rescued
 m_iAccountCT += m_iHostagesRescued * 350; // m_iHostageRescued, is a variable that updates each time a hostage 
        // is rescued, so we know how many we saved.
 */

 // Update individual players accounts and respawn players
 CBaseEntity* pPlayer = NULL;
 CBasePlayer* player;

 pPlayer = UTIL_FindEntityByClassname ( pPlayer, "player" ); // We find the player
 while (  (pPlayer != NULL) && (!FNullEnt(pPlayer->edict())) )
 {
  if ( pPlayer->IsPlayer() && pPlayer->pev->flags != FL_DORMANT )
  {
   player = GetClassPtr((CBasePlayer *)pPlayer->pev);

   if ( (m_iNumCT != 0) && (m_iNumTerrorist != 0) ) // m_iNumCT and m_iNumTerrorist are the variables
          // were he stores the number of players on each team
   {
    if ( player->m_iTeam == CT ) // m_iTeam is the name of the team
     player->AddAccount( m_iAccountCT ); // We update his checkbook
    else if ( player->m_iTeam == TERRORIST )
     player->AddAccount( m_iAccountTerrorist );
   }

   // Respawn players
   if ( player->pev->deadflag == ( (DEAD_DYING) || (DEAD_DEAD) || (DEAD_RESPAWNABLE) ) ) // here he checks
                   every possible dead flag
   {
    respawn ( pPlayer->pev, FALSE ); // Respawn!, FALSE means that we're not leaving a corpse behind
    pPlayer->pev->button = 0;
    player->m_iRespawnFrames = 0;
    pPlayer->pev->nextthink = -1;
   }
   else
   {
    player->m_iRespawnFrames = 0;
    respawn ( pPlayer->pev, FALSE ); // Respawn!, FALSE means that we're not leaving a corpse behind
   }

   EMIT_SOUND(ENT(player->pev), CHAN_VOICE, "radio/go.wav", 1, ATTN_NORM); // Ok lets go...
  }
  pPlayer = UTIL_FindEntityByClassname ( pPlayer, "player" ); // and we find the player
 }
 
 

 // Reset game variables

 m_flIntermissionEndTime = 0;
 m_flRestartRoundTime = 0.0;  // the round is not going to restart anytime soon
 m_iAccountTerrorist = m_iAccountCT = 0; // No money on the floor to pick up until the end of the round
 m_iHostagesRescued = 0; // They're all at the Terrorist's base
 m_iHostagesTouched = 0; // Hmm.. now this is just sick =P.
 m_iCTWin = 0; // Nobody has won the round yet.
 m_flRoundTime = gpGlobals->time; // Timer starts!   
}

Now, for the next tutorial we are going to make the rounds end when all the players on 1 team are dead. Right now you'll probably, don't want players respawing as soon as they're dead, so open player.cpp and go to the StartDeadCam function and comment out the respawn call. Thats it!. Any comment you got about this tutorial, mail me!, don't mail Gooseman, hes working hard on Counter-Strike, so any problem you have, mail me.

 

blank.gif (837 bytes)
bl.jpg (2471 bytes) blank.gif (837 bytes) br.jpg (2132 bytes)