1.  
  2. #include "cship.h"
  3.  
  4. bool CShip::isLoaded()
  5. {
  6.     return (loaded);
  7. }
  8.  
  9. bool CShip::canFire()
  10. {
  11.     // see if ship has enough power to shoot
  12.     if (loaded == false)
  13.         return false;
  14.    
  15.     if (weapon->getEnergy() > getSolar())
  16.         return false;
  17.  
  18.     // else got enough power and solar
  19.  
  20.     // use energy, unload gun
  21.     useSolar(weapon->getEnergy());
  22.     loaded = false;
  23.  
  24.     return true;
  25. };
  26.  
  27. int CShip::getHP()
  28. {
  29.     return (current.Hull + current.Armor + current.Shield);
  30. }
  31. int CShip::getMaxHP()
  32. {
  33.     return (Max.Hull + Max.Armor + Max.Shield);
  34. }
  35.  
  36. // returns current value
  37. int CShip::getCur(DMG_LOC hitLoc)
  38. {
  39.     int temp=0;
  40.     switch(hitLoc)
  41.     {
  42.     case LOC_HULL:      temp=current.Hull;          break;
  43.     case LOC_ARMOR:     temp=current.Armor;         break;
  44.     case LOC_SHIELD:    temp=current.Shield;        break;
  45.     };
  46.     return temp;
  47. }  
  48.  
  49. POINT CShip::getMoveXY()
  50. {
  51.     POINT loc = {0,0};
  52.  
  53.     switch(getFacing())
  54.     {       // based on direction we are heading, scroll the background - if possible
  55.         case NORTH: loc.y-=speed; break;
  56.         case SOUTH: loc.y+=speed; break;
  57.         case EAST:  loc.x+=speed; break;
  58.         case WEST:  loc.x-=speed; break;
  59.         case NE:    loc.x+=speed; loc.y-=speed; break;
  60.         case NW:    loc.x-=speed; loc.y-=speed; break;
  61.         case SE:    loc.x+=speed; loc.y+=speed; break;
  62.         case SW:    loc.x-=speed; loc.y+=speed; break;
  63.     }
  64.  
  65.     return loc;
  66. }
  67. int CShip::getMoveX()
  68. {
  69.     POINT loc = getMoveXY();
  70.     return loc.x;
  71. };
  72. int CShip::getMoveY()
  73. {
  74.     POINT loc = getMoveXY();
  75.     return loc.y;
  76. };
  77.  
  78.  
  79. // returns Max value
  80. int CShip::getMax(DMG_LOC hitLoc)  
  81. {
  82.     int temp=0;
  83.     switch(hitLoc)
  84.     {
  85.     case LOC_HULL:      temp=Max.Hull;          break;
  86.     case LOC_ARMOR:     temp=Max.Armor;         break;
  87.     case LOC_SHIELD:    temp=Max.Shield;        break;
  88.     };
  89.     return temp;
  90. }
  91.  
  92.  
  93. int CShip::getShields()
  94. {
  95.     return current.Shield; //Shield.energy;
  96. };
  97.  
  98. // return false if ship destroyed in the process
  99. bool CShip::applyDmg(DAMAGE dType, int dmg)
  100. {
  101. // shields absorb dmg but drains power
  102.  
  103.     // Apply to shields first
  104.     // cuts in half ENERGY damage
  105.  
  106. // SHIELD BUFFER
  107. /*
  108.     if (current.Shield > 0)
  109.     {
  110.         int buffer = Solar.energy;
  111.         if (dType == ENERGY)
  112.             buffer * 2;
  113.         // energy recharges the shields?
  114.        
  115.         if ( dmg > buffer )
  116.         {
  117.             dmg -= buffer;
  118.             Solar.energy = 0;
  119.         }
  120.         else
  121.         {   // absorbed
  122.             if (dType == ENERGY)
  123.                 Solar.energy -= (dmg/2); // absorbed
  124.             else
  125.                 Solar.energy -= dmg;     // absorbed
  126.  
  127.             if (Solar.energy < 0)
  128.                 Solar.energy =0;
  129.  
  130.             return false; // still alive
  131.         }
  132.     */
  133. // SHIELDS
  134.         // damage got through Buffer
  135.         if (current.Shield > 0)
  136.         {
  137.             current.Shield -= dmg;
  138.             if (current.Shield < 0)
  139.                 current.Shield = 0;
  140.             return false; // not dead
  141.         }
  142.  
  143.     // DMG still coming
  144. // ARMOR
  145.     // cuts in half KINETIC damage
  146. //  if ( dType == KINETIC )
  147. //      dmg = dmg / 2;
  148.  
  149.     if (dmg > current.Armor)
  150.     {
  151.         dmg -= current.Armor;
  152.         current.Armor = 0;
  153.     }
  154.     else
  155.     { // absorbed by armor
  156.         current.Armor -= dmg;
  157.         return false; // still alive, armor saved ya
  158.     }
  159.  
  160. // HULL is taking damage
  161.     // some creatures more than 1 hull?
  162.     if (dmg >= current.Hull)
  163.     {
  164.         // ship destroyed
  165.         current.Shield=0;
  166.         Solar.energy  =0;
  167.         Shield.energy =0;
  168.         current.Armor =0;
  169.         current.Hull  =0;
  170.  
  171.         setSTATE(DEAD);
  172.  
  173.         return true;
  174.     }
  175.     else
  176.         current.Hull -= dmg;
  177.  
  178.     return false;
  179. };
  180.  
  181. void CShip::setMaxSpeed(int newMax)
  182. { max_speed = newMax; }
  183.  
  184. void CShip::setSpeed(int newSpeed)
  185. {
  186.     if (newSpeed <= max_speed)
  187.         speed = newSpeed;
  188.     else
  189.         speed = max_speed;
  190.  
  191.     if (speed < 0)
  192.         speed = 0;
  193.  
  194.     setDelay(max_speed - speed + 1); // what is this for ?
  195. }
  196.  
  197. void CShip::addSpeed(int newSpeed)
  198. {
  199.     setSpeed(speed + newSpeed);
  200. }
  201.  
  202.  
  203. int CShip::getSpeed()
  204. { return speed; }
  205.  
  206. int CShip::getMaxSpeed()
  207. { return max_speed; }
  208.  
  209.  
  210. bool CShip::checkBounds(int xMin,int yMin, int xMax,int yMax)
  211. {
  212.     // checks to make sure the sprite is still on screen
  213.     // fixes it and returns 1 if otherwise ... and stops ship
  214.     bool fixed=false;
  215.     int ranDir = rand() % 2; // 0 or 1 left/right
  216.  
  217.     RECT r1;
  218.  
  219.     r1.left = getX();
  220.     r1.top  = getY();
  221.     r1.bottom = r1.top + getHeight();
  222.     r1.right  = r1.left + getWidth();
  223.  
  224.     if (r1.left < xMin) // lower
  225.     {
  226.         setX(xMin);
  227.         fixed=true;
  228.     }
  229.     else if (r1.right > xMax) // upper
  230.     {
  231.         setX(xMax - getWidth() );
  232.         fixed=true;
  233.     }
  234.  
  235.     if (r1.top < yMin) // lower
  236.     {
  237.         setY( yMin);
  238.         fixed=true;
  239.     }
  240.     else if (r1.bottom > yMax) // upper
  241.     {
  242.         setY( yMax - getHeight() );
  243.         fixed=true;
  244.     }
  245.  
  246.     return fixed;
  247. }
  248.  
  249. void CShip::doMove()
  250. {
  251.     // animate, if necessary
  252.     if (getLastFrame() > 1)
  253.         nextFrame();
  254.  
  255.     POINT move = getMoveXY();
  256.     setMoveXY(move.x,move.y);
  257.     addX(move.x);
  258.     addY(move.y);
  259. //  x += move.x;
  260. //  y += move.yy;
  261.  
  262.     /*
  263.     POINT oldPT = getPT();
  264.     setPT( calcXY( getAngle(), getSpeed(),  getPT() ) );
  265.     setMoveX(getPT().x - oldPT.x);
  266.     setMoveY(getPT().y - oldPT.y);
  267.     */
  268. }
  269.  
  270. void CShip::setGun(CGuns *newGun,int number)
  271. {
  272.     weapon = newGun;
  273.     gunNum = number;
  274. }
  275.  
  276. int CShip::getAmmo()
  277. {
  278.     return weapon->ammoType();
  279. };
  280. int CShip::getGun()
  281. {
  282.     return gunNum;
  283. };
  284.  
  285. // constructor
  286. CShip::CShip(int x, int y, int width, int height, LPCSTR filename, int newSpeed, int newMaxSpd, int Energy, int eRecharge, CGuns *Weapon, int GunNum, int Shields,int Armor, int Hull)
  287.       :CSprite(x,y,width,height,filename)
  288. {   // call the sprites constructor
  289.  
  290.     // ships hp and such   
  291.     Max.Armor   = Armor;
  292.     Max.Hull    = Hull;
  293.     Max.Shield  = Shields;
  294.  
  295.     // set current values to the max values
  296.     current.Armor   = Armor;
  297.     current.Hull    = Hull;
  298.     current.Shield  = Shields;
  299.  
  300.     Shield.energy   = Shields;
  301.     Shield.max      = Shields;
  302.     Shield.delay    = 0;
  303.     Shield.regen    = 50;
  304.  
  305.     // setup the ships speed info
  306.     setMaxSpeed(newMaxSpd);
  307.     setSpeed(newSpeed);
  308.  
  309.     // starter frigate [20] solar energy
  310.     Solar.energy    = Energy;
  311.     Solar.max       = Energy;
  312.     Solar.regen     = eRecharge; // 1 every 50 cycles
  313.     Solar.delay     = 0;
  314.  
  315.     weapon = Weapon; //  blasters
  316.  
  317.     gunNum          = GunNum;
  318.     gunDelay        = 0;
  319.     gunRecharge     = weapon->getReload();
  320.     loaded          = true;
  321. };
  322.  
  323. // destructor
  324. CShip::~CShip()
  325. {
  326.  
  327. };
  328.  
  329. int CShip::getSolar()
  330. {
  331.     return Solar.energy;
  332. };
  333.  
  334. int CShip::getSolarMax()
  335. {
  336.     return Solar.max;
  337. };
  338.  
  339. // returns false if unable to use that amount of energy
  340. bool CShip::useSolar(int amount)
  341. {
  342.     return ((Solar.energy-=amount) > 0);
  343. };
  344.  
  345. /*
  346. void CShip::setFacing(DIRS newFacing)
  347. {
  348.     CSprite::setFacing(newFacing);
  349.  
  350.     // set new angle to match
  351.     // as ships are using 0 degrees equal to EAST
  352.     switch(newFacing)
  353.     {
  354.         case EAST:  setAngle(  0); break;
  355.         case SE:    setAngle( 45); break;
  356.         case SOUTH: setAngle( 90); break;
  357.         case SW:    setAngle(135); break;
  358.         case WEST:  setAngle(180); break;
  359.         case NW:    setAngle(225); break;
  360.         case NORTH: setAngle(270); break;
  361.         case NE:    setAngle(315); break;
  362.     }      
  363. }
  364. */
  365.  
  366. // LEFT=0 RIGHT=1
  367. void CShip::turn(int LEFTorRIGHT )
  368. {
  369.     // 0 = LEFT, 1 = RIGHT
  370.     if ( LEFTorRIGHT == 0 ) // LEFT
  371.         switch(getFacing())
  372.         {
  373.             case NORTH: setFacing(NW);    break; // 45 degree increments
  374.             case SOUTH: setFacing(SE);    break;
  375.             case EAST:  setFacing(NE);    break;
  376.             case WEST:  setFacing(SW);    break;  
  377.             case NE:    setFacing(NORTH); break;
  378.             case NW:    setFacing(WEST);  break;
  379.             case SE:    setFacing(EAST);  break;
  380.             case SW:    setFacing(SOUTH); break;
  381.         }
  382.     else
  383.         switch(getFacing()) // RIGHT
  384.         {
  385.             case NORTH: setFacing(NE);    break;
  386.             case SOUTH: setFacing(SW);    break;
  387.             case EAST:  setFacing(SE);    break;
  388.             case WEST:  setFacing(NW);    break;  
  389.             case NE:    setFacing(EAST);  break;
  390.             case NW:    setFacing(NORTH); break;
  391.             case SE:    setFacing(SOUTH); break;
  392.             case SW:    setFacing(WEST);  break;
  393.         }
  394.  
  395.     doMove();
  396. }
  397. void CShip::setupShip(int nShield, int nArmor, int nHull)
  398. {
  399.     current.Shield = nShield;
  400.     current.Armor  = nArmor;
  401.     current.Hull  = nHull;
  402.  
  403.     Max.Shield = nShield;
  404.     Max.Armor  = nArmor;
  405.     Max.Hull   = nHull;
  406. }
  407.  
  408. // regens solar energy if delay of cycles has passed
  409. void CShip::regenSolar()
  410. {
  411.     Solar.delay++;
  412.  
  413.     if (Solar.delay >= Solar.regen)
  414.     { // recover
  415.         Solar.energy++;
  416.         Solar.delay=0;
  417.     }
  418.  
  419.     if (Solar.energy > Solar.max)
  420.         Solar.energy = Solar.max;
  421. };
  422.  
  423. // regens solar energy if delay of cycles has passed
  424. void CShip::regenShield()
  425. {
  426.     Shield.delay++;
  427.  
  428.     if (Shield.delay >= Shield.regen)
  429.     { // recover
  430.         current.Shield++;
  431.         Shield.energy++;
  432.         Shield.delay=0;
  433.     }
  434.  
  435.     if (Shield.energy > Shield.max)
  436.         Shield.energy = Shield.max;
  437.     if (current.Shield > Max.Shield)
  438.         current.Shield = Max.Shield;
  439. };
  440.  
  441.  
  442. void CShip::recharge()
  443. {
  444.     regenSolar();
  445.     regenShield();
  446.  
  447.     if (loaded)
  448.         return;
  449.  
  450.     //else
  451.     gunDelay++;
  452.  
  453.     if (gunDelay >= gunRecharge)
  454.     {
  455.         loaded = true;
  456.         gunDelay = 0;
  457.     }
  458. }
  459.  
  460. int CShip::getGunDelay()
  461. {
  462.     return gunDelay;
  463. };