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:
parent
bb6959b0fa
commit
d1c0d679b9
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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() {}
|
||||
|
@ -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;
|
||||
|
13
src/format.h
13
src/format.h
@ -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
|
||||
|
80
src/lara.h
80
src/lara.h
@ -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) {
|
||||
|
10
src/level.h
10
src/level.h
@ -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 :
|
||||
|
@ -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>
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
Loading…
x
Reference in New Issue
Block a user