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

BattleGroup Class Reference

#include <BattleGroup.h>

Collaboration diagram for BattleGroup:

Collaboration graph
[legend]
List of all members.

Detailed Description

defines a BattleGroup (1..N units of the same type, moving and acting as a single entity) for the BattleMode.

Definition at line 39 of file BattleGroup.h.

Public Methods

 BattleGroup (Vec3D pos, Vec3D dir, char team, Vec3D color, int unitType, int numUnits, int overheadForceNumber)
void addWaypoint (const Vec3D pt)
void moveBattleGroup ()
 move the entire BG entity to its destination (if any)

void moveUnits ()
 move the individual units in this BG to its appropriate pos in the BG

void acquireGroupTargets ()
 check all hostile BGs, add them to m_targetGroups if is within range

void fire ()
 tell the individual units to fire at target if they can

void fireAntiAir ()
 for launchers. check if there's any enemy jets nearby. if yes, try to shoot it down

void takeHit (const BattleBullet &b)
 checks each unit in BG if it's hit by the bullet. apply damage accordingly

void destroyUnit (BattleUnit &u)
 creates explosion, debris etc

bool isContain2DPoint (Vec2D pt)
void drawOutlineBox (Vec3D c)
void render ()

Public Attributes

BattleStateBS
char m_team
Vec3D m_pos
Vec3D m_size
Vec3D m_dir
Vec3D m_color
int m_unitType
int m_unitArraySize
int m_numUnits
FLOAT m_maxUnitDist
vector< Vec3Dm_waypoints
vector< int > m_targetGroups
BattleUnit m_units [MAX_UNIT]
FLOAT m_statFiringRange
int m_primaryTarget
bool m_isChasePrimaryTarget
bool m_isStrictPrimaryTarget
int m_overheadForceNumber


Constructor & Destructor Documentation

BattleGroup::BattleGroup Vec3D    pos,
Vec3D    dir,
char    team,
Vec3D    color,
int    unitType,
int    numUnits,
int    overheadForceNumber
 

Definition at line 78 of file BattleGroup.cpp.

References BattleUnitData::armor(), BattleUnitData::firingRange(), Singleton< BattleUnitData >::getObj(), m_color, BattleUnit::m_dir, m_dir, BattleUnit::m_firingDelay, BattleUnit::m_health, m_isChasePrimaryTarget, m_isStrictPrimaryTarget, m_numUnits, m_overheadForceNumber, BattleUnit::m_pos, m_pos, m_primaryTarget, BattleUnit::m_recvHitIndex, m_size, m_statFiringRange, BattleUnit::m_target, m_team, BattleUnit::m_turretDir, m_unitArraySize, m_units, m_unitType, math_translateObjectToWorld(), BattleUnitData::numCols(), BattleUnitData::numRows(), BattleUnitData::tightFormationSize(), and Vec3D.

00079 {
00080         assert(unitType>=0 && unitType<UnitTypes::COUNT );
00081         m_team = team;
00082         m_pos = pos;
00083         m_size = BattleUnitData::getObj().tightFormationSize()[unitType];
00084         m_dir = dir;
00085         m_color = color;
00086         m_unitType = unitType;
00087         m_unitArraySize = numUnits;
00088         m_numUnits = numUnits;
00089         m_overheadForceNumber = overheadForceNumber;
00090 
00091         Vec3D halfSize = m_size * 0.5f;
00092         int rows = BattleUnitData::getObj().numRows()[m_unitType];
00093         int cols = BattleUnitData::getObj().numCols()[m_unitType];
00094         FLOAT backDelta  = m_size.x / rows;
00095         FLOAT rightDelta = m_size.y / cols;
00096         Vec3D frontLeftPt = math_translateObjectToWorld( m_pos, m_dir, Vec3D( halfSize.x,halfSize.y,0.0f) );
00097         Vec3D backVec     = math_translateObjectToWorld( m_pos, m_dir, Vec3D( halfSize.x-backDelta,halfSize.y,0.0f) ) - frontLeftPt;
00098         Vec3D rightVec    = math_translateObjectToWorld( m_pos, m_dir, Vec3D( halfSize.x,halfSize.y-rightDelta,0.0f) ) - frontLeftPt;
00099 
00100         for( int i=0; i<m_unitArraySize; i++ )
00101         {
00102                 FLOAT col = (FLOAT)(i%cols) + 0.5f;
00103                 FLOAT row = (FLOAT)(i/cols) + 0.5f;
00104                 m_units[i].m_pos = frontLeftPt + backVec*row + rightVec*col;
00105                 m_units[i].m_dir = m_dir;
00106                 m_units[i].m_turretDir = Vec3D(0,0,0);
00107                 m_units[i].m_target = m_units[i].m_pos;
00108                 m_units[i].m_firingDelay = 0;
00109                 m_units[i].m_health = BattleUnitData::getObj().armor()[m_unitType];
00110                 m_units[i].m_recvHitIndex = 0;
00111         }
00112 
00113         m_statFiringRange = BattleUnitData::getObj().firingRange()[m_unitType];
00114         m_primaryTarget = -1;
00115         m_isStrictPrimaryTarget = false;
00116         m_isChasePrimaryTarget = false;
00117 }


Member Function Documentation

void BattleGroup::acquireGroupTargets  
 

check all hostile BGs, add them to m_targetGroups if is within range

Definition at line 259 of file BattleGroup.cpp.

References absf, BS, clipAngle(), BattleUnitData::firingArc(), Singleton< BattleUnitData >::getObj(), BattleState::groups, m_dir, m_isChasePrimaryTarget, m_isStrictPrimaryTarget, m_numUnits, m_pos, m_primaryTarget, m_statFiringRange, m_targetGroups, m_team, m_unitType, math_dist3D(), math_distPlanar3D(), UINT, and Vec3D.

