aboutsummaryrefslogtreecommitdiff
path: root/src/enemies/hydra.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/enemies/hydra.c')
-rw-r--r--src/enemies/hydra.c1127
1 files changed, 1127 insertions, 0 deletions
diff --git a/src/enemies/hydra.c b/src/enemies/hydra.c
new file mode 100644
index 0000000..d770c9d
--- /dev/null
+++ b/src/enemies/hydra.c
@@ -0,0 +1,1127 @@
+#include "hydra.h"
+#include "../game.h"
+#include "../hero.h"
+#include <stdlib.h>
+#include <math.h>
+
+const double PI = 3.14159;
+
+double headRot = 0;
+
+void hydraStep(Hydra* h);
+void hydraDraw(Hydra* h);
+
+void hydraDestroy(Hydra* h);
+
+void hydraheadStep(Hydrahead* h);
+void hydraheadDraw(Hydrahead* h);
+
+void hydragoopStep(Hydragoop* h);
+void hydragoopDraw(Hydragoop* h);
+
+void hydrarockStep(Hydrarock* h);
+void hydrarockDraw(Hydrarock* h);
+
+void hydrashockStep(Hydrashock* h);
+void hydrashockDraw(Hydrashock* h);
+
+double getHydraX(Hydrahead* h);
+double getHydraY(Hydrahead* h);
+
+Mask getHydraMask(Hydra* h);
+int checkWeaponCollision(Mask m);
+
+double lengthdir_x(double ang, double len);
+double lengthdir_y(double ang, double len);
+
+void setHeadState(int headid, int state);
+
+
+//#hydra
+void createHydra(int x)
+{
+ PHL_FreeSurface(images[imgBoss]);
+ images[imgBoss] = PHL_LoadQDA("lboss01.bmp");
+
+ int i;
+ for (i = 4; i < MAX_ENEMIES; i++) {
+ if (enemies[i] == NULL) {
+ setBossRoom();
+
+ Enemy* e = malloc(sizeof *e);
+ Hydra* h = malloc(sizeof *h);
+ h->id = i;
+
+ h->hp = 10;
+ //h->hp = 1;
+ h->blink = 0;
+
+ h->x = x;
+ h->y = -64;
+
+ h->hsp = 0;
+ h->vsp = 0;
+
+ h->imageIndex = 0;
+
+ h->state = 0;
+ h->timer = 0;
+
+ h->patternCounter = 0;
+
+ h->onground = 0;
+ h->noheads = 0;
+
+ e->data = h;
+ e->enemyStep = hydraStep;
+ e->enemyDraw = hydraDraw;
+ e->type = 47;
+
+ enemies[i] = e;
+
+ h->headid[0] = createHydrahead(-1, 0, i);
+ h->headid[1] = createHydrahead(1, 0, i);
+ h->headid[2] = createHydrahead(1, 1, i);
+ h->headid[3] = createHydrahead(-1, 1, i);
+
+ i = MAX_ENEMIES;
+ }
+ }
+}
+
+void hydraStep(Hydra* h)
+{
+ double grav = 0.2;
+ double fric = 0.1;
+
+ //Death
+ if (h->state == 6) {
+ h->y += 0.2;
+
+ h->timer -= 1;
+ h->blink -= 1;
+
+ if (h->timer % 12 == 0) {
+ createEffect(2, h->x - 64 + (rand() % 128) - 32, h->y - 64 + (rand() % 128));
+ }
+
+ if (h->timer <= 0) {
+ hydraDestroy(h);
+ }
+ }
+ else{
+ //Setup Mask
+ Mask mask = getHydraMask(h);
+
+ //States with hydra heads
+ if (h->noheads == 0) {
+ //Fall in intro
+ if (h->state == 0) {
+ h->hsp = 0;
+ h->timer += 1;
+ if (h->timer >= 50) {
+ h->timer = 50;
+ h->imageIndex = 2;
+
+ if (h->onground == 1) {
+ h->state = 1;
+ h->timer = 0;
+ }
+ }else{
+ grav = 0;
+ }
+ }
+
+ //Wait/Pattern activate
+ else if (h->state == 1)
+ {
+ h->timer += 1;
+
+ //Stop speed animation
+ if (h->timer >= 120) {
+ int patternSize = 9;
+ int pattern[9] = {4, 0, 4, 1, 4, 2, 4, 3, 2};
+
+ //Head seizure
+ if (pattern[h->patternCounter] == 4) {
+ h->state = 4;
+ h->timer = 0;
+ }
+ //Small hop
+ if (pattern[h->patternCounter] == 0) {
+ h->state = 2;
+ h->timer = 0;
+ }
+
+ //Goop
+ if (pattern[h->patternCounter] == 1) {
+ h->timer = -120;
+ setHeadState(h->headid[0], 2);
+ setHeadState(h->headid[1], 2);
+ }
+
+ //Big Hop
+ if (pattern[h->patternCounter] == 2) {
+ h->state = 3;
+ h->timer = 0;
+ }
+
+ //Electricity
+ if (pattern[h->patternCounter] == 3) {
+ h->timer = -40;
+ setHeadState(h->headid[2], 3);
+ setHeadState(h->headid[3], 3);
+ }
+
+ h->patternCounter += 1;
+ if (h->patternCounter >= patternSize) {
+ h->patternCounter = 0;
+ }
+ }
+ }
+
+ //Head seizure state
+ else if (h->state == 4) {
+ //Speed up head animation
+ if (h->timer == 0) {
+ setHeadState(h->headid[0], 1);
+ setHeadState(h->headid[1], 1);
+ setHeadState(h->headid[2], 1);
+ setHeadState(h->headid[3], 1);
+ }
+
+ h->timer += 1;
+
+ //Stop speed animation
+ if (h->timer == 120) {
+ setHeadState(h->headid[0], 0);
+ setHeadState(h->headid[1], 0);
+ setHeadState(h->headid[2], 0);
+ setHeadState(h->headid[3], 0);
+
+ //Pattern
+ h->state = 1;
+ h->timer = 120;
+ }
+ }
+
+ //Switch to noheads mode
+ if (h->onground == 1 &&
+ enemies[h->headid[0]] == NULL &&
+ enemies[h->headid[1]] == NULL &&
+ enemies[h->headid[2]] == NULL &&
+ enemies[h->headid[3]] == NULL)
+ {
+ h->noheads = 1;
+ h->state = 1;
+ h->timer = -15;
+ h->patternCounter = 0;
+ }
+ }
+
+ //States without hydra heads
+ else{
+ //Wait/pattern activate
+ if (h->state == 1) {
+ h->timer += 1;
+
+ if (h->timer >= 0) {
+ int patternSize = 3;
+ int pattern[3] = {0, 0, 2};
+
+ //Small hop
+ if (pattern[h->patternCounter] == 0) {
+ h->state = 2;
+ h->timer = 0;
+ }
+
+ //Big Hop
+ if (pattern[h->patternCounter] == 2) {
+ h->state = 3;
+ h->timer = 0;
+ }
+
+ h->patternCounter += 1;
+ if (h->patternCounter >= patternSize) {
+ h->patternCounter = 0;
+ }
+ }
+ }
+ }
+
+ //States used by both modes
+ {
+ //Small hop
+ if (h->state == 2) {
+ //Setup
+ if (h->timer == 0) {
+ h->vsp = -2;
+ h->onground = 0;
+ h->hsp = 2.5;
+ if (herox < h->x) {
+ h->hsp *= -1;
+ }
+ }
+
+ h->timer += 1;
+
+ if (h->onground == 1) {
+ if (h->noheads == 0 || h->hsp == 0) {
+ h->state = 1;
+ h->timer = 0;
+ }
+ }
+ }
+
+ //Large Hop
+ else if (h->state == 3) {
+ h->hsp = 0;
+
+ //Setup
+ if (h->timer == 0) {
+ h->timer = 1;
+ if (h->noheads == 0) {
+ h->vsp = -8;
+ }else{
+ h->vsp = -5;
+ }
+ h->onground = 0;
+ }
+
+ if (h->onground == 1) {
+ h->timer += 1;
+
+ if (h->timer % 20 == 0) {
+ createHydrarock();
+ }
+
+ if (h->timer >= 220) {
+ h->state = 1;
+ h->timer = -15;
+ }
+ }
+ }
+ }
+
+ //Animate
+ {
+ if (h->onground == 1) {
+ h->imageIndex += 0.1;
+ if (h->imageIndex >= 2) {
+ h->imageIndex -= 2;
+ }
+ }else{
+ if (h->vsp < 0) {
+ h->imageIndex = 3;
+ }
+ else {
+ h->imageIndex = 2;
+ }
+ }
+
+ //Blink
+ if (h->blink > 0) {
+ h->blink -= 1;
+ }
+ }
+
+ //Movement
+ {
+ //Horizontal
+ if (h->hsp != 0) {
+ h->x += h->hsp;
+ mask = getHydraMask(h);
+
+ PHL_Rect collide = getTileCollision(1, mask);
+ if (collide.x != -1) {
+ int dir = 1;
+ if (h->hsp < 0) {
+ dir = -1;
+ }
+ h->x = collide.x + 20 - ((20 + (mask.w / 2)) * dir);
+
+ h->hsp *= -1;
+ }
+ }
+
+ //Friction
+ {
+ if (h->onground == 1) {
+ if (h->hsp > 0) {
+ h->hsp -= fric;
+ if (h->hsp < 0) {
+ h->hsp = 0;
+ }
+ }
+ if (h->hsp < 0) {
+ h->hsp += fric;
+ if (h->hsp > 0) {
+ h->hsp = 0;
+ }
+ }
+ }
+ }
+
+ //Vertical
+ {
+ int maxVsp = 9;
+
+ if (h->onground == 0) {
+ h->y += h->vsp;
+ h->vsp += grav;
+ mask = getHydraMask(h);
+
+ //Limit vsp
+ {
+ if (h->vsp > maxVsp) {
+ h->vsp = maxVsp;
+ }
+ }
+
+ //Collide with floor
+ {
+ PHL_Rect collide = getTileCollision(1, mask);
+ if (collide.x != -1) {
+ h->y = collide.y - 64;
+ h->vsp = 0;
+ h->onground = 1;
+ PHL_PlaySound(sounds[sndHit04], CHN_ENEMIES);
+ quakeTimer = 30;
+ createEffectExtra(3, h->x - 30, h->y + 32, -1, 0, 0);
+ createEffectExtra(3, h->x - 10, h->y + 32, 1, 0, 0);
+ }
+ }
+ }
+ }
+
+ }
+
+ //Update mask
+ mask = getHydraMask(h);
+
+ //Hero Collision
+ {
+ if (checkCollision(mask, getHeroMask()) == 1) {
+ heroHit(25, h->x);
+ }
+ }
+
+ //Weapon Collision
+ {
+ int wid = checkWeaponCollision(mask);
+ if (wid != -1) {
+ //Pushed back
+ if (h->noheads == 0) {
+ h->hsp = weapons[wid]->dir;
+ PHL_PlaySound(sounds[sndPi05], CHN_ENEMIES);
+ }else{
+ h->hp -= 1;
+ h->blink = 15;
+ }
+ weaponHit(weapons[wid]);
+ //Die
+ if (h->hp <= 0) {
+ h->state = 6;
+ h->timer = 180;
+ h->blink = 200;
+ }
+
+ }
+ }
+ }
+
+}
+
+void hydraDraw(Hydra* h)
+{
+ if (h->blink % 2 == 0) {
+ int cropX = (int)h->imageIndex * 128;
+ int cropY = 128;
+
+ if (h->noheads == 1) {
+ cropY += 128;
+ }
+
+ PHL_DrawSurfacePart(h->x - 64, h->y - 64, cropX, cropY, 128, 128, images[imgBoss]);
+ }
+}
+
+void hydraDestroy(Hydra* h)
+{
+ enemyDestroy(h->id);
+ bossDefeatedFlag = 1;
+ roomSecret = 1;
+
+ PHL_StopMusic();
+}
+
+Mask getHydraMask(Hydra* h)
+{
+ Mask mask;
+
+ mask.unused = mask.circle = 0;
+ mask.w = 84;
+ mask.h = 84;
+ mask.x = h->x - (mask.w / 2);
+ mask.y = h->y - 64 + (128 - mask.h);
+
+ return mask;
+}
+
+//#heads
+int createHydrahead(int dir, int position, int bodyid)
+{
+ int result = -1;
+
+ int i;
+ for (i = 0; i < MAX_ENEMIES; i++) {
+ if (enemies[i] == NULL) {
+ Enemy* e = malloc(sizeof *e);
+ Hydrahead* h = malloc(sizeof *h);
+
+ h->id = i;
+ result = i;
+
+ h->hp = 25;
+ //h->hp = 1;
+ h->blink = 0;
+
+ h->dir = dir;
+ h->position = position;
+
+ h->imageIndex = 0;
+
+ h->neckRot = 0;
+ if (position != 0) {
+ h->neckRot -= 45;
+ }
+
+ h->state = 0;
+ h->timer = 0;
+ h->counter = 0;
+
+ h->bodyid = bodyid;
+
+ int a;
+ for (a = 0; a < 7; a++) {
+ h->bodyposX[a] = 0;
+ h->bodyposY[a] = 0;
+ }
+
+ e->data = h;
+ e->enemyStep = hydraheadStep;
+ e->enemyDraw = hydraheadDraw;
+ e->type = -1;
+
+ enemies[i] = e;
+ i = MAX_ENEMIES;
+ }
+ }
+
+ return result;
+}
+
+void hydraheadStep(Hydrahead* h)
+{
+ char dead = 0;
+
+ //Animate
+ {
+ h->imageIndex += 0.1;
+ if (h->imageIndex >= 2) {
+ h->imageIndex -= 2;
+ }
+
+ if (h->blink > 0) {
+ h->blink -= 1;
+ }
+
+ h->neckRot += 2;
+ if (h->neckRot >= 360) {
+ h->neckRot -= 360;
+ }
+ }
+
+ //States
+ {
+ //Death
+ if (h->state == 4) {
+ h->timer += 1;
+ if (h->timer % 6 == 0) {
+ createEffect(2, h->bodyposX[6 - h->counter] - 32, h->bodyposY[6 - h->counter] - 32);
+ h->counter += 1;
+ }
+
+ if (h->counter >= 7) {
+ dead = 1;
+ }
+ }
+ else{
+ if (h->state == 0) {
+ //Do nothing special
+ }
+
+ //Fast movements
+ else if (h->state == 1) {
+ h->neckRot += 2;
+ }
+
+ //Shoot goop
+ else if (h->state == 2) {
+ h->neckRot += 2;
+ h->timer += 1;
+
+ //Create Goop
+ if (h->timer % 15 == 0) {
+ int ghsp = -4 + (rand() % 9),
+ gvsp = -6;
+
+ createHydragoop(h->bodyposX[6], h->bodyposY[6], ghsp, gvsp);
+ }
+
+ if (h->timer >= 120) {
+ h->state = 0;
+ }
+ }
+
+ //Shoot electricity
+ else if (h->state == 3) {
+ if (h->timer == 0) {
+ h->timer = 1;
+ }
+
+ if (h->timer % 20 == 0) {
+ if (h->counter == 0) {
+ createHydrashock(h->bodyposX[6] + (70 * h->dir), h->bodyposY[6] + 20);
+ }
+ h->neckRot -= 2;
+ h->counter += 1;
+ if (h->counter >= 20) {
+ h->counter = 0;
+ h->timer += 1;
+ }
+ }else{
+ h->neckRot += 2;
+ h->timer += 1;
+ }
+
+ if (h->timer > 80) {
+ h->state = 0;
+ /*
+ Hydra* body = enemies[h->bodyid]->data;
+ body->state = 1;
+ body->timer = 239;
+ */
+ }
+
+ }
+
+ Mask mask;
+ mask.circle = mask.unused = 0;
+
+ //Collide with player
+ {
+ int i;
+ for (i = 0; i < 7; i+=2) {
+ //Setup mask
+ {
+ mask.w = 48;
+ mask.h = 48;
+
+ //Head
+ if (i == 6) {
+ mask.w = 60;
+ mask.h = 36;
+ }
+
+ mask.x = h->bodyposX[i] - (mask.w / 2);
+ mask.y = h->bodyposY[i] - (mask.h / 2);
+ }
+
+ //Collide
+ if (checkCollision(getHeroMask(), mask) == 1) {
+ heroHit(25, getHydraX(h));
+ }
+ }
+ }
+
+ //Weapon collision
+ {
+ //Mask should still be on the head
+ int wid = checkWeaponCollision(mask);
+ if (wid != -1) {
+ h->blink = 15;
+ h->hp -= 1;
+ weaponHit(weapons[wid]);
+
+ if (h->hp <= 0) {
+ h->state = 4;
+ h->timer = 0;
+ h->counter = 0;
+ }
+ }
+ }
+
+
+ }
+
+ }
+
+ //Destroy object
+ if (dead == 1) {
+ enemyDestroy(h->id);
+ }
+}
+
+void hydraheadDraw(Hydrahead* h)
+{
+ /*
+ char c[10];
+ sprintf(c, "%02d", h->timer);
+ PHL_DrawTextBold(c, h->bodyposX[6], 0, 0);
+ */
+
+ h->bodyposX[0] = getHydraX(h) + 20;
+ h->bodyposY[0] = getHydraY(h);
+
+ double drawX = getHydraX(h) + 20;
+ double drawY = getHydraY(h);
+
+ int dis = 24;
+ int angle = -25;
+
+ if (h->position == 1) {
+ angle = -60;
+
+ drawX -= 5;
+ drawY -= 20;
+ }
+
+ int i;
+ for (i = 0; i < 7; i++) {
+ double wavlen = sin((h->neckRot + (45 * i)) * PI / 180);
+
+ double incang = 45;
+
+ if (h->position != 0) {
+ incang = 45;
+ }
+
+ if (i == 6) {
+ //incang += 15;
+ incang = 50;
+
+ if (h->position == 1) {
+ incang = 80;
+ }
+ }
+
+ drawX += lengthdir_x(angle + (incang * wavlen), dis);
+ drawY += lengthdir_y(angle + (incang * wavlen), dis);
+
+ h->bodyposX[i] = drawX;
+ h->bodyposY[i] = drawY;
+
+ if (h->dir == -1) {
+ double difference = h->bodyposX[i] - getHydraX(h);
+ h->bodyposX[i] = getHydraX(h) - difference;
+ }
+
+ if (h->blink % 2 == 0) {
+ if (h->state != 4 || (6 - h->counter >= i)) {
+ if (i != 6) {
+ int cropX = 0;
+
+ if (h->dir == -1) {
+ cropX += 64;
+ }
+
+ PHL_DrawSurfacePart(h->bodyposX[i] - 32, h->bodyposY[i] - 32, cropX, 64, 64, 64, images[imgBoss]);
+ }else{
+ int cropX = 0;
+
+ if (h->dir == -1) {
+ cropX += 320;
+ }
+
+ cropX += (int)h->imageIndex * 80;
+
+ PHL_DrawSurfacePart(h->bodyposX[i] - 40, h->bodyposY[i] - 32, cropX, 0, 80, 64, images[imgBoss]);
+ }
+ }
+ }
+ }
+
+}
+
+int checkWeaponCollision(Mask m)
+{
+ int i;
+ for (i = 0; i < MAX_WEAPONS; i++) {
+ if (weapons[i] != NULL) {
+ if (weapons[i]->cooldown == 0) {
+ if (checkCollision(weapons[i]->weaponMask, m) == 1) {
+ return i;
+ }
+ }
+ }
+ }
+
+ return -1;
+}
+
+double lengthdir_x(double ang, double len)
+{
+ return cos(ang * PI / 180) * len;
+}
+
+double lengthdir_y(double ang, double len)
+{
+ return sin(ang * PI / 180) * len;
+}
+
+double getHydraX(Hydrahead* h)
+{
+ if (enemies[h->bodyid] != NULL) {
+ Hydra* hbody = enemies[h->bodyid]->data;
+ return hbody->x;
+ }
+
+ return -1;
+}
+
+double getHydraY(Hydrahead* h)
+{
+ if (enemies[h->bodyid] != NULL) {
+ Hydra* hbody = enemies[h->bodyid]->data;
+ return hbody->y;
+ }
+
+ return -1;
+}
+
+void setHeadState(int headid, int state)
+{
+ if (enemies[headid] != NULL) {
+ Hydrahead* h = enemies[headid]->data;
+ if (h->state != 4) {
+ h->state = state;
+ h->timer = 0;
+ h->counter = 0;
+ }
+ }
+}
+
+//#goop
+void createHydragoop(int x, int y, int hsp, int vsp)
+{
+ int i;
+ for (i = 0; i < MAX_ENEMIES; i++) {
+ if (enemies[i] == NULL) {
+ Enemy* e = malloc(sizeof *e);
+ Hydragoop* h = malloc(sizeof *h);
+ h->id = i;
+
+ h->x = x;
+ h->y = y;
+
+ h->hsp = hsp;
+ h->vsp = vsp;
+
+ h->inwall = 0;
+ h->bounce = 0;
+
+ h->imageIndex = 0;
+
+ e->data = h;
+ e->enemyStep = hydragoopStep;
+ e->enemyDraw = hydragoopDraw;
+ e->type = -1;
+
+ enemies[i] = e;
+ i = MAX_ENEMIES;
+
+ PHL_PlaySound(sounds[sndPi06], CHN_ENEMIES);
+ }
+ }
+}
+
+void hydragoopStep(Hydragoop* h)
+{
+ char dead = 0;
+
+ //Animate
+ {
+ h->imageIndex += 0.16;
+ if (h->imageIndex >= 3) {
+ h->imageIndex -= 3;
+ }
+ }
+
+ //Setup Mask
+ Mask mask;
+ {
+ mask.circle = mask.unused = 0;
+ mask.w = 36;
+ mask.h = 36;
+ mask.x = h->x - mask.w / 2;
+ mask.y = h->y - mask.h / 2;
+ }
+
+ //Movement
+ {
+ double grav = 0.2;
+
+ h->x += h->hsp;
+ mask.x = h->x - mask.w / 2;
+
+ if (checkTileCollision(1, mask) == 1) {
+ h->inwall = 1;
+ }
+
+ h->y += h->vsp;
+ h->vsp += grav;
+ mask.y = h->y - mask.h / 2;
+
+ if (h->inwall == 0 && h->bounce == 0) {
+ if (checkTileCollision(1, mask) == 1) {
+ h->bounce = 1;
+ h->vsp = -2;
+ }
+ }
+ }
+
+ //Outside of room
+ {
+ if ( (h->y > 500 && h->vsp >= 0) ||
+ (h->x < -20 && h->hsp <= 0) ||
+ (h->x > 660 && h->hsp >= 0) )
+ {
+ dead = 1;
+ }
+ }
+
+ //Collide with hero
+ {
+ //Collide with shield
+ if (checkCollision(mask, shieldMask) == 1) {
+ createEffect(1, h->x - 20, h->y - 20);
+ PHL_PlaySound(sounds[sndHit07], CHN_EFFECTS);
+ dead = 1;
+ }
+ else if (checkCollision(mask, getHeroMask()) == 1) {
+ if (heroHit(25, h->x) == 1) {
+ heroPoison();
+ }
+ }
+ }
+
+ //Destroy object
+ {
+ if (dead == 1) {
+ enemyDestroy(h->id);
+ }
+ }
+
+}
+
+void hydragoopDraw(Hydragoop* h)
+{
+ int cropX = 320;
+
+ cropX += (int)h->imageIndex * 40;
+
+ PHL_DrawSurfacePart(h->x - 20, h->y - 20, cropX, 480, 40, 40, images[imgMisc20]);
+}
+
+//#rock
+void createHydrarock()
+{
+ int i;
+ for (i = 0; i < MAX_ENEMIES; i++) {
+ if (enemies[i] == NULL) {
+ Enemy* e = malloc(sizeof *e);
+ Hydrarock* h = malloc(sizeof *h);
+ h->id = i;
+
+ h->x = 70 + (rand() % 26) * 20;
+ h->y = -24;
+
+ h->vsp = 0;
+
+ h->bounce = 0;
+
+ h->imageIndex = 0;
+
+ e->data = h;
+ e->enemyStep = hydrarockStep;
+ e->enemyDraw = hydrarockDraw;
+ e->type = -1;
+
+ enemies[i] = e;
+ i = MAX_ENEMIES;
+ }
+ }
+}
+
+void hydrarockStep(Hydrarock* h)
+{
+ //Animate
+ {
+ h->imageIndex += 0.25;
+ if (h->imageIndex >= 8) {
+ h->imageIndex -= 8;
+ }
+ }
+
+ //Movement
+ {
+ double grav = 0.15;
+
+ h->y += h->vsp;
+ h->vsp += grav;
+ }
+
+ //Setup Mask
+ Mask mask;
+ {
+ mask.circle = mask.unused = 0;
+ mask.w = 44;
+ mask.h = 44;
+ mask.x = h->x - mask.w / 2;
+ mask.y = h->y - mask.h / 2;
+ }
+
+ if (h->bounce == 0) {
+ if (checkTileCollision(1, mask) == 1) {
+ h->bounce = 1;
+ h->vsp = -2;
+ PHL_PlaySound(sounds[sndHit06], CHN_ENEMIES);
+ }
+ }
+
+ //Hero collision
+ {
+ if (checkCollision(mask, getHeroMask()) == 1) {
+ heroHit(30, h->x);
+ }
+ }
+
+ //Weapon Collision
+ {
+ int wid = checkWeaponCollision(mask);
+ if (wid != -1) {
+ weaponHit(weapons[wid]);
+ PHL_PlaySound(sounds[sndHit03], CHN_WEAPONS);
+ }
+ }
+
+ if (h->y >= 520) {
+ enemyDestroy(h->id);
+ }
+}
+
+void hydrarockDraw(Hydrarock* h)
+{
+ int cropX = 128;
+
+ cropX += (int)h->imageIndex * 64;
+
+ PHL_DrawSurfacePart(h->x - 32, h->y - 32, cropX, 128, 64, 64, images[imgMisc32]);
+}
+
+//#electricity
+void createHydrashock(int x, int y)
+{
+ int i;
+ for (i = 0; i < MAX_ENEMIES; i++) {
+ if (enemies[i] == NULL) {
+ Enemy* e = malloc(sizeof *e);
+ Hydrashock* h = malloc(sizeof *h);
+ h->id = i;
+
+ h->timer = 0;
+
+ h->x = x;
+ h->y = y;
+
+ h->angle = 0;
+
+ h->imageIndex = 0;
+
+ e->data = h;
+ e->enemyStep = hydrashockStep;
+ e->enemyDraw = hydrashockDraw;
+ e->type = -1;
+
+ enemies[i] = e;
+ i = MAX_ENEMIES;
+
+ PHL_PlaySound(sounds[sndShot03], CHN_ENEMIES);
+ }
+ }
+}
+
+void hydrashockStep(Hydrashock* h)
+{
+ //Animate
+ {
+ h->imageIndex += 0.5;
+ if (h->imageIndex >= 4) {
+ h->imageIndex -= 4;
+ }
+ }
+
+ h->timer += 1;
+
+ if (h->timer >= 20) {
+ if (h->timer == 20) {
+ //Set angle
+ h->angle = (atan2(h->x - (herox), heroy + 20 - h->y) * 180 / PI) + 90;
+ }
+
+ h->timer = 22;
+
+ //Movement
+ {
+ int spd = 5;
+ h->x += lengthdir_x(h->angle, spd);
+ h->y += lengthdir_y(h->angle, spd);
+ }
+ }
+
+ //Setup mask
+ Mask mask;
+ {
+ mask.unused = mask.circle = 0;
+ mask.w = 28;
+ mask.h = 28;
+ mask.x = h->x - mask.w / 2;
+ mask.y = h->y - mask.h / 2;
+ }
+
+ //Hero Collision
+ {
+ if (checkCollision(mask, getHeroMask()) == 1) {
+ if (heroHit(25, h->x) == 1) {
+ heroStun();
+ }
+ }
+ }
+
+ //Destroy if outside of room
+ {
+ if (mask.x > 660 || mask.x + mask.w < -20 || mask.y > 500 || mask.y + mask.h < -20) {
+ enemyDestroy(h->id);
+ }
+ }
+}
+
+void hydrashockDraw(Hydrashock* h)
+{
+ if (h->timer % 2 == 0) {
+ int cropX = (int)h->imageIndex * 64;
+
+ PHL_DrawSurfacePart(h->x - 32, h->y - 32, cropX, 192, 64, 64, images[imgMisc32]);
+ }
+} \ No newline at end of file