Subversion Repositories Kolibri OS

Rev

Blame | Last modification | View Log | RSS feed

  1. #include "devil.h"
  2. #include "../game.h"
  3. #include "../PHL.h"
  4. #include "../hero.h"
  5. #include <stdlib.h>
  6. #include <math.h>
  7.  
  8. int boss6flag = 31;
  9.  
  10. void devilStep(Devil* d);
  11. void devilDraw(Devil* d);
  12.  
  13. void orbStep(Orb* o);
  14. void orbDraw(Orb* o);
  15.  
  16. void createDevil(int x, int y)
  17. {
  18.         if (flags[boss6flag] == 0) { //have not beaten boss 6
  19.                 PHL_FreeSurface(images[imgBoss]);
  20.                 images[imgBoss] = PHL_LoadQDA("boss04.bmp");
  21.        
  22.                 int i;
  23.                 for (i = 0; i < MAX_ENEMIES; i++) {
  24.                         if (enemies[i] == NULL) {
  25.                                 setBossRoom();
  26.                                
  27.                                 Enemy* e = /*(Enemy*)*/malloc(sizeof *e);
  28.                                 Devil* d = /*(Devil*)*/malloc(sizeof *d);
  29.                                 d->id = i;
  30.                                
  31.                                 d->x = x;
  32.                                 d->y = y;
  33.                                
  34.                                 d->ystart = d->y;
  35.                                 d->newystart = d->ystart;
  36.                                 d->hsp = -2.5;
  37.                                
  38.                                 d->hp = 100;
  39.                                 //d->hp = 1;
  40.                                
  41.                                 d->state = 0;
  42.                                 d->timer = 0;
  43.                                
  44.                                 d->blink = 0;
  45.                                 d->boblen = 32;
  46.                                 d->bobspd = 3;
  47.                                
  48.                                 d->tailangle = 90;
  49.                                
  50.                                 d->rotcounter = 0;
  51.                                 d->bobcounter = 0;
  52.                                
  53.                                 d->bobspd = 3;
  54.                                 d->rotspd = 1;
  55.                                
  56.                                 d->imageIndex = 0;
  57.                                
  58.                                 e->data = d;
  59.                                 e->enemyStep = devilStep;
  60.                                 e->enemyDraw = devilDraw;
  61.                                 e->type = 45;
  62.                                
  63.                                 enemies[i] = e;
  64.                                 i = MAX_ENEMIES;
  65.                         }
  66.                 }
  67.         }
  68. }
  69.  
  70. void devilStep(Devil* d)
  71. {      
  72.         char dead = 0;
  73.  
  74.         //Animate
  75.         {
  76.                 d->imageIndex += 0.1;
  77.                 if (d->imageIndex >= 2) {
  78.                         d->imageIndex -= 2;
  79.                 }
  80.                
  81.                 if (d->blink > 0) {
  82.                         d->blink -= 1;
  83.                 }
  84.         }
  85.        
  86.         //Bob
  87.         {
  88.                 if (d->state != 4) {
  89.                         d->bobcounter += d->bobspd;
  90.                         if (d->bobcounter >= 360) {
  91.                                 d->bobcounter -= 360;
  92.                         }
  93.                        
  94.                         d->y = d->ystart + (d->boblen * cos(d->bobcounter * 3.14159 / 180));
  95.                 }
  96.         }
  97.        
  98.         //Swing tail
  99.         {
  100.                 d->rotcounter += d->rotspd;
  101.                 if (d->rotcounter >= 360) {
  102.                         d->rotcounter -= 360;
  103.                 }
  104.                
  105.                 d->tailangle = 90 + (55 * cos(d->rotcounter * 3.14159 / 180));
  106.         }
  107.        
  108.         //Patterns
  109.         {
  110.                 //movement
  111.                 if (d->state == 0 || d->state == 2)
  112.                 {              
  113.                         d->rotspd = 1;
  114.                         d->boblen = 32;
  115.                         d->bobspd = 3;
  116.                        
  117.                         //Re-align ystart
  118.                         if (d->ystart > d->newystart) {
  119.                                 d->ystart -= 1;
  120.                         }
  121.                         if (d->ystart < d->newystart) {
  122.                                 d->ystart += 1;
  123.                         }
  124.                        
  125.                         d->x += d->hsp;
  126.                        
  127.                         //Slow Down
  128.                         double rate = 0.016;
  129.                         if (d->hsp < 0) {
  130.                                 d->hsp += rate;
  131.                                 if (d->hsp >= 0) {
  132.                                         d->hsp = 0;
  133.                                 }
  134.                         }
  135.                        
  136.                         if (d->hsp > 0) {
  137.                                 d->hsp -= rate;
  138.                                 if (d->hsp <= 0) {
  139.                                         d->hsp = 0;
  140.                                 }
  141.                         }              
  142.                        
  143.                         if (d->hsp == 0) {
  144.                                 d->timer = 0;
  145.                                 if (d->state == 0) {
  146.                                         d->state = 1;
  147.                                 }
  148.                                
  149.                                 if (d->state == 2) {
  150.                                         if ((d->rotcounter >= 90 && d->rotcounter <= 90 + d->rotspd) || (d->rotcounter >= 270 && d->rotcounter <= 270 + d->rotspd)) {
  151.                                                 d->state = 3;
  152.                                         }
  153.                                 }
  154.                         }
  155.                 }
  156.                 //mid room pause
  157.                 else if (d->state == 1)
  158.                 {
  159.                         d->timer += 1;
  160.                         if (d->timer >= 60) {
  161.                                 if (d->state == 1) {
  162.                                         d->hsp = 2.5;
  163.                                         if (herox < d->x) {
  164.                                                 d->hsp *= -1;
  165.                                         }
  166.                                 }
  167.                                 d->state = 2;
  168.                         }
  169.                 }
  170.                 //Shoot
  171.                 else if (d->state == 3)
  172.                 {
  173.                         d->rotspd = 3;
  174.                         d->boblen = 10;
  175.                         d->bobspd = 10;
  176.                        
  177.                         d->timer += 1;
  178.                        
  179.                         //Shoot orbs
  180.                         if (d->timer == 120 || d->timer == 240 || d->timer == 360) {
  181.                                 int aim = (atan2((heroy + 20) - d->y, d->x - herox) * 180 / 3.14159) + 270;
  182.                                
  183.                                 int spawnY = d->y + 20;        
  184.                                 createOrb(d->x, spawnY, aim + 22);
  185.                                 createOrb(d->x, spawnY, aim + 11);
  186.                                 createOrb(d->x, spawnY, aim);
  187.                                 createOrb(d->x, spawnY, aim - 11);                             
  188.                                 createOrb(d->x, spawnY, aim - 22);             
  189.  
  190.                                 PHL_PlaySound(sounds[sndShot03], CHN_ENEMIES);
  191.                         }
  192.                        
  193.                         if (d->timer == 360) {
  194.                                 d->state = 0;
  195.                                 d->hsp = 2.5;
  196.                                
  197.                                 if (d->x > 320) {
  198.                                         d->hsp *= -1;
  199.                                 }                              
  200.                                
  201.                                 int chaseY = heroy - d->ystart;
  202.                                 if (chaseY > 52) { chaseY = 52; }
  203.                                 if (chaseY < -52) { chaseY = -52; }
  204.                                
  205.                                 d->newystart = d->ystart + chaseY;
  206.                         }
  207.                 }
  208.                
  209.                 //Death
  210.                 if (d->state == 4) {
  211.                         d->rotspd = 3;
  212.                         d->y += 0.2;
  213.                         d->timer -= 1;
  214.                
  215.                         if (d->timer % 12 == 0) {
  216.                                 createEffect(2, d->x - 64 + (rand() % 100), d->y - 64 + (rand() % 80));
  217.                         }
  218.                        
  219.                         if (d->timer <= 0) {
  220.                                 dead = 1;
  221.                         }
  222.                 }
  223.         }
  224.        
  225.         //Collisions
  226.         if (d->state != 4) {
  227.                 //Setup masks
  228.                 Mask masks[6];
  229.                
  230.                 //Head mask
  231.                 masks[0].unused = masks[0].circle = 0;
  232.                 masks[0].w = 100;
  233.                 masks[0].h = 104;      
  234.                 masks[0].x = d->x - (masks[0].w / 2);
  235.                 masks[0].y = d->y - (masks[0].h / 2);
  236.                
  237.                 //Link masks
  238.                 for (int i = 1; i < 5; i++) {
  239.                         int taildis[4] = {54, 80, 108, 134};
  240.                         int taillag[4] = {10, 15, 10, 5};
  241.                        
  242.                         double newtailangle = 90 + (55 * cos((d->rotcounter - taillag[i-1]) * 3.14159 / 180));
  243.                        
  244.                         masks[i].unused = 0;
  245.                         masks[i].circle = 1;
  246.                         masks[i].w = 16;
  247.                         masks[i].h = 16;
  248.                         masks[i].x = d->x + (taildis[i-1] * cos(newtailangle * 3.14159 / 180));
  249.                         masks[i].y = d->y + (taildis[i-1] * sin(newtailangle * 3.14159 / 180));
  250.                 }
  251.                
  252.                 //Barb mask
  253.                 masks[5].unused = masks[5].circle = 0;
  254.                 masks[5].w = 40;
  255.                 masks[5].h = 40;
  256.                 masks[5].x = (d->x + (160 * cos(d->tailangle * 3.14159 / 180))) - (masks[5].w / 2);
  257.                 masks[5].y = (d->y + (160 * sin(d->tailangle * 3.14159 / 180))) - (masks[5].h / 2);
  258.                
  259.                 //Collisions
  260.                 int hitHead = 0;
  261.                 for (int a = 0; a < 6; a++)
  262.                 {
  263.                         if (a == 0 || a == 5) {
  264.                                 //Hit Player
  265.                                 if (checkCollision(masks[a], getHeroMask())) {
  266.                                        
  267.                                         int damage = 25;
  268.                                         if (a == 0) {
  269.                                                 damage = 50;
  270.                                         }
  271.                                        
  272.                                         if (heroHit(damage, masks[a].x + (masks[a].w / 2)) == 1) {
  273.                                                 if (a == 5) { //Barb
  274.                                                         heroStun();
  275.                                                 }
  276.                                         }
  277.                                 }
  278.                         }
  279.                        
  280.                         //Weapon collision
  281.                         if (hitHead == 0) {
  282.                                 for (int i = 0; i < MAX_WEAPONS; i++) {
  283.                                         if (weapons[i] != NULL) {
  284.                                                 if (weapons[i]->cooldown == 0) {
  285.                                                         if (checkCollision(masks[a], weapons[i]->weaponMask)) {
  286.                                                                 weaponHit(weapons[i]);
  287.                                                                
  288.                                                                 //Head
  289.                                                                 if (a == 0) {
  290.                                                                         d->hp -= 1;
  291.                                                                         d->blink = 15;
  292.                                                                         hitHead = 1;
  293.                                                                        
  294.                                                                         if (d->hp <= 0) {
  295.                                                                                 d->state = 4;
  296.                                                                                 d->timer = 180;
  297.                                                                                 d->blink = 200;
  298.                                                                         }
  299.                                                                 }else{
  300.                                                                         PHL_PlaySound(sounds[sndHit03], CHN_WEAPONS);
  301.                                                                 }
  302.                                                                
  303.                                                                 i = MAX_WEAPONS;
  304.                                                         }
  305.                                                 }
  306.                                         }      
  307.                                 }
  308.                         }
  309.                 }
  310.         }
  311.        
  312.         //Destroy
  313.         if (dead == 1) {
  314.                 enemyDestroy(d->id);
  315.                 bossDefeatedFlag = 1;
  316.                 roomSecret = 1;
  317.  
  318.                 flags[boss6flag] = 1;
  319.                 PHL_StopMusic();
  320.         }
  321. }
  322.  
  323. void devilDraw(Devil* d)
  324. {
  325.         if (d->blink % 2 == 0)
  326.         {
  327.                 int dx, dy;
  328.                
  329.                 //Draw tail
  330.                 int taildis[4] = {54, 80, 108, 134};
  331.                 int taillag[4] = {10, 15, 10, 5};
  332.                 for (int i = 0; i < 4; i++) {
  333.                         double newtailangle = 90 + (55 * cos((d->rotcounter - taillag[i]) * 3.14159 / 180));
  334.  
  335.                         dx = d->x + (taildis[i] * cos(newtailangle * 3.14159 / 180)) - 32;
  336.                         dy = d->y + (taildis[i] * sin(newtailangle * 3.14159 / 180)) - 32;
  337.                         PHL_DrawSurfacePart(dx, dy, 0, 128, 64, 64, images[imgBoss]);
  338.                 }
  339.                
  340.                 //Draw Head
  341.                 dx = d->x - 64;
  342.                 dy = d->y - 64;
  343.                 PHL_DrawSurfacePart(dx, dy, (int)d->imageIndex * 128, 0, 128, 128, images[imgBoss]);
  344.                
  345.                 //Draw Tail Tip
  346.                 dx = d->x + (160 * cos(d->tailangle * 3.14159 / 180)) - 32;
  347.                 dy = d->y + (160 * sin(d->tailangle * 3.14159 / 180)) - 32;
  348.                 PHL_DrawSurfacePart(dx, dy, 64, 128, 64, 64, images[imgBoss]);
  349.                
  350.         }
  351. }
  352.  
  353.  
  354. //Stone Orbs
  355. void createOrb(int x, int y, double dir)
  356. {
  357.         int i;
  358.         for (i = 0; i < MAX_ENEMIES; i++) {
  359.                 if (enemies[i] == NULL) {                              
  360.                         Enemy* e = /*(Enemy*)*/malloc(sizeof *e);
  361.                         Orb* o = /*(Orb*)*/malloc(sizeof *o);
  362.                         o->id = i;
  363.                        
  364.                         o->x = x;
  365.                         o->y = y;
  366.                        
  367.                         o->dir = dir;
  368.                        
  369.                         o->imageIndex = 0;
  370.                        
  371.                         e->data = o;
  372.                         e->enemyStep = orbStep;
  373.                         e->enemyDraw = orbDraw;
  374.                         e->type = -1;
  375.                        
  376.                         enemies[i] = e;
  377.                         i = MAX_ENEMIES;
  378.                 }
  379.         }
  380. }
  381.  
  382. void orbStep(Orb* o)
  383. {
  384.         char dead = 0;
  385.        
  386.         //Animate
  387.         {
  388.                 o->imageIndex += 0.33;
  389.                 if (o->imageIndex >= 4) {
  390.                         o->imageIndex -= 4;
  391.                 }
  392.         }
  393.        
  394.         //Movement
  395.         {
  396.                 int spd = 4;
  397.                 o->x += spd * sin(o->dir * 3.14159 / 180);
  398.                 o->y += spd * cos(o->dir * 3.14159 / 180);
  399.         }
  400.        
  401.         //Collision
  402.         {
  403.                 Mask mask;
  404.                 mask.unused = 0;
  405.                 mask.circle = 1;
  406.                 mask.w = 6;
  407.                 mask.x = o->x;
  408.                 mask.y = o->y;
  409.                
  410.                 //Collide with shield
  411.                 /*if (checkCollision(mask, shieldMask)) {
  412.                         createEffect(1, o->x - 20, o->y - 20);
  413.                         PHL_PlaySound(sounds[sndHit07], CHN_EFFECTS);
  414.                         dead = 1;
  415.                 }else{*/
  416.                         //Hit player
  417.                         if (checkCollision(getHeroMask(), mask)) {
  418.                                 heroStone();
  419.                                 heroHit(25, mask.x);
  420.                         }
  421.                 //}
  422.                
  423.                 //Collide with weapon
  424.                 int i;
  425.                 for (i = 0; i < MAX_WEAPONS; i++) {
  426.                         if (weapons[i] != NULL) {
  427.                                 if (checkCollision(mask, weapons[i]->weaponMask)) {
  428.                                         weaponHit(weapons[i]);
  429.                                        
  430.                                         createEffect(2, o->x - 32, o->y - 32);
  431.                                         dead = 1;
  432.                                        
  433.                                         i = MAX_WEAPONS;
  434.                                 }
  435.                         }      
  436.                 }
  437.         }
  438.        
  439.         //Destroy if outside of room
  440.         {
  441.                 if (o->x < -20 || o->x > 660 || o->y < -20 || o->y > 500) {
  442.                         dead = 1;
  443.                 }
  444.         }
  445.        
  446.         //Finally erase object
  447.         {
  448.                 if (dead == 1) {
  449.                         enemyDestroy(o->id);
  450.                 }
  451.         }
  452. }
  453.  
  454. void orbDraw(Orb* o)
  455. {
  456.         int animation[4] = {0, 1, 0, 2};
  457.         PHL_DrawSurfacePart(o->x - 20, o->y - 20, 440 + (animation[(int)o->imageIndex] * 40), 480, 40, 40, images[imgMisc20]);
  458. }