Subversion Repositories Kolibri OS

Rev

Blame | Last modification | View Log | RSS feed

  1. #include "garm.h"
  2. #include "../game.h"
  3. #include "../PHL.h"
  4. #include "../hero.h"
  5. #include <stdlib.h>
  6.  
  7. int boss7flag = 47;
  8.  
  9. void garmStep(Garm* g);
  10. void garmDraw(Garm* g);
  11.  
  12. void garmrockStep(Garmrock* g);
  13. void garmrockDraw(Garmrock* g);
  14.  
  15. void createGarm(int x, int y)
  16. {      
  17.         if (flags[boss7flag] == 0) { //have not beaten boss 7
  18.                 PHL_FreeSurface(images[imgBoss]);
  19.                 images[imgBoss] = PHL_LoadQDA("boss07.bmp");
  20.        
  21.                 int i;
  22.                 for (i = 0; i < MAX_ENEMIES; i++) {
  23.                         if (enemies[i] == NULL) {
  24.                                 setBossRoom();
  25.                                
  26.                                 Enemy* e = malloc(sizeof *e);
  27.                                 Garm* g = malloc(sizeof *g);
  28.                                
  29.                                 g->id = i;
  30.                                
  31.                                 g->hp = 105;
  32.                                 //g->hp = 1;
  33.                                
  34.                                 g->x = x;
  35.                                 g->y = y;
  36.                                
  37.                                 g->hsp = 0;
  38.                                 g->vsp = 0;
  39.                                
  40.                                 g->dir = -1;
  41.                                
  42.                                 g->imageIndex = 0;
  43.                                
  44.                                 g->state = 0;
  45.                                 g->timer = 0;
  46.                                
  47.                                 g->blink = 0;
  48.                                
  49.                                 g->substate = 0;
  50.                                 g->wallcounter = 0;
  51.                                 g->targx = 0;
  52.                                
  53.                                 e->data = g;
  54.                                 e->enemyStep = garmStep;
  55.                                 e->enemyDraw = garmDraw;
  56.                                 e->type = 46;
  57.                                
  58.                                 enemies[i] = e;
  59.                                 i = MAX_ENEMIES;
  60.                         }
  61.                 }
  62.         }
  63. }
  64.  
  65. void garmStep(Garm* g)
  66. {
  67.         char dead = 0;
  68.        
  69.         //Blink animation
  70.         {
  71.                 if (g->blink > 0) {
  72.                         g->blink -= 1;
  73.                 }
  74.         }
  75.        
  76.         //Setup Mask
  77.         Mask mask;
  78.         {
  79.                 mask.circle = mask.unused = 0;
  80.                 mask.w = 88;
  81.                 mask.h = 104;
  82.                 mask.x = g->x - (mask.w / 2);
  83.                 mask.y = g->y + (120 - mask.h);
  84.         }
  85.        
  86.         //Stand still
  87.         if (g->state == 0)
  88.         {
  89.                 //Animate
  90.                 {
  91.                         g->imageIndex += 0.0625;
  92.                         if (g->imageIndex >= 2) {
  93.                                 g->imageIndex -= 2;
  94.                         }
  95.                 }
  96.                
  97.                 //End state
  98.                 {
  99.                         g->timer += 1;
  100.                         if (g->timer >= 60) {
  101.                                 g->state = 1;
  102.                                 //g->vsp = -4.5;
  103.                                 g->counter = 0;
  104.                                 g->timer = 0;
  105.                                 //PHL_PlaySound(sounds[sndPi09], CHN_ENEMIES);
  106.                         }
  107.                 }
  108.         }
  109.        
  110.         //Bounce
  111.         else if (g->state == 1)
  112.         {
  113.                 //Animate
  114.                 {
  115.                         g->imageIndex += 0.33;
  116.                         if (g->imageIndex >= 3) {
  117.                                 g->imageIndex -= 3;
  118.                         }
  119.                 }
  120.                
  121.                 if (g->timer > 0) {
  122.                         g->vsp = 0;
  123.                         g->imageIndex = 0;
  124.                         g->timer -= 1;
  125.                         if (g->timer <= 0) {
  126.                                 //End state
  127.                                 if (g->counter >= 3) {
  128.                                         g->state = 2;
  129.                                         g->counter = 0;
  130.                                         g->imageIndex = 0;
  131.                                         g->vsp = -6;
  132.                                         g->hsp = 8;
  133.                                         if (g->x > herox) {
  134.                                                 g->hsp *= -1;
  135.                                         }
  136.                                        
  137.                                         if (g->substate == 0) {
  138.                                                 g->wallcounter = 1;
  139.                                                 g->substate = 1;
  140.                                         }else{
  141.                                                 g->wallcounter = 2;
  142.                                                 g->substate = 0;
  143.                                         }
  144.                                 }else{
  145.                                         g->vsp = -5;                                   
  146.                                 }
  147.                         }
  148.                 }
  149.                
  150.                 else if (g->timer == 0) {
  151.                         double grav = 0.25;
  152.                        
  153.                         //Movement
  154.                         if (g->timer == 0) {
  155.                                 g->y += g->vsp;
  156.                                 g->vsp += grav;
  157.                                 mask.y = g->y + (120 - mask.h);
  158.                         }
  159.                        
  160.                         //Land on ground
  161.                         if (g->vsp >= 0 && g->timer == 0) {
  162.                                 PHL_Rect collide = getTileCollision(1, mask);
  163.                                 if (collide.x != -1) {
  164.                                         g->y = collide.y - 120;
  165.                                         mask.y = g->y + (120 - mask.h);
  166.                                         g->vsp = 0;
  167.                                         g->timer = 3;
  168.                                         g->counter += 1;
  169.                                         PHL_PlaySound(sounds[sndPi09], CHN_ENEMIES);
  170.                                 }
  171.                         }
  172.                 }
  173.         }
  174.        
  175.         //Leap towards wall
  176.         else if (g->state == 2)
  177.         {              
  178.                 double grav = 0.25;
  179.                
  180.                 //Set image
  181.                 {
  182.                         if (g->hsp > 0) {
  183.                                 g->imageIndex = 0;
  184.                         }
  185.                        
  186.                         if (g->hsp < 0) {
  187.                                 g->imageIndex = 1;
  188.                         }
  189.                 }
  190.                
  191.                 //Movement
  192.                 {
  193.                         g->y += g->vsp;
  194.                         g->vsp += grav;
  195.                         mask.y = g->y + (120 - mask.h);
  196.  
  197.                         g->x += g->hsp;
  198.                         mask.x = g->x - (mask.w / 2);
  199.                 }
  200.                
  201.                 if (g->wallcounter > 0)
  202.                 {                              
  203.                         PHL_Rect collide = getTileCollision(1, mask);
  204.                         if (collide.x != -1) {
  205.                                 g->wallcounter -= 1;                           
  206.                                 if (g->hsp < 0) {
  207.                                         g->x = collide.x + 40 + (mask.w / 2);
  208.                                 }
  209.                                 if (g->hsp > 0) {
  210.                                         g->x = collide.x - (mask.w / 2);
  211.                                 }
  212.                                 g->state = 3;
  213.                                 g->timer = 0;
  214.                         }
  215.                 }
  216.                
  217.                 //Ground pound
  218.                 else {
  219.                         char action = 0;
  220.                        
  221.                         if ( (g->hsp > 0 && g->x > g->targx) || (g->hsp < 0 && g->x < g->targx) ) {
  222.                                 action = 1;
  223.                         }
  224.                         //Wall collision backup
  225.                         else{
  226.                                 PHL_Rect collide = getTileCollision(1, mask);
  227.                                 if (collide.x != -1) {
  228.                                         if (g->hsp < 0) {
  229.                                                 g->x = collide.x + 40 + (mask.w / 2);
  230.                                         }
  231.                                         if (g->hsp > 0) {
  232.                                                 g->x = collide.x - (mask.w / 2);
  233.                                         }
  234.                                         action = 1;
  235.                                 }
  236.                         }
  237.                        
  238.                         if (action == 1) {
  239.                                 g->state = 4;
  240.                                 g->vsp = -4;
  241.                                 PHL_PlaySound(sounds[sndWolf01], CHN_ENEMIES);
  242.                         }
  243.                 }
  244.         }
  245.        
  246.         //Grab wall
  247.         else if (g->state == 3)
  248.         {
  249.                 g->timer += 1;
  250.                 if (g->timer > 5) {
  251.                         g->state = 2;
  252.                         g->vsp = -6;
  253.                         g->hsp *= -1;                  
  254.                         PHL_PlaySound(sounds[sndPi09], CHN_ENEMIES);
  255.                        
  256.                         g->targx = herox;
  257.                        
  258.                         if (g->wallcounter <= 0) {
  259.                                 //Get distance from player
  260.                                 int dis = g->x - g->targx;
  261.                                 {                              
  262.                                         if (dis < 0) {
  263.                                                 dis *= -1;
  264.                                         }
  265.                                 }
  266.                                
  267.                                 if (dis < 200 || g->substate == 1) {
  268.                                         g->hsp /= 2;
  269.                                 }
  270.                         }
  271.                 }
  272.         }
  273.        
  274.         //Ground pound
  275.         else if (g->state == 4)
  276.         {
  277.                 double grav = 0.2;
  278.                
  279.                 //Animate
  280.                 {
  281.                         g->imageIndex += 0.33;
  282.                         if (g->imageIndex >= 3) {
  283.                                 g->imageIndex -= 3;
  284.                         }
  285.                 }
  286.                
  287.                 g->y += g->vsp;
  288.                 g->vsp += grav;
  289.                 mask.y = g->y + (120 - mask.h);
  290.                
  291.                 //Collide with floor
  292.                 {
  293.                         PHL_Rect collide = getTileCollision(1, mask);
  294.                        
  295.                         if (collide.x != -1) {
  296.                                 g->y = collide.y - 120;
  297.                                 PHL_PlaySound(sounds[sndHit04], CHN_ENEMIES);
  298.                                 quakeTimer = 30;
  299.                                 g->state = 0;
  300.                                 g->timer = -20;
  301.                                 //Create rocks
  302.                                 createGarmrock(g->x + 64, g->y + 100, 2, -4);
  303.                                 createGarmrock(g->x + 34, g->y + 100, 1, -5);
  304.                                 createGarmrock(g->x - 34, g->y + 100, -1, -5);
  305.                                 createGarmrock(g->x - 64, g->y + 100, -2, -4);
  306.                                
  307.                                 createEffectExtra(3, g->x - 50, g->y + 90, -1, 0, 0);
  308.                                 createEffectExtra(3, g->x + 10, g->y + 90, 1, 0, 0);
  309.                         }
  310.                 }
  311.         }
  312.        
  313.         //Dead
  314.         if (g->state == 5) {
  315.                 //Animate
  316.                 {
  317.                         g->imageIndex += 0.33;
  318.                         if (g->imageIndex >= 3) {
  319.                                 g->imageIndex -= 3;
  320.                         }
  321.                 }
  322.                
  323.                 g->y += 0.2;
  324.                
  325.                 if (g->blink % 12 == 0) {
  326.                         createEffect(2, g->x - 64 + (rand() % 100), g->y + 60 - 64 + (rand() % 80));
  327.                 }
  328.  
  329.                 if (g->blink <= 0) {
  330.                         dead = 1;
  331.                 }
  332.         }
  333.        
  334.         else{  
  335.                 if (dead == 0) {
  336.                         //Update Mask
  337.                         {
  338.                                 mask.x = g->x - (mask.w / 2);
  339.                                 mask.y = g->y + (120 - mask.h);
  340.                         }
  341.                        
  342.                         //Hero collision
  343.                         {
  344.                                 if (checkCollision(getHeroMask(), mask) == 1) {
  345.                                         heroHit(40, mask.x + (mask.w / 2));
  346.                                 }
  347.                         }
  348.                
  349.                         //Weapon collision
  350.                         {
  351.                                 int i;
  352.                                 for (i = 0; i < MAX_WEAPONS; i++) {
  353.                                         if (weapons[i] != NULL) {
  354.                                                 if (weapons[i]->cooldown == 0) {
  355.                                                         if (checkCollision(mask, weapons[i]->weaponMask)) {
  356.                                                                 weaponHit(weapons[i]);
  357.                                                                 g->hp -= 1;
  358.                                                                 g->blink = 15;
  359.                                                                 //Dead
  360.                                                                 if (g->hp <= 0) {
  361.                                                                         g->state = 5;
  362.                                                                         g->blink = 200;
  363.                                                                 }
  364.                                                                
  365.                                                                 i = MAX_WEAPONS;
  366.                                                         }
  367.                                                 }
  368.                                         }      
  369.                                 }
  370.                         }
  371.                        
  372.                 }
  373.         }
  374.        
  375.         if (dead == 1) {
  376.                 //Destroy
  377.                 {
  378.                         enemyDestroy(g->id);
  379.                         bossDefeatedFlag = 1;
  380.                         roomSecret = 1;
  381.  
  382.                         flags[boss7flag] = 1;
  383.                         PHL_StopMusic();
  384.                 }
  385.         }
  386.        
  387. }
  388.  
  389. void garmDraw(Garm* g)
  390. {
  391.         if (g->blink % 2 == 0) {
  392.                 int cropX = 0,
  393.                         cropY = 0;
  394.                
  395.                 //Jump Spinning
  396.                 if ((g->state == 1 && g->timer == 0) || g->state == 4 || g->state == 5) {
  397.                         cropY = 128;
  398.                         cropX = 256;
  399.                 }
  400.                
  401.                 //Jump
  402.                 if (g->state == 2) {
  403.                         cropY = 128;
  404.                 }
  405.                
  406.                 //Wall grab
  407.                 if (g->state == 3) {
  408.                         cropX = 384;
  409.                 }
  410.                        
  411.                 cropX += (int)g->imageIndex * 128;
  412.                        
  413.                 PHL_DrawSurfacePart(g->x - 64, g->y - 8, cropX, cropY, 128, 128, images[imgBoss]);
  414.         }
  415. }
  416.  
  417. //Rocks
  418. void createGarmrock(int x, int y, double hsp, double vsp)
  419. {              
  420.         int i;
  421.         for (i = 0; i < MAX_ENEMIES; i++) {
  422.                 if (enemies[i] == NULL) {                      
  423.                         Enemy* e = malloc(sizeof *e);
  424.                         Garmrock* g = malloc(sizeof *g);
  425.                        
  426.                         g->id = i;
  427.                         g->hp = 3;
  428.                        
  429.                         g->x = x;
  430.                         g->y = y;
  431.                        
  432.                         g->hsp = hsp;
  433.                         g->vsp = vsp;
  434.                        
  435.                         g->imageIndex = 0;
  436.                        
  437.                         g->counter = 0;
  438.                         g->inwall = 0;
  439.                         g->blink = 0;
  440.                        
  441.                         e->data = g;
  442.                         e->enemyStep = garmrockStep;
  443.                         e->enemyDraw = garmrockDraw;
  444.                         e->type = -1;
  445.                        
  446.                         enemies[i] = e;
  447.                         i = MAX_ENEMIES;
  448.                 }
  449.         }
  450. }
  451.  
  452. void garmrockStep(Garmrock* g)
  453. {
  454.         char dead = 0;
  455.        
  456.         //Setup Mask
  457.         Mask mask;
  458.         {
  459.                 mask.circle = mask.unused = 0;
  460.                 mask.w = 44;
  461.                 mask.h = 44;
  462.                 mask.x = g->x - (mask.w / 2);
  463.                 mask.y = g->y - (mask.h / 2);
  464.         }
  465.        
  466.         //Animate
  467.         {
  468.                 g->imageIndex += 0.2;
  469.                 if (g->imageIndex >= 4) {
  470.                         g->imageIndex -= 4;
  471.                 }
  472.                
  473.                 if (g->blink > 0) {
  474.                         g->blink -= 1;
  475.                 }
  476.         }
  477.        
  478.         //Horizontal movement
  479.         {
  480.                 g->x += g->hsp;
  481.                 mask.x = g->x - (mask.w / 2);
  482.                
  483.                 g->inwall = 0;
  484.                 if (checkTileCollision(1, mask) == 1) {
  485.                         g->inwall = 1;
  486.                 }
  487.         }
  488.        
  489.         //Vertical movement
  490.         {
  491.                 double grav = 0.1;
  492.                
  493.                 g->y += g->vsp;
  494.                 g->vsp += grav;
  495.                 mask.y = g->y - (mask.h / 2);
  496.                
  497.                 if (g->inwall == 0 && g->counter == 0) {
  498.                         PHL_Rect collide = getTileCollision(1, mask);
  499.                         if (collide.x != -1) {
  500.                                 g->counter = 1;
  501.                                 g->y = collide.y - (mask.h / 2);
  502.                                 g->vsp = -2;
  503.                                 PHL_PlaySound(sounds[sndHit06], CHN_ENEMIES);
  504.                         }
  505.                 }
  506.         }
  507.        
  508.         //Update mask
  509.         {
  510.                 mask.x = g->x - (mask.w / 2);
  511.                 mask.y = g->y - (mask.h / 2);
  512.         }
  513.        
  514.         //Hero collision
  515.         {
  516.                 if (checkCollision(getHeroMask(), mask) == 1) {
  517.                         heroHit(30, mask.x + (mask.w / 2));
  518.                 }
  519.         }
  520.        
  521.         //Weapon collision
  522.         {
  523.                 int i;
  524.                 for (i = 0; i < MAX_WEAPONS; i++) {
  525.                         if (weapons[i] != NULL) {
  526.                                 if (weapons[i]->cooldown == 0) {
  527.                                         if (checkCollision(mask, weapons[i]->weaponMask)) {
  528.                                                 weaponHit(weapons[i]);
  529.                                                 g->hp -= 1;
  530.                                                 g->blink = 15;
  531.                                                
  532.                                                 if (g->hp <= 0) {
  533.                                                         dead = 1;
  534.                                                         createRockSmash(g->x, g->y + 20);
  535.                                                 }
  536.                                                
  537.                                                 i = MAX_WEAPONS;
  538.                                         }
  539.                                 }
  540.                         }      
  541.                 }
  542.         }
  543.  
  544.         //Destroy when out of room
  545.         {
  546.                 if (mask.y > 480) {
  547.                         dead = 1;
  548.                 }
  549.         }
  550.        
  551.         //Destroy object
  552.         {
  553.                 if (dead == 1) {
  554.                         enemyDestroy(g->id);
  555.                 }
  556.         }
  557. }
  558.  
  559. void garmrockDraw(Garmrock* g)
  560. {
  561.         if (g->blink % 2 == 0) {
  562.                 int cropX = 256,
  563.                         cropY = 192;
  564.                        
  565.                 if (g->hsp < 0) {
  566.                         cropX = 512;
  567.                 }
  568.                
  569.                 cropX += (int)g->imageIndex * 64;
  570.                
  571.                 while (cropX >= 640) {
  572.                         cropX -= 640;
  573.                         cropY += 64;
  574.                 }
  575.                
  576.                 PHL_DrawSurfacePart(g->x - 32, g->y - 32, cropX, cropY, 64, 64, images[imgMisc32]);
  577.         }
  578. }