diff --git a/src/camera.h b/src/camera.h index 48a3ebf..d03a958 100644 --- a/src/camera.h +++ b/src/camera.h @@ -50,6 +50,8 @@ struct Camera : ICamera { room = level->entities[level->cutEntity].room; } else state = STATE_FOLLOW; + destPos = owner->pos - owner->getDir() * 1024.0f; + pos = destPos; advTimer = -1.0f; } diff --git a/src/format.h b/src/format.h index 8fb4807..75b4172 100644 --- a/src/format.h +++ b/src/format.h @@ -191,7 +191,7 @@ E( LAVA_EMITTER ) \ E( FLAME ) \ E( FLAME_EMITTER ) \ - E( LAVA_FLOW ) \ + E( TRAP_LAVA ) \ E( MUTANT_EGG_BIG ) \ E( BOAT ) \ E( EARTHQUAKE ) \ @@ -310,6 +310,7 @@ namespace TR { HIT_BLADE, HIT_BOULDER, HIT_SPIKES, + HIT_FLAME, HIT_REX, }; diff --git a/src/lara.h b/src/lara.h index 76cc274..8408ff2 100644 --- a/src/lara.h +++ b/src/lara.h @@ -105,6 +105,9 @@ struct Lara : Character { ANIM_HIT_BACK = 126, ANIM_HIT_LEFT = 127, ANIM_HIT_RIGHT = 128, + + ANIM_DEATH_BOULDER = 139, + ANIM_STAND_ROLL_BEGIN = 146, ANIM_STAND_ROLL_END = 147, @@ -464,6 +467,8 @@ struct Lara : Character { //reset(12, vec3(34236, -2415, 14974), 0); // level 8b (sphinx) //reset(0, vec3(40913, -1012, 42252), PI); // level 8c //reset(10, vec3(90443, 11264 - 256, 114614), PI, STAND_ONWATER); // villa mortal 2 + //reset(50, vec3(53703, -18688, -13769), PI); // Level 10c (scion holder) + //reset(19, vec3(35364, -512, 40199), PI * 0.5f); // Level 10c (lave flow) #endif chestOffset = animation.getJoints(getMatrix(), 7).pos; } @@ -1333,7 +1338,7 @@ struct Lara : Character { switch (hitType) { case TR::HIT_BOULDER : { - animation.setAnim(level->models[TR::MODEL_LARA_SPEC].animation + 2); + animation.setAnim(ANIM_DEATH_BOULDER); angle = enemy->angle; TR::Level::FloorInfo info; level->getFloorInfo(getRoomIndex(), int(pos.x), int(pos.y), int(pos.z), info); diff --git a/src/level.h b/src/level.h index dac5725..3f93061 100644 --- a/src/level.h +++ b/src/level.h @@ -433,6 +433,9 @@ struct Level : IGame { case TR::Entity::WATERFALL : entity.controller = new Waterfall(this, i); break; + case TR::Entity::TRAP_LAVA : + entity.controller = new TrapLava(this, i); + break; default : if (entity.modelIndex > 0) entity.controller = new Controller(this, i); diff --git a/src/trigger.h b/src/trigger.h index 1d5698d..f4202f8 100644 --- a/src/trigger.h +++ b/src/trigger.h @@ -649,6 +649,35 @@ struct TrapSword : Controller { } }; + +struct TrapLava : Controller { + bool done; + + TrapLava(IGame *game, int entity) : Controller(game, entity), done(false) {} + + virtual void update() { + Character *lara = (Character*)level->laraController; + if (lara->health > 0.0f && collide(lara)) + lara->hit(1000.0f, this, TR::HIT_FLAME); + + if (done) { + deactivate(); + return; + } + + vec3 dir = getDir(); + pos += dir * (25.0f * 30.0f * Core::deltaTime); + + updateEntity(); + int roomIndex = getRoomIndex(); + TR::Room::Sector *s = level->getSector(roomIndex, int(pos.x + dir.x * 2048.0f), int(pos.y), int(pos.z + dir.z * 2048.0f)); + if (!s || s->floor * 256 != int(pos.y)) + done = true; + getEntity().room = roomIndex; + } +}; + + struct KeyHole : Controller { KeyHole(IGame *game, int entity) : Controller(game, entity) {} @@ -666,6 +695,7 @@ struct KeyHole : Controller { virtual void update() {} }; + struct Waterfall : Controller { #define SPLASH_TIMESTEP (1.0f / 30.0f)