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/hero.c | 1406 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 1406 insertions(+) create mode 100644 src/hero.c (limited to 'src/hero.c') diff --git a/src/hero.c b/src/hero.c new file mode 100644 index 0000000..a7f5a7a --- /dev/null +++ b/src/hero.c @@ -0,0 +1,1406 @@ +#include "hero.h" +#include "game.h" +#include +#include "weapon.h" +#include "platform.h" +#include + +//State constants +const char NORMAL = 0; +const char SLASH = 1; +const char HIT = 2; +const char LADDER = 3; +const char STONE = 4; +const char CHARGE = 5; +//#define GETITEM 6 +const char DOOR = 7; +const char DEATH = 8; +const char QUAKE = 9; + +int state; + +void updateMask(); +void heroChangeScreen(int dx, int dy); + +int herodir = 1; + +int canCharge = 0; +int canJump = 0; +int onground = 0; +int heldUp = 0; + +const double GRAVITY = 0.3; +const double CLIMBSPEED = 1; + +double vsp = 0; +double hsp = 0; +double imageIndex = 0; +double jumpspd = 7.5; + + +int invincible = 0; +int timer = 0; +int chargeTimer = 0; +int shieldTimer = 0; //Holds up shield if this is 0 +int stun = 0; +int stunTimer = 0; + +int poisoned = 0; +int stoneTimer = 0; +int stoneState = 0; +int stoneDir = 1; + +int inWater = 0; +int drownTimer = 0; + +void heroSetup() +{ + state = NORMAL; + herodir = 1; + + herox = 320; + heroy = 320; + vsp = 0; + hsp = 0; + imageIndex = 0; + //climbspd = 1; + + invincible = 0; + timer = 0; + chargeTimer = 0; + shieldTimer = 0; + + poisoned = 0; + stoneTimer = 0; + stoneState = 0; + stoneDir = 1; + + herohp = 128; + maxhp = 128; + heroAmmo = 0; + maxAmmo = 99; + heroWeapon = -1; + + heroMask.unused = 0; + heroMask.circle = 0; + heroMask.w = 24; + heroMask.h = 26; + + onground = 0; + canJump = 0; + + heroy += 1; + if (checkTileCollision(1, getHeroMask()) == 1 || checkTileCollision(3, getHeroMask()) == 1) { + onground = 1; + if (hasItem[12] == 1) { + canJump = 1; + } + } + heroy -= 1; + + shieldMask.unused = 1; + shieldMask.circle = 0; + shieldMask.w = 24; + shieldMask.h = 24; + shieldMask.x = 0; + shieldMask.y = 0; + + inWater = -1; +} + +int heroStep() +{ + int result = -1; + + //set HP limits + { + if (herohp > maxhp) { + herohp = maxhp; + } + + if (herohp < 0) { + herohp = 0; + } + } + + heldUp = btnUp.held; + + //Counters + { + if (invincible > 0) { + invincible -= 1; + } + } + + //Scripted states + if (state == DOOR) { + //Remove some status conditions + stun = 0; + poisoned = 0; + inWater = 0; + + //Animate + imageIndex += 0.2; + + //Done walking + if (imageIndex >= 10) { + enterDoor(); + state = NORMAL; + } + } + + else if (state == DEATH) { + stun = 0; + stunTimer = 0; + poisoned = 0; + + //Animate + { + imageIndex += 0.3; + if (imageIndex >= 4) { + imageIndex -= 4; + } + + //blinking + if (timer >= 90) { + invincible = 1; + }else{ + invincible = 0; + } + } + + timer += 1; + + //Poof + if (timer == 90) { + createEffect(2, herox - 32, heroy - 12); + } + //Play Music + if (timer == 150) { + PHL_PlayMusic(bgmGameover); + } + + //End game over screen prematurly + if (timer > 150 && btnStart.pressed == 1) { + btnStart.pressed = 0; + timer = 630; + } + + //Reset game + if (timer == 630) { + /* + FILE* f; + if ((f = fopen("data/save.tmp", "rb"))) { + remove("data/save.tmp"); + } + fclose(f); + */ + PHL_StopMusic(); + result = 1; + } + } + + //Uncontrollable states, but can move + else { + char canGrav = 1; + double grav = GRAVITY; + + if (state == CHARGE) { + canGrav = 0; + shieldTimer = 10; + vsp = 0; + + //Charge start (rear back) + { + if (timer == 0) { + imageIndex = 0; + hsp = -2 * herodir; + } + } + + //Friction + { + double fric = 0.3; + + if (hsp < 0) { + hsp += fric; + if (hsp >= 0) { + hsp = 0; + } + }else if (hsp > 0) { + hsp -= fric; + if (hsp <= 0) { + hsp = 0; + } + } + } + + timer += 1; + + //Forward charge start + { + if (timer == 15) { + invincible = 35; + hsp = 7 * herodir; + PHL_PlaySound(sounds[sndShot01], CHN_WEAPONS); + } + } + + //Animation + { + if (timer > 15) { + imageIndex = 1; + } + if (timer > 19) { + imageIndex = 2; + } + if (timer > 21) { + imageIndex = 3; + } + if (timer == 59) { + imageIndex = 4; + } + } + + //Stop + if (timer == 30) { + hsp = 0; + } + + //End state + if (timer >= 60) { + state = NORMAL; + } + + } + + else if (state == HIT) { + grav = GRAVITY - 0.05; + + //timer + { + timer -= 1; + if (timer < 0) { + timer = 0; + } + } + + //Animate + { + imageIndex += 0.33; + if (imageIndex >= 2) { + imageIndex -= 2; + } + } + + if (onground == 1) { + hsp = 0; + } + + //End hit state + { + if (onground == 1 && vsp == 0 && timer == 0) { + state = NORMAL; + invincible = 60; + } + } + + } + + else if (state == STONE) { + grav = GRAVITY - 0.05; + + if (stoneState != 2) { + stoneTimer -= 1; + //Setup break free animation + if (stoneTimer <= 0) { + stoneTimer = 0; + stoneState = 2; + imageIndex = 0; + + createRockSmash(herox, heroy + 20); + herodir = stoneDir; + } + } + + //Animate + imageIndex += 0.16; + + //Frozen state flashes + if (stoneState != 2 && imageIndex >= 2) { + imageIndex = 0; + } + + //In air + if (stoneState == 0) { + if (onground == 0) { + //hsp = -(herodir * 2); + }else{ + stoneState = 1; + createEffect(9, herox, heroy + 20); + createEffect(9, herox, heroy + 20); + } + } + //On ground + else if (stoneState == 1) { + hsp = 0; + if (btnFaceDown.pressed == 1) { + stoneTimer -= 30; + createEffect(9, herox, heroy + 20); + } + } + //Break free animation + else if (stoneState == 2) { + imageIndex += 0.16; + + if ((int)imageIndex == 3) { + createEffect(8, herox - 32, heroy - 22); + imageIndex += 0.5; + } + + if (imageIndex >= 17) { + state = NORMAL; + stoneState = 0; + } + } + } + + else if (state == QUAKE) { + grav = GRAVITY - 0.05; + hsp = 0; + + if (onground == 1) { + PHL_PlaySound(sounds[sndPi02], CHN_HERO); + if (timer == 0) { + vsp = -2 - grav; + onground = 0; + } + else if (timer == 1) { + vsp = -1 - grav; + onground = 0; + } + else if (timer == 2) { + vsp = -0.5 - grav; + onground = 0; + } + else if (timer == 3) { + state = NORMAL; + vsp = 0; + } + timer += 1; + } + } + + //Controllable states + else { + char canWalk = 1; + + if (state == NORMAL) { + //Timers + { + if (shieldTimer > 0) { + shieldTimer -= 1; + } + } + + //Change direction with buttons + { + if (btnLeft.held == 1) { + herodir = -1; + } + if (btnRight.held == 1) { + herodir = 1; + } + } + + //Jumping + { + if (btnFaceDown.pressed == 1) { + if (onground == 1 || canJump == 1) { + if (onground == 0) { + canJump = 0; + } + vsp = -jumpspd; + onground = 0; + PHL_PlaySound(sounds[sndJump01], CHN_HERO); + } + } + + //cancel jump + if (vsp < 0 && btnFaceDown.released == 1) { + vsp = 0; + } + } + + //Animate + { + if (onground == 1 && hsp != 0) { + imageIndex += 0.1; + if (imageIndex >= 2) { + imageIndex -= 2; + } + } + } + + //Charging + { + if (canCharge == 1 && btnFaceLeft.held == 1) { + chargeTimer += 1; + //Create Effects + if (chargeTimer >= 10 && chargeTimer < 66 && ((chargeTimer - 10) % 8) == 0) { + createEffect(6, herox, heroy + 20); + } + + if (chargeTimer == 70) { + PHL_PlaySound(sounds[sndPower01], CHN_SOUND); + } + } + + if (canCharge == 1 && chargeTimer >= 70 && btnFaceLeft.released == 1) { + state = CHARGE; + timer = 0; + imageIndex = 0; + addWeapon(SWORD, herox, heroy); + } + } + + //Attack + { + if (stun == 0) { + //Slash + if (btnFaceLeft.pressed == 1) { + state = SLASH; + imageIndex = 0; + PHL_PlaySound(sounds[sndShot01], CHN_WEAPONS); + addWeapon(SWORD, herox, heroy); + } + + //Weapon + if (btnFaceRight.pressed == 1) { + if (heroWeapon != -1) { + addWeapon(heroWeapon, (int)herox - 20, (int)heroy); + } + } + } + } + + //Grabbing Ladder + { + //Grab ladder + if (btnUp.held == 1) { + PHL_Rect collide = getTileCollisionXY(2, herox, heroy + 20); + if (collide.x != -1) { + state = LADDER; + canWalk = 0; + hsp = 0; + vsp = 0; + herox = collide.x + 20; + } + } + + //Climb down onto ladder + else if (onground == 1 && btnDown.held == 1) { + PHL_Rect collide = getTileCollisionXY(3, herox, heroy + 40); + if (collide.x != -1) { + state = LADDER; + canWalk = 0; + hsp = 0; + vsp = 0; + herox = collide.x + 20; + heroy += 1; + } + } + } + + } + + else if (state == SLASH) { + shieldTimer = 10; + + //Can move in air, not on the ground + if (onground == 1) { + canWalk = 0; + hsp = 0; + } + + //Animate + { + double imgspd = 0.25; + + if (imageIndex < 1) { + imgspd = 0.25; + }else if (imageIndex < 2) { + imgspd = 0.34; + }else if (imageIndex < 3) { + imgspd = 0.34; + }else if (imageIndex < 4) { + imgspd = 0.125; + }else if (imageIndex < 5) { + imgspd = 0.5; + } + + imageIndex += imgspd; + } + + //Finish slash + { + if (imageIndex >= 5) { + state = NORMAL; + canCharge = hasItem[17]; //Has red scroll + chargeTimer = 0; + } + } + + } + + else if (state == LADDER) { + onground = 0; + canWalk = 0; + canGrav = 0; + hsp = 0; + vsp = 0; + + //Generate final climb speed + double climbspd = CLIMBSPEED; + { + //Has power bracelet + if (hasItem[4] == 1) { + climbspd *= 2; + } + + //Stun slows climb speed + if (stun > 0) { + climbspd /= 2; + } + } + + //Get up/down axis + int yaxis = btnDown.held - btnUp.held; + + //Animate + if (yaxis != 0) { + imageIndex += 0.125; + + //Limit imageIndex + if (imageIndex >= 8) { + imageIndex -= 8; + } + } + + //Movement + heroy += climbspd * yaxis; + + //Touch ground + { + if (yaxis == 1) { + PHL_Rect collide = getTileCollision(1, getHeroMask()); + if (collide.x != -1) { + state = NORMAL; + heroy = collide.y - 40; + imageIndex = 0; + } + } + } + + //Off of ladder + { + if (yaxis != 0) { + if (checkTileCollision(2, getHeroMask()) == 0 && checkTileCollision(3, getHeroMask()) == 0) { + state = NORMAL; + if (btnDown.held == 1) { + onground = 0; + } + } + } + } + } + + //Walking + { + if (canWalk == 1) { + int xaxis = btnRight.held - btnLeft.held; + hsp = 3 * xaxis; + } + } + + //Cancel jump + { + if (vsp < 0 && btnFaceDown.released == 1) { + vsp = 0; + } + } + + //Earthquake + { + if (hasItem[11] == 0) { //Does not have amulete + if (quakeTimer > 0 && onground == 1) { + state = QUAKE; + vsp = -3 - grav; + timer = 0; + PHL_PlaySound(sounds[sndPi02], CHN_HERO); + } + } + } + + } + + //Movement + { + //Used to prevent glitching out on ladder tops + int precheckladder = checkTileCollision(3, getHeroMask()); + + //Horizontal movement + { + if (hsp != 0) { + double finalhsp = hsp; + //Slow when climbing and stunned + { + if ( (inWater == 1 && hasItem[5] == 0) || stun == 1) { + finalhsp /= 4; + } + } + + //Speed up movement in water + { + if (inWater == 1 && hasItem[5] == 1) { //Has fins + finalhsp = (finalhsp / 3) * 2; + } + } + + //Move + herox += finalhsp; + + //Stay within screen during boss fight + { + if (bossFlag == 1) { + if (herox < 10) { + herox = 10; + } + if (herox > 630) { + herox = 630; + } + } + } + + //Collide with wall + { + PHL_Rect collide = getTileCollision(1, getHeroMask()); + if (collide.x == -1 && precheckladder == 0) { + collide = getTileCollision(3, getHeroMask()); + } + + //Did collide + if (collide.x != -1) { + if (hsp > 0) { + herox = collide.x - (heroMask.w / 2); + }else if (hsp < 0) { + herox = collide.x + 40 + (heroMask.w / 2); + } + + if (state == STONE) { + herodir *= -1; + } + } + } + + //Check if walked off ledge + if (vsp >= 0) { + heroy += 1; + + if ( checkTileCollision(1, getHeroMask()) //Solid ground + || (hasItem[13] == 1 && checkTileCollision(5, getHeroMask())) //Has red shoes + || (precheckladder == 0 && checkTileCollision(3, getHeroMask())) ) //Ladder tops + {}else{ + onground = 0; + } + + heroy -= 1; + } + } + } + + //Vertical Movement + { + //Gravity + if (canGrav == 1 && onground == 0) { + int maxVsp = 8; + + //Water slows movement + if (inWater == 1) { + grav *= 0.5; + maxVsp *= 0.5; + } + + vsp += grav; + if (vsp > maxVsp) { + vsp = maxVsp; + } + } + + //Vertical Movement + { + double tempVsp = vsp; + char landed = 0; + + //Water slows movement + if (inWater == 1 || stun == 1) { + tempVsp *= 0.5; + } + + //Movement + heroy += tempVsp; + + //Colliding with floor/ceiling + { + PHL_Rect collide = getTileCollision(1, getHeroMask()); + if (collide.x == -1&& precheckladder == 0) { + collide = getTileCollision(3, getHeroMask()); + } + if (collide.x == -1 && hasItem[13] == 1) { //has red shoes + collide = getTileCollision(5, getHeroMask()); + } + + if (collide.x != -1) { + //Collide with floor + if (vsp > 0) { + heroy = collide.y - 40; + vsp = 0; + + onground = 1; + if (hasItem[12] == 1) { //Has blue boots + canJump = 1; + } + + landed = 1; + } + + //Collide with ceiling + else if (vsp < 0) { + heroy = collide.y + 40 - (40 - heroMask.h); + } + } + + else{ + //Jumpthrough/moving platforms + if (vsp >= 0) { + int i; + for (i = 0; i < MAX_PLATFORMS; i++) { + if (platforms[i] != NULL) { + int onPlatTop = 0; + if (herox - (heroMask.w / 2) > platforms[i]->mask.x + platforms[i]->mask.w || herox + (heroMask.w / 2) < platforms[i]->mask.x) { + } + else{ + if (platforms[i]->y == heroy + 40 && vsp >= 0) { + onPlatTop = 1; + } + } + + if (onPlatTop == 1 || checkCollision(getHeroMask(), platforms[i]->mask) == 1) { + heroMask.y -= vsp; + if (onPlatTop == 1 || checkCollision(heroMask, platforms[i]->mask) == 0) { + heroy = platforms[i]->mask.y - 40; + if (vsp != 0) { + landed = 1; + } + vsp = 0; + onground = 1; + if (hasItem[12] == 1) { + canJump = 1; + } + } + } + } + } + } + } + } + + //Land on ground after a hit + if (landed == 1 && (state == HIT || state == STONE)) { + timer = 60; + PHL_PlaySound(sounds[sndHit01], CHN_HERO); + + createEffectExtra(3, herox - 30, heroy + 8, -1, 0, 0); + createEffectExtra(3, herox - 10, heroy + 8, 1, 0, 0); + } + + } + + } + + } + + //Water stuff + { + //Drown/bubble + if (inWater == 1) { + drownTimer -= 1; + if (drownTimer <= 0) { + drownTimer = 60; + if (hasItem[6] == 0) { + herohp -= 4; + } + createEffect(12, herox, heroy + 20); + PHL_PlaySound(sounds[sndPi06], CHN_SOUND); + } + } + + //Splash + if (checkTileCollision(4, getHeroMask())) { + if (inWater == 0) { + drownTimer = 60; + //Splash effect + createSplash(herox, heroy); + } + inWater = 1; + }else{ + if (checkTileCollision(6, getHeroMask()) == 0) { + if (inWater == 1) { + //Splash effect + createSplash(herox, heroy); + } + inWater = 0; + } + } + } + + //Poison + { + if (poisoned > 0) { + poisoned -= 1; + if (poisoned % 20 == 0) { + herohp -= 1; + createEffect(7, herox, heroy); + } + } + } + + //Switch weapon + { + int axis = btnR.pressed - btnL.pressed; + + if (axis != 0) { + PHL_PlaySound(sounds[sndPi01], CHN_SOUND); + + int i; + for (i = 1; i <= 5; i++) { + int thisweapon = heroWeapon + (i * axis); + + if (thisweapon >= 5) { + thisweapon -= 5; + } + if (thisweapon < 0) { + thisweapon += 5; + } + + if (hasWeapon[thisweapon] == 1) { + heroWeapon = thisweapon; + i = 6; + } + } + } + } + + //Collide with lava + { + heroy -= 20; + if (checkTileCollision(5, getHeroMask())) { + herohp = 0; + setDrawHP(0); + } + heroy += 20; + } + + //Collide with spikes + { + PHL_Rect spike = getTileCollision(6, getHeroMask()); + if (spike.x != -1) { + Mask spikeMask; + spikeMask.circle = spikeMask.unused = 0; + spikeMask.x = spike.x + 10; + spikeMask.y = spike.y + 10; + spikeMask.w = spikeMask.h = 20; + + if (checkCollision(spikeMask, getHeroMask())) { + heroHit(15, spike.x + 20); + } + } + } + + //Death + { + if (getDrawHP() <= 0) { //Based on the hud's opinion on player's health, apparently + state = DEATH; + timer = 0; + imageIndex = 0; + PHL_StopMusic(); + PHL_PlaySound(sounds[sndHit02], CHN_HERO); + } + } + } + + //Manage charge + { + if (state != NORMAL) { + canCharge = 0; + chargeTimer = 0; + } + + if (canCharge == 1) { + if (btnFaceLeft.held == 0 && btnFaceLeft.pressed == 0) { + canCharge = 0; + } + } + } + + //Screen transitions + { + if (herox < -20) { + herox = 620; + heroChangeScreen(-1, 0); + } + else if (herox > 660) { + herox = 20; + heroChangeScreen(1, 0); + } + else if (state == LADDER && heroy < -40) { + heroy = 440; + heroChangeScreen(0, -1); + } + else if (heroy > 480) { + heroy = 0; + heroChangeScreen(0, 1); + } + } + + return result; +} + +void heroChangeScreen(int dx, int dy) +{ + vsp = 0; + chargeTimer = 0; + canCharge = 0; + if (hasItem[12] == 1) { + canJump = 1; + } + if (state == HIT || state == SLASH || state == CHARGE) { + state = NORMAL; + } + + //Force a black screen + PHL_DrawRect(0, 0, 640, 480, PHL_NewRGB(0, 0, 0)); + PHL_ForceScreenUpdate(); + + changeScreen(dx, dy); +} + + +void heroDraw() +{ + int cropX = 0, cropY = 0; + int drawShield = 0; + + if (state == DOOR) { + cropY = 160; + cropX = (int)imageIndex * 40; + } + + + else if (state == GETITEM) { + int animation[7] = {0, 1, 2, 3, 2, 0, 1}; + cropY = 40; + cropX = 320 + (animation[(int)imageIndex] * 40); + } + + //Climbing + else if (state == LADDER) { + cropX = 80; + cropY = 80; + int animation[8] = {0, 1, 2, 1, 0, 3, 4, 3}; + cropX += 40 * animation[(int)floor(imageIndex)]; + } + + + else if (state == NORMAL) + { + if (onground == 1) { + //Walking + if (hsp != 0) { + cropX = floor(imageIndex) * 40; + if (herodir == -1) { + cropX += 80; + } + } + + //Standing + else{ + imageIndex = 0; + cropX = 0; + cropY = 0; + if (hasItem[14] == 1 && shieldTimer <= 0) { + drawShield = 1; + cropY = 120; + if (herodir == -1) { + cropX += 40; + } + if (heldUp == 1) { + cropX += 80; + } + }else{ + if (herodir == -1) { + cropX += 80; + } + } + } + }else{ + //Jumping/falling + if (vsp < 0) { + imageIndex = 0; + }else{ + imageIndex = 1; + } + cropX = 160 + (40 * imageIndex); + if (herodir == -1) { + cropX += 80; + } + } + }else if (state == SLASH) + { + //Sword Slash + int animation[5] = {0, 1, 2, 2, 0}; + + cropY = 40; + cropX = 40 * animation[(int)floor(imageIndex)]; + if (herodir == -1) { + cropX += 120; + } + } + else if (state == CHARGE) { + int animation[5] = {0, 1, 2, 2, 0}; + cropY = 40; + cropX = animation[(int)imageIndex] * 40; + if (herodir == -1) { + cropX += 120; + } + } + else if (state == HIT) { + int thisImage = 12; + + if (onground == 0) { + thisImage = 8; + } + + if (state == STONE) { + thisImage = 28; + } + + thisImage += (int)imageIndex; + if (herodir == -1) { + thisImage += 2; + } + + cropX = 40 * thisImage; + + while (cropX >= 640) { + cropX -= 640; + cropY += 40; + } + } + else if (state == STONE) { + cropY = 40; + + if (stoneState == 0 || stoneState == 1) { //In air/on ground + int thisImage = (int)imageIndex; + if (stoneDir == -1) { + thisImage += 2; + } + + cropX = 480 + (thisImage * 40); + } + else if (stoneState == 2) { //Break free + int animation[17] = {0, 1, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 2, 0, 1, 0}; + cropX = 320 + (animation[(int)imageIndex] * 40); + } + } + else if (state == DEATH) { + if (timer >= 130) { + char tempDark = roomDarkness; + roomDarkness = 0; + + PHL_DrawTextBold("GAME OVER", 248, 240, YELLOW); + + roomDarkness = tempDark; + }else{ + int frame = 0; + if (herodir == 1) { + int animation[4] = {0, 3, 6, 9}; + frame = animation[(int)imageIndex]; + } + if (herodir == -1) { + int animation[4] = {2, 1, 4, 11}; + frame = animation[(int)imageIndex]; + } + cropX = frame * 40; + } + } + else if (state == QUAKE) { + cropY = 80; + if (herodir == -1) { + cropX = 40; + } + } + + if ((state == HIT && invincible % 6 < 3) || invincible % 2 == 0) { + PHL_DrawSurfacePart(herox - 20, heroy, cropX, cropY, 40, 40, images[imgHero]); + if (drawShield == 1) { + int scx = 320; //Shield crop x + int sdx = herox - 2, sdy = heroy + 10; //Shield draw x/y + if (herodir == -1) { + sdx -= 36; + scx += 40; + } + if (heldUp == 1) { + scx += 80; + sdy -= 26; + sdx -= 8 * herodir; + } + PHL_DrawSurfacePart(sdx, sdy, scx, 240, 40, 40, images[imgHero]); + } + } + + //Draw stun effect + if (stun == 1) { + int frame = (int)(((300 - stunTimer) % 32) / 4); + if (frame == 0) { + PHL_PlaySound(sounds[sndHit05], CHN_SOUND); + } + + int animation[8] = {0, 1, 2, 1, 0, -1, -1, -1}; + + if (animation[frame] != -1) { + PHL_DrawSurfacePart(herox - 32, heroy - 12, 384 + (animation[frame] * 64), 64, 64, 64, images[imgMisc32]); + } + + if (stunTimer <= 0) { + stun = 0; + PHL_PlaySound(sounds[sndPower01], CHN_SOUND); + }else{ + stunTimer -= 1; + } + } + + //PHL_DrawRect(mask.x, mask.y, mask.w, mask.h, PHL_NewRGB(0x00, 0x00, 0xFF)); + updateMask(); + //PHL_DrawMask(shieldMask); +} + +void updateMask() +{ + heroMask.x = herox - 12; + heroMask.y = heroy + 14; + + //Update shield mask + { + shieldMask.unused = 1; + if (hasItem[14] == 1) { //has shield + if (state == NORMAL && onground == 1 && hsp == 0 && shieldTimer == 0) { + shieldMask.unused = 0; + + //Shield held in front + if (heldUp == 0) { + shieldMask.w = 14; + shieldMask.h = 20; + shieldMask.x = herox + 10; + shieldMask.y = heroy + 20; + if (herodir == -1) { + shieldMask.x -= 34; + } + } + + //Shield above head + else{ + shieldMask.w = 24; + shieldMask.h = 8; + shieldMask.x = herox - 2; + shieldMask.y = heroy - 2; + if (herodir == -1) { + shieldMask.x -= 20; + } + } + } + } + } + +} + +int heroHit(int damage, int centerx) +{ + if (state != HIT && state != DEATH && state != DOOR && (invincible <= 0 || (state == STONE && invincible == 60))) { + if (state != STONE || (state == STONE && stoneState != 2)) { + PHL_PlaySound(sounds[sndHit02], CHN_HERO); + herohp -= damage; + + vsp = -4; + onground = 0; + + if (herox - centerx > 0) { + herodir = -1; + hsp = herodir * -2; + } + + if (herox - centerx < 0) { + herodir = 1; + hsp = herodir * -2; + } + + if (state != STONE) { + state = HIT; + } + + return 1; + } + } + return 0; +} + +void heroPoison() +{ + if (hasItem[8] != 1) { //Does not have poison resistance ring + if (poisoned <= 0) { + poisoned = 300; + } + } +} + +void heroStone() +{ + //if (((state != HIT && state != DEATH && state != DOOR ) || (state == STONE && stoneState != 2)) && invincible <= 0) { + if (state != HIT && state != DEATH && state != DOOR && (invincible <= 0 || (state == STONE && invincible == 60))) { + if (state != STONE || (state == STONE && stoneState != 2)) { + if (hasItem[9] != 1) { //Does not have green ring + if (state == STONE) { + herodir = stoneDir; + } + setHeroState(STONE); + } + } + } +} + +//Get-ers and set-ers +Mask getHeroMask() +{ + updateMask(); + return heroMask; +} + +int getHeroState() +{ + return state; +} + +void setHeroState(int s) +{ + state = s; + + //Special cases + if (s == GETITEM) { + heldUp = 0; + //timer = 0; + //subPosition = GETITEM; + } + + if (s == DOOR) { + imageIndex = 0; + } + + if (s == STONE) { + if (stoneTimer <= 0) { + stoneTimer = 350; + } + stoneState = 0; + invincible = 60; + stoneDir = herodir; + } +} + +int getHeroInvincible() +{ + return invincible; +} + +int getHeroDirection() +{ + return herodir; +} + +void setHeroDirection(int d) +{ + herodir = d; +} + +double getHeroImageIndex() +{ + return imageIndex; +} + +void setHeroImageIndex(double index) +{ + imageIndex = index; +} + +double getHeroVsp() +{ + return vsp; +} + +double getHeroHsp() +{ + return hsp; +} + +void setHeroHsp(double newHsp) +{ + hsp = newHsp; +} + +void setHeroVsp(double newVsp) +{ + vsp = newVsp; +} + +int getHeroOnground() +{ + return onground; +} + +void setHeroOnground(int val) +{ + onground = val; +} + +void setHeroTimer(int t) +{ + timer = t; +} + +int getHeroPoisoned() +{ + return poisoned; +} + +void heroStun() +{ + if (hasItem[10] == 0) { //Does not have cloak + stun = 1; + if (stunTimer <= 0) { + stunTimer = 300; + } + } +} + +void setHeroCanjump(int set) +{ + canJump = set; +} \ No newline at end of file -- cgit v1.2.3