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

#14 fix disable hit animation and offsets for some states; #4 collisions for enemies and static geometry

This commit is contained in:
XProger
2017-05-10 04:20:03 +03:00
parent 42dc19bb39
commit 7c4f48f378
6 changed files with 91 additions and 21 deletions

View File

@@ -458,10 +458,8 @@ namespace Debug {
TR::Room &r = level.rooms[i];
for (int j = 0; j < r.meshesCount; j++) {
TR::Room::Mesh &m = r.meshes[j];
TR::StaticMesh *sm = level.getMeshByID(m.meshID);
ASSERT(sm != NULL);
TR::Room::Mesh &m = r.meshes[j];
TR::StaticMesh *sm = &level.staticMeshes[m.meshIndex];
Box box;
vec3 offset = vec3(m.x, m.y, m.z);

View File

@@ -148,10 +148,7 @@ struct Enemy : Character {
TR::Level::FloorInfo info;
level->getFloorInfo(getRoomIndex(), (int)pos.x, (int)pos.y, (int)pos.z, info);
int dx, dz;
TR::Room::Sector &s = level->getSector(info.roomNext != TR::NO_ROOM ? info.roomNext : getRoomIndex(), int(pos.x), int(pos.z), dx, dz);
if (s.boxIndex != 0xFFFF && zone == getZones()[s.boxIndex]) {
if (info.boxIndex != 0xFFFF && zone == getZones()[info.boxIndex] && !level->boxes[info.boxIndex].overlap.block) {
switch (stand) {
case STAND_GROUND : {
float fallSpeed = 2048.0f * Core::deltaTime;
@@ -410,6 +407,9 @@ struct Enemy : Character {
TR::Box &b = game->getLevel()->boxes[box];
TR::Entity::Type type = e.type;
if (b.overlap.block)
return false;
if (type == TR::Entity::ENEMY_REX || type == TR::Entity::ENEMY_MUTANT_1 || type == TR::Entity::ENEMY_CENTAUR) {
if (b.overlap.blockable)
return false;

View File

@@ -292,7 +292,7 @@ namespace TR {
angle rotation;
int16 intensity;
uint16 meshID;
uint16 align; // PSX
uint16 meshIndex; // index into static meshes array
} *meshes;
};
@@ -983,8 +983,17 @@ namespace TR {
// meshes
stream.read(r.meshesCount);
r.meshes = r.meshesCount ? new Room::Mesh[r.meshesCount] : NULL;
for (int i = 0; i < r.meshesCount; i++)
stream.raw(&r.meshes[i], sizeof(r.meshes[i]) - (version == VER_TR1_PC ? sizeof(r.meshes[i].align) : 0));
for (int i = 0; i < r.meshesCount; i++) {
Room::Mesh &m = r.meshes[i];
stream.read(m.x);
stream.read(m.y);
stream.read(m.z);
stream.read(m.rotation);
stream.read(m.intensity);
stream.read(m.meshID);
if (version == VER_TR1_PSX)
stream.read(m.meshIndex); // just an align for PSX version
}
// misc flags
stream.read(r.alternateRoom);
stream.read(r.flags);
@@ -1068,6 +1077,7 @@ namespace TR {
stream.read(cameraFrames, stream.read(cameraFramesCount));
}
initRoomMeshes();
initTiles(tiles4, tiles8, palette, cluts);
//delete[] tiles4; tiles4 = NULL;
@@ -1447,6 +1457,14 @@ namespace TR {
spriteSequences[i].sCount = -spriteSequences[i].sCount;
}
void initRoomMeshes() {
for (int i = 0; i < roomsCount; i++) {
Room &room = rooms[i];
for (int j = 0; j < room.meshesCount; j++)
room.meshes[j].meshIndex = getMeshByID(room.meshes[j].meshID);
}
}
void initTiles(Tile4 *tiles4, Tile8 *tiles8, Color24 *palette, CLUT *cluts) {
tiles = new Tile32[tilesCount];
@@ -1542,11 +1560,12 @@ namespace TR {
return new Stream(data, size);
}
StaticMesh* getMeshByID(int id) const { // TODO: map this
int getMeshByID(int id) const {
for (int i = 0; i < staticMeshesCount; i++)
if (staticMeshes[i].id == id)
return &staticMeshes[i];
return NULL;
return i;
ASSERT(false);
return 0;
}
int16 getModelIndex(Entity::Type type) const {

View File

@@ -621,6 +621,19 @@ struct Lara : Character {
&& state != STATE_WATER_OUT;
}
bool canHitAnim() {
return state == STATE_WALK
|| state == STATE_RUN
|| state == STATE_STOP
|| state == STATE_FAST_BACK
|| state == STATE_TURN_RIGHT
|| state == STATE_TURN_LEFT
|| state == STATE_BACK
|| state == STATE_FAST_TURN
|| state == STATE_STEP_RIGHT
|| state == STATE_STEP_LEFT;
}
bool wpnReady() {
return arms[0].anim != Weapon::Anim::PREPARE && arms[0].anim != Weapon::Anim::UNHOLSTER && arms[0].anim != Weapon::Anim::HOLSTER;
}
@@ -1526,7 +1539,7 @@ struct Lara : Character {
if (state == STATE_PUSH_PULL_READY && (input & (FORTH | BACK))) {
int pushState = (input & FORTH) ? STATE_PUSH_BLOCK : STATE_PULL_BLOCK;
Block *block = getBlock();
if (animation.canSetState(pushState) && block->doMove((input & FORTH) != 0)) {
if (block && animation.canSetState(pushState) && block->doMove((input & FORTH) != 0)) {
alignToWall(-LARA_RADIUS);
return pushState;
}
@@ -1921,7 +1934,23 @@ struct Lara : Character {
}
void checkCollisions() {
if (state == STATE_DEATH || stand != STAND_GROUND) {
// check static objects (TODO: check linked rooms?)
TR::Room &room = getRoom();
Box box(pos - vec3(LARA_RADIUS, LARA_HEIGHT, LARA_RADIUS), pos + vec3(LARA_RADIUS, 0.0f, LARA_RADIUS));
for (int i = 0; i < room.meshesCount; i++) {
TR::Room::Mesh &m = room.meshes[i];
TR::StaticMesh &sm = level->staticMeshes[m.meshIndex];
if (sm.flags != 2) continue;
Box meshBox;
sm.getBox(true, m.rotation, meshBox);
meshBox.translate(vec3(float(m.x), float(m.y), float(m.z)));
if (!box.intersect(meshBox)) continue;
collisionOffset += meshBox.pushOut2D(box);
}
if (!canHitAnim()) {
hitDir = -1;
return;
}
@@ -1941,7 +1970,7 @@ struct Lara : Character {
continue;
// get shift
p = enemyBox.closestPoint2D(p);
p += enemyBox.pushOut2D(p);
p = (p.rotateY(enemy->angle.y) + enemy->pos) - pos;
collisionOffset += vec3(p.x, 0.0f, p.z);

View File

@@ -201,7 +201,7 @@ struct MeshBuilder {
for (int j = 0; j < r.meshesCount; j++) {
TR::Room::Mesh &m = r.meshes[j];
TR::StaticMesh *s = level.getMeshByID(m.meshID);
TR::StaticMesh *s = &level.staticMeshes[m.meshIndex];
if (!level.meshOffsets[s->mesh]) continue;
TR::Mesh &mesh = level.meshes[level.meshOffsets[s->mesh]];
@@ -310,7 +310,7 @@ struct MeshBuilder {
// static meshes
for (int j = 0; j < room.meshesCount; j++) {
TR::Room::Mesh &m = room.meshes[j];
TR::StaticMesh *s = level.getMeshByID(m.meshID);
TR::StaticMesh *s = &level.staticMeshes[m.meshIndex];
if (!level.meshOffsets[s->mesh]) continue;
TR::Mesh &mesh = level.meshes[level.meshOffsets[s->mesh]];

View File

@@ -808,17 +808,41 @@ struct Box {
}
}
void translate(const vec3 &offset) {
min += offset;
max += offset;
}
bool contains(const vec3 &v) const {
return v.x >= min.x && v.x <= max.x && v.y >= min.y && v.y <= max.x && v.z >= min.z && v.z <= max.z;
}
vec3 closestPoint2D(const vec3 &v) const {
vec3 pushOut2D(const vec3 &v) const {
float ax = v.x - min.x;
float bx = max.x - v.x;
float az = v.z - min.z;
float bz = max.z - v.z;
vec3 p = v;
vec3 p = vec3(0.0f);
if (ax <= bx && ax <= az && ax <= bz)
p.x = -ax;
else if (bx <= ax && bx <= az && bx <= bz)
p.x = bx;
else if (az <= ax && az <= bx && az <= bz)
p.z = -az;
else
p.z = bz;
return p;
}
vec3 pushOut2D(const Box &b) const {
float ax = b.max.x - min.x;
float bx = max.x - b.min.x;
float az = b.max.z - min.z;
float bz = max.z - b.min.z;
vec3 p = vec3(0.0f);
if (ax <= bx && ax <= az && ax <= bz)
p.x -= ax;
else if (bx <= ax && bx <= az && bx <= bz)