diff --git a/src/controller.h b/src/controller.h index f59e012..21636ea 100644 --- a/src/controller.h +++ b/src/controller.h @@ -448,6 +448,11 @@ struct Controller { return pos; } + bool checkRange(Controller *target, float range) { + vec3 d = target->pos - pos; + return fabsf(d.x) < range && fabsf(d.z) < range && fabsf(d.y) < range; + } + virtual void hit(float damage, Controller *enemy = NULL, TR::HitType hitType = TR::HIT_DEFAULT) {} virtual void doCustomCommand (int curFrame, int prevFrame) {} diff --git a/src/format.h b/src/format.h index aedc437..85570db 100644 --- a/src/format.h +++ b/src/format.h @@ -304,6 +304,7 @@ namespace TR { enum HitType { HIT_DEFAULT, + HIT_BLADE, HIT_BOULDER, HIT_SPIKES, HIT_REX, diff --git a/src/lara.h b/src/lara.h index 9629c3b..2148d99 100644 --- a/src/lara.h +++ b/src/lara.h @@ -443,7 +443,7 @@ struct Lara : Character { //reset(33, vec3(48229, 4608, 78420), 270 * DEG2RAD); // level 1 (end) //reset(15, vec3(70067, -256, 29104), -0.68f); // level 2 (pool) //reset(26, vec3(71980, 1546, 19000), 270 * DEG2RAD); // level 2 (underwater switch) - //reset(61, vec3(27221, -1024, 29205), PI * 0.5f); // level 2 (blade) + //reset(61, vec3(27221, -1024, 29205), -PI * 0.5f); // level 2 (blade) //reset(43, vec3(31400, -2560, 25200), PI); // level 2 (reach) //reset(16, vec3(60907, 0, 39642), PI * 3 / 2); // level 2 (hang & climb) //reset(19, vec3(60843, 1024, 30557), PI); // level 2 (block) @@ -1292,8 +1292,8 @@ struct Lara : Character { } } - void addBlood(float radius, const vec3 &spriteVelocity) { - vec3 p = pos + vec3((randf() * 2.0f - 1.0f) * radius, -randf() * 512.0f, (randf() * 2.0f - 1.0f) * radius); + void addBlood(float radius, float height, const vec3 &spriteVelocity) { + vec3 p = pos + vec3((randf() * 2.0f - 1.0f) * radius, -randf() * height, (randf() * 2.0f - 1.0f) * radius); int index = Sprite::add(game, TR::Entity::BLOOD, getRoomIndex(), int(p.x), int(p.y), int(p.z), Sprite::FRAME_ANIMATED); if (index > -1) ((Sprite*)level->entities[index].controller)->velocity = spriteVelocity; @@ -1301,9 +1301,15 @@ struct Lara : Character { void addBloodSpikes() { float ang = randf() * PI * 2.0f; - addBlood(64.0f, vec3(sinf(ang), 0.0f, cosf(ang)) * 20.0f); + addBlood(64.0f, 512.0f, vec3(sinf(ang), 0.0f, cosf(ang)) * 20.0f); } + void addBloodBlade() { + float ang = angle.y + (randf() - 0.5f) * 30.0f * DEG2RAD; + addBlood(64.0f, 744.0f, vec3(sinf(ang), 0.0f, cosf(ang)) * speed); + } + + virtual void hit(float damage, Controller *enemy = NULL, TR::HitType hitType = TR::HIT_DEFAULT) { if (dozy) return; @@ -1313,11 +1319,14 @@ struct Lara : Character { Character::hit(damage, enemy, hitType); - if (health > 0.0f) { - if (hitType == TR::HIT_SPIKES) - addBloodSpikes(); + if (hitType == TR::HIT_BLADE) + addBloodBlade(); + + if (hitType == TR::HIT_SPIKES) + addBloodSpikes(); + + if (health > 0.0f) return; - } switch (hitType) { case TR::HIT_BOULDER : { @@ -1330,13 +1339,13 @@ struct Lara : Character { angle.x = -acos(d.dot(v)); v = ((TrapBoulder*)enemy)->velocity * 2.0f; for (int i = 0; i < 15; i++) - addBlood(256.0f, v); + addBlood(256.0f, 512.0f, v); break; } case TR::HIT_SPIKES : { pos.y = enemy->pos.y; animation.setAnim(ANIM_DEATH_SPIKES); - for (int i = 0; i < 20; i++) + for (int i = 0; i < 19; i++) addBloodSpikes(); break; } diff --git a/src/trigger.h b/src/trigger.h index c4639ff..1c68142 100644 --- a/src/trigger.h +++ b/src/trigger.h @@ -521,16 +521,46 @@ struct Crystal : Controller { } }; +#define BLADE_DAMAGE 100 +#define BLADE_RANGE 1024 + struct TrapBlade : Controller { + enum { + STATE_STATIC = 0, + STATE_SWING = 2, + }; + TrapBlade(IGame *game, int entity) : Controller(game, entity) {} virtual void update() { updateAnimation(true); + + if (isActive()) { + if (state == STATE_STATIC) + animation.setState(STATE_SWING); + } else { + if (state == STATE_SWING) + animation.setState(STATE_STATIC); + } + + if (state != STATE_SWING) + return; + + int f = animation.frameIndex; + if ((f <= 8 || f >= 20) && (f <= 42 || f >= 57)) + return; + + Character* lara = (Character*)level->laraController; + if (!checkRange(lara, BLADE_RANGE) || !collide(lara)) + return; + + lara->hit(BLADE_DAMAGE * 30.0f * Core::deltaTime, this, TR::HIT_BLADE); } }; #define SPIKES_DAMAGE_FALL 1000 #define SPIKES_DAMAGE_RUN 15 +#define SPIKES_RANGE 1024 struct TrapSpikes : Controller { TrapSpikes(IGame *game, int entity) : Controller(game, entity) { @@ -541,10 +571,10 @@ struct TrapSpikes : Controller { Character *lara = (Character*)level->laraController; if (lara->health <= 0.0f) return; - if (!collide(lara)) + if (!checkRange(lara, SPIKES_RANGE) || !collide(lara)) return; - if (lara->stand != Character::STAND_AIR || lara->velocity.y <= 0.0f || (pos.y - lara->pos.y) > 128.0f) { + if (lara->stand != Character::STAND_AIR || lara->velocity.y <= 0.0f || (pos.y - lara->pos.y) > 256.0f) { if (lara->speed < 30.0f) return; lara->hit(SPIKES_DAMAGE_RUN * 30.0f * Core::deltaTime, this, TR::HIT_SPIKES);