00260 {
00261         if(m_numUnits==0) return;
00262         m_targetGroups.resize(0);
00263         for( UINT i=0; i<BS->groups.size(); i++ )
00264                 if( m_team!=BS->groups[i].m_team && BS->groups[i].m_numUnits > 0)               // check if of different team
00265                         if( BS->groups[i].m_numUnits > 0 )
00266                         {
00267                                 FLOAT dist = math_dist3D( m_pos, BS->groups[i].m_pos );
00268                                 if( dist < m_statFiringRange*1.3f )                                                                     // check if near firing range
00269                                 {
00270                                         Vec3D dirVec = BS->groups[i].m_pos - m_pos;
00271                                         FLOAT angle = clipAngle( 90-D3DXToDegree( atan2f( dirVec.x, dirVec.y ) ) );
00272                                         FLOAT delta;
00273                                         if(angle>m_dir.x)
00274                                         {
00275                                                 delta = angle - m_dir.x;
00276                                                 if(delta>180.0f) delta = delta - 360.0f;
00277                                         }
00278                                         else
00279                                         {
00280                                                 delta = angle - m_dir.x;
00281                                                 if(delta<-180.0f) delta = 360.0f - delta;
00282                                         }
00283                                         if( absf(delta) < BattleUnitData::getObj().firingArc()[m_unitType] )    // check if in firing arc
00284                                                 m_targetGroups.push_back(i);
00285                                 }
00286                         }
00287 
00288         if( (m_primaryTarget==-1 && m_targetGroups.size()>0)            // if have no primary target, pick one randomly
00289                 || !m_isStrictPrimaryTarget )
00290         {
00291                 FLOAT minDist = 999999.0f;
00292                 int   bestIndex = 0;
00293                 for( int i=0; i<(int)m_targetGroups.size(); i++ )
00294                 {
00295                         int targetIndex = m_targetGroups[i];
00296                         FLOAT dist = math_distPlanar3D( m_pos, BS->groups[targetIndex].m_pos );
00297                         if( dist < minDist )
00298                         {
00299                                 bestIndex = targetIndex;
00300                                 minDist = dist;
00301                         }
00302                 }               
00303                 m_isChasePrimaryTarget = false;
00304                 m_isStrictPrimaryTarget = false;
00305                 m_primaryTarget = bestIndex;
00306         }
00307 
00308         if( m_targetGroups.size()==0 && !m_isStrictPrimaryTarget )
00309                 m_primaryTarget = -1;
00310 
00311 }

void BattleGroup::addWaypoint const Vec3D    pt
 

Definition at line 119 of file BattleGroup.cpp.

References m_waypoints.

00120 {
00121         if(m_waypoints.size()<12 ) m_waypoints.push_back(pt);
00122 }

void BattleGroup::destroyUnit BattleUnit   u
 

creates explosion, debris etc

Definition at line 313 of file BattleGroup.cpp.

References GameState::activeBattle(), BS, camera_addVibration(), Globals::currGameTick, BattleState::debris, BattleEntry::getBSPtr(), Sound::getMasterSFXVol(), m_color, m_numUnits, BattleUnit::m_pos, Sound::play(), playVoicePanick(), playVoiceStress(), BattleState::sprites, BattleState::synch_firstKillTick, sys_console(), sys_randFloat(), sys_randInt(), BattleState::teamAColor, BattleState::teamBColor, BattleState::terrain, terrain_getHeight(), and Vec3D.

Referenced by fire(), and takeHit().

00314 {
00315         if( BS->synch_firstKillTick == -1 )
00316         {
00317                 BS->synch_firstKillTick = currGameTick;
00318                 sys_console() << "BATTLE First Kill at tick = " << currGameTick << endl;
00319         }
00320 
00321         sys_console() << "BATTLE Boom pos=" << u.m_pos.x << ' ' << u.m_pos.y << ' ' << u.m_pos.z << endl;
00322         bool isActive = false;                                          // if this battle is active (player's watching it)
00323         if( GameState::activeBattle() )
00324                 if( GameState::activeBattle()->getBSPtr() == BS ) isActive = true;
00325         float vol = Sound::getMasterSFXVol();
00326         if( !isActive ) vol *= 0.92f;
00327         Vec3D playerCol( GameState::consolePlayer()->color() );
00328         if( BS->teamAColor!=playerCol && BS->teamBColor!=playerCol ) vol = 0.0f;
00329 
00330         // conditional voice
00331         Vec3D playerColor( GameState::consolePlayer()->color() );
00332         if( m_numUnits < 10 && m_color==playerColor )  playVoicePanick(*BS,isActive);
00333         if( m_numUnits < 20 && m_color==playerColor )  playVoiceStress(*BS,isActive);
00334 
00335         Vec3D pos = u.m_pos;
00336         pos.z += terrain_getHeight(BS->terrain, pos.x, pos.y );
00337         BS->sprites.push_back( BattleSprite( pos, 45, BattleSpriteTypes::EXPLO_LARGE ));
00338         BS->sprites.push_back( BattleSprite( pos, 75, BattleSpriteTypes::SMOKE_LARGE ));
00339         int numParticles = 2 + sys_randInt()%4;
00340         int numSmokes    = 2 + sys_randInt()%3;
00341         for( int i=0; i<numParticles; i++ )
00342         {
00343                 Vec3D pos2 = pos + Vec3D( 4*sys_randFloat(), 4*sys_randFloat(), sys_randFloat() );
00344                 BS->sprites.push_back( BattleSprite( pos2, 20, BattleSpriteTypes::EXPLO_SMALL ));
00345         }
00346         for( int i=0; i<numSmokes; i++ )
00347         {
00348                 Vec3D pos2 = pos + Vec3D( 6*sys_randFloat(), 6*sys_randFloat(), 2*sys_randFloat() );
00349                 BS->sprites.push_back( BattleSprite( pos2, 65, BattleSpriteTypes::SMOKE_SMALL ));
00350         }
00351 
00352         // debris
00353         int debrisType = sys_randInt()%2;
00354         Vec3D speed = Vec3D( 0.3f*sys_randFloat(), 0.3f*sys_randFloat(), 0.16f*(sys_randFloat()+1.0f) );        
00355         FLOAT dirSpeed = 3.5f;
00356         BS->debris.push_back( BattleDebris(pos,speed,dirSpeed,debrisType) );
00357 
00358         // vibration
00359         if( GameState::activeBattle() )
00360                 if( GameState::activeBattle()->getBSPtr() == BS )                       // we're participating in this battle
00361                         camera_addVibration(5.0f);
00362 
00363         // sound effect
00364         Sound::play(Sound::SMPL_SFX_EXPLOSION_LARGE,vol);
00365 }

void BattleGroup::drawOutlineBox Vec3D    c
 

Definition at line 587 of file BattleGroup.cpp.

