#include "garm.h" #include "../game.h" #include "../PHL.h" #include "../hero.h" #include 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]); } }