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

  1. #include "../idlib/precompiled.h"
  2. #pragma hdrstop
  3.  
  4. #include "Game_local.h"
  5. #include "Healing_Station.h"
  6.  
  7. CLASS_DECLARATION( idAnimatedEntity, rvHealingStation )
  8. END_CLASS
  9.  
  10. /*
  11. ================
  12. rvHealingStation::Think
  13. ================
  14. */
  15. void rvHealingStation::Think ( void ) {
  16.     // TODO: I'm guessing this is bad, but I wanted to get this in so that people could start 
  17.     // placing it.  The entity decided to stop thinking and I didn't have time to debug it.
  18.     BecomeActive( TH_ALL );
  19.  
  20.     stateThread.Execute();
  21.     UpdateAnimation();
  22.  
  23.     if ( thinkFlags & TH_UPDATEVISUALS ) {
  24.         if ( healthDispensed > 0 ) {
  25.             CreateFrame( float( healthDispensed ) / maxHealth );
  26.         }
  27.         Present();
  28.     }
  29. }
  30.  
  31. /*
  32. ================
  33. rvHealingStation::Spawn
  34. ================
  35. */
  36. void rvHealingStation::Spawn ( void ) {
  37.     entityToHeal    = 0;
  38.     nextHealTime    = 0;
  39.     healFrequency    = spawnArgs.GetInt( "heal_frequency", "24" );
  40.     healAmount        = spawnArgs.GetInt( "heal_amount", "1" );
  41.     
  42.     healthDispensed    = 0;
  43.     soundStartTime    = 0;
  44.     soundLength        = 0;
  45.     maxHealth        = spawnArgs.GetInt( "max_health", "100" );
  46.  
  47.     dispenseAnim    = GetAnimator()->GetAnim( spawnArgs.GetString( "dispense_anim", "dispense" ) );
  48.  
  49.     CreateFrame( 0 );
  50.  
  51.     stateThread.SetOwner( this );
  52.     stateThread.SetName( GetName() );
  53.     GetAnimator()->CycleAnim( ANIMCHANNEL_ALL, GetAnimator()->GetAnim( spawnArgs.GetString( "anim", "idle" ) ), gameLocal.time, 4 );
  54. }
  55.  
  56. /*
  57. ================
  58. rvHealingStation::Save
  59. ================
  60. */
  61. void rvHealingStation::Save ( idSaveGame *savefile ) const {
  62.     stateThread.Save( savefile );
  63.     entityToHeal.Save ( savefile );
  64.     savefile->WriteInt( nextHealTime );
  65.     savefile->WriteInt( healFrequency );
  66.     savefile->WriteInt( healAmount );
  67.     savefile->WriteInt( healthDispensed );
  68.     savefile->WriteInt( maxHealth );
  69.     savefile->WriteInt( dispenseAnim );
  70.     savefile->WriteInt( soundStartTime );
  71.     savefile->WriteInt( soundLength );
  72. }
  73.  
  74. /*
  75. ================
  76. rvHealingStation::Restore
  77. ================
  78. */
  79. void rvHealingStation::Restore ( idRestoreGame *savefile ) {
  80.     stateThread.Restore( savefile, this );
  81.     entityToHeal.Restore ( savefile );
  82.     savefile->ReadInt( nextHealTime );
  83.     savefile->ReadInt( healFrequency );
  84.     savefile->ReadInt( healAmount );
  85.     savefile->ReadInt( healthDispensed );
  86.     savefile->ReadInt( maxHealth );
  87.     savefile->ReadInt( dispenseAnim );
  88.     savefile->ReadInt( soundStartTime );
  89.     savefile->ReadInt( soundLength );
  90. }
  91.  
  92. /*
  93. ================
  94. rvHealingStation::BeginHealing
  95. ================
  96. */
  97. void rvHealingStation::BeginHealing ( idEntity *toHeal ) {
  98.     entityToHeal    = toHeal;
  99.     stateThread.SetState( "Healing" );
  100. }
  101.  
  102. /*
  103. ================
  104. rvHealingStation::EndHealing
  105. ================
  106. */
  107. void rvHealingStation::EndHealing ( void ) {
  108.     entityToHeal    = NULL;
  109. }
  110.  
  111. /*
  112. ================
  113. rvHealingStation::CreateFrame
  114. ================
  115. */
  116. void rvHealingStation::CreateFrame ( float station_health ) {
  117.     // Update the GUI
  118.     if ( renderEntity.gui[ 0 ] ) {
  119.         renderEntity.gui[ 0 ]->SetStateFloat( "station_health", 1.0f - station_health );
  120.         renderEntity.gui[ 0 ]->StateChanged( gameLocal.time, true );
  121.     }
  122.  
  123.     // Update the Animation
  124.     int numFrames    = GetAnimator()->GetAnim( dispenseAnim )->NumFrames();
  125.     float lerp        = numFrames * station_health;
  126.     int frame        = lerp;
  127.     lerp            = lerp - frame;
  128.     frameBlend_t frameBlend    = { 0, frame, frame + 1, 1.0f - lerp, lerp };
  129.     GetAnimator()->SetFrame( ANIMCHANNEL_ALL, dispenseAnim, frameBlend );    
  130. }
  131.  
  132. /*
  133. ================
  134. rvHealingStation::IsPlaying
  135. ================
  136. */
  137. bool rvHealingStation::IsPlaying ( void ) {
  138.     idSoundEmitter* emitter = soundSystem->EmitterForIndex ( SOUNDWORLD_GAME, GetSoundEmitter ( ) );
  139.     if( emitter ) {
  140.         return ( emitter->CurrentlyPlaying ( ) );
  141.     }
  142.     return false;
  143. }
  144.  
  145. /*
  146. ===============================================================================
  147.  
  148.     States 
  149.  
  150. ===============================================================================
  151. */
  152.  
  153. CLASS_STATES_DECLARATION ( rvHealingStation )
  154.     STATE ( "Healing",        rvHealingStation::State_Healing )
  155. END_CLASS_STATES
  156.  
  157. /*
  158. ================
  159. rvHealingStation::State_Healing
  160. ================
  161. */
  162. stateResult_t rvHealingStation::State_Healing ( const stateParms_t& parms ) {
  163.     enum { 
  164.         STAGE_INIT,
  165.         STAGE_WAIT,
  166.         STAGE_DISPENSE,
  167.     };
  168.  
  169.     if ( entityToHeal.IsValid() ) {
  170.         idPlayer* player = static_cast<idPlayer*>( entityToHeal.GetEntity( ) );
  171.         const int entityMaxHealth = player->inventory.maxHealth;
  172.         
  173.         if ( healthDispensed        < maxHealth &&            // and we have health to dispense...
  174.              entityToHeal->health    < entityMaxHealth &&    // and the entity needs health.
  175.              entityToHeal->health   > 0    )                    // and he's still alive.
  176.         {
  177.             switch ( parms.stage ) {
  178.                 case STAGE_INIT:
  179.                     soundStartTime = gameLocal.time;
  180.                     StartSound( "snd_start", SND_CHANNEL_ANY, 0, false, &soundLength );
  181.                     return SRESULT_STAGE ( STAGE_WAIT );
  182.  
  183.                 case STAGE_WAIT:
  184.                     if ( gameLocal.time > soundStartTime + soundLength ) {
  185.                         soundStartTime = 0;
  186.                         soundLength = 0;
  187.                         return SRESULT_STAGE ( STAGE_DISPENSE );
  188.                     }
  189.                     return SRESULT_WAIT;
  190.  
  191.                 case STAGE_DISPENSE:
  192.                     if ( gameLocal.time            > nextHealTime ) {    // If it's time to heal...
  193.                         int healthGiven            = Min( maxHealth - healthDispensed, Min( healAmount, entityMaxHealth - entityToHeal->health ) );
  194.                         entityToHeal->health    += healthGiven;
  195.                         healthDispensed            += healthGiven;
  196.                         nextHealTime            = gameLocal.time + healFrequency;
  197.                     }
  198.                     if ( !IsPlaying ( ) ) {
  199.                         StartSound( "snd_loop", SND_CHANNEL_ANY, 0, false, NULL );
  200.                     }
  201.                     return SRESULT_WAIT;
  202.             }
  203.         }
  204.     }
  205.  
  206.     StopSound ( SND_CHANNEL_ANY, 0 );
  207.     StartSound ( "snd_stop", SND_CHANNEL_ANY, 0, false, NULL );
  208.     return SRESULT_DONE;
  209. }
  210.