home *** CD-ROM | disk | FTP | other *** search
/ Programming a Multiplayer FPS in DirectX / Programming a Multiplayer FPS in DirectX (Companion CD).iso / Source / Chapter 13 / Game / Weapon.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  2004-10-28  |  10.1 KB  |  269 lines

  1. //-----------------------------------------------------------------------------
  2. // Weapon.h implementation.
  3. // Refer to the Weapon.h interface for more details.
  4. //
  5. // Programming a Multiplayer First Person Shooter in DirectX
  6. // Copyright (c) 2004 Vaughan Young
  7. //-----------------------------------------------------------------------------
  8. #include "Main.h"
  9.  
  10. //-----------------------------------------------------------------------------
  11. // The weapon class constructor.
  12. //-----------------------------------------------------------------------------
  13. Weapon::Weapon( Script *script, D3DXVECTOR3 viewWeaponOffset )
  14. {
  15.     // Get the name of the weapon.
  16.     m_name = new char[strlen( script->GetStringData( "name" ) ) + 1];
  17.     strcpy( m_name, script->GetStringData( "name" ) );
  18.  
  19.     // Weapons are valid by default.
  20.     m_valid = true;
  21.  
  22.     // Store the view weapon offset.
  23.     m_viewWeaponOffset = viewWeaponOffset;
  24.  
  25.     // Clear the weapon movement smoothing variables.
  26.     m_lastViewPointY = m_offsetViewPointY = 0.0f;
  27.  
  28.     // Do not use the view weapon by default.
  29.     m_useViewWeapon = false;
  30.  
  31.     // Get all the details about the weapon's firing capabilities.
  32.     m_fireTimer = m_rof = *script->GetFloatData( "rate_of_fire" );
  33.     m_velocity = *script->GetFloatData( "muzzle_velocity" ) / g_engine->GetScale();
  34.     m_damage = *script->GetFloatData( "max_damage" );
  35.     m_range = *script->GetFloatData( "range" ) / g_engine->GetScale();
  36.  
  37.     // Create an object for the weapon on the player's body.
  38.     m_bodyWeapon = new SceneObject( TYPE_SCENE_OBJECT, script->GetStringData( "mesh" ), script->GetStringData( "mesh_path" ) );
  39.  
  40.     // Create an object for the weapon in the player's view.
  41.     m_viewWeapon = new AnimatedObject( script->GetStringData( "mesh_hands" ), script->GetStringData( "mesh_path" ) );
  42.  
  43.     // Create the list of shot flashes for this weapon.
  44.     m_flashes = new LinkedList< Material >;
  45.     char flash[16] = { "flash0" };
  46.     while( script->GetStringData( flash ) != NULL )
  47.     {
  48.         m_flashes->Add( new Material( script->GetStringData( flash ), script->GetStringData( "flash_path" ) ) );
  49.         sprintf( flash, "flash%d", m_flashes->GetTotalElements() );
  50.     }
  51.     m_displayFlash = false;
  52.  
  53.     // Load the shot sound and create an audio path for it.
  54.     m_shotSound = new Sound( script->GetStringData( "sound" ) );
  55.     m_shotAudioPath = new AudioPath3D;
  56. }
  57.  
  58. //-----------------------------------------------------------------------------
  59. // The weapont class destructor.
  60. //-----------------------------------------------------------------------------
  61. Weapon::~Weapon()
  62. {
  63.     // Destroy the string buffer containing the name of the weapon.
  64.     SAFE_DELETE( m_name );
  65.  
  66.     // Destroy the weapon objects.
  67.     SAFE_DELETE( m_bodyWeapon );
  68.     SAFE_DELETE( m_viewWeapon );
  69.  
  70.     // Destroy the list of shot flashes.
  71.     SAFE_DELETE( m_flashes );
  72.  
  73.     // Destroy the shot sound and its audio path.
  74.     SAFE_DELETE( m_shotSound );
  75.     SAFE_DELETE( m_shotAudioPath );
  76. }
  77.  
  78. //-----------------------------------------------------------------------------
  79. // Updates the weapon.
  80. //-----------------------------------------------------------------------------
  81. void Weapon::Update( float elapsed, bool fire, SceneObject *parent, float viewPointY )
  82. {
  83.     // Update weapon, using either the 3rd person or the 1st person object.
  84.     if( m_useViewWeapon == false )
  85.         m_bodyWeapon->Update( elapsed, false );
  86.     else
  87.     {
  88.         // Calculate the offset in model space.
  89.         D3DXVECTOR3 offset;
  90.         D3DXVec3TransformCoord( &offset, &m_viewWeaponOffset, parent->GetRotationMatrix() );
  91.  
  92.         // If this is the first time through, then set the view point y value.
  93.         if( m_lastViewPointY == 0.0f )
  94.             m_lastViewPointY = viewPointY;
  95.  
  96.         // When the player's mesh animates, the head moves, which causes the
  97.         // view point to move. Take this movement into account so that the
  98.         // weapon does not fly all over the place on the screen.
  99.         m_offsetViewPointY += ( viewPointY - m_lastViewPointY ) * 0.8f;
  100.         offset.y += m_offsetViewPointY;
  101.         m_lastViewPointY = viewPointY;
  102.  
  103.         // Position the weapon correctly, then update it.
  104.         m_viewWeapon->SetTranslation( parent->GetTranslation() + offset );
  105.         m_viewWeapon->SetRotation( parent->GetRotation() );
  106.         m_viewWeapon->AddRotation( ( (PlayerObject*)parent )->GetViewTilt(), 0.0f, 0.0f );
  107.         m_viewWeapon->Update( elapsed, false );
  108.     }
  109.  
  110.     // Update the fire timer.
  111.     m_fireTimer += elapsed;
  112.  
  113.     // Ensure the weapon is firing.
  114.     if( fire == false )
  115.         return;
  116.  
  117.     // Check if it is time to fire another shot.
  118.     if( m_fireTimer > m_rof )
  119.     {
  120.         // Indicate that a flash needs to be displayed this frame.
  121.         m_displayFlash = true;
  122.  
  123.         // Check if the view weapon is being used (i.e. 1st person view).
  124.         if( m_useViewWeapon == true )
  125.         {
  126.             // Calculate the muzzel point of the weapon in world space
  127.             // using the 1st person view weapon object.
  128.             m_muzzelPoint = m_viewWeapon->GetMesh()->GetReferencePoint( "rp_sight" )->GetTranslation();
  129.  
  130.             D3DXMATRIX rotationXMatrix;
  131.             D3DXMatrixRotationX( &rotationXMatrix, ( (PlayerObject*)parent )->GetViewTilt() );
  132.  
  133.             D3DXMATRIX combinedRotation;
  134.             D3DXMatrixMultiply( &combinedRotation, &rotationXMatrix, parent->GetRotationMatrix() );
  135.  
  136.             D3DXVec3TransformCoord( &m_muzzelPoint, &m_muzzelPoint, &combinedRotation );
  137.  
  138.             m_muzzelPoint += m_viewWeapon->GetTranslation();
  139.  
  140.             // Set the shot audio path to use head realative mode.
  141.             m_shotAudioPath->SetMode( DS3DMODE_HEADRELATIVE );
  142.  
  143.             // Update the shot sound's audio path.
  144.             m_shotAudioPath->SetPosition( m_viewWeapon->GetMesh()->GetReferencePoint( "rp_sight" )->GetTranslation() );
  145.             m_shotAudioPath->SetVelocity( parent->GetVelocity() );
  146.         }
  147.         else
  148.         {
  149.             // Calculate the muzzel point of the weapon in world space
  150.             // using the 3rd person view weapon object.
  151.             m_muzzelPoint = m_bodyWeapon->GetMesh()->GetReferencePoint( "rp_sight" )->GetTranslation();
  152.  
  153.             Frame *attach = ( (PlayerObject*)parent )->GetMesh()->GetReferencePoint( "rp_weapon_attach" );
  154.             D3DXMATRIX transform;
  155.             D3DXMatrixMultiply( &transform, &attach->finalTransformationMatrix, parent->GetWorldMatrix() );
  156.  
  157.             D3DXVec3TransformCoord( &m_muzzelPoint, &m_muzzelPoint, &transform );
  158.  
  159.             // Set the shot audio path to use normal mode.
  160.             m_shotAudioPath->SetMode( DS3DMODE_NORMAL );
  161.  
  162.             // Update the shot sound's audio path.
  163.             m_shotAudioPath->SetPosition( m_muzzelPoint );
  164.             m_shotAudioPath->SetVelocity( parent->GetVelocity() );
  165.         }
  166.  
  167.         // Play the shot sound.
  168.         m_shotAudioPath->Play( m_shotSound->GetSegment() );
  169.  
  170.         // Add the new bullet to the bullet manager.
  171.         g_game->GetBulletManager()->AddBullet( parent, ( (PlayerObject*)parent )->GetEyePoint(), ( (PlayerObject*)parent )->GetForwardVector(), m_velocity, m_range, m_damage );
  172.  
  173.         // Restart the timer.
  174.         m_fireTimer = 0.0f;
  175.     }
  176. }
  177.  
  178. //-----------------------------------------------------------------------------
  179. // Renders the weapon.
  180. //-----------------------------------------------------------------------------
  181. void Weapon::Render( SceneObject *parent )
  182. {
  183.     // Render the weapon using the correct weapon object.
  184.     if( m_useViewWeapon == true )
  185.         m_viewWeapon->Render();
  186.     else
  187.     {
  188.         // Get the translation (world space) to render the 3rd person weapon.
  189.         Frame *attach = ( (PlayerObject*)parent )->GetMesh()->GetReferencePoint( "rp_weapon_attach" );
  190.         D3DXMATRIX transform;
  191.         D3DXMatrixMultiply( &transform, &attach->finalTransformationMatrix, parent->GetWorldMatrix() );
  192.  
  193.         m_bodyWeapon->Render( &transform );
  194.     }
  195.  
  196.     // Check if a flash needs to be displayed.
  197.     if( m_displayFlash == true )
  198.     {
  199.         // Get a random flash material.
  200.         Material *material = m_flashes->GetRandom();
  201.  
  202.         // Use the sprite interface to render the flash at the muzzel point.
  203.         D3DXMATRIX view, world;
  204.         D3DXMatrixIdentity( &world );
  205.         g_engine->GetDevice()->GetTransform( D3DTS_VIEW, &view );
  206.         g_engine->GetSprite()->SetWorldViewLH( &world, &view );
  207.         g_engine->GetSprite()->Begin( D3DXSPRITE_BILLBOARD | D3DXSPRITE_ALPHABLEND );
  208.         g_engine->GetSprite()->Draw( material->GetTexture(), NULL, &D3DXVECTOR3( material->GetWidth() / 2.0f, material->GetHeight() / 2.0f, 0.0f ), &m_muzzelPoint, 0xFFFFFFFF );
  209.         g_engine->GetSprite()->End();
  210.  
  211.         // Indicate that the flash has been rendered this frame.
  212.         m_displayFlash = false;
  213.     }
  214. }
  215.  
  216. //-----------------------------------------------------------------------------
  217. // Raises/Lowers the weapon.
  218. //-----------------------------------------------------------------------------
  219. void Weapon::RaiseLowerWeapon( float elapsed, SceneObject *parent, float move )
  220. {
  221.     // Get the weapon's offset in model space.
  222.     D3DXVECTOR3 offset;
  223.     D3DXVec3TransformCoord( &offset, &m_viewWeaponOffset, parent->GetRotationMatrix() );
  224.  
  225.     // Get the parent's up vector.
  226.     D3DXVECTOR3 up;
  227.     D3DXVec3Cross( &up, &parent->GetForwardVector(), &parent->GetRightVector() );
  228.  
  229.     // Move the weapon (either up or down).
  230.     offset += up * move;
  231.  
  232.     // Apply the offset to the weapon's translation and update the object.
  233.     m_viewWeapon->SetTranslation( parent->GetTranslation() + offset );
  234.     m_viewWeapon->SetRotation( parent->GetRotation() );
  235.     m_viewWeapon->AddRotation( ( (PlayerObject*)parent )->GetViewTilt(), 0.0f, 0.0f );
  236.     m_viewWeapon->Update( elapsed, false );
  237. }
  238.  
  239. //-----------------------------------------------------------------------------
  240. // Set the weapon to use either the 1st person or the 3rd person weapon object.
  241. //-----------------------------------------------------------------------------
  242. void Weapon::UseViewWeapon( bool use )
  243. {
  244.     m_useViewWeapon = use;
  245. }
  246.  
  247. //-----------------------------------------------------------------------------
  248. // Get the name of the weapon.
  249. //-----------------------------------------------------------------------------
  250. char *Weapon::GetName()
  251. {
  252.     return m_name;
  253. }
  254.  
  255. //-----------------------------------------------------------------------------
  256. // Set the weapon's valid flag.
  257. //-----------------------------------------------------------------------------
  258. void Weapon::SetValid( bool valid )
  259. {
  260.     m_valid = valid;
  261. }
  262.  
  263. //-----------------------------------------------------------------------------
  264. // Get the weapon's valid flag.
  265. //-----------------------------------------------------------------------------
  266. bool Weapon::GetValid()
  267. {
  268.     return m_valid;
  269. }