aboutsummaryrefslogtreecommitdiff
path: root/src/enemies/garm.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/enemies/garm.c')
-rw-r--r--src/enemies/garm.c578
1 files changed, 578 insertions, 0 deletions
diff --git a/src/enemies/garm.c b/src/enemies/garm.c
new file mode 100644
index 0000000..b9c59ec
--- /dev/null
+++ b/src/enemies/garm.c
@@ -0,0 +1,578 @@
+#include "garm.h"
+#include "../game.h"
+#include "../PHL.h"
+#include "../hero.h"
+#include <stdlib.h>
+
+int boss7flag = 47;
+
+void garmStep(Garm* g);
+void garmDraw(Garm* g);
+
+void garmrockStep(Garmrock* g);
+void garmrockDraw(Garmrock* g);
+
+void createGarm(int x, int y)
+{
+ if (flags[boss7flag] == 0) { //have not beaten boss 7
+ PHL_FreeSurface(images[imgBoss]);
+ images[imgBoss] = PHL_LoadQDA("boss07.bmp");
+
+ int i;
+ for (i = 0; i < MAX_ENEMIES; i++) {
+ if (enemies[i] == NULL) {
+ setBossRoom();
+
+ Enemy* e = malloc(sizeof *e);
+ Garm* g = malloc(sizeof *g);
+
+ g->id = i;
+
+ g->hp = 105;
+ //g->hp = 1;
+
+ g->x = x;
+ g->y = y;
+
+ g->hsp = 0;
+ g->vsp = 0;
+
+ g->dir = -1;
+
+ g->imageIndex = 0;
+
+ g->state = 0;
+ g->timer = 0;
+
+ g->blink = 0;
+
+ g->substate = 0;
+ g->wallcounter = 0;
+ g->targx = 0;
+
+ e->data = g;
+ e->enemyStep = garmStep;
+ e->enemyDraw = garmDraw;
+ e->type = 46;
+
+ enemies[i] = e;
+ i = MAX_ENEMIES;
+ }
+ }
+ }
+}
+
+void garmStep(Garm* g)
+{
+ char dead = 0;
+
+ //Blink animation
+ {
+ if (g->blink > 0) {
+ g->blink -= 1;
+ }
+ }
+
+ //Setup Mask
+ Mask mask;
+ {
+ mask.circle = mask.unused = 0;
+ mask.w = 88;
+ mask.h = 104;
+ mask.x = g->x - (mask.w / 2);
+ mask.y = g->y + (120 - mask.h);
+ }
+
+ //Stand still
+ if (g->state == 0)
+ {
+ //Animate
+ {
+ g->imageIndex += 0.0625;
+ if (g->imageIndex >= 2) {
+ g->imageIndex -= 2;
+ }
+ }
+
+ //End state
+ {
+ g->timer += 1;
+ if (g->timer >= 60) {
+ g->state = 1;
+ //g->vsp = -4.5;
+ g->counter = 0;
+ g->timer = 0;
+ //PHL_PlaySound(sounds[sndPi09], CHN_ENEMIES);
+ }
+ }
+ }
+
+ //Bounce
+ else if (g->state == 1)
+ {
+ //Animate
+ {
+ g->imageIndex += 0.33;
+ if (g->imageIndex >= 3) {
+ g->imageIndex -= 3;
+ }
+ }
+
+ if (g->timer > 0) {
+ g->vsp = 0;
+ g->imageIndex = 0;
+ g->timer -= 1;
+ if (g->timer <= 0) {
+ //End state
+ if (g->counter >= 3) {
+ g->state = 2;
+ g->counter = 0;
+ g->imageIndex = 0;
+ g->vsp = -6;
+ g->hsp = 8;
+ if (g->x > herox) {
+ g->hsp *= -1;
+ }
+
+ if (g->substate == 0) {
+ g->wallcounter = 1;
+ g->substate = 1;
+ }else{
+ g->wallcounter = 2;
+ g->substate = 0;
+ }
+ }else{
+ g->vsp = -5;
+ }
+ }
+ }
+
+ else if (g->timer == 0) {
+ double grav = 0.25;
+
+ //Movement
+ if (g->timer == 0) {
+ g->y += g->vsp;
+ g->vsp += grav;
+ mask.y = g->y + (120 - mask.h);
+ }
+
+ //Land on ground
+ if (g->vsp >= 0 && g->timer == 0) {
+ PHL_Rect collide = getTileCollision(1, mask);
+ if (collide.x != -1) {
+ g->y = collide.y - 120;
+ mask.y = g->y + (120 - mask.h);
+ g->vsp = 0;
+ g->timer = 3;
+ g->counter += 1;
+ PHL_PlaySound(sounds[sndPi09], CHN_ENEMIES);
+ }
+ }
+ }
+ }
+
+ //Leap towards wall
+ else if (g->state == 2)
+ {
+ double grav = 0.25;
+
+ //Set image
+ {
+ if (g->hsp > 0) {
+ g->imageIndex = 0;
+ }
+
+ if (g->hsp < 0) {
+ g->imageIndex = 1;
+ }
+ }
+
+ //Movement
+ {
+ g->y += g->vsp;
+ g->vsp += grav;
+ mask.y = g->y + (120 - mask.h);
+
+ g->x += g->hsp;
+ mask.x = g->x - (mask.w / 2);
+ }
+
+ if (g->wallcounter > 0)
+ {
+ PHL_Rect collide = getTileCollision(1, mask);
+ if (collide.x != -1) {
+ g->wallcounter -= 1;
+ if (g->hsp < 0) {
+ g->x = collide.x + 40 + (mask.w / 2);
+ }
+ if (g->hsp > 0) {
+ g->x = collide.x - (mask.w / 2);
+ }
+ g->state = 3;
+ g->timer = 0;
+ }
+ }
+
+ //Ground pound
+ else {
+ char action = 0;
+
+ if ( (g->hsp > 0 && g->x > g->targx) || (g->hsp < 0 && g->x < g->targx) ) {
+ action = 1;
+ }
+ //Wall collision backup
+ else{
+ PHL_Rect collide = getTileCollision(1, mask);
+ if (collide.x != -1) {
+ if (g->hsp < 0) {
+ g->x = collide.x + 40 + (mask.w / 2);
+ }
+ if (g->hsp > 0) {
+ g->x = collide.x - (mask.w / 2);
+ }
+ action = 1;
+ }
+ }
+
+ if (action == 1) {
+ g->state = 4;
+ g->vsp = -4;
+ PHL_PlaySound(sounds[sndWolf01], CHN_ENEMIES);
+ }
+ }
+ }
+
+ //Grab wall
+ else if (g->state == 3)
+ {
+ g->timer += 1;
+ if (g->timer > 5) {
+ g->state = 2;
+ g->vsp = -6;
+ g->hsp *= -1;
+ PHL_PlaySound(sounds[sndPi09], CHN_ENEMIES);
+
+ g->targx = herox;
+
+ if (g->wallcounter <= 0) {
+ //Get distance from player
+ int dis = g->x - g->targx;
+ {
+ if (dis < 0) {
+ dis *= -1;
+ }
+ }
+
+ if (dis < 200 || g->substate == 1) {
+ g->hsp /= 2;
+ }
+ }
+ }
+ }
+
+ //Ground pound
+ else if (g->state == 4)
+ {
+ double grav = 0.2;
+
+ //Animate
+ {
+ g->imageIndex += 0.33;
+ if (g->imageIndex >= 3) {
+ g->imageIndex -= 3;
+ }
+ }
+
+ g->y += g->vsp;
+ g->vsp += grav;
+ mask.y = g->y + (120 - mask.h);
+
+ //Collide with floor
+ {
+ PHL_Rect collide = getTileCollision(1, mask);
+
+ if (collide.x != -1) {
+ g->y = collide.y - 120;
+ PHL_PlaySound(sounds[sndHit04], CHN_ENEMIES);
+ quakeTimer = 30;
+ g->state = 0;
+ g->timer = -20;
+ //Create rocks
+ createGarmrock(g->x + 64, g->y + 100, 2, -4);
+ createGarmrock(g->x + 34, g->y + 100, 1, -5);
+ createGarmrock(g->x - 34, g->y + 100, -1, -5);
+ createGarmrock(g->x - 64, g->y + 100, -2, -4);
+
+ createEffectExtra(3, g->x - 50, g->y + 90, -1, 0, 0);
+ createEffectExtra(3, g->x + 10, g->y + 90, 1, 0, 0);
+ }
+ }
+ }
+
+ //Dead
+ if (g->state == 5) {
+ //Animate
+ {
+ g->imageIndex += 0.33;
+ if (g->imageIndex >= 3) {
+ g->imageIndex -= 3;
+ }
+ }
+
+ g->y += 0.2;
+
+ if (g->blink % 12 == 0) {
+ createEffect(2, g->x - 64 + (rand() % 100), g->y + 60 - 64 + (rand() % 80));
+ }
+
+ if (g->blink <= 0) {
+ dead = 1;
+ }
+ }
+
+ else{
+ if (dead == 0) {
+ //Update Mask
+ {
+ mask.x = g->x - (mask.w / 2);
+ mask.y = g->y + (120 - mask.h);
+ }
+
+ //Hero collision
+ {
+ if (checkCollision(getHeroMask(), mask) == 1) {
+ heroHit(40, mask.x + (mask.w / 2));
+ }
+ }
+
+ //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]);
+ g->hp -= 1;
+ g->blink = 15;
+ //Dead
+ if (g->hp <= 0) {
+ g->state = 5;
+ g->blink = 200;
+ }
+
+ i = MAX_WEAPONS;
+ }
+ }
+ }
+ }
+ }
+
+ }
+ }
+
+ if (dead == 1) {
+ //Destroy
+ {
+ enemyDestroy(g->id);
+ bossDefeatedFlag = 1;
+ roomSecret = 1;
+
+ flags[boss7flag] = 1;
+ PHL_StopMusic();
+ }
+ }
+
+}
+
+void garmDraw(Garm* g)
+{
+ if (g->blink % 2 == 0) {
+ int cropX = 0,
+ cropY = 0;
+
+ //Jump Spinning
+ if ((g->state == 1 && g->timer == 0) || g->state == 4 || g->state == 5) {
+ cropY = 128;
+ cropX = 256;
+ }
+
+ //Jump
+ if (g->state == 2) {
+ cropY = 128;
+ }
+
+ //Wall grab
+ if (g->state == 3) {
+ cropX = 384;
+ }
+
+ cropX += (int)g->imageIndex * 128;
+
+ PHL_DrawSurfacePart(g->x - 64, g->y - 8, cropX, cropY, 128, 128, images[imgBoss]);
+ }
+}
+
+//Rocks
+void createGarmrock(int x, int y, double hsp, double vsp)
+{
+ int i;
+ for (i = 0; i < MAX_ENEMIES; i++) {
+ if (enemies[i] == NULL) {
+ Enemy* e = malloc(sizeof *e);
+ Garmrock* g = malloc(sizeof *g);
+
+ g->id = i;
+ g->hp = 3;
+
+ g->x = x;
+ g->y = y;
+
+ g->hsp = hsp;
+ g->vsp = vsp;
+
+ g->imageIndex = 0;
+
+ g->counter = 0;
+ g->inwall = 0;
+ g->blink = 0;
+
+ e->data = g;
+ e->enemyStep = garmrockStep;
+ e->enemyDraw = garmrockDraw;
+ e->type = -1;
+
+ enemies[i] = e;
+ i = MAX_ENEMIES;
+ }
+ }
+}
+
+void garmrockStep(Garmrock* g)
+{
+ char dead = 0;
+
+ //Setup Mask
+ Mask mask;
+ {
+ mask.circle = mask.unused = 0;
+ mask.w = 44;
+ mask.h = 44;
+ mask.x = g->x - (mask.w / 2);
+ mask.y = g->y - (mask.h / 2);
+ }
+
+ //Animate
+ {
+ g->imageIndex += 0.2;
+ if (g->imageIndex >= 4) {
+ g->imageIndex -= 4;
+ }
+
+ if (g->blink > 0) {
+ g->blink -= 1;
+ }
+ }
+
+ //Horizontal movement
+ {
+ g->x += g->hsp;
+ mask.x = g->x - (mask.w / 2);
+
+ g->inwall = 0;
+ if (checkTileCollision(1, mask) == 1) {
+ g->inwall = 1;
+ }
+ }
+
+ //Vertical movement
+ {
+ double grav = 0.1;
+
+ g->y += g->vsp;
+ g->vsp += grav;
+ mask.y = g->y - (mask.h / 2);
+
+ if (g->inwall == 0 && g->counter == 0) {
+ PHL_Rect collide = getTileCollision(1, mask);
+ if (collide.x != -1) {
+ g->counter = 1;
+ g->y = collide.y - (mask.h / 2);
+ g->vsp = -2;
+ PHL_PlaySound(sounds[sndHit06], CHN_ENEMIES);
+ }
+ }
+ }
+
+ //Update mask
+ {
+ mask.x = g->x - (mask.w / 2);
+ mask.y = g->y - (mask.h / 2);
+ }
+
+ //Hero collision
+ {
+ if (checkCollision(getHeroMask(), mask) == 1) {
+ heroHit(30, mask.x + (mask.w / 2));
+ }
+ }
+
+ //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]);
+ g->hp -= 1;
+ g->blink = 15;
+
+ if (g->hp <= 0) {
+ dead = 1;
+ createRockSmash(g->x, g->y + 20);
+ }
+
+ i = MAX_WEAPONS;
+ }
+ }
+ }
+ }
+ }
+
+ //Destroy when out of room
+ {
+ if (mask.y > 480) {
+ dead = 1;
+ }
+ }
+
+ //Destroy object
+ {
+ if (dead == 1) {
+ enemyDestroy(g->id);
+ }
+ }
+}
+
+void garmrockDraw(Garmrock* g)
+{
+ if (g->blink % 2 == 0) {
+ int cropX = 256,
+ cropY = 192;
+
+ if (g->hsp < 0) {
+ cropX = 512;
+ }
+
+ cropX += (int)g->imageIndex * 64;
+
+ while (cropX >= 640) {
+ cropX -= 640;
+ cropY += 64;
+ }
+
+ PHL_DrawSurfacePart(g->x - 32, g->y - 32, cropX, cropY, 64, 64, images[imgMisc32]);
+ }
+} \ No newline at end of file