References BS, m_numUnits, m_size, math_translateObjectToWorld(), math_translateWorldToScreen(), overlay_line(), BattleState::terrain, terrain_getHeight(), Vec2D, and Vec3D.

Referenced by BattleEntry::renderGroups(), and BattleEntry::renderInterface().

00588 {
00589         if(m_numUnits==0) return;
00590         // calc the 4 corner pts of the box
00591         Vec3D halfSize = m_size * 0.5f;
00592         Vec3D pt3D1 = math_translateObjectToWorld( m_pos, m_dir, Vec3D( -halfSize.x, -halfSize.y,0.0f) );
00593         Vec3D pt3D2 = math_translateObjectToWorld( m_pos, m_dir, Vec3D( +halfSize.x, -halfSize.y,0.0f) );
00594         Vec3D pt3D3 = math_translateObjectToWorld( m_pos, m_dir, Vec3D( +halfSize.x, +halfSize.y,0.0f) );
00595         Vec3D pt3D4 = math_translateObjectToWorld( m_pos, m_dir, Vec3D( -halfSize.x, +halfSize.y,0.0f) );
00596         pt3D1.z += terrain_getHeight( BS->terrain, pt3D1.x, pt3D1.y );
00597         pt3D2.z += terrain_getHeight( BS->terrain, pt3D2.x, pt3D2.y );
00598         pt3D3.z += terrain_getHeight( BS->terrain, pt3D3.x, pt3D3.y );
00599         pt3D4.z += terrain_getHeight( BS->terrain, pt3D4.x, pt3D4.y );
00600         Vec2D pt2D1 = math_translateWorldToScreen(pt3D1);
00601         Vec2D pt2D2 = math_translateWorldToScreen(pt3D2);
00602         Vec2D pt2D3 = math_translateWorldToScreen(pt3D3);
00603         Vec2D pt2D4 = math_translateWorldToScreen(pt3D4);
00604         overlay_line(pt2D1, pt2D2, c );
00605         overlay_line(pt2D2, pt2D3, c );
00606         overlay_line(pt2D3, pt2D4, c );
00607         overlay_line(pt2D4, pt2D1, c );
00608 }

void BattleGroup::fire  
 

tell the individual units to fire at target if they can

Definition at line 389 of file BattleGroup.cpp.

References GameState::activeBattle(), BattleState::addBullet(), BattleUnitData::baseDamage(), BS, Player::color(), GameState::consolePlayer(), Globals::currGameTick, destroyUnit(), BattleUnitData::firingArc(), BattleUnitData::firingDelay(), BattleEntry::getBSPtr(), Sound::getMasterSFXVol(), Singleton< BattleUnitData >::getObj(), BattleState::groups, m_color, BattleUnit::m_dir, BattleUnit::m_firingDelay, BattleUnit::m_health, m_numUnits, BattleUnit::m_pos, m_primaryTarget, BattleUnit::m_recvHitIndex, BattleUnit::m_recvHits, m_statFiringRange, m_targetGroups, BattleUnit::m_turretDir, m_unitArraySize, m_units, m_unitType, math_deltaDir(), math_distPlanar3D(), math_getDir(), MAX_RECV_HIT, Sound::play(), playVoiceContact(), BattleState::synch_firstShotTick, sys_console(), sys_randInt(), BattleState::teamAColor, BattleState::teamBColor, BattleState::terrain, terrain_getHeight(), and Vec3D.

