From 167fb1e003d601494188dd2cc0e1d4d027091dbe Mon Sep 17 00:00:00 2001 From: XProger Date: Thu, 31 Aug 2017 01:38:00 +0300 Subject: [PATCH] #8 fix camera targeting; #3 fix reach state in falling state --- src/camera.h | 90 +++++++++++++++---------------- src/character.h | 34 +++++++++++- src/controller.h | 7 ++- src/enemy.h | 34 ++---------- src/lara.h | 135 +++++++++++++++++++++-------------------------- src/level.h | 4 ++ 6 files changed, 148 insertions(+), 156 deletions(-) diff --git a/src/camera.h b/src/camera.h index 7e4d0b0..0e32019 100644 --- a/src/camera.h +++ b/src/camera.h @@ -4,6 +4,7 @@ #include "core.h" #include "frustum.h" #include "controller.h" +#include "character.h" #define CAMERA_OFFSET (1024.0f + 256.0f) @@ -18,11 +19,11 @@ struct Camera : Controller { STATE_HEAVY }; - Controller *owner; + Character *owner; Frustum *frustum; float fov, znear, zfar; - vec3 target, destPos, advAngle; + vec3 target, destPos, lastDest, advAngle; float advTimer; mat4 mViewInv; int room; @@ -41,7 +42,7 @@ struct Camera : Controller { bool firstPerson; bool isVR; - Camera(IGame *game, Controller *owner) : Controller(game, owner ? owner->entity : 0), owner(owner), frustum(new Frustum()), timer(-1.0f), viewIndex(-1), viewIndexLast(-1), viewTarget(NULL), reflectPlane(NULL), isVR(false) { + Camera(IGame *game, Character *owner) : Controller(game, owner ? owner->entity : 0), owner(owner), frustum(new Frustum()), timer(-1.0f), viewIndex(-1), viewIndexLast(-1), viewTarget(NULL), reflectPlane(NULL), isVR(false) { changeView(false); if (owner->getEntity().type != TR::Entity::LARA && level->cameraFrames) { state = STATE_CUTSCENE; @@ -110,6 +111,16 @@ struct Camera : Controller { this->viewIndex = viewIndex; this->timer = timer; this->speed = speed; + lastDest = pos; + } + + vec3 getViewPoint() { + vec3 p = owner->getViewPoint(); + if (owner->stand != Character::STAND_UNDERWATER) + p.y -= 256.0f; + if (state == STATE_COMBAT) + p.y -= 256.0f; + return p; } virtual void update() { @@ -168,49 +179,45 @@ struct Camera : Controller { } else advTimer = -1.0f; -/* toto if (owner->velocity != 0.0f && advTimer < 0.0f && !Input::down[ikMouseL]) advTimer = -advTimer; -*/ + angle = owner->angle + advAngle; angle.z = 0.0f; -/* toto - if (owner->stand == Lara::STAND_ONWATER) - angle.x -= 22.0f * DEG2RAD; - if (owner->state == Lara::STATE_HANG || owner->state == Lara::STATE_HANG_LEFT || owner->state == Lara::STATE_HANG_RIGHT) - angle.x -= 60.0f * DEG2RAD; -*/ - Controller *lookAt = viewTarget; -/* todo - if (owner->arms[0].target > -1 && owner->arms[1].target > -1 && owner->arms[0].target != owner->arms[1].target) { - // two diff targets - } else if (owner->arms[0].target > -1) - lookAt = owner->arms[0].target; - else if (owner->arms[1].target > -1) - lookAt = owner->arms[1].target; - else if (owner->arms[0].tracking > -1) - lookAt = owner->arms[0].tracking; - else if (owner->arms[1].tracking > -1) - lookAt = owner->arms[1].tracking; - owner->viewTarget = lookAt; -*/ + if (owner->stand == Character::STAND_ONWATER) + angle.x -= 22.0f * DEG2RAD; + if (owner->stand == Character::STAND_HANG) + angle.x -= 60.0f * DEG2RAD; + + + Controller *lookAt = viewTarget; + + if (state != STATE_STATIC) { + if (owner->viewTarget) + owner->lookAt(lookAt = owner->viewTarget); + else + owner->lookAt(lookAt = viewTarget); + } + + vec3 viewPoint = getViewPoint(); + if (timer > 0.0f) { timer -= Core::deltaTime; if (timer <= 0.0f) { timer = -1.0f; state = STATE_FOLLOW; - viewTarget = NULL; + viewTarget = owner->viewTarget = NULL; viewIndex = -1; -/* todo - target = owner->getViewPoint(); -*/ + target = viewPoint; + if (room != getRoomIndex()) + pos = lastDest; } - } + } else + viewIndex = -1; - if (timer < 0.0f) { + if (timer < 0.0f) viewTarget = NULL; - } if (firstPerson && viewIndex == -1) { Basis head = owner->animation.getJoints(owner->getMatrix(), 14, true); @@ -233,10 +240,8 @@ struct Camera : Controller { float lerpFactor = lookAt ? 10.0f : 6.0f; vec3 dir; -/* todo - target = target.lerp(owner->getViewPoint(), lerpFactor * Core::deltaTime); -*/ - target = owner->animation.getJoints(owner->getMatrix(), 7).pos; + + target = target.lerp(viewPoint, lerpFactor * Core::deltaTime); if (viewIndex > -1) { TR::Camera &cam = level->cameras[viewIndex]; @@ -252,17 +257,15 @@ struct Camera : Controller { dir = getDir(); int destRoom; -/* todo - if ((!owner->emptyHands() || owner->state != Lara::STATE_BACK_JUMP) || lookAt > -1) { -*/ + if ((state == STATE_COMBAT || owner->state != 25) || lookAt) { // TODO: FUUU! 25 == Lara::STATE_BACK_JUMP vec3 eye = target - dir * CAMERA_OFFSET; destPos = trace(owner->getRoomIndex(), target, eye, destRoom, true); -/* + lastDest = destPos; } else { vec3 eye = lastDest + dir.cross(vec3(0, 1, 0)).normal() * 2048.0f - vec3(0.0f, 512.0f, 0.0f); destPos = trace(owner->getRoomIndex(), target, eye, destRoom, true); } -*/ + room = destRoom; } pos = pos.lerp(destPos, Core::deltaTime * lerpFactor); @@ -317,10 +320,7 @@ struct Camera : Controller { room = owner->getRoomIndex(); pos = owner->pos - owner->getDir() * 1024.0f; -/* todo - target = owner->getViewPoint(); -*/ - target = owner->animation.getJoints(owner->getMatrix(), 7).pos; + target = getViewPoint(); advAngle = vec3(0.0f); advTimer = 0.0f; diff --git a/src/character.h b/src/character.h index e65be94..30c9e4a 100644 --- a/src/character.h +++ b/src/character.h @@ -26,6 +26,10 @@ struct Character : Controller { DEATH = 1 << 9 }; + Controller *viewTarget; + int jointChest; + int jointHead; + vec3 velocity; float angleExt; float speed; @@ -39,7 +43,7 @@ struct Character : Controller { Collision collision; - Character(IGame *game, int entity, float health) : Controller(game, entity), health(health), tilt(0.0f), stand(STAND_GROUND), lastInput(0), velocity(0.0f), angleExt(0.0f) { + Character(IGame *game, int entity, float health) : Controller(game, entity), health(health), tilt(0.0f), stand(STAND_GROUND), lastInput(0), viewTarget(NULL), jointChest(-1), jointHead(-1), velocity(0.0f), angleExt(0.0f) { stepHeight = 256; dropHeight = -256; @@ -197,6 +201,34 @@ struct Character : Controller { level->entities[index].controller = new Bubble(game, index); } } + + vec3 getViewPoint() { + return animation.getJoints(getMatrix(), jointChest).pos; + } + + virtual void lookAt(Controller *target) { + if (health <= 0.0f) + target = NULL; + + float speed = 8.0f * Core::deltaTime; + quat rot; + + if (jointChest > -1) { + if (aim(target, jointChest, vec4(-PI * 0.8f, PI * 0.8f, -PI * 0.75f, PI * 0.75f), rot)) + rotChest = rotChest.slerp(quat(0, 0, 0, 1).slerp(rot, 0.5f), speed); + else + rotChest = rotChest.slerp(quat(0, 0, 0, 1), speed); + animation.overrides[jointChest] = rotChest * animation.overrides[jointChest]; + } + + if (jointHead > -1) { + if (aim(target, jointHead, vec4(-PI * 0.25f, PI * 0.25f, -PI * 0.5f, PI * 0.5f), rot)) + rotHead = rotHead.slerp(rot, speed); + else + rotHead = rotHead.slerp(quat(0, 0, 0, 1), speed); + animation.overrides[jointHead] = rotHead * animation.overrides[jointHead]; + } + } }; #endif \ No newline at end of file diff --git a/src/controller.h b/src/controller.h index 9f3caa5..4cd202c 100644 --- a/src/controller.h +++ b/src/controller.h @@ -200,10 +200,9 @@ struct Controller { layers[layer].mask = mask; } - bool aim(int target, int joint, const vec4 &angleRange, quat &rot, quat *rotAbs = NULL) { - if (target > -1) { - TR::Entity &e = level->entities[target]; - Box box = ((Controller*)e.controller)->getBoundingBox(); + bool aim(Controller *target, int joint, const vec4 &angleRange, quat &rot, quat *rotAbs = NULL) { + if (target) { + Box box = target->getBoundingBox(); vec3 t = (box.min + box.max) * 0.5f; Basis b = animation.getJoints(Basis(getMatrix()), joint); diff --git a/src/enemy.h b/src/enemy.h index 2640d66..800226f 100644 --- a/src/enemy.h +++ b/src/enemy.h @@ -61,9 +61,6 @@ struct Enemy : Character { Character *target; Path *path; - int jointChest; - int jointHead; - float targetDist; bool targetDead; bool targetInView; // target in enemy view zone @@ -71,8 +68,6 @@ struct Enemy : Character { bool targetCanAttack; Enemy(IGame *game, int entity, float health, int radius, float length, float aggression) : Character(game, entity, health), ai(AI_RANDOM), mood(MOOD_SLEEP), wound(false), nextState(0), targetBox(-1), thinkTime(1.0f / 30.0f), length(length), aggression(aggression), radius(radius), target(NULL), path(NULL) { - jointChest = jointHead = -1; - targetDist = +INF; targetInView = targetFromView = targetCanAttack = false; } @@ -177,27 +172,6 @@ struct Enemy : Character { animation.overrideMask &= ~(1 << chest); } - void lookAt(int target, int chest, int head, bool rotate = false) { - float speed = 8.0f * Core::deltaTime; - quat rot; - - if (chest > -1) { - if (rotate && aim(target, chest, vec4(-PI * 0.8f, PI * 0.8f, -PI * 0.75f, PI * 0.75f), rot)) - rotChest = rotChest.slerp(quat(0, 0, 0, 1).slerp(rot, 0.5f), speed); - else - rotChest = rotChest.slerp(quat(0, 0, 0, 1), speed); - animation.overrides[chest] = rotChest * animation.overrides[chest]; - } - - if (head > -1) { - if (rotate && aim(target, head, vec4(-PI * 0.25f, PI * 0.25f, -PI * 0.5f, PI * 0.5f), rot)) - rotHead = rotHead.slerp(rot, speed); - else - rotHead = rotHead.slerp(quat(0, 0, 0, 1), speed); - animation.overrides[head] = rotHead * animation.overrides[head]; - } - } - bool getTargetInfo(int height, vec3 *pos, float *angleX, float *angleY, float *dist) { vec3 p = waypoint; p.y -= height; @@ -621,7 +595,7 @@ struct Wolf : Enemy { Enemy::updatePosition(); setOverrides(state != STATE_DEATH, jointChest, jointHead); - lookAt(target ? target->entity : -1, jointChest, jointHead); + lookAt(target); } }; @@ -770,7 +744,7 @@ struct Bear : Enemy { Enemy::updatePosition(); setOverrides(state == STATE_RUN || state == STATE_WALK || state == STATE_HIND, jointChest, jointHead); - lookAt(target ? target->entity : -1, jointChest, jointHead); + lookAt(target); } }; @@ -963,7 +937,7 @@ struct Rex : Enemy { Enemy::updatePosition(); setOverrides(true, jointChest, jointHead); - lookAt(target ? target->entity : -1, jointChest, jointHead, targetInView && state != STATE_DEATH && state != STATE_FATAL); + lookAt(target); } }; @@ -1081,7 +1055,7 @@ struct Raptor : Enemy { Enemy::updatePosition(); setOverrides(true, jointChest, jointHead); - lookAt(target ? target->entity : -1, jointChest, jointHead, targetInView && state != STATE_DEATH); + lookAt(target); } }; diff --git a/src/lara.h b/src/lara.h index 8acef66..12bf4eb 100644 --- a/src/lara.h +++ b/src/lara.h @@ -211,19 +211,20 @@ struct Lara : Character { vec3 chestOffset; struct Arm { - int tracking; // tracking target (main target) - int target; // target for shooting + Controller *tracking; // tracking target (main target) + Controller *target; // target for shooting float shotTimer; quat rot, rotAbs; Weapon::Anim anim; Animation animation; + + Arm() : tracking(NULL), target(NULL) {} } arms[2]; TR::Entity::Type usedKey; TR::Entity *pickupEntity; KeyHole *keyHole; - int viewTarget; int roomPrev; // water out from room vec2 rotFactor; @@ -394,7 +395,7 @@ struct Lara : Character { } *braid; - Lara(IGame *game, int entity) : Character(game, entity, LARA_MAX_HEALTH), dozy(false), wpnCurrent(Weapon::EMPTY), wpnNext(Weapon::EMPTY), chestOffset(pos), viewTarget(-1), braid(NULL) { + Lara(IGame *game, int entity) : Character(game, entity, LARA_MAX_HEALTH), dozy(false), wpnCurrent(Weapon::EMPTY), wpnNext(Weapon::EMPTY), chestOffset(pos), braid(NULL) { if (getEntity().type == TR::Entity::LARA) { if (getRoom().flags.water) @@ -403,6 +404,8 @@ struct Lara : Character { animation.setAnim(ANIM_STAND); } + jointChest = 7; + jointHead = 14; oxygen = LARA_MAX_OXYGEN; hitDir = -1; damageTime = LARA_DAMAGE_TIME; @@ -754,10 +757,10 @@ struct Lara : Character { //int realFrameIndex = int(arms[i].animation.time * 30.0f / anim->frameRate) % ((anim->frameEnd - anim->frameStart) / anim->frameRate + 1); if (anim.frameIndex != anim.framePrev) { if (anim.frameIndex == 0) { //realFrameIndex < arms[i].animation.framePrev) { - if ((input & ACTION) && (arm.tracking == -1 || arm.target > -1)) { + if ((input & ACTION) && (!arm.tracking || arm.target)) { armShot[i] = true; } else - wpnSetAnim(arm, Weapon::IS_ARMED, Weapon::Anim::AIM, 0.0f, -1.0f, arm.target == -1); + wpnSetAnim(arm, Weapon::IS_ARMED, Weapon::Anim::AIM, 0.0f, -1.0f, arm.target == NULL); } // shotgun reload sound if (wpnCurrent == Weapon::SHOTGUN) { @@ -811,8 +814,8 @@ struct Lara : Character { int room; vec3 hit = trace(getRoomIndex(), p, t, room, false); - if (arm->target > -1 && checkHit(arm->target, p, hit, hit)) { - ((Character*)level->entities[arm->target].controller)->hit(wpnGetDamage()); + if (arm->target && checkHit(arm->target, p, hit, hit)) { + ((Character*)arm->target)->hit(wpnGetDamage()); hit -= d * 64.0f; Sprite::add(game, TR::Entity::BLOOD, room, (int)hit.x, (int)hit.y, (int)hit.z, Sprite::FRAME_ANIMATED); } else { @@ -848,8 +851,8 @@ struct Lara : Character { if (input & DEATH) { arms[0].shotTimer = arms[1].shotTimer = MUZZLE_FLASH_TIME + 1.0f; - arms[0].tracking = arms[1].tracking = -1; - arms[0].target = arms[1].target = -1; + arms[0].tracking = arms[1].tracking = NULL; + arms[0].target = arms[1].target = NULL; animation.overrideMask = 0; return; } @@ -877,7 +880,7 @@ struct Lara : Character { for (int i = 0; i < 2; i++) { Arm &arm = arms[i]; - if (arm.target > -1 || ((input & ACTION) && arm.tracking == -1)) { + if (arm.target || ((input & ACTION) && !arm.tracking)) { if (arm.anim == Weapon::Anim::HOLD) wpnSetAnim(arm, wpnState, Weapon::Anim::AIM, 0.0f, 1.0f); } else @@ -1025,8 +1028,10 @@ struct Lara : Character { } animation.overrideMask = overrideMask; + } - lookAt(viewTarget); + virtual void lookAt(Controller *target) { + Character::lookAt(canLookAt() ? target : NULL); if (wpnCurrent == Weapon::SHOTGUN) aimShotgun(); @@ -1034,31 +1039,11 @@ struct Lara : Character { aimPistols(); } - void lookAt(int target) { // TODO: character lookAt - float speed = 8.0f * Core::deltaTime; - quat rot; - - bool can = canLookAt(); - // chest - if (can && aim(target, 7, vec4(-PI * 0.4f, PI * 0.4f, -PI * 0.9f, PI * 0.9f), rot)) - rotChest = rotChest.slerp(quat(0, 0, 0, 1).slerp(rot, 0.5f), speed); - else - rotChest = rotChest.slerp(quat(0, 0, 0, 1), speed); - animation.overrides[7] = rotChest * animation.overrides[7]; - - // head - if (can && aim(target, 14, vec4(-PI * 0.25f, PI * 0.25f, -PI * 0.5f, PI * 0.5f), rot)) - rotHead = rotHead.slerp(rot, speed); - else - rotHead = rotHead.slerp(quat(0, 0, 0, 1), speed); - animation.overrides[14] = rotHead * animation.overrides[14]; - } - void aimShotgun() { quat rot; Arm &arm = arms[0]; - arm.target = aim(arm.target, 14, vec4(-PI * 0.4f, PI * 0.4f, -PI * 0.25f, PI * 0.25f), rot, &arm.rotAbs) ? arm.target : -1; + arm.target = aim(arm.target, 14, vec4(-PI * 0.4f, PI * 0.4f, -PI * 0.25f, PI * 0.25f), rot, &arm.rotAbs) ? arm.target : NULL; } void aimPistols() { @@ -1080,7 +1065,7 @@ struct Lara : Character { arm.target = arms[i^1].target; if (!aim(arm.target, j, ranges[i], rot, &arm.rotAbs)) { rot = quat(0, 0, 0, 1); - arm.target = -1; + arm.target = NULL; } } @@ -1098,10 +1083,11 @@ struct Lara : Character { } void updateTargets() { - arms[0].target = arms[1].target = -1; + arms[0].target = arms[1].target = NULL; + viewTarget = NULL; if (emptyHands() || !wpnReady()) { - arms[0].tracking = arms[1].tracking = -1; + arms[0].tracking = arms[1].tracking = NULL; return; } @@ -1109,7 +1095,7 @@ struct Lara : Character { bool retarget = false; if (Core::settings.controls.retarget) { for (int i = 0; i < 2; i++) - if (arms[i].tracking == -1 || ((Character*)level->entities[arms[i].tracking].controller)->health <= 0.0f) { + if (!arms[i].tracking || ((Character*)arms[i].tracking)->health <= 0.0f) { retarget = true; break; } @@ -1119,15 +1105,15 @@ struct Lara : Character { if (!(input & ACTION) || retarget) { getTargets(arms[0].tracking, arms[1].tracking); if (count == 1) - arms[1].tracking = -1; - else if (arms[0].tracking == -1 && arms[1].tracking != -1) + arms[1].tracking = NULL; + else if (!arms[0].tracking && arms[1].tracking) arms[0].tracking = arms[1].tracking; - else if (arms[1].tracking == -1 && arms[0].tracking != -1) + else if (!arms[1].tracking && arms[0].tracking) arms[1].tracking = arms[0].tracking; arms[0].target = arms[0].tracking; arms[1].target = arms[1].tracking; } else { - if (arms[0].tracking == -1 && arms[1].tracking == -1) + if (!arms[0].tracking && !arms[1].tracking) return; // flip left and right by relative target direction @@ -1137,8 +1123,8 @@ struct Lara : Character { dir.y = 0.0f; for (int i = 0; i < count; i++) - if (arms[i].tracking != -1) { - vec3 v = ((Controller*)level->entities[arms[i].tracking].controller)->pos - pos; + if (arms[i].tracking) { + vec3 v = arms[i].tracking->pos - pos; v.y = 0; side[i] = sign(v.cross(dir).y); } @@ -1149,32 +1135,42 @@ struct Lara : Character { // check occlusion for tracking targets for (int i = 0; i < count; i++) - if (arms[i].tracking > -1) { - TR::Entity &e = level->entities[arms[i].tracking]; - Controller *enemy = (Controller*)e.controller; + if (arms[i].tracking) { + Controller *enemy = (Controller*)arms[i].tracking; Box box = enemy->getBoundingBox(); vec3 to = box.center(); to.y = box.min.y + (box.max.y - box.min.y) / 3.0f; vec3 from = pos - vec3(0, 650, 0); - arms[i].target = checkOcclusion(from, to, (to - from).length()) ? arms[i].tracking : -1; + arms[i].target = checkOcclusion(from, to, (to - from).length()) ? arms[i].tracking : NULL; } if (count == 1) - arms[1].target = -1; - else if (arms[0].target == -1 && arms[1].target != -1) + arms[1].target = NULL; + else if (!arms[0].target && arms[1].target) arms[0].target = arms[1].target; - else if (arms[1].target == -1 && arms[0].target != -1) + else if (!arms[1].target && arms[0].target) arms[1].target = arms[0].target; } + + if (arms[0].target && arms[1].target && arms[0].target != arms[1].target) { + viewTarget = NULL; //arms[0].target; + } else if (arms[0].target) + viewTarget = arms[0].target; + else if (arms[1].target) + viewTarget = arms[1].target; + else if (arms[0].tracking) + viewTarget = arms[0].tracking; + else if (arms[1].tracking) + viewTarget = arms[1].tracking; } - void getTargets(int &target1, int &target2) { + void getTargets(Controller *&target1, Controller *&target2) { vec3 dir = getDir().normal(); float dist[2] = { TARGET_MAX_DIST, TARGET_MAX_DIST }; - target1 = target2 = -1; + target1 = target2 = NULL; vec3 from = pos - vec3(0, 650, 0); @@ -1199,15 +1195,15 @@ struct Lara : Character { if (d < dist[0]) { target2 = target1; dist[1] = dist[0]; - target1 = i; + target1 = enemy; dist[0] = d; } else if (d < dist[1]) { - target2 = i; + target2 = enemy; dist[1] = d; } } - if (target2 == -1 || dist[1] > dist[0] * 4) + if (!target2 || dist[1] > dist[0] * 4) target2 = target1; } @@ -1217,12 +1213,9 @@ struct Lara : Character { return ((d - from).length() > (dist - 512.0f)); } - bool checkHit(int target, const vec3 &from, const vec3 &to, vec3 &point) { - TR::Entity &e = level->entities[target]; - Controller *controller = (Controller*)e.controller; - - Box box = controller->getBoundingBoxLocal(); - mat4 m = controller->getMatrix(); + bool checkHit(Controller *target, const vec3 &from, const vec3 &to, vec3 &point) { + Box box = target->getBoundingBoxLocal(); + mat4 m = target->getMatrix(); float t; vec3 v = to - from; @@ -1231,7 +1224,7 @@ struct Lara : Character { v = v.normal(); Sphere spheres[34]; int count; - controller->getSpheres(spheres, count); + target->getSpheres(spheres, count); for (int i = 0; i < count; i++) if (spheres[i].intersect(from, v, t)) { point = from + v * t; @@ -1671,16 +1664,6 @@ struct Lara : Character { level->isFlipped = !level->isFlipped; } - vec3 getViewPoint() { - vec3 offset = chestOffset = animation.getJoints(getMatrix(), 7).pos; - if (stand != STAND_UNDERWATER) - offset.y -= 256.0f; - if (!emptyHands()) - offset.y -= 256.0f; - - return offset; - } - virtual Stand getStand() { if (dozy) return STAND_UNDERWATER; @@ -1694,7 +1677,7 @@ struct Lara : Character { return STAND_AIR; } - if (state == STATE_HANDSTAND || state == STATE_HANG_UP) + if (state == STATE_HANDSTAND || (state == STATE_HANG_UP && animation.index != ANIM_CLIMB_JUMP)) return STAND_HANG; if (stand == STAND_ONWATER && state != STATE_STOP) { @@ -1788,14 +1771,14 @@ struct Lara : Character { } } - if (state == STATE_FORWARD_JUMP) { + if (state == STATE_FORWARD_JUMP || state == STATE_FALL_BACK) { if (emptyHands()) { if (input & ACTION) return STATE_REACH; if ((input & (JUMP | FORTH | WALK)) == (JUMP | FORTH | WALK)) return STATE_SWAN_DIVE; } } else if (state != STATE_FALL && state != STATE_FALL_BACK && state != STATE_SWAN_DIVE && state != STATE_FAST_DIVE && state != STATE_REACH && state != STATE_UP_JUMP && state != STATE_BACK_JUMP && state != STATE_LEFT_JUMP && state != STATE_RIGHT_JUMP) - return animation.setAnim( (state == STATE_FAST_BACK || state == STATE_SLIDE_BACK || state == STATE_ROLL_2) ? ANIM_FALL_BACK : ANIM_FALL_FORTH); + return animation.setAnim(ANIM_FALL_FORTH);// (state == STATE_FAST_BACK || state == STATE_SLIDE_BACK || state == STATE_ROLL_2) ? ANIM_FALL_BACK : ANIM_FALL_FORTH); if (state == STATE_SWAN_DIVE) return STATE_FAST_DIVE; @@ -2535,7 +2518,7 @@ struct Lara : Character { // hit the wall switch (stand) { case STAND_AIR : - if (state == STATE_UP_JUMP || state == STATE_REACH) + if (state == STATE_UP_JUMP || state == STATE_REACH || state == STATE_FALL_BACK) velocity.x = velocity.z = 0.0f; if (velocity.x != 0.0f || velocity.z != 0.0f) { diff --git a/src/level.h b/src/level.h index bfa6545..c5a88be 100644 --- a/src/level.h +++ b/src/level.h @@ -811,6 +811,10 @@ struct Level : IGame { c->update(); c = next; } + + if (camera->state != Camera::STATE_STATIC) + camera->state = lara->emptyHands() ? Camera::STATE_FOLLOW : Camera::STATE_COMBAT; + camera->update(); if (waterCache)