From de29b11a88dbdd3af0824e59b51528b91ee73c54 Mon Sep 17 00:00:00 2001 From: ptitSeb Date: Thu, 30 Nov 2017 22:49:38 +0100 Subject: First commit. Version works on Linux (keyboard only, not configurable) --- src/enemies/devil.c | 458 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 458 insertions(+) create mode 100644 src/enemies/devil.c (limited to 'src/enemies/devil.c') diff --git a/src/enemies/devil.c b/src/enemies/devil.c new file mode 100644 index 0000000..ae22e98 --- /dev/null +++ b/src/enemies/devil.c @@ -0,0 +1,458 @@ +#include "devil.h" +#include "../game.h" +#include "../PHL.h" +#include "../hero.h" +#include +#include + +int boss6flag = 31; + +void devilStep(Devil* d); +void devilDraw(Devil* d); + +void orbStep(Orb* o); +void orbDraw(Orb* o); + +void createDevil(int x, int y) +{ + if (flags[boss6flag] == 0) { //have not beaten boss 6 + PHL_FreeSurface(images[imgBoss]); + images[imgBoss] = PHL_LoadQDA("boss04.bmp"); + + int i; + for (i = 0; i < MAX_ENEMIES; i++) { + if (enemies[i] == NULL) { + setBossRoom(); + + Enemy* e = /*(Enemy*)*/malloc(sizeof *e); + Devil* d = /*(Devil*)*/malloc(sizeof *d); + d->id = i; + + d->x = x; + d->y = y; + + d->ystart = d->y; + d->newystart = d->ystart; + d->hsp = -2.5; + + d->hp = 100; + //d->hp = 1; + + d->state = 0; + d->timer = 0; + + d->blink = 0; + d->boblen = 32; + d->bobspd = 3; + + d->tailangle = 90; + + d->rotcounter = 0; + d->bobcounter = 0; + + d->bobspd = 3; + d->rotspd = 1; + + d->imageIndex = 0; + + e->data = d; + e->enemyStep = devilStep; + e->enemyDraw = devilDraw; + e->type = 45; + + enemies[i] = e; + i = MAX_ENEMIES; + } + } + } +} + +void devilStep(Devil* d) +{ + char dead = 0; + + //Animate + { + d->imageIndex += 0.1; + if (d->imageIndex >= 2) { + d->imageIndex -= 2; + } + + if (d->blink > 0) { + d->blink -= 1; + } + } + + //Bob + { + if (d->state != 4) { + d->bobcounter += d->bobspd; + if (d->bobcounter >= 360) { + d->bobcounter -= 360; + } + + d->y = d->ystart + (d->boblen * cos(d->bobcounter * 3.14159 / 180)); + } + } + + //Swing tail + { + d->rotcounter += d->rotspd; + if (d->rotcounter >= 360) { + d->rotcounter -= 360; + } + + d->tailangle = 90 + (55 * cos(d->rotcounter * 3.14159 / 180)); + } + + //Patterns + { + //movement + if (d->state == 0 || d->state == 2) + { + d->rotspd = 1; + d->boblen = 32; + d->bobspd = 3; + + //Re-align ystart + if (d->ystart > d->newystart) { + d->ystart -= 1; + } + if (d->ystart < d->newystart) { + d->ystart += 1; + } + + d->x += d->hsp; + + //Slow Down + double rate = 0.016; + if (d->hsp < 0) { + d->hsp += rate; + if (d->hsp >= 0) { + d->hsp = 0; + } + } + + if (d->hsp > 0) { + d->hsp -= rate; + if (d->hsp <= 0) { + d->hsp = 0; + } + } + + if (d->hsp == 0) { + d->timer = 0; + if (d->state == 0) { + d->state = 1; + } + + if (d->state == 2) { + if ((d->rotcounter >= 90 && d->rotcounter <= 90 + d->rotspd) || (d->rotcounter >= 270 && d->rotcounter <= 270 + d->rotspd)) { + d->state = 3; + } + } + } + } + //mid room pause + else if (d->state == 1) + { + d->timer += 1; + if (d->timer >= 60) { + if (d->state == 1) { + d->hsp = 2.5; + if (herox < d->x) { + d->hsp *= -1; + } + } + d->state = 2; + } + } + //Shoot + else if (d->state == 3) + { + d->rotspd = 3; + d->boblen = 10; + d->bobspd = 10; + + d->timer += 1; + + //Shoot orbs + if (d->timer == 120 || d->timer == 240 || d->timer == 360) { + int aim = (atan2((heroy + 20) - d->y, d->x - herox) * 180 / 3.14159) + 270; + + int spawnY = d->y + 20; + createOrb(d->x, spawnY, aim + 22); + createOrb(d->x, spawnY, aim + 11); + createOrb(d->x, spawnY, aim); + createOrb(d->x, spawnY, aim - 11); + createOrb(d->x, spawnY, aim - 22); + + PHL_PlaySound(sounds[sndShot03], CHN_ENEMIES); + } + + if (d->timer == 360) { + d->state = 0; + d->hsp = 2.5; + + if (d->x > 320) { + d->hsp *= -1; + } + + int chaseY = heroy - d->ystart; + if (chaseY > 52) { chaseY = 52; } + if (chaseY < -52) { chaseY = -52; } + + d->newystart = d->ystart + chaseY; + } + } + + //Death + if (d->state == 4) { + d->rotspd = 3; + d->y += 0.2; + d->timer -= 1; + + if (d->timer % 12 == 0) { + createEffect(2, d->x - 64 + (rand() % 100), d->y - 64 + (rand() % 80)); + } + + if (d->timer <= 0) { + dead = 1; + } + } + } + + //Collisions + if (d->state != 4) { + //Setup masks + Mask masks[6]; + + //Head mask + masks[0].unused = masks[0].circle = 0; + masks[0].w = 100; + masks[0].h = 104; + masks[0].x = d->x - (masks[0].w / 2); + masks[0].y = d->y - (masks[0].h / 2); + + //Link masks + for (int i = 1; i < 5; i++) { + int taildis[4] = {54, 80, 108, 134}; + int taillag[4] = {10, 15, 10, 5}; + + double newtailangle = 90 + (55 * cos((d->rotcounter - taillag[i-1]) * 3.14159 / 180)); + + masks[i].unused = 0; + masks[i].circle = 1; + masks[i].w = 16; + masks[i].h = 16; + masks[i].x = d->x + (taildis[i-1] * cos(newtailangle * 3.14159 / 180)); + masks[i].y = d->y + (taildis[i-1] * sin(newtailangle * 3.14159 / 180)); + } + + //Barb mask + masks[5].unused = masks[5].circle = 0; + masks[5].w = 40; + masks[5].h = 40; + masks[5].x = (d->x + (160 * cos(d->tailangle * 3.14159 / 180))) - (masks[5].w / 2); + masks[5].y = (d->y + (160 * sin(d->tailangle * 3.14159 / 180))) - (masks[5].h / 2); + + //Collisions + int hitHead = 0; + for (int a = 0; a < 6; a++) + { + if (a == 0 || a == 5) { + //Hit Player + if (checkCollision(masks[a], getHeroMask())) { + + int damage = 25; + if (a == 0) { + damage = 50; + } + + if (heroHit(damage, masks[a].x + (masks[a].w / 2)) == 1) { + if (a == 5) { //Barb + heroStun(); + } + } + } + } + + //Weapon collision + if (hitHead == 0) { + for (int i = 0; i < MAX_WEAPONS; i++) { + if (weapons[i] != NULL) { + if (weapons[i]->cooldown == 0) { + if (checkCollision(masks[a], weapons[i]->weaponMask)) { + weaponHit(weapons[i]); + + //Head + if (a == 0) { + d->hp -= 1; + d->blink = 15; + hitHead = 1; + + if (d->hp <= 0) { + d->state = 4; + d->timer = 180; + d->blink = 200; + } + }else{ + PHL_PlaySound(sounds[sndHit03], CHN_WEAPONS); + } + + i = MAX_WEAPONS; + } + } + } + } + } + } + } + + //Destroy + if (dead == 1) { + enemyDestroy(d->id); + bossDefeatedFlag = 1; + roomSecret = 1; + + flags[boss6flag] = 1; + PHL_StopMusic(); + } +} + +void devilDraw(Devil* d) +{ + if (d->blink % 2 == 0) + { + int dx, dy; + + //Draw tail + int taildis[4] = {54, 80, 108, 134}; + int taillag[4] = {10, 15, 10, 5}; + for (int i = 0; i < 4; i++) { + double newtailangle = 90 + (55 * cos((d->rotcounter - taillag[i]) * 3.14159 / 180)); + + dx = d->x + (taildis[i] * cos(newtailangle * 3.14159 / 180)) - 32; + dy = d->y + (taildis[i] * sin(newtailangle * 3.14159 / 180)) - 32; + PHL_DrawSurfacePart(dx, dy, 0, 128, 64, 64, images[imgBoss]); + } + + //Draw Head + dx = d->x - 64; + dy = d->y - 64; + PHL_DrawSurfacePart(dx, dy, (int)d->imageIndex * 128, 0, 128, 128, images[imgBoss]); + + //Draw Tail Tip + dx = d->x + (160 * cos(d->tailangle * 3.14159 / 180)) - 32; + dy = d->y + (160 * sin(d->tailangle * 3.14159 / 180)) - 32; + PHL_DrawSurfacePart(dx, dy, 64, 128, 64, 64, images[imgBoss]); + + } +} + + +//Stone Orbs +void createOrb(int x, int y, double dir) +{ + int i; + for (i = 0; i < MAX_ENEMIES; i++) { + if (enemies[i] == NULL) { + Enemy* e = /*(Enemy*)*/malloc(sizeof *e); + Orb* o = /*(Orb*)*/malloc(sizeof *o); + o->id = i; + + o->x = x; + o->y = y; + + o->dir = dir; + + o->imageIndex = 0; + + e->data = o; + e->enemyStep = orbStep; + e->enemyDraw = orbDraw; + e->type = -1; + + enemies[i] = e; + i = MAX_ENEMIES; + } + } +} + +void orbStep(Orb* o) +{ + char dead = 0; + + //Animate + { + o->imageIndex += 0.33; + if (o->imageIndex >= 4) { + o->imageIndex -= 4; + } + } + + //Movement + { + int spd = 4; + o->x += spd * sin(o->dir * 3.14159 / 180); + o->y += spd * cos(o->dir * 3.14159 / 180); + } + + //Collision + { + Mask mask; + mask.unused = 0; + mask.circle = 1; + mask.w = 6; + mask.x = o->x; + mask.y = o->y; + + //Collide with shield + /*if (checkCollision(mask, shieldMask)) { + createEffect(1, o->x - 20, o->y - 20); + PHL_PlaySound(sounds[sndHit07], CHN_EFFECTS); + dead = 1; + }else{*/ + //Hit player + if (checkCollision(getHeroMask(), mask)) { + heroStone(); + heroHit(25, mask.x); + } + //} + + //Collide with weapon + int i; + for (i = 0; i < MAX_WEAPONS; i++) { + if (weapons[i] != NULL) { + if (checkCollision(mask, weapons[i]->weaponMask)) { + weaponHit(weapons[i]); + + createEffect(2, o->x - 32, o->y - 32); + dead = 1; + + i = MAX_WEAPONS; + } + } + } + } + + //Destroy if outside of room + { + if (o->x < -20 || o->x > 660 || o->y < -20 || o->y > 500) { + dead = 1; + } + } + + //Finally erase object + { + if (dead == 1) { + enemyDestroy(o->id); + } + } +} + +void orbDraw(Orb* o) +{ + int animation[4] = {0, 1, 0, 2}; + PHL_DrawSurfacePart(o->x - 20, o->y - 20, 440 + (animation[(int)o->imageIndex] * 40), 480, 40, 40, images[imgMisc20]); +} \ No newline at end of file -- cgit v1.2.3