1
0
mirror of https://github.com/XProger/OpenLara.git synced 2025-08-14 17:14:29 +02:00

#22 add scion holder pickup (end of LEVEL10B)

This commit is contained in:
XProger
2017-10-20 01:06:02 +03:00
parent 4c8299b803
commit adcc86e412
4 changed files with 41 additions and 24 deletions

View File

@@ -148,7 +148,7 @@ struct Camera : ICamera {
virtual void doCutscene(const vec3 &pos, float rotation) {
state = Camera::STATE_CUTSCENE;
level->cutMatrix.identity();
level->cutMatrix.rotateY(angle.y);
level->cutMatrix.rotateY(rotation);
level->cutMatrix.setPos(pos);
timer = 0.0f;
}
@@ -188,7 +188,7 @@ struct Camera : ICamera {
if (indexA == level->cameraFramesCount - 1) {
if (level->cutEntity != -1)
game->loadLevel(TR::LevelID(level->id + 1));
game->loadNextLevel();
else {
Character *lara = (Character*)game->getLara();
if (lara->health > 0.0f)

View File

@@ -1239,7 +1239,7 @@ struct Mummy : Enemy {
struct Doppelganger : Enemy {
enum {
ANIM_FALL = 32,
ANIM_FALL = 34,
};
Doppelganger(IGame *game, int entity) : Enemy(game, entity, 1000, 341, 150.0f, 0.0f) {
@@ -1401,9 +1401,9 @@ struct Pierre : Human {
virtual void onDead() {
if (level->id == TR::LEVEL_7B) {
game->addEntity(TR::Entity::MAGNUMS, getRoomIndex(), pos, 0);
game->addEntity(TR::Entity::SCION_DROP, getRoomIndex(), pos, 0);
game->addEntity(TR::Entity::KEY_ITEM_1, getRoomIndex(), pos, 0);
game->addEntity(TR::Entity::MAGNUMS, getRoomIndex(), pos, 0);
game->addEntity(TR::Entity::SCION_PICKUP_DROP, getRoomIndex(), pos, 0);
game->addEntity(TR::Entity::KEY_ITEM_1, getRoomIndex(), pos, 0);
}
}
};

View File

@@ -154,10 +154,10 @@
E( KEY_HOLE_4 ) \
E( UNUSED_4 ) \
E( UNUSED_5 ) \
E( SCION_QUALOPEC ) \
E( SCION_DROP ) \
E( SCION_PICKUP_QUALOPEC ) \
E( SCION_PICKUP_DROP ) \
E( SCION_TARGET ) \
E( SCION_NATLA ) \
E( SCION_PICKUP_HOLDER ) \
E( SCION_HOLDER ) \
E( UNUSED_6 ) \
E( UNUSED_7 ) \
@@ -402,6 +402,10 @@ namespace TR {
Limit SCION = {
640, -202, 30, {{-256, 540, -350}, {256, 740, -200}}, false, false
};
Limit SCION_HOLDER = {
640, -202, 10, {{-256, 206, -862}, {256, 306, -200}}, true, false
};
}
struct fixed {
@@ -672,10 +676,8 @@ namespace TR {
return isEnemy() ||
isDoor() ||
(type == DRAWBRIDGE && flags.active != ACTIVE) ||
(type == SCION_HOLDER) ||
((type == HAMMER_HANDLE || type == HAMMER_BLOCK) && flags.collision) ||
(type == CRYSTAL) ||
(type == MOVING_OBJECT);
type == CRYSTAL || type == MOVING_OBJECT || type == SCION_HOLDER;
}
bool isPickup() const {
@@ -683,7 +685,7 @@ namespace TR {
(type >= PUZZLE_1 && type <= PUZZLE_4) ||
(type >= KEY_ITEM_1 && type <= KEY_ITEM_4) ||
(type == MEDIKIT_SMALL || type == MEDIKIT_BIG) ||
(type == SCION_QUALOPEC || type == SCION_DROP || type == SCION_NATLA || type == LEADBAR); // TODO: recheck all items
(type == SCION_PICKUP_QUALOPEC || type == SCION_PICKUP_DROP || type == SCION_PICKUP_HOLDER || type == LEADBAR); // TODO: recheck all items
}
bool isActor() const {

View File

@@ -482,6 +482,7 @@ struct Lara : Character {
//reset(44, vec3(75803, -11008, 21097), 90 * DEG2RAD); // Level 10a (boat)
//reset(47, vec3(50546, -13056, 53783), 270 * DEG2RAD); // Level 10b (trap door slope)
//reset(59, vec3(42907, -13056, 63012), 270 * DEG2RAD); // Level 10b (doppelganger)
//reset(50, vec3(52122, -18688, 47313), 150 * DEG2RAD); // Level 10b (scion holder pickup)
//reset(50, vec3(53703, -18688, 13769), PI); // Level 10c (scion holder)
//reset(19, vec3(35364, -512, 40199), PI * 0.5f); // Level 10c (lava flow)
//reset(9, vec3(69074, -14592, 25192), 0); // Level 10c (trap slam)
@@ -1570,11 +1571,6 @@ struct Lara : Character {
Controller *controller = (Controller*)entity.controller;
// set item orientation to hack limits check
if (stand == STAND_UNDERWATER)
controller->angle.x = -25 * DEG2RAD;
controller->angle.y = angle.y;
if (controller->getRoomIndex() != room || entity.flags.invisible || !canPickup(controller))
continue;
@@ -1596,7 +1592,8 @@ struct Lara : Character {
// get limits
TR::Limits::Limit *limit;
switch (entity.type) {
case TR::Entity::SCION_QUALOPEC : limit = &TR::Limits::SCION; break;
case TR::Entity::SCION_PICKUP_QUALOPEC : limit = &TR::Limits::SCION; break;
case TR::Entity::SCION_PICKUP_HOLDER : limit = &TR::Limits::SCION_HOLDER; break;
default : limit = level->rooms[getRoomIndex()].flags.water ? &TR::Limits::PICKUP_UNDERWATER : &TR::Limits::PICKUP;
}
@@ -1608,10 +1605,18 @@ struct Lara : Character {
// set new state
switch (entity.type) {
case TR::Entity::SCION_QUALOPEC :
case TR::Entity::SCION_PICKUP_QUALOPEC :
animation.setAnim(level->models[TR::MODEL_LARA_SPEC].animation);
game->getCamera()->doCutscene(pos, angle.y);
break;
case TR::Entity::SCION_PICKUP_HOLDER :
animation.setAnim(level->models[TR::MODEL_LARA_SPEC].animation);
angle = controller->angle;
pos = controller->pos - vec3(0, -280, LARA_RADIUS + 512).rotateY(angle.y);
game->getCamera()->doCutscene(pos, angle.y - PI * 0.5f);
break;
default : ;
}
@@ -1656,11 +1661,18 @@ struct Lara : Character {
vec3 deltaAbs = pos - targetPos;
vec3 deltaRel = (controller->getMatrix().transpose() * vec4(pos - controller->pos, 0.0f)).xyz; // inverse transform
// set item orientation to hack limits check
vec3 ctrlAngle = controller->angle;
if (stand == STAND_UNDERWATER)
ctrlAngle.x = -25 * DEG2RAD;
if (!limit->alignAngle)
ctrlAngle.y = angle.y;
if (limit->box.contains(deltaRel)) {
float deltaAngY = shortAngle(angle.y, controller->angle.y);
float deltaAngY = shortAngle(angle.y, ctrlAngle.y);
if (stand == STAND_UNDERWATER) {
float deltaAngX = shortAngle(angle.x, controller->angle.x);
float deltaAngX = shortAngle(angle.x, ctrlAngle.x);
if (deltaAbs.length() > 64.0f || max(fabs(deltaAngX), fabs(deltaAngY)) > (10.0f * DEG2RAD)) {
pos -= deltaAbs.normal() * min(deltaAbs.length(), Core::deltaTime * 512.0f);
@@ -2469,6 +2481,8 @@ struct Lara : Character {
int pickupFrame = stand == STAND_GROUND ? PICKUP_FRAME_GROUND : PICKUP_FRAME_UNDERWATER;
if (animation.isFrameActive(pickupFrame)) {
for (int i = 0; i < pickupListCount; i++) {
if (pickupList[i]->type == TR::Entity::SCION_PICKUP_HOLDER)
continue;
pickupList[i]->flags.invisible = true;
game->invAdd(pickupList[i]->type, 1);
}
@@ -2719,7 +2733,7 @@ struct Lara : Character {
} else {
// fast distance check for object
TR::Entity &entity = getEntity();
if (e.type != TR::Entity::HAMMER_HANDLE && e.type != TR::Entity::HAMMER_BLOCK)
if (e.type != TR::Entity::HAMMER_HANDLE && e.type != TR::Entity::HAMMER_BLOCK && e.type != TR::Entity::SCION_HOLDER)
if (abs(entity.x - e.x) > 1024 || abs(entity.z - e.z) > 1024 || abs(entity.y - e.y) > 2048) continue;
}
@@ -2727,7 +2741,8 @@ struct Lara : Character {
vec3 p = dir.rotateY(controller->angle.y);
Box box = controller->getBoundingBoxLocal();
box.expand(vec3(LARA_RADIUS, 0.0f, LARA_RADIUS));
box.expand(vec3(LARA_RADIUS + 50.0f, 0.0f, LARA_RADIUS + 50.0f));
box.max.y += 768;
if (!box.contains(p)) // TODO: Box vs Box or check Lara's head point? (check thor hammer handle)
continue;