home *** CD-ROM | disk | FTP | other *** search
/ PC Format (South-Africa) 2001 June / PCFJune.iso / Xenon / XenonSource.exe / xenon / source / ship.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  2000-09-13  |  16.8 KB  |  736 lines

  1. //-------------------------------------------------------------
  2. //
  3. // Class:    Ship
  4. //
  5. // Author:    John M Phillips
  6. //
  7. // Started:    06/05/00
  8. //
  9. // Base:    CActor
  10. //
  11. // Derived:    None
  12. //
  13. //-------------------------------------------------------------
  14.  
  15. #include "game.h"
  16.  
  17. //-------------------------------------------------------------
  18.  
  19. CShip::CShip()
  20. {
  21.     m_weapon = 0;
  22.     m_weapon_type = NO_WEAPON;
  23.  
  24.     m_left_clone = 0;
  25.     m_right_clone = 0;
  26.     m_left_wingtip = 0;
  27.     m_right_wingtip = 0;
  28.     m_left_engine = 0;
  29.     m_right_engine = 0;
  30.     m_retro_nw = 0;
  31.     m_retro_ne = 0;
  32.     m_retro_sw = 0;
  33.     m_retro_se = 0;
  34.  
  35.     m_cloak_time_limit = 0.f;
  36.  
  37.     m_dive_mode = DIVE_OFF;
  38.     m_dive_level = 0;
  39. }
  40.  
  41. //-------------------------------------------------------------
  42.  
  43. CShip::~CShip()
  44. {
  45. //    CActor::~CActor();
  46. }
  47.  
  48. //-------------------------------------------------------------
  49.  
  50. bool CShip::activate()
  51. {
  52.     if (!isActive()) {
  53.         setHandling(HANDLING_NORMAL);
  54.  
  55.         m_roll = 0;
  56.         setWeapon(NO_WEAPON);
  57.         setVelocity(gsCVector(0.f,0.f));
  58.  
  59.         m_left_engine = new CShipEngine;
  60.         m_scene->addActor(m_left_engine);
  61.         m_left_engine->activate();
  62.         m_left_engine->setOwner(this);
  63.         m_left_engine->setOffset(gsCVector(-7.f,29.f));
  64.         m_left_engine->setParams(gsCVector(0.f,-16.f),gsCVector(0.f,0.f),0.05f);
  65.  
  66.         m_right_engine = new CShipEngine;
  67.         m_scene->addActor(m_right_engine);
  68.         m_right_engine->activate();
  69.         m_right_engine->setOwner(this);
  70.         m_right_engine->setOffset(gsCVector(7.f,29.f));
  71.         m_right_engine->setParams(gsCVector(0.f,-16.f),gsCVector(0.f,0.f),0.05f);
  72.  
  73.         m_retro_nw = new CRetroEngine;
  74.         m_scene->addActor(m_retro_nw);
  75.         m_retro_nw->activate();
  76.         m_retro_nw->setOwner(this);
  77.         m_retro_nw->setOffset(gsCVector(-30.f,-20.f));
  78.         m_retro_nw->setDirection(RETRO_NW);
  79.         m_retro_nw->setParams(gsCVector(12.f,12.f),gsCVector(0.f,0.f),0.05f);
  80.  
  81.         m_retro_ne = new CRetroEngine;
  82.         m_scene->addActor(m_retro_ne);
  83.         m_retro_ne->activate();
  84.         m_retro_ne->setOwner(this);
  85.         m_retro_ne->setOffset(gsCVector(30.f,-20.f));
  86.         m_retro_ne->setDirection(RETRO_NE);
  87.         m_retro_ne->setParams(gsCVector(-12.f,12.f),gsCVector(0.f,0.f),0.05f);
  88.  
  89.         m_retro_sw = new CRetroEngine;
  90.         m_scene->addActor(m_retro_sw);
  91.         m_retro_sw->activate();
  92.         m_retro_sw->setOwner(this);
  93.         m_retro_sw->setOffset(gsCVector(-30.f,30.f));
  94.         m_retro_sw->setDirection(RETRO_SW);
  95.         m_retro_sw->setParams(gsCVector(12.f,-12.f),gsCVector(0.f,0.f),0.05f);
  96.  
  97.         m_retro_se = new CRetroEngine;
  98.         m_scene->addActor(m_retro_se);
  99.         m_retro_se->activate();
  100.         m_retro_se->setOwner(this);
  101.         m_retro_se->setOffset(gsCVector(30.f,30.f));
  102.         m_retro_se->setDirection(RETRO_SE);
  103.         m_retro_se->setParams(gsCVector(-12.f,-12.f),gsCVector(0.f,0.f),0.05f);
  104.  
  105.         m_timer.reset();
  106.  
  107.         setCloak(2.f);
  108.  
  109.         m_dive_mode = DIVE_OFF;
  110.         m_dive_level = 0;
  111.         }
  112.  
  113.     return CActor::activate();
  114. }
  115.  
  116. //-------------------------------------------------------------
  117.  
  118. void CShip::explode()
  119. {
  120.     if (m_left_clone)
  121.         m_left_clone->explode();
  122.     if (m_right_clone)
  123.         m_right_clone->explode();
  124.     if (m_left_wingtip)
  125.         m_left_wingtip->explode();
  126.     if (m_right_wingtip)
  127.         m_right_wingtip->explode();
  128.  
  129.     CActor::explode();
  130. }
  131.  
  132. //-------------------------------------------------------------
  133.  
  134. void CShip::kill()
  135. {
  136.     removeUpgrades();
  137.  
  138.     if (m_left_engine) {
  139.         m_left_engine->kill();
  140.         m_left_engine = 0;
  141.         }
  142.     if (m_right_engine) {
  143.         m_right_engine->kill();
  144.         m_right_engine = 0;
  145.         }
  146.     if (m_retro_nw) {
  147.         m_retro_nw->kill();
  148.         m_retro_nw = 0;
  149.         }
  150.     if (m_retro_ne) {
  151.         m_retro_ne->kill();
  152.         m_retro_ne = 0;
  153.         }
  154.     if (m_retro_sw) {
  155.         m_retro_sw->kill();
  156.         m_retro_sw = 0;
  157.         }
  158.     if (m_retro_se) {
  159.         m_retro_se->kill();
  160.         m_retro_se = 0;
  161.         }
  162.     if (m_weapon) {
  163.         m_weapon->kill();
  164.         m_weapon = 0;
  165.         }
  166.  
  167.     CActor::kill();
  168. }
  169.  
  170. //-------------------------------------------------------------
  171.  
  172. bool CShip::update(Controls *controls)
  173. {
  174.     if (m_shield == 0)
  175.         return true;
  176.  
  177.     if (m_cloak_time_limit > 0.f) {
  178.         if (m_cloak_timer.getTime() >= m_cloak_time_limit) {
  179.             m_cloak_timer.reset();
  180.             m_cloak_time_limit = 0.f;
  181.             }
  182.         }
  183.  
  184.     gsCVector thrust(0.f,0.f);
  185.  
  186.     int required_roll = 0;
  187.  
  188.     float t = gsCTimer::getDeltaTime();
  189.  
  190.     if (controls) {
  191.  
  192.         if (controls->left) {
  193.             thrust.setX(-m_acceleration);
  194.             required_roll = -SHIP_ROLL_FRAMES;
  195.             }
  196.         if (controls->right) {
  197.             thrust.setX(m_acceleration);
  198.             required_roll = SHIP_ROLL_FRAMES;
  199.             }
  200.         if (controls->up) {
  201.             thrust.setY(-m_acceleration);
  202.             }
  203.         if (controls->down) {
  204.             thrust.setY(m_acceleration);
  205.             }
  206.  
  207.         float x = m_velocity.getX();
  208.         
  209.         if (thrust.getX() != 0.f) {
  210.             x += thrust.getX() * t;
  211.             if (x < -m_max_speed)
  212.                 x = -m_max_speed;
  213.             if (x > m_max_speed)
  214.                 x = m_max_speed;
  215.             }
  216.         else {
  217.             if (x > 0.f) {
  218.                 x -= m_damping * t;
  219.                 if (x < 0.f)
  220.                     x = 0.f;
  221.                 }
  222.             else {
  223.                 x += m_damping * t;
  224.                 if (x > 0.f)
  225.                     x = 0.f;
  226.                 }
  227.             }
  228.  
  229.         float y = m_velocity.getY();
  230.         
  231.         if (thrust.getY() != 0.f) {
  232.             y += thrust.getY() * t;
  233.             if (y < -m_max_speed)
  234.                 y = -m_max_speed;
  235.             if (y > m_max_speed)
  236.                 y = m_max_speed;
  237.             }
  238.         else {
  239.             if (y > 0.f) {
  240.                 y -= m_damping * t;
  241.                 if (y < 0.f)
  242.                     y = 0.f;
  243.                 }
  244.             else {
  245.                 y += m_damping * t;
  246.                 if (y > 0.f)
  247.                     y = 0.f;
  248.                 }
  249.             }
  250.  
  251.         m_velocity = gsCVector(x,y);
  252.         }
  253.  
  254.     m_position += m_velocity * gsCVector(t,t);
  255.  
  256.     m_position += gsCVector(0.f,(float) -CPlayGameState::getYScroll());
  257.  
  258.     int map_y = m_scene->getMap()->getPosition().getY();
  259.  
  260.     gsCScreen *screen = gsCApplication::getScreen();
  261.  
  262.     float minx = 0.f;
  263.     float maxx = (float) screen->getSize().getX();
  264.     float miny = (float) (-map_y);
  265.     float maxy = miny + (float) screen->getSize().getY();
  266.  
  267.     m_position.clamp(minx + 32.f,maxx - 32.f,miny + 32.f,maxy - 32.f);
  268.  
  269.     if (m_roll == required_roll)
  270.         m_timer.reset();
  271.     else {
  272.         if (m_timer.getState() == gsTIMER_RESET)
  273.             m_timer.start();
  274.         else {
  275.             if (m_timer.getTime() >= 1.f / SHIP_ROLL_RATE) {
  276.                 if (required_roll < m_roll)
  277.                     m_roll--;
  278.                 else
  279.                     m_roll++;
  280.                 if (m_roll != required_roll)
  281.                     m_timer.start();
  282.                 }
  283.             }
  284.         }
  285.  
  286.     switch (m_dive_mode) {
  287.         case DIVE_OFF:
  288.             if (isCloaked()) {
  289.                 if (!isCloakFlashing())
  290.                     m_sprite.setFrame(SHIP_CLOAK_OFFSET + SHIP_CENTRE_FRAME + m_roll);
  291.                 else
  292.                     m_sprite.setFrame(SHIP_CENTRE_FRAME + m_roll);
  293.                 }
  294.             else
  295.                 m_sprite.setFrame(SHIP_CENTRE_FRAME + m_roll);
  296.             m_dive_level = 0;
  297.             break;
  298.  
  299.         case DIVING_DOWN:
  300.             m_sprite.setFrame(SHIP_DIVE_OFFSET + m_dive_level);
  301.             if (m_dive_timer.getTime() >= 0.1f) {
  302.                 m_dive_level++;
  303.                 if (m_dive_level < SHIP_DIVE_FRAMES - 1)
  304.                     m_dive_timer.start();
  305.                 else {
  306.                     m_dive_timer.start();
  307.                     m_dive_mode = DIVE_ACTIVE;
  308.                     }
  309.                 }
  310.             break;
  311.  
  312.         case DIVE_ACTIVE:
  313.             m_sprite.setFrame(SHIP_DIVE_OFFSET + m_dive_level);
  314.             if (m_dive_timer.getTime() >= m_dive_time_limit) {
  315.                 m_dive_timer.start();
  316.                 m_dive_mode = DIVING_UP;
  317.                 
  318.                 CGameState::playSample(SAMPLE_DIVE_UP,getPosition().getX());
  319.                 }
  320.             break;
  321.         
  322.         case DIVING_UP:
  323.             m_sprite.setFrame(SHIP_DIVE_OFFSET + m_dive_level);
  324.             if (m_dive_timer.getTime() >= 0.1f) {
  325.                 m_dive_level--;
  326.                 if (m_dive_level >= 0)
  327.                     m_dive_timer.start();
  328.                 else
  329.                     m_dive_mode = DIVE_OFF;
  330.                 }
  331.             break;
  332.         }
  333.  
  334.     if (CPlayGameState::getYScroll() == 1) {
  335.         if (m_left_engine)
  336.             m_left_engine->applyThrust(thrust.getY() <= 0.f);
  337.         if (m_right_engine)
  338.             m_right_engine->applyThrust(thrust.getY() <= 0.f);
  339.         }
  340.     else {
  341.         if (m_left_engine)
  342.             m_left_engine->applyThrust(thrust.getY() < 0.f);
  343.         if (m_right_engine)
  344.             m_right_engine->applyThrust(thrust.getY() < 0.f);
  345.         }
  346.  
  347.     if (m_retro_nw)
  348.         m_retro_nw->applyThrust(thrust.getY() > 0.f && thrust.getX() >= 0);
  349.     if (m_retro_ne)
  350.         m_retro_ne->applyThrust(thrust.getY() > 0.f && thrust.getX() <= 0);
  351.  
  352.     if (m_retro_sw)
  353.         m_retro_sw->applyThrust((thrust.getX() > 0.f && thrust.getY() <= 0) ||
  354.                                 (thrust.getX() == 0.f && thrust.getY() < 0.f));
  355.     if (m_retro_se)
  356.         m_retro_se->applyThrust((thrust.getX() < 0.f && thrust.getY() <= 0) ||
  357.                                 (thrust.getX() == 0.f && thrust.getY() < 0.f));
  358.  
  359.     return true;
  360. }
  361.  
  362. //-------------------------------------------------------------
  363.  
  364. gsCRect CShip::getCollisionRect()
  365. {
  366.     gsCRect r = m_sprite.getRect();
  367.  
  368.     r.expand(-8);
  369.  
  370.     return r;
  371. }
  372.  
  373. //-------------------------------------------------------------
  374.  
  375. void CShip::registerHit(int energy,CActor *hitter)
  376. {
  377.     if (m_dive_mode != DIVE_OFF)
  378.         return;
  379.  
  380.     CActor::registerHit(energy,hitter);
  381. }
  382.  
  383. //-------------------------------------------------------------
  384.  
  385. void CShip::onCollisionWithActor(CActor *actor)
  386. {
  387.     if (m_dive_mode != DIVE_OFF)
  388.         return;
  389.  
  390.     switch (actor->getActorInfo().m_type) {
  391.         case ACTOR_TYPE_PICKUP:
  392.             ((CPickup *) actor)->collect();
  393.             actor->kill();
  394.             break;
  395.         case ACTOR_TYPE_ALIEN:
  396.             registerHit(1,this);
  397.             break;
  398.         }
  399. }
  400.  
  401. //-------------------------------------------------------------
  402.  
  403. void CShip::onCollisionWithMap(gsCMap *map,int hits)
  404. {
  405.     if (m_dive_mode != DIVE_OFF)
  406.         return;
  407.  
  408.     registerHit(SHIP_MAP_HIT,this);
  409. }
  410.  
  411. //-------------------------------------------------------------
  412.  
  413. void CShip::setWeapon(WeaponType type,WeaponGrade grade)
  414. {
  415.     if (m_weapon) {
  416.         m_weapon->kill();
  417.         m_weapon = 0;
  418.         }
  419.  
  420.     m_weapon_type = type;
  421.  
  422.     switch (m_weapon_type) {
  423.         case NO_WEAPON:
  424.             m_weapon = 0;
  425.             break;        
  426.         case MISSILE_WEAPON:
  427.             m_weapon = new CMissileWeapon;
  428.             break;
  429.         case HOMING_MISSILE_WEAPON:
  430.             m_weapon = new CHomingMissileWeapon;
  431.             break;
  432.         case LASER_WEAPON:
  433.             m_weapon = new CLaserWeapon;
  434.             break;
  435.         }
  436.  
  437.     if (m_weapon) {
  438.         m_scene->addActor(m_weapon);
  439.         m_weapon->activate();
  440.         m_weapon->setOwner(this);
  441.         m_weapon->setGrade(grade);
  442.         }
  443. }
  444.  
  445. //-------------------------------------------------------------
  446.  
  447. WeaponType CShip::getWeaponType()
  448. {
  449.     return m_weapon_type;
  450. }
  451.  
  452. //-------------------------------------------------------------
  453.  
  454. void CShip::addWeapon(WeaponType type,WeaponGrade grade)
  455. {
  456.     switch (type) {
  457.         case MISSILE_WEAPON:
  458.             setWeapon(type,grade);
  459.             break;
  460.         case LASER_WEAPON:
  461.             if (!m_left_clone && !m_right_clone &&
  462.                 getWeaponType() != type)
  463.                 setWeapon(type,grade);
  464.             else {
  465.                 if (m_left_clone &&
  466.                     m_left_clone->isActive() &&
  467.                     m_left_clone->getWeaponType() != type)
  468.                     m_left_clone->setWeapon(type,grade);
  469.                 else if (m_right_clone &&
  470.                          m_right_clone->isActive() &&
  471.                          m_right_clone->getWeaponType() != type)
  472.                          m_right_clone->setWeapon(type,grade);
  473.                 else if (getWeaponType() != type)
  474.                     setWeapon(type,grade);
  475.                 }
  476.             break;
  477.         case HOMING_MISSILE_WEAPON:
  478.             if (!m_left_wingtip && !m_right_wingtip)
  479.                 setWeapon(type,grade);
  480.             else {
  481.                 if (m_left_wingtip &&
  482.                     m_left_wingtip->isActive() &&
  483.                     m_left_wingtip->getWeaponType() != type)
  484.                     m_left_wingtip->setWeapon(type,grade);
  485.                 else if (m_right_wingtip &&
  486.                          m_right_wingtip->isActive() &&
  487.                          m_right_wingtip->getWeaponType() != type)
  488.                          m_right_wingtip->setWeapon(type,grade);
  489.                 else if (getWeaponType() != type)
  490.                     setWeapon(type,grade);
  491.                 }
  492.             break;
  493.         }
  494. }
  495.  
  496. //-------------------------------------------------------------
  497.  
  498. bool CShip::upgradeWeapon()
  499. {
  500.     if (m_weapon) {
  501.         if (m_weapon->upgrade())
  502.             return true;
  503.         else if (m_left_wingtip || m_right_wingtip) {
  504.             bool lup = m_left_wingtip && m_left_wingtip->upgradeWeapon();
  505.             bool rup = m_right_wingtip && m_right_wingtip->upgradeWeapon();
  506.             if (lup || rup)
  507.                 return true;
  508.             }
  509.         else if (m_left_clone || m_right_clone) {
  510.             bool lup = m_left_clone && m_left_clone->upgradeWeapon();
  511.             bool rup = m_right_clone && m_right_clone->upgradeWeapon();
  512.             if (lup || rup)
  513.                 return true;
  514.             }
  515.         }
  516.  
  517.     return false;
  518. }
  519.  
  520. //-------------------------------------------------------------
  521.  
  522. bool CShip::attachClone(int side)
  523. {
  524.     if (side <= 0 && !m_left_clone) {
  525.         m_left_clone = new CClone;
  526.         m_scene->addActor(m_left_clone);
  527.         m_left_clone->activate();
  528.         m_left_clone->setOwner(this);
  529.         m_left_clone->setAngleRange(-45.f,-135.f);
  530.         m_left_clone->setAngle(-90.f,true);
  531.         return true;
  532.         }
  533.     else if (!m_right_clone) {
  534.         m_right_clone = new CClone;
  535.         m_scene->addActor(m_right_clone);
  536.         m_right_clone->activate();
  537.         m_right_clone->setOwner(this);
  538.         m_right_clone->setAngleRange(45.f,135.f);
  539.         m_right_clone->setAngle(90.f,true);
  540.         return true;
  541.         }
  542.  
  543.     return false;
  544. }
  545.  
  546. //-------------------------------------------------------------
  547.  
  548. void CShip::detachClone(CClone *clone)
  549. {
  550.     if (m_left_clone == clone)
  551.         m_left_clone = 0;
  552.     if (m_right_clone == clone)
  553.         m_right_clone = 0;
  554. }
  555.  
  556. //-------------------------------------------------------------
  557.  
  558. bool CShip::attachWingtip(int side)
  559. {
  560.     if (side <= 0 && !m_left_wingtip) {
  561.         m_left_wingtip = new CWingtip;
  562.         m_scene->addActor(m_left_wingtip);
  563.         m_left_wingtip->activate();
  564.         m_left_wingtip->setOwner(this);
  565.         m_left_wingtip->setOffset(gsCVector(-34.f,5.f));
  566.         if (m_right_wingtip &&
  567.             m_right_wingtip->getWeapon())
  568.             m_left_wingtip->getWeapon()->setDirection(m_right_wingtip->getWeapon()->getDirection());
  569.         else
  570.             m_left_wingtip->getWeapon()->setDirection(WEAPON_FORWARD);
  571.         return true;
  572.         }
  573.     else if (!m_right_wingtip) {
  574.         m_right_wingtip = new CWingtip;
  575.         m_scene->addActor(m_right_wingtip);
  576.         m_right_wingtip->activate();
  577.         m_right_wingtip->setOwner(this);
  578.         m_right_wingtip->setOffset(gsCVector(34.f,5.f));
  579.         if (m_left_wingtip &&
  580.             m_left_wingtip->getWeapon())
  581.             m_right_wingtip->getWeapon()->setDirection(m_left_wingtip->getWeapon()->getDirection());
  582.         else
  583.             m_right_wingtip->getWeapon()->setDirection(WEAPON_FORWARD);
  584.         return true;
  585.         }
  586.  
  587.     return false;
  588. }
  589.  
  590. //-------------------------------------------------------------
  591.  
  592. void CShip::detachWingtip(CWingtip *wingtip)
  593. {
  594.     if (m_left_wingtip == wingtip)
  595.         m_left_wingtip = 0;
  596.     if (m_right_wingtip == wingtip)
  597.         m_right_wingtip = 0;
  598. }
  599.  
  600. //-------------------------------------------------------------
  601.  
  602. void CShip::removeUpgrades()
  603. {
  604.     if (m_left_clone) {
  605.         m_left_clone->kill();
  606.         m_left_clone = 0;
  607.         }
  608.     if (m_right_clone) {
  609.         m_right_clone->kill();
  610.         m_right_clone = 0;
  611.         }
  612.     if (m_left_wingtip) {
  613.         m_left_wingtip->kill();
  614.         m_left_wingtip = 0;
  615.         }
  616.     if (m_right_wingtip) {
  617.         m_right_wingtip->kill();
  618.         m_right_wingtip = 0;
  619.         }
  620. }
  621.  
  622. //-------------------------------------------------------------
  623.  
  624. void CShip::setHandling(ShipHandling handling)
  625. {
  626.     m_handling = handling;
  627.  
  628.     switch (handling) {
  629.         case HANDLING_BAD:
  630.             m_max_speed = 100.f;
  631.             m_acceleration =  500.f;
  632.             m_damping = 1000.f;
  633.             break;
  634.         case HANDLING_NORMAL:
  635.             m_max_speed = 200.f;
  636.             m_acceleration = 1000.f;
  637.             m_damping = 1500.f;
  638.             break;
  639.         case HANDLING_GOOD:
  640.             m_max_speed = 300.f;
  641.             m_acceleration = 1500.f;
  642.             m_damping = 2000.f;
  643.             break;
  644.         }
  645. }
  646.  
  647. //-------------------------------------------------------------
  648.  
  649. ShipHandling CShip::getHandling()
  650. {
  651.     return m_handling;
  652. }
  653.  
  654. //-------------------------------------------------------------
  655.  
  656. void CShip::setCloak(float time)
  657. {
  658.     m_cloak_time_limit = time;
  659.     m_cloak_timer.start();
  660. }
  661.  
  662. //-------------------------------------------------------------
  663.  
  664. bool CShip::isCloaked()
  665. {
  666.     return (m_cloak_time_limit > 0.f &&
  667.             m_cloak_timer.getTime() < m_cloak_time_limit);
  668. }
  669.  
  670. //-------------------------------------------------------------
  671.  
  672. bool CShip::isCloakFlashing()
  673. {
  674.     float time_to_go = m_cloak_time_limit - m_cloak_timer.getTime();
  675.  
  676.     if (time_to_go <= 0.f)
  677.         return true;
  678.  
  679.     if (time_to_go >= CLOAK_FLASH_TIME)
  680.         return false;
  681.  
  682.     return (((int) (time_to_go / CLOAK_FLASH_RATE)) & 1) == 0;
  683. }
  684.  
  685. //-------------------------------------------------------------
  686.  
  687. void CShip::dive(float time)
  688. {
  689.     m_dive_time_limit = time;
  690.     m_dive_level = 0;
  691.     m_dive_mode = DIVING_DOWN;
  692.     m_dive_timer.start();
  693.  
  694.     CGameState::playSample(SAMPLE_DIVE_DOWN,getPosition().getX());
  695. }
  696.  
  697. //-------------------------------------------------------------
  698.  
  699. int CShip::getDiveLevel()
  700. {
  701.     return m_dive_level;
  702. }
  703.  
  704. //-------------------------------------------------------------
  705.  
  706. float CShip::getDiveScale()
  707. {
  708.     return 1.f - m_dive_level * (1.f - SHIP_DIVE_SCALE) / SHIP_DIVE_FRAMES;
  709. }
  710.  
  711.  
  712. //-------------------------------------------------------------
  713.  
  714. void CShip::reverseWeapon()
  715. {
  716.     WeaponDirection olddir = WEAPON_FORWARD;
  717.  
  718.     if (m_left_wingtip &&
  719.         m_left_wingtip->getWeapon())
  720.         olddir = m_left_wingtip->getWeapon()->getDirection();
  721.     else if (m_right_wingtip &&
  722.              m_right_wingtip->getWeapon())
  723.         olddir = m_right_wingtip->getWeapon()->getDirection();
  724.  
  725.     WeaponDirection newdir = olddir == WEAPON_FORWARD ? WEAPON_REVERSE : WEAPON_FORWARD;
  726.  
  727.     if (m_left_wingtip &&
  728.         m_left_wingtip->getWeapon())
  729.         m_left_wingtip->getWeapon()->setDirection(newdir);
  730.     if (m_right_wingtip &&
  731.         m_right_wingtip->getWeapon())
  732.         m_right_wingtip->getWeapon()->setDirection(newdir);
  733. }
  734.  
  735. //-------------------------------------------------------------
  736.