1
0
mirror of https://github.com/XProger/OpenLara.git synced 2025-08-17 10:30:47 +02:00

fix lava particles emitter

This commit is contained in:
XProger
2019-01-21 11:08:46 +03:00
parent dc9c5837d0
commit b9dee42ae3

View File

@@ -280,7 +280,6 @@ struct MuzzleFlash : Controller {
} }
}; };
#define LAVA_PARTICLE_BOUNCES 4
#define LAVA_PARTICLE_DAMAGE 10 #define LAVA_PARTICLE_DAMAGE 10
#define LAVA_V_SPEED -165 #define LAVA_V_SPEED -165
#define LAVA_H_SPEED 32 #define LAVA_H_SPEED 32
@@ -293,15 +292,21 @@ struct TrapLavaEmitter : Controller {
vec3 velocity; vec3 velocity;
int16 roomIndex; int16 roomIndex;
int8 frame; int8 frame;
int8 bounces;
void update(TR::Level *level, Controller *lara) { void update(TR::Level *level, Controller *lara) {
Controller::applyGravity(velocity.y); Controller::applyGravity(velocity.y);
vec3 opos = pos;
pos += velocity * (30.0f * Core::deltaTime); pos += velocity * (30.0f * Core::deltaTime);
if (!bounces && lara->collide(Sphere(pos, 0.0f))) { if (lara->collide(Sphere(pos, 0.0f))) {
lara->hit(LAVA_PARTICLE_DAMAGE); lara->hit(LAVA_PARTICLE_DAMAGE);
bounces = LAVA_PARTICLE_BOUNCES + 1; frame = -1;
return;
}
if (level->rooms[roomIndex].flags.water) {
frame = -1;
return;
} }
TR::Room::Sector *sector = level->getSector(roomIndex, pos); TR::Room::Sector *sector = level->getSector(roomIndex, pos);
@@ -309,12 +314,29 @@ struct TrapLavaEmitter : Controller {
float ceiling = level->getCeiling(sector, pos); float ceiling = level->getCeiling(sector, pos);
if (pos.y > floor || pos.y < ceiling) { if (pos.y > floor || pos.y < ceiling) {
bounces++; vec3 n;
if (pos.y > floor) pos.y = floor; if (pos.y - floor > 128) {
if (pos.y < ceiling) pos.y = ceiling; int ix = int(pos.x);
int iz = int(pos.z);
ix -= ix / 1024 * 1024 + 512;
iz -= iz / 1024 * 1024 + 512;
velocity = velocity.reflect(vec3(0, 1, 0)) * 0.5f; if (abs(ix) > abs(iz)) {
n = vec3(ix < 0 ? -1.0f : 1.0f, 0, 0);
} else {
n = vec3(0, 0, iz < 0 ? -1.0f : 1.0f);
}
} else if (pos.y > floor) {
n = vec3(0, -1, 0);
} else if (pos.y < ceiling) {
n = vec3(0, 1, 0);
}
velocity = velocity.reflect(n) * 0.5f;
pos = opos;
frame--;
} }
} }
}; };
@@ -323,9 +345,9 @@ struct TrapLavaEmitter : Controller {
int spriteIndex; int spriteIndex;
TrapLavaEmitter(IGame *game, int entity) : Controller(game, entity) { TrapLavaEmitter(IGame *game, int entity) : Controller(game, entity) {
spriteIndex = game->getLevel()->getModelIndex(TR::Entity::LAVA_PARTICLE); spriteIndex = level->getModelIndex(TR::Entity::LAVA_PARTICLE);
if (spriteIndex) { if (spriteIndex) {
game->getLevel()->spriteSequences[-(spriteIndex + 1)].transp = 2; // fix blending mode to additive level->spriteSequences[-(spriteIndex + 1)].transp = 2; // fix blending mode to additive
} }
particles.capacity = 128; particles.capacity = 128;
} }
@@ -334,34 +356,30 @@ struct TrapLavaEmitter : Controller {
if (!spriteIndex) if (!spriteIndex)
return; return;
Controller *lara = game->getLara(); Controller *lara = game->getLara(pos);
vec3 d = (lara->pos - pos).abs(); vec3 d = (lara->pos - pos).abs();
if (!isActive() || max(d.x, d.y, d.z) > LAVA_EMITTER_RANGE) return; if (isActive() && max(d.x, d.z) < LAVA_EMITTER_RANGE) {
if (timer <= 0.0f) { if (timer <= 0.0f) {
float speed = randf() * LAVA_H_SPEED;
float angle = PI * 2.0f * randf();
Particle part; Particle part;
part.pos = pos; part.pos = pos;
part.velocity = vec3(cosf(angle) * speed, randf() * LAVA_V_SPEED, sinf(angle) * speed); part.velocity = vec3((randf() * 2.0f - 1.0f) * LAVA_H_SPEED, randf() * LAVA_V_SPEED, (randf() * 2.0f - 1.0f) * LAVA_H_SPEED);
part.roomIndex = getRoomIndex(); part.roomIndex = getRoomIndex();
part.bounces = 0;
part.frame = rand() % level->spriteSequences[-(spriteIndex + 1)].sCount; part.frame = rand() % level->spriteSequences[-(spriteIndex + 1)].sCount;
particles.push(part); particles.push(part);
game->playSound(TR::SND_LAVA, pos, Sound::PAN); game->playSound(TR::SND_LAVA, pos, Sound::PAN);
timer += 1.0f / 30.0f; timer += 1.0f / 30.0f;
} else { } else {
timer -= Core::deltaTime; timer -= Core::deltaTime;
} }
}
TR::Level *level = game->getLevel();
for (int i = 0; i < particles.length; i++) { for (int i = 0; i < particles.length; i++) {
particles[i].update(level, lara); particles[i].update(level, lara);
if (particles[i].bounces > LAVA_PARTICLE_BOUNCES) { if (particles[i].frame < 0) {
particles.removeFast(i); particles.removeFast(i);
i--; i--;
} }
@@ -372,7 +390,7 @@ struct TrapLavaEmitter : Controller {
for (int i = 0; i < particles.length; i++) { for (int i = 0; i < particles.length; i++) {
Particle &part = particles[i]; Particle &part = particles[i];
uint8 intensity = clamp(int(max(0.0f, 1.0f - part.bounces * 0.25f) * 0.5f * 255.0f), 0, 255); uint8 intensity = clamp(int(part.frame * 0.18f * 255.0f), 0, 255);
Color32 color(intensity, intensity, intensity, 255); Color32 color(intensity, intensity, intensity, 255);
vec3 p = part.pos - Core::viewPos.xyz(); vec3 p = part.pos - Core::viewPos.xyz();
@@ -1599,7 +1617,7 @@ struct Explosion : Sprite {
Explosion(IGame *game, int entity) : Sprite(game, entity, true, Sprite::FRAME_ANIMATED) { Explosion(IGame *game, int entity) : Sprite(game, entity, true, Sprite::FRAME_ANIMATED) {
game->playSound(TR::SND_EXPLOSION, pos, Sound::PAN); game->playSound(TR::SND_EXPLOSION, pos, Sound::PAN);
game->getLevel()->spriteSequences[-(getEntity().modelIndex + 1)].transp = 2; // fix blending mode to additive level->spriteSequences[-(getEntity().modelIndex + 1)].transp = 2; // fix blending mode to additive
} }
virtual bool getSaveData(SaveEntity &data) { virtual bool getSaveData(SaveEntity &data) {
@@ -1708,7 +1726,7 @@ struct Bullet : Controller {
//getRoom().removeDynLight(entity); //getRoom().removeDynLight(entity);
pos = pos + velocity * Core::deltaTime; pos = pos + velocity * Core::deltaTime;
game->getLevel()->getSector(roomIndex, pos); level->getSector(roomIndex, pos);
Controller::update(); Controller::update();
//getRoom().addDynLight(entity, pos, vec4(1, 1, 0, 1.0f / 1024.0f)); //getRoom().addDynLight(entity, pos, vec4(1, 1, 0, 1.0f / 1024.0f));