mirror of
https://github.com/XProger/OpenLara.git
synced 2025-08-17 02:24:07 +02:00
This commit is contained in:
@@ -60,7 +60,7 @@ struct Camera : ICamera {
|
||||
}
|
||||
|
||||
virtual int getRoomIndex() const {
|
||||
return room;
|
||||
return (level->isFlipped && level->rooms[room].alternateRoom > -1) ? level->rooms[room].alternateRoom : room;
|
||||
}
|
||||
|
||||
virtual void checkRoom() {
|
||||
|
@@ -764,7 +764,7 @@ namespace TR {
|
||||
opaque = true;
|
||||
if (type == SWITCH || type == SWITCH_WATER)
|
||||
opaque = true;
|
||||
if (type == PUZZLE_HOLE_1) // LEVEL3A cogs
|
||||
if (type == PUZZLE_HOLE_1 || type == LIGHTNING) // LEVEL3A cogs
|
||||
opaque = false;
|
||||
}
|
||||
};
|
||||
|
25
src/lara.h
25
src/lara.h
@@ -228,6 +228,7 @@ struct Lara : Character {
|
||||
TR::Entity::Type usedKey;
|
||||
TR::Entity *pickupEntity;
|
||||
KeyHole *keyHole;
|
||||
Lightning *lightning;
|
||||
|
||||
int roomPrev; // water out from room
|
||||
vec2 rotFactor;
|
||||
@@ -410,6 +411,9 @@ struct Lara : Character {
|
||||
damageTime = LARA_DAMAGE_TIME;
|
||||
hitTime = 0.0f;
|
||||
|
||||
keyHole = NULL;
|
||||
lightning = NULL;
|
||||
|
||||
getEntity().flags.active = 1;
|
||||
initMeshOverrides();
|
||||
|
||||
@@ -1344,6 +1348,7 @@ struct Lara : Character {
|
||||
case TR::HIT_BLADE : addBloodBlade(); break;
|
||||
case TR::HIT_SPIKES : addBloodSpikes(); break;
|
||||
case TR::HIT_SLAM : addBloodSlam(enemy); break;
|
||||
case TR::HIT_LIGHTNING : lightning = (Lightning*)enemy; break;
|
||||
default : ;
|
||||
}
|
||||
|
||||
@@ -2321,8 +2326,17 @@ struct Lara : Character {
|
||||
if (Input::state[cWeapon]) input |= WEAPON;
|
||||
|
||||
// scion debug (TODO: remove)
|
||||
if (Input::down[ikP] && level->id == TR::LEVEL_3B)
|
||||
if (Input::down[ikP]) {
|
||||
switch (level->id) {
|
||||
case TR::LEVEL_3B :
|
||||
reset(5, vec3(73394, 3840, 60758), 0); // level 3b (scion)
|
||||
break;
|
||||
case TR::LEVEL_4 :
|
||||
reset(18, vec3(34914, 11008, 41315), 90 * DEG2RAD); // main hall
|
||||
break;
|
||||
default : game->playSound(TR::SND_NO, pos, Sound::PAN);
|
||||
}
|
||||
}
|
||||
|
||||
// analog control
|
||||
rotFactor = vec2(1.0f);
|
||||
@@ -2470,7 +2484,7 @@ struct Lara : Character {
|
||||
switch (stand) {
|
||||
case STAND_AIR :
|
||||
velocity.y += (velocity.y >= 128.0f ? 30.0f : GRAVITY) * Core::deltaTime;
|
||||
if (velocity.y >= 154.0f)
|
||||
if (velocity.y >= 154.0f && state == STATE_FALL)
|
||||
game->playSound(TR::SND_SCREAM, pos, Sound::PAN);
|
||||
/*
|
||||
if (state == STATE_FALL || state == STATE_FAST_DIVE) {
|
||||
@@ -2636,7 +2650,14 @@ struct Lara : Character {
|
||||
}
|
||||
};
|
||||
|
||||
if (lightning && lightning->flash && !lightning->armed) {
|
||||
if (hitDir == -1)
|
||||
hitTime = 0.0f;
|
||||
hitDir = int(randf() * 4);
|
||||
} else {
|
||||
hitDir = -1;
|
||||
lightning = NULL;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
28
src/level.h
28
src/level.h
@@ -504,6 +504,8 @@ struct Level : IGame {
|
||||
|
||||
static void fillCallback(int id, int width, int height, int tileX, int tileY, void *userData, void *data) {
|
||||
static const uint32 barColor[UI::BAR_MAX][25] = {
|
||||
// flash bar
|
||||
{ 0x00000000, 0xFFA20058, 0xFFFFFFFF, 0xFFA20058, 0x00000000 },
|
||||
// health bar
|
||||
{ 0xFF2C5D71, 0xFF5E81AE, 0xFF2C5D71, 0xFF1B4557, 0xFF16304F },
|
||||
// oxygen bar
|
||||
@@ -548,6 +550,7 @@ struct Level : IGame {
|
||||
uvCount = 4;
|
||||
|
||||
switch (id) {
|
||||
case UI::BAR_FLASH :
|
||||
case UI::BAR_HEALTH :
|
||||
case UI::BAR_OXYGEN :
|
||||
case UI::BAR_OPTION :
|
||||
@@ -661,14 +664,10 @@ struct Level : IGame {
|
||||
|
||||
tiles->add(uv, texIdx++);
|
||||
}
|
||||
// add health bar
|
||||
tiles->add(short4(2048, 2048, 2048, 2048 + 4), texIdx++);
|
||||
// add oxygen bar
|
||||
tiles->add(short4(4096, 4096, 4096, 4096 + 4), texIdx++);
|
||||
// add option bar
|
||||
tiles->add(short4(8192, 8192, 8192 + 4, 8192 + 4), texIdx++);
|
||||
// add white color
|
||||
tiles->add(short4(2048, 2048, 2048, 2048), texIdx++);
|
||||
// add common textures
|
||||
const short2 bar[UI::BAR_MAX] = { {0, 4}, {0, 4}, {0, 4}, {4, 4}, {0, 0} };
|
||||
for (int i = 0; i < UI::BAR_MAX; i++)
|
||||
tiles->add(short4(i * 32, 4096, i * 32 + bar[i].x, 4096 + bar[i].y), texIdx++);
|
||||
|
||||
// get result texture
|
||||
atlas = tiles->pack();
|
||||
@@ -993,10 +992,19 @@ struct Level : IGame {
|
||||
setupBinding();
|
||||
}
|
||||
|
||||
// TODO: opqque/transparent pass for rooms and entities
|
||||
void renderEntities(bool opaque) {
|
||||
for (int i = 0; i < level.entitiesCount; i++) {
|
||||
int modelIndex = level.entities[i].modelIndex;
|
||||
if ((modelIndex < 0 && !opaque) || (modelIndex > 0 && mesh->models[modelIndex - 1].opaque == opaque))
|
||||
renderEntity(level.entities[i]);
|
||||
}
|
||||
}
|
||||
|
||||
void renderEntities() {
|
||||
PROFILE_MARKER("ENTITIES");
|
||||
for (int i = 0; i < level.entitiesCount; i++)
|
||||
renderEntity(level.entities[i]);
|
||||
renderEntities(true);
|
||||
renderEntities(false);
|
||||
|
||||
for (int i = 0; i < level.entitiesCount; i++) {
|
||||
TR::Entity &entity = level.entities[i];
|
||||
|
@@ -5,8 +5,8 @@
|
||||
#include "format.h"
|
||||
|
||||
|
||||
TR::ObjectTexture barTile[4 /* UI::BAR_MAX */];
|
||||
TR::ObjectTexture &whiteTile = barTile[3];
|
||||
TR::ObjectTexture barTile[5 /* UI::BAR_MAX */];
|
||||
TR::ObjectTexture &whiteTile = barTile[4]; // BAR_WHITE
|
||||
|
||||
struct MeshRange {
|
||||
int iStart;
|
||||
|
109
src/trigger.h
109
src/trigger.h
@@ -353,7 +353,7 @@ struct Block : Controller {
|
||||
pos.y += Core::deltaTime * velocity * 30.0f;
|
||||
if (pos.y >= info.floor) {
|
||||
velocity = 0.0f;
|
||||
pos.y = info.floor;
|
||||
pos.y = float(info.floor);
|
||||
game->setEffect(this, TR::Effect::FLOOR_SHAKE);
|
||||
game->playSound(TR::SND_BOULDER, pos, Sound::PAN);
|
||||
deactivate(true);
|
||||
@@ -839,7 +839,7 @@ struct ThorHammer : Controller {
|
||||
#define LIGHTNING_DAMAGE 400
|
||||
|
||||
struct Lightning : Controller {
|
||||
Basis target;
|
||||
vec3 target;
|
||||
float timer;
|
||||
bool flash;
|
||||
bool armed;
|
||||
@@ -850,6 +850,8 @@ struct Lightning : Controller {
|
||||
if (isActive()) {
|
||||
timer -= Core::deltaTime;
|
||||
|
||||
Character *lara = (Character*)level->laraController;
|
||||
|
||||
if (timer <= 0.0f) {
|
||||
if (flash) {
|
||||
level->isFlipped = false;
|
||||
@@ -861,17 +863,15 @@ struct Lightning : Controller {
|
||||
flash = true;
|
||||
timer = 20.0f / 30.0f;
|
||||
|
||||
Character *lara = (Character*)level->laraController;
|
||||
|
||||
bool hasTargets = getModel()->mCount > 1; // LEVEL4 has, LEVEL10C not
|
||||
|
||||
if ((lara->pos - pos).length() < (hasTargets ? 2560.0f : 1024.0f)) {
|
||||
lara->hit(LIGHTNING_DAMAGE, this, TR::HIT_LIGHTNING);
|
||||
armed = false;
|
||||
} else if (!hasTargets) {
|
||||
//
|
||||
target = pos + vec3(0.0f, 1024.0f, 0.0f);
|
||||
} else
|
||||
animation.getJoints(getMatrix(), int(randf() * 5), false, &target);
|
||||
target = animation.getJoints(getMatrix(), 1 + int(randf() * 5)).pos;
|
||||
}
|
||||
game->playSound(TR::SND_LIGHTNING, pos, Sound::PAN);
|
||||
}
|
||||
@@ -883,10 +883,105 @@ struct Lightning : Controller {
|
||||
}
|
||||
}
|
||||
|
||||
void divide(vec3 *points, int L, int R, float spread) {
|
||||
int M = (L + R) / 2;
|
||||
if (M == L || M == R) return;
|
||||
points[M] = (points[L] + points[R]) * 0.5f + (vec3(randf(), randf(), randf()) - 0.5f) * spread;
|
||||
spread *= 0.5f;
|
||||
divide(points, L, M, spread);
|
||||
divide(points, M, R, spread);
|
||||
}
|
||||
|
||||
short4 toCoord(const vec3 &v, int16 joint) {
|
||||
return short4(int16(v.x), int16(v.y), int16(v.z), joint);
|
||||
}
|
||||
|
||||
void setVertex(Vertex &v, const vec3 &coord, int16 joint, int idx) {
|
||||
v.coord = toCoord(coord, joint);
|
||||
v.normal = { 0, -1, 0, 0 };
|
||||
v.texCoord = { barTile[0].texCoord[idx].x, barTile[0].texCoord[idx].y, 32767, 32767 };
|
||||
v.param = { 0, 0, 0, 0 };
|
||||
v.color = { 255, 255, 255, 255 };
|
||||
}
|
||||
|
||||
void renderPolyline(const vec3 &start, const vec3 &end, float width, float spread, int depth) {
|
||||
vec3 points[9];
|
||||
points[0] = start;
|
||||
points[8] = end;
|
||||
divide(points, 0, 8, spread);
|
||||
|
||||
Index indices[(COUNT(points) - 1) * 6];
|
||||
Vertex vertices[COUNT(points) * 2];
|
||||
|
||||
int iCount = 0;
|
||||
int vCount = 0;
|
||||
int count = COUNT(points);
|
||||
// build indices
|
||||
for (int i = 0; i < count - 1; i++) {
|
||||
indices[iCount++] = vCount;
|
||||
indices[iCount++] = vCount + 1;
|
||||
indices[iCount++] = vCount + 2;
|
||||
indices[iCount++] = vCount + 1;
|
||||
indices[iCount++] = vCount + 3;
|
||||
indices[iCount++] = vCount + 2;
|
||||
vCount += 2;
|
||||
}
|
||||
vCount += 2;
|
||||
ASSERT(iCount == (count - 1) * 6);
|
||||
ASSERT(vCount == count * 2);
|
||||
|
||||
// build vertices
|
||||
vec3 dir = Core::mViewInv.dir.xyz;
|
||||
|
||||
vCount = 0;
|
||||
vec3 n;
|
||||
for (int i = 0; i < count; i++) {
|
||||
if (i < count - 1)
|
||||
n = dir.cross(points[i + 1] - points[i]).normal() * width;
|
||||
setVertex(vertices[vCount++], points[i] - n, 0, 0);
|
||||
setVertex(vertices[vCount++], points[i] + n, 0, 3);
|
||||
}
|
||||
ASSERT(vCount == count * 2);
|
||||
|
||||
game->getMesh()->renderBuffer(indices, iCount, vertices, vCount);
|
||||
|
||||
if (depth > 0) {
|
||||
for (int i = 0; i < 2; i++) {
|
||||
vec3 a = points[int(randf() * (count - 1))];
|
||||
vec3 b = a;
|
||||
b.x += (randf() - 0.5f) * spread;
|
||||
b.y = points[count - 1].y;
|
||||
b.z += (randf() - 0.5f) * spread;
|
||||
|
||||
renderPolyline(a, b, width * 0.75f, spread * 0.5f, depth - 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
virtual void render(Frustum *frustum, MeshBuilder *mesh, Shader::Type type, bool caustics) {
|
||||
Controller::render(frustum, mesh, type, caustics);
|
||||
if (!flash) return;
|
||||
// TODO
|
||||
|
||||
if (!armed)
|
||||
target = game->getLara()->pos;
|
||||
|
||||
Basis b = animation.getJoints(getMatrix(), 0);
|
||||
b.rot = quat(0, 0, 0, 1);
|
||||
|
||||
game->setShader(Core::pass, Shader::FLASH, false, false);
|
||||
Core::active.shader->setParam(uMaterial, vec4(0.0f, 0.0f, 0.0f, 1.0f));
|
||||
Core::active.shader->setParam(uBasis, b);
|
||||
|
||||
Core::setCulling(cfNone);
|
||||
Core::setBlending(bmAdd);
|
||||
Core::setDepthWrite(false);
|
||||
|
||||
renderPolyline(vec3(0.0f), target - b.pos, 64.0f, 512.0f, 1);
|
||||
|
||||
Core::setDepthWrite(true);
|
||||
Core::setBlending(bmNone);
|
||||
Core::setCulling(cfFront);
|
||||
}
|
||||
};
|
||||
|
||||
|
1
src/ui.h
1
src/ui.h
@@ -204,6 +204,7 @@ namespace UI {
|
||||
#define MAX_CHARS DYN_MESH_QUADS
|
||||
|
||||
enum BarType {
|
||||
BAR_FLASH,
|
||||
BAR_HEALTH,
|
||||
BAR_OXYGEN,
|
||||
BAR_OPTION,
|
||||
|
@@ -204,8 +204,8 @@ struct vec2 {
|
||||
|
||||
struct vec3 {
|
||||
union {
|
||||
struct { vec2 xy; };
|
||||
struct { float x, y, z; };
|
||||
struct { vec2 xy; };
|
||||
};
|
||||
|
||||
vec3() {}
|
||||
@@ -271,9 +271,9 @@ struct vec3 {
|
||||
|
||||
struct vec4 {
|
||||
union {
|
||||
struct { float x, y, z, w; };
|
||||
struct { vec2 xy, zw; };
|
||||
struct { vec3 xyz; };
|
||||
struct { float x, y, z, w; };
|
||||
};
|
||||
|
||||
vec4() {}
|
||||
|
Reference in New Issue
Block a user