mirror of
https://github.com/XProger/OpenLara.git
synced 2025-08-08 06:06:51 +02:00
fix gears mesh swap on LEVEL3A; attach puzzle and key items to the hand and keyhole;
This commit is contained in:
@@ -142,10 +142,15 @@ struct Controller {
|
|||||||
} *explodeParts;
|
} *explodeParts;
|
||||||
|
|
||||||
vec3 lastPos;
|
vec3 lastPos;
|
||||||
|
mat4 matrix;
|
||||||
bool invertAim;
|
bool invertAim;
|
||||||
|
bool lockMatrix;
|
||||||
|
|
||||||
Controller(IGame *game, int entity) : next(NULL), game(game), level(game->getLevel()), entity(entity), animation(level, getModel(), level->entities[entity].flags.smooth), state(animation.state), layers(0), explodeMask(0), explodeParts(0), lastPos(0), invertAim(false) {
|
Controller(IGame *game, int entity) : next(NULL), game(game), level(game->getLevel()), entity(entity), animation(level, getModel(), level->entities[entity].flags.smooth), state(animation.state), layers(0), explodeMask(0), explodeParts(0), lastPos(0), invertAim(false) {
|
||||||
const TR::Entity &e = getEntity();
|
const TR::Entity &e = getEntity();
|
||||||
|
lockMatrix = false;
|
||||||
|
matrix.identity();
|
||||||
|
|
||||||
pos = vec3(float(e.x), float(e.y), float(e.z));
|
pos = vec3(float(e.x), float(e.y), float(e.z));
|
||||||
angle = vec3(0.0f, e.rotation, 0.0f);
|
angle = vec3(0.0f, e.rotation, 0.0f);
|
||||||
roomIndex = e.room;
|
roomIndex = e.room;
|
||||||
@@ -1185,12 +1190,13 @@ struct Controller {
|
|||||||
if (level->isCutsceneLevel() && (getEntity().isActor() || getEntity().isLara()))
|
if (level->isCutsceneLevel() && (getEntity().isActor() || getEntity().isLara()))
|
||||||
return level->cutMatrix;
|
return level->cutMatrix;
|
||||||
|
|
||||||
mat4 matrix;
|
if (!lockMatrix) {
|
||||||
matrix.identity();
|
matrix.identity();
|
||||||
matrix.translate(pos);
|
matrix.translate(pos);
|
||||||
if (angle.y != 0.0f) matrix.rotateY(angle.y - animation.rot * animation.delta);
|
if (angle.y != 0.0f) matrix.rotateY(angle.y - animation.rot * animation.delta);
|
||||||
if (angle.x != 0.0f) matrix.rotateX(angle.x);
|
if (angle.x != 0.0f) matrix.rotateX(angle.x);
|
||||||
if (angle.z != 0.0f) matrix.rotateZ(angle.z);
|
if (angle.z != 0.0f) matrix.rotateZ(angle.z);
|
||||||
|
}
|
||||||
return matrix;
|
return matrix;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1320,7 +1326,7 @@ struct Controller {
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
Core::setBasis(joints, model->mCount);
|
Core::setBasis(joints, model->mCount);
|
||||||
mesh->renderModel(getEntity().modelIndex - 1, caustics);
|
mesh->renderModel(model->index, caustics);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -2064,7 +2064,7 @@ namespace TR {
|
|||||||
|
|
||||||
struct Model {
|
struct Model {
|
||||||
Entity::Type type;
|
Entity::Type type;
|
||||||
uint16 unused;
|
uint16 index;
|
||||||
uint16 mCount;
|
uint16 mCount;
|
||||||
uint16 mStart;
|
uint16 mStart;
|
||||||
uint32 node;
|
uint32 node;
|
||||||
@@ -2649,7 +2649,8 @@ namespace TR {
|
|||||||
Model &m = models[i];
|
Model &m = models[i];
|
||||||
uint16 type;
|
uint16 type;
|
||||||
m.type = Entity::Type(stream.read(type));
|
m.type = Entity::Type(stream.read(type));
|
||||||
stream.read(m.unused);
|
stream.seek(sizeof(m.index));
|
||||||
|
m.index = i;
|
||||||
stream.read(m.mCount);
|
stream.read(m.mCount);
|
||||||
stream.read(m.mStart);
|
stream.read(m.mStart);
|
||||||
stream.read(m.node);
|
stream.read(m.node);
|
||||||
|
69
src/lara.h
69
src/lara.h
@@ -244,6 +244,7 @@ struct Lara : Character {
|
|||||||
int pickupListCount;
|
int pickupListCount;
|
||||||
Controller *pickupList[32];
|
Controller *pickupList[32];
|
||||||
KeyHole *keyHole;
|
KeyHole *keyHole;
|
||||||
|
Controller *keyItem;
|
||||||
Lightning *lightning;
|
Lightning *lightning;
|
||||||
Texture *environment;
|
Texture *environment;
|
||||||
vec2 rotFactor;
|
vec2 rotFactor;
|
||||||
@@ -454,6 +455,7 @@ struct Lara : Character {
|
|||||||
hitTime = 0.0f;
|
hitTime = 0.0f;
|
||||||
|
|
||||||
keyHole = NULL;
|
keyHole = NULL;
|
||||||
|
keyItem = NULL;
|
||||||
lightning = NULL;
|
lightning = NULL;
|
||||||
environment = NULL;
|
environment = NULL;
|
||||||
|
|
||||||
@@ -486,6 +488,8 @@ struct Lara : Character {
|
|||||||
//reset(33, vec3(48229, 4608, 78420), 270 * DEG2RAD); // level 1 (end)
|
//reset(33, vec3(48229, 4608, 78420), 270 * DEG2RAD); // level 1 (end)
|
||||||
//reset(9, vec3(63008, 0, 37787), 0); // level 2 (switch)
|
//reset(9, vec3(63008, 0, 37787), 0); // level 2 (switch)
|
||||||
//reset(15, vec3(70067, -256, 29104), -0.68f); // level 2 (pool)
|
//reset(15, vec3(70067, -256, 29104), -0.68f); // level 2 (pool)
|
||||||
|
//reset(5, vec3(55398, 0, 29246), -PI * 0.5f); // level 2 (key hole)
|
||||||
|
//reset(71, vec3(12473, -768, 30208), -PI * 0.5f); // level 2 (puzzle hole)
|
||||||
//reset(26, vec3(71980, 1546, 19000), 270 * DEG2RAD); // level 2 (underwater switch)
|
//reset(26, vec3(71980, 1546, 19000), 270 * DEG2RAD); // level 2 (underwater switch)
|
||||||
//reset(61, vec3(27221, -1024, 29205), -PI * 0.5f); // level 2 (blade)
|
//reset(61, vec3(27221, -1024, 29205), -PI * 0.5f); // level 2 (blade)
|
||||||
//reset(43, vec3(31400, -2560, 25200), PI); // level 2 (reach)
|
//reset(43, vec3(31400, -2560, 25200), PI); // level 2 (reach)
|
||||||
@@ -508,6 +512,7 @@ struct Lara : Character {
|
|||||||
//reset(19, vec3(41418, -3707, 58863), 270 * DEG2RAD); // level 5 (triangle)
|
//reset(19, vec3(41418, -3707, 58863), 270 * DEG2RAD); // level 5 (triangle)
|
||||||
//reset(21, vec3(24106, -4352, 52089), 0); // level 6 (flame traps)
|
//reset(21, vec3(24106, -4352, 52089), 0); // level 6 (flame traps)
|
||||||
//reset(73, vec3(73372, 122, 51687), PI * 0.5f); // level 6 (midas hand)
|
//reset(73, vec3(73372, 122, 51687), PI * 0.5f); // level 6 (midas hand)
|
||||||
|
//reset(20, vec3(25088, -5120, 17593), PI); // level 6 (puzzle slots)
|
||||||
//reset(64, vec3(36839, -2560, 48769), 270 * DEG2RAD); // level 6 (flipmap effect)
|
//reset(64, vec3(36839, -2560, 48769), 270 * DEG2RAD); // level 6 (flipmap effect)
|
||||||
//reset(99, vec3(45562, -3328, 63366), 225 * DEG2RAD); // level 7a (flipmap)
|
//reset(99, vec3(45562, -3328, 63366), 225 * DEG2RAD); // level 7a (flipmap)
|
||||||
//reset(77, vec3(36943, -4096, 62821), 270 * DEG2RAD); // level 7b (heavy trigger)
|
//reset(77, vec3(36943, -4096, 62821), 270 * DEG2RAD); // level 7b (heavy trigger)
|
||||||
@@ -609,6 +614,9 @@ struct Lara : Character {
|
|||||||
visibleMask = 0xFFFFFFFF;
|
visibleMask = 0xFFFFFFFF;
|
||||||
health = LARA_MAX_HEALTH;
|
health = LARA_MAX_HEALTH;
|
||||||
oxygen = LARA_MAX_OXYGEN;
|
oxygen = LARA_MAX_OXYGEN;
|
||||||
|
|
||||||
|
keyHole = NULL;
|
||||||
|
keyItem = NULL;
|
||||||
|
|
||||||
if (room == TR::NO_ROOM) {
|
if (room == TR::NO_ROOM) {
|
||||||
stand = STAND_AIR;
|
stand = STAND_AIR;
|
||||||
@@ -1866,7 +1874,9 @@ struct Lara : Character {
|
|||||||
}
|
}
|
||||||
|
|
||||||
keyHole = controller;
|
keyHole = controller;
|
||||||
game->invUse(camera->cameraIndex, usedKey);
|
|
||||||
|
if (game->invUse(camera->cameraIndex, usedKey))
|
||||||
|
keyItem = game->addEntity(usedKey, getRoomIndex(), pos, 0);
|
||||||
|
|
||||||
animation.setState(actionState);
|
animation.setState(actionState);
|
||||||
}
|
}
|
||||||
@@ -2755,11 +2765,24 @@ struct Lara : Character {
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case STATE_USE_KEY :
|
case STATE_USE_KEY :
|
||||||
case STATE_USE_PUZZLE : {
|
case STATE_USE_PUZZLE : {
|
||||||
if (keyHole && animation.isFrameActive(state == STATE_USE_PUZZLE ? PUZZLE_FRAME : KEY_FRAME)) {
|
if (keyHole) {
|
||||||
keyHole->activate();
|
if (animation.isFrameActive(state == STATE_USE_PUZZLE ? PUZZLE_FRAME : KEY_FRAME)) {
|
||||||
keyHole = NULL;
|
keyHole->activate();
|
||||||
|
if (keyItem) {
|
||||||
|
if (state == STATE_USE_KEY) {
|
||||||
|
mat4 &m = keyItem->matrix;
|
||||||
|
m = keyHole->getMatrix();
|
||||||
|
m.translate(vec3(0, -590, 484));
|
||||||
|
m.rotateX(PI * 0.5f);
|
||||||
|
} else
|
||||||
|
game->removeEntity(keyItem);
|
||||||
|
}
|
||||||
|
|
||||||
|
keyItem = NULL;
|
||||||
|
keyHole = NULL;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -2817,6 +2840,42 @@ struct Lara : Character {
|
|||||||
|
|
||||||
if (camera->mode != Camera::MODE_CUTSCENE && camera->mode != Camera::MODE_STATIC)
|
if (camera->mode != Camera::MODE_CUTSCENE && camera->mode != Camera::MODE_STATIC)
|
||||||
camera->mode = (emptyHands() || health <= 0.0f) ? Camera::MODE_FOLLOW : Camera::MODE_COMBAT;
|
camera->mode = (emptyHands() || health <= 0.0f) ? Camera::MODE_FOLLOW : Camera::MODE_COMBAT;
|
||||||
|
|
||||||
|
if (keyItem) {
|
||||||
|
keyItem->flags.invisible = animation.frameIndex < (state == STATE_USE_KEY ? 70 : 30);
|
||||||
|
keyItem->lockMatrix = true;
|
||||||
|
mat4 &m = keyItem->matrix;
|
||||||
|
Basis b;
|
||||||
|
|
||||||
|
if (state == STATE_USE_KEY) {
|
||||||
|
b = getJoint(10);
|
||||||
|
b.rot = b.rot * quat(vec3(0, 1, 0), PI * 0.5f);
|
||||||
|
b.translate(vec3(0, 120, 0));
|
||||||
|
} else {
|
||||||
|
vec3 rot(0.0f);
|
||||||
|
|
||||||
|
// TODO: hardcode item-hand alignment 8)
|
||||||
|
rot.x = -PI * 0.5f;
|
||||||
|
|
||||||
|
if (animation.frameIndex < 55)
|
||||||
|
b = getJoint(13);
|
||||||
|
else
|
||||||
|
b = getJoint(10);
|
||||||
|
|
||||||
|
b.translate(vec3(0, 48, 0));
|
||||||
|
|
||||||
|
if (rot.x != 0.0f) b.rot = b.rot * quat(vec3(1, 0, 0), rot.x);
|
||||||
|
if (rot.y != 0.0f) b.rot = b.rot * quat(vec3(0, 1, 0), rot.y);
|
||||||
|
if (rot.z != 0.0f) b.rot = b.rot * quat(vec3(0, 0, 1), rot.z);
|
||||||
|
}
|
||||||
|
|
||||||
|
keyItem->joints[0] = b;
|
||||||
|
|
||||||
|
m.identity();
|
||||||
|
m.setRot(b.rot);
|
||||||
|
m.setPos(b.pos);
|
||||||
|
//m = getMatrix();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void updateAnimation(bool commands) {
|
virtual void updateAnimation(bool commands) {
|
||||||
|
16
src/level.h
16
src/level.h
@@ -1444,16 +1444,8 @@ struct Level : IGame {
|
|||||||
void renderEntity(const TR::Entity &entity) {
|
void renderEntity(const TR::Entity &entity) {
|
||||||
//if (entity.room != lara->getRoomIndex()) return;
|
//if (entity.room != lara->getRoomIndex()) return;
|
||||||
if (Core::pass == Core::passShadow && !entity.castShadow()) return;
|
if (Core::pass == Core::passShadow && !entity.castShadow()) return;
|
||||||
bool isModel = entity.modelIndex > 0;
|
|
||||||
|
|
||||||
if (isModel) {
|
|
||||||
if (!mesh->models[entity.modelIndex - 1].geometry[mesh->transparent].count) return;
|
|
||||||
} else {
|
|
||||||
if (mesh->sequences[-(entity.modelIndex + 1)].transp != mesh->transparent) return;
|
|
||||||
}
|
|
||||||
|
|
||||||
Controller *controller = (Controller*)entity.controller;
|
Controller *controller = (Controller*)entity.controller;
|
||||||
|
|
||||||
int roomIndex = controller->getRoomIndex();
|
int roomIndex = controller->getRoomIndex();
|
||||||
TR::Room &room = level.rooms[roomIndex];
|
TR::Room &room = level.rooms[roomIndex];
|
||||||
|
|
||||||
@@ -1463,6 +1455,14 @@ struct Level : IGame {
|
|||||||
if (!entity.isLara() && !entity.isActor() && !room.flags.visible)
|
if (!entity.isLara() && !entity.isActor() && !room.flags.visible)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
bool isModel = entity.modelIndex > 0;
|
||||||
|
|
||||||
|
if (isModel) {
|
||||||
|
if (!mesh->models[controller->getModel()->index].geometry[mesh->transparent].count) return;
|
||||||
|
} else {
|
||||||
|
if (mesh->sequences[-(entity.modelIndex + 1)].transp != mesh->transparent) return;
|
||||||
|
}
|
||||||
|
|
||||||
float intensity = controller->intensity < 0.0f ? intensityf(room.ambient) : controller->intensity;
|
float intensity = controller->intensity < 0.0f ? intensityf(room.ambient) : controller->intensity;
|
||||||
|
|
||||||
Shader::Type type = isModel ? Shader::ENTITY : Shader::SPRITE;
|
Shader::Type type = isModel ? Shader::ENTITY : Shader::SPRITE;
|
||||||
|
@@ -1407,22 +1407,16 @@ struct KeyHole : Controller {
|
|||||||
virtual bool activate() {
|
virtual bool activate() {
|
||||||
if (!Controller::activate()) return false;
|
if (!Controller::activate()) return false;
|
||||||
flags.active = TR::ACTIVE;
|
flags.active = TR::ACTIVE;
|
||||||
swap();
|
|
||||||
deactivate();
|
deactivate();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void setSaveData(const TR::SaveGame::Entity &data) {
|
virtual const TR::Model* getModel() {
|
||||||
Controller::setSaveData(data);
|
if (getEntity().isPuzzleHole() && flags.active == TR::ACTIVE) {
|
||||||
if (flags.active == TR::ACTIVE)
|
|
||||||
swap();
|
|
||||||
}
|
|
||||||
|
|
||||||
void swap() {
|
|
||||||
if (getEntity().isPuzzleHole()) {
|
|
||||||
int doneIdx = TR::Entity::convToInv(TR::Entity::getItemForHole(getEntity().type)) - TR::Entity::INV_PUZZLE_1;
|
int doneIdx = TR::Entity::convToInv(TR::Entity::getItemForHole(getEntity().type)) - TR::Entity::INV_PUZZLE_1;
|
||||||
meshSwap(0, level->extra.puzzleDone[doneIdx]);
|
return &level->models[level->extra.puzzleDone[doneIdx]];
|
||||||
}
|
}
|
||||||
|
return Controller::getModel();
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void update() {}
|
virtual void update() {}
|
||||||
|
Reference in New Issue
Block a user