diff --git a/src/format.h b/src/format.h index 75b4172..6928fd2 100644 --- a/src/format.h +++ b/src/format.h @@ -634,6 +634,13 @@ namespace TR { return type >= DOOR_1 && type <= DOOR_6; } + bool isCollider() const { + return isEnemy() || + isDoor() || + (type == DRAWBRIDGE && flags.active != ACTIVE) || + (type == SCION_HOLDER); + } + bool isItem() const { return (type >= PISTOLS && type <= AMMO_UZIS) || (type >= PUZZLE_1 && type <= PUZZLE_4) || @@ -663,10 +670,10 @@ namespace TR { 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; + 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; } } @@ -2188,23 +2195,39 @@ namespace TR { switch (e.type) { case Entity::TRAP_DOOR_1 : - case Entity::TRAP_DOOR_2 : + case Entity::TRAP_DOOR_2 : { + int dirX, dirZ; + e.getAxis(dirX, dirZ); + + int ex = e.x / 1024; + int ez = e.z / 1024; + if ((ex == sx && ez == sz) || (ex + dirX == sx && ez + dirZ == sz)) { + if (e.y >= y - 128 && e.y < info.floor) + info.floor = e.y; + if (e.y < y - 128 && e.y > info.ceiling) + info.ceiling = e.y + 256; + } + break; + } 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); + int ey = e.y - 512; if (ey >= y - 128 && ey < info.floor) info.floor = ey; if (ey < y - 128 && ey > info.ceiling) - info.ceiling = ey + (e.type == Entity::TRAP_FLOOR ? 0 : 256); + info.ceiling = ey; 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 ex = e.x / 1024; + int ez = e.z / 1024; + + if ((ex - dirX * 1 == sx && ez - dirZ * 1 == sz) || + (ex - dirX * 2 == sx && ez - dirZ * 2 == sz)) { int ey = e.y; if (ey >= y - 128 && ey < info.floor) info.floor = ey; diff --git a/src/lara.h b/src/lara.h index 8408ff2..c4bfd9e 100644 --- a/src/lara.h +++ b/src/lara.h @@ -467,8 +467,8 @@ struct Lara : Character { //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 - //reset(50, vec3(53703, -18688, -13769), PI); // Level 10c (scion holder) - //reset(19, vec3(35364, -512, 40199), PI * 0.5f); // Level 10c (lave flow) + //reset(50, vec3(53703, -18688, 13769), PI); // Level 10c (scion holder) + //reset(19, vec3(35364, -512, 40199), PI * 0.5f); // Level 10c (lava flow) #endif chestOffset = animation.getJoints(getMatrix(), 7).pos; } @@ -2503,18 +2503,19 @@ struct Lara : Character { // check enemies & doors for (int i = 0; i < level->entitiesBaseCount; i++) { TR::Entity &e = level->entities[i]; + + if (!e.isCollider()) continue; + 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() && !(e.type == TR::Entity::DRAWBRIDGE && e.flags.active != TR::ACTIVE)) continue; - - TR::Entity &entity = getEntity(); + // fast distance check for object + 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); @@ -2536,7 +2537,7 @@ struct Lara : Character { if (e.type == TR::Entity::ENEMY_REX && ((Character*)controller)->health <= 0) return true; - if (e.isDoor() || e.type == TR::Entity::DRAWBRIDGE) + if (!e.isEnemy()) return true; if (canHitAnim()) {