aboutsummaryrefslogtreecommitdiff
path: root/src/enemies/dodo.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/enemies/dodo.c')
-rw-r--r--src/enemies/dodo.c587
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