mirror of
https://github.com/XProger/OpenLara.git
synced 2025-08-15 09:34:18 +02:00
21
src/cache.h
21
src/cache.h
@@ -414,20 +414,14 @@ struct WaterCache {
|
||||
for (int x = minX; x < maxX; x++) {
|
||||
TR::Room::Sector &s = r.sectors[x * r.zSectors + z];
|
||||
|
||||
bool hasWater = (s.roomAbove != TR::NO_ROOM && !level->rooms[s.roomAbove].flags.water);
|
||||
bool hasFlow = false;
|
||||
bool hasWater = s.roomAbove != TR::NO_ROOM && !level->rooms[s.roomAbove].flags.water;
|
||||
if (hasWater) {
|
||||
TR::Level::FloorInfo info;
|
||||
game->getLara()->getFloorInfo(to, vec3(float(x + r.info.x), float(r.info.yBottom), float(z + r.info.z)), info);
|
||||
if (info.trigCmdCount && info.trigger == TR::Level::Trigger::ACTIVATE)
|
||||
for (int i = 0; i < info.trigCmdCount; i++)
|
||||
if (info.trigCmd[i].action == TR::Action::FLOW) {
|
||||
hasFlow = true;
|
||||
break;
|
||||
}
|
||||
TR::Room &rt = level->rooms[s.roomAbove];
|
||||
TR::Room::Sector &st = rt.sectors[x * rt.zSectors + z];
|
||||
hasWater = s.ceiling > st.ceiling;
|
||||
}
|
||||
|
||||
m[(x - minX) + w * (z - minZ)] = hasWater ? (hasFlow ? 0xF81F : 0xF800) : 0;
|
||||
|
||||
m[(x - minX) + w * (z - minZ)] = hasWater ? 0xF800 : 0;
|
||||
}
|
||||
|
||||
size = vec3(float((maxX - minX) * 512), 1.0f, float((maxZ - minZ) * 512)); // half size
|
||||
@@ -785,8 +779,10 @@ struct WaterCache {
|
||||
|
||||
refract->bind(sDiffuse);
|
||||
reflect->bind(sReflect);
|
||||
item.mask->bind(sMask);
|
||||
item.data[0]->bind(sNormal);
|
||||
Core::setCulling(cfNone);
|
||||
Core::setBlending(bmAlpha);
|
||||
#ifdef WATER_USE_GRID
|
||||
vec3 rPosScale[2] = { item.pos, item.size * vec3(1.0f / PLANE_DETAIL, 512.0f, 1.0f / PLANE_DETAIL) };
|
||||
Core::active.shader->setParam(uPosScale, rPosScale[0], 2);
|
||||
@@ -796,6 +792,7 @@ struct WaterCache {
|
||||
game->getMesh()->renderQuad();
|
||||
#endif
|
||||
Core::setCulling(cfFront);
|
||||
Core::setBlending(bmNone);
|
||||
}
|
||||
dropCount = 0;
|
||||
}
|
||||
|
@@ -58,6 +58,7 @@ struct IGame {
|
||||
virtual void checkTrigger(Controller *controller, bool heavy) {}
|
||||
|
||||
virtual Controller* addEntity(TR::Entity::Type type, int room, const vec3 &pos, float angle = 0.0f) { return NULL; }
|
||||
virtual void removeEntity(Controller *controller) {}
|
||||
|
||||
virtual bool invUse(TR::Entity::Type type) { return false; }
|
||||
virtual void invAdd(TR::Entity::Type type, int count = 1) {}
|
||||
|
23
src/format.h
23
src/format.h
@@ -2103,29 +2103,6 @@ namespace TR {
|
||||
return 0;
|
||||
}
|
||||
|
||||
int entityAdd(Entity::Type type, int16 room, const vec3 &pos, float rotation, int16 intensity) {
|
||||
for (int i = entitiesBaseCount; i < entitiesCount; i++) {
|
||||
Entity &e = entities[i];
|
||||
if (!e.controller) {
|
||||
e.type = type;
|
||||
e.room = room;
|
||||
e.x = int(pos.x);
|
||||
e.y = int(pos.y);
|
||||
e.z = int(pos.z);
|
||||
e.rotation = angle(normalizeAngle(rotation));
|
||||
e.intensity = intensity;
|
||||
e.flags.value = 0;
|
||||
e.modelIndex = getModelIndex(e.type);
|
||||
return i;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
void entityRemove(int entityIndex) {
|
||||
entities[entityIndex].controller = NULL;
|
||||
}
|
||||
|
||||
int getNextRoom(int floorIndex) const {
|
||||
if (!floorIndex) return NO_ROOM;
|
||||
FloorData *fd = &floors[floorIndex];
|
||||
|
95
src/level.h
95
src/level.h
@@ -319,30 +319,51 @@ struct Level : IGame {
|
||||
}
|
||||
|
||||
virtual Controller* addEntity(TR::Entity::Type type, int room, const vec3 &pos, float angle) {
|
||||
int index = level.entityAdd(type, room, pos, angle, -1);
|
||||
if (index > -1) {
|
||||
int index;
|
||||
for (index = level.entitiesBaseCount; index < level.entitiesCount; index++) {
|
||||
TR::Entity &e = level.entities[index];
|
||||
if (e.isPickup())
|
||||
e.intensity = 4096;
|
||||
else
|
||||
if (e.isSprite()) {
|
||||
if (e.type == TR::Entity::LAVA_PARTICLE || e.type == TR::Entity::FLAME)
|
||||
e.intensity = 0; // emissive
|
||||
else
|
||||
e.intensity = 0x1FFF - level.rooms[room].ambient;
|
||||
}
|
||||
if (!e.controller) {
|
||||
e.type = type;
|
||||
e.room = room;
|
||||
e.x = int(pos.x);
|
||||
e.y = int(pos.y);
|
||||
e.z = int(pos.z);
|
||||
e.rotation = TR::angle(normalizeAngle(angle));
|
||||
e.intensity = -1;
|
||||
e.flags.value = 0;
|
||||
e.modelIndex = level.getModelIndex(e.type);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
Controller *controller = initController(index);
|
||||
e.controller = controller;
|
||||
if (index == level.entitiesCount)
|
||||
return NULL;
|
||||
|
||||
if (e.isEnemy() || e.isSprite()) {
|
||||
controller->flags.active = TR::ACTIVE;
|
||||
controller->activate();
|
||||
TR::Entity &e = level.entities[index];
|
||||
if (e.isPickup())
|
||||
e.intensity = 4096;
|
||||
else
|
||||
if (e.isSprite()) {
|
||||
if (e.type == TR::Entity::LAVA_PARTICLE || e.type == TR::Entity::FLAME)
|
||||
e.intensity = 0; // emissive
|
||||
else
|
||||
e.intensity = 0x1FFF - level.rooms[room].ambient;
|
||||
}
|
||||
|
||||
return controller;
|
||||
Controller *controller = initController(index);
|
||||
e.controller = controller;
|
||||
|
||||
if (e.isEnemy() || e.isSprite()) {
|
||||
controller->flags.active = TR::ACTIVE;
|
||||
controller->activate();
|
||||
}
|
||||
return NULL;
|
||||
|
||||
return controller;
|
||||
}
|
||||
|
||||
virtual void removeEntity(Controller *controller) {
|
||||
level.entities[controller->entity].controller = NULL;
|
||||
delete controller;
|
||||
}
|
||||
|
||||
virtual bool invUse(TR::Entity::Type type) {
|
||||
@@ -618,9 +639,10 @@ struct Level : IGame {
|
||||
case TR::Entity::RICOCHET : return new Sprite(this, index, true, Sprite::FRAME_RANDOM);
|
||||
case TR::Entity::CENTAUR_STATUE : return new CentaurStatue(this, index);
|
||||
case TR::Entity::CABIN : return new Cabin(this, index);
|
||||
case TR::Entity::TRAP_FLAME_EMITTER : return new TrapFlameEmitter(this, index);
|
||||
case TR::Entity::LAVA_PARTICLE : return new LavaParticle(this, index);
|
||||
case TR::Entity::TRAP_LAVA_EMITTER : return new TrapLavaEmitter(this, index);
|
||||
case TR::Entity::FLAME : return new Flame(this, index);
|
||||
case TR::Entity::TRAP_FLAME_EMITTER : return new TrapFlameEmitter(this, index);
|
||||
case TR::Entity::BOAT : return new Boat(this, index);
|
||||
case TR::Entity::EARTHQUAKE : return new Earthquake(this, index);
|
||||
case TR::Entity::MUTANT_EGG_SMALL :
|
||||
@@ -1359,8 +1381,6 @@ struct Level : IGame {
|
||||
void renderDebug() {
|
||||
if (level.id == TR::TITLE) return;
|
||||
|
||||
// Core::mViewInv = camera->mViewInv;
|
||||
// Core::mView = Core::mViewInv.inverse();
|
||||
Core::setViewport(0, 0, Core::width, Core::height);
|
||||
camera->setup(true);
|
||||
|
||||
@@ -1369,39 +1389,6 @@ struct Level : IGame {
|
||||
Input::down[ikF] = false;
|
||||
}
|
||||
|
||||
/*
|
||||
static int snd_index = 0;
|
||||
if (Input::down[ikG]) {
|
||||
snd_index = (snd_index + 1) % level.soundsInfoCount;
|
||||
LOG("play sound: %d\n", snd_index);
|
||||
lara->playSound(snd_index, lara->pos, 0);
|
||||
Input::down[ikG] = false;
|
||||
}
|
||||
|
||||
static int modelIndex = 0;
|
||||
static bool lastStateK = false;
|
||||
static int lastEntity = -1;
|
||||
if (Input::down[ikM]) {
|
||||
if (!lastStateK) {
|
||||
lastStateK = true;
|
||||
modelIndex = (modelIndex + 1) % level.modelsCount;
|
||||
// modelIndex = (modelIndex + 1) % level.spriteSequencesCount;
|
||||
LOG("model: %d %d\n", modelIndex, level.spriteSequences[modelIndex].type);
|
||||
if (lastEntity > -1) {
|
||||
delete level.entities[lastEntity].controller;
|
||||
level.entityRemove(lastEntity);
|
||||
}
|
||||
vec3 p = lara->pos + lara->getDir() * 256.0f;
|
||||
lastEntity = level.entityAdd(level.models[modelIndex].type, lara->getRoomIndex(), p.x, p.y - 512, p.z, lara->getEntity().rotation, -1);
|
||||
level.entities[lastEntity].controller = new Controller(this, lastEntity);
|
||||
}
|
||||
} else
|
||||
lastStateK = false;
|
||||
|
||||
if (lastEntity > -1)
|
||||
renderEntity(level.entities[lastEntity]);
|
||||
// renderModel(level.models[modelIndex], level.entities[4]);
|
||||
*/
|
||||
Debug::begin();
|
||||
/*
|
||||
lara->updateEntity(); // TODO clip angle while rotating
|
||||
|
@@ -177,7 +177,7 @@ uniform sampler2D sNormal;
|
||||
|
||||
vec3 normal = vec3(value.z, -sqrt(1.0 - dot(value.zw, value.zw)), value.w);
|
||||
|
||||
vec2 dudv = (uViewProj * vec4(normal.x, 0.0, normal.z, 0.0)).xy;
|
||||
vec2 dudv = (uViewProj * vec4(normal.x, 0.0, normal.z, 0.0)).xy;
|
||||
|
||||
vec3 viewVec = normalize(vViewVec);
|
||||
vec3 rv = reflect(-viewVec, normal);
|
||||
@@ -185,7 +185,7 @@ uniform sampler2D sNormal;
|
||||
|
||||
float spec = pow(max(0.0, dot(rv, lv)), 64.0) * 0.5;
|
||||
|
||||
vec2 tc = vProjCoord.xy / vProjCoord.w * 0.5 + 0.5;
|
||||
vec2 tc = vProjCoord.xy / vProjCoord.w * 0.5 + 0.5;
|
||||
|
||||
vec4 refrA = texture2D(sDiffuse, uParam.xy * clamp(tc + dudv * uParam.z, 0.0, 0.999) );
|
||||
vec4 refrB = texture2D(sDiffuse, uParam.xy * tc );
|
||||
@@ -199,7 +199,7 @@ uniform sampler2D sNormal;
|
||||
float d = abs((vCoord.y - uViewPos.y) / normalize(vViewVec).y);
|
||||
d *= step(0.0, uViewPos.y - vCoord.y); // apply fog only when camera is underwater
|
||||
color.xyz = applyFog(color.xyz, UNDERWATER_COLOR * 0.2, d * WATER_FOG_DIST);
|
||||
|
||||
color.w *= texture2D(sMask, vTexCoord).x;
|
||||
return color;
|
||||
}
|
||||
|
||||
|
@@ -50,10 +50,8 @@ struct Sprite : Controller {
|
||||
|
||||
pos += velocity * (30.0f * Core::deltaTime);
|
||||
|
||||
if (remove) {
|
||||
level->entityRemove(entity);
|
||||
delete this;
|
||||
}
|
||||
if (remove)
|
||||
game->removeEntity(this);
|
||||
}
|
||||
|
||||
virtual void render(Frustum *frustum, MeshBuilder *mesh, Shader::Type type, bool caustics) {
|
||||
|
@@ -82,8 +82,7 @@ struct Dart : Controller {
|
||||
getFloorInfo(getRoomIndex(), pos, info);
|
||||
if (pos.y > info.floor || pos.y < info.ceiling || !insideRoom(pos, getRoomIndex())) {
|
||||
game->addEntity(TR::Entity::RICOCHET, getRoomIndex(), pos - dir * 64.0f); // with wall offset
|
||||
level->entityRemove(entity);
|
||||
delete this;
|
||||
game->removeEntity(this);
|
||||
}
|
||||
}
|
||||
};
|
||||
@@ -120,24 +119,16 @@ struct TrapDartEmitter : Controller {
|
||||
struct Flame : Sprite {
|
||||
|
||||
static Flame* add(IGame *game, Controller *controller, int jointIndex) {
|
||||
Flame *flame = NULL;
|
||||
|
||||
TR::Level *level = game->getLevel();
|
||||
int roomIndex = controller->getRoomIndex();
|
||||
vec3 pos = controller->pos;
|
||||
|
||||
int index = level->entityAdd(TR::Entity::FLAME, roomIndex, pos, 0, 0);
|
||||
if (index > -1) {
|
||||
flame = new Flame(game, index, jointIndex);
|
||||
level->entities[index].controller = flame;
|
||||
}
|
||||
Flame *flame = (Flame*)game->addEntity(TR::Entity::FLAME, controller->getRoomIndex(), controller->pos);
|
||||
if (flame)
|
||||
flame->jointIndex = jointIndex;
|
||||
return flame;
|
||||
}
|
||||
|
||||
int jointIndex;
|
||||
float sleep;
|
||||
|
||||
Flame(IGame *game, int entity, int jointIndex) : Sprite(game, entity, false, Sprite::FRAME_ANIMATED), jointIndex(jointIndex), sleep(0.0f) {
|
||||
Flame(IGame *game, int entity) : Sprite(game, entity, false, Sprite::FRAME_ANIMATED), jointIndex(0), sleep(0.0f) {
|
||||
time = randf() * 3.0f;
|
||||
activate();
|
||||
}
|
||||
@@ -150,8 +141,7 @@ struct Flame : Sprite {
|
||||
|
||||
if (jointIndex > -1) {
|
||||
if (lara->stand == Character::STAND_UNDERWATER) {
|
||||
level->entityRemove(entity);
|
||||
delete this;
|
||||
game->removeEntity(this);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -185,10 +175,9 @@ struct TrapFlameEmitter : Controller {
|
||||
void virtual update() {
|
||||
if (!isActive()) {
|
||||
if (flame) {
|
||||
level->entityRemove(flame->entity);
|
||||
delete flame;
|
||||
flame = NULL;
|
||||
Sound::stop(TR::SND_FLAME);
|
||||
game->removeEntity(flame);
|
||||
flame = NULL;
|
||||
}
|
||||
return;
|
||||
}
|
||||
@@ -231,8 +220,7 @@ struct LavaParticle : Sprite {
|
||||
|
||||
if (hit || pos.y > info.floor || pos.y < info.ceiling) {
|
||||
if (hit || ++bounces > 4) {
|
||||
level->entityRemove(entity);
|
||||
delete this;
|
||||
game->removeEntity(this);
|
||||
return;
|
||||
}
|
||||
intensity = max(0.0f, 1.0f - bounces * 0.25f);
|
||||
@@ -379,13 +367,15 @@ struct Block : Controller {
|
||||
// check for trapdoor
|
||||
int px = int(p.x) / 1024;
|
||||
int pz = int(p.z) / 1024;
|
||||
for (int i = 0; i < info.trigCmdCount; i++)
|
||||
for (int i = 0; i < info.trigCmdCount; i++) {
|
||||
if (info.trigCmd[i].action == TR::Action::ACTIVATE) {
|
||||
TR::Entity &e = level->entities[info.trigCmd[i].args];
|
||||
vec3 objPos = ((Controller*)e.controller)->pos;
|
||||
if ((e.type == TR::Entity::TRAP_DOOR_1 || e.type == TR::Entity::TRAP_DOOR_2) && px == int(objPos.x) / 1024 && pz == int(objPos.z) / 1024)
|
||||
return false;
|
||||
}
|
||||
} else if (info.trigCmd[i].action == TR::Action::CAMERA_SWITCH)
|
||||
i++; // skip camera switch delay info
|
||||
}
|
||||
|
||||
// check Laras destination position
|
||||
if (!push) {
|
||||
@@ -895,11 +885,8 @@ struct ThorHammer : Controller {
|
||||
Controller *block;
|
||||
|
||||
ThorHammer(IGame *game, int entity) : Controller(game, entity) {
|
||||
int index = level->entityAdd(TR::Entity::HAMMER_BLOCK, getRoomIndex(), pos, angle.y, -1);
|
||||
if (index > -1) {
|
||||
block = new Controller(game, index);
|
||||
level->entities[index].controller = block;
|
||||
}
|
||||
block = game->addEntity(TR::Entity::HAMMER_BLOCK, getRoomIndex(), pos, angle.y);
|
||||
ASSERT(block);
|
||||
flags.collision = block->flags.collision = false;
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user