00390 {
00391         if(m_numUnits==0) return;
00392         //if(m_unitType==UnitTypes::LAUNCHER) fireAntiAir();                            // launchers fire at jets
00393         if( m_primaryTarget==-1 ) return;
00394         if( BS->groups[m_primaryTarget].m_numUnits == 0 )                                       // need new target
00395         {
00396                 m_primaryTarget = -1;
00397                 return;
00398         }
00399         if(m_targetGroups.size()==0)  return;
00400 
00401         BattleGroup &targetGroup = BS->groups[m_primaryTarget];
00402         if( targetGroup.m_numUnits <= 0 ) return;
00403 
00404         bool isActive = false;                                          // if this battle is active (player's watching it)
00405         if( GameState::activeBattle() )
00406                 if( GameState::activeBattle()->getBSPtr() == BS ) isActive = true;      
00407         float vol = Sound::getMasterSFXVol();
00408         if( !isActive ) vol *= 0.92f;
00409         Vec3D playerCol( GameState::consolePlayer()->color() );
00410         if( BS->teamAColor!=playerCol && BS->teamBColor!=playerCol ) vol = 0.0f;
00411 
00412         const bool hasTurretArray[5] = { true, true, false, true, false };
00413         bool hasTurret = hasTurretArray[ m_unitType];
00414         FLOAT firingArc = BattleUnitData::getObj().firingArc()[m_unitType];
00415 
00416         for( int i=0; i<m_unitArraySize; i++ )
00417         {
00418                 BattleUnit &b = m_units[i];
00419                 if( b.m_health<=0 ) continue;
00420                 if( b.m_firingDelay>0 ) continue;
00421                 if( sys_randInt()%10 < 9 ) continue;            // add randomness so that not everyone fires at the same time
00422 
00423                 int targetNum = sys_randInt() % targetGroup.m_unitArraySize;
00424                 int attempt = 12;
00425                 while( targetGroup.m_units[targetNum].m_health <= 0 && attempt-->0 )
00426                         targetNum = (targetNum+1) % targetGroup.m_unitArraySize;
00427                 if( attempt <= 0 ) continue;                                                    // can't find a non-dead target
00428 
00429                 BattleUnit &target = targetGroup.m_units[targetNum];
00430                 
00431                 FLOAT targetDir = math_getDir( b.m_pos, target.m_pos );                 // check if in firing arc + rotate turret
00432                 FLOAT turretDir = b.m_dir.x + b.m_turretDir.x;
00433                 FLOAT deltaDir = math_deltaDir( turretDir, targetDir );
00434                 if( hasTurret )
00435                 {
00436                         const FLOAT turretArc = 5.0f;
00437                         const FLOAT turretTurnRate = 3.0f;
00438                         if( deltaDir < -turretArc || deltaDir > turretArc )                             // rotate turret
00439                         {
00440                                 deltaDir = min(deltaDir,turretTurnRate);
00441                                 deltaDir = max(deltaDir,-turretTurnRate);
00442                                 b.m_turretDir.x += deltaDir;
00443                                 b.m_turretDir.x = min( b.m_turretDir.x, firingArc );
00444                                 b.m_turretDir.x = max( b.m_turretDir.x, -firingArc );
00445                                 continue;
00446                         }
00447                 }
00448                 else
00449                 {
00450                         if( deltaDir < -firingArc || deltaDir > firingArc ) continue;           // out of firing arc
00451                 }
00452 
00453                 if( math_distPlanar3D(b.m_pos, target.m_pos) > m_statFiringRange ) continue;    // only fire if in range
00454 
00455                 if( m_color == GameState::consolePlayer()->color() )  playVoiceContact(*BS,isActive);
00456                 
00457                 if( BS->synch_firstShotTick == -1 )
00458                 {
00459                         BS->synch_firstShotTick = currGameTick;
00460                         sys_console() << "BATTLE First Shot Fired at tick = " << currGameTick << endl;
00461                 }       
00462                 
00463                 //sys_console() << "BATTLE Firing pos=" << b.m_pos.x << ' ' << b.m_pos.y << ' ' << b.m_pos.z
00464                 //                        << " turret = " << b.m_turretDir.x << endl;
00465 
00466                 Vec3D bulletPos = b.m_pos;
00467                 bulletPos.z += terrain_getHeight( BS->terrain, b.m_pos.x, b.m_pos.y );
00468                 Vec3D targetPos = target.m_pos;
00469                 targetPos.z += terrain_getHeight( BS->terrain, target.m_pos.x, target.m_pos.y );
00470 
00471                 switch(m_unitType)
00472                 {
00473                 case UnitTypes::LIGHT_TANK :
00474                         {
00475                                 target.m_health -= BattleUnitData::getObj().baseDamage()[m_unitType];
00476                                 target.m_recvHits[ target.m_recvHitIndex ] = RecvHitEntry( b.m_pos, BattleUnitData::getObj().lightTankHitFlareTime() );
00477                                 target.m_recvHitIndex = (target.m_recvHitIndex+1) % MAX_RECV_HIT;
00478                                 if( target.m_health<=0 )
00479                                 {
00480                                         destroyUnit(target);                                    
00481                                         targetGroup.m_numUnits--;
00482                                 }
00483                                 b.m_firingDelay = BattleUnitData::getObj().firingDelay()[ m_unitType ];
00484                                 Sound::play(Sound::SMPL_SFX_FIRE_LIGHTTANK,vol);
00485                         }
00486                         break;
00487 
00488                 case UnitTypes::HEAVY_TANK :
00489                         {
00490                                 target.m_health -= BattleUnitData::getObj().baseDamage()[m_unitType];
00491                                 target.m_recvHits[ target.m_recvHitIndex ] = RecvHitEntry( b.m_pos, BattleUnitData::getObj().lightTankHitFlareTime() );
00492                                 target.m_recvHitIndex = (target.m_recvHitIndex+1) % MAX_RECV_HIT;
00493                                 if( target.m_health<=0 )
00494                                 {
00495                                         destroyUnit(target);
00496                                         targetGroup.m_numUnits--;
00497                                 }
00498                                 b.m_firingDelay = BattleUnitData::getObj().firingDelay()[ m_unitType ];
00499                                 Sound::play(Sound::SMPL_SFX_FIRE_LIGHTTANK,vol);
00500                         }
00501                         break;
00502 
00503                 case UnitTypes::LAUNCHER :
00504                         {
00505                                 BS->addBullet( BattleBullet( BulletTypes::ROCKET, m_team, m_primaryTarget, bulletPos, targetPos ));
00506                                 b.m_firingDelay = BattleUnitData::getObj().firingDelay()[ m_unitType ];
00507                                 Sound::play(Sound::SMPL_SFX_FIRE_LAUNCHER,vol);
00508                         }
00509                         break;
00510 
00511                 case UnitTypes::ARTILLERY :
00512                         {                               
00513                                 BS->addBullet( BattleBullet( BulletTypes::SHELL, m_team, m_primaryTarget, bulletPos, targetPos ));
00514                                 b.m_firingDelay = BattleUnitData::getObj().firingDelay()[ m_unitType ];
00515                                 Sound::play(Sound::SMPL_SFX_FIRE_ARTILLERY,vol);
00516                         }
00517                         break;
00518 
00519                 case UnitTypes::JET :                   
00520                         break;
00521                         
00522                 }
00523                 
00524         }       
00525 }

void BattleGroup::fireAntiAir  
 

for launchers. check if there's any enemy jets nearby. if yes, try to shoot it down

Definition at line 367 of file BattleGroup.cpp.

References BattleState::addBullet(), BS, BattleUnitData::firingDelay(), Singleton< BattleUnitData >::getObj(), BattleState::jets, BattleUnit::m_firingDelay, BattleUnit::m_health, BattleUnit::m_pos, BattleJets::m_pos, m_unitArraySize, m_units, math_distPlanar3D(), sys_randInt(), BattleState::terrain, terrain_getHeight(), UINT, and Vec3D.

00368 {
00369         for( UINT i=0; i<BS->jets.size(); i++ )
00370         {
00371                 BattleJets &J = BS->jets[i];
00372                 if( math_distPlanar3D( m_pos, J.m_pos) < 100.0f )
00373                 {
00374                         for( int i=0; i<m_unitArraySize; i++ )
00375                         {
00376                                 BattleUnit &b = m_units[i];
00377                                 if( b.m_health<=0 ) continue;
00378                                 if( b.m_firingDelay>0 ) continue;
00379                                 if( sys_randInt()%10 < 9 ) continue;
00380                                 Vec3D bulletPos = b.m_pos;
00381                                 bulletPos.z += terrain_getHeight( BS->terrain, b.m_pos.x, b.m_pos.y );
00382                                 BS->addBullet( BattleBullet( BulletTypes::ANTIAIR, m_team, i, bulletPos, J.m_pos ));
00383                                 b.m_firingDelay = BattleUnitData::getObj().firingDelay()[ UnitTypes::LAUNCHER ];
00384                         }
00385                 }
00386         }
00387 }

bool BattleGroup::isContain2DPoint Vec2D    pt
 

Definition at line 557 of file BattleGroup.cpp.

