mirror of
https://github.com/XProger/OpenLara.git
synced 2025-08-12 16:14:25 +02:00
#22 spike trap
This commit is contained in:
@@ -2,7 +2,6 @@
|
|||||||
#define H_CHARACTER
|
#define H_CHARACTER
|
||||||
|
|
||||||
#include "controller.h"
|
#include "controller.h"
|
||||||
#include "trigger.h"
|
|
||||||
|
|
||||||
struct Character : Controller {
|
struct Character : Controller {
|
||||||
float health;
|
float health;
|
||||||
@@ -82,7 +81,7 @@ struct Character : Controller {
|
|||||||
angle.x = clamp(angle.x + delta, -PI * 0.49f, PI * 0.49f);
|
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);
|
health = max(0.0f, health - damage);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -448,7 +448,7 @@ struct Controller {
|
|||||||
return pos;
|
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 doCustomCommand (int curFrame, int prevFrame) {}
|
||||||
virtual void checkRoom() {}
|
virtual void checkRoom() {}
|
||||||
|
@@ -218,8 +218,8 @@ struct Enemy : Character {
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void hit(float damage, Controller *enemy = NULL) {
|
virtual void hit(float damage, Controller *enemy = NULL, TR::HitType hitType = TR::HIT_DEFAULT) {
|
||||||
Character::hit(damage, enemy);
|
Character::hit(damage, enemy, hitType);
|
||||||
wound = true;
|
wound = true;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -836,7 +836,7 @@ struct Bat : Enemy {
|
|||||||
#define REX_DIST_WALK 5120
|
#define REX_DIST_WALK 5120
|
||||||
#define REX_TURN_FAST (DEG2RAD * 120)
|
#define REX_TURN_FAST (DEG2RAD * 120)
|
||||||
#define REX_TURN_SLOW (DEG2RAD * 60)
|
#define REX_TURN_SLOW (DEG2RAD * 60)
|
||||||
#define REX_DAMAGE 10000
|
#define REX_DAMAGE 1000
|
||||||
|
|
||||||
struct Rex : Enemy {
|
struct Rex : Enemy {
|
||||||
|
|
||||||
@@ -912,7 +912,7 @@ struct Rex : Enemy {
|
|||||||
break;
|
break;
|
||||||
case STATE_BITE :
|
case STATE_BITE :
|
||||||
if (mask & HIT_MASK) {
|
if (mask & HIT_MASK) {
|
||||||
target->hit(REX_DAMAGE, this);
|
target->hit(REX_DAMAGE, this, TR::HIT_REX);
|
||||||
return STATE_FATAL;
|
return STATE_FATAL;
|
||||||
}
|
}
|
||||||
nextState = STATE_WALK;
|
nextState = STATE_WALK;
|
||||||
|
13
src/format.h
13
src/format.h
@@ -54,7 +54,7 @@
|
|||||||
E( TRAP_DARTGUN ) \
|
E( TRAP_DARTGUN ) \
|
||||||
E( DOOR_LIFT ) \
|
E( DOOR_LIFT ) \
|
||||||
E( TRAP_SLAM ) \
|
E( TRAP_SLAM ) \
|
||||||
E( FALLING_SWORD ) \
|
E( TRAP_SWORD ) \
|
||||||
E( HAMMER_HANDLE ) \
|
E( HAMMER_HANDLE ) \
|
||||||
E( HAMMER_BLOCK ) \
|
E( HAMMER_BLOCK ) \
|
||||||
E( LIGHTNING_BALL ) \
|
E( LIGHTNING_BALL ) \
|
||||||
@@ -64,8 +64,8 @@
|
|||||||
E( BLOCK_3 ) \
|
E( BLOCK_3 ) \
|
||||||
E( BLOCK_4 ) \
|
E( BLOCK_4 ) \
|
||||||
E( MOVING_BLOCK ) \
|
E( MOVING_BLOCK ) \
|
||||||
E( FALLING_CEILING_1 ) \
|
E( TRAP_CEILING_1 ) \
|
||||||
E( FALLING_CEILING_2 ) \
|
E( TRAP_CEILING_2 ) \
|
||||||
E( SWITCH ) \
|
E( SWITCH ) \
|
||||||
E( SWITCH_WATER ) \
|
E( SWITCH_WATER ) \
|
||||||
E( DOOR_1 ) \
|
E( DOOR_1 ) \
|
||||||
@@ -302,6 +302,13 @@ namespace TR {
|
|||||||
MODEL_LARA_SPEC = 5,
|
MODEL_LARA_SPEC = 5,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum HitType {
|
||||||
|
HIT_DEFAULT,
|
||||||
|
HIT_BOULDER,
|
||||||
|
HIT_SPIKES,
|
||||||
|
HIT_REX,
|
||||||
|
};
|
||||||
|
|
||||||
enum Action : uint16 {
|
enum Action : uint16 {
|
||||||
ACTIVATE , // activate item
|
ACTIVATE , // activate item
|
||||||
CAMERA_SWITCH , // switch to camera
|
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_BEGIN = 146,
|
||||||
ANIM_STAND_ROLL_END = 147,
|
ANIM_STAND_ROLL_END = 147,
|
||||||
|
|
||||||
|
ANIM_DEATH_SPIKES = 149,
|
||||||
ANIM_HANG_SWING = 150,
|
ANIM_HANG_SWING = 150,
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -434,10 +435,10 @@ struct Lara : Character {
|
|||||||
//reset(9, vec3(63008, 0, 37787), 0); // level 2 (switch)
|
//reset(9, vec3(63008, 0, 37787), 0); // level 2 (switch)
|
||||||
//reset(5, vec3(38643, -3072, 92370), PI * 0.5f); // level 3a (gears)
|
//reset(5, vec3(38643, -3072, 92370), PI * 0.5f); // level 3a (gears)
|
||||||
//reset(15, vec3(70067, -256, 29104), -0.68f); // level 2 (pool)
|
//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)
|
//reset(26, vec3(24475, 6912, 83505), 90 * DEG2RAD); // level 1 (switch timer)
|
||||||
#ifdef _DEBUG
|
#ifdef _DEBUG
|
||||||
//reset(14, vec3(40448, 3584, 60928), PI * 0.5f, STAND_ONWATER); // gym (pool)
|
//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(14, vec3(20215, 6656, 52942), PI); // level 1 (bridge)
|
||||||
//reset(33, vec3(48229, 4608, 78420), 270 * DEG2RAD); // level 1 (end)
|
//reset(33, vec3(48229, 4608, 78420), 270 * DEG2RAD); // level 1 (end)
|
||||||
//reset(15, vec3(70067, -256, 29104), -0.68f); // level 2 (pool)
|
//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(51, vec3(41015, 3584, 34494), -PI); // level 3a (t-rex)
|
||||||
//reset(5, vec3(38643, -3072, 92370), PI * 0.5f); // level 3a (gears)
|
//reset(5, vec3(38643, -3072, 92370), PI * 0.5f); // level 3a (gears)
|
||||||
//reset(43, vec3(64037, 6656, 48229), PI); // level 3b (movingblock)
|
//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(5, vec3(73394, 3840, 60758), 0); // level 3b (scion)
|
||||||
//reset(20, vec3(57724, 6656, 61941), 90 * DEG2RAD); // level 3b (boulder)
|
//reset(20, vec3(57724, 6656, 61941), 90 * DEG2RAD); // level 3b (boulder)
|
||||||
//reset(99, vec3(45562, -3328, 63366), 225 * DEG2RAD); // level 7a (flipmap)
|
//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 (dozy) return;
|
||||||
|
|
||||||
|
if (health <= 0.0f) return;
|
||||||
|
|
||||||
damageTime = LARA_DAMAGE_TIME;
|
damageTime = LARA_DAMAGE_TIME;
|
||||||
|
|
||||||
if (health > 0.0f) {
|
Character::hit(damage, enemy, hitType);
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
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;
|
pos = enemy->pos;
|
||||||
angle = enemy->angle;
|
angle = enemy->angle;
|
||||||
|
|
||||||
@@ -1328,13 +1349,12 @@ struct Lara : Character {
|
|||||||
meshSwap(3, level->extra.weapons[Weapon::UZIS], 0);
|
meshSwap(3, level->extra.weapons[Weapon::UZIS], 0);
|
||||||
|
|
||||||
animation.setAnim(level->models[TR::MODEL_LARA_SPEC].animation + 1);
|
animation.setAnim(level->models[TR::MODEL_LARA_SPEC].animation + 1);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
default : ;
|
||||||
Character::hit(damage, enemy);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
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) {
|
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 :
|
case TR::Entity::MOVING_BLOCK :
|
||||||
entity.controller = new MovingBlock(this, i);
|
entity.controller = new MovingBlock(this, i);
|
||||||
break;
|
break;
|
||||||
case TR::Entity::FALLING_CEILING_1 :
|
case TR::Entity::TRAP_CEILING_1 :
|
||||||
case TR::Entity::FALLING_CEILING_2 :
|
case TR::Entity::TRAP_CEILING_2 :
|
||||||
entity.controller = new FallingCeiling(this, i);
|
entity.controller = new TrapCeiling(this, i);
|
||||||
break;
|
break;
|
||||||
case TR::Entity::FALLING_SWORD :
|
case TR::Entity::TRAP_SWORD :
|
||||||
entity.controller = new FallingSword(this, i);
|
entity.controller = new TrapSword(this, i);
|
||||||
break;
|
break;
|
||||||
case TR::Entity::SWITCH :
|
case TR::Entity::SWITCH :
|
||||||
case TR::Entity::SWITCH_WATER :
|
case TR::Entity::SWITCH_WATER :
|
||||||
|
@@ -107,7 +107,7 @@
|
|||||||
<input type="button" value="Browse Level" onclick="document.getElementById('browseFile').click();" /> (.PHD, .PSX)
|
<input type="button" value="Browse Level" onclick="document.getElementById('browseFile').click();" /> (.PHD, .PSX)
|
||||||
<p style="margin:8px">
|
<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>
|
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>
|
</p>
|
||||||
</span>
|
</span>
|
||||||
|
|
||||||
|
@@ -58,7 +58,7 @@ struct Sprite : Controller {
|
|||||||
if (instant && time >= (1.0f / SPRITE_FPS))
|
if (instant && time >= (1.0f / SPRITE_FPS))
|
||||||
remove = true;
|
remove = true;
|
||||||
|
|
||||||
pos += velocity * Core::deltaTime;
|
pos += velocity * (30.0f * Core::deltaTime);
|
||||||
|
|
||||||
if (remove) {
|
if (remove) {
|
||||||
level->entityRemove(entity);
|
level->entityRemove(entity);
|
||||||
|
@@ -3,6 +3,7 @@
|
|||||||
|
|
||||||
#include "core.h"
|
#include "core.h"
|
||||||
#include "controller.h"
|
#include "controller.h"
|
||||||
|
#include "character.h"
|
||||||
#include "sprite.h"
|
#include "sprite.h"
|
||||||
|
|
||||||
struct Switch : Controller {
|
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
|
#define BOULDER_DAMAGE_AIR 100
|
||||||
|
|
||||||
struct TrapBoulder : Controller {
|
struct TrapBoulder : Controller {
|
||||||
@@ -183,9 +184,13 @@ struct TrapBoulder : Controller {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
Controller *lara = (Controller*)level->laraController;
|
Character *lara = (Character*)level->laraController;
|
||||||
if (collide(lara))
|
if (lara->health > 0.0f && collide(lara)) {
|
||||||
lara->hit(BOULDER_DAMAGE_GROUND, this);
|
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);
|
updateAnimation(true);
|
||||||
updateEntity();
|
updateEntity();
|
||||||
@@ -524,15 +529,31 @@ struct TrapBlade : Controller {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#define SPIKES_DAMAGE_FALL 1000
|
||||||
|
#define SPIKES_DAMAGE_RUN 15
|
||||||
|
|
||||||
struct TrapSpikes : Controller {
|
struct TrapSpikes : Controller {
|
||||||
TrapSpikes(IGame *game, int entity) : Controller(game, entity) {}
|
TrapSpikes(IGame *game, int entity) : Controller(game, entity) {
|
||||||
|
activate();
|
||||||
|
}
|
||||||
|
|
||||||
virtual void update() {
|
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 {
|
enum {
|
||||||
STATE_STATIC,
|
STATE_STATIC,
|
||||||
STATE_FALL,
|
STATE_FALL,
|
||||||
@@ -541,7 +562,7 @@ struct FallingCeiling : Controller {
|
|||||||
|
|
||||||
float speed;
|
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() {
|
virtual void update() {
|
||||||
updateAnimation(true);
|
updateAnimation(true);
|
||||||
@@ -573,8 +594,8 @@ struct FallingCeiling : Controller {
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
struct FallingSword : Controller {
|
struct TrapSword : Controller {
|
||||||
FallingSword(IGame *game, int entity) : Controller(game, entity) {}
|
TrapSword(IGame *game, int entity) : Controller(game, entity) {}
|
||||||
|
|
||||||
virtual void update() {
|
virtual void update() {
|
||||||
updateAnimation(true);
|
updateAnimation(true);
|
||||||
|
Reference in New Issue
Block a user