Subversion Repositories Kolibri OS

Rev

Blame | Last modification | View Log | RSS feed

  1. #include "crab.h"
  2. #include "../PHL.h"
  3. #include "../enemy.h"
  4. #include "../game.h"
  5. #include "../hero.h"
  6. #include <math.h>
  7. #include <stdlib.h>
  8.  
  9. int boss3flag = 13;
  10.  
  11. void crabStep(Crab* c);
  12. void crabDraw(Crab* c);
  13. void updateCrabMask(Crab* c);
  14. void crabDestroy(Crab* c);
  15.  
  16. void electricityStep(Electricity* e);
  17. void electricityDraw(Electricity* e);
  18.  
  19. void createCrab(int x, int y)
  20. {
  21.         if (flags[boss3flag] == 0) { //have not beaten boss 3
  22.                 PHL_FreeSurface(images[imgBoss]);
  23.                 images[imgBoss] = PHL_LoadQDA("boss06.bmp");
  24.        
  25.                 int i;
  26.                 for (i = 0; i < MAX_ENEMIES; i++) {
  27.                         if (enemies[i] == NULL) {
  28.                                 //Boss start
  29.                                 setBossRoom();
  30.                                
  31.                                 Enemy* e = /*(Enemy*)*/malloc(sizeof(Enemy));
  32.                                 Crab* c = /*(Crab*)*/malloc(sizeof(Crab));
  33.                                 c->id = i;
  34.                                
  35.                                 //c->hp = 1;
  36.                                 c->hp = 35;
  37.                                 c->invincible = 0;
  38.                                
  39.                                 c->x = x;
  40.                                 c->y = y;
  41.                                
  42.                                 c->vsp = 0;
  43.                                 c->hsp = 0;
  44.                                
  45.                                 c->imageIndex = 0;
  46.                                
  47.                                 c->state = 0;
  48.                                 c->timer = 0;
  49.                                 c->counter = 0;
  50.                                
  51.                                 c->mask.unused = 0;
  52.                                 c->mask.circle = 1;
  53.                                 c->mask.w = 33;
  54.                                 c->mask.h = 33;
  55.                                 updateCrabMask(c);
  56.                                
  57.                                 //Setup phase
  58.                                 c->timer = 60;
  59.                                
  60.                                 e->data = c;
  61.                                 e->enemyStep = crabStep;
  62.                                 e->enemyDraw = crabDraw;
  63.                                 e->type = 42;
  64.                                
  65.                                 enemies[i] = e;
  66.                                 i = MAX_ENEMIES;
  67.                         }
  68.                 }
  69.         }
  70. }
  71.  
  72. void crabStep(Crab* c)
  73. {
  74.         char dead = 0;
  75.         double grav = 0.15;
  76.        
  77.         if (c->invincible > 0) {
  78.                 c->invincible -= 1;
  79.         }
  80.        
  81.         //Wait
  82.         if (c->state == 0)
  83.         {
  84.                 c->imageIndex = 0;
  85.                
  86.                 if (c->timer <= 0) {
  87.                         c->timer = 0;
  88.                         if (c->counter == 2 || c->counter == 5) { //Goto roll
  89.                                 c->state = 3;
  90.                                 if (c->counter == 5) {
  91.                                         c->counter = 0;
  92.                                 }else{
  93.                                         c->counter = 3;
  94.                                 }
  95.                         }else if (c->counter == 3) {
  96.                                 c->state = 2;
  97.                         }else{
  98.                                 c->state = 1; //Goto shoot
  99.                         }              
  100.                 }else{
  101.                         c->timer -= 1;
  102.                 }
  103.         }
  104.         //Shoot Electric orbs
  105.         else if (c->state == 1)
  106.         {
  107.                 //Create orbs
  108.                 if (c->timer == 0) {
  109.                         PHL_PlaySound(sounds[sndPi05], CHN_ENEMIES);
  110.                        
  111.                         double angle = (atan2(heroy + 20 - (c->y + 60), c->x - (herox - 20)) * 180 / 3.14159) + 270;
  112.                         createElectricity(c->x, c->y + 60, angle - 45, c->id);
  113.                         createElectricity(c->x, c->y + 60, angle - 22.5, c->id);
  114.                         createElectricity(c->x, c->y + 60, angle, c->id);
  115.                         createElectricity(c->x, c->y + 60, angle + 22.5, c->id);
  116.                         createElectricity(c->x, c->y + 60, angle + 45, c->id);
  117.                 }
  118.                
  119.                 if (c->timer >= 20) {
  120.                         c->state = 2;
  121.                         c->timer = 0;
  122.                 }else{
  123.                         c->timer += 1;
  124.                 }
  125.         }
  126.         //Leap
  127.         else if (c->state == 2)
  128.         {
  129.                 c->imageIndex = 1;
  130.                
  131.                 //Hopping down or hopping up
  132.                 int hopup = 1;
  133.                 if (c->counter > 2) {
  134.                         hopup = 0;
  135.                 }
  136.                
  137.                 //Jump
  138.                 if (c->timer == 0) {
  139.                         PHL_PlaySound(sounds[sndJump02], CHN_ENEMIES);
  140.                        
  141.                         c->vsp = -6.5;
  142.                         if (hopup == 0) {
  143.                                 c->vsp = -1.5;
  144.                         }
  145.                         c->timer = 1;
  146.                 }
  147.                
  148.                 //Vertical velocity
  149.                 c->y += c->vsp;
  150.                 c->vsp += grav;
  151.                
  152.                 if (c->vsp >= 6) {
  153.                         c->vsp = 6;
  154.                 }
  155.                
  156.                 //Check if onground
  157.                 if ((hopup == 1 && c->vsp > 0) || (hopup == 0 && c->vsp >= 6)) {
  158.                         Mask area;
  159.                         area.unused = area.circle = 0;
  160.                         area.w = 40;
  161.                         area.h = 10;
  162.                         area.x = c->x - (area.w / 2);
  163.                         area.y = c->y + (80 - area.h);
  164.                        
  165.                         PHL_Rect collide = getTileCollision(1, area);
  166.                         if (collide.x != -1) {
  167.                                 c->y = collide.y - 80;
  168.                                 c->state = 0;
  169.                                 c->counter += 1;
  170.                                 c->timer = 25;
  171.                                 if (c->counter == 2 || c->counter == 5) {
  172.                                         c->timer = 3;
  173.                                 }                              
  174.                         }
  175.                 }
  176.         }
  177.         //Roll hop
  178.         else if (c->state == 3)
  179.         {
  180.                 //Animate
  181.                 if (c->hsp > 0) {
  182.                         c->imageIndex += 0.25;
  183.                 }
  184.                 if (c->hsp < 0) {
  185.                         c->imageIndex -= 0.25;
  186.                 }
  187.                 if (c->imageIndex < 2) { c->imageIndex += 4; }
  188.                 if (c->imageIndex >= 6) { c->imageIndex -= 4; }
  189.                
  190.                
  191.                 if (c->timer == 0) {
  192.                         PHL_PlaySound(sounds[sndHit04], CHN_ENEMIES);
  193.                        
  194.                         c->timer = 1;
  195.                         c->vsp = -1.5;
  196.                         c->imageIndex = 2;
  197.                         if (c->x > 320) {
  198.                                 c->hsp = -8;
  199.                         }else{
  200.                                 c->hsp = 8;
  201.                         }
  202.                 }
  203.                
  204.                 //Movement
  205.                 c->y += c->vsp;
  206.                 c->vsp += grav;
  207.                
  208.                 //Check if onground
  209.                 if (c->vsp > 0) {
  210.                         Mask area;
  211.                         area.unused = area.circle = 0;
  212.                         area.w = 40;
  213.                         area.h = 10;
  214.                         area.x = c->x - (area.w / 2);
  215.                         area.y = c->y + (80 - area.h);
  216.                        
  217.                         PHL_Rect collide = getTileCollision(1, area);
  218.                         if (collide.x != -1) {
  219.                                 c->y = collide.y - 80;
  220.                                 c->state = 4;                  
  221.                         }
  222.                 }
  223.         }
  224.         //Roll
  225.         if (c->state == 4)
  226.         {
  227.                 //Animate
  228.                 if (c->hsp > 0) {
  229.                         c->imageIndex += 0.25;
  230.                 }
  231.                 if (c->hsp < 0) {
  232.                         c->imageIndex -= 0.25;
  233.                 }
  234.                 if (c->imageIndex < 2) { c->imageIndex += 4; }
  235.                 if (c->imageIndex >= 6) { c->imageIndex -= 4; }
  236.                
  237.                 //Movement
  238.                 c->x += c->hsp;
  239.                
  240.                 //Collide with wall
  241.                 Mask area;
  242.                 area.unused = area.circle = 0;
  243.                 area.w = area.h = c->mask.w * 2;
  244.                 area.x = c->x - c->mask.w;
  245.                 area.y = c->y + (40 - c->mask.h);
  246.                
  247.                 if (checkTileCollision(1, area) == 1) {
  248.                         c->state = 5;
  249.                         c->timer = 0;
  250.                 }
  251.         }
  252.         //Bounce off wall
  253.         if (c->state == 5)
  254.         {
  255.                 if (c->timer == 0) {
  256.                         PHL_PlaySound(sounds[sndHit04], CHN_ENEMIES);
  257.                        
  258.                         c->timer = 1;
  259.                         c->vsp = -2;
  260.                         c->hsp = 2;
  261.                         if (c->x > 320) {
  262.                                 c->hsp *= -1;
  263.                         }
  264.                 }
  265.                
  266.                 c->imageIndex = 1;
  267.                
  268.                 c->x += c->hsp;
  269.                
  270.                 c->y += c->vsp;
  271.                 c->vsp += grav;
  272.                
  273.                 //Check if onground
  274.                 if (c->vsp > 0) {
  275.                         Mask area;
  276.                         area.unused = area.circle = 0;
  277.                         area.w = 40;
  278.                         area.h = 10;
  279.                         area.x = c->x - (area.w / 2);
  280.                         area.y = c->y + (80 - area.h);
  281.                        
  282.                         PHL_Rect collide = getTileCollision(1, area);
  283.                         if (collide.x != -1) {
  284.                                 c->y = collide.y - 80;
  285.                                 c->state = 0;
  286.                                 c->timer = 65;
  287.                         }
  288.                 }              
  289.         }
  290.         //Death
  291.         else if (c->state == 6)
  292.         {
  293.                 c->imageIndex = 1;
  294.                
  295.                 c->y += 0.2;
  296.                
  297.                 c->timer -= 1;
  298.                
  299.                 if (c->timer % 12 == 0) {
  300.                         createEffect(2, c->x - 64 + (rand() % 100), c->y + (rand() % 80));
  301.                 }
  302.                
  303.                 if (c->timer <= 0) {
  304.                         crabDestroy(c);
  305.                         dead = 1;
  306.                 }
  307.         }
  308.        
  309.         if (dead == 0) {
  310.                 if (c->state != 6) {
  311.                         //Update Mask
  312.                         c->mask.x = c->x;
  313.                         c->mask.y = c->y + 40;
  314.                        
  315.                         //Weapon collision
  316.                         int i;
  317.                         for (i = 0; i < MAX_WEAPONS; i++) {
  318.                                 if (weapons[i] != NULL) {
  319.                                         if (weapons[i]->cooldown == 0) {
  320.                                                 if (checkCollision(c->mask, weapons[i]->weaponMask)) {
  321.                                                         weaponHit(weapons[i]);
  322.                                                         c->invincible = 15;
  323.                                                         c->hp -= 1;    
  324.                                                         i = MAX_WEAPONS;
  325.                                                 }
  326.                                         }
  327.                                 }      
  328.                         }                              
  329.                        
  330.                         //Hit Player
  331.                         if (checkCollision(c->mask, getHeroMask())) {
  332.                                 heroHit(30, c->x);
  333.                         }
  334.                        
  335.                         //Die
  336.                         if (c->hp <= 0) {
  337.                                 c->state = 6;
  338.                                 c->timer = 180;
  339.                                 c->invincible = 200;
  340.                         }
  341.                 }
  342.         }
  343. }
  344.  
  345. void crabDraw(Crab* c)
  346. {
  347.         if (c->invincible % 2 == 0) {
  348.                 PHL_DrawSurfacePart(c->x - 40, c->y, (int)c->imageIndex * 80, 0, 80, 80, images[imgBoss]);
  349.         }
  350. }
  351.  
  352. void updateCrabMask(Crab* c)
  353. {
  354.         c->mask.x = c->x;
  355.         c->mask.y = c->y + 40;
  356. }
  357.  
  358. void crabDestroy(Crab* c)
  359. {
  360.         enemyDestroy(c->id);
  361.         bossDefeatedFlag = 1;
  362.         roomSecret = 1;
  363.  
  364.         flags[boss3flag] = 1;
  365.         PHL_StopMusic();
  366. }
  367.  
  368.  
  369. void createElectricity(int x, int y, double angle, int minid)
  370. {
  371.         int i;
  372.         for (i = minid; i < MAX_ENEMIES; i++) {
  373.                 if (enemies[i] == NULL) {
  374.                         Enemy* e = /*(Enemy*)*/malloc(sizeof *e);
  375.                         Electricity* el = /*(Electricity*)*/malloc(sizeof *el);
  376.                         el->id = i;
  377.                        
  378.                         el->x = x;
  379.                         el->y = y;
  380.                        
  381.                         //Fix angle
  382.                         if (angle < 0) {
  383.                                 angle += 360;
  384.                         }
  385.                         if (angle >= 360) {
  386.                                 angle -= 360;
  387.                         }
  388.                        
  389.                         el->angle = angle;                     
  390.                         el->imageIndex = 0;
  391.                        
  392.                         el->mask.unused = 0;
  393.                         el->mask.circle = 1;
  394.                         el->mask.w = 16;
  395.                         el->mask.h = 16;
  396.                         el->mask.x = x;
  397.                         el->mask.y = y;
  398.                        
  399.                         e->data = el;
  400.                         e->enemyStep = electricityStep;
  401.                         e->enemyDraw = electricityDraw;
  402.                         e->type = -1;
  403.                        
  404.                         enemies[i] = e;
  405.                         i = MAX_ENEMIES;
  406.                 }
  407.         }
  408.         /*
  409.         int thisid = -1;
  410.         int i;
  411.         for (i = 0; i < MAX_ENEMIES; i++) {
  412.                 if (enemies[i] == NULL) {
  413.                         if (i <= minid) {
  414.                                 thisid = i;
  415.                                 i = MAX_ENEMIES;
  416.                         }else{
  417.                                 i = MAX_ENEMIES;
  418.                         }
  419.                 }
  420.         }
  421.        
  422.         if (thisid == -1) {
  423.                 for (i = minid + 1; i < MAX_ENEMIES; i++) {
  424.                         if (enemies[i] == NULL) {
  425.                                 enemies[i] = enemies[minid];
  426.                                 Crab* c = enemies[i]->data;
  427.                                 c->id = i;
  428.                                 thisid = minid;
  429.                                 i = MAX_ENEMIES;
  430.                         }
  431.                 }
  432.         }
  433.                
  434.         if (thisid != -1) {
  435.                 Enemy* e = (Enemy*)malloc(sizeof(Enemy));
  436.                 Electricity* el = (Electricity*)malloc(sizeof(Electricity));
  437.                 el->id = thisid;
  438.                
  439.                 el->x = x;
  440.                 el->y = y;
  441.                
  442.                 //Fix angle
  443.                 if (angle < 0) {
  444.                         angle += 360;
  445.                 }
  446.                 if (angle >= 360) {
  447.                         angle -= 360;
  448.                 }
  449.                
  450.                 el->angle = angle;                     
  451.                 el->imageIndex = 0;
  452.                
  453.                 el->mask.unused = 0;
  454.                 el->mask.circle = 1;
  455.                 el->mask.w = 16;
  456.                 el->mask.h = 16;
  457.                 el->mask.x = x;
  458.                 el->mask.y = y;
  459.                
  460.                 e->data = el;
  461.                 e->enemyStep = electricityStep;
  462.                 e->enemyDraw = electricityDraw;
  463.                 e->type = -1;
  464.                
  465.                 enemies[thisid] = e;
  466.         }
  467.         */
  468. }
  469.  
  470. void electricityStep(Electricity* e)
  471. {
  472.         double spd = 3;
  473.         e->x += spd * sin(e->angle * 3.14159 / 180);
  474.         e->y += spd * cos(e->angle * 3.14159 / 180);
  475.        
  476.         //Update Mask
  477.         e->mask.x = e->x;
  478.         e->mask.y = e->y;
  479.        
  480.         //Collide with Shield
  481.         if (checkCollision(shieldMask, e->mask) == 1) {
  482.                 createEffect(1, e->x - 20, e->y - 20);
  483.                 PHL_PlaySound(sounds[sndHit07], CHN_EFFECTS);
  484.                 enemyDestroy(e->id);
  485.         }else{
  486.                 //Collide with Hero
  487.                 if (checkCollision(getHeroMask(), e->mask) == 1) {
  488.                         if (heroHit(25, e->x) == 1) {
  489.                                 heroStun();
  490.                         }
  491.                 }
  492.         }
  493.        
  494.         //Animate
  495.         e->imageIndex += 0.25;
  496.         if (e->imageIndex >= 3) {
  497.                 e->imageIndex -= 3;
  498.         }
  499.                
  500.         //Outside of screen
  501.         if (e->x < -20 || e->x > 660 || e->y < -20 || e->y > 500) {
  502.                 enemyDestroy(e->id);
  503.         }
  504. }
  505.  
  506. void electricityDraw(Electricity* e)
  507. {
  508.         PHL_DrawSurfacePart(e->x - 20, e->y - 20, 40 + ((int)e->imageIndex * 40), 0, 40, 40, images[imgMisc20]);
  509. }