From e9a88ce5b1601e6269812d071a82200439d15391 Mon Sep 17 00:00:00 2001 From: XProger Date: Thu, 28 Sep 2017 07:29:12 +0300 Subject: [PATCH] #3 falling death and damage, fix sound modes --- src/enemy.h | 4 ++-- src/format.h | 3 ++- src/lara.h | 30 +++++++++++++++++++++++++++++- src/level.h | 18 +++++++++++------- src/sound.h | 16 ++++++++-------- 5 files changed, 52 insertions(+), 19 deletions(-) diff --git a/src/enemy.h b/src/enemy.h index 5fd5e5b..f3a4865 100644 --- a/src/enemy.h +++ b/src/enemy.h @@ -92,7 +92,7 @@ struct Enemy : Character { velocity = getDir() * animation.getSpeed(); if (health <= 0.0f) - velocity.x = velocity.y = 0.0f; + velocity.x = velocity.z = 0.0f; } bool checkPoint(int x, int z) { @@ -147,7 +147,7 @@ struct Enemy : Character { level->getFloorInfo(getRoomIndex(), int(pos.x), int(pos.y), int(pos.z), info); if (stand == STAND_AIR && !flying && info.floor < pos.y) { stand = STAND_GROUND; - pos.y = info.floor; + pos.y = float(info.floor); } if (info.boxIndex != 0xFFFF && zone == getZones()[info.boxIndex] && !level->boxes[info.boxIndex].overlap.block) { diff --git a/src/format.h b/src/format.h index d9758c1..3285fff 100644 --- a/src/format.h +++ b/src/format.h @@ -323,6 +323,7 @@ namespace TR { enum HitType { HIT_DEFAULT, + HIT_FALL, HIT_BLADE, HIT_BOULDER, HIT_SPIKES, @@ -951,7 +952,7 @@ namespace TR { uint16 volume; uint16 chance; // If !=0 and ((rand()&0x7fff) > Chance), this sound is not played union { - struct { uint16 mode:2, count:4, unused:6, fixed:1, pitch:1, gain:1, :1; }; + struct { uint16 mode:2, count:4, unused:6, camera:1, pitch:1, gain:1, :1; }; uint16 value; } flags; }; diff --git a/src/lara.h b/src/lara.h index dfaaa74..ee14de1 100644 --- a/src/lara.h +++ b/src/lara.h @@ -1354,6 +1354,10 @@ struct Lara : Character { return; switch (hitType) { + case TR::HIT_FALL : { + animation.setState(STATE_DEATH); + break; + } case TR::HIT_BOULDER : { animation.setAnim(ANIM_DEATH_BOULDER); if (enemy) @@ -1854,6 +1858,19 @@ struct Lara : Character { if (stand != STAND_GROUND) { pos.y = float(info.floor); updateEntity(); + // get damage from falling + if (velocity.y > 0.0f) { + if (state == STATE_FAST_DIVE && velocity.y > 133.0f) { + hit(health + 1.0f, NULL, TR::HIT_FALL); + } else { + float v = velocity.y - 140.0f; + if (v > 14.0f) + hit(health + 1.0f, NULL, TR::HIT_FALL); + else + if (v > 0.0f) + hit(v * v * LARA_MAX_HEALTH / 196.0f, NULL, TR::HIT_FALL); + } + } } return STAND_GROUND; } @@ -1870,6 +1887,9 @@ struct Lara : Character { virtual int getStateAir() { angle.x = 0.0f; + if (velocity.y > 131.0f && state != STATE_SWAN_DIVE && state != STATE_FAST_DIVE) + return STATE_FALL; + if (state == STATE_REACH && getDir().dot(vec3(velocity.x, 0.0f, velocity.z)) < 0) velocity.x = velocity.z = 0.0f; @@ -2412,7 +2432,15 @@ struct Lara : Character { switch (stand) { case STAND_AIR : - velocity.y += GRAVITY * Core::deltaTime; + velocity.y += (velocity.y >= 128.0f ? 30.0f : GRAVITY) * Core::deltaTime; + if (velocity.y >= 154.0f) + playSound(TR::SND_SCREAM, pos, Sound::PAN); + /* + if (state == STATE_FALL || state == STATE_FAST_DIVE) { + velocity.x *= 0.95 * Core::deltaTime; + velocity.z *= 0.95 * Core::deltaTime; + } + */ break; case STAND_GROUND : case STAND_SLIDE : diff --git a/src/level.h b/src/level.h index a672ca5..f243a4d 100644 --- a/src/level.h +++ b/src/level.h @@ -281,12 +281,16 @@ struct Level : IGame { if (b.chance == 0 || (rand() & 0x7fff) <= b.chance) { int index = b.offset + rand() % b.flags.count; float volume = (float)b.volume / 0x7FFF; - float pitch = b.flags.pitch ? (0.9f + randf() * 0.2f) : 1.0f; - if (b.flags.mode == 1) flags |= Sound::UNIQUE; - //if (b.flags.mode == 2) flags |= Sound::REPLAY; - if (b.flags.mode == 3) flags |= Sound::SYNC; + float pitch = b.flags.pitch ? (0.9f + randf() * 0.2f) : 1.0f; + if (!(flags & Sound::MUSIC)) { + switch (b.flags.mode) { + case 0 : flags |= Sound::UNIQUE; break; + case 1 : flags |= Sound::REPLAY; break; + case 2 : flags |= Sound::STATIC | Sound::LOOP; break; + } + } if (b.flags.gain) volume = max(0.0f, volume - randf() * 0.25f); - if (b.flags.fixed) flags |= Sound::LOOP; + if (b.flags.camera) flags &= ~Sound::PAN; return Sound::play(level.getSampleStream(index), pos, volume, pitch, flags, group * 1000 + index); } return NULL; @@ -535,7 +539,7 @@ struct Level : IGame { for (int i = 0; i < level.soundSourcesCount; i++) { TR::SoundSource &src = level.soundSources[i]; - lara->playSound(src.id, vec3(float(src.x), float(src.y), float(src.z)), Sound::PAN | Sound::LOOP | Sound::STATIC); + lara->playSound(src.id, vec3(float(src.x), float(src.y), float(src.z)), Sound::PAN); } lastTitle = false; @@ -951,7 +955,7 @@ struct Level : IGame { type = Shader::MIRROR; if (type == Shader::SPRITE) { - float alpha = (entity.type == TR::Entity::SMOKE || entity.type == TR::Entity::WATER_SPLASH) ? 0.75f : 1.0; + float alpha = (entity.type == TR::Entity::SMOKE || entity.type == TR::Entity::WATER_SPLASH) ? 0.75f : 1.0f; float diffuse = entity.isItem() ? 1.0f : 0.5f; setRoomParams(roomIndex, type, diffuse, intensityf(lum), controller->specular, alpha, isModel ? !mesh->models[entity.modelIndex - 1].opaque : true); } else diff --git a/src/sound.h b/src/sound.h index 65d8254..85d845b 100644 --- a/src/sound.h +++ b/src/sound.h @@ -412,9 +412,8 @@ namespace Sound { PAN = 2, UNIQUE = 4, REPLAY = 8, - SYNC = 16, - STATIC = 32, - MUSIC = 64, + STATIC = 16, + MUSIC = 32, }; struct Sample { @@ -602,7 +601,7 @@ namespace Sound { for (int i = 0; i < channelsCount; i++) { if (music != ((channels[i]->flags & MUSIC) != 0)) continue; - + if (channels[i]->flags & STATIC) { vec3 d = channels[i]->pos - listener.matrix.getPos(); if (fabsf(d.x) > SND_FADEOFF_DIST || fabsf(d.y) > SND_FADEOFF_DIST || fabsf(d.z) > SND_FADEOFF_DIST) @@ -697,13 +696,14 @@ namespace Sound { Sample* play(Stream *stream, const vec3 &pos, float volume = 1.0f, float pitch = 0.0f, int flags = 0, int id = - 1) { if (!stream) return NULL; if (volume > 0.001f) { - if (flags & (REPLAY | SYNC | UNIQUE)) + if (flags & (UNIQUE | REPLAY)) for (int i = 0; i < channelsCount; i++) if (channels[i]->id == id) { - channels[i]->pos = pos; - channels[i]->pitch = pitch; - if (flags & (REPLAY | UNIQUE)) + if (!(flags & UNIQUE)) { + channels[i]->pos = pos; + channels[i]->pitch = pitch; channels[i]->replay(); + } delete stream; return channels[i]; }