mirror of
https://github.com/XProger/OpenLara.git
synced 2025-08-18 19:01:45 +02:00
90
src/camera.h
90
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;
|
||||
|
||||
|
@@ -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
|
@@ -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);
|
||||
|
34
src/enemy.h
34
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);
|
||||
}
|
||||
};
|
||||
|
||||
|
135
src/lara.h
135
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) {
|
||||
|
@@ -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)
|
||||
|
Reference in New Issue
Block a user