References BS, m_numUnits, m_size, math_translateObjectToWorld(), math_translateWorldToScreen(), BattleState::terrain, terrain_getHeight(), triArea(), Vec2D, and Vec3D.

00558 {
00559         if(m_numUnits==0) return false;
00560 
00561         // calc the 4 corner pts of the box
00562         Vec3D halfSize = m_size * 0.5f;
00563         Vec3D pt3D1 = math_translateObjectToWorld( m_pos, m_dir, Vec3D( -halfSize.x, -halfSize.y,0.0f) );
00564         Vec3D pt3D2 = math_translateObjectToWorld( m_pos, m_dir, Vec3D( +halfSize.x, -halfSize.y,0.0f) );
00565         Vec3D pt3D3 = math_translateObjectToWorld( m_pos, m_dir, Vec3D( +halfSize.x, +halfSize.y,0.0f) );
00566         Vec3D pt3D4 = math_translateObjectToWorld( m_pos, m_dir, Vec3D( -halfSize.x, +halfSize.y,0.0f) );
00567         pt3D1.z += terrain_getHeight( BS->terrain, pt3D1.x, pt3D1.y );
00568         pt3D2.z += terrain_getHeight( BS->terrain, pt3D2.x, pt3D2.y );
00569         pt3D3.z += terrain_getHeight( BS->terrain, pt3D3.x, pt3D3.y );
00570         pt3D4.z += terrain_getHeight( BS->terrain, pt3D4.x, pt3D4.y );
00571         Vec2D pt2D1 = math_translateWorldToScreen(pt3D1);
00572         Vec2D pt2D2 = math_translateWorldToScreen(pt3D2);
00573         Vec2D pt2D3 = math_translateWorldToScreen(pt3D3);
00574         Vec2D pt2D4 = math_translateWorldToScreen(pt3D4);
00575         int outsideCount = 0;
00576         if( pt2D1.x<0 || pt2D1.x>1 || pt2D1.y<0 || pt2D1.y>1 ) outsideCount++;
00577         if( pt2D2.x<0 || pt2D2.x>1 || pt2D2.y<0 || pt2D2.y>1 ) outsideCount++;
00578         if( pt2D3.x<0 || pt2D3.x>1 || pt2D3.y<0 || pt2D3.y>1 ) outsideCount++;
00579         if( pt2D4.x<0 || pt2D4.x>1 || pt2D4.y<0 || pt2D4.y>1 ) outsideCount++;
00580         if(outsideCount==4) return false;
00581         FLOAT triAreas = triArea(pt2D1,pt2D2,pt) + triArea(pt2D2,pt2D3,pt)
00582                            + triArea(pt2D3,pt2D4,pt) + triArea(pt2D4,pt2D1,pt);
00583         FLOAT rectArea = triArea(pt2D1,pt2D2,pt2D3) + triArea(pt2D3,pt2D4,pt2D1);
00584         return triAreas <= rectArea * 1.05f;
00585 }

void BattleGroup::moveBattleGroup  
 

move the entire BG entity to its destination (if any)

Definition at line 124 of file BattleGroup.cpp.

References absf, BattleUnitData::BGFullSpeed(), BattleUnitData::BGHalfSpeed(), BattleUnitData::BGTurnRate(), BS, clipAngle(), Singleton< BattleUnitData >::getObj(), BattleState::groups, m_dir, m_isChasePrimaryTarget, m_maxUnitDist, m_numUnits, m_pos, m_primaryTarget, m_unitType, m_waypoints, math_dist3D(), and Vec3D.

00125 {
00126         // TEMP DEBUG INFO
00127         //sys_console() << "BG " << m_pos.x << ' ' << m_pos.y << ' ' << terrain_getHeight(BS->terrain,m_pos.x,m_pos.y)
00128         //                << ' ' << m_dir.x << endl;
00129 
00130 
00131         if(m_numUnits==0) return;
00132 
00133         if( m_primaryTarget!=-1 && m_isChasePrimaryTarget )                                     // home in on primary target
00134         {
00135                 Vec3D pt( BS->groups[ m_primaryTarget ].m_pos );
00136                 m_waypoints.resize(0);
00137                 m_waypoints.push_back(pt);
00138         }
00139 
00140         if( m_waypoints.size() == 0 ) return;
00141         
00142         Vec3D targetVec = m_waypoints[0] - m_pos;
00143         FLOAT targetDir = clipAngle( 90-D3DXToDegree( atan2f( targetVec.x, targetVec.y ) ) );
00144         FLOAT currentDir = m_dir[0];
00145         FLOAT delta;                            // signed (+CW,-CCW) smallest-magnitude difference in angle
00146         if( targetDir<0.0f ) targetDir += 360.0f;
00147         else if( targetDir>=360.0f ) targetDir -= 360.0f;
00148         if(targetDir>currentDir)
00149         {
00150                 delta = targetDir - currentDir;
00151                 if(delta>180.0f) delta = delta - 360.0f;
00152         }
00153         else
00154         {
00155                 delta = targetDir - currentDir;
00156                 if(delta<-180.0f) delta = 360.0f - delta;
00157         }               
00158         
00159         const FLOAT turnRate = BattleUnitData::getObj().BGTurnRate()[m_unitType];
00160         FLOAT turnAngle = delta;
00161         if( delta > turnRate ) turnAngle = turnRate;
00162         else if( delta < -turnRate ) turnAngle = -turnRate;
00163         else turnAngle = delta;
00164         m_dir[0] = clipAngle( currentDir + turnAngle );                         // turn
00165 
00166         // move if we're heading roughly the right way
00167         FLOAT speed = 0.0f;
00168         if( absf(delta)<10.0f ) speed = BattleUnitData::getObj().BGFullSpeed()[m_unitType];
00169         else if( absf(delta)<30.0f ) speed = BattleUnitData::getObj().BGHalfSpeed()[m_unitType];
00170         
00171         if( m_maxUnitDist > 4.0f ) speed = speed * 0.25f;       // slow down if units are out of formation
00172 
00173         if(speed>0.0f)
00174         {
00175                 FLOAT rad = D3DXToRadian( m_dir[0] );
00176                 m_pos += speed * Vec3D( cosf(rad), sinf(rad), 0.0f );
00177 
00178                 // delete waypoint once we reach it
00179                 if( math_dist3D(m_pos,m_waypoints[0]) < 1.0f )
00180                         m_waypoints.erase( m_waypoints.begin() );
00181         }
00182 }

