Subversion Repositories Kolibri OS

Rev

Blame | Last modification | View Log | RSS feed

  1. #include "batboss.h"
  2. #include "../game.h"
  3. #include "../PHL.h"
  4. #include "../hero.h"
  5. #include "heads.h"
  6. #include <stdlib.h>
  7. #include <math.h>
  8.  
  9. int boss2flag = 5;
  10.  
  11. //void updateBatMask(Batboss* b);
  12. void batbossStep(Batboss* b);
  13. void batbossDraw(Batboss* b);
  14.  
  15. void createBatboss(int x, int y)
  16. {
  17.         if (flags[boss2flag] == 0) { //have not beaten boss 2
  18.                 PHL_FreeSurface(images[imgBoss]);
  19.                 images[imgBoss] = PHL_LoadQDA("boss03.bmp");
  20.        
  21.                 int i;
  22.                 for (i = 0; i < MAX_ENEMIES; i++) {
  23.                         if (enemies[i] == NULL) {
  24.                                 setBossRoom();
  25.                                
  26.                                 Enemy* e = /*(Enemy*)*/malloc(sizeof *e);
  27.                                 Batboss* b = /*(Batboss*)*/malloc(sizeof *b);
  28.                                 b->id = i;
  29.                                
  30.                                 b->x = x;
  31.                                 b->y = y;
  32.                                
  33.                                 b->vsp = 0;
  34.                                 b->hsp = 0;
  35.                                 b->grav = 0.1;
  36.                                
  37.                                 b->imageIndex = 0;
  38.                                
  39.                                 b->ypos = y;
  40.                                 b->rot = 0;
  41.                                
  42.                                 b->hp = 35;
  43.                                
  44.                                 b->invincible = 0;
  45.                                 b->state = 0;
  46.                                 b->timer = 0;
  47.                                 b->mode = 0; //0 for flame, 1 for tornado stomp
  48.                                
  49.                                 /*
  50.                                 b->mask.unused = b->mask.circle = 0;
  51.                                 b->mask.w = 100;
  52.                                 b->mask.h = 68;
  53.                                 updateBatMask(b);
  54.                                 */
  55.                                 //Setup phase
  56.                                 b->state = 0;
  57.                                 b->hsp = 2;
  58.                                 b->ypos = b->y - 24;
  59.                                 b->timer = 60;
  60.                                
  61.                                 e->data = b;
  62.                                 e->enemyStep = batbossStep;
  63.                                 e->enemyDraw = batbossDraw;
  64.                                 e->type = 41;
  65.                                
  66.                                 enemies[i] = e;
  67.                                 i = MAX_ENEMIES;
  68.                         }
  69.                 }
  70.         }
  71. }
  72.  
  73. void batbossStep(Batboss* b)
  74. {
  75.         char dead = 0;
  76.        
  77.         //Animate
  78.         {
  79.                 //Wing flap
  80.                 if (b->state == 0 || b->state == 1 || b->state == 2 || b->state == 5 || b->state == 6) {
  81.                         b->imageIndex += 0.1;
  82.                         if (b->imageIndex >= 2) {
  83.                                 b->imageIndex -= 2;
  84.                         }
  85.                 }
  86.                 //Twister
  87.                 if (b->state == 3 || b->state == 4) {
  88.                         b->imageIndex += 0.2;
  89.                         if (b->imageIndex >= 5) {
  90.                                 b->imageIndex -= 3;
  91.                         }
  92.                 }
  93.         }
  94.        
  95.         //Counters
  96.         {
  97.                 if (b->timer > 0) {
  98.                         b->timer -= 1;
  99.                 }
  100.                
  101.                 if (b->invincible > 0) {
  102.                         b->invincible -= 1;
  103.                 }
  104.         }
  105.        
  106.         //Large vertical movement
  107.         {
  108.                 if (b->state == 0 || b->state == 1) {
  109.                         b->rot += 2;
  110.                         if (b->rot >= 360) { b->rot -= 360; }
  111.                        
  112.                         b->y = b->ypos - (40 * sin(b->rot * 3.14159 / 180));
  113.                 }
  114.         }
  115.        
  116.         //Small vertical movement
  117.         {
  118.                 if (b->state == 2) {
  119.                         b->rot += 2;
  120.                         if (b->rot >= 360) { b->rot -= 360; }
  121.                        
  122.                         b->y = b->ypos - (20 * sin(b->rot * 3.14159 / 180));
  123.                 }
  124.         }
  125.        
  126.         //Horizontal movement
  127.         if (b->state == 0) {
  128.                 b->x += b->hsp;
  129.                
  130.                 if (b->x >= 520 || b->x <= 120) { //Hit walls
  131.                         b->hsp *= -1;
  132.                 }              
  133.                
  134.                 if (b->timer <= 0) {
  135.                         b->state = 1;
  136.                 }
  137.         }
  138.         //Slow to halt
  139.         else if (b->state == 1) {
  140.                 b->x += b->hsp;
  141.        
  142.                 if (b->x >= 520 || b->x <= 120) { //Hit walls
  143.                         b->hsp *= -1;
  144.                 }
  145.        
  146.                 double rate = 0.03;
  147.                 if (b->hsp > 0) {
  148.                         b->hsp -= rate;
  149.                         if (b->hsp <= 0) { b->hsp = 0; }
  150.                 }
  151.                 else if (b->hsp < 0) {
  152.                         b->hsp += rate;
  153.                         if (b->hsp >= 0) { b->hsp = 0; }
  154.                 }
  155.                
  156.                 if (b->hsp == 0 && b->rot <= 2) {
  157.                         b->state = 2;
  158.                         b->timer = 60;
  159.                 }
  160.         }
  161.         else if (b->state == 2) {
  162.                 if (b->timer == 1) {
  163.                         //Shoot flame
  164.                         int fx = b->x;
  165.                         int fy = b->y + 24;
  166.                         int fangle = (atan2(heroy - fy, fx - (herox - 20)) * 180 / 3.14159) + 270;
  167.                         createFireball(fx, fy, fangle, b->id);
  168.                         createFireball(fx, fy, fangle - 15, b->id);
  169.                         createFireball(fx, fy, fangle + 15, b->id);
  170.                         PHL_PlaySound(sounds[sndShot03], CHN_ENEMIES);
  171.                 }
  172.                
  173.                 if (b->timer <= 0 && b->rot <= 2) {
  174.                         if (b->mode == 0) {
  175.                                 b->state = 0;
  176.                                 b->timer = 60;
  177.                                 b->hsp = 2;
  178.                                 b->mode = 1;
  179.                         }
  180.                         else{
  181.                                 b->mode = 0;
  182.                                 b->state = 3;
  183.                                 b->imageIndex = 2;
  184.                                 b->vsp = -4;
  185.                                 PHL_PlaySound(sounds[sndShot06], CHN_ENEMIES);
  186.                         }
  187.                        
  188.                         if (herox < b->x) {
  189.                                 b->hsp *= -1;
  190.                         }
  191.                 }
  192.         }
  193.         //Stomp
  194.         else if (b->state == 3) {
  195.                 b->y += b->vsp;
  196.                 b->vsp += b->grav;
  197.                 if (b->vsp >= 6) { b->vsp = 6; }
  198.                
  199.                 //Hit floor
  200.                 if (b->y >= 480 - 176) {
  201.                         b->y = 480 - 176;
  202.                         b->state = 4;
  203.                         b->timer = 120;
  204.                         quakeTimer = 30;
  205.                         PHL_PlaySound(sounds[sndHit04], CHN_ENEMIES);
  206.                         b->hsp = 1;
  207.                         if (b->x > herox) {
  208.                                 b->hsp *= -1;
  209.                         }
  210.                 }
  211.         }
  212.         //Chase
  213.         else if (b->state == 4) {
  214.                 b->x += b->hsp;
  215.                
  216.                 if (b->timer <= 0 || b->x >= 520 || b->x <= 120) {
  217.                         b->state = 5;
  218.                         b->timer = 80 + (rand() % 61);
  219.                 }
  220.         }
  221.         //Rise
  222.         else if (b->state == 5) {
  223.                 b->y -= 1;
  224.                
  225.                 if (b->timer <= 0) {
  226.                         b->state = 0;
  227.                         b->ypos = b->y;
  228.                         b->rot = 0;
  229.                         b->timer = 60;
  230.                        
  231.                         b->hsp = 2;
  232.                         if (b->x > herox) {
  233.                                 b->hsp *= -1;
  234.                         }
  235.                 }
  236.         }
  237.         //Death
  238.         else if (b->state == 6) {
  239.                 b->y += 0.2;
  240.                
  241.                 if (b->timer % 12 == 0) {
  242.                         createEffect(2, b->x - 64 + (rand() % 100), b->y + (rand() % 80));
  243.                 }
  244.                
  245.                 if (b->timer <= 0) {
  246.                         dead = 1;
  247.                 }
  248.         }
  249.        
  250.         if (b->state != 6) {
  251.                 //Setup Mask
  252.                 Mask mask;
  253.                 {
  254.                         mask.unused = mask.circle = 0;
  255.                         if (b->state == 3 || b->state == 4) {
  256.                                 mask.w = 64;
  257.                                 mask.h = 96;
  258.                                 mask.y = b->y;
  259.                         }else{
  260.                                 mask.w = 100;
  261.                                 mask.h = 68;
  262.                                 mask.y = b->y + 18;
  263.                         }
  264.                         mask.x = b->x - (mask.w / 2);
  265.                 }
  266.                
  267.                 //Hit Player
  268.                 {
  269.                         if (checkCollision(mask, getHeroMask())) {
  270.                                 heroHit(30, b->x);
  271.                         }
  272.                 }
  273.                
  274.                 //Weapon collision
  275.                 {
  276.                         int i;
  277.                         for (i = 0; i < MAX_WEAPONS; i++) {
  278.                                 if (weapons[i] != NULL) {
  279.                                         if (weapons[i]->cooldown == 0) {
  280.                                                 if (checkCollision(mask, weapons[i]->weaponMask)) {
  281.                                                         weaponHit(weapons[i]);
  282.                                                         //Hit
  283.                                                         b->invincible = 15;
  284.                                                         b->hp -= 1;
  285.                                                        
  286.                                                         i = MAX_WEAPONS;
  287.                                                 }
  288.                                         }
  289.                                 }      
  290.                         }
  291.                 }
  292.                
  293.                 if (b->hp <= 0) {
  294.                         b->state = 6;
  295.                         b->timer = 180;
  296.                         b->invincible = 200;
  297.                 }
  298.         }
  299.        
  300.         //Destroy object
  301.         {
  302.                 if (dead == 1) {
  303.                         enemyDestroy(b->id);
  304.                         bossDefeatedFlag = 1;
  305.                         roomSecret = 1;
  306.  
  307.                         flags[boss2flag] = 1;
  308.                         PHL_StopMusic();
  309.                 }
  310.         }
  311.        
  312. }
  313.  
  314. void batbossDraw(Batboss* b)
  315. {
  316.         if (b->invincible % 2 == 0) {
  317.                 PHL_DrawSurfacePart(b->x - 64, b->y, (int)b->imageIndex * 128, 0, 128, 96, images[imgBoss]);
  318.         }
  319. }