Subversion Repositories Kolibri OS

Rev

Blame | Last modification | View Log | RSS feed

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