From a50e0ccf61a0b01275e95bd16c0db8a165e015b9 Mon Sep 17 00:00:00 2001 From: XProger Date: Sun, 15 Oct 2017 08:37:01 +0300 Subject: [PATCH] #22 fix moving drill (LEVEL10A) --- src/format.h | 5 +++-- src/lara.h | 21 +++++++++++++++------ src/level.h | 2 +- src/trigger.h | 11 +++++++++-- 4 files changed, 28 insertions(+), 11 deletions(-) diff --git a/src/format.h b/src/format.h index a7f83e7..fb13a43 100644 --- a/src/format.h +++ b/src/format.h @@ -58,7 +58,7 @@ E( HAMMER_HANDLE ) \ E( HAMMER_BLOCK ) \ E( LIGHTNING ) \ - E( DOOR_LATCH ) \ + E( MOVING_OBJECT ) \ E( BLOCK_1 ) \ E( BLOCK_2 ) \ E( BLOCK_3 ) \ @@ -674,7 +674,8 @@ namespace TR { (type == DRAWBRIDGE && flags.active != ACTIVE) || (type == SCION_HOLDER) || ((type == HAMMER_HANDLE || type == HAMMER_BLOCK) && flags.collision) || - (type == CRYSTAL); + (type == CRYSTAL) || + (type == MOVING_OBJECT); } bool isPickup() const { diff --git a/src/lara.h b/src/lara.h index dd797ac..63f50b5 100644 --- a/src/lara.h +++ b/src/lara.h @@ -240,6 +240,7 @@ struct Lara : Character { float hitTime; int hitDir; vec3 collisionOffset; + vec3 flowVelocity; struct Braid { Lara *lara; @@ -1825,6 +1826,7 @@ struct Lara : Character { break; } case TR::Action::FLOW : + applyFlow(level->cameras[cmd.args]); break; case TR::Action::FLIP : { TR::Flags &flip = level->flipmap[cmd.args]; @@ -2516,6 +2518,8 @@ struct Lara : Character { } virtual void updateVelocity() { + flowVelocity = vec3(0); + if (getEntity().type != TR::Entity::LARA) return; @@ -2650,7 +2654,7 @@ struct Lara : Character { collisionOffset = vec3(0.0f); - if (checkCollisions() || (velocity + collisionOffset).length2() >= 1.0f) // TODO: stop & smash anim + if (checkCollisions() || (velocity + flowVelocity + collisionOffset).length2() >= 1.0f) // TODO: stop & smash anim move(); if (getEntity().type != TR::Entity::LARA) { @@ -2754,7 +2758,7 @@ struct Lara : Character { } void move() { - vec3 vel = velocity * Core::deltaTime * 30.0f + collisionOffset; + vec3 vel = (velocity + flowVelocity) * Core::deltaTime * 30.0f + collisionOffset; vec3 opos(pos), offset(0.0f); float radius = stand == STAND_UNDERWATER ? LARA_RADIUS_WATER : LARA_RADIUS; @@ -2899,10 +2903,15 @@ struct Lara : Character { virtual void applyFlow(TR::Camera &sink) { if (stand != STAND_UNDERWATER && stand != STAND_ONWATER) return; - vec3 v(0.0f); - v.x = (float)sign((sink.x / 1024 - (int)pos.x / 1024)); - v.z = (float)sign((sink.z / 1024 - (int)pos.z / 1024)); - velocity = v * (sink.speed * 8.0f); + + vec3 target = vec3(sink.x, sink.y, sink.z); + + flowVelocity = vec3(0); + + float speed = sink.speed * 6.0f; + flowVelocity.x = clamp(target.x - pos.x, -speed, +speed); + flowVelocity.y = clamp(target.y - pos.y, -speed, +speed); + flowVelocity.z = clamp(target.z - pos.z, -speed, +speed); } uint32 getMidasMask() { diff --git a/src/level.h b/src/level.h index 30b86f3..2f837c3 100644 --- a/src/level.h +++ b/src/level.h @@ -518,7 +518,7 @@ struct Level : IGame { case TR::Entity::TRAP_SWORD : return new TrapSword(this, index); case TR::Entity::HAMMER_HANDLE : return new ThorHammer(this, index); case TR::Entity::LIGHTNING : return new Lightning(this, index); - case TR::Entity::DOOR_LATCH : return new DoorLatch(this, index); + case TR::Entity::MOVING_OBJECT : return new MovingObject(this, index); case TR::Entity::SWITCH : case TR::Entity::SWITCH_WATER : return new Switch(this, index); case TR::Entity::PUZZLE_HOLE_1 : diff --git a/src/trigger.h b/src/trigger.h index 0be2a1c..6d036bb 100644 --- a/src/trigger.h +++ b/src/trigger.h @@ -1145,19 +1145,26 @@ struct TrapLava : Controller { }; -struct DoorLatch : Controller { +struct MovingObject : Controller { enum { STATE_CLOSE, STATE_OPEN, }; - DoorLatch(IGame *game, int entity) : Controller(game, entity) { + MovingObject(IGame *game, int entity) : Controller(game, entity) { getEntity().flags.collision = true; } virtual void update() { updateAnimation(true); animation.setState(isActive() ? STATE_OPEN : STATE_CLOSE); + pos += getDir() * (animation.getSpeed() * Core::deltaTime * 30.0f); + + TR::Level::FloorInfo info; + level->getFloorInfo(getRoomIndex(), int(pos.x), int(pos.y), int(pos.z), info); + if (info.roomNext != TR::NO_ROOM) + getEntity().room = info.roomNext; + updateEntity(); } };