1
0
mirror of https://github.com/XProger/OpenLara.git synced 2025-08-06 21:26:56 +02:00

#22 swinging blade trap

This commit is contained in:
XProger
2017-09-11 05:08:46 +03:00
parent d1c0d679b9
commit 7e22dbe6bb
4 changed files with 57 additions and 12 deletions

View File

@@ -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) {}

View File

@@ -304,6 +304,7 @@ namespace TR {
enum HitType {
HIT_DEFAULT,
HIT_BLADE,
HIT_BOULDER,
HIT_SPIKES,
HIT_REX,

View File

@@ -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;
}

View File

@@ -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);