1
0
mirror of https://github.com/XProger/OpenLara.git synced 2025-02-24 15:32:30 +01: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;
}
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();
TR::Model &m = level->models[model];
@ -148,6 +150,10 @@ struct Controller {
return getEntity().room;
}
virtual vec3& getPos() {
return pos;
}
int getOverlap(int fromX, int fromY, int fromZ, int toX, int toZ) const {
int 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 cmdKill() {}
virtual void cmdEmpty() {}
virtual void cmdEffect(int fx) { ASSERT(false); } // not implemented
virtual void updateAnimation(bool commands) {
animation.update();
@ -384,8 +390,7 @@ struct Controller {
switch (fx) {
case TR::EFFECT_ROTATE_180 : angle.y = angle.y + PI; break;
case TR::EFFECT_LARA_BUBBLES : doBubbles(); break;
case TR::EFFECT_LARA_HANDSFREE : break;
default : LOG("unknown special cmd %d (anim %d)\n", fx, animation.index);
default : cmdEffect(fx); break;
}
} else
playSound(fx, pos, Sound::Flags::PAN);

View File

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

View File

@ -176,7 +176,7 @@ struct Lara : Character {
bool home;
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 Anim { NONE, PREPARE, UNHOLSTER, HOLSTER, HOLD, AIM, FIRE };
@ -203,14 +203,16 @@ struct Lara : Character {
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) {
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;
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));
if (!home) {
@ -221,6 +223,13 @@ struct Lara : Character {
wpnSet(Weapon::PISTOLS);
} else
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
/*
// gym
@ -301,8 +310,6 @@ struct Lara : Character {
updateEntity();
#endif
chestOffset = animation.getJoints(getMatrix(), 7).pos;
if (getRoom().flags.water)
animation.setAnim(ANIM_UNDERWATER);
}
void wpnSet(Weapon::Type wType) {
@ -346,7 +353,7 @@ struct Lara : Character {
}
void wpnSetState(Weapon::State wState) {
if (wpnState == wState) return;
if (wpnState == wState || !layers) return;
int mask = 0;
switch (wpnCurrent) {
@ -381,15 +388,15 @@ struct Lara : Character {
// swap weapon parts
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
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 {
meshSwap(2, wpnCurrent, mask);
meshSwap(2, level->extra.weapons[wpnCurrent], mask);
}
// 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;
}
@ -872,6 +879,23 @@ struct Lara : Character {
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) {
health -= damage;
if (enemy && health > 0)
@ -1577,6 +1601,20 @@ struct Lara : Character {
if (velocity.length() >= 0.001f)
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() {

View File

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