1
0
mirror of https://github.com/XProger/OpenLara.git synced 2025-02-24 23:42:49 +01:00

#22 spike trap

This commit is contained in:
XProger 2017-09-11 03:53:11 +03:00
parent bb6959b0fa
commit d1c0d679b9
9 changed files with 104 additions and 57 deletions

View File

@ -2,7 +2,6 @@
#define H_CHARACTER
#include "controller.h"
#include "trigger.h"
struct Character : Controller {
float health;
@ -82,7 +81,7 @@ struct Character : Controller {
angle.x = clamp(angle.x + delta, -PI * 0.49f, PI * 0.49f);
}
virtual void hit(float damage, Controller *enemy = NULL) {
virtual void hit(float damage, Controller *enemy = NULL, TR::HitType hitType = TR::HIT_DEFAULT) {
health = max(0.0f, health - damage);
}

View File

@ -448,7 +448,7 @@ struct Controller {
return pos;
}
virtual void hit(float damage, Controller *enemy = NULL) {}
virtual void hit(float damage, Controller *enemy = NULL, TR::HitType hitType = TR::HIT_DEFAULT) {}
virtual void doCustomCommand (int curFrame, int prevFrame) {}
virtual void checkRoom() {}

View File

@ -218,8 +218,8 @@ struct Enemy : Character {
return 0;
}
virtual void hit(float damage, Controller *enemy = NULL) {
Character::hit(damage, enemy);
virtual void hit(float damage, Controller *enemy = NULL, TR::HitType hitType = TR::HIT_DEFAULT) {
Character::hit(damage, enemy, hitType);
wound = true;
};
@ -836,7 +836,7 @@ struct Bat : Enemy {
#define REX_DIST_WALK 5120
#define REX_TURN_FAST (DEG2RAD * 120)
#define REX_TURN_SLOW (DEG2RAD * 60)
#define REX_DAMAGE 10000
#define REX_DAMAGE 1000
struct Rex : Enemy {
@ -912,7 +912,7 @@ struct Rex : Enemy {
break;
case STATE_BITE :
if (mask & HIT_MASK) {
target->hit(REX_DAMAGE, this);
target->hit(REX_DAMAGE, this, TR::HIT_REX);
return STATE_FATAL;
}
nextState = STATE_WALK;

View File

@ -54,7 +54,7 @@
E( TRAP_DARTGUN ) \
E( DOOR_LIFT ) \
E( TRAP_SLAM ) \
E( FALLING_SWORD ) \
E( TRAP_SWORD ) \
E( HAMMER_HANDLE ) \
E( HAMMER_BLOCK ) \
E( LIGHTNING_BALL ) \
@ -64,8 +64,8 @@
E( BLOCK_3 ) \
E( BLOCK_4 ) \
E( MOVING_BLOCK ) \
E( FALLING_CEILING_1 ) \
E( FALLING_CEILING_2 ) \
E( TRAP_CEILING_1 ) \
E( TRAP_CEILING_2 ) \
E( SWITCH ) \
E( SWITCH_WATER ) \
E( DOOR_1 ) \
@ -302,6 +302,13 @@ namespace TR {
MODEL_LARA_SPEC = 5,
};
enum HitType {
HIT_DEFAULT,
HIT_BOULDER,
HIT_SPIKES,
HIT_REX,
};
enum Action : uint16 {
ACTIVATE , // activate item
CAMERA_SWITCH , // switch to camera

View File

@ -108,6 +108,7 @@ struct Lara : Character {
ANIM_STAND_ROLL_BEGIN = 146,
ANIM_STAND_ROLL_END = 147,
ANIM_DEATH_SPIKES = 149,
ANIM_HANG_SWING = 150,
};
@ -434,10 +435,10 @@ struct Lara : Character {
//reset(9, vec3(63008, 0, 37787), 0); // level 2 (switch)
//reset(5, vec3(38643, -3072, 92370), PI * 0.5f); // level 3a (gears)
//reset(15, vec3(70067, -256, 29104), -0.68f); // level 2 (pool)
//reset(0, vec3(74858, 3072, 20795), 0); // level 1 (dart)
//reset(26, vec3(24475, 6912, 83505), 90 * DEG2RAD); // level 1 (switch timer)
#ifdef _DEBUG
//reset(14, vec3(40448, 3584, 60928), PI * 0.5f, STAND_ONWATER); // gym (pool)
//reset(0, vec3(74858, 3072, 20795), 0); // level 1 (dart)
//reset(14, vec3(20215, 6656, 52942), PI); // level 1 (bridge)
//reset(33, vec3(48229, 4608, 78420), 270 * DEG2RAD); // level 1 (end)
//reset(15, vec3(70067, -256, 29104), -0.68f); // level 2 (pool)
@ -454,6 +455,7 @@ struct Lara : Character {
//reset(51, vec3(41015, 3584, 34494), -PI); // level 3a (t-rex)
//reset(5, vec3(38643, -3072, 92370), PI * 0.5f); // level 3a (gears)
//reset(43, vec3(64037, 6656, 48229), PI); // level 3b (movingblock)
//reset(27, vec3(72372, 8704, 46547), PI * 0.5f); // level 3b (spikes)
//reset(5, vec3(73394, 3840, 60758), 0); // level 3b (scion)
//reset(20, vec3(57724, 6656, 61941), 90 * DEG2RAD); // level 3b (boulder)
//reset(99, vec3(45562, -3328, 63366), 225 * DEG2RAD); // level 7a (flipmap)
@ -1290,36 +1292,55 @@ struct Lara : Character {
}
}
virtual void hit(float damage, Controller *enemy = NULL) {
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);
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;
}
void addBloodSpikes() {
float ang = randf() * PI * 2.0f;
addBlood(64.0f, vec3(sinf(ang), 0.0f, cosf(ang)) * 20.0f);
}
virtual void hit(float damage, Controller *enemy = NULL, TR::HitType hitType = TR::HIT_DEFAULT) {
if (dozy) return;
if (health <= 0.0f) return;
damageTime = LARA_DAMAGE_TIME;
if (health > 0.0f) {
if (damage == BOULDER_DAMAGE_GROUND) {
if (stand == STAND_GROUND) {
animation.setAnim(level->models[TR::MODEL_LARA_SPEC].animation + 2);
angle = enemy->angle;
TR::Level::FloorInfo info;
level->getFloorInfo(getRoomIndex(), int(pos.x), int(pos.y), int(pos.z), info);
vec3 d = getDir();
vec3 v = info.getSlant(d);
angle.x = -acos(d.dot(v));
int roomIndex = getRoomIndex();
v = ((TrapBoulder*)enemy)->velocity * 60.0f;
for (int i = 0; i < 15; i++) {
vec3 p = pos + vec3(randf() * 512.0f - 256.0f, -randf() * 512.0f, randf() * 512.0f - 256.0f);
int index = Sprite::add(game, TR::Entity::BLOOD, roomIndex, int(p.x), int(p.y), int(p.z), Sprite::FRAME_ANIMATED);
if (index > -1)
((Sprite*)level->entities[index].controller)->velocity = v;
}
} else if (stand == STAND_AIR) {
damage = BOULDER_DAMAGE_AIR * 30.0f * Core::deltaTime;
} else
damage = 0;
}
Character::hit(damage, enemy, hitType);
if (damage == REX_DAMAGE) { // T-Rex attack (fatal)
if (health > 0.0f) {
if (hitType == TR::HIT_SPIKES)
addBloodSpikes();
return;
}
switch (hitType) {
case TR::HIT_BOULDER : {
animation.setAnim(level->models[TR::MODEL_LARA_SPEC].animation + 2);
angle = enemy->angle;
TR::Level::FloorInfo info;
level->getFloorInfo(getRoomIndex(), int(pos.x), int(pos.y), int(pos.z), info);
vec3 d = getDir();
vec3 v = info.getSlant(d);
angle.x = -acos(d.dot(v));
v = ((TrapBoulder*)enemy)->velocity * 2.0f;
for (int i = 0; i < 15; i++)
addBlood(256.0f, v);
break;
}
case TR::HIT_SPIKES : {
pos.y = enemy->pos.y;
animation.setAnim(ANIM_DEATH_SPIKES);
for (int i = 0; i < 20; i++)
addBloodSpikes();
break;
}
case TR::HIT_REX : {
pos = enemy->pos;
angle = enemy->angle;
@ -1328,13 +1349,12 @@ struct Lara : Character {
meshSwap(3, level->extra.weapons[Weapon::UZIS], 0);
animation.setAnim(level->models[TR::MODEL_LARA_SPEC].animation + 1);
break;
}
Character::hit(damage, enemy);
default : ;
}
if (health <= 0)
Core::lightColor[1 + 0] = Core::lightColor[1 + 1] = vec4(0, 0, 0, 1);
Core::lightColor[1 + 0] = Core::lightColor[1 + 1] = vec4(0, 0, 0, 1);
};
bool useItem(TR::Entity::Type item) {

View File

@ -336,12 +336,12 @@ struct Level : IGame {
case TR::Entity::MOVING_BLOCK :
entity.controller = new MovingBlock(this, i);
break;
case TR::Entity::FALLING_CEILING_1 :
case TR::Entity::FALLING_CEILING_2 :
entity.controller = new FallingCeiling(this, i);
case TR::Entity::TRAP_CEILING_1 :
case TR::Entity::TRAP_CEILING_2 :
entity.controller = new TrapCeiling(this, i);
break;
case TR::Entity::FALLING_SWORD :
entity.controller = new FallingSword(this, i);
case TR::Entity::TRAP_SWORD :
entity.controller = new TrapSword(this, i);
break;
case TR::Entity::SWITCH :
case TR::Entity::SWITCH_WATER :

View File

@ -107,7 +107,7 @@
<input type="button" value="Browse Level" onclick="document.getElementById('browseFile').click();" /> (.PHD, .PSX)
<p style="margin:8px">
OpenLara on <a target="_blank" href="https://github.com/XProger/OpenLara">github</a> & <a target="_blank" href="https://www.facebook.com/OpenLaraTR">facebook</a><br>
<br><i>last update: 9.09.2017</i><br>
<br><i>last update: 11.09.2017</i><br>
</p>
</span>

View File

@ -58,7 +58,7 @@ struct Sprite : Controller {
if (instant && time >= (1.0f / SPRITE_FPS))
remove = true;
pos += velocity * Core::deltaTime;
pos += velocity * (30.0f * Core::deltaTime);
if (remove) {
level->entityRemove(entity);

View File

@ -3,6 +3,7 @@
#include "core.h"
#include "controller.h"
#include "character.h"
#include "sprite.h"
struct Switch : Controller {
@ -136,7 +137,7 @@ struct TrapDartgun : Controller {
}
};
#define BOULDER_DAMAGE_GROUND 1001
#define BOULDER_DAMAGE_GROUND 1000
#define BOULDER_DAMAGE_AIR 100
struct TrapBoulder : Controller {
@ -183,9 +184,13 @@ struct TrapBoulder : Controller {
return;
}
Controller *lara = (Controller*)level->laraController;
if (collide(lara))
lara->hit(BOULDER_DAMAGE_GROUND, this);
Character *lara = (Character*)level->laraController;
if (lara->health > 0.0f && collide(lara)) {
if (lara->stand == Character::STAND_GROUND)
lara->hit(BOULDER_DAMAGE_GROUND, this, TR::HIT_BOULDER);
if (lara->stand == Character::STAND_AIR)
lara->hit(BOULDER_DAMAGE_AIR * 30.0f * Core::deltaTime, this);
}
updateAnimation(true);
updateEntity();
@ -524,15 +529,31 @@ struct TrapBlade : Controller {
}
};
#define SPIKES_DAMAGE_FALL 1000
#define SPIKES_DAMAGE_RUN 15
struct TrapSpikes : Controller {
TrapSpikes(IGame *game, int entity) : Controller(game, entity) {}
TrapSpikes(IGame *game, int entity) : Controller(game, entity) {
activate();
}
virtual void update() {
updateAnimation(true);
Character *lara = (Character*)level->laraController;
if (lara->health <= 0.0f) return;
if (!collide(lara))
return;
if (lara->stand != Character::STAND_AIR || lara->velocity.y <= 0.0f || (pos.y - lara->pos.y) > 128.0f) {
if (lara->speed < 30.0f)
return;
lara->hit(SPIKES_DAMAGE_RUN * 30.0f * Core::deltaTime, this, TR::HIT_SPIKES);
} else
lara->hit(SPIKES_DAMAGE_FALL, this, TR::HIT_SPIKES);
}
};
struct FallingCeiling : Controller {
struct TrapCeiling : Controller {
enum {
STATE_STATIC,
STATE_FALL,
@ -541,7 +562,7 @@ struct FallingCeiling : Controller {
float speed;
FallingCeiling(IGame *game, int entity) : Controller(game, entity), speed(0) {}
TrapCeiling(IGame *game, int entity) : Controller(game, entity), speed(0) {}
virtual void update() {
updateAnimation(true);
@ -573,8 +594,8 @@ struct FallingCeiling : Controller {
};
struct FallingSword : Controller {
FallingSword(IGame *game, int entity) : Controller(game, entity) {}
struct TrapSword : Controller {
TrapSword(IGame *game, int entity) : Controller(game, entity) {}
virtual void update() {
updateAnimation(true);