home *** CD-ROM | disk | FTP | other *** search
/ GameStar 2006 March / Gamestar_82_2006-03_dvd.iso / DVDStar / Editace / quake4_sdkv10.exe / source / game / Instance.cpp < prev    next >
C/C++ Source or Header  |  2005-11-14  |  5KB  |  181 lines

  1. //----------------------------------------------------------------
  2. // Instance.cpp
  3. //
  4. // Copyright 2002-2005 Raven Software
  5. //----------------------------------------------------------------
  6.  
  7. #include "../idlib/precompiled.h"
  8. #pragma hdrstop
  9.  
  10. #include "Instance.h"
  11.  
  12. rvInstance::rvInstance( int id, bool deferPopulate ) {
  13.     instanceID = id;
  14.     spawnInstanceID = id;
  15.  
  16.     gameLocal.AddClipWorld( id );
  17.  
  18.     mapEntityNumbers = NULL;
  19.     numMapEntities = 0;
  20.  
  21.     initialSpawnCount = idGameLocal::INITIAL_SPAWN_COUNT;
  22.  
  23.     if( !deferPopulate ) {
  24.         Populate();
  25.     }
  26. }
  27.  
  28. rvInstance::~rvInstance() {
  29.     delete[] mapEntityNumbers;
  30.     gameLocal.RemoveClipWorld( instanceID );
  31. }
  32.  
  33. void rvInstance::Populate( void ) {
  34.     gameState_t currentState = gameLocal.GameState();
  35.     
  36.     if( currentState != GAMESTATE_STARTUP ) {
  37.         gameLocal.SetGameState( GAMESTATE_RESTART );
  38.     }
  39.  
  40.     if( gameLocal.isServer ) {
  41.         // When populating on a server, record the entity numbers    
  42.         numMapEntities = gameLocal.GetNumMapEntities();
  43.  
  44.         // mwhitlock: Dynamic memory consolidation
  45.         RV_PUSH_SYS_HEAP_ID(RV_HEAP_ID_LEVEL);
  46.         mapEntityNumbers = new unsigned short[ numMapEntities ];
  47.         RV_POP_HEAP();
  48.  
  49.         memset( mapEntityNumbers, -1, sizeof( unsigned short ) * numMapEntities );
  50.  
  51.         // Spawn the map entities for this instance and capture their entity numbers
  52.  
  53.         // remember the spawnCount ahead of time, so that the client can accurately reconstruct its spawnIds
  54.         gameLocal.SpawnMapEntities( spawnInstanceID, NULL, mapEntityNumbers, &initialSpawnCount );
  55.  
  56.         // only build the message in MP
  57.         if( gameLocal.isMultiplayer ) {
  58.             BuildInstanceMessage();
  59.  
  60.             // force joins of anyone in our instance so they get potentially new map entitynumbers
  61.             for( int i = 0; i < MAX_CLIENTS; i++ ) {
  62.                 PACIFIER_UPDATE;
  63.                 idPlayer* player = (idPlayer*)gameLocal.entities[ i ];
  64.                 if( player && player->GetInstance() == instanceID ) {
  65.                     networkSystem->ServerSendReliableMessage( player->entityNumber, mapEntityMsg );
  66.                 }
  67.             }
  68.         }
  69.     } else {
  70.         // When populating on a client, spawn the map using existing numbers
  71.         
  72.         // check for good state
  73.         // OK to spawn w/o specific entity numbers if we're in the startup process.  Otherwise, 
  74.         // we need entity numbers from the server.
  75.         assert( mapEntityNumbers || ( instanceID == 0 && gameLocal.GameState() == GAMESTATE_STARTUP ) );
  76.         
  77.         gameLocal.SetSpawnCount( initialSpawnCount );
  78.         gameLocal.SpawnMapEntities( spawnInstanceID, mapEntityNumbers, NULL );
  79.     }
  80.  
  81.  
  82.     for( int i = 0; i < numMapEntities; i++ ) {
  83.         if( mapEntityNumbers[ i ] < 0 || mapEntityNumbers[ i ] >= MAX_GENTITIES ) {
  84.             continue;
  85.         }
  86.  
  87.         if ( (i % 100) == 0 ) {
  88.             PACIFIER_UPDATE;
  89.         }
  90.  
  91.         idEntity* ent = gameLocal.entities[ mapEntityNumbers[ i ] ];
  92.  
  93.         if( ent ) {
  94.             ent->PostEventMS( &EV_FindTargets, 0 );
  95.             ent->PostEventMS( &EV_PostSpawn, 0 );
  96.         }
  97.     }
  98.  
  99.     if( currentState != GAMESTATE_STARTUP ) {
  100.         gameLocal.SetGameState( currentState );
  101.     }
  102. }
  103.  
  104. void rvInstance::PopulateFromMessage( const idBitMsg& msg ) {
  105.     numMapEntities = msg.ReadShort();
  106.     initialSpawnCount = msg.ReadShort();
  107.  
  108.     delete[] mapEntityNumbers;
  109.  
  110. // RAVEN BEGIN
  111. // mwhitlock: Dynamic memory consolidation
  112.     RV_PUSH_SYS_HEAP_ID(RV_HEAP_ID_LEVEL);
  113.     mapEntityNumbers = new unsigned short[ numMapEntities ];
  114.     RV_POP_HEAP();
  115. // RAVEN END
  116.     memset( mapEntityNumbers, -1, sizeof( unsigned short ) * numMapEntities );
  117.  
  118.     for( int i = 0; i < numMapEntities; i++ ) {
  119.         mapEntityNumbers[ i ] = msg.ReadShort();
  120.     }
  121.  
  122.     Populate();
  123. }
  124.  
  125. void rvInstance::Restart( void ) {
  126.     if( gameLocal.isMultiplayer ) {
  127.         Populate();
  128.     } else {
  129.         gameLocal.SpawnMapEntities();
  130.     }
  131. }
  132.  
  133. void rvInstance::BuildInstanceMessage( void ) {
  134.     // Build the client join instance msg
  135.     mapEntityMsg.BeginWriting();
  136.     mapEntityMsg.Init( mapEntityMsgBuf, sizeof( byte ) * MAX_GAME_MESSAGE_SIZE );
  137.     mapEntityMsg.WriteByte( GAME_RELIABLE_MESSAGE_SET_INSTANCE );
  138.  
  139.     mapEntityMsg.WriteByte( instanceID );
  140.     mapEntityMsg.WriteShort( numMapEntities );
  141.     mapEntityMsg.WriteShort( initialSpawnCount );
  142.  
  143.     for( int i = 0; i < numMapEntities; i++ ) {
  144.         mapEntityMsg.WriteShort( mapEntityNumbers[ i ] );
  145.     }
  146. }
  147.  
  148. void rvInstance::JoinInstance( idPlayer* player ) {
  149.     assert( player && gameLocal.isServer );
  150.  
  151.     // Transmit the instance information to the new client
  152.     if( gameLocal.isListenServer && player == gameLocal.GetLocalPlayer() ) {
  153.         gameLocal.mpGame.ServerSetInstance( instanceID );
  154.     } else {
  155.         networkSystem->ServerSendReliableMessage( player->entityNumber, mapEntityMsg );
  156.     }
  157. }
  158.  
  159. void rvInstance::PrintMapNumbers( void ) {
  160.     gameLocal.Printf( "Instance: %d\n", instanceID );
  161.     gameLocal.Printf( "Num Map Entities: %d\n", numMapEntities );
  162.  
  163.     for( int i = 0; i < numMapEntities; i++ ) {
  164.         gameLocal.Printf( "%d\n", mapEntityNumbers[ i ] );
  165.     }
  166. }
  167.  
  168. /*
  169. ================
  170. rvInstance::SetSpawnInstanceID
  171. Sets the spawn instance ID for this instance.  On the client, only instance 0 is ever 
  172. used, but it spawns in map entities for other instances.  spawnInstanceID is used to
  173. spawn map entities with the correct instance number on the client.
  174. ================
  175. */
  176. void rvInstance::SetSpawnInstanceID( int newInstance ) {
  177.     assert( gameLocal.isClient );
  178.  
  179.     spawnInstanceID = newInstance;
  180. }
  181.