void BattleGroup::moveUnits  
 

move the individual units in this BG to its appropriate pos in the BG

Definition at line 184 of file BattleGroup.cpp.

References absf, clipAngle(), BattleUnitData::fullSpeed(), Singleton< BattleUnitData >::getObj(), BattleUnitData::halfSpeed(), m_dir, BattleUnit::m_dir, BattleUnit::m_firingDelay, BattleUnit::m_health, m_maxUnitDist, m_numUnits, BattleUnit::m_pos, BattleUnit::m_recvHits, m_size, BattleUnit::m_target, m_unitArraySize, m_units, m_unitType, math_dist3D(), math_translateObjectToWorld(), MAX_RECV_HIT, BattleUnitData::numCols(), BattleUnitData::numRows(), RecvHitEntry::timeRemaining, BattleUnitData::turnRate(), and Vec3D.

00185 {
00186         if(m_numUnits==0) return;
00187 
00188         // update each unit's target
00189         Vec3D halfSize = m_size * 0.5f;
00190         int rows = BattleUnitData::getObj().numRows()[m_unitType];
00191         int cols = BattleUnitData::getObj().numCols()[m_unitType];
00192         FLOAT backDelta  = m_size.x / rows;
00193         FLOAT rightDelta = m_size.y / cols;
00194         Vec3D frontLeftPt = math_translateObjectToWorld( m_pos, m_dir, Vec3D( halfSize.x,halfSize.y,0.0f) );
00195         Vec3D backVec     = math_translateObjectToWorld( m_pos, m_dir, Vec3D( halfSize.x-backDelta,halfSize.y,0.0f) ) - frontLeftPt;
00196         Vec3D rightVec    = math_translateObjectToWorld( m_pos, m_dir, Vec3D( halfSize.x,halfSize.y-rightDelta,0.0f) ) - frontLeftPt;
00197         for( int i=0; i<m_unitArraySize; i++ )
00198         {
00199                 FLOAT col = (FLOAT)(i%cols) + 0.5f;
00200                 FLOAT row = (FLOAT)(i/cols) + 0.5f;             
00201                 m_units[i].m_target = frontLeftPt + backVec*row + rightVec*col;
00202         }
00203 
00204         m_maxUnitDist = 0.0f;
00205         for( int i=0; i<m_unitArraySize; i++ )
00206         {
00207                 BattleUnit &u = m_units[i];
00208                 if( u.m_health<=0 ) continue;
00209 
00210                 // dec firing delay
00211                 u.m_firingDelay--;
00212 
00213                 // dec hit flare time
00214                 for( int i=0; i<MAX_RECV_HIT; i++ )             
00215                         u.m_recvHits[i].timeRemaining--;
00216 
00217                 FLOAT dist = math_dist3D(u.m_pos, u.m_target);
00218                 if( dist > m_maxUnitDist ) m_maxUnitDist = dist;
00219                 if( dist > 0.1f )
00220                 {
00221                         Vec3D targetVec = u.m_target - u.m_pos;
00222                         FLOAT targetDir = clipAngle( 90-D3DXToDegree( atan2f(targetVec.x,targetVec.y) ));
00223                         FLOAT currentDir = u.m_dir[0];
00224                         FLOAT delta;
00225                         if(targetDir>currentDir)
00226                         {
00227                                 delta = targetDir - currentDir;
00228                                 if(delta>180.0f) delta = delta - 360.0f;
00229                         }
00230                         else
00231                         {
00232                                 delta = targetDir - currentDir;
00233                                 if(delta<-180.0f) delta = 360.0f - delta;
00234                         }
00235                         const FLOAT turnRate = BattleUnitData::getObj().turnRate()[m_unitType];
00236                         FLOAT turnAngle = delta;
00237                         if( delta > turnRate ) turnAngle = turnRate;
00238                         else if( delta < -turnRate ) turnAngle = -turnRate;
00239                         else turnAngle = delta;
00240                         u.m_dir[0] = clipAngle( currentDir + turnAngle );                               // turn
00241 
00242                         // move if we're heading roughly the right way
00243                         FLOAT speed = 0.0f;
00244                         if( absf(delta)<10.0f ) speed = BattleUnitData::getObj().fullSpeed()[m_unitType];
00245                         else if( absf(delta)<30.0f ) speed = BattleUnitData::getObj().halfSpeed()[m_unitType];
00246                         if(speed>0.0f)
00247                         {
00248                                 FLOAT rad = D3DXToRadian( u.m_dir[0] );
00249                                 u.m_pos += speed * Vec3D( cosf(rad), sinf(rad), 0.0f );
00250                         }                       
00251                 }
00252                 else            // we're already close enough to target
00253                 {
00254                         u.m_dir = u.m_dir*0.99f + m_dir*0.01f;
00255                 }
00256         }
00257 }

void BattleGroup::render  
 

Definition at line 610 of file BattleGroup.cpp.

References AMesh, BattleUnitData::artillerySize(), BattleUnitData::artilleryTurretSize(), Globals::artWork, ATexture, BS, camera_getVec(), BattleUnitData::firingDelay(), flare_addParticle(), RecvHitEntry::from, Singleton< BattleUnitData >::getObj(), BattleState::groups, BattleUnitData::heavyTankSize(), BattleUnitData::heavyTankTurretSize(), BattleUnitData::jetSize(), BattleUnitData::launcherSize(), BattleUnitData::lightTankSize(), BattleUnitData::lightTankTurretSize(), BattleUnit::m_dir, BattleUnit::m_firingDelay, BattleUnit::m_health, m_numUnits, m_pos, BattleUnit::m_pos, m_primaryTarget, BattleUnit::m_recvHits, BattleUnit::m_turretDir, m_unitArraySize, m_units, m_unitType, m_waypoints, math_translateWorldToScreen(), MAX_RECV_HIT, mesh_render(), overlay_line(), overlay_point(), sprite_add(), BattleState::terrain, terrain_getHeight(), RecvHitEntry::timeRemaining, UINT, Vec2D, Vec3D, and Vec4D.

