diff options
Diffstat (limited to 'src/enemies/dodo.c')
-rw-r--r-- | src/enemies/dodo.c | 587 |
1 files changed, 587 insertions, 0 deletions
diff --git a/src/enemies/dodo.c b/src/enemies/dodo.c new file mode 100644 index 0000000..0fc26a4 --- /dev/null +++ b/src/enemies/dodo.c @@ -0,0 +1,587 @@ +#include "dodo.h" +#include "../game.h" +#include "../hero.h" +#include "../PHL.h" +#include "../enemy.h" +#include <stdlib.h> + +void dodoStep(Dodo* d); +void dodoDraw(Dodo* d); + +Mask updateDodoMask(Dodo* d, Mask mask); +int dodoWallCollision(Dodo* d, Mask mask); + +int boss1flag = 1; + +void createDodo(int x, int y, int flag) +{ + char miniboss = 0; + + if (flag != 0) { + miniboss = 1; + }else{ + flag = boss1flag; + } + + if (flags[flag] == 0) { + PHL_FreeSurface(images[imgBoss]); + images[imgBoss] = PHL_LoadQDA("boss01.bmp"); + + int i; + for (i = 0; i < MAX_ENEMIES; i++) { + if (enemies[i] == NULL) { + + if (miniboss == 0) { + setBossRoom(); + } + + Enemy* e = malloc(sizeof *e); + Dodo* d = malloc(sizeof *d); + d->id = i; + + d->x = x; + d->y = y; + + d->vsp = -6; + d->hsp = 0; + d->grav = 0.2; + + d->onground = 0; + d->dir = -1; + if (herox > d->x) { + d->dir = 1; + } + + d->imageIndex = 0; + + d->timer = 0; + d->state = 2; + + d->hp = 45; + d->blink = 0; + + d->tojump = 1; + d->jumptoggle = 0; + + d->flag = flag; + + e->data = d; + e->enemyStep = dodoStep; + e->enemyDraw = dodoDraw; + e->type = 40; + + enemies[i] = e; + i = MAX_ENEMIES; + } + } + } +} + +void dodoStep(Dodo* d) +{ + char dead = 0; + + //Constants + double fric = 0.06; + + //Animation vars + double imgspd = 0; + int frames = 0; + + //timers + { + if (d->timer > 0) { + d->timer -= 1; + } + + if (d->blink > 0) { + d->blink -= 1; + } + } + + //Setup Mask + Mask mask; + { + mask.circle = mask.unused = 0; + mask.w = 56; + mask.h = 56; + mask = updateDodoMask(d, mask); + } + + //Idle + if (d->state == 0) + { + d->hsp = 0; + d->vsp = 0; + + //Animate + imgspd = 0.1; + frames = 4; + + //End state + if (d->timer <= 0) { + //Go to chase + if (d->tojump == 0) { + d->state = 1; + d->timer = 260; + d->tojump = 1; + } + //Go to windup + else { + d->state = 3; + d->timer = 30; + } + } + + //Fall + { + if (d->onground == 0) { + d->state = 6; + d->imageIndex = 1; + } + } + } + + //Chase + else if (d->state == 1) + { + //Animate + imgspd = 0.2; + frames = 4; + + //Chase + if ( (d->dir == -1 && herox < d->x) || (d->dir == 1 && herox > d->x) ) { + d->hsp += (fric / 2) * d->dir; + + //limit speed + if (d->hsp > 3) { + d->hsp = 3; + } + if (d->hsp < -3) { + d->hsp = -3; + } + } + + //Turn around + else{ + d->hsp -= fric * d->dir; + + //Done slowing down + if ( (d->dir == 1 && d->hsp <= 0) || (d->dir == -1 && d->hsp >= 0) ) { + d->hsp = 0; + d->state = 4; + d->imageIndex = 0; + } + } + + //Stop running + { + if (d->timer <= 0) { + if (d->hsp >= 1 || d->hsp <= -1) { + d->state = 5; + } + } + } + + //Fall + { + if (d->onground == 0) { + d->state = 6; + d->imageIndex = 1; + } + } + + } + + //Turn around + else if (d->state == 4) + { + //Animate + imgspd = 0; + d->imageIndex += 0.2; + + //Done turning around + if (d->imageIndex >= 3) { + d->dir *= -1; + d->state = 1; + d->imageIndex = 0; + } + + //Fall + { + if (d->onground == 0) { + d->state = 6; + d->imageIndex = 1; + } + } + } + + //Jump + if (d->state == 2) + { + //Set image + imgspd = 0; + { + //Fall + d->imageIndex = 0; + + //Jump + if (d->vsp < 0) { + d->imageIndex = 1; + } + } + + //Face hsp + { + if (d->hsp > 0) { + d->dir = 1; + } + if (d->hsp < 0) { + d->dir = -1; + } + } + + //Land + { + if (d->onground == 1) { + d->state = 5; + d->tojump = 0; + + PHL_PlaySound(sounds[sndHit04], CHN_ENEMIES); + quakeTimer = 30; + createEffectExtra(3, d->x - 30, d->y + 50, -1, 0, 0); + createEffectExtra(3, d->x - 10, d->y + 50, 1, 0, 0); + } + } + + } + + //Windup + if (d->state == 3) + { + //Set image + imgspd = 0; + d->imageIndex = 0; + + //Jump + if (d->timer <= 0) { + d->state = 2; + PHL_PlaySound(sounds[sndJump01], CHN_ENEMIES); + if (d->jumptoggle == 0) { + d->jumptoggle = 1; + d->vsp = -3; + d->hsp = 2 * d->dir; + }else{ + d->jumptoggle = 0; + d->hsp = 1.5 * d->dir; + d->vsp = -6; + } + } + } + + //Slide to a stop + else if (d->state == 5) + { + //Friction + { + if (d->hsp > 0) { + d->hsp -= fric; + if (d->hsp <= 0) { + d->hsp = 0; + } + } + else if (d->hsp < 0) { + d->hsp += fric; + if (d->hsp >= 0) { + d->hsp = 0; + } + } + } + + //Go to idle + { + if (d->hsp == 0) { + d->state = 0; + d->timer = 140; + } + } + + } + + //Fall + if (d->state == 6) + { + //Set image + imgspd = 0; + d->imageIndex = 0; + + //Face hsp + { + if (d->hsp > 0) { + d->dir = 1; + } + if (d->hsp < 0) { + d->dir = -1; + } + } + + //Land + { + if (d->onground == 1) { + d->state = 5; + d->tojump = 1; + } + } + + } + + //Death + if (d->state == 7) + { + imgspd = 0.2; + frames = 4; + + //Movement + d->y += 0.2; + + if (d->blink % 12 == 0) { + createEffect(2, d->x - 72 + (rand() % 80), d->y - 12 + (rand() % 76)); + } + + if (d->blink <= 0) { + dead = 1; + } + } + + else{ + //Horizontal movement + { + if (d->hsp != 0) { + d->x += d->hsp; + + //Wall collision + if (d->state != 6) { + if (dodoWallCollision(d, mask) == 1) { + d->hsp *= -1; + if (d->state == 1) { + d->state = 5; + } + } + } + + } + } + + //Vertical movement + { + if (d->vsp != 0) { + d->y += d->vsp; + + mask = updateDodoMask(d, mask); + PHL_Rect collide = getTileCollision(1, mask); + if (collide.x != -1) { + if (d->vsp < 0) { + d->y = collide.y + 40 - (96 - 14 - mask.h); + } + else if (d->vsp > 0) { + d->y = collide.y - 96 + 14; + } + } + } + } + + //Check if onground + mask = updateDodoMask(d, mask); + mask.y += 1; + if (!checkTileCollision(1, mask)) { + d->onground = 0; + }else{ + d->onground = 1; + } + mask.y -= 1; + + //Gravity + { + if (d->onground == 0) { + d->vsp += d->grav; + } + } + + //Weapon collision + { + int i; + for (i = 0; i < MAX_WEAPONS; i++) { + if (weapons[i] != NULL) { + if (weapons[i]->cooldown == 0) { + if (checkCollision(mask, weapons[i]->weaponMask)) { + weaponHit(weapons[i]); + //Hit + d->blink = 15; + d->hp -= 1; + + //Death + if (d->hp <= 0) { + d->state = 7; + d->blink = 180; + } + + i = MAX_WEAPONS; + } + } + } + } + } + + //Hit Player + { + if (checkCollision(mask, getHeroMask())) { + heroHit(30, d->x); + } + } + } + + //Animate + { + if (imgspd != 0) { + d->imageIndex += imgspd; + + if (d->imageIndex >= frames) { + d->imageIndex -= frames; + } + } + } + + //Destroy object + { + if (dead == 1) { + //Is the level 1 boss + if (d->flag == boss1flag) { + bossDefeatedFlag = 1; + PHL_StopMusic(); + } + + roomSecret = 1; + flags[d->flag] = 1; + enemyDestroy(d->id); + } + } + +} + +void dodoDraw(Dodo* d) +{ + //PHL_DrawMask(d->mask); + if (d->blink % 2 == 0) { + int cropX = 0, + cropY = 0; + + int dirW = 0; + + //Idle + if (d->state == 0) { + dirW = 0; + int frame = 0; + + if (d->dir == 1) { + int animation[4] = {0, 6, 7, 6}; + frame = animation[(int)d->imageIndex]; + }else{ + int animation[4] = {3, 8, 9, 8}; + frame = animation[(int)d->imageIndex]; + } + + cropX = frame * 96; + + while (cropX >= 576) { + cropX -= 576; + cropY += 96; + } + } + + //Chase + else if (d->state == 1 || d->state == 7) { + dirW = 288; + int animation[4] = {0, 1, 0, 2}; + + cropX = animation[(int)d->imageIndex] * 96; + } + + //Jump + else if (d->state == 2) { + dirW = 192; + + cropY = 192; + cropX = (int)d->imageIndex * 96; + } + + //Turn around + else if (d->state == 4) { + dirW = 0; + cropY = 288; + + if (d->dir == 1) { + int animation[3] = {0, 1, 2}; + cropX = animation[(int)d->imageIndex] * 96; + }else{ + int animation[3] = {2, 1, 0}; + cropX = animation[(int)d->imageIndex] * 96; + } + } + + //Duck + else if (d->state == 3 || d->state == 5 || d->state == 6) { + dirW = 192; + + cropX = 0; + cropY = 192; + } + + //Direction offset + { + if (dirW != 0 && d->dir == -1) { + cropX += dirW; + } + } + + PHL_DrawSurfacePart(d->x - 48, d->y, cropX, cropY, 96, 96, images[imgBoss]); + } +} + +Mask updateDodoMask(Dodo* d, Mask mask) +{ + mask.x = d->x - (mask.w / 2); + mask.y = d->y + (96 - 14 - mask.h); + + return mask; +} + +int dodoWallCollision(Dodo* d, Mask mask) +{ + int result = 0; + + mask = updateDodoMask(d, mask); + + //Stay inside of room + if (d->x < 24) { + result = 1; + d->x = 24; + } + else if (d->x > 616) { + result = 1; + d->x = 616; + } + else{ + //Tile collision + PHL_Rect collide = getTileCollision(1, mask); + if (collide.x != -1) { + result = 1; + if (d->hsp > 0) { + d->x = collide.x - (mask.w / 2); + }else{ + d->x = collide.x + 40 + (mask.w / 2); + } + } + } + + return result; +}
\ No newline at end of file |