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

#22 underwater current (WIP)

This commit is contained in:
XProger
2017-10-16 07:30:30 +03:00
parent 30c15b33af
commit e7d194c0de
5 changed files with 72 additions and 21 deletions

View File

@@ -69,7 +69,7 @@ struct Character : Controller {
}
uint16* getZones() {
return flying ? level->zones[level->isFlipped].fly : (stepHeight == 256 ? level->zones[level->isFlipped].ground1 : level->zones[level->isFlipped].ground2);
return (flying || stand == STAND_UNDERWATER || stand == STAND_ONWATER) ? level->zones[level->isFlipped].fly : (stepHeight == 256 ? level->zones[level->isFlipped].ground1 : level->zones[level->isFlipped].ground2);
}
void rotateY(float delta) {

View File

@@ -347,6 +347,18 @@ namespace Debug {
} while (!(o++)->end);
}
void debugBoxes(const TR::Level &level, uint16 *boxes, int count) {
if (!boxes) return;
glColor4f(0.0f, 1.0f, 0.0f, 0.25f);
Core::setBlending(bmAlpha);
Core::setDepthTest(false);
Core::validateRenderState();
for (int i = 0; i < count; i++)
debugBox(level.boxes[boxes[i]]);
Core::setDepthTest(true);
}
void sectors(const TR::Level &level, int roomIndex, int y, int zone = -1) {
TR::Room &room = level.rooms[roomIndex];

View File

@@ -928,8 +928,9 @@ namespace TR {
int16 room; // for camera
int16 speed; // for sink (underwater current)
};
struct {
uint16 :8, once:1, :5, :2;
union {
struct { uint16 :8, once:1, :5, :2; };
uint16 boxIndex;
} flags;
};

View File

@@ -241,7 +241,10 @@ struct Lara : Character {
int hitDir;
vec3 collisionOffset;
vec3 flowVelocity;
#ifdef _DEBUG
uint16 *dbgBoxes;
int dbgBoxesCount;
#endif
struct Braid {
Lara *lara;
vec3 offset;
@@ -482,6 +485,7 @@ struct Lara : Character {
//reset(9, vec3(69074, -14592, 25192), 0); // Level 10c (trap slam)
//reset(21, vec3(47668, -10752, 32163), 0); // Level 10c (lava emitter)
//reset(10, vec3(90443, 11264 - 256, 114614), PI, STAND_ONWATER); // villa mortal 2
dbgBoxes = NULL;
#endif
if (getEntity().type == TR::Entity::LARA) {
@@ -1360,6 +1364,15 @@ struct Lara : Character {
addBloodSpikes();
}
void bakeEnvironment() {
if (!environment)
environment = new Texture(256, 256, Texture::RGBA, true, NULL, true, true);
Core::beginFrame();
game->renderEnvironment(getRoomIndex(), pos - vec3(0.0f, 384.0f, 0.0f), &environment);
environment->generateMipMap();
Core::endFrame();
}
virtual void hit(float damage, Controller *enemy = NULL, TR::HitType hitType = TR::HIT_DEFAULT) {
if (dozy) return;
@@ -1435,12 +1448,7 @@ struct Lara : Character {
}
case TR::HIT_MIDAS : {
// generate environment map for reflections
if (!environment)
environment = new Texture(256, 256, Texture::RGBA, true, NULL, true, true);
Core::beginFrame();
game->renderEnvironment(73, pos - vec3(0.0f, 384.0f, 0.0f), &environment);
environment->generateMipMap();
Core::endFrame();
bakeEnvironment();
// set death animation
animation.setAnim(level->models[TR::MODEL_LARA_SPEC].animation + 1);
game->getCamera()->doCutscene(pos, angle.y);
@@ -1538,6 +1546,12 @@ struct Lara : Character {
return false;
}
int goUnderwater() {
angle.x = -PI * 0.25f;
game->waterDrop(pos, 256.0f, 0.2f);
return animation.setAnim(ANIM_TO_UNDERWATER);
}
bool doPickUp() {
if (!animation.canSetState(STATE_PICK_UP))
return false;
@@ -2329,11 +2343,8 @@ struct Lara : Character {
}
if (input & FORTH) {
if (input & JUMP) {
angle.x = -PI * 0.25f;
game->waterDrop(pos, 256.0f, 0.2f);
return animation.setAnim(ANIM_TO_UNDERWATER);
}
if (input & JUMP)
return goUnderwater();
if ((input & ACTION) && waterOut()) {
game->waterDrop(pos, 128.0f, 0.2f);
@@ -2904,14 +2915,40 @@ struct Lara : Character {
virtual void applyFlow(TR::Camera &sink) {
if (stand != STAND_UNDERWATER && stand != STAND_ONWATER) return;
vec3 target = vec3(sink.x, sink.y, sink.z);
vec3 target = vec3(float(sink.x), float(sink.y), float(sink.z));
#ifdef _DEBUG
delete[] dbgBoxes;
dbgBoxes = NULL;
#endif
if (box != sink.flags.boxIndex) {
uint16 *boxes;
uint16 count = game->findPath(0xFFFFFF, -0xFFFFFF, false, box, sink.flags.boxIndex, getZones(), &boxes);
if (count > 1) {
#ifdef _DEBUG
dbgBoxesCount = count;
dbgBoxes = new uint16[dbgBoxesCount];
memcpy(dbgBoxes, boxes, sizeof(uint16) * dbgBoxesCount);
#endif
TR::Box &b = level->boxes[boxes[1]];
target.x = (b.minX + b.maxX) * 0.5f;
if (target.y > b.floor)
target.y = float(b.floor);
target.z = (b.minZ + b.maxZ) * 0.5f;
}
}
flowVelocity = vec3(0);
if (!dozy) {
float speed = sink.speed * 6.0f;
flowVelocity.x = clamp(target.x - pos.x, -speed, +speed);
flowVelocity.y = clamp(target.y - pos.y, -speed, +speed);
flowVelocity.z = clamp(target.z - pos.z, -speed, +speed);
float speed = sink.speed * 6.0f;
flowVelocity.x = clamp(target.x - pos.x, -speed, +speed);
flowVelocity.y = clamp(target.y - pos.y, -speed, +speed);
flowVelocity.z = clamp(target.z - pos.z, -speed, +speed);
if (stand == STAND_ONWATER)
goUnderwater();
}
}
uint32 getMidasMask() {
@@ -2966,7 +3003,7 @@ struct Lara : Character {
}
if (state == STATE_MIDAS_DEATH) {
game->setRoomParams(getRoomIndex(), Shader::MIRROR, 1.2f, 1.0f, 0.2f, 1.0f, false);
game->setRoomParams(getRoomIndex(), Shader::MIRROR, 1.2f, 1.0f, 0.2f, 1.0f, false);
environment->bind(sEnvironment);
Core::setBlending(bmAlpha);
visibleMask ^= 0xFFFFFFFF;

View File

@@ -1420,6 +1420,7 @@ struct Level : IGame {
// Debug::Level::blocks(level);
// Debug::Level::path(level, (Enemy*)level.entities[86].controller);
// Debug::Level::debugOverlaps(level, lara->box);
// Debug::Level::debugBoxes(level, lara->dbgBoxes, lara->dbgBoxesCount);
// Core::setBlending(bmNone);
/*