diff --git a/src/camera.h b/src/camera.h index 47709fa..6f327bc 100644 --- a/src/camera.h +++ b/src/camera.h @@ -25,7 +25,7 @@ struct Camera : ICamera { Frustum *frustum; float fov, znear, zfar; - vec3 target, pos, destPos, lastDest, angle, advAngle; + vec3 target, destPos, lastDest, angle, advAngle; float advTimer; mat4 mViewInv; int room; @@ -138,9 +138,14 @@ struct Camera : ICamera { TR::CameraFrame *frameB = &level->cameraFrames[indexB]; if (indexB < indexA) { - level->initCutscene(); - game->playTrack(0, true); - timer = 0.0f; + indexB = indexA; + timer = 0.0f; + if (level->cutEntity != -1) { + // TODO: level end + level->initCutscene(); + game->playTrack(0, true); + } else + state = STATE_FOLLOW; } const int eps = 512; diff --git a/src/controller.h b/src/controller.h index 0cdff23..da11481 100644 --- a/src/controller.h +++ b/src/controller.h @@ -18,6 +18,7 @@ struct Controller; struct ICamera { vec4 *reflectPlane; + vec3 pos; ICamera() : reflectPlane(NULL) {} @@ -489,7 +490,7 @@ struct Controller { if (cmd == TR::ANIM_CMD_EFFECT) { switch (fx) { case TR::Effect::ROTATE_180 : angle.y = angle.y + PI; break; - case TR::Effect::FLOOR_SHAKE : game->setEffect(TR::Effect(fx), 0.5f * max(0.0f, 1.0f - (pos - ((Controller*)level->cameraController)->pos).length2() / (15 * 1024 * 15 * 1024) )); break; + case TR::Effect::FLOOR_SHAKE : game->setEffect(TR::Effect(fx), 0.5f * max(0.0f, 1.0f - (pos - ((ICamera*)level->cameraController)->pos).length2() / (15 * 1024 * 15 * 1024) )); break; case TR::Effect::FLIP_MAP : level->isFlipped = !level->isFlipped; break; default : cmdEffect(fx); break; } diff --git a/src/format.h b/src/format.h index 001eff8..2111efc 100644 --- a/src/format.h +++ b/src/format.h @@ -354,7 +354,7 @@ namespace TR { }; Limit SCION = { - 640, 310, 30, {{-256, 540, -350}, {256, 740, -200}}, true, false + 640, -202, 30, {{-256, 540, -350}, {256, 740, -200}}, false, false }; } diff --git a/src/lara.h b/src/lara.h index e78f12d..4f94183 100644 --- a/src/lara.h +++ b/src/lara.h @@ -1282,6 +1282,7 @@ struct Lara : Character { virtual void cmdEffect(int fx) { switch (fx) { + case TR::Effect::LARA_NORMAL : animation.setAnim(ANIM_STAND); break; case TR::Effect::LARA_BUBBLES : doBubbles(); break; case TR::Effect::LARA_HANDSFREE : break;//meshSwap(1, level->extra.weapons[wpnCurrent], BODY_LEG_L1 | BODY_LEG_R1); break; case TR::Effect::DRAW_RIGHTGUN : drawGun(true); break; @@ -1401,9 +1402,10 @@ struct Lara : Character { pickupEntity = &item; if (item.type == TR::Entity::SCION_1) { - animation.setAnim(level->models[level->entities[TR::MODEL_LARA_SPEC].modelIndex].animation); - ((Controller*)level->cameraController)->state = Camera::STATE_CUTSCENE; + animation.setAnim(level->models[TR::MODEL_LARA_SPEC].animation); + ((Camera*)level->cameraController)->state = Camera::STATE_CUTSCENE; level->cutMatrix.identity(); + level->cutMatrix.rotateY(angle.y); level->cutMatrix.setPos(pos); } else state = STATE_PICK_UP; diff --git a/src/trigger.h b/src/trigger.h index 225b2aa..81e7251 100644 --- a/src/trigger.h +++ b/src/trigger.h @@ -276,6 +276,7 @@ struct MovingBlock : Controller { } }; + struct Door : Controller { enum { STATE_CLOSE, @@ -402,9 +403,9 @@ struct TrapFloor : Controller { STATE_FALL, STATE_DOWN, }; - float velocity; + float speed; - TrapFloor(IGame *game, int entity) : Controller(game, entity), velocity(0) { + TrapFloor(IGame *game, int entity) : Controller(game, entity), speed(0) { getEntity().flags.collision = true; } @@ -422,16 +423,15 @@ struct TrapFloor : Controller { virtual void update() { updateAnimation(true); if (state == STATE_FALL) { - TR::Entity &e = getEntity(); - e.flags.collision = false; - velocity += GRAVITY * 30 * Core::deltaTime; - pos.y += velocity * Core::deltaTime; + getEntity().flags.collision = false; + speed += GRAVITY * 30 * Core::deltaTime; + pos.y += speed * Core::deltaTime; TR::Level::FloorInfo info; - level->getFloorInfo(e.room, e.x, (int)pos.y, e.z, info); + level->getFloorInfo(getRoomIndex(), int(pos.x), int(pos.y), int(pos.z), info); if (pos.y > info.roomFloor && info.roomBelow != 0xFF) - e.room = info.roomBelow; + getEntity().room = info.roomBelow; if (pos.y > info.floor) { pos.y = (float)info.floor; @@ -489,13 +489,46 @@ struct TrapSpikes : Controller { }; struct FallingCeiling : Controller { - FallingCeiling(IGame *game, int entity) : Controller(game, entity) {} + enum { + STATE_STATIC, + STATE_FALL, + STATE_DOWN, + }; + + float speed; + + FallingCeiling(IGame *game, int entity) : Controller(game, entity), speed(0) {} virtual void update() { updateAnimation(true); + + if (state == STATE_STATIC) + animation.setState(STATE_FALL); + + if (state == STATE_FALL) { + speed += GRAVITY * 30 * Core::deltaTime; + pos.y += speed * Core::deltaTime; + + TR::Level::FloorInfo info; + level->getFloorInfo(getRoomIndex(), int(pos.x), int(pos.y), int(pos.z), info); + + if (pos.y > info.roomFloor && info.roomBelow != 0xFF) + getEntity().room = info.roomBelow; + + if (pos.y > info.floor) { + pos.y = (float)info.floor; + animation.setState(STATE_DOWN); + } + updateEntity(); + + Controller *lara = (Controller*)level->laraController; + if (collide(lara)) + lara->hit(1000); + } } }; + struct FallingSword : Controller { FallingSword(IGame *game, int entity) : Controller(game, entity) {}