Main Page   Namespace List   Class Hierarchy   Alphabetical List   Compound List   File List   Namespace Members   Compound Members   File Members  

BattleJets.cpp

Go to the documentation of this file.
00001 /*
00002 CS Senior Project 2003
00003 Team : Leftfield
00004 Project : ModernWarfare
00005 Members :
00006 - Russ Christensen              <rchriste@cs.utah.edu>
00007 - Todd Smith                    <tcsmith@cs.utah.edu>
00008 - Usit Duongsaa                 <duongsaa@cs.utah.edu>
00009 Copyright 2003 Russ Christensen, Usit Duongsaa, and Todd Smith. All rights reserved.
00010 
00011 Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
00012 
00013 Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 
00014 Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. 
00015 THIS SOFTWARE IS PROVIDED BY RUSS CHRISTENSEN, USIT DUONGSAA, AND TODD SMITH ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL RUSS, USIT, TODD OR OTHER CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00016 */
00017 
00022 #include "BattleJets.h"
00023 #include "BattleState.h"
00024 #include "Sound.h"
00025 #include "GameState.h"
00026 
00027 //------------------------------------------------------------------------------------
00028 BattleJets::BattleJets(int numJets, Vec3D color, char team, int cityID )
00029 {
00030         m_totalHealth = numJets * BattleUnitData::getObj().armor()[4];
00031         m_color = color; 
00032         m_team = team;
00033         m_cmdType = JetCommands::IDLE;
00034         m_numMissiles = numJets * 2;
00035         m_delayTime   = 62 * 5;
00036         m_targetGroup = -1;
00037         m_cityID = cityID;
00038         m_pos = Vec3D(10000.0f,10000.0f,0.0f);
00039 }
00040 //------------------------------------------------------------------------------------
00041 int  BattleJets::getNumJets()
00042 {
00043         int jetMaxHealth = BattleUnitData::getObj().armor()[4];
00044         return ( m_totalHealth + jetMaxHealth - 1 ) / jetMaxHealth;
00045 }
00046 //------------------------------------------------------------------------------------
00047 bool BattleJets::isReadyForOrder()
00048 {
00049         return m_cmdType == JetCommands::IDLE && m_delayTime == 0;
00050 }
00051 //------------------------------------------------------------------------------------
00052 void BattleJets::orderToBomb( int targetGroup )
00053 {
00054         m_targetGroup = targetGroup;
00055         m_target = BS->groups[targetGroup].m_pos;
00056         m_target.z += terrain_getHeight( BS->terrain, m_target.x, m_target.y );
00057         
00058         m_cmdType = JetCommands::BOMB;
00059 
00060         if( m_team=='A' ) m_pos = Vec3D( 800.0f, 800.0f, 0.0f );
00061                                 else  m_pos = Vec3D(-800.0f,-800.0f, 0.0f );    
00062         m_dir.x = clipAngle( 90-D3DXToDegree( atan2f( -m_pos.x, -m_pos.y ) ) ); // face origin
00063         m_dir.y = 0.0f;
00064         m_dir.z = 0.0f;
00065 }
00066 //------------------------------------------------------------------------------------
00067 void BattleJets::orderToReturn()
00068 {
00069         m_cmdType = JetCommands::RETURN;
00070         if( m_team=='A' ) m_target = Vec3D( 800.0f, 800.0f, 0.0f );
00071                                 else  m_target = Vec3D(-800.0f,-800.0f, 0.0f );
00072         m_targetGroup = -1;
00073 }
00074 //------------------------------------------------------------------------------------
00075 void BattleJets::orderToGuard( Vec3D target )
00076 {
00077         m_cmdType = JetCommands::GUARD; 
00078         m_target = target;
00079 
00080         if( m_team=='A' ) m_pos = Vec3D( 800.0f, 800.0f, 0.0f );
00081                                 else  m_pos = Vec3D(-800.0f,-800.0f, 0.0f );    
00082         m_dir.x = clipAngle( 90-D3DXToDegree( atan2f( -m_pos.x, -m_pos.y ) ) ); // face origin
00083         m_dir.y = 0.0f;
00084         m_dir.z = 0.0f;
00085 }
00086 //------------------------------------------------------------------------------------
00087 void BattleJets::assignNewGuardTarget( Vec3D target )
00088 {
00089         m_target = target;
00090 }
00091 //------------------------------------------------------------------------------------
00092 void BattleJets::takeHit( BattleBullet &b )
00093 {
00094         bool isActive = false;                                          // if this battle is active (player's watching it)
00095         if( GameState::activeBattle() )
00096                 if( GameState::activeBattle()->getBSPtr() == BS ) isActive = true;      
00097         float vol = Sound::getMasterSFXVol();
00098         if( !isActive ) vol *= 0.92f;
00099         Vec3D playerCol( GameState::consolePlayer()->color() );
00100         if( BS->teamAColor!=playerCol && BS->teamBColor!=playerCol ) vol = 0.0f;
00101 
00102         if( math_distPlanar3D( b.m_pos, m_pos ) < 80.0f )
00103         {
00104                 int prevNumJets = getNumJets();
00105                 m_totalHealth -= BattleUnitData::getObj().baseDamage()[4];
00106                 int newNumJets = getNumJets();
00107 
00108                 for( int i=0; i<prevNumJets-newNumJets; i++ )                           // jets go booomm!!
00109                 {
00110                         int debrisType = sys_randInt()%2;
00111                         Vec3D speed = Vec3D( 0.3f*sys_randFloat(), 0.3f*sys_randFloat(), 0.16f*(sys_randFloat()+1.0f) );
00112                         FLOAT dirSpeed = 3.5f;
00113                         Vec3D pos( m_pos ), target( m_target );
00114                         pos.x += 6.0f * (1.0f + sys_randFloat());
00115                         pos.y += 15.0f * sys_randFloat();
00116                         pos.z += 30.0f;
00117                         BS->debris.push_back( BattleDebris(pos,speed,dirSpeed,debrisType) );
00118                         
00119                         Sound::play(Sound::SMPL_SFX_EXPLOSION_LARGE,vol);
00120                 }
00121 
00122                 if( m_totalHealth < 0 )  m_totalHealth = 0;
00123         }
00124 }
00125 //------------------------------------------------------------------------------------
00126 void BattleJets::flyTo( Vec3D target )
00127 {
00128         if( m_targetGroup!= -1 )
00129         {
00130                 Vec3D targetPos( BS->groups[m_targetGroup].m_pos );
00131                 targetPos.z += terrain_getHeight( BS->terrain, targetPos.x, targetPos.y ) + 5.0f;
00132                 m_target = targetPos;
00133         }
00134 
00135         Vec3D targetVec = target - m_pos;
00136         FLOAT targetDir = clipAngle( 90-D3DXToDegree( atan2f( targetVec.x, targetVec.y ) ) );
00137         if( m_cmdType==JetCommands::GUARD ) targetDir = clipAngle(targetDir+25.0f+10.0f*sys_randFloat() );      // fly around target, not to target
00138 
00139         FLOAT currentDir = m_dir[0];
00140         FLOAT delta;                            // signed (+CW,-CCW) smallest-magnitude difference in angle
00141         if( targetDir<0.0f ) targetDir += 360.0f;
00142         else if( targetDir>=360.0f ) targetDir -= 360.0f;
00143         if(targetDir>currentDir)
00144         {
00145                 delta = targetDir - currentDir;
00146                 if(delta>180.0f) delta = delta - 360.0f;
00147         }
00148         else
00149         {
00150                 delta = targetDir - currentDir;
00151                 if(delta<-180.0f) delta = 360.0f - delta;
00152         }               
00153         
00154         const FLOAT turnRate = BattleUnitData::getObj().BGTurnRate()[4];
00155         FLOAT turnAngle = delta;
00156         if( delta > turnRate ) turnAngle = turnRate;
00157         else if( delta < -turnRate ) turnAngle = -turnRate;
00158         else turnAngle = delta;
00159         m_dir[0] = clipAngle( currentDir + turnAngle );                         // turn
00160         
00161         FLOAT rad = D3DXToRadian( m_dir[0] );
00162         FLOAT speed = BattleUnitData::getObj().BGFullSpeed()[4];        // move
00163         m_pos += speed * Vec3D( cosf(rad), sinf(rad), 0.0f );
00164 }
00165 //------------------------------------------------------------------------------------
00166 void BattleJets::fireAntiSurfaceMissiles()
00167 {
00168         if( m_numMissiles==0 ) return;
00169 
00170         bool isActive = false;                                          // if this battle is active (player's watching it)
00171         if( GameState::activeBattle() )
00172                 if( GameState::activeBattle()->getBSPtr() == BS ) isActive = true;      
00173         float vol = Sound::getMasterSFXVol();
00174         if( !isActive ) vol *= 0.92f;
00175         Vec3D playerCol( GameState::consolePlayer()->color() );
00176         if( BS->teamAColor!=playerCol && BS->teamBColor!=playerCol ) vol = 0.0f;
00177 
00178         FLOAT dist = math_distPlanar3D(m_pos,m_target);
00179         FLOAT targetDir = math_getDir( m_pos, m_target );
00180         FLOAT deltaAngle = math_deltaDir( targetDir, m_dir.x );
00181         if( dist<=100.0f && sys_randInt()%3==0 && deltaAngle<15.0f )
00182         {
00183                 m_numMissiles--;
00184                 Vec3D pos( m_pos ), target( m_target );
00185                 pos.x += 6.0f * (1.0f + sys_randFloat());
00186                 pos.y += 15.0f * sys_randFloat();
00187                 pos.z += 30.0f;
00188                 target.x += 10.0f * sys_randFloat();
00189                 target.y += 10.0f * sys_randFloat();
00190                 BS->addBullet( BattleBullet( BulletTypes::ROCKET, m_team, -1, pos, target ));
00191                 target = m_target;
00192                 target.x += 15.0f * sys_randFloat();
00193                 target.y += 15.0f * sys_randFloat();
00194                 BS->addBullet( BattleBullet( BulletTypes::ROCKET, m_team, -1, pos, target ));
00195 
00196                 Sound::play(Sound::SMPL_SFX_FIRE_JET,vol);
00197         }
00198 }
00199 //------------------------------------------------------------------------------------
00200 void BattleJets::fireAntiAirMissiles()
00201 {
00202         if( m_numMissiles==0 ) return;
00203 
00204         bool isActive = false;                                          // if this battle is active (player's watching it)
00205         if( GameState::activeBattle() )
00206                 if( GameState::activeBattle()->getBSPtr() == BS ) isActive = true;      
00207         float vol = Sound::getMasterSFXVol();
00208         if( !isActive ) vol *= 0.92f;
00209         Vec3D playerCol( GameState::consolePlayer()->color() );
00210         if( BS->teamAColor!=playerCol && BS->teamBColor!=playerCol ) vol = 0.0f;
00211 
00212         for( UINT i=0; i<BS->jets.size(); i++ )
00213         {
00214                 BattleJets &J = BS->jets[i];
00215                 if( J.m_team == m_team ) continue;                      // look for enemy jets
00216                 if( sys_randInt()%3!=0 ) continue;
00217                 FLOAT dist = math_distPlanar3D(m_pos,J.m_pos);
00218                 if( dist > 100.0f ) continue;                                                           // in firing range
00219                 FLOAT targetDir = math_getDir( m_pos, J.m_pos );
00220                 FLOAT deltaAngle = math_deltaDir( targetDir, m_dir.x );
00221                 if( deltaAngle>35.0f ) continue;                                                        // in firing arc
00222 
00223                 m_numMissiles--;
00224                 Vec3D pos( m_pos ), target( J.m_pos );
00225                 pos.x += 6.0f * (1.0f + sys_randFloat());
00226                 pos.y += 15.0f * sys_randFloat();
00227                 pos.z += 30.0f;
00228                 
00229                 target.x += 5.0f * sys_randFloat();
00230                 target.y += 5.0f * sys_randFloat();
00231                 target.z += 30.0f;
00232                 BS->addBullet( BattleBullet( BulletTypes::ANTIAIR, m_team, -1, pos, target ));
00233                 Sound::play(Sound::SMPL_SFX_FIRE_JET,vol);
00234         }
00235 }
00236 //------------------------------------------------------------------------------------
00237 int BattleJets::getCurrentCommand()
00238 {
00239         return m_cmdType;
00240 }
00241 //------------------------------------------------------------------------------------
00242 void BattleJets::assignNewBombingTarget( int targetGroup )
00243 {
00244         m_targetGroup = targetGroup;
00245 }
00246 //------------------------------------------------------------------------------------
00247 void BattleJets::update()
00248 {
00249         if( m_totalHealth <= 0 ) return;
00250 
00251         if( m_delayTime>0 ) m_delayTime--;
00252 
00253         if( m_cmdType==JetCommands::BOMB || m_cmdType==JetCommands::RETURN || m_cmdType==JetCommands::GUARD )
00254                 flyTo(m_target);
00255 
00256         if( m_cmdType==JetCommands::BOMB )  fireAntiSurfaceMissiles();
00257         if( m_cmdType==JetCommands::GUARD)  fireAntiAirMissiles();
00258 
00259         if( m_numMissiles==0 && m_cmdType!=JetCommands::RETURN && m_cmdType!=JetCommands::IDLE )
00260                 orderToReturn();
00261 
00262 
00263         // mission done : rearm & refuel
00264         if( m_cmdType==JetCommands::RETURN && math_distPlanar3D(m_pos,m_target) < 100.0f )
00265         {
00266                 m_cmdType   = JetCommands::IDLE;
00267                 m_delayTime = 62 * 5;
00268                 m_numMissiles = getNumJets() * 2;               
00269         }
00270 }
00271 //------------------------------------------------------------------------------------
00272 void BattleJets::render()
00273 {
00274         if( m_totalHealth <= 0 ) return;
00275 
00276         // bombing target cross hair
00277         const Vec3D crossHairSize(35.0f, 35.0f, 0.05f), dir(0,0,0);
00278         if( m_cmdType==JetCommands::BOMB )
00279                 mesh_render( artWork->crossHair, m_target, crossHairSize, dir, artWork->colorRed );
00280 
00281         // guarding target cross hair
00282         if( m_cmdType==JetCommands::GUARD )
00283                 mesh_render( artWork->crossHair, m_target, crossHairSize*1.5f, dir, artWork->colorGreen );
00284 
00285         // jets
00286         if( m_cmdType != JetCommands::IDLE )
00287         {
00288                 Vec3D leftPt   = math_translateObjectToWorld( m_pos, m_dir, Vec3D( -4.0f, -3.5f, 0.0f) );
00289                 Vec3D rightPt  = math_translateObjectToWorld( m_pos, m_dir, Vec3D( -4.0f, +3.5f, 0.0f) );
00290                 Vec3D leftVec(  leftPt  - m_pos );
00291                 Vec3D rightVec( rightPt - m_pos );
00292                 
00293                 Vec3D size( BattleUnitData::getObj().jetSize() );
00294                 const FLOAT leftStep[12]  = { 0.0f, 1.0f, 0.0f, 2.0f, 1.0f, 0.0f, 3.0f, 2.0f, 1.0f, 0.0f, 3.0f,-1.0f };
00295                 const FLOAT rightStep[12] = { 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, 2.0f, 0.0f, 1.0f, 2.0f, 3.0f,-1.0f, 3.0f };
00296                 int N = getNumJets();
00297                 for( int i=0; i<N; i++ )
00298                 {
00299                         Vec3D pos(  m_pos + leftStep[i]*leftVec + rightStep[i]*rightVec  );
00300                         pos.z += 30.0f;
00301                         mesh_render( artWork->jet_mesh, pos, size, m_dir, artWork->jet_texture, NULL, m_color );
00302                 }
00303         }
00304 }
00305 //------------------------------------------------------------------------------------
00306 void BattleJets::renderIcon(FLOAT y)
00307 {
00308         if( m_totalHealth <= 0 ) return;
00309 
00310         overlay_image( artWork->jetsIconTex, Vec2D(0.970f,y+0.035f), Vec2D(0.06f,0.07f) );
00311 
00312         // number of jets       
00313         overlay_text() << getNumJets();
00314         overlay_textOut( Vec2D(0.946f, y+0.010f), 0.70f, Colors::black );
00315 
00316         // status text  
00317         if( m_cmdType==JetCommands::IDLE)
00318         {
00319                 if( m_delayTime==0 ) overlay_text() << "Ready";
00320                 else
00321                 {
00322                         int sec = m_delayTime / 62;                                     // time til ready
00323                         int min = sec / 60;
00324                         sec = sec % 60;
00325                         overlay_text() << min << ":";
00326                         if( sec<10 ) overlay_text() << 0;
00327                         overlay_text() << sec;
00328                 }                       
00329         }
00330         else if( m_cmdType==JetCommands::BOMB)          overlay_text() << "Bombing";    
00331         else if( m_cmdType==JetCommands::RETURN)        overlay_text() << "Returning";
00332         else  overlay_text() << "Guarding";
00333 
00334         overlay_textOut( Vec2D(0.948f, y+0.048f), 0.58f, Colors::black );
00335 }
00336 //------------------------------------------------------------------------------------

Generated on Wed Apr 23 05:50:14 2003 for Modern Warfare by doxygen1.3-rc2