1
0
mirror of https://github.com/XProger/OpenLara.git synced 2025-08-15 09:34:18 +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) { virtual void doCutscene(const vec3 &pos, float rotation) {
state = Camera::STATE_CUTSCENE; state = Camera::STATE_CUTSCENE;
level->cutMatrix.identity(); level->cutMatrix.identity();
level->cutMatrix.rotateY(angle.y); level->cutMatrix.rotateY(rotation);
level->cutMatrix.setPos(pos); level->cutMatrix.setPos(pos);
timer = 0.0f; timer = 0.0f;
} }
@@ -188,7 +188,7 @@ struct Camera : ICamera {
if (indexA == level->cameraFramesCount - 1) { if (indexA == level->cameraFramesCount - 1) {
if (level->cutEntity != -1) if (level->cutEntity != -1)
game->loadLevel(TR::LevelID(level->id + 1)); game->loadNextLevel();
else { else {
Character *lara = (Character*)game->getLara(); Character *lara = (Character*)game->getLara();
if (lara->health > 0.0f) if (lara->health > 0.0f)

View File

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

View File

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

View File

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