1
0
mirror of https://github.com/XProger/OpenLara.git synced 2025-08-14 17:14:29 +02:00

#3 cutscenes fix, draw weapon animation command

This commit is contained in:
XProger
2016-12-29 02:39:02 +03:00
parent 4c41cacef0
commit 297255e3bd
4 changed files with 80 additions and 24 deletions

View File

@@ -66,7 +66,9 @@ struct Controller {
layers[0].mask = 0xFFFFFFFF; layers[0].mask = 0xFFFFFFFF;
} }
void meshSwap(int layer, uint32 model, uint32 mask = 0xFFFFFFFF) { void meshSwap(int layer, int16 model, uint32 mask = 0xFFFFFFFF) {
if (model < 0) return;
if (!layers) initMeshOverrides(); if (!layers) initMeshOverrides();
TR::Model &m = level->models[model]; TR::Model &m = level->models[model];
@@ -148,6 +150,10 @@ struct Controller {
return getEntity().room; return getEntity().room;
} }
virtual vec3& getPos() {
return pos;
}
int getOverlap(int fromX, int fromY, int fromZ, int toX, int toZ) const { int getOverlap(int fromX, int fromY, int fromZ, int toX, int toZ) const {
int dx, dz; int dx, dz;
TR::Room::Sector &s = level->getSector(getEntity().room, fromX, fromZ, dx, dz); TR::Room::Sector &s = level->getSector(getEntity().room, fromX, fromZ, dx, dz);
@@ -357,7 +363,7 @@ struct Controller {
virtual void cmdJump(const vec3 &vel) {} virtual void cmdJump(const vec3 &vel) {}
virtual void cmdKill() {} virtual void cmdKill() {}
virtual void cmdEmpty() {} virtual void cmdEmpty() {}
virtual void cmdEffect(int fx) { ASSERT(false); } // not implemented
virtual void updateAnimation(bool commands) { virtual void updateAnimation(bool commands) {
animation.update(); animation.update();
@@ -384,8 +390,7 @@ struct Controller {
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_LARA_BUBBLES : doBubbles(); break; case TR::EFFECT_LARA_BUBBLES : doBubbles(); break;
case TR::EFFECT_LARA_HANDSFREE : break; default : cmdEffect(fx); break;
default : LOG("unknown special cmd %d (anim %d)\n", fx, animation.index);
} }
} else } else
playSound(fx, pos, Sound::Flags::PAN); playSound(fx, pos, Sound::Flags::PAN);

View File

@@ -356,6 +356,10 @@ namespace TR {
enum Type : int16 { enum Type : int16 {
NONE = -1, NONE = -1,
LARA = 0, LARA = 0,
LARA_PISTOLS = 1,
LARA_SHOTGUN = 2,
LARA_MAGNUMS = 3,
LARA_UZIS = 4,
ENEMY_TWIN = 6, ENEMY_TWIN = 6,
ENEMY_WOLF = 7, ENEMY_WOLF = 7,
@@ -814,8 +818,9 @@ namespace TR {
void *cameraController; void *cameraController;
struct { struct {
uint16 muzzleFlash; int16 muzzleFlash;
uint16 puzzleSet; int16 puzzleSet;
int16 weapons[4];
} extra; } extra;
Level(Stream &stream, bool demo) { Level(Stream &stream, bool demo) {
@@ -1012,10 +1017,17 @@ namespace TR {
memset(secrets, 0, MAX_SECRETS_COUNT * sizeof(secrets[0])); memset(secrets, 0, MAX_SECRETS_COUNT * sizeof(secrets[0]));
// get special models indices // get special models indices
memset(&extra, 0, sizeof(extra)); memset(&extra, 0, sizeof(extra));
for (int i = 0; i < 4; i++)
extra.weapons[i] = -1;
for (int i = 0; i < modelsCount; i++) for (int i = 0; i < modelsCount; i++)
switch (models[i].type) { switch (models[i].type) {
case Entity::MUZZLE_FLASH : extra.muzzleFlash = i; break; case Entity::MUZZLE_FLASH : extra.muzzleFlash = i; break;
case Entity::HOLE_PUZZLE_SET : extra.puzzleSet = i; break; case Entity::HOLE_PUZZLE_SET : extra.puzzleSet = i; break;
case Entity::LARA_PISTOLS : extra.weapons[0] = i; break;
case Entity::LARA_SHOTGUN : extra.weapons[1] = i; break;
case Entity::LARA_MAGNUMS : extra.weapons[2] = i; break;
case Entity::LARA_UZIS : extra.weapons[3] = i; break;
default : ; default : ;
} }
} }

View File

@@ -176,7 +176,7 @@ struct Lara : Character {
bool home; bool home;
struct Weapon { struct Weapon {
enum Type { EMPTY, PISTOLS, SHOTGUN, MAGNUMS, UZIS, MAX }; enum Type { EMPTY = -1, PISTOLS, SHOTGUN, MAGNUMS, UZIS, MAX };
enum State { IS_HIDDEN, IS_ARMED, IS_FIRING }; enum State { IS_HIDDEN, IS_ARMED, IS_FIRING };
enum Anim { NONE, PREPARE, UNHOLSTER, HOLSTER, HOLD, AIM, FIRE }; enum Anim { NONE, PREPARE, UNHOLSTER, HOLSTER, HOLD, AIM, FIRE };
@@ -203,14 +203,16 @@ struct Lara : Character {
int viewTarget; int viewTarget;
Lara(TR::Level *level, int entity, bool home) : Character(level, entity, 1000), home(home), wpnCurrent(Weapon::EMPTY), wpnNext(Weapon::EMPTY), chestOffset(pos), viewTarget(-1) { Lara(TR::Level *level, int entity, bool home) : Character(level, entity, 1000), home(home), wpnCurrent(Weapon::EMPTY), wpnNext(Weapon::EMPTY), chestOffset(pos), viewTarget(-1) {
animation.setAnim(ANIM_STAND);
if (getEntity().type == TR::Entity::LARA) {
if (getRoom().flags.water)
animation.setAnim(ANIM_UNDERWATER);
else
animation.setAnim(ANIM_STAND);
}
getEntity().flags.active = 1; getEntity().flags.active = 1;
initMeshOverrides(); initMeshOverrides();
for (int i = 0; i < 2; i++) {
arms[i].shotTimer = MUZZLE_FLASH_TIME + 1.0f;
arms[i].rot = quat(0, 0, 0, 1);
arms[i].rotAbs = quat(0, 0, 0, 1);
}
memset(weapons, -1, sizeof(weapons)); memset(weapons, -1, sizeof(weapons));
if (!home) { if (!home) {
@@ -221,6 +223,13 @@ struct Lara : Character {
wpnSet(Weapon::PISTOLS); wpnSet(Weapon::PISTOLS);
} else } else
meshSwap(1, TR::MODEL_LARA_SPEC, BODY_UPPER | BODY_LOWER); meshSwap(1, TR::MODEL_LARA_SPEC, BODY_UPPER | BODY_LOWER);
for (int i = 0; i < 2; i++) {
arms[i].shotTimer = MUZZLE_FLASH_TIME + 1.0f;
arms[i].rot = quat(0, 0, 0, 1);
arms[i].rotAbs = quat(0, 0, 0, 1);
}
#ifdef _DEBUG #ifdef _DEBUG
/* /*
// gym // gym
@@ -301,8 +310,6 @@ struct Lara : Character {
updateEntity(); updateEntity();
#endif #endif
chestOffset = animation.getJoints(getMatrix(), 7).pos; chestOffset = animation.getJoints(getMatrix(), 7).pos;
if (getRoom().flags.water)
animation.setAnim(ANIM_UNDERWATER);
} }
void wpnSet(Weapon::Type wType) { void wpnSet(Weapon::Type wType) {
@@ -346,7 +353,7 @@ struct Lara : Character {
} }
void wpnSetState(Weapon::State wState) { void wpnSetState(Weapon::State wState) {
if (wpnState == wState) return; if (wpnState == wState || !layers) return;
int mask = 0; int mask = 0;
switch (wpnCurrent) { switch (wpnCurrent) {
@@ -381,15 +388,15 @@ struct Lara : Character {
// swap weapon parts // swap weapon parts
if (wpnCurrent != Weapon::SHOTGUN) { if (wpnCurrent != Weapon::SHOTGUN) {
meshSwap(1, wpnCurrent, mask); meshSwap(1, level->extra.weapons[wpnCurrent], mask);
// have a shotgun in inventory place it on the back if another weapon is in use // have a shotgun in inventory place it on the back if another weapon is in use
meshSwap(2, Weapon::SHOTGUN, (weapons[Weapon::SHOTGUN].ammo != -1) ? BODY_CHEST : 0); meshSwap(2, level->extra.weapons[Weapon::SHOTGUN], (weapons[Weapon::SHOTGUN].ammo != -1) ? BODY_CHEST : 0);
} else { } else {
meshSwap(2, wpnCurrent, mask); meshSwap(2, level->extra.weapons[wpnCurrent], mask);
} }
// mesh swap to angry Lara's head while firing (from uzis model) // mesh swap to angry Lara's head while firing (from uzis model)
meshSwap(3, Weapon::UZIS, (wState == Weapon::IS_FIRING) ? BODY_HEAD : 0); meshSwap(3, level->extra.weapons[Weapon::UZIS], (wState == Weapon::IS_FIRING) ? BODY_HEAD : 0);
wpnState = wState; wpnState = wState;
} }
@@ -872,6 +879,23 @@ struct Lara : Character {
wpnHide(); wpnHide();
} }
void drawGun(int right) {
int mask = right ? BODY_ARM_R3 : BODY_ARM_L3; // unholster
if (layers[1].mask & mask)
mask = right ? BODY_LEG_R1 : BODY_LEG_L1; // holster
meshSwap(1, level->extra.weapons[wpnCurrent], mask);
}
virtual void cmdEffect(int fx) {
switch (fx) {
case TR::EFFECT_LARA_HANDSFREE : meshSwap(1, level->extra.weapons[wpnCurrent], BODY_LEG_L1 | BODY_LEG_R1); break;
case TR::EFFECT_DRAW_RIGHTGUN :
case TR::EFFECT_DRAW_LEFTGUN : drawGun(fx == TR::EFFECT_DRAW_RIGHTGUN); break;
default : LOG("unknown effect command %d (anim %d)\n", fx, animation.index);
}
}
virtual void hit(int damage, Controller *enemy = NULL) { virtual void hit(int damage, Controller *enemy = NULL) {
health -= damage; health -= damage;
if (enemy && health > 0) if (enemy && health > 0)
@@ -1577,6 +1601,20 @@ struct Lara : Character {
if (velocity.length() >= 0.001f) if (velocity.length() >= 0.001f)
move(); move();
if (getEntity().type != TR::Entity::LARA) {
TR::Entity &e = getEntity();
vec3 &p = getPos();
e.x = int(p.x);
e.y = int(p.y);
e.z = int(p.z);
checkRoom();
updateEntity();
}
}
virtual vec3& getPos() {
return getEntity().type == TR::Entity::LARA ? pos : chestOffset;
} }
void move() { void move() {

View File

@@ -669,7 +669,7 @@ struct Level {
setRoomParams(room, isModel ? controller->specular : intensityf(lum)); setRoomParams(room, isModel ? controller->specular : intensityf(lum));
if (isModel) { // model if (isModel) { // model
vec3 pos = controller->pos; vec3 pos = controller->getPos();
AmbientCache::Cube cube; AmbientCache::Cube cube;
if (Core::frameIndex != controller->frameIndex) { if (Core::frameIndex != controller->frameIndex) {
ambientCache->getAmbient(entity.room, pos, cube); ambientCache->getAmbient(entity.room, pos, cube);
@@ -875,8 +875,8 @@ struct Level {
if (Input::down[ikM]) { if (Input::down[ikM]) {
if (!lastStateK) { if (!lastStateK) {
lastStateK = true; lastStateK = true;
// modelIndex = (modelIndex + 1) % level.modelsCount; modelIndex = (modelIndex + 1) % level.modelsCount;
modelIndex = (modelIndex + 1) % level.spriteSequencesCount; // modelIndex = (modelIndex + 1) % level.spriteSequencesCount;
LOG("model: %d %d\n", modelIndex, level.spriteSequences[modelIndex].type); LOG("model: %d %d\n", modelIndex, level.spriteSequences[modelIndex].type);
if (lastEntity > -1) { if (lastEntity > -1) {
delete level.entities[lastEntity].controller; delete level.entities[lastEntity].controller;
@@ -912,7 +912,8 @@ struct Level {
glColor3f(1, 1, 1); glColor3f(1, 1, 1);
for (int j = 0; j < 6; j++) { for (int j = 0; j < 6; j++) {
glPushMatrix(); glPushMatrix();
glTranslatef(lara->pos.x, lara->pos.y - 1024, lara->pos.z); vec3 p = lara->getPos();
glTranslatef(p.x, p.y - 1024, p.z);
switch (j) { switch (j) {
case 0 : glRotatef( 90, 0, 1, 0); break; case 0 : glRotatef( 90, 0, 1, 0); break;
case 1 : glRotatef(-90, 0, 1, 0); break; case 1 : glRotatef(-90, 0, 1, 0); break;