1
0
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:
XProger
2017-10-10 06:45:27 +03:00
parent 7e63aaa26e
commit 80b2d70e3c
5 changed files with 143 additions and 21 deletions

View File

@@ -31,6 +31,7 @@ struct ICamera {
struct IGame { struct IGame {
virtual ~IGame() {} virtual ~IGame() {}
virtual void loadLevel(TR::LevelID id) {} virtual void loadLevel(TR::LevelID id) {}
virtual void loadNextLevel() {}
virtual void loadGame(int slot) {} virtual void loadGame(int slot) {}
virtual void saveGame(int slot) {} virtual void saveGame(int slot) {}
virtual void applySettings(const Core::Settings &settings) {} virtual void applySettings(const Core::Settings &settings) {}
@@ -56,7 +57,7 @@ struct IGame {
virtual void checkTrigger(Controller *controller, bool heavy) {} 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 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 bool invUse(TR::Entity::Type type) { return false; }
virtual void invAdd(TR::Entity::Type type, int count = 1) {} virtual void invAdd(TR::Entity::Type type, int count = 1) {}
@@ -527,10 +528,11 @@ struct Controller {
if (animation.isFrameActive(frame)) { if (animation.isFrameActive(frame)) {
if (cmd == TR::ANIM_CMD_EFFECT) { if (cmd == TR::ANIM_CMD_EFFECT) {
switch (fx) { switch (fx) {
case TR::Effect::ROTATE_180 : angle.y = angle.y + PI; 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::FLOOR_SHAKE : game->setEffect(this, TR::Effect(fx)); break;
case TR::Effect::FLIP_MAP : level->isFlipped = !level->isFlipped; break; case TR::Effect::FINISH_LEVEL : game->loadNextLevel(); break;
default : cmdEffect(fx); break; case TR::Effect::FLIP_MAP : level->isFlipped = !level->isFlipped; break;
default : cmdEffect(fx); break;
} }
} else } else
game->playSound(fx, pos, Sound::Flags::PAN); game->playSound(fx, pos, Sound::Flags::PAN);

View File

@@ -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 #endif

View File

@@ -468,11 +468,13 @@ struct Lara : Character {
//reset(99, vec3(45562, -3328, 63366), 225 * DEG2RAD); // level 7a (flipmap) //reset(99, vec3(45562, -3328, 63366), 225 * DEG2RAD); // level 7a (flipmap)
//reset(77, vec3(36943, -4096, 62821), 270 * DEG2RAD); // level 7b (heavy trigger) //reset(77, vec3(36943, -4096, 62821), 270 * DEG2RAD); // level 7b (heavy trigger)
//reset(90, vec3(19438, 3840, 78341), 90 * DEG2RAD); // level 7b (statues) //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(12, vec3(34236, -2415, 14974), 0); // level 8b (sphinx)
//reset(0, vec3(40913, -1012, 42252), PI); // level 8c //reset(0, vec3(40913, -1012, 42252), PI); // level 8c
//reset(30, vec3(69689, -8448, 34922), 330 * DEG2RAD); // Level 10a (cabin) //reset(30, vec3(69689, -8448, 34922), 330 * DEG2RAD); // Level 10a (cabin)
//reset(27, vec3(52631, -4352, 57893), 270 * DEG2RAD); // Level 10a (drill) //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(44, vec3(75803, -11008, 21097), 90 * DEG2RAD); // Level 10a (boat)
//reset(50, vec3(53703, -18688, 13769), PI); // Level 10c (scion holder) //reset(50, vec3(53703, -18688, 13769), PI); // Level 10c (scion holder)
//reset(19, vec3(35364, -512, 40199), PI * 0.5f); // Level 10c (lava flow) //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; cameraTarget = (Controller*)level->entities[cmd.args].controller;
break; break;
case TR::Action::END : case TR::Action::END :
game->loadLevel(level->id == TR::LEVEL_10C ? TR::TITLE : TR::LevelID(level->id + 1)); game->loadNextLevel();
break; break;
case TR::Action::SOUNDTRACK : { case TR::Action::SOUNDTRACK : {
int track = doTutorial(cmd.args); int track = doTutorial(cmd.args);

View File

@@ -69,6 +69,10 @@ struct Level : IGame {
new Stream(buf, loadAsync); 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) { virtual void loadGame(int slot) {
// //
} }
@@ -249,14 +253,18 @@ struct Level : IGame {
return Sprite::add(this, type, room, x, y, z, frame, empty); 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); int index = level.entityAdd(type, room, int(pos.x), int(pos.y), int(pos.z), TR::angle(angle), -1);
if (index > -1) { if (index > -1) {
TR::Entity &e = level.entities[index]; TR::Entity &e = level.entities[index];
Controller *enemy = initController(index); Controller *controller = initController(index);
e.controller = enemy; e.controller = controller;
e.flags.active = TR::ACTIVE; if (e.isEnemy()) {
enemy->activate(); e.flags.active = TR::ACTIVE;
controller->activate();
}
if (e.isPickup())
e.intensity = 4096;
} }
return index; return index;
} }
@@ -464,13 +472,13 @@ struct Level : IGame {
case TR::Entity::ENEMY_CROCODILE_LAND : case TR::Entity::ENEMY_CROCODILE_LAND :
case TR::Entity::ENEMY_CROCODILE_WATER : case TR::Entity::ENEMY_CROCODILE_WATER :
case TR::Entity::ENEMY_PUMA : case TR::Entity::ENEMY_PUMA :
case TR::Entity::ENEMY_GORILLA : case TR::Entity::ENEMY_GORILLA : return new Enemy(this, index, 100, 10, 0.0f, 0.0f);
case TR::Entity::ENEMY_LARSON : case TR::Entity::ENEMY_LARSON : return new Larson(this, index);
case TR::Entity::ENEMY_PIERRE : case TR::Entity::ENEMY_PIERRE : return new Pierre(this, index);
case TR::Entity::ENEMY_SKATEBOY : case TR::Entity::ENEMY_SKATEBOY : return new SkaterBoy(this, index);
case TR::Entity::ENEMY_COWBOY : case TR::Entity::ENEMY_COWBOY : return new Cowboy(this, index);
case TR::Entity::ENEMY_MR_T : case TR::Entity::ENEMY_MR_T : return new MrT(this, index);
case TR::Entity::ENEMY_NATLA : return new Enemy(this, index, 100, 10, 0.0f, 0.0f); case TR::Entity::ENEMY_NATLA : return new Natla(this, index);
case TR::Entity::ENEMY_GIANT_MUTANT : return new GiantMutant(this, index); case TR::Entity::ENEMY_GIANT_MUTANT : return new GiantMutant(this, index);
case TR::Entity::DOOR_1 : case TR::Entity::DOOR_1 :
case TR::Entity::DOOR_2 : case TR::Entity::DOOR_2 :

View File

@@ -1118,7 +1118,7 @@ struct CentaurStatue : Controller {
if ((pos - game->getLara()->pos).length() < CENTAUR_STATUE_RANGE) { if ((pos - game->getLara()->pos).length() < CENTAUR_STATUE_RANGE) {
explode(0xFFFFFFFF); explode(0xFFFFFFFF);
game->playSound(TR::SND_EXPLOSION, pos, Sound::PAN); 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) { if (index > -1) {
Controller *controller = (Controller*)level->entities[index].controller; Controller *controller = (Controller*)level->entities[index].controller;
controller->animation.setAnim(7, -36); controller->animation.setAnim(7, -36);
@@ -1212,7 +1212,7 @@ struct MutantEgg : Controller {
animation.setState(STATE_EXPLOSION); animation.setState(STATE_EXPLOSION);
layers[0].mask = 0xffffffff & ~(1 << 24); layers[0].mask = 0xffffffff & ~(1 << 24);
explode(0x00fffe00); explode(0x00fffe00);
game->addEnemy(enemy, getRoomIndex(), pos, angle.y); game->addEntity(enemy, getRoomIndex(), pos, angle.y);
} }
} }
Controller::update(); Controller::update();