diff --git a/src/controller.h b/src/controller.h index acce20f..a9ab677 100644 --- a/src/controller.h +++ b/src/controller.h @@ -312,6 +312,10 @@ struct Controller { return vec3(angle.x, angle.y); } + static inline void applyGravity(float &speed) { + speed += (speed < 128.0f ? GRAVITY : 30.0f) * Core::deltaTime; + } + bool alignToWall(float offset = 0.0f, int quadrant = -1, int maxDist = 0, int maxWidth = 0) { int q = angleQuadrant(angle.y); int ix = int(pos.x); diff --git a/src/format.h b/src/format.h index b45f1c9..39a1841 100644 --- a/src/format.h +++ b/src/format.h @@ -279,6 +279,7 @@ namespace TR { SND_LIGHTNING = 98, SND_ROCK = 99, + SND_SWORD = 103, SND_EXPLOSION = 104, SND_INV_SPIN = 108, @@ -334,6 +335,7 @@ namespace TR { HIT_BLADE, HIT_BOULDER, HIT_SPIKES, + HIT_SWORD, HIT_LAVA, HIT_SLAM, HIT_REX, @@ -692,7 +694,7 @@ namespace TR { } bool castShadow() const { - return isLara() || isEnemy() || isActor() || type == TRAP_DART; + return isLara() || isEnemy() || isActor() || type == TRAP_DART || type == TRAP_SWORD; } void getAxis(int &dx, int &dz) { diff --git a/src/lara.h b/src/lara.h index 5e7c084..8a8dce1 100644 --- a/src/lara.h +++ b/src/lara.h @@ -1347,6 +1347,7 @@ struct Lara : Character { switch (hitType) { case TR::HIT_BLADE : addBloodBlade(); break; case TR::HIT_SPIKES : addBloodSpikes(); break; + case TR::HIT_SWORD : addBloodBlade(); break; case TR::HIT_SLAM : addBloodSlam(enemy); break; case TR::HIT_LIGHTNING : lightning = (Lightning*)enemy; break; default : ; @@ -2483,7 +2484,7 @@ struct Lara : Character { switch (stand) { case STAND_AIR : - velocity.y += (velocity.y >= 128.0f ? 30.0f : GRAVITY) * Core::deltaTime; + applyGravity(velocity.y); if (velocity.y >= 154.0f && state == STATE_FALL) game->playSound(TR::SND_SCREAM, pos, Sound::PAN); /* diff --git a/src/trigger.h b/src/trigger.h index 2130d2d..f083d5a 100644 --- a/src/trigger.h +++ b/src/trigger.h @@ -775,12 +775,44 @@ struct TrapSlam : Controller { } }; +#define SWORD_DAMAGE 100.0f +#define SWORD_RANGE 1536.0f struct TrapSword : Controller { - TrapSword(IGame *game, int entity) : Controller(game, entity) {} + vec3 dir; + float rot; + + TrapSword(IGame *game, int entity) : Controller(game, entity), dir(0) { + rot = (randf() * 2.0f - 1.0f) * PI; + } virtual void update() { - updateAnimation(true); + TR::Level::FloorInfo info; + level->getFloorInfo(getRoomIndex(), int(pos.x), int(pos.y), int(pos.z), info); + + Controller *lara = game->getLara(); + + if (dir.y == 0.0f) { + dir = lara->pos - pos; + if (dir.y > 0 && dir.y < 3072.0f && fabsf(dir.x) < SWORD_RANGE && fabsf(dir.z) < SWORD_RANGE) { + dir /= 32.0f; + dir.y = 50.0f; + } else + dir.y = 0.0f; + } else { + angle.y += rot * Core::deltaTime; + applyGravity(dir.y); + pos += dir * (30.0f * Core::deltaTime); + if (pos.y > info.floor) { + pos.y = info.floor; + game->playSound(TR::SND_SWORD, pos, Sound::PAN); + deactivate(true); + } + updateEntity(); + + if (collide(lara)) + lara->hit(SWORD_DAMAGE * 30.0f * Core::deltaTime, this, TR::HIT_SWORD); // TODO: push lara + } } };