2018-08-19 09:46:58 +02:00
|
|
|
#include "larafire.h"
|
2018-11-01 22:45:59 +01:00
|
|
|
|
2018-08-19 09:46:58 +02:00
|
|
|
#include "items.h"
|
2019-11-21 07:43:34 +01:00
|
|
|
#include "Lara.h"
|
2018-11-01 22:45:59 +01:00
|
|
|
#include "laraflar.h"
|
|
|
|
#include "lara1gun.h"
|
|
|
|
#include "lara2gun.h"
|
|
|
|
|
|
|
|
#include "..\Scripting\GameFlowScript.h"
|
|
|
|
|
2018-08-19 09:46:58 +02:00
|
|
|
#include <stdio.h>
|
2019-12-01 08:13:19 +01:00
|
|
|
#include "objects.h"
|
|
|
|
#include "effects.h"
|
|
|
|
#include "sphere.h"
|
|
|
|
#include "draw.h"
|
|
|
|
#include "effect2.h"
|
2018-08-19 09:46:58 +02:00
|
|
|
|
2018-11-01 09:10:32 +01:00
|
|
|
WEAPON_INFO Weapons[NUM_WEAPONS] =
|
|
|
|
{
|
|
|
|
/* No weapons */
|
2019-11-12 12:28:54 +01:00
|
|
|
{
|
|
|
|
{ ANGLE(0), ANGLE(0), ANGLE(0), ANGLE(0) },
|
|
|
|
{ ANGLE(0), ANGLE(0), ANGLE(0), ANGLE(0) },
|
|
|
|
{ ANGLE(0), ANGLE(0), ANGLE(0), ANGLE(0) },
|
|
|
|
0,
|
|
|
|
0,
|
|
|
|
0,
|
|
|
|
0,
|
|
|
|
0,
|
|
|
|
0,
|
|
|
|
0,
|
|
|
|
0,
|
|
|
|
0
|
|
|
|
},
|
2018-11-01 09:10:32 +01:00
|
|
|
/* Pistols */
|
2019-11-12 12:28:54 +01:00
|
|
|
{
|
2019-11-20 11:24:36 +01:00
|
|
|
{ -ANGLE(60), ANGLE(60), -ANGLE(60), ANGLE(60) },
|
|
|
|
{ -ANGLE(170), ANGLE(60), -ANGLE(80), ANGLE(80) },
|
|
|
|
{ -ANGLE(60), ANGLE(170), -ANGLE(80), ANGLE(80) },
|
2019-11-12 12:28:54 +01:00
|
|
|
ANGLE(10),
|
|
|
|
ANGLE(8),
|
|
|
|
650,
|
|
|
|
8 * WALL_SIZE,
|
|
|
|
1,
|
|
|
|
9,
|
|
|
|
3,
|
|
|
|
0,
|
2019-11-20 11:24:36 +01:00
|
|
|
SFX_LARA_FIRE
|
2019-11-12 12:28:54 +01:00
|
|
|
},
|
2018-11-01 09:10:32 +01:00
|
|
|
/* Revolver */
|
2019-11-12 12:28:54 +01:00
|
|
|
{
|
2019-11-20 11:24:36 +01:00
|
|
|
{ -ANGLE(60), ANGLE(60), -ANGLE(60), ANGLE(60) },
|
|
|
|
{ -ANGLE(10), ANGLE(10), -ANGLE(80), ANGLE(80) },
|
2019-11-14 14:09:43 +01:00
|
|
|
{ ANGLE(0), ANGLE(0), ANGLE(0), ANGLE(0) },
|
2019-11-12 12:28:54 +01:00
|
|
|
ANGLE(10),
|
|
|
|
ANGLE(4),
|
|
|
|
650,
|
|
|
|
8 * WALL_SIZE,
|
|
|
|
21,
|
|
|
|
16,
|
|
|
|
3,
|
|
|
|
0,
|
2019-11-20 11:24:36 +01:00
|
|
|
SFX_REVOLVER
|
2019-11-12 12:28:54 +01:00
|
|
|
},
|
2018-11-01 09:10:32 +01:00
|
|
|
/* Uzis */
|
2019-11-12 12:28:54 +01:00
|
|
|
{
|
2019-11-20 11:24:36 +01:00
|
|
|
{ -ANGLE(60), ANGLE(60), -ANGLE(60), ANGLE(60) },
|
|
|
|
{ -ANGLE(170), ANGLE(60), -ANGLE(80), ANGLE(80) },
|
|
|
|
{ -ANGLE(60), ANGLE(170), -ANGLE(80), ANGLE(80) },
|
2019-11-12 12:28:54 +01:00
|
|
|
ANGLE(10),
|
|
|
|
ANGLE(8),
|
|
|
|
650,
|
|
|
|
8 * WALL_SIZE,
|
|
|
|
1,
|
|
|
|
3,
|
|
|
|
3,
|
|
|
|
0,
|
2019-11-20 11:24:36 +01:00
|
|
|
SFX_LARA_UZI_FIRE
|
2019-11-12 12:28:54 +01:00
|
|
|
},
|
2018-11-01 09:10:32 +01:00
|
|
|
/* Shotgun */
|
2019-11-12 12:28:54 +01:00
|
|
|
{
|
2019-11-20 11:24:36 +01:00
|
|
|
{ -ANGLE(60), ANGLE(60), -ANGLE(55), ANGLE(55) },
|
|
|
|
{ -ANGLE(80), ANGLE(80), -ANGLE(65), ANGLE(65) },
|
|
|
|
{ -ANGLE(80), ANGLE(80), -ANGLE(65), ANGLE(65) },
|
2019-11-12 12:28:54 +01:00
|
|
|
ANGLE(10),
|
|
|
|
0,
|
|
|
|
500,
|
|
|
|
8 * WALL_SIZE,
|
|
|
|
3,
|
|
|
|
9,
|
|
|
|
3,
|
|
|
|
10,
|
2019-11-20 11:24:36 +01:00
|
|
|
SFX_LARA_SHOTGUN
|
2019-11-12 12:28:54 +01:00
|
|
|
},
|
2018-11-01 09:10:32 +01:00
|
|
|
/* HK */
|
2019-11-12 12:28:54 +01:00
|
|
|
{
|
2019-11-20 11:24:36 +01:00
|
|
|
{ -ANGLE(60), ANGLE(60), -ANGLE(55), ANGLE(55) },
|
|
|
|
{ -ANGLE(80), ANGLE(80), -ANGLE(65), ANGLE(65) },
|
|
|
|
{ -ANGLE(80), ANGLE(80), -ANGLE(65), ANGLE(65) },
|
2019-11-12 12:28:54 +01:00
|
|
|
ANGLE(10),
|
|
|
|
ANGLE(4),
|
|
|
|
500,
|
|
|
|
12 * WALL_SIZE,
|
|
|
|
4,
|
|
|
|
0,
|
|
|
|
3,
|
|
|
|
10,
|
2019-11-20 11:24:36 +01:00
|
|
|
0 // FIRE/SILENCER_FIRE
|
2019-11-12 12:28:54 +01:00
|
|
|
},
|
2018-11-01 09:10:32 +01:00
|
|
|
/* Crossbow */
|
2019-11-12 12:28:54 +01:00
|
|
|
{
|
2019-11-20 11:24:36 +01:00
|
|
|
{ -ANGLE(60), ANGLE(60), -ANGLE(55), ANGLE(55) },
|
|
|
|
{ -ANGLE(80), ANGLE(80), -ANGLE(65), ANGLE(65) },
|
|
|
|
{ -ANGLE(80), ANGLE(80), -ANGLE(65), ANGLE(65) },
|
2019-11-12 12:28:54 +01:00
|
|
|
ANGLE(10),
|
|
|
|
ANGLE(8),
|
|
|
|
500,
|
|
|
|
8 * WALL_SIZE,
|
|
|
|
5,
|
|
|
|
0,
|
|
|
|
2,
|
|
|
|
10,
|
2019-11-20 11:24:36 +01:00
|
|
|
SFX_LARA_CROSSBOW
|
2019-11-12 12:28:54 +01:00
|
|
|
},
|
2018-11-01 09:10:32 +01:00
|
|
|
/* Flare */
|
2019-11-12 12:28:54 +01:00
|
|
|
{
|
|
|
|
{ ANGLE(0), ANGLE(0), ANGLE(0), ANGLE(0) },
|
|
|
|
{ ANGLE(0), ANGLE(0), ANGLE(0), ANGLE(0) },
|
|
|
|
{ ANGLE(0), ANGLE(0), ANGLE(0), ANGLE(0) },
|
|
|
|
0,
|
|
|
|
0,
|
|
|
|
0,
|
|
|
|
0,
|
|
|
|
0,
|
|
|
|
0,
|
|
|
|
0,
|
|
|
|
0,
|
|
|
|
0
|
|
|
|
},
|
2018-11-01 09:10:32 +01:00
|
|
|
/* Flare 2 */
|
2019-11-12 12:28:54 +01:00
|
|
|
{
|
2019-11-20 11:24:36 +01:00
|
|
|
{ -ANGLE(30), ANGLE(30), -ANGLE(55), ANGLE(55) },
|
|
|
|
{ -ANGLE(30), ANGLE(30), -ANGLE(55), ANGLE(55) },
|
|
|
|
{ -ANGLE(30), ANGLE(30), -ANGLE(55), ANGLE(55) },
|
2019-11-12 12:28:54 +01:00
|
|
|
ANGLE(10),
|
|
|
|
ANGLE(8),
|
|
|
|
400,
|
|
|
|
8 * WALL_SIZE,
|
|
|
|
3,
|
|
|
|
0,
|
|
|
|
2,
|
|
|
|
0,
|
2019-11-20 11:24:36 +01:00
|
|
|
SFX_LARA_UZI_FIRE
|
2019-11-12 12:28:54 +01:00
|
|
|
},
|
2018-11-01 09:10:32 +01:00
|
|
|
/* Grenade launcher */
|
2019-11-12 12:28:54 +01:00
|
|
|
{
|
2019-11-20 11:24:36 +01:00
|
|
|
{ -ANGLE(60), ANGLE(60), -ANGLE(55), ANGLE(55) },
|
|
|
|
{ -ANGLE(80), ANGLE(80), -ANGLE(65), ANGLE(65) },
|
|
|
|
{ -ANGLE(80), ANGLE(80), -ANGLE(65), ANGLE(65) },
|
2019-11-12 12:28:54 +01:00
|
|
|
ANGLE(10),
|
|
|
|
ANGLE(8),
|
|
|
|
500,
|
|
|
|
8 * WALL_SIZE,
|
|
|
|
20,
|
|
|
|
0,
|
|
|
|
2,
|
|
|
|
10,
|
|
|
|
0
|
|
|
|
},
|
2018-11-01 09:10:32 +01:00
|
|
|
/* Harpoon gun */
|
2019-11-12 12:28:54 +01:00
|
|
|
{
|
2019-11-20 11:24:36 +01:00
|
|
|
{ -ANGLE(60), ANGLE(60), -ANGLE(65), ANGLE(65) },
|
|
|
|
{ -ANGLE(20), ANGLE(20), -ANGLE(75), ANGLE(75) },
|
|
|
|
{ -ANGLE(80), ANGLE(80), -ANGLE(75), ANGLE(75) },
|
2019-11-12 12:28:54 +01:00
|
|
|
ANGLE(10),
|
|
|
|
ANGLE(8),
|
|
|
|
500,
|
|
|
|
8 * WALL_SIZE,
|
|
|
|
6,
|
|
|
|
0,
|
|
|
|
2,
|
|
|
|
10,
|
|
|
|
0
|
|
|
|
},
|
2018-11-01 09:10:32 +01:00
|
|
|
/* Rocket launcher */
|
2019-11-12 12:28:54 +01:00
|
|
|
{
|
2019-11-20 11:24:36 +01:00
|
|
|
{ -ANGLE(60), ANGLE(60), -ANGLE(55), ANGLE(55) },
|
|
|
|
{ -ANGLE(80), ANGLE(80), -ANGLE(65), ANGLE(65) },
|
|
|
|
{ -ANGLE(80), ANGLE(80), -ANGLE(65), ANGLE(65) },
|
2019-11-12 12:28:54 +01:00
|
|
|
ANGLE(10),
|
|
|
|
ANGLE(8),
|
|
|
|
500,
|
|
|
|
8 * WALL_SIZE,
|
|
|
|
30,
|
|
|
|
0,
|
|
|
|
2,
|
|
|
|
12,
|
|
|
|
77
|
2019-11-20 11:24:36 +01:00
|
|
|
},
|
|
|
|
/* Snowmobile */
|
|
|
|
{
|
|
|
|
{ -ANGLE(30), ANGLE(30), -ANGLE(55), ANGLE(55) },
|
|
|
|
{ -ANGLE(30), ANGLE(30), -ANGLE(55), ANGLE(55) },
|
|
|
|
{ -ANGLE(30), ANGLE(30), -ANGLE(55), ANGLE(55) },
|
|
|
|
ANGLE(10),
|
|
|
|
ANGLE(8),
|
|
|
|
400,
|
|
|
|
8 * WALL_SIZE,
|
|
|
|
3,
|
|
|
|
0,
|
|
|
|
0,
|
|
|
|
0,
|
|
|
|
SFX_LARA_UZI_FIRE
|
2019-11-12 12:28:54 +01:00
|
|
|
}
|
2018-11-01 09:10:32 +01:00
|
|
|
};
|
|
|
|
|
2019-12-04 18:51:23 +01:00
|
|
|
short HoldStates[] = {
|
|
|
|
STATE_LARA_STOP,
|
|
|
|
STATE_LARA_POSE,
|
|
|
|
STATE_LARA_TURN_RIGHT_SLOW,
|
|
|
|
STATE_LARA_TURN_LEFT_SLOW,
|
|
|
|
STATE_LARA_WALK_BACK,
|
|
|
|
STATE_LARA_TURN_FAST,
|
|
|
|
STATE_LARA_WALK_RIGHT,
|
|
|
|
STATE_LARA_WALK_LEFT,
|
|
|
|
STATE_LARA_PICKUP,
|
|
|
|
STATE_LARA_SWITCH_DOWN,
|
|
|
|
STATE_LARA_SWITCH_UP,
|
|
|
|
STATE_LARA_WADE_FORWARD,
|
|
|
|
STATE_LARA_CROUCH_IDLE,
|
|
|
|
STATE_LARA_CROUCH_TURN_LEFT,
|
|
|
|
STATE_LARA_CROUCH_TURN_RIGHT,
|
|
|
|
-1
|
|
|
|
};
|
|
|
|
|
2018-11-01 22:45:59 +01:00
|
|
|
extern GameFlow* g_GameFlow;
|
2018-11-21 09:34:01 +01:00
|
|
|
extern LaraExtraInfo g_LaraExtra;
|
2019-11-24 17:01:13 +01:00
|
|
|
bool MonksAttackLara;
|
2018-11-01 22:45:59 +01:00
|
|
|
|
2019-12-02 14:49:19 +01:00
|
|
|
int WeaponObject(int weaponType)
|
2018-11-01 22:45:59 +01:00
|
|
|
{
|
|
|
|
switch (weaponType)
|
|
|
|
{
|
|
|
|
case WEAPON_UZI:
|
|
|
|
return ID_UZI_ANIM;
|
|
|
|
case WEAPON_SHOTGUN:
|
|
|
|
return ID_SHOTGUN_ANIM;
|
|
|
|
case WEAPON_REVOLVER:
|
|
|
|
return ID_REVOLVER_ANIM;
|
|
|
|
case WEAPON_CROSSBOW:
|
|
|
|
return ID_CROSSBOW_ANIM;
|
|
|
|
case WEAPON_HK:
|
|
|
|
return ID_HK_ANIM;
|
|
|
|
case WEAPON_FLARE:
|
|
|
|
return ID_FLARE_ANIM;
|
2018-11-21 09:34:01 +01:00
|
|
|
case WEAPON_GRENADE_LAUNCHER:
|
2018-11-01 22:45:59 +01:00
|
|
|
return ID_GRENADE_ANIM;
|
2018-11-21 09:34:01 +01:00
|
|
|
case WEAPON_ROCKET_LAUNCHER:
|
2018-11-01 22:45:59 +01:00
|
|
|
return ID_ROCKET_ANIM;
|
2018-11-21 09:34:01 +01:00
|
|
|
case WEAPON_HARPOON_GUN:
|
2018-11-01 22:45:59 +01:00
|
|
|
return ID_HARPOON_ANIM;
|
|
|
|
default:
|
|
|
|
return ID_PISTOLS_ANIM;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-12-02 14:49:19 +01:00
|
|
|
void AimWeapon(WEAPON_INFO* winfo, LARA_ARM* arm)
|
2019-11-12 12:28:54 +01:00
|
|
|
{
|
2019-12-02 09:11:21 +01:00
|
|
|
short rotY, rotX, speed = 0, x = 0, y = 0;
|
2019-11-12 12:28:54 +01:00
|
|
|
|
|
|
|
speed = winfo->aimSpeed;
|
|
|
|
|
|
|
|
if (arm->lock)
|
|
|
|
{
|
|
|
|
y = Lara.targetAngles[0];
|
|
|
|
x = Lara.targetAngles[1];
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
y = 0;
|
|
|
|
x = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* move y axis */
|
|
|
|
rotY = arm->yRot;
|
2019-12-03 14:58:00 +01:00
|
|
|
if ((rotY >= y - speed) && (rotY <= y + speed))
|
2019-11-12 12:28:54 +01:00
|
|
|
rotY = y;
|
2019-12-03 14:58:00 +01:00
|
|
|
else if (rotY < y)
|
2019-11-12 12:28:54 +01:00
|
|
|
rotY += speed;
|
|
|
|
else
|
|
|
|
rotY -= speed;
|
2019-11-14 14:09:43 +01:00
|
|
|
arm->yRot = rotY;
|
2019-11-12 12:28:54 +01:00
|
|
|
|
|
|
|
/* move x axis */
|
|
|
|
rotX = arm->xRot;
|
2019-12-03 14:58:00 +01:00
|
|
|
if ((rotX >= x - speed) && (rotX <= x + speed))
|
2019-11-12 12:28:54 +01:00
|
|
|
rotX = x;
|
|
|
|
else if (rotX < x)
|
|
|
|
rotX += speed;
|
|
|
|
else
|
|
|
|
rotX -= speed;
|
|
|
|
arm->xRot = rotX;
|
2019-11-14 14:09:43 +01:00
|
|
|
|
|
|
|
/* move z axis */
|
2019-11-12 12:28:54 +01:00
|
|
|
arm->zRot = 0;
|
|
|
|
}
|
|
|
|
|
2019-12-02 14:49:19 +01:00
|
|
|
void SmashItem(short itemNum)
|
2018-08-19 09:46:58 +02:00
|
|
|
{
|
2019-12-01 08:13:19 +01:00
|
|
|
ITEM_INFO* item = &Items[itemNum];
|
2019-12-04 13:20:21 +01:00
|
|
|
if (item->objectNumber >= ID_SMASH_OBJECT1 && item->objectNumber <= ID_SMASH_OBJECT8)
|
|
|
|
{
|
2018-08-19 09:46:58 +02:00
|
|
|
SmashObject(itemNum);
|
2019-12-04 13:20:21 +01:00
|
|
|
}
|
|
|
|
/*else if (item->objectNumber == ID_BELL_SWITCH)
|
2018-08-19 09:46:58 +02:00
|
|
|
{
|
|
|
|
if (item->status != ITEM_ACTIVE)
|
|
|
|
{
|
|
|
|
item->status = ITEM_ACTIVE;
|
|
|
|
AddActiveItem(itemNum);
|
|
|
|
}
|
2018-09-08 18:43:59 +02:00
|
|
|
}*/
|
2018-08-19 09:46:58 +02:00
|
|
|
}
|
|
|
|
|
2019-12-02 14:49:19 +01:00
|
|
|
void LaraGun()
|
2018-11-01 22:45:59 +01:00
|
|
|
{
|
|
|
|
if (Lara.leftArm.flash_gun > 0)
|
|
|
|
--Lara.leftArm.flash_gun;
|
|
|
|
if (Lara.rightArm.flash_gun > 0)
|
|
|
|
--Lara.rightArm.flash_gun;
|
|
|
|
|
2018-11-12 20:15:55 +01:00
|
|
|
if (Lara.gunType == WEAPON_TORCH)
|
2018-11-01 22:45:59 +01:00
|
|
|
{
|
|
|
|
DoFlameTorch();
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (LaraItem->hitPoints <= 0)
|
|
|
|
{
|
|
|
|
Lara.gunStatus = LG_NO_ARMS;
|
|
|
|
}
|
|
|
|
else if (!Lara.gunStatus)
|
|
|
|
{
|
|
|
|
if (TrInput & IN_DRAW)
|
2019-12-11 15:57:46 +01:00
|
|
|
{
|
2018-11-01 22:45:59 +01:00
|
|
|
Lara.requestGunType = Lara.lastGunType;
|
2019-12-11 15:57:46 +01:00
|
|
|
}
|
|
|
|
else if (TrInput & IN_FLARE && (g_GameFlow->GetLevel(CurrentLevel)->LaraType != LARA_YOUNG))
|
2018-11-01 22:45:59 +01:00
|
|
|
{
|
2019-12-11 15:57:46 +01:00
|
|
|
if (LaraItem->currentAnimState == STATE_LARA_CROUCH_IDLE && LaraItem->animNumber != ANIMATION_LARA_CROUCH_IDLE)
|
2018-11-01 22:45:59 +01:00
|
|
|
return;
|
|
|
|
|
|
|
|
if (Lara.gunType == WEAPON_FLARE && !Lara.leftArm.frameNumber)
|
2019-12-11 15:57:46 +01:00
|
|
|
{
|
2018-11-01 22:45:59 +01:00
|
|
|
Lara.gunStatus = LG_UNDRAW_GUNS;
|
2019-12-11 15:57:46 +01:00
|
|
|
}
|
2018-11-01 22:45:59 +01:00
|
|
|
else if (Lara.numFlares)
|
|
|
|
{
|
|
|
|
if (Lara.numFlares != -1)
|
|
|
|
Lara.numFlares--;
|
|
|
|
Lara.requestGunType = WEAPON_FLARE;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if ((Lara.requestGunType != Lara.gunType) || (TrInput & IN_DRAW))
|
|
|
|
{
|
2019-12-11 15:57:46 +01:00
|
|
|
if ((LaraItem->currentAnimState == STATE_LARA_CROUCH_IDLE
|
|
|
|
|| LaraItem->currentAnimState == STATE_LARA_CROUCH_TURN_LEFT
|
|
|
|
|| LaraItem->currentAnimState == STATE_LARA_CROUCH_TURN_RIGHT)
|
|
|
|
&& (Lara.requestGunType == WEAPON_HK
|
|
|
|
|| Lara.requestGunType == WEAPON_CROSSBOW
|
|
|
|
|| Lara.requestGunType == WEAPON_FLARE
|
|
|
|
|| Lara.requestGunType == WEAPON_HARPOON_GUN))
|
|
|
|
return;
|
|
|
|
|
|
|
|
if ((Lara.requestGunType == WEAPON_FLARE
|
|
|
|
|| ((g_LaraExtra.Vehicle == NO_ITEM)
|
|
|
|
&& ((Lara.requestGunType == WEAPON_HARPOON_GUN)
|
|
|
|
|| (Lara.waterStatus == LW_ABOVE_WATER)
|
|
|
|
|| ((Lara.waterStatus == LW_WADE)
|
|
|
|
&& Lara.waterSurfaceDist > -Weapons[Lara.gunType].gunHeight)))))
|
2018-11-01 22:45:59 +01:00
|
|
|
{
|
2019-12-11 15:57:46 +01:00
|
|
|
if (Lara.gunType == WEAPON_FLARE)
|
2018-11-01 22:45:59 +01:00
|
|
|
{
|
2019-12-11 15:57:46 +01:00
|
|
|
CreateFlare(ID_FLARE_ITEM, 0);
|
|
|
|
undraw_flare_meshes();
|
2019-12-11 18:07:27 +01:00
|
|
|
Lara.flareControlLeft = false;
|
2019-12-11 15:57:46 +01:00
|
|
|
Lara.flareAge = 0;
|
2018-11-01 22:45:59 +01:00
|
|
|
}
|
2019-12-11 15:57:46 +01:00
|
|
|
|
|
|
|
Lara.gunType = Lara.requestGunType;
|
|
|
|
InitialiseNewWeapon();
|
|
|
|
Lara.rightArm.frameNumber = 0;
|
|
|
|
Lara.leftArm.frameNumber = 0;
|
|
|
|
Lara.gunStatus = LG_DRAW_GUNS;
|
2018-11-01 22:45:59 +01:00
|
|
|
}
|
2019-12-11 15:57:46 +01:00
|
|
|
else
|
2018-11-01 22:45:59 +01:00
|
|
|
{
|
2019-12-11 15:57:46 +01:00
|
|
|
Lara.lastGunType = Lara.requestGunType;
|
|
|
|
if (Lara.gunType != WEAPON_FLARE)
|
|
|
|
Lara.gunType = Lara.requestGunType;
|
|
|
|
else
|
|
|
|
Lara.requestGunType = WEAPON_FLARE;
|
2018-11-01 22:45:59 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else if (Lara.gunStatus == LG_READY)
|
|
|
|
{
|
|
|
|
if ((TrInput & IN_DRAW) || Lara.requestGunType != Lara.gunType)
|
|
|
|
Lara.gunStatus = LG_UNDRAW_GUNS;
|
2019-12-11 15:57:46 +01:00
|
|
|
else if (Lara.gunType != WEAPON_HARPOON_GUN && Lara.waterStatus != LW_ABOVE_WATER && (Lara.waterStatus != LW_WADE || Lara.waterSurfaceDist < -Weapons[Lara.gunType].gunHeight))
|
2018-11-01 22:45:59 +01:00
|
|
|
Lara.gunStatus = LG_UNDRAW_GUNS;
|
|
|
|
}
|
2019-12-11 15:57:46 +01:00
|
|
|
else if (Lara.gunStatus == LG_HANDS_BUSY && (TrInput & IN_FLARE) && LaraItem->currentAnimState == STATE_LARA_CRAWL_IDLE && LaraItem->animNumber == ANIMATION_LARA_CRAWL_IDLE)
|
|
|
|
{
|
2018-11-01 22:45:59 +01:00
|
|
|
Lara.requestGunType = WEAPON_FLARE;
|
2019-12-11 15:57:46 +01:00
|
|
|
}
|
2018-11-01 22:45:59 +01:00
|
|
|
|
|
|
|
switch (Lara.gunStatus)
|
|
|
|
{
|
|
|
|
case LG_DRAW_GUNS:
|
|
|
|
if (Lara.gunType != WEAPON_FLARE && Lara.gunType)
|
|
|
|
Lara.lastGunType = Lara.gunType;
|
2019-12-11 15:57:46 +01:00
|
|
|
|
2018-11-01 22:45:59 +01:00
|
|
|
switch (Lara.gunType)
|
|
|
|
{
|
2019-12-11 15:57:46 +01:00
|
|
|
case WEAPON_PISTOLS:
|
|
|
|
case WEAPON_REVOLVER:
|
|
|
|
case WEAPON_UZI:
|
2019-12-11 18:07:27 +01:00
|
|
|
if (Camera.type != CINEMATIC_CAMERA && Camera.type != LOOK_CAMERA && Camera.type != HEAVY_CAMERA)
|
|
|
|
Camera.type = COMBAT_CAMERA;
|
2019-12-11 15:57:46 +01:00
|
|
|
draw_pistols(Lara.gunType);
|
|
|
|
break;
|
2018-11-01 22:45:59 +01:00
|
|
|
|
|
|
|
case WEAPON_SHOTGUN:
|
|
|
|
case WEAPON_CROSSBOW:
|
|
|
|
case WEAPON_HK:
|
2018-11-21 09:34:01 +01:00
|
|
|
case WEAPON_GRENADE_LAUNCHER:
|
|
|
|
case WEAPON_ROCKET_LAUNCHER:
|
|
|
|
case WEAPON_HARPOON_GUN:
|
2019-12-11 18:07:27 +01:00
|
|
|
if (Camera.type != CINEMATIC_CAMERA && Camera.type != LOOK_CAMERA && Camera.type != HEAVY_CAMERA)
|
|
|
|
Camera.type = COMBAT_CAMERA;
|
2019-12-11 15:57:46 +01:00
|
|
|
DrawShotgun(Lara.gunType);
|
|
|
|
break;
|
2018-11-01 22:45:59 +01:00
|
|
|
|
2019-12-11 15:57:46 +01:00
|
|
|
case WEAPON_FLARE:
|
|
|
|
draw_flare();
|
|
|
|
break;
|
2018-11-01 22:45:59 +01:00
|
|
|
|
2019-12-11 15:57:46 +01:00
|
|
|
default:
|
|
|
|
Lara.gunStatus = LG_NO_ARMS;
|
|
|
|
break;
|
2018-11-01 22:45:59 +01:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
2019-12-11 15:57:46 +01:00
|
|
|
case LG_SPECIAL:
|
|
|
|
draw_flare();
|
2018-11-01 22:45:59 +01:00
|
|
|
break;
|
|
|
|
|
2019-12-11 15:57:46 +01:00
|
|
|
case LG_UNDRAW_GUNS:
|
|
|
|
LARA_MESHES(ID_LARA, HEAD);
|
2018-11-01 22:45:59 +01:00
|
|
|
|
2019-12-11 15:57:46 +01:00
|
|
|
switch (Lara.gunType)
|
|
|
|
{
|
|
|
|
case WEAPON_PISTOLS:
|
|
|
|
case WEAPON_REVOLVER:
|
|
|
|
case WEAPON_UZI:
|
|
|
|
undraw_pistols(Lara.gunType);
|
|
|
|
break;
|
|
|
|
|
|
|
|
case WEAPON_SHOTGUN:
|
|
|
|
case WEAPON_CROSSBOW:
|
|
|
|
case WEAPON_HK:
|
|
|
|
case WEAPON_GRENADE_LAUNCHER:
|
|
|
|
case WEAPON_ROCKET_LAUNCHER:
|
|
|
|
case WEAPON_HARPOON_GUN:
|
|
|
|
undraw_shotgun(Lara.gunType);
|
|
|
|
break;
|
|
|
|
|
|
|
|
case WEAPON_FLARE:
|
|
|
|
undraw_flare();
|
|
|
|
break;
|
|
|
|
|
|
|
|
default:
|
|
|
|
return;
|
|
|
|
}
|
2018-11-01 22:45:59 +01:00
|
|
|
break;
|
|
|
|
|
2019-12-11 15:57:46 +01:00
|
|
|
case LG_READY:
|
|
|
|
if (!(TrInput & IN_ACTION))
|
|
|
|
LARA_MESHES(ID_LARA, HEAD);
|
|
|
|
else
|
|
|
|
LARA_MESHES(ID_LARA_SCREAM, HEAD);
|
2018-11-01 22:45:59 +01:00
|
|
|
|
2019-12-11 18:07:27 +01:00
|
|
|
if (Camera.type != CINEMATIC_CAMERA && Camera.type != LOOK_CAMERA && Camera.type != HEAVY_CAMERA)
|
|
|
|
Camera.type = COMBAT_CAMERA;
|
2018-11-01 22:45:59 +01:00
|
|
|
|
2019-12-11 15:57:46 +01:00
|
|
|
if (TrInput & IN_ACTION)
|
2018-11-01 22:45:59 +01:00
|
|
|
{
|
2019-12-11 15:57:46 +01:00
|
|
|
if (!*GetAmmo(Lara.gunType))
|
|
|
|
{
|
|
|
|
Lara.requestGunType = (Objects[ID_PISTOLS_ITEM].loaded == true) ? WEAPON_PISTOLS : WEAPON_NONE;
|
|
|
|
//SoundEffect(SFX_EMPTY_WEAPON, &LaraItem->pos, 0);
|
|
|
|
return;
|
|
|
|
}
|
2018-11-01 22:45:59 +01:00
|
|
|
}
|
|
|
|
|
2019-12-11 15:57:46 +01:00
|
|
|
switch (Lara.gunType)
|
|
|
|
{
|
|
|
|
case WEAPON_PISTOLS:
|
|
|
|
case WEAPON_UZI:
|
|
|
|
PistolHandler(Lara.gunType);
|
|
|
|
break;
|
|
|
|
|
|
|
|
case WEAPON_SHOTGUN:
|
|
|
|
case WEAPON_CROSSBOW:
|
|
|
|
case WEAPON_HK:
|
|
|
|
case WEAPON_GRENADE_LAUNCHER:
|
|
|
|
case WEAPON_ROCKET_LAUNCHER:
|
|
|
|
case WEAPON_HARPOON_GUN:
|
|
|
|
case WEAPON_REVOLVER:
|
|
|
|
RifleHandler(Lara.gunType);
|
|
|
|
break;
|
|
|
|
|
|
|
|
default:
|
|
|
|
return;
|
|
|
|
}
|
2018-11-01 22:45:59 +01:00
|
|
|
break;
|
|
|
|
|
2019-12-11 15:57:46 +01:00
|
|
|
case LG_NO_ARMS:
|
|
|
|
if (Lara.gunType == WEAPON_FLARE)
|
2018-11-01 22:45:59 +01:00
|
|
|
{
|
2019-12-11 15:57:46 +01:00
|
|
|
if (g_LaraExtra.Vehicle != NO_ITEM || CheckForHoldingState(LaraItem->currentAnimState))
|
2018-11-01 22:45:59 +01:00
|
|
|
{
|
2019-12-11 15:57:46 +01:00
|
|
|
if (Lara.flareControlLeft)
|
2018-11-01 22:45:59 +01:00
|
|
|
{
|
2019-12-11 15:57:46 +01:00
|
|
|
if (Lara.leftArm.frameNumber)
|
|
|
|
{
|
|
|
|
if (++Lara.leftArm.frameNumber == 110)
|
|
|
|
Lara.leftArm.frameNumber = 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
Lara.leftArm.frameNumber = 95;
|
|
|
|
Lara.flareControlLeft = true;
|
2018-11-01 22:45:59 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2019-12-11 15:57:46 +01:00
|
|
|
Lara.flareControlLeft = false;
|
2018-11-01 22:45:59 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
DoFlareInHand(Lara.flareAge);
|
2019-12-01 08:13:19 +01:00
|
|
|
set_flare_arm(Lara.leftArm.frameNumber);
|
2018-11-01 22:45:59 +01:00
|
|
|
}
|
2019-12-11 15:57:46 +01:00
|
|
|
break;
|
2018-11-01 22:45:59 +01:00
|
|
|
|
2019-12-11 15:57:46 +01:00
|
|
|
case LG_HANDS_BUSY:
|
|
|
|
if (Lara.gunType == WEAPON_FLARE)
|
|
|
|
{
|
|
|
|
if (CHECK_LARA_MESHES(ID_FLARE_ANIM, HAND_L))
|
|
|
|
{
|
|
|
|
Lara.flareControlLeft = (g_LaraExtra.Vehicle != NO_ITEM || CheckForHoldingState(LaraItem->currentAnimState));
|
|
|
|
DoFlareInHand(Lara.flareAge);
|
|
|
|
set_flare_arm(Lara.leftArm.frameNumber);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
break;
|
2018-11-01 22:45:59 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-12-02 14:49:19 +01:00
|
|
|
short* GetAmmo(int weaponType)
|
2018-11-01 22:45:59 +01:00
|
|
|
{
|
2018-11-21 09:34:01 +01:00
|
|
|
return &g_LaraExtra.Weapons[weaponType].Ammo[g_LaraExtra.Weapons[weaponType].SelectedAmmo];
|
2018-11-01 22:45:59 +01:00
|
|
|
}
|
|
|
|
|
2019-12-02 14:49:19 +01:00
|
|
|
void InitialiseNewWeapon()
|
2018-11-01 22:45:59 +01:00
|
|
|
{
|
|
|
|
Lara.rightArm.frameNumber = 0;
|
|
|
|
Lara.leftArm.frameNumber = 0;
|
|
|
|
Lara.leftArm.zRot = 0;
|
|
|
|
Lara.leftArm.yRot = 0;
|
|
|
|
Lara.leftArm.xRot = 0;
|
|
|
|
Lara.rightArm.zRot = 0;
|
|
|
|
Lara.rightArm.yRot = 0;
|
|
|
|
Lara.rightArm.xRot = 0;
|
|
|
|
Lara.target = 0;
|
|
|
|
Lara.rightArm.lock = 0;
|
|
|
|
Lara.leftArm.lock = 0;
|
|
|
|
Lara.rightArm.flash_gun = 0;
|
|
|
|
Lara.leftArm.flash_gun = 0;
|
|
|
|
|
|
|
|
switch (Lara.gunType)
|
|
|
|
{
|
|
|
|
case WEAPON_PISTOLS:
|
|
|
|
case WEAPON_UZI:
|
|
|
|
Lara.rightArm.frameBase = Objects[ID_PISTOLS_ANIM].frameBase;
|
|
|
|
Lara.leftArm.frameBase = Objects[ID_PISTOLS_ANIM].frameBase;
|
2019-12-03 13:53:17 +01:00
|
|
|
if (Lara.gunStatus != LG_NO_ARMS)
|
2019-12-01 08:13:19 +01:00
|
|
|
draw_pistol_meshes(Lara.gunType);
|
2018-11-01 22:45:59 +01:00
|
|
|
break;
|
|
|
|
|
|
|
|
case WEAPON_SHOTGUN:
|
|
|
|
case WEAPON_REVOLVER:
|
|
|
|
case WEAPON_HK:
|
2018-11-21 09:34:01 +01:00
|
|
|
case WEAPON_GRENADE_LAUNCHER:
|
|
|
|
case WEAPON_HARPOON_GUN:
|
|
|
|
case WEAPON_ROCKET_LAUNCHER:
|
2018-11-01 22:45:59 +01:00
|
|
|
Lara.rightArm.frameBase = Objects[WeaponObject(Lara.gunType)].frameBase;
|
2019-12-03 13:53:17 +01:00
|
|
|
Lara.leftArm.frameBase = Objects[WeaponObject(Lara.gunType)].frameBase;
|
|
|
|
if (Lara.gunStatus != LG_NO_ARMS)
|
|
|
|
draw_shotgun_meshes(Lara.gunType);
|
2018-11-01 22:45:59 +01:00
|
|
|
break;
|
|
|
|
|
|
|
|
case WEAPON_FLARE:
|
|
|
|
Lara.rightArm.frameBase = Objects[ID_FLARE_ANIM].frameBase;
|
|
|
|
Lara.leftArm.frameBase = Objects[ID_FLARE_ANIM].frameBase;
|
2019-12-03 13:53:17 +01:00
|
|
|
if (Lara.gunStatus != LG_NO_ARMS)
|
2019-12-01 08:13:19 +01:00
|
|
|
draw_flare_meshes();
|
2018-11-01 22:45:59 +01:00
|
|
|
break;
|
|
|
|
|
|
|
|
default:
|
|
|
|
Lara.rightArm.frameBase = Anims[LaraItem->animNumber].framePtr;
|
|
|
|
Lara.leftArm.frameBase = Anims[LaraItem->animNumber].framePtr;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-12-02 14:49:19 +01:00
|
|
|
int WeaponObjectMesh(int weaponType)
|
2018-11-01 22:45:59 +01:00
|
|
|
{
|
|
|
|
switch (weaponType)
|
|
|
|
{
|
|
|
|
case WEAPON_REVOLVER:
|
2019-12-04 13:20:21 +01:00
|
|
|
return (g_LaraExtra.Weapons[WEAPON_REVOLVER].HasLasersight == true ? ID_LARA_REVOLVER_LASER : ID_REVOLVER_ANIM);
|
2018-11-01 22:45:59 +01:00
|
|
|
|
|
|
|
case WEAPON_UZI:
|
|
|
|
return ID_UZI_ANIM;
|
|
|
|
|
|
|
|
case WEAPON_SHOTGUN:
|
|
|
|
return ID_SHOTGUN_ANIM;
|
|
|
|
|
|
|
|
case WEAPON_HK:
|
|
|
|
return ID_HK_ANIM;
|
|
|
|
|
|
|
|
case WEAPON_CROSSBOW:
|
2019-12-04 13:20:21 +01:00
|
|
|
return (g_LaraExtra.Weapons[WEAPON_CROSSBOW].HasLasersight == true ? ID_LARA_CROSSBOW_LASER : ID_CROSSBOW_ANIM);
|
2018-11-01 22:45:59 +01:00
|
|
|
|
2018-11-21 09:34:01 +01:00
|
|
|
case WEAPON_GRENADE_LAUNCHER:
|
2018-11-01 22:45:59 +01:00
|
|
|
return ID_GRENADE_ANIM;
|
|
|
|
|
2018-11-21 09:34:01 +01:00
|
|
|
case WEAPON_HARPOON_GUN:
|
2018-11-01 22:45:59 +01:00
|
|
|
return ID_HARPOON_ANIM;
|
|
|
|
|
2018-11-21 09:34:01 +01:00
|
|
|
case WEAPON_ROCKET_LAUNCHER:
|
2018-11-01 22:45:59 +01:00
|
|
|
return ID_ROCKET_ANIM;
|
|
|
|
|
|
|
|
default:
|
|
|
|
return ID_PISTOLS_ANIM;
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-12-02 14:49:19 +01:00
|
|
|
void HitTarget(ITEM_INFO* item, GAME_VECTOR* hitPos, int damage, int flag)
|
2019-12-01 08:13:19 +01:00
|
|
|
{
|
|
|
|
CREATURE_INFO* creature = (CREATURE_INFO*)item->data;
|
|
|
|
OBJECT_INFO* obj = &Objects[item->objectNumber];
|
|
|
|
|
|
|
|
item->hitStatus = true;
|
|
|
|
if (creature && item != LaraItem)
|
|
|
|
creature->hurtByLara = true;
|
|
|
|
|
|
|
|
if (hitPos)
|
|
|
|
{
|
|
|
|
if (obj->hitEffect)
|
|
|
|
{
|
|
|
|
switch (obj->hitEffect)
|
|
|
|
{
|
2019-12-11 18:07:27 +01:00
|
|
|
case 1:
|
|
|
|
DoBloodSplat(hitPos->x, hitPos->y, hitPos->z, (GetRandomControl() & 3) + 3, item->pos.yRot, item->roomNumber);
|
|
|
|
break;
|
|
|
|
case 3:
|
|
|
|
TriggerRicochetSparks(hitPos, LaraItem->pos.yRot, 3, 0);
|
|
|
|
break;
|
|
|
|
case 2:
|
|
|
|
TriggerRicochetSparks(hitPos, LaraItem->pos.yRot, 3, -5);
|
|
|
|
SoundEffect(SFX_SWORD_GOD_HITMET, &item->pos, 0);
|
|
|
|
break;
|
2019-12-01 08:13:19 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (!obj->undead || flag || item->hitPoints == -16384)
|
|
|
|
{
|
|
|
|
if (item->hitPoints > 0 && item->hitPoints <= damage)
|
|
|
|
++Savegame.Level.Kills;
|
|
|
|
item->hitPoints -= damage;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-12-11 18:07:27 +01:00
|
|
|
int DetectCrouchWhenFiring(ITEM_INFO* src, WEAPON_INFO* weapon)
|
2019-12-01 08:13:19 +01:00
|
|
|
{
|
2019-12-11 18:07:27 +01:00
|
|
|
if (src->currentAnimState == STATE_LARA_CROUCH_IDLE || src->currentAnimState == STATE_LARA_CROUCH_TURN_LEFT || src->currentAnimState == STATE_LARA_CROUCH_TURN_RIGHT)
|
|
|
|
return STEP_SIZE;
|
|
|
|
else
|
|
|
|
return int(weapon->gunHeight);
|
|
|
|
}
|
2019-12-01 08:13:19 +01:00
|
|
|
|
2019-12-11 18:07:27 +01:00
|
|
|
int FireWeapon(int weaponType, ITEM_INFO* target, ITEM_INFO* src, short* angles)
|
|
|
|
{
|
2019-12-02 09:11:21 +01:00
|
|
|
short* ammo = GetAmmo(weaponType);
|
2019-12-01 08:13:19 +01:00
|
|
|
if (!*ammo)
|
|
|
|
return 0;
|
|
|
|
if (*ammo != -1)
|
|
|
|
(*ammo)--;
|
|
|
|
|
|
|
|
WEAPON_INFO* weapon = &Weapons[weaponType];
|
|
|
|
|
2019-12-11 18:07:27 +01:00
|
|
|
PHD_3DPOS pos;
|
|
|
|
pos.xPos = 0;
|
|
|
|
pos.yPos = 0;
|
|
|
|
pos.zPos = 0;
|
|
|
|
GetLaraJointPosition((PHD_VECTOR*)&pos, LJ_RHAND);
|
2019-12-01 08:13:19 +01:00
|
|
|
pos.xPos = src->pos.xPos;
|
2019-12-11 18:07:27 +01:00
|
|
|
pos.yPos = src->pos.yPos - DetectCrouchWhenFiring(src, weapon);
|
2019-12-01 08:13:19 +01:00
|
|
|
pos.zPos = src->pos.zPos;
|
2019-12-11 18:07:27 +01:00
|
|
|
|
|
|
|
short r = short(((GetRandomControl() - 0x4000) * weapon->shotAccuracy) / 0x10000);
|
|
|
|
pos.xRot = angles[1] + r;
|
|
|
|
pos.yRot = angles[0] + r;
|
2019-12-01 08:13:19 +01:00
|
|
|
pos.zRot = 0;
|
|
|
|
|
|
|
|
phd_GenerateW2V(&pos);
|
|
|
|
|
2019-12-02 09:11:21 +01:00
|
|
|
int num = GetSpheres(target, SphereList, 0);
|
|
|
|
int best = -1;
|
|
|
|
int bestDistance = 0x7FFFFFFF;
|
2019-12-01 08:13:19 +01:00
|
|
|
|
2019-12-02 09:11:21 +01:00
|
|
|
for (int i = 0; i < num; i++)
|
2019-12-01 08:13:19 +01:00
|
|
|
{
|
|
|
|
SPHERE* sphere = &SphereList[i];
|
|
|
|
|
|
|
|
r = sphere->r;
|
|
|
|
if ((abs(sphere->x)) < r && (abs(sphere->y)) < r && sphere->z > r && SQUARE(sphere->x) + SQUARE(sphere->y) <= SQUARE(r))
|
|
|
|
{
|
|
|
|
if (sphere->z - r < bestDistance)
|
|
|
|
{
|
|
|
|
bestDistance = sphere->z - r;
|
|
|
|
best = i;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
Lara.hasFired = true;
|
|
|
|
Lara.fired = true;
|
|
|
|
|
|
|
|
GAME_VECTOR vSrc;
|
|
|
|
vSrc.x = pos.xPos;
|
|
|
|
vSrc.y = pos.yPos;
|
|
|
|
vSrc.z = pos.zPos;
|
|
|
|
|
2019-12-02 09:11:21 +01:00
|
|
|
short roomNumber = src->roomNumber;
|
2019-12-01 08:13:19 +01:00
|
|
|
FLOOR_INFO* floor = GetFloor(pos.xPos, pos.yPos, pos.zPos, &roomNumber);
|
|
|
|
vSrc.roomNumber = roomNumber;
|
|
|
|
|
|
|
|
if (best < 0)
|
|
|
|
{
|
|
|
|
GAME_VECTOR vDest;
|
2019-12-04 13:20:21 +01:00
|
|
|
vDest.x = vSrc.x + ((MatrixPtr[M20] * weapon->targetDist) >> W2V_SHIFT);
|
|
|
|
vDest.y = vSrc.y + ((MatrixPtr[M21] * weapon->targetDist) >> W2V_SHIFT);
|
|
|
|
vDest.z = vSrc.z + ((MatrixPtr[M22] * weapon->targetDist) >> W2V_SHIFT);
|
2019-12-01 08:13:19 +01:00
|
|
|
|
|
|
|
GetTargetOnLOS(&vSrc, &vDest, 0, 1);
|
|
|
|
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
Savegame.Game.AmmoHits++;
|
|
|
|
|
|
|
|
GAME_VECTOR vDest;
|
2019-12-04 13:20:21 +01:00
|
|
|
vDest.x = vSrc.x + ((MatrixPtr[M20] * bestDistance) >> W2V_SHIFT);
|
|
|
|
vDest.y = vSrc.y + ((MatrixPtr[M21] * bestDistance) >> W2V_SHIFT);
|
|
|
|
vDest.z = vSrc.z + ((MatrixPtr[M22] * bestDistance) >> W2V_SHIFT);
|
2019-12-01 08:13:19 +01:00
|
|
|
|
2019-12-02 14:49:19 +01:00
|
|
|
// TODO: enable it when the slot is created !
|
2019-12-04 13:20:21 +01:00
|
|
|
/*
|
|
|
|
if (target->objectNumber == ID_TRIBEBOSS)
|
2019-12-02 14:49:19 +01:00
|
|
|
{
|
|
|
|
long dx, dy, dz;
|
|
|
|
|
|
|
|
dx = (vDest.x - vSrc.x) >> 5;
|
|
|
|
dy = (vDest.y - vSrc.y) >> 5;
|
|
|
|
dz = (vDest.z - vSrc.z) >> 5;
|
|
|
|
FindClosestShieldPoint(vDest.x - dx, vDest.y - dy, vDest.z - dz, target);
|
|
|
|
}
|
|
|
|
else if (target->objectNumber == ID_ARMY_WINSTON || target->objectNumber == ID_LONDONBOSS) //Don't want blood on Winston - never get the stains out
|
|
|
|
{
|
|
|
|
short ricochet_angle;
|
|
|
|
target->hitStatus = true; //need to do this to maintain defence state
|
|
|
|
target->hitPoints--;
|
|
|
|
ricochet_angle = (mGetAngle(LaraItem->pos.zPos, LaraItem->pos.xPos, target->pos.zPos, target->pos.xPos) >> 4) & 4095;
|
|
|
|
TriggerRicochetSparks(&vDest, ricochet_angle, 16, 0);
|
|
|
|
SoundEffect(SFX_LARA_RICOCHET, &target->pos, 0); // play RICOCHET Sample
|
|
|
|
}
|
|
|
|
else if (target->objectNumber == ID_SHIVA) //So must be Shiva
|
|
|
|
{
|
|
|
|
z = target->pos.zPos - lara_item->pos.zPos;
|
|
|
|
x = target->pos.xPos - lara_item->pos.xPos;
|
|
|
|
angle = 0x8000 + ATAN(z, x) - target->pos.yRot;
|
|
|
|
|
|
|
|
if ((target->currentAnimState > 1 && target->currentAnimState < 5) && angle < 0x4000 && angle > -0x4000)
|
|
|
|
{
|
|
|
|
target->hitStatus = true; //need to do this to maintain defence state
|
|
|
|
ricochet_angle = (mGetAngle(LaraItem->pos.zPos, LaraItem->pos.xPos, target->pos.zPos, target->pos.xPos) >> 4) & 4095;
|
|
|
|
TriggerRicochetSparks(&vDest, ricochet_angle, 16, 0);
|
|
|
|
SoundEffect(SFX_LARA_RICOCHET, &target->pos, 0); // play RICOCHET Sample
|
|
|
|
}
|
|
|
|
else //Shiva's not in defence mode or has its back to Lara
|
|
|
|
HitTarget(target, &vDest, weapon->damage, 0);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{*/
|
|
|
|
if (!GetTargetOnLOS(&vSrc, &vDest, 0, 1))
|
|
|
|
HitTarget(target, &vDest, weapon->damage, 0);
|
|
|
|
//}
|
2019-12-01 08:13:19 +01:00
|
|
|
|
|
|
|
return 1;
|
|
|
|
}
|
2019-12-04 13:20:21 +01:00
|
|
|
|
|
|
|
return 0;
|
2019-12-01 08:13:19 +01:00
|
|
|
}
|
|
|
|
|
2019-12-02 14:49:19 +01:00
|
|
|
void find_target_point(ITEM_INFO* item, GAME_VECTOR* target)
|
2019-12-01 08:13:19 +01:00
|
|
|
{
|
2019-12-02 09:11:21 +01:00
|
|
|
short* bounds = GetBestFrame(item);
|
2019-12-01 08:13:19 +01:00
|
|
|
|
2019-12-11 18:07:27 +01:00
|
|
|
int x = int((bounds[0] + bounds[1]) / 2);
|
|
|
|
int y = int((bounds[2] + (bounds[3] - bounds[2])) / 3);
|
|
|
|
int z = int((bounds[4] + bounds[5]) / 2);
|
2019-12-01 08:13:19 +01:00
|
|
|
|
2019-12-02 09:11:21 +01:00
|
|
|
int c = COS(item->pos.yRot);
|
|
|
|
int s = SIN(item->pos.yRot);
|
2019-12-01 08:13:19 +01:00
|
|
|
|
|
|
|
target->x = item->pos.xPos + ((c * x + s * z) >> W2V_SHIFT);
|
|
|
|
target->y = item->pos.yPos + y;
|
|
|
|
target->z = item->pos.zPos + ((c * z - s * x) >> W2V_SHIFT);
|
|
|
|
|
|
|
|
target->roomNumber = item->roomNumber;
|
|
|
|
}
|
|
|
|
|
2019-12-02 14:49:19 +01:00
|
|
|
void LaraTargetInfo(WEAPON_INFO* weapon)
|
2019-12-01 08:13:19 +01:00
|
|
|
{
|
|
|
|
if (!Lara.target)
|
|
|
|
{
|
2019-12-11 18:07:27 +01:00
|
|
|
Lara.rightArm.lock = false;
|
|
|
|
Lara.leftArm.lock = false;
|
2019-12-01 08:13:19 +01:00
|
|
|
Lara.targetAngles[1] = 0;
|
|
|
|
Lara.targetAngles[0] = 0;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
GAME_VECTOR pos;
|
|
|
|
pos.x = 0;
|
|
|
|
pos.y = 0;
|
|
|
|
pos.z = 0;
|
|
|
|
|
|
|
|
GetLaraJointPosition((PHD_VECTOR*)&pos, LJ_RHAND);
|
|
|
|
|
|
|
|
pos.x = LaraItem->pos.xPos;
|
|
|
|
pos.z = LaraItem->pos.zPos;
|
|
|
|
pos.roomNumber = LaraItem->roomNumber;
|
|
|
|
|
|
|
|
GAME_VECTOR targetPoint;
|
|
|
|
find_target_point(Lara.target, &targetPoint);
|
|
|
|
|
2019-12-02 09:11:21 +01:00
|
|
|
short angles[2];
|
2019-12-01 08:13:19 +01:00
|
|
|
phd_GetVectorAngles(targetPoint.x - pos.x, targetPoint.y - pos.y, targetPoint.z - pos.z, angles);
|
|
|
|
|
|
|
|
angles[0] -= LaraItem->pos.yRot;
|
|
|
|
angles[1] -= LaraItem->pos.xRot;
|
|
|
|
|
|
|
|
if (LOS(&pos, &targetPoint))
|
|
|
|
{
|
|
|
|
if (angles[0] >= weapon->lockAngles[0]
|
2019-12-04 13:20:21 +01:00
|
|
|
&& angles[0] <= weapon->lockAngles[1]
|
|
|
|
&& angles[1] >= weapon->lockAngles[2]
|
|
|
|
&& angles[1] <= weapon->lockAngles[3])
|
2019-12-01 08:13:19 +01:00
|
|
|
{
|
2019-12-04 13:20:21 +01:00
|
|
|
Lara.rightArm.lock = true;
|
|
|
|
Lara.leftArm.lock = true;
|
2019-12-01 08:13:19 +01:00
|
|
|
Lara.targetAngles[0] = angles[0];
|
|
|
|
Lara.targetAngles[1] = angles[1];
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (Lara.leftArm.lock
|
2019-12-04 13:20:21 +01:00
|
|
|
&& (angles[0] < weapon->leftAngles[0]
|
|
|
|
|| angles[0] > weapon->leftAngles[1]
|
|
|
|
|| angles[1] < weapon->leftAngles[2]
|
|
|
|
|| angles[1] > weapon->leftAngles[3]))
|
2019-12-01 08:13:19 +01:00
|
|
|
{
|
2019-12-04 13:20:21 +01:00
|
|
|
Lara.leftArm.lock = false;
|
2019-12-01 08:13:19 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
if (Lara.rightArm.lock
|
2019-12-04 13:20:21 +01:00
|
|
|
&& (angles[0] < weapon->rightAngles[0]
|
|
|
|
|| angles[0] > weapon->rightAngles[1]
|
|
|
|
|| angles[1] < weapon->rightAngles[2]
|
|
|
|
|| angles[1] > weapon->rightAngles[3]))
|
2019-12-01 08:13:19 +01:00
|
|
|
{
|
2019-12-04 13:20:21 +01:00
|
|
|
Lara.rightArm.lock = false;
|
2019-12-01 08:13:19 +01:00
|
|
|
Lara.targetAngles[0] = angles[0];
|
|
|
|
Lara.targetAngles[1] = angles[1];
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2019-12-04 13:20:21 +01:00
|
|
|
Lara.rightArm.lock = false;
|
|
|
|
Lara.leftArm.lock = false;
|
2019-12-01 08:13:19 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
Lara.targetAngles[0] = angles[0];
|
|
|
|
Lara.targetAngles[1] = angles[1];
|
|
|
|
}
|
|
|
|
|
2019-12-04 18:51:23 +01:00
|
|
|
int CheckForHoldingState(int state)
|
|
|
|
{
|
|
|
|
short* holdState = HoldStates;
|
|
|
|
|
|
|
|
if (g_LaraExtra.ExtraAnim)
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
while (*holdState >= 0)
|
|
|
|
{
|
|
|
|
if (state == *holdState)
|
|
|
|
return 1;
|
|
|
|
holdState++;
|
|
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2018-08-19 09:46:58 +02:00
|
|
|
void Inject_LaraFire()
|
|
|
|
{
|
2019-11-12 12:28:54 +01:00
|
|
|
INJECT(0x00453490, AimWeapon);
|
2018-11-12 20:15:55 +01:00
|
|
|
INJECT(0x00453AE0, WeaponObject);
|
|
|
|
INJECT(0x00452430, LaraGun);
|
|
|
|
INJECT(0x004546C0, GetAmmo);
|
|
|
|
INJECT(0x00452B30, InitialiseNewWeapon);
|
|
|
|
INJECT(0x00453B50, WeaponObjectMesh);
|
2018-09-08 18:43:59 +02:00
|
|
|
//INJECT(0x00453A90, SmashItem);
|
2018-08-19 09:46:58 +02:00
|
|
|
}
|