mirror of
https://github.com/XProger/OpenLara.git
synced 2025-08-18 10:51:23 +02:00
#14 add dummy human enemies with drop items and "finish level" actions
This commit is contained in:
@@ -31,6 +31,7 @@ struct ICamera {
|
||||
struct IGame {
|
||||
virtual ~IGame() {}
|
||||
virtual void loadLevel(TR::LevelID id) {}
|
||||
virtual void loadNextLevel() {}
|
||||
virtual void loadGame(int slot) {}
|
||||
virtual void saveGame(int slot) {}
|
||||
virtual void applySettings(const Core::Settings &settings) {}
|
||||
@@ -56,7 +57,7 @@ struct IGame {
|
||||
virtual void checkTrigger(Controller *controller, bool heavy) {}
|
||||
|
||||
virtual int addSprite(TR::Entity::Type type, int room, int x, int y, int z, int frame = -1, bool empty = false) { return -1; }
|
||||
virtual int addEnemy(TR::Entity::Type type, int room, const vec3 &pos, float angle) { return -1; }
|
||||
virtual int addEntity(TR::Entity::Type type, int room, const vec3 &pos, float angle) { return -1; }
|
||||
|
||||
virtual bool invUse(TR::Entity::Type type) { return false; }
|
||||
virtual void invAdd(TR::Entity::Type type, int count = 1) {}
|
||||
@@ -527,10 +528,11 @@ struct Controller {
|
||||
if (animation.isFrameActive(frame)) {
|
||||
if (cmd == TR::ANIM_CMD_EFFECT) {
|
||||
switch (fx) {
|
||||
case TR::Effect::ROTATE_180 : angle.y = angle.y + PI; break;
|
||||
case TR::Effect::FLOOR_SHAKE : game->setEffect(this, TR::Effect(fx)); break;
|
||||
case TR::Effect::FLIP_MAP : level->isFlipped = !level->isFlipped; break;
|
||||
default : cmdEffect(fx); break;
|
||||
case TR::Effect::ROTATE_180 : angle.y = angle.y + PI; break;
|
||||
case TR::Effect::FLOOR_SHAKE : game->setEffect(this, TR::Effect(fx)); break;
|
||||
case TR::Effect::FINISH_LEVEL : game->loadNextLevel(); break;
|
||||
case TR::Effect::FLIP_MAP : level->isFlipped = !level->isFlipped; break;
|
||||
default : cmdEffect(fx); break;
|
||||
}
|
||||
} else
|
||||
game->playSound(fx, pos, Sound::Flags::PAN);
|
||||
|
110
src/enemy.h
110
src/enemy.h
@@ -1293,4 +1293,114 @@ struct ScionTarget : Enemy {
|
||||
};
|
||||
|
||||
|
||||
struct Human : Enemy {
|
||||
enum {
|
||||
STATE_NONE,
|
||||
STATE_STOP,
|
||||
STATE_WALK,
|
||||
STATE_RUN,
|
||||
STATE_AIM,
|
||||
STATE_DEATH,
|
||||
STATE_UNKNOWN,
|
||||
STATE_FIRE
|
||||
};
|
||||
|
||||
int animDeath;
|
||||
|
||||
Human(IGame *game, int entity, float health) : Enemy(game, entity, health, 100, 375.0f, 1.0f), animDeath(-1) {
|
||||
jointChest = 7;
|
||||
jointHead = 8;
|
||||
}
|
||||
|
||||
virtual void deactivate(bool removeFromList = false) {
|
||||
if (health <= 0.0f)
|
||||
onDead();
|
||||
Enemy::deactivate(removeFromList);
|
||||
}
|
||||
|
||||
virtual int getStateDeath() {
|
||||
return (animDeath == -1 || state == STATE_DEATH || state == STATE_NONE) ? STATE_DEATH : animation.setAnim(animDeath);
|
||||
}
|
||||
|
||||
virtual int getStateGround() {
|
||||
if (!think(true))
|
||||
return state;
|
||||
return state;
|
||||
}
|
||||
|
||||
virtual void updatePosition() {
|
||||
Enemy::updatePosition();
|
||||
setOverrides(true, jointChest, jointHead);
|
||||
lookAt(target);
|
||||
}
|
||||
|
||||
virtual void onDead() {}
|
||||
};
|
||||
|
||||
|
||||
struct Larson : Human {
|
||||
|
||||
Larson(IGame *game, int entity) : Human(game, entity, 50) {
|
||||
animDeath = 15;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
struct Pierre : Human {
|
||||
|
||||
Pierre(IGame *game, int entity) : Human(game, entity, 70) {
|
||||
animDeath = 12;
|
||||
}
|
||||
|
||||
virtual void onDead() {
|
||||
if (level->id == TR::LEVEL_7B) {
|
||||
game->addEntity(TR::Entity::MAGNUMS, getRoomIndex(), pos, 0);
|
||||
game->addEntity(TR::Entity::SCION_DROP, getRoomIndex(), pos, 0);
|
||||
game->addEntity(TR::Entity::KEY_ITEM_1, getRoomIndex(), pos, 0);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
struct SkaterBoy : Human {
|
||||
|
||||
SkaterBoy(IGame *game, int entity) : Human(game, entity, 125) {
|
||||
animDeath = 13;
|
||||
}
|
||||
|
||||
virtual void onDead() {
|
||||
game->addEntity(TR::Entity::UZIS, getRoomIndex(), pos, 0);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
struct Cowboy : Human {
|
||||
|
||||
Cowboy(IGame *game, int entity) : Human(game, entity, 150) {
|
||||
animDeath = 7;
|
||||
}
|
||||
|
||||
virtual void onDead() {
|
||||
game->addEntity(TR::Entity::MAGNUMS, getRoomIndex(), pos, 0);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
struct MrT : Human {
|
||||
|
||||
MrT(IGame *game, int entity) : Human(game, entity, 200) {
|
||||
animDeath = 14;
|
||||
}
|
||||
|
||||
virtual void onDead() {
|
||||
game->addEntity(TR::Entity::SHOTGUN, getRoomIndex(), pos, 0);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
struct Natla : Human {
|
||||
|
||||
Natla(IGame *game, int entity) : Human(game, entity, 400) {}
|
||||
};
|
||||
|
||||
#endif
|
@@ -468,11 +468,13 @@ struct Lara : Character {
|
||||
//reset(99, vec3(45562, -3328, 63366), 225 * DEG2RAD); // level 7a (flipmap)
|
||||
//reset(77, vec3(36943, -4096, 62821), 270 * DEG2RAD); // level 7b (heavy trigger)
|
||||
//reset(90, vec3(19438, 3840, 78341), 90 * DEG2RAD); // level 7b (statues)
|
||||
//reset(57, vec3(54844, -3328, 53145), 0); // level 8b (bridge switch
|
||||
//reset(90, vec3(29000, 3840 - 512, 78341), 90 * DEG2RAD); // level 7b (statues)
|
||||
//reset(57, vec3(54844, -3328, 53145), 0); // level 8b (bridge switch)
|
||||
//reset(12, vec3(34236, -2415, 14974), 0); // level 8b (sphinx)
|
||||
//reset(0, vec3(40913, -1012, 42252), PI); // level 8c
|
||||
//reset(30, vec3(69689, -8448, 34922), 330 * DEG2RAD); // Level 10a (cabin)
|
||||
//reset(27, vec3(52631, -4352, 57893), 270 * DEG2RAD); // Level 10a (drill)
|
||||
//reset(68, vec3(52458, -9984, 93724), 270 * DEG2RAD); // Level 10a (MrT)
|
||||
//reset(44, vec3(75803, -11008, 21097), 90 * DEG2RAD); // Level 10a (boat)
|
||||
//reset(50, vec3(53703, -18688, 13769), PI); // Level 10c (scion holder)
|
||||
//reset(19, vec3(35364, -512, 40199), PI * 0.5f); // Level 10c (lava flow)
|
||||
@@ -1841,7 +1843,7 @@ struct Lara : Character {
|
||||
cameraTarget = (Controller*)level->entities[cmd.args].controller;
|
||||
break;
|
||||
case TR::Action::END :
|
||||
game->loadLevel(level->id == TR::LEVEL_10C ? TR::TITLE : TR::LevelID(level->id + 1));
|
||||
game->loadNextLevel();
|
||||
break;
|
||||
case TR::Action::SOUNDTRACK : {
|
||||
int track = doTutorial(cmd.args);
|
||||
|
32
src/level.h
32
src/level.h
@@ -69,6 +69,10 @@ struct Level : IGame {
|
||||
new Stream(buf, loadAsync);
|
||||
}
|
||||
|
||||
virtual void loadNextLevel() {
|
||||
loadLevel(level.id == TR::LEVEL_10C ? TR::TITLE : TR::LevelID(level.id + 1));
|
||||
}
|
||||
|
||||
virtual void loadGame(int slot) {
|
||||
//
|
||||
}
|
||||
@@ -249,14 +253,18 @@ struct Level : IGame {
|
||||
return Sprite::add(this, type, room, x, y, z, frame, empty);
|
||||
}
|
||||
|
||||
virtual int addEnemy(TR::Entity::Type type, int room, const vec3 &pos, float angle) {
|
||||
virtual int addEntity(TR::Entity::Type type, int room, const vec3 &pos, float angle) {
|
||||
int index = level.entityAdd(type, room, int(pos.x), int(pos.y), int(pos.z), TR::angle(angle), -1);
|
||||
if (index > -1) {
|
||||
TR::Entity &e = level.entities[index];
|
||||
Controller *enemy = initController(index);
|
||||
e.controller = enemy;
|
||||
e.flags.active = TR::ACTIVE;
|
||||
enemy->activate();
|
||||
Controller *controller = initController(index);
|
||||
e.controller = controller;
|
||||
if (e.isEnemy()) {
|
||||
e.flags.active = TR::ACTIVE;
|
||||
controller->activate();
|
||||
}
|
||||
if (e.isPickup())
|
||||
e.intensity = 4096;
|
||||
}
|
||||
return index;
|
||||
}
|
||||
@@ -464,13 +472,13 @@ struct Level : IGame {
|
||||
case TR::Entity::ENEMY_CROCODILE_LAND :
|
||||
case TR::Entity::ENEMY_CROCODILE_WATER :
|
||||
case TR::Entity::ENEMY_PUMA :
|
||||
case TR::Entity::ENEMY_GORILLA :
|
||||
case TR::Entity::ENEMY_LARSON :
|
||||
case TR::Entity::ENEMY_PIERRE :
|
||||
case TR::Entity::ENEMY_SKATEBOY :
|
||||
case TR::Entity::ENEMY_COWBOY :
|
||||
case TR::Entity::ENEMY_MR_T :
|
||||
case TR::Entity::ENEMY_NATLA : return new Enemy(this, index, 100, 10, 0.0f, 0.0f);
|
||||
case TR::Entity::ENEMY_GORILLA : return new Enemy(this, index, 100, 10, 0.0f, 0.0f);
|
||||
case TR::Entity::ENEMY_LARSON : return new Larson(this, index);
|
||||
case TR::Entity::ENEMY_PIERRE : return new Pierre(this, index);
|
||||
case TR::Entity::ENEMY_SKATEBOY : return new SkaterBoy(this, index);
|
||||
case TR::Entity::ENEMY_COWBOY : return new Cowboy(this, index);
|
||||
case TR::Entity::ENEMY_MR_T : return new MrT(this, index);
|
||||
case TR::Entity::ENEMY_NATLA : return new Natla(this, index);
|
||||
case TR::Entity::ENEMY_GIANT_MUTANT : return new GiantMutant(this, index);
|
||||
case TR::Entity::DOOR_1 :
|
||||
case TR::Entity::DOOR_2 :
|
||||
|
@@ -1118,7 +1118,7 @@ struct CentaurStatue : Controller {
|
||||
if ((pos - game->getLara()->pos).length() < CENTAUR_STATUE_RANGE) {
|
||||
explode(0xFFFFFFFF);
|
||||
game->playSound(TR::SND_EXPLOSION, pos, Sound::PAN);
|
||||
int index = game->addEnemy(TR::Entity::ENEMY_CENTAUR, getRoomIndex(), pos, angle.y);
|
||||
int index = game->addEntity(TR::Entity::ENEMY_CENTAUR, getRoomIndex(), pos, angle.y);
|
||||
if (index > -1) {
|
||||
Controller *controller = (Controller*)level->entities[index].controller;
|
||||
controller->animation.setAnim(7, -36);
|
||||
@@ -1212,7 +1212,7 @@ struct MutantEgg : Controller {
|
||||
animation.setState(STATE_EXPLOSION);
|
||||
layers[0].mask = 0xffffffff & ~(1 << 24);
|
||||
explode(0x00fffe00);
|
||||
game->addEnemy(enemy, getRoomIndex(), pos, angle.y);
|
||||
game->addEntity(enemy, getRoomIndex(), pos, angle.y);
|
||||
}
|
||||
}
|
||||
Controller::update();
|
||||
|
Reference in New Issue
Block a user