1
0
mirror of https://github.com/XProger/OpenLara.git synced 2025-08-13 08:34:32 +02:00

#8 fix camera targeting; #22 add drawbridge controller, fix items brightness; fix slide bug (for negative velocity.y)

This commit is contained in:
XProger
2017-09-20 01:40:04 +03:00
parent e9caade9c1
commit 261a86e9c0
5 changed files with 112 additions and 37 deletions

View File

@@ -113,10 +113,13 @@ struct Camera : ICamera {
this->viewIndex = viewIndex;
this->timer = timer;
this->speed = speed;
lastDest = pos;
lastDest = destPos;
if (viewIndex > -1)
room = level->cameras[viewIndex].room;
if (viewIndex > -1) {
TR::Camera &cam = level->cameras[viewIndex];
room = cam.room;
pos = vec3(float(cam.x), float(cam.y), float(cam.z));
}
}
vec3 getViewPoint() {
@@ -129,6 +132,9 @@ struct Camera : ICamera {
}
void resetTarget(const vec3 &viewPoint) {
if (state == STATE_STATIC)
pos = destPos = lastDest;
timer = -1.0f;
state = STATE_FOLLOW;
viewTarget = NULL;

View File

@@ -52,7 +52,7 @@
E( TRAP_BOULDER ) \
E( TRAP_DART ) \
E( TRAP_DARTGUN ) \
E( DOOR_LIFT ) \
E( DRAWBRIDGE ) \
E( TRAP_SLAM ) \
E( TRAP_SWORD ) \
E( HAMMER_HANDLE ) \
@@ -232,7 +232,7 @@ namespace TR {
EARTHQUAKE ,
FLOOD ,
UNK1 ,
UNK2 ,
STAIRS2SLOPE ,
UNK3 ,
UNK4 ,
EXPLOSION ,
@@ -277,6 +277,7 @@ namespace TR {
SND_INV_PAGE = 115,
SND_HEALTH = 116,
SND_EFFECT_8 = 119,
SND_DART = 151,
SND_SECRET = 173,
@@ -629,7 +630,7 @@ namespace TR {
}
bool isDoor() const {
return (type >= DOOR_1 && type <= DOOR_6) || type == DOOR_LIFT;
return type >= DOOR_1 && type <= DOOR_6;
}
bool isItem() const {
@@ -659,6 +660,16 @@ namespace TR {
return isLara() || isEnemy() || isActor();
}
void getAxis(int &dx, int &dz) {
switch (rotation.value / 0x4000) {
case 0 : dx = 0; dz = -1; break;
case 1 : dx = -1; dz = 0; break;
case 2 : dx = 0, dz = 1; break;
case 3 : dx = 1, dz = 0; break;
default : dx = 0; dz = 0; break;
}
}
static Type convToInv(Type type) {
switch (type) {
case PISTOLS : return INV_PISTOLS;
@@ -2174,12 +2185,12 @@ namespace TR {
Entity &e = entities[cmd.args];
if (!e.flags.collision) continue;
if (sx != e.x / 1024 || sz != e.z / 1024) continue;
switch (e.type) {
case Entity::TRAP_DOOR_1 :
case Entity::TRAP_DOOR_2 :
case Entity::TRAP_FLOOR : {
if (sx != e.x / 1024 || sz != e.z / 1024)
break;
int ey = e.y - (e.type == Entity::TRAP_FLOOR ? 512 : 0);
if (ey >= y - 128 && ey < info.floor)
info.floor = ey;
@@ -2187,9 +2198,26 @@ namespace TR {
info.ceiling = ey + (e.type == Entity::TRAP_FLOOR ? 0 : 256);
break;
}
case Entity::DRAWBRIDGE : {
if (e.flags.active != TR::ACTIVE) continue;
int dirX, dirZ;
e.getAxis(dirX, dirZ);
if ((e.x / 1024 + dirX * 1 == sx && e.z / 1024 + dirZ * 1 == sz) ||
(e.x / 1024 + dirX * 2 == sx && e.z / 1024 + dirZ * 2 == sz)) {
int ey = e.y;
if (ey >= y - 128 && ey < info.floor)
info.floor = ey;
if (ey < y - 128 && ey > info.ceiling)
info.ceiling = ey + 256;
}
break;
}
case Entity::BRIDGE_0 :
case Entity::BRIDGE_1 :
case Entity::BRIDGE_2 : {
if (sx != e.x / 1024 || sz != e.z / 1024)
break;
int s = (e.type == Entity::BRIDGE_1) ? 1 :
(e.type == Entity::BRIDGE_2) ? 2 : 0;

View File

@@ -460,6 +460,8 @@ struct Lara : Character {
//reset(5, vec3(73394, 3840, 60758), 0); // level 3b (scion)
//reset(20, vec3(57724, 6656, 61941), 90 * DEG2RAD); // level 3b (boulder)
//reset(99, vec3(45562, -3328, 63366), 225 * DEG2RAD); // level 7a (flipmap)
//reset(57, vec3(54844, -3328, 53145), 0); // level 8b (bridge switch)
//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
#endif
@@ -1639,6 +1641,10 @@ struct Lara : Character {
bool needFlip = false;
TR::Effect effect = TR::Effect::NONE;
int cameraIndex = -1;
Controller *cameraTarget = NULL;
Camera *camera = (Camera*)level->cameraController;
while (cmdIndex < info.trigCmdCount) {
TR::FloorData::TriggerCommand &cmd = info.trigCmd[cmdIndex++];
@@ -1667,8 +1673,6 @@ struct Lara : Character {
break;
}
case TR::Action::CAMERA_SWITCH : {
Camera *camera = (Camera*)level->cameraController;
TR::FloorData::TriggerCommand &cam = info.trigCmd[cmdIndex++];
if (level->cameras[cmd.args].flags.once)
break;
@@ -1678,11 +1682,14 @@ struct Lara : Character {
if (info.trigger == TR::Level::Trigger::SWITCH && info.trigInfo.timer && switchIsDown)
break;
{//if (info.trigger == TR::Level::Trigger::SWITCH || cmd.args != camera->viewIndexLast) {
if (info.trigger == TR::Level::Trigger::SWITCH || cmd.args != camera->viewIndexLast) {
level->cameras[cmd.args].flags.once |= cam.once;
camera->setView(cmd.args, cam.timer == 1 ? EPS : float(cam.timer), cam.speed * 8.0f);
}
if (cmd.args == camera->viewIndexLast)
cameraIndex = cmd.args;
break;
}
case TR::Action::FLOW :
@@ -1715,7 +1722,7 @@ struct Lara : Character {
needFlip = true;
break;
case TR::Action::CAMERA_TARGET :
((Camera*)level->cameraController)->viewTarget = (Controller*)level->entities[cmd.args].controller;
cameraTarget = (Controller*)level->entities[cmd.args].controller;
break;
case TR::Action::END :
game->loadLevel(level->id == TR::LEVEL_10C ? TR::TITLE : TR::LevelID(level->id + 1));
@@ -1759,6 +1766,12 @@ struct Lara : Character {
}
}
if (cameraTarget && (camera->state == Camera::STATE_STATIC || cameraIndex == -1))
camera->viewTarget = cameraTarget;
if (!cameraTarget && cameraIndex > -1)
camera->viewIndex = cameraIndex;
if (needFlip) {
level->isFlipped = !level->isFlipped;
game->setEffect(effect, 0);
@@ -1799,7 +1812,7 @@ struct Lara : Character {
TR::Level::FloorInfo info;
level->getFloorInfo(e.room, e.x, e.y, e.z, info);
if (stand == STAND_SLIDE || (stand == STAND_AIR && velocity.y > 0) || stand == STAND_GROUND) {
if (stand == STAND_SLIDE || stand == STAND_AIR || stand == STAND_GROUND) {
if (e.y + 8 >= info.floor && (abs(info.slantX) > 2 || abs(info.slantZ) > 2)) {
if (stand == STAND_AIR)
playSound(TR::SND_LANDING, pos, Sound::Flags::PAN);
@@ -2444,7 +2457,7 @@ struct Lara : Character {
collisionOffset = vec3(0.0f);
if (checkCollisions() || (velocity + collisionOffset).length2() >= 1.0f)
if (checkCollisions() || (velocity + collisionOffset).length2() >= 1.0f) // TODO: stop & smash anim
move();
if (getEntity().type != TR::Entity::LARA) {
@@ -2482,25 +2495,27 @@ struct Lara : Character {
collisionOffset += meshBox.pushOut2D(box);
}
if (!canHitAnim()) {
hitDir = -1;
return false;
}
// check enemies & doors
Controller *controller = Controller::first;
do {
TR::Entity &e = controller->getEntity();
for (int i = 0; i < level->entitiesBaseCount; i++) {
TR::Entity &e = level->entities[i];
Controller *controller = (Controller*)e.controller;
if (e.isEnemy()) {
if (e.type != TR::Entity::ENEMY_REX && (!e.flags.active || ((Character*)controller)->health <= 0)) continue;
} else
if (!e.isDoor()) continue;
} else {
if (!e.isDoor() && !(e.type == TR::Entity::DRAWBRIDGE && e.flags.active != TR::ACTIVE)) continue;
TR::Entity &entity = getEntity();
if (abs(entity.x - e.x) > 1024 || abs(entity.z - e.z) > 1024 || abs(entity.y - e.y) > 2048) continue;
}
vec3 dir = pos - vec3(0.0f, 128.0f, 0.0f) - controller->pos;
vec3 p = dir.rotateY(controller->angle.y);
Box box = controller->getBoundingBoxLocal();
box.expand(vec3(LARA_RADIUS, 0.0f, LARA_RADIUS));
if (!box.contains(p))
continue;
@@ -2516,9 +2531,10 @@ struct Lara : Character {
if (e.type == TR::Entity::ENEMY_REX && ((Character*)controller)->health <= 0)
return true;
if (e.isDoor())
if (e.isDoor() || e.type == TR::Entity::DRAWBRIDGE)
return true;
if (canHitAnim()) {
// get hit dir
if (hitDir == -1) {
if (health > 0)
@@ -2528,7 +2544,8 @@ struct Lara : Character {
hitDir = angleQuadrant(dir.rotateY(angle.y + PI * 0.5f).angleY());
return true;
} while ((controller = controller->next));
}
};
hitDir = -1;
return false;

View File

@@ -205,6 +205,10 @@ struct Level : IGame {
sample->setVolume(0.0f, 4.0f);
}
if (effect == TR::Effect::STAIRS2SLOPE) {
playSound(TR::SND_EFFECT_8, vec3(), 0);
}
this->effect = effect;
this->effectTimer = 0.0f;
}
@@ -393,6 +397,9 @@ struct Level : IGame {
case TR::Entity::TRAP_DARTGUN :
entity.controller = new TrapDartgun(this, i);
break;
case TR::Entity::DRAWBRIDGE :
entity.controller = new Drawbridge(this, i);
break;
case TR::Entity::BLOCK_1 :
case TR::Entity::BLOCK_2 :
case TR::Entity::BLOCK_3 :
@@ -873,8 +880,9 @@ struct Level : IGame {
type = Shader::MIRROR;
if (type == Shader::SPRITE) {
float alpha = (entity.type == TR::Entity::SMOKE || entity.type == TR::Entity::WATER_SPLASH) ? 0.75f : 1.0f;
setRoomParams(roomIndex, type, 0.5f, intensityf(lum), controller->specular, alpha, isModel ? !mesh->models[entity.modelIndex - 1].opaque : true);
float alpha = (entity.type == TR::Entity::SMOKE || entity.type == TR::Entity::WATER_SPLASH) ? 0.75f : 1.0;
float diffuse = entity.isItem() ? 1.0f : 0.5f;
setRoomParams(roomIndex, type, diffuse, intensityf(lum), controller->specular, alpha, isModel ? !mesh->models[entity.modelIndex - 1].opaque : true);
} else
setRoomParams(roomIndex, type, 1.0f, intensityf(lum), controller->specular, 1.0f, isModel ? !mesh->models[entity.modelIndex - 1].opaque : true);

View File

@@ -498,6 +498,22 @@ struct Bridge : Controller {
}
};
struct Drawbridge : Controller {
enum {
STATE_UP,
STATE_DOWN,
};
Drawbridge(IGame *game, int entity) : Controller(game, entity) {
getEntity().flags.collision = true;
}
virtual void update() {
updateAnimation(true);
animation.setState(isActive() ? STATE_DOWN : STATE_UP);
}
};
struct Crystal : Controller {
Texture *environment;