00611 {
00612         if( m_numUnits<=0 ) return;
00613         
00614         AMesh chasis=-1, turret=-1;
00615         ATexture texture=-1;
00616         Vec3D chasisSize, turretSize;
00617         Vec3D shadowVec = camera_getVec();                      // offset for shadow position
00618         FLOAT shadowSize;
00619         shadowVec.z = 0.0f;
00620 
00621         switch(m_unitType)
00622         {
00623         case UnitTypes::LIGHT_TANK :
00624                 chasis     = artWork->lightTank_mesh;
00625                 turret     = artWork->lightTankTurret_mesh;
00626                 texture    = artWork->lightTank_texture;
00627                 chasisSize = BattleUnitData::getObj().lightTankSize();
00628                 turretSize = BattleUnitData::getObj().lightTankTurretSize();
00629                 shadowSize = 6.0f;
00630                 break;
00631         case UnitTypes::HEAVY_TANK :
00632                 chasis     = artWork->heavyTank_mesh;
00633                 turret     = artWork->heavyTankTurret_mesh;
00634                 texture    = artWork->heavyTank_texture;
00635                 chasisSize = BattleUnitData::getObj().heavyTankSize();
00636                 turretSize = BattleUnitData::getObj().heavyTankTurretSize();
00637                 shadowSize = 7.0f;
00638                 break;
00639         case UnitTypes::LAUNCHER :
00640                 chasis     = artWork->launcher_mesh;
00641                 texture    = artWork->launcher_texture;
00642                 chasisSize = BattleUnitData::getObj().launcherSize();
00643                 shadowSize = 6.0f;
00644                 break;
00645         case UnitTypes::ARTILLERY :
00646                 chasis     = artWork->artillery_mesh;
00647                 turret     = artWork->artilleryTurret_mesh;
00648                 texture    = artWork->artillery_texture;
00649                 chasisSize = BattleUnitData::getObj().artillerySize();
00650                 turretSize = BattleUnitData::getObj().artilleryTurretSize();
00651                 shadowSize = 6.0f;
00652                 break;
00653         case UnitTypes::JET :
00654                 chasis     = artWork->jet_mesh;
00655                 texture    = artWork->jet_texture;
00656                 chasisSize = BattleUnitData::getObj().jetSize();
00657                 shadowSize = 6.0f;
00658                 break;
00659         }
00660 
00661 
00662         for( int i=0; i<m_unitArraySize; i++ )
00663         {
00664                 BattleUnit &u = m_units[i];
00665                 if( u.m_health<=0 ) continue;
00666                 Vec3D pos = u.m_pos;
00667                 pos.z += 0.32f + terrain_getHeight(BS->terrain,pos.x, pos.y);
00668                 
00669                 // chasis & (optional) turret
00670                 mesh_render( chasis, pos, chasisSize, u.m_dir, texture, NULL, m_color );
00671                 if(turret!=-1) mesh_render( turret, pos, turretSize, u.m_dir+u.m_turretDir, texture, NULL, m_color );
00672 
00673                 // unit shadow          
00674                 const Vec4D mult(1,1,1,0.33f);
00675                 sprite_add(artWork->shadow, BlendModes::MIX, pos+shadowVec, mult, shadowSize );
00676 
00677                 // firing flare
00678                 const Vec4D noBlend(1.0f,1.0f,1.0f,1.0f);
00679                 int fireDelay = BattleUnitData::getObj().firingDelay()[ m_unitType];
00680                 if( (m_unitType==UnitTypes::LIGHT_TANK && u.m_firingDelay > fireDelay-5) ||
00681                         (m_unitType==UnitTypes::HEAVY_TANK && u.m_firingDelay > fireDelay-5) )
00682                 {                       
00683                         FLOAT rad = D3DXToRadian( u.m_dir[0] );
00684                         Vec3D target = pos + Vec3D( cosf(rad), sinf(rad), 0.5f );
00685                         flare_addParticle( pos, target, noBlend, 3.0f, 0.3f*(fireDelay-u.m_firingDelay) );
00686                         flare_addParticle( pos, target, noBlend, 5.0f, 0.5f*(fireDelay-u.m_firingDelay) );
00687                 }
00688 
00689                 // hit flare
00690                 for( int i=0; i<MAX_RECV_HIT; i++ )
00691                 {
00692                         static Vec4D mult(1,1,1,1);
00693                         RecvHitEntry &e = u.m_recvHits[i];
00694                         mult.w = (20.0f-e.timeRemaining) / 32.0f;
00695                         if( e.timeRemaining > 0 )
00696                                 flare_addParticle( pos, e.from, mult, 2.0f, 6.0f );
00697                 }
00698         }
00699 
00700         // battle group icon
00701         //mesh_render( artWork->battleGroupMesh, m_pos - Vec3D(0.0f,0.0f,0.6f), m_size,m_dir, artWork->battleGroupTexture );
00702         
00703         Vec3D prevPt = m_pos;                                                                                   // waypoints
00704         for( UINT i=0; i<m_waypoints.size(); i++ )
00705         {
00706                 Vec3D pt13D(prevPt), pt23D(m_waypoints[i]), pt33D(m_waypoints[i]);
00707                 pt13D.z += terrain_getHeight(BS->terrain, pt13D.x, pt13D.y );
00708                 pt23D.z += terrain_getHeight(BS->terrain, pt23D.x, pt23D.y );
00709                 Vec2D pt1 = math_translateWorldToScreen( pt13D );
00710                 Vec2D pt2 = math_translateWorldToScreen( pt23D );
00711                 Vec2D pt3 = math_translateWorldToScreen( pt33D );
00712                 overlay_line( pt1, pt2, Colors::green );
00713                 overlay_line( pt2, pt3, Colors::gray );
00714                 overlay_point( pt2, 2.0f, Colors::red );
00715                 prevPt = m_waypoints[i];
00716         }
00717 
00718         // primary target
00719         if( m_primaryTarget!=-1 )
00720         {
00721                 Vec3D pt13D( m_pos );
00722                 pt13D.z += terrain_getHeight(BS->terrain, pt13D.x, pt13D.y );
00723                 Vec2D pt1 = math_translateWorldToScreen( pt13D );
00724         
00725                 Vec3D pt23D( BS->groups[ m_primaryTarget ].m_pos );
00726                 pt23D.z += terrain_getHeight(BS->terrain, pt23D.x, pt23D.y );
00727                 Vec2D pt2 = math_translateWorldToScreen( pt23D );
00728                 overlay_line( pt1, pt2, Colors::red );
00729         }
00730 }

