diff --git a/src/enemy.h b/src/enemy.h index 6721cce..192c0cd 100644 --- a/src/enemy.h +++ b/src/enemy.h @@ -1260,15 +1260,34 @@ struct Doppelganger : Enemy { struct ScionTarget : Enemy { - ScionTarget(IGame *game, int entity) : Enemy(game, entity, 5, 0, 0, 0) {} + float timer; + + ScionTarget(IGame *game, int entity) : Enemy(game, entity, 5, 0, 0, 0), timer(0.0f) {} virtual void update() { Controller::update(); if (health <= 0.0f) { - getEntity().flags.invisible = true; - game->checkTrigger(this, true); - deactivate(); + if (timer == 0.0f) { + getEntity().flags.invisible = true; + game->checkTrigger(this, true); + timer = 3.0f; + } + + if (timer > 0.0f) { + int index = int(timer / 0.3f); + timer -= Core::deltaTime; + + if (index != int(timer / 0.3f)) { + vec3 p = pos + vec3((randf() * 2.0f - 1.0f) * 512.0f, (randf() * 2.0f - 1.0f) * 64.0f - 500.0f, (randf() * 2.0f - 1.0f) * 512.0f); + game->addSprite(TR::Entity::EXPLOSION, getRoomIndex(), int(p.x), int(p.y), int(p.z)); + game->playSound(TR::SND_EXPLOSION, pos, 0); + game->getCamera()->shake = 0.5f; + } + + if (timer < 0.0f) + deactivate(true); + } } } }; diff --git a/src/format.h b/src/format.h index 6be8b0a..afd8886 100644 --- a/src/format.h +++ b/src/format.h @@ -57,7 +57,7 @@ E( TRAP_SWORD ) \ E( HAMMER_HANDLE ) \ E( HAMMER_BLOCK ) \ - E( LIGHTNING_BALL ) \ + E( LIGHTNING ) \ E( DOOR_LATCH ) \ E( BLOCK_1 ) \ E( BLOCK_2 ) \ @@ -276,6 +276,7 @@ namespace TR { SND_HIT_RAT = 95, + SND_LIGHTNING = 98, SND_ROCK = 99, SND_EXPLOSION = 104, @@ -336,6 +337,7 @@ namespace TR { HIT_LAVA, HIT_SLAM, HIT_REX, + HIT_LIGHTNING, }; enum Action : uint16 { diff --git a/src/lara.h b/src/lara.h index 4210392..72e4c4d 100644 --- a/src/lara.h +++ b/src/lara.h @@ -2320,6 +2320,10 @@ struct Lara : Character { if (Input::state[cAction]) input |= ACTION; if (Input::state[cWeapon]) input |= WEAPON; + // scion debug (TODO: remove) + if (Input::down[ikP] && level->id == TR::LEVEL_3B) + reset(5, vec3(73394, 3840, 60758), 0); // level 3b (scion) + // analog control rotFactor = vec2(1.0f); diff --git a/src/level.h b/src/level.h index b1e99eb..9e07464 100644 --- a/src/level.h +++ b/src/level.h @@ -477,6 +477,7 @@ struct Level : IGame { case TR::Entity::TRAP_SLAM : return new TrapSlam(this, index); case TR::Entity::TRAP_SWORD : return new TrapSword(this, index); case TR::Entity::HAMMER_HANDLE : return new ThorHammer(this, index); + case TR::Entity::LIGHTNING : return new Lightning(this, index); case TR::Entity::DOOR_LATCH : return new DoorLatch(this, index); case TR::Entity::SWITCH : case TR::Entity::SWITCH_WATER : return new Switch(this, index); diff --git a/src/trigger.h b/src/trigger.h index 54ecc05..987bd14 100644 --- a/src/trigger.h +++ b/src/trigger.h @@ -836,6 +836,60 @@ struct ThorHammer : Controller { }; +#define LIGHTNING_DAMAGE 400 + +struct Lightning : Controller { + Basis target; + float timer; + bool flash; + bool armed; + + Lightning(IGame *game, int entity) : Controller(game, entity), timer(0), flash(false) {} + + virtual void update() { + if (isActive()) { + timer -= Core::deltaTime; + + if (timer <= 0.0f) { + if (flash) { + level->isFlipped = false; + flash = false; + armed = true; + timer = (35.0f + randf() * 45.0f) / 30.0f; + } else { + level->isFlipped = true; + 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) { + // + } else + animation.getJoints(getMatrix(), int(randf() * 5), false, &target); + } + game->playSound(TR::SND_LIGHTNING, pos, Sound::PAN); + } + } else { + timer = 0.0f; + flash = false; + level->isFlipped = false; + deactivate(true); + } + } + + virtual void render(Frustum *frustum, MeshBuilder *mesh, Shader::Type type, bool caustics) { + Controller::render(frustum, mesh, type, caustics); + if (!flash) return; + // TODO + } +}; + struct TrapLava : Controller { bool done;