mirror of
https://github.com/XProger/OpenLara.git
synced 2025-02-24 07:22:58 +01:00
#3 fix hang reach state; add hang swing animation
This commit is contained in:
parent
c2aac325b7
commit
f7b8568e44
@ -14,7 +14,7 @@ struct Collision {
|
||||
|
||||
Collision() : side(NONE) {}
|
||||
|
||||
Collision(TR::Level *level, int room, vec3 &pos, const vec3 &offset, const vec3 &velocity, float radius, float angle, int minHeight, int maxHeight, int maxAscent, int maxDescent) {
|
||||
Collision(TR::Level *level, int roomIndex, vec3 &pos, const vec3 &offset, const vec3 &velocity, float radius, float angle, int minHeight, int maxHeight, int maxAscent, int maxDescent) {
|
||||
if (velocity.x > 0.0f || velocity.z > 0.0f)
|
||||
angle = normalizeAngle(PI2 + vec2(velocity.z, velocity.x).angle());
|
||||
pos += velocity;
|
||||
@ -38,7 +38,9 @@ struct Collision {
|
||||
|
||||
int height = maxHeight - minHeight;
|
||||
|
||||
if (checkHeight(level, room, hpos, vec2(0.0f), height, 0xFFFFFF, 0xFFFFFF, side = NONE)) {
|
||||
getFloor(level, roomIndex, vec3(pos.x, hpos.y, pos.z));
|
||||
|
||||
if (checkHeight(level, roomIndex, hpos, vec2(0.0f), height, 0xFFFFFF, 0xFFFFFF, side = NONE)) {
|
||||
pos -= velocity;
|
||||
side = FRONT;
|
||||
return;
|
||||
@ -54,13 +56,13 @@ struct Collision {
|
||||
side = BOTTOM;
|
||||
}
|
||||
|
||||
if (checkHeight(level, room, hpos, f, height, maxAscent, maxDescent, FRONT)) {
|
||||
if (checkHeight(level, roomIndex, hpos, f, height, maxAscent, maxDescent, FRONT)) {
|
||||
d = vec2(-velocity.x, -velocity.z);
|
||||
q ^= 1;
|
||||
d[q] = getOffset(p[q] + f[q], p[q]);
|
||||
} else if (checkHeight(level, room, hpos, l, height, maxAscent, maxDescent, LEFT)) {
|
||||
} else if (checkHeight(level, roomIndex, hpos, l, height, maxAscent, maxDescent, LEFT)) {
|
||||
d[q] = getOffset(p[q] + l[q], p[q] + f[q]);
|
||||
} else if (checkHeight(level, room, hpos, r, height, maxAscent, maxDescent, RIGHT)) {
|
||||
} else if (checkHeight(level, roomIndex, hpos, r, height, maxAscent, maxDescent, RIGHT)) {
|
||||
d[q] = getOffset(p[q] + r[q], p[q] + f[q]);
|
||||
} else
|
||||
return;
|
||||
@ -68,13 +70,13 @@ struct Collision {
|
||||
pos += vec3(d.x, 0.0f, d.y);
|
||||
}
|
||||
|
||||
inline bool checkHeight(TR::Level *level, int room, const vec3 &pos, const vec2 &offset, int height, int maxAscent, int maxDescent, Side side) {
|
||||
inline bool checkHeight(TR::Level *level, int roomIndex, const vec3 &pos, const vec2 &offset, int height, int maxAscent, int maxDescent, Side side) {
|
||||
TR::Level::FloorInfo info;
|
||||
int py = int(pos.y);
|
||||
level->getFloorInfo(room, int(pos.x + offset.x), py, int(pos.z + offset.y), info);
|
||||
level->getFloorInfo(roomIndex, int(pos.x + offset.x), py, int(pos.z + offset.y), info);
|
||||
|
||||
Info &inf = this->info[side];
|
||||
inf.room = info.roomNext != TR::NO_ROOM ? info.roomNext : room;
|
||||
inf.room = info.roomNext != TR::NO_ROOM ? info.roomNext : roomIndex;
|
||||
inf.roomAbove = info.roomAbove;
|
||||
inf.roomBelow = info.roomBelow;
|
||||
inf.floor = info.floor;
|
||||
@ -99,6 +101,18 @@ struct Collision {
|
||||
return -from + 1025.0f;
|
||||
return -from - 1.0f;
|
||||
}
|
||||
|
||||
static int getFloor(TR::Level *level, int &roomIndex, const vec3 &pos) {
|
||||
int dx, dz, x = int(pos.x), z = int(pos.z);
|
||||
|
||||
TR::Room::Sector *s = &level->getSector(roomIndex, x, z, dx, dz);
|
||||
while (s->ceiling * 256 > pos.y && s->roomAbove != TR::NO_ROOM) {
|
||||
roomIndex = s->roomAbove;
|
||||
s = &level->getSector(roomIndex, x, z, dx, dz);
|
||||
}
|
||||
|
||||
return s->floor * 256;
|
||||
}
|
||||
};
|
||||
|
||||
#endif
|
12
src/format.h
12
src/format.h
@ -1572,7 +1572,7 @@ namespace TR {
|
||||
info.ceiling = info.roomCeiling;
|
||||
info.slantX = 0;
|
||||
info.slantZ = 0;
|
||||
info.roomNext = 0xFF;
|
||||
info.roomNext = NO_ROOM;
|
||||
info.roomBelow = s.roomBelow;
|
||||
info.roomAbove = s.roomAbove;
|
||||
info.floorIndex = s.floorIndex;
|
||||
@ -1581,16 +1581,17 @@ namespace TR {
|
||||
info.trigCmdCount = 0;
|
||||
|
||||
if (s.floor == -127)
|
||||
return;
|
||||
return;
|
||||
|
||||
Room::Sector *sBelow = &s;
|
||||
while (sBelow->roomBelow != TR::NO_ROOM) sBelow = &getSector(sBelow->roomBelow, x, z, dx, dz);
|
||||
while (sBelow->roomBelow != NO_ROOM) sBelow = &getSector(sBelow->roomBelow, x, z, dx, dz);
|
||||
info.floor = 256 * sBelow->floor;
|
||||
|
||||
parseFloorData(info, sBelow->floorIndex, dx, dz);
|
||||
|
||||
if (info.roomNext == TR::NO_ROOM) {
|
||||
if (info.roomNext == NO_ROOM) {
|
||||
Room::Sector *sAbove = &s;
|
||||
while (sAbove->roomAbove != TR::NO_ROOM) sAbove = &getSector(sAbove->roomAbove, x, z, dx, dz);
|
||||
while (sAbove->roomAbove != NO_ROOM) sAbove = &getSector(sAbove->roomAbove, x, z, dx, dz);
|
||||
if (sAbove != sBelow) {
|
||||
info.ceiling = 256 * sAbove->ceiling;
|
||||
parseFloorData(info, sAbove->floorIndex, dx, dz);
|
||||
@ -1601,6 +1602,7 @@ namespace TR {
|
||||
info.roomNext = tmp;
|
||||
}
|
||||
|
||||
|
||||
// entities collide
|
||||
if (info.trigCmdCount) {
|
||||
int sx = x / 1024;
|
||||
|
54
src/lara.h
54
src/lara.h
@ -58,7 +58,6 @@ struct Lara : Character {
|
||||
ANIM_CLIMB_JUMP = 26,
|
||||
|
||||
ANIM_HANG_FALL = 28,
|
||||
ANIM_HANG_WALL = 29,
|
||||
|
||||
ANIM_FALL = 34,
|
||||
ANIM_SMASH_JUMP = 32,
|
||||
@ -98,7 +97,7 @@ struct Lara : Character {
|
||||
ANIM_STAND_ROLL_BEGIN = 146,
|
||||
ANIM_STAND_ROLL_END = 147,
|
||||
|
||||
ANIM_HANG_NOWALL = 150,
|
||||
ANIM_HANG_SWING = 150,
|
||||
};
|
||||
|
||||
// http://www.tombraiderforums.com/showthread.php?t=211681
|
||||
@ -417,7 +416,7 @@ struct Lara : Character {
|
||||
//reset(61, vec3(27221, -1024, 29205), PI * 0.5f); // level 2 (blade)
|
||||
//reset(43, vec3(31400, -2560, 25200), PI); // level 2 (reach)
|
||||
//reset(16, vec3(60907, 0, 39642), PI * 3 / 2); // level 2 (hang & climb)
|
||||
reset(19, vec3(60843, 1024, 30557), PI); // level 2 (block)
|
||||
//reset(19, vec3(60843, 1024, 30557), PI); // level 2 (block)
|
||||
//reset(7, vec3(64108, -512, 16514), -PI * 0.5f); // level 2 (bat trigger)
|
||||
//reset(15, vec3(70082, -512, 26935), PI * 0.5f); // level 2 (bear)
|
||||
//reset(63, vec3(31390, -2048, 33472), 0.0f); // level 2 (trap floor)
|
||||
@ -1299,56 +1298,33 @@ struct Lara : Character {
|
||||
if (state == STATE_REACH && velocity.y < 0.0f)
|
||||
return state;
|
||||
|
||||
vec3 p = pos;
|
||||
Box bounds = animation.getBoundingBox(pos, 0);
|
||||
|
||||
vec3 p = vec3(pos.x, bounds.min.y, pos.z);
|
||||
|
||||
Collision c = Collision(level, getRoomIndex(), p, getDir() * 32.0f, vec3(0.0f), LARA_RADIUS, angleExt, 0, 0, 0, 0);
|
||||
|
||||
if (c.side != Collision::FRONT)
|
||||
return state;
|
||||
|
||||
Box bounds = animation.getBoundingBox(pos, 0);
|
||||
|
||||
int floor = c.info[Collision::FRONT].floor;
|
||||
int hands = int(bounds.min.y);
|
||||
|
||||
if (abs(floor - hands) < 32) {
|
||||
if (abs(floor - hands) < 128) {
|
||||
alignToWall(-LARA_RADIUS);
|
||||
pos.y = float(floor + LARA_HANG_OFFSET);
|
||||
stand = STAND_HANG;
|
||||
updateEntity();
|
||||
|
||||
if (state == STATE_REACH) {
|
||||
return STATE_HANG; // TODO: ANIM_HANG_WALL / ANIM_HANG_NOWALL
|
||||
vec3 p = pos + getDir() * 256.0f;
|
||||
TR::Level::FloorInfo info;
|
||||
level->getFloorInfo(getRoomIndex(), int(p.x), int(p.y), int(p.z), info);
|
||||
int h = info.ceiling - floor;
|
||||
return animation.setAnim((h > 0 && h < 400) ? ANIM_HANG_SWING : ANIM_HANG);
|
||||
} else
|
||||
return animation.setAnim(ANIM_HANG, -15);
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
|
||||
vec3 p = pos + getDir() * 128.0f;
|
||||
TR::Level::FloorInfo info;
|
||||
// TODO: use brain
|
||||
info.roomAbove = getRoomIndex();
|
||||
level->getFloorInfo(info.roomAbove, (int)pos.x, (int)pos.y, (int)pos.z, info);
|
||||
if (info.roomAbove == 0xFF)
|
||||
info.roomAbove = getRoomIndex();
|
||||
|
||||
do {
|
||||
level->getFloorInfo(info.roomAbove, (int)p.x, (int)p.y, (int)p.z, info);
|
||||
} while (info.ceiling > bounds.min.y && info.roomAbove != 0xFF);
|
||||
|
||||
if (abs(info.floor - int(bounds.min.y)) < 16) { // reach fall
|
||||
alignToWall(LARA_RADIUS);
|
||||
pos.y = info.floor + 724.0f;
|
||||
updateEntity();
|
||||
|
||||
stand = STAND_HANG;
|
||||
if (state == STATE_REACH) {
|
||||
return STATE_HANG; // TODO: ANIM_HANG_WALL / ANIM_HANG_NOWALL
|
||||
} else
|
||||
return animation.setAnim(ANIM_HANG, -15);
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
if (state == STATE_FORWARD_JUMP) {
|
||||
@ -1850,6 +1826,8 @@ struct Lara : Character {
|
||||
int maxAscent = 256 + 128;
|
||||
int maxDescent = 0xFFFFFF;
|
||||
|
||||
int room = getRoomIndex();
|
||||
|
||||
if (state == STATE_WALK || state == STATE_BACK)
|
||||
maxDescent = maxAscent;
|
||||
if (state == STATE_STEP_LEFT || state == STATE_STEP_RIGHT)
|
||||
@ -1860,14 +1838,12 @@ struct Lara : Character {
|
||||
maxHeight = 0;
|
||||
maxAscent = maxDescent = 64;
|
||||
offset = getDir() * (LARA_RADIUS + 32.0f);
|
||||
offset.y -= LARA_HANG_OFFSET;
|
||||
offset.y -= LARA_HANG_OFFSET + 32;
|
||||
}
|
||||
if (stand == STAND_UNDERWATER) {
|
||||
offset.y += LARA_HEIGHT_WATER * 0.5f;
|
||||
}
|
||||
|
||||
int room = getRoomIndex();
|
||||
|
||||
collision = Collision(level, room, pos, offset, vel, radius, angleExt, minHeight, maxHeight, maxAscent, maxDescent);
|
||||
|
||||
if (stand != STAND_HANG && (collision.side == Collision::LEFT || collision.side == Collision::RIGHT)) {
|
||||
|
Loading…
x
Reference in New Issue
Block a user