void BattleGroup::takeHit const BattleBullet   b
 

checks each unit in BG if it's hit by the bullet. apply damage accordingly

Definition at line 527 of file BattleGroup.cpp.

References BS, destroyUnit(), BattleUnit::m_health, m_numUnits, BattleUnit::m_pos, BattleBullet::m_pos, BattleUnit::m_recvHitIndex, BattleUnit::m_recvHits, BattleBullet::m_type, m_unitArraySize, m_units, MAX_RECV_HIT, BattleState::sprites, and Vec3D.

00528 {
00529         if(b.m_type==BulletTypes::SHELL)
00530                 BS->sprites.push_back( BattleSprite( b.m_pos, 15,  BattleSpriteTypes::ARTIL_SHELL ));
00531 
00532         if(m_numUnits==0) return;
00533 
00534         for( int i=0; i<m_unitArraySize; i++ )
00535         {
00536                 BattleUnit &u = m_units[i];
00537                 if( u.m_health<=0 ) continue;
00538 
00539                 Vec3D delta = u.m_pos - b.m_pos;
00540                 FLOAT dist = sqrtf( delta.x*delta.x + delta.y*delta.y );
00541                 if( dist<8.0f )
00542                 {
00543                         u.m_health -= 50000;
00544                         u.m_recvHits[ u.m_recvHitIndex ] = RecvHitEntry( b.m_pos, 20 );
00545                         u.m_recvHitIndex = (u.m_recvHitIndex+1) % MAX_RECV_HIT;
00546                         if( u.m_health<=0 )
00547                         {
00548                                 destroyUnit(u);
00549                                 m_numUnits--;
00550                         }
00551                 }               
00552         }
00553 }


Member Data Documentation

BattleState* BattleGroup::BS
 

Definition at line 74 of file BattleGroup.h.

Referenced by acquireGroupTargets(), destroyUnit(), drawOutlineBox(), fire(), fireAntiAir(), isContain2DPoint(), moveBattleGroup(), render(), and takeHit().

Vec3D BattleGroup::m_color
 

Definition at line 77 of file BattleGroup.h.

Referenced by BattleGroup(), BattleEntry::countGroupsBelongingToPlayer(), destroyUnit(), fire(), BattleEntry::maySendGroundReinforcement(), BattleEntry::renderGroups(), BattleEntry::renderInterface(), and BattleEntry::renderMiniMap().

Vec3D BattleGroup::m_dir
 

Definition at line 77 of file BattleGroup.h.

Referenced by acquireGroupTargets(), BattleGroup(), moveBattleGroup(), moveUnits(), and BattleEntry::renderMiniMap().

bool BattleGroup::m_isChasePrimaryTarget
 

Definition at line 92 of file BattleGroup.h.

Referenced by acquireGroupTargets(), BattleGroup(), moveBattleGroup(), and BattleEntry::processQueuedInput().

bool BattleGroup::m_isStrictPrimaryTarget
 

Definition at line 93 of file BattleGroup.h.

Referenced by acquireGroupTargets(), BattleGroup(), and BattleEntry::processQueuedInput().

FLOAT BattleGroup::m_maxUnitDist
 

Definition at line 83 of file BattleGroup.h.

Referenced by moveBattleGroup(), and moveUnits().

int BattleGroup::m_numUnits
 

Definition at line 81 of file BattleGroup.h.

Referenced by acquireGroupTargets(), BattleGroup(), BattleEntry::countGroupsBelongingToPlayer(), destroyUnit(), drawOutlineBox(), fire(), BattleEntry::isBattleFinished(), isContain2DPoint(), BattleEntry::maySendGroundReinforcement(), moveBattleGroup(), moveUnits(), render(), BattleEntry::renderMiniMap(), and takeHit().

int BattleGroup::m_overheadForceNumber
 

Definition at line 96 of file BattleGroup.h.

Referenced by BattleGroup(), and BattleEntry::isBattleFinished().

Vec3D BattleGroup::m_pos
 

Definition at line 77 of file BattleGroup.h.

Referenced by acquireGroupTargets(), BattleGroup(), moveBattleGroup(), render(), BattleEntry::renderGroups(), and BattleEntry::renderMiniMap().

int BattleGroup::m_primaryTarget
 

Definition at line 91 of file BattleGroup.h.

Referenced by acquireGroupTargets(), BattleGroup(), fire(), moveBattleGroup(), BattleEntry::processQueuedInput(), and render().

Vec3D BattleGroup::m_size
 

Definition at line 77 of file BattleGroup.h.

Referenced by BattleGroup(), drawOutlineBox(), isContain2DPoint(), and moveUnits().

FLOAT BattleGroup::m_statFiringRange
 

Definition at line 89 of file BattleGroup.h.

Referenced by acquireGroupTargets(), BattleGroup(), and fire().

vector<int> BattleGroup::m_targetGroups
 

Definition at line 86 of file BattleGroup.h.

Referenced by acquireGroupTargets(), and fire().

char BattleGroup::m_team
 

Definition at line 76 of file BattleGroup.h.

Referenced by acquireGroupTargets(), BattleGroup(), and BattleEntry::isBattleFinished().

int BattleGroup::m_unitArraySize
 

Definition at line 79 of file BattleGroup.h.

Referenced by BattleGroup(), fire(), fireAntiAir(), moveUnits(), render(), and takeHit().

BattleUnit BattleGroup::m_units[MAX_UNIT]
 

Definition at line 87 of file BattleGroup.h.

Referenced by BattleGroup(), fire(), fireAntiAir(), moveUnits(), render(), and takeHit().

int BattleGroup::m_unitType
 

Definition at line 78 of file BattleGroup.h.

Referenced by acquireGroupTargets(), BattleGroup(), fire(), BattleEntry::isBattleFinished(), moveBattleGroup(), moveUnits(), render(), and BattleEntry::renderMiniMap().

vector<Vec3D> BattleGroup::m_waypoints
 

Definition at line 85 of file BattleGroup.h.

Referenced by addWaypoint(), moveBattleGroup(), BattleEntry::processQueuedInput(), and render().


The documentation for this class was generated from the following files:
Generated on Wed Apr 23 05:52:01 2003 for Modern Warfare by doxygen1.3-rc2