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

  1. //----------------------------------------------------------------
  2. // CTF.cpp
  3. //
  4. // Copyright 2002-2004 Raven Software
  5. //----------------------------------------------------------------
  6.  
  7. #include "../../idlib/precompiled.h"
  8. #pragma hdrstop
  9.  
  10. #include "CTF.h"
  11.  
  12. /*
  13. ===============================================================================
  14.  
  15. rvCTF_AssaultPoint
  16.  
  17. ===============================================================================
  18. */
  19. CLASS_DECLARATION( idEntity, rvCTF_AssaultPoint )
  20.     EVENT( EV_PostSpawn,    rvCTF_AssaultPoint::Event_InitializeLinks )
  21.     EVENT( EV_Touch,        rvCTF_AssaultPoint::Event_Touch )
  22. END_CLASS
  23.  
  24. rvCTF_AssaultPoint::rvCTF_AssaultPoint() {
  25.     trigger = NULL;
  26.     linked = false;
  27.     owner = AS_NEUTRAL;
  28. }
  29.  
  30. rvCTF_AssaultPoint::~rvCTF_AssaultPoint() {
  31.     delete trigger;
  32.     trigger = NULL;
  33. }
  34.  
  35. /*
  36. ================
  37. rvCTF_AssaultPoint::Spawn
  38. ================
  39. */
  40. void rvCTF_AssaultPoint::Spawn( void ) {
  41.     PostEventMS( &EV_PostSpawn, 0 );
  42. }
  43.  
  44. /*
  45. ================
  46. rvCTF_AssaultPoint::InitializeLinks
  47. ================
  48. */
  49. void rvCTF_AssaultPoint::Event_InitializeLinks( void ) {
  50.     if( linked ) {
  51.         return;
  52.     }
  53.     
  54.     // pull in our targets
  55.     toStrogg = gameLocal.FindEntity( spawnArgs.GetString( "targetStroggAP" ) );    
  56.     toMarine = gameLocal.FindEntity( spawnArgs.GetString( "targetMarineAP" ) );
  57.  
  58.     ResetIndices();
  59.  
  60.     trigger = new idClipModel( idTraceModel( idBounds( vec3_origin ).Expand( 16.0f ) ) );
  61. // RAVEN BEGIN
  62. // ddynerman: multiple clip worlds
  63.     trigger->Link( this, 0, GetPhysics()->GetOrigin(), GetPhysics()->GetAxis() );
  64. // RAVEN END
  65.     trigger->SetContents ( CONTENTS_TRIGGER );
  66.  
  67.     GetPhysics()->SetClipModel( NULL, 1.0f );
  68.  
  69.     linked = true;
  70. }
  71.  
  72. /*
  73. ================
  74. rvCTF_AssaultPoint::ResetIndices
  75. ================
  76. */
  77. void rvCTF_AssaultPoint::ResetIndices( void ) {
  78.     // find the closest AP to the marine flag, which is index 0, then work towards strogg flag
  79.     if ( !toMarine || !toMarine->IsType ( rvItemCTFFlag::GetClassType() ) ) {
  80.         return;
  81.     }
  82.  
  83.     idEntityPtr<rvCTF_AssaultPoint> ptr;
  84.     ptr = this;
  85.     gameLocal.mpGame.assaultPoints.Append( ptr );
  86.     int assignIndices = 0;
  87.     index = assignIndices++;
  88.     rvCTF_AssaultPoint* ap = this;
  89.     while( !ap->toStrogg->IsType ( rvItemCTFFlag::GetClassType() ) ) {
  90.         if( !ap->toStrogg->IsType ( rvCTF_AssaultPoint::GetClassType() ) ) {
  91.             gameLocal.Error( "rvCTF_AssaultPoint::ResetIndices() - non assault point targeted in assault point chain" );
  92.         }
  93.         ap = static_cast<rvCTF_AssaultPoint*>(ap->toStrogg.GetEntity());
  94.         ap->index = assignIndices++;
  95.         
  96.         ptr = ap;
  97.         gameLocal.mpGame.assaultPoints.Append( ptr );
  98.  
  99.         if ( !ap->linked ) {
  100.             ap->Event_InitializeLinks();
  101.         }
  102.  
  103.         if( !ap->toStrogg ) {
  104.             gameLocal.Error( "rvCTF_AssaultPoint::ResetIndices() - break in assault point chain" );
  105.         }
  106.     }
  107. }
  108.  
  109. /*
  110. ================
  111. rvCTF_AssaultPoint::Event_Activate
  112. ================
  113. */
  114. void rvCTF_AssaultPoint::Event_Touch( idEntity *activator, trace_t *trace ) {
  115.     if( !activator->IsType( idPlayer::GetClassType() ) || ((gameLocal.mpGame.GetGameState())->GetMPGameState() != GAMEON && !cvarSystem->GetCVarBool( "g_testCTF" )) ) {
  116.         return;
  117.     }
  118.  
  119.     idPlayer* player = static_cast<idPlayer*>(activator);
  120.     int oldOwner = owner;
  121.  
  122.     if ( owner == player->team )
  123.         return;
  124.  
  125.     int enemyPowerup = -1;
  126.     int friendlyPowerup = -1;
  127.     
  128.     if ( owner == TEAM_MARINE ) {
  129.         friendlyPowerup = POWERUP_CTF_STROGGFLAG;
  130.         enemyPowerup = POWERUP_CTF_MARINEFLAG;
  131.     } else if ( owner == TEAM_STROGG ) {
  132.         friendlyPowerup = POWERUP_CTF_MARINEFLAG;
  133.         enemyPowerup = POWERUP_CTF_STROGGFLAG;
  134.     } else {
  135.         // neutral assault point
  136.         if ( player->team == TEAM_MARINE ) {
  137.             friendlyPowerup = POWERUP_CTF_MARINEFLAG;
  138.             enemyPowerup = POWERUP_CTF_STROGGFLAG;
  139.         } else {
  140.             friendlyPowerup = POWERUP_CTF_STROGGFLAG;
  141.             enemyPowerup = POWERUP_CTF_MARINEFLAG;
  142.         }
  143.     }
  144.  
  145.     if ( !player->PowerUpActive ( enemyPowerup ) ) {
  146.         return;
  147.     }
  148.  
  149.  
  150.     switch( player->team ) {
  151.         case TEAM_MARINE: {
  152.             if( !toMarine || owner == TEAM_MARINE ) {
  153.                 break;
  154.             }
  155.  
  156.             if( toMarine->IsType( rvItemCTFFlag::GetClassType() ) ) {
  157.                 owner = TEAM_MARINE;
  158.                 gameLocal.Printf("Assault point %s captured by marines!\n", name.c_str());
  159.             } else if( toMarine->IsType( rvCTF_AssaultPoint::GetClassType() ) ) {
  160.                 if( static_cast<rvCTF_AssaultPoint*>(toMarine.GetEntity())->owner == TEAM_MARINE ) {
  161.                     owner = TEAM_MARINE;
  162.                     gameLocal.Printf("Assault point %s captured by marines!\n", name.c_str());
  163.                 }
  164.             }
  165.             break;
  166.         }
  167.         case TEAM_STROGG: {
  168.             if( !toStrogg || owner == TEAM_STROGG ) {
  169.                 break;
  170.             }
  171.  
  172.             if( toStrogg->IsType( rvItemCTFFlag::GetClassType() ) ) {
  173.                 owner = TEAM_STROGG;
  174.                 gameLocal.Printf("Assault point %s captured by strogg!\n", name.c_str());
  175.             } else if( toStrogg->IsType( rvCTF_AssaultPoint::GetClassType() ) ) {
  176.                 if( static_cast<rvCTF_AssaultPoint*>(toStrogg.GetEntity())->owner == TEAM_STROGG ) {
  177.                     owner = TEAM_STROGG;
  178.                     gameLocal.Printf("Assault point %s captured by strogg!\n", name.c_str());
  179.                 }
  180.             }            
  181.             break;
  182.         }
  183.     }
  184.     
  185.  
  186.     if( oldOwner != owner ) {
  187.         // we switched hands, reset forward spawns
  188.         gameLocal.ClearForwardSpawns();
  189.         
  190.         if( oldOwner == TEAM_MARINE ) {
  191.             if( static_cast<rvCTF_AssaultPoint*>(toMarine.GetEntity())->IsType( rvCTF_AssaultPoint::Type ) ) {
  192.                 static_cast<rvCTF_AssaultPoint*>(toMarine.GetEntity())->ResetSpawns( oldOwner );
  193.             }
  194.         } else if( oldOwner == TEAM_STROGG ) {
  195.             if( static_cast<rvCTF_AssaultPoint*>(toStrogg.GetEntity())->IsType( rvCTF_AssaultPoint::Type ) ) {
  196.                 static_cast<rvCTF_AssaultPoint*>(toStrogg.GetEntity())->ResetSpawns( oldOwner );
  197.             }
  198.         }
  199.         
  200.         rvItemCTFFlag::ResetFlag ( enemyPowerup );
  201.  
  202.         gameLocal.mpGame.AddPlayerTeamScore( player, 2 );
  203.  
  204.         ((rvCTFGameState*)gameLocal.mpGame.GetGameState())->SetAPOwner( index, owner );
  205.  
  206.         ActivateTargets( this );
  207.  
  208.         SetOwnerColor ();
  209.     }
  210. }
  211.  
  212. /*
  213. ================
  214. rvCTF_AssaultPoint::ResetSpawns
  215. ================
  216. */
  217. void rvCTF_AssaultPoint::ResetSpawns( int team ) {
  218.     // check to see if team can spawn at me, if not pass down
  219.     if( owner == team ) {
  220.         ActivateTargets( this );
  221.     } else {
  222.         if( team == TEAM_MARINE ) {
  223.             if( static_cast<rvCTF_AssaultPoint*>(toMarine.GetEntity())->IsType( rvCTF_AssaultPoint::Type ) ) {
  224.                 static_cast<rvCTF_AssaultPoint*>(toMarine.GetEntity())->ResetSpawns( team );
  225.             }
  226.         } else if( team == TEAM_STROGG ) {
  227.             if( static_cast<rvCTF_AssaultPoint*>(toStrogg.GetEntity())->IsType( rvCTF_AssaultPoint::Type ) ) {
  228.                 static_cast<rvCTF_AssaultPoint*>(toStrogg.GetEntity())->ResetSpawns( team );
  229.             }
  230.         }    
  231.     }
  232. }
  233.  
  234. void rvCTF_AssaultPoint::SetOwner ( int newOwner ) {
  235.     if ( !gameLocal.isClient ) {
  236.         // server should set owner via EVENT_ACTIVATE, not here
  237.         return;
  238.     }
  239.     
  240.     owner = newOwner;
  241.     SetOwnerColor ();
  242. }
  243.  
  244. void rvCTF_AssaultPoint::Reset ( void ) {
  245.     owner = AS_NEUTRAL;
  246.     SetOwnerColor();
  247. }
  248.  
  249. /*
  250. ================
  251. rvCTF_AssaultPoint::ChangeColor
  252. ================
  253. */
  254. void rvCTF_AssaultPoint::SetOwnerColor ( void ) {
  255.     const idDeclSkin* skin = NULL;
  256.     if( owner == TEAM_MARINE ) {
  257.         skin = declManager->FindSkin( "skins/ddynerman/green_glow", false );
  258.     } else if ( owner == TEAM_STROGG ) { 
  259.         skin = declManager->FindSkin( "skins/ddynerman/orange_glow", false );
  260.     } else {
  261.         skin = declManager->FindSkin( "skins/ddynerman/white", false );
  262.     }
  263.  
  264.     if ( skin ) {
  265.         SetSkin( skin );    
  266.     }
  267. }
  268.  
  269. /*
  270. ===============================================================================
  271.  
  272. rvCTFAssaultPlayerStart
  273.  
  274. ===============================================================================
  275. */
  276.  
  277. CLASS_DECLARATION( idPlayerStart, rvCTFAssaultPlayerStart )
  278.     EVENT( EV_Activate,    rvCTFAssaultPlayerStart::Event_Activate )
  279. END_CLASS
  280.  
  281. /*
  282. ================
  283. rvCTFAssaultPlayerStart::Spawn
  284. ================
  285. */
  286. void rvCTFAssaultPlayerStart::Spawn(void) {
  287.     if( !idStr::Icmp( spawnArgs.GetString( "team" ), "marine" ) ) {
  288.         team = TEAM_MARINE;
  289.     } else if( !idStr::Icmp( spawnArgs.GetString( "team" ), "strogg" ) ) {
  290.         team = TEAM_STROGG;
  291.     } else {
  292.         gameLocal.Error("rvCTFAssaultPlayerStart::Spawn() - unknown team\n");
  293.         team = -1;
  294.     }
  295. }
  296.  
  297. void rvCTFAssaultPlayerStart::Event_Activate( idEntity *activator ) {
  298.     if ( !activator->IsType( rvCTF_AssaultPoint::GetClassType() ) ) {
  299.         gameLocal.Warning( "rvCTFAssaultPlayerStart::Event_Activate() - was activated by something other than an assault point\n" );
  300.         return;
  301.     }
  302.     
  303.     rvCTF_AssaultPoint* ap = static_cast<rvCTF_AssaultPoint*>(activator);
  304.  
  305.     if( ap->GetOwner() == team ) {
  306.         gameLocal.UpdateForwardSpawns( this, team );
  307.     }
  308. }
  309.